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