diff options
| author | Igor M. Liplianin <liplianin@me.by> | 2011-01-25 15:04:00 -0500 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:32:18 -0400 |
| commit | 78db854757aa4110f9c6873d1529b851037a3405 (patch) | |
| tree | 52aa3b669d488d117024a970ef67bd313761335d | |
| parent | e80edce1abfabf637edc68e8dd13ef0af6e46cdf (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.h | 4 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-cards.c | 103 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-core.c | 22 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885-dvb.c | 172 | ||||
| -rw-r--r-- | drivers/media/video/cx23885/cx23885.h | 4 |
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 @@ | |||
| 1 | config VIDEO_CX23885 | 1 | config 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 | ||
| 33 | static unsigned int enable_885_ir; | 37 | static 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 | }; |
| 333 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 350 | const 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 | }; |
| 525 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 546 | const 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 | ||
| 1167 | int 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 | |||
| 1116 | void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) | 1192 | void 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 | ||
| 62 | static unsigned int debug; | 64 | static 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 | ||
| 113 | static 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 | |||
| 111 | static struct videobuf_queue_ops dvb_qops = { | 129 | static 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 | }; |
| 591 | static 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 | |||
| 609 | static 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 | |||
| 619 | int 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 | ||
| 574 | static int dvb_register(struct cx23885_tsport *port) | 663 | static 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 | |||
| 1176 | frontend_detach: | ||
| 1177 | port->gate_ctrl = NULL; | ||
| 1178 | videobuf_dvb_dealloc_frontends(&port->frontends); | ||
| 1179 | return -EINVAL; | ||
| 1027 | } | 1180 | } |
| 1028 | 1181 | ||
| 1029 | int cx23885_dvb_register(struct cx23885_tsport *port) | 1182 | int 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 | ||
| 226 | struct cx23885_subid { | 227 | struct 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 | ||
