Portability cleanup as required by Linus.
[linux-2.6/linux-mips.git] / drivers / char / saa7111.c
blob1eeeca3524195be5e612b857a8faed7baf0464b7
1 /*
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>
24 #include <linux/fs.h>
25 #include <linux/kernel.h>
26 #include <linux/major.h>
27 #include <linux/malloc.h>
28 #include <linux/mm.h>
29 #include <linux/pci.h>
30 #include <linux/signal.h>
31 #include <asm/io.h>
32 #include <asm/pgtable.h>
33 #include <asm/page.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 /* ----------------------------------------------------------------------- */
50 struct saa7111 {
51 struct i2c_bus *bus;
52 int addr;
53 unsigned char reg[32];
55 int norm;
56 int input;
57 int enable;
58 int bright;
59 int contrast;
60 int hue;
61 int sat;
64 #define I2C_SAA7111 0x48
66 #define I2C_DELAY 10
68 /* ----------------------------------------------------------------------- */
70 static int saa7111_write(struct saa7111 *dev, unsigned char subaddr, unsigned char data)
72 int ack;
74 LOCK_I2C_BUS(dev->bus);
75 i2c_start(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;
80 i2c_stop(dev->bus);
81 UNLOCK_I2C_BUS(dev->bus);
82 return ack;
85 static int saa7111_write_block(struct saa7111 *dev, unsigned const char *data, unsigned int len)
87 int ack = 0;
88 unsigned subaddr;
90 while (len > 1) {
91 LOCK_I2C_BUS(dev->bus);
92 i2c_start(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);
96 len -= 2;
97 while (len > 1 && *data == ++subaddr) {
98 data++;
99 ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
100 len -= 2;
102 i2c_stop(dev->bus);
103 UNLOCK_I2C_BUS(dev->bus);
105 return ack;
108 static int saa7111_read(struct saa7111 *dev, unsigned char subaddr)
110 int data;
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;
124 /* ----------------------------------------------------------------------- */
126 static int saa7111_attach(struct i2c_device *device)
128 int i;
129 struct saa7111 *decoder;
131 static const unsigned char init[] =
133 0x00, 0x00, /* 00 - ID byte */
134 0x01, 0x00, /* 01 - reserved */
136 /*front end */
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 */
142 /* decoder */
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) {
165 return -ENOMEM;
167 MOD_INC_USE_COUNT;
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;
174 decoder->input = 0;
175 decoder->enable = 1;
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));
182 if (i < 0) {
183 printk(KERN_ERR "%s_attach: init status %d\n", device->name, i);
184 } else {
185 printk(KERN_INFO "%s_attach: chip version %x\n", device->name, saa7111_read(decoder, 0x00));
187 return 0;
191 static int saa7111_detach(struct i2c_device *device)
193 kfree(device->data);
194 MOD_DEC_USE_COUNT;
195 return 0;
198 static int saa7111_command(struct i2c_device *device, unsigned int cmd, void *arg)
200 struct saa7111 *decoder = device->data;
202 switch (cmd) {
204 #if defined(DECODER_DUMP)
205 case DECODER_DUMP:
207 int i;
209 for (i = 0; i < 32; i += 16) {
210 int j;
212 printk("KERN_DEBUG %s: %03x", device->name, i);
213 for (j = 0; j < 16; ++j) {
214 printk(" %02x", saa7111_read(decoder, i + j));
216 printk("\n");
219 break;
220 #endif /* defined(DECODER_DUMP) */
222 case DECODER_GET_CAPABILITIES:
224 struct video_decoder_capability *cap = arg;
226 cap->flags
227 = VIDEO_DECODER_PAL
228 | VIDEO_DECODER_NTSC
229 | VIDEO_DECODER_AUTO
230 | VIDEO_DECODER_CCIR;
231 cap->inputs = 8;
232 cap->outputs = 1;
234 break;
236 case DECODER_GET_STATUS:
238 int *iarg = arg;
239 int status;
240 int res;
242 status = saa7111_read(decoder, 0x1f);
243 res = 0;
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;
250 break;
251 case VIDEO_MODE_PAL:
252 res |= DECODER_STATUS_PAL;
253 break;
254 default:
255 case VIDEO_MODE_AUTO:
256 if ((status & (1 << 5)) != 0) {
257 res |= DECODER_STATUS_NTSC;
258 } else {
259 res |= DECODER_STATUS_PAL;
261 break;
263 if ((status & (1 << 0)) != 0) {
264 res |= DECODER_STATUS_COLOR;
266 *iarg = res;
268 break;
270 case DECODER_SET_NORM:
272 int *iarg = arg;
274 switch (*iarg) {
276 case VIDEO_MODE_NTSC:
277 saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x40);
278 break;
280 case VIDEO_MODE_PAL:
281 saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x00);
282 break;
284 case VIDEO_MODE_AUTO:
285 saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x80);
286 break;
288 default:
289 return -EINVAL;
292 decoder->norm = *iarg;
294 break;
296 case DECODER_SET_INPUT:
298 int *iarg = arg;
300 if (*iarg < 0 || *iarg > 7) {
301 return -EINVAL;
303 if (decoder->input != *iarg) {
304 decoder->input = *iarg;
305 /* select mode */
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));
311 break;
313 case DECODER_SET_OUTPUT:
315 int *iarg = arg;
317 /* not much choice of outputs */
318 if (*iarg != 0) {
319 return -EINVAL;
322 break;
324 case DECODER_ENABLE_OUTPUT:
326 int *iarg = arg;
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
334 // is not necessary.
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);
342 } else {
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));
349 break;
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);
376 break;
378 default:
379 return -EINVAL;
382 return 0;
385 /* ----------------------------------------------------------------------- */
387 struct i2c_driver i2c_driver_saa7111 =
389 "saa7111", /* name */
390 I2C_DRIVERID_VIDEODECODER, /* ID */
391 I2C_SAA7111, I2C_SAA7111 + 1,
393 saa7111_attach,
394 saa7111_detach,
395 saa7111_command
398 EXPORT_NO_SYMBOLS;
400 #ifdef MODULE
401 int init_module(void)
402 #else
403 int saa7111_init(void)
404 #endif
406 return i2c_register_driver(&i2c_driver_saa7111);
411 #ifdef MODULE
413 void cleanup_module(void)
415 i2c_unregister_driver(&i2c_driver_saa7111);
418 #endif