V4L/DVB (4846): Create new lgh06xf atsc tuner module
Michael Krufky [Sun, 19 Nov 2006 22:45:26 +0000 (19:45 -0300)]
This patch creates a new atsc tuner module for the LG TDVS-H06xF ATSC tuners,
called lgh06xf.  The purpose of this change is to reduce some duplicated
code, and to allow the lgh06xf tuner code to take advantage of dvb_attach().
As a side effect, the dependency of dvb-bt8xx on dvb-pll has been removed,
since the lgh06xf module itself will use dvb-pll, while remaining optional
for the dvb-bt8xx driver through the use of DVB_FE_CUSTOMISE
Acked-by: Andrew de Quincey <adq_dvb@lidskialf.net>

Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

14 files changed:
drivers/media/dvb/b2c2/Kconfig
drivers/media/dvb/b2c2/flexcop-fe-tuner.c
drivers/media/dvb/bt8xx/Kconfig
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/bt8xx/dvb-bt8xx.h
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/frontends/Makefile
drivers/media/dvb/frontends/lg_h06xf.h [deleted file]
drivers/media/dvb/frontends/lgh06xf.c [new file with mode: 0644]
drivers/media/dvb/frontends/lgh06xf.h [new file with mode: 0644]
drivers/media/video/cx88/Kconfig
drivers/media/video/cx88/cx88-dvb.c

index a0dcd59..7987595 100644 (file)
@@ -9,6 +9,7 @@ config DVB_B2C2_FLEXCOP
        select DVB_STV0297 if !DVB_FE_CUSTOMISE
        select DVB_BCM3510 if !DVB_FE_CUSTOMISE
        select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
        help
          Support for the digital TV receiver chip made by B2C2 Inc. included in
          Technisats PCI cards and USB boxes.
index b8ba878..c2b35e3 100644 (file)
@@ -14,7 +14,7 @@
 #include "stv0297.h"
 #include "mt312.h"
 #include "lgdt330x.h"
-#include "lg_h06xf.h"
+#include "lgh06xf.h"
 #include "dvb-pll.h"
 
 /* lnb control */
@@ -303,12 +303,6 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir
        return request_firmware(fw, name, fc->dev);
 }
 
-static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
-{
-       struct flexcop_device *fc = fe->dvb->priv;
-       return lg_h06xf_pll_set(fe, &fc->i2c_adap, params);
-}
-
 static struct lgdt330x_config air2pc_atsc_hd5000_config = {
        .demod_address       = 0x59,
        .demod_chip          = LGDT3303,
@@ -533,7 +527,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
        /* try the air atsc 3nd generation (lgdt3303) */
        if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
                fc->dev_type          = FC_AIR_ATSC3;
-               fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
+               dvb_attach(lgh06xf_attach, fc->fe, &fc->i2c_adap);
                info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
        } else
        /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
index ae2ff5d..dd66b60 100644 (file)
@@ -1,13 +1,13 @@
 config DVB_BT8XX
        tristate "BT8xx based PCI cards"
        depends on DVB_CORE && PCI && I2C && VIDEO_BT848
-       select DVB_PLL
        select DVB_MT352 if !DVB_FE_CUSTOMISE
        select DVB_SP887X if !DVB_FE_CUSTOMISE
        select DVB_NXT6000 if !DVB_FE_CUSTOMISE
        select DVB_CX24110 if !DVB_FE_CUSTOMISE
        select DVB_OR51211 if !DVB_FE_CUSTOMISE
        select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
        select DVB_ZL10353 if !DVB_FE_CUSTOMISE
        select FW_LOADER
        help
index 14e69a7..80a85cb 100644 (file)
@@ -34,7 +34,6 @@
 #include "dvb_frontend.h"
 #include "dvb-bt8xx.h"
 #include "bt878.h"
-#include "dvb-pll.h"
 
 static int debug;
 
@@ -568,12 +567,6 @@ static struct mt352_config digitv_alps_tded4_config = {
        .demod_init = digitv_alps_tded4_demod_init,
 };
 
-static int tdvs_tua6034_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
-       struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
-       return lg_h06xf_pll_set(fe, card->i2c_adapter, params);
-}
-
 static struct lgdt330x_config tdvs_tua6034_config = {
        .demod_address    = 0x0e,
        .demod_chip       = LGDT3303,
@@ -616,7 +609,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
                lgdt330x_reset(card);
                card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
                if (card->fe != NULL) {
-                       card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params;
+                       dvb_attach(lgh06xf_attach, card->fe, card->i2c_adapter);
                        dprintk ("dvb_bt8xx: lgdt330x detected\n");
                }
                break;
index 4745a90..e75f417 100644 (file)
@@ -37,7 +37,7 @@
 #include "cx24110.h"
 #include "or51211.h"
 #include "lgdt330x.h"
-#include "lg_h06xf.h"
+#include "lgh06xf.h"
 #include "zl10353.h"
 
 struct dvb_bt8xx_card {
index dfd53d5..bfe5691 100644 (file)
@@ -98,6 +98,7 @@ config DVB_USB_CXUSB
        depends on DVB_USB
        select DVB_CX22702 if !DVB_FE_CUSTOMISE
        select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
        select DVB_MT352 if !DVB_FE_CUSTOMISE
        select DVB_ZL10353 if !DVB_FE_CUSTOMISE
        help
index 4e2eef8..ae039b9 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "cx22702.h"
 #include "lgdt330x.h"
-#include "lg_h06xf.h"
+#include "lgh06xf.h"
 #include "mt352.h"
 #include "mt352_priv.h"
 #include "zl10353.h"
@@ -324,13 +324,6 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
        return 0;
 }
 
-static int cxusb_lgh064f_tuner_set_params(struct dvb_frontend *fe,
-                                         struct dvb_frontend_parameters *fep)
-{
-       struct dvb_usb_adapter *adap = fe->dvb->priv;
-       return lg_h06xf_pll_set(fe, &adap->dev->i2c_adap, fep);
-}
-
 static struct cx22702_config cxusb_cx22702_config = {
        .demod_address = 0x63,
 
@@ -398,7 +391,7 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
 
 static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       adap->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params;
+       dvb_attach(lgh06xf_attach, adap->fe, &adap->dev->i2c_adap);
        return 0;
 }
 
index 7279e58..af314bb 100644 (file)
@@ -297,6 +297,14 @@ config DVB_TUNER_MT2060
        help
          A driver for the silicon IF tuner MT2060 from Microtune.
 
+config DVB_TUNER_LGH06XF
+       tristate "LG TDVS-H06xF ATSC tuner"
+       depends on DVB_CORE && I2C
+       select DVB_PLL
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the LG TDVS-H06xF ATSC tuner family.
+
 comment "Miscellaneous devices"
        depends on DVB_CORE
 
index 593152e..3fa6e5d 100644 (file)
@@ -39,3 +39,4 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o
 obj-$(CONFIG_DVB_TDA826X) += tda826x.o
 obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
 obj-$(CONFIG_DVB_TUA6100) += tua6100.o
+obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o
diff --git a/drivers/media/dvb/frontends/lg_h06xf.h b/drivers/media/dvb/frontends/lg_h06xf.h
deleted file mode 100644 (file)
index 754d51d..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  lg_h06xf.h - ATSC Tuner support for LG TDVS-H06xF
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _LG_H06XF_H_
-#define _LG_H06XF_H_
-#include "dvb-pll.h"
-
-static int lg_h06xf_pll_set(struct dvb_frontend* fe, struct i2c_adapter* i2c_adap,
-                    struct dvb_frontend_parameters* params)
-{
-       u8 buf[4];
-       struct i2c_msg msg = { .addr = 0x61, .flags = 0,
-                              .buf = buf, .len = sizeof(buf) };
-       int err;
-
-       dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) {
-               printk(KERN_WARNING "lg_h06xf: %s error "
-                       "(addr %02x <- %02x, err = %i)\n",
-                       __FUNCTION__, buf[0], buf[1], err);
-               if (err < 0)
-                       return err;
-               else
-                       return -EREMOTEIO;
-       }
-
-       /* Set the Auxiliary Byte. */
-       buf[0] = buf[2];
-       buf[0] &= ~0x20;
-       buf[0] |= 0x18;
-       buf[1] = 0x50;
-       msg.len = 2;
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) {
-               printk(KERN_WARNING "lg_h06xf: %s error "
-                       "(addr %02x <- %02x, err = %i)\n",
-                       __FUNCTION__, buf[0], buf[1], err);
-               if (err < 0)
-                       return err;
-               else
-                       return -EREMOTEIO;
-       }
-
-       return 0;
-}
-#endif
diff --git a/drivers/media/dvb/frontends/lgh06xf.c b/drivers/media/dvb/frontends/lgh06xf.c
new file mode 100644 (file)
index 0000000..badbea8
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *  lgh06xf.c - ATSC Tuner support for LG TDVS-H06xF
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dvb-pll.h"
+#include "lgh06xf.h"
+
+#define LG_H06XF_PLL_I2C_ADDR 0x61
+
+struct lgh06xf_priv {
+       struct i2c_adapter *i2c;
+       u32 frequency;
+};
+
+static int lgh06xf_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int lgh06xf_set_params(struct dvb_frontend* fe,
+                             struct dvb_frontend_parameters* params)
+{
+       struct lgh06xf_priv *priv = fe->tuner_priv;
+       u8 buf[4];
+       struct i2c_msg msg = { .addr = LG_H06XF_PLL_I2C_ADDR, .flags = 0,
+                              .buf = buf, .len = sizeof(buf) };
+       u32 div;
+       int i;
+       int err;
+
+       dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if ((err = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
+               printk(KERN_WARNING "lgh06xf: %s error "
+                      "(addr %02x <- %02x, err = %i)\n",
+                      __FUNCTION__, buf[0], buf[1], err);
+               if (err < 0)
+                       return err;
+               else
+                       return -EREMOTEIO;
+       }
+
+       /* Set the Auxiliary Byte. */
+       buf[0] = buf[2];
+       buf[0] &= ~0x20;
+       buf[0] |= 0x18;
+       buf[1] = 0x50;
+       msg.len = 2;
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if ((err = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
+               printk(KERN_WARNING "lgh06xf: %s error "
+                      "(addr %02x <- %02x, err = %i)\n",
+                      __FUNCTION__, buf[0], buf[1], err);
+               if (err < 0)
+                       return err;
+               else
+                       return -EREMOTEIO;
+       }
+
+       // calculate the frequency we set it to
+       for (i = 0; i < dvb_pll_lg_tdvs_h06xf.count; i++) {
+               if (params->frequency > dvb_pll_lg_tdvs_h06xf.entries[i].limit)
+                       continue;
+               break;
+       }
+       div = (params->frequency + dvb_pll_lg_tdvs_h06xf.entries[i].offset) /
+               dvb_pll_lg_tdvs_h06xf.entries[i].stepsize;
+       priv->frequency = (div * dvb_pll_lg_tdvs_h06xf.entries[i].stepsize) -
+               dvb_pll_lg_tdvs_h06xf.entries[i].offset;
+
+       return 0;
+}
+
+static int lgh06xf_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct lgh06xf_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static struct dvb_tuner_ops lgh06xf_tuner_ops = {
+       .release       = lgh06xf_release,
+       .set_params    = lgh06xf_set_params,
+       .get_frequency = lgh06xf_get_frequency,
+};
+
+struct dvb_frontend* lgh06xf_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter *i2c)
+{
+       struct lgh06xf_priv *priv = NULL;
+
+       priv = kzalloc(sizeof(struct lgh06xf_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->i2c = i2c;
+
+       memcpy(&fe->ops.tuner_ops, &lgh06xf_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       strlcpy(fe->ops.tuner_ops.info.name, dvb_pll_lg_tdvs_h06xf.name,
+               sizeof(fe->ops.tuner_ops.info.name));
+
+       fe->ops.tuner_ops.info.frequency_min = dvb_pll_lg_tdvs_h06xf.min;
+       fe->ops.tuner_ops.info.frequency_max = dvb_pll_lg_tdvs_h06xf.max;
+
+       fe->tuner_priv = priv;
+       return fe;
+}
+
+EXPORT_SYMBOL(lgh06xf_attach);
+
+MODULE_DESCRIPTION("LG TDVS-H06xF ATSC Tuner support");
+MODULE_AUTHOR("Michael Krufky");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/lgh06xf.h b/drivers/media/dvb/frontends/lgh06xf.h
new file mode 100644 (file)
index 0000000..41c41fc
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  lgh06xf.h - ATSC Tuner support for LG TDVS-H06xF
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LGH06XF_H_
+#define _LGH06XF_H_
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_DVB_TUNER_LGH06XF) || (defined(CONFIG_DVB_TUNER_LGH06XF_MODULE) && defined(MODULE))
+extern struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe,
+                                           struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe,
+                                                 struct i2c_adapter *i2c);
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_TUNER_LGH06XF */
+
+#endif /* _LGH06XF_H_ */
index 0f9d969..b2a66ba 100644 (file)
@@ -53,6 +53,7 @@ config VIDEO_CX88_DVB
        select DVB_OR51132 if !DVB_FE_CUSTOMISE
        select DVB_CX22702 if !DVB_FE_CUSTOMISE
        select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
        select DVB_NXT200X if !DVB_FE_CUSTOMISE
        select DVB_CX24123 if !DVB_FE_CUSTOMISE
        select DVB_ISL6421 if !DVB_FE_CUSTOMISE
index 8150c09..0266a36 100644 (file)
@@ -42,7 +42,7 @@
 #include "cx22702.h"
 #include "or51132.h"
 #include "lgdt330x.h"
-#include "lg_h06xf.h"
+#include "lgh06xf.h"
 #include "nxt200x.h"
 #include "cx24123.h"
 #include "isl6421.h"
@@ -392,18 +392,6 @@ static int lgdt3302_tuner_set_params(struct dvb_frontend* fe,
        return 0;
 }
 
-static int lgdt3303_tuner_set_params(struct dvb_frontend* fe,
-                                    struct dvb_frontend_parameters* params)
-{
-       struct cx8802_dev *dev= fe->dvb->priv;
-       struct cx88_core *core = dev->core;
-
-       /* Put the analog decoder in standby to keep it quiet */
-       cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
-
-       return lg_h06xf_pll_set(fe, &core->i2c_adap, params);
-}
-
 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
 {
        struct cx8802_dev *dev= fe->dvb->priv;
@@ -719,7 +707,8 @@ static int dvb_register(struct cx8802_dev *dev)
                                               &fusionhdtv_5_gold,
                                               &dev->core->i2c_adap);
                if (dev->dvb.frontend != NULL) {
-                       dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
+                       dvb_attach(lgh06xf_attach, dev->dvb.frontend,
+                                  &dev->core->i2c_adap);
                }
                }
                break;
@@ -737,7 +726,8 @@ static int dvb_register(struct cx8802_dev *dev)
                                               &pchdtv_hd5500,
                                               &dev->core->i2c_adap);
                if (dev->dvb.frontend != NULL) {
-                       dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
+                       dvb_attach(lgh06xf_attach, dev->dvb.frontend,
+                                  &dev->core->i2c_adap);
                }
                }
                break;