From 86afdeb7375f17f8ee3bbfcb3fcad5babf2ff002 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 15 Nov 2008 21:29:11 -0500 Subject: xc5000: handle tuner reset failures properly From: Devin Heitmueller Properly handle tuner reset failures (before it was always returning success) Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/xc5000.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index e38433ec6..9f7981b29 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -191,10 +191,10 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { {"FM Radio-INPUT1", 0x0208, 0x9002} }; -static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); -static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); -static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); -static void xc5000_TunerReset(struct dvb_frontend *fe); +static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); +static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); +static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); +static int xc5000_TunerReset(struct dvb_frontend *fe); static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) { @@ -208,18 +208,12 @@ static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) ? XC_RESULT_I2C_READ_FAILURE : XC_RESULT_SUCCESS; } -static int xc_reset(struct dvb_frontend *fe) -{ - xc5000_TunerReset(fe); - return XC_RESULT_SUCCESS; -} - static void xc_wait(int wait_ms) { msleep(wait_ms); } -static void xc5000_TunerReset(struct dvb_frontend *fe) +static int xc5000_TunerReset(struct dvb_frontend *fe) { struct xc5000_priv *priv = fe->tuner_priv; int ret; @@ -232,10 +226,15 @@ static void xc5000_TunerReset(struct dvb_frontend *fe) priv->i2c_props.adap->algo_data, DVB_FRONTEND_COMPONENT_TUNER, XC5000_TUNER_RESET, 0); - if (ret) + if (ret) { printk(KERN_ERR "xc5000: reset failed\n"); - } else + return XC_RESULT_RESET_FAILURE; + } + } else { printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n"); + return XC_RESULT_RESET_FAILURE; + } + return XC_RESULT_SUCCESS; } static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) @@ -309,7 +308,7 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; if (len == 0x0000) { /* RESET command */ - result = xc_reset(fe); + result = xc5000_TunerReset(fe); index += 2; if (result != XC_RESULT_SUCCESS) return result; -- cgit v1.2.3 From dae6cf7668ce870a676f7770d4ff930566b8ea2c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 16 Nov 2008 18:17:14 -0500 Subject: xc5000: cleanup i2c read routines From: Devin Heitmueller This patch centralizes the i2c read functions, and eliminates pass-through function only called by one caller. Make reading of xc5000 registers an atomic i2c transaction in case we're on a multi-master bus. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/xc5000.c | 62 ++++++++++-------------------- 1 file changed, 20 insertions(+), 42 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index 9f7981b29..f199e2995 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -193,7 +193,7 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); -static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); +static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val); static int xc5000_TunerReset(struct dvb_frontend *fe); static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) @@ -202,10 +202,19 @@ static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) ? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS; } +/* This routine is never used because the only time we read data from the + i2c bus is when we read registers, and we want that to be an atomic i2c + transaction in case we are on a multi-master bus */ static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) { - return xc5000_readregs(priv, buf, len) - ? XC_RESULT_I2C_READ_FAILURE : XC_RESULT_SUCCESS; + struct i2c_msg msg = { .addr = priv->i2c_props.addr, + .flags = I2C_M_RD, .buf = buf, .len = len }; + + if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { + printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len); + return -EREMOTEIO; + } + return 0; } static void xc_wait(int wait_ms) @@ -275,25 +284,6 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) return result; } -static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData) -{ - u8 buf[2]; - int result; - - buf[0] = (regAddr >> 8) & 0xFF; - buf[1] = regAddr & 0xFF; - result = xc_send_i2c_data(priv, buf, 2); - if (result != XC_RESULT_SUCCESS) - return result; - - result = xc_read_i2c_data(priv, buf, 2); - if (result != XC_RESULT_SUCCESS) - return result; - - *i2cData = buf[0] * 256 + buf[1]; - return result; -} - static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) { struct xc5000_priv *priv = fe->tuner_priv; @@ -442,7 +432,7 @@ static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz) static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) { - return xc_read_reg(priv, XREG_ADC_ENV, adc_envelope); + return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope); } static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) @@ -451,7 +441,7 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) u16 regData; u32 tmp; - result = xc_read_reg(priv, XREG_FREQ_ERROR, ®Data); + result = xc5000_readreg(priv, XREG_FREQ_ERROR, ®Data); if (result) return result; @@ -462,7 +452,7 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status) { - return xc_read_reg(priv, XREG_LOCK, lock_status); + return xc5000_readreg(priv, XREG_LOCK, lock_status); } static int xc_get_version(struct xc5000_priv *priv, @@ -472,7 +462,7 @@ static int xc_get_version(struct xc5000_priv *priv, u16 data; int result; - result = xc_read_reg(priv, XREG_VERSION, &data); + result = xc5000_readreg(priv, XREG_VERSION, &data); if (result) return result; @@ -489,7 +479,7 @@ static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) u16 regData; int result; - result = xc_read_reg(priv, XREG_HSYNC_FREQ, ®Data); + result = xc5000_readreg(priv, XREG_HSYNC_FREQ, ®Data); if (result) return result; @@ -499,12 +489,12 @@ static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines) { - return xc_read_reg(priv, XREG_FRAME_LINES, frame_lines); + return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines); } static int xc_get_quality(struct xc5000_priv *priv, u16 *quality) { - return xc_read_reg(priv, XREG_QUALITY, quality); + return xc5000_readreg(priv, XREG_QUALITY, quality); } static u16 WaitForLock(struct xc5000_priv *priv) @@ -554,7 +544,7 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val) } *val = (bval[0] << 8) | bval[1]; - return 0; + return XC_RESULT_SUCCESS; } static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) @@ -570,18 +560,6 @@ static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) return 0; } -static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len) -{ - struct i2c_msg msg = { .addr = priv->i2c_props.addr, - .flags = I2C_M_RD, .buf = buf, .len = len }; - - if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { - printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len); - return -EREMOTEIO; - } - return 0; -} - static int xc5000_fwupload(struct dvb_frontend *fe) { struct xc5000_priv *priv = fe->tuner_priv; -- cgit v1.2.3 From 41e77d1f0a36b105066e184a540cbd98e4f7caf0 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 16 Nov 2008 18:20:06 -0500 Subject: xc5000: cleanup i2c write routines From: Devin Heitmueller Cleanup the i2c write routine, getting rid of a passthrough function with only one caller Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/xc5000.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index f199e2995..2945075d5 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -192,14 +192,19 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { }; static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); -static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val); static int xc5000_TunerReset(struct dvb_frontend *fe); static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) { - return xc5000_writeregs(priv, buf, len) - ? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS; + struct i2c_msg msg = { .addr = priv->i2c_props.addr, + .flags = 0, .buf = buf, .len = len }; + + if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { + printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len); + return XC_RESULT_I2C_WRITE_FAILURE; + } + return XC_RESULT_SUCCESS; } /* This routine is never used because the only time we read data from the @@ -547,19 +552,6 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val) return XC_RESULT_SUCCESS; } -static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) -{ - struct i2c_msg msg = { .addr = priv->i2c_props.addr, - .flags = 0, .buf = buf, .len = len }; - - if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { - printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", - (int)len); - return -EREMOTEIO; - } - return 0; -} - static int xc5000_fwupload(struct dvb_frontend *fe) { struct xc5000_priv *priv = fe->tuner_priv; -- cgit v1.2.3 From 2615510561f94f4ed387ebad1dd5896e2a62ab60 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 16 Nov 2008 18:23:19 -0500 Subject: xc5000: check xc5000_readreg return value for XC_RESULT_SUCCESS From: Devin Heitmueller Make return value checking for calls to i2c routines explicit. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/xc5000.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index 2945075d5..0b2602d84 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -447,7 +447,7 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) u32 tmp; result = xc5000_readreg(priv, XREG_FREQ_ERROR, ®Data); - if (result) + if (result != XC_RESULT_SUCCESS) return result; tmp = (u32)regData; @@ -468,7 +468,7 @@ static int xc_get_version(struct xc5000_priv *priv, int result; result = xc5000_readreg(priv, XREG_VERSION, &data); - if (result) + if (result != XC_RESULT_SUCCESS) return result; (*hw_majorversion) = (data >> 12) & 0x0F; @@ -485,7 +485,7 @@ static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) int result; result = xc5000_readreg(priv, XREG_HSYNC_FREQ, ®Data); - if (result) + if (result != XC_RESULT_SUCCESS) return result; (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100; @@ -979,7 +979,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, /* Check if firmware has been loaded. It is possible that another instance of the driver has loaded the firmware. */ - if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) + if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS) goto fail; switch (id) { -- cgit v1.2.3 From 34741e4ed101a3989335c03aaaa0c0e7d20f3e94 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 16 Nov 2008 18:41:07 -0500 Subject: xc5000: restore sleep routine From: Devin Heitmueller Bring back the code that puts the xc5000 to sleep. For the Pinnacle 801e this results in power consumption at idle dropping from 325ma to 124ma. If there are *actually* any devices that don't work in this configuration, they should set dvb_frontend.ops.tuner_ops.sleep to NULL (per mkrufky's suggestion) Also, had to make sure we were making sure the firmware was loaded in the digital version of set_params, or else we end up get i2c errors if the device is asleep Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/xc5000.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index 0b2602d84..20e54014a 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -191,6 +191,7 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { {"FM Radio-INPUT1", 0x0208, 0x9002} }; +static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val); static int xc5000_TunerReset(struct dvb_frontend *fe); @@ -365,15 +366,6 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, return ret; } -static int xc_shutdown(struct xc5000_priv *priv) -{ - return XC_RESULT_SUCCESS; - /* Fixme: cannot bring tuner back alive once shutdown - * without reloading the driver modules. - * return xc_write_reg(priv, XREG_POWER_DOWN, 0); - */ -} - static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) { dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, @@ -636,6 +628,9 @@ static int xc5000_set_params(struct dvb_frontend *fe, struct xc5000_priv *priv = fe->tuner_priv; int ret; + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) + xc_load_fw_and_init_tuner(fe); + dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); switch (params->u.vsb.modulation) { @@ -713,8 +708,6 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe) return ret; } -static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); - static int xc5000_set_analog_params(struct dvb_frontend *fe, struct analog_parameters *params) { @@ -868,13 +861,7 @@ static int xc5000_sleep(struct dvb_frontend *fe) dprintk(1, "%s()\n", __func__); - /* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized - * once shutdown without reloading the driver. Maybe I am not - * doing something right. - * - */ - - ret = xc_shutdown(priv); + ret = xc_write_reg(priv, XREG_POWER_DOWN, 0); if (ret != XC_RESULT_SUCCESS) { printk(KERN_ERR "xc5000: %s() unable to shutdown tuner\n", -- cgit v1.2.3 From c48b2e1ef1551ce2b3985730c76b1aa97f653b1b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 16 Nov 2008 18:48:31 -0500 Subject: xc5000: do not sleep after digital tuning From: Devin Heitmueller Don't sleep for 400ms polling the tuner's lock if in digital mode (since the xc5000 lock status registers appear to only be reliable in analog mode) Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/common/tuners/xc5000.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index 20e54014a..42836d695 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -509,7 +509,9 @@ static u16 WaitForLock(struct xc5000_priv *priv) return lockState; } -static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz) +#define XC_TUNE_ANALOG 0 +#define XC_TUNE_DIGITAL 1 +static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode) { int found = 0; @@ -518,8 +520,10 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz) if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) return 0; - if (WaitForLock(priv) == 1) - found = 1; + if (mode == XC_TUNE_ANALOG) { + if (WaitForLock(priv) == 1) + found = 1; + } return found; } @@ -681,7 +685,7 @@ static int xc5000_set_params(struct dvb_frontend *fe, return -EIO; } - xc_tune_channel(priv, priv->freq_hz); + xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL); if (debug) xc_debug_dump(priv); @@ -788,7 +792,7 @@ tune_channel: return -EREMOTEIO; } - xc_tune_channel(priv, priv->freq_hz); + xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); if (debug) xc_debug_dump(priv); -- cgit v1.2.3 From 02073646971a4917cfe3ff0ccb4a85fd126dab6e Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Thu, 2 Apr 2009 20:50:11 -0400 Subject: xc5000: switch to new version of Xceive firmware From: Devin Heitmueller This switches to a new version of the xc5000 firmware, extracted from the latest Hauppauge driver. It includes the support for the XREG_BUSY register (a lack of which was causing tuning to take 3200ms instead of around 300ms). Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/xc5000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index 42836d695..8583689f9 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -42,8 +42,8 @@ static LIST_HEAD(hybrid_tuner_instance_list); #define dprintk(level, fmt, arg...) if (debug >= level) \ printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) -#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" -#define XC5000_DEFAULT_FIRMWARE_SIZE 12332 +#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.4.68.fw" +#define XC5000_DEFAULT_FIRMWARE_SIZE 12378 struct xc5000_priv { struct tuner_i2c_props i2c_props; -- cgit v1.2.3 From 8045b10212368c3a790397140241fedb87693641 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Thu, 2 Apr 2009 21:02:39 -0400 Subject: xc5000: Properly support power down for newer firmware From: Devin Heitmueller Xceive got rid of the XREG_POWER_DOWN register in later firmware revisions. Their technical support informed me that the correct way to put the tuner to sleep is to pull the reset pin (but don't reload the firmware). Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/xc5000.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index 8583689f9..2ca2cba6d 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -83,7 +83,7 @@ struct xc5000_priv { #define XREG_D_CODE 0x04 #define XREG_IF_OUT 0x05 #define XREG_SEEK_MODE 0x07 -#define XREG_POWER_DOWN 0x0A +#define XREG_POWER_DOWN 0x0A /* Obsolete */ #define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ #define XREG_SMOOTHEDCVBS 0x0E #define XREG_XTALFREQ 0x0F @@ -860,12 +860,14 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) static int xc5000_sleep(struct dvb_frontend *fe) { - struct xc5000_priv *priv = fe->tuner_priv; int ret; dprintk(1, "%s()\n", __func__); - ret = xc_write_reg(priv, XREG_POWER_DOWN, 0); + /* According to Xceive technical support, the "powerdown" register + was removed in newer versions of the firmware. The "supported" + way to sleep the tuner is to pull the reset pin low for 10ms */ + ret = xc5000_TunerReset(fe); if (ret != XC_RESULT_SUCCESS) { printk(KERN_ERR "xc5000: %s() unable to shutdown tuner\n", -- cgit v1.2.3 From 56b45a9ffa2227538376556bb0536b1ef932ab33 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Thu, 2 Apr 2009 21:24:38 -0400 Subject: xc5000: add build version to debug info From: Devin Heitmueller Expose the firmware build number along with the other version info Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/xc5000.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index 2ca2cba6d..e35d4d888 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -100,6 +100,7 @@ struct xc5000_priv { #define XREG_VERSION 0x07 #define XREG_PRODUCT_ID 0x08 #define XREG_BUSY 0x09 +#define XREG_BUILD 0x0D /* Basic firmware description. This will remain with @@ -471,6 +472,11 @@ static int xc_get_version(struct xc5000_priv *priv, return 0; } +static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev) +{ + return xc5000_readreg(priv, XREG_BUILD, buildrev); +} + static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) { u16 regData; @@ -593,6 +599,7 @@ static void xc_debug_dump(struct xc5000_priv *priv) u16 quality; u8 hw_majorversion = 0, hw_minorversion = 0; u8 fw_majorversion = 0, fw_minorversion = 0; + u16 fw_buildversion = 0; /* Wait for stats to stabilize. * Frame Lines needs two frame times after initial lock @@ -612,9 +619,10 @@ static void xc_debug_dump(struct xc5000_priv *priv) xc_get_version(priv, &hw_majorversion, &hw_minorversion, &fw_majorversion, &fw_minorversion); - dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n", + xc_get_buildversion(priv, &fw_buildversion); + dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n", hw_majorversion, hw_minorversion, - fw_majorversion, fw_minorversion); + fw_majorversion, fw_minorversion, fw_buildversion); xc_get_hsync_freq(priv, &hsync_freq_hz); dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz); -- cgit v1.2.3 From 327592abb68b0a7f1598ea2e5ffbc770cf1411f5 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Thu, 2 Apr 2009 21:40:29 -0400 Subject: xc5000: start using the newer "finerfreq" tuning command From: Devin Heitmueller Starting in firmware version 1.1.44, Xceive recommends using the FINERFREQ for all normal tuning (the doc indicates reg 0x03 should only be used for fast scanning for channel lock) Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/xc5000.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index e35d4d888..d90bcbe78 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -87,7 +87,7 @@ struct xc5000_priv { #define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ #define XREG_SMOOTHEDCVBS 0x0E #define XREG_XTALFREQ 0x0F -#define XREG_FINERFFREQ 0x10 +#define XREG_FINERFREQ 0x10 #define XREG_DDIMODE 0x11 #define XREG_ADC_ENV 0x00 @@ -395,22 +395,14 @@ static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz) freq_code = (u16)(freq_hz / 15625); - return xc_write_reg(priv, XREG_RF_FREQ, freq_code); + /* Starting in firmware version 1.1.44, Xceive recommends using the + FINERFREQ for all normal tuning (the doc indicates reg 0x03 should + only be used for fast scanning for channel lock) */ + return xc_write_reg(priv, XREG_FINERFREQ, freq_code); } #if 0 /* We'll probably need these for analog support */ -static int xc_FineTune_RF_frequency(struct xc5000_priv *priv, u32 freq_hz) -{ - u16 freq_code = (u16)(freq_hz / 15625); - - if ((freq_hz > xc5000_tuner_ops.info.frequency_max) || - (freq_hz < xc5000_tuner_ops.info.frequency_min)) - return XC_RESULT_OUT_OF_RANGE; - - return xc_write_reg(priv, XREG_FINERFFREQ, freq_code); -} - static int xc_set_Xtal_frequency(struct xc5000_priv *priv, u32 xtalFreqInKHz) { u16 xtalRatio = (32000 * 0x8000)/xtalFreqInKHz; -- cgit v1.2.3 From 72c6b08f362a4159baccf0956151cf54f0f25e2e Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Thu, 2 Apr 2009 21:45:17 -0400 Subject: xc5000: cleanup firmware loading messages From: Devin Heitmueller Make it a little more obvious in the dmesg output what is going on during firmware upload. This is more important for boards like the HVR-950q that take nearly seven seconds to do the upload. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/xc5000.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index d90bcbe78..4045b2d50 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -563,7 +563,7 @@ static int xc5000_fwupload(struct dvb_frontend *fe) ret = XC_RESULT_RESET_FAILURE; goto out; } else { - printk(KERN_INFO "xc5000: firmware read %Zu bytes.\n", + printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n", fw->size); ret = XC_RESULT_SUCCESS; } @@ -572,8 +572,9 @@ static int xc5000_fwupload(struct dvb_frontend *fe) printk(KERN_ERR "xc5000: firmware incorrect size\n"); ret = XC_RESULT_RESET_FAILURE; } else { - printk(KERN_INFO "xc5000: firmware upload\n"); + printk(KERN_INFO "xc5000: firmware uploading...\n"); ret = xc_load_i2c_sequence(fe, fw->data); + printk(KERN_INFO "xc5000: firmware upload complete...\n"); } out: -- cgit v1.2.3 From 413a852cd71a91beba74baab6cd04d6303aed136 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 28 Apr 2009 12:53:38 -0400 Subject: xc5000: add "no_poweroff" module option From: Devin Heitmueller Provide for the ability for a user to disable putting the tuner to sleep, in case he doesn't want to incur the cost of reloading the firmware when starting up his/her application. The module options are intentionally identical to xc3028. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/xc5000.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index 4045b2d50..f2a034b51 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -36,6 +36,12 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); +static int no_poweroff; +module_param(no_poweroff, int, 0644); +MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n" + "\t\t1 keep device energized and with tuner ready all the times.\n" + "\t\tFaster, but consumes more power and keeps the device hotter"); + static DEFINE_MUTEX(xc5000_list_mutex); static LIST_HEAD(hybrid_tuner_instance_list); @@ -865,6 +871,10 @@ static int xc5000_sleep(struct dvb_frontend *fe) dprintk(1, "%s()\n", __func__); + /* Avoid firmware reload on slow devices */ + if (no_poweroff) + return 0; + /* According to Xceive technical support, the "powerdown" register was removed in newer versions of the firmware. The "supported" way to sleep the tuner is to pull the reset pin low for 10ms */ -- cgit v1.2.3 From ed2d96e96805f671a8919bc8a4204f0e7e55238c Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 28 Apr 2009 15:22:47 -0400 Subject: tuner-xc2028: show the proper module description for no_poweroff option From: Devin Heitmueller There was a typo in the module description for the "no_poweroff" option, where the help was being associated with the "debug" option instead. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/tuner-xc2028.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/tuner-xc2028.c b/linux/drivers/media/common/tuners/tuner-xc2028.c index 3f03dfa2c..cb5b577fa 100644 --- a/linux/drivers/media/common/tuners/tuner-xc2028.c +++ b/linux/drivers/media/common/tuners/tuner-xc2028.c @@ -34,7 +34,7 @@ MODULE_PARM_DESC(debug, "enable verbose debug messages"); static int no_poweroff; module_param(no_poweroff, int, 0644); -MODULE_PARM_DESC(debug, "0 (default) powers device off when not used.\n" +MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n" "1 keep device energized and with tuner ready all the times.\n" " Faster, but consumes more power and keeps the device hotter\n"); -- cgit v1.2.3 From 68a68df1c6030e5e259627d4e99b422a4059f5fc Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 4 May 2009 21:04:20 -0400 Subject: xc5000: switch to new xc5000 firmware 1.6.114 with redistribution rights From: Devin Heitmueller Xceive has graciously allowed us to now freely redistribute the xc5000 firmware, which eliminates the need for users to manually extract the blob from the Hauppauge driver. Thanks to Brian Mathews for providing this code Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/xc5000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index f2a034b51..f7358bc6e 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -48,8 +48,8 @@ static LIST_HEAD(hybrid_tuner_instance_list); #define dprintk(level, fmt, arg...) if (debug >= level) \ printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) -#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.4.68.fw" -#define XC5000_DEFAULT_FIRMWARE_SIZE 12378 +#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw" +#define XC5000_DEFAULT_FIRMWARE_SIZE 12401 struct xc5000_priv { struct tuner_i2c_props i2c_props; -- cgit v1.2.3 From 4cca9aa01782049817d8d9abf78e683e3c7dfd0e Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 4 May 2009 21:59:58 -0400 Subject: xc5000: add support for DVB-T tuning From: David T.L. Wong This patch adds XC5000 supports for DVB-T 6MHz and 8MHz bandwidth. Priority: normal Signed-off-by: David T.L. Wong Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/xc5000.c | 63 +++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 18 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index f7358bc6e..8428e341a 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -644,25 +644,52 @@ static int xc5000_set_params(struct dvb_frontend *fe, dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); - switch (params->u.vsb.modulation) { - case VSB_8: - case VSB_16: - dprintk(1, "%s() VSB modulation\n", __func__); + if (fe->ops.info.type == FE_ATSC) { + dprintk(1, "%s() ATSC\n", __func__); + switch (params->u.vsb.modulation) { + case VSB_8: + case VSB_16: + dprintk(1, "%s() VSB modulation\n", __func__); + priv->rf_mode = XC_RF_MODE_AIR; + priv->freq_hz = params->frequency - 1750000; + priv->bandwidth = BANDWIDTH_6_MHZ; + priv->video_standard = DTV6; + break; + case QAM_64: + case QAM_256: + case QAM_AUTO: + dprintk(1, "%s() QAM modulation\n", __func__); + priv->rf_mode = XC_RF_MODE_CABLE; + priv->freq_hz = params->frequency - 1750000; + priv->bandwidth = BANDWIDTH_6_MHZ; + priv->video_standard = DTV6; + break; + default: + return -EINVAL; + } + } else if (fe->ops.info.type == FE_OFDM) { + dprintk(1, "%s() OFDM\n", __func__); + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + priv->bandwidth = BANDWIDTH_6_MHZ; + priv->video_standard = DTV6; + priv->freq_hz = params->frequency - 1750000; + break; + case BANDWIDTH_7_MHZ: + printk(KERN_ERR "xc5000 bandwidth 7MHz not supported\n"); + return -EINVAL; + case BANDWIDTH_8_MHZ: + priv->bandwidth = BANDWIDTH_8_MHZ; + priv->video_standard = DTV8; + priv->freq_hz = params->frequency - 2750000; + break; + default: + printk(KERN_ERR "xc5000 bandwidth not set!\n"); + return -EINVAL; + } priv->rf_mode = XC_RF_MODE_AIR; - priv->freq_hz = params->frequency - 1750000; - priv->bandwidth = BANDWIDTH_6_MHZ; - priv->video_standard = DTV6; - break; - case QAM_64: - case QAM_256: - case QAM_AUTO: - dprintk(1, "%s() QAM modulation\n", __func__); - priv->rf_mode = XC_RF_MODE_CABLE; - priv->freq_hz = params->frequency - 1750000; - priv->bandwidth = BANDWIDTH_6_MHZ; - priv->video_standard = DTV6; - break; - default: + } else { + printk(KERN_ERR "xc5000 modulation type not supported!\n"); return -EINVAL; } -- cgit v1.2.3 From c69585fadf77969b8eb7eee245fcb38f300227dd Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Mon, 4 May 2009 22:29:17 -0400 Subject: xc5000: poll at 5ms interval for register write command completion From: Devin Heitmueller Instead of polling at 100ms intervals for register writes, poll at 5ms intervals. This is consistent with the xc5000 specification, and improves tuning time by up to 500 ms on devices that such as the au0828 which do not properly implement i2c clock stretching (since the five register writes that occur for a tuning request often do not complete immediately but do complete far before 100ms has gone by). The net amount of time we wait before timing out is unchanged (500ms). Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/tuners/xc5000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index 8428e341a..c8c586b64 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -262,7 +262,7 @@ static int xc5000_TunerReset(struct dvb_frontend *fe) static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) { u8 buf[4]; - int WatchDogTimer = 5; + int WatchDogTimer = 100; int result; buf[0] = (regAddr >> 8) & 0xFF; @@ -284,7 +284,7 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) /* busy flag cleared */ break; } else { - xc_wait(100); /* wait 5 ms */ + xc_wait(5); /* wait 5 ms */ WatchDogTimer--; } } -- cgit v1.2.3 From d6b15c1777cb188ed9f4916ec7b6cde43dbd2926 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Thu, 14 May 2009 20:31:11 -0400 Subject: xc5000: add copyright line From: Devin Heitmueller Add copyright line for xc5000.c. Priority: normal Signed-off-by: Devin Heitmueller Cc: Steven Toth --- linux/drivers/media/common/tuners/xc5000.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/xc5000.c b/linux/drivers/media/common/tuners/xc5000.c index c8c586b64..6626d19b3 100644 --- a/linux/drivers/media/common/tuners/xc5000.c +++ b/linux/drivers/media/common/tuners/xc5000.c @@ -3,6 +3,7 @@ * * Copyright (c) 2007 Xceive Corporation * Copyright (c) 2007 Steven Toth + * Copyright (c) 2009 Devin Heitmueller * * 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 -- cgit v1.2.3 From 12f7442713d7eb82fecd42660ef8714f6e7d6e94 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 1 Jun 2009 11:46:08 -0300 Subject: Fix firmware load for DVB-T @ 6MHz From: Mauro Carvalho Chehab bandwidth for xc3028/xc3028L The only two countries that are known to use 6MHz bandwidth are Taiwan and Uruguay. Both use QAM subcarriers at OFTM. This patch fixes the firmware load for such countries, where the required firmware is the QAM one. This also confirms the previous tests where it was noticed that the 6MHz QAM firmware doesn't work for cable. So, this patch also removes support for DVB-C, instead of just printing a warning. Thanks to Terry Wu for pointing this issue and to Andy Walls for an initial patch for this fix. Priority: normal CC: Terry Wu CC: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tuner-xc2028.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/tuner-xc2028.c b/linux/drivers/media/common/tuners/tuner-xc2028.c index cb5b577fa..10becc3c0 100644 --- a/linux/drivers/media/common/tuners/tuner-xc2028.c +++ b/linux/drivers/media/common/tuners/tuner-xc2028.c @@ -1026,21 +1026,20 @@ static int xc2028_set_params(struct dvb_frontend *fe, switch(fe->ops.info.type) { case FE_OFDM: bw = p->u.ofdm.bandwidth; - break; - case FE_QAM: - tuner_info("WARN: There are some reports that " - "QAM 6 MHz doesn't work.\n" - "If this works for you, please report by " - "e-mail to: v4l-dvb-maintainer@linuxtv.org\n"); - bw = BANDWIDTH_6_MHZ; - type |= QAM; + /* + * The only countries with 6MHz seem to be Taiwan/Uruguay. + * Both seem to require QAM firmware for OFDM decoding + * Tested in Taiwan by Terry Wu + */ + if (bw == BANDWIDTH_6_MHZ) + type |= QAM; break; case FE_ATSC: bw = BANDWIDTH_6_MHZ; /* The only ATSC firmware (at least on v2.7) is D2633 */ type |= ATSC | D2633; break; - /* DVB-S is not supported */ + /* DVB-S and pure QAM (FE_QAM) are not supported */ default: return -EINVAL; } -- cgit v1.2.3 From 3cfc0ea022a646fa73ba82352c3a95af859c20f6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 1 Jun 2009 12:18:10 -0300 Subject: tuner-xc2028: Fix offset frequencies for DVB @ 6MHz From: Mauro Carvalho Chehab Both ATSC and DVB @ 6MHz bandwidth require the same offset. While we're fixing it, let's cleanup the bandwidth setup to better reflect the fact that it is a function of the bandwidth. Thanks to Terry Wu for pointing this issue and to Andy Walls for an initial patch for this fix. Priority: normal CC: Terry Wu CC: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tuner-xc2028.c | 32 ++++++++++++++---------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/tuner-xc2028.c b/linux/drivers/media/common/tuners/tuner-xc2028.c index 10becc3c0..493e8d642 100644 --- a/linux/drivers/media/common/tuners/tuner-xc2028.c +++ b/linux/drivers/media/common/tuners/tuner-xc2028.c @@ -921,22 +921,28 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, * that xc2028 will be in a safe state. * Maybe this might also be needed for DTV. */ - if (new_mode == T_ANALOG_TV) { + if (new_mode == T_ANALOG_TV) rc = send_seq(priv, {0x00, 0x00}); - } else if (priv->cur_fw.type & ATSC) { - offset = 1750000; - } else { - offset = 2750000; + + /* + * Digital modes require an offset to adjust to the + * proper frequency + */ + if (new_mode != T_ANALOG_TV) { + /* Sets the offset according with firmware */ + if (priv->cur_fw.type & DTV6) + offset = 1750000; + if (priv->cur_fw.type & DTV7) + offset = 2250000; + else /* DTV8 or DTV78 */ + offset = 2750000; + /* - * We must adjust the offset by 500kHz in two cases in order - * to correctly center the IF output: - * 1) When the ZARLINK456 or DIBCOM52 tables were explicitly - * selected and a 7MHz channel is tuned; - * 2) When tuning a VHF channel with DTV78 firmware. + * We must adjust the offset by 500kHz when + * tuning a 7MHz VHF channel with DTV78 firmware + * (used in Australia) */ - if (((priv->cur_fw.type & DTV7) && - (priv->cur_fw.scode_table & (ZARLINK456 | DIBCOM52))) || - ((priv->cur_fw.type & DTV78) && freq < 470000000)) + if ((priv->cur_fw.type & DTV78) && freq < 470000000) offset -= 500000; } -- cgit v1.2.3 From b49e742345a086611441cc31b1b0041f1fe7051d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 1 Jun 2009 22:34:20 -0300 Subject: tuner-xc3028: fix frequency offset From: Mauro Carvalho Chehab The last changeset has an else missing, causing wrong frequencies for DTV6. Thanks to Terry Wu for pointing the issue. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tuner-xc2028.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/tuner-xc2028.c b/linux/drivers/media/common/tuners/tuner-xc2028.c index 493e8d642..c98a628e8 100644 --- a/linux/drivers/media/common/tuners/tuner-xc2028.c +++ b/linux/drivers/media/common/tuners/tuner-xc2028.c @@ -932,7 +932,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, /* Sets the offset according with firmware */ if (priv->cur_fw.type & DTV6) offset = 1750000; - if (priv->cur_fw.type & DTV7) + else if (priv->cur_fw.type & DTV7) offset = 2250000; else /* DTV8 or DTV78 */ offset = 2750000; -- cgit v1.2.3 From 2e4dae3dad6d21fbd5ce4b97f4724ab1a830af8c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 3 Jun 2009 02:27:34 -0300 Subject: tuner-xc2028: Improve comments, based on Andy Walls and Hermann Pitton From: Mauro Carvalho Chehab feedback CC: Andy Walls CC: Hermann Pitton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tuner-xc2028.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/tuner-xc2028.c b/linux/drivers/media/common/tuners/tuner-xc2028.c index c98a628e8..083e62723 100644 --- a/linux/drivers/media/common/tuners/tuner-xc2028.c +++ b/linux/drivers/media/common/tuners/tuner-xc2028.c @@ -926,7 +926,8 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, /* * Digital modes require an offset to adjust to the - * proper frequency + * proper frequency. + * Analog modes require offset = 0 */ if (new_mode != T_ANALOG_TV) { /* Sets the offset according with firmware */ @@ -940,7 +941,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, /* * We must adjust the offset by 500kHz when * tuning a 7MHz VHF channel with DTV78 firmware - * (used in Australia) + * (used in Australia, Italy and Germany) */ if ((priv->cur_fw.type & DTV78) && freq < 470000000) offset -= 500000; -- cgit v1.2.3 From d336dddd42e43b5465cd58b5a4812011805905df Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 6 Jun 2009 08:15:08 -0300 Subject: tuner-xc2028: cleanup: better use tuner typpe defines From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tuner-xc2028.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/tuner-xc2028.c b/linux/drivers/media/common/tuners/tuner-xc2028.c index 083e62723..a7466867c 100644 --- a/linux/drivers/media/common/tuners/tuner-xc2028.c +++ b/linux/drivers/media/common/tuners/tuner-xc2028.c @@ -929,7 +929,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, * proper frequency. * Analog modes require offset = 0 */ - if (new_mode != T_ANALOG_TV) { + if (new_mode == T_DIGITAL_TV) { /* Sets the offset according with firmware */ if (priv->cur_fw.type & DTV6) offset = 1750000; @@ -1002,7 +1002,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe, if (priv->ctrl.input1) type |= INPUT1; return generic_set_freq(fe, (625l * p->frequency) / 10, - T_ANALOG_TV, type, 0, 0); + T_RADIO, type, 0, 0); } /* if std is not defined, choose one */ -- cgit v1.2.3 From 8817e52a9b01c76ac3a33ac34ab4708fe3bf81a4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 7 Jun 2009 20:39:03 -0400 Subject: tuner-simple, tveeprom: Add Philips FQ1216LME MK3 analog tuner From: Andy Walls Priority: normal Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tuner-simple.c | 51 +++++++++++++----------- linux/drivers/media/common/tuners/tuner-types.c | 29 ++++++++++++++ 2 files changed, 56 insertions(+), 24 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/tuner-simple.c b/linux/drivers/media/common/tuners/tuner-simple.c index 233476df9..ebbc1e045 100644 --- a/linux/drivers/media/common/tuners/tuner-simple.c +++ b/linux/drivers/media/common/tuners/tuner-simple.c @@ -423,6 +423,24 @@ static int simple_std_setup(struct dvb_frontend *fe, return 0; } +static int simple_set_aux_byte(struct dvb_frontend *fe, u8 config, u8 aux) +{ + struct tuner_simple_priv *priv = fe->tuner_priv; + int rc; + u8 buffer[2]; + + buffer[0] = (config & ~0x38) | 0x18; + buffer[1] = aux; + + tuner_dbg("setting aux byte: 0x%02x 0x%02x\n", buffer[0], buffer[1]); + + rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2); + if (2 != rc) + tuner_warn("i2c i/o error: rc == %d (should be 2)\n", rc); + + return rc == 2 ? 0 : rc; +} + static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, u16 div, u8 config, u8 cb) { @@ -431,30 +449,10 @@ static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, switch (priv->type) { case TUNER_LG_TDVS_H06XF: - /* Set the Auxiliary Byte. */ -#if 0 - buffer[2] &= ~0x20; - buffer[2] |= 0x18; - buffer[3] = 0x20; - tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", - buffer[0], buffer[1], buffer[2], buffer[3]); - - rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4); - if (4 != rc) - tuner_warn("i2c i/o error: rc == %d " - "(should be 4)\n", rc); -#else - buffer[0] = buffer[2]; - buffer[0] &= ~0x20; - buffer[0] |= 0x18; - buffer[1] = 0x20; - tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]); - - rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2); - if (2 != rc) - tuner_warn("i2c i/o error: rc == %d " - "(should be 2)\n", rc); -#endif + simple_set_aux_byte(fe, config, 0x20); + break; + case TUNER_PHILIPS_FQ1216LME_MK3: + simple_set_aux_byte(fe, config, 0x60); /* External AGC */ break; case TUNER_MICROTUNE_4042FI5: { @@ -526,6 +524,11 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) case TUNER_THOMSON_DTT761X: buffer[3] = 0x39; break; + case TUNER_PHILIPS_FQ1216LME_MK3: + tuner_err("This tuner doesn't have FM\n"); + /* Set the low band for sanity, since it covers 88-108 MHz */ + buffer[3] = 0x01; + break; case TUNER_MICROTUNE_4049FM5: default: buffer[3] = 0xa4; diff --git a/linux/drivers/media/common/tuners/tuner-types.c b/linux/drivers/media/common/tuners/tuner-types.c index 43afd30b0..e57d7cb2f 100644 --- a/linux/drivers/media/common/tuners/tuner-types.c +++ b/linux/drivers/media/common/tuners/tuner-types.c @@ -1280,6 +1280,28 @@ static struct tuner_params tuner_tcl_mf02gip_5n_params[] = { }, }; +/* 80-89 */ +/* --------- TUNER_PHILIPS_FQ1216LME_MK3 -- active loopthrough, no FM ------- */ + +static struct tuner_params tuner_fq1216lme_mk3_params[] = { + { + .type = TUNER_PARAM_TYPE_PAL, + .ranges = tuner_fm1216me_mk3_pal_ranges, + .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), + .cb_first_if_lower_freq = 1, /* not specified, but safe to do */ + .has_tda9887 = 1, /* TDA9886 */ + .port1_active = 1, + .port2_active = 1, + .port2_invert_for_secam_lc = 1, + .default_top_low = 4, + .default_top_mid = 4, + .default_top_high = 4, + .default_top_secam_low = 4, + .default_top_secam_mid = 4, + .default_top_secam_high = 4, + }, +}; + /* --------------------------------------------------------------------- */ struct tunertype tuners[] = { @@ -1725,6 +1747,13 @@ struct tunertype tuners[] = { .params = tuner_fm1216mk5_params, .count = ARRAY_SIZE(tuner_fm1216mk5_params), }, + + /* 80-89 */ + [TUNER_PHILIPS_FQ1216LME_MK3] = { /* PAL/SECAM, Loop-thru, no FM */ + .name = "Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough", + .params = tuner_fq1216lme_mk3_params, + .count = ARRAY_SIZE(tuner_fq1216lme_mk3_params), + }, }; EXPORT_SYMBOL(tuners); -- cgit v1.2.3 From 8b4ba9e06fa0f932b664304018ac132019dee4e6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 May 2009 01:22:41 +0000 Subject: Change order for FM tune From: Dmitri Belimov Change order data of buffer in FM simple_tune function. It is usefull for: 1. Set data of tuner with CP bit UP. 0xCE for MK5 or 0xC6 for MK3 2. When call simple_fm_tune, read this byte from config and overwrite this byte in function simple_radio_bandswitch for set CP bit to OFF. Of course it can be usefull for other tuner for overwrite default settings of FM. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tuner-simple.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/tuners/tuner-simple.c b/linux/drivers/media/common/tuners/tuner-simple.c index ebbc1e045..2ac1c8edb 100644 --- a/linux/drivers/media/common/tuners/tuner-simple.c +++ b/linux/drivers/media/common/tuners/tuner-simple.c @@ -701,12 +701,12 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, return 0; } - /* Bandswitch byte */ - simple_radio_bandswitch(fe, &buffer[0]); - buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */ + /* Bandswitch byte */ + simple_radio_bandswitch(fe, &buffer[0]); + /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) = freq * (1/800) */ -- cgit v1.2.3 From 0333db7369d656513aa455c497f1e5e56fd9fafa Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sat, 20 Jun 2009 20:34:42 -0400 Subject: em28xx: add Remote control support for EVGA inDtube From: Devin Heitmueller Add an IR profile for the EVGA inDtube remote control (which is an NEC type remote) Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/common/ir-keymaps.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'linux/drivers/media/common') diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index d5fd71968..56fa64b4c 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -2800,3 +2800,26 @@ IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = { [0x1b] = KEY_B, /*recall*/ }; EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec); + +/* EVGA inDtube + Devin Heitmueller + */ +IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE] = { + [0x12] = KEY_POWER, + [0x02] = KEY_MODE, /* TV */ + [0x14] = KEY_MUTE, + [0x1a] = KEY_CHANNELUP, + [0x16] = KEY_TV2, /* PIP */ + [0x1d] = KEY_VOLUMEUP, + [0x05] = KEY_CHANNELDOWN, + [0x0f] = KEY_PLAYPAUSE, + [0x19] = KEY_VOLUMEDOWN, + [0x1c] = KEY_REWIND, + [0x0d] = KEY_RECORD, + [0x18] = KEY_FORWARD, + [0x1e] = KEY_PREVIOUS, + [0x1b] = KEY_STOP, + [0x1f] = KEY_NEXT, + [0x13] = KEY_CAMERA, +}; +EXPORT_SYMBOL_GPL(ir_codes_evga_indtube); -- cgit v1.2.3