diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-26 10:55:09 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-29 17:41:32 -0400 |
commit | 4bf1226a7018bf79d05e0ce59244d702819529d1 (patch) | |
tree | a113ca63819851527db9ae341c6c47b2b64fcad1 /drivers/media/video | |
parent | 7663c1e2792a9662b23dec6e19bfcd3d55360b8f (diff) |
V4L/DVB (7749): cx88: fix tuner setup
Tuner setup were happening during i2c attach callback. This means that it would
happen on two conditions:
1) if tuner module weren't load, it will happen at request_module("tuner");
2) if tuner is not compiled as a module, or it is already loaded
(for example, on setups with more than one tuner), it will happen
when cx88 registers I2C bus.
Due to that, if tuner were loaded, tuner setup will happen _before_ reading
the proper values at tuner eeprom. Since set_addr refuses to change for a tuner
that were previously defined (except if the tuner_addr is set), this were making
eeprom tuner detection useless.
This patch removes tuner type setup from cx88-i2c, moving it to the proper
place, after taking eeprom into account.
Reviewed-by: Gert Vervoort <gert.vervoort@hccnet.nl>
Reviewed-by: Ian Pickworth <ian@pickworth.me.uk>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/cx88/cx88-cards.c | 50 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-i2c.c | 30 |
2 files changed, 44 insertions, 36 deletions
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 2b6b283cda15..aeba26dc0a37 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -57,6 +57,9 @@ MODULE_PARM_DESC(latency,"pci latency timer"); | |||
57 | /* ------------------------------------------------------------------ */ | 57 | /* ------------------------------------------------------------------ */ |
58 | /* board config info */ | 58 | /* board config info */ |
59 | 59 | ||
60 | /* If radio_type !=UNSET, radio_addr should be specified | ||
61 | */ | ||
62 | |||
60 | static const struct cx88_board cx88_boards[] = { | 63 | static const struct cx88_board cx88_boards[] = { |
61 | [CX88_BOARD_UNKNOWN] = { | 64 | [CX88_BOARD_UNKNOWN] = { |
62 | .name = "UNKNOWN/GENERIC", | 65 | .name = "UNKNOWN/GENERIC", |
@@ -2446,25 +2449,31 @@ EXPORT_SYMBOL_GPL(cx88_setup_xc3028); | |||
2446 | static void cx88_card_setup(struct cx88_core *core) | 2449 | static void cx88_card_setup(struct cx88_core *core) |
2447 | { | 2450 | { |
2448 | static u8 eeprom[256]; | 2451 | static u8 eeprom[256]; |
2452 | struct tuner_setup tun_setup; | ||
2453 | unsigned int mode_mask = T_RADIO | | ||
2454 | T_ANALOG_TV | | ||
2455 | T_DIGITAL_TV; | ||
2456 | |||
2457 | memset(&tun_setup, 0, sizeof(tun_setup)); | ||
2449 | 2458 | ||
2450 | if (0 == core->i2c_rc) { | 2459 | if (0 == core->i2c_rc) { |
2451 | core->i2c_client.addr = 0xa0 >> 1; | 2460 | core->i2c_client.addr = 0xa0 >> 1; |
2452 | tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom)); | 2461 | tveeprom_read(&core->i2c_client, eeprom, sizeof(eeprom)); |
2453 | } | 2462 | } |
2454 | 2463 | ||
2455 | switch (core->boardnr) { | 2464 | switch (core->boardnr) { |
2456 | case CX88_BOARD_HAUPPAUGE: | 2465 | case CX88_BOARD_HAUPPAUGE: |
2457 | case CX88_BOARD_HAUPPAUGE_ROSLYN: | 2466 | case CX88_BOARD_HAUPPAUGE_ROSLYN: |
2458 | if (0 == core->i2c_rc) | 2467 | if (0 == core->i2c_rc) |
2459 | hauppauge_eeprom(core,eeprom+8); | 2468 | hauppauge_eeprom(core, eeprom+8); |
2460 | break; | 2469 | break; |
2461 | case CX88_BOARD_GDI: | 2470 | case CX88_BOARD_GDI: |
2462 | if (0 == core->i2c_rc) | 2471 | if (0 == core->i2c_rc) |
2463 | gdi_eeprom(core,eeprom); | 2472 | gdi_eeprom(core, eeprom); |
2464 | break; | 2473 | break; |
2465 | case CX88_BOARD_WINFAST2000XP_EXPERT: | 2474 | case CX88_BOARD_WINFAST2000XP_EXPERT: |
2466 | if (0 == core->i2c_rc) | 2475 | if (0 == core->i2c_rc) |
2467 | leadtek_eeprom(core,eeprom); | 2476 | leadtek_eeprom(core, eeprom); |
2468 | break; | 2477 | break; |
2469 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | 2478 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
2470 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | 2479 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: |
@@ -2474,7 +2483,7 @@ static void cx88_card_setup(struct cx88_core *core) | |||
2474 | case CX88_BOARD_HAUPPAUGE_HVR3000: | 2483 | case CX88_BOARD_HAUPPAUGE_HVR3000: |
2475 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 2484 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
2476 | if (0 == core->i2c_rc) | 2485 | if (0 == core->i2c_rc) |
2477 | hauppauge_eeprom(core,eeprom); | 2486 | hauppauge_eeprom(core, eeprom); |
2478 | break; | 2487 | break; |
2479 | case CX88_BOARD_KWORLD_DVBS_100: | 2488 | case CX88_BOARD_KWORLD_DVBS_100: |
2480 | cx_write(MO_GP0_IO, 0x000007f8); | 2489 | cx_write(MO_GP0_IO, 0x000007f8); |
@@ -2555,6 +2564,35 @@ static void cx88_card_setup(struct cx88_core *core) | |||
2555 | 2564 | ||
2556 | cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); | 2565 | cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); |
2557 | } | 2566 | } |
2567 | } /*end switch() */ | ||
2568 | |||
2569 | |||
2570 | /* Setup tuners */ | ||
2571 | if ((core->board.radio_type != UNSET)) { | ||
2572 | tun_setup.mode_mask = T_RADIO; | ||
2573 | tun_setup.type = core->board.radio_type; | ||
2574 | tun_setup.addr = core->board.radio_addr; | ||
2575 | tun_setup.tuner_callback = cx88_tuner_callback; | ||
2576 | cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup); | ||
2577 | mode_mask &= ~T_RADIO; | ||
2578 | } | ||
2579 | |||
2580 | if (core->board.tuner_type != TUNER_ABSENT) { | ||
2581 | tun_setup.mode_mask = mode_mask; | ||
2582 | tun_setup.type = core->board.tuner_type; | ||
2583 | tun_setup.addr = core->board.tuner_addr; | ||
2584 | tun_setup.tuner_callback = cx88_tuner_callback; | ||
2585 | |||
2586 | cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup); | ||
2587 | } | ||
2588 | |||
2589 | if (core->board.tda9887_conf) { | ||
2590 | struct v4l2_priv_tun_config tda9887_cfg; | ||
2591 | |||
2592 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
2593 | tda9887_cfg.priv = &core->board.tda9887_conf; | ||
2594 | |||
2595 | cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg); | ||
2558 | } | 2596 | } |
2559 | 2597 | ||
2560 | if (core->board.tuner_type == TUNER_XC2028) { | 2598 | if (core->board.tuner_type == TUNER_XC2028) { |
@@ -2572,6 +2610,7 @@ static void cx88_card_setup(struct cx88_core *core) | |||
2572 | ctl.fname); | 2610 | ctl.fname); |
2573 | cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg); | 2611 | cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg); |
2574 | } | 2612 | } |
2613 | cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL); | ||
2575 | } | 2614 | } |
2576 | 2615 | ||
2577 | /* ------------------------------------------------------------------ */ | 2616 | /* ------------------------------------------------------------------ */ |
@@ -2710,7 +2749,6 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) | |||
2710 | if (TUNER_ABSENT != core->board.tuner_type) | 2749 | if (TUNER_ABSENT != core->board.tuner_type) |
2711 | request_module("tuner"); | 2750 | request_module("tuner"); |
2712 | 2751 | ||
2713 | cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL); | ||
2714 | cx88_card_setup(core); | 2752 | cx88_card_setup(core); |
2715 | cx88_ir_init(core, pci); | 2753 | cx88_ir_init(core, pci); |
2716 | 2754 | ||
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index c6b44732a082..00aa7a3f1105 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -104,37 +104,7 @@ static int attach_inform(struct i2c_client *client) | |||
104 | 104 | ||
105 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", | 105 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", |
106 | client->driver->driver.name, client->addr, client->name); | 106 | client->driver->driver.name, client->addr, client->name); |
107 | if (!client->driver->command) | ||
108 | return 0; | ||
109 | |||
110 | if (core->board.radio_type != UNSET) { | ||
111 | if ((core->board.radio_addr==ADDR_UNSET)||(core->board.radio_addr==client->addr)) { | ||
112 | tun_setup.mode_mask = T_RADIO; | ||
113 | tun_setup.type = core->board.radio_type; | ||
114 | tun_setup.addr = core->board.radio_addr; | ||
115 | tun_setup.tuner_callback = cx88_tuner_callback; | ||
116 | client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup); | ||
117 | } | ||
118 | } | ||
119 | if (core->board.tuner_type != UNSET) { | ||
120 | if ((core->board.tuner_addr==ADDR_UNSET)||(core->board.tuner_addr==client->addr)) { | ||
121 | |||
122 | tun_setup.mode_mask = T_ANALOG_TV; | ||
123 | tun_setup.type = core->board.tuner_type; | ||
124 | tun_setup.addr = core->board.tuner_addr; | ||
125 | tun_setup.tuner_callback = cx88_tuner_callback; | ||
126 | client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | if (core->board.tda9887_conf) { | ||
131 | struct v4l2_priv_tun_config tda9887_cfg; | ||
132 | 107 | ||
133 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
134 | tda9887_cfg.priv = &core->board.tda9887_conf; | ||
135 | |||
136 | client->driver->command(client, TUNER_SET_CONFIG, &tda9887_cfg); | ||
137 | } | ||
138 | return 0; | 108 | return 0; |
139 | } | 109 | } |
140 | 110 | ||