aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 17:03:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 17:03:59 -0400
commitcf2fa66055d718ae13e62451bb546505f63906a2 (patch)
treee206d3f04e74a34e9aa88d21af6c26eea21d4121 /drivers/media/video/cx88
parent4501a466f28788485604ee42641d7a5fe7258d16 (diff)
parent57f51dbc45f65f7ee1e8c8f77200bb8000e3e271 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (313 commits) V4L/DVB (9186): Added support for Prof 7300 DVB-S/S2 cards V4L/DVB (9185): S2API: Ensure we have a reasonable ROLLOFF default V4L/DVB (9184): cx24116: Change the default SNR units back to percentage by default. V4L/DVB (9183): S2API: Return error of the caller provides 0 commands. V4L/DVB (9182): S2API: Added support for DTV_HIERARCHY V4L/DVB (9181): S2API: Add support fot DTV_GUARD_INTERVAL and DTV_TRANSMISSION_MODE V4L/DVB (9180): S2API: Added support for DTV_CODE_RATE_HP/LP V4L/DVB (9179): S2API: frontend.h cleanup V4L/DVB (9178): cx24116: Add module parameter to return SNR as ESNO. V4L/DVB (9177): S2API: Change _8PSK / _16APSK to PSK_8 and APSK_16 V4L/DVB (9176): Add support for DvbWorld USB cards with STV0288 demodulator. V4L/DVB (9175): Remove NULL pointer in stb6000 driver. V4L/DVB (9174): Allow custom inittab for ST STV0288 demodulator. V4L/DVB (9173): S2API: Remove the hardcoded command limit during validation V4L/DVB (9172): S2API: Bugfix related to DVB-S / DVB-S2 tuning for the legacy API. V4L/DVB (9171): S2API: Stop an OOPS if illegal commands are dumped in S2API. V4L/DVB (9170): cx24116: Sanity checking to data input via S2API to the cx24116 demod. V4L/DVB (9169): uvcvideo: Support two new Bison Electronics webcams. V4L/DVB (9168): Add support for MSI TV@nywhere Plus remote V4L/DVB: v4l2-dev: remove duplicated #include ...
Diffstat (limited to 'drivers/media/video/cx88')
-rw-r--r--drivers/media/video/cx88/Kconfig4
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c9
-rw-r--r--drivers/media/video/cx88/cx88-cards.c306
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c198
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c16
-rw-r--r--drivers/media/video/cx88/cx88-input.c33
-rw-r--r--drivers/media/video/cx88/cx88-video.c15
-rw-r--r--drivers/media/video/cx88/cx88.h11
8 files changed, 522 insertions, 70 deletions
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 9dd7bdf659b9..0b9e5fac6239 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -58,6 +58,10 @@ config VIDEO_CX88_DVB
58 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 58 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
59 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE 59 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
60 select DVB_S5H1411 if !DVB_FE_CUSTOMISE 60 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
61 select DVB_CX24116 if !DVB_FE_CUSTOMISE
62 select DVB_STV0299 if !DVB_FE_CUSTOMISE
63 select DVB_STV0288 if !DVB_FE_CUSTOMISE
64 select DVB_STB6000 if !DVB_FE_CUSTOMISE
61 ---help--- 65 ---help---
62 This adds support for DVB/ATSC cards based on the 66 This adds support for DVB/ATSC cards based on the
63 Conexant 2388x chip. 67 Conexant 2388x chip.
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 9a1374a38ec7..e71369754305 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1057,12 +1057,15 @@ static int mpeg_open(struct inode *inode, struct file *file)
1057 struct cx8802_driver *drv = NULL; 1057 struct cx8802_driver *drv = NULL;
1058 int err; 1058 int err;
1059 1059
1060 lock_kernel();
1060 dev = cx8802_get_device(inode); 1061 dev = cx8802_get_device(inode);
1061 1062
1062 dprintk( 1, "%s\n", __func__); 1063 dprintk( 1, "%s\n", __func__);
1063 1064
1064 if (dev == NULL) 1065 if (dev == NULL) {
1066 unlock_kernel();
1065 return -ENODEV; 1067 return -ENODEV;
1068 }
1066 1069
1067 /* Make sure we can acquire the hardware */ 1070 /* Make sure we can acquire the hardware */
1068 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); 1071 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
@@ -1070,6 +1073,7 @@ static int mpeg_open(struct inode *inode, struct file *file)
1070 err = drv->request_acquire(drv); 1073 err = drv->request_acquire(drv);
1071 if(err != 0) { 1074 if(err != 0) {
1072 dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); 1075 dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
1076 unlock_kernel();
1073 return err; 1077 return err;
1074 } 1078 }
1075 } 1079 }
@@ -1077,6 +1081,7 @@ static int mpeg_open(struct inode *inode, struct file *file)
1077 if (blackbird_initialize_codec(dev) < 0) { 1081 if (blackbird_initialize_codec(dev) < 0) {
1078 if (drv) 1082 if (drv)
1079 drv->request_release(drv); 1083 drv->request_release(drv);
1084 unlock_kernel();
1080 return -EINVAL; 1085 return -EINVAL;
1081 } 1086 }
1082 dprintk(1,"open minor=%d\n",minor); 1087 dprintk(1,"open minor=%d\n",minor);
@@ -1086,6 +1091,7 @@ static int mpeg_open(struct inode *inode, struct file *file)
1086 if (NULL == fh) { 1091 if (NULL == fh) {
1087 if (drv) 1092 if (drv)
1088 drv->request_release(drv); 1093 drv->request_release(drv);
1094 unlock_kernel();
1089 return -ENOMEM; 1095 return -ENOMEM;
1090 } 1096 }
1091 file->private_data = fh; 1097 file->private_data = fh;
@@ -1101,6 +1107,7 @@ static int mpeg_open(struct inode *inode, struct file *file)
1101 /* FIXME: locking against other video device */ 1107 /* FIXME: locking against other video device */
1102 cx88_set_scale(dev->core, dev->width, dev->height, 1108 cx88_set_scale(dev->core, dev->width, dev->height,
1103 fh->mpegq.field); 1109 fh->mpegq.field);
1110 unlock_kernel();
1104 1111
1105 return 0; 1112 return 0;
1106} 1113}
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index de199a206a15..5da04e811ca2 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1349,27 +1349,30 @@ static const struct cx88_board cx88_boards[] = {
1349 .radio_addr = ADDR_UNSET, 1349 .radio_addr = ADDR_UNSET,
1350 .tda9887_conf = TDA9887_PRESENT, 1350 .tda9887_conf = TDA9887_PRESENT,
1351 .audio_chip = V4L2_IDENT_WM8775, 1351 .audio_chip = V4L2_IDENT_WM8775,
1352 /*
1353 * gpio0 as reported by Mike Crash <mike AT mikecrash.com>
1354 */
1352 .input = {{ 1355 .input = {{
1353 .type = CX88_VMUX_TELEVISION, 1356 .type = CX88_VMUX_TELEVISION,
1354 .vmux = 0, 1357 .vmux = 0,
1355 .gpio0 = 0xe780, 1358 .gpio0 = 0xef88,
1356 .audioroute = 1, 1359 .audioroute = 1,
1357 },{ 1360 },{
1358 .type = CX88_VMUX_COMPOSITE1, 1361 .type = CX88_VMUX_COMPOSITE1,
1359 .vmux = 1, 1362 .vmux = 1,
1360 .gpio0 = 0xe780, 1363 .gpio0 = 0xef88,
1361 .audioroute = 2, 1364 .audioroute = 2,
1362 },{ 1365 },{
1363 .type = CX88_VMUX_SVIDEO, 1366 .type = CX88_VMUX_SVIDEO,
1364 .vmux = 2, 1367 .vmux = 2,
1365 .gpio0 = 0xe780, 1368 .gpio0 = 0xef88,
1366 .audioroute = 2, 1369 .audioroute = 2,
1367 }}, 1370 }},
1368 /* fixme: Add radio support */ 1371 /* fixme: Add radio support */
1369 .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, 1372 .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD,
1370 .radio = { 1373 .radio = {
1371 .type = CX88_RADIO, 1374 .type = CX88_RADIO,
1372 .gpio0 = 0xe780, 1375 .gpio0 = 0xef88,
1373 }, 1376 },
1374 }, 1377 },
1375 [CX88_BOARD_ADSTECH_PTV_390] = { 1378 [CX88_BOARD_ADSTECH_PTV_390] = {
@@ -1446,15 +1449,26 @@ static const struct cx88_board cx88_boards[] = {
1446 .name = "Pinnacle Hybrid PCTV", 1449 .name = "Pinnacle Hybrid PCTV",
1447 .tuner_type = TUNER_XC2028, 1450 .tuner_type = TUNER_XC2028,
1448 .tuner_addr = 0x61, 1451 .tuner_addr = 0x61,
1452 .radio_type = TUNER_XC2028,
1453 .radio_addr = 0x61,
1449 .input = { { 1454 .input = { {
1450 .type = CX88_VMUX_TELEVISION, 1455 .type = CX88_VMUX_TELEVISION,
1451 .vmux = 0, 1456 .vmux = 0,
1457 .gpio0 = 0x004ff,
1458 .gpio1 = 0x010ff,
1459 .gpio2 = 0x00001,
1452 }, { 1460 }, {
1453 .type = CX88_VMUX_COMPOSITE1, 1461 .type = CX88_VMUX_COMPOSITE1,
1454 .vmux = 1, 1462 .vmux = 1,
1463 .gpio0 = 0x004fb,
1464 .gpio1 = 0x010ef,
1465 .audioroute = 1,
1455 }, { 1466 }, {
1456 .type = CX88_VMUX_SVIDEO, 1467 .type = CX88_VMUX_SVIDEO,
1457 .vmux = 2, 1468 .vmux = 2,
1469 .gpio0 = 0x004fb,
1470 .gpio1 = 0x010ef,
1471 .audioroute = 1,
1458 } }, 1472 } },
1459 .radio = { 1473 .radio = {
1460 .type = CX88_RADIO, 1474 .type = CX88_RADIO,
@@ -1462,6 +1476,7 @@ static const struct cx88_board cx88_boards[] = {
1462 .gpio1 = 0x010ff, 1476 .gpio1 = 0x010ff,
1463 .gpio2 = 0x0ff, 1477 .gpio2 = 0x0ff,
1464 }, 1478 },
1479 .mpeg = CX88_MPEG_DVB,
1465 }, 1480 },
1466 [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = { 1481 [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = {
1467 .name = "Winfast TV2000 XP Global", 1482 .name = "Winfast TV2000 XP Global",
@@ -1566,9 +1581,9 @@ static const struct cx88_board cx88_boards[] = {
1566 }, 1581 },
1567 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO] = { 1582 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO] = {
1568 .name = "DViCO FusionHDTV DVB-T PRO", 1583 .name = "DViCO FusionHDTV DVB-T PRO",
1569 .tuner_type = TUNER_ABSENT, /* XXX: Has XC3028 */ 1584 .tuner_type = TUNER_XC2028,
1585 .tuner_addr = 0x61,
1570 .radio_type = UNSET, 1586 .radio_type = UNSET,
1571 .tuner_addr = ADDR_UNSET,
1572 .radio_addr = ADDR_UNSET, 1587 .radio_addr = ADDR_UNSET,
1573 .input = { { 1588 .input = { {
1574 .type = CX88_VMUX_COMPOSITE1, 1589 .type = CX88_VMUX_COMPOSITE1,
@@ -1625,6 +1640,36 @@ static const struct cx88_board cx88_boards[] = {
1625 .gpio2 = 0x0cfb, 1640 .gpio2 = 0x0cfb,
1626 }, 1641 },
1627 }, 1642 },
1643 [CX88_BOARD_PROLINK_PV_GLOBAL_XTREME] = {
1644 .name = "Prolink Pixelview Global Extreme",
1645 .tuner_type = TUNER_XC2028,
1646 .tuner_addr = 0x61,
1647 .input = { {
1648 .type = CX88_VMUX_TELEVISION,
1649 .vmux = 0,
1650 .gpio0 = 0x04fb,
1651 .gpio1 = 0x04080,
1652 .gpio2 = 0x0cf7,
1653 }, {
1654 .type = CX88_VMUX_COMPOSITE1,
1655 .vmux = 1,
1656 .gpio0 = 0x04fb,
1657 .gpio1 = 0x04080,
1658 .gpio2 = 0x0cfb,
1659 }, {
1660 .type = CX88_VMUX_SVIDEO,
1661 .vmux = 2,
1662 .gpio0 = 0x04fb,
1663 .gpio1 = 0x04080,
1664 .gpio2 = 0x0cfb,
1665 } },
1666 .radio = {
1667 .type = CX88_RADIO,
1668 .gpio0 = 0x04ff,
1669 .gpio1 = 0x04080,
1670 .gpio2 = 0x0cf7,
1671 },
1672 },
1628 /* Both radio, analog and ATSC work with this board. 1673 /* Both radio, analog and ATSC work with this board.
1629 However, for analog to work, s5h1409 gate should be open, 1674 However, for analog to work, s5h1409 gate should be open,
1630 otherwise, tuner-xc3028 won't be detected. 1675 otherwise, tuner-xc3028 won't be detected.
@@ -1664,6 +1709,131 @@ static const struct cx88_board cx88_boards[] = {
1664 }, 1709 },
1665 .mpeg = CX88_MPEG_DVB, 1710 .mpeg = CX88_MPEG_DVB,
1666 }, 1711 },
1712 [CX88_BOARD_HAUPPAUGE_HVR4000] = {
1713 .name = "Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid",
1714 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
1715 .radio_type = UNSET,
1716 .tuner_addr = ADDR_UNSET,
1717 .radio_addr = ADDR_UNSET,
1718 .tda9887_conf = TDA9887_PRESENT,
1719 /*
1720 * GPIO0 (WINTV2000)
1721 *
1722 * Analogue SAT DVB-T
1723 * Antenna 0xc4bf 0xc4bb
1724 * Composite 0xc4bf 0xc4bb
1725 * S-Video 0xc4bf 0xc4bb
1726 * Composite1 0xc4ff 0xc4fb
1727 * S-Video1 0xc4ff 0xc4fb
1728 *
1729 * BIT VALUE FUNCTION GP{x}_IO
1730 * 0 1 I:?
1731 * 1 1 I:?
1732 * 2 1 O:DVB-T DEMOD ENABLE LOW/ANALOG DEMOD ENABLE HIGH
1733 * 3 1 I:?
1734 * 4 1 I:?
1735 * 5 1 I:?
1736 * 6 0 O:INPUT SELECTOR 0=INTERNAL 1=EXPANSION
1737 * 7 1 O:DVB-T DEMOD RESET LOW
1738 *
1739 * BIT VALUE FUNCTION GP{x}_OE
1740 * 8 0 I
1741 * 9 0 I
1742 * a 1 O
1743 * b 0 I
1744 * c 0 I
1745 * d 0 I
1746 * e 1 O
1747 * f 1 O
1748 */
1749 .input = {{
1750 .type = CX88_VMUX_TELEVISION,
1751 .vmux = 0,
1752 .gpio0 = 0xc4bf,
1753 }, {
1754 .type = CX88_VMUX_COMPOSITE1,
1755 .vmux = 1,
1756 .gpio0 = 0xc4bf,
1757 }, {
1758 .type = CX88_VMUX_SVIDEO,
1759 .vmux = 2,
1760 .gpio0 = 0xc4bf,
1761 } },
1762 /* fixme: Add radio support */
1763 .mpeg = CX88_MPEG_DVB,
1764 },
1765 [CX88_BOARD_HAUPPAUGE_HVR4000LITE] = {
1766 .name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2",
1767 .tuner_type = UNSET,
1768 .radio_type = UNSET,
1769 .tuner_addr = ADDR_UNSET,
1770 .radio_addr = ADDR_UNSET,
1771 .input = {{
1772 .type = CX88_VMUX_DVB,
1773 .vmux = 0,
1774 } },
1775 .mpeg = CX88_MPEG_DVB,
1776 },
1777 [CX88_BOARD_TEVII_S420] = {
1778 .name = "TeVii S420 DVB-S",
1779 .tuner_type = UNSET,
1780 .radio_type = UNSET,
1781 .tuner_addr = ADDR_UNSET,
1782 .radio_addr = ADDR_UNSET,
1783 .input = {{
1784 .type = CX88_VMUX_DVB,
1785 .vmux = 0,
1786 } },
1787 .mpeg = CX88_MPEG_DVB,
1788 },
1789 [CX88_BOARD_TEVII_S460] = {
1790 .name = "TeVii S460 DVB-S/S2",
1791 .tuner_type = UNSET,
1792 .radio_type = UNSET,
1793 .tuner_addr = ADDR_UNSET,
1794 .radio_addr = ADDR_UNSET,
1795 .input = {{
1796 .type = CX88_VMUX_DVB,
1797 .vmux = 0,
1798 } },
1799 .mpeg = CX88_MPEG_DVB,
1800 },
1801 [CX88_BOARD_OMICOM_SS4_PCI] = {
1802 .name = "Omicom SS4 DVB-S/S2 PCI",
1803 .tuner_type = UNSET,
1804 .radio_type = UNSET,
1805 .tuner_addr = ADDR_UNSET,
1806 .radio_addr = ADDR_UNSET,
1807 .input = {{
1808 .type = CX88_VMUX_DVB,
1809 .vmux = 0,
1810 } },
1811 .mpeg = CX88_MPEG_DVB,
1812 },
1813 [CX88_BOARD_TBS_8920] = {
1814 .name = "TBS 8920 DVB-S/S2",
1815 .tuner_type = TUNER_ABSENT,
1816 .radio_type = UNSET,
1817 .tuner_addr = ADDR_UNSET,
1818 .radio_addr = ADDR_UNSET,
1819 .input = {{
1820 .type = CX88_VMUX_DVB,
1821 .vmux = 1,
1822 } },
1823 .mpeg = CX88_MPEG_DVB,
1824 },
1825 [CX88_BOARD_PROF_7300] = {
1826 .name = "PROF 7300 DVB-S/S2",
1827 .tuner_type = UNSET,
1828 .radio_type = UNSET,
1829 .tuner_addr = ADDR_UNSET,
1830 .radio_addr = ADDR_UNSET,
1831 .input = {{
1832 .type = CX88_VMUX_DVB,
1833 .vmux = 0,
1834 } },
1835 .mpeg = CX88_MPEG_DVB,
1836 },
1667}; 1837};
1668 1838
1669/* ------------------------------------------------------------------ */ 1839/* ------------------------------------------------------------------ */
@@ -2010,9 +2180,53 @@ static const struct cx88_subid cx88_subids[] = {
2010 .subdevice = 0x4935, 2180 .subdevice = 0x4935,
2011 .card = CX88_BOARD_PROLINK_PV_8000GT, 2181 .card = CX88_BOARD_PROLINK_PV_8000GT,
2012 }, { 2182 }, {
2183 .subvendor = 0x1554,
2184 .subdevice = 0x4976,
2185 .card = CX88_BOARD_PROLINK_PV_GLOBAL_XTREME,
2186 }, {
2013 .subvendor = 0x17de, 2187 .subvendor = 0x17de,
2014 .subdevice = 0x08c1, 2188 .subdevice = 0x08c1,
2015 .card = CX88_BOARD_KWORLD_ATSC_120, 2189 .card = CX88_BOARD_KWORLD_ATSC_120,
2190 }, {
2191 .subvendor = 0x0070,
2192 .subdevice = 0x6900,
2193 .card = CX88_BOARD_HAUPPAUGE_HVR4000,
2194 }, {
2195 .subvendor = 0x0070,
2196 .subdevice = 0x6904,
2197 .card = CX88_BOARD_HAUPPAUGE_HVR4000,
2198 }, {
2199 .subvendor = 0x0070,
2200 .subdevice = 0x6902,
2201 .card = CX88_BOARD_HAUPPAUGE_HVR4000,
2202 }, {
2203 .subvendor = 0x0070,
2204 .subdevice = 0x6905,
2205 .card = CX88_BOARD_HAUPPAUGE_HVR4000LITE,
2206 }, {
2207 .subvendor = 0x0070,
2208 .subdevice = 0x6906,
2209 .card = CX88_BOARD_HAUPPAUGE_HVR4000LITE,
2210 }, {
2211 .subvendor = 0xd420,
2212 .subdevice = 0x9022,
2213 .card = CX88_BOARD_TEVII_S420,
2214 }, {
2215 .subvendor = 0xd460,
2216 .subdevice = 0x9022,
2217 .card = CX88_BOARD_TEVII_S460,
2218 }, {
2219 .subvendor = 0xA044,
2220 .subdevice = 0x2011,
2221 .card = CX88_BOARD_OMICOM_SS4_PCI,
2222 }, {
2223 .subvendor = 0x8920,
2224 .subdevice = 0x8888,
2225 .card = CX88_BOARD_TBS_8920,
2226 }, {
2227 .subvendor = 0xB033,
2228 .subdevice = 0x3033,
2229 .card = CX88_BOARD_PROF_7300,
2016 }, 2230 },
2017}; 2231};
2018 2232
@@ -2065,6 +2279,13 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
2065 case 14669: /* WinTV-HVR3000 (OEM, no IR, no b/panel video - Low profile) */ 2279 case 14669: /* WinTV-HVR3000 (OEM, no IR, no b/panel video - Low profile) */
2066 case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ 2280 case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
2067 case 34519: /* WinTV-PCI-FM */ 2281 case 34519: /* WinTV-PCI-FM */
2282 case 69009:
2283 /* WinTV-HVR4000 (DVBS/S2/T, Video and IR, back panel inputs) */
2284 case 69100: /* WinTV-HVR4000LITE (DVBS/S2, IR) */
2285 case 69500: /* WinTV-HVR4000LITE (DVBS/S2, No IR) */
2286 case 69559:
2287 /* WinTV-HVR4000 (DVBS/S2/T, Video no IR, back panel inputs) */
2288 case 69569: /* WinTV-HVR4000 (DVBS/S2/T, Video no IR) */
2068 case 90002: /* Nova-T-PCI (9002) */ 2289 case 90002: /* Nova-T-PCI (9002) */
2069 case 92001: /* Nova-S-Plus (Video and IR) */ 2290 case 92001: /* Nova-S-Plus (Video and IR) */
2070 case 92002: /* Nova-S-Plus (Video and IR) */ 2291 case 92002: /* Nova-S-Plus (Video and IR) */
@@ -2149,9 +2370,21 @@ static int cx88_dvico_xc2028_callback(struct cx88_core *core,
2149{ 2370{
2150 switch (command) { 2371 switch (command) {
2151 case XC2028_TUNER_RESET: 2372 case XC2028_TUNER_RESET:
2152 cx_write(MO_GP0_IO, 0x101000); 2373 switch (core->boardnr) {
2153 mdelay(5); 2374 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2154 cx_set(MO_GP0_IO, 0x101010); 2375 /* GPIO-4 xc3028 tuner */
2376
2377 cx_set(MO_GP0_IO, 0x00001000);
2378 cx_clear(MO_GP0_IO, 0x00000010);
2379 msleep(100);
2380 cx_set(MO_GP0_IO, 0x00000010);
2381 msleep(100);
2382 break;
2383 default:
2384 cx_write(MO_GP0_IO, 0x101000);
2385 mdelay(5);
2386 cx_set(MO_GP0_IO, 0x101010);
2387 }
2155 break; 2388 break;
2156 default: 2389 default:
2157 return -EINVAL; 2390 return -EINVAL;
@@ -2258,8 +2491,10 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
2258 return cx88_xc3028_geniatech_tuner_callback(core, 2491 return cx88_xc3028_geniatech_tuner_callback(core,
2259 command, arg); 2492 command, arg);
2260 case CX88_BOARD_PROLINK_PV_8000GT: 2493 case CX88_BOARD_PROLINK_PV_8000GT:
2494 case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
2261 return cx88_pv_8000gt_callback(core, command, arg); 2495 return cx88_pv_8000gt_callback(core, command, arg);
2262 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: 2496 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2497 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2263 return cx88_dvico_xc2028_callback(core, command, arg); 2498 return cx88_dvico_xc2028_callback(core, command, arg);
2264 } 2499 }
2265 2500
@@ -2327,7 +2562,7 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core,
2327 return 0; /* Should never be here */ 2562 return 0; /* Should never be here */
2328} 2563}
2329 2564
2330int cx88_tuner_callback(void *priv, int command, int arg) 2565int cx88_tuner_callback(void *priv, int component, int command, int arg)
2331{ 2566{
2332 struct i2c_algo_bit_data *i2c_algo = priv; 2567 struct i2c_algo_bit_data *i2c_algo = priv;
2333 struct cx88_core *core; 2568 struct cx88_core *core;
@@ -2344,6 +2579,9 @@ int cx88_tuner_callback(void *priv, int command, int arg)
2344 return -EINVAL; 2579 return -EINVAL;
2345 } 2580 }
2346 2581
2582 if (component != DVB_FRONTEND_COMPONENT_TUNER)
2583 return -EINVAL;
2584
2347 switch (core->board.tuner_type) { 2585 switch (core->board.tuner_type) {
2348 case TUNER_XC2028: 2586 case TUNER_XC2028:
2349 info_printk(core, "Calling XC2028/3028 callback\n"); 2587 info_printk(core, "Calling XC2028/3028 callback\n");
@@ -2392,16 +2630,22 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
2392{ 2630{
2393 switch (core->boardnr) { 2631 switch (core->boardnr) {
2394 case CX88_BOARD_HAUPPAUGE_HVR1300: 2632 case CX88_BOARD_HAUPPAUGE_HVR1300:
2395 /* Bring the 702 demod up before i2c scanning/attach or devices are hidden */ 2633 /*
2396 /* We leave here with the 702 on the bus */ 2634 * Bring the 702 demod up before i2c scanning/attach or devices are hidden
2397 cx_write(MO_GP0_IO, 0x0000e780); 2635 * We leave here with the 702 on the bus
2636 *
2637 * "reset the IR receiver on GPIO[3]"
2638 * Reported by Mike Crash <mike AT mikecrash.com>
2639 */
2640 cx_write(MO_GP0_IO, 0x0000ef88);
2398 udelay(1000); 2641 udelay(1000);
2399 cx_clear(MO_GP0_IO, 0x00000080); 2642 cx_clear(MO_GP0_IO, 0x00000088);
2400 udelay(50); 2643 udelay(50);
2401 cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */ 2644 cx_set(MO_GP0_IO, 0x00000088); /* 702 out of reset */
2402 udelay(1000); 2645 udelay(1000);
2403 break; 2646 break;
2404 2647
2648 case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
2405 case CX88_BOARD_PROLINK_PV_8000GT: 2649 case CX88_BOARD_PROLINK_PV_8000GT:
2406 cx_write(MO_GP2_IO, 0xcf7); 2650 cx_write(MO_GP2_IO, 0xcf7);
2407 mdelay(50); 2651 mdelay(50);
@@ -2411,10 +2655,18 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
2411 msleep(10); 2655 msleep(10);
2412 break; 2656 break;
2413 2657
2414 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: 2658 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
2415 /* Enable the xc5000 tuner */ 2659 /* Enable the xc5000 tuner */
2416 cx_set(MO_GP0_IO, 0x00001010); 2660 cx_set(MO_GP0_IO, 0x00001010);
2417 break; 2661 break;
2662
2663 case CX88_BOARD_HAUPPAUGE_HVR3000:
2664 case CX88_BOARD_HAUPPAUGE_HVR4000:
2665 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
2666 /* Init GPIO */
2667 cx_write(MO_GP0_IO, core->board.input[0].gpio0);
2668 udelay(1000);
2669 break;
2418 } 2670 }
2419} 2671}
2420 2672
@@ -2435,17 +2687,22 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
2435 core->i2c_algo.udelay = 16; 2687 core->i2c_algo.udelay = 16;
2436 break; 2688 break;
2437 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: 2689 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
2438 ctl->scode_table = XC3028_FE_ZARLINK456; 2690 ctl->demod = XC3028_FE_ZARLINK456;
2439 break; 2691 break;
2440 case CX88_BOARD_KWORLD_ATSC_120: 2692 case CX88_BOARD_KWORLD_ATSC_120:
2441 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: 2693 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
2442 ctl->demod = XC3028_FE_OREN538; 2694 ctl->demod = XC3028_FE_OREN538;
2443 break; 2695 break;
2696 case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
2444 case CX88_BOARD_PROLINK_PV_8000GT: 2697 case CX88_BOARD_PROLINK_PV_8000GT:
2445 /* 2698 /*
2446 * This board uses non-MTS firmware 2699 * Those boards uses non-MTS firmware
2447 */ 2700 */
2448 break; 2701 break;
2702 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
2703 ctl->demod = XC3028_FE_ZARLINK456;
2704 ctl->mts = 1;
2705 break;
2449 default: 2706 default:
2450 ctl->demod = XC3028_FE_OREN538; 2707 ctl->demod = XC3028_FE_OREN538;
2451 ctl->mts = 1; 2708 ctl->mts = 1;
@@ -2489,6 +2746,8 @@ static void cx88_card_setup(struct cx88_core *core)
2489 case CX88_BOARD_HAUPPAUGE_HVR1100LP: 2746 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
2490 case CX88_BOARD_HAUPPAUGE_HVR3000: 2747 case CX88_BOARD_HAUPPAUGE_HVR3000:
2491 case CX88_BOARD_HAUPPAUGE_HVR1300: 2748 case CX88_BOARD_HAUPPAUGE_HVR1300:
2749 case CX88_BOARD_HAUPPAUGE_HVR4000:
2750 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
2492 if (0 == core->i2c_rc) 2751 if (0 == core->i2c_rc)
2493 hauppauge_eeprom(core, eeprom); 2752 hauppauge_eeprom(core, eeprom);
2494 break; 2753 break;
@@ -2570,7 +2829,18 @@ static void cx88_card_setup(struct cx88_core *core)
2570 tea5767_cfg.priv = &ctl; 2829 tea5767_cfg.priv = &ctl;
2571 2830
2572 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); 2831 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
2832 break;
2573 } 2833 }
2834 case CX88_BOARD_TEVII_S420:
2835 case CX88_BOARD_TEVII_S460:
2836 case CX88_BOARD_OMICOM_SS4_PCI:
2837 case CX88_BOARD_TBS_8920:
2838 case CX88_BOARD_PROF_7300:
2839 cx_write(MO_SRST_IO, 0);
2840 msleep(100);
2841 cx_write(MO_SRST_IO, 1);
2842 msleep(100);
2843 break;
2574 } /*end switch() */ 2844 } /*end switch() */
2575 2845
2576 2846
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index d96173ff1dba..344ed2626e59 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -48,6 +48,11 @@
48#include "tuner-simple.h" 48#include "tuner-simple.h"
49#include "tda9887.h" 49#include "tda9887.h"
50#include "s5h1411.h" 50#include "s5h1411.h"
51#include "stv0299.h"
52#include "z0194a.h"
53#include "stv0288.h"
54#include "stb6000.h"
55#include "cx24116.h"
51 56
52MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 57MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
53MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 58MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -375,37 +380,28 @@ static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
375 return 0; 380 return 0;
376} 381}
377 382
378static int cx88_pci_nano_callback(void *ptr, int command, int arg) 383static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
384 fe_sec_voltage_t voltage)
379{ 385{
380 struct cx88_core *core = ptr; 386 struct cx8802_dev *dev= fe->dvb->priv;
381 387 struct cx88_core *core = dev->core;
382 switch (command) {
383 case XC2028_TUNER_RESET:
384 /* Send the tuner in then out of reset */
385 dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg);
386
387 switch (core->boardnr) {
388 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
389 /* GPIO-4 xc3028 tuner */
390
391 cx_set(MO_GP0_IO, 0x00001000);
392 cx_clear(MO_GP0_IO, 0x00000010);
393 msleep(100);
394 cx_set(MO_GP0_IO, 0x00000010);
395 msleep(100);
396 break;
397 }
398 388
399 break; 389 switch (voltage) {
400 case XC2028_RESET_CLK: 390 case SEC_VOLTAGE_13:
401 dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); 391 printk("LNB Voltage SEC_VOLTAGE_13\n");
402 break; 392 cx_write(MO_GP0_IO, 0x00006040);
403 default: 393 break;
404 dprintk(1, "%s: unknown command %d, arg %d\n", __func__, 394 case SEC_VOLTAGE_18:
405 command, arg); 395 printk("LNB Voltage SEC_VOLTAGE_18\n");
406 return -EINVAL; 396 cx_write(MO_GP0_IO, 0x00006060);
397 break;
398 case SEC_VOLTAGE_OFF:
399 printk("LNB Voltage SEC_VOLTAGE_off\n");
400 break;
407 } 401 }
408 402
403 if (core->prev_set_voltage)
404 return core->prev_set_voltage(fe, voltage);
409 return 0; 405 return 0;
410} 406}
411 407
@@ -456,7 +452,12 @@ static struct s5h1409_config kworld_atsc_120_config = {
456static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { 452static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
457 .i2c_address = 0x64, 453 .i2c_address = 0x64,
458 .if_khz = 5380, 454 .if_khz = 5380,
459 .tuner_callback = cx88_tuner_callback, 455};
456
457static struct zl10353_config cx88_pinnacle_hybrid_pctv = {
458 .demod_address = (0x1e >> 1),
459 .no_tuner = 1,
460 .if2 = 45600,
460}; 461};
461 462
462static struct zl10353_config cx88_geniatech_x8000_mt = { 463static struct zl10353_config cx88_geniatech_x8000_mt = {
@@ -477,7 +478,6 @@ static struct s5h1411_config dvico_fusionhdtv7_config = {
477static struct xc5000_config dvico_fusionhdtv7_tuner_config = { 478static struct xc5000_config dvico_fusionhdtv7_tuner_config = {
478 .i2c_address = 0xc2 >> 1, 479 .i2c_address = 0xc2 >> 1,
479 .if_khz = 5380, 480 .if_khz = 5380,
480 .tuner_callback = cx88_tuner_callback,
481}; 481};
482 482
483static int attach_xc3028(u8 addr, struct cx8802_dev *dev) 483static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
@@ -488,7 +488,6 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
488 .i2c_adap = &dev->core->i2c_adap, 488 .i2c_adap = &dev->core->i2c_adap,
489 .i2c_addr = addr, 489 .i2c_addr = addr,
490 .ctrl = &ctl, 490 .ctrl = &ctl,
491 .callback = cx88_tuner_callback,
492 }; 491 };
493 492
494 if (!dev->dvb.frontend) { 493 if (!dev->dvb.frontend) {
@@ -518,6 +517,60 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
518 return 0; 517 return 0;
519} 518}
520 519
520static int cx24116_set_ts_param(struct dvb_frontend *fe,
521 int is_punctured)
522{
523 struct cx8802_dev *dev = fe->dvb->priv;
524 dev->ts_gen_cntrl = 0x2;
525
526 return 0;
527}
528
529static int cx24116_reset_device(struct dvb_frontend *fe)
530{
531 struct cx8802_dev *dev = fe->dvb->priv;
532 struct cx88_core *core = dev->core;
533
534 /* Reset the part */
535 cx_write(MO_SRST_IO, 0);
536 msleep(10);
537 cx_write(MO_SRST_IO, 1);
538 msleep(10);
539
540 return 0;
541}
542
543static struct cx24116_config hauppauge_hvr4000_config = {
544 .demod_address = 0x05,
545 .set_ts_params = cx24116_set_ts_param,
546 .reset_device = cx24116_reset_device,
547};
548
549static struct cx24116_config tevii_s460_config = {
550 .demod_address = 0x55,
551 .set_ts_params = cx24116_set_ts_param,
552 .reset_device = cx24116_reset_device,
553};
554
555static struct stv0299_config tevii_tuner_sharp_config = {
556 .demod_address = 0x68,
557 .inittab = sharp_z0194a__inittab,
558 .mclk = 88000000UL,
559 .invert = 1,
560 .skip_reinit = 0,
561 .lock_output = 1,
562 .volt13_op0_op1 = STV0299_VOLT13_OP1,
563 .min_delay_ms = 100,
564 .set_symbol_rate = sharp_z0194a__set_symbol_rate,
565 .set_ts_params = cx24116_set_ts_param,
566};
567
568static struct stv0288_config tevii_tuner_earda_config = {
569 .demod_address = 0x68,
570 .min_delay_ms = 100,
571 .set_ts_params = cx24116_set_ts_param,
572};
573
521static int dvb_register(struct cx8802_dev *dev) 574static int dvb_register(struct cx8802_dev *dev)
522{ 575{
523 struct cx88_core *core = dev->core; 576 struct cx88_core *core = dev->core;
@@ -786,7 +839,7 @@ static int dvb_register(struct cx8802_dev *dev)
786 &core->i2c_adap); 839 &core->i2c_adap);
787 if (dev->dvb.frontend) { 840 if (dev->dvb.frontend) {
788 if (!dvb_attach(isl6421_attach, dev->dvb.frontend, 841 if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
789 &core->i2c_adap, 0x08, 0x00, 0x00)) 842 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
790 goto frontend_detach; 843 goto frontend_detach;
791 } 844 }
792 break; 845 break;
@@ -813,13 +866,9 @@ static int dvb_register(struct cx8802_dev *dev)
813 &pinnacle_pctv_hd_800i_config, 866 &pinnacle_pctv_hd_800i_config,
814 &core->i2c_adap); 867 &core->i2c_adap);
815 if (dev->dvb.frontend != NULL) { 868 if (dev->dvb.frontend != NULL) {
816 /* tuner_config.video_dev must point to
817 * i2c_adap.algo_data
818 */
819 if (!dvb_attach(xc5000_attach, dev->dvb.frontend, 869 if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
820 &core->i2c_adap, 870 &core->i2c_adap,
821 &pinnacle_pctv_hd_800i_tuner_config, 871 &pinnacle_pctv_hd_800i_tuner_config))
822 core->i2c_adap.algo_data))
823 goto frontend_detach; 872 goto frontend_detach;
824 } 873 }
825 break; 874 break;
@@ -832,10 +881,9 @@ static int dvb_register(struct cx8802_dev *dev)
832 struct xc2028_config cfg = { 881 struct xc2028_config cfg = {
833 .i2c_adap = &core->i2c_adap, 882 .i2c_adap = &core->i2c_adap,
834 .i2c_addr = 0x61, 883 .i2c_addr = 0x61,
835 .callback = cx88_pci_nano_callback,
836 }; 884 };
837 static struct xc2028_ctrl ctl = { 885 static struct xc2028_ctrl ctl = {
838 .fname = "xc3028-v27.fw", 886 .fname = XC2028_DEFAULT_FIRMWARE,
839 .max_len = 64, 887 .max_len = 64,
840 .scode_table = XC3028_FE_OREN538, 888 .scode_table = XC3028_FE_OREN538,
841 }; 889 };
@@ -848,10 +896,13 @@ static int dvb_register(struct cx8802_dev *dev)
848 break; 896 break;
849 case CX88_BOARD_PINNACLE_HYBRID_PCTV: 897 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
850 dev->dvb.frontend = dvb_attach(zl10353_attach, 898 dev->dvb.frontend = dvb_attach(zl10353_attach,
851 &cx88_geniatech_x8000_mt, 899 &cx88_pinnacle_hybrid_pctv,
852 &core->i2c_adap); 900 &core->i2c_adap);
853 if (attach_xc3028(0x61, dev) < 0) 901 if (dev->dvb.frontend) {
854 goto frontend_detach; 902 dev->dvb.frontend->ops.i2c_gate_ctrl = NULL;
903 if (attach_xc3028(0x61, dev) < 0)
904 goto frontend_detach;
905 }
855 break; 906 break;
856 case CX88_BOARD_GENIATECH_X8000_MT: 907 case CX88_BOARD_GENIATECH_X8000_MT:
857 dev->ts_gen_cntrl = 0x00; 908 dev->ts_gen_cntrl = 0x00;
@@ -874,16 +925,69 @@ static int dvb_register(struct cx8802_dev *dev)
874 &dvico_fusionhdtv7_config, 925 &dvico_fusionhdtv7_config,
875 &core->i2c_adap); 926 &core->i2c_adap);
876 if (dev->dvb.frontend != NULL) { 927 if (dev->dvb.frontend != NULL) {
877 /* tuner_config.video_dev must point to
878 * i2c_adap.algo_data
879 */
880 if (!dvb_attach(xc5000_attach, dev->dvb.frontend, 928 if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
881 &core->i2c_adap, 929 &core->i2c_adap,
882 &dvico_fusionhdtv7_tuner_config, 930 &dvico_fusionhdtv7_tuner_config))
883 core->i2c_adap.algo_data))
884 goto frontend_detach; 931 goto frontend_detach;
885 } 932 }
886 break; 933 break;
934 case CX88_BOARD_HAUPPAUGE_HVR4000:
935 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
936 /* Support for DVB-S only, not DVB-T support */
937 dev->dvb.frontend = dvb_attach(cx24116_attach,
938 &hauppauge_hvr4000_config,
939 &dev->core->i2c_adap);
940 if (dev->dvb.frontend) {
941 dvb_attach(isl6421_attach, dev->dvb.frontend,
942 &dev->core->i2c_adap,
943 0x08, ISL6421_DCL, 0x00);
944 }
945 break;
946 case CX88_BOARD_TEVII_S420:
947 dev->dvb.frontend = dvb_attach(stv0299_attach,
948 &tevii_tuner_sharp_config,
949 &core->i2c_adap);
950 if (dev->dvb.frontend != NULL) {
951 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
952 &core->i2c_adap, DVB_PLL_OPERA1))
953 goto frontend_detach;
954 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
955 dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
956
957 } else {
958 dev->dvb.frontend = dvb_attach(stv0288_attach,
959 &tevii_tuner_earda_config,
960 &core->i2c_adap);
961 if (dev->dvb.frontend != NULL) {
962 if (!dvb_attach(stb6000_attach, dev->dvb.frontend, 0x61,
963 &core->i2c_adap))
964 goto frontend_detach;
965 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
966 dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
967
968 }
969 }
970 break;
971 case CX88_BOARD_TEVII_S460:
972 dev->dvb.frontend = dvb_attach(cx24116_attach,
973 &tevii_s460_config,
974 &core->i2c_adap);
975 if (dev->dvb.frontend != NULL) {
976 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
977 dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
978 }
979 break;
980 case CX88_BOARD_OMICOM_SS4_PCI:
981 case CX88_BOARD_TBS_8920:
982 case CX88_BOARD_PROF_7300:
983 dev->dvb.frontend = dvb_attach(cx24116_attach,
984 &hauppauge_hvr4000_config,
985 &core->i2c_adap);
986 if (dev->dvb.frontend != NULL) {
987 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
988 dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
989 }
990 break;
887 default: 991 default:
888 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 992 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
889 core->name); 993 core->name);
@@ -895,6 +999,8 @@ static int dvb_register(struct cx8802_dev *dev)
895 core->name); 999 core->name);
896 return -EINVAL; 1000 return -EINVAL;
897 } 1001 }
1002 /* define general-purpose callback pointer */
1003 dev->dvb.frontend->callback = cx88_tuner_callback;
898 1004
899 /* Ensure all frontends negotiate bus access */ 1005 /* Ensure all frontends negotiate bus access */
900 dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; 1006 dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index d7406a994f09..8e74d64fdcd2 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -201,7 +201,23 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
201 201
202 core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap); 202 core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap);
203 if (0 == core->i2c_rc) { 203 if (0 == core->i2c_rc) {
204 static u8 tuner_data[] =
205 { 0x0b, 0xdc, 0x86, 0x52 };
206 static struct i2c_msg tuner_msg =
207 { .flags = 0, .addr = 0xc2 >> 1, .buf = tuner_data, .len = 4 };
208
204 dprintk(1, "i2c register ok\n"); 209 dprintk(1, "i2c register ok\n");
210 switch( core->boardnr ) {
211 case CX88_BOARD_HAUPPAUGE_HVR1300:
212 case CX88_BOARD_HAUPPAUGE_HVR3000:
213 case CX88_BOARD_HAUPPAUGE_HVR4000:
214 printk("%s: i2c init: enabling analog demod on HVR1300/3000/4000 tuner\n",
215 core->name);
216 i2c_transfer(core->i2c_client.adapter, &tuner_msg, 1);
217 break;
218 default:
219 break;
220 }
205 if (i2c_scan) 221 if (i2c_scan)
206 do_i2c_scan(core->name,&core->i2c_client); 222 do_i2c_scan(core->name,&core->i2c_client);
207 } else 223 } else
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 53526d997a4e..8683d104de72 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -224,6 +224,8 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
224 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 224 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
225 case CX88_BOARD_HAUPPAUGE_HVR1100: 225 case CX88_BOARD_HAUPPAUGE_HVR1100:
226 case CX88_BOARD_HAUPPAUGE_HVR3000: 226 case CX88_BOARD_HAUPPAUGE_HVR3000:
227 case CX88_BOARD_HAUPPAUGE_HVR4000:
228 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
227 ir_codes = ir_codes_hauppauge_new; 229 ir_codes = ir_codes_hauppauge_new;
228 ir_type = IR_TYPE_RC5; 230 ir_type = IR_TYPE_RC5;
229 ir->sampling = 1; 231 ir->sampling = 1;
@@ -259,6 +261,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
259 ir->polling = 1; /* ms */ 261 ir->polling = 1; /* ms */
260 break; 262 break;
261 case CX88_BOARD_PROLINK_PV_8000GT: 263 case CX88_BOARD_PROLINK_PV_8000GT:
264 case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
262 ir_codes = ir_codes_pixelview_new; 265 ir_codes = ir_codes_pixelview_new;
263 ir->gpio_addr = MO_GP1_IO; 266 ir->gpio_addr = MO_GP1_IO;
264 ir->mask_keycode = 0x3f; 267 ir->mask_keycode = 0x3f;
@@ -392,7 +395,7 @@ void cx88_ir_irq(struct cx88_core *core)
392{ 395{
393 struct cx88_IR *ir = core->ir; 396 struct cx88_IR *ir = core->ir;
394 u32 samples, ircode; 397 u32 samples, ircode;
395 int i; 398 int i, start, range, toggle, dev, code;
396 399
397 if (NULL == ir) 400 if (NULL == ir)
398 return; 401 return;
@@ -461,6 +464,34 @@ void cx88_ir_irq(struct cx88_core *core)
461 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 464 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
462 case CX88_BOARD_HAUPPAUGE_HVR1100: 465 case CX88_BOARD_HAUPPAUGE_HVR1100:
463 case CX88_BOARD_HAUPPAUGE_HVR3000: 466 case CX88_BOARD_HAUPPAUGE_HVR3000:
467 case CX88_BOARD_HAUPPAUGE_HVR4000:
468 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
469 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
470 ir_dprintk("biphase decoded: %x\n", ircode);
471 /*
472 * RC5 has an extension bit which adds a new range
473 * of available codes, this is detected here. Also
474 * hauppauge remotes (black/silver) always use
475 * specific device ids. If we do not filter the
476 * device ids then messages destined for devices
477 * such as TVs (id=0) will get through to the
478 * device causing mis-fired events.
479 */
480 /* split rc5 data block ... */
481 start = (ircode & 0x2000) >> 13;
482 range = (ircode & 0x1000) >> 12;
483 toggle= (ircode & 0x0800) >> 11;
484 dev = (ircode & 0x07c0) >> 6;
485 code = (ircode & 0x003f) | ((range << 6) ^ 0x0040);
486 if( start != 1)
487 /* no key pressed */
488 break;
489 if ( dev != 0x1e && dev != 0x1f )
490 /* not a hauppauge remote */
491 break;
492 ir_input_keydown(ir->input, &ir->ir, code, ircode);
493 ir->release = jiffies + msecs_to_jiffies(120);
494 break;
464 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 495 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
465 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); 496 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
466 ir_dprintk("biphase decoded: %x\n", ircode); 497 ir_dprintk("biphase decoded: %x\n", ircode);
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index ef4d56ea0027..be45955dff68 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -773,6 +773,7 @@ static int video_open(struct inode *inode, struct file *file)
773 enum v4l2_buf_type type = 0; 773 enum v4l2_buf_type type = 0;
774 int radio = 0; 774 int radio = 0;
775 775
776 lock_kernel();
776 list_for_each_entry(h, &cx8800_devlist, devlist) { 777 list_for_each_entry(h, &cx8800_devlist, devlist) {
777 if (h->video_dev->minor == minor) { 778 if (h->video_dev->minor == minor) {
778 dev = h; 779 dev = h;
@@ -788,8 +789,10 @@ static int video_open(struct inode *inode, struct file *file)
788 dev = h; 789 dev = h;
789 } 790 }
790 } 791 }
791 if (NULL == dev) 792 if (NULL == dev) {
793 unlock_kernel();
792 return -ENODEV; 794 return -ENODEV;
795 }
793 796
794 core = dev->core; 797 core = dev->core;
795 798
@@ -798,8 +801,10 @@ static int video_open(struct inode *inode, struct file *file)
798 801
799 /* allocate + initialize per filehandle data */ 802 /* allocate + initialize per filehandle data */
800 fh = kzalloc(sizeof(*fh),GFP_KERNEL); 803 fh = kzalloc(sizeof(*fh),GFP_KERNEL);
801 if (NULL == fh) 804 if (NULL == fh) {
805 unlock_kernel();
802 return -ENOMEM; 806 return -ENOMEM;
807 }
803 file->private_data = fh; 808 file->private_data = fh;
804 fh->dev = dev; 809 fh->dev = dev;
805 fh->radio = radio; 810 fh->radio = radio;
@@ -832,6 +837,9 @@ static int video_open(struct inode *inode, struct file *file)
832 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); 837 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
833 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); 838 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
834 } 839 }
840 unlock_kernel();
841
842 atomic_inc(&core->users);
835 843
836 return 0; 844 return 0;
837} 845}
@@ -920,7 +928,8 @@ static int video_release(struct inode *inode, struct file *file)
920 file->private_data = NULL; 928 file->private_data = NULL;
921 kfree(fh); 929 kfree(fh);
922 930
923 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 931 if(atomic_dec_and_test(&dev->core->users))
932 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
924 933
925 return 0; 934 return 0;
926} 935}
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 54fe65094711..dbf01b8b57a5 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -221,6 +221,14 @@ extern struct sram_channel cx88_sram_channels[];
221#define CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD 65 221#define CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD 65
222#define CX88_BOARD_PROLINK_PV_8000GT 66 222#define CX88_BOARD_PROLINK_PV_8000GT 66
223#define CX88_BOARD_KWORLD_ATSC_120 67 223#define CX88_BOARD_KWORLD_ATSC_120 67
224#define CX88_BOARD_HAUPPAUGE_HVR4000 68
225#define CX88_BOARD_HAUPPAUGE_HVR4000LITE 69
226#define CX88_BOARD_TEVII_S460 70
227#define CX88_BOARD_OMICOM_SS4_PCI 71
228#define CX88_BOARD_TBS_8920 72
229#define CX88_BOARD_TEVII_S420 73
230#define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74
231#define CX88_BOARD_PROF_7300 75
224 232
225enum cx88_itype { 233enum cx88_itype {
226 CX88_VMUX_COMPOSITE1 = 1, 234 CX88_VMUX_COMPOSITE1 = 1,
@@ -342,6 +350,7 @@ struct cx88_core {
342 struct mutex lock; 350 struct mutex lock;
343 /* various v4l controls */ 351 /* various v4l controls */
344 u32 freq; 352 u32 freq;
353 atomic_t users;
345 354
346 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ 355 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
347 struct cx8802_dev *dvbdev; 356 struct cx8802_dev *dvbdev;
@@ -601,7 +610,7 @@ extern void cx88_call_i2c_clients(struct cx88_core *core,
601/* ----------------------------------------------------------- */ 610/* ----------------------------------------------------------- */
602/* cx88-cards.c */ 611/* cx88-cards.c */
603 612
604extern int cx88_tuner_callback(void *dev, int command, int arg); 613extern int cx88_tuner_callback(void *dev, int component, int command, int arg);
605extern int cx88_get_resources(const struct cx88_core *core, 614extern int cx88_get_resources(const struct cx88_core *core,
606 struct pci_dev *pci); 615 struct pci_dev *pci);
607extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); 616extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr);