summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-08-22 13:53:04 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-08-22 13:53:04 -0300
commitb851f2792eb56fb2608fb21a486bd1e1bc90787b (patch)
tree748a783903c29aa63c5b27d7546a25f091354e73
parent9774032a256c5068759be0d9f4a1413caf020dd1 (diff)
parent34764e7d93869b226c04ddac6b1daf8c93082b53 (diff)
downloadmediapointer-dvb-s2-b851f2792eb56fb2608fb21a486bd1e1bc90787b.tar.gz
mediapointer-dvb-s2-b851f2792eb56fb2608fb21a486bd1e1bc90787b.tar.bz2
merge: http://linuxtv.org/hg/~ajacquet/v4l-dvb/
From: Mauro Carvalho Chehab <mchehab@infradead.org> Priority: normal Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Kconfig7
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dtv5100.c240
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dtv5100.h51
-rw-r--r--linux/drivers/media/video/zr364xx.c41
-rwxr-xr-xv4l/scripts/checkpatch.pl4
6 files changed, 324 insertions, 22 deletions
diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig
index 8a54cb483..1d9e98cee 100644
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig
@@ -264,3 +264,10 @@ config DVB_USB_ANYSEE
help
Say Y here to support the Anysee E30, Anysee E30 Plus or
Anysee E30 C Plus DVB USB2.0 receiver.
+
+config DVB_USB_DTV5100
+ tristate "AME DTV-5100 USB2.0 DVB-T support"
+ depends on DVB_USB
+ select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
+ help
+ Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile
index e206f1ea0..116544f42 100644
--- a/linux/drivers/media/dvb/dvb-usb/Makefile
+++ b/linux/drivers/media/dvb/dvb-usb/Makefile
@@ -67,6 +67,9 @@ obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
dvb-usb-dw2102-objs = dw2102.o
obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
+dvb-usb-dtv5100-objs = dtv5100.o
+obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
+
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/linux/drivers/media/dvb/dvb-usb/dtv5100.c b/linux/drivers/media/dvb/dvb-usb/dtv5100.c
new file mode 100644
index 000000000..078ce92ca
--- /dev/null
+++ b/linux/drivers/media/dvb/dvb-usb/dtv5100.c
@@ -0,0 +1,240 @@
+/*
+ * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
+ *
+ * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
+ * http://royale.zerezo.com/dtv5100/
+ *
+ * Inspired by gl861.c and au6610.c drivers
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "dtv5100.h"
+#include "zl10353.h"
+#include "qt1010.h"
+
+/* debug */
+static int dvb_usb_dtv5100_debug;
+module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
+ u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+ u8 request;
+ u8 type;
+ u16 value;
+ u16 index;
+
+ switch (wlen) {
+ case 1:
+ /* write { reg }, read { value } */
+ request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
+ DTV5100_TUNER_READ);
+ type = USB_TYPE_VENDOR | USB_DIR_IN;
+ value = 0;
+ break;
+ case 2:
+ /* write { reg, value } */
+ request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
+ DTV5100_TUNER_WRITE);
+ type = USB_TYPE_VENDOR | USB_DIR_OUT;
+ value = wbuf[1];
+ break;
+ default:
+ warn("wlen = %x, aborting.", wlen);
+ return -EINVAL;
+ }
+ index = (addr << 8) + wbuf[0];
+
+ msleep(1); /* avoid I2C errors */
+ return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
+ type, value, index, rbuf, rlen,
+ DTV5100_USB_TIMEOUT);
+}
+
+/* I2C */
+static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i;
+
+ if (num > 2)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ for (i = 0; i < num; i++) {
+ /* write/read request */
+ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+ if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
+ msg[i].len, msg[i+1].buf,
+ msg[i+1].len) < 0)
+ break;
+ i++;
+ } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
+ msg[i].len, NULL, 0) < 0)
+ break;
+ }
+
+ mutex_unlock(&d->i2c_mutex);
+ return i;
+}
+
+static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dtv5100_i2c_algo = {
+ .master_xfer = dtv5100_i2c_xfer,
+ .functionality = dtv5100_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config dtv5100_zl10353_config = {
+ .demod_address = DTV5100_DEMOD_ADDR,
+ .no_tuner = 1,
+ .parallel_ts = 1,
+};
+
+static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ adap->fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe == NULL)
+ return -EIO;
+
+ /* disable i2c gate, or it won't work... is this safe? */
+ adap->fe->ops.i2c_gate_ctrl = NULL;
+
+ return 0;
+}
+
+static struct qt1010_config dtv5100_qt1010_config = {
+ .i2c_address = DTV5100_TUNER_ADDR
+};
+
+static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ return dvb_attach(qt1010_attach,
+ adap->fe, &adap->dev->i2c_adap,
+ &dtv5100_qt1010_config) == NULL ? -ENODEV : 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties dtv5100_properties;
+
+static int dtv5100_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int i, ret;
+ struct usb_device *udev = interface_to_usbdev(intf);
+
+ /* initialize non qt1010/zl10353 part? */
+ for (i = 0; dtv5100_init[i].request; i++) {
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ dtv5100_init[i].request,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ dtv5100_init[i].value,
+ dtv5100_init[i].index, NULL, 0,
+ DTV5100_USB_TIMEOUT);
+ if (ret)
+ return ret;
+ }
+
+ ret = dvb_usb_device_init(intf, &dtv5100_properties,
+ THIS_MODULE, NULL, adapter_nr);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct usb_device_id dtv5100_table[] = {
+ { USB_DEVICE(0x06be, 0xa232) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, dtv5100_table);
+
+static struct dvb_usb_device_properties dtv5100_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = DEVICE_SPECIFIC,
+
+ .size_of_priv = 0,
+
+ .num_adapters = 1,
+ .adapter = {{
+ .frontend_attach = dtv5100_frontend_attach,
+ .tuner_attach = dtv5100_tuner_attach,
+
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+ } },
+
+ .i2c_algo = &dtv5100_i2c_algo,
+
+ .num_device_descs = 1,
+ .devices = {
+ {
+ .name = "AME DTV-5100 USB2.0 DVB-T",
+ .cold_ids = { NULL },
+ .warm_ids = { &dtv5100_table[0], NULL },
+ },
+ }
+};
+
+static struct usb_driver dtv5100_driver = {
+ .name = "dvb_usb_dtv5100",
+ .probe = dtv5100_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = dtv5100_table,
+};
+
+/* module stuff */
+static int __init dtv5100_module_init(void)
+{
+ int ret;
+
+ ret = usb_register(&dtv5100_driver);
+ if (ret)
+ err("usb_register failed. Error number %d", ret);
+
+ return ret;
+}
+
+static void __exit dtv5100_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&dtv5100_driver);
+}
+
+module_init(dtv5100_module_init);
+module_exit(dtv5100_module_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/dvb-usb/dtv5100.h b/linux/drivers/media/dvb/dvb-usb/dtv5100.h
new file mode 100644
index 000000000..93e96e04a
--- /dev/null
+++ b/linux/drivers/media/dvb/dvb-usb/dtv5100.h
@@ -0,0 +1,51 @@
+/*
+ * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
+ *
+ * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
+ * http://royale.zerezo.com/dtv5100/
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _DVB_USB_DTV5100_H_
+#define _DVB_USB_DTV5100_H_
+
+#define DVB_USB_LOG_PREFIX "dtv5100"
+#include "dvb-usb.h"
+
+#define DTV5100_USB_TIMEOUT 500
+
+#define DTV5100_DEMOD_ADDR 0x00
+#define DTV5100_DEMOD_WRITE 0xc0
+#define DTV5100_DEMOD_READ 0xc1
+
+#define DTV5100_TUNER_ADDR 0xc4
+#define DTV5100_TUNER_WRITE 0xc7
+#define DTV5100_TUNER_READ 0xc8
+
+#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
+#define DRIVER_DESC "AME DTV-5100 USB2.0 DVB-T"
+
+static struct {
+ u8 request;
+ u8 value;
+ u16 index;
+} dtv5100_init[] = {
+ { 0x000000c5, 0x00000000, 0x00000001 },
+ { 0x000000c5, 0x00000001, 0x00000001 },
+ { } /* Terminating entry */
+};
+
+#endif
diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c
index dbfdd6966..a2a632534 100644
--- a/linux/drivers/media/video/zr364xx.c
+++ b/linux/drivers/media/video/zr364xx.c
@@ -117,6 +117,7 @@ struct zr364xx_camera {
int height;
int method;
struct mutex lock;
+ int users;
};
@@ -642,25 +643,22 @@ static int zr364xx_open(struct inode *inode, struct file *file)
DBG("zr364xx_open");
- cam->skip = 2;
+ mutex_lock(&cam->lock);
- lock_kernel();
- err = video_exclusive_open(inode, file);
- if (err < 0) {
- unlock_kernel();
- return err;
+ if (cam->users) {
+ err = -EBUSY;
+ goto out;
}
if (!cam->framebuf) {
cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES);
if (!cam->framebuf) {
info("vmalloc_32 failed!");
- unlock_kernel();
- return -ENOMEM;
+ err = -ENOMEM;
+ goto out;
}
}
- mutex_lock(&cam->lock);
for (i = 0; init[cam->method][i].size != -1; i++) {
err =
send_control_msg(udev, 1, init[cam->method][i].value,
@@ -668,22 +666,23 @@ static int zr364xx_open(struct inode *inode, struct file *file)
init[cam->method][i].size);
if (err < 0) {
info("error during open sequence: %d", i);
- mutex_unlock(&cam->lock);
- unlock_kernel();
- return err;
+ goto out;
}
}
+ cam->skip = 2;
+ cam->users++;
file->private_data = vdev;
/* Added some delay here, since opening/closing the camera quickly,
* like Ekiga does during its startup, can crash the webcam
*/
mdelay(100);
+ err = 0;
+out:
mutex_unlock(&cam->lock);
- unlock_kernel();
- return 0;
+ return err;
}
@@ -704,6 +703,10 @@ static int zr364xx_release(struct inode *inode, struct file *file)
udev = cam->udev;
mutex_lock(&cam->lock);
+
+ cam->users--;
+ file->private_data = NULL;
+
for (i = 0; i < 2; i++) {
err =
send_control_msg(udev, 1, init[cam->method][i].value,
@@ -711,21 +714,19 @@ static int zr364xx_release(struct inode *inode, struct file *file)
init[cam->method][i].size);
if (err < 0) {
info("error during release sequence");
- mutex_unlock(&cam->lock);
- return err;
+ goto out;
}
}
- file->private_data = NULL;
- video_exclusive_release(inode, file);
-
/* Added some delay here, since opening/closing the camera quickly,
* like Ekiga does during its startup, can crash the webcam
*/
mdelay(100);
+ err = 0;
+out:
mutex_unlock(&cam->lock);
- return 0;
+ return err;
}
diff --git a/v4l/scripts/checkpatch.pl b/v4l/scripts/checkpatch.pl
index bc6779398..a4f512753 100755
--- a/v4l/scripts/checkpatch.pl
+++ b/v4l/scripts/checkpatch.pl
@@ -1686,13 +1686,13 @@ sub process {
($op eq '>' &&
$ca =~ /<\S+\@\S+$/))
{
- $ok = 1;
+ $ok = 1;
}
# Ignore ?:
if (($opv eq ':O' && $ca =~ /\?$/) ||
($op eq '?' && $cc =~ /^:/)) {
- $ok = 1;
+ $ok = 1;
}
if ($ok == 0) {