2 saa7111 - Philips SAA7111A video decoder driver version 0.0.3
4 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <linux/module.h>
22 #include <linux/delay.h>
23 #include <linux/errno.h>
25 #include <linux/kernel.h>
26 #include <linux/major.h>
27 #include <linux/malloc.h>
29 #include <linux/pci.h>
30 #include <linux/signal.h>
32 #include <asm/pgtable.h>
34 #include <linux/sched.h>
35 #include <asm/segment.h>
36 #include <linux/types.h>
37 #include <linux/wrapper.h>
39 #include <linux/videodev.h>
40 #include <linux/version.h>
41 #include <asm/uaccess.h>
43 #include <linux/i2c-old.h>
44 #include <linux/video_decoder.h>
46 #define DEBUG(x) /* Debug driver */
48 /* ----------------------------------------------------------------------- */
53 unsigned char reg
[32];
64 #define I2C_SAA7111 0x48
68 /* ----------------------------------------------------------------------- */
70 static int saa7111_write(struct saa7111
*dev
, unsigned char subaddr
, unsigned char data
)
74 LOCK_I2C_BUS(dev
->bus
);
76 i2c_sendbyte(dev
->bus
, dev
->addr
, I2C_DELAY
);
77 i2c_sendbyte(dev
->bus
, subaddr
, I2C_DELAY
);
78 ack
= i2c_sendbyte(dev
->bus
, data
, I2C_DELAY
);
79 dev
->reg
[subaddr
] = data
;
81 UNLOCK_I2C_BUS(dev
->bus
);
85 static int saa7111_write_block(struct saa7111
*dev
, unsigned const char *data
, unsigned int len
)
91 LOCK_I2C_BUS(dev
->bus
);
93 i2c_sendbyte(dev
->bus
, dev
->addr
, I2C_DELAY
);
94 ack
= i2c_sendbyte(dev
->bus
, (subaddr
= *data
++), I2C_DELAY
);
95 ack
= i2c_sendbyte(dev
->bus
, (dev
->reg
[subaddr
] = *data
++), I2C_DELAY
);
97 while (len
> 1 && *data
== ++subaddr
) {
99 ack
= i2c_sendbyte(dev
->bus
, (dev
->reg
[subaddr
] = *data
++), I2C_DELAY
);
103 UNLOCK_I2C_BUS(dev
->bus
);
108 static int saa7111_read(struct saa7111
*dev
, unsigned char subaddr
)
112 LOCK_I2C_BUS(dev
->bus
);
114 i2c_sendbyte(dev
->bus
, dev
->addr
, I2C_DELAY
);
115 i2c_sendbyte(dev
->bus
, subaddr
, I2C_DELAY
);
117 i2c_sendbyte(dev
->bus
, dev
->addr
| 1, I2C_DELAY
);
118 data
= i2c_readbyte(dev
->bus
, 1);
120 UNLOCK_I2C_BUS(dev
->bus
);
124 /* ----------------------------------------------------------------------- */
126 static int saa7111_attach(struct i2c_device
*device
)
129 struct saa7111
*decoder
;
131 static const unsigned char init
[] =
133 0x00, 0x00, /* 00 - ID byte */
134 0x01, 0x00, /* 01 - reserved */
137 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */
138 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
139 0x04, 0x00, /* 04 - GAI1=256 */
140 0x05, 0x00, /* 05 - GAI2=256 */
143 0x06, 0xf6, /* 06 - HSB at 13(50Hz) / 17(60Hz) pixels after end of last line */
144 0x07, 0xdd, /* 07 - HSS at 113(50Hz) / 117(60Hz) pixels after end of last line */
145 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, HPLL=0, VNOI=0 */
146 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, UPTCV=0, APER=1 */
147 0x0a, 0x80, /* 0a - BRIG=128 */
148 0x0b, 0x47, /* 0b - CONT=1.109 */
149 0x0c, 0x40, /* 0c - SATN=1.0 */
150 0x0d, 0x00, /* 0d - HUE=0 */
151 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
152 0x0f, 0x00, /* 0f - reserved */
153 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
154 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
155 0x12, 0x00, /* 12 - output control 2 */
156 0x13, 0x00, /* 13 - output control 3 */
157 0x14, 0x00, /* 14 - reserved */
158 0x15, 0x00, /* 15 - VBI */
159 0x16, 0x00, /* 16 - VBI */
160 0x17, 0x00, /* 17 - VBI */
163 device
->data
= decoder
= kmalloc(sizeof(struct saa7111
), GFP_KERNEL
);
164 if (decoder
== NULL
) {
169 memset(decoder
, 0, sizeof(struct saa7111
));
170 strcpy(device
->name
, "saa7111");
171 decoder
->bus
= device
->bus
;
172 decoder
->addr
= device
->addr
;
173 decoder
->norm
= VIDEO_MODE_NTSC
;
176 decoder
->bright
= 32768;
177 decoder
->contrast
= 32768;
178 decoder
->hue
= 32768;
179 decoder
->sat
= 32768;
181 i
= saa7111_write_block(decoder
, init
, sizeof(init
));
183 printk(KERN_ERR
"%s_attach: init status %d\n", device
->name
, i
);
185 printk(KERN_INFO
"%s_attach: chip version %x\n", device
->name
, saa7111_read(decoder
, 0x00));
191 static int saa7111_detach(struct i2c_device
*device
)
198 static int saa7111_command(struct i2c_device
*device
, unsigned int cmd
, void *arg
)
200 struct saa7111
*decoder
= device
->data
;
204 #if defined(DECODER_DUMP)
209 for (i
= 0; i
< 32; i
+= 16) {
212 printk("KERN_DEBUG %s: %03x", device
->name
, i
);
213 for (j
= 0; j
< 16; ++j
) {
214 printk(" %02x", saa7111_read(decoder
, i
+ j
));
220 #endif /* defined(DECODER_DUMP) */
222 case DECODER_GET_CAPABILITIES
:
224 struct video_decoder_capability
*cap
= arg
;
230 | VIDEO_DECODER_CCIR
;
236 case DECODER_GET_STATUS
:
242 status
= saa7111_read(decoder
, 0x1f);
244 if ((status
& (1 << 6)) == 0) {
245 res
|= DECODER_STATUS_GOOD
;
247 switch (decoder
->norm
) {
248 case VIDEO_MODE_NTSC
:
249 res
|= DECODER_STATUS_NTSC
;
252 res
|= DECODER_STATUS_PAL
;
255 case VIDEO_MODE_AUTO
:
256 if ((status
& (1 << 5)) != 0) {
257 res
|= DECODER_STATUS_NTSC
;
259 res
|= DECODER_STATUS_PAL
;
263 if ((status
& (1 << 0)) != 0) {
264 res
|= DECODER_STATUS_COLOR
;
270 case DECODER_SET_NORM
:
276 case VIDEO_MODE_NTSC
:
277 saa7111_write(decoder
, 0x08, (decoder
->reg
[0x08] & 0x3f) | 0x40);
281 saa7111_write(decoder
, 0x08, (decoder
->reg
[0x08] & 0x3f) | 0x00);
284 case VIDEO_MODE_AUTO
:
285 saa7111_write(decoder
, 0x08, (decoder
->reg
[0x08] & 0x3f) | 0x80);
292 decoder
->norm
= *iarg
;
296 case DECODER_SET_INPUT
:
300 if (*iarg
< 0 || *iarg
> 7) {
303 if (decoder
->input
!= *iarg
) {
304 decoder
->input
= *iarg
;
306 saa7111_write(decoder
, 0x02, (decoder
->reg
[0x02] & 0xf8) | decoder
->input
);
307 /* bypass chrominance trap for modes 4..7 */
308 saa7111_write(decoder
, 0x09, (decoder
->reg
[0x09] & 0x7f) | ((decoder
->input
> 3) ? 0x80 : 0));
313 case DECODER_SET_OUTPUT
:
317 /* not much choice of outputs */
324 case DECODER_ENABLE_OUTPUT
:
327 int enable
= (*iarg
!= 0);
329 if (decoder
->enable
!= enable
) {
330 decoder
->enable
= enable
;
332 // RJ: If output should be disabled (for playing videos), we also need a open PLL.
333 // The input is set to 0 (where no input source is connected), although this
336 // If output should be enabled, we have to reverse the above.
338 if (decoder
->enable
) {
339 saa7111_write(decoder
, 0x02, (decoder
->reg
[0x02] & 0xf8) | decoder
->input
);
340 saa7111_write(decoder
, 0x08, (decoder
->reg
[0x08] & 0xfb));
341 saa7111_write(decoder
, 0x11, (decoder
->reg
[0x11] & 0xf3) | 0x0c);
343 saa7111_write(decoder
, 0x02, (decoder
->reg
[0x02] & 0xf8));
344 saa7111_write(decoder
, 0x08, (decoder
->reg
[0x08] & 0xfb) | 0x04);
345 saa7111_write(decoder
, 0x11, (decoder
->reg
[0x11] & 0xf3));
351 case DECODER_SET_PICTURE
:
353 struct video_picture
*pic
= arg
;
355 if (decoder
->bright
!= pic
->brightness
) {
356 /* We want 0 to 255 we get 0-65535 */
357 decoder
->bright
= pic
->brightness
;
358 saa7111_write(decoder
, 0x0a, decoder
->bright
>> 8);
360 if (decoder
->contrast
!= pic
->contrast
) {
361 /* We want 0 to 127 we get 0-65535 */
362 decoder
->contrast
= pic
->contrast
;
363 saa7111_write(decoder
, 0x0b, decoder
->contrast
>> 9);
365 if (decoder
->sat
!= pic
->colour
) {
366 /* We want 0 to 127 we get 0-65535 */
367 decoder
->sat
= pic
->colour
;
368 saa7111_write(decoder
, 0x0c, decoder
->sat
>> 9);
370 if (decoder
->hue
!= pic
->hue
) {
371 /* We want -128 to 127 we get 0-65535 */
372 decoder
->hue
= pic
->hue
;
373 saa7111_write(decoder
, 0x0d, (decoder
->hue
- 32768) >> 8);
385 /* ----------------------------------------------------------------------- */
387 struct i2c_driver i2c_driver_saa7111
=
389 "saa7111", /* name */
390 I2C_DRIVERID_VIDEODECODER
, /* ID */
391 I2C_SAA7111
, I2C_SAA7111
+ 1,
401 int init_module(void)
403 int saa7111_init(void)
406 return i2c_register_driver(&i2c_driver_saa7111
);
413 void cleanup_module(void)
415 i2c_unregister_driver(&i2c_driver_saa7111
);