]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/media/video/saa7191.c
3ddbb62312be84acbc3a77b601159c8dfe8925a2
[karo-tx-linux.git] / drivers / media / video / saa7191.c
1 /*
2  *  saa7191.c - Philips SAA7191 video decoder driver
3  *
4  *  Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5  *  Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  */
11
12 #include <linux/delay.h>
13 #include <linux/errno.h>
14 #include <linux/fs.h>
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/major.h>
18 #include <linux/module.h>
19 #include <linux/mm.h>
20 #include <linux/sched.h>
21 #include <linux/slab.h>
22
23 #include <linux/videodev.h>
24 #include <linux/video_decoder.h>
25 #include <linux/i2c.h>
26
27 #include "saa7191.h"
28
29 #define SAA7191_MODULE_VERSION "0.0.3"
30
31 MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
32 MODULE_VERSION(SAA7191_MODULE_VERSION);
33 MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
34 MODULE_LICENSE("GPL");
35
36 struct saa7191 {
37         struct i2c_client *client;
38
39         /* the register values are stored here as the actual
40          * I2C-registers are write-only */
41         unsigned char reg[25];
42
43         unsigned char norm;
44         unsigned char input;
45 };
46
47 static struct i2c_driver i2c_driver_saa7191;
48
49 static const unsigned char initseq[] = {
50         0,      /* Subaddress */
51         0x50,   /* SAA7191_REG_IDEL */
52         0x30,   /* SAA7191_REG_HSYB */
53         0x00,   /* SAA7191_REG_HSYS */
54         0xe8,   /* SAA7191_REG_HCLB */
55         0xb6,   /* SAA7191_REG_HCLS */
56         0xf4,   /* SAA7191_REG_HPHI */
57         0x01,   /* SAA7191_REG_LUMA - chrominance trap active (CVBS) */
58         0x00,   /* SAA7191_REG_HUEC */
59         0xf8,   /* SAA7191_REG_CKTQ */
60         0xf8,   /* SAA7191_REG_CKTS */
61         0x90,   /* SAA7191_REG_PLSE */
62         0x90,   /* SAA7191_REG_SESE */
63         0x00,   /* SAA7191_REG_GAIN */
64         0x0c,   /* SAA7191_REG_STDC - not SECAM, slow time constant */
65         0x78,   /* SAA7191_REG_IOCK - chrominance from CVBS, GPSW1 & 2 off */
66         0x99,   /* SAA7191_REG_CTL3 - automatic field detection */
67         0x00,   /* SAA7191_REG_CTL4 */
68         0x2c,   /* SAA7191_REG_CHCV */
69         0x00,   /* unused */
70         0x00,   /* unused */
71         0x34,   /* SAA7191_REG_HS6B */
72         0x0a,   /* SAA7191_REG_HS6S */
73         0xf4,   /* SAA7191_REG_HC6B */
74         0xce,   /* SAA7191_REG_HC6S */
75         0xf4,   /* SAA7191_REG_HP6I */
76 };
77
78 /* SAA7191 register handling */
79
80 static unsigned char saa7191_read_reg(struct i2c_client *client,
81                                       unsigned char reg)
82 {
83         return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
84 }
85
86 static int saa7191_read_status(struct i2c_client *client,
87                                unsigned char *value)
88 {
89         int ret;
90
91         ret = i2c_master_recv(client, value, 1);
92         if (ret < 0) {
93                 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed");
94                 return ret;
95         }
96
97         return 0;
98 }
99
100
101 static int saa7191_write_reg(struct i2c_client *client, unsigned char reg,
102                              unsigned char value)
103 {
104
105         ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
106         return i2c_smbus_write_byte_data(client, reg, value);
107 }
108
109 /* the first byte of data must be the first subaddress number (register) */
110 static int saa7191_write_block(struct i2c_client *client,
111                                unsigned char length, unsigned char *data)
112 {
113         int i;
114         int ret;
115
116         struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
117         for (i = 0; i < (length - 1); i++) {
118                 decoder->reg[data[0] + i] = data[i + 1];
119         }
120
121         ret = i2c_master_send(client, data, length);
122         if (ret < 0) {
123                 printk(KERN_ERR "SAA7191: saa7191_write_block(): "
124                        "write failed");
125                 return ret;
126         }
127
128         return 0;
129 }
130
131 /* Helper functions */
132
133 static int saa7191_set_input(struct i2c_client *client, int input)
134 {
135         unsigned char luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
136         unsigned char iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
137         int err;
138
139         switch (input) {
140         case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
141                 iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
142                           | SAA7191_IOCK_GPSW2);
143                 /* Chrominance trap active */
144                 luma &= ~SAA7191_LUMA_BYPS;
145                 break;
146         case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
147                 iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
148                 /* Chrominance trap bypassed */
149                 luma |= SAA7191_LUMA_BYPS;
150                 break;
151         default:
152                 return -EINVAL;
153         }
154
155         err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
156         if (err)
157                 return -EIO;
158         err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
159         if (err)
160                 return -EIO;
161
162         return 0;
163 }
164
165 static int saa7191_set_norm(struct i2c_client *client, int norm)
166 {
167         struct saa7191 *decoder = i2c_get_clientdata(client);
168         unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
169         unsigned char ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
170         unsigned char chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
171         int err;
172
173         switch(norm) {
174         case SAA7191_NORM_AUTO: {
175                 unsigned char status;
176
177                 // does status depend on current norm ?
178                 if (saa7191_read_status(client, &status))
179                         return -EIO;
180
181                 stdc &= ~SAA7191_STDC_SECS;
182                 ctl3 &= ~SAA7191_CTL3_FSEL;
183                 ctl3 |= SAA7191_CTL3_AUFD;
184                 chcv = (status & SAA7191_STATUS_FIDT)
185                                ? SAA7191_CHCV_NTSC : SAA7191_CHCV_PAL;
186                 break;
187         }
188         case SAA7191_NORM_PAL:
189                 stdc &= ~SAA7191_STDC_SECS;
190                 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
191                 chcv = SAA7191_CHCV_PAL;
192                 break;
193         case SAA7191_NORM_NTSC:
194                 stdc &= ~SAA7191_STDC_SECS;
195                 ctl3 &= ~SAA7191_CTL3_AUFD;
196                 ctl3 |= SAA7191_CTL3_FSEL;
197                 chcv = SAA7191_CHCV_NTSC;
198                 break;
199         case SAA7191_NORM_SECAM:
200                 stdc |= SAA7191_STDC_SECS;
201                 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
202                 chcv = SAA7191_CHCV_PAL;
203                 break;
204         default:
205                 return -EINVAL;
206         }
207
208         err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
209         if (err)
210                 return -EIO;
211         err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
212         if (err)
213                 return -EIO;
214         err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
215         if (err)
216                 return -EIO;
217
218         decoder->norm = norm;
219
220         return 0;
221 }
222
223 static int saa7191_get_controls(struct i2c_client *client,
224                                 struct saa7191_control *ctrl)
225 {
226         unsigned char hue = saa7191_read_reg(client, SAA7191_REG_HUEC);
227         unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
228
229         if (hue < 0x80) {
230                 hue += 0x80;
231         } else {
232                 hue -= 0x80;
233         }
234         ctrl->hue = hue;
235
236         ctrl->vtrc = (stdc & SAA7191_STDC_VTRC)
237                 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
238
239         return 0;
240 }
241
242 static int saa7191_set_controls(struct i2c_client *client,
243                                 struct saa7191_control *ctrl)
244 {
245         int err;
246
247         if (ctrl->hue >= 0) {
248                 unsigned char hue = ctrl->hue & 0xff;
249                 if (hue < 0x80) {
250                         hue += 0x80;
251                 } else {
252                         hue -= 0x80;
253                 }
254                 err = saa7191_write_reg(client, SAA7191_REG_HUEC, hue);
255                 if (err)
256                         return -EIO;
257         }
258         if (ctrl->vtrc >= 0) {
259                 unsigned char stdc =
260                         saa7191_read_reg(client, SAA7191_REG_STDC);
261
262                 if (ctrl->vtrc) {
263                         stdc |= SAA7191_STDC_VTRC;
264                 } else {
265                         stdc &= ~SAA7191_STDC_VTRC;
266                 }
267
268                 err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
269                 if (err)
270                         return -EIO;
271         }
272
273         return 0;
274 }
275
276 /* I2C-interface */
277
278 static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
279 {
280         int err = 0;
281         struct saa7191 *decoder;
282         struct i2c_client *client;
283
284         printk(KERN_INFO "Philips SAA7191 driver version %s\n",
285                SAA7191_MODULE_VERSION);
286
287         client = kmalloc(sizeof(*client), GFP_KERNEL);
288         if (!client)
289                 return -ENOMEM;
290         decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
291         if (!decoder) {
292                 err = -ENOMEM;
293                 goto out_free_client;
294         }
295
296         memset(client, 0, sizeof(struct i2c_client));
297         memset(decoder, 0, sizeof(struct saa7191));
298
299         client->addr = addr;
300         client->adapter = adap;
301         client->driver = &i2c_driver_saa7191;
302         client->flags = 0;
303         strcpy(client->name, "saa7191 client");
304         i2c_set_clientdata(client, decoder);
305
306         decoder->client = client;
307
308         err = i2c_attach_client(client);
309         if (err)
310                 goto out_free_decoder;
311
312         decoder->input = SAA7191_INPUT_COMPOSITE;
313         decoder->norm = SAA7191_NORM_AUTO;
314
315         err = saa7191_write_block(client, sizeof(initseq),
316                                   (unsigned char *)initseq);
317         if (err) {
318                 printk(KERN_ERR "SAA7191 initialization failed\n");
319                 goto out_detach_client;
320         }
321
322         printk(KERN_INFO "SAA7191 initialized\n");
323
324         return 0;
325
326 out_detach_client:
327         i2c_detach_client(client);
328 out_free_decoder:
329         kfree(decoder);
330 out_free_client:
331         kfree(client);
332         return err;
333 }
334
335 static int saa7191_probe(struct i2c_adapter *adap)
336 {
337         /* Always connected to VINO */
338         if (adap->id == I2C_HW_SGI_VINO)
339                 return saa7191_attach(adap, SAA7191_ADDR, 0);
340         /* Feel free to add probe here :-) */
341         return -ENODEV;
342 }
343
344 static int saa7191_detach(struct i2c_client *client)
345 {
346         struct saa7191 *decoder = i2c_get_clientdata(client);
347
348         i2c_detach_client(client);
349         kfree(decoder);
350         kfree(client);
351         return 0;
352 }
353
354 static int saa7191_command(struct i2c_client *client, unsigned int cmd,
355                            void *arg)
356 {
357         struct saa7191 *decoder = i2c_get_clientdata(client);
358
359         switch (cmd) {
360         case DECODER_GET_CAPABILITIES: {
361                 struct video_decoder_capability *cap = arg;
362
363                 cap->flags  = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
364                               VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
365                 cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
366                 cap->outputs = 1;
367                 break;
368         }
369         case DECODER_GET_STATUS: {
370                 int *iarg = arg;
371                 unsigned char status;
372                 int res = 0;
373
374                 if (saa7191_read_status(client, &status)) {
375                         return -EIO;
376                 }
377                 if ((status & SAA7191_STATUS_HLCK) == 0)
378                         res |= DECODER_STATUS_GOOD;
379                 if (status & SAA7191_STATUS_CODE)
380                         res |= DECODER_STATUS_COLOR;
381                 switch (decoder->norm) {
382                 case SAA7191_NORM_NTSC:
383                         res |= DECODER_STATUS_NTSC;
384                         break;
385                 case SAA7191_NORM_PAL:
386                         res |= DECODER_STATUS_PAL;
387                         break;
388                 case SAA7191_NORM_SECAM:
389                         res |= DECODER_STATUS_SECAM;
390                         break;
391                 case SAA7191_NORM_AUTO:
392                 default:
393                         if (status & SAA7191_STATUS_FIDT)
394                                 res |= DECODER_STATUS_NTSC;
395                         else
396                                 res |= DECODER_STATUS_PAL;
397                         break;
398                 }
399                 *iarg = res;
400                 break;
401         }
402         case DECODER_SET_NORM: {
403                 int *iarg = arg;
404
405                 switch (*iarg) {
406                 case VIDEO_MODE_AUTO:
407                         return saa7191_set_norm(client, SAA7191_NORM_AUTO);
408                 case VIDEO_MODE_PAL:
409                         return saa7191_set_norm(client, SAA7191_NORM_PAL);
410                 case VIDEO_MODE_NTSC:
411                         return saa7191_set_norm(client, SAA7191_NORM_NTSC);
412                 case VIDEO_MODE_SECAM:
413                         return saa7191_set_norm(client, SAA7191_NORM_SECAM);
414                 default:
415                         return -EINVAL;
416                 }
417                 break;
418         }
419         case DECODER_SET_INPUT: {
420                 int *iarg = arg;
421
422                 switch (client->adapter->id) {
423                 case I2C_HW_SGI_VINO:
424                         return saa7191_set_input(client, *iarg);
425                 default:
426                         if (*iarg != 0)
427                                 return -EINVAL;
428                 }
429                 break;
430         }
431         case DECODER_SET_OUTPUT: {
432                 int *iarg = arg;
433
434                 /* not much choice of outputs */
435                 if (*iarg != 0)
436                         return -EINVAL;
437                 break;
438         }
439         case DECODER_ENABLE_OUTPUT: {
440                 /* Always enabled */
441                 break;
442         }
443         case DECODER_SET_PICTURE: {
444                 struct video_picture *pic = arg;
445                 unsigned val;
446                 int err;
447
448                 val = (pic->hue >> 8) - 0x80;
449                 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
450                 if (err)
451                         return -EIO;
452                 break;
453         }
454         case DECODER_SAA7191_GET_STATUS: {
455                 struct saa7191_status *status = arg;
456                 unsigned char status_reg;
457
458                 if (saa7191_read_status(client, &status_reg))
459                         return -EIO;
460                 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
461                         ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
462                 status->ntsc = (status_reg & SAA7191_STATUS_FIDT)
463                         ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
464                 status->color = (status_reg & SAA7191_STATUS_CODE)
465                         ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
466
467                 status->input = decoder->input;
468                 status->norm = decoder->norm;
469         }
470         case DECODER_SAA7191_SET_NORM: {
471                 int *norm = arg;
472                 return saa7191_set_norm(client, *norm);
473         }
474         case DECODER_SAA7191_GET_CONTROLS: {
475                 struct saa7191_control *ctrl = arg;
476                 return saa7191_get_controls(client, ctrl);
477         }
478         case DECODER_SAA7191_SET_CONTROLS: {
479                 struct saa7191_control *ctrl = arg;
480                 return saa7191_set_controls(client, ctrl);
481         }
482         default:
483                 return -EINVAL;
484         }
485
486         return 0;
487 }
488
489 static struct i2c_driver i2c_driver_saa7191 = {
490         .owner          = THIS_MODULE,
491         .name           = "saa7191",
492         .id             = I2C_DRIVERID_SAA7191,
493         .flags          = I2C_DF_NOTIFY,
494         .attach_adapter = saa7191_probe,
495         .detach_client  = saa7191_detach,
496         .command        = saa7191_command
497 };
498
499 static int saa7191_init(void)
500 {
501         return i2c_add_driver(&i2c_driver_saa7191);
502 }
503
504 static void saa7191_exit(void)
505 {
506         i2c_del_driver(&i2c_driver_saa7191);
507 }
508
509 module_init(saa7191_init);
510 module_exit(saa7191_exit);