aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-cards.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-24 14:21:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-24 14:21:08 -0400
commitc328d54cd4ad120d76284e46dcca6c6cf996154a (patch)
tree104c023be66faa5fce6e0a56c0a6d13c62fd21e5 /drivers/media/video/cx88/cx88-cards.c
parent346ad4b7fe392571f19314f153db9151dbc1d82b (diff)
parentb0166ab3a6ae6d7af8d9a21a7836154963c69a11 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (452 commits) V4L/DVB (7731): tuner-xc2028: fix signal strength calculus V4L/DVB (7730): tuner-xc2028: Fix SCODE load for MTS firmwares V4L/DVB (7729): Fix VIDIOCGAP corruption in ivtv V4L/DVB (7728): tea5761: bugzilla #10462: tea5761 autodetection code were broken V4L/DVB (7726): cx23885: Enable cx23417 support on the HVR1800 V4L/DVB (7725): cx23885: Add generic cx23417 hardware encoder support V4L/DVB (7723): pvrusb2: Clean up input selection list generation in V4L interface V4L/DVB (7722): pvrusb2: Implement FM radio support for Gotview USB2.0 DVD 2 V4L/DVB (7721): pvrusb2: Restructure cx23416 firmware loading to have a common exit point V4L/DVB (7720): pvrusb2: Fix bad error code on cx23416 firmware load failure V4L/DVB (7719): pvrusb2: Implement input selection enforcement V4L/DVB (7718): pvrusb2-dvb: update Kbuild selections V4L/DVB (7717): pvrusb2-dvb: add DVB-T support for Hauppauge pvrusb2 model 73xxx V4L/DVB (7716): pvrusb2: clean up global functions V4L/DVB (7715): pvrusb2: Clean out all use of __FUNCTION__ V4L/DVB (7714): pvrusb2: Fix hang on module removal V4L/DVB (7713): pvrusb2: Implement cleaner DVB kernel thread shutdown V4L/DVB (7712): pvrusb2: Close connect/disconnect race V4L/DVB (7711): pvrusb2: Fix race on module unload V4L/DVB (7710): pvrusb2: Implement critical digital streaming quirk for onair devices ...
Diffstat (limited to 'drivers/media/video/cx88/cx88-cards.c')
-rw-r--r--drivers/media/video/cx88/cx88-cards.c585
1 files changed, 542 insertions, 43 deletions
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 8c9a8adf52de..620159d05506 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -44,6 +44,16 @@ static unsigned int latency = UNSET;
44module_param(latency,int,0444); 44module_param(latency,int,0444);
45MODULE_PARM_DESC(latency,"pci latency timer"); 45MODULE_PARM_DESC(latency,"pci latency timer");
46 46
47#define info_printk(core, fmt, arg...) \
48 printk(KERN_INFO "%s: " fmt, core->name , ## arg)
49
50#define warn_printk(core, fmt, arg...) \
51 printk(KERN_WARNING "%s: " fmt, core->name , ## arg)
52
53#define err_printk(core, fmt, arg...) \
54 printk(KERN_ERR "%s: " fmt, core->name , ## arg)
55
56
47/* ------------------------------------------------------------------ */ 57/* ------------------------------------------------------------------ */
48/* board config info */ 58/* board config info */
49 59
@@ -1354,6 +1364,10 @@ static const struct cx88_board cx88_boards[] = {
1354 }}, 1364 }},
1355 /* fixme: Add radio support */ 1365 /* fixme: Add radio support */
1356 .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, 1366 .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD,
1367 .radio = {
1368 .type = CX88_RADIO,
1369 .gpio0 = 0xe780,
1370 },
1357 }, 1371 },
1358 [CX88_BOARD_ADSTECH_PTV_390] = { 1372 [CX88_BOARD_ADSTECH_PTV_390] = {
1359 .name = "ADS Tech Instant Video PCI", 1373 .name = "ADS Tech Instant Video PCI",
@@ -1401,6 +1415,245 @@ static const struct cx88_board cx88_boards[] = {
1401 }}, 1415 }},
1402 .mpeg = CX88_MPEG_DVB, 1416 .mpeg = CX88_MPEG_DVB,
1403 }, 1417 },
1418 [CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO] = {
1419 .name = "DViCO FusionHDTV 5 PCI nano",
1420 /* xc3008 tuner, digital only for now */
1421 .tuner_type = TUNER_ABSENT,
1422 .radio_type = UNSET,
1423 .tuner_addr = ADDR_UNSET,
1424 .radio_addr = ADDR_UNSET,
1425 .input = {{
1426 .type = CX88_VMUX_TELEVISION,
1427 .vmux = 0,
1428 .gpio0 = 0x000027df, /* Unconfirmed */
1429 }, {
1430 .type = CX88_VMUX_COMPOSITE1,
1431 .vmux = 1,
1432 .gpio0 = 0x000027df, /* Unconfirmed */
1433 .audioroute = 1,
1434 }, {
1435 .type = CX88_VMUX_SVIDEO,
1436 .vmux = 2,
1437 .gpio0 = 0x000027df, /* Unconfirmed */
1438 .audioroute = 1,
1439 } },
1440 .mpeg = CX88_MPEG_DVB,
1441 },
1442 [CX88_BOARD_PINNACLE_HYBRID_PCTV] = {
1443 .name = "Pinnacle Hybrid PCTV",
1444 .tuner_type = TUNER_XC2028,
1445 .tuner_addr = 0x61,
1446 .input = { {
1447 .type = CX88_VMUX_TELEVISION,
1448 .vmux = 0,
1449 }, {
1450 .type = CX88_VMUX_COMPOSITE1,
1451 .vmux = 1,
1452 }, {
1453 .type = CX88_VMUX_SVIDEO,
1454 .vmux = 2,
1455 } },
1456 .radio = {
1457 .type = CX88_RADIO,
1458 .gpio0 = 0x004ff,
1459 .gpio1 = 0x010ff,
1460 .gpio2 = 0x0ff,
1461 },
1462 },
1463 [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = {
1464 .name = "Winfast TV2000 XP Global",
1465 .tuner_type = TUNER_XC2028,
1466 .tuner_addr = 0x61,
1467 .input = { {
1468 .type = CX88_VMUX_TELEVISION,
1469 .vmux = 0,
1470 .gpio0 = 0x0400, /* pin 2:mute = 0 (off?) */
1471 .gpio1 = 0x0000,
1472 .gpio2 = 0x0800, /* pin 19:audio = 0 (tv) */
1473
1474 }, {
1475 .type = CX88_VMUX_COMPOSITE1,
1476 .vmux = 1,
1477 .gpio0 = 0x0400, /* probably? or 0x0404 to turn mute on */
1478 .gpio1 = 0x0000,
1479 .gpio2 = 0x0808, /* pin 19:audio = 1 (line) */
1480
1481 }, {
1482 .type = CX88_VMUX_SVIDEO,
1483 .vmux = 2,
1484 } },
1485 .radio = {
1486 .type = CX88_RADIO,
1487 .gpio0 = 0x004ff,
1488 .gpio1 = 0x010ff,
1489 .gpio2 = 0x0ff,
1490 },
1491 },
1492 [CX88_BOARD_POWERCOLOR_REAL_ANGEL] = {
1493 .name = "PowerColor Real Angel 330",
1494 .tuner_type = TUNER_XC2028,
1495 .tuner_addr = 0x61,
1496 .input = { {
1497 .type = CX88_VMUX_TELEVISION,
1498 .vmux = 0,
1499 .gpio0 = 0x00ff,
1500 .gpio1 = 0xf35d,
1501 .gpio3 = 0x0000,
1502 }, {
1503 .type = CX88_VMUX_COMPOSITE1,
1504 .vmux = 1,
1505 .gpio0 = 0x00ff,
1506 .gpio1 = 0xf37d,
1507 .gpio3 = 0x0000,
1508 }, {
1509 .type = CX88_VMUX_SVIDEO,
1510 .vmux = 2,
1511 .gpio0 = 0x000ff,
1512 .gpio1 = 0x0f37d,
1513 .gpio3 = 0x00000,
1514 } },
1515 .radio = {
1516 .type = CX88_RADIO,
1517 .gpio0 = 0x000ff,
1518 .gpio1 = 0x0f35d,
1519 .gpio3 = 0x00000,
1520 },
1521 },
1522 [CX88_BOARD_GENIATECH_X8000_MT] = {
1523 /* Also PowerColor Real Angel 330 and Geniatech X800 OEM */
1524 .name = "Geniatech X8000-MT DVBT",
1525 .tuner_type = TUNER_XC2028,
1526 .tuner_addr = 0x61,
1527 .input = { {
1528 .type = CX88_VMUX_TELEVISION,
1529 .vmux = 0,
1530 .gpio0 = 0x00000000,
1531 .gpio1 = 0x00e3e341,
1532 .gpio2 = 0x00000000,
1533 .gpio3 = 0x00000000,
1534 }, {
1535 .type = CX88_VMUX_COMPOSITE1,
1536 .vmux = 1,
1537 .gpio0 = 0x00000000,
1538 .gpio1 = 0x00e3e361,
1539 .gpio2 = 0x00000000,
1540 .gpio3 = 0x00000000,
1541 }, {
1542 .type = CX88_VMUX_SVIDEO,
1543 .vmux = 2,
1544 .gpio0 = 0x00000000,
1545 .gpio1 = 0x00e3e361,
1546 .gpio2 = 0x00000000,
1547 .gpio3 = 0x00000000,
1548 } },
1549 .radio = {
1550 .type = CX88_RADIO,
1551 .gpio0 = 0x00000000,
1552 .gpio1 = 0x00e3e341,
1553 .gpio2 = 0x00000000,
1554 .gpio3 = 0x00000000,
1555 },
1556 .mpeg = CX88_MPEG_DVB,
1557 },
1558 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO] = {
1559 .name = "DViCO FusionHDTV DVB-T PRO",
1560 .tuner_type = TUNER_ABSENT, /* XXX: Has XC3028 */
1561 .radio_type = UNSET,
1562 .tuner_addr = ADDR_UNSET,
1563 .radio_addr = ADDR_UNSET,
1564 .input = { {
1565 .type = CX88_VMUX_COMPOSITE1,
1566 .vmux = 1,
1567 .gpio0 = 0x000067df,
1568 }, {
1569 .type = CX88_VMUX_SVIDEO,
1570 .vmux = 2,
1571 .gpio0 = 0x000067df,
1572 } },
1573 .mpeg = CX88_MPEG_DVB,
1574 },
1575 [CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD] = {
1576 .name = "DViCO FusionHDTV 7 Gold",
1577 .tuner_type = TUNER_XC5000,
1578 .radio_type = UNSET,
1579 .tuner_addr = ADDR_UNSET,
1580 .radio_addr = ADDR_UNSET,
1581 .input = {{
1582 .type = CX88_VMUX_TELEVISION,
1583 .vmux = 0,
1584 .gpio0 = 0x10df,
1585 },{
1586 .type = CX88_VMUX_COMPOSITE1,
1587 .vmux = 1,
1588 .gpio0 = 0x16d9,
1589 },{
1590 .type = CX88_VMUX_SVIDEO,
1591 .vmux = 2,
1592 .gpio0 = 0x16d9,
1593 }},
1594 },
1595 [CX88_BOARD_PROLINK_PV_8000GT] = {
1596 .name = "Prolink Pixelview MPEG 8000GT",
1597 .tuner_type = TUNER_XC2028,
1598 .tuner_addr = 0x61,
1599 .input = { {
1600 .type = CX88_VMUX_TELEVISION,
1601 .vmux = 0,
1602 .gpio0 = 0x0ff,
1603 .gpio2 = 0x0cfb,
1604 }, {
1605 .type = CX88_VMUX_COMPOSITE1,
1606 .vmux = 1,
1607 .gpio2 = 0x0cfb,
1608 }, {
1609 .type = CX88_VMUX_SVIDEO,
1610 .vmux = 2,
1611 .gpio2 = 0x0cfb,
1612 } },
1613 .radio = {
1614 .type = CX88_RADIO,
1615 .gpio2 = 0x0cfb,
1616 },
1617 },
1618 /* Both radio, analog and ATSC work with this board.
1619 However, for analog to work, s5h1409 gate should be open,
1620 otherwise, tuner-xc3028 won't be detected.
1621 A proper fix require using the newer i2c methods to add
1622 tuner-xc3028 without doing an i2c probe.
1623 */
1624 [CX88_BOARD_KWORLD_ATSC_120] = {
1625 .name = "Kworld PlusTV HD PCI 120 (ATSC 120)",
1626 .tuner_type = TUNER_XC2028,
1627 .radio_type = UNSET,
1628 .tuner_addr = ADDR_UNSET,
1629 .radio_addr = ADDR_UNSET,
1630 .input = { {
1631 .type = CX88_VMUX_TELEVISION,
1632 .vmux = 0,
1633 .gpio0 = 0x000000ff,
1634 .gpio1 = 0x0000f35d,
1635 .gpio2 = 0x00000000,
1636 }, {
1637 .type = CX88_VMUX_COMPOSITE1,
1638 .vmux = 1,
1639 .gpio0 = 0x000000ff,
1640 .gpio1 = 0x0000f37e,
1641 .gpio2 = 0x00000000,
1642 }, {
1643 .type = CX88_VMUX_SVIDEO,
1644 .vmux = 2,
1645 .gpio0 = 0x000000ff,
1646 .gpio1 = 0x0000f37e,
1647 .gpio2 = 0x00000000,
1648 } },
1649 .radio = {
1650 .type = CX88_RADIO,
1651 .gpio0 = 0x000000ff,
1652 .gpio1 = 0x0000f35d,
1653 .gpio2 = 0x00000000,
1654 },
1655 .mpeg = CX88_MPEG_DVB,
1656 },
1404}; 1657};
1405 1658
1406/* ------------------------------------------------------------------ */ 1659/* ------------------------------------------------------------------ */
@@ -1605,7 +1858,11 @@ static const struct cx88_subid cx88_subids[] = {
1605 .subdevice = 0xdb11, 1858 .subdevice = 0xdb11,
1606 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, 1859 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
1607 /* Re-branded DViCO: UltraView DVB-T Plus */ 1860 /* Re-branded DViCO: UltraView DVB-T Plus */
1608 },{ 1861 }, {
1862 .subvendor = 0x18ac,
1863 .subdevice = 0xdb30,
1864 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO,
1865 }, {
1609 .subvendor = 0x17de, 1866 .subvendor = 0x17de,
1610 .subdevice = 0x0840, 1867 .subdevice = 0x0840,
1611 .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, 1868 .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
@@ -1714,6 +1971,38 @@ static const struct cx88_subid cx88_subids[] = {
1714 .subvendor = 0x11bd, 1971 .subvendor = 0x11bd,
1715 .subdevice = 0x0051, 1972 .subdevice = 0x0051,
1716 .card = CX88_BOARD_PINNACLE_PCTV_HD_800i, 1973 .card = CX88_BOARD_PINNACLE_PCTV_HD_800i,
1974 }, {
1975 .subvendor = 0x18ac,
1976 .subdevice = 0xd530,
1977 .card = CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO,
1978 }, {
1979 .subvendor = 0x12ab,
1980 .subdevice = 0x1788,
1981 .card = CX88_BOARD_PINNACLE_HYBRID_PCTV,
1982 }, {
1983 .subvendor = 0x14f1,
1984 .subdevice = 0xea3d,
1985 .card = CX88_BOARD_POWERCOLOR_REAL_ANGEL,
1986 }, {
1987 .subvendor = 0x107d,
1988 .subdevice = 0x6f18,
1989 .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
1990 }, {
1991 .subvendor = 0x14f1,
1992 .subdevice = 0x8852,
1993 .card = CX88_BOARD_GENIATECH_X8000_MT,
1994 }, {
1995 .subvendor = 0x18ac,
1996 .subdevice = 0xd610,
1997 .card = CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD,
1998 }, {
1999 .subvendor = 0x1554,
2000 .subdevice = 0x4935,
2001 .card = CX88_BOARD_PROLINK_PV_8000GT,
2002 }, {
2003 .subvendor = 0x17de,
2004 .subdevice = 0x08c1,
2005 .card = CX88_BOARD_KWORLD_ATSC_120,
1717 }, 2006 },
1718}; 2007};
1719 2008
@@ -1731,17 +2020,16 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
1731 if (eeprom_data[4] != 0x7d || 2020 if (eeprom_data[4] != 0x7d ||
1732 eeprom_data[5] != 0x10 || 2021 eeprom_data[5] != 0x10 ||
1733 eeprom_data[7] != 0x66) { 2022 eeprom_data[7] != 0x66) {
1734 printk(KERN_WARNING "%s: Leadtek eeprom invalid.\n", 2023 warn_printk(core, "Leadtek eeprom invalid.\n");
1735 core->name);
1736 return; 2024 return;
1737 } 2025 }
1738 2026
1739 core->board.tuner_type = (eeprom_data[6] == 0x13) ? 2027 core->board.tuner_type = (eeprom_data[6] == 0x13) ?
1740 TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3; 2028 TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3;
1741 2029
1742 printk(KERN_INFO "%s: Leadtek Winfast 2000XP Expert config: " 2030 info_printk(core, "Leadtek Winfast 2000XP Expert config: "
1743 "tuner=%d, eeprom[0]=0x%02x\n", 2031 "tuner=%d, eeprom[0]=0x%02x\n",
1744 core->name, core->board.tuner_type, eeprom_data[0]); 2032 core->board.tuner_type, eeprom_data[0]);
1745} 2033}
1746 2034
1747static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) 2035static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
@@ -1785,13 +2073,12 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
1785 /* known */ 2073 /* known */
1786 break; 2074 break;
1787 default: 2075 default:
1788 printk("%s: warning: unknown hauppauge model #%d\n", 2076 warn_printk(core, "warning: unknown hauppauge model #%d\n",
1789 core->name, tv.model); 2077 tv.model);
1790 break; 2078 break;
1791 } 2079 }
1792 2080
1793 printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", 2081 info_printk(core, "hauppauge eeprom: model=%d\n", tv.model);
1794 core->name, tv.model);
1795} 2082}
1796 2083
1797/* ----------------------------------------------------------------------- */ 2084/* ----------------------------------------------------------------------- */
@@ -1837,8 +2124,7 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
1837 char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner)) 2124 char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner))
1838 ? gdi_tuner[eeprom_data[0x0d]].name : NULL; 2125 ? gdi_tuner[eeprom_data[0x0d]].name : NULL;
1839 2126
1840 printk(KERN_INFO "%s: GDI: tuner=%s\n", core->name, 2127 info_printk(core, "GDI: tuner=%s\n", name ? name : "unknown");
1841 name ? name : "unknown");
1842 if (NULL == name) 2128 if (NULL == name)
1843 return; 2129 return;
1844 core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id; 2130 core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id;
@@ -1846,6 +2132,75 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
1846 CX88_RADIO : 0; 2132 CX88_RADIO : 0;
1847} 2133}
1848 2134
2135/* ------------------------------------------------------------------- */
2136/* some Divco specific stuff */
2137static int cx88_dvico_xc2028_callback(struct cx88_core *core,
2138 int command, int arg)
2139{
2140 switch (command) {
2141 case XC2028_TUNER_RESET:
2142 cx_write(MO_GP0_IO, 0x101000);
2143 mdelay(5);
2144 cx_set(MO_GP0_IO, 0x101010);
2145 break;
2146 default:
2147 return -EINVAL;
2148 }
2149
2150 return 0;
2151}
2152
2153
2154/* ----------------------------------------------------------------------- */
2155/* some Geniatech specific stuff */
2156
2157static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core,
2158 int command, int mode)
2159{
2160 switch (command) {
2161 case XC2028_TUNER_RESET:
2162 switch (INPUT(core->input).type) {
2163 case CX88_RADIO:
2164 break;
2165 case CX88_VMUX_DVB:
2166 cx_write(MO_GP1_IO, 0x030302);
2167 mdelay(50);
2168 break;
2169 default:
2170 cx_write(MO_GP1_IO, 0x030301);
2171 mdelay(50);
2172 }
2173 cx_write(MO_GP1_IO, 0x101010);
2174 mdelay(50);
2175 cx_write(MO_GP1_IO, 0x101000);
2176 mdelay(50);
2177 cx_write(MO_GP1_IO, 0x101010);
2178 mdelay(50);
2179 return 0;
2180 }
2181 return -EINVAL;
2182}
2183
2184/* ------------------------------------------------------------------- */
2185/* some Divco specific stuff */
2186static int cx88_pv_8000gt_callback(struct cx88_core *core,
2187 int command, int arg)
2188{
2189 switch (command) {
2190 case XC2028_TUNER_RESET:
2191 cx_write(MO_GP2_IO, 0xcf7);
2192 mdelay(50);
2193 cx_write(MO_GP2_IO, 0xef5);
2194 mdelay(50);
2195 cx_write(MO_GP2_IO, 0xcf7);
2196 break;
2197 default:
2198 return -EINVAL;
2199 }
2200
2201 return 0;
2202}
2203
1849/* ----------------------------------------------------------------------- */ 2204/* ----------------------------------------------------------------------- */
1850/* some DViCO specific stuff */ 2205/* some DViCO specific stuff */
1851 2206
@@ -1874,32 +2229,85 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
1874 msg.len = (i != 12 ? 5 : 2); 2229 msg.len = (i != 12 ? 5 : 2);
1875 err = i2c_transfer(&core->i2c_adap, &msg, 1); 2230 err = i2c_transfer(&core->i2c_adap, &msg, 1);
1876 if (err != 1) { 2231 if (err != 1) {
1877 printk("dvico_fusionhdtv_hybrid_init buf %d failed (err = %d)!\n", i, err); 2232 warn_printk(core, "dvico_fusionhdtv_hybrid_init buf %d "
2233 "failed (err = %d)!\n", i, err);
1878 return; 2234 return;
1879 } 2235 }
1880 } 2236 }
1881} 2237}
1882 2238
2239static int cx88_xc2028_tuner_callback(struct cx88_core *core,
2240 int command, int arg)
2241{
2242 /* Board-specific callbacks */
2243 switch (core->boardnr) {
2244 case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
2245 case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
2246 case CX88_BOARD_GENIATECH_X8000_MT:
2247 case CX88_BOARD_KWORLD_ATSC_120:
2248 return cx88_xc3028_geniatech_tuner_callback(core,
2249 command, arg);
2250 case CX88_BOARD_PROLINK_PV_8000GT:
2251 return cx88_pv_8000gt_callback(core, command, arg);
2252 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2253 return cx88_dvico_xc2028_callback(core, command, arg);
2254 }
2255
2256 switch (command) {
2257 case XC2028_TUNER_RESET:
2258 switch (INPUT(core->input).type) {
2259 case CX88_RADIO:
2260 info_printk(core, "setting GPIO to radio!\n");
2261 cx_write(MO_GP0_IO, 0x4ff);
2262 mdelay(250);
2263 cx_write(MO_GP2_IO, 0xff);
2264 mdelay(250);
2265 break;
2266 case CX88_VMUX_DVB: /* Digital TV*/
2267 default: /* Analog TV */
2268 info_printk(core, "setting GPIO to TV!\n");
2269 break;
2270 }
2271 cx_write(MO_GP1_IO, 0x101010);
2272 mdelay(250);
2273 cx_write(MO_GP1_IO, 0x101000);
2274 mdelay(250);
2275 cx_write(MO_GP1_IO, 0x101010);
2276 mdelay(250);
2277 return 0;
2278 }
2279 return -EINVAL;
2280}
2281
1883/* ----------------------------------------------------------------------- */ 2282/* ----------------------------------------------------------------------- */
1884/* Tuner callback function. Currently only needed for the Pinnacle * 2283/* Tuner callback function. Currently only needed for the Pinnacle *
1885 * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both * 2284 * PCTV HD 800i with an xc5000 sillicon tuner. This is used for both *
1886 * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c) */ 2285 * analog tuner attach (tuner-core.c) and dvb tuner attach (cx88-dvb.c) */
1887 2286
1888int cx88_tuner_callback(void *priv, int command, int arg) 2287static int cx88_xc5000_tuner_callback(struct cx88_core *core,
2288 int command, int arg)
1889{ 2289{
1890 struct i2c_algo_bit_data *i2c_algo = priv; 2290 switch (core->boardnr) {
1891 struct cx88_core *core = i2c_algo->data;
1892
1893 switch(core->boardnr) {
1894 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 2291 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
1895 if(command == 0) { /* This is the reset command from xc5000 */ 2292 if (command == 0) { /* This is the reset command from xc5000 */
1896 /* Reset XC5000 tuner via SYS_RSTO_pin */ 2293 /* Reset XC5000 tuner via SYS_RSTO_pin */
1897 cx_write(MO_SRST_IO, 0); 2294 cx_write(MO_SRST_IO, 0);
1898 msleep(10); 2295 msleep(10);
1899 cx_write(MO_SRST_IO, 1); 2296 cx_write(MO_SRST_IO, 1);
1900 return 0; 2297 return 0;
2298 } else {
2299 err_printk(core, "xc5000: unknown tuner "
2300 "callback command.\n");
2301 return -EINVAL;
1901 } 2302 }
1902 else { 2303 break;
2304 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
2305 if (command == 0) { /* This is the reset command from xc5000 */
2306 cx_clear(MO_GP0_IO, 0x00000010);
2307 msleep(10);
2308 cx_set(MO_GP0_IO, 0x00000010);
2309 return 0;
2310 } else {
1903 printk(KERN_ERR 2311 printk(KERN_ERR
1904 "xc5000: unknown tuner callback command.\n"); 2312 "xc5000: unknown tuner callback command.\n");
1905 return -EINVAL; 2313 return -EINVAL;
@@ -1908,6 +2316,36 @@ int cx88_tuner_callback(void *priv, int command, int arg)
1908 } 2316 }
1909 return 0; /* Should never be here */ 2317 return 0; /* Should never be here */
1910} 2318}
2319
2320int cx88_tuner_callback(void *priv, int command, int arg)
2321{
2322 struct i2c_algo_bit_data *i2c_algo = priv;
2323 struct cx88_core *core;
2324
2325 if (!i2c_algo) {
2326 printk(KERN_ERR "cx88: Error - i2c private data undefined.\n");
2327 return -EINVAL;
2328 }
2329
2330 core = i2c_algo->data;
2331
2332 if (!core) {
2333 printk(KERN_ERR "cx88: Error - device struct undefined.\n");
2334 return -EINVAL;
2335 }
2336
2337 switch (core->board.tuner_type) {
2338 case TUNER_XC2028:
2339 info_printk(core, "Calling XC2028/3028 callback\n");
2340 return cx88_xc2028_tuner_callback(core, command, arg);
2341 case TUNER_XC5000:
2342 info_printk(core, "Calling XC5000 callback\n");
2343 return cx88_xc5000_tuner_callback(core, command, arg);
2344 }
2345 err_printk(core, "Error: Calling callback for tuner %d\n",
2346 core->board.tuner_type);
2347 return -EINVAL;
2348}
1911EXPORT_SYMBOL(cx88_tuner_callback); 2349EXPORT_SYMBOL(cx88_tuner_callback);
1912 2350
1913/* ----------------------------------------------------------------------- */ 2351/* ----------------------------------------------------------------------- */
@@ -1918,23 +2356,25 @@ static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
1918 2356
1919 if (0 == pci->subsystem_vendor && 2357 if (0 == pci->subsystem_vendor &&
1920 0 == pci->subsystem_device) { 2358 0 == pci->subsystem_device) {
1921 printk("%s: Your board has no valid PCI Subsystem ID and thus can't\n" 2359 printk(KERN_ERR
2360 "%s: Your board has no valid PCI Subsystem ID and thus can't\n"
1922 "%s: be autodetected. Please pass card=<n> insmod option to\n" 2361 "%s: be autodetected. Please pass card=<n> insmod option to\n"
1923 "%s: workaround that. Redirect complaints to the vendor of\n" 2362 "%s: workaround that. Redirect complaints to the vendor of\n"
1924 "%s: the TV card. Best regards,\n" 2363 "%s: the TV card. Best regards,\n"
1925 "%s: -- tux\n", 2364 "%s: -- tux\n",
1926 core->name,core->name,core->name,core->name,core->name); 2365 core->name,core->name,core->name,core->name,core->name);
1927 } else { 2366 } else {
1928 printk("%s: Your board isn't known (yet) to the driver. You can\n" 2367 printk(KERN_ERR
2368 "%s: Your board isn't known (yet) to the driver. You can\n"
1929 "%s: try to pick one of the existing card configs via\n" 2369 "%s: try to pick one of the existing card configs via\n"
1930 "%s: card=<n> insmod option. Updating to the latest\n" 2370 "%s: card=<n> insmod option. Updating to the latest\n"
1931 "%s: version might help as well.\n", 2371 "%s: version might help as well.\n",
1932 core->name,core->name,core->name,core->name); 2372 core->name,core->name,core->name,core->name);
1933 } 2373 }
1934 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", 2374 err_printk(core, "Here is a list of valid choices for the card=<n> "
1935 core->name); 2375 "insmod option:\n");
1936 for (i = 0; i < ARRAY_SIZE(cx88_boards); i++) 2376 for (i = 0; i < ARRAY_SIZE(cx88_boards); i++)
1937 printk("%s: card=%d -> %s\n", 2377 printk(KERN_ERR "%s: card=%d -> %s\n",
1938 core->name, i, cx88_boards[i].name); 2378 core->name, i, cx88_boards[i].name);
1939} 2379}
1940 2380
@@ -1951,9 +2391,57 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
1951 cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ 2391 cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
1952 udelay(1000); 2392 udelay(1000);
1953 break; 2393 break;
2394
2395 case CX88_BOARD_PROLINK_PV_8000GT:
2396 cx_write(MO_GP2_IO, 0xcf7);
2397 mdelay(50);
2398 cx_write(MO_GP2_IO, 0xef5);
2399 mdelay(50);
2400 cx_write(MO_GP2_IO, 0xcf7);
2401 msleep(10);
2402 break;
2403
2404 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
2405 /* Enable the xc5000 tuner */
2406 cx_set(MO_GP0_IO, 0x00001010);
2407 break;
1954 } 2408 }
1955} 2409}
1956 2410
2411/*
2412 * Sets board-dependent xc3028 configuration
2413 */
2414void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
2415{
2416 memset(ctl, 0, sizeof(*ctl));
2417
2418 ctl->fname = XC2028_DEFAULT_FIRMWARE;
2419 ctl->max_len = 64;
2420
2421 switch (core->boardnr) {
2422 case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
2423 /* Doesn't work with firmware version 2.7 */
2424 ctl->fname = "xc3028-v25.fw";
2425 break;
2426 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2427 ctl->scode_table = XC3028_FE_ZARLINK456;
2428 break;
2429 case CX88_BOARD_KWORLD_ATSC_120:
2430 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2431 ctl->demod = XC3028_FE_OREN538;
2432 break;
2433 case CX88_BOARD_PROLINK_PV_8000GT:
2434 /*
2435 * This board uses non-MTS firmware
2436 */
2437 break;
2438 default:
2439 ctl->demod = XC3028_FE_OREN538;
2440 ctl->mts = 1;
2441 }
2442}
2443EXPORT_SYMBOL_GPL(cx88_setup_xc3028);
2444
1957static void cx88_card_setup(struct cx88_core *core) 2445static void cx88_card_setup(struct cx88_core *core)
1958{ 2446{
1959 static u8 eeprom[256]; 2447 static u8 eeprom[256];
@@ -1991,6 +2479,13 @@ static void cx88_card_setup(struct cx88_core *core)
1991 cx_write(MO_GP0_IO, 0x000007f8); 2479 cx_write(MO_GP0_IO, 0x000007f8);
1992 cx_write(MO_GP1_IO, 0x00000001); 2480 cx_write(MO_GP1_IO, 0x00000001);
1993 break; 2481 break;
2482 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2483 /* GPIO0:0 is hooked to demod reset */
2484 /* GPIO0:4 is hooked to xc3028 reset */
2485 cx_write(MO_GP0_IO, 0x00111100);
2486 msleep(1);
2487 cx_write(MO_GP0_IO, 0x00111111);
2488 break;
1994 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: 2489 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1995 /* GPIO0:6 is hooked to FX2 reset pin */ 2490 /* GPIO0:6 is hooked to FX2 reset pin */
1996 cx_set(MO_GP0_IO, 0x00004040); 2491 cx_set(MO_GP0_IO, 0x00004040);
@@ -2038,10 +2533,8 @@ static void cx88_card_setup(struct cx88_core *core)
2038 for (i = 0; i < ARRAY_SIZE(buffer); i++) 2533 for (i = 0; i < ARRAY_SIZE(buffer); i++)
2039 if (2 != i2c_master_send(&core->i2c_client, 2534 if (2 != i2c_master_send(&core->i2c_client,
2040 buffer[i],2)) 2535 buffer[i],2))
2041 printk(KERN_WARNING 2536 warn_printk(core, "Unable to enable "
2042 "%s: Unable to enable " 2537 "tuner(%i).\n", i);
2043 "tuner(%i).\n",
2044 core->name, i);
2045 } 2538 }
2046 break; 2539 break;
2047 case CX88_BOARD_MSI_TVANYWHERE_MASTER: 2540 case CX88_BOARD_MSI_TVANYWHERE_MASTER:
@@ -2062,6 +2555,22 @@ static void cx88_card_setup(struct cx88_core *core)
2062 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); 2555 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
2063 } 2556 }
2064 } 2557 }
2558
2559 if (core->board.tuner_type == TUNER_XC2028) {
2560 struct v4l2_priv_tun_config xc2028_cfg;
2561 struct xc2028_ctrl ctl;
2562
2563 /* Fills device-dependent initialization parameters */
2564 cx88_setup_xc3028(core, &ctl);
2565
2566 /* Sends parameters to xc2028/3028 tuner */
2567 memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
2568 xc2028_cfg.tuner = TUNER_XC2028;
2569 xc2028_cfg.priv = &ctl;
2570 info_printk(core, "Asking xc2028/3028 to load firmware %s\n",
2571 ctl.fname);
2572 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
2573 }
2065} 2574}
2066 2575
2067/* ------------------------------------------------------------------ */ 2576/* ------------------------------------------------------------------ */
@@ -2178,9 +2687,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
2178 2687
2179 memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); 2688 memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
2180 2689
2181 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", 2690 info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
2182 core->name,pci->subsystem_vendor, 2691 pci->subsystem_vendor, pci->subsystem_device, core->board.name,
2183 pci->subsystem_device, core->board.name,
2184 core->boardnr, card[core->nr] == core->boardnr ? 2692 core->boardnr, card[core->nr] == core->boardnr ?
2185 "insmod option" : "autodetected"); 2693 "insmod option" : "autodetected");
2186 2694
@@ -2189,8 +2697,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
2189 if (radio[core->nr] != UNSET) 2697 if (radio[core->nr] != UNSET)
2190 core->board.radio_type = radio[core->nr]; 2698 core->board.radio_type = radio[core->nr];
2191 2699
2192 printk(KERN_INFO "%s: TV tuner type %d, Radio tuner type %d\n", 2700 info_printk(core, "TV tuner type %d, Radio tuner type %d\n",
2193 core->name, core->board.tuner_type, core->board.radio_type); 2701 core->board.tuner_type, core->board.radio_type);
2194 2702
2195 /* init hardware */ 2703 /* init hardware */
2196 cx88_reset(core); 2704 cx88_reset(core);
@@ -2207,12 +2715,3 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
2207 2715
2208 return core; 2716 return core;
2209} 2717}
2210
2211/* ------------------------------------------------------------------ */
2212
2213/*
2214 * Local variables:
2215 * c-basic-offset: 8
2216 * End:
2217 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
2218 */