Commit 76db93d0 authored by Michael Krufky's avatar Michael Krufky Committed by Mauro Carvalho Chehab

V4L/DVB (4846): Create new lgh06xf atsc tuner module

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: default avatarAndrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: default avatarMichael Krufky <mkrufky@linuxtv.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent f9a76156
...@@ -9,6 +9,7 @@ config DVB_B2C2_FLEXCOP ...@@ -9,6 +9,7 @@ config DVB_B2C2_FLEXCOP
select DVB_STV0297 if !DVB_FE_CUSTOMISE select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_BCM3510 if !DVB_FE_CUSTOMISE select DVB_BCM3510 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE
help help
Support for the digital TV receiver chip made by B2C2 Inc. included in Support for the digital TV receiver chip made by B2C2 Inc. included in
Technisats PCI cards and USB boxes. Technisats PCI cards and USB boxes.
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "stv0297.h" #include "stv0297.h"
#include "mt312.h" #include "mt312.h"
#include "lgdt330x.h" #include "lgdt330x.h"
#include "lg_h06xf.h" #include "lgh06xf.h"
#include "dvb-pll.h" #include "dvb-pll.h"
/* lnb control */ /* lnb control */
...@@ -303,12 +303,6 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir ...@@ -303,12 +303,6 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir
return request_firmware(fw, name, fc->dev); 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 = { static struct lgdt330x_config air2pc_atsc_hd5000_config = {
.demod_address = 0x59, .demod_address = 0x59,
.demod_chip = LGDT3303, .demod_chip = LGDT3303,
...@@ -533,7 +527,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) ...@@ -533,7 +527,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
/* try the air atsc 3nd generation (lgdt3303) */ /* try the air atsc 3nd generation (lgdt3303) */
if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_AIR_ATSC3; 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); info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
} else } else
/* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
......
config DVB_BT8XX config DVB_BT8XX
tristate "BT8xx based PCI cards" tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && I2C && VIDEO_BT848 depends on DVB_CORE && PCI && I2C && VIDEO_BT848
select DVB_PLL
select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_SP887X if !DVB_FE_CUSTOMISE select DVB_SP887X if !DVB_FE_CUSTOMISE
select DVB_NXT6000 if !DVB_FE_CUSTOMISE select DVB_NXT6000 if !DVB_FE_CUSTOMISE
select DVB_CX24110 if !DVB_FE_CUSTOMISE select DVB_CX24110 if !DVB_FE_CUSTOMISE
select DVB_OR51211 if !DVB_FE_CUSTOMISE select DVB_OR51211 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X 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 DVB_ZL10353 if !DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "dvb_frontend.h" #include "dvb_frontend.h"
#include "dvb-bt8xx.h" #include "dvb-bt8xx.h"
#include "bt878.h" #include "bt878.h"
#include "dvb-pll.h"
static int debug; static int debug;
...@@ -568,12 +567,6 @@ static struct mt352_config digitv_alps_tded4_config = { ...@@ -568,12 +567,6 @@ static struct mt352_config digitv_alps_tded4_config = {
.demod_init = digitv_alps_tded4_demod_init, .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 = { static struct lgdt330x_config tdvs_tua6034_config = {
.demod_address = 0x0e, .demod_address = 0x0e,
.demod_chip = LGDT3303, .demod_chip = LGDT3303,
...@@ -616,7 +609,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) ...@@ -616,7 +609,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
lgdt330x_reset(card); lgdt330x_reset(card);
card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
if (card->fe != NULL) { 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"); dprintk ("dvb_bt8xx: lgdt330x detected\n");
} }
break; break;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include "cx24110.h" #include "cx24110.h"
#include "or51211.h" #include "or51211.h"
#include "lgdt330x.h" #include "lgdt330x.h"
#include "lg_h06xf.h" #include "lgh06xf.h"
#include "zl10353.h" #include "zl10353.h"
struct dvb_bt8xx_card { struct dvb_bt8xx_card {
......
...@@ -98,6 +98,7 @@ config DVB_USB_CXUSB ...@@ -98,6 +98,7 @@ config DVB_USB_CXUSB
depends on DVB_USB depends on DVB_USB
select DVB_CX22702 if !DVB_FE_CUSTOMISE select DVB_CX22702 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X 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_MT352 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE
help help
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "cx22702.h" #include "cx22702.h"
#include "lgdt330x.h" #include "lgdt330x.h"
#include "lg_h06xf.h" #include "lgh06xf.h"
#include "mt352.h" #include "mt352.h"
#include "mt352_priv.h" #include "mt352_priv.h"
#include "zl10353.h" #include "zl10353.h"
...@@ -324,13 +324,6 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe) ...@@ -324,13 +324,6 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
return 0; 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 = { static struct cx22702_config cxusb_cx22702_config = {
.demod_address = 0x63, .demod_address = 0x63,
...@@ -398,7 +391,7 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) ...@@ -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) 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; return 0;
} }
......
...@@ -297,6 +297,14 @@ config DVB_TUNER_MT2060 ...@@ -297,6 +297,14 @@ config DVB_TUNER_MT2060
help help
A driver for the silicon IF tuner MT2060 from Microtune. 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" comment "Miscellaneous devices"
depends on DVB_CORE depends on DVB_CORE
......
...@@ -39,3 +39,4 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o ...@@ -39,3 +39,4 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o obj-$(CONFIG_DVB_TDA826X) += tda826x.o
obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
obj-$(CONFIG_DVB_TUA6100) += tua6100.o obj-$(CONFIG_DVB_TUA6100) += tua6100.o
obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o
/*
* 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:
*/
/* /*
* lg_h06xf.h - ATSC Tuner support for LG TDVS-H06xF * lgh06xf.h - ATSC Tuner support for LG TDVS-H06xF
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -16,49 +16,20 @@ ...@@ -16,49 +16,20 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef _LG_H06XF_H_ #ifndef _LGH06XF_H_
#define _LG_H06XF_H_ #define _LGH06XF_H_
#include "dvb-pll.h" #include "dvb_frontend.h"
static int lg_h06xf_pll_set(struct dvb_frontend* fe, struct i2c_adapter* i2c_adap, #if defined(CONFIG_DVB_TUNER_LGH06XF) || (defined(CONFIG_DVB_TUNER_LGH06XF_MODULE) && defined(MODULE))
struct dvb_frontend_parameters* params) 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);
{ {
u8 buf[4]; printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
struct i2c_msg msg = { .addr = 0x61, .flags = 0, return NULL;
.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 #endif /* CONFIG_DVB_TUNER_LGH06XF */
#endif /* _LGH06XF_H_ */
...@@ -53,6 +53,7 @@ config VIDEO_CX88_DVB ...@@ -53,6 +53,7 @@ config VIDEO_CX88_DVB
select DVB_OR51132 if !DVB_FE_CUSTOMISE select DVB_OR51132 if !DVB_FE_CUSTOMISE
select DVB_CX22702 if !DVB_FE_CUSTOMISE select DVB_CX22702 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X 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_NXT200X if !DVB_FE_CUSTOMISE
select DVB_CX24123 if !DVB_FE_CUSTOMISE select DVB_CX24123 if !DVB_FE_CUSTOMISE
select DVB_ISL6421 if !DVB_FE_CUSTOMISE select DVB_ISL6421 if !DVB_FE_CUSTOMISE
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#include "cx22702.h" #include "cx22702.h"
#include "or51132.h" #include "or51132.h"
#include "lgdt330x.h" #include "lgdt330x.h"
#include "lg_h06xf.h" #include "lgh06xf.h"
#include "nxt200x.h" #include "nxt200x.h"
#include "cx24123.h" #include "cx24123.h"
#include "isl6421.h" #include "isl6421.h"
...@@ -392,18 +392,6 @@ static int lgdt3302_tuner_set_params(struct dvb_frontend* fe, ...@@ -392,18 +392,6 @@ static int lgdt3302_tuner_set_params(struct dvb_frontend* fe,
return 0; 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) static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
{ {
struct cx8802_dev *dev= fe->dvb->priv; struct cx8802_dev *dev= fe->dvb->priv;
...@@ -719,7 +707,8 @@ static int dvb_register(struct cx8802_dev *dev) ...@@ -719,7 +707,8 @@ static int dvb_register(struct cx8802_dev *dev)
&fusionhdtv_5_gold, &fusionhdtv_5_gold,
&dev->core->i2c_adap); &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) { 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; break;
...@@ -737,7 +726,8 @@ static int dvb_register(struct cx8802_dev *dev) ...@@ -737,7 +726,8 @@ static int dvb_register(struct cx8802_dev *dev)
&pchdtv_hd5500, &pchdtv_hd5500,
&dev->core->i2c_adap); &dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) { 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; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment