diff options
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/cx88/cx88-cards.c | 168 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-core.c | 163 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 12 |
3 files changed, 172 insertions, 171 deletions
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 8be90ad4e91..6204a453c11 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -27,10 +27,26 @@ #include "cx88.h" +static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; +static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; +static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; + +module_param_array(tuner, int, NULL, 0444); +module_param_array(radio, int, NULL, 0444); +module_param_array(card, int, NULL, 0444); + +MODULE_PARM_DESC(tuner,"tuner type"); +MODULE_PARM_DESC(radio,"radio tuner type"); +MODULE_PARM_DESC(card,"card type"); + +static unsigned int latency = UNSET; +module_param(latency,int,0444); +MODULE_PARM_DESC(latency,"pci latency timer"); + /* ------------------------------------------------------------------ */ /* board config info */ -const struct cx88_board cx88_boards[] = { +static const struct cx88_board cx88_boards[] = { [CX88_BOARD_UNKNOWN] = { .name = "UNKNOWN/GENERIC", .tuner_type = UNSET, @@ -1355,12 +1371,11 @@ const struct cx88_board cx88_boards[] = { }}, }, }; -const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); /* ------------------------------------------------------------------ */ /* PCI subsystem IDs */ -struct cx88_subid cx88_subids[] = { +static const struct cx88_subid cx88_subids[] = { { .subvendor = 0x0070, .subdevice = 0x3400, @@ -1666,7 +1681,6 @@ struct cx88_subid cx88_subids[] = { .card = CX88_BOARD_ADSTECH_PTV_390, }, }; -const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); /* ----------------------------------------------------------------------- */ /* some leadtek specific stuff */ @@ -1833,7 +1847,7 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core) /* ----------------------------------------------------------------------- */ -void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) +static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) { int i; @@ -1854,12 +1868,12 @@ void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) } printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", core->name); - for (i = 0; i < cx88_bcount; i++) + for (i = 0; i < ARRAY_SIZE(cx88_boards); i++) printk("%s: card=%d -> %s\n", core->name, i, cx88_boards[i].name); } -void cx88_card_setup_pre_i2c(struct cx88_core *core) +static void cx88_card_setup_pre_i2c(struct cx88_core *core) { switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: @@ -1875,7 +1889,7 @@ void cx88_card_setup_pre_i2c(struct cx88_core *core) } } -void cx88_card_setup(struct cx88_core *core) +static void cx88_card_setup(struct cx88_core *core) { static u8 eeprom[256]; @@ -1970,6 +1984,144 @@ void cx88_card_setup(struct cx88_core *core) /* ------------------------------------------------------------------ */ +static int cx88_pci_quirks(const char *name, struct pci_dev *pci) +{ + unsigned int lat = UNSET; + u8 ctrl = 0; + u8 value; + + /* check pci quirks */ + if (pci_pci_problems & PCIPCI_TRITON) { + printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n", + name); + ctrl |= CX88X_EN_TBFX; + } + if (pci_pci_problems & PCIPCI_NATOMA) { + printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n", + name); + ctrl |= CX88X_EN_TBFX; + } + if (pci_pci_problems & PCIPCI_VIAETBF) { + printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n", + name); + ctrl |= CX88X_EN_TBFX; + } + if (pci_pci_problems & PCIPCI_VSFX) { + printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n", + name); + ctrl |= CX88X_EN_VSFX; + } +#ifdef PCIPCI_ALIMAGIK + if (pci_pci_problems & PCIPCI_ALIMAGIK) { + printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n", + name); + lat = 0x0A; + } +#endif + + /* check insmod options */ + if (UNSET != latency) + lat = latency; + + /* apply stuff */ + if (ctrl) { + pci_read_config_byte(pci, CX88X_DEVCTRL, &value); + value |= ctrl; + pci_write_config_byte(pci, CX88X_DEVCTRL, value); + } + if (UNSET != lat) { + printk(KERN_INFO "%s: setting pci latency timer to %d\n", + name, latency); + pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency); + } + return 0; +} + +int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci) +{ + if (request_mem_region(pci_resource_start(pci,0), + pci_resource_len(pci,0), + core->name)) + return 0; + printk(KERN_ERR + "%s/%d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n", + core->name, PCI_FUNC(pci->devfn), + (unsigned long long)pci_resource_start(pci, 0), + pci->subsystem_vendor, pci->subsystem_device); + return -EBUSY; +} + +/* Allocate and initialize the cx88 core struct. One should hold the + * devlist mutex before calling this. */ +struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) +{ + struct cx88_core *core; + int i; + + core = kzalloc(sizeof(*core), GFP_KERNEL); + + atomic_inc(&core->refcount); + core->pci_bus = pci->bus->number; + core->pci_slot = PCI_SLOT(pci->devfn); + core->pci_irqmask = 0x00fc00; + mutex_init(&core->lock); + + core->nr = nr; + sprintf(core->name, "cx88[%d]", core->nr); + if (0 != cx88_get_resources(core, pci)) { + kfree(core); + return NULL; + } + + /* PCI stuff */ + cx88_pci_quirks(core->name, pci); + core->lmmio = ioremap(pci_resource_start(pci, 0), + pci_resource_len(pci, 0)); + core->bmmio = (u8 __iomem *)core->lmmio; + + /* board config */ + core->boardnr = UNSET; + if (card[core->nr] < ARRAY_SIZE(cx88_boards)) + core->boardnr = card[core->nr]; + for (i = 0; UNSET == core->boardnr && i < ARRAY_SIZE(cx88_subids); i++) + if (pci->subsystem_vendor == cx88_subids[i].subvendor && + pci->subsystem_device == cx88_subids[i].subdevice) + core->boardnr = cx88_subids[i].card; + if (UNSET == core->boardnr) { + core->boardnr = CX88_BOARD_UNKNOWN; + cx88_card_list(core, pci); + } + + memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); + + printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", + core->name,pci->subsystem_vendor, + pci->subsystem_device, core->board.name, + core->boardnr, card[core->nr] == core->boardnr ? + "insmod option" : "autodetected"); + + if (tuner[core->nr] != UNSET) + core->board.tuner_type = tuner[core->nr]; + if (radio[core->nr] != UNSET) + core->board.radio_type = radio[core->nr]; + + printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", + core->board.tuner_type, core->board.tuner_addr<<1, + core->board.radio_type, core->board.radio_addr<<1); + + /* init hardware */ + cx88_reset(core); + cx88_card_setup_pre_i2c(core); + cx88_i2c_init(core, pci); + cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL); + cx88_card_setup(core); + cx88_ir_init(core, pci); + + return core; +} + +/* ------------------------------------------------------------------ */ + /* * Local variables: * c-basic-offset: 8 diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index ece788bd3d5..0765e9db533 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -52,22 +52,6 @@ static unsigned int core_debug = 0; module_param(core_debug,int,0644); MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); -static unsigned int latency = UNSET; -module_param(latency,int,0444); -MODULE_PARM_DESC(latency,"pci latency timer"); - -static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; -static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; -static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; - -module_param_array(tuner, int, NULL, 0444); -module_param_array(radio, int, NULL, 0444); -module_param_array(card, int, NULL, 0444); - -MODULE_PARM_DESC(tuner,"tuner type"); -MODULE_PARM_DESC(radio,"radio tuner type"); -MODULE_PARM_DESC(card,"card type"); - static unsigned int nicam = 0; module_param(nicam,int,0644); MODULE_PARM_DESC(nicam,"tv audio is nicam"); @@ -997,61 +981,6 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) /* ------------------------------------------------------------------ */ -static int cx88_pci_quirks(char *name, struct pci_dev *pci) -{ - unsigned int lat = UNSET; - u8 ctrl = 0; - u8 value; - - /* check pci quirks */ - if (pci_pci_problems & PCIPCI_TRITON) { - printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n", - name); - ctrl |= CX88X_EN_TBFX; - } - if (pci_pci_problems & PCIPCI_NATOMA) { - printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n", - name); - ctrl |= CX88X_EN_TBFX; - } - if (pci_pci_problems & PCIPCI_VIAETBF) { - printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n", - name); - ctrl |= CX88X_EN_TBFX; - } - if (pci_pci_problems & PCIPCI_VSFX) { - printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n", - name); - ctrl |= CX88X_EN_VSFX; - } -#ifdef PCIPCI_ALIMAGIK - if (pci_pci_problems & PCIPCI_ALIMAGIK) { - printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n", - name); - lat = 0x0A; - } -#endif - - /* check insmod options */ - if (UNSET != latency) - lat = latency; - - /* apply stuff */ - if (ctrl) { - pci_read_config_byte(pci, CX88X_DEVCTRL, &value); - value |= ctrl; - pci_write_config_byte(pci, CX88X_DEVCTRL, value); - } - if (UNSET != lat) { - printk(KERN_INFO "%s: setting pci latency timer to %d\n", - name, latency); - pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency); - } - return 0; -} - -/* ------------------------------------------------------------------ */ - struct video_device *cx88_vdev_init(struct cx88_core *core, struct pci_dev *pci, struct video_device *template, @@ -1071,25 +1000,10 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, return vfd; } -static int get_ressources(struct cx88_core *core, struct pci_dev *pci) -{ - if (request_mem_region(pci_resource_start(pci,0), - pci_resource_len(pci,0), - core->name)) - return 0; - printk(KERN_ERR - "%s/%d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n", - core->name, PCI_FUNC(pci->devfn), - (unsigned long long)pci_resource_start(pci, 0), - pci->subsystem_vendor, pci->subsystem_device); - return -EBUSY; -} - struct cx88_core* cx88_core_get(struct pci_dev *pci) { struct cx88_core *core; struct list_head *item; - int i; mutex_lock(&devlist); list_for_each(item,&cx88_devlist) { @@ -1099,82 +1013,23 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) if (PCI_SLOT(pci->devfn) != core->pci_slot) continue; - if (0 != get_ressources(core,pci)) - goto fail_unlock; + if (0 != cx88_get_resources(core, pci)) { + mutex_unlock(&devlist); + return NULL; + } atomic_inc(&core->refcount); mutex_unlock(&devlist); return core; } - core = kzalloc(sizeof(*core),GFP_KERNEL); - if (NULL == core) - goto fail_unlock; - - atomic_inc(&core->refcount); - core->pci_bus = pci->bus->number; - core->pci_slot = PCI_SLOT(pci->devfn); - core->pci_irqmask = 0x00fc00; - mutex_init(&core->lock); - - core->nr = cx88_devcount++; - sprintf(core->name,"cx88[%d]",core->nr); - if (0 != get_ressources(core,pci)) { - cx88_devcount--; - goto fail_free; - } - list_add_tail(&core->devlist,&cx88_devlist); - - /* PCI stuff */ - cx88_pci_quirks(core->name, pci); - core->lmmio = ioremap(pci_resource_start(pci,0), - pci_resource_len(pci,0)); - core->bmmio = (u8 __iomem *)core->lmmio; - - /* board config */ - core->boardnr = UNSET; - if (card[core->nr] < cx88_bcount) - core->boardnr = card[core->nr]; - for (i = 0; UNSET == core->boardnr && i < cx88_idcount; i++) - if (pci->subsystem_vendor == cx88_subids[i].subvendor && - pci->subsystem_device == cx88_subids[i].subdevice) - core->boardnr = cx88_subids[i].card; - if (UNSET == core->boardnr) { - core->boardnr = CX88_BOARD_UNKNOWN; - cx88_card_list(core,pci); - } - memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); - - printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", - core->name,pci->subsystem_vendor, - pci->subsystem_device, core->board.name, - core->boardnr, card[core->nr] == core->boardnr ? - "insmod option" : "autodetected"); - - if (tuner[core->nr] != UNSET) - core->board.tuner_type = tuner[core->nr]; - if (radio[core->nr] != UNSET) - core->board.radio_type = radio[core->nr]; - - printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", - core->board.tuner_type, core->board.tuner_addr<<1, - core->board.radio_type, core->board.radio_addr<<1); - - /* init hardware */ - cx88_reset(core); - cx88_card_setup_pre_i2c(core); - cx88_i2c_init(core,pci); - cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL); - cx88_card_setup(core); - cx88_ir_init(core,pci); + core = cx88_core_create(pci, cx88_devcount); + if (NULL != core) { + cx88_devcount++; + list_add_tail(&core->devlist, &cx88_devlist); + } mutex_unlock(&devlist); return core; - -fail_free: - kfree(core); -fail_unlock: - mutex_unlock(&devlist); - return NULL; } void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 3636ec26de5..80e49f986fb 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -580,15 +580,9 @@ extern void cx88_call_i2c_clients(struct cx88_core *core, /* ----------------------------------------------------------- */ /* cx88-cards.c */ -extern const struct cx88_board cx88_boards[]; -extern const unsigned int cx88_bcount; - -extern struct cx88_subid cx88_subids[]; -extern const unsigned int cx88_idcount; - -extern void cx88_card_list(struct cx88_core *core, struct pci_dev *pci); -extern void cx88_card_setup(struct cx88_core *core); -extern void cx88_card_setup_pre_i2c(struct cx88_core *core); +extern int cx88_get_resources(const struct cx88_core *core, + struct pci_dev *pci); +extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr); /* ----------------------------------------------------------- */ /* cx88-tvaudio.c */ |