V4L/DVB (9994): gspca: t613: Bad loop in om6802 reset.
[linux-2.6/next.git] / drivers / media / video / bt866.c
blob596f9e2376beccf140690bf92228ef973b32880f
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/types.h>
33 #include <linux/ioctl.h>
34 #include <asm/uaccess.h>
35 #include <linux/i2c.h>
36 #include <linux/i2c-id.h>
37 #include <linux/videodev.h>
38 #include <linux/video_encoder.h>
39 #include <media/v4l2-common.h>
40 #include <media/v4l2-i2c-drv-legacy.h>
42 MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
43 MODULE_AUTHOR("Mike Bernson & Dave Perks");
44 MODULE_LICENSE("GPL");
46 static int debug;
47 module_param(debug, int, 0);
48 MODULE_PARM_DESC(debug, "Debug level (0-1)");
50 /* ----------------------------------------------------------------------- */
52 struct bt866 {
53 u8 reg[256];
55 int norm;
56 int enable;
57 int bright;
58 int contrast;
59 int hue;
60 int sat;
63 static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
65 struct bt866 *encoder = i2c_get_clientdata(client);
66 u8 buffer[2];
67 int err;
69 buffer[0] = subaddr;
70 buffer[1] = data;
72 encoder->reg[subaddr] = data;
74 v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);
76 for (err = 0; err < 3;) {
77 if (i2c_master_send(client, buffer, 2) == 2)
78 break;
79 err++;
80 v4l_warn(client, "error #%d writing to 0x%02x\n",
81 err, subaddr);
82 schedule_timeout_interruptible(msecs_to_jiffies(100));
84 if (err == 3) {
85 v4l_warn(client, "giving up\n");
86 return -1;
89 return 0;
92 static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
94 struct bt866 *encoder = i2c_get_clientdata(client);
96 switch (cmd) {
97 case ENCODER_GET_CAPABILITIES:
99 struct video_encoder_capability *cap = arg;
101 v4l_dbg(1, debug, client, "get capabilities\n");
103 cap->flags
104 = VIDEO_ENCODER_PAL
105 | VIDEO_ENCODER_NTSC
106 | VIDEO_ENCODER_CCIR;
107 cap->inputs = 2;
108 cap->outputs = 1;
109 break;
112 case ENCODER_SET_NORM:
114 int *iarg = arg;
116 v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
118 switch (*iarg) {
119 case VIDEO_MODE_NTSC:
120 break;
122 case VIDEO_MODE_PAL:
123 break;
125 default:
126 return -EINVAL;
128 encoder->norm = *iarg;
129 break;
132 case ENCODER_SET_INPUT:
134 int *iarg = arg;
135 static const __u8 init[] = {
136 0xc8, 0xcc, /* CRSCALE */
137 0xca, 0x91, /* CBSCALE */
138 0xcc, 0x24, /* YC16 | OSDNUM */
139 0xda, 0x00, /* */
140 0xdc, 0x24, /* SETMODE | PAL */
141 0xde, 0x02, /* EACTIVE */
143 /* overlay colors */
144 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
145 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
146 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
147 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
148 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
149 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
150 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
151 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
153 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
154 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
155 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
156 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
157 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
158 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
159 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
160 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
162 int i;
163 u8 val;
165 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
166 bt866_write(client, init[i], init[i+1]);
168 val = encoder->reg[0xdc];
170 if (*iarg == 0)
171 val |= 0x40; /* CBSWAP */
172 else
173 val &= ~0x40; /* !CBSWAP */
175 bt866_write(client, 0xdc, val);
177 val = encoder->reg[0xcc];
178 if (*iarg == 2)
179 val |= 0x01; /* OSDBAR */
180 else
181 val &= ~0x01; /* !OSDBAR */
182 bt866_write(client, 0xcc, val);
184 v4l_dbg(1, debug, client, "set input %d\n", *iarg);
186 switch (*iarg) {
187 case 0:
188 break;
189 case 1:
190 break;
191 default:
192 return -EINVAL;
194 break;
197 case ENCODER_SET_OUTPUT:
199 int *iarg = arg;
201 v4l_dbg(1, debug, client, "set output %d\n", *iarg);
203 /* not much choice of outputs */
204 if (*iarg != 0)
205 return -EINVAL;
206 break;
209 case ENCODER_ENABLE_OUTPUT:
211 int *iarg = arg;
212 encoder->enable = !!*iarg;
214 v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
215 break;
218 case 4711:
220 int *iarg = arg;
221 __u8 val;
223 v4l_dbg(1, debug, client, "square %d\n", *iarg);
225 val = encoder->reg[0xdc];
226 if (*iarg)
227 val |= 1; /* SQUARE */
228 else
229 val &= ~1; /* !SQUARE */
230 bt866_write(client, 0xdc, val);
231 break;
234 default:
235 return -EINVAL;
238 return 0;
241 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
243 I2C_CLIENT_INSMOD;
245 static int bt866_probe(struct i2c_client *client,
246 const struct i2c_device_id *id)
248 struct bt866 *encoder;
250 v4l_info(client, "chip found @ 0x%x (%s)\n",
251 client->addr << 1, client->adapter->name);
253 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
254 if (encoder == NULL)
255 return -ENOMEM;
257 i2c_set_clientdata(client, encoder);
258 return 0;
261 static int bt866_remove(struct i2c_client *client)
263 kfree(i2c_get_clientdata(client));
264 return 0;
267 static int bt866_legacy_probe(struct i2c_adapter *adapter)
269 return adapter->id == I2C_HW_B_ZR36067;
272 static const struct i2c_device_id bt866_id[] = {
273 { "bt866", 0 },
276 MODULE_DEVICE_TABLE(i2c, bt866_id);
278 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
279 .name = "bt866",
280 .driverid = I2C_DRIVERID_BT866,
281 .command = bt866_command,
282 .probe = bt866_probe,
283 .remove = bt866_remove,
284 .legacy_probe = bt866_legacy_probe,
285 .id_table = bt866_id,