diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 17:03:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 17:03:59 -0400 |
commit | cf2fa66055d718ae13e62451bb546505f63906a2 (patch) | |
tree | e206d3f04e74a34e9aa88d21af6c26eea21d4121 /drivers/media/video/cx88 | |
parent | 4501a466f28788485604ee42641d7a5fe7258d16 (diff) | |
parent | 57f51dbc45f65f7ee1e8c8f77200bb8000e3e271 (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/Kconfig | 4 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-blackbird.c | 9 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-cards.c | 306 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-dvb.c | 198 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-i2c.c | 16 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-input.c | 33 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-video.c | 15 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 11 |
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 | ||
2330 | int cx88_tuner_callback(void *priv, int command, int arg) | 2565 | int 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 | ||
52 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); | 57 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); |
53 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | 58 | MODULE_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 | ||
378 | static int cx88_pci_nano_callback(void *ptr, int command, int arg) | 383 | static 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 = { | |||
456 | static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { | 452 | static 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 | |||
457 | static struct zl10353_config cx88_pinnacle_hybrid_pctv = { | ||
458 | .demod_address = (0x1e >> 1), | ||
459 | .no_tuner = 1, | ||
460 | .if2 = 45600, | ||
460 | }; | 461 | }; |
461 | 462 | ||
462 | static struct zl10353_config cx88_geniatech_x8000_mt = { | 463 | static struct zl10353_config cx88_geniatech_x8000_mt = { |
@@ -477,7 +478,6 @@ static struct s5h1411_config dvico_fusionhdtv7_config = { | |||
477 | static struct xc5000_config dvico_fusionhdtv7_tuner_config = { | 478 | static 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 | ||
483 | static int attach_xc3028(u8 addr, struct cx8802_dev *dev) | 483 | static 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 | ||
520 | static 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 | |||
529 | static 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 | |||
543 | static 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 | |||
549 | static 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 | |||
555 | static 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 | |||
568 | static 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 | |||
521 | static int dvb_register(struct cx8802_dev *dev) | 574 | static 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 | ||
225 | enum cx88_itype { | 233 | enum 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 | ||
604 | extern int cx88_tuner_callback(void *dev, int command, int arg); | 613 | extern int cx88_tuner_callback(void *dev, int component, int command, int arg); |
605 | extern int cx88_get_resources(const struct cx88_core *core, | 614 | extern int cx88_get_resources(const struct cx88_core *core, |
606 | struct pci_dev *pci); | 615 | struct pci_dev *pci); |
607 | extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); | 616 | extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); |