From: poma <pomidorabelisima@gmail.com>
To: Antti Palosaari <crope@iki.fi>
Cc: Thomas Mair <thomas.mair86@googlemail.com>, linux-media@vger.kernel.org
Subject: Re: [PATCH 1/5] rtl2832 ver 0.3: suport for RTL2832 demodulator revised version
Date: Wed, 16 May 2012 07:10:21 +0200 [thread overview]
Message-ID: <4FB336BD.1040506@gmail.com> (raw)
In-Reply-To: <4FB061C2.90006@iki.fi>
[-- Attachment #1: Type: text/plain, Size: 49489 bytes --]
On 05/14/2012 03:37 AM, Antti Palosaari wrote:
> On 12.05.2012 21:08, Thomas Mair wrote:
>> Changes compared to version 0.2:
>> - removed reading of signal strength for tuners FC0012,FC0013 (is now
>> supported by fc0012,fc0013 driver)
>> - moved definition of register names to rtl2832_priv.h
>> - cleaned up demod private structure
>> - replaced rtl2832_log2 function with intlog2 from dvb_math
>>
>> Signed-off-by: Thomas Mair<thomas.mair86@googlemail.com>
>> ---
>> drivers/media/dvb/frontends/Kconfig | 7 +
>> drivers/media/dvb/frontends/Makefile | 1 +
>> drivers/media/dvb/frontends/rtl2832.c | 1009
>> ++++++++++++++++++++++++++++
>> drivers/media/dvb/frontends/rtl2832.h | 81 +++
>> drivers/media/dvb/frontends/rtl2832_priv.h | 260 +++++++
>> 5 files changed, 1358 insertions(+), 0 deletions(-)
>> create mode 100644 drivers/media/dvb/frontends/rtl2832.c
>> create mode 100644 drivers/media/dvb/frontends/rtl2832.h
>> create mode 100644 drivers/media/dvb/frontends/rtl2832_priv.h
>>
>> diff --git a/drivers/media/dvb/frontends/Kconfig
>> b/drivers/media/dvb/frontends/Kconfig
>> index f479834..f7d67d7 100644
>> --- a/drivers/media/dvb/frontends/Kconfig
>> +++ b/drivers/media/dvb/frontends/Kconfig
>> @@ -432,6 +432,13 @@ config DVB_RTL2830
>> help
>> Say Y when you want to support this frontend.
>>
>> +config DVB_RTL2832
>> + tristate "Realtek RTL2832 DVB-T"
>> + depends on DVB_CORE&& I2C
>> + default m if DVB_FE_CUSTOMISE
>> + help
>> + Say Y when you want to support this frontend.
>> +
>> comment "DVB-C (cable) frontends"
>> depends on DVB_CORE
>>
>> diff --git a/drivers/media/dvb/frontends/Makefile
>> b/drivers/media/dvb/frontends/Makefile
>> index b0381dc..9731192 100644
>> --- a/drivers/media/dvb/frontends/Makefile
>> +++ b/drivers/media/dvb/frontends/Makefile
>> @@ -98,6 +98,7 @@ obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o
>> obj-$(CONFIG_DVB_A8293) += a8293.o
>> obj-$(CONFIG_DVB_TDA10071) += tda10071.o
>> obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
>> +obj-$(CONFIG_DVB_RTL2832) = rtl2832.o
>> obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
>> obj-$(CONFIG_DVB_AF9033) += af9033.o
>>
>> diff --git a/drivers/media/dvb/frontends/rtl2832.c
>> b/drivers/media/dvb/frontends/rtl2832.c
>> new file mode 100644
>> index 0000000..1936c50
>> --- /dev/null
>> +++ b/drivers/media/dvb/frontends/rtl2832.c
>> @@ -0,0 +1,1009 @@
>> +/*
>> + * Realtek RTL2832 DVB-T demodulator driver
>> + *
>> + * Copyright (C) 2012 Thomas Mair<thomas.mair86@gmail.com>
>> + *
>> + * 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.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#include "rtl2832_priv.h"
>> +#include "dvb_math.h"
>> +
>> +
>> +int rtl2832_debug;
>> +module_param_named(debug, rtl2832_debug, int, 0644);
>> +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging
>> (default:off).");
>> +
>> +
>> +static int reg_mask[32] = {
>> + 0x00000001,
>> + 0x00000003,
>> + 0x00000007,
>> + 0x0000000f,
>> + 0x0000001f,
>> + 0x0000003f,
>> + 0x0000007f,
>> + 0x000000ff,
>> + 0x000001ff,
>> + 0x000003ff,
>> + 0x000007ff,
>> + 0x00000fff,
>> + 0x00001fff,
>> + 0x00003fff,
>> + 0x00007fff,
>> + 0x0000ffff,
>> + 0x0001ffff,
>> + 0x0003ffff,
>> + 0x0007ffff,
>> + 0x000fffff,
>> + 0x001fffff,
>> + 0x003fffff,
>> + 0x007fffff,
>> + 0x00ffffff,
>> + 0x01ffffff,
>> + 0x03ffffff,
>> + 0x07ffffff,
>> + 0x0fffffff,
>> + 0x1fffffff,
>> + 0x3fffffff,
>> + 0x7fffffff,
>> + 0xffffffff
>
> This looks weird but I don't know which is most correct alternative.
> There could be even some macros for the - check kernel bit operations at
> the first hand.
>
> You can consider shifting bits to right in order to get mask. For
> example (0xffffffff >> 30) == 0x00000003.
>
>> +};
>> +
>> +static const rtl2832_reg_entry registers[] = {
>> + [DVBT_SOFT_RST] = {0x1, 0x1, 2, 2},
>> + [DVBT_IIC_REPEAT] = {0x1, 0x1, 3, 3},
>> + [DVBT_TR_WAIT_MIN_8K] = {0x1, 0x88, 11, 2},
>> + [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
>> + [DVBT_EN_BK_TRK] = {0x1, 0xa6, 7, 7},
>> + [DVBT_AD_EN_REG] = {0x0, 0x8, 7, 7},
>> + [DVBT_AD_EN_REG1] = {0x0, 0x8, 6, 6},
>> + [DVBT_EN_BBIN] = {0x1, 0xb1, 0, 0},
>> + [DVBT_MGD_THD0] = {0x1, 0x95, 7, 0},
>> + [DVBT_MGD_THD1] = {0x1, 0x96, 7, 0},
>> + [DVBT_MGD_THD2] = {0x1, 0x97, 7, 0},
>> + [DVBT_MGD_THD3] = {0x1, 0x98, 7, 0},
>> + [DVBT_MGD_THD4] = {0x1, 0x99, 7, 0},
>> + [DVBT_MGD_THD5] = {0x1, 0x9a, 7, 0},
>> + [DVBT_MGD_THD6] = {0x1, 0x9b, 7, 0},
>> + [DVBT_MGD_THD7] = {0x1, 0x9c, 7, 0},
>> + [DVBT_EN_CACQ_NOTCH] = {0x1, 0x61, 4, 4},
>> + [DVBT_AD_AV_REF] = {0x0, 0x9, 6, 0},
>> + [DVBT_REG_PI] = {0x0, 0xa, 2, 0},
>> + [DVBT_PIP_ON] = {0x0, 0x21, 3, 3},
>> + [DVBT_SCALE1_B92] = {0x2, 0x92, 7, 0},
>> + [DVBT_SCALE1_B93] = {0x2, 0x93, 7, 0},
>> + [DVBT_SCALE1_BA7] = {0x2, 0xa7, 7, 0},
>> + [DVBT_SCALE1_BA9] = {0x2, 0xa9, 7, 0},
>> + [DVBT_SCALE1_BAA] = {0x2, 0xaa, 7, 0},
>> + [DVBT_SCALE1_BAB] = {0x2, 0xab, 7, 0},
>> + [DVBT_SCALE1_BAC] = {0x2, 0xac, 7, 0},
>> + [DVBT_SCALE1_BB0] = {0x2, 0xb0, 7, 0},
>> + [DVBT_SCALE1_BB1] = {0x2, 0xb1, 7, 0},
>> + [DVBT_KB_P1] = {0x1, 0x64, 3, 1},
>> + [DVBT_KB_P2] = {0x1, 0x64, 6, 4},
>> + [DVBT_KB_P3] = {0x1, 0x65, 2, 0},
>> + [DVBT_OPT_ADC_IQ] = {0x0, 0x6, 5, 4},
>> + [DVBT_AD_AVI] = {0x0, 0x9, 1, 0},
>> + [DVBT_AD_AVQ] = {0x0, 0x9, 3, 2},
>> + [DVBT_K1_CR_STEP12] = {0x2, 0xad, 9, 4},
>> + [DVBT_TRK_KS_P2] = {0x1, 0x6f, 2, 0},
>> + [DVBT_TRK_KS_I2] = {0x1, 0x70, 5, 3},
>> + [DVBT_TR_THD_SET2] = {0x1, 0x72, 3, 0},
>> + [DVBT_TRK_KC_P2] = {0x1, 0x73, 5, 3},
>> + [DVBT_TRK_KC_I2] = {0x1, 0x75, 2, 0},
>> + [DVBT_CR_THD_SET2] = {0x1, 0x76, 7, 6},
>> + [DVBT_PSET_IFFREQ] = {0x1, 0x19, 21, 0},
>> + [DVBT_SPEC_INV] = {0x1, 0x15, 0, 0},
>> + [DVBT_RSAMP_RATIO] = {0x1, 0x9f, 27, 2},
>> + [DVBT_CFREQ_OFF_RATIO] = {0x1, 0x9d, 23, 4},
>> + [DVBT_FSM_STAGE] = {0x3, 0x51, 6, 3},
>> + [DVBT_RX_CONSTEL] = {0x3, 0x3c, 3, 2},
>> + [DVBT_RX_HIER] = {0x3, 0x3c, 6, 4},
>> + [DVBT_RX_C_RATE_LP] = {0x3, 0x3d, 2, 0},
>> + [DVBT_RX_C_RATE_HP] = {0x3, 0x3d, 5, 3},
>> + [DVBT_GI_IDX] = {0x3, 0x51, 1, 0},
>> + [DVBT_FFT_MODE_IDX] = {0x3, 0x51, 2, 2},
>> + [DVBT_RSD_BER_EST] = {0x3, 0x4e, 15, 0},
>> + [DVBT_CE_EST_EVM] = {0x4, 0xc, 15, 0},
>> + [DVBT_RF_AGC_VAL] = {0x3, 0x5b, 13, 0},
>> + [DVBT_IF_AGC_VAL] = {0x3, 0x59, 13, 0},
>> + [DVBT_DAGC_VAL] = {0x3, 0x5, 7, 0},
>> + [DVBT_SFREQ_OFF] = {0x3, 0x18, 13, 0},
>> + [DVBT_CFREQ_OFF] = {0x3, 0x5f, 17, 0},
>> + [DVBT_POLAR_RF_AGC] = {0x0, 0xe, 1, 1},
>> + [DVBT_POLAR_IF_AGC] = {0x0, 0xe, 0, 0},
>> + [DVBT_AAGC_HOLD] = {0x1, 0x4, 5, 5},
>> + [DVBT_EN_RF_AGC] = {0x1, 0x4, 6, 6},
>> + [DVBT_EN_IF_AGC] = {0x1, 0x4, 7, 7},
>> + [DVBT_IF_AGC_MIN] = {0x1, 0x8, 7, 0},
>> + [DVBT_IF_AGC_MAX] = {0x1, 0x9, 7, 0},
>> + [DVBT_RF_AGC_MIN] = {0x1, 0xa, 7, 0},
>> + [DVBT_RF_AGC_MAX] = {0x1, 0xb, 7, 0},
>> + [DVBT_IF_AGC_MAN] = {0x1, 0xc, 6, 6},
>> + [DVBT_IF_AGC_MAN_VAL] = {0x1, 0xc, 13, 0},
>> + [DVBT_RF_AGC_MAN] = {0x1, 0xe, 6, 6},
>> + [DVBT_RF_AGC_MAN_VAL] = {0x1, 0xe, 13, 0},
>> + [DVBT_DAGC_TRG_VAL] = {0x1, 0x12, 7, 0},
>> + [DVBT_AGC_TARG_VAL_0] = {0x1, 0x2, 0, 0},
>> + [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3, 7, 0},
>> + [DVBT_AAGC_LOOP_GAIN] = {0x1, 0xc7, 5, 1},
>> + [DVBT_LOOP_GAIN2_3_0] = {0x1, 0x4, 4, 1},
>> + [DVBT_LOOP_GAIN2_4] = {0x1, 0x5, 7, 7},
>> + [DVBT_LOOP_GAIN3] = {0x1, 0xc8, 4, 0},
>> + [DVBT_VTOP1] = {0x1, 0x6, 5, 0},
>> + [DVBT_VTOP2] = {0x1, 0xc9, 5, 0},
>> + [DVBT_VTOP3] = {0x1, 0xca, 5, 0},
>> + [DVBT_KRF1] = {0x1, 0xcb, 7, 0},
>> + [DVBT_KRF2] = {0x1, 0x7, 7, 0},
>> + [DVBT_KRF3] = {0x1, 0xcd, 7, 0},
>> + [DVBT_KRF4] = {0x1, 0xce, 7, 0},
>> + [DVBT_EN_GI_PGA] = {0x1, 0xe5, 0, 0},
>> + [DVBT_THD_LOCK_UP] = {0x1, 0xd9, 8, 0},
>> + [DVBT_THD_LOCK_DW] = {0x1, 0xdb, 8, 0},
>> + [DVBT_THD_UP1] = {0x1, 0xdd, 7, 0},
>> + [DVBT_THD_DW1] = {0x1, 0xde, 7, 0},
>> + [DVBT_INTER_CNT_LEN] = {0x1, 0xd8, 3, 0},
>> + [DVBT_GI_PGA_STATE] = {0x1, 0xe6, 3, 3},
>> + [DVBT_EN_AGC_PGA] = {0x1, 0xd7, 0, 0},
>> + [DVBT_CKOUTPAR] = {0x1, 0x7b, 5, 5},
>> + [DVBT_CKOUT_PWR] = {0x1, 0x7b, 6, 6},
>> + [DVBT_SYNC_DUR] = {0x1, 0x7b, 7, 7},
>> + [DVBT_ERR_DUR] = {0x1, 0x7c, 0, 0},
>> + [DVBT_SYNC_LVL] = {0x1, 0x7c, 1, 1},
>> + [DVBT_ERR_LVL] = {0x1, 0x7c, 2, 2},
>> + [DVBT_VAL_LVL] = {0x1, 0x7c, 3, 3},
>> + [DVBT_SERIAL] = {0x1, 0x7c, 4, 4},
>> + [DVBT_SER_LSB] = {0x1, 0x7c, 5, 5},
>> + [DVBT_CDIV_PH0] = {0x1, 0x7d, 3, 0},
>> + [DVBT_CDIV_PH1] = {0x1, 0x7d, 7, 4},
>> + [DVBT_MPEG_IO_OPT_2_2] = {0x0, 0x6, 7, 7},
>> + [DVBT_MPEG_IO_OPT_1_0] = {0x0, 0x7, 7, 6},
>> + [DVBT_CKOUTPAR_PIP] = {0x0, 0xb7, 4, 4},
>> + [DVBT_CKOUT_PWR_PIP] = {0x0, 0xb7, 3, 3},
>> + [DVBT_SYNC_LVL_PIP] = {0x0, 0xb7, 2, 2},
>> + [DVBT_ERR_LVL_PIP] = {0x0, 0xb7, 1, 1},
>> + [DVBT_VAL_LVL_PIP] = {0x0, 0xb7, 0, 0},
>> + [DVBT_CKOUTPAR_PID] = {0x0, 0xb9, 4, 4},
>> + [DVBT_CKOUT_PWR_PID] = {0x0, 0xb9, 3, 3},
>> + [DVBT_SYNC_LVL_PID] = {0x0, 0xb9, 2, 2},
>> + [DVBT_ERR_LVL_PID] = {0x0, 0xb9, 1, 1},
>> + [DVBT_VAL_LVL_PID] = {0x0, 0xb9, 0, 0},
>> + [DVBT_SM_PASS] = {0x1, 0x93, 11, 0},
>> + [DVBT_AD7_SETTING] = {0x0, 0x11, 15, 0},
>> + [DVBT_RSSI_R] = {0x3, 0x1, 6, 0},
>> + [DVBT_ACI_DET_IND] = {0x3, 0x12, 0, 0},
>> + [DVBT_REG_MON] = {0x0, 0xd, 1, 0},
>> + [DVBT_REG_MONSEL] = {0x0, 0xd, 2, 2},
>> + [DVBT_REG_GPE] = {0x0, 0xd, 7, 7},
>> + [DVBT_REG_GPO] = {0x0, 0x10, 0, 0},
>> + [DVBT_REG_4MSEL] = {0x0, 0x13, 0, 0},
>
> I recommend for intending values too. So that all values in a same "row"
> can be easily compared.
>
>> +};
>> +
>> +/* write multiple hardware registers */
>> +static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int
>> len)
>> +{
>> + int ret;
>> + u8 buf[1+len];
>> + struct i2c_msg msg[1] = {
>> + {
>> + .addr = priv->cfg.i2c_addr,
>> + .flags = 0,
>> + .len = 1+len,
>> + .buf = buf,
>> + }
>> + };
>> +
>> + buf[0] = reg;
>> + memcpy(&buf[1], val, len);
>> +
>> + ret = i2c_transfer(priv->i2c, msg, 1);
>> + if (ret == 1) {
>> + ret = 0;
>> + } else {
>> + warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
>> + ret = -EREMOTEIO;
>> + }
>> + return ret;
>> +}
>> +
>> +/* read multiple hardware registers */
>> +static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int
>> len)
>> +{
>> + int ret;
>> + struct i2c_msg msg[2] = {
>> + {
>> + .addr = priv->cfg.i2c_addr,
>> + .flags = 0,
>> + .len = 1,
>> + .buf =®,
>> + }, {
>> + .addr = priv->cfg.i2c_addr,
>> + .flags = I2C_M_RD,
>> + .len = len,
>> + .buf = val,
>> + }
>> + };
>> +
>> + ret = i2c_transfer(priv->i2c, msg, 2);
>> + if (ret == 2) {
>> + ret = 0;
>> + } else {
>> + warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
>> + ret = -EREMOTEIO;
>> +}
>> +return ret;
>> +}
>> +
>> +/* write multiple registers */
>> +static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8
>> page, u8 *val,
>> + int len)
>> +{
>> + int ret;
>> +
>> +
>> + /* switch bank if needed */
>> + if (page != priv->page) {
>> + ret = rtl2832_wr(priv, 0x00,&page, 1);
>> + if (ret)
>> + return ret;
>> +
>> + priv->page = page;
>> +}
>> +
>> +return rtl2832_wr(priv, reg, val, len);
>> +}
>> +
>> +/* read multiple registers */
>> +static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8
>> page, u8 *val,
>> + int len)
>> +{
>> + int ret;
>> +
>> + /* switch bank if needed */
>> + if (page != priv->page) {
>> + ret = rtl2832_wr(priv, 0x00,&page, 1);
>> + if (ret)
>> + return ret;
>> +
>> + priv->page = page;
>> + }
>> +
>> + return rtl2832_rd(priv, reg, val, len);
>> +}
>> +
>> +#if 0 /* currently not used */
>> +/* write single register */
>> +static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page,
>> u8 val)
>> +{
>> + return rtl2832_wr_regs(priv, reg, page,&val, 1);
>> +}
>> +#endif
>> +
>> +/* read single register */
>> +static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page,
>> u8 *val)
>> +{
>> + return rtl2832_rd_regs(priv, reg, page, val, 1);
>> +}
>> +
>> +int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
>> +{
>> + int ret;
>> +
>> + u8 reg_start_addr;
>> + u8 msb, lsb;
>> + u8 page;
>> + u8 reading[4];
>> + u32 reading_tmp;
>> + int i;
>> +
>> + u8 len;
>> + u32 mask;
>> +
>> + reg_start_addr = registers[reg].start_address;
>> + msb = registers[reg].msb;
>> + lsb = registers[reg].lsb;
>> + page = registers[reg].page;
>> +
>> + len = (msb>> 3) + 1;
>> + mask = reg_mask[msb-lsb];
>> +
>> +
>> + ret = rtl2832_rd_regs(priv, reg_start_addr, page,&reading[0], len);
>> + if (ret)
>> + goto err;
>> +
>> + reading_tmp = 0;
>> + for (i = 0; i< len; i++)
>> + reading_tmp |= reading[i]<< ((len-1-i)*8);
>> +
>> + *val = (reading_tmp>> lsb)& mask;
>> +
>> + return ret;
>> +
>> +err:
>> + return ret;
>
> excessive return
>
>> +
>> +}
>> +
>> +int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
>> +{
>> + int ret, i;
>> + u8 len;
>> + u8 reg_start_addr;
>> + u8 msb, lsb;
>> + u8 page;
>> + u32 mask;
>> +
>> +
>> + u8 reading[4];
>> + u8 writing[4];
>> + u32 reading_tmp;
>> + u32 writing_tmp;
>> +
>> +
>> + reg_start_addr = registers[reg].start_address;
>> + msb = registers[reg].msb;
>> + lsb = registers[reg].lsb;
>> + page = registers[reg].page;
>> +
>> + len = (msb>> 3) + 1;
>> + mask = reg_mask[msb-lsb];
>> +
>> +
>> + ret = rtl2832_rd_regs(priv, reg_start_addr, page,&reading[0], len);
>> + if (ret)
>> + goto err;
>> +
>> + reading_tmp = 0;
>> + for (i = 0; i< len; i++)
>> + reading_tmp |= reading[i]<< ((len-1-i)*8);
>> +
>> + writing_tmp = reading_tmp& ~(mask<< lsb);
>> + writing_tmp |= ((val& mask)<< lsb);
>> +
>> +
>> + for (i = 0; i< len; i++)
>> + writing[i] = (writing_tmp>> ((len-1-i)*8))& 0xff;
>> +
>> + ret = rtl2832_wr_regs(priv, reg_start_addr, page,&writing[0], len);
>> + if (ret)
>> + goto err;
>> +
>> + return ret;
>> +
>> +err:
>> + return ret;
>
> excessive return
>
>> +
>> +}
>> +
>> +
>> +static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
>> +{
>> + int ret;
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> +
>> + dbg("%s: enable=%d", __func__, enable);
>> +
>> + /* gate already open or close */
>> + if (priv->i2c_gate_state == enable)
>> + return 0;
>> +
>> + ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 :
>> 0x0));
>> +
>> + if (ret)
>> + goto err;
>> +
>> + priv->i2c_gate_state = enable;
>> +
>> + return ret;
>> +err:
>> + dbg("%s: failed=%d", __func__, ret);
>> + return ret;
>> +}
>> +
>> +
>> +
>> +static int rtl2832_init(struct dvb_frontend *fe)
>> +{
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> + int i, ret;
>> +
>> + u8 en_bbin;
>> + u64 pset_iffreq;
>> +
>> + /* initialization values for the demodulator registers */
>> + static rtl2832_reg_value rtl2832_initial_regs_1[] = {
>> + {DVBT_AD_EN_REG, 0x1},
>> + {DVBT_AD_EN_REG1, 0x1},
>> + {DVBT_RSD_BER_FAIL_VAL, 0x2800},
>> + {DVBT_MGD_THD0, 0x10},
>> + {DVBT_MGD_THD1, 0x20},
>> + {DVBT_MGD_THD2, 0x20},
>> + {DVBT_MGD_THD3, 0x40},
>> + {DVBT_MGD_THD4, 0x22},
>> + {DVBT_MGD_THD5, 0x32},
>> + {DVBT_MGD_THD6, 0x37},
>> + {DVBT_MGD_THD7, 0x39},
>> + {DVBT_EN_BK_TRK, 0x0},
>> + {DVBT_EN_CACQ_NOTCH, 0x0},
>> + {DVBT_AD_AV_REF, 0x2a},
>> + {DVBT_REG_PI, 0x6},
>> + {DVBT_PIP_ON, 0x0},
>> + {DVBT_CDIV_PH0, 0x8},
>> + {DVBT_CDIV_PH1, 0x8},
>> + {DVBT_SCALE1_B92, 0x4},
>> + {DVBT_SCALE1_B93, 0xb0},
>> + {DVBT_SCALE1_BA7, 0x78},
>> + {DVBT_SCALE1_BA9, 0x28},
>> + {DVBT_SCALE1_BAA, 0x59},
>> + {DVBT_SCALE1_BAB, 0x83},
>> + {DVBT_SCALE1_BAC, 0xd4},
>> + {DVBT_SCALE1_BB0, 0x65},
>> + {DVBT_SCALE1_BB1, 0x43},
>> + {DVBT_KB_P1, 0x1},
>> + {DVBT_KB_P2, 0x4},
>> + {DVBT_KB_P3, 0x7},
>> + {DVBT_K1_CR_STEP12, 0xa},
>> + {DVBT_REG_GPE, 0x1},
>> + {DVBT_SERIAL, 0x0},
>> + {DVBT_CDIV_PH0, 0x9},
>> + {DVBT_CDIV_PH1, 0x9},
>> + {DVBT_MPEG_IO_OPT_2_2, 0x0},
>> + {DVBT_MPEG_IO_OPT_1_0, 0x0},
>> + {DVBT_TRK_KS_P2, 0x4},
>> + {DVBT_TRK_KS_I2, 0x7},
>> + {DVBT_TR_THD_SET2, 0x6},
>> + {DVBT_TRK_KC_I2, 0x5},
>> + {DVBT_CR_THD_SET2, 0x1},
>> +
>> +
>> + };
>> +
>> + static rtl2832_reg_value rtl2832_initial_regs_2[] = {
>> + {DVBT_SPEC_INV, 0x0},
>> + {DVBT_DAGC_TRG_VAL, 0x5a},
>> + {DVBT_AGC_TARG_VAL_0, 0x0},
>> + {DVBT_AGC_TARG_VAL_8_1, 0x5a},
>> + {DVBT_AAGC_LOOP_GAIN, 0x16},
>> + {DVBT_LOOP_GAIN2_3_0, 0x6},
>> + {DVBT_LOOP_GAIN2_4, 0x1},
>> + {DVBT_LOOP_GAIN3, 0x16},
>> + {DVBT_VTOP1, 0x35},
>> + {DVBT_VTOP2, 0x21},
>> + {DVBT_VTOP3, 0x21},
>> + {DVBT_KRF1, 0x0},
>> + {DVBT_KRF2, 0x40},
>> + {DVBT_KRF3, 0x10},
>> + {DVBT_KRF4, 0x10},
>> + {DVBT_IF_AGC_MIN, 0x80},
>> + {DVBT_IF_AGC_MAX, 0x7f},
>> + {DVBT_RF_AGC_MIN, 0x80},
>> + {DVBT_RF_AGC_MAX, 0x7f},
>> + {DVBT_POLAR_RF_AGC, 0x0},
>> + {DVBT_POLAR_IF_AGC, 0x0},
>> + {DVBT_AD7_SETTING, 0xe9bf},
>> + {DVBT_EN_GI_PGA, 0x0},
>> + {DVBT_THD_LOCK_UP, 0x0},
>> + {DVBT_THD_LOCK_DW, 0x0},
>> + {DVBT_THD_UP1, 0x11},
>> + {DVBT_THD_DW1, 0xef},
>> + {DVBT_INTER_CNT_LEN, 0xc},
>> + {DVBT_GI_PGA_STATE, 0x0},
>> + {DVBT_EN_AGC_PGA, 0x1},
>> + {DVBT_IF_AGC_MAN, 0x0},
>> + };
>
> Maybe you can check indention here too. Kernel indention is 1 tab == 8
> spaces wide. Check your editor has correct settings.
>
>> +
>> +
>> + dbg("%s", __func__);
>> +
>> + en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
>> +
>> + /*
>> + * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
>> + * / CrystalFreqHz)
>> + */
>> + pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
>> + pset_iffreq *= 0x400000;
>> + pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
>> + pset_iffreq = pset_iffreq& 0x3fffff;
>> +
>> +
>> +
>> + for (i = 0; i< 42; i++) {
>
> You should use ARRAY_SIZE() likely here or some other macro.
>
>> + ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs_1[i].reg,
>> + rtl2832_initial_regs_1[i].value);
>> + if (ret)
>> + goto err;
>> + }
>> +
>> + /* if frequency settings */
>> + ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
>> + if (ret)
>> + goto err;
>> +
>> + ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
>> + if (ret)
>> + goto err;
>> +
>> + for (i = 0; i< 31; i++) {
>
> ARRAY_SIZE()
>
>> + ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs_2[i].reg,
>> + rtl2832_initial_regs_2[i].value);
>> + if (ret)
>> + goto err;
>
> What is the reason behind you have split inittab as a two parts?
>
>> + }
>> +
>> + priv->sleeping = false;
>> +
>> + return ret;
>> +
>> +err:
>> + return ret;
>
> excessive return
>
>> +}
>> +
>> +static int rtl2832_sleep(struct dvb_frontend *fe)
>> +{
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> +
>> + dbg("%s", __func__);
>> + priv->sleeping = true;
>> + return 0;
>> +}
>> +
>> +int rtl2832_get_tune_settings(struct dvb_frontend *fe,
>> + struct dvb_frontend_tune_settings *s)
>> +{
>> + dbg("%s", __func__);
>> + s->min_delay_ms = 1000;
>> + s->step_size = fe->ops.info.frequency_stepsize * 2;
>> + s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
>> + return 0;
>> +}
>> +
>> +static int rtl2832_set_frontend(struct dvb_frontend *fe)
>> +{
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> + struct dtv_frontend_properties *c =&fe->dtv_property_cache;
>> + int ret, i, j;
>> + u64 bw_mode, num, num2;
>> + u32 resamp_ratio, cfreq_off_ratio;
>> +
>> +
>> + static u8 bw_params[3][32] = {
>> + /* 6 MHz bandwidth */
>> + {
>> + 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
>> + 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
>> + 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
>> + 0x19, 0xe0,
>> + },
>> +
>> + /* 7 MHz bandwidth */
>> + {
>> + 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
>> + 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
>> + 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
>> + 0x19, 0x10,
>> + },
>> +
>> + /* 8 MHz bandwidth */
>> + {
>> + 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
>> + 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
>> + 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
>> + 0x19, 0xe0,
>> + },
>> + };
>> +
>> +
>> + dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
>> + c->frequency, c->bandwidth_hz, c->inversion);
>> +
>> +
>> + /* program tuner */
>> + if (fe->ops.tuner_ops.set_params)
>> + fe->ops.tuner_ops.set_params(fe);
>> +
>> +
>> + switch (c->bandwidth_hz) {
>> + case 6000000:
>> + i = 0;
>> + bw_mode = 48000000;
>> + break;
>> + case 7000000:
>> + i = 1;
>> + bw_mode = 56000000;
>> + break;
>> + case 8000000:
>> + i = 2;
>> + bw_mode = 64000000;
>> + break;
>> + default:
>> + dbg("invalid bandwidth");
>> + return -EINVAL;
>> + }
>> +
>> + for (j = 0; j< 32; j++) {
>
> use sizeof() here
>
>> + ret = rtl2832_wr_regs(priv, 0x1c+j, 1,&bw_params[i][j], 1);
>> + if (ret)
>> + goto err;
>> + }
>> +
>> + /* calculate and set resample ratio
>> + * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
>> + * / ConstWithBandwidthMode)
>> + */
>> + num = priv->cfg.xtal * 7;
>> + num *= 0x400000;
>> + num = div_u64(num, bw_mode);
>> + resamp_ratio = num& 0x3ffffff;
>> + ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
>> + if (ret)
>> + goto err;
>> +
>> + /* calculate and set cfreq off ratio
>> + * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
>> + * / (CrystalFreqHz * 7))
>> + */
>> + num = bw_mode<< 20;
>> + num2 = priv->cfg.xtal * 7;
>> + num = div_u64(num, num2);
>> + num = -num;
>> + cfreq_off_ratio = num& 0xfffff;
>> + ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO,
>> cfreq_off_ratio);
>> + if (ret)
>> + goto err;
>> +
>> +
>> + /* soft reset */
>> + ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
>> + if (ret)
>> + goto err;
>> +
>> + ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
>> + if (ret)
>> + goto err;
>> +
>> + return ret;
>> +err:
>> + info("%s: failed=%d", __func__, ret);
>> + return ret;
>> +}
>> +
>> +static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t
>> *status)
>> +{
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> + int ret;
>> + u32 tmp;
>> + *status = 0;
>> +
>> +
>> + dbg("%s", __func__);
>> + if (priv->sleeping)
>> + return 0;
>> +
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE,&tmp);
>> + if (ret)
>> + goto err;
>> +
>> + if (tmp == 11) {
>> + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
>> + FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
>> + }
>> + /* TODO find out if this is also true for rtl2832? */
>> + /*else if (tmp == 10) {
>> + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
>> + FE_HAS_VITERBI;
>> + }*/
>> +
>> + return ret;
>> +err:
>> + info("%s: failed=%d", __func__, ret);
>> + return ret;
>> +}
>> +
>> +
>> +#define RTL2832_CE_EST_EVM_MAX_VALUE 65535
>> +#define RTL2832_SNR_FRAC_BIT_NUM 10
>> +#define RTL2832_SNR_DB_DEN 3402
>> +
>> +static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
>> +{
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> + int ret;
>> + u64 num;
>> + u32 ce_est_evm, fsm_stage, constellation, hierarchy;
>> +
>> + /* Calculated by: 10 * log2(Norm * pow(2, 11)) * pow(2, 10) */
>> + static const long SnrDbNum[3][4] = {
>
> These numbers fits surely smaller space than a long.
>
>> + {122880, 122880, 122880, 122880, },
>> + {146657, 146657, 156897, 171013, },
>> + {167857, 167857, 173127, 181810, },
>> + };
>> +
>> + static const int snrMaxDb[3] = { 23, 26, 29, };
>
> and same here. Wasting few bytes of memory.
>
> And for both of those lastly mentioned : those are against naming rules.
> See naming rules from the Kernel documentation (or just rename style
> snr_max_db).
>
>> +
>> + dbg("%s", __func__);
>> +
>> + /* get FSM Stage */
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE,&fsm_stage);
>> + if (ret)
>> + goto err;
>> +
>> + if (fsm_stage< 10) {
>> + ce_est_evm = RTL2832_CE_EST_EVM_MAX_VALUE;
>> + } else {
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_CE_EST_EVM,&ce_est_evm);
>> + if (ret)
>> + goto err;
>> + }
>> +
>> + /* get constellation */
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_RX_CONSTEL,&constellation);
>> + if (ret)
>> + goto err;
>> + if (constellation> 2)
>> + goto err;
>> +
>> + /* get hierarchy */
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_RX_HIER,&hierarchy);
>> + if (ret)
>> + goto err;
>> + if (hierarchy> 3)
>> + goto err;
>> +
>> +
>> + /*
>> + SNR dB formula
>> + Original formula: SNR_dB = 10 * log10(Norm * pow(2, 11) / CeEstEvm)
>> + Adjusted formula: SNR_dB = (SNR_DB_NUM_CONST - 10 *
>> log2(CeEstEvm) *
>> + pow(2, 10)) / SNR_DB_DEN
>> + SNR_DB_NUM_CONST = 10 * log2(Norm * pow(2, 11)) *
>> + pow(2, 10)
>> + SNR_DB_DEN = log2(10) * pow(2, 10) = 3402 = 0xd4a
>> + Norm:
>> + None Alpha=1 Alpha=2 Alpha=4
>> + 4-QAM 2 2 2 2
>> + 16-QAM 10 10 20 52
>> + 64-QAM 42 42 60 108
>> + */
>> +
>> + /* intlog2 returns log2(x)<< 24 */
>> + num = intlog2(ce_est_evm)>>14;
>> + num = SnrDbNum[constellation][hierarchy] - 10 * num;
>> +
>> + num = div_u64(num, RTL2832_SNR_DB_DEN);
>> + num *= 0xffff;
>> + num = div_u64(num, snrMaxDb[constellation]);
>> +
>> + if (num> 0xffff)
>> + *snr = 0xffff;
>> + else if (num< 0)
>> + *snr = 0;
>> + else
>> + *snr = 0xffff& num;
>
> This is implemented stupidly. num has type u64 *unsigned 64 bit*. Checks
> like that are mostly useless. If you think it twice you can understand
> it will never go to the else if (). Also dropping upper bits starting
> from the 0xffff (else branch) is useless as you have compared it cannot
> be such big value at the first if().
>
>> +
>> + return ret;
>> +
>> +err:
>> + info("%s: failed=%d", __func__, ret);
>> + return ret;
>> +}
>
> Afer some testing I saw this does not work. It returns some crazy numers
> all the time like "b960" => 4745.6 dB uh. Not possible at all.
>
> That driver:
> status 1f | signal 2f2f | snr b960 | ber 00000000 | unc 00000064 |
> FE_HAS_LOCK
> AF9033 driver:
> status 1f | signal 68f5 | snr 0122 | ber 00000000 | unc 00000000 |
> FE_HAS_LOCK
>
> All(?) statistics are quite broken in mean of returned values.
>
>
>> +
>> +static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
>> +{
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> + int ret;
>> + u32 tmp;
>> +
>> + dbg("%s", __func__);
>> +
>> + /* get BER */
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_RSD_BER_EST,&tmp);
>> + if (ret)
>> + goto err;
>> +
>> + *ber = tmp;
>> + return ret;
>> +
>> +err:
>> + info("%s: failed=%d", __func__, ret);
>> + *ber = 19616;
>
> 19616?? what are those magic numbers... it is error situation that
> should never happen (but happens likely when called during sleep).
> Leaving *ber untouched in that kind of error situation is just good
> choise. Caller surely will not look returned value when error status is
> returned.
>
>> + return ret;
>> +}
>> +
>> +static int rtl2832_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
>> +{
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> + int ret;
>> + u32 tmp;
>> + u16 num;
>> +
>> + dbg("%s", __func__);
>> +
>> +
>> + /* get FSM Stage */
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE,&tmp);
>> + if (ret)
>> + goto err;
>> +
>> + /* if signal is not locked quality is zero */
>> + if (tmp< 10) {
>> + *ucblocks = 0;
>> + return 0;
>> + }
>> +
>> + /* get BER */
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_RSD_BER_EST,&tmp);
>> + if (ret)
>> + goto err;
>> +
>> + /*
>> + Determine signal quality according to RSD_BER_EST.
>> + Note: Map RSD_BER_EST value 8192 ~ 128 to 10 ~ 100
>> + Original formula: SignalQuality = 205 - 15 * log2(RSD_BER_EST)
>> + Adjusted formula: SignalQuality = ((205<< 5) - 15 *
>> + (log2(RSD_BER_EST)<< 5))>> 5
>> + If RSD_BER_EST> 8192, signal quality is 10.
>> + If RSD_BER_EST< 128, signal quality is 100.
>> + */
>> +
>> + if (tmp> 8192)
>> + *ucblocks = 10;
>> + else if (tmp< 128)
>> + *ucblocks = 100;
>> + else {
>> + num = intlog2(tmp)>> 19;
>> + *ucblocks = ((205<< 5) - 15 * num)>> 5;
>> + }
>> +
>> + return 0;
>> +
>> +err:
>> + info("%s: failed=%d", __func__, ret);
>> + *ucblocks = 0;
>
> Same here. If it returns error status then returned values are not valid
> in any way.
>
>> + return ret;
>> +}
>
> I have strong feeling whole callback is totally wrong. Looks like you
> are calculating signal quality - not bit error rate as should. Signal
> quality is likely same as SNR - or SNR is way to measure signal quality.
> But BER is quite much different.
>
> And thats why it reports always for me 0x64 == 100.
>
>> +
>> +
>> +static int rtl2832_read_signal_strength(struct dvb_frontend *fe, u16
>> *strength)
>> +{
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> + int ret, if_agc;
>> + u32 fsm_stage, if_agc_raw;
>> +
>> + dbg("%s", __func__);
>> +
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE,&fsm_stage);
>> + if (ret)
>> + goto err;
>
> oops, indentation
>
>> +
>> + if (fsm_stage< 10)
>> + *strength = 0;
> indentation
>
>> + else {
>> + /* if_agc is read as a 10bit binary */
>> + ret = rtl2832_rd_demod_reg(priv, DVBT_IF_AGC_VAL,&if_agc_raw);
>> + if (ret)
>> + goto err;
>> +
>> + if (if_agc_raw< (1<< 9))
>> + if_agc = if_agc_raw;
>> + else
>> + if_agc = -(~(if_agc_raw-1)& 0x1ff);
>> +
>> + *strength = 55 - if_agc / 182;
>> + *strength |= *strength<< 8;
>
> That calculation shows doubtful. Why not to scale directly to the
> counter. Now you divide it by 182 and after that multiply 256 (<< 8
> means same as multiply by 256). It is stupid calculation.
>
>> + }
>> + return 0;
>> +err:
>> + info("%s: failed=%d", __func__, ret);
>> + return ret;
>> +}
>> +
>> +static struct dvb_frontend_ops rtl2832_ops;
>> +
>> +static void rtl2832_release(struct dvb_frontend *fe)
>> +{
>> + struct rtl2832_priv *priv = fe->demodulator_priv;
>> +
>> + dbg("%s", __func__);
>> + kfree(priv);
>> +}
>> +
>> +struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
>> + struct i2c_adapter *i2c)
>> +{
>> + struct rtl2832_priv *priv = NULL;
>> + int ret = 0;
>> + u8 tmp;
>> +
>> + dbg("%s", __func__);
>> +
>> + /* allocate memory for the internal state */
>> + priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
>> + if (priv == NULL)
>> + goto err;
>> +
>> + /* setup the priv */
>> + priv->i2c = i2c;
>> + priv->tuner = cfg->tuner;
>> + memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
>> +
>> + /* check if the demod is there */
>> + ret = rtl2832_rd_reg(priv, 0x00, 0x0,&tmp);
>> + if (ret)
>> + goto err;
>> +
>> + /* create dvb_frontend */
>> + memcpy(&priv->fe.ops,&rtl2832_ops, sizeof(struct dvb_frontend_ops));
>> + priv->fe.demodulator_priv = priv;
>> +
>> + /* TODO implement sleep mode depending on RC */
>> + priv->sleeping = true;
>
> Demod sleep does not have nothing to do with remote AFAIK. Wrong comment?
>
>> +
>> + return&priv->fe;
>> +err:
>> + dbg("%s: failed=%d", __func__, ret);
>> + kfree(priv);
>> + return NULL;
>> +}
>> +EXPORT_SYMBOL(rtl2832_attach);
>> +
>> +static struct dvb_frontend_ops rtl2832_ops = {
>> + .delsys = { SYS_DVBT },
>> + .info = {
>> + .name = "Realtek RTL2832 (DVB-T)",
>> + .type = FE_OFDM,
>
> .type is no longer used as there is .delsys so remove it.
> I wonder why it even exists struct dvb_frontend_ops...
>
>> + .frequency_min = 50000000,
>
> Smallest DVB-T frequency is ~174MHz. 50MHz is for DVB-C...
>
>> + .frequency_max = 862000000,
>> + .frequency_stepsize = 166667,
>> + .caps = FE_CAN_FEC_1_2 |
>> + FE_CAN_FEC_2_3 |
>> + FE_CAN_FEC_3_4 |
>> + FE_CAN_FEC_5_6 |
>> + FE_CAN_FEC_7_8 |
>> + FE_CAN_FEC_AUTO |
>> + FE_CAN_QPSK |
>> + FE_CAN_QAM_16 |
>> + FE_CAN_QAM_64 |
>> + FE_CAN_QAM_AUTO |
>> + FE_CAN_TRANSMISSION_MODE_AUTO |
>> + FE_CAN_GUARD_INTERVAL_AUTO |
>> + FE_CAN_HIERARCHY_AUTO |
>> + FE_CAN_RECOVER |
>> + FE_CAN_MUTE_TS
>> + },
>> +
>> + .release = rtl2832_release,
>> +
>> + .init = rtl2832_init,
>> + .sleep = rtl2832_sleep,
>> +
>> + .get_tune_settings = rtl2832_get_tune_settings,
>> +
>> + .set_frontend = rtl2832_set_frontend,
>> +
>> + .read_status = rtl2832_read_status,
>> + .read_snr = rtl2832_read_snr,
>> + .read_ber = rtl2832_read_ber,
>> + .read_ucblocks = rtl2832_read_ucblocks,
>> + .read_signal_strength = rtl2832_read_signal_strength,
>> + .i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
>> +};
>> +
>> +MODULE_AUTHOR("Thomas Mair<mair.thomas86@gmail.com>");
>> +MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
>> +MODULE_LICENSE("GPL");
>> +MODULE_VERSION("0.3");
>> diff --git a/drivers/media/dvb/frontends/rtl2832.h
>> b/drivers/media/dvb/frontends/rtl2832.h
>> new file mode 100644
>> index 0000000..6918010
>> --- /dev/null
>> +++ b/drivers/media/dvb/frontends/rtl2832.h
>> @@ -0,0 +1,81 @@
>> +/*
>> + * Realtek RTL2832 DVB-T demodulator driver
>> + *
>> + * Copyright (C) 2012 Thomas Mair<thomas.mair86@gmail.com>
>> + *
>> + * 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.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#ifndef RTL2832_H
>> +#define RTL2832_H
>> +
>> +#include<linux/dvb/frontend.h>
>> +
>> +struct rtl2832_config {
>> + /*
>> + * Demodulator I2C address.
>> + */
>> + u8 i2c_addr;
>> +
>> + /*
>> + * Xtal frequency.
>> + * Hz
>> + * 4000000, 16000000, 25000000, 28800000
>> + */
>> + u32 xtal;
>> +
>> + /*
>> + * IFs for all used modes.
>> + * Hz
>> + * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
>> + */
>> + u32 if_dvbt;
>> +
>> + /*
>> + */
>> + u8 tuner;
>> +};
>> +
>> +
>> +#if defined(CONFIG_DVB_RTL2832) || \
>> + (defined(CONFIG_DVB_RTL2832_MODULE)&& defined(MODULE))
>> +extern struct dvb_frontend *rtl2832_attach(
>> + const struct rtl2832_config *cfg,
>> + struct i2c_adapter *i2c
>> +);
>> +
>> +extern struct i2c_adapter *rtl2832_get_tuner_i2c_adapter(
>> + struct dvb_frontend *fe
>> +);
>> +#else
>> +static inline struct dvb_frontend *rtl2832_attach(
>> + const struct rtl2832_config *config,
>> + struct i2c_adapter *i2c
>> +)
>> +{
>> + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
>> + return NULL;
>> +}
>> +
>> +static inline struct i2c_adapter *rtl2832_get_tuner_i2c_adapter(
>> + struct dvb_frontend *fe
>> +)
>> +{
>> + return NULL;
>> +}
>
> There is no i2c_adapter to export. It is copy paste error from the
> RTL2830 which needs I2C-adapter due to automatic I2C-gate close.
>
>> +#endif
>> +
>> +
>> +#endif /* RTL2832_H */
>> diff --git a/drivers/media/dvb/frontends/rtl2832_priv.h
>> b/drivers/media/dvb/frontends/rtl2832_priv.h
>> new file mode 100644
>> index 0000000..0f5df2f
>> --- /dev/null
>> +++ b/drivers/media/dvb/frontends/rtl2832_priv.h
>> @@ -0,0 +1,260 @@
>> +/*
>> + * Realtek RTL2832 DVB-T demodulator driver
>> + *
>> + * Copyright (C) 2012 Thomas Mair<thomas.mair86@gmail.com>
>> + *
>> + * 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.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#ifndef RTL2832_PRIV_H
>> +#define RTL2832_PRIV_H
>> +
>> +#include "dvb_frontend.h"
>> +#include "rtl2832.h"
>> +
>> +#define LOG_PREFIX "rtl2832"
>> +
>> +#undef dbg
>> +#define dbg(f, arg...) \
>> + if (rtl2832_debug) \
>> + printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
>> +#undef err
>> +#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ##
>> arg)
>> +#undef info
>> +#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
>> +#undef warn
>> +#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" ,
>> ## arg)
>> +
>> +struct rtl2832_priv {
>> + struct i2c_adapter *i2c;
>> + struct dvb_frontend fe;
>> + struct rtl2832_config cfg;
>> +
>> + bool i2c_gate_state;
>> + bool sleeping;
>> +
>> + u8 tuner;
>> + u8 page; /* active register page */
>> +};
>> +
>> +typedef struct {
>> + u8 page;
>> + u8 start_address;
>> + u8 msb;
>> + u8 lsb;
>> +}
>> +rtl2832_reg_entry;
>
> typedefs are not allowed
>
>> +
>> +typedef struct {
>> + int reg;
>> + u32 value;
>> +}
>> +rtl2832_reg_value;
>
> typedefs are not allowed
>
>> +
>> +
>> +/* Demod register bit names */
>> +enum DVBT_REG_BIT_NAME {
>> + DVBT_SOFT_RST,
>> + DVBT_IIC_REPEAT,
>> + DVBT_TR_WAIT_MIN_8K,
>> + DVBT_RSD_BER_FAIL_VAL,
>> + DVBT_EN_BK_TRK,
>> + DVBT_REG_PI,
>> + DVBT_REG_PFREQ_1_0,
>> + DVBT_PD_DA8,
>> + DVBT_LOCK_TH,
>> + DVBT_BER_PASS_SCAL,
>> + DVBT_CE_FFSM_BYPASS,
>> + DVBT_ALPHAIIR_N,
>> + DVBT_ALPHAIIR_DIF,
>> + DVBT_EN_TRK_SPAN,
>> + DVBT_LOCK_TH_LEN,
>> + DVBT_CCI_THRE,
>> + DVBT_CCI_MON_SCAL,
>> + DVBT_CCI_M0,
>> + DVBT_CCI_M1,
>> + DVBT_CCI_M2,
>> + DVBT_CCI_M3,
>> + DVBT_SPEC_INIT_0,
>> + DVBT_SPEC_INIT_1,
>> + DVBT_SPEC_INIT_2,
>> + DVBT_AD_EN_REG,
>> + DVBT_AD_EN_REG1,
>> + DVBT_EN_BBIN,
>> + DVBT_MGD_THD0,
>> + DVBT_MGD_THD1,
>> + DVBT_MGD_THD2,
>> + DVBT_MGD_THD3,
>> + DVBT_MGD_THD4,
>> + DVBT_MGD_THD5,
>> + DVBT_MGD_THD6,
>> + DVBT_MGD_THD7,
>> + DVBT_EN_CACQ_NOTCH,
>> + DVBT_AD_AV_REF,
>> + DVBT_PIP_ON,
>> + DVBT_SCALE1_B92,
>> + DVBT_SCALE1_B93,
>> + DVBT_SCALE1_BA7,
>> + DVBT_SCALE1_BA9,
>> + DVBT_SCALE1_BAA,
>> + DVBT_SCALE1_BAB,
>> + DVBT_SCALE1_BAC,
>> + DVBT_SCALE1_BB0,
>> + DVBT_SCALE1_BB1,
>> + DVBT_KB_P1,
>> + DVBT_KB_P2,
>> + DVBT_KB_P3,
>> + DVBT_OPT_ADC_IQ,
>> + DVBT_AD_AVI,
>> + DVBT_AD_AVQ,
>> + DVBT_K1_CR_STEP12,
>> + DVBT_TRK_KS_P2,
>> + DVBT_TRK_KS_I2,
>> + DVBT_TR_THD_SET2,
>> + DVBT_TRK_KC_P2,
>> + DVBT_TRK_KC_I2,
>> + DVBT_CR_THD_SET2,
>> + DVBT_PSET_IFFREQ,
>> + DVBT_SPEC_INV,
>> + DVBT_BW_INDEX,
>> + DVBT_RSAMP_RATIO,
>> + DVBT_CFREQ_OFF_RATIO,
>> + DVBT_FSM_STAGE,
>> + DVBT_RX_CONSTEL,
>> + DVBT_RX_HIER,
>> + DVBT_RX_C_RATE_LP,
>> + DVBT_RX_C_RATE_HP,
>> + DVBT_GI_IDX,
>> + DVBT_FFT_MODE_IDX,
>> + DVBT_RSD_BER_EST,
>> + DVBT_CE_EST_EVM,
>> + DVBT_RF_AGC_VAL,
>> + DVBT_IF_AGC_VAL,
>> + DVBT_DAGC_VAL,
>> + DVBT_SFREQ_OFF,
>> + DVBT_CFREQ_OFF,
>> + DVBT_POLAR_RF_AGC,
>> + DVBT_POLAR_IF_AGC,
>> + DVBT_AAGC_HOLD,
>> + DVBT_EN_RF_AGC,
>> + DVBT_EN_IF_AGC,
>> + DVBT_IF_AGC_MIN,
>> + DVBT_IF_AGC_MAX,
>> + DVBT_RF_AGC_MIN,
>> + DVBT_RF_AGC_MAX,
>> + DVBT_IF_AGC_MAN,
>> + DVBT_IF_AGC_MAN_VAL,
>> + DVBT_RF_AGC_MAN,
>> + DVBT_RF_AGC_MAN_VAL,
>> + DVBT_DAGC_TRG_VAL,
>> + DVBT_AGC_TARG_VAL,
>> + DVBT_LOOP_GAIN_3_0,
>> + DVBT_LOOP_GAIN_4,
>> + DVBT_VTOP,
>> + DVBT_KRF,
>> + DVBT_AGC_TARG_VAL_0,
>> + DVBT_AGC_TARG_VAL_8_1,
>> + DVBT_AAGC_LOOP_GAIN,
>> + DVBT_LOOP_GAIN2_3_0,
>> + DVBT_LOOP_GAIN2_4,
>> + DVBT_LOOP_GAIN3,
>> + DVBT_VTOP1,
>> + DVBT_VTOP2,
>> + DVBT_VTOP3,
>> + DVBT_KRF1,
>> + DVBT_KRF2,
>> + DVBT_KRF3,
>> + DVBT_KRF4,
>> + DVBT_EN_GI_PGA,
>> + DVBT_THD_LOCK_UP,
>> + DVBT_THD_LOCK_DW,
>> + DVBT_THD_UP1,
>> + DVBT_THD_DW1,
>> + DVBT_INTER_CNT_LEN,
>> + DVBT_GI_PGA_STATE,
>> + DVBT_EN_AGC_PGA,
>> + DVBT_CKOUTPAR,
>> + DVBT_CKOUT_PWR,
>> + DVBT_SYNC_DUR,
>> + DVBT_ERR_DUR,
>> + DVBT_SYNC_LVL,
>> + DVBT_ERR_LVL,
>> + DVBT_VAL_LVL,
>> + DVBT_SERIAL,
>> + DVBT_SER_LSB,
>> + DVBT_CDIV_PH0,
>> + DVBT_CDIV_PH1,
>> + DVBT_MPEG_IO_OPT_2_2,
>> + DVBT_MPEG_IO_OPT_1_0,
>> + DVBT_CKOUTPAR_PIP,
>> + DVBT_CKOUT_PWR_PIP,
>> + DVBT_SYNC_LVL_PIP,
>> + DVBT_ERR_LVL_PIP,
>> + DVBT_VAL_LVL_PIP,
>> + DVBT_CKOUTPAR_PID,
>> + DVBT_CKOUT_PWR_PID,
>> + DVBT_SYNC_LVL_PID,
>> + DVBT_ERR_LVL_PID,
>> + DVBT_VAL_LVL_PID,
>> + DVBT_SM_PASS,
>> + DVBT_UPDATE_REG_2,
>> + DVBT_BTHD_P3,
>> + DVBT_BTHD_D3,
>> + DVBT_FUNC4_REG0,
>> + DVBT_FUNC4_REG1,
>> + DVBT_FUNC4_REG2,
>> + DVBT_FUNC4_REG3,
>> + DVBT_FUNC4_REG4,
>> + DVBT_FUNC4_REG5,
>> + DVBT_FUNC4_REG6,
>> + DVBT_FUNC4_REG7,
>> + DVBT_FUNC4_REG8,
>> + DVBT_FUNC4_REG9,
>> + DVBT_FUNC4_REG10,
>> + DVBT_FUNC5_REG0,
>> + DVBT_FUNC5_REG1,
>> + DVBT_FUNC5_REG2,
>> + DVBT_FUNC5_REG3,
>> + DVBT_FUNC5_REG4,
>> + DVBT_FUNC5_REG5,
>> + DVBT_FUNC5_REG6,
>> + DVBT_FUNC5_REG7,
>> + DVBT_FUNC5_REG8,
>> + DVBT_FUNC5_REG9,
>> + DVBT_FUNC5_REG10,
>> + DVBT_FUNC5_REG11,
>> + DVBT_FUNC5_REG12,
>> + DVBT_FUNC5_REG13,
>> + DVBT_FUNC5_REG14,
>> + DVBT_FUNC5_REG15,
>> + DVBT_FUNC5_REG16,
>> + DVBT_FUNC5_REG17,
>> + DVBT_FUNC5_REG18,
>> + DVBT_AD7_SETTING,
>> + DVBT_RSSI_R,
>> + DVBT_ACI_DET_IND,
>> + DVBT_REG_MON,
>> + DVBT_REG_MONSEL,
>> + DVBT_REG_GPE,
>> + DVBT_REG_GPO,
>> + DVBT_REG_4MSEL,
>> + DVBT_TEST_REG_1,
>> + DVBT_TEST_REG_2,
>> + DVBT_TEST_REG_3,
>> + DVBT_TEST_REG_4,
>> + DVBT_REG_BIT_NAME_ITEM_TERMINATOR,
>> +};
>> +
>> +#endif /* RTL2832_PRIV_H */
>
> Puuuh, there was more findings what I supposed earlier. Most of those
> are easy to fix.
>
> But it seems like all the statistics are broken, returning wrong values
> and one BER was even inplemented as a signal quality meter.
>
> What you say if I propose you to remove those statistics and sent driver
> without? Add those then later.
>
> Statistics are not mandatory and it is 3.4-RC7 phase ongoing. It means
> driver should be quite ready during that week if we want it to the
> Kernel 3.5. I am almost sure Kernel 3.4 is released next weekend...
>
> regards
> Antti
As far as I can manage, according to your reply are those FE(rtl2832)
patches:
-rtl2832.c.diff
-rtl2832.h.diff
-rtl2832_priv.h.diff
Tested on 3.3.5-2.fc16.x86_64 - PASSED.
femon -H -a 2 -c 5
FE: Realtek RTL2832 (DVB-T) (DVBT)
status SCVYL | signal 23% | snr 0% | ber 0 | unc 100 | FE_HAS_LOCK
status SCVYL | signal 23% | snr 0% | ber 0 | unc 100 | FE_HAS_LOCK
status SCVYL | signal 23% | snr 0% | ber 0 | unc 100 | FE_HAS_LOCK
status SCVYL | signal 23% | snr 0% | ber 0 | unc 100 | FE_HAS_LOCK
status SCVYL | signal 23% | snr 0% | ber 0 | unc 100 | FE_HAS_LOCK
Cheers,
poma
[-- Attachment #2: rtl2832.c.diff --]
[-- Type: text/x-patch, Size: 20911 bytes --]
--- linux/drivers/media/dvb/frontends/rtl2832.c.orig 2012-05-16 06:46:22.205817091 +0200
+++ linux/drivers/media/dvb/frontends/rtl2832.c 2012-05-16 06:43:29.922912031 +0200
@@ -62,134 +62,134 @@
0xffffffff
};
-static const rtl2832_reg_entry registers[] = {
- [DVBT_SOFT_RST] = {0x1, 0x1, 2, 2},
- [DVBT_IIC_REPEAT] = {0x1, 0x1, 3, 3},
- [DVBT_TR_WAIT_MIN_8K] = {0x1, 0x88, 11, 2},
- [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
- [DVBT_EN_BK_TRK] = {0x1, 0xa6, 7, 7},
- [DVBT_AD_EN_REG] = {0x0, 0x8, 7, 7},
- [DVBT_AD_EN_REG1] = {0x0, 0x8, 6, 6},
- [DVBT_EN_BBIN] = {0x1, 0xb1, 0, 0},
- [DVBT_MGD_THD0] = {0x1, 0x95, 7, 0},
- [DVBT_MGD_THD1] = {0x1, 0x96, 7, 0},
- [DVBT_MGD_THD2] = {0x1, 0x97, 7, 0},
- [DVBT_MGD_THD3] = {0x1, 0x98, 7, 0},
- [DVBT_MGD_THD4] = {0x1, 0x99, 7, 0},
- [DVBT_MGD_THD5] = {0x1, 0x9a, 7, 0},
- [DVBT_MGD_THD6] = {0x1, 0x9b, 7, 0},
- [DVBT_MGD_THD7] = {0x1, 0x9c, 7, 0},
- [DVBT_EN_CACQ_NOTCH] = {0x1, 0x61, 4, 4},
- [DVBT_AD_AV_REF] = {0x0, 0x9, 6, 0},
- [DVBT_REG_PI] = {0x0, 0xa, 2, 0},
- [DVBT_PIP_ON] = {0x0, 0x21, 3, 3},
- [DVBT_SCALE1_B92] = {0x2, 0x92, 7, 0},
- [DVBT_SCALE1_B93] = {0x2, 0x93, 7, 0},
- [DVBT_SCALE1_BA7] = {0x2, 0xa7, 7, 0},
- [DVBT_SCALE1_BA9] = {0x2, 0xa9, 7, 0},
- [DVBT_SCALE1_BAA] = {0x2, 0xaa, 7, 0},
- [DVBT_SCALE1_BAB] = {0x2, 0xab, 7, 0},
- [DVBT_SCALE1_BAC] = {0x2, 0xac, 7, 0},
- [DVBT_SCALE1_BB0] = {0x2, 0xb0, 7, 0},
- [DVBT_SCALE1_BB1] = {0x2, 0xb1, 7, 0},
- [DVBT_KB_P1] = {0x1, 0x64, 3, 1},
- [DVBT_KB_P2] = {0x1, 0x64, 6, 4},
- [DVBT_KB_P3] = {0x1, 0x65, 2, 0},
- [DVBT_OPT_ADC_IQ] = {0x0, 0x6, 5, 4},
- [DVBT_AD_AVI] = {0x0, 0x9, 1, 0},
- [DVBT_AD_AVQ] = {0x0, 0x9, 3, 2},
- [DVBT_K1_CR_STEP12] = {0x2, 0xad, 9, 4},
- [DVBT_TRK_KS_P2] = {0x1, 0x6f, 2, 0},
- [DVBT_TRK_KS_I2] = {0x1, 0x70, 5, 3},
- [DVBT_TR_THD_SET2] = {0x1, 0x72, 3, 0},
- [DVBT_TRK_KC_P2] = {0x1, 0x73, 5, 3},
- [DVBT_TRK_KC_I2] = {0x1, 0x75, 2, 0},
- [DVBT_CR_THD_SET2] = {0x1, 0x76, 7, 6},
- [DVBT_PSET_IFFREQ] = {0x1, 0x19, 21, 0},
- [DVBT_SPEC_INV] = {0x1, 0x15, 0, 0},
- [DVBT_RSAMP_RATIO] = {0x1, 0x9f, 27, 2},
- [DVBT_CFREQ_OFF_RATIO] = {0x1, 0x9d, 23, 4},
- [DVBT_FSM_STAGE] = {0x3, 0x51, 6, 3},
- [DVBT_RX_CONSTEL] = {0x3, 0x3c, 3, 2},
- [DVBT_RX_HIER] = {0x3, 0x3c, 6, 4},
- [DVBT_RX_C_RATE_LP] = {0x3, 0x3d, 2, 0},
- [DVBT_RX_C_RATE_HP] = {0x3, 0x3d, 5, 3},
- [DVBT_GI_IDX] = {0x3, 0x51, 1, 0},
- [DVBT_FFT_MODE_IDX] = {0x3, 0x51, 2, 2},
- [DVBT_RSD_BER_EST] = {0x3, 0x4e, 15, 0},
- [DVBT_CE_EST_EVM] = {0x4, 0xc, 15, 0},
- [DVBT_RF_AGC_VAL] = {0x3, 0x5b, 13, 0},
- [DVBT_IF_AGC_VAL] = {0x3, 0x59, 13, 0},
- [DVBT_DAGC_VAL] = {0x3, 0x5, 7, 0},
- [DVBT_SFREQ_OFF] = {0x3, 0x18, 13, 0},
- [DVBT_CFREQ_OFF] = {0x3, 0x5f, 17, 0},
- [DVBT_POLAR_RF_AGC] = {0x0, 0xe, 1, 1},
- [DVBT_POLAR_IF_AGC] = {0x0, 0xe, 0, 0},
- [DVBT_AAGC_HOLD] = {0x1, 0x4, 5, 5},
- [DVBT_EN_RF_AGC] = {0x1, 0x4, 6, 6},
- [DVBT_EN_IF_AGC] = {0x1, 0x4, 7, 7},
- [DVBT_IF_AGC_MIN] = {0x1, 0x8, 7, 0},
- [DVBT_IF_AGC_MAX] = {0x1, 0x9, 7, 0},
- [DVBT_RF_AGC_MIN] = {0x1, 0xa, 7, 0},
- [DVBT_RF_AGC_MAX] = {0x1, 0xb, 7, 0},
- [DVBT_IF_AGC_MAN] = {0x1, 0xc, 6, 6},
- [DVBT_IF_AGC_MAN_VAL] = {0x1, 0xc, 13, 0},
- [DVBT_RF_AGC_MAN] = {0x1, 0xe, 6, 6},
- [DVBT_RF_AGC_MAN_VAL] = {0x1, 0xe, 13, 0},
- [DVBT_DAGC_TRG_VAL] = {0x1, 0x12, 7, 0},
- [DVBT_AGC_TARG_VAL_0] = {0x1, 0x2, 0, 0},
- [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3, 7, 0},
- [DVBT_AAGC_LOOP_GAIN] = {0x1, 0xc7, 5, 1},
- [DVBT_LOOP_GAIN2_3_0] = {0x1, 0x4, 4, 1},
- [DVBT_LOOP_GAIN2_4] = {0x1, 0x5, 7, 7},
- [DVBT_LOOP_GAIN3] = {0x1, 0xc8, 4, 0},
- [DVBT_VTOP1] = {0x1, 0x6, 5, 0},
- [DVBT_VTOP2] = {0x1, 0xc9, 5, 0},
- [DVBT_VTOP3] = {0x1, 0xca, 5, 0},
- [DVBT_KRF1] = {0x1, 0xcb, 7, 0},
- [DVBT_KRF2] = {0x1, 0x7, 7, 0},
- [DVBT_KRF3] = {0x1, 0xcd, 7, 0},
- [DVBT_KRF4] = {0x1, 0xce, 7, 0},
- [DVBT_EN_GI_PGA] = {0x1, 0xe5, 0, 0},
- [DVBT_THD_LOCK_UP] = {0x1, 0xd9, 8, 0},
- [DVBT_THD_LOCK_DW] = {0x1, 0xdb, 8, 0},
- [DVBT_THD_UP1] = {0x1, 0xdd, 7, 0},
- [DVBT_THD_DW1] = {0x1, 0xde, 7, 0},
- [DVBT_INTER_CNT_LEN] = {0x1, 0xd8, 3, 0},
- [DVBT_GI_PGA_STATE] = {0x1, 0xe6, 3, 3},
- [DVBT_EN_AGC_PGA] = {0x1, 0xd7, 0, 0},
- [DVBT_CKOUTPAR] = {0x1, 0x7b, 5, 5},
- [DVBT_CKOUT_PWR] = {0x1, 0x7b, 6, 6},
- [DVBT_SYNC_DUR] = {0x1, 0x7b, 7, 7},
- [DVBT_ERR_DUR] = {0x1, 0x7c, 0, 0},
- [DVBT_SYNC_LVL] = {0x1, 0x7c, 1, 1},
- [DVBT_ERR_LVL] = {0x1, 0x7c, 2, 2},
- [DVBT_VAL_LVL] = {0x1, 0x7c, 3, 3},
- [DVBT_SERIAL] = {0x1, 0x7c, 4, 4},
- [DVBT_SER_LSB] = {0x1, 0x7c, 5, 5},
- [DVBT_CDIV_PH0] = {0x1, 0x7d, 3, 0},
- [DVBT_CDIV_PH1] = {0x1, 0x7d, 7, 4},
- [DVBT_MPEG_IO_OPT_2_2] = {0x0, 0x6, 7, 7},
- [DVBT_MPEG_IO_OPT_1_0] = {0x0, 0x7, 7, 6},
- [DVBT_CKOUTPAR_PIP] = {0x0, 0xb7, 4, 4},
- [DVBT_CKOUT_PWR_PIP] = {0x0, 0xb7, 3, 3},
- [DVBT_SYNC_LVL_PIP] = {0x0, 0xb7, 2, 2},
- [DVBT_ERR_LVL_PIP] = {0x0, 0xb7, 1, 1},
- [DVBT_VAL_LVL_PIP] = {0x0, 0xb7, 0, 0},
- [DVBT_CKOUTPAR_PID] = {0x0, 0xb9, 4, 4},
- [DVBT_CKOUT_PWR_PID] = {0x0, 0xb9, 3, 3},
- [DVBT_SYNC_LVL_PID] = {0x0, 0xb9, 2, 2},
- [DVBT_ERR_LVL_PID] = {0x0, 0xb9, 1, 1},
- [DVBT_VAL_LVL_PID] = {0x0, 0xb9, 0, 0},
- [DVBT_SM_PASS] = {0x1, 0x93, 11, 0},
- [DVBT_AD7_SETTING] = {0x0, 0x11, 15, 0},
- [DVBT_RSSI_R] = {0x3, 0x1, 6, 0},
- [DVBT_ACI_DET_IND] = {0x3, 0x12, 0, 0},
- [DVBT_REG_MON] = {0x0, 0xd, 1, 0},
- [DVBT_REG_MONSEL] = {0x0, 0xd, 2, 2},
- [DVBT_REG_GPE] = {0x0, 0xd, 7, 7},
- [DVBT_REG_GPO] = {0x0, 0x10, 0, 0},
- [DVBT_REG_4MSEL] = {0x0, 0x13, 0, 0},
+struct rtl2832_reg_entry registers[] = {
+ [DVBT_SOFT_RST] = {0x1, 0x1, 2, 2},
+ [DVBT_IIC_REPEAT] = {0x1, 0x1, 3, 3},
+ [DVBT_TR_WAIT_MIN_8K] = {0x1, 0x88, 11, 2},
+ [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
+ [DVBT_EN_BK_TRK] = {0x1, 0xa6, 7, 7},
+ [DVBT_AD_EN_REG] = {0x0, 0x8, 7, 7},
+ [DVBT_AD_EN_REG1] = {0x0, 0x8, 6, 6},
+ [DVBT_EN_BBIN] = {0x1, 0xb1, 0, 0},
+ [DVBT_MGD_THD0] = {0x1, 0x95, 7, 0},
+ [DVBT_MGD_THD1] = {0x1, 0x96, 7, 0},
+ [DVBT_MGD_THD2] = {0x1, 0x97, 7, 0},
+ [DVBT_MGD_THD3] = {0x1, 0x98, 7, 0},
+ [DVBT_MGD_THD4] = {0x1, 0x99, 7, 0},
+ [DVBT_MGD_THD5] = {0x1, 0x9a, 7, 0},
+ [DVBT_MGD_THD6] = {0x1, 0x9b, 7, 0},
+ [DVBT_MGD_THD7] = {0x1, 0x9c, 7, 0},
+ [DVBT_EN_CACQ_NOTCH] = {0x1, 0x61, 4, 4},
+ [DVBT_AD_AV_REF] = {0x0, 0x9, 6, 0},
+ [DVBT_REG_PI] = {0x0, 0xa, 2, 0},
+ [DVBT_PIP_ON] = {0x0, 0x21, 3, 3},
+ [DVBT_SCALE1_B92] = {0x2, 0x92, 7, 0},
+ [DVBT_SCALE1_B93] = {0x2, 0x93, 7, 0},
+ [DVBT_SCALE1_BA7] = {0x2, 0xa7, 7, 0},
+ [DVBT_SCALE1_BA9] = {0x2, 0xa9, 7, 0},
+ [DVBT_SCALE1_BAA] = {0x2, 0xaa, 7, 0},
+ [DVBT_SCALE1_BAB] = {0x2, 0xab, 7, 0},
+ [DVBT_SCALE1_BAC] = {0x2, 0xac, 7, 0},
+ [DVBT_SCALE1_BB0] = {0x2, 0xb0, 7, 0},
+ [DVBT_SCALE1_BB1] = {0x2, 0xb1, 7, 0},
+ [DVBT_KB_P1] = {0x1, 0x64, 3, 1},
+ [DVBT_KB_P2] = {0x1, 0x64, 6, 4},
+ [DVBT_KB_P3] = {0x1, 0x65, 2, 0},
+ [DVBT_OPT_ADC_IQ] = {0x0, 0x6, 5, 4},
+ [DVBT_AD_AVI] = {0x0, 0x9, 1, 0},
+ [DVBT_AD_AVQ] = {0x0, 0x9, 3, 2},
+ [DVBT_K1_CR_STEP12] = {0x2, 0xad, 9, 4},
+ [DVBT_TRK_KS_P2] = {0x1, 0x6f, 2, 0},
+ [DVBT_TRK_KS_I2] = {0x1, 0x70, 5, 3},
+ [DVBT_TR_THD_SET2] = {0x1, 0x72, 3, 0},
+ [DVBT_TRK_KC_P2] = {0x1, 0x73, 5, 3},
+ [DVBT_TRK_KC_I2] = {0x1, 0x75, 2, 0},
+ [DVBT_CR_THD_SET2] = {0x1, 0x76, 7, 6},
+ [DVBT_PSET_IFFREQ] = {0x1, 0x19, 21, 0},
+ [DVBT_SPEC_INV] = {0x1, 0x15, 0, 0},
+ [DVBT_RSAMP_RATIO] = {0x1, 0x9f, 27, 2},
+ [DVBT_CFREQ_OFF_RATIO] = {0x1, 0x9d, 23, 4},
+ [DVBT_FSM_STAGE] = {0x3, 0x51, 6, 3},
+ [DVBT_RX_CONSTEL] = {0x3, 0x3c, 3, 2},
+ [DVBT_RX_HIER] = {0x3, 0x3c, 6, 4},
+ [DVBT_RX_C_RATE_LP] = {0x3, 0x3d, 2, 0},
+ [DVBT_RX_C_RATE_HP] = {0x3, 0x3d, 5, 3},
+ [DVBT_GI_IDX] = {0x3, 0x51, 1, 0},
+ [DVBT_FFT_MODE_IDX] = {0x3, 0x51, 2, 2},
+ [DVBT_RSD_BER_EST] = {0x3, 0x4e, 15, 0},
+ [DVBT_CE_EST_EVM] = {0x4, 0xc, 15, 0},
+ [DVBT_RF_AGC_VAL] = {0x3, 0x5b, 13, 0},
+ [DVBT_IF_AGC_VAL] = {0x3, 0x59, 13, 0},
+ [DVBT_DAGC_VAL] = {0x3, 0x5, 7, 0},
+ [DVBT_SFREQ_OFF] = {0x3, 0x18, 13, 0},
+ [DVBT_CFREQ_OFF] = {0x3, 0x5f, 17, 0},
+ [DVBT_POLAR_RF_AGC] = {0x0, 0xe, 1, 1},
+ [DVBT_POLAR_IF_AGC] = {0x0, 0xe, 0, 0},
+ [DVBT_AAGC_HOLD] = {0x1, 0x4, 5, 5},
+ [DVBT_EN_RF_AGC] = {0x1, 0x4, 6, 6},
+ [DVBT_EN_IF_AGC] = {0x1, 0x4, 7, 7},
+ [DVBT_IF_AGC_MIN] = {0x1, 0x8, 7, 0},
+ [DVBT_IF_AGC_MAX] = {0x1, 0x9, 7, 0},
+ [DVBT_RF_AGC_MIN] = {0x1, 0xa, 7, 0},
+ [DVBT_RF_AGC_MAX] = {0x1, 0xb, 7, 0},
+ [DVBT_IF_AGC_MAN] = {0x1, 0xc, 6, 6},
+ [DVBT_IF_AGC_MAN_VAL] = {0x1, 0xc, 13, 0},
+ [DVBT_RF_AGC_MAN] = {0x1, 0xe, 6, 6},
+ [DVBT_RF_AGC_MAN_VAL] = {0x1, 0xe, 13, 0},
+ [DVBT_DAGC_TRG_VAL] = {0x1, 0x12, 7, 0},
+ [DVBT_AGC_TARG_VAL_0] = {0x1, 0x2, 0, 0},
+ [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3, 7, 0},
+ [DVBT_AAGC_LOOP_GAIN] = {0x1, 0xc7, 5, 1},
+ [DVBT_LOOP_GAIN2_3_0] = {0x1, 0x4, 4, 1},
+ [DVBT_LOOP_GAIN2_4] = {0x1, 0x5, 7, 7},
+ [DVBT_LOOP_GAIN3] = {0x1, 0xc8, 4, 0},
+ [DVBT_VTOP1] = {0x1, 0x6, 5, 0},
+ [DVBT_VTOP2] = {0x1, 0xc9, 5, 0},
+ [DVBT_VTOP3] = {0x1, 0xca, 5, 0},
+ [DVBT_KRF1] = {0x1, 0xcb, 7, 0},
+ [DVBT_KRF2] = {0x1, 0x7, 7, 0},
+ [DVBT_KRF3] = {0x1, 0xcd, 7, 0},
+ [DVBT_KRF4] = {0x1, 0xce, 7, 0},
+ [DVBT_EN_GI_PGA] = {0x1, 0xe5, 0, 0},
+ [DVBT_THD_LOCK_UP] = {0x1, 0xd9, 8, 0},
+ [DVBT_THD_LOCK_DW] = {0x1, 0xdb, 8, 0},
+ [DVBT_THD_UP1] = {0x1, 0xdd, 7, 0},
+ [DVBT_THD_DW1] = {0x1, 0xde, 7, 0},
+ [DVBT_INTER_CNT_LEN] = {0x1, 0xd8, 3, 0},
+ [DVBT_GI_PGA_STATE] = {0x1, 0xe6, 3, 3},
+ [DVBT_EN_AGC_PGA] = {0x1, 0xd7, 0, 0},
+ [DVBT_CKOUTPAR] = {0x1, 0x7b, 5, 5},
+ [DVBT_CKOUT_PWR] = {0x1, 0x7b, 6, 6},
+ [DVBT_SYNC_DUR] = {0x1, 0x7b, 7, 7},
+ [DVBT_ERR_DUR] = {0x1, 0x7c, 0, 0},
+ [DVBT_SYNC_LVL] = {0x1, 0x7c, 1, 1},
+ [DVBT_ERR_LVL] = {0x1, 0x7c, 2, 2},
+ [DVBT_VAL_LVL] = {0x1, 0x7c, 3, 3},
+ [DVBT_SERIAL] = {0x1, 0x7c, 4, 4},
+ [DVBT_SER_LSB] = {0x1, 0x7c, 5, 5},
+ [DVBT_CDIV_PH0] = {0x1, 0x7d, 3, 0},
+ [DVBT_CDIV_PH1] = {0x1, 0x7d, 7, 4},
+ [DVBT_MPEG_IO_OPT_2_2] = {0x0, 0x6, 7, 7},
+ [DVBT_MPEG_IO_OPT_1_0] = {0x0, 0x7, 7, 6},
+ [DVBT_CKOUTPAR_PIP] = {0x0, 0xb7, 4, 4},
+ [DVBT_CKOUT_PWR_PIP] = {0x0, 0xb7, 3, 3},
+ [DVBT_SYNC_LVL_PIP] = {0x0, 0xb7, 2, 2},
+ [DVBT_ERR_LVL_PIP] = {0x0, 0xb7, 1, 1},
+ [DVBT_VAL_LVL_PIP] = {0x0, 0xb7, 0, 0},
+ [DVBT_CKOUTPAR_PID] = {0x0, 0xb9, 4, 4},
+ [DVBT_CKOUT_PWR_PID] = {0x0, 0xb9, 3, 3},
+ [DVBT_SYNC_LVL_PID] = {0x0, 0xb9, 2, 2},
+ [DVBT_ERR_LVL_PID] = {0x0, 0xb9, 1, 1},
+ [DVBT_VAL_LVL_PID] = {0x0, 0xb9, 0, 0},
+ [DVBT_SM_PASS] = {0x1, 0x93, 11, 0},
+ [DVBT_AD7_SETTING] = {0x0, 0x11, 15, 0},
+ [DVBT_RSSI_R] = {0x3, 0x1, 6, 0},
+ [DVBT_ACI_DET_IND] = {0x3, 0x12, 0, 0},
+ [DVBT_REG_MON] = {0x0, 0xd, 1, 0},
+ [DVBT_REG_MONSEL] = {0x0, 0xd, 2, 2},
+ [DVBT_REG_GPE] = {0x0, 0xd, 7, 7},
+ [DVBT_REG_GPO] = {0x0, 0x10, 0, 0},
+ [DVBT_REG_4MSEL] = {0x0, 0x13, 0, 0},
};
/* write multiple hardware registers */
@@ -334,6 +334,7 @@
return ret;
err:
+ dbg("%s: failed=%d", __func__, ret);
return ret;
}
@@ -385,6 +386,7 @@
return ret;
err:
+ dbg("%s: failed=%d", __func__, ret);
return ret;
}
@@ -425,85 +427,80 @@
u64 pset_iffreq;
/* initialization values for the demodulator registers */
- static rtl2832_reg_value rtl2832_initial_regs_1[] = {
- {DVBT_AD_EN_REG, 0x1},
- {DVBT_AD_EN_REG1, 0x1},
+ struct rtl2832_reg_value rtl2832_initial_regs[] = {
+ {DVBT_AD_EN_REG, 0x1},
+ {DVBT_AD_EN_REG1, 0x1},
{DVBT_RSD_BER_FAIL_VAL, 0x2800},
- {DVBT_MGD_THD0, 0x10},
- {DVBT_MGD_THD1, 0x20},
- {DVBT_MGD_THD2, 0x20},
- {DVBT_MGD_THD3, 0x40},
- {DVBT_MGD_THD4, 0x22},
- {DVBT_MGD_THD5, 0x32},
- {DVBT_MGD_THD6, 0x37},
- {DVBT_MGD_THD7, 0x39},
- {DVBT_EN_BK_TRK, 0x0},
+ {DVBT_MGD_THD0, 0x10},
+ {DVBT_MGD_THD1, 0x20},
+ {DVBT_MGD_THD2, 0x20},
+ {DVBT_MGD_THD3, 0x40},
+ {DVBT_MGD_THD4, 0x22},
+ {DVBT_MGD_THD5, 0x32},
+ {DVBT_MGD_THD6, 0x37},
+ {DVBT_MGD_THD7, 0x39},
+ {DVBT_EN_BK_TRK, 0x0},
{DVBT_EN_CACQ_NOTCH, 0x0},
- {DVBT_AD_AV_REF, 0x2a},
- {DVBT_REG_PI, 0x6},
- {DVBT_PIP_ON, 0x0},
- {DVBT_CDIV_PH0, 0x8},
- {DVBT_CDIV_PH1, 0x8},
- {DVBT_SCALE1_B92, 0x4},
- {DVBT_SCALE1_B93, 0xb0},
- {DVBT_SCALE1_BA7, 0x78},
- {DVBT_SCALE1_BA9, 0x28},
- {DVBT_SCALE1_BAA, 0x59},
- {DVBT_SCALE1_BAB, 0x83},
- {DVBT_SCALE1_BAC, 0xd4},
- {DVBT_SCALE1_BB0, 0x65},
- {DVBT_SCALE1_BB1, 0x43},
- {DVBT_KB_P1, 0x1},
- {DVBT_KB_P2, 0x4},
- {DVBT_KB_P3, 0x7},
- {DVBT_K1_CR_STEP12, 0xa},
- {DVBT_REG_GPE, 0x1},
- {DVBT_SERIAL, 0x0},
- {DVBT_CDIV_PH0, 0x9},
- {DVBT_CDIV_PH1, 0x9},
+ {DVBT_AD_AV_REF, 0x2a},
+ {DVBT_REG_PI, 0x6},
+ {DVBT_PIP_ON, 0x0},
+ {DVBT_CDIV_PH0, 0x8},
+ {DVBT_CDIV_PH1, 0x8},
+ {DVBT_SCALE1_B92, 0x4},
+ {DVBT_SCALE1_B93, 0xb0},
+ {DVBT_SCALE1_BA7, 0x78},
+ {DVBT_SCALE1_BA9, 0x28},
+ {DVBT_SCALE1_BAA, 0x59},
+ {DVBT_SCALE1_BAB, 0x83},
+ {DVBT_SCALE1_BAC, 0xd4},
+ {DVBT_SCALE1_BB0, 0x65},
+ {DVBT_SCALE1_BB1, 0x43},
+ {DVBT_KB_P1, 0x1},
+ {DVBT_KB_P2, 0x4},
+ {DVBT_KB_P3, 0x7},
+ {DVBT_K1_CR_STEP12, 0xa},
+ {DVBT_REG_GPE, 0x1},
+ {DVBT_SERIAL, 0x0},
+ {DVBT_CDIV_PH0, 0x9},
+ {DVBT_CDIV_PH1, 0x9},
{DVBT_MPEG_IO_OPT_2_2, 0x0},
{DVBT_MPEG_IO_OPT_1_0, 0x0},
- {DVBT_TRK_KS_P2, 0x4},
- {DVBT_TRK_KS_I2, 0x7},
- {DVBT_TR_THD_SET2, 0x6},
- {DVBT_TRK_KC_I2, 0x5},
- {DVBT_CR_THD_SET2, 0x1},
-
-
- };
-
- static rtl2832_reg_value rtl2832_initial_regs_2[] = {
- {DVBT_SPEC_INV, 0x0},
- {DVBT_DAGC_TRG_VAL, 0x5a},
+ {DVBT_TRK_KS_P2, 0x4},
+ {DVBT_TRK_KS_I2, 0x7},
+ {DVBT_TR_THD_SET2, 0x6},
+ {DVBT_TRK_KC_I2, 0x5},
+ {DVBT_CR_THD_SET2, 0x1},
+ {DVBT_SPEC_INV, 0x0},
+ {DVBT_DAGC_TRG_VAL, 0x5a},
{DVBT_AGC_TARG_VAL_0, 0x0},
{DVBT_AGC_TARG_VAL_8_1, 0x5a},
{DVBT_AAGC_LOOP_GAIN, 0x16},
{DVBT_LOOP_GAIN2_3_0, 0x6},
- {DVBT_LOOP_GAIN2_4, 0x1},
- {DVBT_LOOP_GAIN3, 0x16},
- {DVBT_VTOP1, 0x35},
- {DVBT_VTOP2, 0x21},
- {DVBT_VTOP3, 0x21},
- {DVBT_KRF1, 0x0},
- {DVBT_KRF2, 0x40},
- {DVBT_KRF3, 0x10},
- {DVBT_KRF4, 0x10},
- {DVBT_IF_AGC_MIN, 0x80},
- {DVBT_IF_AGC_MAX, 0x7f},
- {DVBT_RF_AGC_MIN, 0x80},
- {DVBT_RF_AGC_MAX, 0x7f},
- {DVBT_POLAR_RF_AGC, 0x0},
- {DVBT_POLAR_IF_AGC, 0x0},
- {DVBT_AD7_SETTING, 0xe9bf},
- {DVBT_EN_GI_PGA, 0x0},
- {DVBT_THD_LOCK_UP, 0x0},
- {DVBT_THD_LOCK_DW, 0x0},
- {DVBT_THD_UP1, 0x11},
- {DVBT_THD_DW1, 0xef},
+ {DVBT_LOOP_GAIN2_4, 0x1},
+ {DVBT_LOOP_GAIN3, 0x16},
+ {DVBT_VTOP1, 0x35},
+ {DVBT_VTOP2, 0x21},
+ {DVBT_VTOP3, 0x21},
+ {DVBT_KRF1, 0x0},
+ {DVBT_KRF2, 0x40},
+ {DVBT_KRF3, 0x10},
+ {DVBT_KRF4, 0x10},
+ {DVBT_IF_AGC_MIN, 0x80},
+ {DVBT_IF_AGC_MAX, 0x7f},
+ {DVBT_RF_AGC_MIN, 0x80},
+ {DVBT_RF_AGC_MAX, 0x7f},
+ {DVBT_POLAR_RF_AGC, 0x0},
+ {DVBT_POLAR_IF_AGC, 0x0},
+ {DVBT_AD7_SETTING, 0xe9bf},
+ {DVBT_EN_GI_PGA, 0x0},
+ {DVBT_THD_LOCK_UP, 0x0},
+ {DVBT_THD_LOCK_DW, 0x0},
+ {DVBT_THD_UP1, 0x11},
+ {DVBT_THD_DW1, 0xef},
{DVBT_INTER_CNT_LEN, 0xc},
- {DVBT_GI_PGA_STATE, 0x0},
- {DVBT_EN_AGC_PGA, 0x1},
- {DVBT_IF_AGC_MAN, 0x0},
+ {DVBT_GI_PGA_STATE, 0x0},
+ {DVBT_EN_AGC_PGA, 0x1},
+ {DVBT_IF_AGC_MAN, 0x0},
};
@@ -522,9 +519,9 @@
- for (i = 0; i < 42; i++) {
- ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs_1[i].reg,
- rtl2832_initial_regs_1[i].value);
+ for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
+ ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
+ rtl2832_initial_regs[i].value);
if (ret)
goto err;
}
@@ -538,18 +535,12 @@
if (ret)
goto err;
- for (i = 0; i < 31; i++) {
- ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs_2[i].reg,
- rtl2832_initial_regs_2[i].value);
- if (ret)
- goto err;
- }
-
priv->sleeping = false;
return ret;
err:
+ dbg("%s: failed=%d", __func__, ret);
return ret;
}
@@ -584,26 +575,26 @@
static u8 bw_params[3][32] = {
/* 6 MHz bandwidth */
{
- 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
- 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
- 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
- 0x19, 0xe0,
+ 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
+ 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
+ 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
+ 0x19, 0xe0,
},
/* 7 MHz bandwidth */
{
- 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
- 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
- 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
- 0x19, 0x10,
+ 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
+ 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
+ 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
+ 0x19, 0x10,
},
/* 8 MHz bandwidth */
{
- 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
- 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
- 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
- 0x19, 0xe0,
+ 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
+ 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
+ 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
+ 0x19, 0xe0,
},
};
@@ -635,7 +626,7 @@
return -EINVAL;
}
- for (j = 0; j < 32; j++) {
+ for (j = 0; j < sizeof(bw_params[j]); j++) {
ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
if (ret)
goto err;
@@ -643,7 +634,7 @@
/* calculate and set resample ratio
* RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
- * / ConstWithBandwidthMode)
+ * / ConstWithBandwidthMode)
*/
num = priv->cfg.xtal * 7;
num *= 0x400000;
@@ -655,7 +646,7 @@
/* calculate and set cfreq off ratio
* CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
- * / (CrystalFreqHz * 7))
+ * / (CrystalFreqHz * 7))
*/
num = bw_mode << 20;
num2 = priv->cfg.xtal * 7;
@@ -727,13 +718,13 @@
u32 ce_est_evm, fsm_stage, constellation, hierarchy;
/* Calculated by: 10 * log2(Norm * pow(2, 11)) * pow(2, 10) */
- static const long SnrDbNum[3][4] = {
+ static const int SnrDbNum[3][4] = {
{122880, 122880, 122880, 122880, },
{146657, 146657, 156897, 171013, },
{167857, 167857, 173127, 181810, },
};
- static const int snrMaxDb[3] = { 23, 26, 29, };
+ static const short snr_max_db[3] = { 23, 26, 29, };
dbg("%s", __func__);
@@ -786,14 +777,7 @@
num = div_u64(num, RTL2832_SNR_DB_DEN);
num *= 0xffff;
- num = div_u64(num, snrMaxDb[constellation]);
-
- if (num > 0xffff)
- *snr = 0xffff;
- else if (num < 0)
- *snr = 0;
- else
- *snr = 0xffff & num;
+ num = div_u64(num, snr_max_db[constellation]);
return ret;
@@ -820,7 +804,6 @@
err:
info("%s: failed=%d", __func__, ret);
- *ber = 19616;
return ret;
}
@@ -888,10 +871,10 @@
ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &fsm_stage);
if (ret)
- goto err;
+ goto err;
if (fsm_stage < 10)
- *strength = 0;
+ *strength = 0;
else {
/* if_agc is read as a 10bit binary */
ret = rtl2832_rd_demod_reg(priv, DVBT_IF_AGC_VAL, &if_agc_raw);
@@ -903,8 +886,7 @@
else
if_agc = -(~(if_agc_raw-1) & 0x1ff);
- *strength = 55 - if_agc / 182;
- *strength |= *strength << 8;
+ *strength = 55 - if_agc / 182 * 256;
}
return 0;
err:
@@ -950,7 +932,7 @@
memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
priv->fe.demodulator_priv = priv;
- /* TODO implement sleep mode depending on RC */
+ /* TODO implement sleep mode */
priv->sleeping = true;
return &priv->fe;
@@ -962,14 +944,13 @@
EXPORT_SYMBOL(rtl2832_attach);
static struct dvb_frontend_ops rtl2832_ops = {
- .delsys = { SYS_DVBT },
- .info = {
- .name = "Realtek RTL2832 (DVB-T)",
- .type = FE_OFDM,
- .frequency_min = 50000000,
- .frequency_max = 862000000,
- .frequency_stepsize = 166667,
- .caps = FE_CAN_FEC_1_2 |
+ .delsys = { SYS_DVBT },
+ .info = {
+ .name = "Realtek RTL2832 (DVB-T)",
+ .frequency_min = 174000000,
+ .frequency_max = 862000000,
+ .frequency_stepsize = 166667,
+ .caps = FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 |
[-- Attachment #3: rtl2832.h.diff --]
[-- Type: text/x-patch, Size: 409 bytes --]
--- linux/drivers/media/dvb/frontends/rtl2832.h.orig 2012-05-16 06:46:29.763379985 +0200
+++ linux/drivers/media/dvb/frontends/rtl2832.h 2012-05-16 06:20:17.845569005 +0200
@@ -68,13 +68,6 @@
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-
-static inline struct i2c_adapter *rtl2832_get_tuner_i2c_adapter(
- struct dvb_frontend *fe
-)
-{
- return NULL;
-}
#endif
[-- Attachment #4: rtl2832_priv.h.diff --]
[-- Type: text/x-patch, Size: 506 bytes --]
--- linux/drivers/media/dvb/frontends/rtl2832_priv.h.orig 2012-05-16 06:46:39.478818765 +0200
+++ linux/drivers/media/dvb/frontends/rtl2832_priv.h 2012-05-16 06:20:23.734243672 +0200
@@ -49,19 +49,17 @@
u8 page; /* active register page */
};
-typedef struct {
+struct rtl2832_reg_entry {
u8 page;
u8 start_address;
u8 msb;
u8 lsb;
-}
-rtl2832_reg_entry;
+};
-typedef struct {
+struct rtl2832_reg_value {
int reg;
u32 value;
-}
-rtl2832_reg_value;
+};
/* Demod register bit names */
next prev parent reply other threads:[~2012-05-16 5:10 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-12 18:08 [PATCH 0/5] support rtl2832 demodulator Thomas Mair
2012-05-12 18:08 ` [PATCH 1/5] rtl2832 ver 0.3: suport for RTL2832 demodulator revised version Thomas Mair
2012-05-12 22:07 ` poma
2012-05-13 18:53 ` Antti Palosaari
2012-05-13 20:56 ` Thomas Mair
2012-05-14 1:37 ` Antti Palosaari
2012-05-14 1:46 ` Antti Palosaari
2012-05-15 15:41 ` Antti Palosaari
2012-05-16 5:10 ` poma [this message]
2012-05-18 19:16 ` Antti Palosaari
2012-05-12 18:08 ` [PATCH 2/5] rtl28xxu: support for the rtl2832 demod driver Thomas Mair
2012-05-12 18:08 ` [PATCH 3/5] rtl28xxu: renamed rtl2831_rd/rtl2831_wr to rtl28xx_rd/rtl28xx_wr Thomas Mair
2012-05-12 18:08 ` [PATCH 4/5] rtl28xxu: support G-Tek Electronics Group Lifeview LV5TDLX DVB-T Thomas Mair
2012-05-12 18:08 ` [PATCH 5/5] rtl28xxu: support Terratec Noxon DAB/DAB+ stick Thomas Mair
2012-05-12 20:47 ` Thomas Mair
2012-05-13 21:18 ` [PATCH] rtl28xxu: removed newlines from info strings Thomas Mair
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FB336BD.1040506@gmail.com \
--to=pomidorabelisima@gmail.com \
--cc=crope@iki.fi \
--cc=linux-media@vger.kernel.org \
--cc=thomas.mair86@googlemail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).