aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor M. Liplianin <liplianin@me.by>2011-01-25 15:04:00 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:32:18 -0400
commit78db854757aa4110f9c6873d1529b851037a3405 (patch)
tree52aa3b669d488d117024a970ef67bd313761335d
parente80edce1abfabf637edc68e8dd13ef0af6e46cdf (diff)
[media] Initial commit to support NetUP Dual DVB-T/C CI RF card
The card based on cx23885 PCI-e brige. Altera FPGA for CI, multistandard demods stv0367 from STM for QAM & OFDM, Xcieve xc5000 tuners and additional cx25840 for second analog input. Signed-off-by: Igor M. Liplianin <liplianin@netup.ru> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/frontends/stv0367.h4
-rw-r--r--drivers/media/video/cx23885/Kconfig3
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c103
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c22
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c172
-rw-r--r--drivers/media/video/cx23885/cx23885.h4
6 files changed, 286 insertions, 22 deletions
diff --git a/drivers/media/dvb/frontends/stv0367.h b/drivers/media/dvb/frontends/stv0367.h
index 822a8e98783f..93cc4a57eea0 100644
--- a/drivers/media/dvb/frontends/stv0367.h
+++ b/drivers/media/dvb/frontends/stv0367.h
@@ -4,8 +4,8 @@
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC. 4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 * 5 *
6 * Copyright (C) ST Microelectronics. 6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010 NetUP Inc. 7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru> 8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index 5e5faadd678f..3b6e7f28568e 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -1,6 +1,7 @@
1config VIDEO_CX23885 1config VIDEO_CX23885
2 tristate "Conexant cx23885 (2388x successor) support" 2 tristate "Conexant cx23885 (2388x successor) support"
3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT 3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND
4 select SND_PCM
4 select I2C_ALGOBIT 5 select I2C_ALGOBIT
5 select VIDEO_BTCX 6 select VIDEO_BTCX
6 select VIDEO_TUNER 7 select VIDEO_TUNER
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index b298b730943c..a3fe26cf6367 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -24,10 +24,14 @@
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <media/cx25840.h> 26#include <media/cx25840.h>
27#include <linux/firmware.h>
28#include <staging/altera.h>
27 29
28#include "cx23885.h" 30#include "cx23885.h"
29#include "tuner-xc2028.h" 31#include "tuner-xc2028.h"
30#include "netup-init.h" 32#include "netup-init.h"
33#include "altera-ci.h"
34#include "xc5000.h"
31#include "cx23888-ir.h" 35#include "cx23888-ir.h"
32 36
33static unsigned int enable_885_ir; 37static unsigned int enable_885_ir;
@@ -187,7 +191,7 @@ struct cx23885_board cx23885_boards[] = {
187 .portb = CX23885_MPEG_DVB, 191 .portb = CX23885_MPEG_DVB,
188 }, 192 },
189 [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = { 193 [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = {
190 .cimax = 1, 194 .ci_type = 1,
191 .name = "NetUP Dual DVB-S2 CI", 195 .name = "NetUP Dual DVB-S2 CI",
192 .portb = CX23885_MPEG_DVB, 196 .portb = CX23885_MPEG_DVB,
193 .portc = CX23885_MPEG_DVB, 197 .portc = CX23885_MPEG_DVB,
@@ -329,6 +333,19 @@ struct cx23885_board cx23885_boards[] = {
329 CX25840_SVIDEO_CHROMA4, 333 CX25840_SVIDEO_CHROMA4,
330 } }, 334 } },
331 }, 335 },
336 [CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF] = {
337 .ci_type = 2,
338 .name = "NetUP Dual DVB-T/C-CI RF",
339 .porta = CX23885_ANALOG_VIDEO,
340 .portb = CX23885_MPEG_DVB,
341 .portc = CX23885_MPEG_DVB,
342 .tuner_type = TUNER_XC5000,
343 .tuner_addr = 0x64,
344 .input = { {
345 .type = CX23885_VMUX_TELEVISION,
346 .vmux = CX25840_COMPOSITE1,
347 } },
348 },
332}; 349};
333const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 350const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
334 351
@@ -520,6 +537,10 @@ struct cx23885_subid cx23885_subids[] = {
520 .subvendor = 0x5654, 537 .subvendor = 0x5654,
521 .subdevice = 0x2390, 538 .subdevice = 0x2390,
522 .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID, 539 .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID,
540 }, {
541 .subvendor = 0x1b55,
542 .subdevice = 0xe2e4,
543 .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF,
523 }, 544 },
524}; 545};
525const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 546const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -740,6 +761,9 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
740 /* Tuner Reset Command */ 761 /* Tuner Reset Command */
741 bitmask = 0x02; 762 bitmask = 0x02;
742 break; 763 break;
764 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
765 altera_ci_tuner_reset(dev, port->nr);
766 break;
743 } 767 }
744 768
745 if (bitmask) { 769 if (bitmask) {
@@ -998,6 +1022,33 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
998 case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: 1022 case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
999 cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ 1023 cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */
1000 break; 1024 break;
1025 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1026 /* GPIO-0 ~INT in
1027 GPIO-1 TMS out
1028 GPIO-2 ~reset chips out
1029 GPIO-3 to GPIO-10 data/addr for CA in/out
1030 GPIO-11 ~CS out
1031 GPIO-12 ADDR out
1032 GPIO-13 ~WR out
1033 GPIO-14 ~RD out
1034 GPIO-15 ~RDY in
1035 GPIO-16 TCK out
1036 GPIO-17 TDO in
1037 GPIO-18 TDI out
1038 */
1039 cx_set(GP0_IO, 0x00060000); /* GPIO-1,2 as out */
1040 /* GPIO-0 as INT, reset & TMS low */
1041 cx_clear(GP0_IO, 0x00010006);
1042 mdelay(100);/* reset delay */
1043 cx_set(GP0_IO, 0x00000004); /* reset high */
1044 cx_write(MC417_CTL, 0x00000037);/* enable GPIO-3..18 pins */
1045 /* GPIO-17 is TDO in, GPIO-15 is ~RDY in, rest is out */
1046 cx_write(MC417_OEN, 0x00005000);
1047 /* ~RD, ~WR high; ADDR low; ~CS high */
1048 cx_write(MC417_RWD, 0x00000d00);
1049 /* enable irq */
1050 cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
1051 break;
1001 } 1052 }
1002} 1053}
1003 1054
@@ -1113,6 +1164,31 @@ void cx23885_ir_fini(struct cx23885_dev *dev)
1113 } 1164 }
1114} 1165}
1115 1166
1167int netup_jtag_io(void *device, int tms, int tdi, int read_tdo)
1168{
1169 int data;
1170 int tdo = 0;
1171 struct cx23885_dev *dev = (struct cx23885_dev *)device;
1172 /*TMS*/
1173 data = ((cx_read(GP0_IO)) & (~0x00000002));
1174 data |= (tms ? 0x00020002 : 0x00020000);
1175 cx_write(GP0_IO, data);
1176
1177 /*TDI*/
1178 data = ((cx_read(MC417_RWD)) & (~0x0000a000));
1179 data |= (tdi ? 0x00008000 : 0);
1180 cx_write(MC417_RWD, data);
1181 if (read_tdo)
1182 tdo = (data & 0x00004000) ? 1 : 0; /*TDO*/
1183
1184 cx_write(MC417_RWD, data | 0x00002000);
1185 udelay(1);
1186 /*TCK*/
1187 cx_write(MC417_RWD, data);
1188
1189 return tdo;
1190}
1191
1116void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) 1192void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
1117{ 1193{
1118 switch (dev->board) { 1194 switch (dev->board) {
@@ -1212,6 +1288,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1212 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1288 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1213 break; 1289 break;
1214 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1290 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1291 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1215 ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 1292 ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
1216 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1293 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1217 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1294 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
@@ -1271,6 +1348,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1271 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 1348 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
1272 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 1349 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
1273 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1350 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1351 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1274 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 1352 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
1275 case CX23885_BOARD_HAUPPAUGE_HVR1850: 1353 case CX23885_BOARD_HAUPPAUGE_HVR1850:
1276 case CX23885_BOARD_MYGICA_X8506: 1354 case CX23885_BOARD_MYGICA_X8506:
@@ -1293,6 +1371,29 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1293 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1371 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1294 netup_initialize(dev); 1372 netup_initialize(dev);
1295 break; 1373 break;
1374 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
1375 int ret;
1376 const struct firmware *fw;
1377 const char *filename = "dvb-netup-altera-01.fw";
1378 char *action = "configure";
1379 struct altera_config netup_config = {
1380 .dev = dev,
1381 .action = action,
1382 .jtag_io = netup_jtag_io,
1383 };
1384
1385 netup_initialize(dev);
1386
1387 ret = request_firmware(&fw, filename, &dev->pci->dev);
1388 if (ret != 0)
1389 printk(KERN_ERR "did not find the firmware file. (%s) "
1390 "Please see linux/Documentation/dvb/ for more details "
1391 "on firmware-problems.", filename);
1392 else
1393 altera_init(&netup_config, fw);
1394
1395 break;
1396 }
1296 } 1397 }
1297} 1398}
1298 1399
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 359882419b7f..9ad4c9c577e0 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -29,9 +29,11 @@
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <asm/div64.h> 31#include <asm/div64.h>
32#include <linux/firmware.h>
32 33
33#include "cx23885.h" 34#include "cx23885.h"
34#include "cimax2.h" 35#include "cimax2.h"
36#include "altera-ci.h"
35#include "cx23888-ir.h" 37#include "cx23888-ir.h"
36#include "cx23885-ir.h" 38#include "cx23885-ir.h"
37#include "cx23885-av.h" 39#include "cx23885-av.h"
@@ -902,8 +904,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
902 dev->pci_bus = dev->pci->bus->number; 904 dev->pci_bus = dev->pci->bus->number;
903 dev->pci_slot = PCI_SLOT(dev->pci->devfn); 905 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
904 cx23885_irq_add(dev, 0x001f00); 906 cx23885_irq_add(dev, 0x001f00);
905 if (cx23885_boards[dev->board].cimax > 0)
906 cx23885_irq_add(dev, 0x01800000); /* for CiMaxes */
907 907
908 /* External Master 1 Bus */ 908 /* External Master 1 Bus */
909 dev->i2c_bus[0].nr = 0; 909 dev->i2c_bus[0].nr = 0;
@@ -1822,14 +1822,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1822 PCI_MSK_IR); 1822 PCI_MSK_IR);
1823 } 1823 }
1824 1824
1825 if (cx23885_boards[dev->board].cimax > 0 && 1825 if (cx23885_boards[dev->board].ci_type == 1 &&
1826 ((pci_status & PCI_MSK_GPIO0) || 1826 (pci_status & (PCI_MSK_GPIO1 | PCI_MSK_GPIO0)))
1827 (pci_status & PCI_MSK_GPIO1))) { 1827 handled += netup_ci_slot_status(dev, pci_status);
1828 1828
1829 if (cx23885_boards[dev->board].cimax > 0) 1829 if (cx23885_boards[dev->board].ci_type == 2 &&
1830 handled += netup_ci_slot_status(dev, pci_status); 1830 (pci_status & PCI_MSK_GPIO0))
1831 1831 handled += altera_ci_irq(dev);
1832 }
1833 1832
1834 if (ts1_status) { 1833 if (ts1_status) {
1835 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) 1834 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
@@ -2064,7 +2063,10 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
2064 2063
2065 switch (dev->board) { 2064 switch (dev->board) {
2066 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 2065 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
2067 cx23885_irq_add_enable(dev, 0x01800000); /* for NetUP */ 2066 cx23885_irq_add_enable(dev, PCI_MSK_GPIO1 | PCI_MSK_GPIO0);
2067 break;
2068 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
2069 cx23885_irq_add_enable(dev, PCI_MSK_GPIO0);
2068 break; 2070 break;
2069 } 2071 }
2070 2072
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 5958cb882e93..cf36b9b4794e 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -58,6 +58,8 @@
58#include "atbm8830.h" 58#include "atbm8830.h"
59#include "ds3000.h" 59#include "ds3000.h"
60#include "cx23885-f300.h" 60#include "cx23885-f300.h"
61#include "altera-ci.h"
62#include "stv0367.h"
61 63
62static unsigned int debug; 64static unsigned int debug;
63 65
@@ -108,6 +110,22 @@ static void dvb_buf_release(struct videobuf_queue *q,
108 cx23885_free_buffer(q, (struct cx23885_buffer *)vb); 110 cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
109} 111}
110 112
113static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open)
114{
115 struct videobuf_dvb_frontends *f;
116 struct videobuf_dvb_frontend *fe;
117
118 f = &port->frontends;
119
120 if (f->gate <= 1) /* undefined or fe0 */
121 fe = videobuf_dvb_get_frontend(f, 1);
122 else
123 fe = videobuf_dvb_get_frontend(f, f->gate);
124
125 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
126 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
127}
128
111static struct videobuf_queue_ops dvb_qops = { 129static struct videobuf_queue_ops dvb_qops = {
112 .buf_setup = dvb_buf_setup, 130 .buf_setup = dvb_buf_setup,
113 .buf_prepare = dvb_buf_prepare, 131 .buf_prepare = dvb_buf_prepare,
@@ -570,12 +588,84 @@ static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
570 .i2c_address = 0x60, 588 .i2c_address = 0x60,
571 .osc_clk = 20 589 .osc_clk = 20
572}; 590};
591static struct stv0367_config netup_stv0367_config[] = {
592 {
593 .demod_address = 0x1c,
594 .xtal = 27000000,
595 .if_khz = 4500,
596 .if_iq_mode = 0,
597 .ts_mode = 1,
598 .clk_pol = 0,
599 }, {
600 .demod_address = 0x1d,
601 .xtal = 27000000,
602 .if_khz = 4500,
603 .if_iq_mode = 0,
604 .ts_mode = 1,
605 .clk_pol = 0,
606 },
607};
608
609static struct xc5000_config netup_xc5000_config[] = {
610 {
611 .i2c_address = 0x61,
612 .if_khz = 4500,
613 }, {
614 .i2c_address = 0x64,
615 .if_khz = 4500,
616 },
617};
618
619int netup_altera_fpga_rw(void *device, int flag, int data, int read)
620{
621 struct cx23885_dev *dev = (struct cx23885_dev *)device;
622 unsigned long timeout = jiffies + msecs_to_jiffies(1);
623 int mem = 0;
624
625 cx_set(MC417_RWD, ALT_RD | ALT_WR | ALT_CS);
626 if (read)
627 cx_set(MC417_OEN, ALT_DATA);
628 else {
629 cx_clear(MC417_OEN, ALT_DATA);/* D0-D7 out */
630 mem = cx_read(MC417_RWD);
631 mem &= ~ALT_DATA;
632 mem |= (data & ALT_DATA);
633 cx_write(MC417_RWD, mem);
634 }
635
636 if (flag)
637 cx_set(MC417_RWD, ALT_AD_RG);/* ADDR */
638 else
639 cx_clear(MC417_RWD, ALT_AD_RG);/* VAL */
640
641 cx_clear(MC417_RWD, ALT_CS);/* ~CS */
642 if (read)
643 cx_clear(MC417_RWD, ALT_RD);
644 else
645 cx_clear(MC417_RWD, ALT_WR);
646
647 for (;;) {
648 mem = cx_read(MC417_RWD);
649 if ((mem & ALT_RDY) == 0)
650 break;
651 if (time_after(jiffies, timeout))
652 break;
653 udelay(1);
654 }
655
656 cx_set(MC417_RWD, ALT_RD | ALT_WR | ALT_CS);
657 if (read)
658 return mem & ALT_DATA;
659
660 return 0;
661};
573 662
574static int dvb_register(struct cx23885_tsport *port) 663static int dvb_register(struct cx23885_tsport *port)
575{ 664{
576 struct cx23885_dev *dev = port->dev; 665 struct cx23885_dev *dev = port->dev;
577 struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; 666 struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
578 struct videobuf_dvb_frontend *fe0; 667 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
668 int mfe_shared = 0; /* bus not shared by default */
579 int ret; 669 int ret;
580 670
581 /* Get the first frontend */ 671 /* Get the first frontend */
@@ -586,6 +676,12 @@ static int dvb_register(struct cx23885_tsport *port)
586 /* init struct videobuf_dvb */ 676 /* init struct videobuf_dvb */
587 fe0->dvb.name = dev->name; 677 fe0->dvb.name = dev->name;
588 678
679 /* multi-frontend gate control is undefined or defaults to fe0 */
680 port->frontends.gate = 0;
681
682 /* Sets the gate control callback to be used by i2c command calls */
683 port->gate_ctrl = cx23885_dvb_gate_ctrl;
684
589 /* init frontend */ 685 /* init frontend */
590 switch (dev->board) { 686 switch (dev->board) {
591 case CX23885_BOARD_HAUPPAUGE_HVR1250: 687 case CX23885_BOARD_HAUPPAUGE_HVR1250:
@@ -966,20 +1062,61 @@ static int dvb_register(struct cx23885_tsport *port)
966 break; 1062 break;
967 } 1063 }
968 break; 1064 break;
969 1065 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1066 i2c_bus = &dev->i2c_bus[0];
1067 mfe_shared = 1;/* MFE */
1068 port->frontends.gate = 0;/* not clear for me yet */
1069 /* ports B, C */
1070 /* MFE frontend 1 DVB-T */
1071 fe0->dvb.frontend = dvb_attach(stv0367ter_attach,
1072 &netup_stv0367_config[port->nr - 1],
1073 &i2c_bus->i2c_adap);
1074 if (fe0->dvb.frontend != NULL)
1075 if (NULL == dvb_attach(xc5000_attach,
1076 fe0->dvb.frontend,
1077 &i2c_bus->i2c_adap,
1078 &netup_xc5000_config[port->nr - 1]))
1079 goto frontend_detach;
1080 /* MFE frontend 2 */
1081 fe1 = videobuf_dvb_get_frontend(&port->frontends, 2);
1082 if (fe1 == NULL)
1083 goto frontend_detach;
1084 /* DVB-C init */
1085 fe1->dvb.frontend = dvb_attach(stv0367cab_attach,
1086 &netup_stv0367_config[port->nr - 1],
1087 &i2c_bus->i2c_adap);
1088 if (fe1->dvb.frontend != NULL) {
1089 fe1->dvb.frontend->id = 1;
1090 if (NULL == dvb_attach(xc5000_attach,
1091 fe1->dvb.frontend,
1092 &i2c_bus->i2c_adap,
1093 &netup_xc5000_config[port->nr - 1]))
1094 goto frontend_detach;
1095 }
1096 break;
970 default: 1097 default:
971 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " 1098 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
972 " isn't supported yet\n", 1099 " isn't supported yet\n",
973 dev->name); 1100 dev->name);
974 break; 1101 break;
975 } 1102 }
976 if (NULL == fe0->dvb.frontend) { 1103
1104 if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) {
977 printk(KERN_ERR "%s: frontend initialization failed\n", 1105 printk(KERN_ERR "%s: frontend initialization failed\n",
978 dev->name); 1106 dev->name);
979 return -1; 1107 goto frontend_detach;
980 } 1108 }
1109
981 /* define general-purpose callback pointer */ 1110 /* define general-purpose callback pointer */
982 fe0->dvb.frontend->callback = cx23885_tuner_callback; 1111 fe0->dvb.frontend->callback = cx23885_tuner_callback;
1112 if (fe1)
1113 fe1->dvb.frontend->callback = cx23885_tuner_callback;
1114#if 0
1115 /* Ensure all frontends negotiate bus access */
1116 fe0->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
1117 if (fe1)
1118 fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
1119#endif
983 1120
984 /* Put the analog decoder in standby to keep it quiet */ 1121 /* Put the analog decoder in standby to keep it quiet */
985 call_all(dev, core, s_power, 0); 1122 call_all(dev, core, s_power, 0);
@@ -989,10 +1126,10 @@ static int dvb_register(struct cx23885_tsport *port)
989 1126
990 /* register everything */ 1127 /* register everything */
991 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, 1128 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
992 &dev->pci->dev, adapter_nr, 0, 1129 &dev->pci->dev, adapter_nr, mfe_shared,
993 cx23885_dvb_fe_ioctl_override); 1130 cx23885_dvb_fe_ioctl_override);
994 if (ret) 1131 if (ret)
995 return ret; 1132 goto frontend_detach;
996 1133
997 /* init CI & MAC */ 1134 /* init CI & MAC */
998 switch (dev->board) { 1135 switch (dev->board) {
@@ -1008,6 +1145,17 @@ static int dvb_register(struct cx23885_tsport *port)
1008 netup_ci_init(port); 1145 netup_ci_init(port);
1009 break; 1146 break;
1010 } 1147 }
1148 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
1149 struct altera_ci_config netup_ci_cfg = {
1150 .dev = dev,/* magic number to identify*/
1151 .adapter = &port->frontends.adapter,/* for CI */
1152 .demux = &fe0->dvb.demux,/* for hw pid filter */
1153 .fpga_rw = netup_altera_fpga_rw,
1154 };
1155
1156 altera_ci_init(&netup_ci_cfg, port->nr);
1157 break;
1158 }
1011 case CX23885_BOARD_TEVII_S470: { 1159 case CX23885_BOARD_TEVII_S470: {
1012 u8 eeprom[256]; /* 24C02 i2c eeprom */ 1160 u8 eeprom[256]; /* 24C02 i2c eeprom */
1013 1161
@@ -1024,6 +1172,11 @@ static int dvb_register(struct cx23885_tsport *port)
1024 } 1172 }
1025 1173
1026 return ret; 1174 return ret;
1175
1176frontend_detach:
1177 port->gate_ctrl = NULL;
1178 videobuf_dvb_dealloc_frontends(&port->frontends);
1179 return -EINVAL;
1027} 1180}
1028 1181
1029int cx23885_dvb_register(struct cx23885_tsport *port) 1182int cx23885_dvb_register(struct cx23885_tsport *port)
@@ -1100,8 +1253,13 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
1100 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1253 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1101 netup_ci_exit(port); 1254 netup_ci_exit(port);
1102 break; 1255 break;
1256 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1257 altera_ci_release(port->dev, port->nr);
1258 break;
1103 } 1259 }
1104 1260
1261 port->gate_ctrl = NULL;
1262
1105 return 0; 1263 return 0;
1106} 1264}
1107 1265
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 62e41ab65810..8b77feabc594 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -85,6 +85,7 @@
85#define CX23885_BOARD_MYGICA_X8558PRO 27 85#define CX23885_BOARD_MYGICA_X8558PRO 27
86#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28 86#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
87#define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29 87#define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29
88#define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30
88 89
89#define GPIO_0 0x00000001 90#define GPIO_0 0x00000001
90#define GPIO_1 0x00000002 91#define GPIO_1 0x00000002
@@ -220,7 +221,7 @@ struct cx23885_board {
220 */ 221 */
221 u32 clk_freq; 222 u32 clk_freq;
222 struct cx23885_input input[MAX_CX23885_INPUT]; 223 struct cx23885_input input[MAX_CX23885_INPUT];
223 int cimax; /* for NetUP */ 224 int ci_type; /* for NetUP */
224}; 225};
225 226
226struct cx23885_subid { 227struct cx23885_subid {
@@ -303,6 +304,7 @@ struct cx23885_tsport {
303 304
304 /* Allow a single tsport to have multiple frontends */ 305 /* Allow a single tsport to have multiple frontends */
305 u32 num_frontends; 306 u32 num_frontends;
307 void (*gate_ctrl)(struct cx23885_tsport *port, int open);
306 void *port_priv; 308 void *port_priv;
307}; 309};
308 310