diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-17 20:40:45 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:09:41 -0400 |
commit | 102a0b0879a01a413ed5f667f7db9c2085ca8474 (patch) | |
tree | df057cd2bd569bd9fdeb586927f635d67f2ce6a6 /drivers | |
parent | 3421b7787a2cf41ac5edce9b5766bddd1e1d9986 (diff) |
V4L/DVB (7604): em28xx-dvb: Fix analog mode
The analog entries are wrong. Fix it.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 149 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 9 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 1 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 22 |
4 files changed, 67 insertions, 114 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 2a44d2adeb09..0859a84e7433 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -171,26 +171,6 @@ struct em28xx_board em28xx_boards[] = { | |||
171 | .vmux = TVP5150_SVIDEO, | 171 | .vmux = TVP5150_SVIDEO, |
172 | .amux = 1, | 172 | .amux = 1, |
173 | } }, | 173 | } }, |
174 | .analog_gpio = { | ||
175 | { /* xc3028 reset seq */ | ||
176 | .reg = 0x08, | ||
177 | .val = 0x2d, | ||
178 | .rst = 0x3d, | ||
179 | .t1 = 5, | ||
180 | .t2 = 10, | ||
181 | .t3 = 5, | ||
182 | }, | ||
183 | }, | ||
184 | .digital_gpio = { | ||
185 | { /* xc3028 reset seq */ | ||
186 | .reg = 0x08, | ||
187 | .val = 0x2e, | ||
188 | .rst = 0x3e, | ||
189 | .t1 = 6, | ||
190 | .t2 = 6, | ||
191 | .t3 = 6, | ||
192 | } | ||
193 | }, | ||
194 | }, | 174 | }, |
195 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = { | 175 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = { |
196 | .name = "Hauppauge WinTV HVR 950", | 176 | .name = "Hauppauge WinTV HVR 950", |
@@ -214,32 +194,6 @@ struct em28xx_board em28xx_boards[] = { | |||
214 | .vmux = TVP5150_SVIDEO, | 194 | .vmux = TVP5150_SVIDEO, |
215 | .amux = 1, | 195 | .amux = 1, |
216 | } }, | 196 | } }, |
217 | .analog_gpio = { | ||
218 | { /* xc3028 reset seq */ | ||
219 | .reg = 0x08, | ||
220 | .val = 0x2d, | ||
221 | .rst = 0x3d, | ||
222 | .t1 = 5, | ||
223 | .t2 = 10, | ||
224 | .t3 = 5, | ||
225 | }, | ||
226 | }, | ||
227 | .digital_gpio = { | ||
228 | { /* xc3028 reset seq */ | ||
229 | .reg = 0x08, | ||
230 | .val = 0x2e, | ||
231 | .rst = 0x3e, | ||
232 | .t1 = 6, | ||
233 | .t2 = 6, | ||
234 | .t3 = 6, | ||
235 | }, { /* demod reset seq */ | ||
236 | .reg = 0x04, | ||
237 | .val = 0x04, | ||
238 | .rst = 0x0c, | ||
239 | .t2 = 10, | ||
240 | .t3 = 10, | ||
241 | } | ||
242 | }, | ||
243 | }, | 197 | }, |
244 | [EM2880_BOARD_TERRATEC_HYBRID_XS] = { | 198 | [EM2880_BOARD_TERRATEC_HYBRID_XS] = { |
245 | .name = "Terratec Hybrid XS", | 199 | .name = "Terratec Hybrid XS", |
@@ -476,7 +430,28 @@ struct usb_device_id em28xx_id_table [] = { | |||
476 | }; | 430 | }; |
477 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); | 431 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); |
478 | 432 | ||
479 | /* EEPROM hash table for devices with generic USB IDs */ | 433 | /* |
434 | * Reset sequences for analog/digital modes | ||
435 | */ | ||
436 | |||
437 | /* Board Hauppauge WinTV HVR 900 analog */ | ||
438 | struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { | ||
439 | { -1, -1, 6}, | ||
440 | {0x08, 0x2d, 10}, | ||
441 | {0x08, 0x3d, 5}, | ||
442 | { -1, -1, -1}, | ||
443 | }; | ||
444 | /* Board Hauppauge WinTV HVR 900 digital */ | ||
445 | struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | ||
446 | { -1, -1, 6}, | ||
447 | {0x08, 0x2e, 6}, | ||
448 | {0x08, 0x3e, 6}, | ||
449 | { -1, -1, -1}, | ||
450 | }; | ||
451 | |||
452 | /* | ||
453 | * EEPROM hash table for devices with generic USB IDs | ||
454 | */ | ||
480 | static struct em28xx_hash_table em28xx_eeprom_hash [] = { | 455 | static struct em28xx_hash_table em28xx_eeprom_hash [] = { |
481 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ | 456 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ |
482 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, | 457 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, |
@@ -490,9 +465,9 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { | |||
490 | 465 | ||
491 | int em28xx_tuner_callback(void *ptr, int command, int arg) | 466 | int em28xx_tuner_callback(void *ptr, int command, int arg) |
492 | { | 467 | { |
493 | int rc = 0, i; | 468 | int rc = 0; |
494 | struct em28xx *dev = ptr; | 469 | struct em28xx *dev = ptr; |
495 | struct gpio_ctl *gpio_ctl; | 470 | struct em28xx_reg_seq *gpio; |
496 | 471 | ||
497 | if (dev->tuner_type != TUNER_XC2028) | 472 | if (dev->tuner_type != TUNER_XC2028) |
498 | return 0; | 473 | return 0; |
@@ -501,44 +476,31 @@ int em28xx_tuner_callback(void *ptr, int command, int arg) | |||
501 | return 0; | 476 | return 0; |
502 | 477 | ||
503 | if (dev->mode == EM28XX_ANALOG_MODE) | 478 | if (dev->mode == EM28XX_ANALOG_MODE) |
504 | gpio_ctl = dev->analog_gpio; | 479 | gpio = dev->analog_gpio; |
505 | else | 480 | else |
506 | gpio_ctl = dev->digital_gpio; | 481 | gpio = dev->digital_gpio; |
507 | 482 | ||
508 | /* djh - Not sure if these are still required */ | 483 | /* djh - Not sure if these are still required */ |
509 | if (dev->mode == EM28XX_ANALOG_MODE) { | 484 | dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); |
510 | dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); | 485 | if (dev->mode == EM28XX_ANALOG_MODE) |
511 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); | 486 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); |
512 | msleep(6); | 487 | else |
513 | } else { | 488 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); |
514 | dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); | 489 | msleep(6); |
515 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); | ||
516 | msleep(6); | ||
517 | } | ||
518 | |||
519 | /* Send GPIO reset sequences specified at board entry */ | ||
520 | for (i = 0; i < MAX_GPIO; i++) { | ||
521 | if (!gpio_ctl->val) | ||
522 | break; | ||
523 | |||
524 | dev->em28xx_write_regs(dev, | ||
525 | gpio_ctl->reg, | ||
526 | &gpio_ctl->val, 1); | ||
527 | if (gpio_ctl->t1) | ||
528 | msleep(gpio_ctl->t1); | ||
529 | |||
530 | if (!gpio_ctl->rst) { | ||
531 | gpio_ctl++; | ||
532 | continue; | ||
533 | } | ||
534 | 490 | ||
535 | dev->em28xx_write_regs(dev, | 491 | if (!gpio) |
536 | gpio_ctl->reg, | 492 | return rc; |
537 | &gpio_ctl->rst, 1); | ||
538 | if (gpio_ctl->t2) | ||
539 | msleep(gpio_ctl->t2); | ||
540 | 493 | ||
541 | gpio_ctl++; | 494 | /* Send GPIO reset sequences specified at board entry */ |
495 | while (gpio->sleep >= 0) { | ||
496 | if (gpio->reg >= 0) | ||
497 | rc = dev->em28xx_write_regs(dev, | ||
498 | gpio->reg, | ||
499 | &gpio->val, 1); | ||
500 | if (gpio->sleep > 0) | ||
501 | msleep(gpio->sleep); | ||
502 | |||
503 | gpio++; | ||
542 | } | 504 | } |
543 | return rc; | 505 | return rc; |
544 | } | 506 | } |
@@ -554,8 +516,6 @@ static void em28xx_set_model(struct em28xx *dev) | |||
554 | dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; | 516 | dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; |
555 | dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; | 517 | dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; |
556 | dev->has_dvb = em28xx_boards[dev->model].has_dvb; | 518 | dev->has_dvb = em28xx_boards[dev->model].has_dvb; |
557 | dev->analog_gpio = em28xx_boards[dev->model].analog_gpio; | ||
558 | dev->digital_gpio = em28xx_boards[dev->model].digital_gpio; | ||
559 | } | 519 | } |
560 | 520 | ||
561 | /* Since em28xx_pre_card_setup() requires a proper dev->model, | 521 | /* Since em28xx_pre_card_setup() requires a proper dev->model, |
@@ -573,13 +533,22 @@ void em28xx_pre_card_setup(struct em28xx *dev) | |||
573 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: | 533 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: |
574 | em28xx_write_regs(dev, XCLK_REG, "\x27", 1); | 534 | em28xx_write_regs(dev, XCLK_REG, "\x27", 1); |
575 | em28xx_write_regs(dev, I2C_CLK_REG, "\x40", 1); | 535 | em28xx_write_regs(dev, I2C_CLK_REG, "\x40", 1); |
576 | } | 536 | em28xx_write_regs(dev, 0x08, "\xff", 1); |
537 | em28xx_write_regs(dev, 0x04, "\x00", 1); | ||
538 | msleep(100); | ||
539 | em28xx_write_regs(dev, 0x04, "\x08", 1); | ||
540 | msleep(100); | ||
541 | em28xx_write_regs(dev, 0x08, "\xff", 1); | ||
542 | msleep(50); | ||
543 | em28xx_write_regs(dev, 0x08, "\x2d", 1); | ||
544 | msleep(50); | ||
545 | em28xx_write_regs(dev, 0x08, "\x3d", 1); | ||
546 | |||
547 | dev->analog_gpio = hauppauge_wintv_hvr_900_analog; | ||
548 | dev->digital_gpio = hauppauge_wintv_hvr_900_digital; | ||
577 | 549 | ||
578 | /* Put xc2028 tuners and demods into a sane state */ | 550 | break; |
579 | if (dev->tuner_type == TUNER_XC2028) { | 551 | } |
580 | dev->mode = EM28XX_ANALOG_MODE; | ||
581 | em28xx_tuner_callback(dev, XC2028_TUNER_RESET, 0); | ||
582 | }; | ||
583 | } | 552 | } |
584 | 553 | ||
585 | void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | 554 | void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index cb9f721ca280..77f64900717d 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -331,22 +331,17 @@ int em28xx_capture_start(struct em28xx *dev, int start) | |||
331 | if (!start) { | 331 | if (!start) { |
332 | /* disable video capture */ | 332 | /* disable video capture */ |
333 | rc = em28xx_write_regs(dev, VINENABLE_REG, "\x27", 1); | 333 | rc = em28xx_write_regs(dev, VINENABLE_REG, "\x27", 1); |
334 | if (rc < 0) | 334 | return rc; |
335 | return rc; | ||
336 | } | 335 | } |
337 | 336 | ||
338 | /* enable video capture */ | 337 | /* enable video capture */ |
339 | rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); | 338 | rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); |
340 | if (rc < 0) | 339 | |
341 | return rc; | ||
342 | if (dev->mode == EM28XX_ANALOG_MODE) | 340 | if (dev->mode == EM28XX_ANALOG_MODE) |
343 | rc = em28xx_write_regs(dev, VINENABLE_REG,"\x67", 1); | 341 | rc = em28xx_write_regs(dev, VINENABLE_REG,"\x67", 1); |
344 | else | 342 | else |
345 | rc = em28xx_write_regs(dev, VINENABLE_REG,"\x37", 1); | 343 | rc = em28xx_write_regs(dev, VINENABLE_REG,"\x37", 1); |
346 | 344 | ||
347 | if (rc < 0) | ||
348 | return rc; | ||
349 | |||
350 | msleep (6); | 345 | msleep (6); |
351 | 346 | ||
352 | return rc; | 347 | return rc; |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index fd8f44cb6cbc..64816ae106e3 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -414,6 +414,7 @@ static int dvb_init(struct em28xx *dev) | |||
414 | goto out_free; | 414 | goto out_free; |
415 | } | 415 | } |
416 | 416 | ||
417 | printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); | ||
417 | return 0; | 418 | return 0; |
418 | 419 | ||
419 | out_free: | 420 | out_free: |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index e5fd2dc77355..91dce95cd19c 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -225,19 +225,10 @@ enum em28xx_decoder { | |||
225 | EM28XX_SAA7114 | 225 | EM28XX_SAA7114 |
226 | }; | 226 | }; |
227 | 227 | ||
228 | #define MAX_GPIO 2 | 228 | struct em28xx_reg_seq { |
229 | struct gpio_ctl { | 229 | int reg; |
230 | /* Register to be set */ | ||
231 | unsigned char reg; | ||
232 | /* Initial/final value */ | ||
233 | unsigned char val; | 230 | unsigned char val; |
234 | /* reset value - if set, it will do: | 231 | int sleep; |
235 | val1 - val2 - val1 | ||
236 | */ | ||
237 | unsigned char rst; | ||
238 | /* Sleep times | ||
239 | */ | ||
240 | unsigned int t1, t2, t3; | ||
241 | }; | 232 | }; |
242 | 233 | ||
243 | struct em28xx_board { | 234 | struct em28xx_board { |
@@ -255,9 +246,6 @@ struct em28xx_board { | |||
255 | unsigned int max_range_640_480:1; | 246 | unsigned int max_range_640_480:1; |
256 | unsigned int has_dvb:1; | 247 | unsigned int has_dvb:1; |
257 | 248 | ||
258 | struct gpio_ctl analog_gpio[MAX_GPIO]; | ||
259 | struct gpio_ctl digital_gpio[MAX_GPIO]; | ||
260 | |||
261 | enum em28xx_decoder decoder; | 249 | enum em28xx_decoder decoder; |
262 | 250 | ||
263 | struct em28xx_input input[MAX_EM28XX_INPUT]; | 251 | struct em28xx_input input[MAX_EM28XX_INPUT]; |
@@ -343,8 +331,8 @@ struct em28xx { | |||
343 | unsigned int max_range_640_480:1; | 331 | unsigned int max_range_640_480:1; |
344 | unsigned int has_dvb:1; | 332 | unsigned int has_dvb:1; |
345 | 333 | ||
346 | struct gpio_ctl *analog_gpio; | 334 | /* GPIO sequences for tuner callback */ |
347 | struct gpio_ctl *digital_gpio; | 335 | struct em28xx_reg_seq *analog_gpio, *digital_gpio; |
348 | 336 | ||
349 | int video_inputs; /* number of video inputs */ | 337 | int video_inputs; /* number of video inputs */ |
350 | struct list_head devlist; | 338 | struct list_head devlist; |