870313cc03e120e452903aa8bdbfc8b61c9b90b0
[linux-flexiantxendom0-3.2.10.git] / drivers / media / video / saa7111.c
1 /* 
2     saa7111 - Philips SAA7111A video decoder driver version 0.0.3
3
4     Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5
6     Slight changes for video timing and attachment output by
7     Wolfgang Scherr <scherr@net4you.net>
8     
9     This program is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation; either version 2 of the License, or
12     (at your option) any later version.
13
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18
19     You should have received a copy of the GNU General Public License
20     along with this program; if not, write to the Free Software
21     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/delay.h>
27 #include <linux/errno.h>
28 #include <linux/fs.h>
29 #include <linux/kernel.h>
30 #include <linux/major.h>
31 #include <linux/slab.h>
32 #include <linux/mm.h>
33 #include <linux/sched.h>
34
35 #include <linux/videodev.h>
36 #include <linux/version.h>
37 #include <linux/i2c.h>
38
39 #include <linux/video_decoder.h>
40
41 #define DEBUG(x)                /* Debug driver */
42
43 /* ----------------------------------------------------------------------- */
44
45 struct saa7111 {
46         struct i2c_client *client;
47         int addr;
48         struct semaphore lock;
49         unsigned char reg[32];
50
51         int norm;
52         int input;
53         int enable;
54         int bright;
55         int contrast;
56         int hue;
57         int sat;
58 };
59
60 static unsigned short normal_i2c[] = { 0x24, 0x25, I2C_CLIENT_END };    
61 static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };  
62
63 I2C_CLIENT_INSMOD;
64
65 static struct i2c_client client_template;
66
67 /* ----------------------------------------------------------------------- */
68
69 static int saa7111_attach(struct i2c_adapter *adap, int addr, int kind)
70 {
71         int i;
72         struct saa7111 *decoder;
73         struct i2c_client *client;
74
75         /* who wrote this? init[] is used for i2c_master_send() which expects an array that
76            will be used for the 'buf' part of an i2c message unchanged. so, the first byte
77            needs to be the subaddress to start with, then follow the data bytes... */
78         static const unsigned char init[] = {
79                 0x00,     /* start address */
80         
81                 0x00,     /* 00 - ID byte */
82                 0x00,     /* 01 - reserved */
83
84                 /*front end */
85                 0xd0,     /* 02 - FUSE=3, GUDL=2, MODE=0 */
86                 0x23,     /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
87                 0x00,     /* 04 - GAI1=256 */
88                 0x00,     /* 05 - GAI2=256 */
89
90                 /* decoder */
91                 0xf3,     /* 06 - HSB at  13(50Hz) /  17(60Hz) pixels after end of last line */
92                 0x13,     /* 07 - HSS at 113(50Hz) / 117(60Hz) pixels after end of last line */
93                 0xc8,     /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, HPLL=0, VNOI=0 */
94                 0x01,     /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, UPTCV=0, APER=1 */
95                 0x80,     /* 0a - BRIG=128 */
96                 0x47,     /* 0b - CONT=1.109 */
97                 0x40,     /* 0c - SATN=1.0 */
98                 0x00,     /* 0d - HUE=0 */
99                 0x01,     /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
100                 0x00,     /* 0f - reserved */
101                 0x48,     /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
102                 0x1c,     /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
103                 0x00,     /* 12 - output control 2 */
104                 0x00,     /* 13 - output control 3 */
105                 0x00,     /* 14 - reserved */
106                 0x00,     /* 15 - VBI */
107                 0x00,     /* 16 - VBI */
108                 0x00,     /* 17 - VBI */
109         };
110         client = kmalloc(sizeof(*client), GFP_KERNEL);
111         if(client == NULL) 
112                 return -ENOMEM;
113         client_template.adapter = adap;
114         client_template.addr = addr;
115         memcpy(client, &client_template, sizeof(*client));
116
117         decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
118         if (decoder == NULL)
119         {
120                 kfree(client);
121                 return -ENOMEM;
122         }
123
124         memset(decoder, 0, sizeof(*decoder));
125         strlcpy(client->dev.name, "saa7111", DEVICE_NAME_SIZE);
126         decoder->client = client;
127         i2c_set_clientdata(client, decoder);
128         decoder->addr = addr;
129         decoder->norm = VIDEO_MODE_NTSC;
130         decoder->input = 0;
131         decoder->enable = 1;
132         decoder->bright = 32768;
133         decoder->contrast = 32768;
134         decoder->hue = 32768;
135         decoder->sat = 32768;
136
137         i = i2c_master_send(client, init, sizeof(init));
138         if (i < 0) {
139                 printk(KERN_ERR "%s_attach: init status %d\n",
140                        client->dev.name, i);
141         } else {
142                 printk(KERN_INFO "%s_attach: chip version %x @ 0x%08x\n",
143                        client->dev.name, i2c_smbus_read_byte_data(client, 0x00) >> 4,addr);
144         }
145
146         init_MUTEX(&decoder->lock);
147         i2c_attach_client(client);
148         MOD_INC_USE_COUNT;
149         return 0;
150 }
151 static int saa7111_probe(struct i2c_adapter *adap)
152 {
153         /* probing unknown devices on any Matrox i2c-bus takes ages due to the
154            slow bit banging algorithm used. because of the fact a saa7111(a)
155            is *never* present on a Matrox gfx card, we can skip such adapters
156            here */
157         if( 0 != (adap->id & I2C_HW_B_G400)) {
158                 return -ENODEV;
159         }
160         
161         printk("saa7111: probing %s i2c adapter [id=0x%x]\n",
162                        adap->dev.name,adap->id);
163         return i2c_probe(adap, &addr_data, saa7111_attach);
164 }
165
166 static int saa7111_detach(struct i2c_client *client)
167 {
168         struct saa7111 *decoder = i2c_get_clientdata(client);
169         i2c_detach_client(client);
170         kfree(decoder);
171         kfree(client);
172         MOD_DEC_USE_COUNT;
173         return 0;
174 }
175
176 static int saa7111_command(struct i2c_client *client, unsigned int cmd,
177                            void *arg)
178 {
179         struct saa7111 *decoder = i2c_get_clientdata(client);
180
181         switch (cmd) {
182
183 #if defined(DECODER_DUMP)
184         case DECODER_DUMP:
185                 {
186                         int i;
187
188                         for (i = 0; i < 32; i += 16) {
189                                 int j;
190
191                                 printk("KERN_DEBUG %s: %03x", client->dev.name,
192                                        i);
193                                 for (j = 0; j < 16; ++j) {
194                                         printk(" %02x",
195                                                i2c_smbus_read_byte_data(client,
196                                                             i + j));
197                                 }
198                                 printk("\n");
199                         }
200                 }
201                 break;
202 #endif                          /* defined(DECODER_DUMP) */
203
204         case DECODER_GET_CAPABILITIES:
205                 {
206                         struct video_decoder_capability *cap = arg;
207
208                         cap->flags
209                             = VIDEO_DECODER_PAL
210                             | VIDEO_DECODER_NTSC
211                             | VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
212                         cap->inputs = 8;
213                         cap->outputs = 1;
214                 }
215                 break;
216
217         case DECODER_GET_STATUS:
218                 {
219                         int *iarg = arg;
220                         int status;
221                         int res;
222
223                         status = i2c_smbus_read_byte_data(client, 0x1f);
224                         res = 0;
225                         if ((status & (1 << 6)) == 0) {
226                                 res |= DECODER_STATUS_GOOD;
227                         }
228                         switch (decoder->norm) {
229                         case VIDEO_MODE_NTSC:
230                                 res |= DECODER_STATUS_NTSC;
231                                 break;
232                         case VIDEO_MODE_PAL:
233                                 res |= DECODER_STATUS_PAL;
234                                 break;
235                         default:
236                         case VIDEO_MODE_AUTO:
237                                 if ((status & (1 << 5)) != 0) {
238                                         res |= DECODER_STATUS_NTSC;
239                                 } else {
240                                         res |= DECODER_STATUS_PAL;
241                                 }
242                                 break;
243                         }
244                         if ((status & (1 << 0)) != 0) {
245                                 res |= DECODER_STATUS_COLOR;
246                         }
247                         *iarg = res;
248                 }
249                 break;
250
251         case DECODER_SET_NORM:
252                 {
253                         int *iarg = arg;
254
255                         switch (*iarg) {
256
257                         case VIDEO_MODE_NTSC:
258                                 i2c_smbus_write_byte_data(client, 0x08,
259                                               (decoder->
260                                                reg[0x08] & 0x3f) | 0x40);
261                                 break;
262
263                         case VIDEO_MODE_PAL:
264                                 i2c_smbus_write_byte_data(client, 0x08,
265                                               (decoder->
266                                                reg[0x08] & 0x3f) | 0x00);
267                                 break;
268
269                         case VIDEO_MODE_AUTO:
270                                 i2c_smbus_write_byte_data(client, 0x08,
271                                               (decoder->
272                                                reg[0x08] & 0x3f) | 0x80);
273                                 break;
274
275                         default:
276                                 return -EINVAL;
277
278                         }
279                         decoder->norm = *iarg;
280                 }
281                 break;
282
283         case DECODER_SET_INPUT:
284                 {
285                         int *iarg = arg;
286
287                         if (*iarg < 0 || *iarg > 7) {
288                                 return -EINVAL;
289                         }
290
291                         if (decoder->input != *iarg) {
292                                 decoder->input = *iarg;
293                                 /* select mode */
294                                 i2c_smbus_write_byte_data(client, 0x02,
295                                               (decoder->
296                                                reg[0x02] & 0xf8) |
297                                               decoder->input);
298                                 /* bypass chrominance trap for modes 4..7 */
299                                 i2c_smbus_write_byte_data(client, 0x09,
300                                               (decoder->
301                                                reg[0x09] & 0x7f) |
302                                               ((decoder->input >
303                                                 3) ? 0x80 : 0));
304                         }
305                 }
306                 break;
307
308         case DECODER_SET_OUTPUT:
309                 {
310                         int *iarg = arg;
311
312                         /* not much choice of outputs */
313                         if (*iarg != 0) {
314                                 return -EINVAL;
315                         }
316                 }
317                 break;
318
319         case DECODER_ENABLE_OUTPUT:
320                 {
321                         int *iarg = arg;
322                         int enable = (*iarg != 0);
323
324                         if (decoder->enable != enable) {
325                                 decoder->enable = enable;
326
327 // RJ: If output should be disabled (for playing videos), we also need a open PLL.
328 //     The input is set to 0 (where no input source is connected), although this
329 //     is not necessary.
330 //
331 //     If output should be enabled, we have to reverse the above.
332
333                                 if (decoder->enable) {
334                                         i2c_smbus_write_byte_data(client, 0x02,
335                                                       (decoder->
336                                                        reg[0x02] & 0xf8) |
337                                                       decoder->input);
338                                         i2c_smbus_write_byte_data(client, 0x08,
339                                                       (decoder->
340                                                        reg[0x08] & 0xfb));
341                                         i2c_smbus_write_byte_data(client, 0x11,
342                                                       (decoder->
343                                                        reg[0x11] & 0xf3) |
344                                                       0x0c);
345                                 } else {
346                                         i2c_smbus_write_byte_data(client, 0x02,
347                                                       (decoder->
348                                                        reg[0x02] & 0xf8));
349                                         i2c_smbus_write_byte_data(client, 0x08,
350                                                       (decoder->
351                                                        reg[0x08] & 0xfb) |
352                                                       0x04);
353                                         i2c_smbus_write_byte_data(client, 0x11,
354                                                       (decoder->
355                                                        reg[0x11] & 0xf3));
356                                 }
357                         }
358                 }
359                 break;
360
361         case DECODER_SET_PICTURE:
362                 {
363                         struct video_picture *pic = arg;
364
365                         if (decoder->bright != pic->brightness) {
366                                 /* We want 0 to 255 we get 0-65535 */
367                                 decoder->bright = pic->brightness;
368                                 i2c_smbus_write_byte_data(client, 0x0a,
369                                               decoder->bright >> 8);
370                         }
371                         if (decoder->contrast != pic->contrast) {
372                                 /* We want 0 to 127 we get 0-65535 */
373                                 decoder->contrast = pic->contrast;
374                                 i2c_smbus_write_byte_data(client, 0x0b,
375                                               decoder->contrast >> 9);
376                         }
377                         if (decoder->sat != pic->colour) {
378                                 /* We want 0 to 127 we get 0-65535 */
379                                 decoder->sat = pic->colour;
380                                 i2c_smbus_write_byte_data(client, 0x0c,
381                                               decoder->sat >> 9);
382                         }
383                         if (decoder->hue != pic->hue) {
384                                 /* We want -128 to 127 we get 0-65535 */
385                                 decoder->hue = pic->hue;
386                                 i2c_smbus_write_byte_data(client, 0x0d,
387                                               (decoder->hue - 32768) >> 8);
388                         }
389                 }
390                 break;
391
392         default:
393                 return -EINVAL;
394         }
395
396         return 0;
397 }
398
399 /* ----------------------------------------------------------------------- */
400
401 static struct i2c_driver i2c_driver_saa7111 = {
402 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,54)
403         .owner          = THIS_MODULE,
404 #endif
405         .name           = "saa7111",             /* name */
406         .id             = I2C_DRIVERID_SAA7111A, /* ID */
407         .flags          = I2C_DF_NOTIFY,
408         .attach_adapter = saa7111_probe,
409         .detach_client  = saa7111_detach,
410         .command        = saa7111_command
411 };
412
413 static struct i2c_client client_template = {
414         .id     = -1,
415         .driver = &i2c_driver_saa7111,
416         .dev    = {
417                 .name   = "saa7111_client",
418         },
419 };
420
421 static int saa7111_init(void)
422 {
423         return i2c_add_driver(&i2c_driver_saa7111);
424 }
425
426 static void saa7111_exit(void)
427 {
428         i2c_del_driver(&i2c_driver_saa7111);
429 }
430
431 module_init(saa7111_init);
432 module_exit(saa7111_exit);
433 MODULE_LICENSE("GPL");