aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-03-27 22:18:30 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:07:55 -0400
commit99e09eac25f752b25f65392da7bd747b77040fea (patch)
tree0d60bc8f498aa0d43b92f334e30771131b04dd63 /drivers/media/video/cx88
parenta2401d9eed955d90e682b911c343d7fb4ad22436 (diff)
V4L/DVB (7448): Add support for Kworld ATSC 120
This board has a s5h1409 demod, plus a xc30x8 tuner (probably, xc3018). This patch adds proper support for radio, video, s-video, composite and ATSC. However, support for radio and video depends on having s5h1409 i2c gate open, otherwise, xc30x8 chip won't be visible. For a better support, some rework is needed on cx88 driver, to allow adding xc30x8 to i2c bus without sending i2c 0 byte reading to 0xc2 address. Thanks to Vanessa Ezekowitz <vanessaezekowitz@gmail.com> for helping to figure out the proper parameters for s5h1409 and the GPIO pins used by each configuration. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/cx88')
-rw-r--r--drivers/media/video/cx88/cx88-cards.c110
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c30
-rw-r--r--drivers/media/video/cx88/cx88.h3
3 files changed, 113 insertions, 30 deletions
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 6b83e3457b70..70505b4e5b46 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -27,7 +27,6 @@
27 27
28#include "cx88.h" 28#include "cx88.h"
29#include "tea5767.h" 29#include "tea5767.h"
30#include "tuner-xc2028.h"
31 30
32static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; 31static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
33static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; 32static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
@@ -1614,6 +1613,45 @@ static const struct cx88_board cx88_boards[] = {
1614 .gpio2 = 0x0cfb, 1613 .gpio2 = 0x0cfb,
1615 }, 1614 },
1616 }, 1615 },
1616 /* Both radio, analog and ATSC work with this board.
1617 However, for analog to work, s5h1409 gate should be open,
1618 otherwise, tuner-xc3028 won't be detected.
1619 A proper fix require using the newer i2c methods to add
1620 tuner-xc3028 without doing an i2c probe.
1621 */
1622 [CX88_BOARD_KWORLD_ATSC_120] = {
1623 .name = "Kworld PlusTV HD PCI 120 (ATSC 120)",
1624 .tuner_type = TUNER_XC2028,
1625 .radio_type = UNSET,
1626 .tuner_addr = ADDR_UNSET,
1627 .radio_addr = ADDR_UNSET,
1628 .input = { {
1629 .type = CX88_VMUX_TELEVISION,
1630 .vmux = 0,
1631 .gpio0 = 0x000000ff,
1632 .gpio1 = 0x0000f35d,
1633 .gpio2 = 0x00000000,
1634 }, {
1635 .type = CX88_VMUX_COMPOSITE1,
1636 .vmux = 1,
1637 .gpio0 = 0x000000ff,
1638 .gpio1 = 0x0000f37e,
1639 .gpio2 = 0x00000000,
1640 }, {
1641 .type = CX88_VMUX_SVIDEO,
1642 .vmux = 2,
1643 .gpio0 = 0x000000ff,
1644 .gpio1 = 0x0000f37e,
1645 .gpio2 = 0x00000000,
1646 } },
1647 .radio = {
1648 .type = CX88_RADIO,
1649 .gpio0 = 0x000000ff,
1650 .gpio1 = 0x0000f35d,
1651 .gpio2 = 0x00000000,
1652 },
1653 .mpeg = CX88_MPEG_DVB,
1654 },
1617}; 1655};
1618 1656
1619/* ------------------------------------------------------------------ */ 1657/* ------------------------------------------------------------------ */
@@ -1959,6 +1997,10 @@ static const struct cx88_subid cx88_subids[] = {
1959 .subvendor = 0x1554, 1997 .subvendor = 0x1554,
1960 .subdevice = 0x4935, 1998 .subdevice = 0x4935,
1961 .card = CX88_BOARD_PROLINK_PV_8000GT, 1999 .card = CX88_BOARD_PROLINK_PV_8000GT,
2000 }, {
2001 .subvendor = 0x17de,
2002 .subdevice = 0x08c1,
2003 .card = CX88_BOARD_KWORLD_ATSC_120,
1962 }, 2004 },
1963}; 2005};
1964 2006
@@ -2200,6 +2242,7 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
2200 case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: 2242 case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
2201 case CX88_BOARD_POWERCOLOR_REAL_ANGEL: 2243 case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
2202 case CX88_BOARD_GENIATECH_X8000_MT: 2244 case CX88_BOARD_GENIATECH_X8000_MT:
2245 case CX88_BOARD_KWORLD_ATSC_120:
2203 return cx88_xc3028_geniatech_tuner_callback(core, 2246 return cx88_xc3028_geniatech_tuner_callback(core,
2204 command, arg); 2247 command, arg);
2205 case CX88_BOARD_PROLINK_PV_8000GT: 2248 case CX88_BOARD_PROLINK_PV_8000GT:
@@ -2363,6 +2406,40 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
2363 } 2406 }
2364} 2407}
2365 2408
2409/*
2410 * Sets board-dependent xc3028 configuration
2411 */
2412void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
2413{
2414 memset(ctl, 0, sizeof(*ctl));
2415
2416 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2417 ctl->max_len = 64;
2418
2419 switch (core->boardnr) {
2420 case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
2421 /* Doesn't work with firmware version 2.7 */
2422 ctl->fname = "xc3028-v25.fw";
2423 break;
2424 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2425 ctl->scode_table = XC3028_FE_ZARLINK456;
2426 break;
2427 case CX88_BOARD_KWORLD_ATSC_120:
2428 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2429 ctl->demod = XC3028_FE_OREN538;
2430 break;
2431 case CX88_BOARD_PROLINK_PV_8000GT:
2432 /*
2433 * This board uses non-MTS firmware
2434 */
2435 break;
2436 default:
2437 ctl->demod = XC3028_FE_OREN538;
2438 ctl->mts = 1;
2439 }
2440}
2441EXPORT_SYMBOL_GPL(cx88_setup_xc3028);
2442
2366static void cx88_card_setup(struct cx88_core *core) 2443static void cx88_card_setup(struct cx88_core *core)
2367{ 2444{
2368 static u8 eeprom[256]; 2445 static u8 eeprom[256];
@@ -2481,36 +2558,13 @@ static void cx88_card_setup(struct cx88_core *core)
2481 struct v4l2_priv_tun_config xc2028_cfg; 2558 struct v4l2_priv_tun_config xc2028_cfg;
2482 struct xc2028_ctrl ctl; 2559 struct xc2028_ctrl ctl;
2483 2560
2484 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg)); 2561 /* Fills device-dependent initialization parameters */
2485 memset(&ctl, 0, sizeof(ctl)); 2562 cx88_setup_xc3028(core, &ctl);
2486
2487 ctl.fname = XC2028_DEFAULT_FIRMWARE;
2488 ctl.max_len = 64;
2489
2490 switch (core->boardnr) {
2491 case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
2492 /* Doesn't work with firmware version 2.7 */
2493 ctl.fname = "xc3028-v25.fw";
2494 break;
2495 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2496 ctl.scode_table = XC3028_FE_ZARLINK456;
2497 break;
2498 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2499 ctl.demod = XC3028_FE_OREN538;
2500 break;
2501 case CX88_BOARD_PROLINK_PV_8000GT:
2502 /*
2503 * This board uses non-MTS firmware
2504 */
2505 break;
2506 default:
2507 ctl.demod = XC3028_FE_OREN538;
2508 ctl.mts = 1;
2509 }
2510 2563
2564 /* Sends parameters to xc2028/3028 tuner */
2565 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
2511 xc2028_cfg.tuner = TUNER_XC2028; 2566 xc2028_cfg.tuner = TUNER_XC2028;
2512 xc2028_cfg.priv = &ctl; 2567 xc2028_cfg.priv = &ctl;
2513
2514 info_printk(core, "Asking xc2028/3028 to load firmware %s\n", 2568 info_printk(core, "Asking xc2028/3028 to load firmware %s\n",
2515 ctl.fname); 2569 ctl.fname);
2516 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg); 2570 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 8dca20b944dd..13cc395ca656 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -45,7 +45,6 @@
45#include "nxt200x.h" 45#include "nxt200x.h"
46#include "cx24123.h" 46#include "cx24123.h"
47#include "isl6421.h" 47#include "isl6421.h"
48#include "tuner-xc2028.h"
49#include "tuner-xc2028-types.h" 48#include "tuner-xc2028-types.h"
50#include "tuner-simple.h" 49#include "tuner-simple.h"
51#include "tda9887.h" 50#include "tda9887.h"
@@ -443,6 +442,16 @@ static struct s5h1409_config dvico_hdtv5_pci_nano_config = {
443 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, 442 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
444}; 443};
445 444
445static struct s5h1409_config kworld_atsc_120_config = {
446 .demod_address = 0x32 >> 1,
447 .qam_if = 44000,
448 .output_mode = S5H1409_SERIAL_OUTPUT,
449 .gpio = S5H1409_GPIO_OFF,
450 .inversion = S5H1409_INVERSION_OFF,
451 .status_mode = S5H1409_DEMODLOCKING,
452 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
453};
454
446static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { 455static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
447 .i2c_address = 0x64, 456 .i2c_address = 0x64,
448 .if_khz = 5380, 457 .if_khz = 5380,
@@ -457,9 +466,12 @@ static struct zl10353_config cx88_geniatech_x8000_mt = {
457static int attach_xc3028(u8 addr, struct cx8802_dev *dev) 466static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
458{ 467{
459 struct dvb_frontend *fe; 468 struct dvb_frontend *fe;
469 struct xc2028_ctrl ctl;
460 struct xc2028_config cfg = { 470 struct xc2028_config cfg = {
461 .i2c_adap = &dev->core->i2c_adap, 471 .i2c_adap = &dev->core->i2c_adap,
462 .i2c_addr = addr, 472 .i2c_addr = addr,
473 .ctrl = &ctl,
474 .callback = cx88_tuner_callback,
463 }; 475 };
464 476
465 if (!dev->dvb.frontend) { 477 if (!dev->dvb.frontend) {
@@ -469,6 +481,13 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
469 return -EINVAL; 481 return -EINVAL;
470 } 482 }
471 483
484 /*
485 * Some xc3028 devices may be hidden by an I2C gate. This is known
486 * to happen with some s5h1409-based devices.
487 * Now that I2C gate is open, sets up xc3028 configuration
488 */
489 cx88_setup_xc3028(dev->core, &ctl);
490
472 fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); 491 fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
473 if (!fe) { 492 if (!fe) {
474 printk(KERN_ERR "%s/2: xc3028 attach failed\n", 493 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
@@ -810,7 +829,7 @@ static int dvb_register(struct cx8802_dev *dev)
810 return -EINVAL; 829 return -EINVAL;
811 break; 830 break;
812 case CX88_BOARD_GENIATECH_X8000_MT: 831 case CX88_BOARD_GENIATECH_X8000_MT:
813 dev->ts_gen_cntrl = 0x00; 832 dev->ts_gen_cntrl = 0x00;
814 833
815 dev->dvb.frontend = dvb_attach(zl10353_attach, 834 dev->dvb.frontend = dvb_attach(zl10353_attach,
816 &cx88_geniatech_x8000_mt, 835 &cx88_geniatech_x8000_mt,
@@ -818,6 +837,13 @@ static int dvb_register(struct cx8802_dev *dev)
818 if (attach_xc3028(0x61, dev) < 0) 837 if (attach_xc3028(0x61, dev) < 0)
819 return -EINVAL; 838 return -EINVAL;
820 break; 839 break;
840 case CX88_BOARD_KWORLD_ATSC_120:
841 dev->dvb.frontend = dvb_attach(s5h1409_attach,
842 &kworld_atsc_120_config,
843 &dev->core->i2c_adap);
844 if (attach_xc3028(0x61, dev) < 0)
845 return -EINVAL;
846 break;
821 default: 847 default:
822 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 848 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
823 dev->core->name); 849 dev->core->name);
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index c0f4912793e9..d17ca71c5d95 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -37,6 +37,7 @@
37 37
38#include "btcx-risc.h" 38#include "btcx-risc.h"
39#include "cx88-reg.h" 39#include "cx88-reg.h"
40#include "tuner-xc2028.h"
40 41
41#include <linux/version.h> 42#include <linux/version.h>
42#include <linux/mutex.h> 43#include <linux/mutex.h>
@@ -219,6 +220,7 @@ extern struct sram_channel cx88_sram_channels[];
219#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO 64 220#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO 64
220#define CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD 65 221#define CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD 65
221#define CX88_BOARD_PROLINK_PV_8000GT 66 222#define CX88_BOARD_PROLINK_PV_8000GT 66
223#define CX88_BOARD_KWORLD_ATSC_120 67
222 224
223enum cx88_itype { 225enum cx88_itype {
224 CX88_VMUX_COMPOSITE1 = 1, 226 CX88_VMUX_COMPOSITE1 = 1,
@@ -603,6 +605,7 @@ extern int cx88_tuner_callback(void *dev, int command, int arg);
603extern int cx88_get_resources(const struct cx88_core *core, 605extern int cx88_get_resources(const struct cx88_core *core,
604 struct pci_dev *pci); 606 struct pci_dev *pci);
605extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); 607extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr);
608extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl);
606 609
607/* ----------------------------------------------------------- */ 610/* ----------------------------------------------------------- */
608/* cx88-tvaudio.c */ 611/* cx88-tvaudio.c */