diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-09-07 07:00:14 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-17 16:17:40 -0400 |
commit | 9875c0fb32246f97a9f40bdfe027544b8827f156 (patch) | |
tree | c176f9d0c92e7b7e61b68472643297773ced23cc /drivers/media | |
parent | c18fdcf65732b87f6015ea4e423fc7abf7c26dd2 (diff) |
V4L/DVB (9203): ks0127: convert i2c driver for new i2c API
- Convert to use v4l2-i2c-drv-legacy.h to be able to handle the new i2c API
- Cleanups
- Use v4l_dbg/v4l_info to have uniform kernel messages
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/ks0127.c | 476 |
1 files changed, 212 insertions, 264 deletions
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c index 2fd4b4a44aa9..bae2d2beb709 100644 --- a/drivers/media/video/ks0127.c +++ b/drivers/media/video/ks0127.c | |||
@@ -33,27 +33,20 @@ | |||
33 | * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard | 33 | * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #ifndef __KERNEL__ | ||
37 | #define __KERNEL__ | ||
38 | #endif | ||
39 | |||
40 | #include <linux/init.h> | 36 | #include <linux/init.h> |
41 | #include <linux/module.h> | 37 | #include <linux/module.h> |
42 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
43 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
44 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
45 | #include <linux/slab.h> | ||
46 | #include <linux/proc_fs.h> | ||
47 | #include "ks0127.h" | ||
48 | |||
49 | #include <linux/i2c.h> | 41 | #include <linux/i2c.h> |
50 | #include <linux/video_decoder.h> | 42 | #include <linux/video_decoder.h> |
43 | #include <media/v4l2-common.h> | ||
44 | #include <media/v4l2-i2c-drv-legacy.h> | ||
45 | #include "ks0127.h" | ||
51 | 46 | ||
52 | #define dprintk if (debug) printk | 47 | MODULE_DESCRIPTION("KS0127 video decoder driver"); |
53 | 48 | MODULE_AUTHOR("Ryan Drake"); | |
54 | /* i2c identification */ | 49 | MODULE_LICENSE("GPL"); |
55 | #define I2C_KS0127_ADDON 0xD8 | ||
56 | #define I2C_KS0127_ONBOARD 0xDA | ||
57 | 50 | ||
58 | #define KS_TYPE_UNKNOWN 0 | 51 | #define KS_TYPE_UNKNOWN 0 |
59 | #define KS_TYPE_0122S 1 | 52 | #define KS_TYPE_0122S 1 |
@@ -204,8 +197,6 @@ struct adjust { | |||
204 | }; | 197 | }; |
205 | 198 | ||
206 | struct ks0127 { | 199 | struct ks0127 { |
207 | struct i2c_client *client; | ||
208 | unsigned char addr; | ||
209 | int format_width; | 200 | int format_width; |
210 | int format_height; | 201 | int format_height; |
211 | int cap_width; | 202 | int cap_width; |
@@ -220,16 +211,18 @@ static int debug; /* insmod parameter */ | |||
220 | 211 | ||
221 | module_param(debug, int, 0); | 212 | module_param(debug, int, 0); |
222 | MODULE_PARM_DESC(debug, "Debug output"); | 213 | MODULE_PARM_DESC(debug, "Debug output"); |
223 | MODULE_LICENSE("GPL"); | ||
224 | 214 | ||
225 | static u8 reg_defaults[64]; | 215 | static u8 reg_defaults[64]; |
226 | 216 | ||
227 | |||
228 | |||
229 | static void init_reg_defaults(void) | 217 | static void init_reg_defaults(void) |
230 | { | 218 | { |
219 | static int initialized; | ||
231 | u8 *table = reg_defaults; | 220 | u8 *table = reg_defaults; |
232 | 221 | ||
222 | if (initialized) | ||
223 | return; | ||
224 | initialized = 1; | ||
225 | |||
233 | table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */ | 226 | table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */ |
234 | table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */ | 227 | table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */ |
235 | table[KS_CMDC] = 0x00; /* Test options */ | 228 | table[KS_CMDC] = 0x00; /* Test options */ |
@@ -308,50 +301,53 @@ static void init_reg_defaults(void) | |||
308 | * An explanation from kayork@mail.utexas.edu: | 301 | * An explanation from kayork@mail.utexas.edu: |
309 | * | 302 | * |
310 | * During I2C reads, the KS0127 only samples for a stop condition | 303 | * During I2C reads, the KS0127 only samples for a stop condition |
311 | * during the place where the acknoledge bit should be. Any standard | 304 | * during the place where the acknowledge bit should be. Any standard |
312 | * I2C implementation (correctly) throws in another clock transition | 305 | * I2C implementation (correctly) throws in another clock transition |
313 | * at the 9th bit, and the KS0127 will not recognize the stop condition | 306 | * at the 9th bit, and the KS0127 will not recognize the stop condition |
314 | * and will continue to clock out data. | 307 | * and will continue to clock out data. |
315 | * | 308 | * |
316 | * So we have to do the read ourself. Big deal. | 309 | * So we have to do the read ourself. Big deal. |
317 | workaround in i2c-algo-bit | 310 | * workaround in i2c-algo-bit |
318 | */ | 311 | */ |
319 | 312 | ||
320 | 313 | ||
321 | static u8 ks0127_read(struct ks0127 *ks, u8 reg) | 314 | static u8 ks0127_read(struct i2c_client *c, u8 reg) |
322 | { | 315 | { |
323 | struct i2c_client *c = ks->client; | ||
324 | char val = 0; | 316 | char val = 0; |
325 | struct i2c_msg msgs[] = { | 317 | struct i2c_msg msgs[] = { |
326 | {c->addr, 0, sizeof(reg), ®}, | 318 | { c->addr, 0, sizeof(reg), ® }, |
327 | {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}}; | 319 | { c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val } |
320 | }; | ||
328 | int ret; | 321 | int ret; |
329 | 322 | ||
330 | ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs)); | 323 | ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs)); |
331 | if (ret != ARRAY_SIZE(msgs)) | 324 | if (ret != ARRAY_SIZE(msgs)) |
332 | dprintk("ks0127_write error\n"); | 325 | v4l_dbg(1, debug, c, "read error\n"); |
333 | 326 | ||
334 | return val; | 327 | return val; |
335 | } | 328 | } |
336 | 329 | ||
337 | 330 | ||
338 | static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val) | 331 | static void ks0127_write(struct i2c_client *c, u8 reg, u8 val) |
339 | { | 332 | { |
340 | char msg[] = {reg, val}; | 333 | struct ks0127 *ks = i2c_get_clientdata(c); |
334 | char msg[] = { reg, val }; | ||
341 | 335 | ||
342 | if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg)) | 336 | if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg)) |
343 | dprintk("ks0127_write error\n"); | 337 | v4l_dbg(1, debug, c, "write error\n"); |
344 | 338 | ||
345 | ks->regs[reg] = val; | 339 | ks->regs[reg] = val; |
346 | } | 340 | } |
347 | 341 | ||
348 | 342 | ||
349 | /* generic bit-twiddling */ | 343 | /* generic bit-twiddling */ |
350 | static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v) | 344 | static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v) |
351 | { | 345 | { |
346 | struct ks0127 *ks = i2c_get_clientdata(client); | ||
347 | |||
352 | u8 val = ks->regs[reg]; | 348 | u8 val = ks->regs[reg]; |
353 | val = (val & and_v) | or_v; | 349 | val = (val & and_v) | or_v; |
354 | ks0127_write(ks, reg, val); | 350 | ks0127_write(client, reg, val); |
355 | } | 351 | } |
356 | 352 | ||
357 | 353 | ||
@@ -359,73 +355,69 @@ static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v) | |||
359 | /**************************************************************************** | 355 | /**************************************************************************** |
360 | * ks0127 private api | 356 | * ks0127 private api |
361 | ****************************************************************************/ | 357 | ****************************************************************************/ |
362 | static void ks0127_reset(struct ks0127* ks) | 358 | static void ks0127_reset(struct i2c_client *c) |
363 | { | 359 | { |
364 | int i; | 360 | struct ks0127 *ks = i2c_get_clientdata(c); |
365 | u8 *table = reg_defaults; | 361 | u8 *table = reg_defaults; |
362 | int i; | ||
366 | 363 | ||
367 | ks->ks_type = KS_TYPE_UNKNOWN; | 364 | ks->ks_type = KS_TYPE_UNKNOWN; |
368 | 365 | ||
369 | dprintk("ks0127: reset\n"); | 366 | v4l_dbg(1, debug, c, "reset\n"); |
370 | msleep(1); | 367 | msleep(1); |
371 | 368 | ||
372 | /* initialize all registers to known values */ | 369 | /* initialize all registers to known values */ |
373 | /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */ | 370 | /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */ |
374 | 371 | ||
375 | for(i = 1; i < 33; i++) | 372 | for (i = 1; i < 33; i++) |
376 | ks0127_write(ks, i, table[i]); | 373 | ks0127_write(c, i, table[i]); |
377 | 374 | ||
378 | for(i = 35; i < 40; i++) | 375 | for (i = 35; i < 40; i++) |
379 | ks0127_write(ks, i, table[i]); | 376 | ks0127_write(c, i, table[i]); |
380 | 377 | ||
381 | for(i = 41; i < 56; i++) | 378 | for (i = 41; i < 56; i++) |
382 | ks0127_write(ks, i, table[i]); | 379 | ks0127_write(c, i, table[i]); |
383 | 380 | ||
384 | for(i = 58; i < 64; i++) | 381 | for (i = 58; i < 64; i++) |
385 | ks0127_write(ks, i, table[i]); | 382 | ks0127_write(c, i, table[i]); |
386 | 383 | ||
387 | 384 | ||
388 | if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) { | 385 | if ((ks0127_read(c, KS_STAT) & 0x80) == 0) { |
389 | ks->ks_type = KS_TYPE_0122S; | 386 | ks->ks_type = KS_TYPE_0122S; |
390 | dprintk("ks0127: ks0122s Found\n"); | 387 | v4l_dbg(1, debug, c, "ks0122s found\n"); |
391 | return; | 388 | return; |
392 | } | 389 | } |
393 | 390 | ||
394 | switch(ks0127_read(ks, KS_CMDE) & 0x0f) { | 391 | switch (ks0127_read(c, KS_CMDE) & 0x0f) { |
395 | |||
396 | case 0: | 392 | case 0: |
397 | ks->ks_type = KS_TYPE_0127; | 393 | ks->ks_type = KS_TYPE_0127; |
398 | dprintk("ks0127: ks0127 found\n"); | 394 | v4l_dbg(1, debug, c, "ks0127 found\n"); |
399 | break; | 395 | break; |
400 | 396 | ||
401 | case 9: | 397 | case 9: |
402 | ks->ks_type = KS_TYPE_0127B; | 398 | ks->ks_type = KS_TYPE_0127B; |
403 | dprintk("ks0127: ks0127B Revision A found\n"); | 399 | v4l_dbg(1, debug, c, "ks0127B Revision A found\n"); |
404 | break; | 400 | break; |
405 | 401 | ||
406 | default: | 402 | default: |
407 | dprintk("ks0127: unknown revision\n"); | 403 | v4l_dbg(1, debug, c, "unknown revision\n"); |
408 | break; | 404 | break; |
409 | } | 405 | } |
410 | } | 406 | } |
411 | 407 | ||
412 | static int ks0127_command(struct i2c_client *client, | 408 | static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) |
413 | unsigned int cmd, void *arg) | ||
414 | { | 409 | { |
415 | struct ks0127 *ks = i2c_get_clientdata(client); | 410 | struct ks0127 *ks = i2c_get_clientdata(c); |
416 | 411 | int *iarg = (int *)arg; | |
417 | int *iarg = (int*)arg; | ||
418 | |||
419 | int status; | 412 | int status; |
420 | 413 | ||
421 | if (!ks) | 414 | if (!ks) |
422 | return -ENODEV; | 415 | return -ENODEV; |
423 | 416 | ||
424 | switch (cmd) { | 417 | switch (cmd) { |
425 | |||
426 | case DECODER_INIT: | 418 | case DECODER_INIT: |
427 | dprintk("ks0127: command DECODER_INIT\n"); | 419 | v4l_dbg(1, debug, c, "DECODER_INIT\n"); |
428 | ks0127_reset(ks); | 420 | ks0127_reset(c); |
429 | break; | 421 | break; |
430 | 422 | ||
431 | case DECODER_SET_INPUT: | 423 | case DECODER_SET_INPUT: |
@@ -436,161 +428,160 @@ static int ks0127_command(struct i2c_client *client, | |||
436 | case KS_INPUT_COMPOSITE_4: | 428 | case KS_INPUT_COMPOSITE_4: |
437 | case KS_INPUT_COMPOSITE_5: | 429 | case KS_INPUT_COMPOSITE_5: |
438 | case KS_INPUT_COMPOSITE_6: | 430 | case KS_INPUT_COMPOSITE_6: |
439 | dprintk("ks0127: command DECODER_SET_INPUT %d: " | 431 | v4l_dbg(1, debug, c, |
440 | "Composite\n", *iarg); | 432 | "DECODER_SET_INPUT %d: Composite\n", *iarg); |
441 | /* autodetect 50/60 Hz */ | 433 | /* autodetect 50/60 Hz */ |
442 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); | 434 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); |
443 | /* VSE=0 */ | 435 | /* VSE=0 */ |
444 | ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); | 436 | ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); |
445 | /* set input line */ | 437 | /* set input line */ |
446 | ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); | 438 | ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); |
447 | /* non-freerunning mode */ | 439 | /* non-freerunning mode */ |
448 | ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); | 440 | ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); |
449 | /* analog input */ | 441 | /* analog input */ |
450 | ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); | 442 | ks0127_and_or(c, KS_CMDD, 0x03, 0x00); |
451 | /* enable chroma demodulation */ | 443 | /* enable chroma demodulation */ |
452 | ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); | 444 | ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); |
453 | /* chroma trap, HYBWR=1 */ | 445 | /* chroma trap, HYBWR=1 */ |
454 | ks0127_and_or(ks, KS_LUMA, 0x00, | 446 | ks0127_and_or(c, KS_LUMA, 0x00, |
455 | (reg_defaults[KS_LUMA])|0x0c); | 447 | (reg_defaults[KS_LUMA])|0x0c); |
456 | /* scaler fullbw, luma comb off */ | 448 | /* scaler fullbw, luma comb off */ |
457 | ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); | 449 | ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); |
458 | /* manual chroma comb .25 .5 .25 */ | 450 | /* manual chroma comb .25 .5 .25 */ |
459 | ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90); | 451 | ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90); |
460 | 452 | ||
461 | /* chroma path delay */ | 453 | /* chroma path delay */ |
462 | ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90); | 454 | ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90); |
463 | 455 | ||
464 | ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); | 456 | ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); |
465 | ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); | 457 | ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); |
466 | ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); | 458 | ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); |
467 | ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); | 459 | ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); |
468 | break; | 460 | break; |
469 | 461 | ||
470 | case KS_INPUT_SVIDEO_1: | 462 | case KS_INPUT_SVIDEO_1: |
471 | case KS_INPUT_SVIDEO_2: | 463 | case KS_INPUT_SVIDEO_2: |
472 | case KS_INPUT_SVIDEO_3: | 464 | case KS_INPUT_SVIDEO_3: |
473 | dprintk("ks0127: command DECODER_SET_INPUT %d: " | 465 | v4l_dbg(1, debug, c, |
474 | "S-Video\n", *iarg); | 466 | "DECODER_SET_INPUT %d: S-Video\n", *iarg); |
475 | /* autodetect 50/60 Hz */ | 467 | /* autodetect 50/60 Hz */ |
476 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); | 468 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); |
477 | /* VSE=0 */ | 469 | /* VSE=0 */ |
478 | ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00); | 470 | ks0127_and_or(c, KS_CMDA, ~0x40, 0x00); |
479 | /* set input line */ | 471 | /* set input line */ |
480 | ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg); | 472 | ks0127_and_or(c, KS_CMDB, 0xb0, *iarg); |
481 | /* non-freerunning mode */ | 473 | /* non-freerunning mode */ |
482 | ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a); | 474 | ks0127_and_or(c, KS_CMDC, 0x70, 0x0a); |
483 | /* analog input */ | 475 | /* analog input */ |
484 | ks0127_and_or(ks, KS_CMDD, 0x03, 0x00); | 476 | ks0127_and_or(c, KS_CMDD, 0x03, 0x00); |
485 | /* enable chroma demodulation */ | 477 | /* enable chroma demodulation */ |
486 | ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00); | 478 | ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00); |
487 | ks0127_and_or(ks, KS_LUMA, 0x00, | 479 | ks0127_and_or(c, KS_LUMA, 0x00, |
488 | reg_defaults[KS_LUMA]); | 480 | reg_defaults[KS_LUMA]); |
489 | /* disable luma comb */ | 481 | /* disable luma comb */ |
490 | ks0127_and_or(ks, KS_VERTIA, 0x08, | 482 | ks0127_and_or(c, KS_VERTIA, 0x08, |
491 | (reg_defaults[KS_VERTIA]&0xf0)|0x01); | 483 | (reg_defaults[KS_VERTIA]&0xf0)|0x01); |
492 | ks0127_and_or(ks, KS_VERTIC, 0x0f, | 484 | ks0127_and_or(c, KS_VERTIC, 0x0f, |
493 | reg_defaults[KS_VERTIC]&0xf0); | 485 | reg_defaults[KS_VERTIC]&0xf0); |
494 | 486 | ||
495 | ks0127_and_or(ks, KS_CHROMB, 0x0f, | 487 | ks0127_and_or(c, KS_CHROMB, 0x0f, |
496 | reg_defaults[KS_CHROMB]&0xf0); | 488 | reg_defaults[KS_CHROMB]&0xf0); |
497 | 489 | ||
498 | ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]); | 490 | ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]); |
499 | ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]); | 491 | ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]); |
500 | ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]); | 492 | ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]); |
501 | ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]); | 493 | ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]); |
502 | break; | 494 | break; |
503 | 495 | ||
504 | case KS_INPUT_YUV656: | 496 | case KS_INPUT_YUV656: |
505 | dprintk("ks0127: command DECODER_SET_INPUT 15: " | 497 | v4l_dbg(1, debug, c, |
506 | "YUV656\n"); | 498 | "DECODER_SET_INPUT 15: YUV656\n"); |
507 | if (ks->norm == VIDEO_MODE_NTSC || | 499 | if (ks->norm == VIDEO_MODE_NTSC || |
508 | ks->norm == KS_STD_PAL_M) | 500 | ks->norm == KS_STD_PAL_M) |
509 | /* force 60 Hz */ | 501 | /* force 60 Hz */ |
510 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03); | 502 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x03); |
511 | else | 503 | else |
512 | /* force 50 Hz */ | 504 | /* force 50 Hz */ |
513 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02); | 505 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x02); |
514 | 506 | ||
515 | ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */ | 507 | ks0127_and_or(c, KS_CMDA, 0xff, 0x40); /* VSE=1 */ |
516 | /* set input line and VALIGN */ | 508 | /* set input line and VALIGN */ |
517 | ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40)); | 509 | ks0127_and_or(c, KS_CMDB, 0xb0, (*iarg | 0x40)); |
518 | /* freerunning mode, */ | 510 | /* freerunning mode, */ |
519 | /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ | 511 | /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/ |
520 | ks0127_and_or(ks, KS_CMDC, 0x70, 0x87); | 512 | ks0127_and_or(c, KS_CMDC, 0x70, 0x87); |
521 | /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ | 513 | /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */ |
522 | ks0127_and_or(ks, KS_CMDD, 0x03, 0x08); | 514 | ks0127_and_or(c, KS_CMDD, 0x03, 0x08); |
523 | /* disable chroma demodulation */ | 515 | /* disable chroma demodulation */ |
524 | ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30); | 516 | ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30); |
525 | /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ | 517 | /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */ |
526 | ks0127_and_or(ks, KS_LUMA, 0x00, 0x71); | 518 | ks0127_and_or(c, KS_LUMA, 0x00, 0x71); |
527 | ks0127_and_or(ks, KS_VERTIC, 0x0f, | 519 | ks0127_and_or(c, KS_VERTIC, 0x0f, |
528 | reg_defaults[KS_VERTIC]&0xf0); | 520 | reg_defaults[KS_VERTIC]&0xf0); |
529 | 521 | ||
530 | /* scaler fullbw, luma comb off */ | 522 | /* scaler fullbw, luma comb off */ |
531 | ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81); | 523 | ks0127_and_or(c, KS_VERTIA, 0x08, 0x81); |
532 | 524 | ||
533 | ks0127_and_or(ks, KS_CHROMB, 0x0f, | 525 | ks0127_and_or(c, KS_CHROMB, 0x0f, |
534 | reg_defaults[KS_CHROMB]&0xf0); | 526 | reg_defaults[KS_CHROMB]&0xf0); |
535 | 527 | ||
536 | ks0127_and_or(ks, KS_CON, 0x00, 0x00); | 528 | ks0127_and_or(c, KS_CON, 0x00, 0x00); |
537 | ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */ | 529 | ks0127_and_or(c, KS_BRT, 0x00, 32); /* spec: 34 */ |
538 | /* spec: 229 (e5) */ | 530 | /* spec: 229 (e5) */ |
539 | ks0127_and_or(ks, KS_SAT, 0x00, 0xe8); | 531 | ks0127_and_or(c, KS_SAT, 0x00, 0xe8); |
540 | ks0127_and_or(ks, KS_HUE, 0x00, 0); | 532 | ks0127_and_or(c, KS_HUE, 0x00, 0); |
541 | 533 | ||
542 | ks0127_and_or(ks, KS_UGAIN, 0x00, 238); | 534 | ks0127_and_or(c, KS_UGAIN, 0x00, 238); |
543 | ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00); | 535 | ks0127_and_or(c, KS_VGAIN, 0x00, 0x00); |
544 | 536 | ||
545 | /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ | 537 | /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */ |
546 | ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f); | 538 | ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f); |
547 | ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00); | 539 | ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00); |
548 | break; | 540 | break; |
549 | 541 | ||
550 | default: | 542 | default: |
551 | dprintk("ks0127: command DECODER_SET_INPUT: " | 543 | v4l_dbg(1, debug, c, |
552 | "Unknown input %d\n", *iarg); | 544 | "DECODER_SET_INPUT: Unknown input %d\n", *iarg); |
553 | break; | 545 | break; |
554 | } | 546 | } |
555 | 547 | ||
556 | /* hack: CDMLPF sometimes spontaneously switches on; */ | 548 | /* hack: CDMLPF sometimes spontaneously switches on; */ |
557 | /* force back off */ | 549 | /* force back off */ |
558 | ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]); | 550 | ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]); |
559 | break; | 551 | break; |
560 | 552 | ||
561 | case DECODER_SET_OUTPUT: | 553 | case DECODER_SET_OUTPUT: |
562 | switch(*iarg) { | 554 | switch(*iarg) { |
563 | case KS_OUTPUT_YUV656E: | 555 | case KS_OUTPUT_YUV656E: |
564 | dprintk("ks0127: command DECODER_SET_OUTPUT: " | 556 | v4l_dbg(1, debug, c, |
565 | "OUTPUT_YUV656E (Missing)\n"); | 557 | "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n"); |
566 | return -EINVAL; | 558 | return -EINVAL; |
567 | break; | ||
568 | 559 | ||
569 | case KS_OUTPUT_EXV: | 560 | case KS_OUTPUT_EXV: |
570 | dprintk("ks0127: command DECODER_SET_OUTPUT: " | 561 | v4l_dbg(1, debug, c, |
571 | "OUTPUT_EXV\n"); | 562 | "DECODER_SET_OUTPUT: OUTPUT_EXV\n"); |
572 | ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09); | 563 | ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09); |
573 | break; | 564 | break; |
574 | } | 565 | } |
575 | break; | 566 | break; |
576 | 567 | ||
577 | case DECODER_SET_NORM: //sam This block mixes old and new norm names... | 568 | case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */ |
578 | /* Set to automatic SECAM/Fsc mode */ | 569 | /* Set to automatic SECAM/Fsc mode */ |
579 | ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); | 570 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); |
580 | 571 | ||
581 | ks->norm = *iarg; | 572 | ks->norm = *iarg; |
582 | switch(*iarg) | 573 | switch (*iarg) { |
583 | { | ||
584 | /* this is untested !! */ | 574 | /* this is untested !! */ |
585 | /* It just detects PAL_N/NTSC_M (no special frequencies) */ | 575 | /* It just detects PAL_N/NTSC_M (no special frequencies) */ |
586 | /* And you have to set the standard a second time afterwards */ | 576 | /* And you have to set the standard a second time afterwards */ |
587 | case VIDEO_MODE_AUTO: | 577 | case VIDEO_MODE_AUTO: |
588 | dprintk("ks0127: command DECODER_SET_NORM: AUTO\n"); | 578 | v4l_dbg(1, debug, c, |
579 | "DECODER_SET_NORM: AUTO\n"); | ||
589 | 580 | ||
590 | /* The chip determines the format */ | 581 | /* The chip determines the format */ |
591 | /* based on the current field rate */ | 582 | /* based on the current field rate */ |
592 | ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00); | 583 | ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); |
593 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); | 584 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); |
594 | /* This is wrong for PAL ! As I said, */ | 585 | /* This is wrong for PAL ! As I said, */ |
595 | /* you need to set the standard once again !! */ | 586 | /* you need to set the standard once again !! */ |
596 | ks->format_height = 240; | 587 | ks->format_height = 240; |
@@ -598,84 +589,86 @@ static int ks0127_command(struct i2c_client *client, | |||
598 | break; | 589 | break; |
599 | 590 | ||
600 | case VIDEO_MODE_NTSC: | 591 | case VIDEO_MODE_NTSC: |
601 | dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n"); | 592 | v4l_dbg(1, debug, c, |
602 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); | 593 | "DECODER_SET_NORM: NTSC_M\n"); |
594 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); | ||
603 | ks->format_height = 240; | 595 | ks->format_height = 240; |
604 | ks->format_width = 704; | 596 | ks->format_width = 704; |
605 | break; | 597 | break; |
606 | 598 | ||
607 | case KS_STD_NTSC_N: | 599 | case KS_STD_NTSC_N: |
608 | dprintk("ks0127: command KS0127_SET_STANDARD: " | 600 | v4l_dbg(1, debug, c, |
609 | "NTSC_N (fixme)\n"); | 601 | "KS0127_SET_NORM: NTSC_N (fixme)\n"); |
610 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); | 602 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); |
611 | ks->format_height = 240; | 603 | ks->format_height = 240; |
612 | ks->format_width = 704; | 604 | ks->format_width = 704; |
613 | break; | 605 | break; |
614 | 606 | ||
615 | case VIDEO_MODE_PAL: | 607 | case VIDEO_MODE_PAL: |
616 | dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n"); | 608 | v4l_dbg(1, debug, c, |
617 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20); | 609 | "DECODER_SET_NORM: PAL_N\n"); |
610 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); | ||
618 | ks->format_height = 290; | 611 | ks->format_height = 290; |
619 | ks->format_width = 704; | 612 | ks->format_width = 704; |
620 | break; | 613 | break; |
621 | 614 | ||
622 | case KS_STD_PAL_M: | 615 | case KS_STD_PAL_M: |
623 | dprintk("ks0127: command KS0127_SET_STANDARD: " | 616 | v4l_dbg(1, debug, c, |
624 | "PAL_M (fixme)\n"); | 617 | "KS0127_SET_NORM: PAL_M (fixme)\n"); |
625 | ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40); | 618 | ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); |
626 | ks->format_height = 290; | 619 | ks->format_height = 290; |
627 | ks->format_width = 704; | 620 | ks->format_width = 704; |
628 | break; | 621 | break; |
629 | 622 | ||
630 | case VIDEO_MODE_SECAM: | 623 | case VIDEO_MODE_SECAM: |
631 | dprintk("ks0127: command KS0127_SET_STANDARD: " | 624 | v4l_dbg(1, debug, c, |
632 | "SECAM\n"); | 625 | "KS0127_SET_NORM: SECAM\n"); |
633 | ks->format_height = 290; | 626 | ks->format_height = 290; |
634 | ks->format_width = 704; | 627 | ks->format_width = 704; |
635 | 628 | ||
636 | /* set to secam autodetection */ | 629 | /* set to secam autodetection */ |
637 | ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20); | 630 | ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20); |
638 | ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00); | 631 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); |
639 | schedule_timeout_interruptible(HZ/10+1); | 632 | schedule_timeout_interruptible(HZ/10+1); |
640 | 633 | ||
641 | /* did it autodetect? */ | 634 | /* did it autodetect? */ |
642 | if (ks0127_read(ks, KS_DEMOD) & 0x40) | 635 | if (ks0127_read(c, KS_DEMOD) & 0x40) |
643 | break; | 636 | break; |
644 | 637 | ||
645 | /* force to secam mode */ | 638 | /* force to secam mode */ |
646 | ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f); | 639 | ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); |
647 | break; | 640 | break; |
648 | 641 | ||
649 | default: | 642 | default: |
650 | dprintk("ks0127: command DECODER_SET_NORM: " | 643 | v4l_dbg(1, debug, c, |
651 | "Unknown norm %d\n", *iarg); | 644 | "DECODER_SET_NORM: Unknown norm %d\n", *iarg); |
652 | break; | 645 | break; |
653 | } | 646 | } |
654 | break; | 647 | break; |
655 | 648 | ||
656 | case DECODER_SET_PICTURE: | 649 | case DECODER_SET_PICTURE: |
657 | dprintk("ks0127: command DECODER_SET_PICTURE " | 650 | v4l_dbg(1, debug, c, |
658 | "not yet supported (fixme)\n"); | 651 | "DECODER_SET_PICTURE: not yet supported\n"); |
659 | return -EINVAL; | 652 | return -EINVAL; |
660 | 653 | ||
661 | //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE | 654 | /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */ |
662 | //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE | 655 | /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */ |
663 | //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? | 656 | /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */ |
664 | //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE | 657 | /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */ |
665 | //sam todo: KS0127_SET_AGC_MODE: | 658 | /* sam todo: KS0127_SET_AGC_MODE: */ |
666 | //sam todo: KS0127_SET_AGC: | 659 | /* sam todo: KS0127_SET_AGC: */ |
667 | //sam todo: KS0127_SET_CHROMA_MODE: | 660 | /* sam todo: KS0127_SET_CHROMA_MODE: */ |
668 | //sam todo: KS0127_SET_PIXCLK_MODE: | 661 | /* sam todo: KS0127_SET_PIXCLK_MODE: */ |
669 | //sam todo: KS0127_SET_GAMMA_MODE: | 662 | /* sam todo: KS0127_SET_GAMMA_MODE: */ |
670 | //sam todo: KS0127_SET_UGAIN: | 663 | /* sam todo: KS0127_SET_UGAIN: */ |
671 | //sam todo: KS0127_SET_VGAIN: | 664 | /* sam todo: KS0127_SET_VGAIN: */ |
672 | //sam todo: KS0127_SET_INVALY: | 665 | /* sam todo: KS0127_SET_INVALY: */ |
673 | //sam todo: KS0127_SET_INVALU: | 666 | /* sam todo: KS0127_SET_INVALU: */ |
674 | //sam todo: KS0127_SET_INVALV: | 667 | /* sam todo: KS0127_SET_INVALV: */ |
675 | //sam todo: KS0127_SET_UNUSEY: | 668 | /* sam todo: KS0127_SET_UNUSEY: */ |
676 | //sam todo: KS0127_SET_UNUSEU: | 669 | /* sam todo: KS0127_SET_UNUSEU: */ |
677 | //sam todo: KS0127_SET_UNUSEV: | 670 | /* sam todo: KS0127_SET_UNUSEV: */ |
678 | //sam todo: KS0127_SET_VSALIGN_MODE: | 671 | /* sam todo: KS0127_SET_VSALIGN_MODE: */ |
679 | 672 | ||
680 | case DECODER_ENABLE_OUTPUT: | 673 | case DECODER_ENABLE_OUTPUT: |
681 | { | 674 | { |
@@ -684,34 +677,32 @@ static int ks0127_command(struct i2c_client *client, | |||
684 | iarg = arg; | 677 | iarg = arg; |
685 | enable = (*iarg != 0); | 678 | enable = (*iarg != 0); |
686 | if (enable) { | 679 | if (enable) { |
687 | dprintk("ks0127: command " | 680 | v4l_dbg(1, debug, c, |
688 | "DECODER_ENABLE_OUTPUT on " | 681 | "DECODER_ENABLE_OUTPUT on\n"); |
689 | "(%d)\n", enable); | ||
690 | /* All output pins on */ | 682 | /* All output pins on */ |
691 | ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30); | 683 | ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30); |
692 | /* Obey the OEN pin */ | 684 | /* Obey the OEN pin */ |
693 | ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00); | 685 | ks0127_and_or(c, KS_CDEM, 0x7f, 0x00); |
694 | } else { | 686 | } else { |
695 | dprintk("ks0127: command " | 687 | v4l_dbg(1, debug, c, |
696 | "DECODER_ENABLE_OUTPUT off " | 688 | "DECODER_ENABLE_OUTPUT off\n"); |
697 | "(%d)\n", enable); | ||
698 | /* Video output pins off */ | 689 | /* Video output pins off */ |
699 | ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00); | 690 | ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00); |
700 | /* Ignore the OEN pin */ | 691 | /* Ignore the OEN pin */ |
701 | ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80); | 692 | ks0127_and_or(c, KS_CDEM, 0x7f, 0x80); |
702 | } | 693 | } |
703 | } | ||
704 | break; | 694 | break; |
695 | } | ||
705 | 696 | ||
706 | //sam todo: KS0127_SET_OUTPUT_MODE: | 697 | /* sam todo: KS0127_SET_OUTPUT_MODE: */ |
707 | //sam todo: KS0127_SET_WIDTH: | 698 | /* sam todo: KS0127_SET_WIDTH: */ |
708 | //sam todo: KS0127_SET_HEIGHT: | 699 | /* sam todo: KS0127_SET_HEIGHT: */ |
709 | //sam todo: KS0127_SET_HSCALE: | 700 | /* sam todo: KS0127_SET_HSCALE: */ |
710 | 701 | ||
711 | case DECODER_GET_STATUS: | 702 | case DECODER_GET_STATUS: |
712 | dprintk("ks0127: command DECODER_GET_STATUS\n"); | 703 | v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n"); |
713 | *iarg = 0; | 704 | *iarg = 0; |
714 | status = ks0127_read(ks, KS_STAT); | 705 | status = ks0127_read(c, KS_STAT); |
715 | if (!(status & 0x20)) /* NOVID not set */ | 706 | if (!(status & 0x20)) /* NOVID not set */ |
716 | *iarg = (*iarg | DECODER_STATUS_GOOD); | 707 | *iarg = (*iarg | DECODER_STATUS_GOOD); |
717 | if ((status & 0x01)) /* CLOCK set */ | 708 | if ((status & 0x01)) /* CLOCK set */ |
@@ -722,124 +713,81 @@ static int ks0127_command(struct i2c_client *client, | |||
722 | *iarg = (*iarg | DECODER_STATUS_NTSC); | 713 | *iarg = (*iarg | DECODER_STATUS_NTSC); |
723 | break; | 714 | break; |
724 | 715 | ||
725 | //Catch any unknown command | 716 | /* Catch any unknown command */ |
726 | default: | 717 | default: |
727 | dprintk("ks0127: command unknown: %04X\n", cmd); | 718 | v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd); |
728 | return -EINVAL; | 719 | return -EINVAL; |
729 | } | 720 | } |
730 | return 0; | 721 | return 0; |
731 | } | 722 | } |
732 | 723 | ||
733 | 724 | ||
734 | |||
735 | |||
736 | static int ks0127_probe(struct i2c_adapter *adapter); | ||
737 | static int ks0127_detach(struct i2c_client *client); | ||
738 | static int ks0127_command(struct i2c_client *client, | ||
739 | unsigned int cmd, void *arg); | ||
740 | |||
741 | |||
742 | |||
743 | /* Addresses to scan */ | 725 | /* Addresses to scan */ |
744 | static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1, | 726 | #define I2C_KS0127_ADDON 0xD8 |
745 | I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END}; | 727 | #define I2C_KS0127_ONBOARD 0xDA |
746 | static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
747 | static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END}; | ||
748 | static struct i2c_client_address_data addr_data = { | ||
749 | normal_i2c, | ||
750 | probe, | ||
751 | ignore, | ||
752 | }; | ||
753 | 728 | ||
754 | static struct i2c_driver i2c_driver_ks0127 = { | 729 | static unsigned short normal_i2c[] = { |
755 | .driver.name = "ks0127", | 730 | I2C_KS0127_ADDON >> 1, |
756 | .id = I2C_DRIVERID_KS0127, | 731 | I2C_KS0127_ONBOARD >> 1, |
757 | .attach_adapter = ks0127_probe, | 732 | I2C_CLIENT_END |
758 | .detach_client = ks0127_detach, | ||
759 | .command = ks0127_command | ||
760 | }; | 733 | }; |
761 | 734 | ||
762 | static struct i2c_client ks0127_client_tmpl = | 735 | I2C_CLIENT_INSMOD; |
763 | { | ||
764 | .name = "(ks0127 unset)", | ||
765 | .addr = 0, | ||
766 | .adapter = NULL, | ||
767 | .driver = &i2c_driver_ks0127, | ||
768 | }; | ||
769 | 736 | ||
770 | static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind) | 737 | static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id) |
771 | { | 738 | { |
772 | struct ks0127 *ks; | 739 | struct ks0127 *ks; |
773 | struct i2c_client *client; | ||
774 | 740 | ||
775 | client = kzalloc(sizeof(*client), GFP_KERNEL); | 741 | v4l_info(c, "%s chip found @ 0x%x (%s)\n", |
776 | if (client == NULL) | 742 | c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board", |
777 | return -ENOMEM; | 743 | c->addr << 1, c->adapter->name); |
778 | memcpy(client, &ks0127_client_tmpl, sizeof(*client)); | ||
779 | 744 | ||
780 | ks = kzalloc(sizeof(*ks), GFP_KERNEL); | 745 | ks = kzalloc(sizeof(*ks), GFP_KERNEL); |
781 | if (ks == NULL) { | 746 | if (ks == NULL) |
782 | kfree(client); | ||
783 | return -ENOMEM; | 747 | return -ENOMEM; |
784 | } | ||
785 | 748 | ||
786 | i2c_set_clientdata(client, ks); | 749 | i2c_set_clientdata(c, ks); |
787 | client->adapter = adapter; | ||
788 | client->addr = addr; | ||
789 | sprintf(client->name, "ks0127-%02x", adapter->id); | ||
790 | 750 | ||
791 | ks->client = client; | ||
792 | ks->addr = addr; | ||
793 | ks->ks_type = KS_TYPE_UNKNOWN; | 751 | ks->ks_type = KS_TYPE_UNKNOWN; |
794 | 752 | ||
795 | /* power up */ | 753 | /* power up */ |
796 | ks0127_write(ks, KS_CMDA, 0x2c); | 754 | init_reg_defaults(); |
755 | ks0127_write(c, KS_CMDA, 0x2c); | ||
797 | mdelay(10); | 756 | mdelay(10); |
798 | 757 | ||
799 | /* reset the device */ | 758 | /* reset the device */ |
800 | ks0127_reset(ks); | 759 | ks0127_reset(c); |
801 | printk(KERN_INFO "ks0127: attach: %s video decoder\n", | ||
802 | ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board"); | ||
803 | |||
804 | i2c_attach_client(client); | ||
805 | return 0; | 760 | return 0; |
806 | } | 761 | } |
807 | 762 | ||
808 | 763 | static int ks0127_remove(struct i2c_client *c) | |
809 | static int ks0127_probe(struct i2c_adapter *adapter) | ||
810 | { | 764 | { |
811 | if (adapter->id == I2C_HW_B_ZR36067) | 765 | struct ks0127 *ks = i2c_get_clientdata(c); |
812 | return i2c_probe(adapter, &addr_data, ks0127_found_proc); | ||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | static int ks0127_detach(struct i2c_client *client) | ||
817 | { | ||
818 | struct ks0127 *ks = i2c_get_clientdata(client); | ||
819 | 766 | ||
820 | ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/ | 767 | ks0127_write(c, KS_OFMTA, 0x20); /* tristate */ |
821 | ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */ | 768 | ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */ |
822 | 769 | ||
823 | i2c_detach_client(client); | ||
824 | kfree(ks); | 770 | kfree(ks); |
825 | kfree(client); | ||
826 | |||
827 | dprintk("ks0127: detach\n"); | ||
828 | return 0; | 771 | return 0; |
829 | } | 772 | } |
830 | 773 | ||
831 | 774 | static int ks0127_legacy_probe(struct i2c_adapter *adapter) | |
832 | static int __devinit ks0127_init_module(void) | ||
833 | { | 775 | { |
834 | init_reg_defaults(); | 776 | return adapter->id == I2C_HW_B_ZR36067; |
835 | return i2c_add_driver(&i2c_driver_ks0127); | ||
836 | } | 777 | } |
837 | 778 | ||
838 | static void __devexit ks0127_cleanup_module(void) | 779 | static const struct i2c_device_id ks0127_id[] = { |
839 | { | 780 | { "ks0127", 0 }, |
840 | i2c_del_driver(&i2c_driver_ks0127); | 781 | { } |
841 | } | 782 | }; |
842 | 783 | MODULE_DEVICE_TABLE(i2c, ks0127_id); | |
843 | 784 | ||
844 | module_init(ks0127_init_module); | 785 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
845 | module_exit(ks0127_cleanup_module); | 786 | .name = "ks0127", |
787 | .driverid = I2C_DRIVERID_KS0127, | ||
788 | .command = ks0127_command, | ||
789 | .probe = ks0127_probe, | ||
790 | .remove = ks0127_remove, | ||
791 | .legacy_probe = ks0127_legacy_probe, | ||
792 | .id_table = ks0127_id, | ||
793 | }; | ||