V4L/DVB (7749): cx88: fix tuner setup
authorMauro Carvalho Chehab <mchehab@infradead.org>
Sat, 26 Apr 2008 14:55:09 +0000 (11:55 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Tue, 29 Apr 2008 21:41:32 +0000 (18:41 -0300)
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>
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-i2c.c

index 2b6b283cda15b658c08d1841328350c80aa069f2..aeba26dc0a37ce69a8da26cd7fff176b139da54a 100644 (file)
@@ -57,6 +57,9 @@ MODULE_PARM_DESC(latency,"pci latency timer");
 /* ------------------------------------------------------------------ */
 /* board config info                                                  */
 
+/* If radio_type !=UNSET, radio_addr should be specified
+ */
+
 static const struct cx88_board cx88_boards[] = {
        [CX88_BOARD_UNKNOWN] = {
                .name           = "UNKNOWN/GENERIC",
@@ -2446,25 +2449,31 @@ EXPORT_SYMBOL_GPL(cx88_setup_xc3028);
 static void cx88_card_setup(struct cx88_core *core)
 {
        static u8 eeprom[256];
+       struct tuner_setup tun_setup;
+       unsigned int mode_mask = T_RADIO     |
+                                T_ANALOG_TV |
+                                T_DIGITAL_TV;
+
+       memset(&tun_setup, 0, sizeof(tun_setup));
 
        if (0 == core->i2c_rc) {
                core->i2c_client.addr = 0xa0 >> 1;
-               tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom));
+               tveeprom_read(&core->i2c_client, eeprom, sizeof(eeprom));
        }
 
        switch (core->boardnr) {
        case CX88_BOARD_HAUPPAUGE:
        case CX88_BOARD_HAUPPAUGE_ROSLYN:
                if (0 == core->i2c_rc)
-                       hauppauge_eeprom(core,eeprom+8);
+                       hauppauge_eeprom(core, eeprom+8);
                break;
        case CX88_BOARD_GDI:
                if (0 == core->i2c_rc)
-                       gdi_eeprom(core,eeprom);
+                       gdi_eeprom(core, eeprom);
                break;
        case CX88_BOARD_WINFAST2000XP_EXPERT:
                if (0 == core->i2c_rc)
-                       leadtek_eeprom(core,eeprom);
+                       leadtek_eeprom(core, eeprom);
                break;
        case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
        case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
@@ -2474,7 +2483,7 @@ static void cx88_card_setup(struct cx88_core *core)
        case CX88_BOARD_HAUPPAUGE_HVR3000:
        case CX88_BOARD_HAUPPAUGE_HVR1300:
                if (0 == core->i2c_rc)
-                       hauppauge_eeprom(core,eeprom);
+                       hauppauge_eeprom(core, eeprom);
                break;
        case CX88_BOARD_KWORLD_DVBS_100:
                cx_write(MO_GP0_IO, 0x000007f8);
@@ -2555,6 +2564,35 @@ static void cx88_card_setup(struct cx88_core *core)
 
                cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
        }
+       } /*end switch() */
+
+
+       /* Setup tuners */
+       if ((core->board.radio_type != UNSET)) {
+               tun_setup.mode_mask      = T_RADIO;
+               tun_setup.type           = core->board.radio_type;
+               tun_setup.addr           = core->board.radio_addr;
+               tun_setup.tuner_callback = cx88_tuner_callback;
+               cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+               mode_mask &= ~T_RADIO;
+       }
+
+       if (core->board.tuner_type != TUNER_ABSENT) {
+               tun_setup.mode_mask      = mode_mask;
+               tun_setup.type           = core->board.tuner_type;
+               tun_setup.addr           = core->board.tuner_addr;
+               tun_setup.tuner_callback = cx88_tuner_callback;
+
+               cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+       }
+
+       if (core->board.tda9887_conf) {
+               struct v4l2_priv_tun_config tda9887_cfg;
+
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv  = &core->board.tda9887_conf;
+
+               cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg);
        }
 
        if (core->board.tuner_type == TUNER_XC2028) {
@@ -2572,6 +2610,7 @@ static void cx88_card_setup(struct cx88_core *core)
                            ctl.fname);
                cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
        }
+       cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
 }
 
 /* ------------------------------------------------------------------ */
@@ -2710,7 +2749,6 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
        if (TUNER_ABSENT != core->board.tuner_type)
                request_module("tuner");
 
-       cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
        cx88_card_setup(core);
        cx88_ir_init(core, pci);
 
index c6b44732a082fd743b6fbbc3ac39f4ab511e514f..00aa7a3f11053c615dafbcacd669ac59e2e5490c 100644 (file)
@@ -104,37 +104,7 @@ static int attach_inform(struct i2c_client *client)
 
        dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
                client->driver->driver.name, client->addr, client->name);
-       if (!client->driver->command)
-               return 0;
-
-       if (core->board.radio_type != UNSET) {
-               if ((core->board.radio_addr==ADDR_UNSET)||(core->board.radio_addr==client->addr)) {
-                       tun_setup.mode_mask      = T_RADIO;
-                       tun_setup.type           = core->board.radio_type;
-                       tun_setup.addr           = core->board.radio_addr;
-                       tun_setup.tuner_callback = cx88_tuner_callback;
-                       client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
-               }
-       }
-       if (core->board.tuner_type != UNSET) {
-               if ((core->board.tuner_addr==ADDR_UNSET)||(core->board.tuner_addr==client->addr)) {
-
-                       tun_setup.mode_mask      = T_ANALOG_TV;
-                       tun_setup.type           = core->board.tuner_type;
-                       tun_setup.addr           = core->board.tuner_addr;
-                       tun_setup.tuner_callback = cx88_tuner_callback;
-                       client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
-               }
-       }
-
-       if (core->board.tda9887_conf) {
-               struct v4l2_priv_tun_config tda9887_cfg;
 
-               tda9887_cfg.tuner = TUNER_TDA9887;
-               tda9887_cfg.priv  = &core->board.tda9887_conf;
-
-               client->driver->command(client, TUNER_SET_CONFIG, &tda9887_cfg);
-       }
        return 0;
 }