diff options
Diffstat (limited to 'drivers/media/video/bt819.c')
-rw-r--r-- | drivers/media/video/bt819.c | 321 |
1 files changed, 92 insertions, 229 deletions
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index ddd2a7964dec..a07b7b88e5b8 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c | |||
@@ -29,44 +29,25 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | ||
33 | #include <linux/delay.h> | 32 | #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 <linux/types.h> | 33 | #include <linux/types.h> |
42 | #include <linux/i2c.h> | 34 | #include <linux/ioctl.h> |
43 | #include <asm/io.h> | ||
44 | #include <asm/pgtable.h> | ||
45 | #include <asm/page.h> | ||
46 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
47 | 36 | #include <linux/i2c.h> | |
37 | #include <linux/i2c-id.h> | ||
48 | #include <linux/videodev.h> | 38 | #include <linux/videodev.h> |
49 | #include <linux/video_decoder.h> | 39 | #include <linux/video_decoder.h> |
50 | 40 | #include <media/v4l2-common.h> | |
41 | #include <media/v4l2-i2c-drv-legacy.h> | ||
51 | 42 | ||
52 | MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); | 43 | MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); |
53 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); | 44 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); |
54 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
55 | 46 | ||
56 | |||
57 | #define I2C_NAME(s) (s)->name | ||
58 | |||
59 | |||
60 | static int debug; | 47 | static int debug; |
61 | module_param(debug, int, 0); | 48 | module_param(debug, int, 0); |
62 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 49 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
63 | 50 | ||
64 | #define dprintk(num, format, args...) \ | ||
65 | do { \ | ||
66 | if (debug >= num) \ | ||
67 | printk(format, ##args); \ | ||
68 | } while (0) | ||
69 | |||
70 | /* ----------------------------------------------------------------------- */ | 51 | /* ----------------------------------------------------------------------- */ |
71 | 52 | ||
72 | struct bt819 { | 53 | struct bt819 { |
@@ -97,14 +78,9 @@ static struct timing timing_data[] = { | |||
97 | {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000}, | 78 | {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000}, |
98 | }; | 79 | }; |
99 | 80 | ||
100 | #define I2C_BT819 0x8a | ||
101 | |||
102 | /* ----------------------------------------------------------------------- */ | 81 | /* ----------------------------------------------------------------------- */ |
103 | 82 | ||
104 | static inline int | 83 | static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value) |
105 | bt819_write (struct i2c_client *client, | ||
106 | u8 reg, | ||
107 | u8 value) | ||
108 | { | 84 | { |
109 | struct bt819 *decoder = i2c_get_clientdata(client); | 85 | struct bt819 *decoder = i2c_get_clientdata(client); |
110 | 86 | ||
@@ -112,24 +88,15 @@ bt819_write (struct i2c_client *client, | |||
112 | return i2c_smbus_write_byte_data(client, reg, value); | 88 | return i2c_smbus_write_byte_data(client, reg, value); |
113 | } | 89 | } |
114 | 90 | ||
115 | static inline int | 91 | static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value) |
116 | bt819_setbit (struct i2c_client *client, | ||
117 | u8 reg, | ||
118 | u8 bit, | ||
119 | u8 value) | ||
120 | { | 92 | { |
121 | struct bt819 *decoder = i2c_get_clientdata(client); | 93 | struct bt819 *decoder = i2c_get_clientdata(client); |
122 | 94 | ||
123 | return bt819_write(client, reg, | 95 | return bt819_write(client, reg, |
124 | (decoder-> | 96 | (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0)); |
125 | reg[reg] & ~(1 << bit)) | | ||
126 | (value ? (1 << bit) : 0)); | ||
127 | } | 97 | } |
128 | 98 | ||
129 | static int | 99 | static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len) |
130 | bt819_write_block (struct i2c_client *client, | ||
131 | const u8 *data, | ||
132 | unsigned int len) | ||
133 | { | 100 | { |
134 | int ret = -1; | 101 | int ret = -1; |
135 | u8 reg; | 102 | u8 reg; |
@@ -150,10 +117,9 @@ bt819_write_block (struct i2c_client *client, | |||
150 | decoder->reg[reg++] = data[1]; | 117 | decoder->reg[reg++] = data[1]; |
151 | len -= 2; | 118 | len -= 2; |
152 | data += 2; | 119 | data += 2; |
153 | } while (len >= 2 && data[0] == reg && | 120 | } while (len >= 2 && data[0] == reg && block_len < 32); |
154 | block_len < 32); | 121 | ret = i2c_master_send(client, block_data, block_len); |
155 | if ((ret = i2c_master_send(client, block_data, | 122 | if (ret < 0) |
156 | block_len)) < 0) | ||
157 | break; | 123 | break; |
158 | } | 124 | } |
159 | } else { | 125 | } else { |
@@ -169,20 +135,17 @@ bt819_write_block (struct i2c_client *client, | |||
169 | return ret; | 135 | return ret; |
170 | } | 136 | } |
171 | 137 | ||
172 | static inline int | 138 | static inline int bt819_read(struct i2c_client *client, u8 reg) |
173 | bt819_read (struct i2c_client *client, | ||
174 | u8 reg) | ||
175 | { | 139 | { |
176 | return i2c_smbus_read_byte_data(client, reg); | 140 | return i2c_smbus_read_byte_data(client, reg); |
177 | } | 141 | } |
178 | 142 | ||
179 | static int | 143 | static int bt819_init(struct i2c_client *client) |
180 | bt819_init (struct i2c_client *client) | ||
181 | { | 144 | { |
182 | struct bt819 *decoder = i2c_get_clientdata(client); | 145 | struct bt819 *decoder = i2c_get_clientdata(client); |
183 | 146 | ||
184 | static unsigned char init[] = { | 147 | static unsigned char init[] = { |
185 | //0x1f, 0x00, /* Reset */ | 148 | /*0x1f, 0x00,*/ /* Reset */ |
186 | 0x01, 0x59, /* 0x01 input format */ | 149 | 0x01, 0x59, /* 0x01 input format */ |
187 | 0x02, 0x00, /* 0x02 temporal decimation */ | 150 | 0x02, 0x00, /* 0x02 temporal decimation */ |
188 | 0x03, 0x12, /* 0x03 Cropping msb */ | 151 | 0x03, 0x12, /* 0x03 Cropping msb */ |
@@ -218,12 +181,10 @@ bt819_init (struct i2c_client *client) | |||
218 | struct timing *timing = &timing_data[decoder->norm]; | 181 | struct timing *timing = &timing_data[decoder->norm]; |
219 | 182 | ||
220 | init[0x03 * 2 - 1] = | 183 | init[0x03 * 2 - 1] = |
221 | (((timing->vdelay >> 8) & 0x03) << 6) | (((timing-> | 184 | (((timing->vdelay >> 8) & 0x03) << 6) | |
222 | vactive >> 8) & | 185 | (((timing->vactive >> 8) & 0x03) << 4) | |
223 | 0x03) << 4) | | 186 | (((timing->hdelay >> 8) & 0x03) << 2) | |
224 | (((timing->hdelay >> 8) & 0x03) << 2) | ((timing-> | 187 | ((timing->hactive >> 8) & 0x03); |
225 | hactive >> 8) & | ||
226 | 0x03); | ||
227 | init[0x04 * 2 - 1] = timing->vdelay & 0xff; | 188 | init[0x04 * 2 - 1] = timing->vdelay & 0xff; |
228 | init[0x05 * 2 - 1] = timing->vactive & 0xff; | 189 | init[0x05 * 2 - 1] = timing->vactive & 0xff; |
229 | init[0x06 * 2 - 1] = timing->hdelay & 0xff; | 190 | init[0x06 * 2 - 1] = timing->hdelay & 0xff; |
@@ -238,27 +199,22 @@ bt819_init (struct i2c_client *client) | |||
238 | 199 | ||
239 | /* init */ | 200 | /* init */ |
240 | return bt819_write_block(client, init, sizeof(init)); | 201 | return bt819_write_block(client, init, sizeof(init)); |
241 | |||
242 | } | 202 | } |
243 | 203 | ||
244 | /* ----------------------------------------------------------------------- */ | 204 | /* ----------------------------------------------------------------------- */ |
245 | 205 | ||
246 | static int | 206 | static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) |
247 | bt819_command (struct i2c_client *client, | ||
248 | unsigned int cmd, | ||
249 | void *arg) | ||
250 | { | 207 | { |
251 | int temp; | 208 | int temp; |
252 | 209 | ||
253 | struct bt819 *decoder = i2c_get_clientdata(client); | 210 | struct bt819 *decoder = i2c_get_clientdata(client); |
254 | 211 | ||
255 | if (!decoder->initialized) { // First call to bt819_init could be | 212 | if (!decoder->initialized) { /* First call to bt819_init could be */ |
256 | bt819_init(client); // without #FRST = 0 | 213 | bt819_init(client); /* without #FRST = 0 */ |
257 | decoder->initialized = 1; | 214 | decoder->initialized = 1; |
258 | } | 215 | } |
259 | 216 | ||
260 | switch (cmd) { | 217 | switch (cmd) { |
261 | |||
262 | case 0: | 218 | case 0: |
263 | /* This is just for testing!!! */ | 219 | /* This is just for testing!!! */ |
264 | bt819_init(client); | 220 | bt819_init(client); |
@@ -274,8 +230,8 @@ bt819_command (struct i2c_client *client, | |||
274 | VIDEO_DECODER_CCIR; | 230 | VIDEO_DECODER_CCIR; |
275 | cap->inputs = 8; | 231 | cap->inputs = 8; |
276 | cap->outputs = 1; | 232 | cap->outputs = 1; |
277 | } | ||
278 | break; | 233 | break; |
234 | } | ||
279 | 235 | ||
280 | case DECODER_GET_STATUS: | 236 | case DECODER_GET_STATUS: |
281 | { | 237 | { |
@@ -285,9 +241,9 @@ bt819_command (struct i2c_client *client, | |||
285 | 241 | ||
286 | status = bt819_read(client, 0x00); | 242 | status = bt819_read(client, 0x00); |
287 | res = 0; | 243 | res = 0; |
288 | if ((status & 0x80)) { | 244 | if ((status & 0x80)) |
289 | res |= DECODER_STATUS_GOOD; | 245 | res |= DECODER_STATUS_GOOD; |
290 | } | 246 | |
291 | switch (decoder->norm) { | 247 | switch (decoder->norm) { |
292 | case VIDEO_MODE_NTSC: | 248 | case VIDEO_MODE_NTSC: |
293 | res |= DECODER_STATUS_NTSC; | 249 | res |= DECODER_STATUS_NTSC; |
@@ -297,28 +253,25 @@ bt819_command (struct i2c_client *client, | |||
297 | break; | 253 | break; |
298 | default: | 254 | default: |
299 | case VIDEO_MODE_AUTO: | 255 | case VIDEO_MODE_AUTO: |
300 | if ((status & 0x10)) { | 256 | if ((status & 0x10)) |
301 | res |= DECODER_STATUS_PAL; | 257 | res |= DECODER_STATUS_PAL; |
302 | } else { | 258 | else |
303 | res |= DECODER_STATUS_NTSC; | 259 | res |= DECODER_STATUS_NTSC; |
304 | } | ||
305 | break; | 260 | break; |
306 | } | 261 | } |
307 | res |= DECODER_STATUS_COLOR; | 262 | res |= DECODER_STATUS_COLOR; |
308 | *iarg = res; | 263 | *iarg = res; |
309 | 264 | ||
310 | dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client), | 265 | v4l_dbg(1, debug, client, "get status %x\n", *iarg); |
311 | *iarg); | ||
312 | } | ||
313 | break; | 266 | break; |
267 | } | ||
314 | 268 | ||
315 | case DECODER_SET_NORM: | 269 | case DECODER_SET_NORM: |
316 | { | 270 | { |
317 | int *iarg = arg; | 271 | int *iarg = arg; |
318 | struct timing *timing = NULL; | 272 | struct timing *timing = NULL; |
319 | 273 | ||
320 | dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client), | 274 | v4l_dbg(1, debug, client, "set norm %x\n", *iarg); |
321 | *iarg); | ||
322 | 275 | ||
323 | switch (*iarg) { | 276 | switch (*iarg) { |
324 | case VIDEO_MODE_NTSC: | 277 | case VIDEO_MODE_NTSC: |
@@ -327,7 +280,7 @@ bt819_command (struct i2c_client *client, | |||
327 | bt819_setbit(client, 0x01, 5, 0); | 280 | bt819_setbit(client, 0x01, 5, 0); |
328 | bt819_write(client, 0x18, 0x68); | 281 | bt819_write(client, 0x18, 0x68); |
329 | bt819_write(client, 0x19, 0x5d); | 282 | bt819_write(client, 0x19, 0x5d); |
330 | //bt819_setbit(client, 0x1a, 5, 1); | 283 | /* bt819_setbit(client, 0x1a, 5, 1); */ |
331 | timing = &timing_data[VIDEO_MODE_NTSC]; | 284 | timing = &timing_data[VIDEO_MODE_NTSC]; |
332 | break; | 285 | break; |
333 | case VIDEO_MODE_PAL: | 286 | case VIDEO_MODE_PAL: |
@@ -336,7 +289,7 @@ bt819_command (struct i2c_client *client, | |||
336 | bt819_setbit(client, 0x01, 5, 1); | 289 | bt819_setbit(client, 0x01, 5, 1); |
337 | bt819_write(client, 0x18, 0x7f); | 290 | bt819_write(client, 0x18, 0x7f); |
338 | bt819_write(client, 0x19, 0x72); | 291 | bt819_write(client, 0x19, 0x72); |
339 | //bt819_setbit(client, 0x1a, 5, 0); | 292 | /* bt819_setbit(client, 0x1a, 5, 0); */ |
340 | timing = &timing_data[VIDEO_MODE_PAL]; | 293 | timing = &timing_data[VIDEO_MODE_PAL]; |
341 | break; | 294 | break; |
342 | case VIDEO_MODE_AUTO: | 295 | case VIDEO_MODE_AUTO: |
@@ -344,10 +297,7 @@ bt819_command (struct i2c_client *client, | |||
344 | bt819_setbit(client, 0x01, 1, 0); | 297 | bt819_setbit(client, 0x01, 1, 0); |
345 | break; | 298 | break; |
346 | default: | 299 | default: |
347 | dprintk(1, | 300 | v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg); |
348 | KERN_ERR | ||
349 | "%s: unsupported norm %d\n", | ||
350 | I2C_NAME(client), *iarg); | ||
351 | return -EINVAL; | 301 | return -EINVAL; |
352 | } | 302 | } |
353 | 303 | ||
@@ -366,19 +316,17 @@ bt819_command (struct i2c_client *client, | |||
366 | } | 316 | } |
367 | 317 | ||
368 | decoder->norm = *iarg; | 318 | decoder->norm = *iarg; |
369 | } | ||
370 | break; | 319 | break; |
320 | } | ||
371 | 321 | ||
372 | case DECODER_SET_INPUT: | 322 | case DECODER_SET_INPUT: |
373 | { | 323 | { |
374 | int *iarg = arg; | 324 | int *iarg = arg; |
375 | 325 | ||
376 | dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client), | 326 | v4l_dbg(1, debug, client, "set input %x\n", *iarg); |
377 | *iarg); | ||
378 | 327 | ||
379 | if (*iarg < 0 || *iarg > 7) { | 328 | if (*iarg < 0 || *iarg > 7) |
380 | return -EINVAL; | 329 | return -EINVAL; |
381 | } | ||
382 | 330 | ||
383 | if (decoder->input != *iarg) { | 331 | if (decoder->input != *iarg) { |
384 | decoder->input = *iarg; | 332 | decoder->input = *iarg; |
@@ -391,52 +339,42 @@ bt819_command (struct i2c_client *client, | |||
391 | bt819_setbit(client, 0x1a, 1, 0); | 339 | bt819_setbit(client, 0x1a, 1, 0); |
392 | } | 340 | } |
393 | } | 341 | } |
394 | } | ||
395 | break; | 342 | break; |
343 | } | ||
396 | 344 | ||
397 | case DECODER_SET_OUTPUT: | 345 | case DECODER_SET_OUTPUT: |
398 | { | 346 | { |
399 | int *iarg = arg; | 347 | int *iarg = arg; |
400 | 348 | ||
401 | dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client), | 349 | v4l_dbg(1, debug, client, "set output %x\n", *iarg); |
402 | *iarg); | ||
403 | 350 | ||
404 | /* not much choice of outputs */ | 351 | /* not much choice of outputs */ |
405 | if (*iarg != 0) { | 352 | if (*iarg != 0) |
406 | return -EINVAL; | 353 | return -EINVAL; |
407 | } | ||
408 | } | ||
409 | break; | 354 | break; |
355 | } | ||
410 | 356 | ||
411 | case DECODER_ENABLE_OUTPUT: | 357 | case DECODER_ENABLE_OUTPUT: |
412 | { | 358 | { |
413 | int *iarg = arg; | 359 | int *iarg = arg; |
414 | int enable = (*iarg != 0); | 360 | int enable = (*iarg != 0); |
415 | 361 | ||
416 | dprintk(1, KERN_INFO "%s: enable output %x\n", | 362 | v4l_dbg(1, debug, client, "enable output %x\n", *iarg); |
417 | I2C_NAME(client), *iarg); | ||
418 | 363 | ||
419 | if (decoder->enable != enable) { | 364 | if (decoder->enable != enable) { |
420 | decoder->enable = enable; | 365 | decoder->enable = enable; |
421 | 366 | bt819_setbit(client, 0x16, 7, !enable); | |
422 | if (decoder->enable) { | ||
423 | bt819_setbit(client, 0x16, 7, 0); | ||
424 | } else { | ||
425 | bt819_setbit(client, 0x16, 7, 1); | ||
426 | } | ||
427 | } | 367 | } |
428 | } | ||
429 | break; | 368 | break; |
369 | } | ||
430 | 370 | ||
431 | case DECODER_SET_PICTURE: | 371 | case DECODER_SET_PICTURE: |
432 | { | 372 | { |
433 | struct video_picture *pic = arg; | 373 | struct video_picture *pic = arg; |
434 | 374 | ||
435 | dprintk(1, | 375 | v4l_dbg(1, debug, client, |
436 | KERN_INFO | 376 | "set picture brightness %d contrast %d colour %d\n", |
437 | "%s: set picture brightness %d contrast %d colour %d\n", | 377 | pic->brightness, pic->contrast, pic->colour); |
438 | I2C_NAME(client), pic->brightness, pic->contrast, | ||
439 | pic->colour); | ||
440 | 378 | ||
441 | 379 | ||
442 | if (decoder->bright != pic->brightness) { | 380 | if (decoder->bright != pic->brightness) { |
@@ -474,8 +412,8 @@ bt819_command (struct i2c_client *client, | |||
474 | bt819_write(client, 0x0f, | 412 | bt819_write(client, 0x0f, |
475 | 128 - (decoder->hue >> 8)); | 413 | 128 - (decoder->hue >> 8)); |
476 | } | 414 | } |
477 | } | ||
478 | break; | 415 | break; |
416 | } | ||
479 | 417 | ||
480 | default: | 418 | default: |
481 | return -EINVAL; | 419 | return -EINVAL; |
@@ -486,55 +424,44 @@ bt819_command (struct i2c_client *client, | |||
486 | 424 | ||
487 | /* ----------------------------------------------------------------------- */ | 425 | /* ----------------------------------------------------------------------- */ |
488 | 426 | ||
489 | /* | 427 | static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END }; |
490 | * Generic i2c probe | ||
491 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
492 | */ | ||
493 | static unsigned short normal_i2c[] = { | ||
494 | I2C_BT819 >> 1, | ||
495 | I2C_CLIENT_END, | ||
496 | }; | ||
497 | |||
498 | static unsigned short ignore = I2C_CLIENT_END; | ||
499 | |||
500 | static struct i2c_client_address_data addr_data = { | ||
501 | .normal_i2c = normal_i2c, | ||
502 | .probe = &ignore, | ||
503 | .ignore = &ignore, | ||
504 | }; | ||
505 | 428 | ||
506 | static struct i2c_driver i2c_driver_bt819; | 429 | I2C_CLIENT_INSMOD; |
507 | 430 | ||
508 | static int | 431 | static int bt819_probe(struct i2c_client *client, |
509 | bt819_detect_client (struct i2c_adapter *adapter, | 432 | const struct i2c_device_id *id) |
510 | int address, | ||
511 | int kind) | ||
512 | { | 433 | { |
513 | int i, id; | 434 | int i, ver; |
514 | struct bt819 *decoder; | 435 | struct bt819 *decoder; |
515 | struct i2c_client *client; | 436 | const char *name; |
516 | |||
517 | dprintk(1, | ||
518 | KERN_INFO | ||
519 | "bt819: detecting bt819 client on address 0x%x\n", | ||
520 | address << 1); | ||
521 | 437 | ||
522 | /* Check if the adapter supports the needed features */ | 438 | /* Check if the adapter supports the needed features */ |
523 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 439 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
524 | return 0; | 440 | return -ENODEV; |
525 | 441 | ||
526 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 442 | ver = bt819_read(client, 0x17); |
527 | if (!client) | 443 | switch (ver & 0xf0) { |
528 | return -ENOMEM; | 444 | case 0x70: |
529 | client->addr = address; | 445 | name = "bt819a"; |
530 | client->adapter = adapter; | 446 | break; |
531 | client->driver = &i2c_driver_bt819; | 447 | case 0x60: |
448 | name = "bt817a"; | ||
449 | break; | ||
450 | case 0x20: | ||
451 | name = "bt815a"; | ||
452 | break; | ||
453 | default: | ||
454 | v4l_dbg(1, debug, client, | ||
455 | "unknown chip version 0x%02x\n", ver); | ||
456 | return -ENODEV; | ||
457 | } | ||
458 | |||
459 | v4l_info(client, "%s found @ 0x%x (%s)\n", name, | ||
460 | client->addr << 1, client->adapter->name); | ||
532 | 461 | ||
533 | decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); | 462 | decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); |
534 | if (decoder == NULL) { | 463 | if (decoder == NULL) |
535 | kfree(client); | ||
536 | return -ENOMEM; | 464 | return -ENOMEM; |
537 | } | ||
538 | decoder->norm = VIDEO_MODE_NTSC; | 465 | decoder->norm = VIDEO_MODE_NTSC; |
539 | decoder->input = 0; | 466 | decoder->input = 0; |
540 | decoder->enable = 1; | 467 | decoder->enable = 1; |
@@ -545,97 +472,33 @@ bt819_detect_client (struct i2c_adapter *adapter, | |||
545 | decoder->initialized = 0; | 472 | decoder->initialized = 0; |
546 | i2c_set_clientdata(client, decoder); | 473 | i2c_set_clientdata(client, decoder); |
547 | 474 | ||
548 | id = bt819_read(client, 0x17); | ||
549 | switch (id & 0xf0) { | ||
550 | case 0x70: | ||
551 | strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client))); | ||
552 | break; | ||
553 | case 0x60: | ||
554 | strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client))); | ||
555 | break; | ||
556 | case 0x20: | ||
557 | strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client))); | ||
558 | break; | ||
559 | default: | ||
560 | dprintk(1, | ||
561 | KERN_ERR | ||
562 | "bt819: unknown chip version 0x%x (ver 0x%x)\n", | ||
563 | id & 0xf0, id & 0x0f); | ||
564 | kfree(decoder); | ||
565 | kfree(client); | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | i = i2c_attach_client(client); | ||
570 | if (i) { | ||
571 | kfree(client); | ||
572 | kfree(decoder); | ||
573 | return i; | ||
574 | } | ||
575 | |||
576 | i = bt819_init(client); | 475 | i = bt819_init(client); |
577 | if (i < 0) { | 476 | if (i < 0) |
578 | dprintk(1, KERN_ERR "%s_attach: init status %d\n", | 477 | v4l_dbg(1, debug, client, "init status %d\n", i); |
579 | I2C_NAME(client), i); | ||
580 | } else { | ||
581 | dprintk(1, | ||
582 | KERN_INFO | ||
583 | "%s_attach: chip version 0x%x at address 0x%x\n", | ||
584 | I2C_NAME(client), id & 0x0f, | ||
585 | client->addr << 1); | ||
586 | } | ||
587 | |||
588 | return 0; | 478 | return 0; |
589 | } | 479 | } |
590 | 480 | ||
591 | static int | 481 | static int bt819_remove(struct i2c_client *client) |
592 | bt819_attach_adapter (struct i2c_adapter *adapter) | ||
593 | { | ||
594 | return i2c_probe(adapter, &addr_data, &bt819_detect_client); | ||
595 | } | ||
596 | |||
597 | static int | ||
598 | bt819_detach_client (struct i2c_client *client) | ||
599 | { | 482 | { |
600 | struct bt819 *decoder = i2c_get_clientdata(client); | 483 | kfree(i2c_get_clientdata(client)); |
601 | int err; | ||
602 | |||
603 | err = i2c_detach_client(client); | ||
604 | if (err) { | ||
605 | return err; | ||
606 | } | ||
607 | |||
608 | kfree(decoder); | ||
609 | kfree(client); | ||
610 | |||
611 | return 0; | 484 | return 0; |
612 | } | 485 | } |
613 | 486 | ||
614 | /* ----------------------------------------------------------------------- */ | 487 | /* ----------------------------------------------------------------------- */ |
615 | 488 | ||
616 | static struct i2c_driver i2c_driver_bt819 = { | 489 | static const struct i2c_device_id bt819_id[] = { |
617 | .driver = { | 490 | { "bt819a", 0 }, |
618 | .name = "bt819", | 491 | { "bt817a", 0 }, |
619 | }, | 492 | { "bt815a", 0 }, |
620 | 493 | { } | |
621 | .id = I2C_DRIVERID_BT819, | 494 | }; |
495 | MODULE_DEVICE_TABLE(i2c, bt819_id); | ||
622 | 496 | ||
623 | .attach_adapter = bt819_attach_adapter, | 497 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
624 | .detach_client = bt819_detach_client, | 498 | .name = "bt819", |
499 | .driverid = I2C_DRIVERID_BT819, | ||
625 | .command = bt819_command, | 500 | .command = bt819_command, |
501 | .probe = bt819_probe, | ||
502 | .remove = bt819_remove, | ||
503 | .id_table = bt819_id, | ||
626 | }; | 504 | }; |
627 | |||
628 | static int __init | ||
629 | bt819_init_module (void) | ||
630 | { | ||
631 | return i2c_add_driver(&i2c_driver_bt819); | ||
632 | } | ||
633 | |||
634 | static void __exit | ||
635 | bt819_exit (void) | ||
636 | { | ||
637 | i2c_del_driver(&i2c_driver_bt819); | ||
638 | } | ||
639 | |||
640 | module_init(bt819_init_module); | ||
641 | module_exit(bt819_exit); | ||