summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video')
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-cards.c17
-rw-r--r--linux/drivers/media/video/bt8xx/bttv.h1
-rw-r--r--linux/drivers/media/video/cx18/cx18-av-firmware.c6
-rw-r--r--linux/drivers/media/video/cx18/cx18-cards.c5
-rw-r--r--linux/drivers/media/video/cx18/cx18-driver.c97
-rw-r--r--linux/drivers/media/video/cx18/cx18-driver.h11
-rw-r--r--linux/drivers/media/video/cx18/cx18-dvb.c2
-rw-r--r--linux/drivers/media/video/cx18/cx18-fileops.c10
-rw-r--r--linux/drivers/media/video/cx18/cx18-firmware.c4
-rw-r--r--linux/drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--linux/drivers/media/video/cx18/cx18-ioctl.c9
-rw-r--r--linux/drivers/media/video/cx18/cx18-mailbox.c44
-rw-r--r--linux/drivers/media/video/cx18/cx18-queue.c4
-rw-r--r--linux/drivers/media/video/cx18/cx18-queue.h4
-rw-r--r--linux/drivers/media/video/cx18/cx18-streams.c59
-rw-r--r--linux/drivers/media/video/cx18/cx23418.h16
-rw-r--r--linux/drivers/media/video/cx2341x.c101
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-cards.c37
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-dvb.c54
-rw-r--r--linux/drivers/media/video/cx23885/cx23885.h3
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-core.c2
-rw-r--r--linux/drivers/media/video/dabusb.c74
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-video.c11
-rw-r--r--linux/drivers/media/video/hexium_gemini.c292
-rw-r--r--linux/drivers/media/video/hexium_orion.c103
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-driver.h2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-fileops.c8
-rw-r--r--linux/drivers/media/video/mxb.c641
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c5
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c12
-rw-r--r--linux/drivers/media/video/s2255drv.c41
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-core.c44
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-i2c.c6
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-video.c39
-rw-r--r--linux/drivers/media/video/uvc/uvc_ctrl.c2
-rw-r--r--linux/drivers/media/video/uvc/uvc_driver.c27
-rw-r--r--linux/drivers/media/video/uvc/uvc_status.c16
-rw-r--r--linux/drivers/media/video/uvc/uvc_v4l2.c14
-rw-r--r--linux/drivers/media/video/uvc/uvc_video.c79
-rw-r--r--linux/drivers/media/video/uvc/uvcvideo.h7
-rw-r--r--linux/drivers/media/video/videobuf-dma-contig.c2
-rw-r--r--linux/drivers/media/video/videobuf-vmalloc.c2
42 files changed, 1103 insertions, 812 deletions
diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c
index aea093419..e0bfbbc74 100644
--- a/linux/drivers/media/video/bt8xx/bttv-cards.c
+++ b/linux/drivers/media/video/bt8xx/bttv-cards.c
@@ -247,6 +247,10 @@ static struct CARD {
{ 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
{ 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
{ 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xf0500000, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500001, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500002, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500003, BTTV_BOARD_IVCE8784, "IVCE-8784" },
{ 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
{ 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
@@ -2182,6 +2186,19 @@ struct tvcard bttv_tvcards[] = {
.muxsel = { 2 },
.pll = PLL_28,
},
+ [BTTV_BOARD_IVCE8784] = {
+ .name = "IVCE-8784",
+ .video_inputs = 1,
+ .audio_inputs = 0,
+ .tuner = UNSET,
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .svhs = UNSET,
+ .gpiomask = 0xdf,
+ .muxsel = { 2 },
+ .pll = PLL_28,
+ },
[BTTV_BOARD_XGUARD] = {
.name = "Grand X-Guard / Trust 814PCI",
.video_inputs = 16,
diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h
index ed0446a20..0c07dc9b7 100644
--- a/linux/drivers/media/video/bt8xx/bttv.h
+++ b/linux/drivers/media/video/bt8xx/bttv.h
@@ -181,6 +181,7 @@
#define BTTV_BOARD_VD012 0x99
#define BTTV_BOARD_VD012_X1 0x9a
#define BTTV_BOARD_VD012_X2 0x9b
+#define BTTV_BOARD_IVCE8784 0x9c
/* more card-specific defines */
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
diff --git a/linux/drivers/media/video/cx2341x.c b/linux/drivers/media/video/cx2341x.c
index f31f11e3f..c92b98135 100644
--- a/linux/drivers/media/video/cx2341x.c
+++ b/linux/drivers/media/video/cx2341x.c
@@ -1,5 +1,5 @@
/*
- * cx2341x - generic code for cx23415/6 based devices
+ * cx2341x - generic code for cx23415/6/8 based devices
*
* Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
*
@@ -31,7 +31,7 @@
#include <media/v4l2-common.h>
#include "compat.h"
-MODULE_DESCRIPTION("cx23415/6 driver");
+MODULE_DESCRIPTION("cx23415/6/8 driver");
MODULE_AUTHOR("Hans Verkuil");
MODULE_LICENSE("GPL");
@@ -46,6 +46,7 @@ const u32 cx2341x_mpeg_ctrls[] = {
V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
V4L2_CID_MPEG_AUDIO_ENCODING,
V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+ V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
V4L2_CID_MPEG_AUDIO_MODE,
V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
V4L2_CID_MPEG_AUDIO_EMPHASIS,
@@ -95,6 +96,7 @@ static const struct cx2341x_mpeg_params default_params = {
.audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
.audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
.audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
+ .audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
.audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
.audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
.audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
@@ -149,6 +151,9 @@ static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
ctrl->value = params->audio_l2_bitrate;
break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ ctrl->value = params->audio_ac3_bitrate;
+ break;
case V4L2_CID_MPEG_AUDIO_MODE:
ctrl->value = params->audio_mode;
break;
@@ -257,6 +262,12 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
params->audio_sampling_freq = ctrl->value;
break;
case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (busy)
+ return -EBUSY;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3)
+ if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+ ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
+ return -ERANGE;
params->audio_encoding = ctrl->value;
break;
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
@@ -264,6 +275,13 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
return -EBUSY;
params->audio_l2_bitrate = ctrl->value;
break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (busy)
+ return -EBUSY;
+ if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
+ return -EINVAL;
+ params->audio_ac3_bitrate = ctrl->value;
+ break;
case V4L2_CID_MPEG_AUDIO_MODE:
params->audio_mode = ctrl->value;
break;
@@ -483,21 +501,55 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
switch (qctrl->id) {
case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ /*
+ * The state of L2 & AC3 bitrate controls can change
+ * when this control changes, but v4l2_ctrl_query_fill()
+ * already sets V4L2_CTRL_FLAG_UPDATE for
+ * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
+ */
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
+ default_params.audio_encoding);
+ }
+
return v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
default_params.audio_encoding);
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
+ err = v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_L2_BITRATE_192K,
V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
default_params.audio_l2_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
+ params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
return -EINVAL;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
+ default_params.audio_ac3_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ if (params->audio_encoding !=
+ V4L2_MPEG_AUDIO_ENCODING_AC3)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ } else
+ qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+ return 0;
+
case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
err = v4l2_ctrl_query_fill_std(qctrl);
if (err == 0 &&
@@ -672,6 +724,15 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
NULL
};
+ static const char *mpeg_audio_encoding_l2_ac3[] = {
+ "",
+ "MPEG-1/2 Layer II",
+ "",
+ "",
+ "AC-3",
+ NULL
+ };
+
static const char *cx2341x_video_spatial_filter_mode_menu[] = {
"Manual",
"Auto",
@@ -712,6 +773,9 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
case V4L2_CID_MPEG_STREAM_TYPE:
return (p->capabilities & CX2341X_CAP_HAS_TS) ?
mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
+ mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
return NULL;
@@ -731,16 +795,36 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
}
EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
+/* definitions for audio properties bits 29-28 */
+#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
+#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
+#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
+
static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
{
- params->audio_properties = (params->audio_sampling_freq << 0) |
- ((3 - params->audio_encoding) << 2) |
- ((1 + params->audio_l2_bitrate) << 4) |
+ params->audio_properties =
+ (params->audio_sampling_freq << 0) |
(params->audio_mode << 8) |
(params->audio_mode_extension << 10) |
(((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
? 3 : params->audio_emphasis) << 12) |
(params->audio_crc << 14);
+
+ if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
+ params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
+ params->audio_properties |=
+#if 1
+ /* Not sure if this MPEG Layer II setting is required */
+ ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
+#endif
+ (params->audio_ac3_bitrate << 4) |
+ (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
+ } else {
+ /* Assuming MPEG Layer II */
+ params->audio_properties |=
+ ((3 - params->audio_encoding) << 2) |
+ ((1 + params->audio_l2_bitrate) << 4);
+ }
}
int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
@@ -1023,7 +1107,10 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
prefix,
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
- cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
+ cx2341x_menu_item(p,
+ p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
+ ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
+ : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
p->audio_mute ? " (muted)" : "");
if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c
index db1e8bdab..a8201ceaa 100644
--- a/linux/drivers/media/video/cx23885/cx23885-cards.c
+++ b/linux/drivers/media/video/cx23885/cx23885-cards.c
@@ -163,6 +163,18 @@ struct cx23885_board cx23885_boards[] = {
.name = "Compro VideoMate E650F",
.portc = CX23885_MPEG_DVB,
},
+ [CX23885_BOARD_TBS_6920] = {
+ .name = "TurboSight TBS 6920",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_TEVII_S470] = {
+ .name = "TeVii S470",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_DVBWORLD_2005] = {
+ .name = "DVBWorld DVB-S2 2005",
+ .portb = CX23885_MPEG_DVB,
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -246,6 +258,18 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x185b,
.subdevice = 0xe800,
.card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F,
+ }, {
+ .subvendor = 0x6920,
+ .subdevice = 0x8888,
+ .card = CX23885_BOARD_TBS_6920,
+ }, {
+ .subvendor = 0xd470,
+ .subdevice = 0x9022,
+ .card = CX23885_BOARD_TEVII_S470,
+ }, {
+ .subvendor = 0x0001,
+ .subdevice = 0x2005,
+ .card = CX23885_BOARD_DVBWORLD_2005,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -553,6 +577,12 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
mdelay(20);
cx_set(GP0_IO, 0x00040004);
break;
+ case CX23885_BOARD_TBS_6920:
+ case CX23885_BOARD_TEVII_S470:
+ cx_write(MC417_CTL, 0x00000036);
+ cx_write(MC417_OEN, 0x00001000);
+ cx_write(MC417_RWD, 0x00001800);
+ break;
}
}
@@ -633,6 +663,13 @@ void cx23885_card_setup(struct cx23885_dev *dev)
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
break;
+ case CX23885_BOARD_TEVII_S470:
+ case CX23885_BOARD_TBS_6920:
+ case CX23885_BOARD_DVBWORLD_2005:
+ ts1->gen_ctrl_val = 0x5; /* Parallel */
+ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ break;
case CX23885_BOARD_HAUPPAUGE_HVR1250:
case CX23885_BOARD_HAUPPAUGE_HVR1500:
case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c
index 990fd217b..90dbf49ea 100644
--- a/linux/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c
@@ -44,6 +44,7 @@
#include "dib7000p.h"
#include "dibx000_common.h"
#include "zl10353.h"
+#include "cx24116.h"
static unsigned int debug;
@@ -309,6 +310,32 @@ static struct zl10353_config dvico_fusionhdtv_xc3028 = {
.no_tuner = 1,
};
+static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ struct cx23885_tsport *port = fe->dvb->priv;
+ struct cx23885_dev *dev = port->dev;
+
+ if (voltage == SEC_VOLTAGE_18)
+ cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
+ else if (voltage == SEC_VOLTAGE_13)
+ cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
+ else
+ cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
+ return 0;
+}
+
+static struct cx24116_config tbs_cx24116_config = {
+ .demod_address = 0x05,
+};
+
+static struct cx24116_config tevii_cx24116_config = {
+ .demod_address = 0x55,
+};
+
+static struct cx24116_config dvbworld_cx24116_config = {
+ .demod_address = 0x05,
+};
+
static int dvb_register(struct cx23885_tsport *port)
{
struct cx23885_dev *dev = port->dev;
@@ -527,6 +554,33 @@ static int dvb_register(struct cx23885_tsport *port)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
break;
+ case CX23885_BOARD_TBS_6920:
+ i2c_bus = &dev->i2c_bus[0];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &tbs_cx24116_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL)
+ fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+ break;
+ case CX23885_BOARD_TEVII_S470:
+ i2c_bus = &dev->i2c_bus[1];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &tevii_cx24116_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL)
+ fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+ break;
+ case CX23885_BOARD_DVBWORLD_2005:
+ i2c_bus = &dev->i2c_bus[1];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &dvbworld_cx24116_config,
+ &i2c_bus->i2c_adap);
+ break;
default:
printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
" isn't supported yet\n",
diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h
index ad93e0e88..cae0a74bd 100644
--- a/linux/drivers/media/video/cx23885/cx23885.h
+++ b/linux/drivers/media/video/cx23885/cx23885.h
@@ -68,6 +68,9 @@
#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11
#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12
#define CX23885_BOARD_COMPRO_VIDEOMATE_E650F 13
+#define CX23885_BOARD_TBS_6920 14
+#define CX23885_BOARD_TEVII_S470 15
+#define CX23885_BOARD_DVBWORLD_2005 16
/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
#define CX23885_NORMS (\
diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c
index 6d324002a..57e80717f 100644
--- a/linux/drivers/media/video/cx25840/cx25840-core.c
+++ b/linux/drivers/media/video/cx25840/cx25840-core.c
@@ -1412,7 +1412,7 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
{
/* ignore this command */
- if (cmd == TUNER_SET_TYPE_ADDR)
+ if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
return 0;
/* Old-style drivers rely on initialization on first use, so
diff --git a/linux/drivers/media/video/dabusb.c b/linux/drivers/media/video/dabusb.c
index 7ba206b34..b399f18c1 100644
--- a/linux/drivers/media/video/dabusb.c
+++ b/linux/drivers/media/video/dabusb.c
@@ -199,17 +199,20 @@ static void dabusb_iso_complete (struct urb *purb)
dst += len;
}
else
- err("dabusb_iso_complete: invalid len %d", len);
+ dev_err(&purb->dev->dev,
+ "dabusb_iso_complete: invalid len %d\n", len);
}
else
dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
if (dst != purb->actual_length)
- err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
+ dev_err(&purb->dev->dev,
+ "dst!=purb->actual_length:%d!=%d\n",
+ dst, purb->actual_length);
}
if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
s->overruns++;
- err("overrun (%d)", s->overruns);
+ dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns);
}
wake_up (&s->wait);
}
@@ -230,13 +233,14 @@ static int dabusb_alloc_buffers (pdabusb_t s)
while (transfer_len < (s->total_buffer_size << 10)) {
b = kzalloc(sizeof (buff_t), GFP_KERNEL);
if (!b) {
- err("kzalloc(sizeof(buff_t))==NULL");
+ dev_err(&s->usbdev->dev,
+ "kzalloc(sizeof(buff_t))==NULL\n");
goto err;
}
b->s = s;
b->purb = usb_alloc_urb(packets, GFP_KERNEL);
if (!b->purb) {
- err("usb_alloc_urb == NULL");
+ dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n");
kfree (b);
goto err;
}
@@ -245,7 +249,8 @@ static int dabusb_alloc_buffers (pdabusb_t s)
if (!b->purb->transfer_buffer) {
kfree (b->purb);
kfree (b);
- err("kmalloc(%d)==NULL", transfer_buffer_length);
+ dev_err(&s->usbdev->dev,
+ "kmalloc(%d)==NULL\n", transfer_buffer_length);
goto err;
}
@@ -289,10 +294,11 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100);
if(ret<0) {
- err("dabusb: usb_bulk_msg failed(%d)",ret);
+ dev_err(&s->usbdev->dev,
+ "usb_bulk_msg failed(%d)\n", ret);
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
return -EINVAL;
}
@@ -301,7 +307,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
if( ret == -EPIPE ) {
dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
- err("request failed");
+ dev_err(&s->usbdev->dev, "request failed\n");
}
pb->size = actual_length;
@@ -319,7 +325,8 @@ static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data,
unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL);
if (!transfer_buffer) {
- err("dabusb_writemem: kmalloc(%d) failed.", len);
+ dev_err(&s->usbdev->dev,
+ "dabusb_writemem: kmalloc(%d) failed.\n", len);
return -ENOMEM;
}
@@ -352,7 +359,8 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev);
if (ret) {
- err("Failed to load \"dabusb/firmware.fw\": %d\n", ret);
+ dev_err(&s->usbdev->dev,
+ "Failed to load \"dabusb/firmware.fw\": %d\n", ret);
goto out;
}
#endif
@@ -378,11 +386,14 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
#endif
if (ret < 0) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
- err("dabusb_writemem failed (%d %04X %p %d)", ret, ptr->Address, ptr->Data, ptr->Length);
+ dev_err(&s->usbdev->dev,
+ "dabusb_writemem failed (%d %04X %p %d)\n",
+ ret, ptr->Address, ptr->Data, ptr->Length);
#else
- err("dabusb_writemem failed (%d %04X %p %d)", ret,
- be32_to_cpu(rec->addr), rec->data,
- be16_to_cpu(rec->len));
+ dev_err(&s->usbdev->dev,
+ "dabusb_writemem failed (%d %04X %p %d)\n",
+ ret, be32_to_cpu(rec->addr),
+ rec->data, be16_to_cpu(rec->len));
#endif
break;
}
@@ -443,14 +454,16 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
dbg("Enter dabusb_fpga_download (internal)");
if (!b) {
- err("kmalloc(sizeof(bulk_transfer_t))==NULL");
+ dev_err(&s->usbdev->dev,
+ "kmalloc(sizeof(bulk_transfer_t))==NULL\n");
return -ENOMEM;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
if (ret) {
- err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
+ dev_err(&s->usbdev->dev,
+ "Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
kfree(b);
return ret;
}
@@ -482,7 +495,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
#endif
ret = dabusb_bulk (s, b);
if (ret < 0) {
- err("dabusb_bulk failed.");
+ dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n");
break;
}
mdelay (1);
@@ -537,9 +550,11 @@ static int dabusb_startrek (pdabusb_t s)
ret = usb_submit_urb (end->purb, GFP_KERNEL);
if (ret) {
- err("usb_submit_urb returned:%d", ret);
+ dev_err(&s->usbdev->dev,
+ "usb_submit_urb returned:%d\n", ret);
if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
- err("startrek: dabusb_add_buf_tail failed");
+ dev_err(&s->usbdev->dev,
+ "startrek: dabusb_add_buf_tail failed\n");
break;
}
else
@@ -582,7 +597,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
spin_unlock_irqrestore(&s->lock, flags);
- err("error: rec_buf_list is empty");
+ dev_err(&s->usbdev->dev,
+ "error: rec_buf_list is empty\n");
goto err;
}
@@ -611,7 +627,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
if (list_empty (&s->rec_buff_list)) {
spin_unlock_irqrestore(&s->lock, flags);
- err("error: still no buffer available.");
+ dev_err(&s->usbdev->dev,
+ "error: still no buffer available.\n");
goto err;
}
spin_unlock_irqrestore(&s->lock, flags);
@@ -632,7 +649,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
- err("read: copy_to_user failed");
+ dev_err(&s->usbdev->dev, "read: copy_to_user failed\n");
if (!ret)
ret = -EFAULT;
goto err;
@@ -646,7 +663,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
if (s->readptr == purb->actual_length) {
// finished, take next buffer
if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
- err("read: dabusb_add_buf_tail failed");
+ dev_err(&s->usbdev->dev,
+ "read: dabusb_add_buf_tail failed\n");
s->readptr = 0;
}
}
@@ -682,7 +700,7 @@ static int dabusb_open (struct inode *inode, struct file *file)
}
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
mutex_unlock(&s->mutex);
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
return -EINVAL;
}
s->opened = 1;
@@ -707,7 +725,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
if (!s->remove_pending) {
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
}
else
wake_up (&s->remove_ok);
@@ -827,7 +845,7 @@ static int dabusb_probe (struct usb_interface *intf,
s->devnum = intf->minor;
if (usb_reset_configuration (usbdev) < 0) {
- err("reset_configuration failed");
+ dev_err(&intf->dev, "reset_configuration failed\n");
goto reject;
}
if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
@@ -838,7 +856,7 @@ static int dabusb_probe (struct usb_interface *intf,
dabusb_fpga_download (s, NULL);
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
- err("set_interface failed");
+ dev_err(&intf->dev, "set_interface failed\n");
goto reject;
}
}
diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c
index 37577a670..50c3af538 100644
--- a/linux/drivers/media/video/em28xx/em28xx-video.c
+++ b/linux/drivers/media/video/em28xx/em28xx-video.c
@@ -1018,8 +1018,13 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
if (dev->board.has_msp34xx)
em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
- else
+ else {
rc = em28xx_get_ctrl(dev, ctrl);
+ if (rc < 0) {
+ em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ rc = 0;
+ }
+ }
mutex_unlock(&dev->lock);
return rc;
@@ -1355,7 +1360,7 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
@@ -1543,7 +1548,7 @@ static int radio_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
cap->capabilities = V4L2_CAP_TUNER;
diff --git a/linux/drivers/media/video/hexium_gemini.c b/linux/drivers/media/video/hexium_gemini.c
index 043a3080b..bcd8144c5 100644
--- a/linux/drivers/media/video/hexium_gemini.c
+++ b/linux/drivers/media/video/hexium_gemini.c
@@ -57,17 +57,6 @@ struct hexium_data
u8 byte;
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_STD, SAA7146_AFTER },
- { VIDIOC_G_CTRL, SAA7146_BEFORE },
- { VIDIOC_S_CTRL, SAA7146_BEFORE },
- { 0, 0 }
-};
-
#define HEXIUM_CONTROLS 1
static struct v4l2_queryctrl hexium_controls[] = {
{ V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
@@ -232,6 +221,132 @@ static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
return 0;
}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+ if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+ DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ *input = hexium->cur_input;
+
+ DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+
+ if (input < 0 || input >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ hexium->cur_input = input;
+ hexium_set_input(hexium, input);
+ return 0;
+}
+
+/* the saa7146 provides some controls (brightness, contrast, saturation)
+ which gets registered *after* this function. because of this we have
+ to return with a value != 0 even if the function succeded.. */
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ int i;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == qc->id) {
+ *qc = hexium_controls[i];
+ DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+ return 0;
+ }
+ }
+ return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+ int i;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == vc->id)
+ break;
+ }
+
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_PRIVATE_BASE) {
+ vc->value = hexium->cur_bw;
+ DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+ int i = 0;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == vc->id)
+ break;
+ }
+
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_PRIVATE_BASE)
+ hexium->cur_bw = vc->value;
+
+ DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
+
+ if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_pal);
+ return 0;
+ }
+ if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_ntsc);
+ return 0;
+ }
+ if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_secam);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_pal_bw);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_ntsc_bw);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
+ /* fixme: is there no bw secam mode? */
+ return -EINVAL;
+
+ return -EINVAL;
+}
+
+
static struct saa7146_ext_vv vv_data;
/* this function only gets called when the probing was successful */
@@ -280,6 +395,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
hexium->cur_input = 0;
saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+ vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+ vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
return -1;
@@ -307,153 +428,6 @@ static int hexium_detach(struct saa7146_dev *dev)
return 0;
}
-static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
- struct saa7146_dev *dev = fh->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-/*
- struct saa7146_vv *vv = dev->vv_data;
-*/
- switch (cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
- if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- int *input = (int *) arg;
- *input = hexium->cur_input;
-
- DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *) arg;
-
- DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
-
- if (input < 0 || input >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
-
- return 0;
- }
- /* the saa7146 provides some controls (brightness, contrast, saturation)
- which gets registered *after* this function. because of this we have
- to return with a value != 0 even if the function succeded.. */
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == qc->id) {
- *qc = hexium_controls[i];
- DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
- return 0;
- }
- }
- return -EAGAIN;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == vc->id) {
- break;
- }
- }
-
- if (i < 0) {
- return -EAGAIN;
- }
-
- switch (vc->id) {
- case V4L2_CID_PRIVATE_BASE:{
- vc->value = hexium->cur_bw;
- DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
- return 0;
- }
- }
- return -EINVAL;
- }
-
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i = 0;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == vc->id) {
- break;
- }
- }
-
- if (i < 0) {
- return -EAGAIN;
- }
-
- switch (vc->id) {
- case V4L2_CID_PRIVATE_BASE:{
- hexium->cur_bw = vc->value;
- break;
- }
- }
-
- DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
-
- if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_pal);
- return 0;
- }
- if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_ntsc);
- return 0;
- }
- if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_secam);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_pal_bw);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_ntsc_bw);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
- /* fixme: is there no bw secam mode? */
- return -EINVAL;
- }
-
- return -EINVAL;
- }
- default:
-/*
- DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
{
struct hexium *hexium = (struct hexium *) dev->ext_priv;
@@ -515,8 +489,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &hexium_standards[0],
.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = hexium_ioctl,
};
static struct saa7146_extension hexium_extension = {
diff --git a/linux/drivers/media/video/hexium_orion.c b/linux/drivers/media/video/hexium_orion.c
index 847518f78..4178edcc2 100644
--- a/linux/drivers/media/video/hexium_orion.c
+++ b/linux/drivers/media/video/hexium_orion.c
@@ -58,14 +58,6 @@ struct hexium_data
u8 byte;
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_STD, SAA7146_AFTER },
- { 0, 0 }
-};
-
struct hexium
{
int type;
@@ -330,6 +322,44 @@ static int hexium_set_input(struct hexium *hexium, int input)
return 0;
}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+ if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+ DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ *input = hexium->cur_input;
+
+ DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ if (input < 0 || input >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ hexium->cur_input = input;
+ hexium_set_input(hexium, input);
+
+ return 0;
+}
+
static struct saa7146_ext_vv vv_data;
/* this function only gets called when the probing was successful */
@@ -340,6 +370,9 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
DEB_EE((".\n"));
saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
printk("hexium_orion: cannot register capture v4l2 device. skipping.\n");
return -1;
@@ -371,58 +404,6 @@ static int hexium_detach(struct saa7146_dev *dev)
return 0;
}
-static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
- struct saa7146_dev *dev = fh->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-/*
- struct saa7146_vv *vv = dev->vv_data;
-*/
- switch (cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
- if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- int *input = (int *) arg;
- *input = hexium->cur_input;
-
- DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *) arg;
-
- if (input < 0 || input >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
-
- return 0;
- }
- default:
-/*
- DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
{
return 0;
@@ -480,8 +461,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &hexium_standards[0],
.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = hexium_ioctl,
};
static struct saa7146_extension extension = {
diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.h b/linux/drivers/media/video/ivtv/ivtv-driver.h
index 51f6e54ba..03df1cb7d 100644
--- a/linux/drivers/media/video/ivtv/ivtv-driver.h
+++ b/linux/drivers/media/video/ivtv/ivtv-driver.h
@@ -697,7 +697,7 @@ struct ivtv {
u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */
u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */
unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */
- u16 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
+ u32 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
/* VBI state info */
diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c
index d594bc29f..617667d1c 100644
--- a/linux/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c
@@ -148,10 +148,10 @@ void ivtv_release_stream(struct ivtv_stream *s)
static void ivtv_dualwatch(struct ivtv *itv)
{
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;
new_stereo_mode = itv->params.audio_properties & stereo_mask;
memset(&vt, 0, sizeof(vt));
diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c
index 974d9bcbd..e7b94e6b1 100644
--- a/linux/drivers/media/video/mxb.c
+++ b/linux/drivers/media/video/mxb.c
@@ -111,26 +111,6 @@ static struct v4l2_queryctrl mxb_controls[] = {
{ V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
- { VIDIOC_G_CTRL, SAA7146_BEFORE },
- { VIDIOC_S_CTRL, SAA7146_BEFORE },
- { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_DBG_G_REGISTER, SAA7146_EXCLUSIVE },
- { VIDIOC_DBG_S_REGISTER, SAA7146_EXCLUSIVE },
- { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
- { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
- { 0, 0 }
-};
-
struct mxb
{
struct video_device *video_dev;
@@ -425,387 +405,430 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
}
*/
-static struct saa7146_ext_vv vv_data;
-
-/* this function only gets called when the probing was successful */
-static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
{
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ int i;
- DEB_EE(("dev:%p\n", dev));
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == qc->id) {
+ *qc = mxb_controls[i];
+ DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+ return 0;
+ }
+ }
+ return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
- /* checking for i2c-devices can be omitted here, because we
- already did this in "mxb_vl42_probe" */
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ int i;
- saa7146_vv_init(dev, &vv_data);
- if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
- ERR(("cannot register capture v4l2 device. skipping.\n"));
- return -1;
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == vc->id)
+ break;
}
- /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
- if (MXB_BOARD_CAN_DO_VBI(dev)) {
- if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
- ERR(("cannot register vbi v4l2 device. skipping.\n"));
- }
- }
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
- i2c_use_client(mxb->tea6420_1);
- i2c_use_client(mxb->tea6420_2);
- i2c_use_client(mxb->tea6415c);
- i2c_use_client(mxb->tda9840);
- i2c_use_client(mxb->saa7111a);
- i2c_use_client(mxb->tuner);
-
- printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+ if (vc->id == V4L2_CID_AUDIO_MUTE) {
+ vc->value = mxb->cur_mute;
+ DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
+ return 0;
+ }
- mxb_num++;
- mxb_init_done(dev);
+ DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
return 0;
}
-static int mxb_detach(struct saa7146_dev *dev)
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ int i = 0;
- DEB_EE(("dev:%p\n", dev));
-
- i2c_release_client(mxb->tea6420_1);
- i2c_release_client(mxb->tea6420_2);
- i2c_release_client(mxb->tea6415c);
- i2c_release_client(mxb->tda9840);
- i2c_release_client(mxb->saa7111a);
- i2c_release_client(mxb->tuner);
-
- saa7146_unregister_device(&mxb->video_dev,dev);
- if (MXB_BOARD_CAN_DO_VBI(dev))
- saa7146_unregister_device(&mxb->vbi_dev, dev);
- saa7146_vv_release(dev);
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == vc->id)
+ break;
+ }
- mxb_num--;
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
- i2c_del_adapter(&mxb->i2c_adapter);
- kfree(mxb);
+ if (vc->id == V4L2_CID_AUDIO_MUTE) {
+ mxb->cur_mute = vc->value;
+ if (!vc->value) {
+ /* switch the audio-source */
+ mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
+ &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
+ mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
+ &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
+ } else {
+ mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
+ &TEA6420_line[6][0]);
+ mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
+ &TEA6420_line[6][1]);
+ }
+ DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
+ }
+ return 0;
+}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+ if (i->index < 0 || i->index >= MXB_INPUTS)
+ return -EINVAL;
+ memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
return 0;
}
-static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
{
- struct saa7146_dev *dev = fh->dev;
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
- struct saa7146_vv *vv = dev->vv_data;
+ *i = mxb->cur_input;
- switch(cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
+ DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
+ return 0;
+}
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
- if (i->index < 0 || i->index >= MXB_INPUTS)
- return -EINVAL;
- memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
- return 0;
- }
- /* the saa7146 provides some controls (brightness, contrast, saturation)
- which gets registered *after* this function. because of this we have
- to return with a value != 0 even if the function succeded.. */
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == qc->id) {
- *qc = mxb_controls[i];
- DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
- return 0;
- }
- }
- return -EAGAIN;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ struct tea6415c_multiplex vm;
+ struct v4l2_routing route;
+ int i = 0;
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == vc->id)
- break;
- }
+ DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
- if (i < 0)
- return -EAGAIN;
+ if (input < 0 || input >= MXB_INPUTS)
+ return -EINVAL;
- if (vc->id == V4L2_CID_AUDIO_MUTE) {
- vc->value = mxb->cur_mute;
- DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
- return 0;
- }
+ mxb->cur_input = input;
- DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
- return 0;
- }
+ saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
+ input_port_selection[input].hps_sync);
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i = 0;
+ /* prepare switching of tea6415c and saa7111a;
+ have a look at the 'background'-file for further informations */
+ switch (input) {
+ case TUNER:
+ i = SAA7115_COMPOSITE0;
+ vm.in = 3;
+ vm.out = 17;
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == vc->id)
- break;
+ if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
+ return -EFAULT;
}
+ /* connect tuner-output always to multicable */
+ vm.in = 3;
+ vm.out = 13;
+ break;
+ case AUX3_YC:
+ /* nothing to be done here. aux3_yc is
+ directly connected to the saa711a */
+ i = SAA7115_SVIDEO1;
+ break;
+ case AUX3:
+ /* nothing to be done here. aux3 is
+ directly connected to the saa711a */
+ i = SAA7115_COMPOSITE1;
+ break;
+ case AUX1:
+ i = SAA7115_COMPOSITE0;
+ vm.in = 1;
+ vm.out = 17;
+ break;
+ }
- if (i < 0)
- return -EAGAIN;
-
- if (vc->id == V4L2_CID_AUDIO_MUTE) {
- mxb->cur_mute = vc->value;
- if (!vc->value) {
- /* switch the audio-source */
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
- } else {
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[6][1]);
- }
- DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
+ /* switch video in tea6415c only if necessary */
+ switch (input) {
+ case TUNER:
+ case AUX1:
+ if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
+ return -EFAULT;
}
- return 0;
+ break;
+ default:
+ break;
}
- case VIDIOC_G_INPUT:
- {
- int *input = (int *)arg;
- *input = mxb->cur_input;
- DEB_EE(("VIDIOC_G_INPUT %d.\n", *input));
- return 0;
+ /* switch video in saa7111a */
+ route.input = i;
+ route.output = 0;
+ if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
+
+ /* switch the audio-source only if necessary */
+ if (0 == mxb->cur_mute) {
+ mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
+ &TEA6420_line[video_audio_connect[input]][0]);
+ mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
+ &TEA6420_line[video_audio_connect[input]][1]);
}
- case VIDIOC_S_INPUT:
- {
- int input = *(int *)arg;
- struct tea6415c_multiplex vm;
- struct v4l2_routing route;
- int i = 0;
- DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+ return 0;
+}
- if (input < 0 || input >= MXB_INPUTS)
- return -EINVAL;
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- mxb->cur_input = input;
+ if (t->index) {
+ DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
+ return -EINVAL;
+ }
- saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
- input_port_selection[input].hps_sync);
+ DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
- /* prepare switching of tea6415c and saa7111a;
- have a look at the 'background'-file for further informations */
- switch (input) {
- case TUNER:
- i = SAA7115_COMPOSITE0;
- vm.in = 3;
- vm.out = 17;
+ memset(t, 0, sizeof(*t));
+ i2c_clients_command(&mxb->i2c_adapter, VIDIOC_G_TUNER, t);
- if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
- return -EFAULT;
- }
- /* connect tuner-output always to multicable */
- vm.in = 3;
- vm.out = 13;
- break;
- case AUX3_YC:
- /* nothing to be done here. aux3_yc is
- directly connected to the saa711a */
- i = SAA7115_SVIDEO1;
- break;
- case AUX3:
- /* nothing to be done here. aux3 is
- directly connected to the saa711a */
- i = SAA7115_COMPOSITE1;
- break;
- case AUX1:
- i = SAA7115_COMPOSITE0;
- vm.in = 1;
- vm.out = 17;
- break;
- }
+ strlcpy(t->name, "TV Tuner", sizeof(t->name));
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+ t->audmode = mxb->cur_mode;
+ return 0;
+}
- /* switch video in tea6415c only if necessary */
- switch (input) {
- case TUNER:
- case AUX1:
- if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
- return -EFAULT;
- }
- break;
- default:
- break;
- }
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- /* switch video in saa7111a */
- route.input = i;
- route.output = 0;
- if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
- printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
+ if (t->index) {
+ DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
+ return -EINVAL;
+ }
- /* switch the audio-source only if necessary */
- if( 0 == mxb->cur_mute ) {
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[input]][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[input]][1]);
- }
+ mxb->cur_mode = t->audmode;
+ i2c_clients_command(&mxb->i2c_adapter, VIDIOC_S_TUNER, t);
+ return 0;
+}
- return 0;
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ if (mxb->cur_input) {
+ DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
+ mxb->cur_input));
+ return -EINVAL;
}
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
- if (t->index) {
- DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
- return -EINVAL;
- }
+ *f = mxb->cur_freq;
- DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
+ DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
+ return 0;
+}
- memset(t, 0, sizeof(*t));
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ struct saa7146_vv *vv = dev->vv_data;
- strlcpy(t->name, "TV Tuner", sizeof(t->name));
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
- t->audmode = mxb->cur_mode;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
+ if (f->tuner)
+ return -EINVAL;
- if (t->index) {
- DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
- return -EINVAL;
- }
+ if (V4L2_TUNER_ANALOG_TV != f->type)
+ return -EINVAL;
- mxb->cur_mode = t->audmode;
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
- return 0;
+ if (mxb->cur_input) {
+ DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
+ return -EINVAL;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- if (mxb->cur_input) {
- DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
- mxb->cur_input));
- return -EINVAL;
- }
+ mxb->cur_freq = *f;
+ DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
- *f = mxb->cur_freq;
+ /* tune in desired frequency */
+ mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
- DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
- return 0;
+ /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
+ spin_lock(&dev->slock);
+ vv->vbi_fieldcount = 0;
+ spin_unlock(&dev->slock);
+
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ if (a->index < 0 || a->index > MXB_INPUTS) {
+ DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
+ return -EINVAL;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- if (f->tuner)
- return -EINVAL;
+ DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
+ memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
+ return 0;
+}
- if (V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
+ return 0;
+}
- if (mxb->cur_input) {
- DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
- return -EINVAL;
- }
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- mxb->cur_freq = *f;
- DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
+ i2c_clients_command(&mxb->i2c_adapter, VIDIOC_DBG_G_REGISTER, reg);
+ return 0;
+}
- /* tune in desired frequency */
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
+static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
- spin_lock(&dev->slock);
- vv->vbi_fieldcount = 0;
- spin_unlock(&dev->slock);
+ i2c_clients_command(&mxb->i2c_adapter, VIDIOC_DBG_S_REGISTER, reg);
+ return 0;
+}
+#endif
- return 0;
- }
+static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ switch (cmd) {
case MXB_S_AUDIO_CD:
{
- int i = *(int*)arg;
+ int i = *(int *)arg;
if (i < 0 || i >= MXB_AUDIOS) {
- DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
+ DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i));
return -EINVAL;
}
- DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
+ DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
- mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
+ mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[i][0]);
+ mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[i][1]);
return 0;
}
case MXB_S_AUDIO_LINE:
{
- int i = *(int*)arg;
+ int i = *(int *)arg;
if (i < 0 || i >= MXB_AUDIOS) {
- DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
+ DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i));
return -EINVAL;
}
- DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
- mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
+ DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
+ mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[i][0]);
+ mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[i][1]);
return 0;
}
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *a = arg;
+ default:
+/*
+ DEB2(printk("does not handle this ioctl.\n"));
+*/
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
- if (a->index < 0 || a->index > MXB_INPUTS) {
- DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
- return -EINVAL;
- }
+static struct saa7146_ext_vv vv_data;
+
+/* this function only gets called when the probing was successful */
+static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+{
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
- memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
+ DEB_EE(("dev:%p\n", dev));
- return 0;
- }
- case VIDIOC_S_AUDIO:
- {
- struct v4l2_audio *a = arg;
+ /* checking for i2c-devices can be omitted here, because we
+ already did this in "mxb_vl42_probe" */
- DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
- return 0;
- }
+ saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+ vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+ vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
+ vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
+ vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
+ vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
+ vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
+ vv_data.ops.vidioc_g_audio = vidioc_g_audio;
+ vv_data.ops.vidioc_s_audio = vidioc_s_audio;
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_DBG_S_REGISTER:
- case VIDIOC_DBG_G_REGISTER:
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
- return 0;
+ vv_data.ops.vidioc_g_register = vidioc_g_register;
+ vv_data.ops.vidioc_s_register = vidioc_s_register;
#endif
- default:
-/*
- DEB2(printk("does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
+ vv_data.ops.vidioc_default = vidioc_default;
+ if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
+ ERR(("cannot register capture v4l2 device. skipping.\n"));
+ return -1;
+ }
+
+ /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
+ if (MXB_BOARD_CAN_DO_VBI(dev)) {
+ if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
+ ERR(("cannot register vbi v4l2 device. skipping.\n"));
+ }
}
+
+ i2c_use_client(mxb->tea6420_1);
+ i2c_use_client(mxb->tea6420_2);
+ i2c_use_client(mxb->tea6415c);
+ i2c_use_client(mxb->tda9840);
+ i2c_use_client(mxb->saa7111a);
+ i2c_use_client(mxb->tuner);
+
+ printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+
+ mxb_num++;
+ mxb_init_done(dev);
+ return 0;
+}
+
+static int mxb_detach(struct saa7146_dev *dev)
+{
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ DEB_EE(("dev:%p\n", dev));
+
+ i2c_release_client(mxb->tea6420_1);
+ i2c_release_client(mxb->tea6420_2);
+ i2c_release_client(mxb->tea6415c);
+ i2c_release_client(mxb->tda9840);
+ i2c_release_client(mxb->saa7111a);
+ i2c_release_client(mxb->tuner);
+
+ saa7146_unregister_device(&mxb->video_dev,dev);
+ if (MXB_BOARD_CAN_DO_VBI(dev))
+ saa7146_unregister_device(&mxb->vbi_dev, dev);
+ saa7146_vv_release(dev);
+
+ mxb_num--;
+
+ i2c_del_adapter(&mxb->i2c_adapter);
+ kfree(mxb);
+
return 0;
}
@@ -886,8 +909,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &standard[0],
.num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = mxb_ioctl,
};
static struct saa7146_extension extension = {
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index ad34cc74a..19e12c5aa 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2436,10 +2436,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->usb_intf = intf;
hdw->usb_dev = interface_to_usbdev(intf);
- scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
- "usb %s address %d",
- dev_name(&hdw->usb_dev->dev),
- hdw->usb_dev->devnum);
+ usb_make_path(hdw->usb_dev, hdw->bus_info, sizeof(hdw->bus_info));
ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
usb_set_interface(hdw->usb_dev,ifnum,0);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 26da521f1..e4bf0278c 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -1275,8 +1275,9 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
dip->minor_type = pvr2_v4l_type_video;
nr_ptr = video_nr;
if (!dip->stream) {
- err("Failed to set up pvrusb2 v4l video dev"
- " due to missing stream instance");
+ pr_err(KBUILD_MODNAME
+ ": Failed to set up pvrusb2 v4l video dev"
+ " due to missing stream instance\n");
return;
}
break;
@@ -1293,8 +1294,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
break;
default:
/* Bail out (this should be impossible) */
- err("Failed to set up pvrusb2 v4l dev"
- " due to unrecognized config");
+ pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
+ " due to unrecognized config\n");
return;
}
@@ -1310,7 +1311,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
dip->v4l_type, mindevnum) < 0) &&
(video_register_device(&dip->devbase,
dip->v4l_type, -1) < 0)) {
- err("Failed to register pvrusb2 v4l device");
+ pr_err(KBUILD_MODNAME
+ ": Failed to register pvrusb2 v4l device\n");
}
printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
diff --git a/linux/drivers/media/video/s2255drv.c b/linux/drivers/media/video/s2255drv.c
index 2a2cbb418..edfac2f9e 100644
--- a/linux/drivers/media/video/s2255drv.c
+++ b/linux/drivers/media/video/s2255drv.c
@@ -337,14 +337,19 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
u16 index, u16 value, void *buf,
s32 buf_len, int bOut);
+/* dev_err macro with driver name */
+#define S2255_DRIVER_NAME "s2255"
+#define s2255_dev_err(dev, fmt, arg...) \
+ dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
+
#define dprintk(level, fmt, arg...) \
do { \
if (*s2255_debug >= (level)) { \
- printk(KERN_DEBUG "s2255: " fmt, ##arg); \
+ printk(KERN_DEBUG S2255_DRIVER_NAME \
+ ": " fmt, ##arg); \
} \
} while (0)
-
static struct usb_driver s2255_driver;
@@ -529,14 +534,14 @@ static void s2255_fwchunk_complete(struct urb *urb)
int len;
dprintk(100, "udev %p urb %p", udev, urb);
if (urb->status) {
- dev_err(&udev->dev, "URB failed with status %d", urb->status);
+ dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
atomic_set(&data->fw_state, S2255_FW_FAILED);
/* wake up anything waiting for the firmware */
wake_up(&data->wait_fw);
return;
}
if (data->fw_urb == NULL) {
- dev_err(&udev->dev, "s2255 disconnected\n");
+ s2255_dev_err(&udev->dev, "disconnected\n");
atomic_set(&data->fw_state, S2255_FW_FAILED);
/* wake up anything waiting for the firmware */
wake_up(&data->wait_fw);
@@ -842,8 +847,7 @@ static int vidioc_querycap(struct file *file, void *priv,
struct s2255_dev *dev = fh->dev;
strlcpy(cap->driver, "s2255", sizeof(cap->driver));
strlcpy(cap->card, "s2255", sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev),
- sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = S2255_VERSION;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
return 0;
@@ -1279,7 +1283,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
}
if (!res_get(dev, fh)) {
- dev_err(&dev->udev->dev, "s2255: stream busy\n");
+ s2255_dev_err(&dev->udev->dev, "stream busy\n");
return -EBUSY;
}
@@ -1546,7 +1550,8 @@ static int s2255_open(struct file *file)
switch (atomic_read(&dev->fw_data->fw_state)) {
case S2255_FW_FAILED:
- err("2255 firmware load failed. retrying.\n");
+ s2255_dev_err(&dev->udev->dev,
+ "firmware load failed. retrying.\n");
s2255_fwload_start(dev, 1);
wait_event_timeout(dev->fw_data->wait_fw,
((atomic_read(&dev->fw_data->fw_state)
@@ -2174,7 +2179,8 @@ static int s2255_board_init(struct s2255_dev *dev)
printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver);
if (fw_ver < CUR_USB_FWVER)
- err("usb firmware not up to date %d\n", fw_ver);
+ dev_err(&dev->udev->dev,
+ "usb firmware not up to date %d\n", fw_ver);
for (j = 0; j < MAX_CHANNELS; j++) {
dev->b_acquire[j] = 0;
@@ -2229,13 +2235,13 @@ static void read_pipe_completion(struct urb *purb)
dprintk(100, "read pipe completion %p, status %d\n", purb,
purb->status);
if (pipe_info == NULL) {
- err("no context !");
+ dev_err(&purb->dev->dev, "no context!\n");
return;
}
dev = pipe_info->dev;
if (dev == NULL) {
- err("no context !");
+ dev_err(&purb->dev->dev, "no context!\n");
return;
}
status = purb->status;
@@ -2287,7 +2293,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!pipe_info->stream_urb) {
dev_err(&dev->udev->dev,
- "ReadStream: Unable to alloc URB");
+ "ReadStream: Unable to alloc URB\n");
return -ENOMEM;
}
/* transfer buffer allocated in board_init */
@@ -2392,7 +2398,7 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
int j;
if (dev == NULL) {
- err("s2255: invalid device");
+ s2255_dev_err(&dev->udev->dev, "invalid device\n");
return;
}
dprintk(4, "stop read pipe\n");
@@ -2454,7 +2460,7 @@ static int s2255_probe(struct usb_interface *interface,
/* allocate memory for our device state and initialize it to zero */
dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
if (dev == NULL) {
- err("s2255: out of memory");
+ s2255_dev_err(&interface->dev, "out of memory\n");
goto error;
}
@@ -2488,7 +2494,7 @@ static int s2255_probe(struct usb_interface *interface,
}
if (!dev->read_endpoint) {
- dev_err(&interface->dev, "Could not find bulk-in endpoint");
+ dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
goto error;
}
@@ -2584,7 +2590,7 @@ static void s2255_disconnect(struct usb_interface *interface)
}
static struct usb_driver s2255_driver = {
- .name = "s2255",
+ .name = S2255_DRIVER_NAME,
.probe = s2255_probe,
.disconnect = s2255_disconnect,
.id_table = s2255_table,
@@ -2598,7 +2604,8 @@ static int __init usb_s2255_init(void)
result = usb_register(&s2255_driver);
if (result)
- err("usb_register failed. Error number %d", result);
+ pr_err(KBUILD_MODNAME
+ ": usb_register failed. Error number %d\n", result);
dprintk(2, "s2255_init: done\n");
return result;
diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c
index 33f37ac46..440f1b05a 100644
--- a/linux/drivers/media/video/usbvision/usbvision-core.c
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c
@@ -381,8 +381,9 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
usbvision->scratch = vmalloc_32(scratch_buf_size);
scratch_reset(usbvision);
if(usbvision->scratch == NULL) {
- err("%s: unable to allocate %d bytes for scratch",
- __func__, scratch_buf_size);
+ dev_err(&usbvision->dev->dev,
+ "%s: unable to allocate %d bytes for scratch\n",
+ __func__, scratch_buf_size);
return -ENOMEM;
}
return 0;
@@ -491,8 +492,9 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
usbvision->IntraFrameBuffer = vmalloc_32(IFB_size);
if (usbvision->IntraFrameBuffer == NULL) {
- err("%s: unable to allocate %d for compr. frame buffer",
- __func__, IFB_size);
+ dev_err(&usbvision->dev->dev,
+ "%s: unable to allocate %d for compr. frame buffer\n",
+ __func__, IFB_size);
return -ENOMEM;
}
return 0;
@@ -1519,8 +1521,9 @@ static void usbvision_isocIrq(struct urb *urb, struct pt_regs *regs)
errCode = usb_submit_urb (urb, GFP_ATOMIC);
if(errCode) {
- err("%s: usb_submit_urb failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_submit_urb failed: error %d\n",
+ __func__, errCode);
}
return;
@@ -1551,7 +1554,8 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
0, (__u16) reg, buffer, 1, HZ);
if (errCode < 0) {
- err("%s: failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: failed: error %d\n", __func__, errCode);
return errCode;
}
return buffer[0];
@@ -1579,7 +1583,8 @@ int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
if (errCode < 0) {
- err("%s: failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: failed: error %d\n", __func__, errCode);
}
return errCode;
}
@@ -1859,7 +1864,8 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ);
if (errCode < 0) {
- err("%s failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s failed: error %d\n", __func__, errCode);
return errCode;
}
usbvision->curwidth = usbvision->stretch_width * UsbWidth;
@@ -2245,7 +2251,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
(__u16) USBVISION_DRM_PRM1, value, 8, HZ);
if (rc < 0) {
- err("%sERROR=%d", __func__, rc);
+ dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc);
return rc;
}
@@ -2453,8 +2459,9 @@ int usbvision_set_alternate(struct usb_usbvision *dev)
PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
if (errCode < 0) {
- err ("cannot change alternate number to %d (error=%i)",
- dev->ifaceAlt, errCode);
+ dev_err(&dev->dev->dev,
+ "cannot change alternate number to %d (error=%i)\n",
+ dev->ifaceAlt, errCode);
return errCode;
}
}
@@ -2505,7 +2512,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
if (urb == NULL) {
- err("%s: usb_alloc_urb() failed", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_alloc_urb() failed\n", __func__);
return -ENOMEM;
}
usbvision->sbuf[bufIdx].urb = urb;
@@ -2537,8 +2545,9 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
GFP_KERNEL);
if (errCode) {
- err("%s: usb_submit_urb(%d) failed: error %d",
- __func__, bufIdx, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_submit_urb(%d) failed: error %d\n",
+ __func__, bufIdx, errCode);
}
}
@@ -2587,8 +2596,9 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
usbvision->ifaceAlt);
if (errCode < 0) {
- err("%s: usb_set_interface() failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_set_interface() failed: error %d\n",
+ __func__, errCode);
usbvision->last_error = errCode;
}
regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
diff --git a/linux/drivers/media/video/usbvision/usbvision-i2c.c b/linux/drivers/media/video/usbvision/usbvision-i2c.c
index 1d37e6206..4c74861f4 100644
--- a/linux/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/linux/drivers/media/video/usbvision/usbvision-i2c.c
@@ -120,7 +120,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
/* try extended address code... */
ret = try_write_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while writing");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while writing\n");
return -EREMOTEIO;
}
add[0] = addr;
@@ -129,7 +130,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
addr |= 0x01;
ret = try_read_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while reading");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while reading\n");
return -EREMOTEIO;
}
}
diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c
index 2622de003..334c77d91 100644
--- a/linux/drivers/media/video/usbvision/usbvision-video.c
+++ b/linux/drivers/media/video/usbvision/usbvision-video.c
@@ -329,7 +329,7 @@ static void usbvision_create_sysfs(struct video_device *vdev)
return;
} while (0);
- err("%s error: %d\n", __func__, res);
+ dev_err(&vdev->dev, "%s error: %d\n", __func__, res);
}
static void usbvision_remove_sysfs(struct video_device *vdev)
@@ -487,8 +487,9 @@ static int vidioc_g_register (struct file *file, void *priv,
/* NT100x has a 8-bit register space */
errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
if (errCode < 0) {
- err("%s: VIDIOC_DBG_G_REGISTER failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->vdev->dev,
+ "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n",
+ __func__, errCode);
return errCode;
}
reg->val = errCode;
@@ -507,8 +508,9 @@ static int vidioc_s_register (struct file *file, void *priv,
/* NT100x has a 8-bit register space */
errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
if (errCode < 0) {
- err("%s: VIDIOC_DBG_S_REGISTER failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->vdev->dev,
+ "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n",
+ __func__, errCode);
return errCode;
}
return 0;
@@ -524,8 +526,7 @@ static int vidioc_querycap (struct file *file, void *priv,
strlcpy(vc->card,
usbvision_device_data[usbvision->DevModel].ModelString,
sizeof(vc->card));
- strlcpy(vc->bus_info, dev_name(&usbvision->dev->dev),
- sizeof(vc->bus_info));
+ usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
vc->version = USBVISION_DRIVER_VERSION;
vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_AUDIO |
@@ -1189,7 +1190,9 @@ static int usbvision_radio_open(struct file *file)
mutex_lock(&usbvision->lock);
if (usbvision->user) {
- err("%s: Someone tried to open an already opened USBVision Radio!", __func__);
+ dev_err(&usbvision->rdev->dev,
+ "%s: Someone tried to open an already opened USBVision Radio!\n",
+ __func__);
errCode = -EBUSY;
}
else {
@@ -1413,7 +1416,8 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
struct video_device *vdev;
if (usb_dev == NULL) {
- err("%s: usbvision->dev is not set", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usbvision->dev is not set\n", __func__);
return NULL;
}
@@ -1524,7 +1528,9 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
return 0;
err_exit:
- err("USBVision[%d]: video_register_device() failed", usbvision->nr);
+ dev_err(&usbvision->dev->dev,
+ "USBVision[%d]: video_register_device() failed\n",
+ usbvision->nr);
usbvision_unregister_video(usbvision);
return -1;
}
@@ -1675,20 +1681,20 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
}
endpoint = &interface->endpoint[1].desc;
if (!usb_endpoint_xfer_isoc(endpoint)) {
- err("%s: interface %d. has non-ISO endpoint!",
+ dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
__func__, ifnum);
- err("%s: Endpoint attributes %d",
+ dev_err(&intf->dev, "%s: Endpoint attributes %d",
__func__, endpoint->bmAttributes);
return -ENODEV;
}
if (usb_endpoint_dir_out(endpoint)) {
- err("%s: interface %d. has ISO OUT endpoint!",
+ dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n",
__func__, ifnum);
return -ENODEV;
}
if ((usbvision = usbvision_alloc(dev)) == NULL) {
- err("%s: couldn't allocate USBVision struct", __func__);
+ dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__);
return -ENOMEM;
}
@@ -1711,7 +1717,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
usbvision->alt_max_pkt_size = kmalloc(32*
usbvision->num_alt,GFP_KERNEL);
if (usbvision->alt_max_pkt_size == NULL) {
- err("usbvision: out of memory!\n");
+ dev_err(&intf->dev, "usbvision: out of memory!\n");
mutex_unlock(&usbvision->lock);
return -ENOMEM;
}
@@ -1772,7 +1778,8 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
PDEBUG(DBG_PROBE, "");
if (usbvision == NULL) {
- err("%s: usb_get_intfdata() failed", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_get_intfdata() failed\n", __func__);
return;
}
usb_set_intfdata (intf, NULL);
diff --git a/linux/drivers/media/video/uvc/uvc_ctrl.c b/linux/drivers/media/video/uvc/uvc_ctrl.c
index f3f36f625..7774ce6b5 100644
--- a/linux/drivers/media/video/uvc/uvc_ctrl.c
+++ b/linux/drivers/media/video/uvc/uvc_ctrl.c
@@ -788,7 +788,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
v4l2_ctrl->id = mapping->id;
v4l2_ctrl->type = mapping->v4l2_type;
- strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
+ strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
v4l2_ctrl->flags = 0;
if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c
index 401bb7c15..2a41eb418 100644
--- a/linux/drivers/media/video/uvc/uvc_driver.c
+++ b/linux/drivers/media/video/uvc/uvc_driver.c
@@ -314,7 +314,7 @@ static int uvc_parse_format(struct uvc_device *dev,
fmtdesc = uvc_format_by_guid(&buffer[5]);
if (fmtdesc != NULL) {
- strncpy(format->name, fmtdesc->name,
+ strlcpy(format->name, fmtdesc->name,
sizeof format->name);
format->fcc = fmtdesc->fcc;
} else {
@@ -345,7 +345,7 @@ static int uvc_parse_format(struct uvc_device *dev,
return -EINVAL;
}
- strncpy(format->name, "MJPEG", sizeof format->name);
+ strlcpy(format->name, "MJPEG", sizeof format->name);
format->fcc = V4L2_PIX_FMT_MJPEG;
format->flags = UVC_FMT_FLAG_COMPRESSED;
format->bpp = 0;
@@ -363,13 +363,13 @@ static int uvc_parse_format(struct uvc_device *dev,
switch (buffer[8] & 0x7f) {
case 0:
- strncpy(format->name, "SD-DV", sizeof format->name);
+ strlcpy(format->name, "SD-DV", sizeof format->name);
break;
case 1:
- strncpy(format->name, "SDL-DV", sizeof format->name);
+ strlcpy(format->name, "SDL-DV", sizeof format->name);
break;
case 2:
- strncpy(format->name, "HD-DV", sizeof format->name);
+ strlcpy(format->name, "HD-DV", sizeof format->name);
break;
default:
uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
@@ -379,7 +379,7 @@ static int uvc_parse_format(struct uvc_device *dev,
return -EINVAL;
}
- strncat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
+ strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
sizeof format->name);
format->fcc = V4L2_PIX_FMT_DV;
@@ -1526,7 +1526,7 @@ static int uvc_register_video(struct uvc_device *dev)
vdev->minor = -1;
vdev->fops = &uvc_fops;
vdev->release = video_device_release;
- strncpy(vdev->name, dev->name, sizeof vdev->name);
+ strlcpy(vdev->name, dev->name, sizeof vdev->name);
/* Set the driver data before calling video_register_device, otherwise
* uvc_v4l2_open might race us.
@@ -1621,7 +1621,7 @@ static int uvc_probe(struct usb_interface *intf,
dev->quirks = id->driver_info | uvc_quirks_param;
if (udev->product != NULL)
- strncpy(dev->name, udev->product, sizeof dev->name);
+ strlcpy(dev->name, udev->product, sizeof dev->name);
else
snprintf(dev->name, sizeof dev->name,
"UVC Camera (%04x:%04x)",
@@ -1835,6 +1835,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0 },
+ /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x058f,
+ .idProduct = 0x3820,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* Apple Built-In iSight */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1881,7 +1890,7 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Asus F9SG */
+ /* Syntek (Asus F9SG) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x174f,
diff --git a/linux/drivers/media/video/uvc/uvc_status.c b/linux/drivers/media/video/uvc/uvc_status.c
index 77a263463..4f4171fa8 100644
--- a/linux/drivers/media/video/uvc/uvc_status.c
+++ b/linux/drivers/media/video/uvc/uvc_status.c
@@ -28,26 +28,19 @@
#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
static int uvc_input_init(struct uvc_device *dev)
{
- struct usb_device *udev = dev->udev;
struct input_dev *input;
- char *phys = NULL;
int ret;
input = input_allocate_device();
if (input == NULL)
return -ENOMEM;
- phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath),
- GFP_KERNEL);
- if (phys == NULL) {
- ret = -ENOMEM;
- goto error;
- }
- sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath);
+ usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
+ strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));
input->name = dev->name;
- input->phys = phys;
- usb_to_input_id(udev, &input->id);
+ input->phys = dev->input_phys;
+ usb_to_input_id(dev->udev, &input->id);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
input->dev.parent = &dev->intf->dev;
#else
@@ -65,7 +58,6 @@ static int uvc_input_init(struct uvc_device *dev)
error:
input_free_device(input);
- kfree(phys);
return ret;
}
diff --git a/linux/drivers/media/video/uvc/uvc_v4l2.c b/linux/drivers/media/video/uvc/uvc_v4l2.c
index f295d7169..0baa59f61 100644
--- a/linux/drivers/media/video/uvc/uvc_v4l2.c
+++ b/linux/drivers/media/video/uvc/uvc_v4l2.c
@@ -55,7 +55,7 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
return -EINVAL;
menu_info = &mapping->menu_info[query_menu->index];
- strncpy(query_menu->name, menu_info->name, 32);
+ strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
return 0;
}
@@ -492,10 +492,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
struct v4l2_capability *cap = arg;
memset(cap, 0, sizeof *cap);
- strncpy(cap->driver, "uvcvideo", sizeof cap->driver);
- strncpy(cap->card, vdev->name, 32);
- strncpy(cap->bus_info, video->dev->udev->bus->bus_name,
- sizeof cap->bus_info);
+ strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
+ strlcpy(cap->card, vdev->name, sizeof cap->card);
+ usb_make_path(video->dev->udev,
+ cap->bus_info, sizeof(cap->bus_info));
cap->version = DRIVER_VERSION_NUMBER;
if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
@@ -626,7 +626,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
memset(input, 0, sizeof *input);
input->index = index;
- strncpy(input->name, iterm->name, sizeof input->name);
+ strlcpy(input->name, iterm->name, sizeof input->name);
if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA)
input->type = V4L2_INPUT_TYPE_CAMERA;
break;
@@ -688,7 +688,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
fmt->flags = 0;
if (format->flags & UVC_FMT_FLAG_COMPRESSED)
fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
- strncpy(fmt->description, format->name,
+ strlcpy(fmt->description, format->name,
sizeof fmt->description);
fmt->description[sizeof fmt->description - 1] = 0;
fmt->pixelformat = format->fcc;
diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c
index 999155fc2..04c791213 100644
--- a/linux/drivers/media/video/uvc/uvc_video.c
+++ b/linux/drivers/media/video/uvc/uvc_video.c
@@ -703,27 +703,47 @@ static void uvc_free_urb_buffers(struct uvc_video_device *video)
* already allocated when resuming from suspend, in which case it will
* return without touching the buffers.
*
- * Return 0 on success or -ENOMEM when out of memory.
+ * Limit the buffer size to UVC_MAX_PACKETS bulk/isochronous packets. If the
+ * system is too low on memory try successively smaller numbers of packets
+ * until allocation succeeds.
+ *
+ * Return the number of allocated packets on success or 0 when out of memory.
*/
static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
- unsigned int size)
+ unsigned int size, unsigned int psize, gfp_t gfp_flags)
{
+ unsigned int npackets;
unsigned int i;
/* Buffers are already allocated, bail out. */
if (video->urb_size)
return 0;
- for (i = 0; i < UVC_URBS; ++i) {
- video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
- size, GFP_KERNEL, &video->urb_dma[i]);
- if (video->urb_buffer[i] == NULL) {
- uvc_free_urb_buffers(video);
- return -ENOMEM;
+ /* Compute the number of packets. Bulk endpoints might transfer UVC
+ * payloads accross multiple URBs.
+ */
+ npackets = DIV_ROUND_UP(size, psize);
+ if (npackets > UVC_MAX_PACKETS)
+ npackets = UVC_MAX_PACKETS;
+
+ /* Retry allocations until one succeed. */
+ for (; npackets > 1; npackets /= 2) {
+ for (i = 0; i < UVC_URBS; ++i) {
+ video->urb_buffer[i] = usb_buffer_alloc(
+ video->dev->udev, psize * npackets,
+ gfp_flags | __GFP_NOWARN, &video->urb_dma[i]);
+ if (!video->urb_buffer[i]) {
+ uvc_free_urb_buffers(video);
+ break;
+ }
+ }
+
+ if (i == UVC_URBS) {
+ video->urb_size = psize * npackets;
+ return npackets;
}
}
- video->urb_size = size;
return 0;
}
@@ -757,29 +777,19 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
{
struct urb *urb;
unsigned int npackets, i, j;
- __u16 psize;
- __u32 size;
+ u16 psize;
+ u32 size;
- /* Compute the number of isochronous packets to allocate by dividing
- * the maximum video frame size by the packet size. Limit the result
- * to UVC_MAX_ISO_PACKETS.
- */
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
-
size = video->streaming->ctrl.dwMaxVideoFrameSize;
- if (size > UVC_MAX_FRAME_SIZE)
- return -EINVAL;
- npackets = DIV_ROUND_UP(size, psize);
- if (npackets > UVC_MAX_ISO_PACKETS)
- npackets = UVC_MAX_ISO_PACKETS;
+ npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+ if (npackets == 0)
+ return -ENOMEM;
size = npackets * psize;
- if (uvc_alloc_urb_buffers(video, size) < 0)
- return -ENOMEM;
-
for (i = 0; i < UVC_URBS; ++i) {
urb = usb_alloc_urb(npackets, gfp_flags);
if (urb == NULL) {
@@ -818,25 +828,20 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
struct usb_host_endpoint *ep, gfp_t gfp_flags)
{
struct urb *urb;
- unsigned int pipe, i;
- __u16 psize;
- __u32 size;
-
- /* Compute the bulk URB size. Some devices set the maximum payload
- * size to a value too high for memory-constrained devices. We must
- * then transfer the payload accross multiple URBs. To be consistant
- * with isochronous mode, allocate maximum UVC_MAX_ISO_PACKETS per bulk
- * URB.
- */
+ unsigned int npackets, pipe, i;
+ u16 psize;
+ u32 size;
+
psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
size = video->streaming->ctrl.dwMaxPayloadTransferSize;
video->bulk.max_payload_size = size;
- if (size > psize * UVC_MAX_ISO_PACKETS)
- size = psize * UVC_MAX_ISO_PACKETS;
- if (uvc_alloc_urb_buffers(video, size) < 0)
+ npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+ if (npackets == 0)
return -ENOMEM;
+ size = npackets * psize;
+
if (usb_endpoint_dir_in(&ep->desc))
pipe = usb_rcvbulkpipe(video->dev->udev,
ep->desc.bEndpointAddress);
diff --git a/linux/drivers/media/video/uvc/uvcvideo.h b/linux/drivers/media/video/uvc/uvcvideo.h
index c9f4973ea..408b8b846 100644
--- a/linux/drivers/media/video/uvc/uvcvideo.h
+++ b/linux/drivers/media/video/uvc/uvcvideo.h
@@ -297,10 +297,8 @@ struct uvc_xu_control {
/* Number of isochronous URBs. */
#define UVC_URBS 5
-/* Maximum number of packets per isochronous URB. */
-#define UVC_MAX_ISO_PACKETS 40
-/* Maximum frame size in bytes, for sanity checking. */
-#define UVC_MAX_FRAME_SIZE (16*1024*1024)
+/* Maximum number of packets per URB. */
+#define UVC_MAX_PACKETS 32
/* Maximum number of video buffers. */
#define UVC_MAX_VIDEO_BUFFERS 32
/* Maximum status buffer size in bytes of interrupt URB. */
@@ -650,6 +648,7 @@ struct uvc_device {
struct urb *int_urb;
__u8 *status;
struct input_dev *input;
+ char input_phys[64];
/* Video Streaming interfaces */
struct list_head streaming;
diff --git a/linux/drivers/media/video/videobuf-dma-contig.c b/linux/drivers/media/video/videobuf-dma-contig.c
index a3bf4c151..6db1398fd 100644
--- a/linux/drivers/media/video/videobuf-dma-contig.c
+++ b/linux/drivers/media/video/videobuf-dma-contig.c
@@ -401,7 +401,7 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
So, it should free memory only if the memory were allocated for
read() operation.
*/
- if ((buf->memory != V4L2_MEMORY_USERPTR) || !buf->baddr)
+ if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
return;
if (!mem)
diff --git a/linux/drivers/media/video/videobuf-vmalloc.c b/linux/drivers/media/video/videobuf-vmalloc.c
index e9cf83572..d863723e8 100644
--- a/linux/drivers/media/video/videobuf-vmalloc.c
+++ b/linux/drivers/media/video/videobuf-vmalloc.c
@@ -426,7 +426,7 @@ void videobuf_vmalloc_free (struct videobuf_buffer *buf)
So, it should free memory only if the memory were allocated for
read() operation.
*/
- if ((buf->memory != V4L2_MEMORY_USERPTR) || (buf->baddr == 0))
+ if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
return;
if (!mem)