Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[sfrench/cifs-2.6.git] / drivers / media / video / bt866.c
1 /*
2     bt866 - BT866 Digital Video Encoder (Rockwell Part)
3
4     Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5     Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6
7     Modifications for LML33/DC10plus unified driver
8     Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9
10     This code was modify/ported from the saa7111 driver written
11     by Dave Perks.
12
13     This code was adapted for the bt866 by Christer Weinigel and ported
14     to 2.6 by Martin Samuelsson.
15
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.
20
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.
25
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.
29 */
30
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/signal.h>
41 #include <asm/io.h>
42 #include <asm/pgtable.h>
43 #include <asm/page.h>
44 #include <linux/sched.h>
45 #include <linux/types.h>
46 #include <linux/i2c.h>
47
48 #include <linux/videodev.h>
49 #include <asm/uaccess.h>
50
51 #include <linux/video_encoder.h>
52
53 MODULE_LICENSE("GPL");
54
55 #define BT866_DEVNAME   "bt866"
56 #define I2C_BT866       0x88
57
58 MODULE_LICENSE("GPL");
59
60 #define DEBUG(x)                /* Debug driver */
61
62 /* ----------------------------------------------------------------------- */
63
64 struct bt866 {
65         struct i2c_client *i2c;
66         int addr;
67         unsigned char reg[256];
68
69         int norm;
70         int enable;
71         int bright;
72         int contrast;
73         int hue;
74         int sat;
75 };
76
77 static int bt866_write(struct bt866 *dev,
78                         unsigned char subaddr, unsigned char data);
79
80 static int bt866_do_command(struct bt866 *encoder,
81                         unsigned int cmd, void *arg)
82 {
83         switch (cmd) {
84         case ENCODER_GET_CAPABILITIES:
85         {
86                 struct video_encoder_capability *cap = arg;
87
88                 DEBUG(printk
89                       (KERN_INFO "%s: get capabilities\n",
90                        encoder->i2c->name));
91
92                 cap->flags
93                         = VIDEO_ENCODER_PAL
94                         | VIDEO_ENCODER_NTSC
95                         | VIDEO_ENCODER_CCIR;
96                 cap->inputs = 2;
97                 cap->outputs = 1;
98         }
99         break;
100
101         case ENCODER_SET_NORM:
102         {
103                 int *iarg = arg;
104
105                 DEBUG(printk(KERN_INFO "%s: set norm %d\n",
106                              encoder->i2c->name, *iarg));
107
108                 switch (*iarg) {
109
110                 case VIDEO_MODE_NTSC:
111                         break;
112
113                 case VIDEO_MODE_PAL:
114                         break;
115
116                 default:
117                         return -EINVAL;
118
119                 }
120                 encoder->norm = *iarg;
121         }
122         break;
123
124         case ENCODER_SET_INPUT:
125         {
126                 int *iarg = arg;
127                 static const __u8 init[] = {
128                         0xc8, 0xcc, /* CRSCALE */
129                         0xca, 0x91, /* CBSCALE */
130                         0xcc, 0x24, /* YC16 | OSDNUM */
131                         0xda, 0x00, /*  */
132                         0xdc, 0x24, /* SETMODE | PAL */
133                         0xde, 0x02, /* EACTIVE */
134
135                         /* overlay colors */
136                         0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
137                         0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
138                         0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
139                         0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
140                         0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
141                         0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
142                         0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
143                         0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
144
145                         0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
146                         0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
147                         0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
148                         0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
149                         0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
150                         0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
151                         0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
152                         0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
153                 };
154                 int i;
155                 u8 val;
156
157                 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
158                         bt866_write(encoder, init[i], init[i+1]);
159
160                 val = encoder->reg[0xdc];
161
162                 if (*iarg == 0)
163                         val |= 0x40; /* CBSWAP */
164                 else
165                         val &= ~0x40; /* !CBSWAP */
166
167                 bt866_write(encoder, 0xdc, val);
168
169                 val = encoder->reg[0xcc];
170                 if (*iarg == 2)
171                         val |= 0x01; /* OSDBAR */
172                 else
173                         val &= ~0x01; /* !OSDBAR */
174                 bt866_write(encoder, 0xcc, val);
175
176                 DEBUG(printk(KERN_INFO "%s: set input %d\n",
177                              encoder->i2c->name, *iarg));
178
179                 switch (*iarg) {
180                 case 0:
181                         break;
182                 case 1:
183                         break;
184                 default:
185                         return -EINVAL;
186
187                 }
188         }
189         break;
190
191         case ENCODER_SET_OUTPUT:
192         {
193                 int *iarg = arg;
194
195                 DEBUG(printk(KERN_INFO "%s: set output %d\n",
196                              encoder->i2c->name, *iarg));
197
198                 /* not much choice of outputs */
199                 if (*iarg != 0)
200                         return -EINVAL;
201         }
202         break;
203
204         case ENCODER_ENABLE_OUTPUT:
205         {
206                 int *iarg = arg;
207                 encoder->enable = !!*iarg;
208
209                 DEBUG(printk
210                       (KERN_INFO "%s: enable output %d\n",
211                        encoder->i2c->name, encoder->enable));
212         }
213         break;
214
215         case 4711:
216         {
217                 int *iarg = arg;
218                 __u8 val;
219
220                 printk("bt866: square = %d\n", *iarg);
221
222                 val = encoder->reg[0xdc];
223                 if (*iarg)
224                         val |= 1; /* SQUARE */
225                 else
226                         val &= ~1; /* !SQUARE */
227                 bt866_write(encoder, 0xdc, val);
228                 break;
229         }
230
231         default:
232                 return -EINVAL;
233         }
234
235         return 0;
236 }
237
238 static int bt866_write(struct bt866 *encoder,
239                         unsigned char subaddr, unsigned char data)
240 {
241         unsigned char buffer[2];
242         int err;
243
244         buffer[0] = subaddr;
245         buffer[1] = data;
246
247         encoder->reg[subaddr] = data;
248
249         DEBUG(printk
250               ("%s: write 0x%02X = 0x%02X\n",
251                encoder->i2c->name, subaddr, data));
252
253         for (err = 0; err < 3;) {
254                 if (i2c_master_send(encoder->i2c, buffer, 2) == 2)
255                         break;
256                 err++;
257                 printk(KERN_WARNING "%s: I/O error #%d "
258                        "(write 0x%02x/0x%02x)\n",
259                        encoder->i2c->name, err, encoder->addr, subaddr);
260                 schedule_timeout_interruptible(HZ/10);
261         }
262         if (err == 3) {
263                 printk(KERN_WARNING "%s: giving up\n",
264                        encoder->i2c->name);
265                 return -1;
266         }
267
268         return 0;
269 }
270
271 static int bt866_attach(struct i2c_adapter *adapter);
272 static int bt866_detach(struct i2c_client *client);
273 static int bt866_command(struct i2c_client *client,
274                          unsigned int cmd, void *arg);
275
276
277 /* Addresses to scan */
278 static unsigned short normal_i2c[]      = {I2C_BT866>>1, I2C_CLIENT_END};
279 static unsigned short probe[2]          = {I2C_CLIENT_END, I2C_CLIENT_END};
280 static unsigned short ignore[2]         = {I2C_CLIENT_END, I2C_CLIENT_END};
281
282 static struct i2c_client_address_data addr_data = {
283         normal_i2c,
284         probe,
285         ignore,
286 };
287
288 static struct i2c_driver i2c_driver_bt866 = {
289         .driver.name = BT866_DEVNAME,
290         .id = I2C_DRIVERID_BT866,
291         .attach_adapter = bt866_attach,
292         .detach_client = bt866_detach,
293         .command = bt866_command
294 };
295
296
297 static struct i2c_client bt866_client_tmpl =
298 {
299         .name = "(nil)",
300         .addr = 0,
301         .adapter = NULL,
302         .driver = &i2c_driver_bt866,
303         .usage_count = 0
304 };
305
306 static int bt866_found_proc(struct i2c_adapter *adapter,
307                             int addr, int kind)
308 {
309         struct bt866 *encoder;
310         struct i2c_client *client;
311
312         client = kzalloc(sizeof(*client), GFP_KERNEL);
313         if (client == NULL)
314                 return -ENOMEM;
315         memcpy(client, &bt866_client_tmpl, sizeof(*client));
316
317         encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
318         if (encoder == NULL) {
319                 kfree(client);
320                 return -ENOMEM;
321         }
322
323         i2c_set_clientdata(client, encoder);
324         client->adapter = adapter;
325         client->addr = addr;
326         sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
327
328         encoder->i2c = client;
329         encoder->addr = addr;
330         //encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
331
332         /* initialize */
333
334         i2c_attach_client(client);
335
336         return 0;
337 }
338
339 static int bt866_attach(struct i2c_adapter *adapter)
340 {
341         if (adapter->id == I2C_HW_B_ZR36067)
342                 return i2c_probe(adapter, &addr_data, bt866_found_proc);
343         return 0;
344 }
345
346 static int bt866_detach(struct i2c_client *client)
347 {
348         struct bt866 *encoder = i2c_get_clientdata(client);
349
350         i2c_detach_client(client);
351         kfree(encoder);
352         kfree(client);
353
354         return 0;
355 }
356
357 static int bt866_command(struct i2c_client *client,
358                          unsigned int cmd, void *arg)
359 {
360         struct bt866 *encoder = i2c_get_clientdata(client);
361         return bt866_do_command(encoder, cmd, arg);
362 }
363
364 static int __devinit bt866_init(void)
365 {
366         i2c_add_driver(&i2c_driver_bt866);
367         return 0;
368 }
369
370 static void __devexit bt866_exit(void)
371 {
372         i2c_del_driver(&i2c_driver_bt866);
373 }
374
375 module_init(bt866_init);
376 module_exit(bt866_exit);