[media] Change frontend allocation strategy for NetUP Universal DVB cards
authorAbylay Ospan <aospan@netup.ru>
Sat, 14 May 2016 03:08:40 +0000 (00:08 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 7 Jun 2016 15:16:37 +0000 (12:16 -0300)
Old behaviour:
frontend0 - DVB-S/S2
frontend1 - DVB-T/T2
frontend2 - DVB-C
frontend3 - ISDB-T

New behaviour (DVBv5 API compliant):
frontend0 - DVB-S/S2
frontend1 - DVB-T/T2/C/ISDB-T

DTV standard should be selected by DTV_DELIVERY_SYSTEM call.

And DVB-C default bandwidth now 8MHz

Signed-off-by: Abylay Ospan <aospan@netup.ru>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/dvb-frontends/cxd2841er.c
drivers/media/dvb-frontends/cxd2841er.h
drivers/media/pci/netup_unidvb/netup_unidvb_core.c

index 50bdd40fdd4e47de3ec32790dde303c181b6eaab..cc306b66c6e52fb80eb4883c2f080c09ce3e587d 100644 (file)
@@ -54,6 +54,7 @@ struct cxd2841er_priv {
        enum cxd2841er_state            state;
        u8                              system;
        enum cxd2841er_xtal             xtal;
+       enum fe_caps caps;
 };
 
 static const struct cxd2841er_cnr_data s_cn_data[] = {
@@ -791,6 +792,7 @@ static int cxd2841er_shutdown_to_sleep_s(struct cxd2841er_priv *priv)
 static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv)
 {
        u8 data = 0;
+
        dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
        if (priv->state != STATE_SHUTDOWN) {
                dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
@@ -2496,7 +2498,7 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
        u8 b10_b6[3];
        u32 iffreq;
 
-       dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
+       dev_dbg(&priv->i2c->dev, "%s() bw=%d\n", __func__, bandwidth);
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
        switch (bandwidth) {
        case 8000000:
@@ -2513,7 +2515,7 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
                iffreq = MAKE_IFFREQ_CONFIG(3.7);
                break;
        default:
-               dev_dbg(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n",
+               dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n",
                        __func__, bandwidth);
                return -EINVAL;
        }
@@ -2909,7 +2911,7 @@ static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv,
        cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01);
        cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01);
 
-       cxd2841er_sleep_tc_to_active_c_band(priv, 8000000);
+       cxd2841er_sleep_tc_to_active_c_band(priv, bandwidth);
        /* Set SLV-T Bank : 0x00 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
        /* Disable HiZ Setting 1 */
@@ -3029,7 +3031,8 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
        struct cxd2841er_priv *priv = fe->demodulator_priv;
        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 
-       dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
+       dev_dbg(&priv->i2c->dev, "%s() delivery_system=%d bandwidth_hz=%d\n",
+                __func__, p->delivery_system, p->bandwidth_hz);
        if (p->delivery_system == SYS_DVBT) {
                priv->system = SYS_DVBT;
                switch (priv->state) {
@@ -3081,6 +3084,15 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
        } else if (p->delivery_system == SYS_DVBC_ANNEX_A ||
                        p->delivery_system == SYS_DVBC_ANNEX_C) {
                priv->system = SYS_DVBC_ANNEX_A;
+               /* correct bandwidth */
+               if (p->bandwidth_hz != 6000000 &&
+                               p->bandwidth_hz != 7000000 &&
+                               p->bandwidth_hz != 8000000) {
+                       p->bandwidth_hz = 8000000;
+                       dev_dbg(&priv->i2c->dev, "%s(): forcing bandwidth to %d\n",
+                                       __func__, p->bandwidth_hz);
+               }
+
                switch (priv->state) {
                case STATE_SLEEP_TC:
                        ret = cxd2841er_sleep_tc_to_active_c(
@@ -3166,7 +3178,8 @@ static int cxd2841er_tune_tc(struct dvb_frontend *fe,
        struct cxd2841er_priv *priv = fe->demodulator_priv;
        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 
-       dev_dbg(&priv->i2c->dev, "%s(): re_tune %d\n", __func__, re_tune);
+       dev_dbg(&priv->i2c->dev, "%s(): re_tune %d bandwidth=%d\n", __func__,
+                       re_tune, p->bandwidth_hz);
        if (re_tune) {
                ret = cxd2841er_set_frontend_tc(fe);
                if (ret)
@@ -3396,8 +3409,10 @@ static int cxd2841er_init_s(struct dvb_frontend *fe)
 static int cxd2841er_init_tc(struct dvb_frontend *fe)
 {
        struct cxd2841er_priv *priv = fe->demodulator_priv;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 
-       dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
+       dev_dbg(&priv->i2c->dev, "%s() bandwidth_hz=%d\n",
+                       __func__, p->bandwidth_hz);
        cxd2841er_shutdown_to_sleep_tc(priv);
        /* SONY_DEMOD_CONFIG_IFAGCNEG = 1 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
@@ -3411,9 +3426,7 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
 }
 
 static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops;
-static struct dvb_frontend_ops cxd2841er_dvbt_t2_ops;
-static struct dvb_frontend_ops cxd2841er_dvbc_ops;
-static struct dvb_frontend_ops cxd2841er_isdbt_ops;
+static struct dvb_frontend_ops cxd2841er_t_c_ops;
 
 static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
                                             struct i2c_adapter *i2c,
@@ -3421,6 +3434,7 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
 {
        u8 chip_id = 0;
        const char *type;
+       const char *name;
        struct cxd2841er_priv *priv = NULL;
 
        /* allocate memory for the internal state */
@@ -3432,52 +3446,48 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
        priv->i2c_addr_slvx = (cfg->i2c_addr + 4) >> 1;
        priv->i2c_addr_slvt = (cfg->i2c_addr) >> 1;
        priv->xtal = cfg->xtal;
-       /* create dvb_frontend */
-       switch (system) {
-       case SYS_DVBS:
-               memcpy(&priv->frontend.ops,
-                       &cxd2841er_dvbs_s2_ops,
-                       sizeof(struct dvb_frontend_ops));
-               type = "S/S2";
-               break;
-       case SYS_DVBT:
-               memcpy(&priv->frontend.ops,
-                       &cxd2841er_dvbt_t2_ops,
-                       sizeof(struct dvb_frontend_ops));
-               type = "T/T2";
-               break;
-       case SYS_ISDBT:
-               memcpy(&priv->frontend.ops,
-                               &cxd2841er_isdbt_ops,
-                               sizeof(struct dvb_frontend_ops));
-               type = "ISDBT";
-               break;
-       case SYS_DVBC_ANNEX_A:
-               memcpy(&priv->frontend.ops,
-                       &cxd2841er_dvbc_ops,
-                       sizeof(struct dvb_frontend_ops));
-               type = "C/C2";
-               break;
-       default:
-               kfree(priv);
-               return NULL;
-       }
        priv->frontend.demodulator_priv = priv;
-       dev_info(&priv->i2c->dev,
-               "%s(): attaching CXD2841ER DVB-%s frontend\n",
-               __func__, type);
        dev_info(&priv->i2c->dev,
                "%s(): I2C adapter %p SLVX addr %x SLVT addr %x\n",
                __func__, priv->i2c,
                priv->i2c_addr_slvx, priv->i2c_addr_slvt);
        chip_id = cxd2841er_chip_id(priv);
-       if (chip_id != CXD2841ER_CHIP_ID && chip_id != CXD2854ER_CHIP_ID) {
+       switch (chip_id) {
+       case CXD2841ER_CHIP_ID:
+               snprintf(cxd2841er_t_c_ops.info.name, 128,
+                               "Sony CXD2841ER DVB-T/T2/C demodulator");
+               name = "CXD2841ER";
+               break;
+       case CXD2854ER_CHIP_ID:
+               snprintf(cxd2841er_t_c_ops.info.name, 128,
+                               "Sony CXD2854ER DVB-T/T2/C and ISDB-T demodulator");
+               cxd2841er_t_c_ops.delsys[3] = SYS_ISDBT;
+               name = "CXD2854ER";
+               break;
+       default:
                dev_err(&priv->i2c->dev, "%s(): invalid chip ID 0x%02x\n",
-                       __func__, chip_id);
+                               __func__, chip_id);
                priv->frontend.demodulator_priv = NULL;
                kfree(priv);
                return NULL;
        }
+
+       /* create dvb_frontend */
+       if (system == SYS_DVBS) {
+               memcpy(&priv->frontend.ops,
+                       &cxd2841er_dvbs_s2_ops,
+                       sizeof(struct dvb_frontend_ops));
+               type = "S/S2";
+       } else {
+               memcpy(&priv->frontend.ops,
+                       &cxd2841er_t_c_ops,
+                       sizeof(struct dvb_frontend_ops));
+               type = "T/T2/C/ISDB-T";
+       }
+
+       dev_info(&priv->i2c->dev,
+               "%s(): attaching %s DVB-%s frontend\n",
+               __func__, name, type);
        dev_info(&priv->i2c->dev, "%s(): chip ID 0x%02x OK.\n",
                __func__, chip_id);
        return &priv->frontend;
@@ -3490,26 +3500,12 @@ struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg,
 }
 EXPORT_SYMBOL(cxd2841er_attach_s);
 
-struct dvb_frontend *cxd2841er_attach_t(struct cxd2841er_config *cfg,
-                                       struct i2c_adapter *i2c)
-{
-       return cxd2841er_attach(cfg, i2c, SYS_DVBT);
-}
-EXPORT_SYMBOL(cxd2841er_attach_t);
-
-struct dvb_frontend *cxd2841er_attach_i(struct cxd2841er_config *cfg,
-               struct i2c_adapter *i2c)
-{
-       return cxd2841er_attach(cfg, i2c, SYS_ISDBT);
-}
-EXPORT_SYMBOL(cxd2841er_attach_i);
-
-struct dvb_frontend *cxd2841er_attach_c(struct cxd2841er_config *cfg,
+struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg,
                                        struct i2c_adapter *i2c)
 {
-       return cxd2841er_attach(cfg, i2c, SYS_DVBC_ANNEX_A);
+       return cxd2841er_attach(cfg, i2c, 0);
 }
-EXPORT_SYMBOL(cxd2841er_attach_c);
+EXPORT_SYMBOL(cxd2841er_attach_t_c);
 
 static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = {
        .delsys = { SYS_DVBS, SYS_DVBS2 },
@@ -3539,46 +3535,10 @@ static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = {
        .tune = cxd2841er_tune_s
 };
 
-static struct  dvb_frontend_ops cxd2841er_dvbt_t2_ops = {
-       .delsys = { SYS_DVBT, SYS_DVBT2 },
-       .info = {
-               .name   = "Sony CXD2841ER DVB-T/T2 demodulator",
-               .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_32 |
-                       FE_CAN_QAM_64 |
-                       FE_CAN_QAM_128 |
-                       FE_CAN_QAM_256 |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_HIERARCHY_AUTO |
-                       FE_CAN_MUTE_TS |
-                       FE_CAN_2G_MODULATION,
-               .frequency_min = 42000000,
-               .frequency_max = 1002000000
-       },
-       .init = cxd2841er_init_tc,
-       .sleep = cxd2841er_sleep_tc,
-       .release = cxd2841er_release,
-       .set_frontend = cxd2841er_set_frontend_tc,
-       .get_frontend = cxd2841er_get_frontend,
-       .read_status = cxd2841er_read_status_tc,
-       .tune = cxd2841er_tune_tc,
-       .i2c_gate_ctrl = cxd2841er_i2c_gate_ctrl,
-       .get_frontend_algo = cxd2841er_get_algo
-};
-
-static struct  dvb_frontend_ops cxd2841er_isdbt_ops = {
-       .delsys = { SYS_ISDBT },
+static struct  dvb_frontend_ops cxd2841er_t_c_ops = {
+       .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
        .info = {
-               .name   = "Sony CXD2854ER ISDBT demodulator",
+               .name   = "", /* will set in attach function */
                .caps = FE_CAN_FEC_1_2 |
                        FE_CAN_FEC_2_3 |
                        FE_CAN_FEC_3_4 |
@@ -3611,37 +3571,6 @@ static struct  dvb_frontend_ops cxd2841er_isdbt_ops = {
        .get_frontend_algo = cxd2841er_get_algo
 };
 
-static struct  dvb_frontend_ops cxd2841er_dvbc_ops = {
-       .delsys = { SYS_DVBC_ANNEX_A },
-       .info = {
-               .name   = "Sony CXD2841ER DVB-C demodulator",
-               .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_QAM_16 |
-                       FE_CAN_QAM_32 |
-                       FE_CAN_QAM_64 |
-                       FE_CAN_QAM_128 |
-                       FE_CAN_QAM_256 |
-                       FE_CAN_QAM_AUTO |
-                       FE_CAN_INVERSION_AUTO,
-               .frequency_min = 42000000,
-               .frequency_max = 1002000000
-       },
-       .init = cxd2841er_init_tc,
-       .sleep = cxd2841er_sleep_tc,
-       .release = cxd2841er_release,
-       .set_frontend = cxd2841er_set_frontend_tc,
-       .get_frontend = cxd2841er_get_frontend,
-       .read_status = cxd2841er_read_status_tc,
-       .tune = cxd2841er_tune_tc,
-       .i2c_gate_ctrl = cxd2841er_i2c_gate_ctrl,
-       .get_frontend_algo = cxd2841er_get_algo,
-};
-
 MODULE_DESCRIPTION("Sony CXD2841ER/CXD2854ER DVB-C/C2/T/T2/S/S2 demodulator driver");
 MODULE_AUTHOR("Sergey Kozlov <serjk@netup.ru>, Abylay Ospan <aospan@netup.ru>");
 MODULE_LICENSE("GPL");
index 9b0d2c1c607a248e8c3dae5fe8df6ce86e55f74d..62ad5f07390ba6f1340fed44966bf4e0e05cfbf4 100644 (file)
@@ -40,13 +40,8 @@ struct cxd2841er_config {
 extern struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg,
                                               struct i2c_adapter *i2c);
 
-extern struct dvb_frontend *cxd2841er_attach_t(struct cxd2841er_config *cfg,
+extern struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg,
                                               struct i2c_adapter *i2c);
-
-extern struct dvb_frontend *cxd2841er_attach_c(struct cxd2841er_config *cfg,
-                                              struct i2c_adapter *i2c);
-extern struct dvb_frontend *cxd2841er_attach_i(struct cxd2841er_config *cfg,
-               struct i2c_adapter *i2c);
 #else
 static inline struct dvb_frontend *cxd2841er_attach_s(
                                        struct cxd2841er_config *cfg,
@@ -56,21 +51,7 @@ static inline struct dvb_frontend *cxd2841er_attach_s(
        return NULL;
 }
 
-static inline struct dvb_frontend *cxd2841er_attach_t(
-               struct cxd2841er_config *cfg, struct i2c_adapter *i2c)
-{
-       pr_warn("%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline struct dvb_frontend *cxd2841er_attach_c(
-               struct cxd2841er_config *cfg, struct i2c_adapter *i2c)
-{
-       pr_warn("%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline struct dvb_frontend *cxd2841er_attach_i(
+static inline struct dvb_frontend *cxd2841er_attach_t_c(
                struct cxd2841er_config *cfg, struct i2c_adapter *i2c)
 {
        pr_warn("%s: driver disabled by Kconfig\n", __func__);
index 950092344eb32b957079daa8ea373d7912079c65..d278d4e151a0a71f25a5e3dade33a51d0220c04e 100644 (file)
@@ -385,18 +385,15 @@ static int netup_unidvb_queue_init(struct netup_dma *dma,
 static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev,
                                 int num)
 {
-       int fe_count = 0;
+       int fe_count = 2;
        int i = 0;
-       struct vb2_dvb_frontend *fes[4];
+       struct vb2_dvb_frontend *fes[2];
        u8 fe_name[32];
 
-       if (ndev->rev == NETUP_HW_REV_1_3) {
-               fe_count = 3;
+       if (ndev->rev == NETUP_HW_REV_1_3)
                demod_config.xtal = SONY_XTAL_20500;
-       } else {
-               fe_count = 4;
+       else
                demod_config.xtal = SONY_XTAL_24000;
-       }
 
        if (num < 0 || num > 1) {
                dev_dbg(&ndev->pci_dev->dev,
@@ -469,11 +466,11 @@ static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev,
        }
 
        /* DVB-T/T2 frontend */
-       fes[1]->dvb.frontend = dvb_attach(cxd2841er_attach_t,
+       fes[1]->dvb.frontend = dvb_attach(cxd2841er_attach_t_c,
                &demod_config, &ndev->i2c[num].adap);
        if (fes[1]->dvb.frontend == NULL) {
                dev_dbg(&ndev->pci_dev->dev,
-                       "%s(): unable to attach DVB-T frontend\n", __func__);
+                       "%s(): unable to attach Ter frontend\n", __func__);
                goto frontend_detach;
        }
        fes[1]->dvb.frontend->id = 1;
@@ -482,7 +479,7 @@ static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev,
                if (!dvb_attach(ascot2e_attach, fes[1]->dvb.frontend,
                                        &ascot2e_conf, &ndev->i2c[num].adap)) {
                        dev_dbg(&ndev->pci_dev->dev,
-                                       "%s(): unable to attach DVB-T tuner frontend\n",
+                                       "%s(): unable to attach Ter tuner frontend\n",
                                        __func__);
                        goto frontend_detach;
                }
@@ -490,55 +487,6 @@ static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev,
                helene_conf.set_tuner_priv = &ndev->dma[num];
                if (!dvb_attach(helene_attach, fes[1]->dvb.frontend,
                                        &helene_conf, &ndev->i2c[num].adap)) {
-                       dev_err(&ndev->pci_dev->dev,
-                                       "%s(): unable to attach HELENE DVB-T/T2 tuner frontend\n",
-                                       __func__);
-                       goto frontend_detach;
-               }
-       }
-
-       /* DVB-C/C2 frontend */
-       fes[2]->dvb.frontend = dvb_attach(cxd2841er_attach_c,
-                               &demod_config, &ndev->i2c[num].adap);
-       if (fes[2]->dvb.frontend == NULL) {
-               dev_dbg(&ndev->pci_dev->dev,
-                       "%s(): unable to attach DVB-C frontend\n", __func__);
-               goto frontend_detach;
-       }
-       fes[2]->dvb.frontend->id = 2;
-       if (ndev->rev == NETUP_HW_REV_1_3) {
-               if (!dvb_attach(ascot2e_attach, fes[2]->dvb.frontend,
-                                       &ascot2e_conf, &ndev->i2c[num].adap)) {
-                       dev_dbg(&ndev->pci_dev->dev,
-                                       "%s(): unable to attach DVB-T/C tuner frontend\n",
-                                       __func__);
-                       goto frontend_detach;
-               }
-       } else {
-               helene_conf.set_tuner_priv = &ndev->dma[num];
-               if (!dvb_attach(helene_attach, fes[2]->dvb.frontend,
-                                       &helene_conf, &ndev->i2c[num].adap)) {
-                       dev_err(&ndev->pci_dev->dev,
-                                       "%s(): unable to attach HELENE Ter tuner frontend\n",
-                                       __func__);
-                       goto frontend_detach;
-               }
-       }
-
-       if (ndev->rev == NETUP_HW_REV_1_4) {
-               /* ISDB-T frontend */
-               fes[3]->dvb.frontend = dvb_attach(cxd2841er_attach_i,
-                               &demod_config, &ndev->i2c[num].adap);
-               if (fes[3]->dvb.frontend == NULL) {
-                       dev_dbg(&ndev->pci_dev->dev,
-                               "%s(): unable to attach ISDB-T frontend\n",
-                               __func__);
-                       goto frontend_detach;
-               }
-               fes[3]->dvb.frontend->id = 3;
-               helene_conf.set_tuner_priv = &ndev->dma[num];
-               if (!dvb_attach(helene_attach, fes[3]->dvb.frontend,
-                                       &helene_conf, &ndev->i2c[num].adap)) {
                        dev_err(&ndev->pci_dev->dev,
                                        "%s(): unable to attach HELENE Ter tuner frontend\n",
                                        __func__);