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 = kmalloc(sizeof(*client), GFP_KERNEL);
575         if (!client)
576                 return -ENOMEM;
577         decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
578         if (!decoder) {
579                 err = -ENOMEM;
580                 goto out_free_client;
581         }
582
583         memset(client, 0, sizeof(struct i2c_client));
584         memset(decoder, 0, sizeof(struct saa7191));
585
586         client->addr = addr;
587         client->adapter = adap;
588         client->driver = &i2c_driver_saa7191;
589         client->flags = 0;
590         strcpy(client->name, "saa7191 client");
591         i2c_set_clientdata(client, decoder);
592
593         decoder->client = client;
594
595         err = i2c_attach_client(client);
596         if (err)
597                 goto out_free_decoder;
598
599         err = saa7191_write_block(client, sizeof(initseq), (u8 *)initseq);
600         if (err) {
601                 printk(KERN_ERR "SAA7191 initialization failed\n");
602                 goto out_detach_client;
603         }
604
605         printk(KERN_INFO "SAA7191 initialized\n");
606
607         decoder->input = SAA7191_INPUT_COMPOSITE;
608         decoder->norm = SAA7191_NORM_PAL;
609
610         err = saa7191_autodetect_norm(client);
611         if (err && (err != -EBUSY)) {
612                 printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
613         }
614
615         return 0;
616
617 out_detach_client:
618         i2c_detach_client(client);
619 out_free_decoder:
620         kfree(decoder);
621 out_free_client:
622         kfree(client);
623         return err;
624 }
625
626 static int saa7191_probe(struct i2c_adapter *adap)
627 {
628         /* Always connected to VINO */
629         if (adap->id == I2C_HW_SGI_VINO)
630                 return saa7191_attach(adap, SAA7191_ADDR, 0);
631         /* Feel free to add probe here :-) */
632         return -ENODEV;
633 }
634
635 static int saa7191_detach(struct i2c_client *client)
636 {
637         struct saa7191 *decoder = i2c_get_clientdata(client);
638
639         i2c_detach_client(client);
640         kfree(decoder);
641         kfree(client);
642         return 0;
643 }
644
645 static int saa7191_command(struct i2c_client *client, unsigned int cmd,
646                            void *arg)
647 {
648         struct saa7191 *decoder = i2c_get_clientdata(client);
649
650         switch (cmd) {
651         case DECODER_GET_CAPABILITIES: {
652                 struct video_decoder_capability *cap = arg;
653
654                 cap->flags  = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
655                               VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
656                 cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
657                 cap->outputs = 1;
658                 break;
659         }
660         case DECODER_GET_STATUS: {
661                 int *iarg = arg;
662                 u8 status;
663                 int res = 0;
664
665                 if (saa7191_read_status(client, &status)) {
666                         return -EIO;
667                 }
668                 if ((status & SAA7191_STATUS_HLCK) == 0)
669                         res |= DECODER_STATUS_GOOD;
670                 if (status & SAA7191_STATUS_CODE)
671                         res |= DECODER_STATUS_COLOR;
672                 switch (decoder->norm) {
673                 case SAA7191_NORM_NTSC:
674                         res |= DECODER_STATUS_NTSC;
675                         break;
676                 case SAA7191_NORM_PAL:
677                         res |= DECODER_STATUS_PAL;
678                         break;
679                 case SAA7191_NORM_SECAM:
680                         res |= DECODER_STATUS_SECAM;
681                         break;
682                 case SAA7191_NORM_AUTO:
683                 default:
684                         if (status & SAA7191_STATUS_FIDT)
685                                 res |= DECODER_STATUS_NTSC;
686                         else
687                                 res |= DECODER_STATUS_PAL;
688                         break;
689                 }
690                 *iarg = res;
691                 break;
692         }
693         case DECODER_SET_NORM: {
694                 int *iarg = arg;
695
696                 switch (*iarg) {
697                 case VIDEO_MODE_AUTO:
698                         return saa7191_autodetect_norm(client);
699                 case VIDEO_MODE_PAL:
700                         return saa7191_set_norm(client, SAA7191_NORM_PAL);
701                 case VIDEO_MODE_NTSC:
702                         return saa7191_set_norm(client, SAA7191_NORM_NTSC);
703                 case VIDEO_MODE_SECAM:
704                         return saa7191_set_norm(client, SAA7191_NORM_SECAM);
705                 default:
706                         return -EINVAL;
707                 }
708                 break;
709         }
710         case DECODER_SET_INPUT: {
711                 int *iarg = arg;
712
713                 switch (client->adapter->id) {
714                 case I2C_HW_SGI_VINO:
715                         return saa7191_set_input(client, *iarg);
716                 default:
717                         if (*iarg != 0)
718                                 return -EINVAL;
719                 }
720                 break;
721         }
722         case DECODER_SET_OUTPUT: {
723                 int *iarg = arg;
724
725                 /* not much choice of outputs */
726                 if (*iarg != 0)
727                         return -EINVAL;
728                 break;
729         }
730         case DECODER_ENABLE_OUTPUT: {
731                 /* Always enabled */
732                 break;
733         }
734         case DECODER_SET_PICTURE: {
735                 struct video_picture *pic = arg;
736                 unsigned val;
737                 int err;
738
739                 val = (pic->hue >> 8) - 0x80;
740
741                 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
742                 if (err)
743                         return -EIO;
744
745                 break;
746         }
747         case DECODER_SAA7191_GET_STATUS: {
748                 struct saa7191_status *status = arg;
749                 u8 status_reg;
750
751                 if (saa7191_read_status(client, &status_reg))
752                         return -EIO;
753
754                 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
755                         ? 1 : 0;
756                 status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
757                         ? 1 : 0;
758                 status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
759
760                 status->input = decoder->input;
761                 status->norm = decoder->norm;
762
763                 break;
764         }
765         case DECODER_SAA7191_SET_NORM: {
766                 int *norm = arg;
767
768                 switch (*norm) {
769                 case SAA7191_NORM_AUTO:
770                         return saa7191_autodetect_norm(client);
771                 case SAA7191_NORM_AUTO_EXT:
772                         return saa7191_autodetect_norm_extended(client);
773                 default:
774                         return saa7191_set_norm(client, *norm);
775                 }
776         }
777         case DECODER_SAA7191_GET_CONTROL: {
778                 return saa7191_get_control(client, arg);
779         }
780         case DECODER_SAA7191_SET_CONTROL: {
781                 return saa7191_set_control(client, arg);
782         }
783         default:
784                 return -EINVAL;
785         }
786
787         return 0;
788 }
789
790 static struct i2c_driver i2c_driver_saa7191 = {
791         .owner          = THIS_MODULE,
792         .name           = "saa7191",
793         .id             = I2C_DRIVERID_SAA7191,
794         .flags          = I2C_DF_NOTIFY,
795         .attach_adapter = saa7191_probe,
796         .detach_client  = saa7191_detach,
797         .command        = saa7191_command
798 };
799
800 static int saa7191_init(void)
801 {
802         return i2c_add_driver(&i2c_driver_saa7191);
803 }
804
805 static void saa7191_exit(void)
806 {
807         i2c_del_driver(&i2c_driver_saa7191);
808 }
809
810 module_init(saa7191_init);
811 module_exit(saa7191_exit);