mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 05:11:48 +00:00
Merge branch 'topic/r820t' into patchwork
* topic/r820t: (31 commits) [media] r820t: Don't divide the IF by two [media] r820t: disable auto gain/VGA setting [media] rtl2832: Fix IF calculus [media] r820t: put it into automatic gain mode [media] r820t: Fix hp_cor filter mask [media] r820t: fix PLL calculus [media] r820t: Don't put it in standby if not initialized yet [media] r820t: avoid rewrite all regs when not needed [media] r820t: Allow disabling IMR callibration [media] r820t: add a commented code for GPIO [media] r820t: add IMR calibrate code [media] r820t: proper initialize the PLL register [media] r820t: use usleep_range() [media] r820t: fix prefix of the r820t_read() function [media] r820t: split the function that read cached regs [media] r820t: better report signal strength [media] r820t: add support for diplexer [media] r820t: Show the read data in the bit-reversed order [media] r820t: use the second table for 7MHz [media] r820t: Invert bits for read ops ...
This commit is contained in:
commit
cfc3d6c444
@ -380,13 +380,41 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int rtl2832_set_if(struct dvb_frontend *fe, u32 if_freq)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
int ret;
|
||||
u64 pset_iffreq;
|
||||
u8 en_bbin = (if_freq == 0 ? 0x1 : 0x0);
|
||||
|
||||
/*
|
||||
* PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
|
||||
* / CrystalFreqHz)
|
||||
*/
|
||||
|
||||
pset_iffreq = if_freq % priv->cfg.xtal;
|
||||
pset_iffreq *= 0x400000;
|
||||
pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
|
||||
pset_iffreq = -pset_iffreq;
|
||||
pset_iffreq = pset_iffreq & 0x3fffff;
|
||||
dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d pset_iffreq=%08x\n",
|
||||
__func__, if_freq, (unsigned)pset_iffreq);
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int rtl2832_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
int i, ret, len;
|
||||
u8 en_bbin;
|
||||
u64 pset_iffreq;
|
||||
const struct rtl2832_reg_value *init;
|
||||
int i, ret, len;
|
||||
|
||||
/* initialization values for the demodulator registers */
|
||||
struct rtl2832_reg_value rtl2832_initial_regs[] = {
|
||||
@ -432,22 +460,10 @@ static int rtl2832_init(struct dvb_frontend *fe)
|
||||
{DVBT_TR_THD_SET2, 0x6},
|
||||
{DVBT_TRK_KC_I2, 0x5},
|
||||
{DVBT_CR_THD_SET2, 0x1},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
dev_dbg(&priv->i2c->dev, "%s:\n", __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 < ARRAY_SIZE(rtl2832_initial_regs); i++) {
|
||||
ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
|
||||
rtl2832_initial_regs[i].value);
|
||||
@ -472,6 +488,10 @@ static int rtl2832_init(struct dvb_frontend *fe)
|
||||
len = ARRAY_SIZE(rtl2832_tuner_init_e4000);
|
||||
init = rtl2832_tuner_init_e4000;
|
||||
break;
|
||||
case RTL2832_TUNER_R820T:
|
||||
len = ARRAY_SIZE(rtl2832_tuner_init_r820t);
|
||||
init = rtl2832_tuner_init_r820t;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
@ -483,14 +503,26 @@ static int rtl2832_init(struct dvb_frontend *fe)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* if frequency settings */
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
|
||||
if (!fe->ops.tuner_ops.get_if_frequency) {
|
||||
ret = rtl2832_set_if(fe, priv->cfg.if_dvbt);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
|
||||
if (ret)
|
||||
goto err;
|
||||
/*
|
||||
* r820t NIM code does a software reset here at the demod -
|
||||
* may not be needed, as there's already a software reset at set_params()
|
||||
*/
|
||||
#if 1
|
||||
/* 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;
|
||||
#endif
|
||||
|
||||
priv->sleeping = false;
|
||||
|
||||
@ -564,6 +596,19 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
|
||||
if (fe->ops.tuner_ops.set_params)
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
|
||||
/* If the frontend has get_if_frequency(), use it */
|
||||
if (fe->ops.tuner_ops.get_if_frequency) {
|
||||
u32 if_freq;
|
||||
|
||||
ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rtl2832_set_if(fe, if_freq);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (c->bandwidth_hz) {
|
||||
case 6000000:
|
||||
i = 0;
|
||||
|
@ -52,6 +52,7 @@ struct rtl2832_config {
|
||||
#define RTL2832_TUNER_FC0012 0x26
|
||||
#define RTL2832_TUNER_E4000 0x27
|
||||
#define RTL2832_TUNER_FC0013 0x29
|
||||
#define RTL2832_TUNER_R820T 0x2a
|
||||
u8 tuner;
|
||||
};
|
||||
|
||||
|
@ -267,6 +267,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_tua9001[] = {
|
||||
{DVBT_OPT_ADC_IQ, 0x1},
|
||||
{DVBT_AD_AVI, 0x0},
|
||||
{DVBT_AD_AVQ, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
|
||||
@ -300,6 +301,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
|
||||
{DVBT_GI_PGA_STATE, 0x0},
|
||||
{DVBT_EN_AGC_PGA, 0x1},
|
||||
{DVBT_IF_AGC_MAN, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
|
||||
@ -337,6 +339,32 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
|
||||
{DVBT_REG_MONSEL, 0x1},
|
||||
{DVBT_REG_MON, 0x1},
|
||||
{DVBT_REG_4MSEL, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
static const struct rtl2832_reg_value rtl2832_tuner_init_r820t[] = {
|
||||
{DVBT_DAGC_TRG_VAL, 0x39},
|
||||
{DVBT_AGC_TARG_VAL_0, 0x0},
|
||||
{DVBT_AGC_TARG_VAL_8_1, 0x40},
|
||||
{DVBT_AAGC_LOOP_GAIN, 0x16},
|
||||
{DVBT_LOOP_GAIN2_3_0, 0x8},
|
||||
{DVBT_LOOP_GAIN2_4, 0x1},
|
||||
{DVBT_LOOP_GAIN3, 0x18},
|
||||
{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, 0xe9f4},
|
||||
{DVBT_SPEC_INV, 0x1},
|
||||
};
|
||||
|
||||
#endif /* RTL2832_PRIV_H */
|
||||
|
@ -248,4 +248,11 @@ config MEDIA_TUNER_IT913X
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
ITE Tech IT913x silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_R820T
|
||||
tristate "Rafael Micro R820T silicon tuner"
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Rafael Micro R820T silicon tuner driver.
|
||||
endmenu
|
||||
|
@ -35,6 +35,7 @@ obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_IT913X) += tuner_it913x.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_R820T) += r820t.o
|
||||
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb-core
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
|
||||
|
2352
drivers/media/tuners/r820t.c
Normal file
2352
drivers/media/tuners/r820t.c
Normal file
File diff suppressed because it is too large
Load Diff
58
drivers/media/tuners/r820t.h
Normal file
58
drivers/media/tuners/r820t.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Elonics R820T silicon tuner driver
|
||||
*
|
||||
* Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* 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 R820T_H
|
||||
#define R820T_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
enum r820t_chip {
|
||||
CHIP_R820T,
|
||||
CHIP_R620D,
|
||||
CHIP_R828D,
|
||||
CHIP_R828,
|
||||
CHIP_R828S,
|
||||
CHIP_R820C,
|
||||
};
|
||||
|
||||
struct r820t_config {
|
||||
u8 i2c_addr; /* 0x34 */
|
||||
u32 xtal;
|
||||
enum r820t_chip rafael_chip;
|
||||
unsigned max_i2c_msg_len;
|
||||
bool use_diplexer;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_MEDIA_TUNER_R820T)
|
||||
struct dvb_frontend *r820t_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
const struct r820t_config *cfg);
|
||||
#else
|
||||
static inline struct dvb_frontend *r820t_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
const struct r820t_config *cfg)
|
||||
{
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -143,6 +143,7 @@ config DVB_USB_RTL28XXU
|
||||
select MEDIA_TUNER_FC0013 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_E4000 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_FC2580 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_R820T if MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y here to support the Realtek RTL28xxU DVB USB receiver.
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "e4000.h"
|
||||
#include "fc2580.h"
|
||||
#include "tua9001.h"
|
||||
#include "r820t.h"
|
||||
|
||||
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
||||
|
||||
@ -375,6 +376,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
|
||||
struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf};
|
||||
struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf};
|
||||
struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
|
||||
struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 5, buf};
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s:\n", __func__);
|
||||
|
||||
@ -479,6 +481,14 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* check R820T by reading tuner stats at I2C addr 0x1a */
|
||||
ret = rtl28xxu_ctrl_msg(d, &req_r820t);
|
||||
if (ret == 0) {
|
||||
priv->tuner = TUNER_RTL2832_R820T;
|
||||
priv->tuner_name = "R820T";
|
||||
goto found;
|
||||
}
|
||||
|
||||
found:
|
||||
dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name);
|
||||
|
||||
@ -589,6 +599,12 @@ static struct rtl2832_config rtl28xxu_rtl2832_e4000_config = {
|
||||
.tuner = TUNER_RTL2832_E4000,
|
||||
};
|
||||
|
||||
static struct rtl2832_config rtl28xxu_rtl2832_r820t_config = {
|
||||
.i2c_addr = 0x10,
|
||||
.xtal = 28800000,
|
||||
.tuner = TUNER_RTL2832_R820T,
|
||||
};
|
||||
|
||||
static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d,
|
||||
int cmd, int arg)
|
||||
{
|
||||
@ -728,6 +744,9 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
case TUNER_RTL2832_E4000:
|
||||
rtl2832_config = &rtl28xxu_rtl2832_e4000_config;
|
||||
break;
|
||||
case TUNER_RTL2832_R820T:
|
||||
rtl2832_config = &rtl28xxu_rtl2832_r820t_config;
|
||||
break;
|
||||
default:
|
||||
dev_err(&d->udev->dev, "%s: unknown tuner=%s\n",
|
||||
KBUILD_MODNAME, priv->tuner_name);
|
||||
@ -840,6 +859,13 @@ static const struct fc0012_config rtl2832u_fc0012_config = {
|
||||
.xtal_freq = FC_XTAL_28_8_MHZ,
|
||||
};
|
||||
|
||||
static const struct r820t_config rtl2832u_r820t_config = {
|
||||
.i2c_addr = 0x1a,
|
||||
.xtal = 28800000,
|
||||
.max_i2c_msg_len = 2,
|
||||
.rafael_chip = CHIP_R820T,
|
||||
};
|
||||
|
||||
static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
int ret;
|
||||
@ -889,6 +915,14 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
fe = dvb_attach(tua9001_attach, adap->fe[0], &d->i2c_adap,
|
||||
&rtl2832u_tua9001_config);
|
||||
break;
|
||||
case TUNER_RTL2832_R820T:
|
||||
fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap,
|
||||
&rtl2832u_r820t_config);
|
||||
|
||||
/* Use tuner to get the signal strength */
|
||||
adap->fe[0]->ops.read_signal_strength =
|
||||
adap->fe[0]->ops.tuner_ops.get_rf_strength;
|
||||
break;
|
||||
default:
|
||||
fe = NULL;
|
||||
dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
|
||||
|
@ -82,6 +82,7 @@ enum rtl28xxu_tuner {
|
||||
TUNER_RTL2832_E4000,
|
||||
TUNER_RTL2832_TDA18272,
|
||||
TUNER_RTL2832_FC0013,
|
||||
TUNER_RTL2832_R820T,
|
||||
};
|
||||
|
||||
struct rtl28xxu_req {
|
||||
|
Loading…
Reference in New Issue
Block a user