From 269c11fbac4f7b4ed58e77f3049b64b55a342234 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 2 Sep 2012 19:13:14 -0300 Subject: [media] ivtv, ivtv-alsa: Add initial ivtv-alsa interface driver for ivtv This is a cut-and-paste port of the cx18-alsa driver to create an ivtv-alsa interface module for the ivtv driver. It is not actually hooked-up to the PCM stream DMA buffers from the ivtv driver yet. That will be done in a coming change, since that portion is so very different from the cx18 driver. This code has all or more of the bugs and shortcomings of the cx18-alsa interface driver: inconsistent use of itvsc->slock, ivtv-alsa-mixer.c is dead code, assumes 48 ksps regardless of the actual setting of the audio capture, problems with proper struct ivtv and struct ivtv_stream housekeeping, struct ivtv_open_id.v4l2_fh abuse, and $DIETY knows what else. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ivtv/ivtv-driver.c | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'drivers/media/pci/ivtv/ivtv-driver.c') diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index 5462ce2f60ea..eed95a396665 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -68,6 +68,10 @@ setting this to 1 you ensure that radio0 is now also radio1. */ int ivtv_first_minor; +/* Callback for registering extensions */ +int (*ivtv_ext_init)(struct ivtv *); +EXPORT_SYMBOL(ivtv_ext_init); + /* add your revision and whatnot here */ static struct pci_device_id ivtv_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15, @@ -279,6 +283,34 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(IVTV_VERSION); +#if defined(CONFIG_MODULES) && defined(MODULE) +static void request_module_async(struct work_struct *work) +{ + struct ivtv *dev = container_of(work, struct ivtv, request_module_wk); + + /* Make sure ivtv-alsa module is loaded */ + request_module("ivtv-alsa"); + + /* Initialize ivtv-alsa for this instance of the cx18 device */ + if (ivtv_ext_init != NULL) + ivtv_ext_init(dev); +} + +static void request_modules(struct ivtv *dev) +{ + INIT_WORK(&dev->request_module_wk, request_module_async); + schedule_work(&dev->request_module_wk); +} + +static void flush_request_modules(struct ivtv *dev) +{ + flush_work_sync(&dev->request_module_wk); +} +#else +#define request_modules(dev) +#define flush_request_modules(dev) +#endif /* CONFIG_MODULES */ + void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask) { itv->irqmask &= ~mask; @@ -1253,6 +1285,9 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, goto free_streams; } IVTV_INFO("Initialized card: %s\n", itv->card_name); + + /* Load ivtv submodules (ivtv-alsa) */ + request_modules(itv); return 0; free_streams: @@ -1380,6 +1415,8 @@ static void ivtv_remove(struct pci_dev *pdev) IVTV_DEBUG_INFO("Removing card\n"); + flush_request_modules(itv); + if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) { /* Stop all captures */ IVTV_DEBUG_INFO("Stopping all streams\n"); -- cgit