[media] rtl2832: add code to bind r820t on it
authorMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 9 Apr 2013 21:19:50 +0000 (18:19 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 17 Apr 2013 00:25:52 +0000 (21:25 -0300)
There are some init stuff to be done for each new tuner at the
demod code. Add the code there for r820t.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Tested-by: Antti Palosaari <crope@iki.fi>
drivers/media/dvb-frontends/rtl2832.c
drivers/media/dvb-frontends/rtl2832.h
drivers/media/dvb-frontends/rtl2832_priv.h

index 7388769..b6f50c7 100644 (file)
@@ -432,22 +432,12 @@ 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 +462,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 +477,43 @@ 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 (ret)
-                       goto err;
+       /*
+        * if frequency settings
+        * Some tuners (r820t) don't initialize IF here; instead; they do it
+        * at set_params()
+        */
+       if (!fe->ops.tuner_ops.get_if_frequency) {
+               /*
+               * 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;
+               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;
+       }
 
-       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 +587,25 @@ 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;
+               u64 pset_iffreq;
+
+               ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
+               if (ret)
+                       goto err;
+
+               pset_iffreq = if_freq % priv->cfg.xtal;
+               pset_iffreq *= 0x400000;
+               pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
+               pset_iffreq = pset_iffreq & 0x3fffff;
+
+               ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
+               if (ret)
+                       goto err;
+       }
+
        switch (c->bandwidth_hz) {
        case 6000000:
                i = 0;
index fefba0e..91b2dcf 100644 (file)
@@ -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;
 };
 
index 7d97ce9..b5f2b80 100644 (file)
@@ -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 */