From 6ea8c902e8570020863cd2257cc9c3a8fdf0cffc Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Tue, 31 Oct 2006 03:20:50 +0100 Subject: budget-ci: Inversion setting fixed for Technotrend 1500 T From: Raymond Mantchala Technotrend 1500 T card have "inverted inversion". This patch fixes that. Many thanks to Martin Zwickel from Technotrend for his confirmation and correction proposal. Signed-off-by: Raymond Mantchala Signed-off-by: Perceval Anichini Thanks-to: Martin Zwickel Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/budget-ci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index ac0cecb14..cd5ec489a 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -1035,6 +1035,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) { -- cgit v1.2.3 From cfd8831e8de9a3173cf301540aab72f0b2228731 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Tue, 31 Oct 2006 04:29:30 +0100 Subject: tda8083: support for uncorrectable blocks and bit error rate From: Christoph Haubrich Copied routines for uc blocks and BER from the removed tda80xx.c into tda8083.c. Signed-off-by: Christoph Haubrich Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/frontends/tda8083.c | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'linux/drivers/media/dvb') 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, -- cgit v1.2.3 From 2b9c9bdaea52a03d2cb74480253c8a7a69520a88 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 2 Nov 2006 19:45:13 -0300 Subject: dvb: dibx000_common-fix From: Andrew Morton Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/dibx000_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') 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); -- cgit v1.2.3 From 19a1085a8f018688d06141a9f9ce9d7b7e070c54 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 3 Nov 2006 07:14:32 -0300 Subject: tda826x: use correct max frequency From: Alexey Dobriyan sparse "defined twice" warning Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/tda826x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/tda826x.c b/linux/drivers/media/dvb/frontends/tda826x.c index eeab26bd3..34815b0b9 100644 --- a/linux/drivers/media/dvb/frontends/tda826x.c +++ b/linux/drivers/media/dvb/frontends/tda826x.c @@ -121,7 +121,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, -- cgit v1.2.3 From 699714423c7bc084d7cd158508621eb316a93373 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 8 Nov 2006 14:47:32 -0500 Subject: dib0700: Add support for Leadtek Winfast DTV Dongle (STK7700P based) From: Michael Krufky This patch adds support for the new, STK7700-based revision of the Leadtek Winfast DTV Dongle. Signed-off-by: Michal CIJOML Semler Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index 1b1598d08..1c3546d6c 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -277,6 +277,7 @@ 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) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -318,7 +319,7 @@ 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] }, @@ -339,6 +340,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..727d50039 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -129,6 +129,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 -- cgit v1.2.3 From 6de59172cca9d588a1618bdf18529db25838201b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 9 Nov 2006 15:36:44 -0500 Subject: flexcop-usb: fix debug printk From: Alexey Dobriyan .. fix debug printk. Why, oh why, one would want to do (u16 & 0xff) << 8 and print it with %02x format? Signed-off-by: Alexey Dobriyan Acked-by: Patrick Boettcher Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/b2c2/flexcop-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') 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, -- cgit v1.2.3 From 7b002be60b03a06493b32634f963bdf5c9b9d87e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 12 Nov 2006 11:02:51 -0500 Subject: dib0700: Add support for new revision of Nova-T Stick From: Stefan Traby Added support for Nova-T Stick with USB-pid: 0x7060 Signed-off-by: Stefan Traby Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 3 ++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index 1c3546d6c..4428ab322 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -278,6 +278,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { 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) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -326,7 +327,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { { 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", 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 727d50039..ec1f3b31c 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -101,6 +101,7 @@ #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_NEBULA_DIGITV 0x0201 #define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 -- cgit v1.2.3 From d240f3ce2bdbcb32ad1feb3819d03e2903ca682e Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Tue, 14 Nov 2006 10:01:47 +0200 Subject: Add alternative device ID (0xb808) for AverMedia AverTV Volar dongles. From: Jose Carlos Garcia Sogo Add alternative device ID (0xb808) for AverMedia AverTV Volar dongles. Signed-off-by: Jose Carlos Garcia Sogo Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 3 ++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index 4428ab322..2208757d9 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -279,6 +279,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { 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); @@ -331,7 +332,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { { 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", 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 ec1f3b31c..6a55ea222 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -103,6 +103,7 @@ #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 -- cgit v1.2.3 From aa7384e979fc421adb40e52474a2f54d0a0a0780 Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Thu, 16 Nov 2006 01:31:54 +0100 Subject: Added support for the Terratec Cinergy HT PCMCIA module From: Hartmut Hackmann This is a hybrid cardbus module. Besides the card support, i modified the definition names for AGC and GPIO of the tda10046. Signed-off-by: Hartmut Hackmann --- linux/drivers/media/dvb/frontends/tda1004x.c | 10 ++++++++-- linux/drivers/media/dvb/frontends/tda1004x.h | 5 +++-- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb') 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 { -- cgit v1.2.3 From 971c5ed4df1537d045161b0bffd321af79176f64 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Thu, 16 Nov 2006 21:31:04 +0000 Subject: Fix tuning on older budget DVBS cards. From: Andrew de Quincey Fixes to DISEQC on these cards inadvertently broke normal tone/voltage signalling. This restores the necessary function. Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c index e58f0391e..e28617bd5 100644 --- a/linux/drivers/media/dvb/ttpci/budget.c +++ b/linux/drivers/media/dvb/ttpci/budget.c @@ -382,6 +382,7 @@ 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; + budget->dvb_frontend->ops.set_tone = budget_set_tone; break; } break; -- cgit v1.2.3 From 2cbf04dad677697654e539a8bf0427d302d2f522 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Fri, 17 Nov 2006 01:12:40 +0000 Subject: Fix uninitialised variable in dvb_frontend_swzigzag From: Andrew de Quincey Spotted by coverity/Adrian Bunk. Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') 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 */ -- cgit v1.2.3 From f981f5cebfee55531cdf8ce208e871e83eae2780 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Fri, 17 Nov 2006 10:12:58 +0000 Subject: Patch for SATELCO EasyWatch PCI (DVB-C) From: Thomas Hamm Add support for Satelco EasyWatch PCI DVBC cards Signed-off-by: Thomas Hamm Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-av.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index 2235ff8b8..c7312420c 100644 --- a/linux/drivers/media/dvb/ttpci/budget-av.c +++ b/linux/drivers/media/dvb/ttpci/budget-av.c @@ -914,6 +914,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 +953,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,6 +1008,7 @@ 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, @@ -1242,6 +1245,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 +1264,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), -- cgit v1.2.3 From b9ecb0a4e9cc9d07ffe87c8dc9ef0b8b75ea7396 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sun, 19 Nov 2006 06:15:37 +0100 Subject: budget: diseqc_method module parameter for cards with subsystem-id 13c2:1003 From: Oliver Endriss New module parameter diseqc_method for cards with subsystem-id 13c2:1003. - 0: unreliable method, can be used by all board revisions (default) - 1: reliable method, works for newer board layouts only The parameter has no effect for cards with other subsystem-ids. Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/budget.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) mode change 100644 => 100755 linux/drivers/media/dvb/ttpci/budget.c (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c old mode 100644 new mode 100755 index e28617bd5..56f1c80de --- 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,7 +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; - budget->dvb_frontend->ops.set_tone = budget_set_tone; + 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; -- cgit v1.2.3 From d5b1dfdd38731fd13595ee828949098c7f9b62f7 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Sun, 19 Nov 2006 17:10:59 +0000 Subject: Support KNC1 DVBC cards with alternative tda10021 i2c address From: Andrew de Quincey For some reason, some of these cards have the tda10021 configured to a different address. This adds support for such cards Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-av.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index c7312420c..461e8d75b 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, +}; + @@ -1013,6 +1017,10 @@ static void frontend_init(struct budget_av *budget_av) 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; -- cgit v1.2.3 From 294d93fa8164775bbabde48a5b7cdb88a9b4c109 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 19 Nov 2006 17:45:26 -0500 Subject: create new lgh06xf atsc tuner module From: Michael Krufky 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 Signed-off-by: Michael Krufky Acked-by: Andrew de Quincey --- linux/drivers/media/dvb/b2c2/Kconfig | 1 + linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 10 +- linux/drivers/media/dvb/bt8xx/Kconfig | 2 +- linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c | 9 +- linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h | 2 +- linux/drivers/media/dvb/dvb-usb/Kconfig | 1 + linux/drivers/media/dvb/dvb-usb/cxusb.c | 11 +- linux/drivers/media/dvb/frontends/Kconfig | 8 ++ linux/drivers/media/dvb/frontends/Makefile | 1 + linux/drivers/media/dvb/frontends/lg_h06xf.h | 70 ------------ linux/drivers/media/dvb/frontends/lgh06xf.c | 145 ++++++++++++++++++++++++ linux/drivers/media/dvb/frontends/lgh06xf.h | 35 ++++++ 12 files changed, 198 insertions(+), 97 deletions(-) delete mode 100644 linux/drivers/media/dvb/frontends/lg_h06xf.h create mode 100644 linux/drivers/media/dvb/frontends/lgh06xf.c create mode 100644 linux/drivers/media/dvb/frontends/lgh06xf.h (limited to 'linux/drivers/media/dvb') 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/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/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index dfd53d5e7..bfe5691dd 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 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/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/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..8bbabd731 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgh06xf.c @@ -0,0 +1,145 @@ +/* + * 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. */ +#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(priv->i2c, &msg, 1)) != 1) { + printk(KERN_WARNING "lgh06xf: %s error " + "(addr %02x <- %02x, err = %i)\n", + __FUNCTION__, buf[0], buf[1], err); + if (err < 0) + return err; + else + return -EREMOTEIO; + } + + // calculate the frequency we set it to + for (i = 0; i < dvb_pll_lg_tdvs_h06xf.count; i++) { + if (params->frequency > dvb_pll_lg_tdvs_h06xf.entries[i].limit) + continue; + break; + } + div = (params->frequency + dvb_pll_lg_tdvs_h06xf.entries[i].offset) / + dvb_pll_lg_tdvs_h06xf.entries[i].stepsize; + priv->frequency = (div * dvb_pll_lg_tdvs_h06xf.entries[i].stepsize) - + dvb_pll_lg_tdvs_h06xf.entries[i].offset; + + return 0; +} + +static int lgh06xf_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct lgh06xf_priv *priv = fe->tuner_priv; + *frequency = priv->frequency; + return 0; +} + +static struct dvb_tuner_ops lgh06xf_tuner_ops = { + .release = lgh06xf_release, + .set_params = lgh06xf_set_params, + .get_frequency = lgh06xf_get_frequency, +}; + +struct dvb_frontend* lgh06xf_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c) +{ + struct lgh06xf_priv *priv = NULL; + + priv = kzalloc(sizeof(struct lgh06xf_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + priv->i2c = i2c; + + memcpy(&fe->ops.tuner_ops, &lgh06xf_tuner_ops, + sizeof(struct dvb_tuner_ops)); + + strlcpy(fe->ops.tuner_ops.info.name, dvb_pll_lg_tdvs_h06xf.name, + sizeof(fe->ops.tuner_ops.info.name)); + + fe->ops.tuner_ops.info.frequency_min = dvb_pll_lg_tdvs_h06xf.min; + fe->ops.tuner_ops.info.frequency_max = dvb_pll_lg_tdvs_h06xf.max; + + fe->tuner_priv = priv; + return fe; +} + +EXPORT_SYMBOL(lgh06xf_attach); + +MODULE_DESCRIPTION("LG TDVS-H06xF ATSC Tuner support"); +MODULE_AUTHOR("Michael Krufky"); +MODULE_LICENSE("GPL"); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/linux/drivers/media/dvb/frontends/lgh06xf.h b/linux/drivers/media/dvb/frontends/lgh06xf.h new file mode 100644 index 000000000..41c41fc59 --- /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_ */ -- cgit v1.2.3 From 2ae35ace4793a2030014f74c49856bbefb6f9e05 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 19 Nov 2006 17:49:11 -0500 Subject: drivers/media/dvb/frontends: kfree() cleanups From: Michael Krufky We don't have to check for NULL before kfree() Signed-off-by: Michael Krufky Acked-by: Andrew de Quincey --- linux/drivers/media/dvb/frontends/dvb-pll.c | 3 +-- linux/drivers/media/dvb/frontends/tda826x.c | 3 +-- linux/drivers/media/dvb/frontends/tua6100.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c index b7e7108ee..78114fc26 100644 --- a/linux/drivers/media/dvb/frontends/dvb-pll.c +++ b/linux/drivers/media/dvb/frontends/dvb-pll.c @@ -478,8 +478,7 @@ 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; } diff --git a/linux/drivers/media/dvb/frontends/tda826x.c b/linux/drivers/media/dvb/frontends/tda826x.c index 34815b0b9..4f01d7b47 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; } 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; } -- cgit v1.2.3 From 6ee36831242fc0257295617cf8b7de7d41c99e54 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 19 Nov 2006 20:58:19 -0500 Subject: lgh06xf: fix compiler error when not selected From: Michael Krufky fix build error: lgh06xf.h:29: error: syntax error before '{' token Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/lgh06xf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lgh06xf.h b/linux/drivers/media/dvb/frontends/lgh06xf.h index 41c41fc59..510b4bedf 100644 --- a/linux/drivers/media/dvb/frontends/lgh06xf.h +++ b/linux/drivers/media/dvb/frontends/lgh06xf.h @@ -25,7 +25,7 @@ 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); + struct i2c_adapter *i2c) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); return NULL; -- cgit v1.2.3 From 1eab1d48fccb589c82e5f4ed660a2002fff802d2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 20 Nov 2006 11:23:04 -0200 Subject: Handle errors from input_register_device() From: Dmitry Torokhov Also sprinkled some input_sync() throughout the code. Signed-off-by: Dmitry Torokhov Acked-by: Ricardo Cerqueira Acked-by: Oliver Endriss Acked-by: Andrew de Quincey Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/cinergyT2/cinergyT2.c | 13 ++++++-- linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 37 +++++++++++++-------- linux/drivers/media/dvb/ttpci/av7110_ir.c | 25 +++++++++----- linux/drivers/media/dvb/ttpci/budget-ci.c | 42 ++++++++++++++---------- linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c | 11 +++++-- 5 files changed, 85 insertions(+), 43 deletions(-) (limited to 'linux/drivers/media/dvb') 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-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/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-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index cd5ec489a..25d0dfc1f 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -143,14 +143,14 @@ static void msp430_ir_debounce(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; + input_event(dev, EV_KEY, key_map[dev->repeat_key], 0); + } else { + 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 */ } - - 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 */ + input_sync(dev); } static void msp430_ir_interrupt(unsigned long data) @@ -169,7 +169,7 @@ static void msp430_ir_interrupt(unsigned long data) return; } del_timer(&dev->timer); - input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0); + input_event(dev, EV_KEY, key_map[dev->repeat_key], 0); } if (!key_map[code]) { @@ -177,15 +177,14 @@ static void msp430_ir_interrupt(unsigned long data) return; } + input_event(dev, EV_KEY, key_map[code], 1); + input_sync(dev); + /* 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); + mod_timer(&dev->timer, jiffies + msecs_to_jiffies(350)); } } @@ -194,8 +193,9 @@ 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; + int err; - budget_ci->input_dev = input_dev = input_allocate_device(); + input_dev = input_allocate_device(); if (!input_dev) return -ENOMEM; @@ -208,10 +208,16 @@ static int msp430_ir_init(struct budget_ci *budget_ci) if (key_map[i]) set_bit(key_map[i], input_dev->keybit); - input_register_device(budget_ci->input_dev); + err = input_register_device(input_dev); + if (err) { + input_free_device(input_dev); + return err; + } input_dev->timer.function = msp430_ir_debounce; + budget_ci->input_dev = input_dev; + saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); @@ -226,8 +232,10 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - if (del_timer(&dev->timer)) - input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0); + if (del_timer(&dev->timer)) { + input_event(dev, EV_KEY, key_map[dev->repeat_key], 0); + input_sync(dev); + } input_unregister_device(dev); } 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 */ -- cgit v1.2.3 From 5c13f3be9133087a6f21f3a335aa370077cb6554 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 20 Nov 2006 14:38:42 -0500 Subject: whitespace cleanup From: Michael Krufky - adhere to 80-column limit - replace some spaces with tabs Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/dvb-pll.c | 42 ++++++++++++++++++++--------- linux/drivers/media/dvb/frontends/dvb-pll.h | 7 +++-- linux/drivers/media/dvb/ttpci/budget-av.c | 2 +- 3 files changed, 35 insertions(+), 16 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c index 78114fc26..b0785d542 100644 --- a/linux/drivers/media/dvb/frontends/dvb-pll.c +++ b/linux/drivers/media/dvb/frontends/dvb-pll.c @@ -488,7 +488,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; @@ -516,12 +517,14 @@ 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; @@ -535,7 +538,8 @@ 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; if (fe->ops.i2c_gate_ctrl) @@ -550,14 +554,18 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, struct dvb_frontend_param 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; + 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->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; @@ -573,7 +581,8 @@ 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; buf[0] = priv->pll_i2c_address; @@ -583,8 +592,10 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parame 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; + 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->bandwidth = bandwidth; return 5; @@ -613,10 +624,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; @@ -639,7 +653,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/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index 461e8d75b..8bdc90a70 100644 --- a/linux/drivers/media/dvb/ttpci/budget-av.c +++ b/linux/drivers/media/dvb/ttpci/budget-av.c @@ -835,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) -- cgit v1.2.3 From 11e47ce1e81e4caf80d0de2b8545236e67149a8f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 20 Nov 2006 14:45:29 -0500 Subject: dvb-pll: return frequency set by dvb_pll_configure() From: Michael Krufky This patch removes some duplicated code by returning the frequency set by dvb_pll_configure(), instead of recalculating it again in dvb_pll_set_params() and dvb_pll_calc_regs(). If the return value of dvb_pll_configure is less than zero, it is an error code. Otherwise, the return value is the frequency actually set by the function. Signed-off-by: Michael Krufky Acked-by: Andrew de Quincey --- linux/drivers/media/dvb/frontends/dvb-pll.c | 44 +++++++++-------------------- 1 file changed, 14 insertions(+), 30 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c index b0785d542..62de760c8 100644 --- a/linux/drivers/media/dvb/frontends/dvb-pll.c +++ b/linux/drivers/media/dvb/frontends/dvb-pll.c @@ -472,7 +472,8 @@ 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); @@ -526,9 +527,7 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, { .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; @@ -538,9 +537,11 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, 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); @@ -548,16 +549,7 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, 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; @@ -569,9 +561,7 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, { 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; @@ -582,20 +572,14 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, } if ((result = dvb_pll_configure(priv->pll_desc, buf+1, - params->frequency, bandwidth)) != 0) + 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; -- cgit v1.2.3 From 84fad7e5d89c6d848c581cfe0367f9027400bc0d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 20 Nov 2006 15:03:48 -0500 Subject: lgh06xf: use return value of dvb_pll_configure() to fill priv->frequency From: Michael Krufky In lgh06xf_set_params: Rename int variable "err" to "result". Remove needless calculation of the set frequency, since this value is now being returned by dvb_pll_configure(). Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/lgh06xf.c | 43 +++++++++++++---------------- 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/lgh06xf.c b/linux/drivers/media/dvb/frontends/lgh06xf.c index 8bbabd731..25396d199 100644 --- a/linux/drivers/media/dvb/frontends/lgh06xf.c +++ b/linux/drivers/media/dvb/frontends/lgh06xf.c @@ -40,19 +40,23 @@ static int lgh06xf_set_params(struct dvb_frontend* fe, 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; + u32 frequency; + int result; + + if ((result = dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, + params->frequency, 0)) < 0) + return result; + else + frequency = result; - 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) { + if ((result = 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; + "(addr %02x <- %02x, result = %i)\n", + __FUNCTION__, buf[0], buf[1], result); + if (result < 0) + return result; else return -EREMOTEIO; } @@ -71,26 +75,17 @@ static int lgh06xf_set_params(struct dvb_frontend* fe, #endif if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - if ((err = i2c_transfer(priv->i2c, &msg, 1)) != 1) { + if ((result = 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; + "(addr %02x <- %02x, result = %i)\n", + __FUNCTION__, buf[0], buf[1], result); + if (result < 0) + return result; 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; + priv->frequency = frequency; return 0; } -- cgit v1.2.3 From 1d3442aedeb650d29782a45b25920036c95e29a8 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Tue, 21 Nov 2006 10:34:42 +0200 Subject: Adding support for Pinnacle PCTV 400e DVB-S From: Patrick Boettcher Adding support for Pinnacle PCTV 400e DVB-S. The module name is called ttusb2, because it this device (and other Pinnacle devices) is using the USB-protocol originally used by Technotrend device. I'm suspecting Technotrend as the device-designer. Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/Kconfig | 11 +++++++++++ linux/drivers/media/dvb/dvb-usb/Makefile | 3 +++ 2 files changed, 14 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index bfe5691dd..ad5214360 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -160,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 -- cgit v1.2.3 From 7e385b9df5fa0f2d85b30da7e758739a06563650 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Tue, 21 Nov 2006 10:35:10 +0200 Subject: TDA826x I2C read with 2 messages From: Patrick Boettcher Added a dump I2C message to the TDA826x-driver to fix I2C read for identification with ttusb2-driver. Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/frontends/tda826x.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/tda826x.c b/linux/drivers/media/dvb/frontends/tda826x.c index 4f01d7b47..79f971dc5 100644 --- a/linux/drivers/media/dvb/frontends/tda826x.c +++ b/linux/drivers/media/dvb/frontends/tda826x.c @@ -132,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; -- cgit v1.2.3 From 665a2be1ea17ed99d3373f80031063fae340cfcd Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Tue, 21 Nov 2006 14:34:28 +0200 Subject: adding support for 400e (forgot the files :) ) From: Patrick Boettcher adding files is sometimes better Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/ttusb2.c | 276 +++++++++++++++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/ttusb2.h | 70 ++++++++ 2 files changed, 346 insertions(+) create mode 100644 linux/drivers/media/dvb/dvb-usb/ttusb2.c create mode 100644 linux/drivers/media/dvb/dvb-usb/ttusb2.h (limited to 'linux/drivers/media/dvb') 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 + * Copyright (c) 2003 Felix Domke + * Copyright (C) 2005-6 Patrick Boettcher + * + * 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 "); +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 + * Copyright (c) 2003 Felix Domke + * Copyright (C) 2005-6 Patrick Boettcher + * + * 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 + * + * in message (complete block is always 0x40 bytes long) + * 0x55 + * + * id is incremented for each transaction + */ + +#define CMD_DSP_DOWNLOAD 0x13 +/* out data: [28] + * last block must be empty */ + +#define CMD_DSP_BOOT 0x14 +/* out data: nothing */ + +#define CMD_POWER 0x15 +/* out data: */ + +#define CMD_LNB 0x16 +/* out data: <18V=0,13V=1> */ + +#define CMD_GET_VERSION 0x17 +/* in data: [5] */ + +#define CMD_DISEQC 0x18 +/* out data: [cmdlen] */ + +#define CMD_PID_ENABLE 0x22 +/* out data: */ + +#define CMD_PID_DISABLE 0x23 +/* out data: */ + +#define CMD_FILTER_ENABLE 0x24 +/* out data: [12] [12] */ + +#define CMD_FILTER_DISABLE 0x25 +/* out data: */ + +#define CMD_GET_DSP_VERSION 0x26 +/* in data: [28] */ + +#define CMD_I2C_XFER 0x31 +/* out data: [sndlen] + * in data: [rcvlen] */ + +#define CMD_I2C_BITRATE 0x32 +/* out data: */ + +#endif -- cgit v1.2.3 From 789537fc93581d475173b1b0741022b4a1bad857 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 20:43:38 +0000 Subject: Correct budget.c permissions From: Andrew de Quincey budget.c permissions seem to have accidentally been changed to executable - this removes that Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 linux/drivers/media/dvb/ttpci/budget.c (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c old mode 100755 new mode 100644 -- cgit v1.2.3 From 4044249adf2b23eb944b0676d182611a26f2c27d Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:01:21 +0000 Subject: Fix oops on symbol rate==0 From: Andrew de Quincey The tda10086 causes an oops (divide by zero) if a zero symbol rate is used; this prevents this. Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/frontends/tda10086.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'linux/drivers/media/dvb') 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); -- cgit v1.2.3 From 7d62f8cfb898a81f0196aee85700519aaecd27b5 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:01:28 +0000 Subject: [PATCH 1/8] budget-ci IR: groundwork for following patches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch lays down some groundwork for later budget-ci patches. The bulk of this consists of moving a few members into a new struct and renaming a few of them. It also allocates extra space for the device name (the "name" field in /proc/bus/input/devices and in the relevant sysfs dir) to avoid truncation and uses snprintf rather than sprintf in case the extra space shouldn't be enough. Taken from Darren Salt's dvb-ir patchset Signed-off-by: Darren Salt Signed-off-by: David Härdeman Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 34 +++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 25d0dfc1f..2893e7527 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -72,15 +72,19 @@ #define SLOTSTATUS_READY 8 #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) +struct budget_ci_ir { + struct input_dev *dev; + struct tasklet_struct msp430_irq_tasklet; + char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ +}; + 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 */ }; @@ -156,7 +160,7 @@ static void msp430_ir_debounce(unsigned long data) 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; + struct input_dev *dev = budget_ci->ir.dev; unsigned int code = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; @@ -191,17 +195,17 @@ static void msp430_ir_interrupt(unsigned long data) static int msp430_ir_init(struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; - struct input_dev *input_dev; + struct input_dev *input_dev = budget_ci->ir.dev; int i; int err; - input_dev = input_allocate_device(); + budget_ci->ir.dev = input_dev = input_allocate_device(); if (!input_dev) return -ENOMEM; - sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name); - - input_dev->name = budget_ci->ir_dev_name; + snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), + "Budget-CI dvb ir receiver %s", saa->name); + input_dev->name = budget_ci->ir.name; set_bit(EV_KEY, input_dev->evbit); for (i = 0; i < ARRAY_SIZE(key_map); i++) @@ -214,9 +218,9 @@ static int msp430_ir_init(struct budget_ci *budget_ci) return err; } - input_dev->timer.function = msp430_ir_debounce; + input_register_device(budget_ci->ir.dev); - budget_ci->input_dev = input_dev; + input_dev->timer.function = msp430_ir_debounce; saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); @@ -227,7 +231,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) 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); @@ -548,7 +552,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); @@ -1105,7 +1109,7 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio return err; } - tasklet_init(&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt, + tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, (unsigned long) budget_ci); msp430_ir_init(budget_ci); @@ -1134,7 +1138,7 @@ static int budget_ci_detach(struct saa7146_dev *dev) } err = ttpci_budget_deinit(&budget_ci->budget); - tasklet_kill(&budget_ci->msp430_irq_tasklet); + tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); msp430_ir_deinit(budget_ci); -- cgit v1.2.3 From f88750c2f34c88b87198cac5895b0be11a2609d2 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:01:34 +0000 Subject: [PATCH 2/8] budget-ci IR: support EVIOCGPHYS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a 'phys' string, of the same form as used by various other DVB cards' IR drivers, for access by any program which uses the EVIOCPHYS ioctl or may read /sys/class/input/*/phys (e.g. udev) to identify input device nodes. Taken from Darren Salt's dvb-ir patchset. Signed-off-by: Darren Salt Signed-off-by: David Härdeman Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 2893e7527..253b5ff8a 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -76,6 +76,7 @@ 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 budget_ci { @@ -205,8 +206,29 @@ static int msp430_ir_init(struct budget_ci *budget_ci) 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)); + input_dev->name = budget_ci->ir.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 + set_bit(EV_KEY, input_dev->evbit); for (i = 0; i < ARRAY_SIZE(key_map); i++) if (key_map[i]) -- cgit v1.2.3 From fdeda4d783d96704c5ae4a4901e9dad99f1a73c0 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:01:44 +0000 Subject: [PATCH 3/8] budget-ci IR: improve error checking in init and deinit functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve the error checking in the IR init and deinit functions. Based on Darren Salt's dvb-ir patchset. Signed-off-by: David Härdeman Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 64 ++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 23 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 253b5ff8a..ce368d5f8 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -198,11 +198,13 @@ static int msp430_ir_init(struct budget_ci *budget_ci) struct saa7146_dev *saa = budget_ci->budget.dev; struct input_dev *input_dev = budget_ci->ir.dev; int i; - int err; + int error; budget_ci->ir.dev = input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; + if (!input_dev) { + error = -ENOMEM; + goto out1; + } snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), "Budget-CI dvb ir receiver %s", saa->name); @@ -234,20 +236,30 @@ static int msp430_ir_init(struct budget_ci *budget_ci) if (key_map[i]) set_bit(key_map[i], input_dev->keybit); - err = input_register_device(input_dev); - if (err) { - input_free_device(input_dev); - return err; +#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; } - - input_register_device(budget_ci->ir.dev); +#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) @@ -257,6 +269,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) 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); @@ -1117,8 +1130,11 @@ 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 = kmalloc(sizeof(struct budget_ci), GFP_KERNEL); + if (!budget_ci) { + err = -ENOMEM; + goto out1; + } dprintk(2, "budget_ci: %p\n", budget_ci); @@ -1126,15 +1142,13 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio 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->ir.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); @@ -1144,6 +1158,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) @@ -1154,16 +1175,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->ir.msp430_irq_tasklet); - - msp430_ir_deinit(budget_ci); - // disable frontend and CI interface saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); -- cgit v1.2.3 From ed706037e5ded7b8c6eac4f54233f22f5c3546fd Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:02:32 +0000 Subject: [PATCH 4/8] budget-ci IR: be more verbose in case of init failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trivial change to help the user understand what went wrong. Taken from Darren Salt's dvb-ir patchset. Signed-off-by: Darren Salt Signed-off-by: David Härdeman Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index ce368d5f8..7d6a85827 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -202,6 +202,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) 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; } @@ -1130,7 +1131,7 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio struct budget_ci *budget_ci; int err; - budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL); + budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL); if (!budget_ci) { err = -ENOMEM; goto out1; @@ -1138,8 +1139,6 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio dprintk(2, "budget_ci: %p\n", budget_ci); - budget_ci->budget.ci_present = 0; - dev->ext_priv = budget_ci; err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE); -- cgit v1.2.3 From 225cfe3996e2ce939a1bf2e19e5746d64ebe293a Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:02:37 +0000 Subject: [PATCH 5/8] budget-ci IR: integrate with ir-common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This converts the budget-ci driver so that it uses ir-common for some of its IR processing. In particular, the keymap for the Nova-T (sub 13c2:1011) is switched to the Hauppauge grey/black keymap, of which the keys on the supplied R808 remote control form a subset. The old budget-ci keymap is moved to ir-keymaps.c and is used for other remotes. The debounce logic for buggy remotes (i.e. Zenith) is made conditional the new debounce parameter and defaults to off (so that repeat keypresses aren't ignored for all working remotes). Some parts are based on Darren Salt's dvb-ir patchset. Signed-off-by: David Härdeman Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/Kconfig | 1 + linux/drivers/media/dvb/ttpci/budget-ci.c | 138 +++++++++++++++++------------- 2 files changed, 78 insertions(+), 61 deletions(-) (limited to 'linux/drivers/media/dvb') 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/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 7d6a85827..e7313f74c 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "dvb_ca_en50221.h" #include "stv0299.h" @@ -72,11 +73,24 @@ #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 + +/* 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)"); + 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; }; struct budget_ci { @@ -89,59 +103,44 @@ struct budget_ci { 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_keyup(unsigned long data) +{ + 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->ir.dev; + static int bounces = 0; + u32 ir_key; + u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; + + if (command & 0x40) { + ir_key = command & 0x3f; + + if (ir_key != dev->repeat_key && del_timer(&dev->timer)) + /* We were still waiting for a keyup event but this is a new key */ + ir_input_nokey(dev, &budget_ci->ir.state); + + if (ir_key == dev->repeat_key && bounces > 0 && timer_pending(&dev->timer)) { + /* Ignore repeated key sequences if requested */ + bounces--; + return; + } + + if (!timer_pending(&dev->timer)) + /* New keypress */ + bounces = debounce; + + /* Prepare a keyup event sometime in the future */ + mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT)); + + /* Generate a new or repeated keypress */ + ir_input_keydown(dev, &budget_ci->ir.state, ir_key, command); + } +} static void msp430_ir_debounce(unsigned long data) { @@ -197,7 +196,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; struct input_dev *input_dev = budget_ci->ir.dev; - int i; int error; budget_ci->ir.dev = input_dev = input_allocate_device(); @@ -232,10 +230,30 @@ static int msp430_ir_init(struct budget_ci *budget_ci) # endif #endif - 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); + /* Select keymap */ + 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); + break; + default: + /* unknown remote */ + ir_input_init(input_dev, &budget_ci->ir.state, + IR_TYPE_RC5, ir_codes_budget_ci_old); + break; + } + + /* initialise the key-up timeout handler */ + input_dev->timer.function = msp430_ir_keyup; + input_dev->timer.data = (unsigned long) &budget_ci->ir; + input_dev->rep[REP_DELAY] = 1; + input_dev->rep[REP_PERIOD] = 1; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) error = input_register_device(input_dev); @@ -247,8 +265,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) 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); @@ -273,7 +289,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); if (del_timer(&dev->timer)) { - input_event(dev, EV_KEY, key_map[dev->repeat_key], 0); + ir_input_nokey(dev, &budget_ci->ir.state); input_sync(dev); } -- cgit v1.2.3 From bb8a8592ad802919c2d8b99e774a41ad7d4a02a9 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:02:46 +0000 Subject: [PATCH 6/8] budget-ci IR: decode rc5 device byte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Decode the RC5 device byte as well as the command byte. Introduce a parameter to set the device events to listen for. Default to try to auto-detect the proper device code, otherwise, listen to any device as the old code did. Based on Darren Salt's dvb-ir patchset. Signed-off-by: Darren Salt Signed-off-by: David Härdeman Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 76 ++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 17 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index e7313f74c..cb3185440 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -78,6 +78,9 @@ */ #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 */ @@ -85,12 +88,17 @@ 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)"); + 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 { @@ -114,32 +122,56 @@ static void msp430_ir_interrupt(unsigned long data) struct budget_ci *budget_ci = (struct budget_ci *) data; struct input_dev *dev = budget_ci->ir.dev; static int bounces = 0; - u32 ir_key; + 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) { ir_key = command & 0x3f; + return; + } - if (ir_key != dev->repeat_key && del_timer(&dev->timer)) - /* We were still waiting for a keyup event but this is a new key */ - ir_input_nokey(dev, &budget_ci->ir.state); + /* It's a RC5 device byte */ + device = command & 0x1f; + toggle = command & 0x20; - if (ir_key == dev->repeat_key && bounces > 0 && timer_pending(&dev->timer)) { - /* Ignore repeated key sequences if requested */ - bounces--; - return; - } + if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && budget_ci->ir.rc5_device != device) + return; - if (!timer_pending(&dev->timer)) - /* New keypress */ - bounces = debounce; + /* Are we still waiting for a keyup event while this is a new key? */ + if ((ir_key != dev->repeat_key || toggle != prev_toggle) && del_timer(&dev->timer)) + ir_input_nokey(dev, &budget_ci->ir.state); - /* Prepare a keyup event sometime in the future */ - mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT)); + prev_toggle = toggle; - /* Generate a new or repeated keypress */ - ir_input_keydown(dev, &budget_ci->ir.state, ir_key, command); + /* Ignore repeated key sequences if requested */ + if (ir_key == dev->repeat_key && bounces > 0 && timer_pending(&dev->timer)) { + bounces--; + return; } + + /* New keypress? */ + if (!timer_pending(&dev->timer)) + bounces = debounce; + + /* Prepare a keyup event sometime in the future */ + mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT)); + + /* Generate a new or repeated keypress */ + ir_input_keydown(dev, &budget_ci->ir.state, ir_key, ((device << 8) | command)); } static void msp430_ir_debounce(unsigned long data) @@ -230,7 +262,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) # endif #endif - /* Select keymap */ + /* Select keymap and address */ switch (budget_ci->budget.dev->pci->subsystem_device) { case 0x100c: case 0x100f: @@ -241,11 +273,21 @@ static int msp430_ir_init(struct budget_ci *budget_ci) /* 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; } -- cgit v1.2.3 From c6a44299a7a4152b3d9b7911985042a10a498502 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:02:54 +0000 Subject: [PATCH 7/8] budget-ci IR: add IR debugging information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a ir_debug parameter which is useful in tracking down IR decoding problems. Based on Darren Salt's dvb-ir patchset. Signed-off-by: Darren Salt Signed-off-by: David Härdeman Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index cb3185440..8ed2411d0 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -92,6 +92,10 @@ 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; @@ -140,11 +144,15 @@ static void msp430_ir_interrupt(unsigned long data) /* 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; } /* 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; -- cgit v1.2.3 From cfcc8582645e1e806642feaa6e5c0b61fea735a9 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:02:58 +0000 Subject: [PATCH 8/8] budget-ci IR: make debounce logic conditional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the debounce logic so that it is not used at all unless the debounce parameter has been set. This makes for a much "snappier" remote for most users as there is no timeout to wait for (the debounce logic has a 350ms timer for the next repeat, but with the RC5 protocol, one event per ~110ms is possible) Signed-off-by: David Härdeman Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 37 +++++++++++++++++-------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 8ed2411d0..4f28257c6 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -159,27 +159,32 @@ static void msp430_ir_interrupt(unsigned long data) if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && budget_ci->ir.rc5_device != device) return; - /* Are we still waiting for a keyup event while this is a new key? */ - if ((ir_key != dev->repeat_key || toggle != prev_toggle) && del_timer(&dev->timer)) - ir_input_nokey(dev, &budget_ci->ir.state); - - prev_toggle = toggle; - /* Ignore repeated key sequences if requested */ - if (ir_key == dev->repeat_key && bounces > 0 && timer_pending(&dev->timer)) { + 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; - /* New keypress? */ - if (!timer_pending(&dev->timer)) - bounces = debounce; + /* Are we still waiting for a keyup event? */ + if (del_timer(&dev->timer)) + ir_input_nokey(dev, &budget_ci->ir.state); - /* Prepare a keyup event sometime in the future */ - mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT)); + /* 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))); - /* Generate a new or repeated keypress */ - ir_input_keydown(dev, &budget_ci->ir.state, ir_key, ((device << 8) | command)); + /* 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 void msp430_ir_debounce(unsigned long data) @@ -299,11 +304,9 @@ static int msp430_ir_init(struct budget_ci *budget_ci) break; } - /* initialise the key-up timeout handler */ + /* initialise the key-up debounce timeout handler */ input_dev->timer.function = msp430_ir_keyup; input_dev->timer.data = (unsigned long) &budget_ci->ir; - input_dev->rep[REP_DELAY] = 1; - input_dev->rep[REP_PERIOD] = 1; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) error = input_register_device(input_dev); -- cgit v1.2.3 From cbb6c6e602c63aeeac44f3ec4567fa4ed1f91933 Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Wed, 22 Nov 2006 21:15:19 +0000 Subject: Fix TD1316 tuner for DVBC From: Thomas Kaiser If your device is using the philips tda1316 tuner, i think there is a problem in setting the correct Band. 162 MHz and above should be band 2 (Mid-Band). But in dvbc_philips_tdm1316l_tuner_set_params band 1 is set for frequencies below 200 MHz. Signed-off-by: Thomas Kaiser Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 4f28257c6..ab7c1b7fd 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -952,7 +952,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; -- cgit v1.2.3 From 93ffb66cdd656ce714aba619c5c41ec66d33009c Mon Sep 17 00:00:00 2001 From: Andrew de Quincey Date: Fri, 24 Nov 2006 15:58:42 +0000 Subject: Remove stray IR code left from patchset From: Andrew de Quincey This caused compilation to fail - completely replaced by new style functions, so can be removed. Signed-off-by: Andrew de Quincey --- linux/drivers/media/dvb/ttpci/budget-ci.c | 50 ------------------------------- 1 file changed, 50 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index ab7c1b7fd..8dae16f88 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -187,56 +187,6 @@ static void msp430_ir_interrupt(unsigned long data) } } -static void msp430_ir_debounce(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); - } else { - 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 */ - } - input_sync(dev); -} - -static void msp430_ir_interrupt(unsigned long data) -{ - struct budget_ci *budget_ci = (struct budget_ci *) data; - struct input_dev *dev = budget_ci->ir.dev; - unsigned int code = - ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; - - if (code & 0x40) { - code &= 0x3f; - - 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 (!key_map[code]) { - printk("DVB (%s): no key for %02x!\n", __FUNCTION__, code); - return; - } - - input_event(dev, EV_KEY, key_map[code], 1); - input_sync(dev); - - /* initialize debounce and repeat */ - dev->repeat_key = code; - /* Zenith remote _always_ sends 2 sequences */ - dev->rep[0] = ~0; - mod_timer(&dev->timer, jiffies + msecs_to_jiffies(350)); - } -} - static int msp430_ir_init(struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; -- cgit v1.2.3