summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-11-28 08:03:23 -0200
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-11-28 08:03:23 -0200
commit05222402b72fa35a14adb35db4e51e55d3b72f2f (patch)
treece5a78e12fb23de330787a3d4d440433af1f6f78 /linux/drivers/media/dvb
parent87fc384f35e1ee563498df696b57b908a215a499 (diff)
parent080a587ad1c509488047ab48c14f424b3e3c2cd9 (diff)
downloadmediapointer-dvb-s2-05222402b72fa35a14adb35db4e51e55d3b72f2f.tar.gz
mediapointer-dvb-s2-05222402b72fa35a14adb35db4e51e55d3b72f2f.tar.bz2
merge: http://linuxtv.org/hg/~mkrufky/lgdt330x
From: Mauro Carvalho Chehab <mchehab@infradead.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r--linux/drivers/media/dvb/b2c2/Kconfig1
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c10
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-usb.c2
-rw-r--r--linux/drivers/media/dvb/bt8xx/Kconfig2
-rw-r--r--linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c9
-rw-r--r--linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h2
-rw-r--r--linux/drivers/media/dvb/cinergyT2/cinergyT2.c13
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Kconfig12
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--linux/drivers/media/dvb/dvb-usb/cxusb.c11
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dib0700_devices.c13
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h3
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c37
-rw-r--r--linux/drivers/media/dvb/dvb-usb/ttusb2.c276
-rw-r--r--linux/drivers/media/dvb/dvb-usb/ttusb2.h70
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig8
-rw-r--r--linux/drivers/media/dvb/frontends/Makefile1
-rw-r--r--linux/drivers/media/dvb/frontends/dibx000_common.c2
-rw-r--r--linux/drivers/media/dvb/frontends/dvb-pll.c67
-rw-r--r--linux/drivers/media/dvb/frontends/dvb-pll.h7
-rw-r--r--linux/drivers/media/dvb/frontends/lg_h06xf.h70
-rw-r--r--linux/drivers/media/dvb/frontends/lgh06xf.c140
-rw-r--r--linux/drivers/media/dvb/frontends/lgh06xf.h35
-rw-r--r--linux/drivers/media/dvb/frontends/tda1004x.c10
-rw-r--r--linux/drivers/media/dvb/frontends/tda1004x.h5
-rw-r--r--linux/drivers/media/dvb/frontends/tda10086.c4
-rw-r--r--linux/drivers/media/dvb/frontends/tda8083.c30
-rw-r--r--linux/drivers/media/dvb/frontends/tda826x.c14
-rw-r--r--linux/drivers/media/dvb/frontends/tua6100.c3
-rw-r--r--linux/drivers/media/dvb/ttpci/Kconfig1
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_ir.c25
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-av.c15
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-ci.c329
-rw-r--r--linux/drivers/media/dvb/ttpci/budget.c9
-rw-r--r--linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c11
36 files changed, 945 insertions, 307 deletions
diff --git a/linux/drivers/media/dvb/b2c2/Kconfig b/linux/drivers/media/dvb/b2c2/Kconfig
index a0dcd59da..798759589 100644
--- a/linux/drivers/media/dvb/b2c2/Kconfig
+++ b/linux/drivers/media/dvb/b2c2/Kconfig
@@ -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.
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index fbca9ed4b..a63387705 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -18,7 +18,7 @@
#endif
#include "mt312.h"
#include "lgdt330x.h"
-#include "lg_h06xf.h"
+#include "lgh06xf.h"
#include "dvb-pll.h"
/* lnb control */
@@ -307,12 +307,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,
@@ -544,7 +538,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 */
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-usb.c b/linux/drivers/media/dvb/b2c2/flexcop-usb.c
index 8d16d6e72..397d0d6a7 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -246,7 +246,7 @@ static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb,
wIndex = (chipaddr << 8 ) | addr;
deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req,
- ((wValue && 0xff) << 8),wValue >> 8,((wIndex && 0xff) << 8),wIndex >> 8);
+ wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8);
len = usb_control_msg(fc_usb->udev,pipe,
req,
diff --git a/linux/drivers/media/dvb/bt8xx/Kconfig b/linux/drivers/media/dvb/bt8xx/Kconfig
index ae2ff5dc2..dd66b60fb 100644
--- a/linux/drivers/media/dvb/bt8xx/Kconfig
+++ b/linux/drivers/media/dvb/bt8xx/Kconfig
@@ -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
diff --git a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index dfe79310a..742828084 100644
--- a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -35,7 +35,6 @@
#include "dvb_frontend.h"
#include "dvb-bt8xx.h"
#include "bt878.h"
-#include "dvb-pll.h"
static int debug;
@@ -569,12 +568,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,
@@ -617,7 +610,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;
diff --git a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index a7c1e7867..a18b98ca9 100644
--- a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -40,7 +40,7 @@
#include "cx24110.h"
#include "or51211.h"
#include "lgdt330x.h"
-#include "lg_h06xf.h"
+#include "lgh06xf.h"
#include "zl10353.h"
struct dvb_bt8xx_card {
diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c
index 90672efea..52e242d1d 100644
--- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -771,6 +771,7 @@ static void cinergyt2_query_rc (void *data)
dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
input_report_key(cinergyt2->rc_input_dev,
cinergyt2->rc_input_event, 0);
+ input_sync(cinergyt2->rc_input_dev);
cinergyt2->rc_input_event = KEY_MAX;
}
cinergyt2->rc_last_code = ~0;
@@ -808,6 +809,7 @@ static void cinergyt2_query_rc (void *data)
dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
input_report_key(cinergyt2->rc_input_dev,
cinergyt2->rc_input_event, 1);
+ input_sync(cinergyt2->rc_input_dev);
cinergyt2->rc_last_code = rc_events[n].value;
}
}
@@ -823,8 +825,9 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
{
struct input_dev *input_dev;
int i;
+ int err;
- cinergyt2->rc_input_dev = input_dev = input_allocate_device();
+ input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
@@ -842,7 +845,13 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
input_dev->keycodesize = 0;
input_dev->keycodemax = 0;
- input_register_device(cinergyt2->rc_input_dev);
+ err = input_register_device(input_dev);
+ if (err) {
+ input_free_device(input_dev);
+ return err;
+ }
+
+ cinergyt2->rc_input_dev = input_dev;
schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
return 0;
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index 3bc3a37e6..52008bc96 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -348,7 +348,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
{
- fe_status_t s;
+ fe_status_t s = 0;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
/* if we've got no parameters, just keep idling */
diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig
index dfd53d5e7..ad5214360 100644
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig
@@ -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
@@ -159,6 +160,17 @@ config DVB_USB_NOVA_T_USB2
help
Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
+config DVB_USB_TTUSB2
+ tristate "Pinnacle 400e DVB-S USB2.0 support"
+ depends on DVB_USB
+ select DVB_TDA10086 if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_TDA826X if !DVB_FE_CUSTOMISE
+ help
+ Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The
+ firmware protocol used by this module is similar to the one used by the
+ old ttusb-driver - that's why the module is called dvb-usb-ttusb2.ko.
+
config DVB_USB_DTT200U
tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
depends on DVB_USB
diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile
index e23910799..154d593bb 100644
--- a/linux/drivers/media/dvb/dvb-usb/Makefile
+++ b/linux/drivers/media/dvb/dvb-usb/Makefile
@@ -36,6 +36,9 @@ obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
dvb-usb-cxusb-objs = cxusb.o
obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
+dvb-usb-ttusb2-objs = ttusb2.o
+obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
+
dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
diff --git a/linux/drivers/media/dvb/dvb-usb/cxusb.c b/linux/drivers/media/dvb/dvb-usb/cxusb.c
index ecc764c85..e474ae657 100644
--- a/linux/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/linux/drivers/media/dvb/dvb-usb/cxusb.c
@@ -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;
}
diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 1b1598d08..2208757d9 100644
--- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -277,6 +277,9 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
{ USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) },
{ USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) },
+ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
+ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
+ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -318,18 +321,18 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 5,
+ .num_device_descs = 6,
.devices = {
{ "DiBcom STK7700P reference design",
{ &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
{ NULL },
},
{ "Hauppauge Nova-T Stick",
- { &dib0700_usb_id_table[4], NULL },
+ { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
{ NULL },
},
{ "AVerMedia AVerTV DVB-T Volar",
- { &dib0700_usb_id_table[5], NULL },
+ { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
{ NULL },
},
{ "Compro Videomate U500",
@@ -339,6 +342,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Uniwill STK7700P based (Hama and others)",
{ &dib0700_usb_id_table[7], NULL },
{ NULL },
+ },
+ { "Leadtek Winfast DTV Dongle (STK7700P based)",
+ { &dib0700_usb_id_table[8], NULL },
+ { NULL },
}
}
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 58e1a449b..6a55ea222 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -101,7 +101,9 @@
#define USB_PID_HAUPPAUGE_NOVA_T_500 0x9941
#define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950
#define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050
+#define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060
#define USB_PID_AVERMEDIA_VOLAR 0xa807
+#define USB_PID_AVERMEDIA_VOLAR_2 0xb808
#define USB_PID_NEBULA_DIGITV 0x0201
#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500
@@ -129,6 +131,7 @@
#define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7
#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025
#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
+#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
#define USB_PID_GENPIX_8PSK_COLD 0x0200
#define USB_PID_GENPIX_8PSK_WARM 0x0201
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index ed4537045..5fbb70c80 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -95,7 +95,9 @@ schedule:
int dvb_usb_remote_init(struct dvb_usb_device *d)
{
+ struct input_dev *input_dev;
int i;
+ int err;
if (d->props.rc_key_map == NULL ||
d->props.rc_query == NULL ||
@@ -105,25 +107,26 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
- d->rc_input_dev = input_allocate_device();
- if (!d->rc_input_dev)
+ input_dev = input_allocate_device();
+ if (!input_dev)
return -ENOMEM;
- d->rc_input_dev->evbit[0] = BIT(EV_KEY);
- d->rc_input_dev->keycodesize = sizeof(unsigned char);
- d->rc_input_dev->keycodemax = KEY_MAX;
- d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver";
- d->rc_input_dev->phys = d->rc_phys;
- usb_to_input_id(d->udev, &d->rc_input_dev->id);
+ input_dev->evbit[0] = BIT(EV_KEY);
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = KEY_MAX;
+ input_dev->name = "IR-receiver inside an USB DVB receiver";
+ input_dev->phys = d->rc_phys;
+ usb_to_input_id(d->udev, &input_dev->id);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
- d->rc_input_dev->cdev.dev = &d->udev->dev;
+ input_dev->cdev.dev = &d->udev->dev;
#endif
/* set the bits for the keys */
deb_rc("key map size: %d\n", d->props.rc_key_map_size);
for (i = 0; i < d->props.rc_key_map_size; i++) {
- deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
- set_bit(d->props.rc_key_map[i].event, d->rc_input_dev->keybit);
+ deb_rc("setting bit for event %d item %d\n",
+ d->props.rc_key_map[i].event, i);
+ set_bit(d->props.rc_key_map[i].event, input_dev->keybit);
}
/* Start the remote-control polling. */
@@ -131,10 +134,16 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
d->props.rc_interval = 100; /* default */
/* setting these two values to non-zero, we have to manage key repeats */
- d->rc_input_dev->rep[REP_PERIOD] = d->props.rc_interval;
- d->rc_input_dev->rep[REP_DELAY] = d->props.rc_interval + 150;
+ input_dev->rep[REP_PERIOD] = d->props.rc_interval;
+ input_dev->rep[REP_DELAY] = d->props.rc_interval + 150;
- input_register_device(d->rc_input_dev);
+ err = input_register_device(input_dev);
+ if (err) {
+ input_free_device(input_dev);
+ return err;
+ }
+
+ d->rc_input_dev = input_dev;
INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
diff --git a/linux/drivers/media/dvb/dvb-usb/ttusb2.c b/linux/drivers/media/dvb/dvb-usb/ttusb2.c
new file mode 100644
index 000000000..afc0b7efb
--- /dev/null
+++ b/linux/drivers/media/dvb/dvb-usb/ttusb2.c
@@ -0,0 +1,276 @@
+/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
+ * (e.g. Pinnacle 400e DVB-S USB2.0).
+ *
+ * The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes.
+ *
+ * TDA8263 + TDA10086
+ *
+ * I2C addresses:
+ * 0x08 - LNBP21PD - LNB power supply
+ * 0x0e - TDA10086 - Demodulator
+ * 0x50 - FX2 eeprom
+ * 0x60 - TDA8263 - Tuner
+ * 0x78 ???
+ *
+ * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
+ * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
+ * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.org>
+ *
+ * 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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#define DVB_USB_LOG_PREFIX "ttusb2"
+#include "dvb-usb.h"
+
+#include "ttusb2.h"
+
+#include "tda826x.h"
+#include "tda10086.h"
+#include "lnbp21.h"
+
+/* debug */
+static int dvb_usb_ttusb2_debug;
+#define deb_info(args...) dprintk(dvb_usb_ttusb2_debug,0x01,args)
+module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS);
+
+struct ttusb2_state {
+ u8 id;
+};
+
+static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
+ u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+ struct ttusb2_state *st = d->priv;
+ u8 s[wlen+4],r[64] = { 0 };
+ int ret = 0;
+
+ memset(s,0,wlen+4);
+
+ s[0] = 0xaa;
+ s[1] = ++st->id;
+ s[2] = cmd;
+ s[3] = wlen;
+ memcpy(&s[4],wbuf,wlen);
+
+ ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0);
+
+ if (ret != 0 ||
+ r[0] != 0x55 ||
+ r[1] != s[1] ||
+ r[2] != cmd ||
+ (rlen > 0 && r[3] != rlen)) {
+ warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
+ return -EIO;
+ }
+
+ if (rlen > 0)
+ memcpy(rbuf, &r[4], rlen);
+
+ return 0;
+}
+
+static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ static u8 obuf[60], ibuf[60];
+ int i,read;
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ if (num > 2)
+ warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+ for (i = 0; i < num; i++) {
+ read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
+
+ obuf[0] = (msg[i].addr << 1) | read;
+ obuf[1] = msg[i].len;
+
+ /* read request */
+ if (read)
+ obuf[2] = msg[i+1].len;
+ else
+ obuf[2] = 0;
+
+ memcpy(&obuf[3],msg[i].buf,msg[i].len);
+
+ if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) {
+ err("i2c transfer failed.");
+ break;
+ }
+
+ if (read) {
+ memcpy(msg[i+1].buf,&ibuf[3],msg[i+1].len);
+ i++;
+ }
+ }
+
+ mutex_unlock(&d->i2c_mutex);
+ return i;
+}
+
+static u32 ttusb2_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ttusb2_i2c_algo = {
+ .master_xfer = ttusb2_i2c_xfer,
+ .functionality = ttusb2_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static int ttusb2_identify_state (struct usb_device *udev, struct
+ dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
+ int *cold)
+{
+ *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
+ return 0;
+}
+
+static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 b = onoff;
+ ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
+ return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
+}
+
+#if 0
+static int ttusb2_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ return 0;
+}
+#endif
+
+static struct tda10086_config tda10086_config = {
+ .demod_address = 0x0e,
+ .invert = 0,
+};
+
+static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ if (usb_set_interface(adap->dev->udev,0,3) < 0)
+ err("set interface to alts=3 failed");
+
+ if ((adap->fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) {
+ deb_info("TDA10086 attach failed\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
+ deb_info("TDA8263 attach failed\n");
+ return -ENODEV;
+ }
+
+ if (dvb_attach(lnbp21_attach, adap->fe, &adap->dev->i2c_adap, 0, 0) == NULL) {
+ deb_info("LNBP21 attach failed\n");
+ return -ENODEV;
+ }
+ return 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ttusb2_properties;
+
+static int ttusb2_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf,&ttusb2_properties,THIS_MODULE,NULL);
+}
+
+static struct usb_device_id ttusb2_table [] = {
+ { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
+ {} /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, ttusb2_table);
+
+static struct dvb_usb_device_properties ttusb2_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-pctv-400e-01.fw",
+
+ .size_of_priv = sizeof(struct ttusb2_state),
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .streaming_ctrl = NULL, // ttusb2_streaming_ctrl,
+
+ .frontend_attach = ttusb2_frontend_attach,
+ .tuner_attach = ttusb2_tuner_attach,
+
+ /* parameter for the MPEG2-data transfer */
+ .stream = {
+ .type = USB_ISOC,
+ .count = 5,
+ .endpoint = 0x02,
+ .u = {
+ .isoc = {
+ .framesperurb = 4,
+ .framesize = 940,
+ .interval = 1,
+ }
+ }
+ }
+ }
+ },
+
+ .power_ctrl = ttusb2_power_ctrl,
+ .identify_state = ttusb2_identify_state,
+
+ .i2c_algo = &ttusb2_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+
+ .num_device_descs = 1,
+ .devices = {
+ { "Pinnacle 400e DVB-S USB2.0",
+ { &ttusb2_table[0], NULL },
+ { NULL },
+ },
+ }
+};
+
+static struct usb_driver ttusb2_driver = {
+ .name = "dvb_usb_ttusb2",
+ .probe = ttusb2_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = ttusb2_table,
+};
+
+/* module stuff */
+static int __init ttusb2_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&ttusb2_driver))) {
+ err("usb_register failed. Error number %d",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit ttusb2_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&ttusb2_driver);
+}
+
+module_init (ttusb2_module_init);
+module_exit (ttusb2_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/dvb-usb/ttusb2.h b/linux/drivers/media/dvb/dvb-usb/ttusb2.h
new file mode 100644
index 000000000..52a63af40
--- /dev/null
+++ b/linux/drivers/media/dvb/dvb-usb/ttusb2.h
@@ -0,0 +1,70 @@
+/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
+ * (e.g. Pinnacle 400e DVB-S USB2.0).
+ *
+ * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
+ * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
+ * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.de>
+ *
+ * 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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_TTUSB2_H_
+#define _DVB_USB_TTUSB2_H_
+
+/* TTUSB protocol
+ *
+ * always to messages (out/in)
+ * out message:
+ * 0xaa <id> <cmdbyte> <datalen> <data...>
+ *
+ * in message (complete block is always 0x40 bytes long)
+ * 0x55 <id> <cmdbyte> <datalen> <data...>
+ *
+ * id is incremented for each transaction
+ */
+
+#define CMD_DSP_DOWNLOAD 0x13
+/* out data: <byte>[28]
+ * last block must be empty */
+
+#define CMD_DSP_BOOT 0x14
+/* out data: nothing */
+
+#define CMD_POWER 0x15
+/* out data: <on=1/off=0> */
+
+#define CMD_LNB 0x16
+/* out data: <power=1> <18V=0,13V=1> <tone> <??=1> <??=1> */
+
+#define CMD_GET_VERSION 0x17
+/* in data: <version_byte>[5] */
+
+#define CMD_DISEQC 0x18
+/* out data: <master=0xff/burst=??> <cmdlen> <cmdbytes>[cmdlen] */
+
+#define CMD_PID_ENABLE 0x22
+/* out data: <index> <type: ts=1/sec=2> <pid msb> <pid lsb> */
+
+#define CMD_PID_DISABLE 0x23
+/* out data: <index> */
+
+#define CMD_FILTER_ENABLE 0x24
+/* out data: <index> <pid_idx> <filter>[12] <mask>[12] */
+
+#define CMD_FILTER_DISABLE 0x25
+/* out data: <index> */
+
+#define CMD_GET_DSP_VERSION 0x26
+/* in data: <version_byte>[28] */
+
+#define CMD_I2C_XFER 0x31
+/* out data: <addr << 1> <sndlen> <rcvlen> <data>[sndlen]
+ * in data: <addr << 1> <sndlen> <rcvlen> <data>[rcvlen] */
+
+#define CMD_I2C_BITRATE 0x32
+/* out data: <default=0> */
+
+#endif
diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig
index 7279e587e..af314bb1d 100644
--- a/linux/drivers/media/dvb/frontends/Kconfig
+++ b/linux/drivers/media/dvb/frontends/Kconfig
@@ -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
diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile
index 593152ecf..3fa6e5d32 100644
--- a/linux/drivers/media/dvb/frontends/Makefile
+++ b/linux/drivers/media/dvb/frontends/Makefile
@@ -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/linux/drivers/media/dvb/frontends/dibx000_common.c b/linux/drivers/media/dvb/frontends/dibx000_common.c
index bdc6d7a7d..1f6dc06a3 100644
--- a/linux/drivers/media/dvb/frontends/dibx000_common.c
+++ b/linux/drivers/media/dvb/frontends/dibx000_common.c
@@ -85,7 +85,7 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c
struct i2c_msg m[2 + num];
u8 tx_open[4], tx_close[4];
- memset(m,0, sizeof(struct i2c_msg) * (2 + num)),
+ memset(m,0, sizeof(struct i2c_msg) * (2 + num));
dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c
index b7e7108ee..62de760c8 100644
--- a/linux/drivers/media/dvb/frontends/dvb-pll.c
+++ b/linux/drivers/media/dvb/frontends/dvb-pll.c
@@ -472,14 +472,14 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
desc->name, div, buf[0], buf[1], buf[2], buf[3]);
- return 0;
+ // calculate the frequency we set it to
+ return (div * desc->entries[i].stepsize) - desc->entries[i].offset;
}
EXPORT_SYMBOL(dvb_pll_configure);
static int dvb_pll_release(struct dvb_frontend *fe)
{
- if (fe->tuner_priv)
- kfree(fe->tuner_priv);
+ kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
@@ -489,7 +489,8 @@ static int dvb_pll_sleep(struct dvb_frontend *fe)
struct dvb_pll_priv *priv = fe->tuner_priv;
u8 buf[4];
struct i2c_msg msg =
- { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) };
+ { .addr = priv->pll_i2c_address, .flags = 0,
+ .buf = buf, .len = sizeof(buf) };
int i;
int result;
@@ -517,16 +518,16 @@ static int dvb_pll_sleep(struct dvb_frontend *fe)
return 0;
}
-static int dvb_pll_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+static int dvb_pll_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
{
struct dvb_pll_priv *priv = fe->tuner_priv;
u8 buf[4];
struct i2c_msg msg =
- { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) };
+ { .addr = priv->pll_i2c_address, .flags = 0,
+ .buf = buf, .len = sizeof(buf) };
int result;
- u32 div;
- int i;
- u32 bandwidth = 0;
+ u32 bandwidth = 0, frequency = 0;
if (priv->i2c == NULL)
return -EINVAL;
@@ -536,8 +537,11 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
bandwidth = params->u.ofdm.bandwidth;
}
- if ((result = dvb_pll_configure(priv->pll_desc, buf, params->frequency, bandwidth)) != 0)
+ if ((result = dvb_pll_configure(priv->pll_desc, buf,
+ params->frequency, bandwidth)) < 0)
return result;
+ else
+ frequency = result;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -545,26 +549,19 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
return result;
}
- // calculate the frequency we set it to
- for (i = 0; i < priv->pll_desc->count; i++) {
- if (params->frequency > priv->pll_desc->entries[i].limit)
- continue;
- break;
- }
- div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize;
- priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset;
+ priv->frequency = frequency;
priv->bandwidth = bandwidth;
return 0;
}
-static int dvb_pll_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len)
+static int dvb_pll_calc_regs(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params,
+ u8 *buf, int buf_len)
{
struct dvb_pll_priv *priv = fe->tuner_priv;
int result;
- u32 div;
- int i;
- u32 bandwidth = 0;
+ u32 bandwidth = 0, frequency = 0;
if (buf_len < 5)
return -EINVAL;
@@ -574,18 +571,15 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parame
bandwidth = params->u.ofdm.bandwidth;
}
- if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params->frequency, bandwidth)) != 0)
+ if ((result = dvb_pll_configure(priv->pll_desc, buf+1,
+ params->frequency, bandwidth)) < 0)
return result;
+ else
+ frequency = result;
+
buf[0] = priv->pll_i2c_address;
- // calculate the frequency we set it to
- for (i = 0; i < priv->pll_desc->count; i++) {
- if (params->frequency > priv->pll_desc->entries[i].limit)
- continue;
- break;
- }
- div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize;
- priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset;
+ priv->frequency = frequency;
priv->bandwidth = bandwidth;
return 5;
@@ -614,10 +608,13 @@ static struct dvb_tuner_ops dvb_pll_tuner_ops = {
.get_bandwidth = dvb_pll_get_bandwidth,
};
-struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc)
+struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
+ struct i2c_adapter *i2c,
+ struct dvb_pll_desc *desc)
{
u8 b1 [] = { 0 };
- struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 };
+ struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD,
+ .buf = b1, .len = 1 };
struct dvb_pll_priv *priv = NULL;
int ret;
@@ -640,7 +637,9 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struc
priv->i2c = i2c;
priv->pll_desc = desc;
- memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, sizeof(struct dvb_tuner_ops));
+ memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+
strncpy(fe->ops.tuner_ops.info.name, desc->name, 128);
fe->ops.tuner_ops.info.frequency_min = desc->min;
fe->ops.tuner_ops.info.frequency_min = desc->max;
diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.h b/linux/drivers/media/dvb/frontends/dvb-pll.h
index ed5ac5a36..681186a5e 100644
--- a/linux/drivers/media/dvb/frontends/dvb-pll.h
+++ b/linux/drivers/media/dvb/frontends/dvb-pll.h
@@ -48,7 +48,7 @@ extern struct dvb_pll_desc dvb_pll_philips_td1316;
extern struct dvb_pll_desc dvb_pll_thomson_fe6600;
extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
- u32 freq, int bandwidth);
+ u32 freq, int bandwidth);
/**
* Attach a dvb-pll to the supplied frontend structure.
@@ -59,6 +59,9 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
* @param desc dvb_pll_desc to use.
* @return Frontend pointer on success, NULL on failure
*/
-extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc);
+extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
+ int pll_addr,
+ struct i2c_adapter *i2c,
+ struct dvb_pll_desc *desc);
#endif
diff --git a/linux/drivers/media/dvb/frontends/lg_h06xf.h b/linux/drivers/media/dvb/frontends/lg_h06xf.h
deleted file mode 100644
index d41e0299f..000000000
--- a/linux/drivers/media/dvb/frontends/lg_h06xf.h
+++ /dev/null
@@ -1,70 +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. */
-#if 0
- buf[2] &= ~0x20;
- buf[2] |= 0x18;
- buf[3] = 0x50;
-#else
- buf[0] = buf[2];
- buf[0] &= ~0x20;
- buf[0] |= 0x18;
- buf[1] = 0x50;
- msg.len = 2;
-#endif
- 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/linux/drivers/media/dvb/frontends/lgh06xf.c b/linux/drivers/media/dvb/frontends/lgh06xf.c
new file mode 100644
index 000000000..25396d199
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/lgh06xf.c
@@ -0,0 +1,140 @@
+/*
+ * 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 frequency;
+ int result;
+
+ if ((result = dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf,
+ params->frequency, 0)) < 0)
+ return result;
+ else
+ frequency = result;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
+ printk(KERN_WARNING "lgh06xf: %s error "
+ "(addr %02x <- %02x, result = %i)\n",
+ __FUNCTION__, buf[0], buf[1], result);
+ if (result < 0)
+ return result;
+ else
+ return -EREMOTEIO;
+ }
+
+ /* Set the Auxiliary Byte. */
+#if 0
+ buf[2] &= ~0x20;
+ buf[2] |= 0x18;
+ buf[3] = 0x50;
+#else
+ buf[0] = buf[2];
+ buf[0] &= ~0x20;
+ buf[0] |= 0x18;
+ buf[1] = 0x50;
+ msg.len = 2;
+#endif
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
+ printk(KERN_WARNING "lgh06xf: %s error "
+ "(addr %02x <- %02x, result = %i)\n",
+ __FUNCTION__, buf[0], buf[1], result);
+ if (result < 0)
+ return result;
+ else
+ return -EREMOTEIO;
+ }
+
+ priv->frequency = frequency;
+
+ 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/linux/drivers/media/dvb/frontends/lgh06xf.h b/linux/drivers/media/dvb/frontends/lgh06xf.h
new file mode 100644
index 000000000..510b4bedf
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/lgh06xf.h
@@ -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_ */
diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c
index 11e0dca9a..00e4bcd9f 100644
--- a/linux/drivers/media/dvb/frontends/tda1004x.c
+++ b/linux/drivers/media/dvb/frontends/tda1004x.c
@@ -648,18 +648,24 @@ static int tda10046_init(struct dvb_frontend* fe)
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities
break;
- case TDA10046_AGC_TDA827X:
+ case TDA10046_AGC_TDA827X_GP11:
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
break;
- case TDA10046_AGC_TDA827X_GPL:
+ case TDA10046_AGC_TDA827X_GP00:
tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
break;
+ case TDA10046_AGC_TDA827X_GP01:
+ tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
+ tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
+ tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
+ tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x62); // set AGC polarities
+ break;
}
tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
diff --git a/linux/drivers/media/dvb/frontends/tda1004x.h b/linux/drivers/media/dvb/frontends/tda1004x.h
index 605ad2dfc..ec502d71b 100644
--- a/linux/drivers/media/dvb/frontends/tda1004x.h
+++ b/linux/drivers/media/dvb/frontends/tda1004x.h
@@ -35,8 +35,9 @@ enum tda10046_agc {
TDA10046_AGC_DEFAULT, /* original configuration */
TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
- TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
- TDA10046_AGC_TDA827X_GPL, /* same as above, but GPIOs 0 */
+ TDA10046_AGC_TDA827X_GP11, /* IF AGC only, special setup for tda827x */
+ TDA10046_AGC_TDA827X_GP00, /* same as above, but GPIOs 0 */
+ TDA10046_AGC_TDA827X_GP01, /* same as above, but GPIO3=0 GPIO1=1*/
};
enum tda10046_if {
diff --git a/linux/drivers/media/dvb/frontends/tda10086.c b/linux/drivers/media/dvb/frontends/tda10086.c
index 7456b0b99..4c27a2d90 100644
--- a/linux/drivers/media/dvb/frontends/tda10086.c
+++ b/linux/drivers/media/dvb/frontends/tda10086.c
@@ -441,6 +441,10 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
dprintk ("%s\n", __FUNCTION__);
+ // check for invalid symbol rate
+ if (fe_params->u.qpsk.symbol_rate < 500000)
+ return -EINVAL;
+
// calculate the updated frequency (note: we convert from Hz->kHz)
tmp64 = tda10086_read_byte(state, 0x52);
tmp64 |= (tda10086_read_byte(state, 0x51) << 8);
diff --git a/linux/drivers/media/dvb/frontends/tda8083.c b/linux/drivers/media/dvb/frontends/tda8083.c
index 3aa45ebba..67415c9db 100644
--- a/linux/drivers/media/dvb/frontends/tda8083.c
+++ b/linux/drivers/media/dvb/frontends/tda8083.c
@@ -262,12 +262,29 @@ static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status)
if (sync & 0x10)
*status |= FE_HAS_SYNC;
+ if (sync & 0x20) /* frontend can not lock */
+ *status |= FE_TIMEDOUT;
+
if ((sync & 0x1f) == 0x1f)
*status |= FE_HAS_LOCK;
return 0;
}
+static int tda8083_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+ struct tda8083_state* state = fe->demodulator_priv;
+ int ret;
+ u8 buf[3];
+
+ if ((ret = tda8083_readregs(state, 0x0b, buf, sizeof(buf))))
+ return ret;
+
+ *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
+
+ return 0;
+}
+
static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
{
struct tda8083_state* state = fe->demodulator_priv;
@@ -288,6 +305,17 @@ static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
return 0;
}
+static int tda8083_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+ struct tda8083_state* state = fe->demodulator_priv;
+
+ *ucblocks = tda8083_readreg(state, 0x0f);
+ if (*ucblocks == 0xff)
+ *ucblocks = 0xffffffff;
+
+ return 0;
+}
+
static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
{
struct tda8083_state* state = fe->demodulator_priv;
@@ -440,6 +468,8 @@ static struct dvb_frontend_ops tda8083_ops = {
.read_status = tda8083_read_status,
.read_signal_strength = tda8083_read_signal_strength,
.read_snr = tda8083_read_snr,
+ .read_ber = tda8083_read_ber,
+ .read_ucblocks = tda8083_read_ucblocks,
.diseqc_send_master_cmd = tda8083_send_diseqc_msg,
.diseqc_send_burst = tda8083_diseqc_send_burst,
diff --git a/linux/drivers/media/dvb/frontends/tda826x.c b/linux/drivers/media/dvb/frontends/tda826x.c
index eeab26bd3..79f971dc5 100644
--- a/linux/drivers/media/dvb/frontends/tda826x.c
+++ b/linux/drivers/media/dvb/frontends/tda826x.c
@@ -42,8 +42,7 @@ struct tda826x_priv {
static int tda826x_release(struct dvb_frontend *fe)
{
- if (fe->tuner_priv)
- kfree(fe->tuner_priv);
+ kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
@@ -121,7 +120,7 @@ static struct dvb_tuner_ops tda826x_tuner_ops = {
.info = {
.name = "Philips TDA826X",
.frequency_min = 950000,
- .frequency_min = 2175000
+ .frequency_max = 2175000
},
.release = tda826x_release,
.sleep = tda826x_sleep,
@@ -133,18 +132,21 @@ struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2
{
struct tda826x_priv *priv = NULL;
u8 b1 [] = { 0, 0 };
- struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 };
+ struct i2c_msg msg[2] = {
+ { .addr = addr, .flags = 0, .buf = NULL, .len = 0 },
+ { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 }
+ };
int ret;
dprintk("%s:\n", __FUNCTION__);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- ret = i2c_transfer (i2c, &msg, 1);
+ ret = i2c_transfer (i2c, msg, 2);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
- if (ret != 1)
+ if (ret != 2)
return NULL;
if (!(b1[1] & 0x80))
return NULL;
diff --git a/linux/drivers/media/dvb/frontends/tua6100.c b/linux/drivers/media/dvb/frontends/tua6100.c
index 88554393a..6ba0029dc 100644
--- a/linux/drivers/media/dvb/frontends/tua6100.c
+++ b/linux/drivers/media/dvb/frontends/tua6100.c
@@ -43,8 +43,7 @@ struct tua6100_priv {
static int tua6100_release(struct dvb_frontend *fe)
{
- if (fe->tuner_priv)
- kfree(fe->tuner_priv);
+ kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig
index 95531a624..eec7ccf41 100644
--- a/linux/drivers/media/dvb/ttpci/Kconfig
+++ b/linux/drivers/media/dvb/ttpci/Kconfig
@@ -92,6 +92,7 @@ config DVB_BUDGET_CI
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select VIDEO_IR
help
Support for simple SAA7146 based DVB cards
(so called Budget- or Nova-PCI cards) without onboard
diff --git a/linux/drivers/media/dvb/ttpci/av7110_ir.c b/linux/drivers/media/dvb/ttpci/av7110_ir.c
index d54bbcdde..e4544ea2b 100644
--- a/linux/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/linux/drivers/media/dvb/ttpci/av7110_ir.c
@@ -48,7 +48,8 @@ static void av7110_emit_keyup(unsigned long data)
if (!data || !test_bit(data, input_dev->key))
return;
- input_event(input_dev, EV_KEY, data, !!0);
+ input_report_key(input_dev, data, 0);
+ input_sync(input_dev);
}
@@ -115,14 +116,17 @@ static void av7110_emit_key(unsigned long parm)
del_timer(&keyup_timer);
if (keyup_timer.data != keycode || new_toggle != old_toggle) {
delay_timer_finished = 0;
- input_event(input_dev, EV_KEY, keyup_timer.data, !!0);
- input_event(input_dev, EV_KEY, keycode, !0);
- } else
- if (delay_timer_finished)
- input_event(input_dev, EV_KEY, keycode, 2);
+ input_event(input_dev, EV_KEY, keyup_timer.data, 0);
+ input_event(input_dev, EV_KEY, keycode, 1);
+ input_sync(input_dev);
+ } else if (delay_timer_finished) {
+ input_event(input_dev, EV_KEY, keycode, 2);
+ input_sync(input_dev);
+ }
} else {
delay_timer_finished = 0;
- input_event(input_dev, EV_KEY, keycode, !0);
+ input_event(input_dev, EV_KEY, keycode, 1);
+ input_sync(input_dev);
}
keyup_timer.expires = jiffies + UP_TIMEOUT;
@@ -211,6 +215,7 @@ static void ir_handler(struct av7110 *av7110, u32 ircom)
int __devinit av7110_ir_init(struct av7110 *av7110)
{
static struct proc_dir_entry *e;
+ int err;
if (av_cnt >= sizeof av_list/sizeof av_list[0])
return -ENOSPC;
@@ -231,7 +236,11 @@ int __devinit av7110_ir_init(struct av7110 *av7110)
set_bit(EV_KEY, input_dev->evbit);
set_bit(EV_REP, input_dev->evbit);
input_register_keys();
- input_register_device(input_dev);
+ err = input_register_device(input_dev);
+ if (err) {
+ input_free_device(input_dev);
+ return err;
+ }
input_dev->timer.function = input_repeat_key;
e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c
index 2235ff8b8..8bdc90a70 100644
--- a/linux/drivers/media/dvb/ttpci/budget-av.c
+++ b/linux/drivers/media/dvb/ttpci/budget-av.c
@@ -655,6 +655,10 @@ static struct tda10021_config philips_cu1216_config = {
.demod_address = 0x0c,
};
+static struct tda10021_config philips_cu1216_config_altaddress = {
+ .demod_address = 0x0d,
+};
+
@@ -831,7 +835,7 @@ static int philips_sd1878_tda8261_tuner_set_params(struct dvb_frontend *fe,
return -EINVAL;
rc=dvb_pll_configure(&dvb_pll_philips_sd1878_tda8261, buf,
- params->frequency, 0);
+ params->frequency, 0);
if(rc < 0) return rc;
if (fe->ops.i2c_gate_ctrl)
@@ -914,6 +918,7 @@ static u8 read_pwm(struct budget_av *budget_av)
#define SUBID_DVBS_TV_STAR_CI 0x0016
#define SUBID_DVBS_EASYWATCH_1 0x001a
#define SUBID_DVBS_EASYWATCH 0x001e
+#define SUBID_DVBC_EASYWATCH 0x002a
#define SUBID_DVBC_KNC1 0x0020
#define SUBID_DVBC_KNC1_PLUS 0x0021
#define SUBID_DVBC_CINERGY1200 0x1156
@@ -952,6 +957,7 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBS_KNC1_PLUS:
case SUBID_DVBC_KNC1_PLUS:
case SUBID_DVBT_KNC1_PLUS:
+ case SUBID_DVBC_EASYWATCH:
saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
break;
}
@@ -1006,10 +1012,15 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBC_KNC1:
case SUBID_DVBC_KNC1_PLUS:
case SUBID_DVBC_CINERGY1200:
+ case SUBID_DVBC_EASYWATCH:
budget_av->reinitialise_demod = 1;
fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
&budget_av->budget.i2c_adap,
read_pwm(budget_av));
+ if (fe == NULL)
+ fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
+ &budget_av->budget.i2c_adap,
+ read_pwm(budget_av));
if (fe) {
budget_av->tda10021_poclkp = 1;
budget_av->tda10021_set_frontend = fe->ops.set_frontend;
@@ -1242,6 +1253,7 @@ MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
+MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
@@ -1260,6 +1272,7 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
+ MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c
index ac0cecb14..8dae16f88 100644
--- a/linux/drivers/media/dvb/ttpci/budget-ci.c
+++ b/linux/drivers/media/dvb/ttpci/budget-ci.c
@@ -37,6 +37,7 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/spinlock.h>
+#include <media/ir-common.h>
#include "dvb_ca_en50221.h"
#include "stv0299.h"
@@ -72,162 +73,228 @@
#define SLOTSTATUS_READY 8
#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
+/* Milliseconds during which key presses are regarded as key repeat and during
+ * which the debounce logic is active
+ */
+#define IR_REPEAT_TIMEOUT 350
+
+/* RC5 device wildcard */
+#define IR_DEVICE_ANY 255
+
+/* Some remotes sends multiple sequences per keypress (e.g. Zenith sends two),
+ * this setting allows the superflous sequences to be ignored
+ */
+static int debounce = 0;
+module_param(debounce, int, 0644);
+MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)");
+
+static int rc5_device = -1;
+module_param(rc5_device, int, 0644);
+MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
+
+static int ir_debug = 0;
+module_param(ir_debug, int, 0644);
+MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
+
+struct budget_ci_ir {
+ struct input_dev *dev;
+ struct tasklet_struct msp430_irq_tasklet;
+ char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
+ char phys[32];
+ struct ir_input_state state;
+ int rc5_device;
+};
+
struct budget_ci {
struct budget budget;
- struct input_dev *input_dev;
- struct tasklet_struct msp430_irq_tasklet;
struct tasklet_struct ciintf_irq_tasklet;
int slot_status;
int ci_irq;
struct dvb_ca_en50221 ca;
- char ir_dev_name[50];
+ struct budget_ci_ir ir;
u8 tuner_pll_address; /* used for philips_tdm1316l configs */
};
-/* from reading the following remotes:
- Zenith Universal 7 / TV Mode 807 / VCR Mode 837
- Hauppauge (from NOVA-CI-s box product)
- i've taken a "middle of the road" approach and note the differences
-*/
-static u16 key_map[64] = {
- /* 0x0X */
- KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8,
- KEY_9,
- KEY_ENTER,
- KEY_RED,
- KEY_POWER, /* RADIO on Hauppauge */
- KEY_MUTE,
- 0,
- KEY_A, /* TV on Hauppauge */
- /* 0x1X */
- KEY_VOLUMEUP, KEY_VOLUMEDOWN,
- 0, 0,
- KEY_B,
- 0, 0, 0, 0, 0, 0, 0,
- KEY_UP, KEY_DOWN,
- KEY_OPTION, /* RESERVED on Hauppauge */
- KEY_BREAK,
- /* 0x2X */
- KEY_CHANNELUP, KEY_CHANNELDOWN,
- KEY_PREVIOUS, /* Prev. Ch on Zenith, SOURCE on Hauppauge */
- 0, KEY_RESTART, KEY_OK,
- KEY_CYCLEWINDOWS, /* MINIMIZE on Hauppauge */
- 0,
- KEY_ENTER, /* VCR mode on Zenith */
- KEY_PAUSE,
- 0,
- KEY_RIGHT, KEY_LEFT,
- 0,
- KEY_MENU, /* FULL SCREEN on Hauppauge */
- 0,
- /* 0x3X */
- KEY_SLOW,
- KEY_PREVIOUS, /* VCR mode on Zenith */
- KEY_REWIND,
- 0,
- KEY_FASTFORWARD,
- KEY_PLAY, KEY_STOP,
- KEY_RECORD,
- KEY_TUNER, /* TV/VCR on Zenith */
- 0,
- KEY_C,
- 0,
- KEY_EXIT,
- KEY_POWER2,
- KEY_TUNER, /* VCR mode on Zenith */
- 0,
-};
-
-static void msp430_ir_debounce(unsigned long data)
+static void msp430_ir_keyup(unsigned long data)
{
- struct input_dev *dev = (struct input_dev *) data;
-
- if (dev->rep[0] == 0 || dev->rep[0] == ~0) {
- input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
- return;
- }
-
- dev->rep[0] = 0;
- dev->timer.expires = jiffies + HZ * 350 / 1000;
- add_timer(&dev->timer);
- input_event(dev, EV_KEY, key_map[dev->repeat_key], 2); /* REPEAT */
+ struct budget_ci_ir *ir = (struct budget_ci_ir *) data;
+ ir_input_nokey(ir->dev, &ir->state);
}
static void msp430_ir_interrupt(unsigned long data)
{
struct budget_ci *budget_ci = (struct budget_ci *) data;
- struct input_dev *dev = budget_ci->input_dev;
- unsigned int code =
- ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
+ struct input_dev *dev = budget_ci->ir.dev;
+ static int bounces = 0;
+ int device;
+ int toggle;
+ static int prev_toggle = -1;
+ static u32 ir_key;
+ u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
+
+ /*
+ * The msp430 chip can generate two different bytes, command and device
+ *
+ * type1: X1CCCCCC, C = command bits (0 - 63)
+ * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
+ *
+ * More than one command byte may be generated before the device byte
+ * Only when we have both, a correct keypress is generated
+ */
+
+ /* Is this a RC5 command byte? */
+ if (command & 0x40) {
+ if (ir_debug)
+ printk("budget_ci: received command byte 0x%02x\n", command);
+ ir_key = command & 0x3f;
+ return;
+ }
- if (code & 0x40) {
- code &= 0x3f;
+ /* It's a RC5 device byte */
+ if (ir_debug)
+ printk("budget_ci: received device byte 0x%02x\n", command);
+ device = command & 0x1f;
+ toggle = command & 0x20;
- if (timer_pending(&dev->timer)) {
- if (code == dev->repeat_key) {
- ++dev->rep[0];
- return;
- }
- del_timer(&dev->timer);
- input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
- }
+ if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && budget_ci->ir.rc5_device != device)
+ return;
- if (!key_map[code]) {
- printk("DVB (%s): no key for %02x!\n", __FUNCTION__, code);
- return;
- }
+ /* Ignore repeated key sequences if requested */
+ if (toggle == prev_toggle && ir_key == dev->repeat_key &&
+ bounces > 0 && timer_pending(&dev->timer)) {
+ if (ir_debug)
+ printk("budget_ci: debounce logic ignored IR command\n");
+ bounces--;
+ return;
+ }
+ prev_toggle = toggle;
+
+ /* Are we still waiting for a keyup event? */
+ if (del_timer(&dev->timer))
+ ir_input_nokey(dev, &budget_ci->ir.state);
+
+ /* Generate keypress */
+ if (ir_debug)
+ printk("budget_ci: generating keypress 0x%02x\n", ir_key);
+ ir_input_keydown(dev, &budget_ci->ir.state, ir_key, (ir_key & (command << 8)));
- /* initialize debounce and repeat */
- dev->repeat_key = code;
- /* Zenith remote _always_ sends 2 sequences */
- dev->rep[0] = ~0;
- /* 350 milliseconds */
- dev->timer.expires = jiffies + HZ * 350 / 1000;
- /* MAKE */
- input_event(dev, EV_KEY, key_map[code], !0);
- add_timer(&dev->timer);
+ /* Do we want to delay the keyup event? */
+ if (debounce) {
+ bounces = debounce;
+ mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT));
+ } else {
+ ir_input_nokey(dev, &budget_ci->ir.state);
}
}
static int msp430_ir_init(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *input_dev;
- int i;
+ struct input_dev *input_dev = budget_ci->ir.dev;
+ int error;
+
+ budget_ci->ir.dev = input_dev = input_allocate_device();
+ if (!input_dev) {
+ printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
+ error = -ENOMEM;
+ goto out1;
+ }
- budget_ci->input_dev = input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
+ snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
+ "Budget-CI dvb ir receiver %s", saa->name);
+ snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
+ "pci-%s/ir0", pci_name(saa->pci));
- sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
+ input_dev->name = budget_ci->ir.name;
- input_dev->name = budget_ci->ir_dev_name;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ input_dev->phys = budget_ci->ir.phys;
+ input_dev->id.bustype = BUS_PCI;
+ input_dev->id.version = 1;
+ if (saa->pci->subsystem_vendor) {
+ input_dev->id.vendor = saa->pci->subsystem_vendor;
+ input_dev->id.product = saa->pci->subsystem_device;
+ } else {
+ input_dev->id.vendor = saa->pci->vendor;
+ input_dev->id.product = saa->pci->device;
+ }
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+ input_dev->cdev.dev = &saa->pci->dev;
+# else
+ input_dev->dev = &saa->pci->dev;
+# endif
+#endif
+
+ /* Select keymap and address */
+ switch (budget_ci->budget.dev->pci->subsystem_device) {
+ case 0x100c:
+ case 0x100f:
+ case 0x1010:
+ case 0x1011:
+ case 0x1012:
+ case 0x1017:
+ /* The hauppauge keymap is a superset of these remotes */
+ ir_input_init(input_dev, &budget_ci->ir.state,
+ IR_TYPE_RC5, ir_codes_hauppauge_new);
+
+ if (rc5_device < 0)
+ budget_ci->ir.rc5_device = 0x1f;
+ else
+ budget_ci->ir.rc5_device = rc5_device;
+ break;
+ default:
+ /* unknown remote */
+ ir_input_init(input_dev, &budget_ci->ir.state,
+ IR_TYPE_RC5, ir_codes_budget_ci_old);
+
+ if (rc5_device < 0)
+ budget_ci->ir.rc5_device = IR_DEVICE_ANY;
+ else
+ budget_ci->ir.rc5_device = rc5_device;
+ break;
+ }
- set_bit(EV_KEY, input_dev->evbit);
- for (i = 0; i < ARRAY_SIZE(key_map); i++)
- if (key_map[i])
- set_bit(key_map[i], input_dev->keybit);
+ /* initialise the key-up debounce timeout handler */
+ input_dev->timer.function = msp430_ir_keyup;
+ input_dev->timer.data = (unsigned long) &budget_ci->ir;
- input_register_device(budget_ci->input_dev);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+ error = input_register_device(input_dev);
+ if (error) {
+ printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
+ goto out2;
+ }
+#else
+ input_register_device(input_dev);
+#endif
- input_dev->timer.function = msp430_ir_debounce;
+ tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
+ (unsigned long) budget_ci);
saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
return 0;
+
+out2:
+ input_free_device(input_dev);
+out1:
+ return error;
}
static void msp430_ir_deinit(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *dev = budget_ci->input_dev;
+ struct input_dev *dev = budget_ci->ir.dev;
saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
+ tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
- if (del_timer(&dev->timer))
- input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
+ if (del_timer(&dev->timer)) {
+ ir_input_nokey(dev, &budget_ci->ir.state);
+ input_sync(dev);
+ }
input_unregister_device(dev);
}
@@ -540,7 +607,7 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
if (*isr & MASK_06)
- tasklet_schedule(&budget_ci->msp430_irq_tasklet);
+ tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
if (*isr & MASK_10)
ttpci_budget_irq10_handler(dev, isr);
@@ -835,7 +902,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc
band = 1;
} else if (tuner_frequency < 200000000) {
cp = 6;
- band = 1;
+ band = 2;
} else if (tuner_frequency < 290000000) {
cp = 3;
band = 2;
@@ -1035,6 +1102,7 @@ static void frontend_init(struct budget_ci *budget_ci)
case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
budget_ci->tuner_pll_address = 0x60;
+ philips_tdm1316l_config.invert = 1;
budget_ci->budget.dvb_frontend =
dvb_attach(tda10046_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
if (budget_ci->budget.dvb_frontend) {
@@ -1082,24 +1150,23 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
struct budget_ci *budget_ci;
int err;
- if (!(budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL)))
- return -ENOMEM;
+ budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
+ if (!budget_ci) {
+ err = -ENOMEM;
+ goto out1;
+ }
dprintk(2, "budget_ci: %p\n", budget_ci);
- budget_ci->budget.ci_present = 0;
-
dev->ext_priv = budget_ci;
- if ((err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE))) {
- kfree(budget_ci);
- return err;
- }
-
- tasklet_init(&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt,
- (unsigned long) budget_ci);
+ err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE);
+ if (err)
+ goto out2;
- msp430_ir_init(budget_ci);
+ err = msp430_ir_init(budget_ci);
+ if (err)
+ goto out3;
ciintf_init(budget_ci);
@@ -1109,6 +1176,13 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
ttpci_budget_init_hooks(&budget_ci->budget);
return 0;
+
+out3:
+ ttpci_budget_deinit(&budget_ci->budget);
+out2:
+ kfree(budget_ci);
+out1:
+ return err;
}
static int budget_ci_detach(struct saa7146_dev *dev)
@@ -1119,16 +1193,13 @@ static int budget_ci_detach(struct saa7146_dev *dev)
if (budget_ci->budget.ci_present)
ciintf_deinit(budget_ci);
+ msp430_ir_deinit(budget_ci);
if (budget_ci->budget.dvb_frontend) {
dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
dvb_frontend_detach(budget_ci->budget.dvb_frontend);
}
err = ttpci_budget_deinit(&budget_ci->budget);
- tasklet_kill(&budget_ci->msp430_irq_tasklet);
-
- msp430_ir_deinit(budget_ci);
-
// disable frontend and CI interface
saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c
index e58f0391e..56f1c80de 100644
--- a/linux/drivers/media/dvb/ttpci/budget.c
+++ b/linux/drivers/media/dvb/ttpci/budget.c
@@ -46,6 +46,10 @@
#include "lnbp21.h"
#include "bsru6.h"
+static int diseqc_method;
+module_param(diseqc_method, int, 0444);
+MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)");
+
static void Set22K (struct budget *budget, int state)
{
struct saa7146_dev *dev=budget->dev;
@@ -382,6 +386,11 @@ static void frontend_init(struct budget *budget)
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
+ if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) {
+ budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
+ budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
+ budget->dvb_frontend->ops.set_tone = budget_set_tone;
+ }
break;
}
break;
diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index f2d18a5fb..aab71ee63 100644
--- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -253,6 +253,7 @@ static void ttusb_dec_handle_irq( struct urb *urb)
* for now lets report each signal as a key down and up*/
dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]);
input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
+ input_sync(dec->rc_input_dev);
input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
input_sync(dec->rc_input_dev);
}
@@ -1207,11 +1208,12 @@ static int ttusb_init_rc( struct ttusb_dec *dec)
struct input_dev *input_dev;
u8 b[] = { 0x00, 0x01 };
int i;
+ int err;
usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
- dec->rc_input_dev = input_dev = input_allocate_device();
+ input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM;
@@ -1225,8 +1227,13 @@ static int ttusb_init_rc( struct ttusb_dec *dec)
for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
set_bit(rc_keys[i], input_dev->keybit);
- input_register_device(input_dev);
+ err = input_register_device(input_dev);
+ if (err) {
+ input_free_device(input_dev);
+ return err;
+ }
+ dec->rc_input_dev = input_dev;
if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
printk("%s: usb_submit_urb failed\n",__FUNCTION__);
/* enable irq pipe */