From 723befdc4c49248742d482a254b1d382ce84a41d Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Mon, 11 Aug 2008 18:12:19 +0200 Subject: Initial support for AME DTV-5100 USB2.0 DVB-T From: Antoine Jacquet Basic support for AME DTV-5100 USB2.0 DVB-T using the qt1010 tuner and a dummy frontend. Priority: normal Signed-off-by: Antoine Jacquet --- linux/drivers/media/dvb/dvb-usb/Kconfig | 7 + linux/drivers/media/dvb/dvb-usb/Makefile | 3 + linux/drivers/media/dvb/dvb-usb/dtv5100-fe.c | 147 ++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/dtv5100.c | 217 +++++++++++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/dtv5100.h | 128 ++++++++++++++++ 5 files changed, 502 insertions(+) create mode 100644 linux/drivers/media/dvb/dvb-usb/dtv5100-fe.c create mode 100644 linux/drivers/media/dvb/dvb-usb/dtv5100.c create mode 100644 linux/drivers/media/dvb/dvb-usb/dtv5100.h (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index e84152b75..369226220 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -262,3 +262,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..5e170fba1 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 dtv5100-fe.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-fe.c b/linux/drivers/media/dvb/dvb-usb/dtv5100-fe.c new file mode 100644 index 000000000..08fe33bcc --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/dtv5100-fe.c @@ -0,0 +1,147 @@ +/* + * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T + * + * Copyright (C) 2008 Antoine Jacquet + * http://royale.zerezo.com/dtv5100/ + * + * Inspired by dvb_dummy_fe.c + * + * 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 "dvb-usb.h" +#include "qt1010_priv.h" + +struct dtv5100_fe_state { + struct dvb_frontend frontend; +}; + +static int dtv5100_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) +{ + *status = FE_HAS_SIGNAL + | FE_HAS_CARRIER + | FE_HAS_VITERBI + | FE_HAS_SYNC + | FE_HAS_LOCK; + + return 0; +} + +static int dtv5100_fe_read_ber(struct dvb_frontend* fe, u32* ber) +{ + *ber = 0; + return 0; +} + +static int dtv5100_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength) +{ + *strength = 0; + return 0; +} + +static int dtv5100_fe_read_snr(struct dvb_frontend* fe, u16* snr) +{ + *snr = 0; + return 0; +} + +static int dtv5100_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) +{ + *ucblocks = 0; + return 0; +} + +static int dtv5100_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +{ + return 0; +} + +static int dtv5100_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +{ + 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); + } + + return 0; +} + +static int dtv5100_fe_sleep(struct dvb_frontend* fe) +{ + return 0; +} + +static int dtv5100_fe_init(struct dvb_frontend* fe) +{ + return 0; +} + +static void dtv5100_fe_release(struct dvb_frontend* fe) +{ + struct dtv5100_fe_state* state = fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops dtv5100_fe_ops; + +struct dvb_frontend* dtv5100_fe_attach(void) +{ + struct dtv5100_fe_state* state = NULL; + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct dtv5100_fe_state), GFP_KERNEL); + if (state == NULL) goto error; + + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &dtv5100_fe_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + return &state->frontend; + +error: + kfree(state); + return NULL; +} + +static struct dvb_frontend_ops dtv5100_fe_ops = { + + .info = { + .name = "Dummy DVB-T", + .type = FE_OFDM, + .frequency_min = QT1010_MIN_FREQ, + .frequency_max = QT1010_MAX_FREQ, + .frequency_stepsize = QT1010_STEP, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | + FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO, + }, + + .release = dtv5100_fe_release, + + .init = dtv5100_fe_init, + .sleep = dtv5100_fe_sleep, + + .set_frontend = dtv5100_fe_set_frontend, + .get_frontend = dtv5100_fe_get_frontend, + + .read_status = dtv5100_fe_read_status, + .read_ber = dtv5100_fe_read_ber, + .read_signal_strength = dtv5100_fe_read_signal_strength, + .read_snr = dtv5100_fe_read_snr, + .read_ucblocks = dtv5100_fe_read_ucblocks, +}; 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..f89d01755 --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/dtv5100.c @@ -0,0 +1,217 @@ +/* + * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T + * + * Copyright (C) 2008 Antoine Jacquet + * 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 "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_read_reg(struct dvb_usb_device *d, u8 addr, u8 reg, u8 *value) +{ + return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), + DTV5100_I2C_READ, USB_TYPE_VENDOR|USB_DIR_IN, + 0, (addr << 8) + reg, value, 1, + DTV5100_USB_TIMEOUT); +} + +static int dtv5100_write_reg(struct dvb_usb_device *d, u8 addr, u8 reg, u8 value) +{ + return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), + DTV5100_I2C_WRITE, USB_TYPE_VENDOR|USB_DIR_OUT, + value, (addr << 8) + reg, NULL, 0, + 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++) { + if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + /* write/read request, 2 messages + * msg = { + * { reg }, + * { val }, + * } + */ + if (dtv5100_read_reg(d, msg[i].addr, msg[i].buf[0], msg[i+1].buf) < 0) + break; + i++; + } else { + /* write request, 1 message + * msg = { + * { reg, val }, + * } + */ + if (dtv5100_write_reg(d, msg[i].addr, msg[i].buf[0], msg[i].buf[1]) < 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 int dtv5100_frontend_attach(struct dvb_usb_adapter *adap) +{ + adap->fe = dtv5100_fe_attach(); + return 0; +} + +static struct qt1010_config dtv5100_qt1010_config = { + .i2c_address = 0xc4 +}; + +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); + + ret = dvb_usb_device_init(intf, &dtv5100_properties, + THIS_MODULE, NULL, adapter_nr); + if (ret) + return ret; + + /* initialize frontend & non qt1010 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; + } + + 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..1aadb86f7 --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/dtv5100.h @@ -0,0 +1,128 @@ +/* + * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T + * + * Copyright (C) 2008 Antoine Jacquet + * 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_I2C_WRITE 0xc7 +#define DTV5100_I2C_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 }, + { 0x000000c0, 0x0000000b, 0x00000050 }, + { 0x000000c0, 0x00000044, 0x00000051 }, + { 0x000000c0, 0x00000046, 0x00000052 }, + { 0x000000c0, 0x00000015, 0x00000053 }, + { 0x000000c0, 0x0000000f, 0x00000054 }, + { 0x000000c0, 0x00000080, 0x00000055 }, + { 0x000000c0, 0x00000001, 0x000000ea }, + { 0x000000c0, 0x00000000, 0x000000ea }, + { 0x000000c0, 0x00000075, 0x0000005c }, + { 0x000000c0, 0x000000a1, 0x0000009c }, + { 0x000000c0, 0x00000000, 0x0000008e }, + { 0x000000c0, 0x00000000, 0x00000090 }, + { 0x000000c0, 0x000000ff, 0x00000091 }, + { 0x000000c0, 0x000000ff, 0x00000092 }, + { 0x000000c0, 0x00000000, 0x00000093 }, + { 0x000000c0, 0x000000ff, 0x00000094 }, + { 0x000000c0, 0x00000000, 0x00000058 }, + { 0x000000c0, 0x0000003f, 0x00000095 }, + { 0x000000c0, 0x0000003f, 0x00000096 }, + { 0x000000c0, 0x0000000c, 0x0000005a }, + { 0x000000c0, 0x0000002b, 0x00000056 }, + { 0x000000c0, 0x00000017, 0x0000005f }, + { 0x000000c0, 0x00000040, 0x0000005e }, + { 0x000000c0, 0x00000036, 0x00000064 }, + { 0x000000c0, 0x00000067, 0x00000065 }, + { 0x000000c0, 0x000000e5, 0x00000066 }, + { 0x000000c0, 0x00000073, 0x000000cc }, + { 0x000000c0, 0x000000cd, 0x0000006c }, + { 0x000000c0, 0x0000007e, 0x0000006d }, + { 0x000000c0, 0x00000001, 0x00000071 }, + { 0x000000c0, 0x00000001, 0x00000070 }, + /**/ + { 0x000000c7, 0x00000080, 0x0000c401 }, + { 0x000000c7, 0x0000003f, 0x0000c402 }, + { 0x000000c7, 0x00000034, 0x0000c405 }, // 2 + { 0x000000c7, 0x00000044, 0x0000c406 }, + { 0x000000c7, 0x00000038, 0x0000c407 }, // 4 + { 0x000000c7, 0x00000008, 0x0000c408 }, + { 0x000000c7, 0x0000001c, 0x0000c409 }, // 6 + { 0x000000c7, 0x0000000d, 0x0000c40a }, // 7 + { 0x000000c7, 0x00000045, 0x0000c40b }, // 8 + { 0x000000c7, 0x000000e1, 0x0000c40c }, + { 0x000000c7, 0x00000078, 0x0000c41a }, // 10 + { 0x000000c7, 0x00000000, 0x0000c41b }, + { 0x000000c7, 0x00000089, 0x0000c41c }, + { 0x000000c7, 0x000000fd, 0x0000c411 }, // 13 + { 0x000000c7, 0x00000095, 0x0000c412 }, // 14 + { 0x000000c7, 0x000000d6, 0x0000c422 }, // 15 + { 0x000000c7, 0x00000000, 0x0000c41e }, + { 0x000000c7, 0x000000d0, 0x0000c41e }, + { 0x000000c8, 0x00000000, 0x0000c422 }, + { 0x000000c7, 0x00000000, 0x0000c41e }, + { 0x000000c8, 0x00000000, 0x0000c405 }, + { 0x000000c8, 0x00000000, 0x0000c422 }, + { 0x000000c7, 0x000000d0, 0x0000c423 }, + { 0x000000c7, 0x00000000, 0x0000c41e }, + { 0x000000c7, 0x000000e0, 0x0000c41e }, + { 0x000000c8, 0x00000000, 0x0000c423 }, + { 0x000000c8, 0x00000000, 0x0000c423 }, + { 0x000000c7, 0x00000000, 0x0000c41e }, + { 0x000000c7, 0x000000d0, 0x0000c424 }, + { 0x000000c7, 0x00000000, 0x0000c41e }, + { 0x000000c7, 0x000000f0, 0x0000c41e }, + { 0x000000c8, 0x00000000, 0x0000c424 }, + { 0x000000c7, 0x00000000, 0x0000c41e }, + { 0x000000c7, 0x0000007f, 0x0000c414 }, + { 0x000000c7, 0x0000007f, 0x0000c415 }, + { 0x000000c7, 0x00000030, 0x0000c405 }, + { 0x000000c7, 0x00000000, 0x0000c406 }, + { 0x000000c7, 0x0000001f, 0x0000c415 }, + { 0x000000c7, 0x000000ff, 0x0000c416 }, + { 0x000000c7, 0x000000ff, 0x0000c418 }, + { 0x000000c7, 0x00000051, 0x0000c41f }, // here + { 0x000000c7, 0x00000016, 0x0000c420 }, // here + { 0x000000c7, 0x00000053, 0x0000c421 }, + { 0x000000c7, 0x000000c1, 0x0000c425 }, // here + { 0x000000c7, 0x00000014, 0x0000c426 }, // here + { 0x000000c7, 0x00000082, 0x0000c400 }, + { 0x000000c7, 0x00000000, 0x0000c402 }, + { 0x000000c7, 0x00000000, 0x0000c401 }, + /**/ + { } /* Terminating entry */ +}; + +extern struct dvb_frontend* dtv5100_fe_attach(void); + +#endif -- cgit v1.2.3 From bb349c708ba7b43225db2baa6daad703a3b0100e Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Tue, 12 Aug 2008 00:21:33 +0200 Subject: dtv5100: replace dummy frontend by zl10353 From: Antoine Jacquet Remove the dtv5100-fe.c dummy frontend and replace it by the real frontend for the chipset. Priority: normal Signed-off-by: Antoine Jacquet --- linux/drivers/media/dvb/dvb-usb/Makefile | 2 +- linux/drivers/media/dvb/dvb-usb/dtv5100-fe.c | 147 --------------------------- linux/drivers/media/dvb/dvb-usb/dtv5100.c | 94 ++++++++++------- linux/drivers/media/dvb/dvb-usb/dtv5100.h | 91 ++--------------- 4 files changed, 68 insertions(+), 266 deletions(-) delete mode 100644 linux/drivers/media/dvb/dvb-usb/dtv5100-fe.c (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile index 5e170fba1..116544f42 100644 --- a/linux/drivers/media/dvb/dvb-usb/Makefile +++ b/linux/drivers/media/dvb/dvb-usb/Makefile @@ -67,7 +67,7 @@ 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 dtv5100-fe.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/ diff --git a/linux/drivers/media/dvb/dvb-usb/dtv5100-fe.c b/linux/drivers/media/dvb/dvb-usb/dtv5100-fe.c deleted file mode 100644 index 08fe33bcc..000000000 --- a/linux/drivers/media/dvb/dvb-usb/dtv5100-fe.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T - * - * Copyright (C) 2008 Antoine Jacquet - * http://royale.zerezo.com/dtv5100/ - * - * Inspired by dvb_dummy_fe.c - * - * 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 "dvb-usb.h" -#include "qt1010_priv.h" - -struct dtv5100_fe_state { - struct dvb_frontend frontend; -}; - -static int dtv5100_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - *status = FE_HAS_SIGNAL - | FE_HAS_CARRIER - | FE_HAS_VITERBI - | FE_HAS_SYNC - | FE_HAS_LOCK; - - return 0; -} - -static int dtv5100_fe_read_ber(struct dvb_frontend* fe, u32* ber) -{ - *ber = 0; - return 0; -} - -static int dtv5100_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - *strength = 0; - return 0; -} - -static int dtv5100_fe_read_snr(struct dvb_frontend* fe, u16* snr) -{ - *snr = 0; - return 0; -} - -static int dtv5100_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - *ucblocks = 0; - return 0; -} - -static int dtv5100_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - return 0; -} - -static int dtv5100_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - 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); - } - - return 0; -} - -static int dtv5100_fe_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int dtv5100_fe_init(struct dvb_frontend* fe) -{ - return 0; -} - -static void dtv5100_fe_release(struct dvb_frontend* fe) -{ - struct dtv5100_fe_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops dtv5100_fe_ops; - -struct dvb_frontend* dtv5100_fe_attach(void) -{ - struct dtv5100_fe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct dtv5100_fe_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dtv5100_fe_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops dtv5100_fe_ops = { - - .info = { - .name = "Dummy DVB-T", - .type = FE_OFDM, - .frequency_min = QT1010_MIN_FREQ, - .frequency_max = QT1010_MAX_FREQ, - .frequency_stepsize = QT1010_STEP, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dtv5100_fe_release, - - .init = dtv5100_fe_init, - .sleep = dtv5100_fe_sleep, - - .set_frontend = dtv5100_fe_set_frontend, - .get_frontend = dtv5100_fe_get_frontend, - - .read_status = dtv5100_fe_read_status, - .read_ber = dtv5100_fe_read_ber, - .read_signal_strength = dtv5100_fe_read_signal_strength, - .read_snr = dtv5100_fe_read_snr, - .read_ucblocks = dtv5100_fe_read_ucblocks, -}; diff --git a/linux/drivers/media/dvb/dvb-usb/dtv5100.c b/linux/drivers/media/dvb/dvb-usb/dtv5100.c index f89d01755..7168a49ce 100644 --- a/linux/drivers/media/dvb/dvb-usb/dtv5100.c +++ b/linux/drivers/media/dvb/dvb-usb/dtv5100.c @@ -22,6 +22,7 @@ */ #include "dtv5100.h" +#include "zl10353.h" #include "qt1010.h" /* debug */ @@ -30,25 +31,44 @@ 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_read_reg(struct dvb_usb_device *d, u8 addr, u8 reg, u8 *value) +static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, + u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), - DTV5100_I2C_READ, USB_TYPE_VENDOR|USB_DIR_IN, - 0, (addr << 8) + reg, value, 1, - DTV5100_USB_TIMEOUT); -} + 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]; -static int dtv5100_write_reg(struct dvb_usb_device *d, u8 addr, u8 reg, u8 value) -{ - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), - DTV5100_I2C_WRITE, USB_TYPE_VENDOR|USB_DIR_OUT, - value, (addr << 8) + reg, NULL, 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) + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i; @@ -60,25 +80,16 @@ static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], return -EAGAIN; for (i = 0; i < num; i++) { + /* write/read request */ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - /* write/read request, 2 messages - * msg = { - * { reg }, - * { val }, - * } - */ - if (dtv5100_read_reg(d, msg[i].addr, msg[i].buf[0], msg[i+1].buf) < 0) + 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 { - /* write request, 1 message - * msg = { - * { reg, val }, - * } - */ - if (dtv5100_write_reg(d, msg[i].addr, msg[i].buf[0], msg[i].buf[1]) < 0) + } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf, + msg[i].len, NULL, 0) < 0) break; - } } mutex_unlock(&d->i2c_mutex); @@ -96,14 +107,27 @@ static struct i2c_algorithm dtv5100_i2c_algo = { }; /* 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 = dtv5100_fe_attach(); + 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 = 0xc4 + .i2c_address = DTV5100_TUNER_ADDR }; static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap) @@ -122,12 +146,7 @@ static int dtv5100_probe(struct usb_interface *intf, int i, ret; struct usb_device *udev = interface_to_usbdev(intf); - ret = dvb_usb_device_init(intf, &dtv5100_properties, - THIS_MODULE, NULL, adapter_nr); - if (ret) - return ret; - - /* initialize frontend & non qt1010 part? */ + /* initialize non qt1010/zl10353 part? */ for (i = 0; dtv5100_init[i].request; i++) { ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), @@ -140,6 +159,11 @@ static int dtv5100_probe(struct usb_interface *intf, return ret; } + ret = dvb_usb_device_init(intf, &dtv5100_properties, + THIS_MODULE, NULL, adapter_nr); + if (ret) + return ret; + return 0; } diff --git a/linux/drivers/media/dvb/dvb-usb/dtv5100.h b/linux/drivers/media/dvb/dvb-usb/dtv5100.h index 1aadb86f7..e36bf2d5c 100644 --- a/linux/drivers/media/dvb/dvb-usb/dtv5100.h +++ b/linux/drivers/media/dvb/dvb-usb/dtv5100.h @@ -26,8 +26,14 @@ #include "dvb-usb.h" #define DTV5100_USB_TIMEOUT 500 -#define DTV5100_I2C_WRITE 0xc7 -#define DTV5100_I2C_READ 0xc8 + +#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" @@ -39,87 +45,6 @@ static struct { } dtv5100_init[] = { { 0x000000c5, 0x00000000, 0x00000001 }, { 0x000000c5, 0x00000001, 0x00000001 }, - { 0x000000c0, 0x0000000b, 0x00000050 }, - { 0x000000c0, 0x00000044, 0x00000051 }, - { 0x000000c0, 0x00000046, 0x00000052 }, - { 0x000000c0, 0x00000015, 0x00000053 }, - { 0x000000c0, 0x0000000f, 0x00000054 }, - { 0x000000c0, 0x00000080, 0x00000055 }, - { 0x000000c0, 0x00000001, 0x000000ea }, - { 0x000000c0, 0x00000000, 0x000000ea }, - { 0x000000c0, 0x00000075, 0x0000005c }, - { 0x000000c0, 0x000000a1, 0x0000009c }, - { 0x000000c0, 0x00000000, 0x0000008e }, - { 0x000000c0, 0x00000000, 0x00000090 }, - { 0x000000c0, 0x000000ff, 0x00000091 }, - { 0x000000c0, 0x000000ff, 0x00000092 }, - { 0x000000c0, 0x00000000, 0x00000093 }, - { 0x000000c0, 0x000000ff, 0x00000094 }, - { 0x000000c0, 0x00000000, 0x00000058 }, - { 0x000000c0, 0x0000003f, 0x00000095 }, - { 0x000000c0, 0x0000003f, 0x00000096 }, - { 0x000000c0, 0x0000000c, 0x0000005a }, - { 0x000000c0, 0x0000002b, 0x00000056 }, - { 0x000000c0, 0x00000017, 0x0000005f }, - { 0x000000c0, 0x00000040, 0x0000005e }, - { 0x000000c0, 0x00000036, 0x00000064 }, - { 0x000000c0, 0x00000067, 0x00000065 }, - { 0x000000c0, 0x000000e5, 0x00000066 }, - { 0x000000c0, 0x00000073, 0x000000cc }, - { 0x000000c0, 0x000000cd, 0x0000006c }, - { 0x000000c0, 0x0000007e, 0x0000006d }, - { 0x000000c0, 0x00000001, 0x00000071 }, - { 0x000000c0, 0x00000001, 0x00000070 }, - /**/ - { 0x000000c7, 0x00000080, 0x0000c401 }, - { 0x000000c7, 0x0000003f, 0x0000c402 }, - { 0x000000c7, 0x00000034, 0x0000c405 }, // 2 - { 0x000000c7, 0x00000044, 0x0000c406 }, - { 0x000000c7, 0x00000038, 0x0000c407 }, // 4 - { 0x000000c7, 0x00000008, 0x0000c408 }, - { 0x000000c7, 0x0000001c, 0x0000c409 }, // 6 - { 0x000000c7, 0x0000000d, 0x0000c40a }, // 7 - { 0x000000c7, 0x00000045, 0x0000c40b }, // 8 - { 0x000000c7, 0x000000e1, 0x0000c40c }, - { 0x000000c7, 0x00000078, 0x0000c41a }, // 10 - { 0x000000c7, 0x00000000, 0x0000c41b }, - { 0x000000c7, 0x00000089, 0x0000c41c }, - { 0x000000c7, 0x000000fd, 0x0000c411 }, // 13 - { 0x000000c7, 0x00000095, 0x0000c412 }, // 14 - { 0x000000c7, 0x000000d6, 0x0000c422 }, // 15 - { 0x000000c7, 0x00000000, 0x0000c41e }, - { 0x000000c7, 0x000000d0, 0x0000c41e }, - { 0x000000c8, 0x00000000, 0x0000c422 }, - { 0x000000c7, 0x00000000, 0x0000c41e }, - { 0x000000c8, 0x00000000, 0x0000c405 }, - { 0x000000c8, 0x00000000, 0x0000c422 }, - { 0x000000c7, 0x000000d0, 0x0000c423 }, - { 0x000000c7, 0x00000000, 0x0000c41e }, - { 0x000000c7, 0x000000e0, 0x0000c41e }, - { 0x000000c8, 0x00000000, 0x0000c423 }, - { 0x000000c8, 0x00000000, 0x0000c423 }, - { 0x000000c7, 0x00000000, 0x0000c41e }, - { 0x000000c7, 0x000000d0, 0x0000c424 }, - { 0x000000c7, 0x00000000, 0x0000c41e }, - { 0x000000c7, 0x000000f0, 0x0000c41e }, - { 0x000000c8, 0x00000000, 0x0000c424 }, - { 0x000000c7, 0x00000000, 0x0000c41e }, - { 0x000000c7, 0x0000007f, 0x0000c414 }, - { 0x000000c7, 0x0000007f, 0x0000c415 }, - { 0x000000c7, 0x00000030, 0x0000c405 }, - { 0x000000c7, 0x00000000, 0x0000c406 }, - { 0x000000c7, 0x0000001f, 0x0000c415 }, - { 0x000000c7, 0x000000ff, 0x0000c416 }, - { 0x000000c7, 0x000000ff, 0x0000c418 }, - { 0x000000c7, 0x00000051, 0x0000c41f }, // here - { 0x000000c7, 0x00000016, 0x0000c420 }, // here - { 0x000000c7, 0x00000053, 0x0000c421 }, - { 0x000000c7, 0x000000c1, 0x0000c425 }, // here - { 0x000000c7, 0x00000014, 0x0000c426 }, // here - { 0x000000c7, 0x00000082, 0x0000c400 }, - { 0x000000c7, 0x00000000, 0x0000c402 }, - { 0x000000c7, 0x00000000, 0x0000c401 }, - /**/ { } /* Terminating entry */ }; -- cgit v1.2.3 From 6419821388c400bcd9ed1bcf50230b56d2205dcf Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Tue, 12 Aug 2008 21:56:34 +0200 Subject: dtv5100: CodingStyle cleanups From: Antoine Jacquet Priority: normal Signed-off-by: Antoine Jacquet --- linux/drivers/media/dvb/dvb-usb/dtv5100.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/dtv5100.c b/linux/drivers/media/dvb/dvb-usb/dtv5100.c index 7168a49ce..b2e6f7ff1 100644 --- a/linux/drivers/media/dvb/dvb-usb/dtv5100.c +++ b/linux/drivers/media/dvb/dvb-usb/dtv5100.c @@ -32,7 +32,7 @@ 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 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { u8 request; u8 type; @@ -44,14 +44,14 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, /* write { reg }, read { value } */ request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ : DTV5100_TUNER_READ); - type = USB_TYPE_VENDOR|USB_DIR_IN; + 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; + type = USB_TYPE_VENDOR | USB_DIR_OUT; value = wbuf[1]; break; default: @@ -68,7 +68,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, /* I2C */ static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i; @@ -116,7 +116,7 @@ static struct zl10353_config dtv5100_zl10353_config = { static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap) { adap->fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config, - &adap->dev->i2c_adap); + &adap->dev->i2c_adap); if (adap->fe == NULL) return -EIO; @@ -147,11 +147,10 @@ static int dtv5100_probe(struct usb_interface *intf, struct usb_device *udev = interface_to_usbdev(intf); /* initialize non qt1010/zl10353 part? */ - for (i = 0; dtv5100_init[i].request; i++) - { + 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, + USB_TYPE_VENDOR | USB_DIR_OUT, dtv5100_init[i].value, dtv5100_init[i].index, NULL, 0, DTV5100_USB_TIMEOUT); -- cgit v1.2.3 From 677ec00d28b905a78c8fa5f623be5f29ac1e384a Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Mon, 18 Aug 2008 22:09:53 +0200 Subject: zr364xx: remove BKL From: Antoine Jacquet Remove the Big Kernel Lock from zr364xx driver after pushdown. Now using an internal locking mecanism on open(). Priority: normal Signed-off-by: Antoine Jacquet --- linux/drivers/media/video/zr364xx.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index dbfdd6966..9d07e6185 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -642,25 +642,23 @@ static int zr364xx_open(struct inode *inode, struct file *file) DBG("zr364xx_open"); + mutex_lock(&cam->lock); + cam->skip = 2; - lock_kernel(); err = video_exclusive_open(inode, file); - if (err < 0) { - unlock_kernel(); - return err; - } + if (err < 0) + 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,9 +666,7 @@ 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; } } @@ -680,10 +676,11 @@ static int zr364xx_open(struct inode *inode, struct file *file) * 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; } -- cgit v1.2.3 From 907cb68cd937317d682455610490e10b06389d22 Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Mon, 18 Aug 2008 22:14:30 +0200 Subject: zr364xx: handle video exclusive open internaly From: Antoine Jacquet Count the users and do not use video_exclusive_open() anymore. Priority: normal Signed-off-by: Antoine Jacquet --- linux/drivers/media/video/zr364xx.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index 9d07e6185..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; }; @@ -644,11 +645,10 @@ static int zr364xx_open(struct inode *inode, struct file *file) mutex_lock(&cam->lock); - cam->skip = 2; - - err = video_exclusive_open(inode, file); - if (err < 0) + if (cam->users) { + err = -EBUSY; goto out; + } if (!cam->framebuf) { cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES); @@ -670,6 +670,8 @@ static int zr364xx_open(struct inode *inode, struct file *file) } } + cam->skip = 2; + cam->users++; file->private_data = vdev; /* Added some delay here, since opening/closing the camera quickly, @@ -701,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, @@ -708,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; } -- cgit v1.2.3 From a970f3ac8255fd6a2b45fc6b7496aca94696ba30 Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Mon, 18 Aug 2008 23:22:00 +0200 Subject: dtv5100: remove old definition from header From: Antoine Jacquet Priority: normal Signed-off-by: Antoine Jacquet --- linux/drivers/media/dvb/dvb-usb/dtv5100.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/dtv5100.h b/linux/drivers/media/dvb/dvb-usb/dtv5100.h index e36bf2d5c..93e96e04a 100644 --- a/linux/drivers/media/dvb/dvb-usb/dtv5100.h +++ b/linux/drivers/media/dvb/dvb-usb/dtv5100.h @@ -48,6 +48,4 @@ static struct { { } /* Terminating entry */ }; -extern struct dvb_frontend* dtv5100_fe_attach(void); - #endif -- cgit v1.2.3 From 039ea34cc5feb0f324b4cc4b4fabcf135aced355 Mon Sep 17 00:00:00 2001 From: Antoine Jacquet Date: Mon, 18 Aug 2008 23:38:51 +0200 Subject: dtv5100: remove prohibited space... From: Antoine Jacquet Priority: normal Signed-off-by: Antoine Jacquet --- linux/drivers/media/dvb/dvb-usb/dtv5100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/dvb-usb/dtv5100.c b/linux/drivers/media/dvb/dvb-usb/dtv5100.c index b2e6f7ff1..078ce92ca 100644 --- a/linux/drivers/media/dvb/dvb-usb/dtv5100.c +++ b/linux/drivers/media/dvb/dvb-usb/dtv5100.c @@ -166,7 +166,7 @@ static int dtv5100_probe(struct usb_interface *intf, return 0; } -static struct usb_device_id dtv5100_table [] = { +static struct usb_device_id dtv5100_table[] = { { USB_DEVICE(0x06be, 0xa232) }, { } /* Terminating entry */ }; -- cgit v1.2.3