File: /usr/src/linux/drivers/media/video/saa7111.c

1     /* 
2         saa7111 - Philips SAA7111A video decoder driver version 0.0.3
3     
4         Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5     
6         Slight changes for video timing and attachment output by
7         Wolfgang Scherr <scherr@net4you.net>
8         
9         This program is free software; you can redistribute it and/or modify
10         it under the terms of the GNU General Public License as published by
11         the Free Software Foundation; either version 2 of the License, or
12         (at your option) any later version.
13     
14         This program is distributed in the hope that it will be useful,
15         but WITHOUT ANY WARRANTY; without even the implied warranty of
16         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17         GNU General Public License for more details.
18     
19         You should have received a copy of the GNU General Public License
20         along with this program; if not, write to the Free Software
21         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22     */
23     
24     #include <linux/module.h>
25     #include <linux/init.h>
26     #include <linux/delay.h>
27     #include <linux/errno.h>
28     #include <linux/fs.h>
29     #include <linux/kernel.h>
30     #include <linux/major.h>
31     #include <linux/slab.h>
32     #include <linux/mm.h>
33     #include <linux/sched.h>
34     
35     #include <linux/videodev.h>
36     #include <linux/version.h>
37     #include <linux/i2c-old.h>
38     
39     #include <linux/video_decoder.h>
40     
41     #define DEBUG(x)		/* Debug driver */
42     
43     /* ----------------------------------------------------------------------- */
44     
45     struct saa7111 {
46     	struct i2c_bus *bus;
47     	int addr;
48     	unsigned char reg[32];
49     
50     	int norm;
51     	int input;
52     	int enable;
53     	int bright;
54     	int contrast;
55     	int hue;
56     	int sat;
57     };
58     
59     #define   I2C_SAA7111        0x48
60     
61     #define   I2C_DELAY   10
62     
63     /* ----------------------------------------------------------------------- */
64     
65     static int saa7111_write(struct saa7111 *dev, unsigned char subaddr,
66     			 unsigned char data)
67     {
68     	int ack;
69     
70     	LOCK_I2C_BUS(dev->bus);
71     	i2c_start(dev->bus);
72     	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
73     	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
74     	ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
75     	dev->reg[subaddr] = data;
76     	i2c_stop(dev->bus);
77     	UNLOCK_I2C_BUS(dev->bus);
78     	return ack;
79     }
80     
81     static int saa7111_write_block(struct saa7111 *dev,
82     	       unsigned const char *data, unsigned int len)
83     {
84     	int ack = -1;
85     	unsigned subaddr;
86     
87     	while (len > 1) {
88     		LOCK_I2C_BUS(dev->bus);
89     		i2c_start(dev->bus);
90     		i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
91     		ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
92     		ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
93     		len -= 2;
94     		while (len > 1 && *data == ++subaddr) {
95     			data++;
96     			ack =
97     			    i2c_sendbyte(dev->bus,
98     					 (dev->reg[subaddr] =
99     					  *data++), I2C_DELAY);
100     			len -= 2;
101     		}
102     		i2c_stop(dev->bus);
103     		UNLOCK_I2C_BUS(dev->bus);
104     	}
105     	return ack;
106     }
107     
108     static int saa7111_read(struct saa7111 *dev, unsigned char subaddr)
109     {
110     	int data;
111     
112     	LOCK_I2C_BUS(dev->bus);
113     	i2c_start(dev->bus);
114     	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
115     	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
116     	i2c_start(dev->bus);
117     	i2c_sendbyte(dev->bus, dev->addr | 1, I2C_DELAY);
118     	data = i2c_readbyte(dev->bus, 1);
119     	i2c_stop(dev->bus);
120     	UNLOCK_I2C_BUS(dev->bus);
121     	return data;
122     }
123     
124     /* ----------------------------------------------------------------------- */
125     
126     static int saa7111_attach(struct i2c_device *device)
127     {
128     	int i;
129     	struct saa7111 *decoder;
130     
131     	static const unsigned char init[] = {
132     		0x00, 0x00,	/* 00 - ID byte */
133     		0x01, 0x00,	/* 01 - reserved */
134     
135     		/*front end */
136     		0x02, 0xd0,	/* 02 - FUSE=3, GUDL=2, MODE=0 */
137     		0x03, 0x23,	/* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
138     		0x04, 0x00,	/* 04 - GAI1=256 */
139     		0x05, 0x00,	/* 05 - GAI2=256 */
140     
141     		/* decoder */
142     		0x06, 0xf3,	/* 06 - HSB at  13(50Hz) /  17(60Hz) pixels after end of last line */
143     		0x07, 0x13,	/* 07 - HSS at 113(50Hz) / 117(60Hz) pixels after end of last line */
144     		0x08, 0xc8,	/* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, HPLL=0, VNOI=0 */
145     		0x09, 0x01,	/* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, UPTCV=0, APER=1 */
146     		0x0a, 0x80,	/* 0a - BRIG=128 */
147     		0x0b, 0x47,	/* 0b - CONT=1.109 */
148     		0x0c, 0x40,	/* 0c - SATN=1.0 */
149     		0x0d, 0x00,	/* 0d - HUE=0 */
150     		0x0e, 0x01,	/* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
151     		0x0f, 0x00,	/* 0f - reserved */
152     		0x10, 0x48,	/* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
153     		0x11, 0x1c,	/* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
154     		0x12, 0x00,	/* 12 - output control 2 */
155     		0x13, 0x00,	/* 13 - output control 3 */
156     		0x14, 0x00,	/* 14 - reserved */
157     		0x15, 0x00,	/* 15 - VBI */
158     		0x16, 0x00,	/* 16 - VBI */
159     		0x17, 0x00,	/* 17 - VBI */
160     	};
161     
162     	MOD_INC_USE_COUNT;
163     
164     	device->data = decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
165     	if (decoder == NULL)
166     	{
167     		MOD_DEC_USE_COUNT;
168     		return -ENOMEM;
169     	}
170     
171     	memset(decoder, 0, sizeof(struct saa7111));
172     	strcpy(device->name, "saa7111");
173     	decoder->bus = device->bus;
174     	decoder->addr = device->addr;
175     	decoder->norm = VIDEO_MODE_NTSC;
176     	decoder->input = 0;
177     	decoder->enable = 1;
178     	decoder->bright = 32768;
179     	decoder->contrast = 32768;
180     	decoder->hue = 32768;
181     	decoder->sat = 32768;
182     
183     	i = saa7111_write_block(decoder, init, sizeof(init));
184     	if (i < 0) {
185     		printk(KERN_ERR "%s_attach: init status %d\n",
186     		       device->name, i);
187     	} else {
188     		printk(KERN_INFO "%s_attach: chip version %x\n",
189     		       device->name, saa7111_read(decoder, 0x00) >> 4);
190     	}
191     	return 0;
192     }
193     
194     
195     static int saa7111_detach(struct i2c_device *device)
196     {
197     	kfree(device->data);
198     	MOD_DEC_USE_COUNT;
199     	return 0;
200     }
201     
202     static int saa7111_command(struct i2c_device *device, unsigned int cmd,
203     			   void *arg)
204     {
205     	struct saa7111 *decoder = device->data;
206     
207     	switch (cmd) {
208     
209     #if defined(DECODER_DUMP)
210     	case DECODER_DUMP:
211     		{
212     			int i;
213     
214     			for (i = 0; i < 32; i += 16) {
215     				int j;
216     
217     				printk("KERN_DEBUG %s: %03x", device->name,
218     				       i);
219     				for (j = 0; j < 16; ++j) {
220     					printk(" %02x",
221     					       saa7111_read(decoder,
222     							    i + j));
223     				}
224     				printk("\n");
225     			}
226     		}
227     		break;
228     #endif				/* defined(DECODER_DUMP) */
229     
230     	case DECODER_GET_CAPABILITIES:
231     		{
232     			struct video_decoder_capability *cap = arg;
233     
234     			cap->flags
235     			    = VIDEO_DECODER_PAL
236     			    | VIDEO_DECODER_NTSC
237     			    | VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
238     			cap->inputs = 8;
239     			cap->outputs = 1;
240     		}
241     		break;
242     
243     	case DECODER_GET_STATUS:
244     		{
245     			int *iarg = arg;
246     			int status;
247     			int res;
248     
249     			status = saa7111_read(decoder, 0x1f);
250     			res = 0;
251     			if ((status & (1 << 6)) == 0) {
252     				res |= DECODER_STATUS_GOOD;
253     			}
254     			switch (decoder->norm) {
255     			case VIDEO_MODE_NTSC:
256     				res |= DECODER_STATUS_NTSC;
257     				break;
258     			case VIDEO_MODE_PAL:
259     				res |= DECODER_STATUS_PAL;
260     				break;
261     			default:
262     			case VIDEO_MODE_AUTO:
263     				if ((status & (1 << 5)) != 0) {
264     					res |= DECODER_STATUS_NTSC;
265     				} else {
266     					res |= DECODER_STATUS_PAL;
267     				}
268     				break;
269     			}
270     			if ((status & (1 << 0)) != 0) {
271     				res |= DECODER_STATUS_COLOR;
272     			}
273     			*iarg = res;
274     		}
275     		break;
276     
277     	case DECODER_SET_NORM:
278     		{
279     			int *iarg = arg;
280     
281     			switch (*iarg) {
282     
283     			case VIDEO_MODE_NTSC:
284     				saa7111_write(decoder, 0x08,
285     					      (decoder->
286     					       reg[0x08] & 0x3f) | 0x40);
287     				break;
288     
289     			case VIDEO_MODE_PAL:
290     				saa7111_write(decoder, 0x08,
291     					      (decoder->
292     					       reg[0x08] & 0x3f) | 0x00);
293     				break;
294     
295     			case VIDEO_MODE_AUTO:
296     				saa7111_write(decoder, 0x08,
297     					      (decoder->
298     					       reg[0x08] & 0x3f) | 0x80);
299     				break;
300     
301     			default:
302     				return -EINVAL;
303     
304     			}
305     			decoder->norm = *iarg;
306     		}
307     		break;
308     
309     	case DECODER_SET_INPUT:
310     		{
311     			int *iarg = arg;
312     
313     			if (*iarg < 0 || *iarg > 7) {
314     				return -EINVAL;
315     			}
316     
317     			if (decoder->input != *iarg) {
318     				decoder->input = *iarg;
319     				/* select mode */
320     				saa7111_write(decoder, 0x02,
321     					      (decoder->
322     					       reg[0x02] & 0xf8) |
323     					      decoder->input);
324     				/* bypass chrominance trap for modes 4..7 */
325     				saa7111_write(decoder, 0x09,
326     					      (decoder->
327     					       reg[0x09] & 0x7f) |
328     					      ((decoder->input >
329     						3) ? 0x80 : 0));
330     			}
331     		}
332     		break;
333     
334     	case DECODER_SET_OUTPUT:
335     		{
336     			int *iarg = arg;
337     
338     			/* not much choice of outputs */
339     			if (*iarg != 0) {
340     				return -EINVAL;
341     			}
342     		}
343     		break;
344     
345     	case DECODER_ENABLE_OUTPUT:
346     		{
347     			int *iarg = arg;
348     			int enable = (*iarg != 0);
349     
350     			if (decoder->enable != enable) {
351     				decoder->enable = enable;
352     
353     // RJ: If output should be disabled (for playing videos), we also need a open PLL.
354     //     The input is set to 0 (where no input source is connected), although this
355     //     is not necessary.
356     //
357     //     If output should be enabled, we have to reverse the above.
358     
359     				if (decoder->enable) {
360     					saa7111_write(decoder, 0x02,
361     						      (decoder->
362     						       reg[0x02] & 0xf8) |
363     						      decoder->input);
364     					saa7111_write(decoder, 0x08,
365     						      (decoder->
366     						       reg[0x08] & 0xfb));
367     					saa7111_write(decoder, 0x11,
368     						      (decoder->
369     						       reg[0x11] & 0xf3) |
370     						      0x0c);
371     				} else {
372     					saa7111_write(decoder, 0x02,
373     						      (decoder->
374     						       reg[0x02] & 0xf8));
375     					saa7111_write(decoder, 0x08,
376     						      (decoder->
377     						       reg[0x08] & 0xfb) |
378     						      0x04);
379     					saa7111_write(decoder, 0x11,
380     						      (decoder->
381     						       reg[0x11] & 0xf3));
382     				}
383     			}
384     		}
385     		break;
386     
387     	case DECODER_SET_PICTURE:
388     		{
389     			struct video_picture *pic = arg;
390     
391     			if (decoder->bright != pic->brightness) {
392     				/* We want 0 to 255 we get 0-65535 */
393     				decoder->bright = pic->brightness;
394     				saa7111_write(decoder, 0x0a,
395     					      decoder->bright >> 8);
396     			}
397     			if (decoder->contrast != pic->contrast) {
398     				/* We want 0 to 127 we get 0-65535 */
399     				decoder->contrast = pic->contrast;
400     				saa7111_write(decoder, 0x0b,
401     					      decoder->contrast >> 9);
402     			}
403     			if (decoder->sat != pic->colour) {
404     				/* We want 0 to 127 we get 0-65535 */
405     				decoder->sat = pic->colour;
406     				saa7111_write(decoder, 0x0c,
407     					      decoder->sat >> 9);
408     			}
409     			if (decoder->hue != pic->hue) {
410     				/* We want -128 to 127 we get 0-65535 */
411     				decoder->hue = pic->hue;
412     				saa7111_write(decoder, 0x0d,
413     					      (decoder->hue - 32768) >> 8);
414     			}
415     		}
416     		break;
417     
418     	default:
419     		return -EINVAL;
420     	}
421     
422     	return 0;
423     }
424     
425     /* ----------------------------------------------------------------------- */
426     
427     static struct i2c_driver i2c_driver_saa7111 = {
428     	"saa7111",		/* name */
429     	I2C_DRIVERID_VIDEODECODER,	/* ID */
430     	I2C_SAA7111, I2C_SAA7111 + 1,
431     
432     	saa7111_attach,
433     	saa7111_detach,
434     	saa7111_command
435     };
436     
437     EXPORT_NO_SYMBOLS;
438     
439     static int saa7111_init(void)
440     {
441     	return i2c_register_driver(&i2c_driver_saa7111);
442     }
443     
444     static void saa7111_exit(void)
445     {
446     	i2c_unregister_driver(&i2c_driver_saa7111);
447     }
448     
449     module_init(saa7111_init);
450     module_exit(saa7111_exit);
451