PNP: stop using the subsystem rwsem
[linux/fpc-iii.git] / drivers / media / video / bt866.c
blob772fd52d551aaf35a5a43cb363831e1f51be9bc8
1 /*
2 bt866 - BT866 Digital Video Encoder (Rockwell Part)
4 Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
7 Modifications for LML33/DC10plus unified driver
8 Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
10 This code was modify/ported from the saa7111 driver written
11 by Dave Perks.
13 This code was adapted for the bt866 by Christer Weinigel and ported
14 to 2.6 by Martin Samuelsson.
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/delay.h>
34 #include <linux/errno.h>
35 #include <linux/fs.h>
36 #include <linux/kernel.h>
37 #include <linux/major.h>
38 #include <linux/slab.h>
39 #include <linux/mm.h>
40 #include <linux/pci.h>
41 #include <linux/signal.h>
42 #include <asm/io.h>
43 #include <asm/pgtable.h>
44 #include <asm/page.h>
45 #include <linux/sched.h>
46 #include <linux/types.h>
47 #include <linux/i2c.h>
49 #include <linux/videodev.h>
50 #include <asm/uaccess.h>
52 #include <linux/video_encoder.h>
54 MODULE_LICENSE("GPL");
56 #define BT866_DEVNAME "bt866"
57 #define I2C_BT866 0x88
59 MODULE_LICENSE("GPL");
61 #define DEBUG(x) /* Debug driver */
63 /* ----------------------------------------------------------------------- */
65 struct bt866 {
66 struct i2c_client *i2c;
67 int addr;
68 unsigned char reg[256];
70 int norm;
71 int enable;
72 int bright;
73 int contrast;
74 int hue;
75 int sat;
78 static int bt866_write(struct bt866 *dev,
79 unsigned char subaddr, unsigned char data);
81 static int bt866_do_command(struct bt866 *encoder,
82 unsigned int cmd, void *arg)
84 switch (cmd) {
85 case ENCODER_GET_CAPABILITIES:
87 struct video_encoder_capability *cap = arg;
89 DEBUG(printk
90 (KERN_INFO "%s: get capabilities\n",
91 encoder->i2c->name));
93 cap->flags
94 = VIDEO_ENCODER_PAL
95 | VIDEO_ENCODER_NTSC
96 | VIDEO_ENCODER_CCIR;
97 cap->inputs = 2;
98 cap->outputs = 1;
100 break;
102 case ENCODER_SET_NORM:
104 int *iarg = arg;
106 DEBUG(printk(KERN_INFO "%s: set norm %d\n",
107 encoder->i2c->name, *iarg));
109 switch (*iarg) {
111 case VIDEO_MODE_NTSC:
112 break;
114 case VIDEO_MODE_PAL:
115 break;
117 default:
118 return -EINVAL;
121 encoder->norm = *iarg;
123 break;
125 case ENCODER_SET_INPUT:
127 int *iarg = arg;
128 static const __u8 init[] = {
129 0xc8, 0xcc, /* CRSCALE */
130 0xca, 0x91, /* CBSCALE */
131 0xcc, 0x24, /* YC16 | OSDNUM */
132 0xda, 0x00, /* */
133 0xdc, 0x24, /* SETMODE | PAL */
134 0xde, 0x02, /* EACTIVE */
136 /* overlay colors */
137 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
138 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
139 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
140 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
141 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
142 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
143 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
144 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
146 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
147 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
148 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
149 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
150 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
151 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
152 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
153 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
155 int i;
156 u8 val;
158 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
159 bt866_write(encoder, init[i], init[i+1]);
161 val = encoder->reg[0xdc];
163 if (*iarg == 0)
164 val |= 0x40; /* CBSWAP */
165 else
166 val &= ~0x40; /* !CBSWAP */
168 bt866_write(encoder, 0xdc, val);
170 val = encoder->reg[0xcc];
171 if (*iarg == 2)
172 val |= 0x01; /* OSDBAR */
173 else
174 val &= ~0x01; /* !OSDBAR */
175 bt866_write(encoder, 0xcc, val);
177 DEBUG(printk(KERN_INFO "%s: set input %d\n",
178 encoder->i2c->name, *iarg));
180 switch (*iarg) {
181 case 0:
182 break;
183 case 1:
184 break;
185 default:
186 return -EINVAL;
190 break;
192 case ENCODER_SET_OUTPUT:
194 int *iarg = arg;
196 DEBUG(printk(KERN_INFO "%s: set output %d\n",
197 encoder->i2c->name, *iarg));
199 /* not much choice of outputs */
200 if (*iarg != 0)
201 return -EINVAL;
203 break;
205 case ENCODER_ENABLE_OUTPUT:
207 int *iarg = arg;
208 encoder->enable = !!*iarg;
210 DEBUG(printk
211 (KERN_INFO "%s: enable output %d\n",
212 encoder->i2c->name, encoder->enable));
214 break;
216 case 4711:
218 int *iarg = arg;
219 __u8 val;
221 printk("bt866: square = %d\n", *iarg);
223 val = encoder->reg[0xdc];
224 if (*iarg)
225 val |= 1; /* SQUARE */
226 else
227 val &= ~1; /* !SQUARE */
228 bt866_write(encoder, 0xdc, val);
229 break;
232 default:
233 return -EINVAL;
236 return 0;
239 static int bt866_write(struct bt866 *encoder,
240 unsigned char subaddr, unsigned char data)
242 unsigned char buffer[2];
243 int err;
245 buffer[0] = subaddr;
246 buffer[1] = data;
248 encoder->reg[subaddr] = data;
250 DEBUG(printk
251 ("%s: write 0x%02X = 0x%02X\n",
252 encoder->i2c->name, subaddr, data));
254 for (err = 0; err < 3;) {
255 if (i2c_master_send(encoder->i2c, buffer, 2) == 2)
256 break;
257 err++;
258 printk(KERN_WARNING "%s: I/O error #%d "
259 "(write 0x%02x/0x%02x)\n",
260 encoder->i2c->name, err, encoder->addr, subaddr);
261 schedule_timeout_interruptible(HZ/10);
263 if (err == 3) {
264 printk(KERN_WARNING "%s: giving up\n",
265 encoder->i2c->name);
266 return -1;
269 return 0;
272 static int bt866_attach(struct i2c_adapter *adapter);
273 static int bt866_detach(struct i2c_client *client);
274 static int bt866_command(struct i2c_client *client,
275 unsigned int cmd, void *arg);
278 /* Addresses to scan */
279 static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END};
280 static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
281 static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
283 static struct i2c_client_address_data addr_data = {
284 normal_i2c,
285 probe,
286 ignore,
289 static struct i2c_driver i2c_driver_bt866 = {
290 .driver.name = BT866_DEVNAME,
291 .id = I2C_DRIVERID_BT866,
292 .attach_adapter = bt866_attach,
293 .detach_client = bt866_detach,
294 .command = bt866_command
298 static struct i2c_client bt866_client_tmpl =
300 .name = "(nil)",
301 .addr = 0,
302 .adapter = NULL,
303 .driver = &i2c_driver_bt866,
304 .usage_count = 0
307 static int bt866_found_proc(struct i2c_adapter *adapter,
308 int addr, int kind)
310 struct bt866 *encoder;
311 struct i2c_client *client;
313 client = kzalloc(sizeof(*client), GFP_KERNEL);
314 if (client == NULL)
315 return -ENOMEM;
316 memcpy(client, &bt866_client_tmpl, sizeof(*client));
318 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
319 if (encoder == NULL) {
320 kfree(client);
321 return -ENOMEM;
324 i2c_set_clientdata(client, encoder);
325 client->adapter = adapter;
326 client->addr = addr;
327 sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
329 encoder->i2c = client;
330 encoder->addr = addr;
331 //encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
333 /* initialize */
335 i2c_attach_client(client);
337 return 0;
340 static int bt866_attach(struct i2c_adapter *adapter)
342 if (adapter->id == I2C_HW_B_ZR36067)
343 return i2c_probe(adapter, &addr_data, bt866_found_proc);
344 return 0;
347 static int bt866_detach(struct i2c_client *client)
349 struct bt866 *encoder = i2c_get_clientdata(client);
351 i2c_detach_client(client);
352 kfree(encoder);
353 kfree(client);
355 return 0;
358 static int bt866_command(struct i2c_client *client,
359 unsigned int cmd, void *arg)
361 struct bt866 *encoder = i2c_get_clientdata(client);
362 return bt866_do_command(encoder, cmd, arg);
365 static int __devinit bt866_init(void)
367 i2c_add_driver(&i2c_driver_bt866);
368 return 0;
371 static void __devexit bt866_exit(void)
373 i2c_del_driver(&i2c_driver_bt866);
376 module_init(bt866_init);
377 module_exit(bt866_exit);