aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt866.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/bt866.c')
-rw-r--r--drivers/media/video/bt866.c255
1 files changed, 83 insertions, 172 deletions
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index 96b415576f0d..596f9e2376be 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.c
@@ -29,42 +29,28 @@
29*/ 29*/
30 30
31#include <linux/module.h> 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> 32#include <linux/types.h>
33#include <linux/ioctl.h>
34#include <asm/uaccess.h>
46#include <linux/i2c.h> 35#include <linux/i2c.h>
47 36#include <linux/i2c-id.h>
48#include <linux/videodev.h> 37#include <linux/videodev.h>
49#include <asm/uaccess.h>
50
51#include <linux/video_encoder.h> 38#include <linux/video_encoder.h>
39#include <media/v4l2-common.h>
40#include <media/v4l2-i2c-drv-legacy.h>
52 41
42MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
43MODULE_AUTHOR("Mike Bernson & Dave Perks");
53MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
54 45
55#define BT866_DEVNAME "bt866" 46static int debug;
56#define I2C_BT866 0x88 47module_param(debug, int, 0);
57 48MODULE_PARM_DESC(debug, "Debug level (0-1)");
58MODULE_LICENSE("GPL");
59
60#define DEBUG(x) /* Debug driver */
61 49
62/* ----------------------------------------------------------------------- */ 50/* ----------------------------------------------------------------------- */
63 51
64struct bt866 { 52struct bt866 {
65 struct i2c_client *i2c; 53 u8 reg[256];
66 int addr;
67 unsigned char reg[256];
68 54
69 int norm; 55 int norm;
70 int enable; 56 int enable;
@@ -74,20 +60,45 @@ struct bt866 {
74 int sat; 60 int sat;
75}; 61};
76 62
77static int bt866_write(struct bt866 *dev, 63static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
78 unsigned char subaddr, unsigned char 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}
79 91
80static int bt866_do_command(struct bt866 *encoder, 92static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
81 unsigned int cmd, void *arg)
82{ 93{
94 struct bt866 *encoder = i2c_get_clientdata(client);
95
83 switch (cmd) { 96 switch (cmd) {
84 case ENCODER_GET_CAPABILITIES: 97 case ENCODER_GET_CAPABILITIES:
85 { 98 {
86 struct video_encoder_capability *cap = arg; 99 struct video_encoder_capability *cap = arg;
87 100
88 DEBUG(printk 101 v4l_dbg(1, debug, client, "get capabilities\n");
89 (KERN_INFO "%s: get capabilities\n",
90 encoder->i2c->name));
91 102
92 cap->flags 103 cap->flags
93 = VIDEO_ENCODER_PAL 104 = VIDEO_ENCODER_PAL
@@ -95,18 +106,16 @@ static int bt866_do_command(struct bt866 *encoder,
95 | VIDEO_ENCODER_CCIR; 106 | VIDEO_ENCODER_CCIR;
96 cap->inputs = 2; 107 cap->inputs = 2;
97 cap->outputs = 1; 108 cap->outputs = 1;
109 break;
98 } 110 }
99 break;
100 111
101 case ENCODER_SET_NORM: 112 case ENCODER_SET_NORM:
102 { 113 {
103 int *iarg = arg; 114 int *iarg = arg;
104 115
105 DEBUG(printk(KERN_INFO "%s: set norm %d\n", 116 v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
106 encoder->i2c->name, *iarg));
107 117
108 switch (*iarg) { 118 switch (*iarg) {
109
110 case VIDEO_MODE_NTSC: 119 case VIDEO_MODE_NTSC:
111 break; 120 break;
112 121
@@ -115,11 +124,10 @@ static int bt866_do_command(struct bt866 *encoder,
115 124
116 default: 125 default:
117 return -EINVAL; 126 return -EINVAL;
118
119 } 127 }
120 encoder->norm = *iarg; 128 encoder->norm = *iarg;
129 break;
121 } 130 }
122 break;
123 131
124 case ENCODER_SET_INPUT: 132 case ENCODER_SET_INPUT:
125 { 133 {
@@ -155,7 +163,7 @@ static int bt866_do_command(struct bt866 *encoder,
155 u8 val; 163 u8 val;
156 164
157 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) 165 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
158 bt866_write(encoder, init[i], init[i+1]); 166 bt866_write(client, init[i], init[i+1]);
159 167
160 val = encoder->reg[0xdc]; 168 val = encoder->reg[0xdc];
161 169
@@ -164,17 +172,16 @@ static int bt866_do_command(struct bt866 *encoder,
164 else 172 else
165 val &= ~0x40; /* !CBSWAP */ 173 val &= ~0x40; /* !CBSWAP */
166 174
167 bt866_write(encoder, 0xdc, val); 175 bt866_write(client, 0xdc, val);
168 176
169 val = encoder->reg[0xcc]; 177 val = encoder->reg[0xcc];
170 if (*iarg == 2) 178 if (*iarg == 2)
171 val |= 0x01; /* OSDBAR */ 179 val |= 0x01; /* OSDBAR */
172 else 180 else
173 val &= ~0x01; /* !OSDBAR */ 181 val &= ~0x01; /* !OSDBAR */
174 bt866_write(encoder, 0xcc, val); 182 bt866_write(client, 0xcc, val);
175 183
176 DEBUG(printk(KERN_INFO "%s: set input %d\n", 184 v4l_dbg(1, debug, client, "set input %d\n", *iarg);
177 encoder->i2c->name, *iarg));
178 185
179 switch (*iarg) { 186 switch (*iarg) {
180 case 0: 187 case 0:
@@ -183,48 +190,44 @@ static int bt866_do_command(struct bt866 *encoder,
183 break; 190 break;
184 default: 191 default:
185 return -EINVAL; 192 return -EINVAL;
186
187 } 193 }
194 break;
188 } 195 }
189 break;
190 196
191 case ENCODER_SET_OUTPUT: 197 case ENCODER_SET_OUTPUT:
192 { 198 {
193 int *iarg = arg; 199 int *iarg = arg;
194 200
195 DEBUG(printk(KERN_INFO "%s: set output %d\n", 201 v4l_dbg(1, debug, client, "set output %d\n", *iarg);
196 encoder->i2c->name, *iarg));
197 202
198 /* not much choice of outputs */ 203 /* not much choice of outputs */
199 if (*iarg != 0) 204 if (*iarg != 0)
200 return -EINVAL; 205 return -EINVAL;
206 break;
201 } 207 }
202 break;
203 208
204 case ENCODER_ENABLE_OUTPUT: 209 case ENCODER_ENABLE_OUTPUT:
205 { 210 {
206 int *iarg = arg; 211 int *iarg = arg;
207 encoder->enable = !!*iarg; 212 encoder->enable = !!*iarg;
208 213
209 DEBUG(printk 214 v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
210 (KERN_INFO "%s: enable output %d\n", 215 break;
211 encoder->i2c->name, encoder->enable));
212 } 216 }
213 break;
214 217
215 case 4711: 218 case 4711:
216 { 219 {
217 int *iarg = arg; 220 int *iarg = arg;
218 __u8 val; 221 __u8 val;
219 222
220 printk("bt866: square = %d\n", *iarg); 223 v4l_dbg(1, debug, client, "square %d\n", *iarg);
221 224
222 val = encoder->reg[0xdc]; 225 val = encoder->reg[0xdc];
223 if (*iarg) 226 if (*iarg)
224 val |= 1; /* SQUARE */ 227 val |= 1; /* SQUARE */
225 else 228 else
226 val &= ~1; /* !SQUARE */ 229 val &= ~1; /* !SQUARE */
227 bt866_write(encoder, 0xdc, val); 230 bt866_write(client, 0xdc, val);
228 break; 231 break;
229 } 232 }
230 233
@@ -235,141 +238,49 @@ static int bt866_do_command(struct bt866 *encoder,
235 return 0; 238 return 0;
236} 239}
237 240
238static int bt866_write(struct bt866 *encoder, 241static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
239 unsigned char subaddr, unsigned char data)
240{
241 unsigned char buffer[2];
242 int err;
243 242
244 buffer[0] = subaddr; 243I2C_CLIENT_INSMOD;
245 buffer[1] = data;
246
247 encoder->reg[subaddr] = data;
248 244
249 DEBUG(printk 245static int bt866_probe(struct i2c_client *client,
250 ("%s: write 0x%02X = 0x%02X\n", 246 const struct i2c_device_id *id)
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(msecs_to_jiffies(100));
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
271static int bt866_attach(struct i2c_adapter *adapter);
272static int bt866_detach(struct i2c_client *client);
273static int bt866_command(struct i2c_client *client,
274 unsigned int cmd, void *arg);
275
276
277/* Addresses to scan */
278static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END};
279static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
280static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
281
282static struct i2c_client_address_data addr_data = {
283 normal_i2c,
284 probe,
285 ignore,
286};
287
288static 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
297static struct i2c_client bt866_client_tmpl =
298{
299 .name = "(nil)",
300 .addr = 0,
301 .adapter = NULL,
302 .driver = &i2c_driver_bt866,
303};
304
305static int bt866_found_proc(struct i2c_adapter *adapter,
306 int addr, int kind)
307{ 247{
308 struct bt866 *encoder; 248 struct bt866 *encoder;
309 struct i2c_client *client;
310 249
311 client = kzalloc(sizeof(*client), GFP_KERNEL); 250 v4l_info(client, "chip found @ 0x%x (%s)\n",
312 if (client == NULL) 251 client->addr << 1, client->adapter->name);
313 return -ENOMEM;
314 memcpy(client, &bt866_client_tmpl, sizeof(*client));
315 252
316 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); 253 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
317 if (encoder == NULL) { 254 if (encoder == NULL)
318 kfree(client);
319 return -ENOMEM; 255 return -ENOMEM;
320 }
321 256
322 i2c_set_clientdata(client, encoder); 257 i2c_set_clientdata(client, encoder);
323 client->adapter = adapter;
324 client->addr = addr;
325 sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
326
327 encoder->i2c = client;
328 encoder->addr = addr;
329 //encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
330
331 /* initialize */
332
333 i2c_attach_client(client);
334
335 return 0;
336}
337
338static int bt866_attach(struct i2c_adapter *adapter)
339{
340 if (adapter->id == I2C_HW_B_ZR36067)
341 return i2c_probe(adapter, &addr_data, bt866_found_proc);
342 return 0;
343}
344
345static int bt866_detach(struct i2c_client *client)
346{
347 struct bt866 *encoder = i2c_get_clientdata(client);
348
349 i2c_detach_client(client);
350 kfree(encoder);
351 kfree(client);
352
353 return 0; 258 return 0;
354} 259}
355 260
356static int bt866_command(struct i2c_client *client, 261static int bt866_remove(struct i2c_client *client)
357 unsigned int cmd, void *arg)
358{ 262{
359 struct bt866 *encoder = i2c_get_clientdata(client); 263 kfree(i2c_get_clientdata(client));
360 return bt866_do_command(encoder, cmd, arg);
361}
362
363static int __devinit bt866_init(void)
364{
365 i2c_add_driver(&i2c_driver_bt866);
366 return 0; 264 return 0;
367} 265}
368 266
369static void __devexit bt866_exit(void) 267static int bt866_legacy_probe(struct i2c_adapter *adapter)
370{ 268{
371 i2c_del_driver(&i2c_driver_bt866); 269 return adapter->id == I2C_HW_B_ZR36067;
372} 270}
373 271
374module_init(bt866_init); 272static const struct i2c_device_id bt866_id[] = {
375module_exit(bt866_exit); 273 { "bt866", 0 },
274 { }
275};
276MODULE_DEVICE_TABLE(i2c, bt866_id);
277
278static 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};