[media] New hw revision 1.4 of NetUP Universal DVB card added
authorAbylay Ospan <aospan@netup.ru>
Thu, 24 Mar 2016 01:34:07 +0000 (22:34 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 7 Jun 2016 15:10:30 +0000 (12:10 -0300)
New hardware revision of NetUP Universal DVB card (rev 1.4):
* changed tuners (CXD2861ER and CXD2832AER) to CXD2858ER
* changed demodulator (CXD2841ER) to CXD2854ER

card now supports:
DVB-S/S2, DVB-T/T2, DVB-C/C2, ISDB-T

PCI id's assigned for new hardware revision is:
1b55:18f7

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

index a67b281..39b08ec 100644 (file)
 #define NETUP_UNIDVB_IRQ_CAM0  (1 << 11)
 #define NETUP_UNIDVB_IRQ_CAM1  (1 << 12)
 
+/* NetUP Universal DVB card hardware revisions and it's PCI device id's:
+ * 1.3 - CXD2841ER demod, ASCOT2E and HORUS3A tuners
+ * 1.4 - CXD2854ER demod, HELENE tuner
+*/
+enum netup_hw_rev {
+       NETUP_HW_REV_1_3 = 0x18F6,
+       NETUP_HW_REV_1_4 = 0x18F7
+};
+
 struct netup_dma {
        u8                      num;
        spinlock_t              lock;
@@ -119,6 +128,7 @@ struct netup_unidvb_dev {
        struct netup_dma                dma[2];
        struct netup_ci_state           ci[2];
        struct netup_spi                *spi;
+       enum netup_hw_rev               rev;
 };
 
 int netup_i2c_register(struct netup_unidvb_dev *ndev);
index 2b667b3..9500923 100644 (file)
@@ -34,6 +34,7 @@
 #include "cxd2841er.h"
 #include "horus3a.h"
 #include "ascot2e.h"
+#include "helene.h"
 #include "lnbh25.h"
 
 static int spi_enable;
@@ -120,7 +121,8 @@ static int netup_unidvb_tuner_ctrl(void *priv, int is_dvb_tc);
 static void netup_unidvb_queue_cleanup(struct netup_dma *dma);
 
 static struct cxd2841er_config demod_config = {
-       .i2c_addr = 0xc8
+       .i2c_addr = 0xc8,
+       .xtal = SONY_XTAL_24000
 };
 
 static struct horus3a_config horus3a_conf = {
@@ -134,6 +136,12 @@ static struct ascot2e_config ascot2e_conf = {
        .set_tuner_callback = netup_unidvb_tuner_ctrl
 };
 
+static struct helene_config helene_conf = {
+       .i2c_address = 0xc0,
+       .xtal = SONY_HELENE_XTAL_24000,
+       .set_tuner_callback = netup_unidvb_tuner_ctrl
+};
+
 static struct lnbh25_config lnbh25_conf = {
        .i2c_address = 0x10,
        .data2_config = LNBH25_TEN | LNBH25_EXTM
@@ -152,6 +160,11 @@ static int netup_unidvb_tuner_ctrl(void *priv, int is_dvb_tc)
                __func__, dma->num, is_dvb_tc);
        reg = readb(ndev->bmmio0 + GPIO_REG_IO);
        mask = (dma->num == 0) ? GPIO_RFA_CTL : GPIO_RFB_CTL;
+
+       /* inverted tuner control in hw rev. 1.4 */
+       if (ndev->rev == NETUP_HW_REV_1_4)
+               is_dvb_tc = !is_dvb_tc;
+
        if (!is_dvb_tc)
                reg |= mask;
        else
@@ -372,7 +385,18 @@ static int netup_unidvb_queue_init(struct netup_dma *dma,
 static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev,
                                 int num)
 {
-       struct vb2_dvb_frontend *fe0, *fe1, *fe2;
+       int fe_count = 0;
+       int i = 0;
+       struct vb2_dvb_frontend *fes[4];
+       u8 fe_name[32];
+
+       if (ndev->rev == NETUP_HW_REV_1_3) {
+               fe_count = 3;
+               demod_config.xtal = SONY_XTAL_20500;
+       } else {
+               fe_count = 4;
+               demod_config.xtal = SONY_XTAL_24000;
+       }
 
        if (num < 0 || num > 1) {
                dev_dbg(&ndev->pci_dev->dev,
@@ -381,84 +405,145 @@ static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev,
        }
        mutex_init(&ndev->frontends[num].lock);
        INIT_LIST_HEAD(&ndev->frontends[num].felist);
-       if (vb2_dvb_alloc_frontend(&ndev->frontends[num], 1) == NULL ||
-               vb2_dvb_alloc_frontend(
-                       &ndev->frontends[num], 2) == NULL ||
-               vb2_dvb_alloc_frontend(
-                       &ndev->frontends[num], 3) == NULL) {
-               dev_dbg(&ndev->pci_dev->dev,
-                       "%s(): unable to allocate vb2_dvb_frontend\n",
-                       __func__);
-               return -ENOMEM;
+
+       for (i = 0; i < fe_count; i++) {
+               if (vb2_dvb_alloc_frontend(&ndev->frontends[num], i+1)
+                               == NULL) {
+                       dev_err(&ndev->pci_dev->dev,
+                                       "%s(): unable to allocate vb2_dvb_frontend\n",
+                                       __func__);
+                       return -ENOMEM;
+               }
        }
-       fe0 = vb2_dvb_get_frontend(&ndev->frontends[num], 1);
-       fe1 = vb2_dvb_get_frontend(&ndev->frontends[num], 2);
-       fe2 = vb2_dvb_get_frontend(&ndev->frontends[num], 3);
-       if (fe0 == NULL || fe1 == NULL || fe2 == NULL) {
-               dev_dbg(&ndev->pci_dev->dev,
-                       "%s(): frontends has not been allocated\n", __func__);
-               return -EINVAL;
+
+       for (i = 0; i < fe_count; i++) {
+               fes[i] = vb2_dvb_get_frontend(&ndev->frontends[num], i+1);
+               if (fes[i] == NULL) {
+                       dev_err(&ndev->pci_dev->dev,
+                               "%s(): frontends has not been allocated\n",
+                               __func__);
+                       return -EINVAL;
+               }
+       }
+
+       for (i = 0; i < fe_count; i++) {
+               netup_unidvb_queue_init(&ndev->dma[num], &fes[i]->dvb.dvbq);
+               snprintf(fe_name, sizeof(fe_name), "netup_fe%d", i);
+               fes[i]->dvb.name = fe_name;
        }
-       netup_unidvb_queue_init(&ndev->dma[num], &fe0->dvb.dvbq);
-       netup_unidvb_queue_init(&ndev->dma[num], &fe1->dvb.dvbq);
-       netup_unidvb_queue_init(&ndev->dma[num], &fe2->dvb.dvbq);
-       fe0->dvb.name = "netup_fe0";
-       fe1->dvb.name = "netup_fe1";
-       fe2->dvb.name = "netup_fe2";
-       fe0->dvb.frontend = dvb_attach(cxd2841er_attach_s,
+
+       fes[0]->dvb.frontend = dvb_attach(cxd2841er_attach_s,
                &demod_config, &ndev->i2c[num].adap);
-       if (fe0->dvb.frontend == NULL) {
+       if (fes[0]->dvb.frontend == NULL) {
                dev_dbg(&ndev->pci_dev->dev,
                        "%s(): unable to attach DVB-S/S2 frontend\n",
                        __func__);
                goto frontend_detach;
        }
-       horus3a_conf.set_tuner_priv = &ndev->dma[num];
-       if (!dvb_attach(horus3a_attach, fe0->dvb.frontend,
-                       &horus3a_conf, &ndev->i2c[num].adap)) {
-               dev_dbg(&ndev->pci_dev->dev,
-                       "%s(): unable to attach DVB-S/S2 tuner frontend\n",
-                       __func__);
-               goto frontend_detach;
+
+       if (ndev->rev == NETUP_HW_REV_1_3) {
+               horus3a_conf.set_tuner_priv = &ndev->dma[num];
+               if (!dvb_attach(horus3a_attach, fes[0]->dvb.frontend,
+                                       &horus3a_conf, &ndev->i2c[num].adap)) {
+                       dev_dbg(&ndev->pci_dev->dev,
+                                       "%s(): unable to attach HORUS3A DVB-S/S2 tuner frontend\n",
+                                       __func__);
+                       goto frontend_detach;
+               }
+       } else {
+               helene_conf.set_tuner_priv = &ndev->dma[num];
+               if (!dvb_attach(helene_attach_s, fes[0]->dvb.frontend,
+                                       &helene_conf, &ndev->i2c[num].adap)) {
+                       dev_err(&ndev->pci_dev->dev,
+                                       "%s(): unable to attach HELENE DVB-S/S2 tuner frontend\n",
+                                       __func__);
+                       goto frontend_detach;
+               }
        }
-       if (!dvb_attach(lnbh25_attach, fe0->dvb.frontend,
+
+       if (!dvb_attach(lnbh25_attach, fes[0]->dvb.frontend,
                        &lnbh25_conf, &ndev->i2c[num].adap)) {
                dev_dbg(&ndev->pci_dev->dev,
                        "%s(): unable to attach SEC frontend\n", __func__);
                goto frontend_detach;
        }
+
        /* DVB-T/T2 frontend */
-       fe1->dvb.frontend = dvb_attach(cxd2841er_attach_t,
+       fes[1]->dvb.frontend = dvb_attach(cxd2841er_attach_t,
                &demod_config, &ndev->i2c[num].adap);
-       if (fe1->dvb.frontend == NULL) {
+       if (fes[1]->dvb.frontend == NULL) {
                dev_dbg(&ndev->pci_dev->dev,
                        "%s(): unable to attach DVB-T frontend\n", __func__);
                goto frontend_detach;
        }
-       fe1->dvb.frontend->id = 1;
-       ascot2e_conf.set_tuner_priv = &ndev->dma[num];
-       if (!dvb_attach(ascot2e_attach, fe1->dvb.frontend,
-                       &ascot2e_conf, &ndev->i2c[num].adap)) {
-               dev_dbg(&ndev->pci_dev->dev,
-                       "%s(): unable to attach DVB-T tuner frontend\n",
-                       __func__);
-               goto frontend_detach;
+       fes[1]->dvb.frontend->id = 1;
+       if (ndev->rev == NETUP_HW_REV_1_3) {
+               ascot2e_conf.set_tuner_priv = &ndev->dma[num];
+               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",
+                                       __func__);
+                       goto frontend_detach;
+               }
+       } else {
+               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 */
-       fe2->dvb.frontend = dvb_attach(cxd2841er_attach_c,
+       fes[2]->dvb.frontend = dvb_attach(cxd2841er_attach_c,
                                &demod_config, &ndev->i2c[num].adap);
-       if (fe2->dvb.frontend == NULL) {
+       if (fes[2]->dvb.frontend == NULL) {
                dev_dbg(&ndev->pci_dev->dev,
                        "%s(): unable to attach DVB-C frontend\n", __func__);
                goto frontend_detach;
        }
-       fe2->dvb.frontend->id = 2;
-       if (!dvb_attach(ascot2e_attach, fe2->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;
+       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__);
+                       goto frontend_detach;
+               }
        }
 
        if (vb2_dvb_register_bus(&ndev->frontends[num],
@@ -730,7 +815,7 @@ static int netup_unidvb_request_mmio(struct pci_dev *pci_dev)
 static int netup_unidvb_request_modules(struct device *dev)
 {
        static const char * const modules[] = {
-               "lnbh25", "ascot2e", "horus3a", "cxd2841er", NULL
+               "lnbh25", "ascot2e", "horus3a", "cxd2841er", "helene", NULL
        };
        const char * const *curr_mod = modules;
        int err;
@@ -774,6 +859,16 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
        if (!ndev)
                goto dev_alloc_err;
 
+       /* detect hardware revision */
+       if (pci_dev->device == NETUP_HW_REV_1_3)
+               ndev->rev = NETUP_HW_REV_1_3;
+       else
+               ndev->rev = NETUP_HW_REV_1_4;
+
+       dev_info(&pci_dev->dev,
+               "%s(): board (0x%x) hardware revision 0x%x\n",
+               __func__, pci_dev->device, ndev->rev);
+
        ndev->old_fw = old_firmware;
        ndev->wq = create_singlethread_workqueue(NETUP_UNIDVB_NAME);
        if (!ndev->wq) {
@@ -972,7 +1067,8 @@ static void netup_unidvb_finidev(struct pci_dev *pci_dev)
 
 
 static struct pci_device_id netup_unidvb_pci_tbl[] = {
-       { PCI_DEVICE(0x1b55, 0x18f6) },
+       { PCI_DEVICE(0x1b55, 0x18f6) }, /* hw rev. 1.3 */
+       { PCI_DEVICE(0x1b55, 0x18f7) }, /* hw rev. 1.4 */
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, netup_unidvb_pci_tbl);