diff options
Diffstat (limited to 'linux/drivers/media/video/cx18')
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-av-firmware.c | 6 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-cards.c | 5 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-driver.c | 97 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-driver.h | 11 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-dvb.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-fileops.c | 10 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-firmware.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-i2c.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-ioctl.c | 9 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-mailbox.c | 44 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-queue.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-queue.h | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-streams.c | 59 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx23418.h | 16 |
14 files changed, 170 insertions, 103 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-av-firmware.c b/linux/drivers/media/video/cx18/cx18-av-firmware.c index c64fd0a05..b374c74d3 100644 --- a/linux/drivers/media/video/cx18/cx18-av-firmware.c +++ b/linux/drivers/media/video/cx18/cx18-av-firmware.c @@ -36,7 +36,7 @@ int cx18_av_loadfw(struct cx18 *cx) int i; int retries1 = 0; - if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { + if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) { CX18_ERR("unable to open firmware %s\n", FWFILE); return -EINVAL; } @@ -115,9 +115,9 @@ int cx18_av_loadfw(struct cx18 *cx) are generated) */ cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0); - /* set alt I2s master clock to /16 and enable alt divider i2s + /* set alt I2s master clock to /0x16 and enable alt divider i2s passthrough */ - cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687); + cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687); cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6, 0x3F00FFFF); diff --git a/linux/drivers/media/video/cx18/cx18-cards.c b/linux/drivers/media/video/cx18/cx18-cards.c index 10cddba3e..53217cf45 100644 --- a/linux/drivers/media/video/cx18/cx18-cards.c +++ b/linux/drivers/media/video/cx18/cx18-cards.c @@ -349,13 +349,14 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = { /* Leadtek WinFast PVR2100 */ static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, + { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */ + { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */ { 0, 0, 0 } }; static const struct cx18_card cx18_card_leadtek_pvr2100 = { .type = CX18_CARD_LEADTEK_PVR2100, - .name = "Leadtek WinFast PVR2100", + .name = "Leadtek WinFast PVR2100/DVR3100 H", .comment = "Experimenters and photos needed for device to work well.\n" "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", .v4l2_capabilities = CX18_CAP_ENCODER, diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index e447b4ce7..fe2324ef2 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -159,7 +159,7 @@ MODULE_PARM_DESC(cardtype, "\t\t\t 4 = Yuan MPC718\n" "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" - "\t\t\t 7 = Leadtek WinFast PVR2100\n" + "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n" "\t\t\t 0 = Autodetect (default)\n" "\t\t\t-1 = Ignore this card\n\t\t"); MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); @@ -502,7 +502,7 @@ static void cx18_process_options(struct cx18 *cx) else if (cx->options.cardtype != 0) CX18_ERR("Unknown user specified type, trying to autodetect card\n"); if (cx->card == NULL) { - if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) { + if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_INFO("Autodetected Hauppauge card\n"); } @@ -512,13 +512,13 @@ static void cx18_process_options(struct cx18 *cx) if (cx->card->pci_list == NULL) continue; for (j = 0; cx->card->pci_list[j].device; j++) { - if (cx->dev->device != + if (cx->pci_dev->device != cx->card->pci_list[j].device) continue; - if (cx->dev->subsystem_vendor != + if (cx->pci_dev->subsystem_vendor != cx->card->pci_list[j].subsystem_vendor) continue; - if (cx->dev->subsystem_device != + if (cx->pci_dev->subsystem_device != cx->card->pci_list[j].subsystem_device) continue; CX18_INFO("Autodetected %s card\n", cx->card->name); @@ -531,9 +531,10 @@ done: if (cx->card == NULL) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n", - cx->dev->vendor, cx->dev->device); + cx->pci_dev->vendor, cx->pci_dev->device); CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n", - cx->dev->subsystem_vendor, cx->dev->subsystem_device); + cx->pci_dev->subsystem_vendor, + cx->pci_dev->subsystem_device); CX18_ERR("Defaulting to %s card\n", cx->card->name); CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n"); @@ -553,7 +554,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) { int i; - cx->base_addr = pci_resource_start(cx->dev, 0); + cx->base_addr = pci_resource_start(cx->pci_dev, 0); mutex_init(&cx->serialize_lock); mutex_init(&cx->i2c_bus_lock[0]); @@ -592,7 +593,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) (cx->params.video_temporal_filter_mode << 1) | (cx->params.video_median_filter_type << 2); cx->params.port = CX2341X_PORT_MEMORY; - cx->params.capabilities = CX2341X_CAP_HAS_TS; + cx->params.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_AC3; init_waitqueue_head(&cx->cap_w); init_waitqueue_head(&cx->mb_apu_waitq); init_waitqueue_head(&cx->mb_cpu_waitq); @@ -681,7 +682,7 @@ static void __devinit cx18_init_struct2(struct cx18 *cx) cx->av_state.vbi_line_offset = 8; } -static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev, +static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { u16 cmd; @@ -689,11 +690,11 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev, CX18_DEBUG_INFO("Enabling pci device\n"); - if (pci_enable_device(dev)) { + if (pci_enable_device(pci_dev)) { CX18_ERR("Can't enable device %d!\n", cx->num); return -EIO; } - if (pci_set_dma_mask(dev, 0xffffffff)) { + if (pci_set_dma_mask(pci_dev, 0xffffffff)) { CX18_ERR("No suitable DMA available on card %d.\n", cx->num); return -EIO; } @@ -703,25 +704,25 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev, } /* Enable bus mastering and memory mapped IO for the CX23418 */ - pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_read_config_word(pci_dev, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config_word(dev, PCI_COMMAND, cmd); + pci_write_config_word(pci_dev, PCI_COMMAND, cmd); - pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev); - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); + pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cx->card_rev); + pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 64 && cx18_pci_latency) { CX18_INFO("Unreasonably low latency timer, " "setting to 64 (was %d)\n", pci_latency); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); + pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64); + pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency); } CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " "irq: %d, latency: %d, memory: 0x%lx\n", - cx->dev->device, cx->card_rev, dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), - cx->dev->irq, pci_latency, (unsigned long)cx->base_addr); + cx->pci_dev->device, cx->card_rev, pci_dev->bus->number, + PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn), + cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr); return 0; } @@ -732,7 +733,7 @@ static u32 cx18_request_module(struct cx18 *cx, u32 hw, { if ((hw & id) == 0) return hw; - if (request_module(name) != 0) { + if (request_module("%s", name) != 0) { CX18_ERR("Failed to load module %s\n", name); return hw & ~id; } @@ -776,7 +777,7 @@ static void cx18_load_and_init_modules(struct cx18 *cx) hw = cx->hw_flags; } -static int __devinit cx18_probe(struct pci_dev *dev, +static int __devinit cx18_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { int retval = 0; @@ -801,33 +802,37 @@ static int __devinit cx18_probe(struct pci_dev *dev, return -ENOMEM; } cx18_cards[cx18_cards_active] = cx; - cx->dev = dev; cx->num = cx18_cards_active++; snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num); CX18_INFO("Initializing card #%d\n", cx->num); spin_unlock(&cx18_cards_lock); + cx->pci_dev = pci_dev; + retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev); + if (retval) { + CX18_ERR("Call to v4l2_device_register() failed\n"); + goto err; + } + CX18_DEBUG_INFO("registered v4l2_device name: %s\n", cx->v4l2_dev.name); + cx18_process_options(cx); if (cx->options.cardtype == -1) { retval = -ENODEV; - goto err; + goto unregister_v4l2; } if (cx18_init_struct1(cx)) { retval = -ENOMEM; - goto err; + goto unregister_v4l2; } CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); /* PCI Device Setup */ - retval = cx18_setup_pci(cx, dev, pci_id); + retval = cx18_setup_pci(cx, pci_dev, pci_id); if (retval != 0) goto free_workqueue; - /* save cx in the pci struct for later use */ - pci_set_drvdata(dev, cx); - /* map io memory */ CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); @@ -886,7 +891,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, cx18_init_scb(cx); /* Register IRQ */ - retval = request_irq(cx->dev->irq, cx18_irq_handler, + retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx); if (retval) { CX18_ERR("Failed to register irq %d\n", retval); @@ -997,7 +1002,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, free_streams: cx18_streams_cleanup(cx, 1); free_irq: - free_irq(cx->dev->irq, (void *)cx); + free_irq(cx->pci_dev->irq, (void *)cx); free_i2c: exit_cx18_i2c(cx); free_map: @@ -1006,6 +1011,8 @@ free_mem: release_mem_region(cx->base_addr, CX18_MEM_SIZE); free_workqueue: destroy_workqueue(cx->work_queue); +unregister_v4l2: + v4l2_device_unregister(&cx->v4l2_dev); err: if (retval == 0) retval = -ENODEV; @@ -1048,8 +1055,21 @@ int cx18_init_on_first_open(struct cx18 *cx) } set_bit(CX18_F_I_LOADED_FW, &cx->i_flags); - /* Init the firmware twice to work around a silicon bug - * transport related. */ + /* + * Init the firmware twice to work around a silicon bug + * with the digital TS. + * + * The second firmware load requires us to normalize the APU state, + * or the audio for the first analog capture will be badly incorrect. + * + * I can't seem to call APU_RESETAI and have it succeed without the + * APU capturing audio, so we start and stop it here to do the reset + */ + + /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */ + cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0); + cx18_vapi(cx, CX18_APU_RESETAI, 0); + cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG); fw_retry_count = 3; while (--fw_retry_count > 0) { @@ -1099,7 +1119,8 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx) #endif static void cx18_remove(struct pci_dev *pci_dev) { - struct cx18 *cx = pci_get_drvdata(pci_dev); + struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); + struct cx18 *cx = container_of(v4l2_dev, struct cx18, v4l2_dev); CX18_DEBUG_INFO("Removing Card #%d\n", cx->num); @@ -1131,13 +1152,15 @@ static void cx18_remove(struct pci_dev *pci_dev) exit_cx18_i2c(cx); - free_irq(cx->dev->irq, (void *)cx); + free_irq(cx->pci_dev->irq, (void *)cx); cx18_iounmap(cx); release_mem_region(cx->base_addr, CX18_MEM_SIZE); - pci_disable_device(cx->dev); + pci_disable_device(cx->pci_dev); + + v4l2_device_unregister(v4l2_dev); CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); } diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index 0d2edebc3..3a21013cd 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -48,6 +48,7 @@ #include <linux/dvb/audio.h> #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-device.h> #include <media/tuner.h> #include "cx18-mailbox.h" #include "cx18-av-core.h" @@ -79,7 +80,7 @@ #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ -#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ +#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100/DVR3100 H */ #define CX18_CARD_LAST 6 #define CX18_ENC_STREAM_TYPE_MPG 0 @@ -279,7 +280,7 @@ struct cx18_epu_work_order { struct cx18_stream { /* These first four fields are always set, even if the stream is not actually created. */ - struct video_device *v4l2dev; /* NULL when stream not created */ + struct video_device *video_dev; /* NULL when stream not created */ struct cx18 *cx; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ @@ -385,7 +386,9 @@ struct cx18_i2c_algo_callback_data { struct cx18 { int num; /* board number, -1 during init! */ char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */ - struct pci_dev *dev; /* PCI device */ + struct pci_dev *pci_dev; + struct v4l2_device v4l2_dev; + const struct cx18_card *card; /* card information */ const char *card_name; /* full name of the card */ const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ @@ -413,7 +416,7 @@ struct cx18 { /* dualwatch */ unsigned long dualwatch_jiffies; - u16 dualwatch_stereo_mode; + u32 dualwatch_stereo_mode; /* Digitizer type */ int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */ diff --git a/linux/drivers/media/video/cx18/cx18-dvb.c b/linux/drivers/media/video/cx18/cx18-dvb.c index bd5e6f3fd..3b86f57cd 100644 --- a/linux/drivers/media/video/cx18/cx18-dvb.c +++ b/linux/drivers/media/video/cx18/cx18-dvb.c @@ -167,7 +167,7 @@ int cx18_dvb_register(struct cx18_stream *stream) ret = dvb_register_adapter(&dvb->dvb_adapter, CX18_DRIVER_NAME, - THIS_MODULE, &cx->dev->dev, adapter_nr); + THIS_MODULE, &cx->pci_dev->dev, adapter_nr); if (ret < 0) goto err_out; diff --git a/linux/drivers/media/video/cx18/cx18-fileops.c b/linux/drivers/media/video/cx18/cx18-fileops.c index 0aaea0e7f..36c380b66 100644 --- a/linux/drivers/media/video/cx18/cx18-fileops.c +++ b/linux/drivers/media/video/cx18/cx18-fileops.c @@ -128,10 +128,10 @@ static void cx18_release_stream(struct cx18_stream *s) static void cx18_dualwatch(struct cx18 *cx) { struct v4l2_tuner vt; - u16 new_bitmap; - u16 new_stereo_mode; - const u16 stereo_mask = 0x0300; - const u16 dual = 0x0200; + u32 new_bitmap; + u32 new_stereo_mode; + const u32 stereo_mask = 0x0300; + const u32 dual = 0x0200; u32 h; new_stereo_mode = cx->params.audio_properties & stereo_mask; @@ -703,7 +703,7 @@ int cx18_v4l2_open(struct file *filp) if (cx18_cards[x] == NULL) continue; s = &cx18_cards[x]->streams[y]; - if (s->v4l2dev && s->v4l2dev->minor == minor) { + if (s->video_dev && s->video_dev->minor == minor) { cx = cx18_cards[x]; break; } diff --git a/linux/drivers/media/video/cx18/cx18-firmware.c b/linux/drivers/media/video/cx18/cx18-firmware.c index 1fa95da15..aa89bee65 100644 --- a/linux/drivers/media/video/cx18/cx18-firmware.c +++ b/linux/drivers/media/video/cx18/cx18-firmware.c @@ -107,7 +107,7 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx) u32 __iomem *dst = (u32 __iomem *)mem; const u32 *src; - if (request_firmware(&fw, fn, &cx->dev->dev)) { + if (request_firmware(&fw, fn, &cx->pci_dev->dev)) { CX18_ERR("Unable to open firmware %s\n", fn); CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); return -ENOMEM; @@ -151,7 +151,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, u32 apu_version = 0; int sz; - if (request_firmware(&fw, fn, &cx->dev->dev)) { + if (request_firmware(&fw, fn, &cx->pci_dev->dev)) { CX18_ERR("unable to open firmware %s\n", fn); CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); cx18_setup_page(cx, 0); diff --git a/linux/drivers/media/video/cx18/cx18-i2c.c b/linux/drivers/media/video/cx18/cx18-i2c.c index efae2301a..fe6fa60a7 100644 --- a/linux/drivers/media/video/cx18/cx18-i2c.c +++ b/linux/drivers/media/video/cx18/cx18-i2c.c @@ -393,7 +393,7 @@ int init_cx18_i2c(struct cx18 *cx) strlen(cx->i2c_client[i].name), "%d", i); cx->i2c_client[i].adapter = &cx->i2c_adap[i]; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) - cx->i2c_adap[i].dev.parent = &cx->dev->dev; + cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev; #endif } diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index 84d6381aa..4a49b0819 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -407,7 +407,8 @@ static int cx18_querycap(struct file *file, void *fh, strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); - snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->dev)); + snprintf(vcap->bus_info, sizeof(vcap->bus_info), + "PCI:%s", pci_name(cx->pci_dev)); vcap->version = CX18_DRIVER_VERSION; /* version */ vcap->capabilities = cx->v4l2_cap; /* capabilities */ return 0; @@ -813,7 +814,9 @@ static int cx18_log_status(struct file *file, void *fh) struct v4l2_audio audin; int i; - CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num); + CX18_INFO("================= START STATUS CARD #%d " + "=================\n", cx->num); + CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name); if (cx->hw_flags & CX18_HW_TVEEPROM) { struct tveeprom tv; @@ -835,7 +838,7 @@ static int cx18_log_status(struct file *file, void *fh) for (i = 0; i < CX18_MAX_STREAMS; i++) { struct cx18_stream *s = &cx->streams[i]; - if (s->v4l2dev == NULL || s->buffers == 0) + if (s->video_dev == NULL || s->buffers == 0) continue; CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, diff --git a/linux/drivers/media/video/cx18/cx18-mailbox.c b/linux/drivers/media/video/cx18/cx18-mailbox.c index 89a45f51f..66964722f 100644 --- a/linux/drivers/media/video/cx18/cx18-mailbox.c +++ b/linux/drivers/media/video/cx18/cx18-mailbox.c @@ -83,6 +83,8 @@ static const struct cx18_api_info api_info[] = { API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), + API_ENTRY(APU, CX18_APU_START, 0), + API_ENTRY(APU, CX18_APU_STOP, 0), API_ENTRY(APU, CX18_APU_RESETAI, 0), API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0), API_ENTRY(0, 0, 0), @@ -98,21 +100,30 @@ static const struct cx18_api_info *find_api_info(u32 cmd) return NULL; } -static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name) +/* Call with buf of n*11+1 bytes */ +static char *u32arr2hex(u32 data[], int n, char *buf) { - char argstr[MAX_MB_ARGUMENTS*11+1]; char *p; int i; + for (i = 0, p = buf; i < n; i++, p += 11) { + /* kernel snprintf() appends '\0' always */ + snprintf(p, 12, " %#010x", data[i]); + } + *p = '\0'; + return buf; +} + +static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name) +{ + char argstr[MAX_MB_ARGUMENTS*11+1]; + if (!(cx18_debug & CX18_DBGFLG_API)) return; - for (i = 0, p = argstr; i < MAX_MB_ARGUMENTS; i++, p += 11) { - /* kernel snprintf() appends '\0' always */ - snprintf(p, 12, " %#010x", mb->args[i]); - } CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s" - "\n", name, mb->request, mb->ack, mb->cmd, mb->error, argstr); + "\n", name, mb->request, mb->ack, mb->cmd, mb->error, + u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr)); } @@ -445,7 +456,8 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) "incoming %s to EPU mailbox (sequence no. %u)" "\n", rpu_str[rpu], rpu_str[rpu], order_mb->request); - dump_mb(cx, order_mb, "incoming"); + if (cx18_debug & CX18_DBGFLG_WARN) + dump_mb(cx, order_mb, "incoming"); order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT; } @@ -474,16 +486,24 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) struct mutex *mb_lock; long int timeout, ret; int i; + char argstr[MAX_MB_ARGUMENTS*11+1]; if (info == NULL) { CX18_WARN("unknown cmd %x\n", cmd); return -EINVAL; } - if (cmd == CX18_CPU_DE_SET_MDL) - CX18_DEBUG_HI_API("%s\n", info->name); - else - CX18_DEBUG_API("%s\n", info->name); + if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */ + if (cmd == CX18_CPU_DE_SET_MDL) { + if (cx18_debug & CX18_DBGFLG_HIGHVOL) + CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n", + info->name, cmd, + u32arr2hex(data, args, argstr)); + } else + CX18_DEBUG_API("%s\tcmd %#010x args%s\n", + info->name, cmd, + u32arr2hex(data, args, argstr)); + } switch (info->rpu) { case APU: diff --git a/linux/drivers/media/video/cx18/cx18-queue.c b/linux/drivers/media/video/cx18/cx18-queue.c index 8d9441e88..3046b8e74 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.c +++ b/linux/drivers/media/video/cx18/cx18-queue.c @@ -204,7 +204,7 @@ int cx18_stream_alloc(struct cx18_stream *s) } buf->id = cx->buffer_id++; INIT_LIST_HEAD(&buf->list); - buf->dma_handle = pci_map_single(s->cx->dev, + buf->dma_handle = pci_map_single(s->cx->pci_dev, buf->buf, s->buf_size, s->dma); cx18_buf_sync_for_cpu(s, buf); cx18_enqueue(s, buf, &s->q_free); @@ -227,7 +227,7 @@ void cx18_stream_free(struct cx18_stream *s) /* empty q_free */ while ((buf = cx18_dequeue(s, &s->q_free))) { - pci_unmap_single(s->cx->dev, buf->dma_handle, + pci_unmap_single(s->cx->pci_dev, buf->dma_handle, s->buf_size, s->dma); kfree(buf->buf); kfree(buf); diff --git a/linux/drivers/media/video/cx18/cx18-queue.h b/linux/drivers/media/video/cx18/cx18-queue.h index 456cec3bc..4de06269d 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.h +++ b/linux/drivers/media/video/cx18/cx18-queue.h @@ -29,14 +29,14 @@ static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s, struct cx18_buffer *buf) { - pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle, + pci_dma_sync_single_for_cpu(s->cx->pci_dev, buf->dma_handle, s->buf_size, s->dma); } static inline void cx18_buf_sync_for_device(struct cx18_stream *s, struct cx18_buffer *buf) { - pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle, + pci_dma_sync_single_for_device(s->cx->pci_dev, buf->dma_handle, s->buf_size, s->dma); } diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index 5eb99ea7b..88b101401 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -101,11 +101,11 @@ static struct { static void cx18_stream_init(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; - struct video_device *dev = s->v4l2dev; + struct video_device *video_dev = s->video_dev; - /* we need to keep v4l2dev, so restore it afterwards */ + /* we need to keep video_dev, so restore it afterwards */ memset(s, 0, sizeof(*s)); - s->v4l2dev = dev; + s->video_dev = video_dev; /* initialize cx18_stream fields */ s->cx = cx; @@ -132,10 +132,10 @@ static int cx18_prep_dev(struct cx18 *cx, int type) int num_offset = cx18_stream_info[type].num_offset; int num = cx->num + cx18_first_minor + num_offset; - /* These four fields are always initialized. If v4l2dev == NULL, then + /* These four fields are always initialized. If video_dev == NULL, then this stream is not in use. In that case no other fields but these four can be used. */ - s->v4l2dev = NULL; + s->video_dev = NULL; s->cx = cx; s->type = type; s->name = cx18_stream_info[type].name; @@ -163,22 +163,22 @@ static int cx18_prep_dev(struct cx18 *cx, int type) return 0; /* allocate and initialize the v4l2 video device structure */ - s->v4l2dev = video_device_alloc(); - if (s->v4l2dev == NULL) { + s->video_dev = video_device_alloc(); + if (s->video_dev == NULL) { CX18_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); return -ENOMEM; } - snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", + snprintf(s->video_dev->name, sizeof(s->video_dev->name), "cx18-%d", cx->num); - s->v4l2dev->num = num; - s->v4l2dev->parent = &cx->dev->dev; - s->v4l2dev->fops = &cx18_v4l2_enc_fops; - s->v4l2dev->release = video_device_release; - s->v4l2dev->tvnorms = V4L2_STD_ALL; - cx18_set_funcs(s->v4l2dev); + s->video_dev->num = num; + s->video_dev->parent = &cx->pci_dev->dev; + s->video_dev->fops = &cx18_v4l2_enc_fops; + s->video_dev->release = video_device_release; + s->video_dev->tvnorms = V4L2_STD_ALL; + cx18_set_funcs(s->video_dev); return 0; } @@ -227,28 +227,29 @@ static int cx18_reg_dev(struct cx18 *cx, int type) } } - if (s->v4l2dev == NULL) + if (s->video_dev == NULL) return 0; - num = s->v4l2dev->num; + num = s->video_dev->num; /* card number + user defined offset + device offset */ if (type != CX18_ENC_STREAM_TYPE_MPG) { struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; - if (s_mpg->v4l2dev) - num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset; + if (s_mpg->video_dev) + num = s_mpg->video_dev->num + + cx18_stream_info[type].num_offset; } /* Register device. First try the desired minor, then any free one. */ - ret = video_register_device(s->v4l2dev, vfl_type, num); + ret = video_register_device(s->video_dev, vfl_type, num); if (ret < 0) { CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n", s->name, num); - video_device_release(s->v4l2dev); - s->v4l2dev = NULL; + video_device_release(s->video_dev); + s->video_dev = NULL; return ret; } - num = s->v4l2dev->num; + num = s->video_dev->num; switch (vfl_type) { case VFL_TYPE_GRABBER: @@ -312,9 +313,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) cx->streams[type].dvb.enabled = false; } - vdev = cx->streams[type].v4l2dev; + vdev = cx->streams[type].video_dev; - cx->streams[type].v4l2dev = NULL; + cx->streams[type].video_dev = NULL; if (vdev == NULL) continue; @@ -437,7 +438,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) int ts = 0; int captype = 0; - if (s->v4l2dev == NULL && s->dvb.enabled == 0) + if (s->video_dev == NULL && s->dvb.enabled == 0) return -EINVAL; CX18_DEBUG_INFO("Start encoder stream %s\n", s->name); @@ -565,7 +566,7 @@ void cx18_stop_all_captures(struct cx18 *cx) for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) { struct cx18_stream *s = &cx->streams[i]; - if (s->v4l2dev == NULL && s->dvb.enabled == 0) + if (s->video_dev == NULL && s->dvb.enabled == 0) continue; if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) cx18_stop_v4l2_encode_stream(s, 0); @@ -577,7 +578,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) struct cx18 *cx = s->cx; unsigned long then; - if (s->v4l2dev == NULL && s->dvb.enabled == 0) + if (s->video_dev == NULL && s->dvb.enabled == 0) return -EINVAL; /* This function assumes that you are allowed to stop the capture @@ -656,7 +657,7 @@ u32 cx18_find_handle(struct cx18 *cx) for (i = 0; i < CX18_MAX_STREAMS; i++) { struct cx18_stream *s = &cx->streams[i]; - if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE)) + if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE)) return s->handle; } return CX18_INVALID_TASK_HANDLE; @@ -674,7 +675,7 @@ struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle) s = &cx->streams[i]; if (s->handle != handle) continue; - if (s->v4l2dev || s->dvb.enabled) + if (s->video_dev || s->dvb.enabled) return s; } return NULL; diff --git a/linux/drivers/media/video/cx18/cx23418.h b/linux/drivers/media/video/cx18/cx23418.h index 601f3a2ab..9956abf57 100644 --- a/linux/drivers/media/video/cx18/cx23418.h +++ b/linux/drivers/media/video/cx18/cx23418.h @@ -56,6 +56,22 @@ #define APU_CMD_MASK 0x10000000 #define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000) +#define CX18_APU_ENCODING_METHOD_MPEG (0 << 28) +#define CX18_APU_ENCODING_METHOD_AC3 (1 << 28) + +/* Description: Command APU to start audio + IN[0] - audio parameters (same as CX18_CPU_SET_AUDIO_PARAMETERS?) + IN[1] - caller buffer address, or 0 + ReturnCode - ??? */ +#define CX18_APU_START (APU_CMD_MASK | 0x01) + +/* Description: Command APU to stop audio + IN[0] - encoding method to stop + ReturnCode - ??? */ +#define CX18_APU_STOP (APU_CMD_MASK | 0x02) + +/* Description: Command APU to reset the AI + ReturnCode - ??? */ #define CX18_APU_RESETAI (APU_CMD_MASK | 0x05) /* Description: This command indicates that a Memory Descriptor List has been |