summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-09-29 12:34:29 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-09-29 12:34:29 -0300
commit1de263ac921ae95a5ef9594515cace643d30535f (patch)
treef6e7110966fe08f61626326d6ede39d6fd4b0568 /linux/drivers/media/video
parented09f5a6d29bd6e33fb9cfc374afe3d605e9f180 (diff)
parentbfbd3992d437c1f8f45dffa075261dd0fe93e983 (diff)
downloadmediapointer-dvb-s2-1de263ac921ae95a5ef9594515cace643d30535f.tar.gz
mediapointer-dvb-s2-1de263ac921ae95a5ef9594515cace643d30535f.tar.bz2
merge: http://linuxtv.org/hg/~mkrufky/cx88
From: Mauro Carvalho Chehab <mchehab@infradead.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video')
-rw-r--r--linux/drivers/media/video/cx88/cx88-blackbird.c166
-rw-r--r--linux/drivers/media/video/cx88/cx88-cards.c2
-rw-r--r--linux/drivers/media/video/cx88/cx88-dvb.c180
-rw-r--r--linux/drivers/media/video/cx88/cx88-i2c.c2
-rw-r--r--linux/drivers/media/video/cx88/cx88-mpeg.c351
-rw-r--r--linux/drivers/media/video/cx88/cx88.h40
-rw-r--r--linux/drivers/media/video/ir-kbd-i2c.c19
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c9
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c4
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-cards.c36
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-dvb.c1
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-input.c1
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h1
14 files changed, 648 insertions, 166 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c
index 02160c90c..dc27d74eb 100644
--- a/linux/drivers/media/video/cx88/cx88-blackbird.c
+++ b/linux/drivers/media/video/cx88/cx88-blackbird.c
@@ -53,7 +53,6 @@ MODULE_PARM_DESC(debug,"enable debug messages [blackbird]");
#define dprintk(level,fmt, arg...) if (debug >= level) \
printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg)
-static LIST_HEAD(cx8802_devlist);
/* ------------------------------------------------------------------ */
@@ -929,7 +928,7 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
snprintf(name, sizeof(name), "%s/2", core->name);
printk("%s/2: ============ START LOG STATUS ============\n",
core->name);
- cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, 0);
+ cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, NULL);
cx2341x_log_status(&dev->params, name);
printk("%s/2: ============= END LOG STATUS =============\n",
core->name);
@@ -971,26 +970,41 @@ static int mpeg_ioctl(struct inode *inode, struct file *file,
static int mpeg_open(struct inode *inode, struct file *file)
{
int minor = iminor(inode);
- struct cx8802_dev *h,*dev = NULL;
+ struct cx8802_dev *dev = NULL;
struct cx8802_fh *fh;
- struct list_head *list;
+ struct cx8802_driver *drv = NULL;
+ int err;
- list_for_each(list,&cx8802_devlist) {
- h = list_entry(list, struct cx8802_dev, devlist);
- if (h->mpeg_dev->minor == minor)
- dev = h;
- }
- if (NULL == dev)
+ dprintk( 1, "%s\n", __FUNCTION__);
+
+ dev = cx8802_get_device(inode);
+ if (dev == NULL)
return -ENODEV;
- if (blackbird_initialize_codec(dev) < 0)
+ /* Make sure we can acquire the hardware */
+ drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
+ if (drv) {
+ err = drv->request_acquire(drv);
+ if(err != 0) {
+ dprintk(1,"%s: Unable to acquire hardware, %d\n", __FUNCTION__, err);
+ return err;
+ }
+ }
+
+ if (blackbird_initialize_codec(dev) < 0) {
+ if (drv)
+ drv->request_release(drv);
return -EINVAL;
+ }
dprintk(1,"open minor=%d\n",minor);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh),GFP_KERNEL);
- if (NULL == fh)
+ if (NULL == fh) {
+ if (drv)
+ drv->request_release(drv);
return -ENOMEM;
+ }
file->private_data = fh;
fh->dev = dev;
@@ -1011,6 +1025,8 @@ static int mpeg_open(struct inode *inode, struct file *file)
static int mpeg_release(struct inode *inode, struct file *file)
{
struct cx8802_fh *fh = file->private_data;
+ struct cx8802_dev *dev = NULL;
+ struct cx8802_driver *drv = NULL;
/* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */
blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
@@ -1029,6 +1045,16 @@ static int mpeg_release(struct inode *inode, struct file *file)
videobuf_mmap_free(&fh->mpegq);
file->private_data = NULL;
kfree(fh);
+
+ /* Make sure we release the hardware */
+ dev = cx8802_get_device(inode);
+ if (dev == NULL)
+ return -ENODEV;
+
+ drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
+ if (drv)
+ drv->request_release(drv);
+
return 0;
}
@@ -1080,6 +1106,47 @@ static struct video_device cx8802_mpeg_template =
/* ------------------------------------------------------------------ */
+/* The CX8802 MPEG API will call this when we can use the hardware */
+static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv)
+{
+ struct cx88_core *core = drv->core;
+ int err = 0;
+
+ switch (core->board) {
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ /* By default, core setup will leave the cx22702 out of reset, on the bus.
+ * We left the hardware on power up with the cx22702 active.
+ * We're being given access to re-arrange the GPIOs.
+ * Take the bus off the cx22702 and put the cx23416 on it.
+ */
+ cx_clear(MO_GP0_IO, 0x00000080); /* cx22702 in reset */
+ cx_set(MO_GP0_IO, 0x00000004); /* Disable the cx22702 */
+ break;
+ default:
+ err = -ENODEV;
+ }
+ return err;
+}
+
+/* The CX8802 MPEG API will call this when we need to release the hardware */
+static int cx8802_blackbird_advise_release(struct cx8802_driver *drv)
+{
+ struct cx88_core *core = drv->core;
+ int err = 0;
+
+ switch (core->board) {
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ /* Exit leaving the cx23416 on the bus */
+#if 0
+ cx_clear(MO_GP0_IO, 0x00000020); /* Take down I2S */
+#endif
+ break;
+ default:
+ err = -ENODEV;
+ }
+ return err;
+}
+
static void blackbird_unregister_video(struct cx8802_dev *dev)
{
if (dev->mpeg_dev) {
@@ -1110,28 +1177,23 @@ static int blackbird_register_video(struct cx8802_dev *dev)
/* ----------------------------------------------------------- */
-static int __devinit blackbird_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
+static int cx8802_blackbird_probe(struct cx8802_driver *drv)
{
- struct cx8802_dev *dev;
- struct cx88_core *core;
+ struct cx88_core *core = drv->core;
+ struct cx8802_dev *dev = core->dvbdev;
int err;
- /* general setup */
- core = cx88_core_get(pci_dev);
- if (NULL == core)
- return -EINVAL;
+ dprintk( 1, "%s\n", __FUNCTION__);
+ dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
+ core->board,
+ core->name,
+ core->pci_bus,
+ core->pci_slot);
err = -ENODEV;
if (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD))
goto fail_core;
- err = -ENOMEM;
- dev = kzalloc(sizeof(*dev),GFP_KERNEL);
- if (NULL == dev)
- goto fail_core;
- dev->pci = pci_dev;
- dev->core = core;
dev->width = 720;
dev->height = 576;
cx2341x_fill_defaults(&dev->params);
@@ -1143,16 +1205,11 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
dev->height = 576;
}
- err = cx8802_init_common(dev);
- if (0 != err)
- goto fail_free;
-
/* blackbird stuff */
printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
core->name);
host_setup(dev->core);
- list_add_tail(&dev->devlist,&cx8802_devlist);
blackbird_register_video(dev);
/* initial device configuration: needed ? */
@@ -1179,48 +1236,25 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
return 0;
- fail_free:
- kfree(dev);
fail_core:
- cx88_core_put(core,pci_dev);
return err;
}
-static void __devexit blackbird_remove(struct pci_dev *pci_dev)
+static int cx8802_blackbird_remove(struct cx8802_driver *drv)
{
- struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
-
/* blackbird */
- blackbird_unregister_video(dev);
- list_del(&dev->devlist);
+ blackbird_unregister_video(drv->core->dvbdev);
- /* common */
- cx8802_fini_common(dev);
- cx88_core_put(dev->core,dev->pci);
- kfree(dev);
+ return 0;
}
-static struct pci_device_id cx8802_pci_tbl[] = {
- {
- .vendor = 0x14f1,
- .device = 0x8802,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },{
- /* --- end of list --- */
- }
-};
-MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
-
-static struct pci_driver blackbird_pci_driver = {
- .name = "cx88-blackbird",
- .id_table = cx8802_pci_tbl,
- .probe = blackbird_probe,
- .remove = __devexit_p(blackbird_remove),
-#ifdef CONFIG_PM
- .suspend = cx8802_suspend_common,
- .resume = cx8802_resume_common,
-#endif
+static struct cx8802_driver cx8802_blackbird_driver = {
+ .type_id = CX88_MPEG_BLACKBIRD,
+ .hw_access = CX8802_DRVCTL_SHARED,
+ .probe = cx8802_blackbird_probe,
+ .remove = cx8802_blackbird_remove,
+ .advise_acquire = cx8802_blackbird_advise_acquire,
+ .advise_release = cx8802_blackbird_advise_release,
};
static int blackbird_init(void)
@@ -1235,12 +1269,12 @@ static int blackbird_init(void)
#endif
cx88_ioctl_hook = mpeg_do_ioctl;
cx88_ioctl_translator = mpeg_translate_ioctl;
- return pci_register_driver(&blackbird_pci_driver);
+ return cx8802_register_driver(&cx8802_blackbird_driver);
}
static void blackbird_fini(void)
{
- pci_unregister_driver(&blackbird_pci_driver);
+ cx8802_unregister_driver(&cx8802_blackbird_driver);
}
module_init(blackbird_init);
diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c
index 9ac3f40e2..e89cb8450 100644
--- a/linux/drivers/media/video/cx88/cx88-cards.c
+++ b/linux/drivers/media/video/cx88/cx88-cards.c
@@ -1335,7 +1335,7 @@ struct cx88_board cx88_boards[] = {
.gpio0 = 0xe780,
}},
/* fixme: Add radio support */
- .mpeg = CX88_MPEG_DVB,
+ .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD,
},
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c
index 3e964258d..2fd4c99c4 100644
--- a/linux/drivers/media/video/cx88/cx88-dvb.c
+++ b/linux/drivers/media/video/cx88/cx88-dvb.c
@@ -58,7 +58,7 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
#define dprintk(level,fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->core->name , ## arg)
+ printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
/* ------------------------------------------------------------------ */
@@ -320,6 +320,33 @@ static struct cx22702_config hauppauge_hvr1100_config = {
.demod_address = 0x63,
.output_mode = CX22702_SERIAL_OUTPUT,
};
+
+static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe,
+ int acquire)
+{
+ struct cx8802_dev *dev= fe->dvb->priv;
+ struct cx8802_driver *drv = NULL;
+ struct cx88_core *core = dev->core;
+ int ret = 0;
+
+ dprintk(1, "%s(acquire=%d)\n", __FUNCTION__, acquire);
+
+ switch (dev->core->board) {
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
+ if (drv) {
+ if(acquire)
+ ret = drv->request_acquire(drv);
+ else
+ ret = drv->request_release(drv);
+ }
+ break;
+ }
+
+ dprintk(1, "%s(acquire=%d) returns %d\n", __FUNCTION__, acquire, ret);
+ return ret;
+}
+
static struct cx22702_config hauppauge_hvr1300_config = {
.demod_address = 0x63,
.output_mode = CX22702_SERIAL_OUTPUT,
@@ -549,16 +576,6 @@ static int dvb_register(struct cx8802_dev *dev)
&dvb_pll_fmd1216me);
}
break;
- case CX88_BOARD_HAUPPAUGE_HVR1300:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
- &hauppauge_hvr1300_config,
- &dev->core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- &dvb_pll_fmd1216me);
- }
- break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
dev->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv,
@@ -766,6 +783,17 @@ static int dvb_register(struct cx8802_dev *dev)
dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
}
break;
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ dev->dvb.frontend = dvb_attach(cx22702_attach,
+ &hauppauge_hvr1300_config,
+ &dev->core->i2c_adap);
+ if (dev->dvb.frontend != NULL) {
+ dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ &dev->core->i2c_adap,
+ &dvb_pll_fmd1216me);
+ dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
+ }
+ break;
default:
printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
dev->core->name);
@@ -790,37 +818,70 @@ static int dvb_register(struct cx8802_dev *dev)
/* ----------------------------------------------------------- */
-static int __devinit dvb_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_id)
+/* CX8802 MPEG -> mini driver - We have been given the hardware */
+static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
{
- struct cx8802_dev *dev;
- struct cx88_core *core;
+ struct cx88_core *core = drv->core;
+ int err = 0;
+ dprintk( 1, "%s\n", __FUNCTION__);
+
+ switch (core->board) {
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ /* We arrive here with either the cx23416 or the cx22702
+ * on the bus. Take the bus from the cx23416 and enable the
+ * cx22702 demod
+ */
+ cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */
+ cx_clear(MO_GP0_IO, 0x00000004);
+ udelay(1000);
+ break;
+ default:
+ err = -ENODEV;
+ }
+ return err;
+}
+
+/* CX8802 MPEG -> mini driver - We no longer have the hardware */
+static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
+{
+ struct cx88_core *core = drv->core;
+ int err = 0;
+ dprintk( 1, "%s\n", __FUNCTION__);
+
+ switch (core->board) {
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ /* Do Nothing, leave the cx22702 on the bus. */
+#if 0
+ cx_set(MO_GP0_IO, 0x00000004);
+#endif
+ break;
+ default:
+ err = -ENODEV;
+ }
+ return err;
+}
+
+static int cx8802_dvb_probe(struct cx8802_driver *drv)
+{
+ struct cx88_core *core = drv->core;
+ struct cx8802_dev *dev = drv->core->dvbdev;
int err;
- /* general setup */
- core = cx88_core_get(pci_dev);
- if (NULL == core)
- return -EINVAL;
+ dprintk( 1, "%s\n", __FUNCTION__);
+ dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
+ core->board,
+ core->name,
+ core->pci_bus,
+ core->pci_slot);
err = -ENODEV;
if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB))
goto fail_core;
- err = -ENOMEM;
- dev = kzalloc(sizeof(*dev),GFP_KERNEL);
- if (NULL == dev)
- goto fail_core;
- dev->pci = pci_dev;
- dev->core = core;
-
- err = cx8802_init_common(dev);
- if (0 != err)
- goto fail_free;
-
#ifdef HAVE_VP3054_I2C
err = vp3054_i2c_probe(dev);
if (0 != err)
- goto fail_free;
+ goto fail_core;
#endif
/* dvb stuff */
@@ -832,28 +893,16 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
sizeof(struct cx88_buffer),
dev);
err = dvb_register(dev);
- if (0 != err)
- goto fail_fini;
-
- /* Maintain a reference to cx88-video can query the 8802 device. */
- core->dvbdev = dev;
- return 0;
+ if (err != 0)
+ printk("%s dvb_register failed err = %d\n", __FUNCTION__, err);
- fail_fini:
- cx8802_fini_common(dev);
- fail_free:
- kfree(dev);
fail_core:
- cx88_core_put(core,pci_dev);
return err;
}
-static void __devexit dvb_remove(struct pci_dev *pci_dev)
+static int cx8802_dvb_remove(struct cx8802_driver *drv)
{
- struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
-
- /* Destroy any 8802 reference. */
- dev->core->dvbdev = NULL;
+ struct cx8802_dev *dev = drv->core->dvbdev;
/* dvb */
videobuf_dvb_unregister(&dev->dvb);
@@ -862,33 +911,16 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev)
vp3054_i2c_remove(dev);
#endif
- /* common */
- cx8802_fini_common(dev);
- cx88_core_put(dev->core,dev->pci);
- kfree(dev);
+ return 0;
}
-static struct pci_device_id cx8802_pci_tbl[] = {
- {
- .vendor = 0x14f1,
- .device = 0x8802,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },{
- /* --- end of list --- */
- }
-};
-MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
-
-static struct pci_driver dvb_pci_driver = {
- .name = "cx88-dvb",
- .id_table = cx8802_pci_tbl,
- .probe = dvb_probe,
- .remove = __devexit_p(dvb_remove),
-#ifdef CONFIG_PM
- .suspend = cx8802_suspend_common,
- .resume = cx8802_resume_common,
-#endif
+static struct cx8802_driver cx8802_dvb_driver = {
+ .type_id = CX88_MPEG_DVB,
+ .hw_access = CX8802_DRVCTL_SHARED,
+ .probe = cx8802_dvb_probe,
+ .remove = cx8802_dvb_remove,
+ .advise_acquire = cx8802_dvb_advise_acquire,
+ .advise_release = cx8802_dvb_advise_release,
};
static int dvb_init(void)
@@ -901,12 +933,12 @@ static int dvb_init(void)
printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
#endif
- return pci_register_driver(&dvb_pci_driver);
+ return cx8802_register_driver(&cx8802_dvb_driver);
}
static void dvb_fini(void)
{
- pci_unregister_driver(&dvb_pci_driver);
+ cx8802_unregister_driver(&cx8802_dvb_driver);
}
module_init(dvb_init);
diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c
index 8a64f795a..672747a5f 100644
--- a/linux/drivers/media/video/cx88/cx88-i2c.c
+++ b/linux/drivers/media/video/cx88/cx88-i2c.c
@@ -155,7 +155,7 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
return;
#ifdef HAVE_VIDEO_BUF_DVB
- if (core->dvbdev) {
+ if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) {
if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c
index 865cb6d25..b5ef885ac 100644
--- a/linux/drivers/media/video/cx88/cx88-mpeg.c
+++ b/linux/drivers/media/video/cx88/cx88-mpeg.c
@@ -51,8 +51,12 @@ module_param(debug,int,0644);
MODULE_PARM_DESC(debug,"enable debug messages [mpeg]");
#define dprintk(level,fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG "%s/2: " fmt, dev->core->name , ## arg)
+ printk(KERN_DEBUG "%s/2-mpeg: " fmt, dev->core->name, ## arg)
+#define mpeg_dbg(level,fmt, arg...) if (debug >= level) \
+ printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg)
+
+static LIST_HEAD(cx8802_devlist);
/* ------------------------------------------------------------------ */
static int cx8802_start_dma(struct cx8802_dev *dev,
@@ -75,17 +79,13 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
/* FIXME: this needs a review.
* also: move to cx88-blackbird + cx88-dvb source files? */
- if (cx88_boards[core->board].mpeg == (CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD) ) {
- /* Report a warning until the mini driver patch is applied,
- * else the following conditions will set the dma registers incorrectly.
- * This will be removed in the next major patch and changes to the conditions
- * will be made.
- */
- printk(KERN_INFO "%s() board->(CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD) is invalid\n", __FUNCTION__);
- return -EINVAL;
- }
- if (cx88_boards[core->board].mpeg & CX88_MPEG_DVB) {
+ dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id);
+
+ if ( (core->active_type_id == CX88_MPEG_DVB) &&
+ (cx88_boards[core->board].mpeg & CX88_MPEG_DVB) ) {
+
+ dprintk( 1, "cx8802_start_dma doing .dvb\n");
/* negedge driven & software reset */
cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl);
udelay(100);
@@ -103,15 +103,17 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
udelay(100);
break;
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ break;
default:
cx_write(TS_SOP_STAT, 0x00);
break;
}
cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
udelay(100);
- }
-
- if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) {
+ } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) &&
+ (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) ) {
+ dprintk( 1, "cx8802_start_dma doing .blackbird\n");
cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
#if 0
@@ -128,6 +130,10 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
udelay(100);
+ } else {
+ printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __FUNCTION__,
+ cx88_boards[core->board].mpeg );
+ return -EINVAL;
}
/* reset counter */
@@ -465,6 +471,8 @@ int cx8802_init_common(struct cx8802_dev *dev)
#endif
spin_lock_init(&dev->slock);
+ init_MUTEX(&dev->drvlist_lock);
+
/* init dma queue */
INIT_LIST_HEAD(&dev->mpegq.active);
INIT_LIST_HEAD(&dev->mpegq.queued);
@@ -583,8 +591,316 @@ int cx8802_resume_common(struct pci_dev *pci_dev)
return 0;
}
+struct cx8802_dev * cx8802_get_device(struct inode *inode)
+{
+ int minor = iminor(inode);
+ struct cx8802_dev *h = NULL;
+ struct list_head *list;
+
+ list_for_each(list,&cx8802_devlist) {
+ h = list_entry(list, struct cx8802_dev, devlist);
+ if (h->mpeg_dev->minor == minor)
+ return h;
+ }
+
+ return NULL;
+}
+
+struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
+{
+ struct cx8802_dev *h = NULL;
+ struct cx8802_driver *d = NULL;
+ struct list_head *list;
+ struct list_head *list2;
+
+ list_for_each(list,&cx8802_devlist) {
+ h = list_entry(list, struct cx8802_dev, devlist);
+
+ list_for_each(list2, &h->drvlist.devlist) {
+ d = list_entry(list2, struct cx8802_driver, devlist);
+
+ /* only unregister the correct driver type */
+ if (d->type_id == btype) {
+ return d;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/* Driver asked for hardware access. */
+int cx8802_request_acquire(struct cx8802_driver *drv)
+{
+ struct cx88_core *core = drv->core;
+
+ /* Fail a request for hardware if the device is busy. */
+ if (core->active_type_id != CX88_BOARD_NONE)
+ return -EBUSY;
+
+ if (drv->advise_acquire)
+ {
+ core->active_type_id = drv->type_id;
+ drv->advise_acquire(drv);
+
+ mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
+ }
+
+ return 0;
+}
+
+/* Driver asked to release hardware. */
+int cx8802_request_release(struct cx8802_driver *drv)
+{
+ struct cx88_core *core = drv->core;
+
+ if (drv->advise_release)
+ {
+ drv->advise_release(drv);
+ core->active_type_id = CX88_BOARD_NONE;
+ mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
+ }
+
+ return 0;
+}
+
+static int cx8802_check_driver(struct cx8802_driver *drv)
+{
+ if (drv == NULL)
+ return -ENODEV;
+
+ if ((drv->type_id != CX88_MPEG_DVB) &&
+ (drv->type_id != CX88_MPEG_BLACKBIRD))
+ return -EINVAL;
+
+ if ((drv->hw_access != CX8802_DRVCTL_SHARED) &&
+ (drv->hw_access != CX8802_DRVCTL_EXCLUSIVE))
+ return -EINVAL;
+
+ if ((drv->probe == NULL) ||
+ (drv->remove == NULL) ||
+ (drv->advise_acquire == NULL) ||
+ (drv->advise_release == NULL))
+ return -EINVAL;
+
+ return 0;
+}
+
+int cx8802_register_driver(struct cx8802_driver *drv)
+{
+ struct cx8802_dev *h;
+ struct cx8802_driver *driver;
+ struct list_head *list;
+ int err = 0, i = 0;
+
+ printk(KERN_INFO "%s() ->registering driver type=%s access=%s\n", __FUNCTION__ ,
+ drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
+ drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
+
+ if ((err = cx8802_check_driver(drv)) != 0) {
+ printk(KERN_INFO "%s() cx8802_driver is invalid\n", __FUNCTION__ );
+ return err;
+ }
+
+ list_for_each(list,&cx8802_devlist) {
+ i++;
+ h = list_entry(list, struct cx8802_dev, devlist);
+
+ printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n",
+ h->core->name,h->pci->subsystem_vendor,
+ h->pci->subsystem_device,cx88_boards[h->core->board].name,
+ h->core->board);
+
+ /* Bring up a new struct for each driver instance */
+ driver = kzalloc(sizeof(*drv),GFP_KERNEL);
+ if (driver == NULL)
+ return -ENOMEM;
+
+ /* Snapshot of the driver registration data */
+ drv->core = h->core;
+ drv->suspend = cx8802_suspend_common;
+ drv->resume = cx8802_resume_common;
+ drv->request_acquire = cx8802_request_acquire;
+ drv->request_release = cx8802_request_release;
+ memcpy(driver, drv, sizeof(*driver));
+
+ err = drv->probe(driver);
+ if (err == 0) {
+ down(&h->drvlist_lock);
+ list_add_tail(&driver->devlist,&h->drvlist.devlist);
+ up(&h->drvlist_lock);
+ } else {
+ printk(KERN_ERR "%s() ->probe failed err = %d\n", __FUNCTION__, err);
+ }
+
+ }
+ if (i == 0)
+ err = -ENODEV;
+
+ return err;
+}
+
+int cx8802_unregister_driver(struct cx8802_driver *drv)
+{
+ struct cx8802_dev *h;
+ struct cx8802_driver *d;
+ struct list_head *list;
+ struct list_head *list2, *q;
+ int err = 0, i = 0;
+
+ printk(KERN_INFO "%s() ->unregistering driver type=%s\n", __FUNCTION__ ,
+ drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird");
+
+ list_for_each(list,&cx8802_devlist) {
+ i++;
+ h = list_entry(list, struct cx8802_dev, devlist);
+
+ printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n",
+ h->core->name,h->pci->subsystem_vendor,
+ h->pci->subsystem_device,cx88_boards[h->core->board].name,
+ h->core->board);
+
+ list_for_each_safe(list2, q, &h->drvlist.devlist) {
+ d = list_entry(list2, struct cx8802_driver, devlist);
+
+ /* only unregister the correct driver type */
+ if (d->type_id != drv->type_id)
+ continue;
+
+ err = d->remove(d);
+ if (err == 0) {
+ down(&h->drvlist_lock);
+ list_del(list2);
+ up(&h->drvlist_lock);
+ } else
+ printk(KERN_ERR "%s() ->remove failed err = %d\n", __FUNCTION__, err);
+
+ }
+
+ }
+
+ return err;
+}
+
/* ----------------------------------------------------------- */
+static int __devinit cx8802_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *pci_id)
+{
+ struct cx8802_dev *dev;
+ struct cx88_core *core;
+ int err;
+
+ /* general setup */
+ core = cx88_core_get(pci_dev);
+ if (NULL == core)
+ return -EINVAL;
+
+ printk("%s/2: cx2388x 8802 Driver Manager\n", core->name);
+
+ err = -ENODEV;
+ if (!cx88_boards[core->board].mpeg)
+ goto fail_core;
+
+ err = -ENOMEM;
+ dev = kzalloc(sizeof(*dev),GFP_KERNEL);
+ if (NULL == dev)
+ goto fail_core;
+ dev->pci = pci_dev;
+ dev->core = core;
+
+ err = cx8802_init_common(dev);
+ if (err != 0)
+ goto fail_free;
+
+ INIT_LIST_HEAD(&dev->drvlist.devlist);
+ list_add_tail(&dev->devlist,&cx8802_devlist);
+
+ /* Maintain a reference so cx88-video can query the 8802 device. */
+ core->dvbdev = dev;
+ return 0;
+
+ fail_free:
+ kfree(dev);
+ fail_core:
+ cx88_core_put(core,pci_dev);
+ return err;
+}
+static void __devexit cx8802_remove(struct pci_dev *pci_dev)
+{
+ struct cx8802_dev *dev;
+ struct cx8802_driver *h;
+ struct list_head *list;
+
+ dev = pci_get_drvdata(pci_dev);
+
+ dprintk( 1, "%s\n", __FUNCTION__);
+
+ list_for_each(list,&dev->drvlist.devlist) {
+ h = list_entry(list, struct cx8802_driver, devlist);
+ dprintk( 1, " ->driver\n");
+ if (h->remove == NULL) {
+ printk(KERN_ERR "%s .. skipping driver, no probe function\n", __FUNCTION__);
+ continue;
+ }
+ printk(KERN_INFO "%s .. Removing driver type %d\n", __FUNCTION__, h->type_id);
+ cx8802_unregister_driver(h);
+ list_del(&dev->drvlist.devlist);
+ }
+
+ /* Destroy any 8802 reference. */
+ dev->core->dvbdev = NULL;
+
+ /* common */
+ cx8802_fini_common(dev);
+ cx88_core_put(dev->core,dev->pci);
+ kfree(dev);
+}
+
+static struct pci_device_id cx8802_pci_tbl[] = {
+ {
+ .vendor = 0x14f1,
+ .device = 0x8802,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },{
+ /* --- end of list --- */
+ }
+};
+MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
+
+static struct pci_driver cx8802_pci_driver = {
+ .name = "cx88-mpeg driver manager",
+ .id_table = cx8802_pci_tbl,
+ .probe = cx8802_probe,
+ .remove = __devexit_p(cx8802_remove),
+#if 0
+ /* TODO: Implement this */
+ .suspend = cx8802_suspend_common,
+ .resume = cx8802_resume_common,
+#endif
+};
+
+static int cx8802_init(void)
+{
+ printk(KERN_INFO "cx2388x cx88-mpeg Driver Manager version %d.%d.%d loaded\n",
+ (CX88_VERSION_CODE >> 16) & 0xff,
+ (CX88_VERSION_CODE >> 8) & 0xff,
+ CX88_VERSION_CODE & 0xff);
+#ifdef SNAPSHOT
+ printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
+ SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
+#endif
+ return pci_register_driver(&cx8802_pci_driver);
+}
+
+static void cx8802_fini(void)
+{
+ pci_unregister_driver(&cx8802_pci_driver);
+}
+
+module_init(cx8802_init);
+module_exit(cx8802_fini);
EXPORT_SYMBOL(cx8802_buf_prepare);
EXPORT_SYMBOL(cx8802_buf_queue);
EXPORT_SYMBOL(cx8802_cancel_buffers);
@@ -592,9 +908,14 @@ EXPORT_SYMBOL(cx8802_cancel_buffers);
EXPORT_SYMBOL(cx8802_init_common);
EXPORT_SYMBOL(cx8802_fini_common);
+EXPORT_SYMBOL(cx8802_register_driver);
+EXPORT_SYMBOL(cx8802_unregister_driver);
+EXPORT_SYMBOL(cx8802_get_device);
+EXPORT_SYMBOL(cx8802_get_driver);
+#if 0
EXPORT_SYMBOL(cx8802_suspend_common);
EXPORT_SYMBOL(cx8802_resume_common);
-
+#endif
/* ----------------------------------------------------------- */
/*
* Local variables:
diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h
index 4b7c3cf25..5f84e3af5 100644
--- a/linux/drivers/media/video/cx88/cx88.h
+++ b/linux/drivers/media/video/cx88/cx88.h
@@ -85,6 +85,11 @@ enum cx88_board_type {
CX88_MPEG_BLACKBIRD
};
+enum cx8802_board_access {
+ CX8802_DRVCTL_SHARED = 1,
+ CX8802_DRVCTL_EXCLUSIVE = 2,
+};
+
/* ----------------------------------------------------------- */
/* tv norms */
@@ -353,6 +358,7 @@ struct cx88_core {
/* cx88-video needs to access cx8802 for hybrid tuner pll access. */
struct cx8802_dev *dvbdev;
+ enum cx88_board_type active_type_id;
};
struct cx8800_dev;
@@ -447,6 +453,31 @@ struct cx8802_suspend_state {
int disabled;
};
+struct cx8802_driver {
+ struct cx88_core *core;
+ struct list_head devlist;
+
+ /* Type of driver and access required */
+ enum cx88_board_type type_id;
+ enum cx8802_board_access hw_access;
+
+ /* MPEG 8802 internal only */
+ int (*suspend)(struct pci_dev *pci_dev, pm_message_t state);
+ int (*resume)(struct pci_dev *pci_dev);
+
+ /* MPEG 8802 -> mini driver - Driver probe and configuration */
+ int (*probe)(struct cx8802_driver *drv);
+ int (*remove)(struct cx8802_driver *drv);
+
+ /* MPEG 8802 -> mini driver - Access for hardware control */
+ int (*advise_acquire)(struct cx8802_driver *drv);
+ int (*advise_release)(struct cx8802_driver *drv);
+
+ /* MPEG 8802 <- mini driver - Access for hardware control */
+ int (*request_acquire)(struct cx8802_driver *drv);
+ int (*request_release)(struct cx8802_driver *drv);
+};
+
struct cx8802_dev {
struct cx88_core *core;
#if 0
@@ -487,6 +518,10 @@ struct cx8802_dev {
/* mpeg params */
struct cx2341x_mpeg_params params;
+
+ /* List of attached drivers */
+ struct semaphore drvlist_lock;
+ struct cx8802_driver drvlist;
};
/* ----------------------------------------------------------- */
@@ -619,6 +654,11 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
int cx88_audio_thread(void *data);
+int cx8802_register_driver(struct cx8802_driver *drv);
+int cx8802_unregister_driver(struct cx8802_driver *drv);
+struct cx8802_dev * cx8802_get_device(struct inode *inode);
+struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
+
/* ----------------------------------------------------------- */
/* cx88-input.c */
diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c
index 91ff43d93..b826dcca2 100644
--- a/linux/drivers/media/video/ir-kbd-i2c.c
+++ b/linux/drivers/media/video/ir-kbd-i2c.c
@@ -65,23 +65,32 @@ MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults
static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
{
unsigned char buf[3];
- int start, toggle, dev, code;
+ int start, range, toggle, dev, code;
/* poll IR chip */
if (3 != i2c_master_recv(&ir->c,buf,3))
return -EIO;
/* split rc5 data block ... */
- start = (buf[0] >> 6) & 3;
+ start = (buf[0] >> 7) & 1;
+ range = (buf[0] >> 6) & 1;
toggle = (buf[0] >> 5) & 1;
dev = buf[0] & 0x1f;
code = (buf[1] >> 2) & 0x3f;
- if (3 != start)
+ /* rc5 has two start bits
+ * the first bit must be one
+ * the second bit defines the command range (1 = 0-63, 0 = 64 - 127)
+ */
+ if (!start)
/* no key pressed */
return 0;
- dprintk(1,"ir hauppauge (rc5): s%d t%d dev=%d code=%d\n",
- start, toggle, dev, code);
+
+ if (!range)
+ code += 64;
+
+ dprintk(1,"ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
+ start, range, toggle, dev, code);
/* return key */
*ir_key = code;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index f6e5771f4..065ccb0bb 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -3245,7 +3245,8 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
struct list_head *item;
struct pvr2_i2c_client *cp;
struct v4l2_register req;
- int stat;
+ int stat = 0;
+ int okFl = 0;
req.i2c_id = chip_id;
req.reg = reg_id;
@@ -3258,9 +3259,13 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
cp,(setFl ? VIDIOC_INT_S_REGISTER :
VIDIOC_INT_G_REGISTER),&req);
if (!setFl) *val_ptr = req.val;
- return stat;
+ okFl = !0;
+ break;
}
} while (0); mutex_unlock(&hdw->i2c_list_lock);
+ if (okFl) {
+ return stat;
+ }
return -EINVAL;
#else
return -ENOSYS;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
index 99daf3c1f..dbd2466ef 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -20,6 +20,7 @@
*/
#include "compat.h"
+#include <linux/kernel.h>
#include "pvrusb2-i2c-core.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
@@ -90,7 +91,8 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
{
- if (idx >= sizeof(ops)/sizeof(ops[0])) return 0;
+ if (idx >= ARRAY_SIZE(ops))
+ return NULL;
return ops[idx];
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 0da6c9ec6..6b72efd56 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -687,7 +687,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
ret = pvr2_hdw_register_access(
hdw,req->i2c_id,req->reg,
cmd == VIDIOC_INT_S_REGISTER,&val);
- if (cmd == 0) req->val = val;
+ if (cmd == VIDIOC_INT_G_REGISTER) req->val = val;
break;
}
#endif
diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c
index c62dd357d..d6850d5bd 100644
--- a/linux/drivers/media/video/saa7134/saa7134-cards.c
+++ b/linux/drivers/media/video/saa7134/saa7134-cards.c
@@ -3005,6 +3005,35 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
},
},
+ [SAA7134_BOARD_AVERMEDIA_A16AR] = {
+ /* Petr Baudis <pasky@ucw.cz> */
+ .name = "AVerMedia TV Hybrid A16AR",
+ .audio_clock = 0x187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290, /* untested */
+ .radio_type = TUNER_TEA5767, /* untested */
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ },
+ },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3602,6 +3631,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x2003,
.driver_data = SAA7134_BOARD_PROTEUS_2309,
},{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x1461,
+ .subdevice = 0x2c00,
+ .driver_data = SAA7134_BOARD_AVERMEDIA_A16AR,
+ },{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -3780,6 +3815,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00);
break;
+ case SAA7134_BOARD_AVERMEDIA_A16AR:
case SAA7134_BOARD_AVERMEDIA_CARDBUS:
/* power-up tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff);
diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c
index 352f9ebf6..0718f131a 100644
--- a/linux/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1056,6 +1056,7 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_AVERMEDIA_777:
+ case SAA7134_BOARD_AVERMEDIA_A16AR:
printk("%s: avertv 777 dvb setup\n",dev->name);
dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
&dev->i2c_adap);
diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c
index d3fbfbfdf..0799ce916 100644
--- a/linux/drivers/media/video/saa7134/saa7134-input.c
+++ b/linux/drivers/media/video/saa7134/saa7134-input.c
@@ -186,6 +186,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
+ case SAA7134_BOARD_AVERMEDIA_A16AR:
ir_codes = ir_codes_avermedia;
mask_keycode = 0x0007C8;
mask_keydown = 0x000010;
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index 84a8c70b8..2a4320c38 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -235,6 +235,7 @@ struct saa7134_format {
#define SAA7134_BOARD_MEDION_MD8800_QUADRO 96
#define SAA7134_BOARD_FLYDVBS_LR300 97
#define SAA7134_BOARD_PROTEUS_2309 98
+#define SAA7134_BOARD_AVERMEDIA_A16AR 99
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8