summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/Kconfig9
-rw-r--r--linux/drivers/media/Makefile2
-rw-r--r--linux/drivers/media/common/ir-keymaps.c8
-rw-r--r--linux/drivers/media/common/saa7146_core.c54
-rw-r--r--linux/drivers/media/common/saa7146_fops.c1
-rw-r--r--linux/drivers/media/common/saa7146_video.c6
-rw-r--r--linux/drivers/media/dvb/Kconfig24
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-pci.c9
-rw-r--r--linux/drivers/media/dvb/bt8xx/bt878.c4
-rw-r--r--linux/drivers/media/dvb/dvb-core/Kconfig14
-rw-r--r--linux/drivers/media/dvb/dvb-core/dmxdev.c56
-rw-r--r--linux/drivers/media/dvb/dvb-core/dmxdev.h2
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c20
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_net.c32
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_net.h1
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.c1
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.h1
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Kconfig7
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Makefile4
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h3
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c2
-rw-r--r--linux/drivers/media/dvb/dvb-usb/opera1.c595
-rw-r--r--linux/drivers/media/dvb/dvb-usb/opera1.h9
-rw-r--r--linux/drivers/media/dvb/dvb-usb/vp702x-fe.c14
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig7
-rw-r--r--linux/drivers/media/dvb/frontends/Makefile1
-rw-r--r--linux/drivers/media/dvb/frontends/dvb-pll.c301
-rw-r--r--linux/drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--linux/drivers/media/dvb/frontends/isl6421.c1
-rw-r--r--linux/drivers/media/dvb/frontends/lgdt330x.c4
-rw-r--r--linux/drivers/media/dvb/frontends/nxt200x.c4
-rw-r--r--linux/drivers/media/dvb/frontends/tda10021.c45
-rw-r--r--linux/drivers/media/dvb/frontends/tda10023.c548
-rw-r--r--linux/drivers/media/dvb/frontends/tda1002x.h (renamed from linux/drivers/media/dvb/frontends/tda10021.h)33
-rw-r--r--linux/drivers/media/dvb/frontends/tda10086.c2
-rw-r--r--linux/drivers/media/dvb/frontends/tda827x.c85
-rw-r--r--linux/drivers/media/dvb/pluto2/pluto2.c30
-rw-r--r--linux/drivers/media/dvb/ttpci/Kconfig2
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.c9
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-av.c147
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-ci.c2
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-core.c95
-rw-r--r--linux/drivers/media/dvb/ttpci/budget.h3
-rw-r--r--linux/drivers/media/radio/Kconfig11
-rw-r--r--linux/drivers/media/radio/radio-aimslab.c240
-rw-r--r--linux/drivers/media/radio/radio-gemtek-pci.c253
-rw-r--r--linux/drivers/media/radio/radio-gemtek.c260
-rw-r--r--linux/drivers/media/radio/radio-maestro.c277
-rw-r--r--linux/drivers/media/radio/radio-rtrack2.c255
-rw-r--r--linux/drivers/media/radio/radio-sf16fmi.c274
-rw-r--r--linux/drivers/media/radio/radio-sf16fmr2.c362
-rw-r--r--linux/drivers/media/radio/radio-terratec.c247
-rw-r--r--linux/drivers/media/radio/radio-trust.c258
-rw-r--r--linux/drivers/media/radio/radio-typhoon.c239
-rw-r--r--linux/drivers/media/radio/radio-zoltrix.c256
-rw-r--r--linux/drivers/media/video/Kconfig47
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-cards.c53
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-driver.c36
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-i2c.c2
-rw-r--r--linux/drivers/media/video/bt8xx/bttv.h2
-rw-r--r--linux/drivers/media/video/bt8xx/bttvp.h3
-rw-r--r--linux/drivers/media/video/cafe_ccic.c71
-rw-r--r--linux/drivers/media/video/cpia_pp.c46
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-core.c4
-rw-r--r--linux/drivers/media/video/cx88/cx88-alsa.c10
-rw-r--r--linux/drivers/media/video/cx88/cx88-cards.c25
-rw-r--r--linux/drivers/media/video/cx88/cx88-core.c8
-rw-r--r--linux/drivers/media/video/cx88/cx88-dvb.c20
-rw-r--r--linux/drivers/media/video/cx88/cx88-i2c.c3
-rw-r--r--linux/drivers/media/video/cx88/cx88-mpeg.c10
-rw-r--r--linux/drivers/media/video/cx88/cx88-video.c6
-rw-r--r--linux/drivers/media/video/cx88/cx88.h2
-rw-r--r--linux/drivers/media/video/em28xx/Kconfig2
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-i2c.c2
-rw-r--r--linux/drivers/media/video/et61x251/Kconfig2
-rw-r--r--linux/drivers/media/video/ir-kbd-i2c.c2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-fileops.c2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-ioctl.c6
-rw-r--r--linux/drivers/media/video/ov7670.c34
-rw-r--r--linux/drivers/media/video/planb.c6
-rw-r--r--linux/drivers/media/video/planb.h1
-rw-r--r--linux/drivers/media/video/pvrusb2/Kconfig2
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c13
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h2
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c28
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h3
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c23
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c42
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c8
-rw-r--r--linux/drivers/media/video/pwc/Kconfig2
-rw-r--r--linux/drivers/media/video/pwc/pwc-ctrl.c61
-rw-r--r--linux/drivers/media/video/pwc/pwc-if.c16
-rw-r--r--linux/drivers/media/video/pwc/pwc-ioctl.h40
-rw-r--r--linux/drivers/media/video/pwc/pwc-kiara.c2
-rw-r--r--linux/drivers/media/video/pwc/pwc-kiara.h5
-rw-r--r--linux/drivers/media/video/pwc/pwc-timon.c4
-rw-r--r--linux/drivers/media/video/pwc/pwc-timon.h6
-rw-r--r--linux/drivers/media/video/pwc/pwc-v4l.c62
-rw-r--r--linux/drivers/media/video/pwc/pwc.h5
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-cards.c127
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-dvb.c19
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-i2c.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-input.c1
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h3
-rw-r--r--linux/drivers/media/video/se401.c36
-rw-r--r--linux/drivers/media/video/sn9c102/Kconfig2
-rw-r--r--linux/drivers/media/video/sn9c102/Makefile17
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102.h21
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_core.c327
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_devtable.h18
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c31
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_hv7131r.c362
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_mi0343.c133
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_mi0360.c452
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_ov7630.c126
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_ov7660.c297
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_pas106b.c27
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c77
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_sensor.h35
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c20
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_tas5110d.c118
-rw-r--r--linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c21
-rw-r--r--linux/drivers/media/video/tda7432.c1
-rw-r--r--linux/drivers/media/video/tda8290.c8
-rw-r--r--linux/drivers/media/video/tda9875.c1
-rw-r--r--linux/drivers/media/video/tvaudio.c1
-rw-r--r--linux/drivers/media/video/usbvideo/Kconfig8
-rw-r--r--linux/drivers/media/video/usbvision/Kconfig2
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-cards.c1183
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-cards.h66
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-core.c10
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-i2c.c110
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-video.c212
-rw-r--r--linux/drivers/media/video/usbvision/usbvision.h60
-rw-r--r--linux/drivers/media/video/v4l1-compat.c64
-rw-r--r--linux/drivers/media/video/video-buf.c4
-rw-r--r--linux/drivers/media/video/videocodec.c3
-rw-r--r--linux/drivers/media/video/videodev.c55
-rw-r--r--linux/drivers/media/video/zc0301/Kconfig2
140 files changed, 6953 insertions, 2973 deletions
diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig
index 91d25798a..a852799f7 100644
--- a/linux/drivers/media/Kconfig
+++ b/linux/drivers/media/Kconfig
@@ -86,6 +86,14 @@ config VIDEO_TVEEPROM
tristate
depends on I2C
+config DAB
+ boolean "DAB adapters"
+ default y
+ ---help---
+ Allow selecting support for for Digital Audio Broadcasting (DAB)
+ Receiver adapters.
+
+if DAB
config USB_DABUSB
tristate "DABUSB driver"
depends on USB
@@ -99,5 +107,6 @@ config USB_DABUSB
To compile this driver as a module, choose M here: the
module will be called dabusb.
+endif # DAB
endmenu
diff --git a/linux/drivers/media/Makefile b/linux/drivers/media/Makefile
index c578a529e..8fa19939c 100644
--- a/linux/drivers/media/Makefile
+++ b/linux/drivers/media/Makefile
@@ -5,4 +5,4 @@
obj-y := common/
obj-$(CONFIG_VIDEO_DEV) += video/
obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-$(CONFIG_DVB) += dvb/
+obj-$(CONFIG_DVB_CORE) += dvb/
diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c
index 430314831..0f4d805f3 100644
--- a/linux/drivers/media/common/ir-keymaps.c
+++ b/linux/drivers/media/common/ir-keymaps.c
@@ -1789,7 +1789,7 @@ IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = {
EXPORT_SYMBOL_GPL(ir_codes_encore_enltv);
-/* for the Technotrend 1500 bundled remote: */
+/* for the Technotrend 1500 bundled remotes (grey and black): */
IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
[ 0x01 ] = KEY_POWER,
[ 0x02 ] = KEY_SHUFFLE, /* ? double-arrow key */
@@ -1824,6 +1824,12 @@ IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
[ 0x25 ] = KEY_VOLUMEUP,
[ 0x26 ] = KEY_VOLUMEDOWN,
[ 0x27 ] = KEY_SETUP,
+ [ 0x3a ] = KEY_RECORD, /* these keys are only in the black remote */
+ [ 0x3b ] = KEY_PLAY,
+ [ 0x3c ] = KEY_STOP,
+ [ 0x3d ] = KEY_REWIND,
+ [ 0x3e ] = KEY_PAUSE,
+ [ 0x3f ] = KEY_FORWARD,
};
EXPORT_SYMBOL_GPL(ir_codes_tt_1500);
diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c
index b13f2ade3..06edb5fc1 100644
--- a/linux/drivers/media/common/saa7146_core.c
+++ b/linux/drivers/media/common/saa7146_core.c
@@ -136,28 +136,45 @@ char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa
char *mem = vmalloc_32(length);
int slen = 0;
- if (NULL == mem) {
- return NULL;
- }
+ if (NULL == mem)
+ goto err_null;
- if (!(pt->slist = vmalloc_to_sg(mem, pages))) {
- vfree(mem);
- return NULL;
- }
+ if (!(pt->slist = vmalloc_to_sg(mem, pages)))
+ goto err_free_mem;
- if (saa7146_pgtable_alloc(pci, pt)) {
- kfree(pt->slist);
- pt->slist = NULL;
- vfree(mem);
- return NULL;
- }
+ if (saa7146_pgtable_alloc(pci, pt))
+ goto err_free_slist;
- slen = pci_map_sg(pci,pt->slist,pages,PCI_DMA_FROMDEVICE);
- if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) {
- return NULL;
- }
+ pt->nents = pages;
+ slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE);
+ if (0 == slen)
+ goto err_free_pgtable;
+
+ if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
+ goto err_unmap_sg;
return mem;
+
+err_unmap_sg:
+ pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+err_free_pgtable:
+ saa7146_pgtable_free(pci, pt);
+err_free_slist:
+ kfree(pt->slist);
+ pt->slist = NULL;
+err_free_mem:
+ vfree(mem);
+err_null:
+ return NULL;
+}
+
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt)
+{
+ pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+ saa7146_pgtable_free(pci, pt);
+ kfree(pt->slist);
+ pt->slist = NULL;
+ vfree(mem);
}
void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -166,8 +183,6 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
return;
pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
pt->cpu = NULL;
- kfree(pt->slist);
- pt->slist = NULL;
}
int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -532,6 +547,7 @@ EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
+EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
EXPORT_SYMBOL_GPL(saa7146_setgpio);
diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c
index 67d4d1a51..33257be76 100644
--- a/linux/drivers/media/common/saa7146_fops.c
+++ b/linux/drivers/media/common/saa7146_fops.c
@@ -308,7 +308,6 @@ static int fops_release(struct inode *inode, struct file *file)
return 0;
}
-int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
/*
diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c
index 35288c4bc..d3537ff4f 100644
--- a/linux/drivers/media/common/saa7146_video.c
+++ b/linux/drivers/media/common/saa7146_video.c
@@ -1429,6 +1429,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
{
struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
struct saa7146_vv *vv = dev->vv_data;
+ struct videobuf_queue *q = &fh->video_q;
int err;
if (IS_CAPTURE_ACTIVE(fh) != 0) {
@@ -1437,6 +1438,11 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
err = saa7146_stop_preview(fh);
}
+ // release all capture buffers
+ mutex_lock(&q->lock);
+ videobuf_read_stop(q);
+ mutex_unlock(&q->lock);
+
/* hmm, why is this function declared void? */
/* return err */
}
diff --git a/linux/drivers/media/dvb/Kconfig b/linux/drivers/media/dvb/Kconfig
index a97c8f5e9..efd2b7468 100644
--- a/linux/drivers/media/dvb/Kconfig
+++ b/linux/drivers/media/dvb/Kconfig
@@ -2,24 +2,16 @@
# Multimedia device configuration
#
-menu "Digital Video Broadcasting Devices"
+source "drivers/media/dvb/dvb-core/Kconfig"
-config DVB
- bool "DVB For Linux"
- depends on NET && INET
+menuconfig DVB_CAPTURE_DRIVERS
+ bool "DVB/ATSC adapters"
+ depends on DVB_CORE
+ default y
---help---
- Support Digital Video Broadcasting hardware. Enable this if you
- own a DVB adapter and want to use it or if you compile Linux for
- a digital SetTopBox.
-
- API specs and user tools are available from <http://www.linuxtv.org/>.
+ Say Y to select Digital TV adapters
- Please report problems regarding this driver to the LinuxDVB
- mailing list.
-
- If unsure say N.
-
-source "drivers/media/dvb/dvb-core/Kconfig"
+if DVB_CAPTURE_DRIVERS
comment "Supported SAA7146 based PCI Adapters"
depends on DVB_CORE && PCI && I2C
@@ -48,4 +40,4 @@ comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"
-endmenu
+endif # DVB_CAPTURE_DRIVERS
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-pci.c b/linux/drivers/media/dvb/b2c2/flexcop-pci.c
index 648f319b2..4388a78a1 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -143,10 +143,11 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
{
struct flexcop_pci *fc_pci = dev_id;
struct flexcop_device *fc = fc_pci->fc_dev;
+ unsigned long flags;
flexcop_ibi_value v;
irqreturn_t ret = IRQ_HANDLED;
- spin_lock_irq(&fc_pci->irq_lock);
+ spin_lock_irqsave(&fc_pci->irq_lock,flags);
v = fc->read_ibi_reg(fc,irq_20c);
@@ -210,7 +211,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
ret = IRQ_NONE;
}
- spin_unlock_irq(&fc_pci->irq_lock);
+ spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
return ret;
}
@@ -309,12 +310,12 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
}
pci_set_drvdata(fc_pci->pdev, fc_pci);
-
+ spin_lock_init(&fc_pci->irq_lock);
if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
goto err_pci_iounmap;
- spin_lock_init(&fc_pci->irq_lock);
+
fc_pci->init_state |= FC_PCI_INIT;
return ret;
diff --git a/linux/drivers/media/dvb/bt8xx/bt878.c b/linux/drivers/media/dvb/bt8xx/bt878.c
index 3a99cc594..1a75690f2 100644
--- a/linux/drivers/media/dvb/bt8xx/bt878.c
+++ b/linux/drivers/media/dvb/bt8xx/bt878.c
@@ -397,9 +397,7 @@ static struct cards card_list[] __devinitdata = {
{ 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" },
{ 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
{ 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" },
- { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" },
-
- { 0, -1, NULL }
+ { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }
};
diff --git a/linux/drivers/media/dvb/dvb-core/Kconfig b/linux/drivers/media/dvb/dvb-core/Kconfig
index 1990eda10..e3e6839f8 100644
--- a/linux/drivers/media/dvb/dvb-core/Kconfig
+++ b/linux/drivers/media/dvb/dvb-core/Kconfig
@@ -1,12 +1,22 @@
config DVB_CORE
- tristate "DVB Core Support"
- depends on DVB
+ tristate "DVB for Linux"
+ depends on NET && INET
select CRC32
help
+ Support Digital Video Broadcasting hardware. Enable this if you
+ own a DVB adapter and want to use it or if you compile Linux for
+ a digital SetTopBox.
+
DVB core utility functions for device handling, software fallbacks etc.
Say Y when you have a DVB card and want to use it. Say Y if your want
to build your drivers outside the kernel, but need the DVB core. All
in-kernel drivers will select this automatically if needed.
+
+ API specs and user tools are available from <http://www.linuxtv.org/>.
+
+ Please report problems regarding this driver to the LinuxDVB
+ mailing list.
+
If unsure say N.
config DVB_CORE_ATTACH
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c
index a5c0e1a3e..275df65fd 100644
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c
@@ -132,6 +132,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
+ if (dmxdev->exit) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ENODEV;
+ }
+
if ((file->f_flags & O_ACCMODE) == O_RDWR) {
if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
mutex_unlock(&dmxdev->mutex);
@@ -171,6 +176,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
dmxdev->demux->disconnect_frontend(dmxdev->demux);
dmxdev->demux->connect_frontend(dmxdev->demux, front);
}
+ dvbdev->users++;
mutex_unlock(&dmxdev->mutex);
return 0;
}
@@ -198,7 +204,16 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
vfree(mem);
}
}
- mutex_unlock(&dmxdev->mutex);
+ /* TODO */
+ dvbdev->users--;
+ if(dvbdev->users==-1 && dmxdev->exit==1) {
+ fops_put(file->f_op);
+ file->f_op = NULL;
+ mutex_unlock(&dmxdev->mutex);
+ wake_up(&dvbdev->wait_queue);
+ } else
+ mutex_unlock(&dmxdev->mutex);
+
return 0;
}
@@ -215,6 +230,11 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
return -EINVAL;
if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
+
+ if (dmxdev->exit) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ENODEV;
+ }
ret = dmxdev->demux->write(dmxdev->demux, buf, count);
mutex_unlock(&dmxdev->mutex);
return ret;
@@ -227,6 +247,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
struct dmxdev *dmxdev = dvbdev->priv;
int ret;
+ if (dmxdev->exit) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ENODEV;
+ }
+
//mutex_lock(&dmxdev->mutex);
ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
file->f_flags & O_NONBLOCK,
@@ -665,6 +690,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
dmxdevfilter->feed.ts = NULL;
init_timer(&dmxdevfilter->timer);
+ dvbdev->users++;
+
mutex_unlock(&dmxdev->mutex);
return 0;
}
@@ -943,7 +970,21 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
struct dmxdev_filter *dmxdevfilter = file->private_data;
struct dmxdev *dmxdev = dmxdevfilter->dev;
- return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+ int ret;
+
+ ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+
+ mutex_lock(&dmxdev->mutex);
+ dmxdev->dvbdev->users--;
+ if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) {
+ fops_put(file->f_op);
+ file->f_op = NULL;
+ mutex_unlock(&dmxdev->mutex);
+ wake_up(&dmxdev->dvbdev->wait_queue);
+ } else
+ mutex_unlock(&dmxdev->mutex);
+
+ return ret;
}
static struct file_operations dvb_demux_fops = {
@@ -1027,6 +1068,7 @@ static struct file_operations dvb_dvr_fops = {
static struct dvb_device dvbdev_dvr = {
.priv = NULL,
.readers = 1,
+ .users = 1,
.fops = &dvb_dvr_fops
};
@@ -1064,6 +1106,16 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
void dvb_dmxdev_release(struct dmxdev *dmxdev)
{
+ dmxdev->exit=1;
+ if (dmxdev->dvbdev->users > 1) {
+ wait_event(dmxdev->dvbdev->wait_queue,
+ dmxdev->dvbdev->users==1);
+ }
+ if (dmxdev->dvr_dvbdev->users > 1) {
+ wait_event(dmxdev->dvr_dvbdev->wait_queue,
+ dmxdev->dvr_dvbdev->users==1);
+ }
+
dvb_unregister_device(dmxdev->dvbdev);
dvb_unregister_device(dmxdev->dvr_dvbdev);
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.h b/linux/drivers/media/dvb/dvb-core/dmxdev.h
index 080abd9a9..bb416e6c2 100644
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.h
@@ -98,6 +98,8 @@ struct dmxdev {
int filternum;
int capabilities;
+
+ unsigned int exit:1;
#define DMXDEV_CAP_DUPLEX 1
struct dmx_frontend *dvr_orig_fe;
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index 60c8b0da2..2cad44fb2 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -611,6 +611,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
return;
kthread_stop(fepriv->thread);
+
init_MUTEX (&fepriv->sem);
fepriv->state = FESTATE_IDLE;
@@ -1028,6 +1029,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ int ret;
dprintk ("%s\n", __FUNCTION__);
@@ -1037,7 +1039,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
if (fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl (fe, 0);
- return dvb_generic_release (inode, file);
+ ret = dvb_generic_release (inode, file);
+
+ if (dvbdev->users==-1 && fepriv->exit==1) {
+ fops_put(file->f_op);
+ file->f_op = NULL;
+ wake_up(&dvbdev->wait_queue);
+ }
+ return ret;
}
static struct file_operations dvb_frontend_fops = {
@@ -1097,8 +1106,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
dprintk ("%s\n", __FUNCTION__);
mutex_lock(&frontend_mutex);
- dvb_unregister_device (fepriv->dvbdev);
dvb_frontend_stop (fe);
+ mutex_unlock(&frontend_mutex);
+
+ if (fepriv->dvbdev->users < -1)
+ wait_event(fepriv->dvbdev->wait_queue,
+ fepriv->dvbdev->users==-1);
+
+ mutex_lock(&frontend_mutex);
+ dvb_unregister_device (fepriv->dvbdev);
/* fe is invalid now */
kfree(fepriv);
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c
index 3e94e6cf9..7089412e3 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1476,11 +1476,36 @@ static int dvb_net_ioctl(struct inode *inode, struct file *file,
return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl);
}
+static int dvb_net_close(struct inode *inode, struct file *file)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct dvb_net *dvbnet = dvbdev->priv;
+
+ if (!dvbdev)
+ return -ENODEV;
+
+ if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+ dvbdev->readers++;
+ } else {
+ dvbdev->writers++;
+ }
+
+ dvbdev->users++;
+
+ if(dvbdev->users == 1 && dvbnet->exit==1) {
+ fops_put(file->f_op);
+ file->f_op = NULL;
+ wake_up(&dvbdev->wait_queue);
+ }
+ return 0;
+}
+
+
static struct file_operations dvb_net_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_net_ioctl,
.open = dvb_generic_open,
- .release = dvb_generic_release,
+ .release = dvb_net_close,
};
static struct dvb_device dvbdev_net = {
@@ -1495,6 +1520,11 @@ void dvb_net_release (struct dvb_net *dvbnet)
{
int i;
+ dvbnet->exit = 1;
+ if (dvbnet->dvbdev->users < 1)
+ wait_event(dvbnet->dvbdev->wait_queue,
+ dvbnet->dvbdev->users==1);
+
dvb_unregister_device(dvbnet->dvbdev);
for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.h b/linux/drivers/media/dvb/dvb-core/dvb_net.h
index f14e4ca38..3a3126cae 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_net.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_net.h
@@ -36,6 +36,7 @@ struct dvb_net {
struct dvb_device *dvbdev;
struct net_device *device[DVB_NET_DEVICES_MAX];
int state[DVB_NET_DEVICES_MAX];
+ unsigned int exit:1;
struct dmx_demux *demux;
};
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c
index 9c8e9c3f4..17104fb4b 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c
@@ -244,6 +244,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdev->adapter = adap;
dvbdev->priv = priv;
dvbdev->fops = dvbdevfops;
+ init_waitqueue_head (&dvbdev->wait_queue);
memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
dvbdev->fops->owner = adap->module;
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h
index 26e4a9135..cb76869bd 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h
@@ -70,6 +70,7 @@ struct dvb_device {
int writers;
int users;
+ wait_queue_head_t wait_queue;
/* don't really need those !? -- FIXME: use video_usercopy */
int (*kernel_ioctl)(struct inode *inode, struct file *file,
unsigned int cmd, void *arg);
diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig
index 8aa12722c..54488737a 100644
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig
@@ -211,3 +211,10 @@ config DVB_USB_DTT200U
The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
The WT-220U and its clones are pen-sized.
+
+config DVB_USB_OPERA1
+ tristate "Opera1 DVB-S USB2.0 receiver"
+ depends on DVB_USB
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ help
+ Say Y here to support the Opera DVB-S USB2.0 receiver.
diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile
index 40f28f559..976f840cc 100644
--- a/linux/drivers/media/dvb/dvb-usb/Makefile
+++ b/linux/drivers/media/dvb/dvb-usb/Makefile
@@ -51,4 +51,8 @@ obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
+dvb-usb-opera-objs = opera1.o
+obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
+
+
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 9b762a7f2..403081689 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -33,6 +33,7 @@
#define USB_VID_LITEON 0x04ca
#define USB_VID_MEDION 0x1660
#define USB_VID_MSI 0x0db0
+#define USB_VID_OPERA1 0x695c
#define USB_VID_PINNACLE 0x2304
#define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_TWINHAN 0x1822
@@ -145,6 +146,8 @@
#define USB_PID_GENPIX_8PSK_WARM 0x0201
#define USB_PID_SIGMATEK_DVB_110 0x6610
#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
+#define USB_PID_OPERA1_COLD 0x2830
+#define USB_PID_OPERA1_WARM 0x3829
#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514
#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index cccc2512a..9d5f1bc1e 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -121,8 +121,6 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
return -ENOMEM;
input_dev->evbit[0] = BIT(EV_KEY);
- input_dev->keycodesize = sizeof(unsigned char);
- input_dev->keycodemax = KEY_MAX;
input_dev->name = "IR-receiver inside an USB DVB receiver";
input_dev->phys = d->rc_phys;
usb_to_input_id(d->udev, &input_dev->id);
diff --git a/linux/drivers/media/dvb/dvb-usb/opera1.c b/linux/drivers/media/dvb/dvb-usb/opera1.c
new file mode 100644
index 000000000..dda7a44bf
--- /dev/null
+++ b/linux/drivers/media/dvb/dvb-usb/opera1.c
@@ -0,0 +1,595 @@
+/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
+*
+* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
+* Copyright (C) 2006 Marco Gittler (g.marco@freenet.de)
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the Free
+* Software Foundation, version 2.
+*
+* see Documentation/dvb/README.dvb-usb for more information
+*/
+
+#include "opera1.h"
+#include "stv0299.h"
+
+#define OPERA_READ_MSG 0
+#define OPERA_WRITE_MSG 1
+#define OPERA_I2C_TUNER 0xd1
+
+#define READ_FX2_REG_REQ 0xba
+#define READ_MAC_ADDR 0x08
+#define OPERA_WRITE_FX2 0xbb
+#define OPERA_TUNER_REQ 0xb1
+#define REG_1F_SYMBOLRATE_BYTE0 0x1f
+#define REG_20_SYMBOLRATE_BYTE1 0x20
+#define REG_21_SYMBOLRATE_BYTE2 0x21
+
+#define ADDR_B600_VOLTAGE_13V (0x02)
+#define ADDR_B601_VOLTAGE_18V (0x03)
+#define ADDR_B1A6_STREAM_CTRL (0x04)
+#define ADDR_B880_READ_REMOTE (0x05)
+
+struct opera1_state {
+ u32 last_key_pressed;
+};
+struct opera_rc_keys {
+ u32 keycode;
+ u32 event;
+};
+
+int dvb_usb_opera1_debug;
+module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+ "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
+ DVB_USB_DEBUG_STATUS);
+#if 0
+struct mutex mymutex;
+#endif
+
+static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
+ u8 * data, u16 len, int flags)
+{
+ int ret;
+ u8 r;
+ u8 u8buf[len];
+
+ unsigned int pipe = (flags == OPERA_READ_MSG) ?
+ usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
+ u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
+
+#if 0
+ if (mutex_lock_interruptible(&mymutex)) {
+ return -EAGAIN;
+ }
+#endif
+ if (flags == OPERA_WRITE_MSG)
+ memcpy(u8buf, data, len);
+ ret =
+ usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
+ value, 0x0, u8buf, len, 2000);
+
+ if (request == OPERA_TUNER_REQ) {
+ if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
+ 0x01, 0x0, &r, 1, 2000)<1 || r!=0x08)
+ return 0;
+ }
+ if (flags == OPERA_READ_MSG)
+ memcpy(data, u8buf, len);
+#if 0
+ mutex_unlock(&mymutex);
+#endif
+ return ret;
+}
+
+/* I2C */
+
+static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
+ u8 * buf, u16 len)
+{
+ int ret = 0;
+ u8 request;
+ u16 value;
+
+ if (!dev) {
+ info("no usb_device");
+ return -EINVAL;
+ }
+ if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
+ return -EAGAIN;
+
+ switch (addr>>1){
+ case ADDR_B600_VOLTAGE_13V:
+ request=0xb6;
+ value=0x00;
+ break;
+ case ADDR_B601_VOLTAGE_18V:
+ request=0xb6;
+ value=0x01;
+ break;
+ case ADDR_B1A6_STREAM_CTRL:
+ request=0xb1;
+ value=0xa6;
+ break;
+ case ADDR_B880_READ_REMOTE:
+ request=0xb8;
+ value=0x80;
+ break;
+ default:
+ request=0xb1;
+ value=addr;
+ }
+ ret = opera1_xilinx_rw(dev->udev, request,
+ value, buf, len,
+ addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
+
+ mutex_unlock(&dev->usb_mutex);
+ return ret;
+}
+
+static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i = 0, tmp = 0;
+
+ if (!d)
+ return -ENODEV;
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ for (i = 0; i < num; i++) {
+ if ((tmp = opera1_usb_i2c_msgxfer(d,
+ (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
+ msg[i].buf,
+ msg[i].len
+ )!= msg[i].len)) {
+ break;
+ }
+ if (dvb_usb_opera1_debug & 0x10)
+ info("sending i2c mesage %d %d", tmp, msg[i].len);
+ }
+ mutex_unlock(&d->i2c_mutex);
+ return num;
+}
+
+static u32 opera1_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm opera1_i2c_algo = {
+ .master_xfer = opera1_i2c_xfer,
+ .functionality = opera1_i2c_func,
+};
+
+static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ static u8 command_13v[1]={0x00};
+ static u8 command_18v[1]={0x01};
+ struct i2c_msg msg[] = {
+ {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
+ };
+ struct dvb_usb_adapter *udev_adap =
+ (struct dvb_usb_adapter *)(fe->dvb->priv);
+ if (voltage == SEC_VOLTAGE_18) {
+ msg[0].addr = ADDR_B601_VOLTAGE_18V;
+ msg[0].buf = command_18v;
+ }
+ i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
+ return 0;
+}
+
+static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
+ u32 ratio)
+{
+ stv0299_writereg(fe, 0x13, 0x98);
+ stv0299_writereg(fe, 0x14, 0x95);
+ stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
+ stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
+ stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
+ return 0;
+
+}
+static u8 opera1_inittab[] = {
+ 0x00, 0xa1,
+ 0x01, 0x15,
+ 0x02, 0x00,
+ 0x03, 0x00,
+ 0x04, 0x7d,
+ 0x05, 0x05,
+ 0x06, 0x02,
+ 0x07, 0x00,
+ 0x0b, 0x00,
+ 0x0c, 0x01,
+ 0x0d, 0x81,
+ 0x0e, 0x44,
+ 0x0f, 0x19,
+ 0x10, 0x3f,
+ 0x11, 0x84,
+ 0x12, 0xda,
+ 0x13, 0x98,
+ 0x14, 0x95,
+ 0x15, 0xc9,
+ 0x16, 0xeb,
+ 0x17, 0x00,
+ 0x18, 0x19,
+ 0x19, 0x8b,
+ 0x1a, 0x00,
+ 0x1b, 0x82,
+ 0x1c, 0x7f,
+ 0x1d, 0x00,
+ 0x1e, 0x00,
+ REG_1F_SYMBOLRATE_BYTE0, 0x06,
+ REG_20_SYMBOLRATE_BYTE1, 0x50,
+ REG_21_SYMBOLRATE_BYTE2, 0x10,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x24, 0x37,
+ 0x25, 0xbc,
+ 0x26, 0x00,
+ 0x27, 0x00,
+ 0x28, 0x00,
+ 0x29, 0x1e,
+ 0x2a, 0x14,
+ 0x2b, 0x1f,
+ 0x2c, 0x09,
+ 0x2d, 0x0a,
+ 0x2e, 0x00,
+ 0x2f, 0x00,
+ 0x30, 0x00,
+ 0x31, 0x1f,
+ 0x32, 0x19,
+ 0x33, 0xfc,
+ 0x34, 0x13,
+ 0xff, 0xff,
+};
+
+static struct stv0299_config opera1_stv0299_config = {
+ .demod_address = 0xd0>>1,
+ .min_delay_ms = 100,
+ .mclk = 88000000UL,
+ .invert = 1,
+ .skip_reinit = 0,
+ .lock_output = STV0229_LOCKOUTPUT_0,
+ .volt13_op0_op1 = STV0299_VOLT13_OP0,
+ .inittab = opera1_inittab,
+ .set_symbol_rate = opera1_stv0299_set_symbol_rate,
+};
+
+static int opera1_frontend_attach(struct dvb_usb_adapter *d)
+{
+ if ((d->fe =
+ dvb_attach(stv0299_attach, &opera1_stv0299_config,
+ &d->dev->i2c_adap)) != NULL) {
+ d->fe->ops.set_voltage = opera1_set_voltage;
+ return 0;
+ }
+ info("not attached stv0299");
+ return -EIO;
+}
+
+static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ dvb_attach(
+ dvb_pll_attach, adap->fe, 0xc0>>1,
+ &adap->dev->i2c_adap, &dvb_pll_opera1
+ );
+ return 0;
+}
+
+static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 val = onoff ? 0x01 : 0x00;
+
+ if (dvb_usb_opera1_debug)
+ info("power %s", onoff ? "on" : "off");
+ return opera1_xilinx_rw(d->udev, 0xb7, val,
+ &val, 1, OPERA_WRITE_MSG);
+}
+
+static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+ static u8 buf_start[2] = { 0xff, 0x03 };
+ static u8 buf_stop[2] = { 0xff, 0x00 };
+ struct i2c_msg start_tuner[] = {
+ {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
+ };
+ if (dvb_usb_opera1_debug)
+ info("streaming %s", onoff ? "on" : "off");
+ i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
+ return 0;
+}
+
+static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+ int onoff)
+{
+ u8 b_pid[3];
+ struct i2c_msg msg[] = {
+ {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
+ };
+ if (dvb_usb_opera1_debug)
+ info("pidfilter index: %d pid: %d %s", index, pid,
+ onoff ? "on" : "off");
+ b_pid[0] = (2 * index) + 4;
+ b_pid[1] = onoff ? (pid & 0xff) : (0x00);
+ b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
+ i2c_transfer(&adap->dev->i2c_adap, msg, 1);
+ return 0;
+}
+
+static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
+{
+ int u = 0x04;
+ u8 b_pid[3];
+ struct i2c_msg msg[] = {
+ {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
+ };
+ if (dvb_usb_opera1_debug)
+ info("%s hw-pidfilter", onoff ? "enable" : "disable");
+ for (; u < 0x7e; u += 2) {
+ b_pid[0] = u;
+ b_pid[1] = 0;
+ b_pid[2] = 0x80;
+ i2c_transfer(&adap->dev->i2c_adap, msg, 1);
+ }
+ return 0;
+}
+
+static struct dvb_usb_rc_key opera1_rc_keys[] = {
+ {0x5f, 0xa0, KEY_1},
+ {0x51, 0xaf, KEY_2},
+ {0x5d, 0xa2, KEY_3},
+ {0x41, 0xbe, KEY_4},
+ {0x0b, 0xf5, KEY_5},
+ {0x43, 0xbd, KEY_6},
+ {0x47, 0xb8, KEY_7},
+ {0x49, 0xb6, KEY_8},
+ {0x05, 0xfa, KEY_9},
+ {0x45, 0xba, KEY_0},
+ {0x09, 0xf6, KEY_UP}, /*chanup */
+ {0x1b, 0xe5, KEY_DOWN}, /*chandown */
+ {0x5d, 0xa3, KEY_LEFT}, /*voldown */
+ {0x5f, 0xa1, KEY_RIGHT}, /*volup */
+ {0x07, 0xf8, KEY_SPACE}, /*tab */
+ {0x1f, 0xe1, KEY_ENTER}, /*play ok */
+ {0x1b, 0xe4, KEY_Z}, /*zoom */
+ {0x59, 0xa6, KEY_M}, /*mute */
+ {0x5b, 0xa5, KEY_F}, /*tv/f */
+ {0x19, 0xe7, KEY_R}, /*rec */
+ {0x01, 0xfe, KEY_S}, /*Stop */
+ {0x03, 0xfd, KEY_P}, /*pause */
+ {0x03, 0xfc, KEY_W}, /*<- -> */
+ {0x07, 0xf9, KEY_C}, /*capture */
+ {0x47, 0xb9, KEY_Q}, /*exit */
+ {0x43, 0xbc, KEY_O}, /*power */
+
+};
+
+static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
+{
+ struct opera1_state *opst = dev->priv;
+ u8 rcbuffer[32];
+ const u16 startmarker1 = 0x10ed;
+ const u16 startmarker2 = 0x11ec;
+ struct i2c_msg read_remote[] = {
+ {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
+ };
+ int i = 0;
+ u32 send_key = 0;
+
+ if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
+ for (i = 0; i < 32; i++) {
+ if (rcbuffer[i])
+ send_key |= 1;
+ if (i < 31)
+ send_key = send_key << 1;
+ }
+ if (send_key & 0x8000)
+ send_key = (send_key << 1) | (send_key >> 15 & 0x01);
+
+ if (send_key == 0xffff && opst->last_key_pressed != 0) {
+ *state = REMOTE_KEY_REPEAT;
+ *event = opst->last_key_pressed;
+ return 0;
+ }
+ for (; send_key != 0;) {
+ if (send_key >> 16 == startmarker2) {
+ break;
+ } else if (send_key >> 16 == startmarker1) {
+ send_key =
+ (send_key & 0xfffeffff) | (startmarker1 << 16);
+ break;
+ } else
+ send_key >>= 1;
+ }
+
+ if (send_key == 0)
+ return 0;
+
+ send_key = (send_key & 0xffff) | 0x0100;
+
+ for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) {
+ if ((opera1_rc_keys[i].custom * 256 +
+ opera1_rc_keys[i].data) == (send_key & 0xffff)) {
+ *state = REMOTE_KEY_PRESSED;
+ *event = opera1_rc_keys[i].event;
+ opst->last_key_pressed =
+ opera1_rc_keys[i].event;
+ break;
+ }
+ opst->last_key_pressed = 0;
+ }
+ } else
+ *state = REMOTE_NO_KEY_PRESSED;
+ return 0;
+}
+
+static struct usb_device_id opera1_table[] = {
+ {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)},
+ {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, opera1_table);
+
+static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+{
+ u8 command[] = { READ_MAC_ADDR };
+ opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
+ opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
+ return 0;
+}
+static int opera1_xilinx_load_firmware(struct usb_device *dev,
+ const char *filename)
+{
+ const struct firmware *fw = NULL;
+ u8 *b, *p;
+ int ret = 0, i;
+ u8 testval;
+ info("start downloading fpga firmware");
+
+ if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
+ err("did not find the firmware file. (%s) "
+ "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
+ filename);
+ return ret;
+ } else {
+ p = kmalloc(fw->size, GFP_KERNEL);
+ opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
+ if (p != NULL && testval != 0x67) {
+
+ u8 reset = 0, fpga_command = 0;
+ memcpy(p, fw->data, fw->size);
+ /* clear fpga ? */
+ opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
+ OPERA_WRITE_MSG);
+ for (i = 0; p[i] != 0 && i < fw->size;) {
+ b = (u8 *) p + i;
+ if (opera1_xilinx_rw
+ (dev, OPERA_WRITE_FX2, 0x0, b + 1, b[0],
+ OPERA_WRITE_MSG) != b[0]
+ ) {
+ err("error while transferring firmware");
+ ret = -EINVAL;
+ break;
+ }
+ i = i + 1 + b[0];
+ }
+ /* restart the CPU */
+ if (ret || opera1_xilinx_rw
+ (dev, 0xa0, 0xe600, &reset, 1,
+ OPERA_WRITE_MSG) != 1) {
+ err("could not restart the USB controller CPU.");
+ ret = -EINVAL;
+ }
+ kfree(p);
+ }
+ }
+ if (fw) {
+ release_firmware(fw);
+ }
+ return ret;
+}
+
+static struct dvb_usb_device_properties opera1_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-opera-01.fw",
+ .size_of_priv = sizeof(struct opera1_state),
+
+ .power_ctrl = opera1_power_ctrl,
+ .i2c_algo = &opera1_i2c_algo,
+
+ .rc_key_map = opera1_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(opera1_rc_keys),
+ .rc_interval = 200,
+ .rc_query = opera1_rc_query,
+ .read_mac_address = opera1_read_mac_address,
+ .generic_bulk_ctrl_endpoint = 0x00,
+ /* parameter for the MPEG2-data transfer */
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = opera1_frontend_attach,
+ .streaming_ctrl = opera1_streaming_ctrl,
+ .tuner_attach = opera1_tuner_attach,
+ .caps =
+ DVB_USB_ADAP_HAS_PID_FILTER |
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+ .pid_filter = opera1_pid_filter,
+ .pid_filter_ctrl = opera1_pid_filter_control,
+ .pid_filter_count = 252,
+ .stream = {
+ .type = USB_BULK,
+ .count = 10,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+ }
+ },
+ .num_device_descs = 1,
+ .devices = {
+ {"Opera1 DVB-S USB2.0",
+ {&opera1_table[0], NULL},
+ {&opera1_table[1], NULL},
+ },
+ }
+};
+
+static int opera1_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct dvb_usb_device *d;
+ struct usb_device *udev = interface_to_usbdev(intf);
+
+ if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
+ udev->descriptor.idVendor == USB_VID_OPERA1 &&
+ (d == NULL
+ || opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga.fw") != 0)
+ ) {
+ return -EINVAL;
+ }
+
+ if (dvb_usb_device_init(intf, &opera1_properties, THIS_MODULE, &d) != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static struct usb_driver opera1_driver = {
+ .name = "opera1",
+ .probe = opera1_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = opera1_table,
+};
+
+static int __init opera1_module_init(void)
+{
+ int result = 0;
+#if 0
+ mutex_init(&mymutex);
+#endif
+ if ((result = usb_register(&opera1_driver))) {
+ err("usb_register failed. Error number %d", result);
+ }
+ return result;
+}
+
+static void __exit opera1_module_exit(void)
+{
+ usb_deregister(&opera1_driver);
+}
+
+module_init(opera1_module_init);
+module_exit(opera1_module_exit);
+
+MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
+MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
+MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/dvb-usb/opera1.h b/linux/drivers/media/dvb/dvb-usb/opera1.h
new file mode 100644
index 000000000..531744279
--- /dev/null
+++ b/linux/drivers/media/dvb/dvb-usb/opera1.h
@@ -0,0 +1,9 @@
+#ifndef _OPERA1_H_
+#define _OPERA1_H_
+
+#define DVB_USB_LOG_PREFIX "opera"
+#include "dvb-usb.h"
+
+extern int dvb_usb_opera1_debug;
+#define deb_xfer(args...) dprintk(dvb_usb_opera1_debug,0x02,args)
+#endif
diff --git a/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c b/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c
index 3ecb2e0ce..c3fdc7cd0 100644
--- a/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -204,8 +204,8 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
struct dvb_diseqc_master_cmd *m)
{
- //struct vp702x_fe_state *st = fe->demodulator_priv;
- u8 cmd[8];//,ibuf[10];
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u8 cmd[8],ibuf[10];
memset(cmd,0,8);
deb_fe("%s\n",__FUNCTION__);
@@ -218,12 +218,12 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
memcpy(&cmd[3], m->msg, m->msg_len);
cmd[7] = vp702x_chksum(cmd,0,7);
-// vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+ vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
-// if (ibuf[2] == 0 && ibuf[3] == 0)
-// deb_fe("diseqc cmd failed.\n");
-// else
-// deb_fe("diseqc cmd succeeded.\n");
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("diseqc cmd failed.\n");
+ else
+ deb_fe("diseqc cmd succeeded.\n");
return 0;
}
diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig
index 10c4e7bdd..ff448761d 100644
--- a/linux/drivers/media/dvb/frontends/Kconfig
+++ b/linux/drivers/media/dvb/frontends/Kconfig
@@ -205,6 +205,13 @@ config DVB_TDA10021
help
A DVB-C tuner module. Say Y when you want to support this frontend.
+config DVB_TDA10023
+ tristate "Philips TDA10023 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-C tuner module. Say Y when you want to support this frontend.
+
config DVB_STV0297
tristate "ST STV0297 based"
depends on DVB_CORE && I2C
diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile
index 905fcfc87..27f386585 100644
--- a/linux/drivers/media/dvb/frontends/Makefile
+++ b/linux/drivers/media/dvb/frontends/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_MT352) += mt352.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
+obj-$(CONFIG_DVB_TDA10023) += tda10023.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o
obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
obj-$(CONFIG_DVB_OR51211) += or51211.o
diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c
index abc08f0ae..5f96ffda9 100644
--- a/linux/drivers/media/dvb/frontends/dvb-pll.c
+++ b/linux/drivers/media/dvb/frontends/dvb-pll.c
@@ -42,13 +42,14 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
.name = "Thomson dtt7579",
.min = 177000000,
.max = 858000000,
- .count = 5,
+ .iffreq= 36166667,
+ .sleepdata = (u8[]){ 2, 0xb4, 0x03 },
+ .count = 4,
.entries = {
- { 0, 36166667, 166666, 0xb4, 0x03 }, /* go sleep */
- { 443250000, 36166667, 166666, 0xb4, 0x02 },
- { 542000000, 36166667, 166666, 0xb4, 0x08 },
- { 771000000, 36166667, 166666, 0xbc, 0x08 },
- { 999999999, 36166667, 166666, 0xf4, 0x08 },
+ { 443250000, 166667, 0xb4, 0x02 },
+ { 542000000, 166667, 0xb4, 0x08 },
+ { 771000000, 166667, 0xbc, 0x08 },
+ { 999999999, 166667, 0xf4, 0x08 },
},
};
EXPORT_SYMBOL(dvb_pll_thomson_dtt7579);
@@ -57,11 +58,12 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
.name = "Thomson dtt7610",
.min = 44000000,
.max = 958000000,
+ .iffreq= 44000000,
.count = 3,
.entries = {
- { 157250000, 44000000, 62500, 0x8e, 0x39 },
- { 454000000, 44000000, 62500, 0x8e, 0x3a },
- { 999999999, 44000000, 62500, 0x8e, 0x3c },
+ { 157250000, 62500, 0x8e, 0x39 },
+ { 454000000, 62500, 0x8e, 0x3a },
+ { 999999999, 62500, 0x8e, 0x3c },
},
};
EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
@@ -77,14 +79,15 @@ struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
.min = 177000000,
.max = 896000000,
.setbw = thomson_dtt759x_bw,
- .count = 6,
+ .iffreq= 36166667,
+ .sleepdata = (u8[]){ 2, 0x84, 0x03 },
+ .count = 5,
.entries = {
- { 0, 36166667, 166666, 0x84, 0x03 },
- { 264000000, 36166667, 166666, 0xb4, 0x02 },
- { 470000000, 36166667, 166666, 0xbc, 0x02 },
- { 735000000, 36166667, 166666, 0xbc, 0x08 },
- { 835000000, 36166667, 166666, 0xf4, 0x08 },
- { 999999999, 36166667, 166666, 0xfc, 0x08 },
+ { 264000000, 166667, 0xb4, 0x02 },
+ { 470000000, 166667, 0xbc, 0x02 },
+ { 735000000, 166667, 0xbc, 0x08 },
+ { 835000000, 166667, 0xf4, 0x08 },
+ { 999999999, 166667, 0xfc, 0x08 },
},
};
EXPORT_SYMBOL(dvb_pll_thomson_dtt759x);
@@ -93,14 +96,15 @@ struct dvb_pll_desc dvb_pll_lg_z201 = {
.name = "LG z201",
.min = 174000000,
.max = 862000000,
- .count = 6,
+ .iffreq= 36166667,
+ .sleepdata = (u8[]){ 2, 0xbc, 0x03 },
+ .count = 5,
.entries = {
- { 0, 36166667, 166666, 0xbc, 0x03 },
- { 157500000, 36166667, 166666, 0xbc, 0x01 },
- { 443250000, 36166667, 166666, 0xbc, 0x02 },
- { 542000000, 36166667, 166666, 0xbc, 0x04 },
- { 830000000, 36166667, 166666, 0xf4, 0x04 },
- { 999999999, 36166667, 166666, 0xfc, 0x04 },
+ { 157500000, 166667, 0xbc, 0x01 },
+ { 443250000, 166667, 0xbc, 0x02 },
+ { 542000000, 166667, 0xbc, 0x04 },
+ { 830000000, 166667, 0xf4, 0x04 },
+ { 999999999, 166667, 0xfc, 0x04 },
},
};
EXPORT_SYMBOL(dvb_pll_lg_z201);
@@ -109,11 +113,12 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = {
.name = "Microtune 4042 FI5",
.min = 57000000,
.max = 858000000,
+ .iffreq= 44000000,
.count = 3,
.entries = {
- { 162000000, 44000000, 62500, 0x8e, 0xa1 },
- { 457000000, 44000000, 62500, 0x8e, 0x91 },
- { 999999999, 44000000, 62500, 0x8e, 0x31 },
+ { 162000000, 62500, 0x8e, 0xa1 },
+ { 457000000, 62500, 0x8e, 0x91 },
+ { 999999999, 62500, 0x8e, 0x31 },
},
};
EXPORT_SYMBOL(dvb_pll_microtune_4042);
@@ -123,12 +128,13 @@ struct dvb_pll_desc dvb_pll_thomson_dtt761x = {
.name = "Thomson dtt761x",
.min = 57000000,
.max = 863000000,
+ .iffreq= 44000000,
.count = 3,
.initdata = tua603x_agc103,
.entries = {
- { 147000000, 44000000, 62500, 0x8e, 0x39 },
- { 417000000, 44000000, 62500, 0x8e, 0x3a },
- { 999999999, 44000000, 62500, 0x8e, 0x3c },
+ { 147000000, 62500, 0x8e, 0x39 },
+ { 417000000, 62500, 0x8e, 0x3a },
+ { 999999999, 62500, 0x8e, 0x3c },
},
};
EXPORT_SYMBOL(dvb_pll_thomson_dtt761x);
@@ -137,17 +143,18 @@ struct dvb_pll_desc dvb_pll_unknown_1 = {
.name = "unknown 1", /* used by dntv live dvb-t */
.min = 174000000,
.max = 862000000,
+ .iffreq= 36166667,
.count = 9,
.entries = {
- { 150000000, 36166667, 166666, 0xb4, 0x01 },
- { 173000000, 36166667, 166666, 0xbc, 0x01 },
- { 250000000, 36166667, 166666, 0xb4, 0x02 },
- { 400000000, 36166667, 166666, 0xbc, 0x02 },
- { 420000000, 36166667, 166666, 0xf4, 0x02 },
- { 470000000, 36166667, 166666, 0xfc, 0x02 },
- { 600000000, 36166667, 166666, 0xbc, 0x08 },
- { 730000000, 36166667, 166666, 0xf4, 0x08 },
- { 999999999, 36166667, 166666, 0xfc, 0x08 },
+ { 150000000, 166667, 0xb4, 0x01 },
+ { 173000000, 166667, 0xbc, 0x01 },
+ { 250000000, 166667, 0xb4, 0x02 },
+ { 400000000, 166667, 0xbc, 0x02 },
+ { 420000000, 166667, 0xf4, 0x02 },
+ { 470000000, 166667, 0xfc, 0x02 },
+ { 600000000, 166667, 0xbc, 0x08 },
+ { 730000000, 166667, 0xf4, 0x08 },
+ { 999999999, 166667, 0xfc, 0x08 },
},
};
EXPORT_SYMBOL(dvb_pll_unknown_1);
@@ -159,11 +166,12 @@ struct dvb_pll_desc dvb_pll_tua6010xs = {
.name = "Infineon TUA6010XS",
.min = 44250000,
.max = 858000000,
+ .iffreq= 36125000,
.count = 3,
.entries = {
- { 115750000, 36125000, 62500, 0x8e, 0x03 },
- { 403250000, 36125000, 62500, 0x8e, 0x06 },
- { 999999999, 36125000, 62500, 0x8e, 0x85 },
+ { 115750000, 62500, 0x8e, 0x03 },
+ { 403250000, 62500, 0x8e, 0x06 },
+ { 999999999, 62500, 0x8e, 0x85 },
},
};
EXPORT_SYMBOL(dvb_pll_tua6010xs);
@@ -173,12 +181,13 @@ struct dvb_pll_desc dvb_pll_env57h1xd5 = {
.name = "Panasonic ENV57H1XD5",
.min = 44250000,
.max = 858000000,
+ .iffreq= 36125000,
.count = 4,
.entries = {
- { 153000000, 36291666, 166666, 0xc2, 0x41 },
- { 470000000, 36291666, 166666, 0xc2, 0x42 },
- { 526000000, 36291666, 166666, 0xc2, 0x84 },
- { 999999999, 36291666, 166666, 0xc2, 0xa4 },
+ { 153000000, 166667, 0xc2, 0x41 },
+ { 470000000, 166667, 0xc2, 0x42 },
+ { 526000000, 166667, 0xc2, 0x84 },
+ { 999999999, 166667, 0xc2, 0xa4 },
},
};
EXPORT_SYMBOL(dvb_pll_env57h1xd5);
@@ -197,20 +206,21 @@ struct dvb_pll_desc dvb_pll_tda665x = {
.min = 44250000,
.max = 858000000,
.setbw = tda665x_bw,
+ .iffreq= 36166667,
.count = 12,
.entries = {
- { 93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
- { 123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
- { 161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
- { 163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
- { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
- { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
- { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
- { 444000000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
- { 583834000, 36249333, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ },
- { 793834000, 36249333, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ },
- { 444834000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
- { 861000000, 36249333, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ },
+ { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
+ { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
+ { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
+ { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
+ { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
+ { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
+ { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
+ { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
+ { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ },
+ { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ },
+ { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
+ { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ },
}
};
EXPORT_SYMBOL(dvb_pll_tda665x);
@@ -228,12 +238,13 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
.name = "Infineon TUA6034",
.min = 44250000,
.max = 858000000,
+ .iffreq= 36166667,
.count = 3,
.setbw = tua6034_bw,
.entries = {
- { 174500000, 36166667, 62500, 0xce, 0x01 },
- { 230000000, 36166667, 62500, 0xce, 0x02 },
- { 999999999, 36166667, 62500, 0xce, 0x04 },
+ { 174500000, 62500, 0xce, 0x01 },
+ { 230000000, 62500, 0xce, 0x02 },
+ { 999999999, 62500, 0xce, 0x04 },
},
};
EXPORT_SYMBOL(dvb_pll_tua6034);
@@ -245,12 +256,13 @@ struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = {
.name = "LG TDVS-H06xF",
.min = 54000000,
.max = 863000000,
+ .iffreq= 44000000,
.initdata = tua603x_agc103,
.count = 3,
.entries = {
- { 165000000, 44000000, 62500, 0xce, 0x01 },
- { 450000000, 44000000, 62500, 0xce, 0x02 },
- { 999999999, 44000000, 62500, 0xce, 0x04 },
+ { 165000000, 62500, 0xce, 0x01 },
+ { 450000000, 62500, 0xce, 0x02 },
+ { 999999999, 62500, 0xce, 0x04 },
},
};
EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf);
@@ -268,16 +280,17 @@ struct dvb_pll_desc dvb_pll_fmd1216me = {
.name = "Philips FMD1216ME",
.min = 50870000,
.max = 858000000,
+ .iffreq= 36125000,
.setbw = fmd1216me_bw,
.count = 7,
.entries = {
- { 143870000, 36213333, 166667, 0xbc, 0x41 },
- { 158870000, 36213333, 166667, 0xf4, 0x41 },
- { 329870000, 36213333, 166667, 0xbc, 0x42 },
- { 441870000, 36213333, 166667, 0xf4, 0x42 },
- { 625870000, 36213333, 166667, 0xbc, 0x44 },
- { 803870000, 36213333, 166667, 0xf4, 0x44 },
- { 999999999, 36213333, 166667, 0xfc, 0x44 },
+ { 143870000, 166667, 0xbc, 0x41 },
+ { 158870000, 166667, 0xf4, 0x41 },
+ { 329870000, 166667, 0xbc, 0x42 },
+ { 441870000, 166667, 0xf4, 0x42 },
+ { 625870000, 166667, 0xbc, 0x44 },
+ { 803870000, 166667, 0xf4, 0x44 },
+ { 999999999, 166667, 0xfc, 0x44 },
}
};
EXPORT_SYMBOL(dvb_pll_fmd1216me);
@@ -295,13 +308,14 @@ struct dvb_pll_desc dvb_pll_tded4 = {
.name = "ALPS TDED4",
.min = 47000000,
.max = 863000000,
+ .iffreq= 36166667,
.setbw = tded4_bw,
.count = 4,
.entries = {
- { 153000000, 36166667, 166667, 0x85, 0x01 },
- { 470000000, 36166667, 166667, 0x85, 0x02 },
- { 823000000, 36166667, 166667, 0x85, 0x08 },
- { 999999999, 36166667, 166667, 0x85, 0x88 },
+ { 153000000, 166667, 0x85, 0x01 },
+ { 470000000, 166667, 0x85, 0x02 },
+ { 823000000, 166667, 0x85, 0x08 },
+ { 999999999, 166667, 0x85, 0x88 },
}
};
EXPORT_SYMBOL(dvb_pll_tded4);
@@ -313,12 +327,13 @@ struct dvb_pll_desc dvb_pll_tdhu2 = {
.name = "ALPS TDHU2",
.min = 54000000,
.max = 864000000,
+ .iffreq= 44000000,
.count = 4,
.entries = {
- { 162000000, 44000000, 62500, 0x85, 0x01 },
- { 426000000, 44000000, 62500, 0x85, 0x02 },
- { 782000000, 44000000, 62500, 0x85, 0x08 },
- { 999999999, 44000000, 62500, 0x85, 0x88 },
+ { 162000000, 62500, 0x85, 0x01 },
+ { 426000000, 62500, 0x85, 0x02 },
+ { 782000000, 62500, 0x85, 0x08 },
+ { 999999999, 62500, 0x85, 0x88 },
}
};
EXPORT_SYMBOL(dvb_pll_tdhu2);
@@ -330,11 +345,12 @@ struct dvb_pll_desc dvb_pll_tuv1236d = {
.name = "Philips TUV1236D",
.min = 54000000,
.max = 864000000,
+ .iffreq= 44000000,
.count = 3,
.entries = {
- { 157250000, 44000000, 62500, 0xc6, 0x41 },
- { 454000000, 44000000, 62500, 0xc6, 0x42 },
- { 999999999, 44000000, 62500, 0xc6, 0x44 },
+ { 157250000, 62500, 0xc6, 0x41 },
+ { 454000000, 62500, 0xc6, 0x42 },
+ { 999999999, 62500, 0xc6, 0x44 },
},
};
EXPORT_SYMBOL(dvb_pll_tuv1236d);
@@ -346,14 +362,15 @@ struct dvb_pll_desc dvb_pll_samsung_tbmv = {
.name = "Samsung TBMV30111IN / TBMV30712IN1",
.min = 54000000,
.max = 860000000,
+ .iffreq= 44000000,
.count = 6,
.entries = {
- { 172000000, 44000000, 166666, 0xb4, 0x01 },
- { 214000000, 44000000, 166666, 0xb4, 0x02 },
- { 467000000, 44000000, 166666, 0xbc, 0x02 },
- { 721000000, 44000000, 166666, 0xbc, 0x08 },
- { 841000000, 44000000, 166666, 0xf4, 0x08 },
- { 999999999, 44000000, 166666, 0xfc, 0x02 },
+ { 172000000, 166667, 0xb4, 0x01 },
+ { 214000000, 166667, 0xb4, 0x02 },
+ { 467000000, 166667, 0xbc, 0x02 },
+ { 721000000, 166667, 0xbc, 0x08 },
+ { 841000000, 166667, 0xf4, 0x08 },
+ { 999999999, 166667, 0xfc, 0x02 },
}
};
EXPORT_SYMBOL(dvb_pll_samsung_tbmv);
@@ -365,12 +382,13 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
.name = "Philips SD1878",
.min = 950000,
.max = 2150000,
+ .iffreq= 249, /* zero-IF, offset 249 is to round up */
.count = 4,
.entries = {
- { 1250000, 499, 500, 0xc4, 0x00},
- { 1550000, 499, 500, 0xc4, 0x40},
- { 2050000, 499, 500, 0xc4, 0x80},
- { 2150000, 499, 500, 0xc4, 0xc0},
+ { 1250000, 500, 0xc4, 0x00},
+ { 1550000, 500, 0xc4, 0x40},
+ { 2050000, 500, 0xc4, 0x80},
+ { 2150000, 500, 0xc4, 0xc0},
},
};
EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261);
@@ -401,18 +419,19 @@ struct dvb_pll_desc dvb_pll_philips_td1316 = {
.name = "Philips TD1316",
.min = 87000000,
.max = 895000000,
+ .iffreq= 36166667,
.setbw = td1316_bw,
.count = 9,
.entries = {
- { 93834000, 36166000, 166666, 0xca, 0x60},
- { 123834000, 36166000, 166666, 0xca, 0xa0},
- { 163834000, 36166000, 166666, 0xca, 0xc0},
- { 253834000, 36166000, 166666, 0xca, 0x60},
- { 383834000, 36166000, 166666, 0xca, 0xa0},
- { 443834000, 36166000, 166666, 0xca, 0xc0},
- { 583834000, 36166000, 166666, 0xca, 0x60},
- { 793834000, 36166000, 166666, 0xca, 0xa0},
- { 858834000, 36166000, 166666, 0xca, 0xe0},
+ { 93834000, 166667, 0xca, 0x60},
+ { 123834000, 166667, 0xca, 0xa0},
+ { 163834000, 166667, 0xca, 0xc0},
+ { 253834000, 166667, 0xca, 0x60},
+ { 383834000, 166667, 0xca, 0xa0},
+ { 443834000, 166667, 0xca, 0xc0},
+ { 583834000, 166667, 0xca, 0x60},
+ { 793834000, 166667, 0xca, 0xa0},
+ { 858834000, 166667, 0xca, 0xe0},
},
};
EXPORT_SYMBOL(dvb_pll_philips_td1316);
@@ -422,15 +441,41 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
.name = "Thomson FE6600",
.min = 44250000,
.max = 858000000,
+ .iffreq= 36125000,
.count = 4,
.entries = {
- { 250000000, 36213333, 166667, 0xb4, 0x12 },
- { 455000000, 36213333, 166667, 0xfe, 0x11 },
- { 775500000, 36213333, 166667, 0xbc, 0x18 },
- { 999999999, 36213333, 166667, 0xf4, 0x18 },
+ { 250000000, 166667, 0xb4, 0x12 },
+ { 455000000, 166667, 0xfe, 0x11 },
+ { 775500000, 166667, 0xbc, 0x18 },
+ { 999999999, 166667, 0xf4, 0x18 },
}
};
EXPORT_SYMBOL(dvb_pll_thomson_fe6600);
+static void opera1_bw(u8 *buf, u32 freq, int bandwidth)
+{
+ if (bandwidth == BANDWIDTH_8_MHZ)
+ buf[2] |= 0x08;
+}
+
+struct dvb_pll_desc dvb_pll_opera1 = {
+ .name = "Opera Tuner",
+ .min = 900000,
+ .max = 2250000,
+ .iffreq= 0,
+ .setbw = opera1_bw,
+ .count = 8,
+ .entries = {
+ { 1064000, 500, 0xe5, 0xc6 },
+ { 1169000, 500, 0xe5, 0xe6 },
+ { 1299000, 500, 0xe5, 0x24 },
+ { 1444000, 500, 0xe5, 0x44 },
+ { 1606000, 500, 0xe5, 0x64 },
+ { 1777000, 500, 0xe5, 0x84 },
+ { 1941000, 500, 0xe5, 0xa4 },
+ { 2250000, 500, 0xe5, 0xc4 },
+ }
+};
+EXPORT_SYMBOL(dvb_pll_opera1);
struct dvb_pll_priv {
/* i2c details */
@@ -472,7 +517,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
if (i == desc->count)
return -EINVAL;
- div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
+ div = (freq + desc->iffreq + desc->entries[i].stepsize/2) /
+ desc->entries[i].stepsize;
buf[0] = div >> 8;
buf[1] = div & 0xff;
buf[2] = desc->entries[i].config;
@@ -486,7 +532,7 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
desc->name, div, buf[0], buf[1], buf[2], buf[3]);
// calculate the frequency we set it to
- return (div * desc->entries[i].stepsize) - desc->entries[i].offset;
+ return (div * desc->entries[i].stepsize) - desc->iffreq;
}
EXPORT_SYMBOL(dvb_pll_configure);
@@ -500,35 +546,27 @@ static int dvb_pll_release(struct dvb_frontend *fe)
static int dvb_pll_sleep(struct dvb_frontend *fe)
{
struct dvb_pll_priv *priv = fe->tuner_priv;
- u8 buf[4];
- struct i2c_msg msg =
- { .addr = priv->pll_i2c_address, .flags = 0,
- .buf = buf, .len = sizeof(buf) };
- int i;
- int result;
if (priv->i2c == NULL)
return -EINVAL;
- for (i = 0; i < priv->pll_desc->count; i++) {
- if (priv->pll_desc->entries[i].limit == 0)
- break;
- }
- if (i == priv->pll_desc->count)
- return 0;
+ if (priv->pll_desc->sleepdata) {
+ struct i2c_msg msg = { .flags = 0,
+ .addr = priv->pll_i2c_address,
+ .buf = priv->pll_desc->sleepdata + 1,
+ .len = priv->pll_desc->sleepdata[0] };
- buf[0] = 0;
- buf[1] = 0;
- buf[2] = priv->pll_desc->entries[i].config;
- buf[3] = priv->pll_desc->entries[i].cb;
+ int result;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
- return result;
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
+ return result;
+ }
+ return 0;
}
-
- return 0;
+ /* Shouldn't be called when initdata is NULL, maybe BUG()? */
+ return -EINVAL;
}
static int dvb_pll_set_params(struct dvb_frontend *fe,
@@ -640,6 +678,7 @@ static int dvb_pll_init(struct dvb_frontend *fe)
static struct dvb_tuner_ops dvb_pll_tuner_ops = {
.release = dvb_pll_release,
.sleep = dvb_pll_sleep,
+ .init = dvb_pll_init,
.set_params = dvb_pll_set_params,
.calc_regs = dvb_pll_calc_regs,
.get_frequency = dvb_pll_get_frequency,
@@ -682,8 +721,10 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
sizeof(fe->ops.tuner_ops.info.name));
fe->ops.tuner_ops.info.frequency_min = desc->min;
fe->ops.tuner_ops.info.frequency_min = desc->max;
- if (desc->initdata)
- fe->ops.tuner_ops.init = dvb_pll_init;
+ if (!desc->initdata)
+ fe->ops.tuner_ops.init = NULL;
+ if (!desc->sleepdata)
+ fe->ops.tuner_ops.sleep = NULL;
fe->tuner_priv = priv;
return fe;
diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.h b/linux/drivers/media/dvb/frontends/dvb-pll.h
index bb79a7815..5209f46f0 100644
--- a/linux/drivers/media/dvb/frontends/dvb-pll.h
+++ b/linux/drivers/media/dvb/frontends/dvb-pll.h
@@ -12,12 +12,13 @@ struct dvb_pll_desc {
char *name;
u32 min;
u32 max;
+ u32 iffreq;
void (*setbw)(u8 *buf, u32 freq, int bandwidth);
u8 *initdata;
+ u8 *sleepdata;
int count;
struct {
u32 limit;
- u32 offset;
u32 stepsize;
u8 config;
u8 cb;
@@ -47,6 +48,7 @@ extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261;
extern struct dvb_pll_desc dvb_pll_philips_td1316;
extern struct dvb_pll_desc dvb_pll_thomson_fe6600;
+extern struct dvb_pll_desc dvb_pll_opera1;
extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
u32 freq, int bandwidth);
diff --git a/linux/drivers/media/dvb/frontends/isl6421.c b/linux/drivers/media/dvb/frontends/isl6421.c
index ef319369e..c967148a5 100644
--- a/linux/drivers/media/dvb/frontends/isl6421.c
+++ b/linux/drivers/media/dvb/frontends/isl6421.c
@@ -122,6 +122,7 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter
/* detect if it is present or not */
if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
kfree(isl6421);
+ fe->sec_priv = NULL;
return NULL;
}
diff --git a/linux/drivers/media/dvb/frontends/lgdt330x.c b/linux/drivers/media/dvb/frontends/lgdt330x.c
index 48ad12c49..706f78b4f 100644
--- a/linux/drivers/media/dvb/frontends/lgdt330x.c
+++ b/linux/drivers/media/dvb/frontends/lgdt330x.c
@@ -481,7 +481,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
*status |= FE_HAS_CARRIER;
break;
default:
- printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
+ printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
}
return 0;
@@ -540,7 +540,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
}
break;
default:
- printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
+ printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
}
return 0;
}
diff --git a/linux/drivers/media/dvb/frontends/nxt200x.c b/linux/drivers/media/dvb/frontends/nxt200x.c
index 87c286ee6..b809f83d9 100644
--- a/linux/drivers/media/dvb/frontends/nxt200x.c
+++ b/linux/drivers/media/dvb/frontends/nxt200x.c
@@ -562,7 +562,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
/* set input */
if (state->config->set_pll_input)
- state->config->set_pll_input(buf, 1);
+ state->config->set_pll_input(buf+1, 1);
break;
case VSB_8:
/* Set non-punctured clock for VSB */
@@ -571,7 +571,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
/* set input */
if (state->config->set_pll_input)
- state->config->set_pll_input(buf, 0);
+ state->config->set_pll_input(buf+1, 0);
break;
default:
return -EINVAL;
diff --git a/linux/drivers/media/dvb/frontends/tda10021.c b/linux/drivers/media/dvb/frontends/tda10021.c
index f34f82fa9..3bc71c601 100644
--- a/linux/drivers/media/dvb/frontends/tda10021.c
+++ b/linux/drivers/media/dvb/frontends/tda10021.c
@@ -30,13 +30,13 @@
#include <linux/slab.h>
#include "dvb_frontend.h"
-#include "tda10021.h"
+#include "tda1002x.h"
struct tda10021_state {
struct i2c_adapter* i2c;
/* configuration settings */
- const struct tda10021_config* config;
+ const struct tda1002x_config* config;
struct dvb_frontend frontend;
u8 pwm;
@@ -53,9 +53,6 @@ struct tda10021_state {
static int verbose;
#define XIN 57840000UL
-#define DISABLE_INVERSION(reg0) do { reg0 |= 0x20; } while (0)
-#define ENABLE_INVERSION(reg0) do { reg0 &= ~0x20; } while (0)
-#define HAS_INVERSION(reg0) (!(reg0 & 0x20))
#define FIN (XIN >> 4)
@@ -64,7 +61,7 @@ static u8 tda10021_inittab[0x40]=
{
0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
- 0xb8, 0x3f, 0xa0, 0x00, 0xcd, 0x01, 0x00, 0xff,
+ 0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff,
0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
@@ -97,7 +94,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
int ret;
ret = i2c_transfer (state->i2c, msg, 2);
- if (ret != 2)
+ // Don't print an error message if the id is read.
+ if (ret != 2 && reg != 0x1a)
printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
__FUNCTION__, ret);
return b1[0];
@@ -136,10 +134,10 @@ static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
{
reg0 |= state->reg0 & 0x63;
- if (INVERSION_ON == inversion)
- ENABLE_INVERSION(reg0);
- else if (INVERSION_OFF == inversion)
- DISABLE_INVERSION(reg0);
+ if ((INVERSION_ON == inversion) ^ (state->config->invert == 0))
+ reg0 &= ~0x20;
+ else
+ reg0 |= 0x20;
_tda10021_writereg (state, 0x00, reg0 & 0xfe);
_tda10021_writereg (state, 0x00, reg0 | 0x01);
@@ -201,16 +199,6 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
return 0;
}
-static int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len)
-{
- struct tda10021_state* state = fe->demodulator_priv;
-
- if (len != 2)
- return -EINVAL;
-
- return _tda10021_writereg(state, buf[0], buf[1]);
-}
-
static int tda10021_init (struct dvb_frontend *fe)
{
struct tda10021_state* state = fe->demodulator_priv;
@@ -258,6 +246,9 @@ static int tda10021_set_parameters (struct dvb_frontend *fe,
if (qam < 0 || qam > 5)
return -EINVAL;
+ if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF)
+ return -EINVAL;
+
//printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
if (fe->ops.tuner_ops.set_params) {
@@ -366,7 +357,7 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
-((s32)p->u.qam.symbol_rate * afc) >> 10);
}
- p->inversion = HAS_INVERSION(state->reg0) ? INVERSION_ON : INVERSION_OFF;
+ p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF;
p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
p->u.qam.fec_inner = FEC_NONE;
@@ -408,11 +399,12 @@ static void tda10021_release(struct dvb_frontend* fe)
static struct dvb_frontend_ops tda10021_ops;
-struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
+struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
struct i2c_adapter* i2c,
u8 pwm)
{
struct tda10021_state* state = NULL;
+ u8 id;
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
@@ -425,7 +417,11 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
state->reg0 = tda10021_inittab[0];
/* check if the demod is there */
- if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
+ id = tda10021_readreg(state, 0x1a);
+ if ((id & 0xf0) != 0x70) goto error;
+
+ printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
+ state->config->demod_address, id);
/* create dvb_frontend */
memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
@@ -461,7 +457,6 @@ static struct dvb_frontend_ops tda10021_ops = {
.init = tda10021_init,
.sleep = tda10021_sleep,
- .write = tda10021_write,
.i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
.set_frontend = tda10021_set_parameters,
diff --git a/linux/drivers/media/dvb/frontends/tda10023.c b/linux/drivers/media/dvb/frontends/tda10023.c
new file mode 100644
index 000000000..5452526ff
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/tda10023.c
@@ -0,0 +1,548 @@
+/*
+ TDA10023 - DVB-C decoder
+ (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card)
+
+ Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de)
+ Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com)
+
+ Remotely based on tda10021.c
+ Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
+ Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
+ Support for TDA10021
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "tda1002x.h"
+
+
+struct tda10023_state {
+ struct i2c_adapter* i2c;
+ /* configuration settings */
+ const struct tda1002x_config* config;
+ struct dvb_frontend frontend;
+
+ u8 pwm;
+ u8 reg0;
+};
+
+
+#if 0
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+static int verbose;
+
+#define XTAL 28920000UL
+#define PLL_M 8UL
+#define PLL_P 4UL
+#define PLL_N 1UL
+#define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000
+
+static u8 tda10023_inittab[]={
+ // reg mask val
+ 0x2a,0xff,0x02, // PLL3, Bypass, Power Down
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0x2a,0xff,0x03, // PLL3, Bypass, Power Down
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0x28,0xff,PLL_M-1, // PLL1 M=8
+ 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2
+ 0x00,0xff,0x23, // GPR FSAMPLING=1
+ 0x2a,0xff,0x08, // PLL3 PSACLK=1
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0x1f,0xff,0x00, // RESET
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0xe6,0x0c,0x04, // RSCFG_IND
+ 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1
+
+ 0x0e,0xff,0x82, // GAIN1
+ 0x03,0x08,0x08, // CLKCONF DYN=1
+ 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0
+ 0x01,0xff,0x30, // AGCREF
+ 0x1e,0x84,0x84, // CONTROL SACLK_ON=1
+ 0x1b,0xff,0xc8, // ADC TWOS=1
+ 0x3b,0xff,0xff, // IFMAX
+ 0x3c,0xff,0x00, // IFMIN
+ 0x34,0xff,0x00, // PWMREF
+ 0x35,0xff,0xff, // TUNMAX
+ 0x36,0xff,0x00, // TUNMIN
+ 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77
+ 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1
+ 0x37,0xff,0xf6, // DELTAF_LSB
+ 0x38,0xff,0xff, // DELTAF_MSB
+ 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3
+ 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2
+ 0x04,0x10,0x00, // SWRAMP=1
+ 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0
+ 0x2b,0x01,0xa1, // INTS1
+ 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=?
+ 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0
+ 0xc4,0xff,0x00,
+ 0xc3,0x30,0x00,
+ 0xb5,0xff,0x19, // ERAGC_THD
+ 0x00,0x03,0x01, // GPR, CLBS soft reset
+ 0x00,0x03,0x03, // GPR, CLBS soft reset
+ 0xff,0x64,0x00, // Sleep 100ms
+ 0xff,0xff,0xff
+};
+
+static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
+{
+ u8 b0 [] = { reg };
+ u8 b1 [] = { 0 };
+ struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+ { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+ int ret;
+
+ ret = i2c_transfer (state->i2c, msg, 2);
+ if (ret != 2)
+ printk("DVB: TDA10023: %s: readreg error (ret == %i)\n",
+ __FUNCTION__, ret);
+ return b1[0];
+}
+
+static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
+{
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+ int ret;
+
+ ret = i2c_transfer (state->i2c, &msg, 1);
+ if (ret != 1)
+ printk("DVB: TDA10023(%d): %s, writereg error "
+ "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
+ state->frontend.dvb->num, __FUNCTION__, reg, data, ret);
+
+ return (ret != 1) ? -EREMOTEIO : 0;
+}
+
+
+static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data)
+{
+ if (mask==0xff)
+ return tda10023_writereg(state, reg, data);
+ else {
+ u8 val;
+ val=tda10023_readreg(state,reg);
+ val&=~mask;
+ val|=(data&mask);
+ return tda10023_writereg(state, reg, val);
+ }
+}
+
+static void tda10023_writetab(struct tda10023_state* state, u8* tab)
+{
+ u8 r,m,v;
+ while (1) {
+ r=*tab++;
+ m=*tab++;
+ v=*tab++;
+ if (r==0xff) {
+ if (m==0xff)
+ break;
+ else
+ msleep(m);
+ }
+ else
+ tda10023_writebit(state,r,m,v);
+ }
+}
+
+//get access to tuner
+static int lock_tuner(struct tda10023_state* state)
+{
+ u8 buf[2] = { 0x0f, 0xc0 };
+ struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
+
+ if(i2c_transfer(state->i2c, &msg, 1) != 1)
+ {
+ printk("tda10023: lock tuner fails\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+//release access from tuner
+static int unlock_tuner(struct tda10023_state* state)
+{
+ u8 buf[2] = { 0x0f, 0x40 };
+ struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
+
+ if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
+ {
+ printk("tda10023: unlock tuner fails\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0)
+{
+ reg0 |= state->reg0 & 0x63;
+
+ tda10023_writereg (state, 0x00, reg0 & 0xfe);
+ tda10023_writereg (state, 0x00, reg0 | 0x01);
+
+ state->reg0 = reg0;
+ return 0;
+}
+
+static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
+{
+ s32 BDR;
+ s32 BDRI;
+ s16 SFIL=0;
+ u16 NDEC = 0;
+
+ if (sr > (SYSCLK/(2*4)))
+ sr=SYSCLK/(2*4);
+
+ if (sr<870000)
+ sr=870000;
+
+ if (sr < (u32)(SYSCLK/98.40)) {
+ NDEC=3;
+ SFIL=1;
+ } else if (sr<(u32)(SYSCLK/64.0)) {
+ NDEC=3;
+ SFIL=0;
+ } else if (sr<(u32)(SYSCLK/49.2)) {
+ NDEC=2;
+ SFIL=1;
+ } else if (sr<(u32)(SYSCLK/32.0)) {
+ NDEC=2;
+ SFIL=0;
+ } else if (sr<(u32)(SYSCLK/24.6)) {
+ NDEC=1;
+ SFIL=1;
+ } else if (sr<(u32)(SYSCLK/16.0)) {
+ NDEC=1;
+ SFIL=0;
+ } else if (sr<(u32)(SYSCLK/12.3)) {
+ NDEC=0;
+ SFIL=1;
+ }
+
+ BDRI=SYSCLK*16;
+ BDRI>>=NDEC;
+ BDRI +=sr/2;
+ BDRI /=sr;
+
+ if (BDRI>255)
+ BDRI=255;
+
+ {
+ u64 BDRX;
+
+ BDRX=1<<(24+NDEC);
+ BDRX*=sr;
+ do_div(BDRX,SYSCLK); // BDRX/=SYSCLK;
+
+ BDR=(s32)BDRX;
+ }
+// printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC);
+ tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
+ tda10023_writereg (state, 0x0a, BDR&255);
+ tda10023_writereg (state, 0x0b, (BDR>>8)&255);
+ tda10023_writereg (state, 0x0c, (BDR>>16)&31);
+ tda10023_writereg (state, 0x0d, BDRI);
+ tda10023_writereg (state, 0x3d, (SFIL<<7));
+ return 0;
+}
+
+static int tda10023_init (struct dvb_frontend *fe)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num);
+
+ tda10023_writetab(state, tda10023_inittab);
+
+ return 0;
+}
+
+static int tda10023_set_parameters (struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ static int qamvals[6][6] = {
+ // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD
+ { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM
+ { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM
+ { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM
+ { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM
+ { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM
+ { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM
+ };
+
+ int qam = p->u.qam.modulation;
+
+ if (qam < 0 || qam > 5)
+ return -EINVAL;
+
+ if (fe->ops.tuner_ops.set_params) {
+ fe->ops.tuner_ops.set_params(fe, p);
+ if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
+ tda10023_set_symbolrate (state, p->u.qam.symbol_rate);
+ tda10023_writereg (state, 0x05, qamvals[qam][1]);
+ tda10023_writereg (state, 0x08, qamvals[qam][2]);
+ tda10023_writereg (state, 0x09, qamvals[qam][3]);
+ tda10023_writereg (state, 0xb4, qamvals[qam][4]);
+ tda10023_writereg (state, 0xb6, qamvals[qam][5]);
+
+// tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32));
+// tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20));
+ tda10023_writebit (state, 0x04, 0x40, 0x40);
+ tda10023_setup_reg0 (state, qamvals[qam][0]);
+
+ return 0;
+}
+
+static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ int sync;
+
+ *status = 0;
+
+ //0x11[1] == CARLOCK -> Carrier locked
+ //0x11[2] == FSYNC -> Frame synchronisation
+ //0x11[3] == FEL -> Front End locked
+ //0x11[6] == NODVB -> DVB Mode Information
+ sync = tda10023_readreg (state, 0x11);
+
+ if (sync & 2)
+ *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
+
+ if (sync & 4)
+ *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
+
+ if (sync & 8)
+ *status |= FE_HAS_LOCK;
+
+ return 0;
+}
+
+static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ u8 a,b,c;
+ a=tda10023_readreg(state, 0x14);
+ b=tda10023_readreg(state, 0x15);
+ c=tda10023_readreg(state, 0x16)&0xf;
+ tda10023_writebit (state, 0x10, 0xc0, 0x00);
+
+ *ber = a | (b<<8)| (c<<16);
+ return 0;
+}
+
+static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ u8 ifgain=tda10023_readreg(state, 0x2f);
+
+ u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16;
+ // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90
+ if (gain>0x90)
+ gain=gain+2*(gain-0x90);
+ if (gain>255)
+ gain=255;
+
+ *strength = (gain<<8)|gain;
+ return 0;
+}
+
+static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ u8 quality = ~tda10023_readreg(state, 0x18);
+ *snr = (quality << 8) | quality;
+ return 0;
+}
+
+static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ u8 a,b,c,d;
+ a= tda10023_readreg (state, 0x74);
+ b= tda10023_readreg (state, 0x75);
+ c= tda10023_readreg (state, 0x76);
+ d= tda10023_readreg (state, 0x77);
+ *ucblocks = a | (b<<8)|(c<<16)|(d<<24);
+
+ tda10023_writebit (state, 0x10, 0x20,0x00);
+ tda10023_writebit (state, 0x10, 0x20,0x20);
+ tda10023_writebit (state, 0x13, 0x01, 0x00);
+
+ return 0;
+}
+
+static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ int sync,inv;
+ s8 afc = 0;
+
+ sync = tda10023_readreg(state, 0x11);
+ afc = tda10023_readreg(state, 0x19);
+ inv = tda10023_readreg(state, 0x04);
+
+ if (verbose) {
+ /* AFC only valid when carrier has been recovered */
+ printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" :
+ "DVB: TDA10023(%d): [AFC (%d) %dHz]\n",
+ state->frontend.dvb->num, afc,
+ -((s32)p->u.qam.symbol_rate * afc) >> 10);
+ }
+
+ p->inversion = (inv&0x20?0:1);
+ p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
+
+ p->u.qam.fec_inner = FEC_NONE;
+ p->frequency = ((p->frequency + 31250) / 62500) * 62500;
+
+ if (sync & 2)
+ p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10;
+
+ return 0;
+}
+
+static int tda10023_sleep(struct dvb_frontend* fe)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ tda10023_writereg (state, 0x1b, 0x02); /* pdown ADC */
+ tda10023_writereg (state, 0x00, 0x80); /* standby */
+
+ return 0;
+}
+
+static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+
+ if (enable) {
+ lock_tuner(state);
+ } else {
+ unlock_tuner(state);
+ }
+ return 0;
+}
+
+static void tda10023_release(struct dvb_frontend* fe)
+{
+ struct tda10023_state* state = fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops tda10023_ops;
+
+struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
+ struct i2c_adapter* i2c,
+ u8 pwm)
+{
+ struct tda10023_state* state = NULL;
+ int i;
+
+ /* allocate memory for the internal state */
+ state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL);
+ if (state == NULL) goto error;
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+ memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
+ state->pwm = pwm;
+ for (i=0; i < sizeof(tda10023_inittab)/sizeof(*tda10023_inittab);i+=3) {
+ if (tda10023_inittab[i] == 0x00) {
+ state->reg0 = tda10023_inittab[i+2];
+ break;
+ }
+ }
+
+ // Wakeup if in standby
+ tda10023_writereg (state, 0x00, 0x33);
+ /* check if the demod is there */
+ if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+
+static struct dvb_frontend_ops tda10023_ops = {
+
+ .info = {
+ .name = "Philips TDA10023 DVB-C",
+ .type = FE_QAM,
+ .frequency_stepsize = 62500,
+ .frequency_min = 51000000,
+ .frequency_max = 858000000,
+ .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */
+ .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */
+ #if 0
+ .frequency_tolerance = ???,
+ .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
+ #endif
+ .caps = 0x400 | //FE_CAN_QAM_4
+ FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_128 | FE_CAN_QAM_256 |
+ FE_CAN_FEC_AUTO
+ },
+
+ .release = tda10023_release,
+
+ .init = tda10023_init,
+ .sleep = tda10023_sleep,
+ .i2c_gate_ctrl = tda10023_i2c_gate_ctrl,
+
+ .set_frontend = tda10023_set_parameters,
+ .get_frontend = tda10023_get_frontend,
+
+ .read_status = tda10023_read_status,
+ .read_ber = tda10023_read_ber,
+ .read_signal_strength = tda10023_read_signal_strength,
+ .read_snr = tda10023_read_snr,
+ .read_ucblocks = tda10023_read_ucblocks,
+};
+
+
+MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver");
+MODULE_AUTHOR("Georg Acher, Hartmut Birr");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(tda10023_attach);
diff --git a/linux/drivers/media/dvb/frontends/tda10021.h b/linux/drivers/media/dvb/frontends/tda1002x.h
index e3da78010..e9094d812 100644
--- a/linux/drivers/media/dvb/frontends/tda10021.h
+++ b/linux/drivers/media/dvb/frontends/tda1002x.h
@@ -1,6 +1,6 @@
/*
- TDA10021 - Single Chip Cable Channel Receiver driver module
- used on the the Siemens DVB-C cards
+ TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module
+ used on the the Siemens DVB-C cards
Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
@@ -21,22 +21,23 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef TDA10021_H
-#define TDA10021_H
+#ifndef TDA1002x_H
+#define TDA1002x_H
#include <linux/dvb/frontend.h>
-struct tda10021_config
+struct tda1002x_config
{
/* the demodulator's i2c address */
u8 demod_address;
+ u8 invert;
};
#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
+extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
struct i2c_adapter* i2c, u8 pwm);
#else
-static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
+static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
struct i2c_adapter* i2c, u8 pwm)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
@@ -44,12 +45,16 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config*
}
#endif // CONFIG_DVB_TDA10021
-static inline int tda10021_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
- int r = 0;
- u8 buf[] = {reg, val};
- if (fe->ops.write)
- r = fe->ops.write(fe, buf, 2);
- return r;
+#if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
+extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
+ struct i2c_adapter* i2c, u8 pwm);
+#else
+static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
+ struct i2c_adapter* i2c, u8 pwm)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
}
+#endif // CONFIG_DVB_TDA10023
-#endif // TDA10021_H
+#endif // TDA1002x_H
diff --git a/linux/drivers/media/dvb/frontends/tda10086.c b/linux/drivers/media/dvb/frontends/tda10086.c
index 4c27a2d90..ccc429cbb 100644
--- a/linux/drivers/media/dvb/frontends/tda10086.c
+++ b/linux/drivers/media/dvb/frontends/tda10086.c
@@ -212,7 +212,7 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
for(i=0; i< cmd->msg_len; i++) {
tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
}
- tda10086_write_byte(state, 0x36, 0x08 | ((cmd->msg_len + 1) << 4));
+ tda10086_write_byte(state, 0x36, 0x08 | ((cmd->msg_len - 1) << 4));
tda10086_diseqc_wait(state);
diff --git a/linux/drivers/media/dvb/frontends/tda827x.c b/linux/drivers/media/dvb/frontends/tda827x.c
index 8176a9b58..256fc4bf5 100644
--- a/linux/drivers/media/dvb/frontends/tda827x.c
+++ b/linux/drivers/media/dvb/frontends/tda827x.c
@@ -91,6 +91,7 @@ static int tda827xo_set_params(struct dvb_frontend *fe,
int i, tuner_freq, if_freq;
u32 N;
+ dprintk("%s:\n", __FUNCTION__);
switch (params->u.ofdm.bandwidth) {
case BANDWIDTH_6_MHZ:
if_freq = 4000000;
@@ -159,6 +160,7 @@ static int tda827xo_sleep(struct dvb_frontend *fe)
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
+ dprintk("%s:\n", __FUNCTION__);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
i2c_transfer(priv->i2c_adap, &msg, 1);
@@ -222,6 +224,7 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
int i, tuner_freq, if_freq;
u32 N;
+ dprintk("%s:\n", __FUNCTION__);
if (priv->cfg && priv->cfg->lna_gain)
priv->cfg->lna_gain(fe, 1);
msleep(20);
@@ -350,6 +353,7 @@ static int tda827xa_sleep(struct dvb_frontend *fe)
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
+ dprintk("%s:\n", __FUNCTION__);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -388,13 +392,32 @@ static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
static int tda827x_init(struct dvb_frontend *fe)
{
struct tda827x_priv *priv = fe->tuner_priv;
-
+ dprintk("%s:\n", __FUNCTION__);
if (priv->cfg && priv->cfg->init)
priv->cfg->init(fe);
return 0;
}
+static int tda827x_probe_version(struct dvb_frontend *fe);
+
+static int tda827x_initial_init(struct dvb_frontend *fe)
+{
+ int ret;
+ ret = tda827x_probe_version(fe);
+ if (ret)
+ return ret;
+ return fe->ops.tuner_ops.init(fe);
+}
+
+static int tda827x_initial_sleep(struct dvb_frontend *fe)
+{
+ int ret;
+ ret = tda827x_probe_version(fe);
+ if (ret)
+ return ret;
+ return fe->ops.tuner_ops.sleep(fe);
+}
static struct dvb_tuner_ops tda827xo_tuner_ops = {
.info = {
@@ -404,8 +427,8 @@ static struct dvb_tuner_ops tda827xo_tuner_ops = {
.frequency_step = 250000
},
.release = tda827x_release,
- .init = tda827x_init,
- .sleep = tda827xo_sleep,
+ .init = tda827x_initial_init,
+ .sleep = tda827x_initial_sleep,
.set_params = tda827xo_set_params,
.get_frequency = tda827x_get_frequency,
.get_bandwidth = tda827x_get_bandwidth,
@@ -426,26 +449,36 @@ static struct dvb_tuner_ops tda827xa_tuner_ops = {
.get_bandwidth = tda827x_get_bandwidth,
};
-struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
- struct i2c_adapter *i2c,
- struct tda827x_config *cfg)
-{
- struct tda827x_priv *priv = NULL;
- u8 data;
- u8 sb_msg[] = { 0x30, 0xd0 };
- struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD,
+static int tda827x_probe_version(struct dvb_frontend *fe)
+{ u8 data;
+ struct tda827x_priv *priv = fe->tuner_priv;
+ struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
.buf = &data, .len = 1 };
- dprintk("%s:\n", __FUNCTION__);
-
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
-
- if (i2c_transfer(i2c, &msg, 1) != 1) {
+ if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
printk("%s: could not read from tuner at addr: 0x%02x\n",
- __FUNCTION__, addr << 1);
- return NULL;
+ __FUNCTION__, msg.addr << 1);
+ return -EIO;
+ }
+ if ((data & 0x3c) == 0) {
+ dprintk("tda827x tuner found\n");
+ fe->ops.tuner_ops.init = tda827x_init;
+ fe->ops.tuner_ops.sleep = tda827xo_sleep;
+ } else {
+ dprintk("tda827xa tuner found\n");
+ memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
}
+ return 0;
+}
+
+struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
+ struct i2c_adapter *i2c,
+ struct tda827x_config *cfg)
+{
+ struct tda827x_priv *priv = NULL;
+ dprintk("%s:\n", __FUNCTION__);
priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
if (priv == NULL)
return NULL;
@@ -453,25 +486,13 @@ struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
priv->i2c_addr = addr;
priv->i2c_adap = i2c;
priv->cfg = cfg;
+ memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
- msg.flags = 0;
- msg.buf = sb_msg;
- msg.len = sizeof(sb_msg);
-
- if ((data & 0x3c) == 0) {
- dprintk("tda827x tuner found\n");
- memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
- } else {
- dprintk("tda827xa tuner found\n");
- memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
- sb_msg[1] = 0x90;
- }
fe->tuner_priv = priv;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(i2c, &msg, 1);
+
return fe;
}
+
EXPORT_SYMBOL(tda827x_attach);
module_param(debug, int, 0644);
diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c
index cb049d1a8..b104e63eb 100644
--- a/linux/drivers/media/dvb/pluto2/pluto2.c
+++ b/linux/drivers/media/dvb/pluto2/pluto2.c
@@ -149,6 +149,15 @@ static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits)
writel(val, &pluto->io_mem[reg]);
}
+static void pluto_write_tscr(struct pluto *pluto, u32 val)
+{
+ /* set the number of packets */
+ val &= ~TSCR_ADEF;
+ val |= TS_DMA_PACKETS / 2;
+
+ pluto_writereg(pluto, REG_TSCR, val);
+}
+
static void pluto_setsda(void *data, int state)
{
struct pluto *pluto = data;
@@ -213,11 +222,11 @@ static void pluto_reset_ts(struct pluto *pluto, int reenable)
if (val & TSCR_RSTN) {
val &= ~TSCR_RSTN;
- pluto_writereg(pluto, REG_TSCR, val);
+ pluto_write_tscr(pluto, val);
}
if (reenable) {
val |= TSCR_RSTN;
- pluto_writereg(pluto, REG_TSCR, val);
+ pluto_write_tscr(pluto, val);
}
}
@@ -284,12 +293,20 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
* but no packets have been transfered.
* [2] Sometimes (actually very often) NBPACKETS stays at zero
* although one packet has been transfered.
+ * [3] Sometimes (actually rarely), the card gets into an erroneous
+ * mode where it continuously generates interrupts, claiming it
+ * has recieved nbpackets>TS_DMA_PACKETS packets, but no packet
+ * has been transfered. Only a reset seems to solve this
*/
if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
unsigned int i = 0;
while (pluto->dma_buf[i] == 0x47)
i += 188;
nbpackets = i / 188;
+ if (i == 0) {
+ pluto_reset_ts(pluto, 1);
+ dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n");
+ }
}
dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
@@ -343,7 +360,7 @@ static irqreturn_t pluto_irq(int irq, void *dev_id)
}
/* ACK the interrupt */
- pluto_writereg(pluto, REG_TSCR, tscr | TSCR_IACK);
+ pluto_write_tscr(pluto, tscr | TSCR_IACK);
return IRQ_HANDLED;
}
@@ -352,9 +369,6 @@ static void __devinit pluto_enable_irqs(struct pluto *pluto)
{
u32 val = pluto_readreg(pluto, REG_TSCR);
- /* set the number of packets */
- val &= ~TSCR_ADEF;
- val |= TS_DMA_PACKETS / 2;
/* disable AFUL and LOCK interrupts */
val |= (TSCR_MSKA | TSCR_MSKL);
/* enable DMA and OVERFLOW interrupts */
@@ -362,7 +376,7 @@ static void __devinit pluto_enable_irqs(struct pluto *pluto)
/* clear pending interrupts */
val |= TSCR_IACK;
- pluto_writereg(pluto, REG_TSCR, val);
+ pluto_write_tscr(pluto, val);
}
static void pluto_disable_irqs(struct pluto *pluto)
@@ -374,7 +388,7 @@ static void pluto_disable_irqs(struct pluto *pluto)
/* clear pending interrupts */
val |= TSCR_IACK;
- pluto_writereg(pluto, REG_TSCR, val);
+ pluto_write_tscr(pluto, val);
}
static int __devinit pluto_hw_init(struct pluto *pluto)
diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig
index 3cd319ff0..7751628e1 100644
--- a/linux/drivers/media/dvb/ttpci/Kconfig
+++ b/linux/drivers/media/dvb/ttpci/Kconfig
@@ -67,6 +67,7 @@ config DVB_BUDGET
select DVB_L64781 if !DVB_FE_CUSTOMISE
select DVB_TDA8083 if !DVB_FE_CUSTOMISE
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select DVB_S5H1420 if !DVB_FE_CUSTOMISE
select DVB_TDA10086 if !DVB_FE_CUSTOMISE
select DVB_TDA826X if !DVB_FE_CUSTOMISE
@@ -111,6 +112,7 @@ config DVB_BUDGET_AV
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select DVB_TUA6100 if !DVB_FE_CUSTOMISE
select FW_LOADER
help
diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c
index 77ccd99ad..3b31c294d 100644
--- a/linux/drivers/media/dvb/ttpci/av7110.c
+++ b/linux/drivers/media/dvb/ttpci/av7110.c
@@ -1246,6 +1246,9 @@ static void vpeirq(unsigned long data)
if (!budget->feeding1 || (newdma == olddma))
return;
+ /* Ensure streamed PCI data is synced to CPU */
+ pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
#if 0 /* keep */
/* track rps1 activity */
printk("vpeirq: %02x Event Counter 1 0x%04x\n",
@@ -2679,8 +2682,8 @@ err_iobuf_vfree_6:
err_pci_free_5:
pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
err_saa71466_vfree_4:
- if (!av7110->grabbing)
- saa7146_pgtable_free(pdev, &av7110->pt);
+ if (av7110->grabbing)
+ saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt);
err_i2c_del_3:
i2c_del_adapter(&av7110->i2c_adap);
err_dvb_unregister_adapter_2:
@@ -2710,7 +2713,7 @@ static int __devexit av7110_detach(struct saa7146_dev* saa)
SAA7146_ISR_CLEAR(saa, MASK_10);
msleep(50);
tasklet_kill(&av7110->vpe_tasklet);
- saa7146_pgtable_free(saa->pci, &av7110->pt);
+ saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt);
}
av7110_exit_v4l(av7110);
diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c
index 3035b224c..0e817d6f1 100644
--- a/linux/drivers/media/dvb/ttpci/budget-av.c
+++ b/linux/drivers/media/dvb/ttpci/budget-av.c
@@ -35,7 +35,7 @@
#include "budget.h"
#include "stv0299.h"
-#include "tda10021.h"
+#include "tda1002x.h"
#include "tda1004x.h"
#include "tua6100.h"
#include "dvb-pll.h"
@@ -66,9 +66,6 @@ struct budget_av {
int slot_status;
struct dvb_ca_en50221 ca;
u8 reinitialise_demod:1;
- u8 tda10021_poclkp:1;
- u8 tda10021_ts_enabled;
- int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
};
static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
@@ -234,12 +231,6 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
if (budget_av->reinitialise_demod)
dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
- /* set tda10021 back to original clock configuration on reset */
- if (budget_av->tda10021_poclkp) {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
- budget_av->tda10021_ts_enabled = 0;
- }
-
return 0;
}
@@ -256,11 +247,6 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
budget_av->slot_status = SLOTSTATUS_NONE;
- /* set tda10021 back to original clock configuration when cam removed */
- if (budget_av->tda10021_poclkp) {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
- budget_av->tda10021_ts_enabled = 0;
- }
return 0;
}
@@ -276,12 +262,6 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
- /* tda10021 seems to need a different TS clock config when data is routed to the CAM */
- if (budget_av->tda10021_poclkp) {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
- budget_av->tda10021_ts_enabled = 1;
- }
-
return 0;
}
@@ -631,37 +611,62 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = {
static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
{
struct budget *budget = (struct budget *) fe->dvb->priv;
- u8 buf[4];
+ u8 buf[6];
struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
+ int i;
+#define CU1216_IF 36125000
#define TUNER_MUL 62500
- u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
+ u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
buf[0] = (div >> 8) & 0x7f;
buf[1] = div & 0xff;
- buf[2] = 0x86;
+ buf[2] = 0xce;
buf[3] = (params->frequency < 150000000 ? 0x01 :
params->frequency < 445000000 ? 0x02 : 0x04);
+ buf[4] = 0xde;
+ buf[5] = 0x20;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
+ return -EIO;
+ /* wait for the pll lock */
+ msg.flags = I2C_M_RD;
+ msg.len = 1;
+ for (i = 0; i < 20; i++) {
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
+ break;
+ msleep(10);
+ }
+
+ /* switch the charge pump to the lower current */
+ msg.flags = 0;
+ msg.len = 2;
+ msg.buf = &buf[2];
+ buf[2] &= ~0x40;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
return -EIO;
+
return 0;
}
-static struct tda10021_config philips_cu1216_config = {
+static struct tda1002x_config philips_cu1216_config = {
.demod_address = 0x0c,
+ .invert = 1,
};
-static struct tda10021_config philips_cu1216_config_altaddress = {
+static struct tda1002x_config philips_cu1216_config_altaddress = {
.demod_address = 0x0d,
+ .invert = 0,
};
-
-
-
static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
{
struct budget *budget = (struct budget *) fe->dvb->priv;
@@ -908,41 +913,28 @@ static u8 read_pwm(struct budget_av *budget_av)
return pwm;
}
-#define SUBID_DVBS_KNC1 0x0010
-#define SUBID_DVBS_KNC1_PLUS 0x0011
-#define SUBID_DVBS_TYPHOON 0x4f56
-#define SUBID_DVBS_CINERGY1200 0x1154
-#define SUBID_DVBS_CYNERGY1200N 0x1155
-
-#define SUBID_DVBS_TV_STAR 0x0014
-#define SUBID_DVBS_TV_STAR_CI 0x0016
-#define SUBID_DVBS_EASYWATCH_1 0x001a
-#define SUBID_DVBS_EASYWATCH 0x001e
-#define SUBID_DVBC_EASYWATCH 0x002a
-#define SUBID_DVBC_KNC1 0x0020
-#define SUBID_DVBC_KNC1_PLUS 0x0021
-#define SUBID_DVBC_CINERGY1200 0x1156
-
-#define SUBID_DVBT_KNC1_PLUS 0x0031
-#define SUBID_DVBT_KNC1 0x0030
-#define SUBID_DVBT_CINERGY1200 0x1157
-
-
-static int tda10021_set_frontend(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *p)
-{
- struct budget_av* budget_av = fe->dvb->priv;
- int result;
-
- result = budget_av->tda10021_set_frontend(fe, p);
- if (budget_av->tda10021_ts_enabled) {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
- } else {
- tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
- }
-
- return result;
-}
+#define SUBID_DVBS_KNC1 0x0010
+#define SUBID_DVBS_KNC1_PLUS 0x0011
+#define SUBID_DVBS_TYPHOON 0x4f56
+#define SUBID_DVBS_CINERGY1200 0x1154
+#define SUBID_DVBS_CYNERGY1200N 0x1155
+#define SUBID_DVBS_TV_STAR 0x0014
+#define SUBID_DVBS_TV_STAR_CI 0x0016
+#define SUBID_DVBS_EASYWATCH_1 0x001a
+#define SUBID_DVBS_EASYWATCH 0x001e
+
+#define SUBID_DVBC_EASYWATCH 0x002a
+#define SUBID_DVBC_EASYWATCH_MK3 0x002c
+#define SUBID_DVBC_KNC1 0x0020
+#define SUBID_DVBC_KNC1_PLUS 0x0021
+#define SUBID_DVBC_KNC1_MK3 0x0022
+#define SUBID_DVBC_KNC1_PLUS_MK3 0x0023
+#define SUBID_DVBC_CINERGY1200 0x1156
+#define SUBID_DVBC_CINERGY1200_MK3 0x1176
+
+#define SUBID_DVBT_KNC1_PLUS 0x0031
+#define SUBID_DVBT_KNC1 0x0030
+#define SUBID_DVBT_CINERGY1200 0x1157
static void frontend_init(struct budget_av *budget_av)
{
@@ -961,6 +953,7 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBC_KNC1_PLUS:
case SUBID_DVBT_KNC1_PLUS:
case SUBID_DVBC_EASYWATCH:
+ case SUBID_DVBC_KNC1_PLUS_MK3:
saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
break;
}
@@ -1017,6 +1010,7 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBC_CINERGY1200:
case SUBID_DVBC_EASYWATCH:
budget_av->reinitialise_demod = 1;
+ budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
&budget_av->budget.i2c_adap,
read_pwm(budget_av));
@@ -1025,9 +1019,20 @@ static void frontend_init(struct budget_av *budget_av)
&budget_av->budget.i2c_adap,
read_pwm(budget_av));
if (fe) {
- budget_av->tda10021_poclkp = 1;
- budget_av->tda10021_set_frontend = fe->ops.set_frontend;
- fe->ops.set_frontend = tda10021_set_frontend;
+ fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
+ }
+ break;
+
+ case SUBID_DVBC_EASYWATCH_MK3:
+ case SUBID_DVBC_CINERGY1200_MK3:
+ case SUBID_DVBC_KNC1_MK3:
+ case SUBID_DVBC_KNC1_PLUS_MK3:
+ budget_av->reinitialise_demod = 1;
+ budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
+ fe = dvb_attach(tda10023_attach, &philips_cu1216_config,
+ &budget_av->budget.i2c_adap,
+ read_pwm(budget_av));
+ if (fe) {
fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
}
break;
@@ -1260,12 +1265,16 @@ MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
+MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
+MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
+MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
+MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
static struct pci_device_id pci_tbl[] = {
@@ -1279,13 +1288,17 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
+ MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
+ MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
+ MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
+ MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
{
.vendor = 0,
diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c
index 0152eff90..302c5a786 100644
--- a/linux/drivers/media/dvb/ttpci/budget-ci.c
+++ b/linux/drivers/media/dvb/ttpci/budget-ci.c
@@ -910,7 +910,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc
band = 1;
} else if (tuner_frequency < 200000000) {
cp = 6;
- band = 2;
+ band = 1;
} else if (tuner_frequency < 290000000) {
cp = 3;
band = 2;
diff --git a/linux/drivers/media/dvb/ttpci/budget-core.c b/linux/drivers/media/dvb/ttpci/budget-core.c
index e15562f81..2557ac962 100644
--- a/linux/drivers/media/dvb/ttpci/budget-core.c
+++ b/linux/drivers/media/dvb/ttpci/budget-core.c
@@ -41,11 +41,14 @@
#define TS_WIDTH (2 * TS_SIZE)
#define TS_WIDTH_ACTIVY TS_SIZE
+#define TS_WIDTH_DVBC TS_SIZE
#define TS_HEIGHT_MASK 0xf00
#define TS_HEIGHT_MASK_ACTIVY 0xc00
+#define TS_HEIGHT_MASK_DVBC 0xe00
#define TS_MIN_BUFSIZE_K 188
#define TS_MAX_BUFSIZE_K 1410
#define TS_MAX_BUFSIZE_K_ACTIVY 564
+#define TS_MAX_BUFSIZE_K_DVBC 1316
#define BUFFER_WARNING_WAIT (30*HZ)
int budget_debug;
@@ -106,6 +109,19 @@ static int start_ts_capture(struct budget *budget)
saa7146_write(dev, MC2, (MASK_10 | MASK_26));
saa7146_write(dev, BRS_CTRL, 0x60000000);
break;
+ case BUDGET_CIN1200C_MK3:
+ case BUDGET_KNC1C_MK3:
+ case BUDGET_KNC1CP_MK3:
+ if (budget->video_port == BUDGET_VIDEO_PORTA) {
+ saa7146_write(dev, DD1_INIT, 0x06000200);
+ saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+ saa7146_write(dev, BRS_CTRL, 0x00000000);
+ } else {
+ saa7146_write(dev, DD1_INIT, 0x00000600);
+ saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+ saa7146_write(dev, BRS_CTRL, 0x60000000);
+ }
+ break;
default:
if (budget->video_port == BUDGET_VIDEO_PORTA) {
saa7146_write(dev, DD1_INIT, 0x06000200);
@@ -122,7 +138,13 @@ static int start_ts_capture(struct budget *budget)
mdelay(10);
saa7146_write(dev, BASE_ODD3, 0);
- saa7146_write(dev, BASE_EVEN3, 0);
+ if (budget->buffer_size > budget->buffer_height * budget->buffer_width) {
+ // using odd/even buffers
+ saa7146_write(dev, BASE_EVEN3, budget->buffer_height * budget->buffer_width);
+ } else {
+ // using a single buffer
+ saa7146_write(dev, BASE_EVEN3, 0);
+ }
saa7146_write(dev, PROT_ADDR3, budget->buffer_size);
saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90);
@@ -173,6 +195,9 @@ static void vpeirq(unsigned long data)
u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
u32 count;
+ /* Ensure streamed PCI data is synced to CPU */
+ pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
/* nearest lower position divisible by 188 */
newdma -= newdma % 188;
@@ -399,11 +424,25 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
budget->card = bi;
budget->dev = (struct saa7146_dev *) dev;
- if (budget->card->type == BUDGET_FS_ACTIVY) {
+ switch(budget->card->type) {
+ case BUDGET_FS_ACTIVY:
budget->buffer_width = TS_WIDTH_ACTIVY;
max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY;
height_mask = TS_HEIGHT_MASK_ACTIVY;
- } else {
+ break;
+
+ case BUDGET_KNC1C:
+ case BUDGET_KNC1CP:
+ case BUDGET_CIN1200C:
+ case BUDGET_KNC1C_MK3:
+ case BUDGET_KNC1CP_MK3:
+ case BUDGET_CIN1200C_MK3:
+ budget->buffer_width = TS_WIDTH_DVBC;
+ max_bufsize = TS_MAX_BUFSIZE_K_DVBC;
+ height_mask = TS_HEIGHT_MASK_DVBC;
+ break;
+
+ default:
budget->buffer_width = TS_WIDTH;
max_bufsize = TS_MAX_BUFSIZE_K;
height_mask = TS_HEIGHT_MASK;
@@ -415,14 +454,22 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
dma_buffer_size = max_bufsize;
budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width;
- budget->buffer_height &= height_mask;
- budget->buffer_size = budget->buffer_height * budget->buffer_width;
+ if (budget->buffer_height > 0xfff) {
+ budget->buffer_height /= 2;
+ budget->buffer_height &= height_mask;
+ budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width;
+ } else {
+ budget->buffer_height &= height_mask;
+ budget->buffer_size = budget->buffer_height * budget->buffer_width;
+ }
budget->buffer_warning_threshold = budget->buffer_size * 80/100;
budget->buffer_warnings = 0;
budget->buffer_warning_time = jiffies;
- dprintk(2, "%s: width = %d, height = %d\n",
- budget->dev->name, budget->buffer_width, budget->buffer_height);
+ dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n",
+ budget->dev->name,
+ budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single",
+ budget->buffer_width, budget->buffer_height);
printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size);
if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) {
@@ -460,16 +507,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
strcpy(budget->i2c_adap.name, budget->card->name);
if (i2c_add_adapter(&budget->i2c_adap) < 0) {
- dvb_unregister_adapter(&budget->dvb_adapter);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_dvb_unregister;
}
ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);
- if (NULL ==
- (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt))) {
+ budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt);
+ if (NULL == budget->grabbing) {
ret = -ENOMEM;
- goto err;
+ goto err_del_i2c;
}
saa7146_write(dev, PCI_BT_V1, 0x001c0000);
@@ -482,14 +529,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
if (bi->type != BUDGET_FS_ACTIVY)
saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
- if (budget_register(budget) == 0) {
- return 0;
- }
-err:
- i2c_del_adapter(&budget->i2c_adap);
+ if (budget_register(budget) == 0)
+ return 0; /* Everything OK */
- vfree(budget->grabbing);
+ /* An error occurred, cleanup resources */
+ saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
+err_del_i2c:
+ i2c_del_adapter(&budget->i2c_adap);
+
+err_dvb_unregister:
dvb_unregister_adapter(&budget->dvb_adapter);
return ret;
@@ -511,15 +560,13 @@ int ttpci_budget_deinit(struct budget *budget)
budget_unregister(budget);
- i2c_del_adapter(&budget->i2c_adap);
-
- dvb_unregister_adapter(&budget->dvb_adapter);
-
tasklet_kill(&budget->vpe_tasklet);
- saa7146_pgtable_free(dev->pci, &budget->pt);
+ saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
+
+ i2c_del_adapter(&budget->i2c_adap);
- vfree(budget->grabbing);
+ dvb_unregister_adapter(&budget->dvb_adapter);
return 0;
}
diff --git a/linux/drivers/media/dvb/ttpci/budget.h b/linux/drivers/media/dvb/ttpci/budget.h
index 8a20d59b7..94922db7a 100644
--- a/linux/drivers/media/dvb/ttpci/budget.h
+++ b/linux/drivers/media/dvb/ttpci/budget.h
@@ -107,6 +107,9 @@ static struct saa7146_pci_extension_data x_var = { \
#define BUDGET_KNC1CP 12
#define BUDGET_KNC1TP 13
#define BUDGET_TVSTAR 14
+#define BUDGET_CIN1200C_MK3 15
+#define BUDGET_KNC1C_MK3 16
+#define BUDGET_KNC1CP_MK3 17
#define BUDGET_VIDEO_PORTA 0
#define BUDGET_VIDEO_PORTB 1
diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig
index 4ab38a851..fe881407f 100644
--- a/linux/drivers/media/radio/Kconfig
+++ b/linux/drivers/media/radio/Kconfig
@@ -2,8 +2,14 @@
# Multimedia Video device configuration
#
-menu "Radio Adapters"
+menuconfig RADIO_ADAPTERS
+ bool "Radio Adapters"
depends on VIDEO_DEV
+ default y
+ ---help---
+ Say Y here to enable selecting AM/FM radio adapters.
+
+if RADIO_ADAPTERS
config RADIO_CADET
tristate "ADS Cadet AM/FM Tuner"
@@ -360,4 +366,5 @@ config USB_DSBR
To compile this driver as a module, choose M here: the
module will be called dsbr100.
-endmenu
+
+endif # RADIO_ADAPTERS
diff --git a/linux/drivers/media/radio/radio-aimslab.c b/linux/drivers/media/radio/radio-aimslab.c
index 2ec2b1401..920f097fb 100644
--- a/linux/drivers/media/radio/radio-aimslab.c
+++ b/linux/drivers/media/radio/radio-aimslab.c
@@ -236,129 +236,149 @@ static struct v4l2_queryctrl radio_qctrl[] = {
}
};
-static int rt_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-aimslab", sizeof(v->driver));
+ strlcpy(v->card, "RadioTrack", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
- struct rt_device *rt=dev->priv;
+ struct rt_device *rt = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-aimslab", sizeof (v->driver));
- strlcpy(v->card, "RadioTrack", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xffff*rt_getsigstr(rt);
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+ rt->curfreq = f->frequency;
+ rt_setfreq(rt, rt->curfreq);
+ return 0;
+}
- v->rangelow=(87*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*rt_getsigstr(rt);
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = rt->curfreq;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- rt->curfreq = f->frequency;
- rt_setfreq(rt, rt->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = rt->curfreq;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = rt->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = rt->curvol * 6554;
+ return 0;
+ }
+ return -EINVAL;
+}
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=rt->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=rt->curvol * 6554;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- rt_mute(rt);
- } else {
- rt_setvol(rt,rt->curvol);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- rt_setvol(rt,ctrl->value);
- return (0);
- }
- return -EINVAL;
- }
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- rt_do_ioctl);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ rt_mute(rt);
+ else
+ rt_setvol(rt,rt->curvol);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ rt_setvol(rt,ctrl->value);
+ return 0;
}
+ return -EINVAL;
+}
+
+static int vidioc_g_audio (struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
}
-static int rt_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, rt_do_ioctl);
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct rt_device rtrack_unit;
@@ -367,7 +387,7 @@ static const struct file_operations rtrack_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = rt_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -379,6 +399,18 @@ static struct video_device rtrack_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &rtrack_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __init rtrack_init(void)
diff --git a/linux/drivers/media/radio/radio-gemtek-pci.c b/linux/drivers/media/radio/radio-gemtek-pci.c
index 98c0da421..09cb193e0 100644
--- a/linux/drivers/media/radio/radio-gemtek-pci.c
+++ b/linux/drivers/media/radio/radio-gemtek-pci.c
@@ -193,131 +193,158 @@ static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card )
return ( inb( card->iobase ) & 0x08 ) ? 0 : 1;
}
-static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));
+ strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
struct gemtek_pci_card *card = dev->priv;
- switch ( cmd ) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-gemtek-pci", sizeof (v->driver));
- strlcpy(v->card, "GemTek PCI Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
-
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ if (v->index > 0)
+ return -EINVAL;
+
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = GEMTEK_PCI_RANGE_LOW;
+ v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xffff * gemtek_pci_getsignal(card);
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_pci_card *card = dev->priv;
- v->rangelow = GEMTEK_PCI_RANGE_LOW;
- v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*gemtek_pci_getsignal( card );
+ if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
+ (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
+ return -EINVAL;
+ gemtek_pci_setfrequency(card, f->frequency);
+ card->current_frequency = f->frequency;
+ card->mute = false;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_pci_card *card = dev->priv;
- if (v->index > 0)
- return -EINVAL;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = card->current_frequency;
+ return 0;
+}
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
- (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
- return -EINVAL;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_pci_card *card = dev->priv;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = card->mute;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (card->mute)
+ ctrl->value = 0;
+ else
+ ctrl->value = 65535;
+ return 0;
+ }
+ return -EINVAL;
+}
- gemtek_pci_setfrequency( card, f->frequency );
- card->current_frequency = f->frequency;
- card->mute = false;
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=card->mute;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (card->mute)
- ctrl->value=0;
- else
- ctrl->value=65535;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- gemtek_pci_mute(card);
- } else {
- gemtek_pci_unmute(card);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value) {
- gemtek_pci_unmute(card);
- } else {
- gemtek_pci_mute(card);
- }
- return (0);
- }
- return -EINVAL;
- }
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- gemtek_pci_do_ioctl);
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_pci_card *card = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ gemtek_pci_mute(card);
+ else
+ gemtek_pci_unmute(card);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->value)
+ gemtek_pci_unmute(card);
+ else
+ gemtek_pci_mute(card);
+ return 0;
}
+ return -EINVAL;
}
-static int gemtek_pci_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, gemtek_pci_do_ioctl);
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
enum {
@@ -343,7 +370,7 @@ static const struct file_operations gemtek_pci_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = gemtek_pci_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -354,6 +381,18 @@ static struct video_device vdev_template = {
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &gemtek_pci_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
diff --git a/linux/drivers/media/radio/radio-gemtek.c b/linux/drivers/media/radio/radio-gemtek.c
index 7b09b4f2a..f44a213a9 100644
--- a/linux/drivers/media/radio/radio-gemtek.c
+++ b/linux/drivers/media/radio/radio-gemtek.c
@@ -162,137 +162,157 @@ static int gemtek_getsigstr(struct gemtek_device *dev)
return 1; /* signal present */
}
-static int gemtek_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-gemtek", sizeof(v->driver));
+ strlcpy(v->card, "GemTek", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
- struct gemtek_device *rt=dev->priv;
+ struct gemtek_device *rt = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-gemtek", sizeof (v->driver));
- strlcpy(v->card, "GemTek", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xffff*gemtek_getsigstr(rt);
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_device *rt = dev->priv;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+ rt->curfreq = f->frequency;
+ /* needs to be called twice in order for getsigstr to work */
+ gemtek_setfreq(rt, rt->curfreq);
+ gemtek_setfreq(rt, rt->curfreq);
+ return 0;
+}
- v->rangelow=(87*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*gemtek_getsigstr(rt);
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_device *rt = dev->priv;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = rt->curfreq;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
-
- rt->curfreq = f->frequency;
- /* needs to be called twice in order for getsigstr to work */
- gemtek_setfreq(rt, rt->curfreq);
- gemtek_setfreq(rt, rt->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = rt->curfreq;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_device *rt = dev->priv;
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=rt->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (rt->muted)
- ctrl->value=0;
- else
- ctrl->value=65535;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- gemtek_mute(rt);
- } else {
- gemtek_unmute(rt);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value) {
- gemtek_unmute(rt);
- } else {
- gemtek_mute(rt);
- }
- return (0);
- }
- return -EINVAL;
- }
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- gemtek_do_ioctl);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = rt->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (rt->muted)
+ ctrl->value = 0;
+ else
+ ctrl->value = 65535;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct gemtek_device *rt = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ gemtek_mute(rt);
+ else
+ gemtek_unmute(rt);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->value)
+ gemtek_unmute(rt);
+ else
+ gemtek_mute(rt);
+ return 0;
}
+ return -EINVAL;
}
-static int gemtek_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_g_audio (struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, gemtek_do_ioctl);
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct gemtek_device gemtek_unit;
@@ -301,7 +321,7 @@ static const struct file_operations gemtek_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = gemtek_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -313,6 +333,18 @@ static struct video_device gemtek_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &gemtek_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __init gemtek_init(void)
diff --git a/linux/drivers/media/radio/radio-maestro.c b/linux/drivers/media/radio/radio-maestro.c
index ffecdcdea..792116a91 100644
--- a/linux/drivers/media/radio/radio-maestro.c
+++ b/linux/drivers/media/radio/radio-maestro.c
@@ -78,8 +78,6 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int radio_nr = -1;
module_param(radio_nr, int, 0);
-static int radio_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void maestro_remove(struct pci_dev *pdev);
@@ -105,18 +103,11 @@ static const struct file_operations maestro_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = radio_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
-static struct video_device maestro_radio = {
- .name = "Maestro radio",
- .type = VID_TYPE_TUNER,
- .hardware = 0,
- .fops = &maestro_fops,
-};
-
struct radio_device {
u16 io, /* base of Maestro card radio io (GPIO_DATA)*/
muted, /* VIDEO_AUDIO_MUTE */
@@ -197,153 +188,153 @@ static void radio_bits_set(struct radio_device *dev, u32 data)
msleep(125);
}
-static inline int radio_function(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
+ strlcpy(v->card, "Maestro Radio", sizeof(v->card));
+ sprintf(v->bus_info, "PCI");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
struct radio_device *card = video_get_drvdata(dev);
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-maestro", sizeof (v->driver));
- strlcpy(v->card, "Maestro Radio", sizeof (v->card));
- sprintf(v->bus_info,"PCI");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
-
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
-
- if (v->index > 0)
- return -EINVAL;
-
- (void)radio_bits_get(card);
+ if (v->index > 0)
+ return -EINVAL;
+
+ (void)radio_bits_get(card);
+
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = FREQ_LO;
+ v->rangehigh = FREQ_HI;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if(card->stereo)
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = card->tuned;
+ return 0;
+}
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- v->rangelow = FREQ_LO;
- v->rangehigh = FREQ_HI;
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(card->stereo)
- v->audmode = V4L2_TUNER_MODE_STEREO;
- else
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=card->tuned;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct radio_device *card = video_get_drvdata(dev);
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
+ return -EINVAL;
+ radio_bits_set(card, FREQ2BITS(f->frequency));
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct radio_device *card = video_get_drvdata(dev);
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = BITS2FREQ(radio_bits_get(card));
+ return 0;
+}
- if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
- return -EINVAL;
- radio_bits_set(card, FREQ2BITS(f->frequency));
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = BITS2FREQ(radio_bits_get(card));
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct radio_device *card = video_get_drvdata(dev);
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=card->muted;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- {
- register u16 io = card->io;
- register u16 omask = inw(io + IO_MASK);
- outw(~STR_WREN, io + IO_MASK);
- outw((card->muted = ctrl->value ) ?
- STR_WREN : 0, io);
- udelay(4);
- outw(omask, io + IO_MASK);
- msleep(125);
-
- return (0);
- }
- }
- return -EINVAL;
- }
-#if 0 /* Probably, this is useless */
- case VIDIOCGUNIT: {
- struct video_unit *v = arg;
- v->video = VIDEO_NO_UNIT;
- v->vbi = VIDEO_NO_UNIT;
- v->radio = dev->minor;
- v->audio = 0;
- v->teletext = VIDEO_NO_UNIT;
- return 0;
- }
-#endif
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- radio_function);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = card->muted;
+ return 0;
}
+ return -EINVAL;
}
-static int radio_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
{
struct video_device *dev = video_devdata(file);
struct radio_device *card = video_get_drvdata(dev);
- int ret;
+ register u16 io = card->io;
+ register u16 omask = inw(io + IO_MASK);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ outw(~STR_WREN, io + IO_MASK);
+ outw((card->muted = ctrl->value ) ?
+ STR_WREN : 0, io);
+ udelay(4);
+ outw(omask, io + IO_MASK);
+ msleep(125);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
- mutex_lock(&card->lock);
- ret = video_usercopy(inode, file, cmd, arg, radio_function);
- mutex_unlock(&card->lock);
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
- return ret;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static u16 __devinit radio_power_on(struct radio_device *dev)
@@ -370,6 +361,24 @@ static u16 __devinit radio_power_on(struct radio_device *dev)
return (ofreq == radio_bits_get(dev));
}
+static struct video_device maestro_radio = {
+ .name = "Maestro radio",
+ .type = VID_TYPE_TUNER,
+ .fops = &maestro_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+};
+
static int __devinit maestro_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
diff --git a/linux/drivers/media/radio/radio-rtrack2.c b/linux/drivers/media/radio/radio-rtrack2.c
index 80fcbde1f..e8ab31ab6 100644
--- a/linux/drivers/media/radio/radio-rtrack2.c
+++ b/linux/drivers/media/radio/radio-rtrack2.c
@@ -123,6 +123,26 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
return 0;
}
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver));
+ strlcpy(v->card, "RadioTrack II", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+
+ return 0;
+}
+
static int rt_getsigstr(struct rt_device *dev)
{
if (inb(io) & 2) /* bit set = no signal present */
@@ -130,135 +150,136 @@ static int rt_getsigstr(struct rt_device *dev)
return 1; /* signal present */
}
-static int rt_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
- struct rt_device *rt=dev->priv;
+ struct rt_device *rt = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-rtrack2", sizeof (v->driver));
- strlcpy(v->card, "RadioTrack II", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (88*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF*rt_getsigstr(rt);
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+ rt->curfreq = f->frequency;
+ rt_setfreq(rt, rt->curfreq);
+ return 0;
+}
- v->rangelow=(88*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*rt_getsigstr(rt);
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = rt->curfreq;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- rt->curfreq = f->frequency;
- rt_setfreq(rt, rt->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = rt->curfreq;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = rt->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (rt->muted)
+ ctrl->value = 0;
+ else
+ ctrl->value = 65535;
+ return 0;
+ }
+ return -EINVAL;
+}
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=rt->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (rt->muted)
- ctrl->value=0;
- else
- ctrl->value=65535;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- rt_mute(rt);
- } else {
- rt_unmute(rt);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value) {
- rt_unmute(rt);
- } else {
- rt_mute(rt);
- }
- return (0);
- }
- return -EINVAL;
- }
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- rt_do_ioctl);
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct rt_device *rt = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ rt_mute(rt);
+ else
+ rt_unmute(rt);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ if (ctrl->value)
+ rt_unmute(rt);
+ else
+ rt_mute(rt);
+ return 0;
}
+ return -EINVAL;
}
-static int rt_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, rt_do_ioctl);
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct rt_device rtrack2_unit;
@@ -267,7 +288,7 @@ static const struct file_operations rtrack2_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = rt_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -279,6 +300,18 @@ static struct video_device rtrack2_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &rtrack2_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
};
static int __init rtrack2_init(void)
diff --git a/linux/drivers/media/radio/radio-sf16fmi.c b/linux/drivers/media/radio/radio-sf16fmi.c
index 00f9c12e7..925fe9205 100644
--- a/linux/drivers/media/radio/radio-sf16fmi.c
+++ b/linux/drivers/media/radio/radio-sf16fmi.c
@@ -137,149 +137,155 @@ static inline int fmi_getsigstr(struct fmi_device *dev)
return (res & 2) ? 0 : 0xFFFF;
}
-static int fmi_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
{
+ strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
+ strlcpy(v->card, "SF16-FMx radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ int mult;
struct video_device *dev = video_devdata(file);
- struct fmi_device *fmi=dev->priv;
+ struct fmi_device *fmi = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-sf16fmi", sizeof (v->driver));
- strlcpy(v->card, "SF16-FMx radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
- int mult;
-
- if (v->index > 0)
- return -EINVAL;
-
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
-
- mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
- v->rangelow = RSF16_MINFREQ/mult;
- v->rangehigh = RSF16_MAXFREQ/mult;
- v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
- v->capability=fmi->flags&V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_STEREO;
- v->signal = fmi_getsigstr(fmi);
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
+ v->rangelow = RSF16_MINFREQ/mult;
+ v->rangehigh = RSF16_MAXFREQ/mult;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
+ v->capability = fmi->flags&V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ v->signal = fmi_getsigstr(fmi);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmi_device *fmi = dev->priv;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
-
- if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
- f->frequency *= 1000;
- if (f->frequency < RSF16_MINFREQ ||
- f->frequency > RSF16_MAXFREQ )
- return -EINVAL;
- /*rounding in steps of 800 to match th freq
- that will be used */
- fmi->curfreq = (f->frequency/800)*800;
- fmi_setfreq(fmi);
+ if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency *= 1000;
+ if (f->frequency < RSF16_MINFREQ ||
+ f->frequency > RSF16_MAXFREQ )
+ return -EINVAL;
+ /*rounding in steps of 800 to match th freq
+ that will be used */
+ fmi->curfreq = (f->frequency/800)*800;
+ fmi_setfreq(fmi);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmi_device *fmi = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = fmi->curfreq;
- if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
- f->frequency /= 1000;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = fmi->curfreq;
+ if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency /= 1000;
+ return 0;
+}
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=fmi->curvol;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- {
- if (ctrl->value)
- fmi_mute(fmi->port);
- else
- fmi_unmute(fmi->port);
-
- fmi->curvol=ctrl->value;
- return (0);
- }
- }
- return -EINVAL;
- }
-#if 0 /* Probably, this is useless */
- case VIDIOCGUNIT:
- {
- struct video_unit *v = arg;
- v->video=VIDEO_NO_UNIT;
- v->vbi=VIDEO_NO_UNIT;
- v->radio=dev->minor;
- v->audio=0; /* How do we find out this??? */
- v->teletext=VIDEO_NO_UNIT;
- return 0;
- }
-#endif
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- fmi_do_ioctl);
}
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmi_device *fmi = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = fmi->curvol;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmi_device *fmi = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ fmi_mute(fmi->port);
+ else
+ fmi_unmute(fmi->port);
+ fmi->curvol = ctrl->value;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
}
-static int fmi_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, fmi_do_ioctl);
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct fmi_device fmi_unit;
@@ -288,7 +294,7 @@ static const struct file_operations fmi_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = fmi_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -300,6 +306,18 @@ static struct video_device fmi_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &fmi_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
/* ladis: this is my card. does any other types exist? */
diff --git a/linux/drivers/media/radio/radio-sf16fmr2.c b/linux/drivers/media/radio/radio-sf16fmr2.c
index 267c3d8d4..e2b037fad 100644
--- a/linux/drivers/media/radio/radio-sf16fmr2.c
+++ b/linux/drivers/media/radio/radio-sf16fmr2.c
@@ -231,198 +231,204 @@ static int fmr2_setvolume(struct fmr2_device *dev)
return 0;
}
-static int fmr2_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
{
+ strlcpy(v->driver, "radio-sf16fmr2", sizeof(v->driver));
+ strlcpy(v->card, "SF16-FMR2 radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ int mult;
struct video_device *dev = video_devdata(file);
struct fmr2_device *fmr2 = dev->priv;
- debug_print((KERN_DEBUG "freq %ld flags %d vol %d mute %d "
- "stereo %d type %d\n",
- fmr2->curfreq, fmr2->flags, fmr2->curvol, fmr2->mute,
- fmr2->stereo, fmr2->card_type));
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-sf16fmr2", sizeof (v->driver));
- strlcpy(v->card, "SF16-FMR2 radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
- int mult;
-
- if (v->index > 0)
- return -EINVAL;
-
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
-
- mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
- v->rangelow = RSF16_MINFREQ/mult;
- v->rangehigh = RSF16_MAXFREQ/mult;
- v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
- v->capability=fmr2->flags&V4L2_TUNER_CAP_LOW;
-
- v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
- V4L2_TUNER_MODE_MONO;
- mutex_lock(&lock);
- v->signal = fmr2_getsigstr(fmr2);
- mutex_unlock(&lock);
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
+ v->rangelow = RSF16_MINFREQ/mult;
+ v->rangehigh = RSF16_MAXFREQ/mult;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
+ v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW;
+ v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
+ V4L2_TUNER_MODE_MONO;
+ mutex_lock(&lock);
+ v->signal = fmr2_getsigstr(fmr2);
+ mutex_unlock(&lock);
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
-
- if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
- f->frequency *= 1000;
- if (f->frequency < RSF16_MINFREQ ||
- f->frequency > RSF16_MAXFREQ )
- return -EINVAL;
- /*rounding in steps of 200 to match th freq
- that will be used */
- fmr2->curfreq = (f->frequency/200)*200;
-
- /* set card freq (if not muted) */
- if (fmr2->curvol && !fmr2->mute)
- {
- mutex_lock(&lock);
- fmr2_setfreq(fmr2);
- mutex_unlock(&lock);
- }
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency *= 1000;
+ if (f->frequency < RSF16_MINFREQ ||
+ f->frequency > RSF16_MAXFREQ )
+ return -EINVAL;
+ /*rounding in steps of 200 to match th freq
+ that will be used */
+ fmr2->curfreq = (f->frequency/200)*200;
+
+ /* set card freq (if not muted) */
+ if (fmr2->curvol && !fmr2->mute) {
+ mutex_lock(&lock);
+ fmr2_setfreq(fmr2);
+ mutex_unlock(&lock);
+ }
+ return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = fmr2->curfreq;
- if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
- f->frequency /= 1000;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = fmr2->curfreq;
+ if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
+ f->frequency /= 1000;
+ return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if ((fmr2->card_type != 11)
+ && V4L2_CID_AUDIO_VOLUME)
+ radio_qctrl[i].step = 65535;
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if ((fmr2->card_type != 11)
- && V4L2_CID_AUDIO_VOLUME)
- radio_qctrl[i].step=65535;
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = fmr2->mute;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = fmr2->curvol;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct fmr2_device *fmr2 = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ fmr2->mute = ctrl->value;
+ if (fmr2->card_type != 11) {
+ if (!fmr2->mute)
+ fmr2->curvol = 65535;
+ else
+ fmr2->curvol = 0;
}
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=fmr2->mute;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=fmr2->curvol;
- return (0);
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ fmr2->curvol = ctrl->value;
+ if (fmr2->card_type != 11) {
+ if (fmr2->curvol) {
+ fmr2->curvol = 65535;
+ fmr2->mute = 0;
+ } else {
+ fmr2->curvol = 0;
+ fmr2->mute = 1;
}
- return -EINVAL;
}
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- fmr2->mute=ctrl->value;
- if (fmr2->card_type != 11) {
- if (!fmr2->mute) {
- fmr2->curvol = 65535;
- } else {
- fmr2->curvol = 0;
- }
- }
- break;
- case V4L2_CID_AUDIO_VOLUME:
- fmr2->curvol = ctrl->value;
- if (fmr2->card_type != 11) {
- if (fmr2->curvol) {
- fmr2->curvol = 65535;
- fmr2->mute = 0;
- } else {
- fmr2->curvol = 0;
- fmr2->mute = 1;
- }
- }
- break;
- default:
- return -EINVAL;
- }
+ break;
+ default:
+ return -EINVAL;
+ }
+
#ifdef DEBUG
- if (fmr2->curvol && !fmr2->mute)
- printk(KERN_DEBUG "unmute\n");
- else
- printk(KERN_DEBUG "mute\n");
-#endif
- mutex_lock(&lock);
- if (fmr2->curvol && !fmr2->mute) {
- fmr2_setvolume(fmr2);
- fmr2_setfreq(fmr2);
- } else
- fmr2_mute(fmr2->port);
- mutex_unlock(&lock);
- return (0);
- }
-#if 0
- case VIDIOCGUNIT:
- {
- struct video_unit *v = arg;
- v->video=VIDEO_NO_UNIT;
- v->vbi=VIDEO_NO_UNIT;
- v->radio=dev->minor;
- v->audio=0; /* How do we find out this??? */
- v->teletext=VIDEO_NO_UNIT;
- return 0;
- }
+ if (fmr2->curvol && !fmr2->mute)
+ printk(KERN_DEBUG "unmute\n");
+ else
+ printk(KERN_DEBUG "mute\n");
#endif
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- fmr2_do_ioctl);
- }
+ mutex_lock(&lock);
+ if (fmr2->curvol && !fmr2->mute) {
+ fmr2_setvolume(fmr2);
+ fmr2_setfreq(fmr2);
+ } else
+ fmr2_mute(fmr2->port);
+ mutex_unlock(&lock);
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
}
-static int fmr2_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
- {
- return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl);
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct fmr2_device fmr2_unit;
@@ -431,7 +437,7 @@ static const struct file_operations fmr2_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = fmr2_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -443,6 +449,18 @@ static struct video_device fmr2_radio=
. type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &fmr2_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __init fmr2_init(void)
diff --git a/linux/drivers/media/radio/radio-terratec.c b/linux/drivers/media/radio/radio-terratec.c
index ffe1ffd31..d8a48bf85 100644
--- a/linux/drivers/media/radio/radio-terratec.c
+++ b/linux/drivers/media/radio/radio-terratec.c
@@ -206,135 +206,152 @@ static int tt_getsigstr(struct tt_device *dev) /* TODO */
return 1; /* signal present */
}
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-terratec", sizeof(v->driver));
+ strlcpy(v->card, "ActiveRadio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
-/* implement the video4linux api */
-
-static int tt_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
- struct tt_device *tt=dev->priv;
+ struct tt_device *tt = dev->priv;
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-terratec", sizeof (v->driver));
- strlcpy(v->card, "ActiveRadio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF*tt_getsigstr(tt);
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct tt_device *tt = dev->priv;
- v->rangelow=(87*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*tt_getsigstr(tt);
+ tt->curfreq = f->frequency;
+ tt_setfreq(tt, tt->curfreq);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct tt_device *tt = dev->priv;
- if (v->index > 0)
- return -EINVAL;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = tt->curfreq;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
- tt->curfreq = f->frequency;
- tt_setfreq(tt, tt->curfreq);
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ }
+ return -EINVAL;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = tt->curfreq;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct tt_device *tt = dev->priv;
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (tt->muted)
- ctrl->value=1;
- else
- ctrl->value=0;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=tt->curvol * 6554;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- tt_mute(tt);
- } else {
- tt_setvol(tt,tt->curvol);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- tt_setvol(tt,ctrl->value);
- return (0);
- }
- return -EINVAL;
- }
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (tt->muted)
+ ctrl->value = 1;
+ else
+ ctrl->value = 0;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = tt->curvol * 6554;
+ return 0;
+ }
+ return -EINVAL;
+}
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- tt_do_ioctl);
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct tt_device *tt = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ tt_mute(tt);
+ else
+ tt_setvol(tt,tt->curvol);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ tt_setvol(tt,ctrl->value);
+ return 0;
}
+ return -EINVAL;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
}
-static int tt_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- return video_usercopy(inode, file, cmd, arg, tt_do_ioctl);
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct tt_device terratec_unit;
@@ -343,7 +360,7 @@ static const struct file_operations terratec_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = tt_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -355,6 +372,18 @@ static struct video_device terratec_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &terratec_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
};
static int __init terratec_init(void)
diff --git a/linux/drivers/media/radio/radio-trust.c b/linux/drivers/media/radio/radio-trust.c
index ee903a52b..f2196933a 100644
--- a/linux/drivers/media/radio/radio-trust.c
+++ b/linux/drivers/media/radio/radio-trust.c
@@ -193,147 +193,157 @@ static void tr_setfreq(unsigned long f)
write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
}
-static int tr_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
{
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-trust", sizeof (v->driver));
- strlcpy(v->card, "Trust FM Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ strlcpy(v->driver, "radio-trust", sizeof(v->driver));
+ strlcpy(v->card, "Trust FM Radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
-
- if (v->index > 0)
- return -EINVAL;
-
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
-
- v->rangelow=(87.5*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(tr_getstereo())
- v->audmode = V4L2_TUNER_MODE_STEREO;
- else
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=tr_getsigstr();
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87.5*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if (tr_getstereo())
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = tr_getsigstr();
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ return 0;
+}
- curfreq = f->frequency;
- tr_setfreq(curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ curfreq = f->frequency;
+ tr_setfreq(curfreq);
+ return 0;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = curfreq;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = curfreq;
+ return 0;
+}
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=curmute;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value= curvol * 2048;
- return (0);
- case V4L2_CID_AUDIO_BASS:
- ctrl->value= curbass * 4370;
- return (0);
- case V4L2_CID_AUDIO_TREBLE:
- ctrl->value= curtreble * 4370;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- tr_setmute(ctrl->value);
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- tr_setvol(ctrl->value);
- return 0;
- case V4L2_CID_AUDIO_BASS:
- tr_setbass(ctrl->value);
- return 0;
- case V4L2_CID_AUDIO_TREBLE:
- tr_settreble(ctrl->value);
- return (0);
- }
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = curmute;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = curvol * 2048;
+ return 0;
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value = curbass * 4370;
+ return 0;
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value = curtreble * 4370;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ tr_setmute(ctrl->value);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ tr_setvol(ctrl->value);
+ return 0;
+ case V4L2_CID_AUDIO_BASS:
+ tr_setbass(ctrl->value);
+ return 0;
+ case V4L2_CID_AUDIO_TREBLE:
+ tr_settreble(ctrl->value);
+ return 0;
+ }
#if 0 /* Should implement mono/stereo on V4L2 */
tr_setstereo(v->mode & VIDEO_SOUND_STEREO);
#endif
- return -EINVAL;
- }
+ return -EINVAL;
+}
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- tr_do_ioctl);
- }
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
}
-static int tr_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- return video_usercopy(inode, file, cmd, arg, tr_do_ioctl);
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static const struct file_operations trust_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = tr_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -345,6 +355,18 @@ static struct video_device trust_radio=
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &trust_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
};
static int __init trust_init(void)
diff --git a/linux/drivers/media/radio/radio-typhoon.c b/linux/drivers/media/radio/radio-typhoon.c
index 66b21f2cd..ca326b666 100644
--- a/linux/drivers/media/radio/radio-typhoon.c
+++ b/linux/drivers/media/radio/radio-typhoon.c
@@ -98,8 +98,6 @@ static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency);
static void typhoon_mute(struct typhoon_device *dev);
static void typhoon_unmute(struct typhoon_device *dev);
static int typhoon_setvol(struct typhoon_device *dev, int vol);
-static int typhoon_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
static int typhoon_get_info(char *buf, char **start, off_t offset, int len);
#endif
@@ -191,129 +189,148 @@ static int typhoon_setvol(struct typhoon_device *dev, int vol)
return 0;
}
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-typhoon", sizeof(v->driver));
+ strlcpy(v->card, "Typhoon Radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (87.5*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF; /* We can't get the signal strength */
+ return 0;
+}
-static int typhoon_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
{
struct video_device *dev = video_devdata(file);
struct typhoon_device *typhoon = dev->priv;
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-typhoon", sizeof (v->driver));
- strlcpy(v->card, "Typhoon Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ typhoon->curfreq = f->frequency;
+ typhoon_setfreq(typhoon, typhoon->curfreq);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct typhoon_device *typhoon = dev->priv;
- if (v->index > 0)
- return -EINVAL;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = typhoon->curfreq;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+ return 0;
+}
- v->rangelow=(87.5*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO;
- v->capability=V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF; /* We can't get the signal strength */
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+ }
+ return -EINVAL;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct typhoon_device *typhoon = dev->priv;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = typhoon->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = typhoon->curvol;
+ return 0;
+ }
+ return -EINVAL;
+}
- typhoon->curfreq = f->frequency;
- typhoon_setfreq(typhoon, typhoon->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_s_ctrl (struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct typhoon_device *typhoon = dev->priv;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = typhoon->curfreq;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ typhoon_mute(typhoon);
+ else
+ typhoon_unmute(typhoon);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ typhoon_setvol(typhoon, ctrl->value);
+ return 0;
+ }
+ return -EINVAL;
+}
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=typhoon->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=typhoon->curvol;
- return (0);
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- typhoon_mute(typhoon);
- } else {
- typhoon_unmute(typhoon);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- typhoon_setvol(typhoon, ctrl->value);
- return (0);
- }
- return -EINVAL;
- }
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- typhoon_do_ioctl);
- }
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
}
-static int typhoon_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, typhoon_do_ioctl);
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct typhoon_device typhoon_unit =
@@ -327,7 +344,7 @@ static const struct file_operations typhoon_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = typhoon_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -339,6 +356,18 @@ static struct video_device typhoon_radio =
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &typhoon_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
diff --git a/linux/drivers/media/radio/radio-zoltrix.c b/linux/drivers/media/radio/radio-zoltrix.c
index d1473bf04..2175bc2d8 100644
--- a/linux/drivers/media/radio/radio-zoltrix.c
+++ b/linux/drivers/media/radio/radio-zoltrix.c
@@ -235,121 +235,123 @@ static int zol_is_stereo (struct zol_device *dev)
return 0;
}
-static int zol_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver));
+ strlcpy(v->card, "Zoltrix Radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
struct video_device *dev = video_devdata(file);
struct zol_device *zol = dev->priv;
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "radio-zoltrix", sizeof (v->driver));
- strlcpy(v->card, "Zoltrix Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ if (v->index > 0)
+ return -EINVAL;
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
-
- if (v->index > 0)
- return -EINVAL;
-
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
-
- v->rangelow=(88*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(zol_is_stereo(zol))
- v->audmode = V4L2_TUNER_MODE_STEREO;
- else
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*zol_getsigstr(zol);
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = (88*16000);
+ v->rangehigh = (108*16000);
+ v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if (zol_is_stereo(zol))
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xFFFF*zol_getsigstr(zol);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+ return 0;
+}
- if (v->index > 0)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct zol_device *zol = dev->priv;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ zol->curfreq = f->frequency;
+ zol_setfreq(zol, zol->curfreq);
+ return 0;
+}
- zol->curfreq = f->frequency;
- zol_setfreq(zol, zol->curfreq);
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct video_device *dev = video_devdata(file);
+ struct zol_device *zol = dev->priv;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = zol->curfreq;
+ return 0;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = zol->curfreq;
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=zol->muted;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=zol->curvol * 4096;
- return (0);
- }
- return -EINVAL;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct zol_device *zol = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = zol->muted;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = zol->curvol * 4096;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct video_device *dev = video_devdata(file);
+ struct zol_device *zol = dev->priv;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ zol_mute(zol);
+ else {
+ zol_unmute(zol);
+ zol_setvol(zol,zol->curvol);
}
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- zol_mute(zol);
- } else {
- zol_unmute(zol);
- zol_setvol(zol,zol->curvol);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- zol_setvol(zol,ctrl->value/4096);
- return (0);
- }
- zol->stereo = 1;
- zol_setfreq(zol, zol->curfreq);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ zol_setvol(zol,ctrl->value/4096);
+ return 0;
+ }
+ zol->stereo = 1;
+ zol_setfreq(zol, zol->curfreq);
#if 0 /*keep*/
/* FIXME: Implement stereo/mono switch on V4L2 */
if (v->mode & VIDEO_SOUND_STEREO) {
@@ -361,19 +363,39 @@ static int zol_do_ioctl(struct inode *inode, struct file *file,
zol_setfreq(zol, zol->curfreq);
}
#endif
- return -EINVAL;
- }
+ return -EINVAL;
+}
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- zol_do_ioctl);
- }
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
}
-static int zol_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- return video_usercopy(inode, file, cmd, arg, zol_do_ioctl);
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static struct zol_device zoltrix_unit;
@@ -383,7 +405,7 @@ static const struct file_operations zoltrix_fops =
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
- .ioctl = zol_ioctl,
+ .ioctl = video_ioctl2,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
};
@@ -395,6 +417,18 @@ static struct video_device zoltrix_radio =
.type = VID_TYPE_TUNER,
.hardware = 0,
.fops = &zoltrix_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __init zoltrix_init(void)
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index ac65aaf20..41e36bc3f 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -2,14 +2,19 @@
# Multimedia Video device configuration
#
-menu "Video Capture Adapters"
+menuconfig VIDEO_CAPTURE_DRIVERS
+ bool "Video capture adapters"
depends on VIDEO_DEV
+ default y
+ ---help---
+ Say Y here to enable selecting the video adapters for
+ webcams, analog TV, and hybrid analog/digital TV.
+ Some of those devices also supports FM radio.
-comment "Video Capture Adapters"
+if VIDEO_CAPTURE_DRIVERS
config VIDEO_ADV_DEBUG
bool "Enable advanced debug functionality"
- depends on VIDEO_DEV
default n
---help---
Say Y here to enable advanced debugging functionality on some
@@ -34,7 +39,7 @@ config VIDEO_HELPER_CHIPS_AUTO
#
menu "Encoders/decoders and other helper chips"
- depends on VIDEO_DEV && !VIDEO_HELPER_CHIPS_AUTO
+ depends on !VIDEO_HELPER_CHIPS_AUTO
comment "Audio decoders"
@@ -61,7 +66,7 @@ config VIDEO_TDA7432
config VIDEO_TDA9840
tristate "Philips TDA9840 audio processor"
- depends on VIDEO_DEV && I2C
+ depends on I2C
---help---
Support for tda9840 audio decoder chip found on some Zoran boards.
@@ -79,7 +84,7 @@ config VIDEO_TDA9875
config VIDEO_TEA6415C
tristate "Philips TEA6415C audio processor"
- depends on VIDEO_DEV && I2C
+ depends on I2C
---help---
Support for tea6415c audio decoder chip found on some bt8xx boards.
@@ -88,7 +93,7 @@ config VIDEO_TEA6415C
config VIDEO_TEA6420
tristate "Philips TEA6420 audio processor"
- depends on VIDEO_DEV && I2C
+ depends on I2C
---help---
Support for tea6420 audio decoder chip found on some bt8xx boards.
@@ -469,7 +474,7 @@ config VIDEO_SAA5246A
config VIDEO_SAA5249
tristate "SAA5249 Teletext processor"
- depends on VIDEO_DEV && I2C && VIDEO_V4L2
+ depends on I2C && VIDEO_V4L2
help
Support for I2C bus based teletext using the SAA5249 chip. At the
moment this is only useful on some European WinTV cards.
@@ -479,14 +484,14 @@ config VIDEO_SAA5249
config TUNER_3036
tristate "SAB3036 tuner"
- depends on VIDEO_DEV && I2C && VIDEO_V4L1
+ depends on I2C && VIDEO_V4L1
help
Say Y here to include support for Philips SAB3036 compatible tuners.
If in doubt, say N.
config TUNER_TEA5761
tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
- depends on VIDEO_DEV && I2C
+ depends on I2C
select VIDEO_TUNER
help
Say Y here to include support for Philips TEA5761 radio tuner.
@@ -689,8 +694,12 @@ config VIDEO_CAFE_CCIC
# USB Multimedia device configuration
#
-menu "V4L USB devices"
- depends on USB && VIDEO_DEV
+menuconfig V4L_USB_DRIVERS
+ bool "V4L USB devices"
+ depends on USB
+ default y
+
+if V4L_USB_DRIVERS
source "drivers/media/video/pvrusb2/Kconfig"
@@ -715,7 +724,7 @@ config VIDEO_OVCAMCHIP
config USB_W9968CF
tristate "USB W996[87]CF JPEG Dual Mode Camera support"
- depends on USB && VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L1 && I2C
select VIDEO_OVCAMCHIP
---help---
Say Y here if you want support for cameras based on OV681 or
@@ -733,7 +742,7 @@ config USB_W9968CF
config USB_OV511
tristate "USB OV511 Camera support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. See <file:Documentation/video4linux/ov511.txt>
@@ -744,7 +753,7 @@ config USB_OV511
config USB_SE401
tristate "USB SE401 Camera support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. See <file:Documentation/video4linux/se401.txt>
@@ -757,7 +766,7 @@ source "drivers/media/video/sn9c102/Kconfig"
config USB_STV680
tristate "USB STV680 (Pencam) Camera support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. This includes the Pencam line of cameras.
@@ -773,7 +782,7 @@ source "drivers/media/video/pwc/Kconfig"
config USB_ZR364XX
tristate "USB ZR364XX Camera support"
- depends on USB && VIDEO_V4L2
+ depends on VIDEO_V4L2
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port.
@@ -783,6 +792,6 @@ config USB_ZR364XX
To compile this driver as a module, choose M here: the
module will be called zr364xx.
-endmenu # V4L USB devices
+endif # V4L_USB_DRIVERS
-endmenu
+endif # VIDEO_CAPTURE_DRIVERS
diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c
index b0e6c3e9c..c704efb05 100644
--- a/linux/drivers/media/video/bt8xx/bttv-cards.c
+++ b/linux/drivers/media/video/bt8xx/bttv-cards.c
@@ -314,6 +314,9 @@ static struct CARD {
{ 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
+ { 0x53534149, BTTV_BOARD_SSAI_SECURITY, "SSAI Security Video Interface" },
+ { 0x5353414a, BTTV_BOARD_SSAI_ULTRASOUND, "SSAI Ultrasound Video Interface" },
+
/* likely broken, vendor id doesn't match the other magic views ...
* { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
@@ -2952,6 +2955,28 @@ struct tvcard bttv_tvcards[] = {
.has_radio = 1,
.has_remote = 1,
},
+ [BTTV_BOARD_SSAI_SECURITY] = {
+ .name = "SSAI Security Video Interface",
+ .video_inputs = 4,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = -1,
+ .muxsel = { 0, 1, 2, 3 },
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
+ [BTTV_BOARD_SSAI_ULTRASOUND] = {
+ .name = "SSAI Ultrasound Video Interface",
+ .video_inputs = 2,
+ .audio_inputs = 0,
+ .tuner = -1,
+ .svhs = 1,
+ .muxsel = { 2, 0, 1, 3 },
+ .tuner_type = -1,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ },
};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3015,20 +3040,20 @@ void __devinit bttv_idcard(struct bttv *btv)
if (UNSET != audiomux[0]) {
gpiobits = 0;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i];
gpiobits |= audiomux[i];
}
} else {
gpiobits = audioall;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
bttv_tvcards[btv->c.type].gpiomux[i] = audioall;
}
}
bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=",
btv->c.nr,bttv_tvcards[btv->c.type].gpiomask);
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].gpiomux[i]);
}
printk("\n");
@@ -3692,7 +3717,7 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
for (n = 0; n < microlen; n++) {
bits = micro[n];
- for ( i = 0 ; i < 8 ; i++ ) {
+ for (i = 0 ; i < 8 ; i++) {
gpio_bits(BTTV_ALT_DCLK,0);
if (bits & 0x01)
gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA);
@@ -3749,7 +3774,7 @@ static void __devinit osprey_eeprom(struct bttv *btv)
/* this might be an antique... check for MMAC label in eeprom */
if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
unsigned char checksum = 0;
- for (i =0; i<21; i++)
+ for (i = 0; i < 21; i++)
checksum += ee[i];
if (checksum != ee[21])
return;
@@ -3761,12 +3786,13 @@ static void __devinit osprey_eeprom(struct bttv *btv)
unsigned short type;
int offset = 4*16;
- for(; offset < 8*16; offset += 16) {
+ for (; offset < 8*16; offset += 16) {
unsigned short checksum = 0;
/* verify the checksum */
- for(i = 0; i<14; i++) checksum += ee[i+offset];
- checksum = ~checksum; /* no idea why */
- if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
+ for (i = 0; i < 14; i++)
+ checksum += ee[i+offset];
+ checksum = ~checksum; /* no idea why */
+ if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
((checksum & 0x0FF) == ee[offset+15])) {
break;
}
@@ -3779,7 +3805,6 @@ static void __devinit osprey_eeprom(struct bttv *btv)
type = (ee[offset+4]<<8) | (ee[offset+5]);
switch(type) {
-
/* 848 based */
case 0x0004:
btv->c.type = BTTV_BOARD_OSPREY1x0_848;
@@ -4245,8 +4270,7 @@ static int tea5757_read(struct bttv *btv)
}
dprintk("bttv%d: tea5757:",btv->c.nr);
- for(i = 0; i < 24; i++)
- {
+ for (i = 0; i < 24; i++) {
udelay(5);
bus_high(btv,btv->mbox_clk);
udelay(5);
@@ -4278,8 +4302,7 @@ static int tea5757_write(struct bttv *btv, int value)
dprintk("bttv%d: tea5757: write 0x%X\n", btv->c.nr, value);
bus_low(btv,btv->mbox_clk);
bus_high(btv,btv->mbox_we);
- for(i = 0; i < 25; i++)
- {
+ for (i = 0; i < 25; i++) {
if (reg & 0x1000000)
bus_high(btv,btv->mbox_data);
else
@@ -4871,7 +4894,7 @@ static void kodicom4400r_init(struct bttv *btv)
gpio_write(1 << 9); /* reset MUX */
gpio_write(0);
/* Preset camera 0 to the 4 controllers */
- for (ix=0; ix<4; ix++) {
+ for (ix = 0; ix < 4; ix++) {
sw_status[ix] = ix;
kodicom4400r_write(btv, ix, ix, 1);
}
diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c
index 25a61e379..2aad57b5a 100644
--- a/linux/drivers/media/video/bt8xx/bttv-driver.c
+++ b/linux/drivers/media/video/bt8xx/bttv-driver.c
@@ -177,6 +177,36 @@ static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
#endif
/* ----------------------------------------------------------------------- */
+/* dvb auto-load setup */
+#if defined(CONFIG_MODULES) && defined(MODULE)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void request_module_async(void *ptr)
+#else
+static void request_module_async(struct work_struct *work)
+#endif
+{
+ request_module("dvb-bt8xx");
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define request_modules(dev)
+#else
+static void request_modules(struct bttv *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+ INIT_WORK(&dev->request_module_wk, request_module_async, (void*)dev);
+#else
+ INIT_WORK(&dev->request_module_wk, request_module_async);
+#endif
+ schedule_work(&dev->request_module_wk);
+}
+#endif
+#else
+#define request_modules(dev)
+#endif /* CONFIG_MODULES */
+
+
+/* ----------------------------------------------------------------------- */
/* static data */
/* special timing tables from conexant... */
@@ -4811,9 +4841,11 @@ static int __devinit bttv_probe(struct pci_dev *dev,
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- /* add subdevices */
- if (bttv_tvcards[btv->c.type].has_dvb)
+ /* add subdevices and autoload dvb-bt8xx if needed */
+ if (bttv_tvcards[btv->c.type].has_dvb) {
bttv_sub_add_device(&btv->c, "dvb");
+ request_modules(btv);
+ }
#endif
bttv_input_init(btv);
diff --git a/linux/drivers/media/video/bt8xx/bttv-i2c.c b/linux/drivers/media/video/bt8xx/bttv-i2c.c
index 68522754a..3f545c610 100644
--- a/linux/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/linux/drivers/media/video/bt8xx/bttv-i2c.c
@@ -426,7 +426,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
unsigned char buf;
int i,rc;
- for (i = 0; i < 128; i++) {
+ for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
c->addr = i;
rc = i2c_master_recv(c,&buf,0);
if (rc < 0)
diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h
index ed565fb8b..f9681147d 100644
--- a/linux/drivers/media/video/bt8xx/bttv.h
+++ b/linux/drivers/media/video/bt8xx/bttv.h
@@ -169,6 +169,8 @@
#define BTTV_BOARD_SABRENT_TVFM 0x8e
#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
#define BTTV_BOARD_MACHTV_MAGICTV 0x90
+#define BTTV_BOARD_SSAI_SECURITY 0x91
+#define BTTV_BOARD_SSAI_ULTRASOUND 0x92
/* more card-specific defines */
#define PT2254_L_CHANNEL 0x10
diff --git a/linux/drivers/media/video/bt8xx/bttvp.h b/linux/drivers/media/video/bt8xx/bttvp.h
index a273c424b..eee6f5ae3 100644
--- a/linux/drivers/media/video/bt8xx/bttvp.h
+++ b/linux/drivers/media/video/bt8xx/bttvp.h
@@ -452,6 +452,9 @@ struct bttv {
unsigned int users;
struct bttv_fh init;
+ /* used to make dvb-bt8xx autoloadable */
+ struct work_struct request_module_wk;
+
/* Default (0) and current (1) video capturing and overlay
cropping parameters in bttv_tvnorm.cropcap units. Protected
by bttv.lock. */
diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c
index b96d45654..0615ec50c 100644
--- a/linux/drivers/media/video/cafe_ccic.c
+++ b/linux/drivers/media/video/cafe_ccic.c
@@ -4,6 +4,7 @@
* sensor.
*
* Copyright 2006 One Laptop Per Child Association, Inc.
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
*
* Written by Jonathan Corbet, corbet@lwn.net.
*
@@ -38,7 +39,7 @@
#include "cafe_ccic-regs.h"
-#define CAFE_VERSION 0x000001
+#define CAFE_VERSION 0x000002
/*
@@ -712,7 +713,13 @@ static void cafe_ctlr_init(struct cafe_camera *cam)
cafe_reg_write(cam, REG_GL_CSR, GCSR_SRS|GCSR_MRS); /* Needed? */
cafe_reg_write(cam, REG_GL_CSR, GCSR_SRC|GCSR_MRC);
cafe_reg_write(cam, REG_GL_CSR, GCSR_SRC|GCSR_MRS);
+ /*
+ * Here we must wait a bit for the controller to come around.
+ */
+ spin_unlock_irqrestore(&cam->dev_lock, flags);
mdelay(5); /* FIXME revisit this */
+ spin_lock_irqsave(&cam->dev_lock, flags);
+
cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC);
cafe_reg_set_bit(cam, REG_GL_IMASK, GIMSK_CCIC_EN);
/*
@@ -780,9 +787,9 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam)
* Control 1 is power down, set to 0 to operate.
*/
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */
- mdelay(1); /* Marvell says 1ms will do it */
+// mdelay(1); /* Marvell says 1ms will do it */
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
- mdelay(1); /* Enough? */
+// mdelay(1); /* Enough? */
spin_unlock_irqrestore(&cam->dev_lock, flags);
}
@@ -1803,18 +1810,19 @@ static void cafe_frame_tasklet(unsigned long data)
if (list_empty(&cam->sb_avail))
break; /* Leave it valid, hope for better later */
clear_bit(bufno, &cam->flags);
- /*
- * We could perhaps drop the spinlock during this
- * big copy. Something to consider.
- */
sbuf = list_entry(cam->sb_avail.next,
struct cafe_sio_buffer, list);
+ /*
+ * Drop the lock during the big copy. This *should* be safe...
+ */
+ spin_unlock_irqrestore(&cam->dev_lock, flags);
memcpy(sbuf->buffer, cam->dma_bufs[bufno],
cam->pix_format.sizeimage);
sbuf->v4lbuf.bytesused = cam->pix_format.sizeimage;
sbuf->v4lbuf.sequence = cam->buf_seq[bufno];
sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;
+ spin_lock_irqsave(&cam->dev_lock, flags);
list_move_tail(&sbuf->list, &cam->sb_full);
}
if (! list_empty(&cam->sb_full))
@@ -2118,6 +2126,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
cam->v4ldev = cafe_v4l_template;
cam->v4ldev.debug = 0;
// cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG;
+ cam->v4ldev.dev = &pdev->dev;
ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1);
if (ret)
goto out_smbus;
@@ -2187,10 +2196,52 @@ static void cafe_pci_remove(struct pci_dev *pdev)
}
+#ifdef CONFIG_PM
+/*
+ * Basic power management.
+ */
+static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ int ret;
+
+ ret = pci_save_state(pdev);
+ if (ret)
+ return ret;
+ cafe_ctlr_stop_dma(cam);
+ cafe_ctlr_power_down(cam);
+ pci_disable_device(pdev);
+ return 0;
+}
+
+
+static int cafe_pci_resume(struct pci_dev *pdev)
+{
+ struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ int ret = 0;
+
+ ret = pci_restore_state(pdev);
+ if (ret)
+ return ret;
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ cam_warn(cam, "Unable to re-enable device on resume!\n");
+ return ret;
+ }
+ cafe_ctlr_init(cam);
+ cafe_ctlr_power_up(cam);
+ set_bit(CF_CONFIG_NEEDED, &cam->flags);
+ if (cam->state == S_SPECREAD)
+ cam->state = S_IDLE; /* Don't bother restarting */
+ else if (cam->state == S_SINGLEREAD || cam->state == S_STREAMING)
+ ret = cafe_read_setup(cam, cam->state);
+ return ret;
+}
+
+#endif /* CONFIG_PM */
static struct pci_device_id cafe_ids[] = {
- { PCI_DEVICE(0x1148, 0x4340) }, /* Temporary ID on devel board */
{ PCI_DEVICE(0x11ab, 0x4100) }, /* Eventual real ID */
{ PCI_DEVICE(0x11ab, 0x4102) }, /* Really eventual real ID */
{ 0, }
@@ -2203,6 +2254,10 @@ static struct pci_driver cafe_pci_driver = {
.id_table = cafe_ids,
.probe = cafe_pci_probe,
.remove = cafe_pci_remove,
+#ifdef CONFIG_PM
+ .suspend = cafe_pci_suspend,
+ .resume = cafe_pci_resume,
+#endif
};
diff --git a/linux/drivers/media/video/cpia_pp.c b/linux/drivers/media/video/cpia_pp.c
index 337675e96..d2c34c156 100644
--- a/linux/drivers/media/video/cpia_pp.c
+++ b/linux/drivers/media/video/cpia_pp.c
@@ -62,7 +62,6 @@ static int cpia_pp_close(void *privdata);
#define PPCPIA_PARPORT_OFF -2
#define PPCPIA_PARPORT_NONE -1
-#ifdef MODULE
static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
static char *parport[PARPORT_MAX] = {NULL,};
@@ -72,11 +71,6 @@ MODULE_LICENSE("GPL");
module_param_array(parport, charp, NULL, 0);
MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
-#else
-static int parport_nr[PARPORT_MAX] __initdata =
- {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
-static int parport_ptr = 0;
-#endif
struct pp_cam_entry {
struct pardevice *pdev;
@@ -827,7 +821,7 @@ static struct parport_driver cpia_pp_driver = {
.detach = cpia_pp_detach,
};
-static int cpia_pp_init(void)
+static int __init cpia_pp_init(void)
{
printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
@@ -846,8 +840,7 @@ static int cpia_pp_init(void)
return 0;
}
-#ifdef MODULE
-int init_module(void)
+static int __init cpia_init(void)
{
if (parport[0]) {
/* The user gave some parameters. Let's see what they were. */
@@ -874,38 +867,11 @@ int init_module(void)
return cpia_pp_init();
}
-void cleanup_module(void)
+static void __exit cpia_cleanup(void)
{
- parport_unregister_driver (&cpia_pp_driver);
+ parport_unregister_driver(&cpia_pp_driver);
return;
}
-#else /* !MODULE */
-
-static int __init cpia_pp_setup(char *str)
-{
- int err;
-
- if (!strncmp(str, "parport", 7)) {
- int n = simple_strtoul(str + 7, NULL, 10);
- if (parport_ptr < PARPORT_MAX) {
- parport_nr[parport_ptr++] = n;
- } else {
- LOG("too many ports, %s ignored.\n", str);
- }
- } else if (!strcmp(str, "auto")) {
- parport_nr[0] = PPCPIA_PARPORT_AUTO;
- } else if (!strcmp(str, "none")) {
- parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
- }
-
- err=cpia_pp_init();
- if (err)
- return err;
-
- return 1;
-}
-
-__setup("cpia_pp=", cpia_pp_setup);
-
-#endif /* !MODULE */
+module_init(cpia_init);
+module_exit(cpia_cleanup);
diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c
index c401c1ee7..9d40a2b95 100644
--- a/linux/drivers/media/video/cx25840/cx25840-core.c
+++ b/linux/drivers/media/video/cx25840/cx25840-core.c
@@ -566,7 +566,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
{
struct v4l2_pix_format *pix;
int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
- int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+ int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
switch (fmt->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -578,7 +578,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
- Vlines = pix->height + (is_pal ? 4 : 7);
+ Vlines = pix->height + (is_50Hz ? 4 : 7);
if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c
index bf67ec27d..7131e05a3 100644
--- a/linux/drivers/media/video/cx88/cx88-alsa.c
+++ b/linux/drivers/media/video/cx88/cx88-alsa.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
#include <asm/delay.h>
#include <sound/driver.h>
#include <sound/core.h>
@@ -257,7 +258,8 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip)
cx_write(MO_AUD_INTSTAT, status);
if (debug > 1 || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq aud",
- cx88_aud_irqs, status, mask);
+ cx88_aud_irqs, ARRAY_SIZE(cx88_aud_irqs),
+ status, mask);
/* risc op code error */
if (status & (1 << 16)) {
printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name);
@@ -467,11 +469,9 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
dprintk(1,"Setting buffer\n");
- buf = kmalloc(sizeof(*buf),GFP_KERNEL);
+ buf = kzalloc(sizeof(*buf),GFP_KERNEL);
if (NULL == buf)
return -ENOMEM;
- memset(buf,0,sizeof(*buf));
-
buf->vb.memory = V4L2_MEMORY_MMAP;
buf->vb.width = chip->period_size;
@@ -789,7 +789,7 @@ static int __devinit snd_cx88_create(struct snd_card *card,
return err;
}
- if (!pci_dma_supported(pci,0xffffffff)) {
+ if (!pci_dma_supported(pci,DMA_32BIT_MASK)) {
dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
err = -EIO;
cx88_core_put(core,pci);
diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c
index 774bcfed9..6be16512a 100644
--- a/linux/drivers/media/video/cx88/cx88-cards.c
+++ b/linux/drivers/media/video/cx88/cx88-cards.c
@@ -886,6 +886,12 @@ struct cx88_board cx88_boards[] = {
.input = {{
.type = CX88_VMUX_DVB,
.vmux = 0,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
}},
.mpeg = CX88_MPEG_DVB,
},
@@ -1823,7 +1829,7 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
{ 0x03, 0x0C },
};
- for (i = 0; i < 13; i++) {
+ for (i = 0; i < ARRAY_SIZE(init_bufs); i++) {
msg.buf = init_bufs[i];
msg.len = (i != 12 ? 5 : 2);
err = i2c_transfer(&core->i2c_adap, &msg, 1);
@@ -1950,12 +1956,21 @@ void cx88_card_setup(struct cx88_core *core)
if (0 == core->i2c_rc) {
/* enable tuner */
int i;
- static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
+ static const u8 buffer [][2] = {
+ {0x10,0x12},
+ {0x13,0x04},
+ {0x16,0x00},
+ {0x14,0x04},
+ {0x17,0x00}
+ };
core->i2c_client.addr = 0x0a;
- for (i = 0; i < 5; i++)
- if (2 != i2c_master_send(&core->i2c_client,&buffer[i*2],2))
- printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n",
+ for (i = 0; i < ARRAY_SIZE(buffer); i++)
+ if (2 != i2c_master_send(&core->i2c_client,
+ buffer[i],2))
+ printk(KERN_WARNING
+ "%s: Unable to enable "
+ "tuner(%i).\n",
core->name, i);
}
break;
diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c
index 367dc3c7b..ba132d065 100644
--- a/linux/drivers/media/video/cx88/cx88-core.c
+++ b/linux/drivers/media/video/cx88/cx88-core.c
@@ -524,12 +524,12 @@ static char *cx88_pci_irqs[32] = {
};
void cx88_print_irqbits(char *name, char *tag, char **strings,
- u32 bits, u32 mask)
+ int len, u32 bits, u32 mask)
{
unsigned int i;
printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
- for (i = 0; i < 32; i++) {
+ for (i = 0; i < len; i++) {
if (!(bits & (1 << i)))
continue;
if (strings[i])
@@ -555,8 +555,8 @@ int cx88_core_irq(struct cx88_core *core, u32 status)
}
if (!handled)
cx88_print_irqbits(core->name, "irq pci",
- cx88_pci_irqs, status,
- core->pci_irqmask);
+ cx88_pci_irqs, ARRAY_SIZE(cx88_pci_irqs),
+ status, core->pci_irqmask);
return handled;
}
diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c
index 2b24c27a6..2327b32fd 100644
--- a/linux/drivers/media/video/cx88/cx88-dvb.c
+++ b/linux/drivers/media/video/cx88/cx88-dvb.c
@@ -476,6 +476,8 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_WINFAST_DTV2000H:
case CX88_BOARD_HAUPPAUGE_HVR1100:
case CX88_BOARD_HAUPPAUGE_HVR1100LP:
+ case CX88_BOARD_HAUPPAUGE_HVR1300:
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
dev->dvb.frontend = dvb_attach(cx22702_attach,
&hauppauge_hvr_config,
&dev->core->i2c_adap);
@@ -694,24 +696,6 @@ 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_hvr_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_HAUPPAUGE_HVR3000:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
- &hauppauge_hvr_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;
default:
printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
dev->core->name);
diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c
index 2f60c957b..30fd0776a 100644
--- a/linux/drivers/media/video/cx88/cx88-i2c.c
+++ b/linux/drivers/media/video/cx88/cx88-i2c.c
@@ -1,3 +1,4 @@
+
/*
cx88-i2c.c -- all the i2c code is here
@@ -206,7 +207,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
unsigned char buf;
int i,rc;
- for (i = 0; i < 128; i++) {
+ for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
c->addr = i;
rc = i2c_master_recv(c,&buf,0);
if (rc < 0)
diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c
index cb642ca03..861ac813e 100644
--- a/linux/drivers/media/video/cx88/cx88-mpeg.c
+++ b/linux/drivers/media/video/cx88/cx88-mpeg.c
@@ -30,6 +30,7 @@
#include <linux/device.h>
#endif
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
#include <asm/delay.h>
#include "cx88.h"
@@ -405,7 +406,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
if (debug || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq mpeg ",
- cx88_mpeg_irqs, status, mask);
+ cx88_mpeg_irqs, ARRAY_SIZE(cx88_mpeg_irqs),
+ status, mask);
/* risc op code error */
if (status & (1 << 16)) {
@@ -491,7 +493,7 @@ int cx8802_init_common(struct cx8802_dev *dev)
if (pci_enable_device(dev->pci))
return -EIO;
pci_set_master(dev->pci);
- if (!pci_dma_supported(dev->pci,0xffffffff)) {
+ if (!pci_dma_supported(dev->pci,DMA_32BIT_MASK)) {
printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
return -EIO;
}
@@ -669,7 +671,7 @@ struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board
}
/* Driver asked for hardware access. */
-int cx8802_request_acquire(struct cx8802_driver *drv)
+static int cx8802_request_acquire(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
@@ -689,7 +691,7 @@ int cx8802_request_acquire(struct cx8802_driver *drv)
}
/* Driver asked to release hardware. */
-int cx8802_request_release(struct cx8802_driver *drv)
+static int cx8802_request_release(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c
index 2e6259ceb..9b8edf555 100644
--- a/linux/drivers/media/video/cx88/cx88-video.c
+++ b/linux/drivers/media/video/cx88/cx88-video.c
@@ -39,6 +39,7 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <linux/kthread.h>
#endif
+#include <linux/dma-mapping.h>
#include <asm/div64.h>
#include "cx88.h"
@@ -1836,7 +1837,8 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
cx_write(MO_VID_INTSTAT, status);
if (irq_debug || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq vid",
- cx88_vid_irqs, status, mask);
+ cx88_vid_irqs, ARRAY_SIZE(cx88_vid_irqs),
+ status, mask);
/* risc op code error */
if (status & (1 << 16)) {
@@ -2067,7 +2069,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
pci_set_master(pci_dev);
- if (!pci_dma_supported(pci_dev,0xffffffff)) {
+ if (!pci_dma_supported(pci_dev,DMA_32BIT_MASK)) {
printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name);
err = -EIO;
goto fail_core;
diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h
index 4719046e1..a35b46cab 100644
--- a/linux/drivers/media/video/cx88/cx88.h
+++ b/linux/drivers/media/video/cx88/cx88.h
@@ -545,7 +545,7 @@ struct cx8802_dev {
/* cx88-core.c */
extern void cx88_print_irqbits(char *name, char *tag, char **strings,
- u32 bits, u32 mask);
+ int len, u32 bits, u32 mask);
extern int cx88_core_irq(struct cx88_core *core, u32 status);
extern void cx88_wakeup(struct cx88_core *core,
diff --git a/linux/drivers/media/video/em28xx/Kconfig b/linux/drivers/media/video/em28xx/Kconfig
index 9285a58e4..3823b62da 100644
--- a/linux/drivers/media/video/em28xx/Kconfig
+++ b/linux/drivers/media/video/em28xx/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_EM28XX
tristate "Empia EM2800/2820/2840 USB video capture support"
- depends on VIDEO_V4L1 && USB && I2C
+ depends on VIDEO_V4L1 && I2C
select VIDEO_BUF
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c
index 4ee4cea10..ceb71f67c 100644
--- a/linux/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c
@@ -544,7 +544,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
unsigned char buf;
int i, rc;
- for (i = 0; i < 128; i++) {
+ for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
c->addr = i;
rc = i2c_master_recv(c, &buf, 0);
if (rc < 0)
diff --git a/linux/drivers/media/video/et61x251/Kconfig b/linux/drivers/media/video/et61x251/Kconfig
index c6bff7056..664676f44 100644
--- a/linux/drivers/media/video/et61x251/Kconfig
+++ b/linux/drivers/media/video/et61x251/Kconfig
@@ -1,6 +1,6 @@
config USB_ET61X251
tristate "USB ET61X[12]51 PC Camera Controller support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want support for cameras based on Etoms ET61X151
or ET61X251 PC Camera Controllers.
diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c
index d20bad700..8d0c49782 100644
--- a/linux/drivers/media/video/ir-kbd-i2c.c
+++ b/linux/drivers/media/video/ir-kbd-i2c.c
@@ -174,7 +174,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
return -EIO;
}
- for (start = 0; start<4; start++) {
+ for (start = 0; start < ARRAY_SIZE(b); start++) {
if (b[start] == marker) {
code=b[(start+parity_offset+1)%4];
parity=b[(start+parity_offset)%4];
diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c
index 4031df6db..8fbc34db5 100644
--- a/linux/drivers/media/video/ivtv/ivtv-driver.c
+++ b/linux/drivers/media/video/ivtv/ivtv-driver.c
@@ -74,7 +74,7 @@ int ivtv_first_minor = 0;
struct ivtv *ivtv_cards[IVTV_MAX_CARDS];
/* Protects ivtv_cards_active */
-spinlock_t ivtv_cards_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ivtv_cards_lock);
/* add your revision and whatnot here */
static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c
index 1637097dd..8976487a6 100644
--- a/linux/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c
@@ -804,7 +804,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
struct ivtv_open_id *item;
struct ivtv *itv = NULL;
struct ivtv_stream *s = NULL;
- int minor = MINOR(inode->i_rdev);
+ int minor = iminor(inode);
/* Find which card this open was on */
spin_lock(&ivtv_cards_lock);
diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
index d6f0b0235..f29c55d3b 100644
--- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -289,7 +289,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
}
case VIDEO_CMD_STOP:
- vc->flags &= ~(VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK);
+ vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
vc->stop.pts = 0;
if (try) break;
@@ -302,7 +302,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
case VIDEO_CMD_FREEZE:
- vc->flags &= ~VIDEO_CMD_FREEZE_TO_BLACK;
+ vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
if (try) break;
if (itv->output_mode != OUT_MPG)
return -EBUSY;
@@ -1107,7 +1107,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
return ivtv_start_capture(id);
case V4L2_ENC_CMD_STOP:
- enc->flags &= ~V4L2_ENC_CMD_STOP_AT_GOP_END;
+ enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
if (try)
return 0;
ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
diff --git a/linux/drivers/media/video/ov7670.c b/linux/drivers/media/video/ov7670.c
index b033bf334..8b2c19df9 100644
--- a/linux/drivers/media/video/ov7670.c
+++ b/linux/drivers/media/video/ov7670.c
@@ -5,6 +5,8 @@
* by Jonathan Corbet with substantial inspiration from Mark
* McClelland's ovcamchip code.
*
+ * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
+ *
* This file may be distributed under the terms of the GNU General
* Public License, version 2.
*/
@@ -164,6 +166,10 @@ MODULE_LICENSE("GPL");
#define REG_GFIX 0x69 /* Fix gain control */
+#define REG_REG76 0x76 /* OV's name */
+#define R76_BLKPCOR 0x80 /* Black pixel correction enable */
+#define R76_WHTPCOR 0x40 /* White pixel correction enable */
+
#define REG_RGB444 0x8c /* RGB 444 control */
#define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */
#define R444_RGBX 0x01 /* Empty nibble at end */
@@ -257,7 +263,7 @@ static struct regval_list ov7670_default_regs[] = {
/* Almost all of these are magic "reserved" values. */
{ REG_COM5, 0x61 }, { REG_COM6, 0x4b },
- { 0x16, 0x02 }, { REG_MVFP, 0x07|MVFP_MIRROR },
+ { 0x16, 0x02 }, { REG_MVFP, 0x07 },
{ 0x21, 0x02 }, { 0x22, 0x91 },
{ 0x29, 0x07 }, { 0x33, 0x0b },
{ 0x35, 0x0b }, { 0x37, 0x1d },
@@ -382,6 +388,13 @@ static struct regval_list ov7670_fmt_rgb444[] = {
{ 0xff, 0xff },
};
+static struct regval_list ov7670_fmt_raw[] = {
+ { REG_COM7, COM7_BAYER },
+ { REG_COM13, 0x08 }, /* No gamma, magic rsvd bit */
+ { REG_COM16, 0x3d }, /* Edge enhancement, denoise */
+ { REG_REG76, 0xe1 }, /* Pix correction, magic rsvd */
+ { 0xff, 0xff },
+};
@@ -506,32 +519,39 @@ static struct ov7670_format_struct {
__u32 pixelformat;
struct regval_list *regs;
int cmatrix[CMATRIX_LEN];
+ int bpp; /* Bytes per pixel */
} ov7670_formats[] = {
{
.desc = "YUYV 4:2:2",
.pixelformat = V4L2_PIX_FMT_YUYV,
.regs = ov7670_fmt_yuv422,
.cmatrix = { 128, -128, 0, -34, -94, 128 },
+ .bpp = 2,
},
{
.desc = "RGB 444",
.pixelformat = V4L2_PIX_FMT_RGB444,
.regs = ov7670_fmt_rgb444,
.cmatrix = { 179, -179, 0, -61, -176, 228 },
+ .bpp = 2,
},
{
.desc = "RGB 565",
.pixelformat = V4L2_PIX_FMT_RGB565,
.regs = ov7670_fmt_rgb565,
.cmatrix = { 179, -179, 0, -61, -176, 228 },
+ .bpp = 2,
+ },
+ {
+ .desc = "Raw RGB Bayer",
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .regs = ov7670_fmt_raw,
+ .cmatrix = { 0, 0, 0, 0, 0, 0 },
+ .bpp = 1
},
};
-#define N_OV7670_FMTS (sizeof(ov7670_formats)/sizeof(ov7670_formats[0]))
+#define N_OV7670_FMTS ARRAY_SIZE(ov7670_formats)
-/*
- * All formats we support are 2 bytes/pixel.
- */
-#define BYTES_PER_PIXEL 2
/*
* Then there is the issue of window sizes. Try to capture the info here.
@@ -708,7 +728,7 @@ static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
*/
pix->width = wsize->width;
pix->height = wsize->height;
- pix->bytesperline = pix->width*BYTES_PER_PIXEL;
+ pix->bytesperline = pix->width*ov7670_formats[index].bpp;
pix->sizeimage = pix->height*pix->bytesperline;
return 0;
}
diff --git a/linux/drivers/media/video/planb.c b/linux/drivers/media/video/planb.c
index c393b26e1..c6f2dc6cf 100644
--- a/linux/drivers/media/video/planb.c
+++ b/linux/drivers/media/video/planb.c
@@ -2216,7 +2216,7 @@ static int find_planb(void)
"membase 0x%x (base reg. 0x%x)\n",
bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg);
- pdev = pci_find_slot (bus, dev_fn);
+ pdev = pci_get_bus_and_slot(bus, dev_fn);
if (!pdev) {
printk(KERN_ERR "planb: cannot find slot\n");
goto err_out;
@@ -2246,6 +2246,7 @@ static int find_planb(void)
pb->planb_base = planb_regs;
pb->planb_base_phys = (struct planb_registers *)new_base;
pb->irq = irq;
+ pb->dev = pdev;
return planb_num;
@@ -2253,6 +2254,7 @@ err_out_disable:
pci_disable_device(pdev);
err_out:
/* FIXME handle error */ /* comment moved from pci_find_slot, above */
+ pci_dev_put(pdev);
return 0;
}
@@ -2280,6 +2282,8 @@ static void release_planb(void)
printk(KERN_INFO "PlanB: unregistering with v4l\n");
video_unregister_device(&pb->video_dev);
+ pci_dev_put(pb->dev);
+
/* note that iounmap() does nothing on the PPC right now */
iounmap ((void *)pb->planb_base);
}
diff --git a/linux/drivers/media/video/planb.h b/linux/drivers/media/video/planb.h
index 92823211d..e21b5735c 100644
--- a/linux/drivers/media/video/planb.h
+++ b/linux/drivers/media/video/planb.h
@@ -177,6 +177,7 @@ struct planb {
struct mutex lock;
unsigned int irq; /* interrupt number */
volatile unsigned int intr_mask;
+ struct pci_dev *dev; /* Our PCI device */
int overlay; /* overlay running? */
struct planb_window win;
diff --git a/linux/drivers/media/video/pvrusb2/Kconfig b/linux/drivers/media/video/pvrusb2/Kconfig
index 5645c9318..d0c2cd785 100644
--- a/linux/drivers/media/video/pvrusb2/Kconfig
+++ b/linux/drivers/media/video/pvrusb2/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_PVRUSB2
tristate "Hauppauge WinTV-PVR USB2 support"
- depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
select FW_LOADER
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index a7424f847..4abee970c 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -424,22 +424,29 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
int pvr2_encoder_configure(struct pvr2_hdw *hdw)
{
int ret;
+ int val;
pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure"
" (cx2341x module)");
hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING;
hdw->enc_ctl_state.width = hdw->res_hor_val;
hdw->enc_ctl_state.height = hdw->res_ver_val;
- hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur &
- (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ?
+ hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ?
0 : 1);
ret = 0;
ret |= pvr2_encoder_prep_config(hdw);
+ /* saa7115: 0xf0 */
+ val = 0xf0;
+ if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ /* ivtv cx25840: 0x140 */
+ val = 0x140;
+ }
+
if (!ret) ret = pvr2_encoder_vcmd(
hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
- 0xf0, 0xf0);
+ val, val);
/* setup firmware to notify us about some events (don't know why...) */
if (!ret) ret = pvr2_encoder_vcmd(
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index db0b02f0f..e8ee1bf73 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -299,6 +299,8 @@ struct pvr2_hdw {
int unit_number; /* ID for driver instance */
unsigned long serial_number; /* ID for hardware itself */
+ char bus_info[32]; /* Bus location info */
+
/* Minor numbers used by v4l logic (yes, this is a hack, as there
should be no v4l junk here). Probably a better way to do this. */
int v4l_minor_number_video;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index d1de5cd59..52078f4d0 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -84,7 +84,7 @@ static struct pvr2_string_table pvr2_client_lists[] = {
};
static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
-static DECLARE_MUTEX(pvr2_unit_sem);
+static DEFINE_MUTEX(pvr2_unit_mtx);
static int ctlchg = 0;
static int initusbreset = 1;
@@ -1009,6 +1009,13 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
return hdw->serial_number;
}
+
+const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
+{
+ return hdw->bus_info;
+}
+
+
unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
{
return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
@@ -1258,10 +1265,10 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
LOCK_TAKE(hdw->ctl_lock); do {
hdw->cmd_buffer[0] = FX2CMD_FWPOST1;
- ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
+ ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
hdw->cmd_buffer[1] = 0;
- ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0);
+ ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
} while (0); LOCK_GIVE(hdw->ctl_lock);
if (ret) {
@@ -1330,7 +1337,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
LOCK_TAKE(hdw->ctl_lock); do {
hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
hdw->cmd_buffer[1] = 0;
- ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0);
+ ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
} while (0); LOCK_GIVE(hdw->ctl_lock);
if (ret) {
@@ -2096,14 +2103,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
if (!hdw->ctl_read_urb) goto fail;
- down(&pvr2_unit_sem); do {
+ mutex_lock(&pvr2_unit_mtx); do {
for (idx = 0; idx < PVR_NUM; idx++) {
if (unit_pointers[idx]) continue;
hdw->unit_number = idx;
unit_pointers[idx] = hdw;
break;
}
- } while (0); up(&pvr2_unit_sem);
+ } while (0); mutex_unlock(&pvr2_unit_mtx);
cnt1 = 0;
cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
@@ -2132,6 +2139,11 @@ 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",
+ hdw->usb_dev->dev.bus_id,
+ hdw->usb_dev->devnum);
+
ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
usb_set_interface(hdw->usb_dev,ifnum,0);
@@ -2201,13 +2213,13 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
}
pvr2_i2c_core_done(hdw);
pvr2_hdw_remove_usb_stuff(hdw);
- down(&pvr2_unit_sem); do {
+ mutex_lock(&pvr2_unit_mtx); do {
if ((hdw->unit_number >= 0) &&
(hdw->unit_number < PVR_NUM) &&
(unit_pointers[hdw->unit_number] == hdw)) {
unit_pointers[hdw->unit_number] = NULL;
}
- } while (0); up(&pvr2_unit_sem);
+ } while (0); mutex_unlock(&pvr2_unit_mtx);
kfree(hdw->controls);
kfree(hdw->mpeg_ctrl_info);
kfree(hdw->std_defs);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 319dab523..6e4cd7976 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -133,6 +133,9 @@ struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *);
/* Retrieve serial number of device */
unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
+/* Retrieve bus location info of device */
+const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *);
+
/* Called when hardware has been unplugged */
void pvr2_hdw_disconnect(struct pvr2_hdw *);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 22a02dd76..1a9563aa5 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -23,6 +23,7 @@
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
#include "pvrusb2-fx2-cmd.h"
+#include "pvrusb2.h"
#include "compat.h"
#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
@@ -39,6 +40,10 @@ static unsigned int i2c_scan = 0;
module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
+static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
+module_param_array(ir_mode, int, NULL, 0444);
+MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
+
static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
unsigned int detail,
char *buf,unsigned int maxlen);
@@ -348,6 +353,15 @@ static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
}
+/* This is an entry point designed to always fail any attempt to perform a
+ transfer. We use this to cause certain I2C addresses to not be
+ probed. */
+static int i2c_black_hole(struct pvr2_hdw *hdw,
+ u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
+{
+ return -EIO;
+}
+
/* This is a special entry point that is entered if an I2C operation is
attempted to a cx25840 chip on model 24xxx hardware. This chip can
sometimes wedge itself. Worse still, when this happens msp3400 can
@@ -1080,10 +1094,17 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
}
/* However, deal with various special cases for 24xxx hardware. */
+ if (ir_mode[hdw->unit_number] == 0) {
+ printk(KERN_INFO "%s: IR disabled\n",hdw->name);
+ hdw->i2c_func[0x18] = i2c_black_hole;
+ } else if (ir_mode[hdw->unit_number] == 1) {
+ if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ hdw->i2c_func[0x18] = i2c_24xxx_ir;
+ }
+ }
if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
hdw->i2c_func[0x1b] = i2c_hack_wm8775;
hdw->i2c_func[0x44] = i2c_hack_cx25840;
- hdw->i2c_func[0x18] = i2c_24xxx_ir;
}
// Configure the adapter and set up everything else related to it.
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 4e3dd17dc..e28cc23ea 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -43,9 +43,11 @@ struct pvr2_sysfs {
struct class_device_attribute attr_v4l_minor_number;
struct class_device_attribute attr_v4l_radio_minor_number;
struct class_device_attribute attr_unit_number;
+ struct class_device_attribute attr_bus_info;
int v4l_minor_number_created_ok;
int v4l_radio_minor_number_created_ok;
int unit_number_created_ok;
+ int bus_info_created_ok;
};
#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
@@ -517,40 +519,32 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
}
sfp->item_last = cip;
- cip->attr_name.attr.owner = THIS_MODULE;
cip->attr_name.attr.name = "name";
cip->attr_name.attr.mode = S_IRUGO;
cip->attr_name.show = fp->show_name;
- cip->attr_type.attr.owner = THIS_MODULE;
cip->attr_type.attr.name = "type";
cip->attr_type.attr.mode = S_IRUGO;
cip->attr_type.show = fp->show_type;
- cip->attr_min.attr.owner = THIS_MODULE;
cip->attr_min.attr.name = "min_val";
cip->attr_min.attr.mode = S_IRUGO;
cip->attr_min.show = fp->show_min;
- cip->attr_max.attr.owner = THIS_MODULE;
cip->attr_max.attr.name = "max_val";
cip->attr_max.attr.mode = S_IRUGO;
cip->attr_max.show = fp->show_max;
- cip->attr_val.attr.owner = THIS_MODULE;
cip->attr_val.attr.name = "cur_val";
cip->attr_val.attr.mode = S_IRUGO;
- cip->attr_custom.attr.owner = THIS_MODULE;
cip->attr_custom.attr.name = "custom_val";
cip->attr_custom.attr.mode = S_IRUGO;
- cip->attr_enum.attr.owner = THIS_MODULE;
cip->attr_enum.attr.name = "enum_val";
cip->attr_enum.attr.mode = S_IRUGO;
cip->attr_enum.show = fp->show_enum;
- cip->attr_bits.attr.owner = THIS_MODULE;
cip->attr_bits.attr.name = "bit_val";
cip->attr_bits.attr.mode = S_IRUGO;
cip->attr_bits.show = fp->show_bits;
@@ -615,12 +609,10 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
dip = kzalloc(sizeof(*dip),GFP_KERNEL);
if (!dip) return;
- dip->attr_debugcmd.attr.owner = THIS_MODULE;
dip->attr_debugcmd.attr.name = "debugcmd";
dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
dip->attr_debugcmd.show = debugcmd_show;
dip->attr_debugcmd.store = debugcmd_store;
- dip->attr_debuginfo.attr.owner = THIS_MODULE;
dip->attr_debuginfo.attr.name = "debuginfo";
dip->attr_debuginfo.attr.mode = S_IRUGO;
dip->attr_debuginfo.show = debuginfo_show;
@@ -706,6 +698,10 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
pvr2_sysfs_tear_down_debugifc(sfp);
#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
pvr2_sysfs_tear_down_controls(sfp);
+ if (sfp->bus_info_created_ok) {
+ class_device_remove_file(sfp->class_dev,
+ &sfp->attr_bus_info);
+ }
if (sfp->v4l_minor_number_created_ok) {
class_device_remove_file(sfp->class_dev,
&sfp->attr_v4l_minor_number);
@@ -736,6 +732,16 @@ static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf)
}
+static ssize_t bus_info_show(struct class_device *class_dev,char *buf)
+{
+ struct pvr2_sysfs *sfp;
+ sfp = (struct pvr2_sysfs *)class_dev->class_data;
+ if (!sfp) return -EINVAL;
+ return scnprintf(buf,PAGE_SIZE,"%s\n",
+ pvr2_hdw_get_bus_info(sfp->channel.hdw));
+}
+
+
static ssize_t v4l_radio_minor_number_show(struct class_device *class_dev,
char *buf)
{
@@ -796,7 +802,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
return;
}
- sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE;
sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
@@ -810,7 +815,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_minor_number_created_ok = !0;
}
- sfp->attr_v4l_radio_minor_number.attr.owner = THIS_MODULE;
sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
@@ -824,7 +828,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_radio_minor_number_created_ok = !0;
}
- sfp->attr_unit_number.attr.owner = THIS_MODULE;
sfp->attr_unit_number.attr.name = "unit_number";
sfp->attr_unit_number.attr.mode = S_IRUGO;
sfp->attr_unit_number.show = unit_number_show;
@@ -837,6 +840,19 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->unit_number_created_ok = !0;
}
+ sfp->attr_bus_info.attr.name = "bus_info_str";
+ sfp->attr_bus_info.attr.mode = S_IRUGO;
+ sfp->attr_bus_info.show = bus_info_show;
+ sfp->attr_bus_info.store = NULL;
+ ret = class_device_create_file(sfp->class_dev,
+ &sfp->attr_bus_info);
+ if (ret < 0) {
+ printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+ __FUNCTION__, ret);
+ } else {
+ sfp->bus_info_created_ok = !0;
+ }
+
pvr2_sysfs_add_controls(sfp);
#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
pvr2_sysfs_add_debugifc(sfp);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 9f2f11754..a8a8a36ee 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -204,6 +204,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_capability *cap = arg;
memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
+ strlcpy(cap->bus_info,pvr2_hdw_get_bus_info(hdw),
+ sizeof(cap->bus_info));
ret = 0;
break;
@@ -809,11 +811,11 @@ static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
{
if (vp->dev_video) {
pvr2_v4l2_dev_destroy(vp->dev_video);
- vp->dev_video = 0;
+ vp->dev_video = NULL;
}
if (vp->dev_radio) {
pvr2_v4l2_dev_destroy(vp->dev_radio);
- vp->dev_radio = 0;
+ vp->dev_radio = NULL;
}
pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
@@ -1142,7 +1144,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
#endif
int mindevnum;
int unit_number;
- int *nr_ptr = 0;
+ int *nr_ptr = NULL;
dip->v4lp = vp;
#if 0
diff --git a/linux/drivers/media/video/pwc/Kconfig b/linux/drivers/media/video/pwc/Kconfig
index 8fdf7101d..7298cf2e1 100644
--- a/linux/drivers/media/video/pwc/Kconfig
+++ b/linux/drivers/media/video/pwc/Kconfig
@@ -1,6 +1,6 @@
config USB_PWC
tristate "USB Philips Cameras"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y or M here if you want to use one of these Philips & OEM
webcams:
diff --git a/linux/drivers/media/video/pwc/pwc-ctrl.c b/linux/drivers/media/video/pwc/pwc-ctrl.c
index acd8d4af1..9cc416a59 100644
--- a/linux/drivers/media/video/pwc/pwc-ctrl.c
+++ b/linux/drivers/media/video/pwc/pwc-ctrl.c
@@ -140,6 +140,8 @@ static const char *size2name[PSZ_MAX] =
An alternate value of 0 means this mode is not available at all.
*/
+#define PWC_FPS_MAX_NALA 8
+
struct Nala_table_entry {
char alternate; /* USB alternate setting */
int compressed; /* Compressed yes/no */
@@ -147,7 +149,9 @@ struct Nala_table_entry {
unsigned char mode[3]; /* precomputed mode table */
};
-static struct Nala_table_entry Nala_table[PSZ_MAX][8] =
+static unsigned int Nala_fps_vector[PWC_FPS_MAX_NALA] = { 4, 5, 7, 10, 12, 15, 20, 24 };
+
+static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
{
#include "pwc-nala.h"
};
@@ -423,6 +427,59 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
return 0;
}
+static unsigned int pwc_get_fps_Nala(struct pwc_device *pdev, unsigned int index, unsigned int size)
+{
+ unsigned int i;
+
+ for (i = 0; i < PWC_FPS_MAX_NALA; i++) {
+ if (Nala_table[size][i].alternate) {
+ if (index--==0) return Nala_fps_vector[i];
+ }
+ }
+ return 0;
+}
+
+static unsigned int pwc_get_fps_Kiara(struct pwc_device *pdev, unsigned int index, unsigned int size)
+{
+ unsigned int i;
+
+ for (i = 0; i < PWC_FPS_MAX_KIARA; i++) {
+ if (Kiara_table[size][i][3].alternate) {
+ if (index--==0) return Kiara_fps_vector[i];
+ }
+ }
+ return 0;
+}
+
+static unsigned int pwc_get_fps_Timon(struct pwc_device *pdev, unsigned int index, unsigned int size)
+{
+ unsigned int i;
+
+ for (i=0; i < PWC_FPS_MAX_TIMON; i++) {
+ if (Timon_table[size][i][3].alternate) {
+ if (index--==0) return Timon_fps_vector[i];
+ }
+ }
+ return 0;
+}
+
+unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size)
+{
+ unsigned int ret;
+
+ if (DEVICE_USE_CODEC1(pdev->type)) {
+ ret = pwc_get_fps_Nala(pdev, index, size);
+
+ } else if (DEVICE_USE_CODEC3(pdev->type)) {
+ ret = pwc_get_fps_Kiara(pdev, index, size);
+
+ } else {
+ ret = pwc_get_fps_Timon(pdev, index, size);
+ }
+
+ return ret;
+}
+
#define BLACK_Y 0
#define BLACK_U 128
#define BLACK_V 128
@@ -1362,7 +1419,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red);
if (ret < 0)
break;
- ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
+ ret = pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
if (ret < 0)
break;
}
diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c
index 782699cf9..282ec2153 100644
--- a/linux/drivers/media/video/pwc/pwc-if.c
+++ b/linux/drivers/media/video/pwc/pwc-if.c
@@ -95,8 +95,8 @@ static const struct usb_device_id pwc_device_table [] = {
{ USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
{ USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
{ USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
- { USB_DEVICE(0x046D, 0x08B6) }, /* Logitech (reserved) */
- { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech (reserved) */
+ { USB_DEVICE(0x046D, 0x08B6) }, /* Cisco VT Camera */
+ { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech ViewPort AV 100 */
{ USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
{ USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
{ USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
@@ -1541,7 +1541,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
case 0x0329:
PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
name = "Philips SPC 900NC webcam";
- type_id = 720;
+ type_id = 740;
break;
default:
return -ENODEV;
@@ -1595,8 +1595,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
features |= FEATURE_MOTOR_PANTILT;
break;
case 0x08b6:
+ PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n");
+ name = "Cisco VT Camera";
+ type_id = 740; /* CCD sensor */
+ break;
case 0x08b7:
- case 0x08b8:
+ PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n");
+ name = "Logitech ViewPort AV 100";
+ type_id = 740; /* CCD sensor */
+ break;
+ case 0x08b8: /* Where this released? */
PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
name = "Logitech QuickCam (res.)";
type_id = 730; /* Assuming CMOS */
diff --git a/linux/drivers/media/video/pwc/pwc-ioctl.h b/linux/drivers/media/video/pwc/pwc-ioctl.h
index 784bc7252..58904acda 100644
--- a/linux/drivers/media/video/pwc/pwc-ioctl.h
+++ b/linux/drivers/media/video/pwc/pwc-ioctl.h
@@ -2,7 +2,7 @@
#define PWC_IOCTL_H
/* (C) 2001-2004 Nemosoft Unv.
- (C) 2004 Luc Saillard (luc@saillard.org)
+ (C) 2004-2006 Luc Saillard (luc@saillard.org)
NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
driver and thus may have bugs that are not present in the original version.
@@ -25,7 +25,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* This is pwc-ioctl.h belonging to PWC 8.12.1
+/* This is pwc-ioctl.h belonging to PWC 10.0.10
It contains structures and defines to communicate from user space
directly to the driver.
*/
@@ -51,6 +51,13 @@
... the function
*/
+#include <linux/types.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 10)
+/* Compatibility for older kernel */
+typedef __u16 __le16;
+#endif
/* Enumeration of image sizes */
#define PSZ_SQCIF 0x00
@@ -65,6 +72,8 @@
/* The frame rate is encoded in the video_window.flags parameter using
the upper 16 bits, since some flags are defined nowadays. The following
defines provide a mask and shift to filter out this value.
+ This value can also be passing using the private flag when using v4l2 and
+ VIDIOC_S_FMT ioctl.
In 'Snapshot' mode the camera freezes its automatic exposure and colour
balance controls.
@@ -73,6 +82,8 @@
#define PWC_FPS_MASK 0x00FF0000
#define PWC_FPS_FRMASK 0x003F0000
#define PWC_FPS_SNAPSHOT 0x00400000
+#define PWC_QLT_MASK 0x03000000
+#define PWC_QLT_SHIFT 24
/* structure for transferring x & y coordinates */
@@ -289,4 +300,29 @@ struct pwc_table_init_buffer {
};
#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer)
+/*
+ * This is private command used when communicating with v4l2.
+ * In the future all private ioctl will be remove/replace to
+ * use interface offer by v4l2.
+ */
+
+#define V4L2_CID_PRIVATE_SAVE_USER (V4L2_CID_PRIVATE_BASE + 0)
+#define V4L2_CID_PRIVATE_RESTORE_USER (V4L2_CID_PRIVATE_BASE + 1)
+#define V4L2_CID_PRIVATE_RESTORE_FACTORY (V4L2_CID_PRIVATE_BASE + 2)
+#define V4L2_CID_PRIVATE_COLOUR_MODE (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_PRIVATE_AUTOCONTOUR (V4L2_CID_PRIVATE_BASE + 4)
+#define V4L2_CID_PRIVATE_CONTOUR (V4L2_CID_PRIVATE_BASE + 5)
+#define V4L2_CID_PRIVATE_BACKLIGHT (V4L2_CID_PRIVATE_BASE + 6)
+#define V4L2_CID_PRIVATE_FLICKERLESS (V4L2_CID_PRIVATE_BASE + 7)
+#define V4L2_CID_PRIVATE_NOISE_REDUCTION (V4L2_CID_PRIVATE_BASE + 8)
+
+struct pwc_raw_frame {
+ __le16 type; /* type of the webcam */
+ __le16 vbandlength; /* Size of 4lines compressed (used by the decompressor) */
+ __u8 cmd[4]; /* the four byte of the command (in case of nala,
+ only the first 3 bytes is filled) */
+ __u8 rawframe[0]; /* frame_size = H/4*vbandlength */
+} __attribute__ ((packed));
+
+
#endif
diff --git a/linux/drivers/media/video/pwc/pwc-kiara.c b/linux/drivers/media/video/pwc/pwc-kiara.c
index fec39cc5a..f4ae83c0c 100644
--- a/linux/drivers/media/video/pwc/pwc-kiara.c
+++ b/linux/drivers/media/video/pwc/pwc-kiara.c
@@ -42,6 +42,8 @@
#include "pwc-kiara.h"
#include "pwc-uncompress.h"
+const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA] = { 5, 10, 15, 20, 25, 30 };
+
const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
{
/* SQCIF */
diff --git a/linux/drivers/media/video/pwc/pwc-kiara.h b/linux/drivers/media/video/pwc/pwc-kiara.h
index 0bdb22547..047dad8c1 100644
--- a/linux/drivers/media/video/pwc/pwc-kiara.h
+++ b/linux/drivers/media/video/pwc/pwc-kiara.h
@@ -29,6 +29,8 @@
#include <media/pwc-ioctl.h>
+#define PWC_FPS_MAX_KIARA 6
+
struct Kiara_table_entry
{
char alternate; /* USB alternate interface */
@@ -37,8 +39,9 @@ struct Kiara_table_entry
unsigned char mode[12]; /* precomputed mode settings for cam */
};
-extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4];
+extern const struct Kiara_table_entry Kiara_table[PSZ_MAX][PWC_FPS_MAX_KIARA][4];
extern const unsigned int KiaraRomTable[8][2][16][8];
+extern const unsigned int Kiara_fps_vector[PWC_FPS_MAX_KIARA];
#endif
diff --git a/linux/drivers/media/video/pwc/pwc-timon.c b/linux/drivers/media/video/pwc/pwc-timon.c
index be65bdcd1..c56c174b1 100644
--- a/linux/drivers/media/video/pwc/pwc-timon.c
+++ b/linux/drivers/media/video/pwc/pwc-timon.c
@@ -40,7 +40,9 @@
#include "pwc-timon.h"
-const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
+const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON] = { 5, 10, 15, 20, 25, 30 };
+
+const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4] =
{
/* SQCIF */
{
diff --git a/linux/drivers/media/video/pwc/pwc-timon.h b/linux/drivers/media/video/pwc/pwc-timon.h
index eef9e2cd4..a6e22224c 100644
--- a/linux/drivers/media/video/pwc/pwc-timon.h
+++ b/linux/drivers/media/video/pwc/pwc-timon.h
@@ -44,6 +44,8 @@
#include <media/pwc-ioctl.h>
+#define PWC_FPS_MAX_TIMON 6
+
struct Timon_table_entry
{
char alternate; /* USB alternate interface */
@@ -52,9 +54,9 @@ struct Timon_table_entry
unsigned char mode[13]; /* precomputed mode settings for cam */
};
-extern const struct Timon_table_entry Timon_table[PSZ_MAX][6][4];
+extern const struct Timon_table_entry Timon_table[PSZ_MAX][PWC_FPS_MAX_TIMON][4];
extern const unsigned int TimonRomTable [16][2][16][8];
-
+extern const unsigned int Timon_fps_vector[PWC_FPS_MAX_TIMON];
#endif
diff --git a/linux/drivers/media/video/pwc/pwc-v4l.c b/linux/drivers/media/video/pwc/pwc-v4l.c
index 2d5bb48f3..32fbe1ae6 100644
--- a/linux/drivers/media/video/pwc/pwc-v4l.c
+++ b/linux/drivers/media/video/pwc/pwc-v4l.c
@@ -127,7 +127,6 @@ static struct v4l2_queryctrl pwc_controls[] = {
.step = 1,
.default_value = 0,
},
-#ifndef BROKEN_XAWTV
{
.id = V4L2_CID_PRIVATE_SAVE_USER,
.type = V4L2_CTRL_TYPE_BUTTON,
@@ -209,7 +208,6 @@ static struct v4l2_queryctrl pwc_controls[] = {
.step = 1,
.default_value = 0,
},
-#endif
};
@@ -1170,7 +1168,7 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file,
buf->sequence = 0;
buf->memory = V4L2_MEMORY_MMAP;
buf->m.offset = pdev->fill_image * pdev->len_per_image;
- buf->length = buf->bytesused;
+ buf->length = pdev->len_per_image;
pwc_next_image(pdev);
PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index);
@@ -1195,6 +1193,64 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file,
return 0;
}
+ case VIDIOC_ENUM_FRAMESIZES:
+ {
+ struct v4l2_frmsizeenum *fsize = arg;
+ unsigned int i = 0, index = fsize->index;
+
+ if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
+ for (i = 0; i < PSZ_MAX; i++) {
+ if (pdev->image_mask & (1UL << i)) {
+ if (!index--) {
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = pwc_image_sizes[i].x;
+ fsize->discrete.height = pwc_image_sizes[i].y;
+ return 0;
+ }
+ }
+ }
+ } else if (fsize->index == 0 &&
+ ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
+ (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = pdev->abs_max.x;
+ fsize->discrete.height = pdev->abs_max.y;
+ return 0;
+ }
+ return -EINVAL;
+ }
+
+ case VIDIOC_ENUM_FRAMEINTERVALS:
+ {
+ struct v4l2_frmivalenum *fival = arg;
+ int size = -1;
+ unsigned int i;
+
+ for (i = 0; i < PSZ_MAX; i++) {
+ if (pwc_image_sizes[i].x == fival->width &&
+ pwc_image_sizes[i].y == fival->height) {
+ size = i;
+ break;
+ }
+ }
+
+ /* TODO: Support raw format */
+ if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) {
+ return -EINVAL;
+ }
+
+ i = pwc_get_fps(pdev, fival->index, size);
+ if (!i)
+ return -EINVAL;
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete.numerator = 1;
+ fival->discrete.denominator = i;
+
+ return 0;
+ }
+
default:
return pwc_ioctl(pdev, cmd, arg);
} /* ..switch */
diff --git a/linux/drivers/media/video/pwc/pwc.h b/linux/drivers/media/video/pwc/pwc.h
index e778a2b8c..acbb93129 100644
--- a/linux/drivers/media/video/pwc/pwc.h
+++ b/linux/drivers/media/video/pwc/pwc.h
@@ -44,7 +44,7 @@
#define PWC_MINOR 0
#define PWC_EXTRAMINOR 12
#define PWC_VERSION_CODE KERNEL_VERSION(PWC_MAJOR,PWC_MINOR,PWC_EXTRAMINOR)
-#define PWC_VERSION "10.0.12"
+#define PWC_VERSION "10.0.13"
#define PWC_NAME "pwc"
#define PFX PWC_NAME ": "
@@ -85,7 +85,7 @@
#define PWC_INFO(fmt, args...) printk(KERN_INFO PFX fmt, ##args)
#define PWC_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args)
-#else /* if ! CONFIG_PWC_DEBUG */
+#else /* if ! CONFIG_USB_PWC_DEBUG */
#define PWC_ERROR(fmt, args...) printk(KERN_ERR PFX fmt, ##args)
#define PWC_WARNING(fmt, args...) printk(KERN_WARNING PFX fmt, ##args)
@@ -287,6 +287,7 @@ void pwc_construct(struct pwc_device *pdev);
/** Functions in pwc-ctrl.c */
/* Request a certain video mode. Returns < 0 if not possible */
extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot);
+extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
/* Calculate the number of bytes per image (not frame) */
extern int pwc_mpt_reset(struct pwc_device *pdev, int flags);
extern int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt);
diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c
index 5e8a2f498..a722ae8bd 100644
--- a/linux/drivers/media/video/saa7134/saa7134-cards.c
+++ b/linux/drivers/media/video/saa7134/saa7134-cards.c
@@ -1171,6 +1171,42 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
},
},
+ [SAA7134_BOARD_ECS_TVP3XP_4CB6] = {
+ /* Barry Scott <barry.scott@onelan.co.uk> */
+ .name = "Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM)",
+ .audio_clock = 0x187de7,
+ .tuner_type = TUNER_PHILIPS_PAL_I,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_tv_mono,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = "CVid over SVid",
+ .vmux = 0,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
[SAA7134_BOARD_AVACSSMARTTV] = {
/* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
.name = "AVACS SmartTV",
@@ -1544,12 +1580,12 @@ struct saa7134_board saa7134_boards[] = {
},{
.name = name_comp1,
.vmux = 0,
- .amux = LINE2,
+ .amux = LINE1,
.gpio = 0x02,
},{
.name = name_svideo,
.vmux = 6,
- .amux = LINE2,
+ .amux = LINE1,
.gpio = 0x02,
}},
.radio = {
@@ -2755,6 +2791,35 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
},
},
+ [SAA7134_BOARD_KWORLD_DVBT_210] = {
+ .name = "KWorld DVB-T 210",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .gpiomask = 1 << 21,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0200000,
+ },
+ },
[SAA7134_BOARD_KWORLD_ATSC110] = {
.name = "Kworld ATSC110",
.audio_clock = 0x00187de7,
@@ -3447,6 +3512,36 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x0200000,
},
},
+ [SAA7134_BOARD_SABRENT_TV_PCB05] = {
+ .name = "Sabrent PCMCIA TV-PCB05",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_comp2,
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ },
+ },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3555,7 +3650,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5168, /* Animation Technologies (LifeView) */
- .subdevice = 0x0214, /* Standard PCI, LR214WF */
+ .subdevice = 0x0214, /* Standard PCI, LR214 Rev E and earlier (SAA7135) */
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x5168, /* Animation Technologies (LifeView) */
+ .subdevice = 0x5214, /* Standard PCI, LR214 Rev F onwards (SAA7131) */
.driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
@@ -3729,6 +3830,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x1019,
+ .subdevice = 0x4cb6,
+ .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB6,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x12ab,
.subdevice = 0x0800,
@@ -3955,6 +4062,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_TEVION_DVBT_220RF,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x17de,
+ .subdevice = 0x7250,
+ .driver_data = SAA7134_BOARD_KWORLD_DVBT_210,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
.subvendor = 0x17de,
.subdevice = 0x7350,
@@ -4140,6 +4253,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x4857,
.driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
},{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x0919, /* SinoVideo PCI 2309 Proteus (7134) */
+ .subdevice = 0x2003, /* OEM cardbus */
+ .driver_data = SAA7134_BOARD_SABRENT_TV_PCB05,
+ },{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -4255,6 +4374,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_CINERGY600_MK3:
case SAA7134_BOARD_ECS_TVP3XP:
case SAA7134_BOARD_ECS_TVP3XP_4CB5:
+ case SAA7134_BOARD_ECS_TVP3XP_4CB6:
case SAA7134_BOARD_MD2819:
case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
case SAA7134_BOARD_KWORLD_XPERT:
@@ -4503,6 +4623,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_PINNACLE_PCTV_310i:
+ case SAA7134_BOARD_KWORLD_DVBT_210:
case SAA7134_BOARD_TEVION_DVBT_220RF:
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c
index 752e90e97..12af25bd1 100644
--- a/linux/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c
@@ -888,6 +888,20 @@ static struct tda1004x_config asus_p7131_hybrid_lna_config = {
.antenna_switch= 2,
.request_firmware = philips_tda1004x_request_firmware
};
+static struct tda1004x_config kworld_dvb_t_210_config = {
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .gpio_config = TDA10046_GP11_I,
+ .if_freq = TDA10046_FREQ_045,
+ .i2c_gate = 0x4b,
+ .tuner_address = 0x61,
+ .tuner_config = 2,
+ .antenna_switch= 1,
+ .request_firmware = philips_tda1004x_request_firmware
+};
/* ------------------------------------------------------------------
* special case: this card uses saa713x GPIO22 for the mode switch
*/
@@ -1040,6 +1054,9 @@ static int dvb_init(struct saa7134_dev *dev)
dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
}
break;
+ case SAA7134_BOARD_KWORLD_DVBT_210:
+ configure_tda827x_fe(dev, &kworld_dvb_t_210_config);
+ break;
case SAA7134_BOARD_PHILIPS_TIGER:
configure_tda827x_fe(dev, &philips_tiger_config);
break;
@@ -1178,6 +1195,8 @@ static int dvb_init(struct saa7134_dev *dev)
dev->dvb.frontend->ops.init(dev->dvb.frontend);
if (dev->dvb.frontend->ops.sleep)
dev->dvb.frontend->ops.sleep(dev->dvb.frontend);
+ if (dev->dvb.frontend->ops.tuner_ops.sleep)
+ dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
}
return ret;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c
index 1d41abee5..f470c85e7 100644
--- a/linux/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c
@@ -465,7 +465,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
unsigned char buf;
int i,rc;
- for (i = 0; i < 128; i++) {
+ for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
c->addr = i;
rc = i2c_master_recv(c,&buf,0);
if (rc < 0)
diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c
index 24d3f5088..c1ab20e63 100644
--- a/linux/drivers/media/video/saa7134/saa7134-input.c
+++ b/linux/drivers/media/video/saa7134/saa7134-input.c
@@ -322,6 +322,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keydown = 0x0040000;
break;
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
+ case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
ir_codes = ir_codes_asus_pc39;
mask_keydown = 0x0040000;
rc5_gpio = 1;
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index aa9d73c6b..dd028dec3 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -242,6 +242,9 @@ struct saa7134_format {
#define SAA7134_BOARD_AVERMEDIA_M102 110
#define SAA7134_BOARD_ASUS_P7131_4871 111
#define SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA 112
+#define SAA7134_BOARD_ECS_TVP3XP_4CB6 113
+#define SAA7134_BOARD_KWORLD_DVBT_210 114
+#define SAA7134_BOARD_SABRENT_TV_PCB05 115
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
diff --git a/linux/drivers/media/video/se401.c b/linux/drivers/media/video/se401.c
index eecb4002e..bf8a6d560 100644
--- a/linux/drivers/media/video/se401.c
+++ b/linux/drivers/media/video/se401.c
@@ -458,6 +458,13 @@ static int se401_start_stream(struct usb_se401 *se401)
}
for (i=0; i<SE401_NUMSBUF; i++) {
se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
+ if (!se401->sbuf[i].data) {
+ for(i = i - 1; i >= 0; i--) {
+ kfree(se401->sbuf[i].data);
+ se401->sbuf[i].data = NULL;
+ }
+ return -ENOMEM;
+ }
}
se401->bayeroffset=0;
@@ -466,13 +473,26 @@ static int se401_start_stream(struct usb_se401 *se401)
se401->scratch_overflow=0;
for (i=0; i<SE401_NUMSCRATCH; i++) {
se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
+ if (!se401->scratch[i].data) {
+ for(i = i - 1; i >= 0; i--) {
+ kfree(se401->scratch[i].data);
+ se401->scratch[i].data = NULL;
+ }
+ goto nomem_sbuf;
+ }
se401->scratch[i].state=BUFFER_UNUSED;
}
for (i=0; i<SE401_NUMSBUF; i++) {
urb=usb_alloc_urb(0, GFP_KERNEL);
- if(!urb)
- return -ENOMEM;
+ if(!urb) {
+ for(i = i - 1; i >= 0; i--) {
+ usb_kill_urb(se401->urb[i]);
+ usb_free_urb(se401->urb[i]);
+ se401->urb[i] = NULL;
+ }
+ goto nomem_scratch;
+ }
usb_fill_bulk_urb(urb, se401->dev,
usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
@@ -490,6 +510,18 @@ static int se401_start_stream(struct usb_se401 *se401)
se401->framecount=0;
return 0;
+
+ nomem_scratch:
+ for (i=0; i<SE401_NUMSCRATCH; i++) {
+ kfree(se401->scratch[i].data);
+ se401->scratch[i].data = NULL;
+ }
+ nomem_sbuf:
+ for (i=0; i<SE401_NUMSBUF; i++) {
+ kfree(se401->sbuf[i].data);
+ se401->sbuf[i].data = NULL;
+ }
+ return -ENOMEM;
}
static int se401_stop_stream(struct usb_se401 *se401)
diff --git a/linux/drivers/media/video/sn9c102/Kconfig b/linux/drivers/media/video/sn9c102/Kconfig
index 1a7ccb666..f71f27277 100644
--- a/linux/drivers/media/video/sn9c102/Kconfig
+++ b/linux/drivers/media/video/sn9c102/Kconfig
@@ -1,6 +1,6 @@
config USB_SN9C102
tristate "USB SN9C1xx PC Camera Controller support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L2
---help---
Say Y here if you want support for cameras based on SONiX SN9C101,
SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
diff --git a/linux/drivers/media/video/sn9c102/Makefile b/linux/drivers/media/video/sn9c102/Makefile
index 30e3dfe53..a56d16f69 100644
--- a/linux/drivers/media/video/sn9c102/Makefile
+++ b/linux/drivers/media/video/sn9c102/Makefile
@@ -1,7 +1,14 @@
-sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o \
- sn9c102_ov7630.o sn9c102_ov7660.o sn9c102_pas106b.o \
- sn9c102_pas202bcb.o sn9c102_tas5110c1b.o \
- sn9c102_tas5130d1b.o
+sn9c102-objs := sn9c102_core.o \
+ sn9c102_hv7131d.o \
+ sn9c102_hv7131r.o \
+ sn9c102_mi0343.o \
+ sn9c102_mi0360.o \
+ sn9c102_ov7630.o \
+ sn9c102_ov7660.o \
+ sn9c102_pas106b.o \
+ sn9c102_pas202bcb.o \
+ sn9c102_tas5110c1b.o \
+ sn9c102_tas5110d.o \
+ sn9c102_tas5130d1b.o
obj-$(CONFIG_USB_SN9C102) += sn9c102.o
-
diff --git a/linux/drivers/media/video/sn9c102/sn9c102.h b/linux/drivers/media/video/sn9c102/sn9c102.h
index d6af8fa87..4561c294f 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102.h
+++ b/linux/drivers/media/video/sn9c102/sn9c102.h
@@ -23,7 +23,6 @@
#include <linux/version.h>
#include <linux/usb.h>
-#include "compat.h"
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/device.h>
@@ -39,6 +38,7 @@
#endif
#include <linux/string.h>
#include <linux/stddef.h>
+#include "compat.h"
#include "sn9c102_config.h"
#include "sn9c102_sensor.h"
@@ -81,8 +81,13 @@ enum sn9c102_stream_state {
typedef char sn9c102_sof_header_t[62];
+struct sn9c102_sof_t {
+ sn9c102_sof_header_t header;
+ u16 bytesread;
+};
+
struct sn9c102_sysfs_attr {
- u8 reg, i2c_reg;
+ u16 reg, i2c_reg;
sn9c102_sof_header_t frame_header;
};
@@ -115,7 +120,7 @@ struct sn9c102_device {
struct v4l2_jpegcompression compression;
struct sn9c102_sysfs_attr sysfs;
- sn9c102_sof_header_t sof_header;
+ struct sn9c102_sof_t sof;
u16 reg[384];
struct sn9c102_module_param module_param;
@@ -143,7 +148,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id)
void
sn9c102_attach_sensor(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor)
+ const struct sn9c102_sensor* sensor)
{
memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
}
@@ -189,8 +194,8 @@ do { \
if ((level) == 1 || (level) == 2) \
pr_info("sn9c102: " fmt "\n", ## args); \
else if ((level) == 3) \
- pr_debug("sn9c102: [%s:%d] " fmt "\n", __FUNCTION__, \
- __LINE__ , ## args); \
+ pr_debug("sn9c102: [%s:%d] " fmt "\n", \
+ __FUNCTION__, __LINE__ , ## args); \
} \
} while (0)
#else
@@ -201,8 +206,8 @@ do { \
#undef PDBG
#define PDBG(fmt, args...) \
-dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
- __FUNCTION__, __LINE__ , ## args)
+dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \
+ __LINE__ , ## args)
#undef PDBGG
#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_core.c b/linux/drivers/media/video/sn9c102/sn9c102_core.c
index a02d43ece..d22638c01 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_core.c
@@ -44,11 +44,12 @@
/*****************************************************************************/
#define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers"
-#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia"
+#define SN9C102_MODULE_ALIAS "sn9c1xx"
+#define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia"
#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
#define SN9C102_MODULE_LICENSE "GPL"
-#define SN9C102_MODULE_VERSION "1:1.34"
-#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 34)
+#define SN9C102_MODULE_VERSION "1:1.44"
+#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 44)
/*****************************************************************************/
@@ -56,6 +57,7 @@ MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
MODULE_DESCRIPTION(SN9C102_MODULE_NAME);
+MODULE_ALIAS(SN9C102_MODULE_ALIAS);
MODULE_VERSION(SN9C102_MODULE_VERSION);
MODULE_LICENSE(SN9C102_MODULE_LICENSE);
@@ -106,8 +108,7 @@ MODULE_PARM_DESC(debug,
"\n1 = critical errors"
"\n2 = significant informations"
"\n3 = more verbose messages"
- "\nLevel 3 is useful for testing only, when only "
- "one device is used."
+ "\nLevel 3 is useful for testing only."
"\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"."
"\n");
#endif
@@ -121,8 +122,8 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
struct v4l2_pix_format* p = &(cam->sensor.pix_format);
struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
size_t imagesize = cam->module_param.force_munmap || io == IO_READ ?
- (p->width * p->height * p->priv) / 8 :
- (r->width * r->height * p->priv) / 8;
+ (p->width * p->height * p->priv) / 8 :
+ (r->width * r->height * p->priv) / 8;
void* buff = NULL;
u32 i;
@@ -209,25 +210,41 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
/*****************************************************************************/
-int sn9c102_write_regs(struct sn9c102_device* cam, u8* buff, u16 index)
+/*
+ Write a sequence of count value/register pairs. Returns -1 after the first
+ failed write, or 0 for no errors.
+*/
+int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
+ int count)
{
struct usb_device* udev = cam->usbdev;
+ u8* buff = cam->control_buffer;
int i, res;
- if (index + sizeof(buff) >= ARRAY_SIZE(cam->reg))
- return -1;
+ for (i = 0; i < count; i++) {
+ u8 index = valreg[i][1];
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- index, 0, buff, sizeof(buff),
- SN9C102_CTRL_TIMEOUT*sizeof(buff));
- if (res < 0) {
- DBG(3, "Failed to write registers (index 0x%02X, error %d)",
- index, res);
- return -1;
- }
+ /*
+ index is a u8, so it must be <256 and can't be out of range.
+ If we put in a check anyway, gcc annoys us with a warning
+ hat our check is useless. People get all uppity when they
+ see warnings in the kernel compile.
+ */
+
+ *buff = valreg[i][0];
+
+ res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
+ 0x41, index, 0, buff, 1,
+ SN9C102_CTRL_TIMEOUT);
+
+ if (res < 0) {
+ DBG(3, "Failed to write a register (value 0x%02X, "
+ "index 0x%02X, error %d)", *buff, index, res);
+ return -1;
+ }
- for (i = 0; i < sizeof(buff); i++)
- cam->reg[index+i] = buff[i];
+ cam->reg[index] = *buff;
+ }
return 0;
}
@@ -258,8 +275,8 @@ int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
}
-/* NOTE: reading some registers always returns 0 */
-static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
+/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
+int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
{
struct usb_device* udev = cam->usbdev;
u8* buff = cam->control_buffer;
@@ -285,7 +302,8 @@ int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
static int
-sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
+sn9c102_i2c_wait(struct sn9c102_device* cam,
+ const struct sn9c102_sensor* sensor)
{
int i, r;
@@ -306,7 +324,7 @@ sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
static int
sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor)
+ const struct sn9c102_sensor* sensor)
{
int r , err = 0;
@@ -328,7 +346,7 @@ sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
static int
sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor)
+ const struct sn9c102_sensor* sensor)
{
int r;
r = sn9c102_read_reg(cam, 0x08);
@@ -338,12 +356,12 @@ sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
int
sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 data0, u8 data1,
- u8 n, u8 buffer[])
+ const struct sn9c102_sensor* sensor, u8 data0,
+ u8 data1, u8 n, u8 buffer[])
{
struct usb_device* udev = cam->usbdev;
u8* data = cam->control_buffer;
- int err = 0, res;
+ int i = 0, err = 0, res;
/* Write cycle */
data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
@@ -388,7 +406,8 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
}
if (buffer)
- memcpy(buffer, data, sizeof(buffer));
+ for (i = 0; i < n && i < 5; i++)
+ buffer[n-i-1] = data[4-i];
return (int)data[4];
}
@@ -396,7 +415,7 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
int
sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 n, u8 data0,
+ const struct sn9c102_sensor* sensor, u8 n, u8 data0,
u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
{
struct usb_device* udev = cam->usbdev;
@@ -435,7 +454,7 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
int
sn9c102_i2c_try_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 address)
+ const struct sn9c102_sensor* sensor, u8 address)
{
return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
address, 1, NULL);
@@ -444,7 +463,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam,
int
sn9c102_i2c_try_write(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 address, u8 value)
+ const struct sn9c102_sensor* sensor, u8 address, u8 value)
{
return sn9c102_i2c_try_raw_write(cam, sensor, 3,
sensor->i2c_slave_id, address,
@@ -485,18 +504,43 @@ static size_t sn9c102_sof_length(struct sn9c102_device* cam)
static void*
sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
{
- char sof_header[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
- size_t soflen = 0, i;
+ static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
+ const char *m = mem;
+ size_t soflen = 0, i, j;
soflen = sn9c102_sof_length(cam);
- for (i = 0; (len >= soflen) && (i <= len - soflen); i++)
- if (!memcmp(mem + i, sof_header, sizeof(sof_header))) {
- memcpy(cam->sof_header, mem + i,
- sizeof(sn9c102_sof_header_t));
- /* Skip the header */
- return mem + i + soflen;
+ for (i = 0; i < len; i++) {
+ size_t b;
+
+ /* Read the variable part of the header */
+ if (unlikely(cam->sof.bytesread >= sizeof(marker))) {
+ cam->sof.header[cam->sof.bytesread] = *(m+i);
+ if (++cam->sof.bytesread == soflen) {
+ cam->sof.bytesread = 0;
+ return mem + i;
}
+ continue;
+ }
+
+ /* Search for the SOF marker (fixed part) in the header */
+ for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) {
+ if (unlikely(i+j) == len)
+ return NULL;
+ if (*(m+i+j) == marker[cam->sof.bytesread]) {
+ cam->sof.header[cam->sof.bytesread] = *(m+i+j);
+ if (++cam->sof.bytesread == sizeof(marker)) {
+ PDBGG("Bytes to analyze: %zd. SOF "
+ "starts at byte #%zd", len, i);
+ i += j+1;
+ break;
+ }
+ } else {
+ cam->sof.bytesread = 0;
+ break;
+ }
+ }
+ }
return NULL;
}
@@ -505,7 +549,7 @@ sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len)
static void*
sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
{
- char eof_header[4][4] = {
+ static const u8 eof_header[4][4] = {
{0x00, 0x00, 0x00, 0x00},
{0x40, 0x00, 0x00, 0x00},
{0x80, 0x00, 0x00, 0x00},
@@ -513,10 +557,16 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
};
size_t i, j;
+ /* The EOF header does not exist in compressed data */
if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- return NULL; /* EOF header does not exist in compressed data */
+ return NULL;
+ /*
+ The EOF header might cross the packet boundary, but this is not a
+ problem, since the end of a frame is determined by checking its size
+ in the first place.
+ */
for (i = 0; (len >= 4) && (i <= len - 4); i++)
for (j = 0; j < ARRAY_SIZE(eof_header); j++)
if (!memcmp(mem + i, eof_header[j], 4))
@@ -529,7 +579,7 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
static void
sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
{
- static u8 jpeg_header[589] = {
+ static const u8 jpeg_header[589] = {
0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05,
0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06,
0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e,
@@ -612,16 +662,6 @@ sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
}
-static void
-sn9c102_write_eoimarker(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
-{
- static const u8 eoi_marker[2] = {0xff, 0xd9};
-
- memcpy(f->bufmem + f->buf.bytesused, eoi_marker, sizeof(eoi_marker));
- f->buf.bytesused += sizeof(eoi_marker);
-}
-
-
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
#else
@@ -643,6 +683,7 @@ static void sn9c102_urb_complete(struct urb *urb)
cam->stream = STREAM_OFF;
if ((*f))
(*f)->state = F_QUEUED;
+ cam->sof.bytesread = 0;
DBG(3, "Stream interrupted by application");
wake_up(&cam->wait_stream);
}
@@ -680,6 +721,7 @@ static void sn9c102_urb_complete(struct urb *urb)
if (status) {
DBG(3, "Error in isochronous frame");
(*f)->state = F_ERROR;
+ cam->sof.bytesread = 0;
continue;
}
@@ -696,13 +738,13 @@ end_of_frame:
if (eof)
img = (eof > pos) ? eof - pos - 1 : 0;
- if ((*f)->buf.bytesused+img > imagesize) {
+ if ((*f)->buf.bytesused + img > imagesize) {
u32 b;
b = (*f)->buf.bytesused + img -
imagesize;
img = imagesize - (*f)->buf.bytesused;
- DBG(3, "Expected EOF not found: "
- "video frame cut");
+ PDBGG("Expected EOF not found: video "
+ "frame cut");
if (eof)
DBG(3, "Exceeded limit: +%u "
"bytes", (unsigned)(b));
@@ -723,11 +765,6 @@ end_of_frame:
V4L2_PIX_FMT_JPEG) && eof)) {
u32 b;
- if (cam->sensor.pix_format.pixelformat
- == V4L2_PIX_FMT_JPEG)
- sn9c102_write_eoimarker(cam,
- (*f));
-
b = (*f)->buf.bytesused;
(*f)->state = F_DONE;
(*f)->buf.sequence= ++cam->frame_count;
@@ -745,7 +782,7 @@ end_of_frame:
spin_unlock(&cam->queue_lock);
memcpy(cam->sysfs.frame_header,
- cam->sof_header, soflen);
+ cam->sof.header, soflen);
DBG(3, "Video frame captured: %lu "
"bytes", (unsigned long)(b));
@@ -795,7 +832,13 @@ start_of_frame:
V4L2_PIX_FMT_SN9C10X ||
cam->sensor.pix_format.pixelformat ==
V4L2_PIX_FMT_JPEG) {
- eof = sof - soflen;
+ if (sof - pos >= soflen) {
+ eof = sof - soflen;
+ } else { /* remove header */
+ eof = pos;
+ (*f)->buf.bytesused -=
+ (soflen - (sof - pos));
+ }
goto end_of_frame;
} else {
DBG(3, "SOF before expected EOF after "
@@ -882,6 +925,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam)
}
cam->frame_current = NULL;
+ cam->sof.bytesread = 0;
for (i = 0; i < SN9C102_URBS; i++) {
err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
@@ -963,9 +1007,9 @@ static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count)
if (len < 6) {
strncpy(str, buff, len);
- str[len+1] = '\0';
+ str[len] = '\0';
} else {
- strncpy(str, buff, 4);
+ strncpy(str, buff, 6);
str[6] = '\0';
}
@@ -1066,7 +1110,7 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
count = sprintf(buf, "%d\n", val);
- DBG(3, "Read bytes: %zd", count);
+ DBG(3, "Read bytes: %zd, value: %d", count, val);
mutex_unlock(&sn9c102_sysfs_lock);
@@ -1201,7 +1245,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
count = sprintf(buf, "%d\n", val);
- DBG(3, "Read bytes: %zd", count);
+ DBG(3, "Read bytes: %zd, value: %d", count, val);
mutex_unlock(&sn9c102_sysfs_lock);
@@ -1375,35 +1419,35 @@ static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
static int sn9c102_create_sysfs(struct sn9c102_device* cam)
{
- struct video_device *v4ldev = cam->v4ldev;
+ struct class_device *classdev = &(cam->v4ldev->class_dev);
int err = 0;
- if ((err = video_device_create_file(v4ldev, &class_device_attr_reg)))
+ if ((err = class_device_create_file(classdev, &class_device_attr_reg)))
goto err_out;
- if ((err = video_device_create_file(v4ldev, &class_device_attr_val)))
+ if ((err = class_device_create_file(classdev, &class_device_attr_val)))
goto err_reg;
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_frame_header)))
goto err_val;
if (cam->sensor.sysfs_ops) {
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_i2c_reg)))
goto err_frame_header;
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_i2c_val)))
goto err_i2c_reg;
}
if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_green)))
goto err_i2c_val;
} else {
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_blue)))
goto err_i2c_val;
- if ((err = video_device_create_file(v4ldev,
+ if ((err = class_device_create_file(classdev,
&class_device_attr_red)))
goto err_blue;
}
@@ -1411,19 +1455,19 @@ static int sn9c102_create_sysfs(struct sn9c102_device* cam)
return 0;
err_blue:
- video_device_remove_file(v4ldev, &class_device_attr_blue);
+ class_device_remove_file(classdev, &class_device_attr_blue);
err_i2c_val:
if (cam->sensor.sysfs_ops)
- video_device_remove_file(v4ldev, &class_device_attr_i2c_val);
+ class_device_remove_file(classdev, &class_device_attr_i2c_val);
err_i2c_reg:
if (cam->sensor.sysfs_ops)
- video_device_remove_file(v4ldev, &class_device_attr_i2c_reg);
+ class_device_remove_file(classdev, &class_device_attr_i2c_reg);
err_frame_header:
- video_device_remove_file(v4ldev, &class_device_attr_frame_header);
+ class_device_remove_file(classdev, &class_device_attr_frame_header);
err_val:
- video_device_remove_file(v4ldev, &class_device_attr_val);
+ class_device_remove_file(classdev, &class_device_attr_val);
err_reg:
- video_device_remove_file(v4ldev, &class_device_attr_reg);
+ class_device_remove_file(classdev, &class_device_attr_reg);
err_out:
return err;
}
@@ -1481,10 +1525,10 @@ sn9c102_set_compression(struct sn9c102_device* cam,
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
case BRIDGE_SN9C103:
- if (compression->quality == 0)
+ if (compression->quality == 0)
err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01,
0x17);
- else if (compression->quality == 1)
+ else if (compression->quality == 1)
err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe,
0x17);
break;
@@ -1493,10 +1537,10 @@ sn9c102_set_compression(struct sn9c102_device* cam,
if (compression->quality == 0) {
for (i = 0; i <= 63; i++) {
err += sn9c102_write_reg(cam,
- SN9C102_Y_QTABLE0[i],
+ SN9C102_Y_QTABLE1[i],
0x100 + i);
err += sn9c102_write_reg(cam,
- SN9C102_UV_QTABLE0[i],
+ SN9C102_UV_QTABLE1[i],
0x140 + i);
}
err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf,
@@ -1601,9 +1645,13 @@ static int sn9c102_init(struct sn9c102_device* cam)
if (cam->bridge == BRIDGE_SN9C101 ||
cam->bridge == BRIDGE_SN9C102 ||
cam->bridge == BRIDGE_SN9C103) {
+ if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
+ s->pix_format.pixelformat= V4L2_PIX_FMT_SBGGR8;
cam->compression.quality = cam->reg[0x17] & 0x01 ?
0 : 1;
} else {
+ if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
+ s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG;
cam->compression.quality = cam->reg[0x18] & 0x40 ?
0 : 1;
err += sn9c102_set_compression(cam, &cam->compression);
@@ -1809,7 +1857,7 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
DBG(3, "Close and open the device again to choose "
"the read method");
mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
+ return -EBUSY;
}
if (cam->io == IO_NONE) {
@@ -1849,16 +1897,16 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
return err;
}
} else {
- timeout = wait_event_interruptible_timeout
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- cam->module_param.frame_timeout *
- 1000 * msecs_to_jiffies(1) );
- if (timeout < 0) {
- mutex_unlock(&cam->fileop_mutex);
- return timeout;
+ timeout = wait_event_interruptible_timeout
+ ( cam->wait_frame,
+ (!list_empty(&cam->outqueue)) ||
+ (cam->state & DEV_DISCONNECTED) ||
+ (cam->state & DEV_MISCONFIGURED),
+ cam->module_param.frame_timeout *
+ 1000 * msecs_to_jiffies(1) );
+ if (timeout < 0) {
+ mutex_unlock(&cam->fileop_mutex);
+ return timeout;
} else if (timeout == 0 &&
!(cam->state & DEV_DISCONNECTED)) {
DBG(1, "Video frame timeout elapsed");
@@ -2005,7 +2053,12 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
return -EIO;
}
- if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
+ if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
+ mutex_unlock(&cam->fileop_mutex);
+ return -EACCES;
+ }
+
+ if (cam->io != IO_MMAP ||
size != PAGE_ALIGN(cam->frame[0].buf.length)) {
mutex_unlock(&cam->fileop_mutex);
return -EINVAL;
@@ -2271,7 +2324,7 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
if (cam->frame[i].vma_use_count) {
DBG(3, "VIDIOC_S_CROP failed. "
"Unmap the buffers first.");
- return -EINVAL;
+ return -EBUSY;
}
/* Preserve R,G or B origin */
@@ -2414,8 +2467,8 @@ sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg)
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
case BRIDGE_SN9C103:
- strcpy(fmtd.description, "compressed");
- fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
+ strcpy(fmtd.description, "compressed");
+ fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
break;
case BRIDGE_SN9C105:
case BRIDGE_SN9C120:
@@ -2449,8 +2502,10 @@ sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_SN9C10X ||
- pfmt->pixelformat==V4L2_PIX_FMT_JPEG)
+ pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ?
+ V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
+ pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X ||
+ pfmt->pixelformat == V4L2_PIX_FMT_JPEG)
? 0 : (pfmt->width * pfmt->priv) / 8;
pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
pfmt->field = V4L2_FIELD_NONE;
@@ -2525,9 +2580,9 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
case BRIDGE_SN9C103:
- if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
- pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
- pix->pixelformat = pfmt->pixelformat;
+ if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
+ pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
+ pix->pixelformat = pfmt->pixelformat;
break;
case BRIDGE_SN9C105:
case BRIDGE_SN9C120:
@@ -2537,7 +2592,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
break;
}
pix->priv = pfmt->priv; /* bpp */
- pix->colorspace = pfmt->colorspace;
+ pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ?
+ V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
pix->pixelformat == V4L2_PIX_FMT_JPEG)
? 0 : (pix->width * pix->priv) / 8;
@@ -2555,7 +2611,7 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
if (cam->frame[i].vma_use_count) {
DBG(3, "VIDIOC_S_FMT failed. Unmap the "
"buffers first.");
- return -EINVAL;
+ return -EBUSY;
}
if (cam->stream == STREAM_ON)
@@ -2670,14 +2726,14 @@ sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg)
if (cam->io == IO_READ) {
DBG(3, "Close and open the device again to choose the mmap "
"I/O method");
- return -EINVAL;
+ return -EBUSY;
}
for (i = 0; i < cam->nbuffers; i++)
if (cam->frame[i].vma_use_count) {
DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
"still mapped.");
- return -EINVAL;
+ return -EBUSY;
}
if (cam->stream == STREAM_ON)
@@ -2789,15 +2845,15 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
if (err)
return err;
} else {
- timeout = wait_event_interruptible_timeout
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- cam->module_param.frame_timeout *
- 1000 * msecs_to_jiffies(1) );
- if (timeout < 0)
- return timeout;
+ timeout = wait_event_interruptible_timeout
+ ( cam->wait_frame,
+ (!list_empty(&cam->outqueue)) ||
+ (cam->state & DEV_DISCONNECTED) ||
+ (cam->state & DEV_MISCONFIGURED),
+ cam->module_param.frame_timeout *
+ 1000 * msecs_to_jiffies(1) );
+ if (timeout < 0)
+ return timeout;
else if (timeout == 0 &&
!(cam->state & DEV_DISCONNECTED)) {
DBG(1, "Video frame timeout elapsed");
@@ -2841,9 +2897,6 @@ sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg)
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
return -EINVAL;
- if (list_empty(&cam->inqueue))
- return -EINVAL;
-
cam->stream = STREAM_ON;
DBG(3, "Stream on");
@@ -3127,14 +3180,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
static const struct file_operations sn9c102_fops = {
.owner = THIS_MODULE,
- .open = sn9c102_open,
+ .open = sn9c102_open,
.release = sn9c102_release,
- .ioctl = sn9c102_ioctl,
+ .ioctl = sn9c102_ioctl,
.compat_ioctl = v4l_compat_ioctl32,
- .read = sn9c102_read,
- .poll = sn9c102_poll,
- .mmap = sn9c102_mmap,
- .llseek = no_llseek,
+ .read = sn9c102_read,
+ .poll = sn9c102_poll,
+ .mmap = sn9c102_mmap,
+ .llseek = no_llseek,
};
/*****************************************************************************/
@@ -3170,8 +3223,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
r = sn9c102_read_reg(cam, 0x00);
if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) {
- DBG(1, "Sorry, this is not a SN9C1xx based camera "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ DBG(1, "Sorry, this is not a SN9C1xx-based camera "
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
err = -ENODEV;
goto fail;
}
@@ -3181,23 +3234,23 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
DBG(2, "SN9C10[12] PC Camera Controller detected "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
break;
case BRIDGE_SN9C103:
DBG(2, "SN9C103 PC Camera Controller detected "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
break;
case BRIDGE_SN9C105:
DBG(2, "SN9C105 PC Camera Controller detected "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
break;
case BRIDGE_SN9C120:
DBG(2, "SN9C120 PC Camera Controller detected "
- "(vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
break;
}
- for (i = 0; sn9c102_sensor_table[i]; i++) {
+ for (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
err = sn9c102_sensor_table[i](cam);
if (!err)
break;
@@ -3208,7 +3261,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
DBG(3, "Support for %s maintained by %s",
cam->sensor.name, cam->sensor.maintainer);
} else {
- DBG(1, "No supported image sensor detected");
+ DBG(1, "No supported image sensor detected for this bridge");
err = -ENODEV;
goto fail;
}
@@ -3264,6 +3317,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
"device controlling. Error #%d", err);
#else
DBG(2, "Optional device control through 'sysfs' interface disabled");
+ DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' "
+ "configuration option to enable it.");
#endif
usb_set_intfdata(intf, cam);
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_devtable.h b/linux/drivers/media/video/sn9c102/sn9c102_devtable.h
index 3a682eca6..916054faf 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/linux/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -86,19 +86,28 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), },
/* SN9C105 */
+ { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
+ { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x60ef, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
/* SN9C120 */
+ { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
+ { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
@@ -114,12 +123,15 @@ static const struct usb_device_id sn9c102_id_table[] = {
Functions must return 0 on success, the appropriate error otherwise.
*/
extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
+extern int sn9c102_probe_hv7131r(struct sn9c102_device* cam);
extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
+extern int sn9c102_probe_mi0360(struct sn9c102_device* cam);
extern int sn9c102_probe_ov7630(struct sn9c102_device* cam);
extern int sn9c102_probe_ov7660(struct sn9c102_device* cam);
extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
+extern int sn9c102_probe_tas5110d(struct sn9c102_device* cam);
extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
/*
@@ -128,15 +140,17 @@ extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam);
the order of the list below, from top to bottom.
*/
static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = {
+ &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */
+ &sn9c102_probe_hv7131r, /* strong detection based on SENSOR ids */
&sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */
+ &sn9c102_probe_mi0360, /* strong detection based on SENSOR ids */
&sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */
&sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */
- &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */
&sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */
&sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */
&sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
+ &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
&sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
- NULL,
};
#endif /* _SN9C102_DEVTABLE_H_ */
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c
index 7ae368f60..eaf9ad0dc 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_hv7131d.c
@@ -22,19 +22,13 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor hv7131d;
-
-
static int hv7131d_init(struct sn9c102_device* cam)
{
- int err = 0;
+ int err;
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x0e, 0x18);
- err += sn9c102_write_reg(cam, 0xf2, 0x19);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x60, 0x17},
+ {0x0e, 0x18}, {0xf2, 0x19});
err += sn9c102_i2c_write(cam, 0x01, 0x04);
err += sn9c102_i2c_write(cam, 0x02, 0x00);
@@ -150,10 +144,10 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor hv7131d = {
+static const struct sn9c102_sensor hv7131d = {
.name = "HV7131D",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
@@ -250,20 +244,17 @@ static struct sn9c102_sensor hv7131d = {
int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
{
- int r0 = 0, r1 = 0, err = 0;
+ int r0 = 0, r1 = 0, err;
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
- if (err)
- return -EIO;
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17});
r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
- if (r0 < 0 || r1 < 0)
+ if (err || r0 < 0 || r1 < 0)
return -EIO;
- if (r0 != 0x00 && r1 != 0x04)
+ if (r0 != 0x00 || r1 != 0x04)
return -ENODEV;
sn9c102_attach_sensor(cam, &hv7131d);
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_hv7131r.c b/linux/drivers/media/video/sn9c102/sn9c102_hv7131r.c
new file mode 100644
index 000000000..0fc401223
--- /dev/null
+++ b/linux/drivers/media/video/sn9c102/sn9c102_hv7131r.c
@@ -0,0 +1,362 @@
+/***************************************************************************
+ * Plug-in for HV7131R image sensor connected to the SN9C1xx PC Camera *
+ * Controllers *
+ * *
+ * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ ***************************************************************************/
+
+#include "sn9c102_sensor.h"
+
+
+static int hv7131r_init(struct sn9c102_device* cam)
+{
+ int err = 0;
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ err = sn9c102_write_const_regs(cam, {0x00, 0x03}, {0x1a, 0x04},
+ {0x20, 0x05}, {0x20, 0x06},
+ {0x03, 0x10}, {0x00, 0x14},
+ {0x60, 0x17}, {0x0a, 0x18},
+ {0xf0, 0x19}, {0x1d, 0x1a},
+ {0x10, 0x1b}, {0x02, 0x1c},
+ {0x03, 0x1d}, {0x0f, 0x1e},
+ {0x0c, 0x1f}, {0x00, 0x20},
+ {0x10, 0x21}, {0x20, 0x22},
+ {0x30, 0x23}, {0x40, 0x24},
+ {0x50, 0x25}, {0x60, 0x26},
+ {0x70, 0x27}, {0x80, 0x28},
+ {0x90, 0x29}, {0xa0, 0x2a},
+ {0xb0, 0x2b}, {0xc0, 0x2c},
+ {0xd0, 0x2d}, {0xe0, 0x2e},
+ {0xf0, 0x2f}, {0xff, 0x30});
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
+ {0x00, 0x03}, {0x1a, 0x04},
+ {0x44, 0x05}, {0x3e, 0x06},
+ {0x1a, 0x07}, {0x03, 0x10},
+ {0x08, 0x14}, {0xa3, 0x17},
+ {0x4b, 0x18}, {0x00, 0x19},
+ {0x1d, 0x1a}, {0x10, 0x1b},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x29, 0x21},
+ {0x40, 0x22}, {0x54, 0x23},
+ {0x66, 0x24}, {0x76, 0x25},
+ {0x85, 0x26}, {0x94, 0x27},
+ {0xa1, 0x28}, {0xae, 0x29},
+ {0xbb, 0x2a}, {0xc7, 0x2b},
+ {0xd3, 0x2c}, {0xde, 0x2d},
+ {0xea, 0x2e}, {0xf4, 0x2f},
+ {0xff, 0x30}, {0x00, 0x3F},
+ {0xC7, 0x40}, {0x01, 0x41},
+ {0x44, 0x42}, {0x00, 0x43},
+ {0x44, 0x44}, {0x00, 0x45},
+ {0x44, 0x46}, {0x00, 0x47},
+ {0xC7, 0x48}, {0x01, 0x49},
+ {0xC7, 0x4A}, {0x01, 0x4B},
+ {0xC7, 0x4C}, {0x01, 0x4D},
+ {0x44, 0x4E}, {0x00, 0x4F},
+ {0x44, 0x50}, {0x00, 0x51},
+ {0x44, 0x52}, {0x00, 0x53},
+ {0xC7, 0x54}, {0x01, 0x55},
+ {0xC7, 0x56}, {0x01, 0x57},
+ {0xC7, 0x58}, {0x01, 0x59},
+ {0x44, 0x5A}, {0x00, 0x5B},
+ {0x44, 0x5C}, {0x00, 0x5D},
+ {0x44, 0x5E}, {0x00, 0x5F},
+ {0xC7, 0x60}, {0x01, 0x61},
+ {0xC7, 0x62}, {0x01, 0x63},
+ {0xC7, 0x64}, {0x01, 0x65},
+ {0x44, 0x66}, {0x00, 0x67},
+ {0x44, 0x68}, {0x00, 0x69},
+ {0x44, 0x6A}, {0x00, 0x6B},
+ {0xC7, 0x6C}, {0x01, 0x6D},
+ {0xC7, 0x6E}, {0x01, 0x6F},
+ {0xC7, 0x70}, {0x01, 0x71},
+ {0x44, 0x72}, {0x00, 0x73},
+ {0x44, 0x74}, {0x00, 0x75},
+ {0x44, 0x76}, {0x00, 0x77},
+ {0xC7, 0x78}, {0x01, 0x79},
+ {0xC7, 0x7A}, {0x01, 0x7B},
+ {0xC7, 0x7C}, {0x01, 0x7D},
+ {0x44, 0x7E}, {0x00, 0x7F},
+ {0x14, 0x84}, {0x00, 0x85},
+ {0x27, 0x86}, {0x00, 0x87},
+ {0x07, 0x88}, {0x00, 0x89},
+ {0xEC, 0x8A}, {0x0f, 0x8B},
+ {0xD8, 0x8C}, {0x0f, 0x8D},
+ {0x3D, 0x8E}, {0x00, 0x8F},
+ {0x3D, 0x90}, {0x00, 0x91},
+ {0xCD, 0x92}, {0x0f, 0x93},
+ {0xf7, 0x94}, {0x0f, 0x95},
+ {0x0C, 0x96}, {0x00, 0x97},
+ {0x00, 0x98}, {0x66, 0x99},
+ {0x05, 0x9A}, {0x00, 0x9B},
+ {0x04, 0x9C}, {0x00, 0x9D},
+ {0x08, 0x9E}, {0x00, 0x9F},
+ {0x2D, 0xC0}, {0x2D, 0xC1},
+ {0x3A, 0xC2}, {0x05, 0xC3},
+ {0x04, 0xC4}, {0x3F, 0xC5},
+ {0x00, 0xC6}, {0x00, 0xC7},
+ {0x50, 0xC8}, {0x3C, 0xC9},
+ {0x28, 0xCA}, {0xD8, 0xCB},
+ {0x14, 0xCC}, {0xEC, 0xCD},
+ {0x32, 0xCE}, {0xDD, 0xCF},
+ {0x32, 0xD0}, {0xDD, 0xD1},
+ {0x6A, 0xD2}, {0x50, 0xD3},
+ {0x00, 0xD4}, {0x00, 0xD5},
+ {0x00, 0xD6});
+ break;
+ default:
+ break;
+ }
+
+ err += sn9c102_i2c_write(cam, 0x20, 0x00);
+ err += sn9c102_i2c_write(cam, 0x21, 0xd6);
+ err += sn9c102_i2c_write(cam, 0x25, 0x06);
+
+ return err;
+}
+
+
+static int hv7131r_get_ctrl(struct sn9c102_device* cam,
+ struct v4l2_control* ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_GAIN:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x30)) < 0)
+ return -EIO;
+ return 0;
+ case V4L2_CID_RED_BALANCE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x31)) < 0)
+ return -EIO;
+ ctrl->value = ctrl->value & 0x3f;
+ return 0;
+ case V4L2_CID_BLUE_BALANCE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x33)) < 0)
+ return -EIO;
+ ctrl->value = ctrl->value & 0x3f;
+ return 0;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x32)) < 0)
+ return -EIO;
+ ctrl->value = ctrl->value & 0x3f;
+ return 0;
+ case V4L2_CID_BLACK_LEVEL:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x01)) < 0)
+ return -EIO;
+ ctrl->value = (ctrl->value & 0x08) ? 1 : 0;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+
+static int hv7131r_set_ctrl(struct sn9c102_device* cam,
+ const struct v4l2_control* ctrl)
+{
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_GAIN:
+ err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
+ break;
+ case V4L2_CID_RED_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x31, ctrl->value);
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x33, ctrl->value);
+ break;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ err += sn9c102_i2c_write(cam, 0x32, ctrl->value);
+ break;
+ case V4L2_CID_BLACK_LEVEL:
+ {
+ int r = sn9c102_i2c_read(cam, 0x01);
+ if (r < 0)
+ return -EIO;
+ err += sn9c102_i2c_write(cam, 0x01,
+ (ctrl->value<<3) | (r&0xf7));
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return err ? -EIO : 0;
+}
+
+
+static int hv7131r_set_crop(struct sn9c102_device* cam,
+ const struct v4l2_rect* rect)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+ u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1,
+ v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+ err += sn9c102_write_reg(cam, h_start, 0x12);
+ err += sn9c102_write_reg(cam, v_start, 0x13);
+
+ return err;
+}
+
+
+static int hv7131r_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
+ err += sn9c102_write_reg(cam, 0xa0, 0x19);
+ err += sn9c102_i2c_write(cam, 0x01, 0x04);
+ } else {
+ err += sn9c102_write_reg(cam, 0x30, 0x19);
+ err += sn9c102_i2c_write(cam, 0x01, 0x04);
+ }
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
+ err += sn9c102_write_reg(cam, 0xa5, 0x17);
+ err += sn9c102_i2c_write(cam, 0x01, 0x24);
+ } else {
+ err += sn9c102_write_reg(cam, 0xa3, 0x17);
+ err += sn9c102_i2c_write(cam, 0x01, 0x04);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+
+static const struct sn9c102_sensor hv7131r = {
+ .name = "HV7131R",
+ .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+ .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
+ .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
+ .frequency = SN9C102_I2C_100KHZ,
+ .interface = SN9C102_I2C_2WIRES,
+ .i2c_slave_id = 0x11,
+ .init = &hv7131r_init,
+ .qctrl = {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "global gain",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x01,
+ .default_value = 0x40,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x08,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x1a,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_GREEN_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "green balance",
+ .minimum = 0x00,
+ .maximum = 0x3f,
+ .step = 0x01,
+ .default_value = 0x2f,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLACK_LEVEL,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "auto black level compensation",
+ .minimum = 0x00,
+ .maximum = 0x01,
+ .step = 0x01,
+ .default_value = 0x00,
+ .flags = 0,
+ },
+ },
+ .get_ctrl = &hv7131r_get_ctrl,
+ .set_ctrl = &hv7131r_set_ctrl,
+ .cropcap = {
+ .bounds = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ .defrect = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ },
+ .set_crop = &hv7131r_set_crop,
+ .pix_format = {
+ .width = 640,
+ .height = 480,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .priv = 8,
+ },
+ .set_pix_format = &hv7131r_set_pix_format
+};
+
+
+int sn9c102_probe_hv7131r(struct sn9c102_device* cam)
+{
+ int devid, err;
+
+ err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x02},
+ {0x34, 0x01}, {0x20, 0x17},
+ {0x34, 0x01}, {0x46, 0x01});
+
+ devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
+ if (err || devid < 0)
+ return -EIO;
+
+ if (devid != 0x02)
+ return -ENODEV;
+
+ sn9c102_attach_sensor(cam, &hv7131r);
+
+ return 0;
+}
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_mi0343.c b/linux/drivers/media/video/sn9c102/sn9c102_mi0343.c
index a33d1bc10..00b134ca0 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_mi0343.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_mi0343.c
@@ -22,36 +22,30 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor mi0343;
-static u8 mi0343_i2c_data[5+1];
-
-
static int mi0343_init(struct sn9c102_device* cam)
{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
int err = 0;
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x0a, 0x14);
- err += sn9c102_write_reg(cam, 0x40, 0x01);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x07, 0x18);
- err += sn9c102_write_reg(cam, 0xa0, 0x19);
-
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x0d, 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x0d, 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x03, 0x01, 0xe1, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x04, 0x02, 0x81, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x05, 0x00, 0x17, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x06, 0x00, 0x11, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4, mi0343.i2c_slave_id,
- 0x62, 0x04, 0x9a, 0, 0);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x0a, 0x14}, {0x40, 0x01},
+ {0x20, 0x17}, {0x07, 0x18},
+ {0xa0, 0x19});
+
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
+ 0x00, 0x01, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
+ 0x00, 0x00, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
+ 0x01, 0xe1, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
+ 0x02, 0x81, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
+ 0x00, 0x17, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
+ 0x00, 0x11, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
+ 0x04, 0x9a, 0, 0);
return err;
}
@@ -60,43 +54,46 @@ static int mi0343_init(struct sn9c102_device* cam)
static int mi0343_get_ctrl(struct sn9c102_device* cam,
struct v4l2_control* ctrl)
{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ u8 data[2];
+
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x09, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+ data) < 0)
return -EIO;
- ctrl->value = mi0343_i2c_data[2];
+ ctrl->value = data[0];
return 0;
case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x35, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+ data) < 0)
return -EIO;
break;
case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x20, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
return -EIO;
- ctrl->value = mi0343_i2c_data[3] & 0x20 ? 1 : 0;
+ ctrl->value = data[1] & 0x20 ? 1 : 0;
return 0;
case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x20, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
return -EIO;
- ctrl->value = mi0343_i2c_data[3] & 0x80 ? 1 : 0;
+ ctrl->value = data[1] & 0x80 ? 1 : 0;
return 0;
case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x2d, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+ data) < 0)
return -EIO;
break;
case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x2c, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+ data) < 0)
return -EIO;
break;
case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id,
- 0x2e, 2+1, mi0343_i2c_data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+ data) < 0)
return -EIO;
break;
default:
@@ -108,7 +105,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
case V4L2_CID_RED_BALANCE:
case V4L2_CID_BLUE_BALANCE:
case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = mi0343_i2c_data[3] | (mi0343_i2c_data[2] << 8);
+ ctrl->value = data[1] | (data[0] << 8);
if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
ctrl->value -= 0x10;
else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
@@ -124,6 +121,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
static int mi0343_set_ctrl(struct sn9c102_device* cam,
const struct v4l2_control* ctrl)
{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
u16 reg = 0;
int err = 0;
@@ -143,50 +141,42 @@ static int mi0343_set_ctrl(struct sn9c102_device* cam,
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x09, ctrl->value, 0x00,
0, 0);
break;
case V4L2_CID_GAIN:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x35, reg >> 8, reg & 0xff,
0, 0);
break;
case V4L2_CID_HFLIP:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x20, ctrl->value ? 0x40:0x00,
ctrl->value ? 0x20:0x00,
0, 0);
break;
case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x20, ctrl->value ? 0x80:0x00,
ctrl->value ? 0x80:0x00,
0, 0);
break;
case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x2d, reg >> 8, reg & 0xff,
0, 0);
break;
case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x2c, reg >> 8, reg & 0xff,
0, 0);
break;
case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x2b, reg >> 8, reg & 0xff,
0, 0);
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x2e, reg >> 8, reg & 0xff,
0, 0);
break;
@@ -216,16 +206,15 @@ static int mi0343_set_crop(struct sn9c102_device* cam,
static int mi0343_set_pix_format(struct sn9c102_device* cam,
const struct v4l2_pix_format* pix)
{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
int err = 0;
if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x0a, 0x00, 0x03, 0, 0);
err += sn9c102_write_reg(cam, 0x20, 0x19);
} else {
- err += sn9c102_i2c_try_raw_write(cam, &mi0343, 4,
- mi0343.i2c_slave_id,
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x0a, 0x00, 0x05, 0, 0);
err += sn9c102_write_reg(cam, 0xa0, 0x19);
}
@@ -234,10 +223,10 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor mi0343 = {
+static const struct sn9c102_sensor mi0343 = {
.name = "MI-0343",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
.i2c_slave_id = 0x5d,
@@ -343,19 +332,17 @@ static struct sn9c102_sensor mi0343 = {
int sn9c102_probe_mi0343(struct sn9c102_device* cam)
{
- int err = 0;
+ u8 data[2];
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
- if (err)
+ if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17}))
return -EIO;
if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
- 2, mi0343_i2c_data) < 0)
+ 2, data) < 0)
return -EIO;
- if (mi0343_i2c_data[4] != 0x32 && mi0343_i2c_data[3] != 0xe3)
+ if (data[1] != 0x42 || data[0] != 0xe3)
return -ENODEV;
sn9c102_attach_sensor(cam, &mi0343);
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_mi0360.c b/linux/drivers/media/video/sn9c102/sn9c102_mi0360.c
new file mode 100644
index 000000000..f8d81d82e
--- /dev/null
+++ b/linux/drivers/media/video/sn9c102/sn9c102_mi0360.c
@@ -0,0 +1,452 @@
+/***************************************************************************
+ * Plug-in for MI-0360 image sensor connected to the SN9C1xx PC Camera *
+ * Controllers *
+ * *
+ * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ ***************************************************************************/
+
+#include "sn9c102_sensor.h"
+
+
+static int mi0360_init(struct sn9c102_device* cam)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x0a, 0x14}, {0x40, 0x01},
+ {0x20, 0x17}, {0x07, 0x18},
+ {0xa0, 0x19}, {0x02, 0x1c},
+ {0x03, 0x1d}, {0x0f, 0x1e},
+ {0x0c, 0x1f}, {0x00, 0x20},
+ {0x10, 0x21}, {0x20, 0x22},
+ {0x30, 0x23}, {0x40, 0x24},
+ {0x50, 0x25}, {0x60, 0x26},
+ {0x70, 0x27}, {0x80, 0x28},
+ {0x90, 0x29}, {0xa0, 0x2a},
+ {0xb0, 0x2b}, {0xc0, 0x2c},
+ {0xd0, 0x2d}, {0xe0, 0x2e},
+ {0xf0, 0x2f}, {0xff, 0x30});
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
+ {0x00, 0x03}, {0x1a, 0x04},
+ {0x50, 0x05}, {0x20, 0x06},
+ {0x10, 0x07}, {0x03, 0x10},
+ {0x08, 0x14}, {0xa2, 0x17},
+ {0x47, 0x18}, {0x00, 0x19},
+ {0x1d, 0x1a}, {0x10, 0x1b},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x29, 0x21},
+ {0x40, 0x22}, {0x54, 0x23},
+ {0x66, 0x24}, {0x76, 0x25},
+ {0x85, 0x26}, {0x94, 0x27},
+ {0xa1, 0x28}, {0xae, 0x29},
+ {0xbb, 0x2a}, {0xc7, 0x2b},
+ {0xd3, 0x2c}, {0xde, 0x2d},
+ {0xea, 0x2e}, {0xf4, 0x2f},
+ {0xff, 0x30}, {0x00, 0x3F},
+ {0xC7, 0x40}, {0x01, 0x41},
+ {0x44, 0x42}, {0x00, 0x43},
+ {0x44, 0x44}, {0x00, 0x45},
+ {0x44, 0x46}, {0x00, 0x47},
+ {0xC7, 0x48}, {0x01, 0x49},
+ {0xC7, 0x4A}, {0x01, 0x4B},
+ {0xC7, 0x4C}, {0x01, 0x4D},
+ {0x44, 0x4E}, {0x00, 0x4F},
+ {0x44, 0x50}, {0x00, 0x51},
+ {0x44, 0x52}, {0x00, 0x53},
+ {0xC7, 0x54}, {0x01, 0x55},
+ {0xC7, 0x56}, {0x01, 0x57},
+ {0xC7, 0x58}, {0x01, 0x59},
+ {0x44, 0x5A}, {0x00, 0x5B},
+ {0x44, 0x5C}, {0x00, 0x5D},
+ {0x44, 0x5E}, {0x00, 0x5F},
+ {0xC7, 0x60}, {0x01, 0x61},
+ {0xC7, 0x62}, {0x01, 0x63},
+ {0xC7, 0x64}, {0x01, 0x65},
+ {0x44, 0x66}, {0x00, 0x67},
+ {0x44, 0x68}, {0x00, 0x69},
+ {0x44, 0x6A}, {0x00, 0x6B},
+ {0xC7, 0x6C}, {0x01, 0x6D},
+ {0xC7, 0x6E}, {0x01, 0x6F},
+ {0xC7, 0x70}, {0x01, 0x71},
+ {0x44, 0x72}, {0x00, 0x73},
+ {0x44, 0x74}, {0x00, 0x75},
+ {0x44, 0x76}, {0x00, 0x77},
+ {0xC7, 0x78}, {0x01, 0x79},
+ {0xC7, 0x7A}, {0x01, 0x7B},
+ {0xC7, 0x7C}, {0x01, 0x7D},
+ {0x44, 0x7E}, {0x00, 0x7F},
+ {0x14, 0x84}, {0x00, 0x85},
+ {0x27, 0x86}, {0x00, 0x87},
+ {0x07, 0x88}, {0x00, 0x89},
+ {0xEC, 0x8A}, {0x0f, 0x8B},
+ {0xD8, 0x8C}, {0x0f, 0x8D},
+ {0x3D, 0x8E}, {0x00, 0x8F},
+ {0x3D, 0x90}, {0x00, 0x91},
+ {0xCD, 0x92}, {0x0f, 0x93},
+ {0xf7, 0x94}, {0x0f, 0x95},
+ {0x0C, 0x96}, {0x00, 0x97},
+ {0x00, 0x98}, {0x66, 0x99},
+ {0x05, 0x9A}, {0x00, 0x9B},
+ {0x04, 0x9C}, {0x00, 0x9D},
+ {0x08, 0x9E}, {0x00, 0x9F},
+ {0x2D, 0xC0}, {0x2D, 0xC1},
+ {0x3A, 0xC2}, {0x05, 0xC3},
+ {0x04, 0xC4}, {0x3F, 0xC5},
+ {0x00, 0xC6}, {0x00, 0xC7},
+ {0x50, 0xC8}, {0x3C, 0xC9},
+ {0x28, 0xCA}, {0xD8, 0xCB},
+ {0x14, 0xCC}, {0xEC, 0xCD},
+ {0x32, 0xCE}, {0xDD, 0xCF},
+ {0x32, 0xD0}, {0xDD, 0xD1},
+ {0x6A, 0xD2}, {0x50, 0xD3},
+ {0x00, 0xD4}, {0x00, 0xD5},
+ {0x00, 0xD6});
+ break;
+ default:
+ break;
+ }
+
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
+ 0x00, 0x01, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
+ 0x00, 0x00, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
+ 0x01, 0xe1, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
+ 0x02, 0x81, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
+ 0x00, 0x17, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
+ 0x00, 0x11, 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
+ 0x04, 0x9a, 0, 0);
+
+ return err;
+}
+
+
+static int mi0360_get_ctrl(struct sn9c102_device* cam,
+ struct v4l2_control* ctrl)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ u8 data[2];
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[0];
+ return 0;
+ case V4L2_CID_GAIN:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1];
+ return 0;
+ case V4L2_CID_RED_BALANCE:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1];
+ return 0;
+ case V4L2_CID_BLUE_BALANCE:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1];
+ return 0;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1];
+ return 0;
+ case V4L2_CID_HFLIP:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1] & 0x20 ? 1 : 0;
+ return 0;
+ case V4L2_CID_VFLIP:
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
+ return -EIO;
+ ctrl->value = data[1] & 0x80 ? 1 : 0;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+static int mi0360_set_ctrl(struct sn9c102_device* cam,
+ const struct v4l2_control* ctrl)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x09, ctrl->value, 0x00,
+ 0, 0);
+ break;
+ case V4L2_CID_GAIN:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x35, 0x03, ctrl->value,
+ 0, 0);
+ break;
+ case V4L2_CID_RED_BALANCE:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x2c, 0x03, ctrl->value,
+ 0, 0);
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x2d, 0x03, ctrl->value,
+ 0, 0);
+ break;
+ case SN9C102_V4L2_CID_GREEN_BALANCE:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x2b, 0x03, ctrl->value,
+ 0, 0);
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x2e, 0x03, ctrl->value,
+ 0, 0);
+ break;
+ case V4L2_CID_HFLIP:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x20, ctrl->value ? 0x40:0x00,
+ ctrl->value ? 0x20:0x00,
+ 0, 0);
+ break;
+ case V4L2_CID_VFLIP:
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x20, ctrl->value ? 0x80:0x00,
+ ctrl->value ? 0x80:0x00,
+ 0, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return err ? -EIO : 0;
+}
+
+
+static int mi0360_set_crop(struct sn9c102_device* cam,
+ const struct v4l2_rect* rect)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+ u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0;
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
+ break;
+ default:
+ break;
+ }
+
+ err += sn9c102_write_reg(cam, h_start, 0x12);
+ err += sn9c102_write_reg(cam, v_start, 0x13);
+
+ return err;
+}
+
+
+static int mi0360_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x0a, 0x00, 0x05, 0, 0);
+ err += sn9c102_write_reg(cam, 0x60, 0x19);
+ if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+ sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+ err += sn9c102_write_reg(cam, 0xa6, 0x17);
+ } else {
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x0a, 0x00, 0x02, 0, 0);
+ err += sn9c102_write_reg(cam, 0x20, 0x19);
+ if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+ sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+ err += sn9c102_write_reg(cam, 0xa2, 0x17);
+ }
+
+ return err;
+}
+
+
+static const struct sn9c102_sensor mi0360 = {
+ .name = "MI-0360",
+ .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+ .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
+ .frequency = SN9C102_I2C_100KHZ,
+ .interface = SN9C102_I2C_2WIRES,
+ .i2c_slave_id = 0x5d,
+ .init = &mi0360_init,
+ .qctrl = {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x00,
+ .maximum = 0x0f,
+ .step = 0x01,
+ .default_value = 0x05,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "global gain",
+ .minimum = 0x00,
+ .maximum = 0x7f,
+ .step = 0x01,
+ .default_value = 0x25,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal mirror",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical mirror",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "blue balance",
+ .minimum = 0x00,
+ .maximum = 0x7f,
+ .step = 0x01,
+ .default_value = 0x0f,
+ .flags = 0,
+ },
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "red balance",
+ .minimum = 0x00,
+ .maximum = 0x7f,
+ .step = 0x01,
+ .default_value = 0x32,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_GREEN_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "green balance",
+ .minimum = 0x00,
+ .maximum = 0x7f,
+ .step = 0x01,
+ .default_value = 0x25,
+ .flags = 0,
+ },
+ },
+ .get_ctrl = &mi0360_get_ctrl,
+ .set_ctrl = &mi0360_set_ctrl,
+ .cropcap = {
+ .bounds = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ .defrect = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+ },
+ .set_crop = &mi0360_set_crop,
+ .pix_format = {
+ .width = 640,
+ .height = 480,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .priv = 8,
+ },
+ .set_pix_format = &mi0360_set_pix_format
+};
+
+
+int sn9c102_probe_mi0360(struct sn9c102_device* cam)
+{
+
+ u8 data[2];
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17}))
+ return -EIO;
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
+ {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17}))
+ return -EIO;
+ break;
+ default:
+ break;
+ }
+
+ if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
+ 2, data) < 0)
+ return -EIO;
+
+ if (data[0] != 0x82 || data[1] != 0x43)
+ return -ENODEV;
+
+ sn9c102_attach_sensor(cam, &mi0360);
+
+ return 0;
+}
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_ov7630.c b/linux/drivers/media/video/sn9c102/sn9c102_ov7630.c
index 7df09ff38..e68323478 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_ov7630.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_ov7630.c
@@ -22,9 +22,6 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor ov7630;
-
-
static int ov7630_init(struct sn9c102_device* cam)
{
int err = 0;
@@ -32,21 +29,19 @@ static int ov7630_init(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x0f, 0x18);
- err += sn9c102_write_reg(cam, 0x50, 0x19);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17},
+ {0x0f, 0x18}, {0x50, 0x19});
err += sn9c102_i2c_write(cam, 0x12, 0x8d);
err += sn9c102_i2c_write(cam, 0x12, 0x0d);
err += sn9c102_i2c_write(cam, 0x11, 0x00);
- err += sn9c102_i2c_write(cam, 0x15, 0x34);
- err += sn9c102_i2c_write(cam, 0x16, 0x03);
- err += sn9c102_i2c_write(cam, 0x17, 0x1c);
- err += sn9c102_i2c_write(cam, 0x18, 0xbd);
- err += sn9c102_i2c_write(cam, 0x19, 0x06);
- err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
+ err += sn9c102_i2c_write(cam, 0x15, 0x35);
+ err += sn9c102_i2c_write(cam, 0x16, 0x03);
+ err += sn9c102_i2c_write(cam, 0x17, 0x1c);
+ err += sn9c102_i2c_write(cam, 0x18, 0xbd);
+ err += sn9c102_i2c_write(cam, 0x19, 0x06);
+ err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
+ err += sn9c102_i2c_write(cam, 0x1b, 0x04);
err += sn9c102_i2c_write(cam, 0x20, 0x44);
err += sn9c102_i2c_write(cam, 0x23, 0xee);
err += sn9c102_i2c_write(cam, 0x26, 0xa0);
@@ -67,40 +62,23 @@ static int ov7630_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
break;
case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, 0x00, 0x02);
- err += sn9c102_write_reg(cam, 0x00, 0x03);
- err += sn9c102_write_reg(cam, 0x1a, 0x04);
- err += sn9c102_write_reg(cam, 0x20, 0x05);
- err += sn9c102_write_reg(cam, 0x20, 0x06);
- err += sn9c102_write_reg(cam, 0x20, 0x07);
- err += sn9c102_write_reg(cam, 0x03, 0x10);
- err += sn9c102_write_reg(cam, 0x0a, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x0f, 0x18);
- err += sn9c102_write_reg(cam, 0x50, 0x19);
- err += sn9c102_write_reg(cam, 0x1d, 0x1a);
- err += sn9c102_write_reg(cam, 0x10, 0x1b);
- err += sn9c102_write_reg(cam, 0x02, 0x1c);
- err += sn9c102_write_reg(cam, 0x03, 0x1d);
- err += sn9c102_write_reg(cam, 0x0f, 0x1e);
- err += sn9c102_write_reg(cam, 0x0c, 0x1f);
- err += sn9c102_write_reg(cam, 0x00, 0x20);
- err += sn9c102_write_reg(cam, 0x10, 0x21);
- err += sn9c102_write_reg(cam, 0x20, 0x22);
- err += sn9c102_write_reg(cam, 0x30, 0x23);
- err += sn9c102_write_reg(cam, 0x40, 0x24);
- err += sn9c102_write_reg(cam, 0x50, 0x25);
- err += sn9c102_write_reg(cam, 0x60, 0x26);
- err += sn9c102_write_reg(cam, 0x70, 0x27);
- err += sn9c102_write_reg(cam, 0x80, 0x28);
- err += sn9c102_write_reg(cam, 0x90, 0x29);
- err += sn9c102_write_reg(cam, 0xa0, 0x2a);
- err += sn9c102_write_reg(cam, 0xb0, 0x2b);
- err += sn9c102_write_reg(cam, 0xc0, 0x2c);
- err += sn9c102_write_reg(cam, 0xd0, 0x2d);
- err += sn9c102_write_reg(cam, 0xe0, 0x2e);
- err += sn9c102_write_reg(cam, 0xf0, 0x2f);
- err += sn9c102_write_reg(cam, 0xff, 0x30);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
+ {0x1a, 0x04}, {0x20, 0x05},
+ {0x20, 0x06}, {0x20, 0x07},
+ {0x03, 0x10}, {0x0a, 0x14},
+ {0x60, 0x17}, {0x0f, 0x18},
+ {0x50, 0x19}, {0x1d, 0x1a},
+ {0x10, 0x1b}, {0x02, 0x1c},
+ {0x03, 0x1d}, {0x0f, 0x1e},
+ {0x0c, 0x1f}, {0x00, 0x20},
+ {0x10, 0x21}, {0x20, 0x22},
+ {0x30, 0x23}, {0x40, 0x24},
+ {0x50, 0x25}, {0x60, 0x26},
+ {0x70, 0x27}, {0x80, 0x28},
+ {0x90, 0x29}, {0xa0, 0x2a},
+ {0xb0, 0x2b}, {0xc0, 0x2c},
+ {0xd0, 0x2d}, {0xe0, 0x2e},
+ {0xf0, 0x2f}, {0xff, 0x30});
err += sn9c102_i2c_write(cam, 0x12, 0x8d);
err += sn9c102_i2c_write(cam, 0x12, 0x0d);
@@ -108,23 +86,23 @@ static int ov7630_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x11, 0x01);
err += sn9c102_i2c_write(cam, 0x1b, 0x04);
err += sn9c102_i2c_write(cam, 0x20, 0x44);
- err += sn9c102_i2c_write(cam, 0x23, 0xee);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0x9a);
+ err += sn9c102_i2c_write(cam, 0x23, 0xee);
+ err += sn9c102_i2c_write(cam, 0x26, 0xa0);
+ err += sn9c102_i2c_write(cam, 0x27, 0x9a);
err += sn9c102_i2c_write(cam, 0x28, 0x20);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
- err += sn9c102_i2c_write(cam, 0x30, 0x24);
- err += sn9c102_i2c_write(cam, 0x32, 0x86);
- err += sn9c102_i2c_write(cam, 0x60, 0xa9);
- err += sn9c102_i2c_write(cam, 0x61, 0x42);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x88);
- err += sn9c102_i2c_write(cam, 0x70, 0x0b);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x74, 0x21);
- err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
+ err += sn9c102_i2c_write(cam, 0x29, 0x30);
+ err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
+ err += sn9c102_i2c_write(cam, 0x30, 0x24);
+ err += sn9c102_i2c_write(cam, 0x32, 0x86);
+ err += sn9c102_i2c_write(cam, 0x60, 0xa9);
+ err += sn9c102_i2c_write(cam, 0x61, 0x42);
+ err += sn9c102_i2c_write(cam, 0x65, 0x00);
+ err += sn9c102_i2c_write(cam, 0x69, 0x38);
+ err += sn9c102_i2c_write(cam, 0x6f, 0x88);
+ err += sn9c102_i2c_write(cam, 0x70, 0x0b);
+ err += sn9c102_i2c_write(cam, 0x71, 0x00);
+ err += sn9c102_i2c_write(cam, 0x74, 0x21);
+ err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
break;
default:
break;
@@ -273,7 +251,7 @@ static int ov7630_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor ov7630 = {
+static const struct sn9c102_sensor ov7630 = {
.name = "OV7630",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -428,20 +406,16 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17});
break;
case BRIDGE_SN9C103: /* do _not_ change anything! */
- err += sn9c102_write_reg(cam, 0x09, 0x01);
- err += sn9c102_write_reg(cam, 0x42, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
- err += sn9c102_write_reg(cam, 0x44, 0x02);
+ err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01},
+ {0x28, 0x17}, {0x44, 0x02});
pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
- if (err || pid < 0) { /* try a different initialization */
- err = sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- }
+ if (err || pid < 0) /* try a different initialization */
+ err += sn9c102_write_const_regs(cam, {0x01, 0x01},
+ {0x00, 0x01});
break;
default:
break;
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_ov7660.c b/linux/drivers/media/video/sn9c102/sn9c102_ov7660.c
index d670c24d4..4b6474048 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_ov7660.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_ov7660.c
@@ -22,166 +22,90 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor ov7660;
-
-
static int ov7660_init(struct sn9c102_device* cam)
{
int err = 0;
- err += sn9c102_write_reg(cam, 0x40, 0x02);
- err += sn9c102_write_reg(cam, 0x00, 0x03);
- err += sn9c102_write_reg(cam, 0x1a, 0x04);
- err += sn9c102_write_reg(cam, 0x03, 0x10);
- err += sn9c102_write_reg(cam, 0x08, 0x14);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x8b, 0x18);
- err += sn9c102_write_reg(cam, 0x00, 0x19);
- err += sn9c102_write_reg(cam, 0x1d, 0x1a);
- err += sn9c102_write_reg(cam, 0x10, 0x1b);
- err += sn9c102_write_reg(cam, 0x02, 0x1c);
- err += sn9c102_write_reg(cam, 0x03, 0x1d);
- err += sn9c102_write_reg(cam, 0x0f, 0x1e);
- err += sn9c102_write_reg(cam, 0x0c, 0x1f);
- err += sn9c102_write_reg(cam, 0x00, 0x20);
- err += sn9c102_write_reg(cam, 0x29, 0x21);
- err += sn9c102_write_reg(cam, 0x40, 0x22);
- err += sn9c102_write_reg(cam, 0x54, 0x23);
- err += sn9c102_write_reg(cam, 0x66, 0x24);
- err += sn9c102_write_reg(cam, 0x76, 0x25);
- err += sn9c102_write_reg(cam, 0x85, 0x26);
- err += sn9c102_write_reg(cam, 0x94, 0x27);
- err += sn9c102_write_reg(cam, 0xa1, 0x28);
- err += sn9c102_write_reg(cam, 0xae, 0x29);
- err += sn9c102_write_reg(cam, 0xbb, 0x2a);
- err += sn9c102_write_reg(cam, 0xc7, 0x2b);
- err += sn9c102_write_reg(cam, 0xd3, 0x2c);
- err += sn9c102_write_reg(cam, 0xde, 0x2d);
- err += sn9c102_write_reg(cam, 0xea, 0x2e);
- err += sn9c102_write_reg(cam, 0xf4, 0x2f);
- err += sn9c102_write_reg(cam, 0xff, 0x30);
- err += sn9c102_write_reg(cam, 0x00, 0x3F);
- err += sn9c102_write_reg(cam, 0xC7, 0x40);
- err += sn9c102_write_reg(cam, 0x01, 0x41);
- err += sn9c102_write_reg(cam, 0x44, 0x42);
- err += sn9c102_write_reg(cam, 0x00, 0x43);
- err += sn9c102_write_reg(cam, 0x44, 0x44);
- err += sn9c102_write_reg(cam, 0x00, 0x45);
- err += sn9c102_write_reg(cam, 0x44, 0x46);
- err += sn9c102_write_reg(cam, 0x00, 0x47);
- err += sn9c102_write_reg(cam, 0xC7, 0x48);
- err += sn9c102_write_reg(cam, 0x01, 0x49);
- err += sn9c102_write_reg(cam, 0xC7, 0x4A);
- err += sn9c102_write_reg(cam, 0x01, 0x4B);
- err += sn9c102_write_reg(cam, 0xC7, 0x4C);
- err += sn9c102_write_reg(cam, 0x01, 0x4D);
- err += sn9c102_write_reg(cam, 0x44, 0x4E);
- err += sn9c102_write_reg(cam, 0x00, 0x4F);
- err += sn9c102_write_reg(cam, 0x44, 0x50);
- err += sn9c102_write_reg(cam, 0x00, 0x51);
- err += sn9c102_write_reg(cam, 0x44, 0x52);
- err += sn9c102_write_reg(cam, 0x00, 0x53);
- err += sn9c102_write_reg(cam, 0xC7, 0x54);
- err += sn9c102_write_reg(cam, 0x01, 0x55);
- err += sn9c102_write_reg(cam, 0xC7, 0x56);
- err += sn9c102_write_reg(cam, 0x01, 0x57);
- err += sn9c102_write_reg(cam, 0xC7, 0x58);
- err += sn9c102_write_reg(cam, 0x01, 0x59);
- err += sn9c102_write_reg(cam, 0x44, 0x5A);
- err += sn9c102_write_reg(cam, 0x00, 0x5B);
- err += sn9c102_write_reg(cam, 0x44, 0x5C);
- err += sn9c102_write_reg(cam, 0x00, 0x5D);
- err += sn9c102_write_reg(cam, 0x44, 0x5E);
- err += sn9c102_write_reg(cam, 0x00, 0x5F);
- err += sn9c102_write_reg(cam, 0xC7, 0x60);
- err += sn9c102_write_reg(cam, 0x01, 0x61);
- err += sn9c102_write_reg(cam, 0xC7, 0x62);
- err += sn9c102_write_reg(cam, 0x01, 0x63);
- err += sn9c102_write_reg(cam, 0xC7, 0x64);
- err += sn9c102_write_reg(cam, 0x01, 0x65);
- err += sn9c102_write_reg(cam, 0x44, 0x66);
- err += sn9c102_write_reg(cam, 0x00, 0x67);
- err += sn9c102_write_reg(cam, 0x44, 0x68);
- err += sn9c102_write_reg(cam, 0x00, 0x69);
- err += sn9c102_write_reg(cam, 0x44, 0x6A);
- err += sn9c102_write_reg(cam, 0x00, 0x6B);
- err += sn9c102_write_reg(cam, 0xC7, 0x6C);
- err += sn9c102_write_reg(cam, 0x01, 0x6D);
- err += sn9c102_write_reg(cam, 0xC7, 0x6E);
- err += sn9c102_write_reg(cam, 0x01, 0x6F);
- err += sn9c102_write_reg(cam, 0xC7, 0x70);
- err += sn9c102_write_reg(cam, 0x01, 0x71);
- err += sn9c102_write_reg(cam, 0x44, 0x72);
- err += sn9c102_write_reg(cam, 0x00, 0x73);
- err += sn9c102_write_reg(cam, 0x44, 0x74);
- err += sn9c102_write_reg(cam, 0x00, 0x75);
- err += sn9c102_write_reg(cam, 0x44, 0x76);
- err += sn9c102_write_reg(cam, 0x00, 0x77);
- err += sn9c102_write_reg(cam, 0xC7, 0x78);
- err += sn9c102_write_reg(cam, 0x01, 0x79);
- err += sn9c102_write_reg(cam, 0xC7, 0x7A);
- err += sn9c102_write_reg(cam, 0x01, 0x7B);
- err += sn9c102_write_reg(cam, 0xC7, 0x7C);
- err += sn9c102_write_reg(cam, 0x01, 0x7D);
- err += sn9c102_write_reg(cam, 0x44, 0x7E);
- err += sn9c102_write_reg(cam, 0x00, 0x7F);
- err += sn9c102_write_reg(cam, 0x14, 0x84);
- err += sn9c102_write_reg(cam, 0x00, 0x85);
- err += sn9c102_write_reg(cam, 0x27, 0x86);
- err += sn9c102_write_reg(cam, 0x00, 0x87);
- err += sn9c102_write_reg(cam, 0x07, 0x88);
- err += sn9c102_write_reg(cam, 0x00, 0x89);
- err += sn9c102_write_reg(cam, 0xEC, 0x8A);
- err += sn9c102_write_reg(cam, 0x0f, 0x8B);
- err += sn9c102_write_reg(cam, 0xD8, 0x8C);
- err += sn9c102_write_reg(cam, 0x0f, 0x8D);
- err += sn9c102_write_reg(cam, 0x3D, 0x8E);
- err += sn9c102_write_reg(cam, 0x00, 0x8F);
- err += sn9c102_write_reg(cam, 0x3D, 0x90);
- err += sn9c102_write_reg(cam, 0x00, 0x91);
- err += sn9c102_write_reg(cam, 0xCD, 0x92);
- err += sn9c102_write_reg(cam, 0x0f, 0x93);
- err += sn9c102_write_reg(cam, 0xf7, 0x94);
- err += sn9c102_write_reg(cam, 0x0f, 0x95);
- err += sn9c102_write_reg(cam, 0x0C, 0x96);
- err += sn9c102_write_reg(cam, 0x00, 0x97);
- err += sn9c102_write_reg(cam, 0x00, 0x98);
- err += sn9c102_write_reg(cam, 0x66, 0x99);
- err += sn9c102_write_reg(cam, 0x05, 0x9A);
- err += sn9c102_write_reg(cam, 0x00, 0x9B);
- err += sn9c102_write_reg(cam, 0x04, 0x9C);
- err += sn9c102_write_reg(cam, 0x00, 0x9D);
- err += sn9c102_write_reg(cam, 0x08, 0x9E);
- err += sn9c102_write_reg(cam, 0x00, 0x9F);
- err += sn9c102_write_reg(cam, 0x2D, 0xC0);
- err += sn9c102_write_reg(cam, 0x2D, 0xC1);
- err += sn9c102_write_reg(cam, 0x3A, 0xC2);
- err += sn9c102_write_reg(cam, 0x05, 0xC3);
- err += sn9c102_write_reg(cam, 0x04, 0xC4);
- err += sn9c102_write_reg(cam, 0x3F, 0xC5);
- err += sn9c102_write_reg(cam, 0x00, 0xC6);
- err += sn9c102_write_reg(cam, 0x00, 0xC7);
- err += sn9c102_write_reg(cam, 0x50, 0xC8);
- err += sn9c102_write_reg(cam, 0x3C, 0xC9);
- err += sn9c102_write_reg(cam, 0x28, 0xCA);
- err += sn9c102_write_reg(cam, 0xD8, 0xCB);
- err += sn9c102_write_reg(cam, 0x14, 0xCC);
- err += sn9c102_write_reg(cam, 0xEC, 0xCD);
- err += sn9c102_write_reg(cam, 0x32, 0xCE);
- err += sn9c102_write_reg(cam, 0xDD, 0xCF);
- err += sn9c102_write_reg(cam, 0x32, 0xD0);
- err += sn9c102_write_reg(cam, 0xDD, 0xD1);
- err += sn9c102_write_reg(cam, 0x6A, 0xD2);
- err += sn9c102_write_reg(cam, 0x50, 0xD3);
- err += sn9c102_write_reg(cam, 0x00, 0xD4);
- err += sn9c102_write_reg(cam, 0x00, 0xD5);
- err += sn9c102_write_reg(cam, 0x00, 0xD6);
+ err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03},
+ {0x1a, 0x04}, {0x03, 0x10},
+ {0x08, 0x14}, {0x20, 0x17},
+ {0x8b, 0x18}, {0x00, 0x19},
+ {0x1d, 0x1a}, {0x10, 0x1b},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x29, 0x21},
+ {0x40, 0x22}, {0x54, 0x23},
+ {0x66, 0x24}, {0x76, 0x25},
+ {0x85, 0x26}, {0x94, 0x27},
+ {0xa1, 0x28}, {0xae, 0x29},
+ {0xbb, 0x2a}, {0xc7, 0x2b},
+ {0xd3, 0x2c}, {0xde, 0x2d},
+ {0xea, 0x2e}, {0xf4, 0x2f},
+ {0xff, 0x30}, {0x00, 0x3F},
+ {0xC7, 0x40}, {0x01, 0x41},
+ {0x44, 0x42}, {0x00, 0x43},
+ {0x44, 0x44}, {0x00, 0x45},
+ {0x44, 0x46}, {0x00, 0x47},
+ {0xC7, 0x48}, {0x01, 0x49},
+ {0xC7, 0x4A}, {0x01, 0x4B},
+ {0xC7, 0x4C}, {0x01, 0x4D},
+ {0x44, 0x4E}, {0x00, 0x4F},
+ {0x44, 0x50}, {0x00, 0x51},
+ {0x44, 0x52}, {0x00, 0x53},
+ {0xC7, 0x54}, {0x01, 0x55},
+ {0xC7, 0x56}, {0x01, 0x57},
+ {0xC7, 0x58}, {0x01, 0x59},
+ {0x44, 0x5A}, {0x00, 0x5B},
+ {0x44, 0x5C}, {0x00, 0x5D},
+ {0x44, 0x5E}, {0x00, 0x5F},
+ {0xC7, 0x60}, {0x01, 0x61},
+ {0xC7, 0x62}, {0x01, 0x63},
+ {0xC7, 0x64}, {0x01, 0x65},
+ {0x44, 0x66}, {0x00, 0x67},
+ {0x44, 0x68}, {0x00, 0x69},
+ {0x44, 0x6A}, {0x00, 0x6B},
+ {0xC7, 0x6C}, {0x01, 0x6D},
+ {0xC7, 0x6E}, {0x01, 0x6F},
+ {0xC7, 0x70}, {0x01, 0x71},
+ {0x44, 0x72}, {0x00, 0x73},
+ {0x44, 0x74}, {0x00, 0x75},
+ {0x44, 0x76}, {0x00, 0x77},
+ {0xC7, 0x78}, {0x01, 0x79},
+ {0xC7, 0x7A}, {0x01, 0x7B},
+ {0xC7, 0x7C}, {0x01, 0x7D},
+ {0x44, 0x7E}, {0x00, 0x7F},
+ {0x14, 0x84}, {0x00, 0x85},
+ {0x27, 0x86}, {0x00, 0x87},
+ {0x07, 0x88}, {0x00, 0x89},
+ {0xEC, 0x8A}, {0x0f, 0x8B},
+ {0xD8, 0x8C}, {0x0f, 0x8D},
+ {0x3D, 0x8E}, {0x00, 0x8F},
+ {0x3D, 0x90}, {0x00, 0x91},
+ {0xCD, 0x92}, {0x0f, 0x93},
+ {0xf7, 0x94}, {0x0f, 0x95},
+ {0x0C, 0x96}, {0x00, 0x97},
+ {0x00, 0x98}, {0x66, 0x99},
+ {0x05, 0x9A}, {0x00, 0x9B},
+ {0x04, 0x9C}, {0x00, 0x9D},
+ {0x08, 0x9E}, {0x00, 0x9F},
+ {0x2D, 0xC0}, {0x2D, 0xC1},
+ {0x3A, 0xC2}, {0x05, 0xC3},
+ {0x04, 0xC4}, {0x3F, 0xC5},
+ {0x00, 0xC6}, {0x00, 0xC7},
+ {0x50, 0xC8}, {0x3C, 0xC9},
+ {0x28, 0xCA}, {0xD8, 0xCB},
+ {0x14, 0xCC}, {0xEC, 0xCD},
+ {0x32, 0xCE}, {0xDD, 0xCF},
+ {0x32, 0xD0}, {0xDD, 0xD1},
+ {0x6A, 0xD2}, {0x50, 0xD3},
+ {0x00, 0xD4}, {0x00, 0xD5},
+ {0x00, 0xD6});
err += sn9c102_i2c_write(cam, 0x12, 0x80);
err += sn9c102_i2c_write(cam, 0x11, 0x09);
err += sn9c102_i2c_write(cam, 0x00, 0x0A);
- err += sn9c102_i2c_write(cam, 0x01, 0x78);
- err += sn9c102_i2c_write(cam, 0x02, 0x90);
+ err += sn9c102_i2c_write(cam, 0x01, 0x80);
+ err += sn9c102_i2c_write(cam, 0x02, 0x80);
err += sn9c102_i2c_write(cam, 0x03, 0x00);
err += sn9c102_i2c_write(cam, 0x04, 0x00);
err += sn9c102_i2c_write(cam, 0x05, 0x08);
@@ -198,7 +122,7 @@ static int ov7660_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x10, 0x20);
err += sn9c102_i2c_write(cam, 0x11, 0x03);
err += sn9c102_i2c_write(cam, 0x12, 0x05);
- err += sn9c102_i2c_write(cam, 0x13, 0xF8);
+ err += sn9c102_i2c_write(cam, 0x13, 0xC7);
err += sn9c102_i2c_write(cam, 0x14, 0x2C);
err += sn9c102_i2c_write(cam, 0x15, 0x00);
err += sn9c102_i2c_write(cam, 0x16, 0x02);
@@ -238,7 +162,7 @@ static int ov7660_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x38, 0x02);
err += sn9c102_i2c_write(cam, 0x39, 0x43);
err += sn9c102_i2c_write(cam, 0x3A, 0x00);
- err += sn9c102_i2c_write(cam, 0x3B, 0x02);
+ err += sn9c102_i2c_write(cam, 0x3B, 0x0A);
err += sn9c102_i2c_write(cam, 0x3C, 0x6C);
err += sn9c102_i2c_write(cam, 0x3D, 0x99);
err += sn9c102_i2c_write(cam, 0x3E, 0x0E);
@@ -357,25 +281,34 @@ static int ov7660_get_ctrl(struct sn9c102_device* cam,
return -EIO;
break;
case V4L2_CID_DO_WHITE_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x02);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x02)) < 0)
+ return -EIO;
ctrl->value = (ctrl->value & 0x04) ? 1 : 0;
break;
case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x05);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x05)) < 0)
+ return -EIO;
ctrl->value &= 0x7f;
break;
case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x06);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x06)) < 0)
+ return -EIO;
ctrl->value &= 0x7f;
break;
case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x07);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x07)) < 0)
+ return -EIO;
ctrl->value &= 0x7f;
break;
+ case SN9C102_V4L2_CID_BAND_FILTER:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x3b)) < 0)
+ return -EIO;
+ ctrl->value &= 0x08;
+ break;
case V4L2_CID_GAIN:
if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0)
return -EIO;
- ctrl->value &= 0x7f;
+ ctrl->value &= 0x1f;
break;
case V4L2_CID_AUTOGAIN:
if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0)
@@ -411,12 +344,15 @@ static int ov7660_set_ctrl(struct sn9c102_device* cam,
case SN9C102_V4L2_CID_GREEN_BALANCE:
err += sn9c102_write_reg(cam, ctrl->value, 0x07);
break;
+ case SN9C102_V4L2_CID_BAND_FILTER:
+ err += sn9c102_i2c_write(cam, ctrl->value << 3, 0x3b);
+ break;
case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
+ err += sn9c102_i2c_write(cam, 0x00, 0x60 + ctrl->value);
break;
case V4L2_CID_AUTOGAIN:
- err += sn9c102_i2c_write(cam, 0x13, 0xf0 | ctrl->value |
- (ctrl->value << 1));
+ err += sn9c102_i2c_write(cam, 0x13, 0xc0 |
+ (ctrl->value * 0x07));
break;
default:
return -EINVAL;
@@ -462,7 +398,7 @@ static int ov7660_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor ov7660 = {
+static const struct sn9c102_sensor ov7660 = {
.name = "OV7660",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -477,9 +413,9 @@ static struct sn9c102_sensor ov7660 = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "global gain",
.minimum = 0x00,
- .maximum = 0x7f,
+ .maximum = 0x1f,
.step = 0x01,
- .default_value = 0x0a,
+ .default_value = 0x09,
.flags = 0,
},
{
@@ -489,7 +425,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0xff,
.step = 0x01,
- .default_value = 0x50,
+ .default_value = 0x27,
.flags = 0,
},
{
@@ -509,7 +445,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x7f,
.step = 0x01,
- .default_value = 0x1f,
+ .default_value = 0x14,
.flags = 0,
},
{
@@ -519,7 +455,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x7f,
.step = 0x01,
- .default_value = 0x1e,
+ .default_value = 0x14,
.flags = 0,
},
{
@@ -529,7 +465,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x01,
.step = 0x01,
- .default_value = 0x00,
+ .default_value = 0x01,
.flags = 0,
},
{
@@ -539,7 +475,17 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x7f,
.step = 0x01,
- .default_value = 0x20,
+ .default_value = 0x14,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_BAND_FILTER,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "band filter",
+ .minimum = 0x00,
+ .maximum = 0x01,
+ .step = 0x01,
+ .default_value = 0x00,
.flags = 0,
},
},
@@ -572,13 +518,11 @@ static struct sn9c102_sensor ov7660 = {
int sn9c102_probe_ov7660(struct sn9c102_device* cam)
{
- int pid, ver, err = 0;
+ int pid, ver, err;
- err += sn9c102_write_reg(cam, 0x01, 0xf1);
- err += sn9c102_write_reg(cam, 0x00, 0xf1);
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- err += sn9c102_write_reg(cam, 0x28, 0x17);
+ err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
+ {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17});
pid = sn9c102_i2c_try_read(cam, &ov7660, 0x0a);
ver = sn9c102_i2c_try_read(cam, &ov7660, 0x0b);
@@ -586,6 +530,7 @@ int sn9c102_probe_ov7660(struct sn9c102_device* cam)
return -EIO;
if (pid != 0x76 || ver != 0x60)
return -ENODEV;
+
sn9c102_attach_sensor(cam, &ov7660);
return 0;
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_pas106b.c b/linux/drivers/media/video/sn9c102/sn9c102_pas106b.c
index 8d79a5fae..360f2a848 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_pas106b.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_pas106b.c
@@ -23,19 +23,13 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor pas106b;
-
-
static int pas106b_init(struct sn9c102_device* cam)
{
int err = 0;
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- err += sn9c102_write_reg(cam, 0x09, 0x18);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x20, 0x17},
+ {0x20, 0x19}, {0x09, 0x18});
err += sn9c102_i2c_write(cam, 0x02, 0x0c);
err += sn9c102_i2c_write(cam, 0x05, 0x5a);
@@ -169,10 +163,10 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor pas106b = {
+static const struct sn9c102_sensor pas106b = {
.name = "PAS106B",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
@@ -279,22 +273,21 @@ static struct sn9c102_sensor pas106b = {
int sn9c102_probe_pas106b(struct sn9c102_device* cam)
{
- int r0 = 0, r1 = 0, err = 0;
+ int r0 = 0, r1 = 0;
unsigned int pid = 0;
/*
Minimal initialization to enable the I2C communication
NOTE: do NOT change the values!
*/
- err += sn9c102_write_reg(cam, 0x01, 0x01); /* sensor power down */
- err += sn9c102_write_reg(cam, 0x00, 0x01); /* sensor power on */
- err += sn9c102_write_reg(cam, 0x28, 0x17); /* sensor clock at 24 MHz */
- if (err)
+ if (sn9c102_write_const_regs(cam,
+ {0x01, 0x01}, /* sensor power down */
+ {0x00, 0x01}, /* sensor power on */
+ {0x28, 0x17})) /* sensor clock at 24 MHz */
return -EIO;
r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
-
if (r0 < 0 || r1 < 0)
return -EIO;
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
index 7894f01b5..ca4a1506e 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
@@ -28,9 +28,6 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor pas202bcb;
-
-
static int pas202bcb_init(struct sn9c102_device* cam)
{
int err = 0;
@@ -38,47 +35,28 @@ static int pas202bcb_init(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x30, 0x19);
- err += sn9c102_write_reg(cam, 0x09, 0x18);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x20, 0x17},
+ {0x30, 0x19}, {0x09, 0x18});
break;
case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, 0x00, 0x02);
- err += sn9c102_write_reg(cam, 0x00, 0x03);
- err += sn9c102_write_reg(cam, 0x1a, 0x04);
- err += sn9c102_write_reg(cam, 0x20, 0x05);
- err += sn9c102_write_reg(cam, 0x20, 0x06);
- err += sn9c102_write_reg(cam, 0x20, 0x07);
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x30, 0x19);
- err += sn9c102_write_reg(cam, 0x09, 0x18);
- err += sn9c102_write_reg(cam, 0x02, 0x1c);
- err += sn9c102_write_reg(cam, 0x03, 0x1d);
- err += sn9c102_write_reg(cam, 0x0f, 0x1e);
- err += sn9c102_write_reg(cam, 0x0c, 0x1f);
- err += sn9c102_write_reg(cam, 0x00, 0x20);
- err += sn9c102_write_reg(cam, 0x10, 0x21);
- err += sn9c102_write_reg(cam, 0x20, 0x22);
- err += sn9c102_write_reg(cam, 0x30, 0x23);
- err += sn9c102_write_reg(cam, 0x40, 0x24);
- err += sn9c102_write_reg(cam, 0x50, 0x25);
- err += sn9c102_write_reg(cam, 0x60, 0x26);
- err += sn9c102_write_reg(cam, 0x70, 0x27);
- err += sn9c102_write_reg(cam, 0x80, 0x28);
- err += sn9c102_write_reg(cam, 0x90, 0x29);
- err += sn9c102_write_reg(cam, 0xa0, 0x2a);
- err += sn9c102_write_reg(cam, 0xb0, 0x2b);
- err += sn9c102_write_reg(cam, 0xc0, 0x2c);
- err += sn9c102_write_reg(cam, 0xd0, 0x2d);
- err += sn9c102_write_reg(cam, 0xe0, 0x2e);
- err += sn9c102_write_reg(cam, 0xf0, 0x2f);
- err += sn9c102_write_reg(cam, 0xff, 0x30);
+ err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
+ {0x1a, 0x04}, {0x20, 0x05},
+ {0x20, 0x06}, {0x20, 0x07},
+ {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x20, 0x17},
+ {0x30, 0x19}, {0x09, 0x18},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x10, 0x21},
+ {0x20, 0x22}, {0x30, 0x23},
+ {0x40, 0x24}, {0x50, 0x25},
+ {0x60, 0x26}, {0x70, 0x27},
+ {0x80, 0x28}, {0x90, 0x29},
+ {0xa0, 0x2a}, {0xb0, 0x2b},
+ {0xc0, 0x2c}, {0xd0, 0x2d},
+ {0xe0, 0x2e}, {0xf0, 0x2f},
+ {0xff, 0x30});
break;
default:
break;
@@ -218,7 +196,7 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor pas202bcb = {
+static const struct sn9c102_sensor pas202bcb = {
.name = "PAS202BCB",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -328,15 +306,14 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err += sn9c102_write_reg(cam, 0x01, 0x01); /* power down */
- err += sn9c102_write_reg(cam, 0x40, 0x01); /* power on */
- err += sn9c102_write_reg(cam, 0x28, 0x17); /* clock 24 MHz */
+ err = sn9c102_write_const_regs(cam,
+ {0x01, 0x01}, /* power down */
+ {0x40, 0x01}, /* power on */
+ {0x28, 0x17});/* clock 24 MHz */
break;
case BRIDGE_SN9C103: /* do _not_ change anything! */
- err += sn9c102_write_reg(cam, 0x09, 0x01);
- err += sn9c102_write_reg(cam, 0x44, 0x01);
- err += sn9c102_write_reg(cam, 0x44, 0x02);
- err += sn9c102_write_reg(cam, 0x29, 0x17);
+ err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01},
+ {0x44, 0x02}, {0x29, 0x17});
break;
default:
break;
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_sensor.h b/linux/drivers/media/video/sn9c102/sn9c102_sensor.h
index 4fceceab6..d5fffc569 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_sensor.h
+++ b/linux/drivers/media/video/sn9c102/sn9c102_sensor.h
@@ -22,12 +22,12 @@
#define _SN9C102_SENSOR_H_
#include <linux/usb.h>
-#include "compat.h"
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/device.h>
#include <linux/stddef.h>
#include <linux/errno.h>
#include <asm/types.h>
+#include "compat.h"
struct sn9c102_device;
struct sn9c102_sensor;
@@ -75,7 +75,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id);
/* Attach a probed sensor to the camera. */
extern void
sn9c102_attach_sensor(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor);
+ const struct sn9c102_sensor* sensor);
/*
Read/write routines: they always return -1 on error, 0 or the read value
@@ -86,10 +86,11 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
*/
/* The "try" I2C I/O versions are used when probing the sensor */
-extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
- u8 address, u8 value);
-extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
- u8 address);
+extern int sn9c102_i2c_try_write(struct sn9c102_device*,
+ const struct sn9c102_sensor*, u8 address,
+ u8 value);
+extern int sn9c102_i2c_try_read(struct sn9c102_device*,
+ const struct sn9c102_sensor*, u8 address);
/*
These must be used if and only if the sensor doesn't implement the standard
@@ -103,21 +104,31 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
byte.
*/
extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 n,
+ const struct sn9c102_sensor* sensor, u8 n,
u8 data0, u8 data1, u8 data2, u8 data3,
u8 data4, u8 data5);
extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 data0,
- u8 data1, u8 n, u8 buffer[]);
+ const struct sn9c102_sensor* sensor,
+ u8 data0, u8 data1, u8 n, u8 buffer[]);
/* To be used after the sensor struct has been attached to the camera struct */
extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
/* I/O on registers in the bridge. Could be used by the sensor methods too */
-extern int sn9c102_write_regs(struct sn9c102_device*, u8* buff, u16 index);
-extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
+extern int sn9c102_read_reg(struct sn9c102_device*, u16 index);
extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
+extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
+extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
+ int count);
+/*
+ Write multiple registers with constant values. For example:
+ sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
+ Register adresses must be < 256.
+*/
+#define sn9c102_write_const_regs(sn9c102_device, data...) \
+ ({ const static u8 _valreg[][2] = {data}; \
+ sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); })
/*****************************************************************************/
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
index 90023ad63..e7d2de2ba 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
@@ -22,21 +22,14 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor tas5110c1b;
-
-
static int tas5110c1b_init(struct sn9c102_device* cam)
{
int err = 0;
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x44, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x0a, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x06, 0x18);
- err += sn9c102_write_reg(cam, 0xfb, 0x19);
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x44, 0x01},
+ {0x00, 0x10}, {0x00, 0x11},
+ {0x0a, 0x14}, {0x60, 0x17},
+ {0x06, 0x18}, {0xfb, 0x19});
err += sn9c102_i2c_write(cam, 0xc0, 0x80);
@@ -95,10 +88,10 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor tas5110c1b = {
+static const struct sn9c102_sensor tas5110c1b = {
.name = "TAS5110C1B",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.sysfs_ops = SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_3WIRES,
@@ -146,7 +139,6 @@ int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam)
const struct usb_device_id tas5110c1b_id_table[] = {
{ USB_DEVICE(0x0c45, 0x6001), },
{ USB_DEVICE(0x0c45, 0x6005), },
- { USB_DEVICE(0x0c45, 0x6007), },
{ USB_DEVICE(0x0c45, 0x60ab), },
{ }
};
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/linux/drivers/media/video/sn9c102/sn9c102_tas5110d.c
new file mode 100644
index 000000000..d32fdbccd
--- /dev/null
+++ b/linux/drivers/media/video/sn9c102/sn9c102_tas5110d.c
@@ -0,0 +1,118 @@
+/***************************************************************************
+ * Plug-in for TAS5110D image sensor connected to the SN9C1xx PC Camera *
+ * Controllers *
+ * *
+ * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ ***************************************************************************/
+
+#include "sn9c102_sensor.h"
+
+
+static int tas5110d_init(struct sn9c102_device* cam)
+{
+ int err;
+
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x04, 0x01},
+ {0x0a, 0x14}, {0x60, 0x17},
+ {0x06, 0x18}, {0xfb, 0x19});
+
+ err += sn9c102_i2c_write(cam, 0x9a, 0xca);
+
+ return err;
+}
+
+
+static int tas5110d_set_crop(struct sn9c102_device* cam,
+ const struct v4l2_rect* rect)
+{
+ struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
+ int err = 0;
+ u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69,
+ v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9;
+
+ err += sn9c102_write_reg(cam, h_start, 0x12);
+ err += sn9c102_write_reg(cam, v_start, 0x13);
+
+ err += sn9c102_write_reg(cam, 0x14, 0x1a);
+ err += sn9c102_write_reg(cam, 0x0a, 0x1b);
+
+ return err;
+}
+
+
+static int tas5110d_set_pix_format(struct sn9c102_device* cam,
+ const struct v4l2_pix_format* pix)
+{
+ int err = 0;
+
+ if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+ err += sn9c102_write_reg(cam, 0x3b, 0x19);
+ else
+ err += sn9c102_write_reg(cam, 0xfb, 0x19);
+
+ return err;
+}
+
+
+static const struct sn9c102_sensor tas5110d = {
+ .name = "TAS5110D",
+ .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
+ .sysfs_ops = SN9C102_I2C_WRITE,
+ .frequency = SN9C102_I2C_100KHZ,
+ .interface = SN9C102_I2C_2WIRES,
+ .i2c_slave_id = 0x61,
+ .init = &tas5110d_init,
+ .cropcap = {
+ .bounds = {
+ .left = 0,
+ .top = 0,
+ .width = 352,
+ .height = 288,
+ },
+ .defrect = {
+ .left = 0,
+ .top = 0,
+ .width = 352,
+ .height = 288,
+ },
+ },
+ .set_crop = &tas5110d_set_crop,
+ .pix_format = {
+ .width = 352,
+ .height = 288,
+ .pixelformat = V4L2_PIX_FMT_SBGGR8,
+ .priv = 8,
+ },
+ .set_pix_format = &tas5110d_set_pix_format
+};
+
+
+int sn9c102_probe_tas5110d(struct sn9c102_device* cam)
+{
+ const struct usb_device_id tas5110d_id_table[] = {
+ { USB_DEVICE(0x0c45, 0x6007), },
+ { }
+ };
+
+ if (!sn9c102_match_id(cam, tas5110d_id_table))
+ return -ENODEV;
+
+ sn9c102_attach_sensor(cam, &tas5110d);
+
+ return 0;
+}
diff --git a/linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
index cb1b318bc..56fb1d575 100644
--- a/linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
+++ b/linux/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
@@ -22,21 +22,14 @@
#include "sn9c102_sensor.h"
-static struct sn9c102_sensor tas5130d1b;
-
-
static int tas5130d1b_init(struct sn9c102_device* cam)
{
- int err = 0;
+ int err;
- err += sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x20, 0x17);
- err += sn9c102_write_reg(cam, 0x04, 0x01);
- err += sn9c102_write_reg(cam, 0x01, 0x10);
- err += sn9c102_write_reg(cam, 0x00, 0x11);
- err += sn9c102_write_reg(cam, 0x00, 0x14);
- err += sn9c102_write_reg(cam, 0x60, 0x17);
- err += sn9c102_write_reg(cam, 0x07, 0x18);
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x20, 0x17},
+ {0x04, 0x01}, {0x01, 0x10},
+ {0x00, 0x11}, {0x00, 0x14},
+ {0x60, 0x17}, {0x07, 0x18});
return err;
}
@@ -96,10 +89,10 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor tas5130d1b = {
+static const struct sn9c102_sensor tas5130d1b = {
.name = "TAS5130D1B",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
.sysfs_ops = SN9C102_I2C_WRITE,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_3WIRES,
diff --git a/linux/drivers/media/video/tda7432.c b/linux/drivers/media/video/tda7432.c
index 849309fff..3e9ca9ace 100644
--- a/linux/drivers/media/video/tda7432.c
+++ b/linux/drivers/media/video/tda7432.c
@@ -46,7 +46,6 @@
#include "compat.h"
#include <linux/videodev.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include "i2c-compat.h"
diff --git a/linux/drivers/media/video/tda8290.c b/linux/drivers/media/video/tda8290.c
index 109eb44a9..90ba0384e 100644
--- a/linux/drivers/media/video/tda8290.c
+++ b/linux/drivers/media/video/tda8290.c
@@ -466,7 +466,6 @@ static void set_audio(struct tuner *t)
char* mode;
t->tda827x_lpsel = 0;
- mode = "xx";
if (t->std & V4L2_STD_MN) {
t->sgIF = 92;
t->tda8290_easy_mode = 0x01;
@@ -496,8 +495,12 @@ static void set_audio(struct tuner *t)
t->sgIF = 20;
t->tda8290_easy_mode = 0x40;
mode = "LC";
+ } else {
+ t->sgIF = 124;
+ t->tda8290_easy_mode = 0x10;
+ mode = "xx";
}
- tuner_dbg("setting tda8290 to system %s\n", mode);
+ tuner_dbg("setting tda8290 to system %s\n", mode);
}
static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -640,6 +643,7 @@ int tda8290_init(struct i2c_client *c)
t->has_signal = has_signal;
t->standby = standby;
t->tda827x_lpsel = 0;
+ t->mode = V4L2_TUNER_ANALOG_TV;
tda8290_init_tuner(c);
tda8290_init_if(c);
diff --git a/linux/drivers/media/video/tda9875.c b/linux/drivers/media/video/tda9875.c
index c7fbfc1b3..12abefad7 100644
--- a/linux/drivers/media/video/tda9875.c
+++ b/linux/drivers/media/video/tda9875.c
@@ -28,7 +28,6 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
diff --git a/linux/drivers/media/video/tvaudio.c b/linux/drivers/media/video/tvaudio.c
index cc885951e..4b4153939 100644
--- a/linux/drivers/media/video/tvaudio.c
+++ b/linux/drivers/media/video/tvaudio.c
@@ -26,7 +26,6 @@
#include "compat.h"
#include <linux/videodev.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/kthread.h>
diff --git a/linux/drivers/media/video/usbvideo/Kconfig b/linux/drivers/media/video/usbvideo/Kconfig
index a0fd82b92..e4cb99c1f 100644
--- a/linux/drivers/media/video/usbvideo/Kconfig
+++ b/linux/drivers/media/video/usbvideo/Kconfig
@@ -3,7 +3,7 @@ config VIDEO_USBVIDEO
config USB_VICAM
tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
- depends on USB && VIDEO_DEV && VIDEO_V4L1 && EXPERIMENTAL
+ depends on VIDEO_V4L1 && EXPERIMENTAL
select VIDEO_USBVIDEO
---help---
Say Y here if you have 3com homeconnect camera (vicam).
@@ -13,7 +13,7 @@ config USB_VICAM
config USB_IBMCAM
tristate "USB IBM (Xirlink) C-it Camera support"
- depends on USB && VIDEO_DEV && VIDEO_V4L1
+ depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y here if you want to connect a IBM "C-It" camera, also known as
@@ -28,7 +28,7 @@ config USB_IBMCAM
config USB_KONICAWC
tristate "USB Konica Webcam support"
- depends on USB && VIDEO_DEV && VIDEO_V4L1
+ depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y here if you want support for webcams based on a Konica
@@ -39,7 +39,7 @@ config USB_KONICAWC
config USB_QUICKCAM_MESSENGER
tristate "USB Logitech Quickcam Messenger"
- depends on USB && VIDEO_DEV && VIDEO_V4L1
+ depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y or M here to enable support for the USB Logitech Quickcam
diff --git a/linux/drivers/media/video/usbvision/Kconfig b/linux/drivers/media/video/usbvision/Kconfig
index c43a5d899..fc24ef05b 100644
--- a/linux/drivers/media/video/usbvision/Kconfig
+++ b/linux/drivers/media/video/usbvision/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_USBVISION
tristate "USB video devices based on Nogatech NT1003/1004/1005"
- depends on I2C && VIDEO_V4L2 && USB
+ depends on I2C && VIDEO_V4L2
select VIDEO_TUNER
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
---help---
diff --git a/linux/drivers/media/video/usbvision/usbvision-cards.c b/linux/drivers/media/video/usbvision/usbvision-cards.c
index b23672ad9..3a704d07b 100644
--- a/linux/drivers/media/video/usbvision/usbvision-cards.c
+++ b/linux/drivers/media/video/usbvision/usbvision-cards.c
@@ -1,6 +1,6 @@
/*
- * USBVISION.H
- * usbvision header file
+ * usbvision-cards.c
+ * usbvision cards definition file
*
* Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
*
@@ -29,147 +29,1060 @@
#include <media/v4l2-dev.h>
#include <media/tuner.h>
#include "usbvision.h"
+#include "usbvision-cards.h"
/* Supported Devices: A table for usbvision.c*/
struct usbvision_device_data_st usbvision_device_data[] = {
- {0xfff0, 0xfff0, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Custom Dummy USBVision Device"},
- {0x0a6f, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "Xanboo"},
- {0x050d, 0x0106, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Belkin USB VideoBus II Adapter"},
- {0x050d, 0x0207, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "Belkin Components USB VideoBus"},
- {0x050d, 0x0208, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Belkin USB VideoBus II"},
- {0x0571, 0x0002, 0, CODEC_SAA7111, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, -1, -1, 7, "echoFX InterView Lite"},
- {0x0573, 0x0003, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "USBGear USBG-V1 resp. HAMA USB"},
- {0x0573, 0x0400, -1, CODEC_SAA7113, 4, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "D-Link V100"},
- {0x0573, 0x2000, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, "X10 USB Camera"},
- {0x0573, 0x2d00, -1, CODEC_SAA7111, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, -1, 3, 7, "Hauppauge WinTV USB Live (PAL B/G)"},
- {0x0573, 0x2d01, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Live Pro (NTSC M/N)"},
- {0x0573, 0x2101, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 2, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Zoran Co. PMD (Nogatech) AV-grabber Manhattan"},
- {0x0573, 0x4100, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "Nogatech USB-TV (NTSC) FM"},
- {0x0573, 0x4110, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "PNY USB-TV (NTSC) FM"},
- {0x0573, 0x4450, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "PixelView PlayTv-USB PRO (PAL) FM"},
- {0x0573, 0x4550, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "ZTV ZT-721 2.4GHz USB A/V Receiver"},
- {0x0573, 0x4d00, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, 20, -1, "Hauppauge WinTV USB (NTSC M/N)"},
- {0x0573, 0x4d01, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL B/G)"},
- {0x0573, 0x4d02, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL I)"},
- {0x0573, 0x4d03, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL/SECAM L)"},
- {0x0573, 0x4d04, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL D/K)"},
- {0x0573, 0x4d10, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (NTSC FM)"},
- {0x0573, 0x4d11, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL B/G FM)"},
- {0x0573, 0x4d12, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL I FM)"},
- {0x0573, 0x4d14, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Hauppauge WinTV USB (PAL D/K FM)"},
- {0x0573, 0x4d2a, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N)"},
- {0x0573, 0x4d2b, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N)"},
- {0x0573, 0x4d2c, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)"},
- {0x0573, 0x4d20, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N)"},
- {0x0573, 0x4d21, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G)"},
- {0x0573, 0x4d22, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL I)"},
- {0x0573, 0x4d23, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM L)"},
- {0x0573, 0x4d24, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL D/K)"},
- {0x0573, 0x4d25, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)"},
- {0x0573, 0x4d26, -1, CODEC_SAA7113, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)"},
- {0x0573, 0x4d27, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_ALPS_TSBE1_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G)"},
- {0x0573, 0x4d28, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_ALPS_TSBE1_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G,D/K)"},
- {0x0573, 0x4d29, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL I,D/K)"},
- {0x0573, 0x4d30, -1, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N FM)"},
- {0x0573, 0x4d31, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL B/G FM)"},
- {0x0573, 0x4d32, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL I FM)"},
- {0x0573, 0x4d34, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL D/K FM)"},
- {0x0573, 0x4d35, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)"},
- {0x0573, 0x4d36, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_MICROTUNE_4049FM5, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (Temic PAL B/G FM)"},
- {0x0573, 0x4d37, 0, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)"},
- {0x0573, 0x4d38, 0, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 0, 3, 7, "Hauppauge WinTV USB Pro (NTSC M/N FM)"},
- {0x0768, 0x0006, -1, CODEC_SAA7113, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, 5, 5, -1, "Camtel Technology USB TV Genie Pro FM Model TVB330"},
- {0x07d0, 0x0001, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Digital Video Creator I"},
- {0x07d0, 0x0002, -1, CODEC_SAA7111, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 82, 20, 7, "Global Village GV-007 (NTSC)"},
- {0x07d0, 0x0003, 0, CODEC_SAA7113, 2, V4L2_STD_NTSC, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)"},
- {0x07d0, 0x0004, 0, CODEC_SAA7113, 2, V4L2_STD_PAL, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-80 Rev 1 (PAL)"},
- {0x07d0, 0x0005, 0, CODEC_SAA7113, 2, V4L2_STD_SECAM, 0, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)"},
- {0x07f8, 0x9104, 0, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_FM1216ME_MK3, -1, -1, 0, 3, 7, "Eskape Labs MyTV2Go"},
- {0x2304, 0x010d, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 0, 1, TUNER_TEMIC_4066FY5_PAL_I, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (PAL)"},
- {0x2304, 0x0109, -1, CODEC_SAA7111, 3, V4L2_STD_SECAM, 1, 0, 1, 1, TUNER_PHILIPS_SECAM, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (SECAM)"},
- {0x2304, 0x0110, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_PHILIPS_PAL, -1, -1,128, 23, -1, "Pinnacle Studio PCTV USB (PAL) FM"},
- {0x2304, 0x0111, -1, CODEC_SAA7111, 3, V4L2_STD_PAL, 1, 0, 1, 1, TUNER_PHILIPS_PAL, -1, -1, -1, -1, -1, "Miro PCTV USB"},
- {0x2304, 0x0112, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Pinnacle Studio PCTV USB (NTSC) FM"},
- {0x2304, 0x0210, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_TEMIC_4009FR5_PAL, -1, -1, 0, 3, 7, "Pinnacle Studio PCTV USB (PAL) FM"},
- {0x2304, 0x0212, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 1, 1, 1, TUNER_TEMIC_4039FR5_NTSC, -1, -1, 0, 3, 7, "Pinnacle Studio PCTV USB (NTSC) FM"},
- {0x2304, 0x0214, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_TEMIC_4009FR5_PAL, -1, -1, 0, 3, 7, "Pinnacle Studio PCTV USB (PAL) FM"},
- {0x2304, 0x0300, -1, CODEC_SAA7113, 2, V4L2_STD_NTSC, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Pinnacle Studio Linx Video input cable (NTSC)"},
- {0x2304, 0x0301, -1, CODEC_SAA7113, 2, V4L2_STD_PAL, 1, 0, 1, 0, 0, -1, -1, 0, 3, 7, "Pinnacle Studio Linx Video input cable (PAL)"},
- {0x2304, 0x0419, -1, CODEC_SAA7113, 3, V4L2_STD_PAL, 1, 1, 1, 1, TUNER_TEMIC_4009FR5_PAL, -1, -1, 0, 3, 7, "Pinnacle PCTV Bungee USB (PAL) FM"},
- {0x2400, 0x4200, -1, CODEC_SAA7111, 3, V4L2_STD_NTSC, 1, 0, 1, 1, TUNER_PHILIPS_NTSC_M, -1, -1, -1, -1, -1, "Hauppauge WinTv-USB"},
- {} /* Terminating entry */
+ [XANBOO] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 4,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Xanboo",
+ },
+ [BELKIN_VIDEOBUS_II] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Belkin USB VideoBus II Adapter",
+ },
+ [BELKIN_VIDEOBUS] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Belkin Components USB VideoBus",
+ },
+ [BELKIN_USB_VIDEOBUS_II] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Belkin USB VideoBus II",
+ },
+ [ECHOFX_INTERVIEW_LITE] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "echoFX InterView Lite",
+ },
+ [USBGEAR_USBG_V1] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "USBGear USBG-V1 resp. HAMA USB",
+ },
+ [D_LINK_V100] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 4,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "D-Link V100",
+ },
+ [X10_USB_CAMERA] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "X10 USB Camera",
+ },
+ [HPG_WINTV_LIVE_PAL_BG] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = -1,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Live (PAL B/G)",
+ },
+ [HPG_WINTV_LIVE_PRO_NTSC_MN] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Live Pro (NTSC M/N)",
+ },
+ [ZORAN_PMD_NOGATECH] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 2,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Zoran Co. PMD (Nogatech) AV-grabber Manhattan",
+ },
+ [NOGATECH_USB_TV_NTSC_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = 20,
+ .ModelString = "Nogatech USB-TV (NTSC) FM",
+ },
+ [PNY_USB_TV_NTSC_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = 20,
+ .ModelString = "PNY USB-TV (NTSC) FM",
+ },
+ [PV_PLAYTV_USB_PRO_PAL_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "PixelView PlayTv-USB PRO (PAL) FM",
+ },
+ [ZT_721] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "ZTV ZT-721 2.4GHz USB A/V Receiver",
+ },
+ [HPG_WINTV_NTSC_MN] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = 20,
+ .ModelString = "Hauppauge WinTV USB (NTSC M/N)",
+ },
+ [HPG_WINTV_PAL_BG] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL B/G)",
+ },
+ [HPG_WINTV_PAL_I] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL I)",
+ },
+ [HPG_WINTV_PAL_SECAM_L] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL/SECAM L)",
+ },
+ [HPG_WINTV_PAL_D_K] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL D/K)",
+ },
+ [HPG_WINTV_NTSC_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (NTSC FM)",
+ },
+ [HPG_WINTV_PAL_BG_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL B/G FM)",
+ },
+ [HPG_WINTV_PAL_I_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL I FM)",
+ },
+ [HPG_WINTV_PAL_D_K_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTV USB (PAL D/K FM)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_MICROTUNE_4049FM5,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN_V2] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_MICROTUNE_4049FM5,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V2",
+ },
+ [HPG_WINTV_PRO_PAL] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN_V3] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N) V3",
+ },
+ [HPG_WINTV_PRO_PAL_BG] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL B/G)",
+ },
+ [HPG_WINTV_PRO_PAL_I] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL I)",
+ },
+ [HPG_WINTV_PRO_PAL_SECAM_L] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM L)",
+ },
+ [HPG_WINTV_PRO_PAL_D_K] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL D/K)",
+ },
+ [HPG_WINTV_PRO_PAL_SECAM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L)",
+ },
+ [HPG_WINTV_PRO_PAL_SECAM_V2] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2",
+ },
+ [HPG_WINTV_PRO_PAL_BG_V2] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_ALPS_TSBE1_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL B/G) V2",
+ },
+ [HPG_WINTV_PRO_PAL_BG_D_K] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_ALPS_TSBE1_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL B/G,D/K)",
+ },
+ [HPG_WINTV_PRO_PAL_I_D_K] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL I,D/K)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM)",
+ },
+ [HPG_WINTV_PRO_PAL_BG_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL B/G FM)",
+ },
+ [HPG_WINTV_PRO_PAL_I_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL I FM)",
+ },
+ [HPG_WINTV_PRO_PAL_D_K_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL D/K FM)",
+ },
+ [HPG_WINTV_PRO_TEMIC_PAL_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_MICROTUNE_4049FM5,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM)",
+ },
+ [HPG_WINTV_PRO_TEMIC_PAL_BG_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_MICROTUNE_4049FM5,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (Temic PAL B/G FM)",
+ },
+ [HPG_WINTV_PRO_PAL_FM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM)",
+ },
+ [HPG_WINTV_PRO_NTSC_MN_FM_V2] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Hauppauge WinTV USB Pro (NTSC M/N FM) V2",
+ },
+ [CAMTEL_TVB330] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = 5,
+ .Y_Offset = 5,
+ .ModelString = "Camtel Technology USB TV Genie Pro FM Model TVB330",
+ },
+ [DIGITAL_VIDEO_CREATOR_I] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Digital Video Creator I",
+ },
+ [GLOBAL_VILLAGE_GV_007_NTSC] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 82,
+ .Y_Offset = 20,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Global Village GV-007 (NTSC)",
+ },
+ [DAZZLE_DVC_50_REV_1_NTSC] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Dazzle Fusion Model DVC-50 Rev 1 (NTSC)",
+ },
+ [DAZZLE_DVC_80_REV_1_PAL] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Dazzle Fusion Model DVC-80 Rev 1 (PAL)",
+ },
+ [DAZZLE_DVC_90_REV_1_SECAM] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 0,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)",
+ },
+ [ESKAPE_LABS_MYTV2GO] = {
+ .Interface = 0,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_FM1216ME_MK3,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Eskape Labs MyTV2Go",
+ },
+ [PINNA_PCTV_USB_PAL] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 0,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4066FY5_PAL_I,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Pinnacle Studio PCTV USB (PAL)",
+ },
+ [PINNA_PCTV_USB_SECAM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_SECAM,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_SECAM,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Pinnacle Studio PCTV USB (SECAM)",
+ },
+ [PINNA_PCTV_USB_PAL_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = 128,
+ .Y_Offset = 23,
+ .ModelString = "Pinnacle Studio PCTV USB (PAL) FM",
+ },
+ [MIRO_PCTV_USB] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_PAL,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Miro PCTV USB",
+ },
+ [PINNA_PCTV_USB_NTSC_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM",
+ },
+ [PINNA_PCTV_USB_PAL_FM_V2] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4009FR5_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V2",
+ },
+ [PINNA_PCTV_USB_NTSC_FM_V2] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4039FR5_NTSC,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio PCTV USB (NTSC) FM V2",
+ },
+ [PINNA_PCTV_USB_PAL_FM_V3] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4009FR5_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio PCTV USB (PAL) FM V3",
+ },
+ [PINNA_LINX_VD_IN_CAB_NTSC] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio Linx Video input cable (NTSC)",
+ },
+ [PINNA_LINX_VD_IN_CAB_PAL] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 2,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 0,
+ .TunerType = 0,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle Studio Linx Video input cable (PAL)",
+ },
+ [PINNA_PCTV_BUNGEE_PAL_FM] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7113,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_PAL,
+ .AudioChannels = 1,
+ .Radio = 1,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_TEMIC_4009FR5_PAL,
+ .X_Offset = 0,
+ .Y_Offset = 3,
+ .Dvi_yuv_override = 1,
+ .Dvi_yuv = 7,
+ .ModelString = "Pinnacle PCTV Bungee USB (PAL) FM",
+ },
+ [HPG_WINTV] = {
+ .Interface = -1,
+ .Codec = CODEC_SAA7111,
+ .VideoChannels = 3,
+ .VideoNorm = V4L2_STD_NTSC,
+ .AudioChannels = 1,
+ .Radio = 0,
+ .vbi = 1,
+ .Tuner = 1,
+ .TunerType = TUNER_PHILIPS_NTSC_M,
+ .X_Offset = -1,
+ .Y_Offset = -1,
+ .ModelString = "Hauppauge WinTv-USB",
+ },
};
+const int usbvision_device_data_size=ARRAY_SIZE(usbvision_device_data);
/* Supported Devices */
struct usb_device_id usbvision_table [] = {
- { USB_DEVICE(0xfff0, 0xfff0) }, /* Custom Dummy USBVision Device */
- { USB_DEVICE(0x0a6f, 0x0400) }, /* Xanboo */
- { USB_DEVICE(0x050d, 0x0106) }, /* Belkin USB VideoBus II Adapter */
- { USB_DEVICE(0x050d, 0x0207) }, /* Belkin Components USB VideoBus */
- { USB_DEVICE(0x050d, 0x0208) }, /* Belkin USB VideoBus II */
- { USB_DEVICE(0x0571, 0x0002) }, /* echoFX InterView Lite */
- { USB_DEVICE(0x0573, 0x0003) }, /* USBGear USBG-V1 resp. HAMA USB */
- { USB_DEVICE(0x0573, 0x0400) }, /* D-Link V100 */
- { USB_DEVICE(0x0573, 0x2000) }, /* X10 USB Camera */
- { USB_DEVICE(0x0573, 0x2d00) }, /* Hauppauge WinTV USB Live (PAL B/G) */
- { USB_DEVICE(0x0573, 0x2d01) }, /* Hauppauge WinTV USB Live Pro (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x2101) }, /* Zoran Co. PMD (Nogatech) AV-grabber Manhattan */
- { USB_DEVICE(0x0573, 0x4100) }, /* Nogatech USB-TV FM (NTSC) */
- { USB_DEVICE(0x0573, 0x4110) }, /* PNY USB-TV (NTSC) FM */
- { USB_DEVICE(0x0573, 0x4450) }, /* PixelView PlayTv-USB PRO (PAL) FM */
- { USB_DEVICE(0x0573, 0x4550) }, /* ZTV ZT-721 2.4GHz USB A/V Receiver */
- { USB_DEVICE(0x0573, 0x4d00) }, /* Hauppauge WinTV USB (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x4d01) }, /* Hauppauge WinTV USB (PAL B/G) */
- { USB_DEVICE(0x0573, 0x4d02) }, /* Hauppauge WinTV USB (PAL I) */
- { USB_DEVICE(0x0573, 0x4d03) }, /* Hauppauge WinTV USB (PAL/SECAM L) */
- { USB_DEVICE(0x0573, 0x4d04) }, /* Hauppauge WinTV USB (PAL D/K) */
- { USB_DEVICE(0x0573, 0x4d10) }, /* Hauppauge WinTV USB (NTSC FM) */
- { USB_DEVICE(0x0573, 0x4d11) }, /* Hauppauge WinTV USB (PAL B/G FM) */
- { USB_DEVICE(0x0573, 0x4d12) }, /* Hauppauge WinTV USB (PAL I FM) */
- { USB_DEVICE(0x0573, 0x4d14) }, /* Hauppauge WinTV USB (PAL D/K FM) */
- { USB_DEVICE(0x0573, 0x4d2a) }, /* Hauppauge WinTV USB Pro (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x4d2b) }, /* Hauppauge WinTV USB Pro (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x4d2c) }, /* Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) */
- { USB_DEVICE(0x0573, 0x4d20) }, /* Hauppauge WinTV USB Pro (NTSC M/N) */
- { USB_DEVICE(0x0573, 0x4d21) }, /* Hauppauge WinTV USB Pro (PAL B/G) */
- { USB_DEVICE(0x0573, 0x4d22) }, /* Hauppauge WinTV USB Pro (PAL I) */
- { USB_DEVICE(0x0573, 0x4d23) }, /* Hauppauge WinTV USB Pro (PAL/SECAM L) */
- { USB_DEVICE(0x0573, 0x4d24) }, /* Hauppauge WinTV USB Pro (PAL D/K) */
- { USB_DEVICE(0x0573, 0x4d25) }, /* Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) */
- { USB_DEVICE(0x0573, 0x4d26) }, /* Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) */
- { USB_DEVICE(0x0573, 0x4d27) }, /* Hauppauge WinTV USB Pro (PAL B/G) */
- { USB_DEVICE(0x0573, 0x4d28) }, /* Hauppauge WinTV USB Pro (PAL B/G,D/K) */
- { USB_DEVICE(0x0573, 0x4d29) }, /* Hauppauge WinTV USB Pro (PAL I,D/K) */
- { USB_DEVICE(0x0573, 0x4d30) }, /* Hauppauge WinTV USB Pro (NTSC M/N FM) */
- { USB_DEVICE(0x0573, 0x4d31) }, /* Hauppauge WinTV USB Pro (PAL B/G FM) */
- { USB_DEVICE(0x0573, 0x4d32) }, /* Hauppauge WinTV USB Pro (PAL I FM) */
- { USB_DEVICE(0x0573, 0x4d34) }, /* Hauppauge WinTV USB Pro (PAL D/K FM) */
- { USB_DEVICE(0x0573, 0x4d35) }, /* Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) */
- { USB_DEVICE(0x0573, 0x4d36) }, /* Hauppauge WinTV USB Pro (Temic PAL B/G FM) */
- { USB_DEVICE(0x0573, 0x4d37) }, /* Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) */
- { USB_DEVICE(0x0573, 0x4d38) }, /* Hauppauge WinTV USB Pro (NTSC M/N FM) */
- { USB_DEVICE(0x0768, 0x0006) }, /* Camtel Technology USB TV Genie Pro FM Model TVB330 */
- { USB_DEVICE(0x07d0, 0x0001) }, /* Digital Video Creator I */
- { USB_DEVICE(0x07d0, 0x0002) }, /* Global Village GV-007 (NTSC) */
- { USB_DEVICE(0x07d0, 0x0003) }, /* Dazzle Fusion Model DVC-50 Rev 1 (NTSC) */
- { USB_DEVICE(0x07d0, 0x0004) }, /* Dazzle Fusion Model DVC-80 Rev 1 (PAL) */
- { USB_DEVICE(0x07d0, 0x0005) }, /* Dazzle Fusion Model DVC-90 Rev 1 (SECAM) */
- { USB_DEVICE(0x07f8, 0x9104) }, /* Eskape Labs MyTV2Go */
- { USB_DEVICE(0x2304, 0x010d) }, /* Pinnacle Studio PCTV USB (PAL) */
- { USB_DEVICE(0x2304, 0x0109) }, /* Pinnacle Studio PCTV USB (SECAM) */
- { USB_DEVICE(0x2304, 0x0110) }, /* Pinnacle Studio PCTV USB (PAL) */
- { USB_DEVICE(0x2304, 0x0111) }, /* Miro PCTV USB */
- { USB_DEVICE(0x2304, 0x0112) }, /* Pinnacle Studio PCTV USB (NTSC) with FM radio */
- { USB_DEVICE(0x2304, 0x0210) }, /* Pinnacle Studio PCTV USB (PAL) with FM radio */
- { USB_DEVICE(0x2304, 0x0212) }, /* Pinnacle Studio PCTV USB (NTSC) with FM radio */
- { USB_DEVICE(0x2304, 0x0214) }, /* Pinnacle Studio PCTV USB (PAL) with FM radio */
- { USB_DEVICE(0x2304, 0x0300) }, /* Pinnacle Studio Linx Video input cable (NTSC) */
- { USB_DEVICE(0x2304, 0x0301) }, /* Pinnacle Studio Linx Video input cable (PAL) */
- { USB_DEVICE(0x2304, 0x0419) }, /* Pinnacle PCTV Bungee USB (PAL) FM */
- { USB_DEVICE(0x2400, 0x4200) }, /* Hauppauge WinTv-USB2 Model 42012 */
-
- { } /* Terminating entry */
+ { USB_DEVICE(0x0a6f, 0x0400), .driver_info=XANBOO },
+ { USB_DEVICE(0x050d, 0x0106), .driver_info=BELKIN_VIDEOBUS_II },
+ { USB_DEVICE(0x050d, 0x0207), .driver_info=BELKIN_VIDEOBUS },
+ { USB_DEVICE(0x050d, 0x0208), .driver_info=BELKIN_USB_VIDEOBUS_II },
+ { USB_DEVICE(0x0571, 0x0002), .driver_info=ECHOFX_INTERVIEW_LITE },
+ { USB_DEVICE(0x0573, 0x0003), .driver_info=USBGEAR_USBG_V1 },
+ { USB_DEVICE(0x0573, 0x0400), .driver_info=D_LINK_V100 },
+ { USB_DEVICE(0x0573, 0x2000), .driver_info=X10_USB_CAMERA },
+ { USB_DEVICE(0x0573, 0x2d00), .driver_info=HPG_WINTV_LIVE_PAL_BG },
+ { USB_DEVICE(0x0573, 0x2d01), .driver_info=HPG_WINTV_LIVE_PRO_NTSC_MN },
+ { USB_DEVICE(0x0573, 0x2101), .driver_info=ZORAN_PMD_NOGATECH },
+ { USB_DEVICE(0x0573, 0x4100), .driver_info=NOGATECH_USB_TV_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4110), .driver_info=PNY_USB_TV_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4450), .driver_info=PV_PLAYTV_USB_PRO_PAL_FM },
+ { USB_DEVICE(0x0573, 0x4550), .driver_info=ZT_721 },
+ { USB_DEVICE(0x0573, 0x4d00), .driver_info=HPG_WINTV_NTSC_MN },
+ { USB_DEVICE(0x0573, 0x4d01), .driver_info=HPG_WINTV_PAL_BG },
+ { USB_DEVICE(0x0573, 0x4d02), .driver_info=HPG_WINTV_PAL_I },
+ { USB_DEVICE(0x0573, 0x4d03), .driver_info=HPG_WINTV_PAL_SECAM_L },
+ { USB_DEVICE(0x0573, 0x4d04), .driver_info=HPG_WINTV_PAL_D_K },
+ { USB_DEVICE(0x0573, 0x4d10), .driver_info=HPG_WINTV_NTSC_FM },
+ { USB_DEVICE(0x0573, 0x4d11), .driver_info=HPG_WINTV_PAL_BG_FM },
+ { USB_DEVICE(0x0573, 0x4d12), .driver_info=HPG_WINTV_PAL_I_FM },
+ { USB_DEVICE(0x0573, 0x4d14), .driver_info=HPG_WINTV_PAL_D_K_FM },
+ { USB_DEVICE(0x0573, 0x4d2a), .driver_info=HPG_WINTV_PRO_NTSC_MN },
+ { USB_DEVICE(0x0573, 0x4d2b), .driver_info=HPG_WINTV_PRO_NTSC_MN_V2 },
+ { USB_DEVICE(0x0573, 0x4d2c), .driver_info=HPG_WINTV_PRO_PAL },
+ { USB_DEVICE(0x0573, 0x4d20), .driver_info=HPG_WINTV_PRO_NTSC_MN_V3 },
+ { USB_DEVICE(0x0573, 0x4d21), .driver_info=HPG_WINTV_PRO_PAL_BG },
+ { USB_DEVICE(0x0573, 0x4d22), .driver_info=HPG_WINTV_PRO_PAL_I },
+ { USB_DEVICE(0x0573, 0x4d23), .driver_info=HPG_WINTV_PRO_PAL_SECAM_L },
+ { USB_DEVICE(0x0573, 0x4d24), .driver_info=HPG_WINTV_PRO_PAL_D_K },
+ { USB_DEVICE(0x0573, 0x4d25), .driver_info=HPG_WINTV_PRO_PAL_SECAM },
+ { USB_DEVICE(0x0573, 0x4d26), .driver_info=HPG_WINTV_PRO_PAL_SECAM_V2 },
+ { USB_DEVICE(0x0573, 0x4d27), .driver_info=HPG_WINTV_PRO_PAL_BG_V2 },
+ { USB_DEVICE(0x0573, 0x4d28), .driver_info=HPG_WINTV_PRO_PAL_BG_D_K },
+ { USB_DEVICE(0x0573, 0x4d29), .driver_info=HPG_WINTV_PRO_PAL_I_D_K },
+ { USB_DEVICE(0x0573, 0x4d30), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM },
+ { USB_DEVICE(0x0573, 0x4d31), .driver_info=HPG_WINTV_PRO_PAL_BG_FM },
+ { USB_DEVICE(0x0573, 0x4d32), .driver_info=HPG_WINTV_PRO_PAL_I_FM },
+ { USB_DEVICE(0x0573, 0x4d34), .driver_info=HPG_WINTV_PRO_PAL_D_K_FM },
+ { USB_DEVICE(0x0573, 0x4d35), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_FM },
+ { USB_DEVICE(0x0573, 0x4d36), .driver_info=HPG_WINTV_PRO_TEMIC_PAL_BG_FM },
+ { USB_DEVICE(0x0573, 0x4d37), .driver_info=HPG_WINTV_PRO_PAL_FM },
+ { USB_DEVICE(0x0573, 0x4d38), .driver_info=HPG_WINTV_PRO_NTSC_MN_FM_V2 },
+ { USB_DEVICE(0x0768, 0x0006), .driver_info=CAMTEL_TVB330 },
+ { USB_DEVICE(0x07d0, 0x0001), .driver_info=DIGITAL_VIDEO_CREATOR_I },
+ { USB_DEVICE(0x07d0, 0x0002), .driver_info=GLOBAL_VILLAGE_GV_007_NTSC },
+ { USB_DEVICE(0x07d0, 0x0003), .driver_info=DAZZLE_DVC_50_REV_1_NTSC },
+ { USB_DEVICE(0x07d0, 0x0004), .driver_info=DAZZLE_DVC_80_REV_1_PAL },
+ { USB_DEVICE(0x07d0, 0x0005), .driver_info=DAZZLE_DVC_90_REV_1_SECAM },
+ { USB_DEVICE(0x07f8, 0x9104), .driver_info=ESKAPE_LABS_MYTV2GO },
+ { USB_DEVICE(0x2304, 0x010d), .driver_info=PINNA_PCTV_USB_PAL },
+ { USB_DEVICE(0x2304, 0x0109), .driver_info=PINNA_PCTV_USB_SECAM },
+ { USB_DEVICE(0x2304, 0x0110), .driver_info=PINNA_PCTV_USB_PAL_FM },
+ { USB_DEVICE(0x2304, 0x0111), .driver_info=MIRO_PCTV_USB },
+ { USB_DEVICE(0x2304, 0x0112), .driver_info=PINNA_PCTV_USB_NTSC_FM },
+ { USB_DEVICE(0x2304, 0x0210), .driver_info=PINNA_PCTV_USB_PAL_FM_V2 },
+ { USB_DEVICE(0x2304, 0x0212), .driver_info=PINNA_PCTV_USB_NTSC_FM_V2 },
+ { USB_DEVICE(0x2304, 0x0214), .driver_info=PINNA_PCTV_USB_PAL_FM_V3 },
+ { USB_DEVICE(0x2304, 0x0300), .driver_info=PINNA_LINX_VD_IN_CAB_NTSC },
+ { USB_DEVICE(0x2304, 0x0301), .driver_info=PINNA_LINX_VD_IN_CAB_PAL },
+ { USB_DEVICE(0x2304, 0x0419), .driver_info=PINNA_PCTV_BUNGEE_PAL_FM },
+ { USB_DEVICE(0x2400, 0x4200), .driver_info=HPG_WINTV },
};
MODULE_DEVICE_TABLE (usb, usbvision_table);
diff --git a/linux/drivers/media/video/usbvision/usbvision-cards.h b/linux/drivers/media/video/usbvision/usbvision-cards.h
new file mode 100644
index 000000000..512c5cee4
--- /dev/null
+++ b/linux/drivers/media/video/usbvision/usbvision-cards.h
@@ -0,0 +1,66 @@
+#define XANBOO 0
+#define BELKIN_VIDEOBUS_II 1
+#define BELKIN_VIDEOBUS 2
+#define BELKIN_USB_VIDEOBUS_II 3
+#define ECHOFX_INTERVIEW_LITE 4
+#define USBGEAR_USBG_V1 5
+#define D_LINK_V100 6
+#define X10_USB_CAMERA 7
+#define HPG_WINTV_LIVE_PAL_BG 8
+#define HPG_WINTV_LIVE_PRO_NTSC_MN 9
+#define ZORAN_PMD_NOGATECH 10
+#define NOGATECH_USB_TV_NTSC_FM 11
+#define PNY_USB_TV_NTSC_FM 12
+#define PV_PLAYTV_USB_PRO_PAL_FM 13
+#define ZT_721 14
+#define HPG_WINTV_NTSC_MN 15
+#define HPG_WINTV_PAL_BG 16
+#define HPG_WINTV_PAL_I 17
+#define HPG_WINTV_PAL_SECAM_L 18
+#define HPG_WINTV_PAL_D_K 19
+#define HPG_WINTV_NTSC_FM 20
+#define HPG_WINTV_PAL_BG_FM 21
+#define HPG_WINTV_PAL_I_FM 22
+#define HPG_WINTV_PAL_D_K_FM 23
+#define HPG_WINTV_PRO_NTSC_MN 24
+#define HPG_WINTV_PRO_NTSC_MN_V2 25
+#define HPG_WINTV_PRO_PAL 26
+#define HPG_WINTV_PRO_NTSC_MN_V3 27
+#define HPG_WINTV_PRO_PAL_BG 28
+#define HPG_WINTV_PRO_PAL_I 29
+#define HPG_WINTV_PRO_PAL_SECAM_L 30
+#define HPG_WINTV_PRO_PAL_D_K 31
+#define HPG_WINTV_PRO_PAL_SECAM 32
+#define HPG_WINTV_PRO_PAL_SECAM_V2 33
+#define HPG_WINTV_PRO_PAL_BG_V2 34
+#define HPG_WINTV_PRO_PAL_BG_D_K 35
+#define HPG_WINTV_PRO_PAL_I_D_K 36
+#define HPG_WINTV_PRO_NTSC_MN_FM 37
+#define HPG_WINTV_PRO_PAL_BG_FM 38
+#define HPG_WINTV_PRO_PAL_I_FM 39
+#define HPG_WINTV_PRO_PAL_D_K_FM 40
+#define HPG_WINTV_PRO_TEMIC_PAL_FM 41
+#define HPG_WINTV_PRO_TEMIC_PAL_BG_FM 42
+#define HPG_WINTV_PRO_PAL_FM 43
+#define HPG_WINTV_PRO_NTSC_MN_FM_V2 44
+#define CAMTEL_TVB330 45
+#define DIGITAL_VIDEO_CREATOR_I 46
+#define GLOBAL_VILLAGE_GV_007_NTSC 47
+#define DAZZLE_DVC_50_REV_1_NTSC 48
+#define DAZZLE_DVC_80_REV_1_PAL 49
+#define DAZZLE_DVC_90_REV_1_SECAM 50
+#define ESKAPE_LABS_MYTV2GO 51
+#define PINNA_PCTV_USB_PAL 52
+#define PINNA_PCTV_USB_SECAM 53
+#define PINNA_PCTV_USB_PAL_FM 54
+#define MIRO_PCTV_USB 55
+#define PINNA_PCTV_USB_NTSC_FM 56
+#define PINNA_PCTV_USB_PAL_FM_V2 57
+#define PINNA_PCTV_USB_NTSC_FM_V2 58
+#define PINNA_PCTV_USB_PAL_FM_V3 59
+#define PINNA_LINX_VD_IN_CAB_NTSC 60
+#define PINNA_LINX_VD_IN_CAB_PAL 61
+#define PINNA_PCTV_BUNGEE_PAL_FM 62
+#define HPG_WINTV 63
+
+extern const int usbvision_device_data_size;
diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c
index 2d8dc023d..325561324 100644
--- a/linux/drivers/media/video/usbvision/usbvision-core.c
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c
@@ -2103,8 +2103,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
return 0;
/* Set input format expected from decoder*/
- if (usbvision_device_data[usbvision->DevModel].Vin_Reg1 >= 0) {
- value[0] = usbvision_device_data[usbvision->DevModel].Vin_Reg1 & 0xff;
+ if (usbvision_device_data[usbvision->DevModel].Vin_Reg1_override) {
+ value[0] = usbvision_device_data[usbvision->DevModel].Vin_Reg1;
} else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
/* SAA7113 uses 8 bit output */
value[0] = USBVISION_8_422_SYNC;
@@ -2175,8 +2175,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
dvi_yuv_value = 0x00; /* U comes after V, Ya comes after U/V, Yb comes after Yb */
- if(usbvision_device_data[usbvision->DevModel].Dvi_yuv >= 0){
- dvi_yuv_value = usbvision_device_data[usbvision->DevModel].Dvi_yuv & 0xff;
+ if(usbvision_device_data[usbvision->DevModel].Dvi_yuv_override){
+ dvi_yuv_value = usbvision_device_data[usbvision->DevModel].Dvi_yuv;
}
else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
/* This changes as the fine sync control changes. Further investigation necessary */
@@ -2309,7 +2309,7 @@ static void call_usbvision_power_off(struct work_struct *work)
PDEBUG(DBG_FUNC, "");
down_interruptible(&usbvision->lock);
if(usbvision->user == 0) {
- usbvision_i2c_usb_del_bus(&usbvision->i2c_adap);
+ usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
usbvision->initialized = 0;
diff --git a/linux/drivers/media/video/usbvision/usbvision-i2c.c b/linux/drivers/media/video/usbvision/usbvision-i2c.c
index e942b1bf2..e91add952 100644
--- a/linux/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/linux/drivers/media/video/usbvision/usbvision-i2c.c
@@ -1,8 +1,8 @@
/*
- * I2C_ALGO_USB.C
+ * usbvision_i2c.c
* i2c algorithm for USB-I2C Bridges
*
- * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
+ * Copyright (c) 1999-2007 Joerg Heckenbach <joerg@heckenbach-aw.de>
* Dwaine Garden <dwainegarden@rogers.com>
*
* This module is part of usbvision driver project.
@@ -42,7 +42,6 @@
#include "usbvision.h"
#define DBG_I2C 1<<0
-#define DBG_ALGO 1<<1
static int i2c_debug = 0;
@@ -52,22 +51,22 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
#define PDEBUG(level, fmt, args...) \
if (i2c_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args)
-static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
+static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len);
-static int usbvision_i2c_read(void *data, unsigned char addr, char *buf,
+static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len);
static inline int try_write_address(struct i2c_adapter *i2c_adap,
unsigned char addr, int retries)
{
- void *data;
+ struct usb_usbvision *usbvision;
int i, ret = -1;
char buf[4];
- data = i2c_get_adapdata(i2c_adap);
+ usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
buf[0] = 0x00;
for (i = 0; i <= retries; i++) {
- ret = (usbvision_i2c_write(data, addr, buf, 1));
+ ret = (usbvision_i2c_write(usbvision, addr, buf, 1));
if (ret == 1)
break; /* success! */
udelay(5);
@@ -76,8 +75,8 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
udelay(10);
}
if (i) {
- PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr);
- PDEBUG(DBG_ALGO,"Maybe there's no device at this address");
+ PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
+ PDEBUG(DBG_I2C,"Maybe there's no device at this address");
}
return ret;
}
@@ -85,13 +84,13 @@ static inline int try_write_address(struct i2c_adapter *i2c_adap,
static inline int try_read_address(struct i2c_adapter *i2c_adap,
unsigned char addr, int retries)
{
- void *data;
+ struct usb_usbvision *usbvision;
int i, ret = -1;
char buf[4];
- data = i2c_get_adapdata(i2c_adap);
+ usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
for (i = 0; i <= retries; i++) {
- ret = (usbvision_i2c_read(data, addr, buf, 1));
+ ret = (usbvision_i2c_read(usbvision, addr, buf, 1));
if (ret == 1)
break; /* success! */
udelay(5);
@@ -100,8 +99,8 @@ static inline int try_read_address(struct i2c_adapter *i2c_adap,
udelay(10);
}
if (i) {
- PDEBUG(DBG_ALGO,"Needed %d retries for address %#2x", i, addr);
- PDEBUG(DBG_ALGO,"Maybe there's no device at this address");
+ PDEBUG(DBG_I2C,"Needed %d retries for address %#2x", i, addr);
+ PDEBUG(DBG_I2C,"Maybe there's no device at this address");
}
return ret;
}
@@ -155,32 +154,32 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
}
static int
-usb_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
{
struct i2c_msg *pmsg;
- void *data;
+ struct usb_usbvision *usbvision;
int i, ret;
unsigned char addr;
- data = i2c_get_adapdata(i2c_adap);
+ usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
for (i = 0; i < num; i++) {
pmsg = &msgs[i];
ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr);
if (ret != 0) {
- PDEBUG(DBG_ALGO,"got NAK from device, message #%d", i);
+ PDEBUG(DBG_I2C,"got NAK from device, message #%d", i);
return (ret < 0) ? ret : -EREMOTEIO;
}
if (pmsg->flags & I2C_M_RD) {
/* read bytes into buffer */
- ret = (usbvision_i2c_read(data, addr, pmsg->buf, pmsg->len));
+ ret = (usbvision_i2c_read(usbvision, addr, pmsg->buf, pmsg->len));
if (ret < pmsg->len) {
return (ret < 0) ? ret : -EREMOTEIO;
}
} else {
/* write bytes from buffer */
- ret = (usbvision_i2c_write(data, addr, pmsg->buf, pmsg->len));
+ ret = (usbvision_i2c_write(usbvision, addr, pmsg->buf, pmsg->len));
if (ret < pmsg->len) {
return (ret < 0) ? ret : -EREMOTEIO;
}
@@ -194,7 +193,7 @@ static int algo_control(struct i2c_adapter *adapter, unsigned int cmd, unsigned
return 0;
}
-static u32 usb_func(struct i2c_adapter *adap)
+static u32 functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
}
@@ -213,7 +212,7 @@ static void dec_use(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */
-static struct i2c_algorithm i2c_usb_algo = {
+static struct i2c_algorithm usbvision_algo = {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,30))
.owner = THIS_MODULE,
#endif
@@ -221,10 +220,10 @@ static struct i2c_algorithm i2c_usb_algo = {
.name = "USB algorithm",
.id = I2C_ALGO_BIT, /* FIXME */
#endif
- .master_xfer = usb_xfer,
+ .master_xfer = usbvision_i2c_xfer,
.smbus_xfer = NULL,
.algo_control = algo_control,
- .functionality = usb_func,
+ .functionality = functionality,
};
@@ -234,44 +233,32 @@ static struct i2c_algorithm i2c_usb_algo = {
static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap)
{
PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
- PDEBUG(DBG_ALGO, "ALGO debugging is enabled [i2c]");
+ PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]");
/* register new adapter to i2c module... */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
- adap->id |= i2c_usb_algo.id;
+ adap->id |= usbvision_algo.id;
#endif
- adap->algo = &i2c_usb_algo;
+ adap->algo = &usbvision_algo;
adap->timeout = 100; /* default values, should */
adap->retries = 3; /* be replaced by defines */
i2c_add_adapter(adap);
- PDEBUG(DBG_ALGO,"i2c bus for %s registered", adap->name);
+ PDEBUG(DBG_I2C,"i2c bus for %s registered", adap->name);
return 0;
}
-
-int usbvision_i2c_usb_del_bus(struct i2c_adapter *adap)
-{
-
- i2c_del_adapter(adap);
-
- PDEBUG(DBG_ALGO,"i2c bus for %s unregistered", adap->name);
-
- return 0;
-}
-
-
/* ----------------------------------------------------------------------- */
/* usbvision specific I2C functions */
/* ----------------------------------------------------------------------- */
static struct i2c_adapter i2c_adap_template;
static struct i2c_client i2c_client_template;
-int usbvision_init_i2c(struct usb_usbvision *usbvision)
+int usbvision_i2c_register(struct usb_usbvision *usbvision)
{
memcpy(&usbvision->i2c_adap, &i2c_adap_template,
sizeof(struct i2c_adapter));
@@ -289,7 +276,7 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision)
usbvision->i2c_client.adapter = &usbvision->i2c_adap;
if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
- printk(KERN_ERR "usbvision_init_i2c: can't write reg\n");
+ printk(KERN_ERR "usbvision_register: can't write reg\n");
return -EBUSY;
}
@@ -311,6 +298,16 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision)
return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap);
}
+int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
+{
+
+ i2c_del_adapter(&(usbvision->i2c_adap));
+
+ PDEBUG(DBG_I2C,"i2c bus for %s unregistered", usbvision->i2c_adap.name);
+
+ return 0;
+}
+
void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,
void *arg)
{
@@ -324,19 +321,12 @@ static int attach_inform(struct i2c_client *client)
usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
switch (client->addr << 1) {
- case 0x43:
- case 0x4b:
- {
- struct tuner_setup tun_setup;
-
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = TUNER_TDA9887;
- tun_setup.addr = client->addr;
-
- call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
-
+ case 0x42 << 1:
+ case 0x43 << 1:
+ case 0x4a << 1:
+ case 0x4b << 1:
+ PDEBUG(DBG_I2C,"attach_inform: tda9887 detected.");
break;
- }
case 0x42:
PDEBUG(DBG_I2C,"attach_inform: saa7114 detected.");
break;
@@ -373,11 +363,7 @@ static int detach_inform(struct i2c_client *client)
{
struct usb_usbvision *usbvision;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- usbvision = (struct usb_usbvision *)client->adapter->data;
-#else
usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
-#endif
PDEBUG(DBG_I2C,"usbvision[%d] detaches %s", usbvision->nr, client->name);
return 0;
@@ -508,7 +494,7 @@ static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision,
return len;
}
-static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
+static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len)
{
char *bufPtr = buf;
@@ -516,7 +502,6 @@ static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
int wrcount = 0;
int count;
int maxLen = 4;
- struct usb_usbvision *usbvision = (struct usb_usbvision *) data;
while (len > 0) {
count = (len > maxLen) ? maxLen : len;
@@ -531,14 +516,13 @@ static int usbvision_i2c_write(void *data, unsigned char addr, char *buf,
return wrcount;
}
-static int usbvision_i2c_read(void *data, unsigned char addr, char *buf,
+static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len)
{
char temp[4];
int retval, i;
int rdcount = 0;
int count;
- struct usb_usbvision *usbvision = (struct usb_usbvision *) data;
while (len > 0) {
count = (len > 3) ? 4 : len;
diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c
index 89aedd783..6a32c1479 100644
--- a/linux/drivers/media/video/usbvision/usbvision-video.c
+++ b/linux/drivers/media/video/usbvision/usbvision-video.c
@@ -83,6 +83,7 @@
#endif
#include "usbvision.h"
+#include "usbvision-cards.h"
#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, Dwaine Garden <DwaineGarden@rogers.com>"
#define DRIVER_NAME "usbvision"
@@ -157,7 +158,6 @@ static int PowerOnAtOpen = 1; // Set the default device to power on at startu
static int video_nr = -1; // Sequential Number of Video Device
static int radio_nr = -1; // Sequential Number of Radio Device
static int vbi_nr = -1; // Sequential Number of VBI Device
-static char *CustomDevice=NULL; // Set as nothing....
// Grab parameters for the device driver
@@ -168,7 +168,6 @@ module_param(PowerOnAtOpen, int, 0444);
module_param(video_nr, int, 0444);
module_param(radio_nr, int, 0444);
module_param(vbi_nr, int, 0444);
-module_param(CustomDevice, charp, 0444);
#else // Old Style
MODULE_PARAM(isocMode, "i");
MODULE_PARM(video_debug, "i"); // Grab the Debug Mode of the device driver
@@ -178,7 +177,6 @@ MODULE_PARM(SwitchSVideoInput, "i"); // To help people with Black and White ou
MODULE_PARM(video_nr, "i"); // video_nr option allows to specify a certain /dev/videoX device (like /dev/video0 or /dev/video1 ...)
MODULE_PARM(radio_nr, "i"); // radio_nr option allows to specify a certain /dev/radioX device (like /dev/radio0 or /dev/radio1 ...)
MODULE_PARM(vbi_nr, "i"); // vbi_nr option allows to specify a certain /dev/vbiX device (like /dev/vbi0 or /dev/vbi1 ...)
-MODULE_PARM(CustomDevice, "s"); // .... CustomDevice
#endif
MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
@@ -187,7 +185,6 @@ MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device
MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");
MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
MODULE_PARM_DESC(vbi_nr, "Set vbi device number (/dev/vbiX). Default: -1 (autodetect)");
-MODULE_PARM_DESC(CustomDevice, " Define the fine tuning parameters for the device. Default: null");
// Misc stuff
@@ -429,7 +426,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
down(&usbvision->lock);
if (usbvision->power == 0) {
usbvision_power_on(usbvision);
- usbvision_init_i2c(usbvision);
+ usbvision_i2c_register(usbvision);
}
/* Send init sequence only once, it's large! */
@@ -451,7 +448,7 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
}
else {
if (PowerOnAtOpen) {
- usbvision_i2c_usb_del_bus(&usbvision->i2c_adap);
+ usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
usbvision->initialized = 0;
}
@@ -1302,7 +1299,7 @@ static int usbvision_radio_open(struct inode *inode, struct file *file)
usbvision_reset_powerOffTimer(usbvision);
if (usbvision->power == 0) {
usbvision_power_on(usbvision);
- usbvision_init_i2c(usbvision);
+ usbvision_i2c_register(usbvision);
}
}
@@ -1327,7 +1324,7 @@ static int usbvision_radio_open(struct inode *inode, struct file *file)
MOD_DEC_USE_COUNT;
#endif
if (PowerOnAtOpen) {
- usbvision_i2c_usb_del_bus(&usbvision->i2c_adap);
+ usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
usbvision->initialized = 0;
}
@@ -1913,8 +1910,8 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
model = usbvision->DevModel;
usbvision->palette = usbvision_v4l2_format[2]; // V4L2_PIX_FMT_RGB24;
- if (usbvision_device_data[usbvision->DevModel].Vin_Reg2 >= 0) {
- usbvision->Vin_Reg2_Preset = usbvision_device_data[usbvision->DevModel].Vin_Reg2 & 0xff;
+ if (usbvision_device_data[usbvision->DevModel].Vin_Reg2_override) {
+ usbvision->Vin_Reg2_Preset = usbvision_device_data[usbvision->DevModel].Vin_Reg2;
} else {
usbvision->Vin_Reg2_Preset = 0;
}
@@ -1933,7 +1930,7 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
usbvision_audio_off(usbvision); //first switch off audio
if (!PowerOnAtOpen) {
usbvision_power_on(usbvision); //and then power up the noisy tuner
- usbvision_init_i2c(usbvision);
+ usbvision_i2c_register(usbvision);
}
}
@@ -1944,74 +1941,29 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
* if it looks like USBVISION video device
*
*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void *usbvision_probe(struct usb_device *dev, unsigned int ifnum,
- const struct usb_device_id *id)
-{
- const struct usb_interface_descriptor *interface;
-#else
-static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid)
+static int __devinit usbvision_probe(struct usb_interface *intf,
+ const struct usb_device_id *devid)
{
struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf));
struct usb_interface *uif;
__u8 ifnum = intf->altsetting->desc.bInterfaceNumber;
const struct usb_host_interface *interface;
-#endif
struct usb_usbvision *usbvision = NULL;
const struct usb_endpoint_descriptor *endpoint;
int model,i;
PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
- dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
-
- /* Is it an USBVISION video dev? */
- model = 0;
- for(model = 0; usbvision_device_data[model].idVendor; model++) {
- if (le16_to_cpu(dev->descriptor.idVendor) != usbvision_device_data[model].idVendor) {
- continue;
- }
- if (le16_to_cpu(dev->descriptor.idProduct) != usbvision_device_data[model].idProduct) {
- continue;
- }
+ dev->descriptor.idVendor,
+ dev->descriptor.idProduct, ifnum);
- printk(KERN_INFO "%s: %s found\n", __FUNCTION__, usbvision_device_data[model].ModelString);
- break;
- }
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- if (usbvision_device_data[model].idVendor == 0) {
- return NULL; //no matching device
- }
- if (usbvision_device_data[model].Interface >= 0) {
- interface = &dev->actconfig->interface[usbvision_device_data[model].Interface].altsetting[0];
- }
- else {
- interface = &dev->actconfig->interface[ifnum].altsetting[0];
- }
- endpoint = &interface->endpoint[1];
-
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) {
- err("%s: USBVision interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum);
- err("%s: USBVision Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes);
- return NULL;
- }
- if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
- err("%s: USBVision interface %d. has ISO OUT endpoint!", __FUNCTION__, ifnum);
- return NULL;
+ model = devid->driver_info;
+ if ( (model<0) || (model>=usbvision_device_data_size) ) {
+ PDEBUG(DBG_PROBE, "model out of bounds %d",model);
+ return -ENODEV;
}
+ printk(KERN_INFO "%s: %s found\n", __FUNCTION__,
+ usbvision_device_data[model].ModelString);
- MOD_INC_USE_COUNT;
-
- /* Allocate the usbvision device structure so that we can set some variables */
- if ((usbvision = usbvision_alloc(dev)) == NULL) {
- err("%s: couldn't allocate USBVision struct", __FUNCTION__);
- MOD_DEC_USE_COUNT;
- return NULL;
- }
-#else
- if (usbvision_device_data[model].idVendor == 0) {
- return -ENODEV; //no matching device
- }
if (usbvision_device_data[model].Interface >= 0) {
interface = &dev->actconfig->interface[usbvision_device_data[model].Interface]->altsetting[0];
}
@@ -2029,17 +1981,15 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
return -ENODEV;
}
- usb_get_dev(dev);
-
if ((usbvision = usbvision_alloc(dev)) == NULL) {
err("%s: couldn't allocate USBVision struct", __FUNCTION__);
return -ENOMEM;
}
-#endif
+
if (dev->descriptor.bNumConfigurations > 1) {
usbvision->bridgeType = BRIDGE_NT1004;
}
- else if (usbvision_device_data[model].ModelString == "Dazzle Fusion Model DVC-90 Rev 1 (SECAM)") {
+ else if (model == DAZZLE_DVC_90_REV_1_SECAM) {
usbvision->bridgeType = BRIDGE_NT1005;
}
else {
@@ -2143,7 +2093,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
usbvision_stop_isoc(usbvision);
if (usbvision->power) {
- usbvision_i2c_usb_del_bus(&usbvision->i2c_adap);
+ usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
}
usbvision->remove_pending = 1; // Now all ISO data will be ignored
@@ -2182,124 +2132,6 @@ static struct usb_driver usbvision_driver = {
};
/*
- * customdevice_process()
- *
- * This procedure preprocesses CustomDevice parameter if any
- *
- */
-static void customdevice_process(void)
-{
- usbvision_device_data[0]=usbvision_device_data[1];
- usbvision_table[0]=usbvision_table[1];
-
- if(CustomDevice)
- {
- char *parse=CustomDevice;
-
- PDEBUG(DBG_PROBE, "CustomDevide=%s", CustomDevice);
-
- /*format is CustomDevice="0x0573 0x4D31 0 7113 3 PAL 1 1 1 5 -1 -1 -1 -1 -1"
- usbvision_device_data[0].idVendor;
- usbvision_device_data[0].idProduct;
- usbvision_device_data[0].Interface;
- usbvision_device_data[0].Codec;
- usbvision_device_data[0].VideoChannels;
- usbvision_device_data[0].VideoNorm;
- usbvision_device_data[0].AudioChannels;
- usbvision_device_data[0].Radio;
- usbvision_device_data[0].Tuner;
- usbvision_device_data[0].TunerType;
- usbvision_device_data[0].Vin_Reg1;
- usbvision_device_data[0].Vin_Reg2;
- usbvision_device_data[0].X_Offset;
- usbvision_device_data[0].Y_Offset;
- usbvision_device_data[0].Dvi_yuv;
- usbvision_device_data[0].ModelString;
- */
-
- rmspace(parse);
- usbvision_device_data[0].ModelString="USBVISION Custom Device";
-
- parse+=2;
- sscanf(parse,"%x",&usbvision_device_data[0].idVendor);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "idVendor=0x%.4X", usbvision_device_data[0].idVendor);
- parse+=2;
- sscanf(parse,"%x",&usbvision_device_data[0].idProduct);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "idProduct=0x%.4X", usbvision_device_data[0].idProduct);
- sscanf(parse,"%d",&usbvision_device_data[0].Interface);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Interface=%d", usbvision_device_data[0].Interface);
- sscanf(parse,"%d",&usbvision_device_data[0].Codec);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Codec=%d", usbvision_device_data[0].Codec);
- sscanf(parse,"%d",&usbvision_device_data[0].VideoChannels);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "VideoChannels=%d", usbvision_device_data[0].VideoChannels);
-
- switch(*parse)
- {
- case 'P':
- PDEBUG(DBG_PROBE, "VideoNorm=PAL");
- usbvision_device_data[0].VideoNorm=V4L2_STD_PAL;
- break;
-
- case 'S':
- PDEBUG(DBG_PROBE, "VideoNorm=SECAM");
- usbvision_device_data[0].VideoNorm=V4L2_STD_SECAM;
- break;
-
- case 'N':
- PDEBUG(DBG_PROBE, "VideoNorm=NTSC");
- usbvision_device_data[0].VideoNorm=V4L2_STD_NTSC;
- break;
-
- default:
- PDEBUG(DBG_PROBE, "VideoNorm=PAL (by default)");
- usbvision_device_data[0].VideoNorm=V4L2_STD_PAL;
- break;
- }
- goto2next(parse);
-
- sscanf(parse,"%d",&usbvision_device_data[0].AudioChannels);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "AudioChannels=%d", usbvision_device_data[0].AudioChannels);
- sscanf(parse,"%d",&usbvision_device_data[0].Radio);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Radio=%d", usbvision_device_data[0].Radio);
- sscanf(parse,"%d",&usbvision_device_data[0].Tuner);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Tuner=%d", usbvision_device_data[0].Tuner);
- sscanf(parse,"%d",&usbvision_device_data[0].TunerType);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "TunerType=%d", usbvision_device_data[0].TunerType);
- sscanf(parse,"%d",&usbvision_device_data[0].Vin_Reg1);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Vin_Reg1=%d", usbvision_device_data[0].Vin_Reg1);
- sscanf(parse,"%d",&usbvision_device_data[0].Vin_Reg2);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Vin_Reg2=%d", usbvision_device_data[0].Vin_Reg2);
- sscanf(parse,"%d",&usbvision_device_data[0].X_Offset);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "X_Offset=%d", usbvision_device_data[0].X_Offset);
- sscanf(parse,"%d",&usbvision_device_data[0].Y_Offset);
- goto2next(parse);
- PDEBUG(DBG_PROBE, "Y_Offset=%d", usbvision_device_data[0].Y_Offset);
- sscanf(parse,"%d",&usbvision_device_data[0].Dvi_yuv);
- PDEBUG(DBG_PROBE, "Dvi_yuv=%d", usbvision_device_data[0].Dvi_yuv);
-
- //add to usbvision_table also
- usbvision_table[0].match_flags=USB_DEVICE_ID_MATCH_DEVICE;
- usbvision_table[0].idVendor=usbvision_device_data[0].idVendor;
- usbvision_table[0].idProduct=usbvision_device_data[0].idProduct;
-
- }
-}
-
-
-
-/*
* usbvision_init()
*
* This code is run to initialize the driver.
@@ -2323,8 +2155,6 @@ static int __init usbvision_init(void)
usbvision_v4l2_format[7].supported = 0; // V4L2_PIX_FMT_YUV422P
}
- customdevice_process();
-
errCode = usb_register(&usbvision_driver);
if (errCode == 0) {
diff --git a/linux/drivers/media/video/usbvision/usbvision.h b/linux/drivers/media/video/usbvision/usbvision.h
index bee7d06bc..c810a6bda 100644
--- a/linux/drivers/media/video/usbvision/usbvision.h
+++ b/linux/drivers/media/video/usbvision/usbvision.h
@@ -342,23 +342,24 @@ struct usbvision_frame {
#define BRIDGE_NT1005 1005
struct usbvision_device_data_st {
- int idVendor;
- int idProduct;
- int Interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
- int Codec;
- int VideoChannels;
__u64 VideoNorm;
- int AudioChannels;
- int Radio;
- int vbi;
- int Tuner;
- int TunerType;
- int Vin_Reg1;
- int Vin_Reg2;
- int X_Offset;
- int Y_Offset;
- int Dvi_yuv;
- char *ModelString;
+ const char *ModelString;
+ int Interface; /* to handle special interface number like BELKIN and Hauppauge WinTV-USB II */
+ __u16 Codec;
+ unsigned VideoChannels:3;
+ unsigned AudioChannels:2;
+ unsigned Radio:1;
+ unsigned vbi:1;
+ unsigned Tuner:1;
+ unsigned Vin_Reg1_override:1; /* Override default value with */
+ unsigned Vin_Reg2_override:1; /* Vin_Reg1, Vin_Reg2, etc. */
+ unsigned Dvi_yuv_override:1;
+ __u8 Vin_Reg1;
+ __u8 Vin_Reg2;
+ __u8 Dvi_yuv;
+ __u8 TunerType;
+ __s16 X_Offset;
+ __s16 Y_Offset;
};
/* Declared on usbvision-cards.c */
@@ -485,34 +486,11 @@ struct usb_usbvision {
/* i2c-algo-usb declaration */
/* --------------------------------------------------------------- */
-int usbvision_i2c_usb_del_bus(struct i2c_adapter *);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static inline void *i2c_get_clientdata (struct i2c_client *dev)
-{
- return dev->data;
-}
-
-static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
-{
- dev->data = data;
-}
-
-static inline void *i2c_get_adapdata (struct i2c_adapter *dev)
-{
- return dev->data;
-}
-
-static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data)
-{
- dev->data = data;
-}
-#endif
-
/* ----------------------------------------------------------------------- */
/* usbvision specific I2C functions */
/* ----------------------------------------------------------------------- */
-int usbvision_init_i2c(struct usb_usbvision *usbvision);
+int usbvision_i2c_register(struct usb_usbvision *usbvision);
+int usbvision_i2c_unregister(struct usb_usbvision *usbvision);
void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg);
/* defined in usbvision-core.c */
diff --git a/linux/drivers/media/video/v4l1-compat.c b/linux/drivers/media/video/v4l1-compat.c
index 2e42ee3a2..253771b0b 100644
--- a/linux/drivers/media/video/v4l1-compat.c
+++ b/linux/drivers/media/video/v4l1-compat.c
@@ -129,7 +129,7 @@ set_v4l_control(struct inode *inode,
/* ----------------------------------------------------------------- */
-static int palette2pixelformat[] = {
+const static unsigned int palette2pixelformat[] = {
[VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY,
[VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555,
[VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565,
@@ -147,7 +147,7 @@ static int palette2pixelformat[] = {
[VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
};
-static unsigned int
+static unsigned int __attribute_pure__
palette_to_pixelformat(unsigned int palette)
{
if (palette < ARRAY_SIZE(palette2pixelformat))
@@ -156,8 +156,8 @@ palette_to_pixelformat(unsigned int palette)
return 0;
}
-static unsigned int
-pixelformat_to_palette(int pixelformat)
+static unsigned int __attribute_const__
+pixelformat_to_palette(unsigned int pixelformat)
{
int palette = 0;
switch (pixelformat)
@@ -629,6 +629,8 @@ v4l_compat_translate_ioctl(struct inode *inode,
case VIDIOCSPICT: /* set tone controls & partial capture format */
{
struct video_picture *pict = arg;
+ int mem_err = 0, ovl_err = 0;
+
memset(&fbuf2, 0, sizeof(fbuf2));
set_v4l_control(inode, file,
@@ -641,33 +643,61 @@ v4l_compat_translate_ioctl(struct inode *inode,
V4L2_CID_SATURATION, pict->colour, drv);
set_v4l_control(inode, file,
V4L2_CID_WHITENESS, pict->whiteness, drv);
+ /*
+ * V4L1 uses this ioctl to set both memory capture and overlay
+ * pixel format, while V4L2 has two different ioctls for this.
+ * Some cards may not support one or the other, and may support
+ * different pixel formats for memory vs overlay.
+ */
fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
err = drv(inode, file, VIDIOC_G_FMT, fmt2);
- if (err < 0)
+ /* If VIDIOC_G_FMT failed, then the driver likely doesn't
+ support memory capture. Trying to set the memory capture
+ parameters would be pointless. */
+ if (err < 0) {
dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
- if (fmt2->fmt.pix.pixelformat !=
- palette_to_pixelformat(pict->palette)) {
+ mem_err = -1000; /* didn't even try */
+ } else if (fmt2->fmt.pix.pixelformat !=
+ palette_to_pixelformat(pict->palette)) {
fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
pict->palette);
- err = drv(inode, file, VIDIOC_S_FMT, fmt2);
- if (err < 0)
- dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
+ mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2);
+ if (mem_err < 0)
+ dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
+ mem_err);
}
err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
- if (err < 0)
+ /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
+ support overlay. Trying to set the overlay parameters
+ would be quite pointless. */
+ if (err < 0) {
dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
- if (fbuf2.fmt.pixelformat !=
- palette_to_pixelformat(pict->palette)) {
+ ovl_err = -1000; /* didn't even try */
+ } else if (fbuf2.fmt.pixelformat !=
+ palette_to_pixelformat(pict->palette)) {
fbuf2.fmt.pixelformat = palette_to_pixelformat(
pict->palette);
- err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
- if (err < 0)
- dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err);
- err = 0; /* likely fails for non-root */
+ ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
+ if (ovl_err < 0)
+ dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
+ ovl_err);
+ if (ovl_err == -EPERM)
+ ovl_err = 0;
}
+ if (ovl_err < 0 && mem_err < 0)
+ /* ioctl failed, couldn't set either parameter */
+ if (mem_err != -1000) {
+ err = mem_err;
+ } else if (ovl_err == -EPERM) {
+ err = 0;
+ } else {
+ err = ovl_err;
+ }
+ else
+ err = 0;
break;
}
case VIDIOCGTUNER: /* get tuner information */
diff --git a/linux/drivers/media/video/video-buf.c b/linux/drivers/media/video/video-buf.c
index 5564e20af..c053375bb 100644
--- a/linux/drivers/media/video/video-buf.c
+++ b/linux/drivers/media/video/video-buf.c
@@ -708,9 +708,7 @@ videobuf_qbuf(struct videobuf_queue *q,
dprintk(1,"qbuf: memory type is wrong.\n");
goto done;
}
- if (buf->state == STATE_QUEUED ||
- buf->state == STATE_PREPARED ||
- buf->state == STATE_ACTIVE) {
+ if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) {
dprintk(1,"qbuf: buffer is already queued or active.\n");
goto done;
}
diff --git a/linux/drivers/media/video/videocodec.c b/linux/drivers/media/video/videocodec.c
index 290e64135..f2bbd7a4d 100644
--- a/linux/drivers/media/video/videocodec.c
+++ b/linux/drivers/media/video/videocodec.c
@@ -348,6 +348,9 @@ videocodec_build_table (void)
kfree(videocodec_buf);
videocodec_buf = kmalloc(size, GFP_KERNEL);
+ if (!videocodec_buf)
+ return 0;
+
i = 0;
i += scnprintf(videocodec_buf + i, size - 1,
"<S>lave or attached <M>aster name type flags magic ");
diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c
index acb3c4fbf..b8e022aed 100644
--- a/linux/drivers/media/video/videodev.c
+++ b/linux/drivers/media/video/videodev.c
@@ -461,9 +461,39 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
v4l_print_ioctl(vfd->name, cmd);
}
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ /***********************************************************
+ Handles calls to the obsoleted V4L1 API
+ Due to the nature of VIDIOCGMBUF, each driver that supports
+ V4L1 should implement its own handler for this ioctl.
+ ***********************************************************/
+
+ /* --- streaming capture ------------------------------------- */
+ if (cmd == VIDIOCGMBUF) {
+ struct video_mbuf *p=arg;
+
+ memset(p,0,sizeof(p));
+
+ if (!vfd->vidiocgmbuf)
+ return ret;
+ ret=vfd->vidiocgmbuf(file, fh, p);
+ if (!ret)
+ dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
+ p->size, p->frames,
+ (unsigned long)p->offsets);
+ return ret;
+ }
+
+ /********************************************************
+ All other V4L1 calls are handled by v4l1_compat module.
+ Those calls will be translated into V4L2 calls, and
+ __video_do_ioctl will be called again, with one or more
+ V4L2 ioctls.
+ ********************************************************/
if (_IOC_TYPE(cmd)=='v')
return v4l_compat_translate_ioctl(inode,file,cmd,arg,
__video_do_ioctl);
+#endif
switch(cmd) {
/* --- capabilities ------------------------------------------ */
@@ -815,24 +845,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
ret=vfd->vidioc_overlay(file, fh, *i);
break;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- /* --- streaming capture ------------------------------------- */
- case VIDIOCGMBUF:
- {
- struct video_mbuf *p=arg;
-
- memset(p,0,sizeof(p));
-
- if (!vfd->vidiocgmbuf)
- break;
- ret=vfd->vidiocgmbuf(file, fh, p);
- if (!ret)
- dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
- p->size, p->frames,
- (unsigned long)p->offsets);
- break;
- }
-#endif
case VIDIOC_G_FBUF:
{
struct v4l2_framebuffer *p=arg;
@@ -1427,6 +1439,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_PARM:
{
struct v4l2_streamparm *p=arg;
+ __u32 type=p->type;
+
+ memset(p,0,sizeof(*p));
+ p->type=type;
+
if (vfd->vidioc_g_parm) {
ret=vfd->vidioc_g_parm(file, fh, p);
} else {
@@ -1438,8 +1455,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
v4l2_video_std_construct(&s, vfd->current_norm,
v4l2_norm_to_name(vfd->current_norm));
- memset(p,0,sizeof(*p));
-
p->parm.capture.timeperframe = s.frameperiod;
ret=0;
}
diff --git a/linux/drivers/media/video/zc0301/Kconfig b/linux/drivers/media/video/zc0301/Kconfig
index a859a6920..47cd93f9c 100644
--- a/linux/drivers/media/video/zc0301/Kconfig
+++ b/linux/drivers/media/video/zc0301/Kconfig
@@ -1,6 +1,6 @@
config USB_ZC0301
tristate "USB ZC0301[P] Image Processor and Control Chip support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want support for cameras based on the ZC0301 or
ZC0301P Image Processors and Control Chips.