aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-cards.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx88/cx88-cards.c')
-rw-r--r--drivers/media/video/cx88/cx88-cards.c219
1 files changed, 184 insertions, 35 deletions
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 6a136ddbccf8..a4eb6a87a761 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -27,10 +27,26 @@
27 27
28#include "cx88.h" 28#include "cx88.h"
29 29
30static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
31static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
32static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
33
34module_param_array(tuner, int, NULL, 0444);
35module_param_array(radio, int, NULL, 0444);
36module_param_array(card, int, NULL, 0444);
37
38MODULE_PARM_DESC(tuner,"tuner type");
39MODULE_PARM_DESC(radio,"radio tuner type");
40MODULE_PARM_DESC(card,"card type");
41
42static unsigned int latency = UNSET;
43module_param(latency,int,0444);
44MODULE_PARM_DESC(latency,"pci latency timer");
45
30/* ------------------------------------------------------------------ */ 46/* ------------------------------------------------------------------ */
31/* board config info */ 47/* board config info */
32 48
33struct cx88_board cx88_boards[] = { 49static const struct cx88_board cx88_boards[] = {
34 [CX88_BOARD_UNKNOWN] = { 50 [CX88_BOARD_UNKNOWN] = {
35 .name = "UNKNOWN/GENERIC", 51 .name = "UNKNOWN/GENERIC",
36 .tuner_type = UNSET, 52 .tuner_type = UNSET,
@@ -575,35 +591,34 @@ struct cx88_board cx88_boards[] = {
575 .tuner_addr = ADDR_UNSET, 591 .tuner_addr = ADDR_UNSET,
576 .radio_addr = ADDR_UNSET, 592 .radio_addr = ADDR_UNSET,
577 .tda9887_conf = TDA9887_PRESENT, 593 .tda9887_conf = TDA9887_PRESENT,
594 /* GPIO[2] = audio source for analog audio out connector
595 * 0 = analog audio input connector
596 * 1 = CX88 audio DACs
597 *
598 * GPIO[7] = input to CX88's audio/chroma ADC
599 * 0 = FM 10.7 MHz IF
600 * 1 = Sound 4.5 MHz IF
601 *
602 * GPIO[1,5,6] = Oren 51132 pins 27,35,28 respectively
603 *
604 * GPIO[16] = Remote control input
605 */
578 .input = {{ 606 .input = {{
579 .type = CX88_VMUX_TELEVISION, 607 .type = CX88_VMUX_TELEVISION,
580 .vmux = 0, 608 .vmux = 0,
581 .gpio0 = 0x00008484, 609 .gpio0 = 0x00008484,
582 .gpio1 = 0x00000000,
583 .gpio2 = 0x00000000,
584 .gpio3 = 0x00000000,
585 },{ 610 },{
586 .type = CX88_VMUX_COMPOSITE1, 611 .type = CX88_VMUX_COMPOSITE1,
587 .vmux = 1, 612 .vmux = 1,
588 .gpio0 = 0x00008400, 613 .gpio0 = 0x00008400,
589 .gpio1 = 0x00000000,
590 .gpio2 = 0x00000000,
591 .gpio3 = 0x00000000,
592 },{ 614 },{
593 .type = CX88_VMUX_SVIDEO, 615 .type = CX88_VMUX_SVIDEO,
594 .vmux = 2, 616 .vmux = 2,
595 .gpio0 = 0x00008400, 617 .gpio0 = 0x00008400,
596 .gpio1 = 0x00000000,
597 .gpio2 = 0x00000000,
598 .gpio3 = 0x00000000,
599 }}, 618 }},
600 .radio = { 619 .radio = {
601 .type = CX88_RADIO, 620 .type = CX88_RADIO,
602 .vmux = 2, 621 .gpio0 = 0x00008404,
603 .gpio0 = 0x00008400,
604 .gpio1 = 0x00000000,
605 .gpio2 = 0x00000000,
606 .gpio3 = 0x00000000,
607 }, 622 },
608 .mpeg = CX88_MPEG_DVB, 623 .mpeg = CX88_MPEG_DVB,
609 }, 624 },
@@ -1356,12 +1371,11 @@ struct cx88_board cx88_boards[] = {
1356 }}, 1371 }},
1357 }, 1372 },
1358}; 1373};
1359const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
1360 1374
1361/* ------------------------------------------------------------------ */ 1375/* ------------------------------------------------------------------ */
1362/* PCI subsystem IDs */ 1376/* PCI subsystem IDs */
1363 1377
1364struct cx88_subid cx88_subids[] = { 1378static const struct cx88_subid cx88_subids[] = {
1365 { 1379 {
1366 .subvendor = 0x0070, 1380 .subvendor = 0x0070,
1367 .subdevice = 0x3400, 1381 .subdevice = 0x3400,
@@ -1667,7 +1681,6 @@ struct cx88_subid cx88_subids[] = {
1667 .card = CX88_BOARD_ADSTECH_PTV_390, 1681 .card = CX88_BOARD_ADSTECH_PTV_390,
1668 }, 1682 },
1669}; 1683};
1670const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
1671 1684
1672/* ----------------------------------------------------------------------- */ 1685/* ----------------------------------------------------------------------- */
1673/* some leadtek specific stuff */ 1686/* some leadtek specific stuff */
@@ -1688,12 +1701,12 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
1688 return; 1701 return;
1689 } 1702 }
1690 1703
1691 core->has_radio = 1; 1704 core->board.tuner_type = (eeprom_data[6] == 0x13) ?
1692 core->tuner_type = (eeprom_data[6] == 0x13) ? 43 : 38; 1705 TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3;
1693 1706
1694 printk(KERN_INFO "%s: Leadtek Winfast 2000XP Expert config: " 1707 printk(KERN_INFO "%s: Leadtek Winfast 2000XP Expert config: "
1695 "tuner=%d, eeprom[0]=0x%02x\n", 1708 "tuner=%d, eeprom[0]=0x%02x\n",
1696 core->name, core->tuner_type, eeprom_data[0]); 1709 core->name, core->board.tuner_type, eeprom_data[0]);
1697} 1710}
1698 1711
1699static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) 1712static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
@@ -1701,9 +1714,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
1701 struct tveeprom tv; 1714 struct tveeprom tv;
1702 1715
1703 tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data); 1716 tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
1704 core->tuner_type = tv.tuner_type; 1717 core->board.tuner_type = tv.tuner_type;
1705 core->tuner_formats = tv.tuner_formats; 1718 core->tuner_formats = tv.tuner_formats;
1706 core->has_radio = tv.has_radio; 1719 core->board.radio.type = tv.has_radio ? CX88_RADIO : 0;
1707 1720
1708 /* Make sure we support the board model */ 1721 /* Make sure we support the board model */
1709 switch (tv.model) 1722 switch (tv.model)
@@ -1793,8 +1806,9 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
1793 name ? name : "unknown"); 1806 name ? name : "unknown");
1794 if (NULL == name) 1807 if (NULL == name)
1795 return; 1808 return;
1796 core->tuner_type = gdi_tuner[eeprom_data[0x0d]].id; 1809 core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id;
1797 core->has_radio = gdi_tuner[eeprom_data[0x0d]].fm; 1810 core->board.radio.type = gdi_tuner[eeprom_data[0x0d]].fm ?
1811 CX88_RADIO : 0;
1798} 1812}
1799 1813
1800/* ----------------------------------------------------------------------- */ 1814/* ----------------------------------------------------------------------- */
@@ -1833,7 +1847,7 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
1833 1847
1834/* ----------------------------------------------------------------------- */ 1848/* ----------------------------------------------------------------------- */
1835 1849
1836void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) 1850static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
1837{ 1851{
1838 int i; 1852 int i;
1839 1853
@@ -1854,14 +1868,14 @@ void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
1854 } 1868 }
1855 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", 1869 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
1856 core->name); 1870 core->name);
1857 for (i = 0; i < cx88_bcount; i++) 1871 for (i = 0; i < ARRAY_SIZE(cx88_boards); i++)
1858 printk("%s: card=%d -> %s\n", 1872 printk("%s: card=%d -> %s\n",
1859 core->name, i, cx88_boards[i].name); 1873 core->name, i, cx88_boards[i].name);
1860} 1874}
1861 1875
1862void cx88_card_setup_pre_i2c(struct cx88_core *core) 1876static void cx88_card_setup_pre_i2c(struct cx88_core *core)
1863{ 1877{
1864 switch (core->board) { 1878 switch (core->boardnr) {
1865 case CX88_BOARD_HAUPPAUGE_HVR1300: 1879 case CX88_BOARD_HAUPPAUGE_HVR1300:
1866 /* Bring the 702 demod up before i2c scanning/attach or devices are hidden */ 1880 /* Bring the 702 demod up before i2c scanning/attach or devices are hidden */
1867 /* We leave here with the 702 on the bus */ 1881 /* We leave here with the 702 on the bus */
@@ -1875,7 +1889,7 @@ void cx88_card_setup_pre_i2c(struct cx88_core *core)
1875 } 1889 }
1876} 1890}
1877 1891
1878void cx88_card_setup(struct cx88_core *core) 1892static void cx88_card_setup(struct cx88_core *core)
1879{ 1893{
1880 static u8 eeprom[256]; 1894 static u8 eeprom[256];
1881 1895
@@ -1884,7 +1898,7 @@ void cx88_card_setup(struct cx88_core *core)
1884 tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom)); 1898 tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom));
1885 } 1899 }
1886 1900
1887 switch (core->board) { 1901 switch (core->boardnr) {
1888 case CX88_BOARD_HAUPPAUGE: 1902 case CX88_BOARD_HAUPPAUGE:
1889 case CX88_BOARD_HAUPPAUGE_ROSLYN: 1903 case CX88_BOARD_HAUPPAUGE_ROSLYN:
1890 if (0 == core->i2c_rc) 1904 if (0 == core->i2c_rc)
@@ -1928,7 +1942,7 @@ void cx88_card_setup(struct cx88_core *core)
1928 msleep(1); 1942 msleep(1);
1929 cx_set(MO_GP0_IO, 0x00000101); 1943 cx_set(MO_GP0_IO, 0x00000101);
1930 if (0 == core->i2c_rc && 1944 if (0 == core->i2c_rc &&
1931 core->board == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID) 1945 core->boardnr == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID)
1932 dvico_fusionhdtv_hybrid_init(core); 1946 dvico_fusionhdtv_hybrid_init(core);
1933 break; 1947 break;
1934 case CX88_BOARD_KWORLD_DVB_T: 1948 case CX88_BOARD_KWORLD_DVB_T:
@@ -1966,13 +1980,148 @@ void cx88_card_setup(struct cx88_core *core)
1966 } 1980 }
1967 break; 1981 break;
1968 } 1982 }
1969 if (cx88_boards[core->board].radio.type == CX88_RADIO)
1970 core->has_radio = 1;
1971} 1983}
1972 1984
1973/* ------------------------------------------------------------------ */ 1985/* ------------------------------------------------------------------ */
1974 1986
1975EXPORT_SYMBOL(cx88_boards); 1987static int cx88_pci_quirks(const char *name, struct pci_dev *pci)
1988{
1989 unsigned int lat = UNSET;
1990 u8 ctrl = 0;
1991 u8 value;
1992
1993 /* check pci quirks */
1994 if (pci_pci_problems & PCIPCI_TRITON) {
1995 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
1996 name);
1997 ctrl |= CX88X_EN_TBFX;
1998 }
1999 if (pci_pci_problems & PCIPCI_NATOMA) {
2000 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
2001 name);
2002 ctrl |= CX88X_EN_TBFX;
2003 }
2004 if (pci_pci_problems & PCIPCI_VIAETBF) {
2005 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
2006 name);
2007 ctrl |= CX88X_EN_TBFX;
2008 }
2009 if (pci_pci_problems & PCIPCI_VSFX) {
2010 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
2011 name);
2012 ctrl |= CX88X_EN_VSFX;
2013 }
2014#ifdef PCIPCI_ALIMAGIK
2015 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
2016 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
2017 name);
2018 lat = 0x0A;
2019 }
2020#endif
2021
2022 /* check insmod options */
2023 if (UNSET != latency)
2024 lat = latency;
2025
2026 /* apply stuff */
2027 if (ctrl) {
2028 pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
2029 value |= ctrl;
2030 pci_write_config_byte(pci, CX88X_DEVCTRL, value);
2031 }
2032 if (UNSET != lat) {
2033 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
2034 name, latency);
2035 pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
2036 }
2037 return 0;
2038}
2039
2040int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci)
2041{
2042 if (request_mem_region(pci_resource_start(pci,0),
2043 pci_resource_len(pci,0),
2044 core->name))
2045 return 0;
2046 printk(KERN_ERR
2047 "%s/%d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n",
2048 core->name, PCI_FUNC(pci->devfn),
2049 (unsigned long long)pci_resource_start(pci, 0),
2050 pci->subsystem_vendor, pci->subsystem_device);
2051 return -EBUSY;
2052}
2053
2054/* Allocate and initialize the cx88 core struct. One should hold the
2055 * devlist mutex before calling this. */
2056struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
2057{
2058 struct cx88_core *core;
2059 int i;
2060
2061 core = kzalloc(sizeof(*core), GFP_KERNEL);
2062
2063 atomic_inc(&core->refcount);
2064 core->pci_bus = pci->bus->number;
2065 core->pci_slot = PCI_SLOT(pci->devfn);
2066 core->pci_irqmask = PCI_INT_RISC_RD_BERRINT | PCI_INT_RISC_WR_BERRINT |
2067 PCI_INT_BRDG_BERRINT | PCI_INT_SRC_DMA_BERRINT |
2068 PCI_INT_DST_DMA_BERRINT | PCI_INT_IPB_DMA_BERRINT;
2069 mutex_init(&core->lock);
2070
2071 core->nr = nr;
2072 sprintf(core->name, "cx88[%d]", core->nr);
2073 if (0 != cx88_get_resources(core, pci)) {
2074 kfree(core);
2075 return NULL;
2076 }
2077
2078 /* PCI stuff */
2079 cx88_pci_quirks(core->name, pci);
2080 core->lmmio = ioremap(pci_resource_start(pci, 0),
2081 pci_resource_len(pci, 0));
2082 core->bmmio = (u8 __iomem *)core->lmmio;
2083
2084 /* board config */
2085 core->boardnr = UNSET;
2086 if (card[core->nr] < ARRAY_SIZE(cx88_boards))
2087 core->boardnr = card[core->nr];
2088 for (i = 0; UNSET == core->boardnr && i < ARRAY_SIZE(cx88_subids); i++)
2089 if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
2090 pci->subsystem_device == cx88_subids[i].subdevice)
2091 core->boardnr = cx88_subids[i].card;
2092 if (UNSET == core->boardnr) {
2093 core->boardnr = CX88_BOARD_UNKNOWN;
2094 cx88_card_list(core, pci);
2095 }
2096
2097 memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
2098
2099 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
2100 core->name,pci->subsystem_vendor,
2101 pci->subsystem_device, core->board.name,
2102 core->boardnr, card[core->nr] == core->boardnr ?
2103 "insmod option" : "autodetected");
2104
2105 if (tuner[core->nr] != UNSET)
2106 core->board.tuner_type = tuner[core->nr];
2107 if (radio[core->nr] != UNSET)
2108 core->board.radio_type = radio[core->nr];
2109
2110 printk(KERN_INFO "%s: TV tuner type %d, Radio tuner type %d\n",
2111 core->name, core->board.tuner_type, core->board.radio_type);
2112
2113 /* init hardware */
2114 cx88_reset(core);
2115 cx88_card_setup_pre_i2c(core);
2116 cx88_i2c_init(core, pci);
2117 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
2118 cx88_card_setup(core);
2119 cx88_ir_init(core, pci);
2120
2121 return core;
2122}
2123
2124/* ------------------------------------------------------------------ */
1976 2125
1977/* 2126/*
1978 * Local variables: 2127 * Local variables: