[media] Add DVB support for SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG
Mauro Carvalho Chehab [Sun, 3 Oct 2010 10:01:26 +0000 (07:01 -0300)]
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c

index 58c8c03..ff23e6e 100644 (file)
@@ -5179,12 +5179,23 @@ struct saa7134_board saa7134_boards[] = {
        [SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG] = {
                .name           = "Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid",
                .audio_clock    = 0x00187de7,
+#if 0
+       /*
+        * FIXME: Analog mode doesn't work, if digital is enabled. The proper
+        * fix is to use tda8290 driver, but Kworld seems to use an
+        * unsupported version of tda8295.
+        */
                .tuner_type     = TUNER_NXP_TDA18271,   /* TUNER_PHILIPS_TDA8290 */
-               .radio_type     = UNSET,
                .tuner_addr     = 0x60,
+#else
+               .tuner_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+#endif
+               .radio_type     = UNSET,
                .radio_addr     = ADDR_UNSET,
                .gpiomask       = 0x8e054000,
                .mpeg           = SAA7134_MPEG_DVB,
+               .ts_type        = SAA7134_MPEG_TS_PARALLEL,
                .inputs = { {
                        .name   = name_tv,
                        .vmux   = 1,
@@ -7623,16 +7634,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                        {0x45, 0x97},
                        {0x45, 0xc1},
                };
-
-               saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x0000);
-               saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000);
-               saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x0000);
-               saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
-               saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000);
-               saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
-               saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000);
-               saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
-               saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000);
                saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
                saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000);
 
index beb95e2..3315a48 100644 (file)
@@ -52,6 +52,7 @@
 #include "tda18271.h"
 #include "lgdt3305.h"
 #include "tda8290.h"
+#include "mb86a20s.h"
 
 #include "zl10353.h"
 
@@ -228,6 +229,20 @@ static struct mt352_config avermedia_xc3028_mt352_dev = {
        .demod_init      = mt352_avermedia_xc3028_init,
 };
 
+static struct tda18271_std_map mb86a20s_tda18271_std_map = {
+       .dvbt_6   = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+                     .if_lvl = 7, .rfagc_top = 0x37, },
+};
+
+static struct tda18271_config kworld_tda18271_config = {
+       .std_map = &mb86a20s_tda18271_std_map,
+       .gate    = TDA18271_GATE_DIGITAL,
+};
+
+static const struct mb86a20s_config kworld_mb86a20s_config = {
+       .demod_address = 0x10,
+};
+
 /* ==================================================================
  * tda1004x based DVB-T cards, helper functions
  */
@@ -608,6 +623,37 @@ static struct tda827x_config tda827x_cfg_2_sw42 = {
 
 /* ------------------------------------------------------------------ */
 
+static int __kworld_sbtvd_i2c_gate_ctrl(struct saa7134_dev *dev, int enable)
+{
+       unsigned char initmsg[] = {0x45, 0x97};
+       unsigned char msg_enable[] = {0x45, 0xc1};
+       unsigned char msg_disable[] = {0x45, 0x81};
+       struct i2c_msg msg = {.addr = 0x4b, .flags = 0, .buf = initmsg, .len = 2};
+
+       if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) {
+               wprintk("could not access the I2C gate\n");
+               return -EIO;
+       }
+       if (enable)
+               msg.buf = msg_enable;
+       else
+               msg.buf = msg_disable;
+       if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) {
+               wprintk("could not access the I2C gate\n");
+               return -EIO;
+       }
+       msleep(20);
+       return 0;
+}
+static int kworld_sbtvd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct saa7134_dev *dev = fe->dvb->priv;
+
+       return __kworld_sbtvd_i2c_gate_ctrl(dev, enable);
+}
+
+/* ------------------------------------------------------------------ */
+
 static struct tda1004x_config tda827x_lifeview_config = {
        .demod_address = 0x08,
        .invert        = 1,
@@ -1613,6 +1659,29 @@ static int dvb_init(struct saa7134_dev *dev)
                                   &dtv1000s_tda18271_config);
                }
                break;
+       case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
+               __kworld_sbtvd_i2c_gate_ctrl(dev, 0);
+               saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x14000);
+               saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x14000);
+               msleep(20);
+               saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x54000);
+               saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x54000);
+               msleep(20);
+               fe0->dvb.frontend = dvb_attach(mb86a20s_attach,
+                                              &kworld_mb86a20s_config,
+                                              &dev->i2c_adap);
+               __kworld_sbtvd_i2c_gate_ctrl(dev, 1);
+               if (fe0->dvb.frontend != NULL) {
+                       dvb_attach(tda18271_attach, fe0->dvb.frontend,
+                                  0x60, &dev->i2c_adap,
+                                  &kworld_tda18271_config);
+                       /*
+                        * Only after success, it can initialize the gate, otherwise
+                        * an OOPS will hit, due to kfree(fe0->dvb.frontend)
+                        */
+                       fe0->dvb.frontend->ops.i2c_gate_ctrl = kworld_sbtvd_i2c_gate_ctrl;
+               }
+               break;
        default:
                wprintk("Huh? unknown DVB card?\n");
                break;