Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[deliverable/linux.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/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>
41
42 MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
43 MODULE_AUTHOR("Mike Bernson & Dave Perks");
44 MODULE_LICENSE("GPL");
45
46 static int debug;
47 module_param(debug, int, 0);
48 MODULE_PARM_DESC(debug, "Debug level (0-1)");
49
50 /* ----------------------------------------------------------------------- */
51
52 struct bt866 {
53 u8 reg[256];
54
55 int norm;
56 int enable;
57 int bright;
58 int contrast;
59 int hue;
60 int sat;
61 };
62
63 static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
64 {
65 struct bt866 *encoder = i2c_get_clientdata(client);
66 u8 buffer[2];
67 int err;
68
69 buffer[0] = subaddr;
70 buffer[1] = data;
71
72 encoder->reg[subaddr] = data;
73
74 v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);
75
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));
83 }
84 if (err == 3) {
85 v4l_warn(client, "giving up\n");
86 return -1;
87 }
88
89 return 0;
90 }
91
92 static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
93 {
94 struct bt866 *encoder = i2c_get_clientdata(client);
95
96 switch (cmd) {
97 case ENCODER_GET_CAPABILITIES:
98 {
99 struct video_encoder_capability *cap = arg;
100
101 v4l_dbg(1, debug, client, "get capabilities\n");
102
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;
110 }
111
112 case ENCODER_SET_NORM:
113 {
114 int *iarg = arg;
115
116 v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
117
118 switch (*iarg) {
119 case VIDEO_MODE_NTSC:
120 break;
121
122 case VIDEO_MODE_PAL:
123 break;
124
125 default:
126 return -EINVAL;
127 }
128 encoder->norm = *iarg;
129 break;
130 }
131
132 case ENCODER_SET_INPUT:
133 {
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 */
142
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 */
152
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 */
161 };
162 int i;
163 u8 val;
164
165 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
166 bt866_write(client, init[i], init[i+1]);
167
168 val = encoder->reg[0xdc];
169
170 if (*iarg == 0)
171 val |= 0x40; /* CBSWAP */
172 else
173 val &= ~0x40; /* !CBSWAP */
174
175 bt866_write(client, 0xdc, val);
176
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);
183
184 v4l_dbg(1, debug, client, "set input %d\n", *iarg);
185
186 switch (*iarg) {
187 case 0:
188 break;
189 case 1:
190 break;
191 default:
192 return -EINVAL;
193 }
194 break;
195 }
196
197 case ENCODER_SET_OUTPUT:
198 {
199 int *iarg = arg;
200
201 v4l_dbg(1, debug, client, "set output %d\n", *iarg);
202
203 /* not much choice of outputs */
204 if (*iarg != 0)
205 return -EINVAL;
206 break;
207 }
208
209 case ENCODER_ENABLE_OUTPUT:
210 {
211 int *iarg = arg;
212 encoder->enable = !!*iarg;
213
214 v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
215 break;
216 }
217
218 case 4711:
219 {
220 int *iarg = arg;
221 __u8 val;
222
223 v4l_dbg(1, debug, client, "square %d\n", *iarg);
224
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;
232 }
233
234 default:
235 return -EINVAL;
236 }
237
238 return 0;
239 }
240
241 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
242
243 I2C_CLIENT_INSMOD;
244
245 static int bt866_probe(struct i2c_client *client,
246 const struct i2c_device_id *id)
247 {
248 struct bt866 *encoder;
249
250 v4l_info(client, "chip found @ 0x%x (%s)\n",
251 client->addr << 1, client->adapter->name);
252
253 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
254 if (encoder == NULL)
255 return -ENOMEM;
256
257 i2c_set_clientdata(client, encoder);
258 return 0;
259 }
260
261 static int bt866_remove(struct i2c_client *client)
262 {
263 kfree(i2c_get_clientdata(client));
264 return 0;
265 }
266
267 static int bt866_legacy_probe(struct i2c_adapter *adapter)
268 {
269 return adapter->id == I2C_HW_B_ZR36067;
270 }
271
272 static const struct i2c_device_id bt866_id[] = {
273 { "bt866", 0 },
274 { }
275 };
276 MODULE_DEVICE_TABLE(i2c, bt866_id);
277
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,
286 };
This page took 0.051278 seconds and 6 git commands to generate.