Merge master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6] / 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.5"
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 // #define SAA7191_DEBUG
37
38 #ifdef SAA7191_DEBUG
39 #define dprintk(x...) printk("SAA7191: " x);
40 #else
41 #define dprintk(x...)
42 #endif
43
44 #define SAA7191_SYNC_COUNT      30
45 #define SAA7191_SYNC_DELAY      100     /* milliseconds */
46
47 struct saa7191 {
48         struct i2c_client *client;
49
50         /* the register values are stored here as the actual
51          * I2C-registers are write-only */
52         u8 reg[25];
53
54         int input;
55         int norm;
56 };
57
58 static struct i2c_driver i2c_driver_saa7191;
59
60 static const u8 initseq[] = {
61         0,      /* Subaddress */
62
63         0x50,   /* (0x50) SAA7191_REG_IDEL */
64
65         /* 50 Hz signal timing */
66         0x30,   /* (0x30) SAA7191_REG_HSYB */
67         0x00,   /* (0x00) SAA7191_REG_HSYS */
68         0xe8,   /* (0xe8) SAA7191_REG_HCLB */
69         0xb6,   /* (0xb6) SAA7191_REG_HCLS */
70         0xf4,   /* (0xf4) SAA7191_REG_HPHI */
71
72         /* control */
73         SAA7191_LUMA_APER_1,    /* (0x01) SAA7191_REG_LUMA - CVBS mode */
74         0x00,   /* (0x00) SAA7191_REG_HUEC */
75         0xf8,   /* (0xf8) SAA7191_REG_CKTQ */
76         0xf8,   /* (0xf8) SAA7191_REG_CKTS */
77         0x90,   /* (0x90) SAA7191_REG_PLSE */
78         0x90,   /* (0x90) SAA7191_REG_SESE */
79         0x00,   /* (0x00) SAA7191_REG_GAIN */
80         SAA7191_STDC_NFEN | SAA7191_STDC_HRMV,  /* (0x0c) SAA7191_REG_STDC
81                                                  * - not SECAM,
82                                                  * slow time constant */
83         SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
84         | SAA7191_IOCK_OEDY,    /* (0x78) SAA7191_REG_IOCK
85                                  * - chroma from CVBS, GPSW1 & 2 off */
86         SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
87         | SAA7191_CTL3_YDEL0,   /* (0x99) SAA7191_REG_CTL3
88                                  * - automatic field detection */
89         0x00,   /* (0x00) SAA7191_REG_CTL4 */
90         0x2c,   /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
91         0x00,   /* unused */
92         0x00,   /* unused */
93
94         /* 60 Hz signal timing */
95         0x34,   /* (0x34) SAA7191_REG_HS6B */
96         0x0a,   /* (0x0a) SAA7191_REG_HS6S */
97         0xf4,   /* (0xf4) SAA7191_REG_HC6B */
98         0xce,   /* (0xce) SAA7191_REG_HC6S */
99         0xf4,   /* (0xf4) SAA7191_REG_HP6I */
100 };
101
102 /* SAA7191 register handling */
103
104 static u8 saa7191_read_reg(struct i2c_client *client,
105                            u8 reg)
106 {
107         return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
108 }
109
110 static int saa7191_read_status(struct i2c_client *client,
111                                u8 *value)
112 {
113         int ret;
114
115         ret = i2c_master_recv(client, value, 1);
116         if (ret < 0) {
117                 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
118                 return ret;
119         }
120
121         return 0;
122 }
123
124
125 static int saa7191_write_reg(struct i2c_client *client, u8 reg,
126                              u8 value)
127 {
128         ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
129         return i2c_smbus_write_byte_data(client, reg, value);
130 }
131
132 /* the first byte of data must be the first subaddress number (register) */
133 static int saa7191_write_block(struct i2c_client *client,
134                                u8 length, u8 *data)
135 {
136         int i;
137         int ret;
138
139         struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
140         for (i = 0; i < (length - 1); i++) {
141                 decoder->reg[data[0] + i] = data[i + 1];
142         }
143
144         ret = i2c_master_send(client, data, length);
145         if (ret < 0) {
146                 printk(KERN_ERR "SAA7191: saa7191_write_block(): "
147                        "write failed\n");
148                 return ret;
149         }
150
151         return 0;
152 }
153
154 /* Helper functions */
155
156 static int saa7191_set_input(struct i2c_client *client, int input)
157 {
158         struct saa7191 *decoder = i2c_get_clientdata(client);
159         u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
160         u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
161         int err;
162
163         switch (input) {
164         case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
165                 iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
166                           | SAA7191_IOCK_GPSW2);
167                 /* Chrominance trap active */
168                 luma &= ~SAA7191_LUMA_BYPS;
169                 break;
170         case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
171                 iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
172                 /* Chrominance trap bypassed */
173                 luma |= SAA7191_LUMA_BYPS;
174                 break;
175         default:
176                 return -EINVAL;
177         }
178
179         err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
180         if (err)
181                 return -EIO;
182         err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
183         if (err)
184                 return -EIO;
185
186         decoder->input = input;
187
188         return 0;
189 }
190
191 static int saa7191_set_norm(struct i2c_client *client, int norm)
192 {
193         struct saa7191 *decoder = i2c_get_clientdata(client);
194         u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
195         u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
196         u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
197         int err;
198
199         switch(norm) {
200         case SAA7191_NORM_PAL:
201                 stdc &= ~SAA7191_STDC_SECS;
202                 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
203                 chcv = SAA7191_CHCV_PAL;
204                 break;
205         case SAA7191_NORM_NTSC:
206                 stdc &= ~SAA7191_STDC_SECS;
207                 ctl3 &= ~SAA7191_CTL3_AUFD;
208                 ctl3 |= SAA7191_CTL3_FSEL;
209                 chcv = SAA7191_CHCV_NTSC;
210                 break;
211         case SAA7191_NORM_SECAM:
212                 stdc |= SAA7191_STDC_SECS;
213                 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
214                 chcv = SAA7191_CHCV_PAL;
215                 break;
216         default:
217                 return -EINVAL;
218         }
219
220         err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
221         if (err)
222                 return -EIO;
223         err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
224         if (err)
225                 return -EIO;
226         err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
227         if (err)
228                 return -EIO;
229
230         decoder->norm = norm;
231
232         dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
233                 stdc, chcv);
234         dprintk("norm: %d\n", norm);
235
236         return 0;
237 }
238
239 static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
240 {
241         int i = 0;
242
243         dprintk("Checking for signal...\n");
244
245         for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
246                 if (saa7191_read_status(client, status))
247                         return -EIO;
248
249                 if (((*status) & SAA7191_STATUS_HLCK) == 0) {
250                         dprintk("Signal found\n");
251                         return 0;
252                 }
253
254                 msleep(SAA7191_SYNC_DELAY);
255         }
256
257         dprintk("No signal\n");
258
259         return -EBUSY;
260 }
261
262 static int saa7191_autodetect_norm_extended(struct i2c_client *client)
263 {
264         u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
265         u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
266         u8 status;
267         int err = 0;
268
269         dprintk("SAA7191 extended signal auto-detection...\n");
270
271         stdc &= ~SAA7191_STDC_SECS;
272         ctl3 &= ~(SAA7191_CTL3_FSEL);
273
274         err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
275         if (err) {
276                 err = -EIO;
277                 goto out;
278         }
279         err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
280         if (err) {
281                 err = -EIO;
282                 goto out;
283         }
284
285         ctl3 |= SAA7191_CTL3_AUFD;
286         err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
287         if (err) {
288                 err = -EIO;
289                 goto out;
290         }
291
292         msleep(SAA7191_SYNC_DELAY);
293
294         err = saa7191_wait_for_signal(client, &status);
295         if (err)
296                 goto out;
297
298         if (status & SAA7191_STATUS_FIDT) {
299                 /* 60Hz signal -> NTSC */
300                 dprintk("60Hz signal: NTSC\n");
301                 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
302         }
303
304         /* 50Hz signal */
305         dprintk("50Hz signal: Trying PAL...\n");
306
307         /* try PAL first */
308         err = saa7191_set_norm(client, SAA7191_NORM_PAL);
309         if (err)
310                 goto out;
311
312         msleep(SAA7191_SYNC_DELAY);
313
314         err = saa7191_wait_for_signal(client, &status);
315         if (err)
316                 goto out;
317
318         /* not 50Hz ? */
319         if (status & SAA7191_STATUS_FIDT) {
320                 dprintk("No 50Hz signal\n");
321                 err = -EAGAIN;
322                 goto out;
323         }
324
325         if (status & SAA7191_STATUS_CODE) {
326                 dprintk("PAL\n");
327                 return 0;
328         }
329
330         dprintk("No color detected with PAL - Trying SECAM...\n");
331
332         /* no color detected ? -> try SECAM */
333         err = saa7191_set_norm(client,
334                                SAA7191_NORM_SECAM);
335         if (err)
336                 goto out;
337
338         msleep(SAA7191_SYNC_DELAY);
339
340         err = saa7191_wait_for_signal(client, &status);
341         if (err)
342                 goto out;
343
344         /* not 50Hz ? */
345         if (status & SAA7191_STATUS_FIDT) {
346                 dprintk("No 50Hz signal\n");
347                 err = -EAGAIN;
348                 goto out;
349         }
350
351         if (status & SAA7191_STATUS_CODE) {
352                 /* Color detected -> SECAM */
353                 dprintk("SECAM\n");
354                 return 0;
355         }
356
357         dprintk("No color detected with SECAM - Going back to PAL.\n");
358
359         /* still no color detected ?
360          * -> set norm back to PAL */
361         err = saa7191_set_norm(client,
362                                SAA7191_NORM_PAL);
363         if (err)
364                 goto out;
365
366 out:
367         ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
368         if (ctl3 & SAA7191_CTL3_AUFD) {
369                 ctl3 &= ~(SAA7191_CTL3_AUFD);
370                 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
371                 if (err) {
372                         err = -EIO;
373                 }
374         }
375
376         return err;
377 }
378
379 static int saa7191_autodetect_norm(struct i2c_client *client)
380 {
381         u8 status;
382
383         dprintk("SAA7191 signal auto-detection...\n");
384
385         dprintk("Reading status...\n");
386
387         if (saa7191_read_status(client, &status))
388                 return -EIO;
389
390         dprintk("Checking for signal...\n");
391
392         /* no signal ? */
393         if (status & SAA7191_STATUS_HLCK) {
394                 dprintk("No signal\n");
395                 return -EBUSY;
396         }
397
398         dprintk("Signal found\n");
399
400         if (status & SAA7191_STATUS_FIDT) {
401                 /* 60hz signal -> NTSC */
402                 dprintk("NTSC\n");
403                 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
404         } else {
405                 /* 50hz signal -> PAL */
406                 dprintk("PAL\n");
407                 return saa7191_set_norm(client, SAA7191_NORM_PAL);
408         }
409 }
410
411 static int saa7191_get_control(struct i2c_client *client,
412                                struct saa7191_control *ctrl)
413 {
414         u8 reg;
415         int ret = 0;
416
417         switch (ctrl->type) {
418         case SAA7191_CONTROL_BANDPASS:
419         case SAA7191_CONTROL_BANDPASS_WEIGHT:
420         case SAA7191_CONTROL_CORING:
421                 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
422                 switch (ctrl->type) {
423                 case SAA7191_CONTROL_BANDPASS:
424                         ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
425                                 >> SAA7191_LUMA_BPSS_SHIFT;
426                         break;
427                 case SAA7191_CONTROL_BANDPASS_WEIGHT:
428                         ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
429                                 >> SAA7191_LUMA_APER_SHIFT;
430                         break;
431                 case SAA7191_CONTROL_CORING:
432                         ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
433                                 >> SAA7191_LUMA_CORI_SHIFT;
434                         break;
435                 }
436                 break;
437         case SAA7191_CONTROL_FORCE_COLOUR:
438         case SAA7191_CONTROL_CHROMA_GAIN:
439                 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
440                 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
441                         ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
442                 else
443                         ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
444                                 >> SAA7191_GAIN_LFIS_SHIFT;
445                 break;
446         case SAA7191_CONTROL_HUE:
447                 reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
448                 if (reg < 0x80)
449                         reg += 0x80;
450                 else
451                         reg -= 0x80;
452                 ctrl->value = (s32)reg;
453                 break;
454         case SAA7191_CONTROL_VTRC:
455                 reg = saa7191_read_reg(client, SAA7191_REG_STDC);
456                 ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
457                 break;
458         case SAA7191_CONTROL_LUMA_DELAY:
459                 reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
460                 ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
461                         >> SAA7191_CTL3_YDEL_SHIFT;
462                 if (ctrl->value >= 4)
463                         ctrl->value -= 8;
464                 break;
465         case SAA7191_CONTROL_VNR:
466                 reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
467                 ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
468                         >> SAA7191_CTL4_VNOI_SHIFT;
469                 break;
470         default:
471                 ret = -EINVAL;
472         }
473
474         return ret;
475 }
476
477 static int saa7191_set_control(struct i2c_client *client,
478                                struct saa7191_control *ctrl)
479 {
480         u8 reg;
481         int ret = 0;
482
483         switch (ctrl->type) {
484         case SAA7191_CONTROL_BANDPASS:
485         case SAA7191_CONTROL_BANDPASS_WEIGHT:
486         case SAA7191_CONTROL_CORING:
487                 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
488                 switch (ctrl->type) {
489                 case SAA7191_CONTROL_BANDPASS:
490                         reg &= ~SAA7191_LUMA_BPSS_MASK;
491                         reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
492                                 & SAA7191_LUMA_BPSS_MASK;
493                         break;
494                 case SAA7191_CONTROL_BANDPASS_WEIGHT:
495                         reg &= ~SAA7191_LUMA_APER_MASK;
496                         reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
497                                 & SAA7191_LUMA_APER_MASK;
498                         break;
499                 case SAA7191_CONTROL_CORING:
500                         reg &= ~SAA7191_LUMA_CORI_MASK;
501                         reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
502                                 & SAA7191_LUMA_CORI_MASK;
503                         break;
504                 }
505                 ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
506                 break;
507         case SAA7191_CONTROL_FORCE_COLOUR:
508         case SAA7191_CONTROL_CHROMA_GAIN:
509                 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
510                 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
511                         if (ctrl->value)
512                                 reg |= SAA7191_GAIN_COLO;
513                         else
514                                 reg &= ~SAA7191_GAIN_COLO;
515                 } else {
516                         reg &= ~SAA7191_GAIN_LFIS_MASK;
517                         reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
518                                 & SAA7191_GAIN_LFIS_MASK;
519                 }
520                 ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
521                 break;
522         case SAA7191_CONTROL_HUE:
523                 reg = ctrl->value & 0xff;
524                 if (reg < 0x80)
525                         reg += 0x80;
526                 else
527                         reg -= 0x80;
528                 ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
529                 break;
530         case SAA7191_CONTROL_VTRC:
531                 reg = saa7191_read_reg(client, SAA7191_REG_STDC);
532                 if (ctrl->value)
533                         reg |= SAA7191_STDC_VTRC;
534                 else
535                         reg &= ~SAA7191_STDC_VTRC;
536                 ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
537                 break;
538         case SAA7191_CONTROL_LUMA_DELAY: {
539                 s32 value = ctrl->value;
540                 if (value < 0)
541                         value += 8;
542                 reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
543                 reg &= ~SAA7191_CTL3_YDEL_MASK;
544                 reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
545                         & SAA7191_CTL3_YDEL_MASK;
546                 ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
547                 break;
548         }
549         case SAA7191_CONTROL_VNR:
550                 reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
551                 reg &= ~SAA7191_CTL4_VNOI_MASK;
552                 reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
553                         & SAA7191_CTL4_VNOI_MASK;
554                 ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
555                 break;
556         default:
557                 ret = -EINVAL;
558         }
559
560         return ret;
561 }
562
563 /* I2C-interface */
564
565 static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
566 {
567         int err = 0;
568         struct saa7191 *decoder;
569         struct i2c_client *client;
570
571         printk(KERN_INFO "Philips SAA7191 driver version %s\n",
572                SAA7191_MODULE_VERSION);
573
574         client = kzalloc(sizeof(*client), GFP_KERNEL);
575         if (!client)
576                 return -ENOMEM;
577         decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
578         if (!decoder) {
579                 err = -ENOMEM;
580                 goto out_free_client;
581         }
582
583         client->addr = addr;
584         client->adapter = adap;
585         client->driver = &i2c_driver_saa7191;
586         client->flags = 0;
587         strcpy(client->name, "saa7191 client");
588         i2c_set_clientdata(client, decoder);
589
590         decoder->client = client;
591
592         err = i2c_attach_client(client);
593         if (err)
594                 goto out_free_decoder;
595
596         err = saa7191_write_block(client, sizeof(initseq), (u8 *)initseq);
597         if (err) {
598                 printk(KERN_ERR "SAA7191 initialization failed\n");
599                 goto out_detach_client;
600         }
601
602         printk(KERN_INFO "SAA7191 initialized\n");
603
604         decoder->input = SAA7191_INPUT_COMPOSITE;
605         decoder->norm = SAA7191_NORM_PAL;
606
607         err = saa7191_autodetect_norm(client);
608         if (err && (err != -EBUSY)) {
609                 printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
610         }
611
612         return 0;
613
614 out_detach_client:
615         i2c_detach_client(client);
616 out_free_decoder:
617         kfree(decoder);
618 out_free_client:
619         kfree(client);
620         return err;
621 }
622
623 static int saa7191_probe(struct i2c_adapter *adap)
624 {
625         /* Always connected to VINO */
626         if (adap->id == I2C_HW_SGI_VINO)
627                 return saa7191_attach(adap, SAA7191_ADDR, 0);
628         /* Feel free to add probe here :-) */
629         return -ENODEV;
630 }
631
632 static int saa7191_detach(struct i2c_client *client)
633 {
634         struct saa7191 *decoder = i2c_get_clientdata(client);
635
636         i2c_detach_client(client);
637         kfree(decoder);
638         kfree(client);
639         return 0;
640 }
641
642 static int saa7191_command(struct i2c_client *client, unsigned int cmd,
643                            void *arg)
644 {
645         struct saa7191 *decoder = i2c_get_clientdata(client);
646
647         switch (cmd) {
648         case DECODER_GET_CAPABILITIES: {
649                 struct video_decoder_capability *cap = arg;
650
651                 cap->flags  = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
652                               VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
653                 cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
654                 cap->outputs = 1;
655                 break;
656         }
657         case DECODER_GET_STATUS: {
658                 int *iarg = arg;
659                 u8 status;
660                 int res = 0;
661
662                 if (saa7191_read_status(client, &status)) {
663                         return -EIO;
664                 }
665                 if ((status & SAA7191_STATUS_HLCK) == 0)
666                         res |= DECODER_STATUS_GOOD;
667                 if (status & SAA7191_STATUS_CODE)
668                         res |= DECODER_STATUS_COLOR;
669                 switch (decoder->norm) {
670                 case SAA7191_NORM_NTSC:
671                         res |= DECODER_STATUS_NTSC;
672                         break;
673                 case SAA7191_NORM_PAL:
674                         res |= DECODER_STATUS_PAL;
675                         break;
676                 case SAA7191_NORM_SECAM:
677                         res |= DECODER_STATUS_SECAM;
678                         break;
679                 case SAA7191_NORM_AUTO:
680                 default:
681                         if (status & SAA7191_STATUS_FIDT)
682                                 res |= DECODER_STATUS_NTSC;
683                         else
684                                 res |= DECODER_STATUS_PAL;
685                         break;
686                 }
687                 *iarg = res;
688                 break;
689         }
690         case DECODER_SET_NORM: {
691                 int *iarg = arg;
692
693                 switch (*iarg) {
694                 case VIDEO_MODE_AUTO:
695                         return saa7191_autodetect_norm(client);
696                 case VIDEO_MODE_PAL:
697                         return saa7191_set_norm(client, SAA7191_NORM_PAL);
698                 case VIDEO_MODE_NTSC:
699                         return saa7191_set_norm(client, SAA7191_NORM_NTSC);
700                 case VIDEO_MODE_SECAM:
701                         return saa7191_set_norm(client, SAA7191_NORM_SECAM);
702                 default:
703                         return -EINVAL;
704                 }
705                 break;
706         }
707         case DECODER_SET_INPUT: {
708                 int *iarg = arg;
709
710                 switch (client->adapter->id) {
711                 case I2C_HW_SGI_VINO:
712                         return saa7191_set_input(client, *iarg);
713                 default:
714                         if (*iarg != 0)
715                                 return -EINVAL;
716                 }
717                 break;
718         }
719         case DECODER_SET_OUTPUT: {
720                 int *iarg = arg;
721
722                 /* not much choice of outputs */
723                 if (*iarg != 0)
724                         return -EINVAL;
725                 break;
726         }
727         case DECODER_ENABLE_OUTPUT: {
728                 /* Always enabled */
729                 break;
730         }
731         case DECODER_SET_PICTURE: {
732                 struct video_picture *pic = arg;
733                 unsigned val;
734                 int err;
735
736                 val = (pic->hue >> 8) - 0x80;
737
738                 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
739                 if (err)
740                         return -EIO;
741
742                 break;
743         }
744         case DECODER_SAA7191_GET_STATUS: {
745                 struct saa7191_status *status = arg;
746                 u8 status_reg;
747
748                 if (saa7191_read_status(client, &status_reg))
749                         return -EIO;
750
751                 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
752                         ? 1 : 0;
753                 status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
754                         ? 1 : 0;
755                 status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
756
757                 status->input = decoder->input;
758                 status->norm = decoder->norm;
759
760                 break;
761         }
762         case DECODER_SAA7191_SET_NORM: {
763                 int *norm = arg;
764
765                 switch (*norm) {
766                 case SAA7191_NORM_AUTO:
767                         return saa7191_autodetect_norm(client);
768                 case SAA7191_NORM_AUTO_EXT:
769                         return saa7191_autodetect_norm_extended(client);
770                 default:
771                         return saa7191_set_norm(client, *norm);
772                 }
773         }
774         case DECODER_SAA7191_GET_CONTROL: {
775                 return saa7191_get_control(client, arg);
776         }
777         case DECODER_SAA7191_SET_CONTROL: {
778                 return saa7191_set_control(client, arg);
779         }
780         default:
781                 return -EINVAL;
782         }
783
784         return 0;
785 }
786
787 static struct i2c_driver i2c_driver_saa7191 = {
788         .driver = {
789                 .name   = "saa7191",
790         },
791         .id             = I2C_DRIVERID_SAA7191,
792         .attach_adapter = saa7191_probe,
793         .detach_client  = saa7191_detach,
794         .command        = saa7191_command
795 };
796
797 static int saa7191_init(void)
798 {
799         return i2c_add_driver(&i2c_driver_saa7191);
800 }
801
802 static void saa7191_exit(void)
803 {
804         i2c_del_driver(&i2c_driver_saa7191);
805 }
806
807 module_init(saa7191_init);
808 module_exit(saa7191_exit);