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: Andrew de Quincey <adq_dvb@lidskialf.net> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
f9a7615686
commit
76db93d03f
14 changed files with 198 additions and 106 deletions
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
139
drivers/media/dvb/frontends/lgh06xf.c
Normal file
139
drivers/media/dvb/frontends/lgh06xf.c
Normal file
|
@ -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:
|
||||
*/
|
35
drivers/media/dvb/frontends/lgh06xf.h
Normal file
35
drivers/media/dvb/frontends/lgh06xf.h
Normal file
|
@ -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_ */
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue