commented early_printk patch because of rejects.
[linux-flexiantxendom0-3.2.10.git] / drivers / media / video / saa7110.c
1 /*
2     saa7110 - Philips SAA7110(A) video decoder driver
3
4     Copyright (C) 1998 Pauline Middelink <middelin@polyware.nl>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/types.h>
24 #include <linux/delay.h>
25 #include <linux/slab.h>
26 #include <asm/io.h>
27 #include <asm/uaccess.h>
28
29 #include <linux/i2c.h>
30 #include <linux/videodev.h>
31 #include "linux/video_decoder.h"
32
33 #define DEBUG(x...)                     /* remove when no long debugging */
34
35 #define SAA7110_MAX_INPUT       9       /* 6 CVBS, 3 SVHS */
36 #define SAA7110_MAX_OUTPUT      0       /* it's a decoder only */
37
38 #define I2C_SAA7110             0x9C    /* or 0x9E */
39
40 #define IF_NAME "saa7110"
41 #define I2C_DELAY               10      /* 10 us or 100khz */
42
43 static unsigned short normal_i2c[] = {34>>1, I2C_CLIENT_END };
44 static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
45 static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
46 static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
47 static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
48 static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
49 static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
50
51 static struct i2c_client_address_data addr_data = {
52         normal_i2c, normal_i2c_range,
53         probe, probe_range,
54         ignore, ignore_range,
55         force
56 };
57
58 static struct i2c_client client_template;
59
60 struct saa7110 {
61         struct i2c_client *client;
62         int             addr;
63         unsigned char   reg[36];
64         struct semaphore lock;
65         int             norm;
66         int             input;
67         int             enable;
68         int             bright;
69         int             contrast;
70         int             hue;
71         int             sat;
72 };
73
74 /* ----------------------------------------------------------------------- */
75 /* SAA7110 functions                                                       */
76 /* ----------------------------------------------------------------------- */
77 static
78 int saa7110_selmux(struct i2c_client *client, int chan)
79 {
80 static  const unsigned char modes[9][8] = {
81 /* mode 0 */    { 0x00, 0xD9, 0x17, 0x40, 0x03, 0x44, 0x75, 0x16 },
82 /* mode 1 */    { 0x00, 0xD8, 0x17, 0x40, 0x03, 0x44, 0x75, 0x16 },
83 /* mode 2 */    { 0x00, 0xBA, 0x07, 0x91, 0x03, 0x60, 0xB5, 0x05 },
84 /* mode 3 */    { 0x00, 0xB8, 0x07, 0x91, 0x03, 0x60, 0xB5, 0x05 },
85 /* mode 4 */    { 0x00, 0x7C, 0x07, 0xD2, 0x83, 0x60, 0xB5, 0x03 },
86 /* mode 5 */    { 0x00, 0x78, 0x07, 0xD2, 0x83, 0x60, 0xB5, 0x03 },
87 /* mode 6 */    { 0x80, 0x59, 0x17, 0x42, 0xA3, 0x44, 0x75, 0x12 },
88 /* mode 7 */    { 0x80, 0x9A, 0x17, 0xB1, 0x13, 0x60, 0xB5, 0x14 },
89 /* mode 8 */    { 0x80, 0x3C, 0x27, 0xC1, 0x23, 0x44, 0x75, 0x21 } };
90         const unsigned char* ptr = modes[chan];
91
92         i2c_smbus_write_byte_data(client,0x06,ptr[0]);  /* Luminance control    */
93         i2c_smbus_write_byte_data(client,0x20,ptr[1]);  /* Analog Control #1    */
94         i2c_smbus_write_byte_data(client,0x21,ptr[2]);  /* Analog Control #2    */
95         i2c_smbus_write_byte_data(client,0x22,ptr[3]);  /* Mixer Control #1     */
96         i2c_smbus_write_byte_data(client,0x2C,ptr[4]);  /* Mixer Control #2     */
97         i2c_smbus_write_byte_data(client,0x30,ptr[5]);  /* ADCs gain control    */
98         i2c_smbus_write_byte_data(client,0x31,ptr[6]);  /* Mixer Control #3     */
99         i2c_smbus_write_byte_data(client,0x21,ptr[7]);  /* Analog Control #2    */
100
101         return 0;
102 }
103
104 static
105 int determine_norm(struct i2c_client* client)
106 {
107         int     status;
108
109         /* mode changed, start automatic detection */
110         status = i2c_smbus_read_byte(client);
111         if ((status & 3) == 0) {
112                 i2c_smbus_write_byte_data(client,0x06,0x80);
113                 if (status & 0x20) {
114                         DEBUG(printk(KERN_INFO "%s: norm=bw60\n",adp->name));
115                         i2c_smbus_write_byte_data(client,0x2E,0x81);
116                         return VIDEO_MODE_NTSC;
117                 }
118                 DEBUG(printk(KERN_INFO "%s: norm=bw50\n",adp->name));
119                 i2c_smbus_write_byte_data(client,0x2E,0x9A);
120                 return VIDEO_MODE_PAL;
121         }
122
123         i2c_smbus_write_byte_data(client,0x06,0x00);
124         if (status & 0x20) {    /* 60Hz */
125                 DEBUG(printk(KERN_INFO "%s: norm=ntsc\n",adp->name));
126                 i2c_smbus_write_byte_data(client,0x0D,0x06);
127                 i2c_smbus_write_byte_data(client,0x11,0x2C);
128                 i2c_smbus_write_byte_data(client,0x2E,0x81);
129                 return VIDEO_MODE_NTSC;
130         }
131
132         /* 50Hz -> PAL/SECAM */
133         i2c_smbus_write_byte_data(client,0x0D,0x06);
134         i2c_smbus_write_byte_data(client,0x11,0x59);
135         i2c_smbus_write_byte_data(client,0x2E,0x9A);
136
137         mdelay(150);    /* pause 150 ms */
138
139         status = i2c_smbus_read_byte(client);
140         if ((status & 0x03) == 0x01) {
141                 DEBUG(printk(KERN_INFO "%s: norm=secam\n",dev->name));
142                 i2c_smbus_write_byte_data(client,0x0D,0x07);
143                 return VIDEO_MODE_SECAM;
144         }
145         DEBUG(printk(KERN_INFO "%s: norm=pal\n",dev->name));
146         return VIDEO_MODE_PAL;
147 }
148
149 static
150 int saa7110_attach(struct i2c_adapter *adap, int  addr, int kind)
151 {
152 static  const unsigned char initseq[] = {
153              0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF0, 0x00, 0x00,
154                 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x06, 0x18, 0x90,
155                 0x00, 0x2C, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA,
156                 0xF0, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157                 0xD9, 0x17, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
158                 0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x81, 0x03,
159                 0x40, 0x75, 0x01, 0x8C, 0x03};
160         struct  saa7110 *decoder;
161         struct i2c_client *client;
162         int                     rv;
163         client=kmalloc(sizeof(*client), GFP_KERNEL);
164         if(client == NULL) 
165                 return -ENOMEM;
166         memset(client, 0, sizeof(*client));
167         client_template.adapter = adap;
168         client_template.addr = addr;
169         memcpy(client, &client_template, sizeof(*client));
170
171         decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
172         if (decoder == NULL) {
173                 kfree(client);
174                 return -ENOMEM;
175                 }
176
177         /* clear our private data */
178         memset(decoder, 0, sizeof(*decoder));
179         strlcpy(client->name, IF_NAME, DEVICE_NAME_SIZE);
180         decoder->client = client;
181         i2c_set_clientdata(client, decoder);
182         decoder->addr = addr;
183         decoder->norm = VIDEO_MODE_PAL;
184         decoder->input = 0;
185         decoder->enable = 1;
186         decoder->bright = 32768;
187         decoder->contrast = 32768;
188         decoder->hue = 32768;
189         decoder->sat = 32768;
190
191         rv = i2c_master_send(client, initseq, sizeof(initseq));
192         if (rv < 0)
193                 printk(KERN_ERR "%s_attach: init status %d\n", client->name, rv);
194         else {
195                 i2c_smbus_write_byte_data(client,0x21,0x16);
196                 i2c_smbus_write_byte_data(client,0x0D,0x04);
197                 DEBUG(printk(KERN_INFO "%s_attach: chip version %x\n", client->name, i2c_smbus_read_byte(client)));
198                 i2c_smbus_write_byte_data(client,0x0D,0x06);
199         }
200
201         init_MUTEX(&decoder->lock);
202         i2c_attach_client(client);
203         MOD_INC_USE_COUNT;
204         /* setup and implicit mode 0 select has been performed */
205         return 0;
206 }
207
208 static 
209 int saa7110_probe(struct i2c_adapter *adap) 
210 {
211         return i2c_probe(adap, &addr_data, saa7110_attach);
212 }
213
214 static
215 int saa7110_detach(struct i2c_client *client)
216 {
217         struct saa7110* decoder = i2c_get_clientdata(client);
218
219         i2c_detach_client(client);
220
221         DEBUG(printk(KERN_INFO "%s_detach\n",client->name));
222
223         /* stop further output */
224         i2c_smbus_write_byte_data(client,0x0E,0x00);
225
226         kfree(decoder);
227         kfree(client);
228
229         MOD_DEC_USE_COUNT;
230         return 0;
231 }
232
233 static
234 int saa7110_command(struct i2c_client *client, unsigned int cmd, void *arg)
235 {
236         struct saa7110* decoder = i2c_get_clientdata(client);
237         int     v;
238
239         switch (cmd) {
240          case DECODER_GET_CAPABILITIES:
241                 {
242                         struct video_decoder_capability *dc = arg;
243                         dc->flags = VIDEO_DECODER_PAL
244                                   | VIDEO_DECODER_NTSC
245                                   | VIDEO_DECODER_SECAM
246                                   | VIDEO_DECODER_AUTO
247                                   | VIDEO_DECODER_CCIR;
248                         dc->inputs = SAA7110_MAX_INPUT;
249                         dc->outputs = SAA7110_MAX_OUTPUT;
250                 }
251                 break;
252
253          case DECODER_GET_STATUS:
254                 {
255                         struct saa7110* decoder = i2c_get_clientdata(client);
256                         int status;
257                         int res = 0;
258
259                         status = i2c_smbus_read_byte(client);
260                         if (status & 0x40)
261                                 res |= DECODER_STATUS_GOOD;
262                         if (status & 0x03)
263                                 res |= DECODER_STATUS_COLOR;
264
265                         switch (decoder->norm) {
266                          case VIDEO_MODE_NTSC:
267                                 res |= DECODER_STATUS_NTSC;
268                                 break;
269                          case VIDEO_MODE_PAL:
270                                 res |= DECODER_STATUS_PAL;
271                                 break;
272                          case VIDEO_MODE_SECAM:
273                                 res |= DECODER_STATUS_SECAM;
274                                 break;
275                         }
276                         *(int*)arg = res;
277                 }
278                 break;
279
280          case DECODER_SET_NORM:
281                 v = *(int*)arg;
282                 if (decoder->norm != v) {
283                         decoder->norm = v;
284                         i2c_smbus_write_byte_data(client, 0x06, 0x00);
285                         switch (v) {
286                          case VIDEO_MODE_NTSC:
287                                 i2c_smbus_write_byte_data(client, 0x0D, 0x06);
288                                 i2c_smbus_write_byte_data(client, 0x11, 0x2C);
289                                 i2c_smbus_write_byte_data(client, 0x30, 0x81);
290                                 i2c_smbus_write_byte_data(client, 0x2A, 0xDF);
291                                 break;
292                          case VIDEO_MODE_PAL:
293                                 i2c_smbus_write_byte_data(client, 0x0D, 0x06);
294                                 i2c_smbus_write_byte_data(client, 0x11, 0x59);
295                                 i2c_smbus_write_byte_data(client, 0x2E, 0x9A);
296                                 break;
297                          case VIDEO_MODE_SECAM:
298                                 i2c_smbus_write_byte_data(client, 0x0D, 0x07);
299                                 i2c_smbus_write_byte_data(client, 0x11, 0x59);
300                                 i2c_smbus_write_byte_data(client, 0x2E, 0x9A);
301                                 break;
302                          case VIDEO_MODE_AUTO:
303                                 *(int*)arg = determine_norm(client);
304                                 break;
305                          default:
306                                 return -EPERM;
307                         }
308                 }
309                 break;
310
311          case DECODER_SET_INPUT:
312                 v = *(int*)arg;
313                 if (v<0 || v>SAA7110_MAX_INPUT)
314                         return -EINVAL;
315                 if (decoder->input != v) {
316                         decoder->input = v;
317                         saa7110_selmux(client, v);
318                 }
319                 break;
320
321          case DECODER_SET_OUTPUT:
322                 v = *(int*)arg;
323                 /* not much choice of outputs */
324                 if (v != 0)
325                         return -EINVAL;
326                 break;
327
328          case DECODER_ENABLE_OUTPUT:
329                 v = *(int*)arg;
330                 if (decoder->enable != v) {
331                         decoder->enable = v;
332                         i2c_smbus_write_byte_data(client,0x0E, v ? 0x18 : 0x00);
333                 }
334                 break;
335
336          case DECODER_SET_PICTURE:
337                 {
338                         struct video_picture *pic = arg;
339
340                         if (decoder->bright != pic->brightness) {
341                                 /* We want 0 to 255 we get 0-65535 */
342                                 decoder->bright = pic->brightness;
343                                 i2c_smbus_write_byte_data(client, 0x19, decoder->bright >> 8);
344                         }
345                         if (decoder->contrast != pic->contrast) {
346                                 /* We want 0 to 127 we get 0-65535 */
347                                 decoder->contrast = pic->contrast;
348                                 i2c_smbus_write_byte_data(client, 0x13, decoder->contrast >> 9);
349                         }
350                         if (decoder->sat != pic->colour) {
351                                 /* We want 0 to 127 we get 0-65535 */
352                                 decoder->sat = pic->colour;
353                                 i2c_smbus_write_byte_data(client, 0x12, decoder->sat >> 9);
354                         }
355                         if (decoder->hue != pic->hue) {
356                                 /* We want -128 to 127 we get 0-65535 */
357                                 decoder->hue = pic->hue;
358                                 i2c_smbus_write_byte_data(client, 0x07, (decoder->hue>>8)-128);
359                         }
360                 }
361                 break;
362
363          case DECODER_DUMP:
364                 for (v=0; v<34; v+=16) {
365                         int j;
366                         DEBUG(printk(KERN_INFO "%s: %03x\n",client->name,v));
367                         for (j=0; j<16; j++) {
368                                 DEBUG(printk(KERN_INFO " %02x",decoder->reg[v+j]));
369                         }
370                         DEBUG(printk(KERN_INFO "\n"));
371                 }
372                 break;
373
374          default:
375                 DEBUG(printk(KERN_INFO "unknown saa7110_command??(%d)\n",cmd));
376                 return -EINVAL;
377         }
378         return 0;
379 }
380
381 /* ----------------------------------------------------------------------- */
382
383 static struct i2c_driver i2c_driver_saa7110 =
384 {
385         .owner          = THIS_MODULE,
386         .name           = IF_NAME,                      /* name */
387         .id             = I2C_DRIVERID_SAA7110, /* in i2c.h */
388         .flags          = I2C_DF_NOTIFY,        /* Addr range */
389         .attach_adapter = saa7110_probe,
390         .detach_client  = saa7110_detach,
391         .command        = saa7110_command
392 };
393 static struct i2c_client client_template = {
394         .id             = -1,
395         .driver         = &i2c_driver_saa7110,
396         .name           = "saa7110_client",
397 };
398
399 static int saa7110_init(void)
400 {
401         return i2c_add_driver(&i2c_driver_saa7110);
402 }
403
404 static void saa7110_exit(void)
405 {
406         i2c_del_driver(&i2c_driver_saa7110);
407 }
408
409
410 module_init(saa7110_init);
411 module_exit(saa7110_exit);
412 MODULE_LICENSE("GPL");