diff options
author | Trent Piepho <xyzzy@speakeasy.org> | 2007-08-15 13:41:58 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 21:05:16 -0400 |
commit | bbc83597dfe3093b161014e6ebb351279eabaa7c (patch) | |
tree | 57514dd42f55d6dec350648a7bdaa1a3266daf68 /drivers/media/video/cx88/cx88-cards.c | |
parent | 6a59d64c5cc302e0139ddb1f5e57afceecb14368 (diff) |
V4L/DVB (6022): cx88: Move card core creation from cx88-core.c to cx88-cards.c
A lot of code in cx88-cards.c was only used by cx88-core.c when the core state
is first allocated and initialized. Moving that task to cx88-cards makes the
driver simpler and the files more self contained.
- Module parameters tuner, radio, card, and latency move to cx88-cards.c
- cx88_boards is made static
- cx88_subids is made static and const
- cx88_bcount is eliminated
- cx88_idcount is eliminated
- cx88_card_list() is made static
- cx88_card_setup_pre_i2c() is made static
- cx88_card_setup() is made static
- cx88_pci_quirks() is moved from cx88-core to cx88-cards
The function argument "char *name" is made const too
- get_ressources() is moved from cx88-core to cx88-cards, and renamed to
cx88_get_resources()
- The code to allocate and initialize the core state struct and the chip is
moved out of cx88-core.c:cx88_get_core() and into a new function in
cx88-cards.c, cx88_core_create(). This makes both functions simpler.
Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/cx88/cx88-cards.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-cards.c | 168 |
1 files changed, 160 insertions, 8 deletions
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 8be90ad4e910..6204a453c11e 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 | ||
30 | static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; | ||
31 | static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; | ||
32 | static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; | ||
33 | |||
34 | module_param_array(tuner, int, NULL, 0444); | ||
35 | module_param_array(radio, int, NULL, 0444); | ||
36 | module_param_array(card, int, NULL, 0444); | ||
37 | |||
38 | MODULE_PARM_DESC(tuner,"tuner type"); | ||
39 | MODULE_PARM_DESC(radio,"radio tuner type"); | ||
40 | MODULE_PARM_DESC(card,"card type"); | ||
41 | |||
42 | static unsigned int latency = UNSET; | ||
43 | module_param(latency,int,0444); | ||
44 | MODULE_PARM_DESC(latency,"pci latency timer"); | ||
45 | |||
30 | /* ------------------------------------------------------------------ */ | 46 | /* ------------------------------------------------------------------ */ |
31 | /* board config info */ | 47 | /* board config info */ |
32 | 48 | ||
33 | const struct cx88_board cx88_boards[] = { | 49 | static 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, |
@@ -1355,12 +1371,11 @@ const struct cx88_board cx88_boards[] = { | |||
1355 | }}, | 1371 | }}, |
1356 | }, | 1372 | }, |
1357 | }; | 1373 | }; |
1358 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); | ||
1359 | 1374 | ||
1360 | /* ------------------------------------------------------------------ */ | 1375 | /* ------------------------------------------------------------------ */ |
1361 | /* PCI subsystem IDs */ | 1376 | /* PCI subsystem IDs */ |
1362 | 1377 | ||
1363 | struct cx88_subid cx88_subids[] = { | 1378 | static const struct cx88_subid cx88_subids[] = { |
1364 | { | 1379 | { |
1365 | .subvendor = 0x0070, | 1380 | .subvendor = 0x0070, |
1366 | .subdevice = 0x3400, | 1381 | .subdevice = 0x3400, |
@@ -1666,7 +1681,6 @@ struct cx88_subid cx88_subids[] = { | |||
1666 | .card = CX88_BOARD_ADSTECH_PTV_390, | 1681 | .card = CX88_BOARD_ADSTECH_PTV_390, |
1667 | }, | 1682 | }, |
1668 | }; | 1683 | }; |
1669 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); | ||
1670 | 1684 | ||
1671 | /* ----------------------------------------------------------------------- */ | 1685 | /* ----------------------------------------------------------------------- */ |
1672 | /* some leadtek specific stuff */ | 1686 | /* some leadtek specific stuff */ |
@@ -1833,7 +1847,7 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core) | |||
1833 | 1847 | ||
1834 | /* ----------------------------------------------------------------------- */ | 1848 | /* ----------------------------------------------------------------------- */ |
1835 | 1849 | ||
1836 | void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) | 1850 | static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) |
1837 | { | 1851 | { |
1838 | int i; | 1852 | int i; |
1839 | 1853 | ||
@@ -1854,12 +1868,12 @@ 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 | ||
1862 | void cx88_card_setup_pre_i2c(struct cx88_core *core) | 1876 | static void cx88_card_setup_pre_i2c(struct cx88_core *core) |
1863 | { | 1877 | { |
1864 | switch (core->boardnr) { | 1878 | switch (core->boardnr) { |
1865 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 1879 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
@@ -1875,7 +1889,7 @@ void cx88_card_setup_pre_i2c(struct cx88_core *core) | |||
1875 | } | 1889 | } |
1876 | } | 1890 | } |
1877 | 1891 | ||
1878 | void cx88_card_setup(struct cx88_core *core) | 1892 | static void cx88_card_setup(struct cx88_core *core) |
1879 | { | 1893 | { |
1880 | static u8 eeprom[256]; | 1894 | static u8 eeprom[256]; |
1881 | 1895 | ||
@@ -1970,6 +1984,144 @@ void cx88_card_setup(struct cx88_core *core) | |||
1970 | 1984 | ||
1971 | /* ------------------------------------------------------------------ */ | 1985 | /* ------------------------------------------------------------------ */ |
1972 | 1986 | ||
1987 | static 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 | |||
2040 | int 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. */ | ||
2056 | struct 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 = 0x00fc00; | ||
2067 | mutex_init(&core->lock); | ||
2068 | |||
2069 | core->nr = nr; | ||
2070 | sprintf(core->name, "cx88[%d]", core->nr); | ||
2071 | if (0 != cx88_get_resources(core, pci)) { | ||
2072 | kfree(core); | ||
2073 | return NULL; | ||
2074 | } | ||
2075 | |||
2076 | /* PCI stuff */ | ||
2077 | cx88_pci_quirks(core->name, pci); | ||
2078 | core->lmmio = ioremap(pci_resource_start(pci, 0), | ||
2079 | pci_resource_len(pci, 0)); | ||
2080 | core->bmmio = (u8 __iomem *)core->lmmio; | ||
2081 | |||
2082 | /* board config */ | ||
2083 | core->boardnr = UNSET; | ||
2084 | if (card[core->nr] < ARRAY_SIZE(cx88_boards)) | ||
2085 | core->boardnr = card[core->nr]; | ||
2086 | for (i = 0; UNSET == core->boardnr && i < ARRAY_SIZE(cx88_subids); i++) | ||
2087 | if (pci->subsystem_vendor == cx88_subids[i].subvendor && | ||
2088 | pci->subsystem_device == cx88_subids[i].subdevice) | ||
2089 | core->boardnr = cx88_subids[i].card; | ||
2090 | if (UNSET == core->boardnr) { | ||
2091 | core->boardnr = CX88_BOARD_UNKNOWN; | ||
2092 | cx88_card_list(core, pci); | ||
2093 | } | ||
2094 | |||
2095 | memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); | ||
2096 | |||
2097 | printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", | ||
2098 | core->name,pci->subsystem_vendor, | ||
2099 | pci->subsystem_device, core->board.name, | ||
2100 | core->boardnr, card[core->nr] == core->boardnr ? | ||
2101 | "insmod option" : "autodetected"); | ||
2102 | |||
2103 | if (tuner[core->nr] != UNSET) | ||
2104 | core->board.tuner_type = tuner[core->nr]; | ||
2105 | if (radio[core->nr] != UNSET) | ||
2106 | core->board.radio_type = radio[core->nr]; | ||
2107 | |||
2108 | printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", | ||
2109 | core->board.tuner_type, core->board.tuner_addr<<1, | ||
2110 | core->board.radio_type, core->board.radio_addr<<1); | ||
2111 | |||
2112 | /* init hardware */ | ||
2113 | cx88_reset(core); | ||
2114 | cx88_card_setup_pre_i2c(core); | ||
2115 | cx88_i2c_init(core, pci); | ||
2116 | cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL); | ||
2117 | cx88_card_setup(core); | ||
2118 | cx88_ir_init(core, pci); | ||
2119 | |||
2120 | return core; | ||
2121 | } | ||
2122 | |||
2123 | /* ------------------------------------------------------------------ */ | ||
2124 | |||
1973 | /* | 2125 | /* |
1974 | * Local variables: | 2126 | * Local variables: |
1975 | * c-basic-offset: 8 | 2127 | * c-basic-offset: 8 |