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
30MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
31MODULE_VERSION(SAA7191_MODULE_VERSION);
32MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
33MODULE_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
46struct 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
57static struct i2c_driver i2c_driver_saa7191;
58
59static 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
103static u8 saa7191_read_reg(struct i2c_client *client,
104			   u8 reg)
105{
106	return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
107}
108
109static 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
124static 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) */
132static 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
155static 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
190static 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
238static 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
261static 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
365out:
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
378static 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
410static 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
476static 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
564static 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
613out_detach_client:
614	i2c_detach_client(client);
615out_free_decoder:
616	kfree(decoder);
617out_free_client:
618	kfree(client);
619	return err;
620}
621
622static 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
631static 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
641static 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
786static 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
796static int saa7191_init(void)
797{
798	return i2c_add_driver(&i2c_driver_saa7191);
799}
800
801static void saa7191_exit(void)
802{
803	i2c_del_driver(&i2c_driver_saa7191);
804}
805
806module_init(saa7191_init);
807module_exit(saa7191_exit);
808