The patch number 10507 was added via Mauro Carvalho Chehab <mche...@redhat.com>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        Linux Media Mailing List <linux-me...@vger.kernel.org>

------

From: Mauro Carvalho Chehab  <mche...@redhat.com>
saa7134: Fix analog mode on devices that need to open an i2c gate


Some saa7134 devices require to open an i2c gate before tuning. This
patch fix the initialization for those devices.

The nxt200x_gate_ctrl() logic were returned back to the old place, since
we don't know how to close the gate. A future pacth could revert that
change and provide the proper close gate control, to avoid keeping it
open forever.

Priority: normal

Signed-off-by: Mauro Carvalho Chehab <mche...@redhat.com>


---

 linux/drivers/media/video/saa7134/saa7134-cards.c |  147 +++++++-------
 1 file changed, 77 insertions(+), 70 deletions(-)

diff -r 5bad8b1eec7b -r ec84c420abdd 
linux/drivers/media/video/saa7134/saa7134-cards.c
--- a/linux/drivers/media/video/saa7134/saa7134-cards.c Sun Feb 08 09:50:50 
2009 -0200
+++ b/linux/drivers/media/video/saa7134/saa7134-cards.c Sun Feb 08 10:33:15 
2009 -0200
@@ -5994,32 +5994,6 @@ static void hauppauge_eeprom(struct saa7
 }
 
 /* ----------------------------------------------------------- */
-
-static void nxt200x_gate_ctrl(struct saa7134_dev *dev, int open)
-{
-       /* enable tuner */
-       int i;
-       static const u8 buffer [][2] = {
-               { 0x10, 0x12 },
-               { 0x13, 0x04 },
-               { 0x16, 0x00 },
-               { 0x14, 0x04 },
-               { 0x17, 0x00 },
-       };
-
-       dev->i2c_client.addr = 0x0a;
-
-       /* FIXME: don't know how to close the i2c gate on NXT200x */
-       if (!open)
-               return;
-
-       for (i = 0; i < ARRAY_SIZE(buffer); i++)
-               if (2 != i2c_master_send(&dev->i2c_client,
-                                        &buffer[i][0], ARRAY_SIZE(buffer[0])))
-                       printk(KERN_WARNING
-                              "%s: Unable to enable tuner(%i).\n",
-                              dev->name, i);
-}
 
 int saa7134_board_init1(struct saa7134_dev *dev)
 {
@@ -6218,10 +6192,6 @@ int saa7134_board_init1(struct saa7134_d
                       "are supported for now.\n",
                        dev->name, card(dev).name, dev->name);
                break;
-       case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
-       case SAA7134_BOARD_KWORLD_ATSC110:
-               dev->gate_ctrl = nxt200x_gate_ctrl;
-               break;
        }
        return 0;
 }
@@ -6300,33 +6270,20 @@ int saa7134_board_init2(struct saa7134_d
        unsigned char buf;
        int board;
 
-       /* initialize hardware #2 */
-       if (TUNER_ABSENT != dev->tuner_type) {
-               int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
-
-               /* Note: radio tuner address is always filled in,
-                  so we do not need to probe for a radio tuner device. */
-               if (dev->radio_type != UNSET)
-                       v4l2_i2c_new_subdev(&dev->i2c_adap,
-                               "tuner", "tuner", dev->radio_addr);
-               if (has_demod)
-                       v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
-                               "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
-               if (dev->tuner_addr == ADDR_UNSET) {
-                       enum v4l2_i2c_tuner_type type =
-                               has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
-
-                       v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
-                               "tuner", v4l2_i2c_tuner_addrs(type));
-               } else {
-                       v4l2_i2c_new_subdev(&dev->i2c_adap,
-                               "tuner", "tuner", dev->tuner_addr);
-               }
-       }
-
+       /* Put here the code that enables the chips that are needed
+          for analog mode and doesn't depend on the tuner attachment.
+          It is also a good idea to get tuner type from eeprom, etc before
+          initializing tuner, since we can avoid loading tuner driver
+          on devices that has TUNER_ABSENT
+        */
        switch (dev->board) {
        case SAA7134_BOARD_BMK_MPEX_NOTUNER:
        case SAA7134_BOARD_BMK_MPEX_TUNER:
+               /* Checks if the device has a tuner at 0x60 addr
+                  If the device doesn't have a tuner, TUNER_ABSENT
+                  will be used at tuner_type, avoiding loading tuner
+                  without needing it
+                */
                dev->i2c_client.addr = 0x60;
                board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
                        ? SAA7134_BOARD_BMK_MPEX_NOTUNER
@@ -6344,11 +6301,15 @@ int saa7134_board_init2(struct saa7134_d
                u8 subaddr;
                u8 data[3];
                int ret, tuner_t;
-
                struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, 
.len = 1},
                                        {.addr=0x50, .flags=I2C_M_RD, 
.buf=data, .len = 3}};
+
                subaddr= 0x14;
                tuner_t = 0;
+
+               /* Retrieve device data from eeprom, checking for the
+                  proper tuner_type.
+                */
                ret = i2c_transfer(&dev->i2c_adap, msg, 2);
                if (ret != 2) {
                        printk(KERN_ERR "EEPROM read failure\n");
@@ -6404,12 +6365,14 @@ int saa7134_board_init2(struct saa7134_d
                                dev->name, saa7134_boards[dev->board].name);
                        break;
                }
+               /* break intentionally omitted */
        case SAA7134_BOARD_VIDEOMATE_DVBT_300:
        case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
        {
 
-               /* The Philips EUROPA based hybrid boards have the tuner 
connected through
-                * the channel decoder. We have to make it transparent to find 
it
+               /* The Philips EUROPA based hybrid boards have the tuner
+                  connected through the channel decoder. We have to make it
+                  transparent to find it
                 */
                u8 data[] = { 0x07, 0x02};
                struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = 
sizeof(data)};
@@ -6430,21 +6393,15 @@ int saa7134_board_init2(struct saa7134_d
                if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
                        dev->tuner_type = TUNER_PHILIPS_TDA8290;
 
-                       saa7134_tuner_setup(dev);
-
                        data[2] = 0x68;
                        i2c_transfer(&dev->i2c_adap, &msg, 1);
-
-                       /* Tuner setup is handled before I2C transfer.
-                          Due to that, there's no need to do it later
-                        */
-                       return 0;
+                       break;
                }
                i2c_transfer(&dev->i2c_adap, &msg, 1);
                break;
        }
-       case SAA7134_BOARD_ASUSTeK_TVFM7135:
-       /* The card below is detected as card=53, but is different */
+       case SAA7134_BOARD_ASUSTeK_TVFM7135:
+       /* The card below is detected as card=53, but is different */
               if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
                       dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
                       printk(KERN_INFO "%s: P7131 analog only, using "
@@ -6515,9 +6472,9 @@ int saa7134_board_init2(struct saa7134_d
 
                /* Don't do this if the board was specifically selected with an
                 * insmod option or if we have the default configuration T200*/
-               if(!dev->autodetected || (dev->eedata[0x41] == 0xd0))
+               if (!dev->autodetected || (dev->eedata[0x41] == 0xd0))
                        break;
-               if(dev->eedata[0x41] == 0x02) {
+               if (dev->eedata[0x41] == 0x02) {
                        /* Reconfigure board  as T200A */
                        dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
                        dev->tuner_type   = 
saa7134_boards[dev->board].tuner_type;
@@ -6530,6 +6487,58 @@ int saa7134_board_init2(struct saa7134_d
                        break;
                }
                break;
+       case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
+       case SAA7134_BOARD_KWORLD_ATSC110:
+       {
+               struct i2c_msg msg = { .addr = 0x0a, .flags = 0 };
+               int i;
+               static u8 buffer[][2] = {
+                       { 0x10, 0x12 },
+                       { 0x13, 0x04 },
+                       { 0x16, 0x00 },
+                       { 0x14, 0x04 },
+                       { 0x17, 0x00 },
+               };
+
+               for (i = 0; i < ARRAY_SIZE(buffer); i++) {
+                       msg.buf = &buffer[i][0];
+                       msg.len = ARRAY_SIZE(buffer[0]);
+                       if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+                               printk(KERN_WARNING
+                                      "%s: Unable to enable tuner(%i).\n",
+                                      dev->name, i);
+               }
+               break;
+       }
+       } /* switch() */
+
+       /* initialize tuner */
+       if (TUNER_ABSENT != dev->tuner_type) {
+               int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+               /* Note: radio tuner address is always filled in,
+                  so we do not need to probe for a radio tuner device. */
+               if (dev->radio_type != UNSET)
+                       v4l2_i2c_new_subdev(&dev->i2c_adap,
+                               "tuner", "tuner", dev->radio_addr);
+               if (has_demod)
+                       v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+                               "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+               if (dev->tuner_addr == ADDR_UNSET) {
+                       enum v4l2_i2c_tuner_type type =
+                               has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+                       v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+                               "tuner", v4l2_i2c_tuner_addrs(type));
+               } else {
+                       v4l2_i2c_new_subdev(&dev->i2c_adap,
+                               "tuner", "tuner", dev->tuner_addr);
+               }
+       }
+
+       saa7134_tuner_setup(dev);
+
+       switch (dev->board) {
        case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
        {
                struct v4l2_priv_tun_config tea5767_cfg;
@@ -6546,7 +6555,5 @@ int saa7134_board_init2(struct saa7134_d
        }
        } /* switch() */
 
-       saa7134_tuner_setup(dev);
-
        return 0;
 }


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/ec84c420abdd53bf0baa79ce69f23cc215893741

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to