From d0fbca290058bee7a54aefcc462e9ef33929d948 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 16 Aug 2008 11:55:04 +0100 Subject: Fix header export of videodev2.h, ivtv.h, ivtvfb.h From: David Woodhouse The exported copy of videodev2.h contains this line: #define #include This is because for some reason it defines __user for itself -- despite the fact that we remove all instances of __user when exporting headers. _All_ pointers in userspace are user pointers. Fix it by removing the unnecessary '#define __user' from the file. The new headers ivtv.h and ivtvfb.h would have the same problem... if whoever put them there had actually remembered to add them to the Kbuild file while he was at it. Fix those too, and export them as was presumably intended. Note that includes of are also stripped by the header export process, so those don't need to be conditional. kernel-sync: [mchehab.infradead.org: This is the backported version without the changes at include/linux/Kbuild, to be applied only at -hg] Signed-off-by: David Woodhouse Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/ivtv.h | 6 +----- linux/include/linux/ivtvfb.h | 6 +----- linux/include/linux/videodev2.h | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) (limited to 'linux') diff --git a/linux/include/linux/ivtv.h b/linux/include/linux/ivtv.h index 794b8daa9..17ca64b5a 100644 --- a/linux/include/linux/ivtv.h +++ b/linux/include/linux/ivtv.h @@ -21,11 +21,7 @@ #ifndef __LINUX_IVTV_H__ #define __LINUX_IVTV_H__ -#ifdef __KERNEL__ -#include /* need __user */ -#else -#define __user -#endif +#include #include /* ivtv knows several distinct output modes: MPEG streaming, diff --git a/linux/include/linux/ivtvfb.h b/linux/include/linux/ivtvfb.h index e980ba62d..e20af47b5 100644 --- a/linux/include/linux/ivtvfb.h +++ b/linux/include/linux/ivtvfb.h @@ -21,11 +21,7 @@ #ifndef __LINUX_IVTVFB_H__ #define __LINUX_IVTVFB_H__ -#ifdef __KERNEL__ -#include /* need __user */ -#else -#define __user -#endif +#include #include /* Framebuffer external API */ diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index f3ae9c88e..a79fc1584 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -55,13 +55,13 @@ */ #ifndef __LINUX_VIDEODEV2_H #define __LINUX_VIDEODEV2_H + #ifdef __KERNEL__ #include /* need struct timeval */ -#include /* need __user */ #else -#define __user #include #endif +#include #include #include -- cgit v1.2.3 From 8896d4269aa500bfa93d4a088bf12c470cfa5a2e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Aug 2008 16:44:54 -0700 Subject: saa7134-core.c: fix warning From: Alexander Beregalov drivers/media/video/saa7134/saa7134-core.c:366: warning: 'saa7134_buffer_requeue' defined but not used Signed-off-by: Alexander Beregalov Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-core.c | 52 ++++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index e02c3c1b1..62c9322aa 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -408,32 +408,6 @@ void saa7134_buffer_timeout(unsigned long data) spin_unlock_irqrestore(&dev->slock,flags); } -/* resends a current buffer in queue after resume */ - -static int saa7134_buffer_requeue(struct saa7134_dev *dev, - struct saa7134_dmaqueue *q) -{ - struct saa7134_buf *buf, *next; - - assert_spin_locked(&dev->slock); - - buf = q->curr; - next = buf; - dprintk("buffer_requeue\n"); - - if (!buf) - return 0; - - dprintk("buffer_requeue : resending active buffers \n"); - - if (!list_empty(&q->queue)) - next = list_entry(q->queue.next, struct saa7134_buf, - vb.queue); - buf->activate(dev, buf, next); - - return 0; -} - /* ------------------------------------------------------------------ */ int saa7134_set_dmabits(struct saa7134_dev *dev) @@ -1203,6 +1177,32 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) } #ifdef CONFIG_PM + +/* resends a current buffer in queue after resume */ +static int saa7134_buffer_requeue(struct saa7134_dev *dev, + struct saa7134_dmaqueue *q) +{ + struct saa7134_buf *buf, *next; + + assert_spin_locked(&dev->slock); + + buf = q->curr; + next = buf; + dprintk("buffer_requeue\n"); + + if (!buf) + return 0; + + dprintk("buffer_requeue : resending active buffers \n"); + + if (!list_empty(&q->queue)) + next = list_entry(q->queue.next, struct saa7134_buf, + vb.queue); + buf->activate(dev, buf, next); + + return 0; +} + static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) { -- cgit v1.2.3 From ea03de48c87e9209713cf3fb48848ab9cf138c0e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Aug 2008 19:09:42 -0300 Subject: v4l2-ioctl.c: fix warning From: Alexander Beregalov drivers/media/video/v4l2-ioctl.c:496: warning: format '%08ld' expects type 'long int', but argument 5 has type 'suseconds_t' Signed-off-by: Alexander Beregalov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/v4l2-ioctl.c b/linux/drivers/media/video/v4l2-ioctl.c index 1c8fa257d..51569f888 100644 --- a/linux/drivers/media/video/v4l2-ioctl.c +++ b/linux/drivers/media/video/v4l2-ioctl.c @@ -500,7 +500,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd, p->timestamp.tv_sec / 3600, (int)(p->timestamp.tv_sec / 60) % 60, (int)(p->timestamp.tv_sec % 60), - p->timestamp.tv_usec, + (long)p->timestamp.tv_usec, p->index, prt_names(p->type, v4l2_type_names), p->bytesused, p->flags, -- cgit v1.2.3 From 189a39592e02ff2f9a387eff92dfc3a3a2e4ddfb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Aug 2008 08:54:24 +0200 Subject: V4L: fix return value of register video func From: Henrik Kretzschmar If a wrong device type is used with video_register_device_index() it should better return an error number, instead of a constant. Signed-off-by: Henrik Kretzschmar Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index d97320091..594f2477f 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -316,7 +316,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, default: printk(KERN_ERR "%s called with unknown type: %d\n", __func__, type); - return -1; + return -EINVAL; } /* pick a minor number */ -- cgit v1.2.3 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 ad4e9eb607f09f8918f58c2d974e51a19db1b1d0 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 14 Aug 2008 16:36:37 +0200 Subject: Add Micron mt9m111 chip ID in V4L2 identifiers Signed-off-by: Robert Jarzmik Signed-off-by: Guennadi Liakhovetski --- include/media/v4l2-chip-ident.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) --- linux/include/media/v4l2-chip-ident.h | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index be782d5fc..d73a8e902 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -165,6 +165,7 @@ enum { /* Micron CMOS sensor chips: 45000-45099 */ V4L2_IDENT_MT9M001C12ST = 45000, V4L2_IDENT_MT9M001C12STM = 45005, + V4L2_IDENT_MT9M111 = 45007, V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ }; -- cgit v1.2.3 From abbb53148b769e275aba74bdf00b7dc50b937628 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 14 Aug 2008 17:02:51 +0200 Subject: Add support for Micron MT9M111 camera. Adds support for Micron MT9M111 camera chip, with basic features : - view rectangle configurable - some output formats (bayer8, bayer10, rgb565, rgb555, ycbycr) - autoexposure - only highpower mode context used (ie. context B) Signed-off-by: Robert Jarzmik Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/Kconfig | 6 + drivers/media/video/Makefile | 1 + drivers/media/video/mt9m111.c | 960 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 967 insertions(+), 0 deletions(-) create mode 100644 drivers/media/video/mt9m111.c --- linux/drivers/media/video/Kconfig | 6 + linux/drivers/media/video/Makefile | 1 + linux/drivers/media/video/mt9m111.c | 960 ++++++++++++++++++++++++++++++++++++ 3 files changed, 967 insertions(+) create mode 100644 linux/drivers/media/video/mt9m111.c (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 4c96b690a..c6516d42c 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -809,6 +809,12 @@ config MT9M001_PCA9536_SWITCH Select this if your MT9M001 camera uses a PCA9536 I2C GPIO extender to switch between 8 and 10 bit datawidth modes +config SOC_CAMERA_MT9M111 + tristate "mt9m001 support" + depends on SOC_CAMERA && I2C + help + This driver supports MT9M111 cameras from Micron + config SOC_CAMERA_MT9V022 tristate "mt9v022 support" depends on SOC_CAMERA && I2C diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index bf429b023..44e6ab891 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -138,6 +138,7 @@ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o +obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c new file mode 100644 index 000000000..0c88e5d6d --- /dev/null +++ b/linux/drivers/media/video/mt9m111.c @@ -0,0 +1,960 @@ +/* + * Driver for MT9M111 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Robert Jarzmik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * mt9m111 i2c address is 0x5d or 0x48 (depending on SAddr pin) + * The platform has to define i2c_board_info and call i2c_register_board_info() + */ + +/* mt9m111: Sensor register addresses */ +#define MT9M111_CHIP_VERSION 0x000 +#define MT9M111_ROW_START 0x001 +#define MT9M111_COLUMN_START 0x002 +#define MT9M111_WINDOW_HEIGHT 0x003 +#define MT9M111_WINDOW_WIDTH 0x004 +#define MT9M111_HORIZONTAL_BLANKING_B 0x005 +#define MT9M111_VERTICAL_BLANKING_B 0x006 +#define MT9M111_HORIZONTAL_BLANKING_A 0x007 +#define MT9M111_VERTICAL_BLANKING_A 0x008 +#define MT9M111_SHUTTER_WIDTH 0x009 +#define MT9M111_ROW_SPEED 0x00a +#define MT9M111_EXTRA_DELAY 0x00b +#define MT9M111_SHUTTER_DELAY 0x00c +#define MT9M111_RESET 0x00d +#define MT9M111_READ_MODE_B 0x020 +#define MT9M111_READ_MODE_A 0x021 +#define MT9M111_FLASH_CONTROL 0x023 +#define MT9M111_GREEN1_GAIN 0x02b +#define MT9M111_BLUE_GAIN 0x02c +#define MT9M111_RED_GAIN 0x02d +#define MT9M111_GREEN2_GAIN 0x02e +#define MT9M111_GLOBAL_GAIN 0x02f +#define MT9M111_CONTEXT_CONTROL 0x0c8 +#define MT9M111_PAGE_MAP 0x0f0 +#define MT9M111_BYTE_WISE_ADDR 0x0f1 + +#define MT9M111_RESET_SYNC_CHANGES (1 << 15) +#define MT9M111_RESET_RESTART_BAD_FRAME (1 << 9) +#define MT9M111_RESET_SHOW_BAD_FRAMES (1 << 8) +#define MT9M111_RESET_RESET_SOC (1 << 5) +#define MT9M111_RESET_OUTPUT_DISABLE (1 << 4) +#define MT9M111_RESET_CHIP_ENABLE (1 << 3) +#define MT9M111_RESET_ANALOG_STANDBY (1 << 2) +#define MT9M111_RESET_RESTART_FRAME (1 << 1) +#define MT9M111_RESET_RESET_MODE (1 << 0) + +#define MT9M111_RMB_MIRROR_COLS (1 << 1) +#define MT9M111_RMB_MIRROR_ROWS (1 << 0) +#define MT9M111_CTXT_CTRL_RESTART (1 << 15) +#define MT9M111_CTXT_CTRL_DEFECTCOR_B (1 << 12) +#define MT9M111_CTXT_CTRL_RESIZE_B (1 << 10) +#define MT9M111_CTXT_CTRL_CTRL2_B (1 << 9) +#define MT9M111_CTXT_CTRL_GAMMA_B (1 << 8) +#define MT9M111_CTXT_CTRL_XENON_EN (1 << 7) +#define MT9M111_CTXT_CTRL_READ_MODE_B (1 << 3) +#define MT9M111_CTXT_CTRL_LED_FLASH_EN (1 << 2) +#define MT9M111_CTXT_CTRL_VBLANK_SEL_B (1 << 1) +#define MT9M111_CTXT_CTRL_HBLANK_SEL_B (1 << 0) +/* + * mt9m111: Colorpipe register addresses (0x100..0x1ff) + */ +#define MT9M111_OPER_MODE_CTRL 0x106 +#define MT9M111_OUTPUT_FORMAT_CTRL 0x108 +#define MT9M111_REDUCER_XZOOM_B 0x1a0 +#define MT9M111_REDUCER_XSIZE_B 0x1a1 +#define MT9M111_REDUCER_YZOOM_B 0x1a3 +#define MT9M111_REDUCER_YSIZE_B 0x1a4 +#define MT9M111_REDUCER_XZOOM_A 0x1a6 +#define MT9M111_REDUCER_XSIZE_A 0x1a7 +#define MT9M111_REDUCER_YZOOM_A 0x1a9 +#define MT9M111_REDUCER_YSIZE_A 0x1aa + +#define MT9M111_OUTPUT_FORMAT_CTRL2_A 0x13a +#define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b + +#define MT9M111_OPMODE_AUTOEXPO_EN (1 << 14) + + +#define MT9M111_OUTFMT_PROCESSED_BAYER (1 << 14) +#define MT9M111_OUTFMT_BYPASS_IFP (1 << 10) +#define MT9M111_OUTFMT_INV_PIX_CLOCK (1 << 9) +#define MT9M111_OUTFMT_RGB (1 << 8) +#define MT9M111_OUTFMT_RGB565 (0x0 << 6) +#define MT9M111_OUTFMT_RGB555 (0x1 << 6) +#define MT9M111_OUTFMT_RGB444x (0x2 << 6) +#define MT9M111_OUTFMT_RGBx444 (0x3 << 6) +#define MT9M111_OUTFMT_TST_RAMP_OFF (0x0 << 4) +#define MT9M111_OUTFMT_TST_RAMP_COL (0x1 << 4) +#define MT9M111_OUTFMT_TST_RAMP_ROW (0x2 << 4) +#define MT9M111_OUTFMT_TST_RAMP_FRAME (0x3 << 4) +#define MT9M111_OUTFMT_SHIFT_3_UP (1 << 3) +#define MT9M111_OUTFMT_AVG_CHROMA (1 << 2) +#define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 << 1) +#define MT9M111_OUTFMT_SWAP_RGB_EVEN (1 << 1) +#define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr (1 << 0) +/* + * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) + */ + +#define reg_read(reg) mt9m111_reg_read(icd, MT9M111_##reg) +#define reg_write(reg, val) mt9m111_reg_write(icd, MT9M111_##reg, (val)) +#define reg_set(reg, val) mt9m111_reg_set(icd, MT9M111_##reg, (val)) +#define reg_clear(reg, val) mt9m111_reg_clear(icd, MT9M111_##reg, (val)) + +#define MT9M111_MIN_DARK_ROWS 8 +#define MT9M111_MIN_DARK_COLS 24 +#define MT9M111_MAX_HEIGHT 1024 +#define MT9M111_MAX_WIDTH 1280 + +#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ + { .name = _name, .depth = _depth, .fourcc = _fourcc, \ + .colorspace = _colorspace } +#define RGB_FMT(_name, _depth, _fourcc) \ + COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB) + +static const struct soc_camera_data_format mt9m111_colour_formats[] = { + COL_FMT("YCrYCb 8 bit", 8, V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_JPEG), + RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565), + RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555), + RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16), + RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8), +}; + +enum mt9m111_context { + HIGHPOWER = 0, + LOWPOWER, +}; + +struct mt9m111 { + struct i2c_client *client; + struct soc_camera_device icd; + int model; /* V4L2_IDENT_MT9M111* codes from v4l2-chip-ident.h */ + enum mt9m111_context context; + unsigned int left, top, width, height; + u32 pixfmt; + unsigned char autoexposure; + unsigned char datawidth; + unsigned int powered:1; + unsigned int hflip:1; + unsigned int vflip:1; + unsigned int swap_rgb_even_odd:1; + unsigned int swap_rgb_red_blue:1; + unsigned int swap_yuv_y_chromas:1; + unsigned int swap_yuv_cb_cr:1; +}; + +static int reg_page_map_set(struct i2c_client *client, const u16 reg) +{ + int ret; + u16 page; + static int lastpage = -1; /* PageMap cache value */ + + page = (reg >> 8); + if (page == lastpage) + return 0; + if (page > 2) + return -EINVAL; + + ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); + if (ret >= 0) + lastpage = page; + return ret; +} + +static int mt9m111_reg_read(struct soc_camera_device *icd, const u16 reg) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct i2c_client *client = mt9m111->client; + int ret; + + ret = reg_page_map_set(client, reg); + if (!ret) + ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); + + dev_dbg(&icd->dev, "read reg.%03x -> %04x\n", reg, ret); + return ret; +} + +static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, + const u16 data) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct i2c_client *client = mt9m111->client; + int ret; + + ret = reg_page_map_set(client, reg); + if (ret >= 0) + ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), + swab16(data)); + dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); + return ret; +} + +static int mt9m111_reg_set(struct soc_camera_device *icd, const u16 reg, + const u16 data) +{ + int ret; + + ret = mt9m111_reg_read(icd, reg); + if (ret >= 0) + ret = mt9m111_reg_write(icd, reg, ret | data); + return ret; +} + +static int mt9m111_reg_clear(struct soc_camera_device *icd, const u16 reg, + const u16 data) +{ + int ret; + + ret = mt9m111_reg_read(icd, reg); + return mt9m111_reg_write(icd, reg, ret & ~data); +} + +static int mt9m111_set_context(struct soc_camera_device *icd, + enum mt9m111_context ctxt) +{ + int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B + | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B + | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B + | MT9M111_CTXT_CTRL_VBLANK_SEL_B + | MT9M111_CTXT_CTRL_HBLANK_SEL_B; + int valA = MT9M111_CTXT_CTRL_RESTART; + + if (ctxt == HIGHPOWER) + return reg_write(CONTEXT_CONTROL, valB); + else + return reg_write(CONTEXT_CONTROL, valA); +} + +static int mt9m111_setup_rect(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0, is_raw_format; + int width = mt9m111->width; + int height = mt9m111->height; + + if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) + || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) + is_raw_format = 1; + else + is_raw_format = 0; + + if (ret >= 0) + ret = reg_write(COLUMN_START, mt9m111->left); + if (ret >= 0) + ret = reg_write(ROW_START, mt9m111->top); + + if (is_raw_format) { + if (ret >= 0) + ret = reg_write(WINDOW_WIDTH, width); + if (ret >= 0) + ret = reg_write(WINDOW_HEIGHT, height); + } else { + if (ret >= 0) + ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH); + if (ret >= 0) + ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT); + if (ret >= 0) + ret = reg_write(REDUCER_XSIZE_B, width); + if (ret >= 0) + ret = reg_write(REDUCER_YSIZE_B, height); + if (ret >= 0) + ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH); + if (ret >= 0) + ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT); + if (ret >= 0) + ret = reg_write(REDUCER_XSIZE_A, width); + if (ret >= 0) + ret = reg_write(REDUCER_YSIZE_A, height); + } + + return ret; +} + +static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) +{ + int ret; + + ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); + if (ret >= 0) + ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); + return ret; +} + +static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) +{ + return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER); +} + +static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) +{ + + return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); +} + +static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int val = 0; + + if (mt9m111->swap_rgb_red_blue) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_rgb_even_odd) + val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; + val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; + + return mt9m111_setup_pixfmt(icd, val); +} + +static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int val = 0; + + if (mt9m111->swap_rgb_red_blue) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_rgb_even_odd) + val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; + val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; + + return mt9m111_setup_pixfmt(icd, val); +} + +static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int val = 0; + + if (mt9m111->swap_yuv_cb_cr) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_yuv_y_chromas) + val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; + + return mt9m111_setup_pixfmt(icd, val); +} + +static int mt9m111_enable(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); + if (ret >= 0) + mt9m111->powered = 1; + return ret; +} + +static int mt9m111_disable(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); + if (ret >= 0) + mt9m111->powered = 0; + return ret; +} + +static int mt9m111_reset(struct soc_camera_device *icd) +{ + int ret; + + ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); + if (ret >= 0) + ret = reg_set(RESET, MT9M111_RESET_RESET_SOC); + if (ret >= 0) + ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE + | MT9M111_RESET_RESET_SOC); + return ret; +} + +static int mt9m111_start_capture(struct soc_camera_device *icd) +{ + return 0; +} + +static int mt9m111_stop_capture(struct soc_camera_device *icd) +{ + return 0; +} + +static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) +{ + return SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | + SOCAM_DATAWIDTH_8; +} + +static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) +{ + return 0; +} + +static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0; + + switch (pixfmt) { + case V4L2_PIX_FMT_SBGGR8: + ret = mt9m111_setfmt_bayer8(icd); + break; + case V4L2_PIX_FMT_SBGGR16: + ret = mt9m111_setfmt_bayer10(icd); + break; + case V4L2_PIX_FMT_RGB555: + ret = mt9m111_setfmt_rgb555(icd); + break; + case V4L2_PIX_FMT_RGB565: + ret = mt9m111_setfmt_rgb565(icd); + break; + case V4L2_PIX_FMT_YUYV: + ret = mt9m111_setfmt_yuv(icd); + break; + default: + dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt); + ret = -EINVAL; + } + + if (ret >= 0) + mt9m111->pixfmt = pixfmt; + + return ret; +} + +static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0; + + mt9m111->left = rect->left; + mt9m111->top = rect->top; + mt9m111->width = rect->width; + mt9m111->height = rect->height; + + dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", + __func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width, + mt9m111->height); + + ret = mt9m111_setup_rect(icd); + if (ret >= 0) + ret = mt9m111_set_pixfmt(icd, pixfmt); + return ret < 0 ? ret : 0; +} + +static int mt9m111_try_fmt_cap(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + if (f->fmt.pix.height > MT9M111_MAX_HEIGHT) + f->fmt.pix.height = MT9M111_MAX_HEIGHT; + if (f->fmt.pix.width > MT9M111_MAX_WIDTH) + f->fmt.pix.width = MT9M111_MAX_WIDTH; + + return 0; +} + +static int mt9m111_get_chip_id(struct soc_camera_device *icd, + struct v4l2_chip_ident *id) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match_chip != mt9m111->client->addr) + return -ENODEV; + + id->ident = mt9m111->model; + id->revision = 0; + + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int mt9m111_get_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + int val; + + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + return -EINVAL; + if (reg->match_chip != mt9m111->client->addr) + return -ENODEV; + + val = mt9m111_reg_read(icd, reg->reg); + reg->val = (u64)val; + + if (reg->val > 0xffff) + return -EIO; + + return 0; +} + +static int mt9m111_set_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + return -EINVAL; + + if (reg->match_chip != mt9m111->client->addr) + return -ENODEV; + + if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) + return -EIO; + + return 0; +} +#endif + +static const struct v4l2_queryctrl mt9m111_controls[] = { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Verticaly", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Horizontaly", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { /* gain = 1/32*val (=>gain=1 if val==32) */ + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, + .maximum = 63 * 2 * 2, + .step = 1, + .default_value = 32, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_EXPOSURE_AUTO, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Exposure", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + } +}; + +static int mt9m111_video_probe(struct soc_camera_device *); +static void mt9m111_video_remove(struct soc_camera_device *); +static int mt9m111_get_control(struct soc_camera_device *, + struct v4l2_control *); +static int mt9m111_set_control(struct soc_camera_device *, + struct v4l2_control *); +static int mt9m111_resume(struct soc_camera_device *icd); +static int mt9m111_init(struct soc_camera_device *icd); +static int mt9m111_release(struct soc_camera_device *icd); + +static struct soc_camera_ops mt9m111_ops = { + .owner = THIS_MODULE, + .probe = mt9m111_video_probe, + .remove = mt9m111_video_remove, + .init = mt9m111_init, + .resume = mt9m111_resume, + .release = mt9m111_release, + .start_capture = mt9m111_start_capture, + .stop_capture = mt9m111_stop_capture, + .set_fmt_cap = mt9m111_set_fmt_cap, + .try_fmt_cap = mt9m111_try_fmt_cap, + .query_bus_param = mt9m111_query_bus_param, + .set_bus_param = mt9m111_set_bus_param, + .controls = mt9m111_controls, + .num_controls = ARRAY_SIZE(mt9m111_controls), + .get_control = mt9m111_get_control, + .set_control = mt9m111_set_control, + .get_chip_id = mt9m111_get_chip_id, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .get_register = mt9m111_get_register, + .set_register = mt9m111_set_register, +#endif +}; + +static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + if (mt9m111->context == HIGHPOWER) { + if (flip) + ret = reg_set(READ_MODE_B, mask); + else + ret = reg_clear(READ_MODE_B, mask); + } else { + if (flip) + ret = reg_set(READ_MODE_A, mask); + else + ret = reg_clear(READ_MODE_A, mask); + } + + return ret; +} + +static int mt9m111_get_global_gain(struct soc_camera_device *icd) +{ + unsigned int data, gain; + + data = reg_read(GLOBAL_GAIN); + if (data >= 0) + gain = ((data & (1 << 10)) * 2) + | ((data & (1 << 9)) * 2) + | (data & 0x2f); + else + gain = data; + + return gain; +} +static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) +{ + u16 val; + + if (gain > 63 * 2 * 2) + return -EINVAL; + + icd->gain = gain; + if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) + val = (1 << 10) | (1 << 9) | (gain / 4); + else if ((gain >= 64) && (gain < 64 * 2)) + val = (1<<9) | (gain / 2); + else + val = gain; + + return reg_write(GLOBAL_GAIN, val); +} + +static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + if (on) + ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); + else + ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); + + if (ret >= 0) + mt9m111->autoexposure = on; + + return ret; +} +static int mt9m111_get_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int data; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + if (mt9m111->context == HIGHPOWER) + data = reg_read(READ_MODE_B); + else + data = reg_read(READ_MODE_A); + + if (data < 0) + return -EIO; + ctrl->value = !!(data & MT9M111_RMB_MIRROR_ROWS); + break; + case V4L2_CID_HFLIP: + if (mt9m111->context == HIGHPOWER) + data = reg_read(READ_MODE_B); + else + data = reg_read(READ_MODE_A); + + if (data < 0) + return -EIO; + ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); + break; + case V4L2_CID_GAIN: + data = mt9m111_get_global_gain(icd); + if (data < 0) + return data; + ctrl->value = data; + break; + case V4L2_CID_EXPOSURE_AUTO: + ctrl->value = mt9m111->autoexposure; + break; + } + return 0; +} + +static int mt9m111_set_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + const struct v4l2_queryctrl *qctrl; + int ret = 0; + + qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); + + if (!qctrl) + return -EINVAL; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + mt9m111->vflip = ctrl->value; + ret = mt9m111_set_flip(icd, ctrl->value, + MT9M111_RMB_MIRROR_ROWS); + break; + case V4L2_CID_HFLIP: + mt9m111->hflip = ctrl->value; + ret = mt9m111_set_flip(icd, ctrl->value, + MT9M111_RMB_MIRROR_COLS); + break; + case V4L2_CID_GAIN: + ret = mt9m111_set_global_gain(icd, ctrl->value); + break; + case V4L2_CID_EXPOSURE_AUTO: + ret = mt9m111_set_autoexposure(icd, ctrl->value); + break; + default: + ret = -EINVAL; + } + + return ret < 0 ? -EIO : 0; +} + +int mt9m111_restore_state(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + mt9m111_set_context(icd, mt9m111->context); + mt9m111_set_pixfmt(icd, mt9m111->pixfmt); + mt9m111_setup_rect(icd); + mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); + mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); + mt9m111_set_global_gain(icd, icd->gain); + mt9m111_set_autoexposure(icd, mt9m111->autoexposure); + return 0; +} + +static int mt9m111_resume(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0; + + if (mt9m111->powered) { + ret = mt9m111_enable(icd); + if (ret >= 0) + mt9m111_reset(icd); + if (ret >= 0) + mt9m111_restore_state(icd); + } + return ret; +} + +static int mt9m111_init(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + mt9m111->context = HIGHPOWER; + ret = mt9m111_enable(icd); + if (ret >= 0) + mt9m111_reset(icd); + if (ret >= 0) + mt9m111_set_context(icd, mt9m111->context); + if (ret >= 0) + mt9m111_set_autoexposure(icd, mt9m111->autoexposure); + if (ret < 0) + dev_err(&icd->dev, "mt9m111 init failed: %d\n", ret); + return ret ? -EIO : 0; +} + +static int mt9m111_release(struct soc_camera_device *icd) +{ + int ret; + + ret = mt9m111_disable(icd); + if (ret < 0) + dev_err(&icd->dev, "mt9m111 release failed: %d\n", ret); + + return ret ? -EIO : 0; +} + +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ +static int mt9m111_video_probe(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + s32 data; + int ret; + + /* + * We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. + */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + ret = mt9m111_enable(icd); + if (ret) + goto ei2c; + ret = mt9m111_reset(icd); + if (ret) + goto ei2c; + + data = reg_read(CHIP_VERSION); + + switch (data) { + case 0x143a: + mt9m111->model = V4L2_IDENT_MT9M111; + icd->formats = mt9m111_colour_formats; + icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); + break; + default: + ret = -ENODEV; + dev_err(&icd->dev, + "No MT9M111 chip detected, register read %x\n", data); + goto ei2c; + } + + dev_info(&icd->dev, "Detected a MT9M111 chip ID 0x143a\n"); + + ret = soc_camera_video_start(icd); + if (ret) + goto eisis; + + mt9m111->autoexposure = 1; + + mt9m111->swap_rgb_even_odd = 1; + mt9m111->swap_rgb_red_blue = 1; + + return 0; +eisis: +ei2c: + return ret; +} + +static void mt9m111_video_remove(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m111->client->addr, + mt9m111->icd.dev.parent, mt9m111->icd.vdev); + soc_camera_video_stop(&mt9m111->icd); +} + +static int mt9m111_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct mt9m111 *mt9m111; + struct soc_camera_device *icd; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl = client->dev.platform_data; + int ret; + + if (!icl) { + dev_err(&client->dev, "MT9M111 driver needs platform data\n"); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); + return -EIO; + } + + mt9m111 = kzalloc(sizeof(struct mt9m111), GFP_KERNEL); + if (!mt9m111) + return -ENOMEM; + + mt9m111->client = client; + i2c_set_clientdata(client, mt9m111); + + /* Second stage probe - when a capture adapter is there */ + icd = &mt9m111->icd; + icd->ops = &mt9m111_ops; + icd->control = &client->dev; + icd->x_min = MT9M111_MIN_DARK_COLS; + icd->y_min = MT9M111_MIN_DARK_ROWS; + icd->x_current = icd->x_min; + icd->y_current = icd->y_min; + icd->width_min = MT9M111_MIN_DARK_ROWS; + icd->width_max = MT9M111_MAX_WIDTH; + icd->height_min = MT9M111_MIN_DARK_COLS; + icd->height_max = MT9M111_MAX_HEIGHT; + icd->y_skip_top = 0; + icd->iface = icl->bus_id; + + ret = soc_camera_device_register(icd); + if (ret) + goto eisdr; + return 0; + +eisdr: + kfree(mt9m111); + return ret; +} + +static int mt9m111_remove(struct i2c_client *client) +{ + struct mt9m111 *mt9m111 = i2c_get_clientdata(client); + soc_camera_device_unregister(&mt9m111->icd); + kfree(mt9m111); + + return 0; +} + +static const struct i2c_device_id mt9m111_id[] = { + { "mt9m111", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mt9m111_id); + +static struct i2c_driver mt9m111_i2c_driver = { + .driver = { + .name = "mt9m111", + }, + .probe = mt9m111_probe, + .remove = mt9m111_remove, + .id_table = mt9m111_id, +}; + +static int __init mt9m111_mod_init(void) +{ + return i2c_add_driver(&mt9m111_i2c_driver); +} + +static void __exit mt9m111_mod_exit(void) +{ + i2c_del_driver(&mt9m111_i2c_driver); +} + +module_init(mt9m111_mod_init); +module_exit(mt9m111_mod_exit); + +MODULE_DESCRIPTION("Micron MT9M111 Camera driver"); +MODULE_AUTHOR("Robert Jarzmik"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 2068653681ec2030c378a0d1e25d1d451f7cd929 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 14 Aug 2008 17:03:18 +0200 Subject: mt9m001, mt9v022: Simplify return code checking i2c_smbus_write_word_data() returns 0 or a negative error, hence no need to check for "> 0". Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/mt9m001.c | 24 ++++++++++++------------ drivers/media/video/mt9v022.c | 28 ++++++++++++++-------------- 2 files changed, 26 insertions(+), 26 deletions(-) --- linux/drivers/media/video/mt9m001.c | 24 ++++++++++++------------ linux/drivers/media/video/mt9v022.c | 28 ++++++++++++++-------------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c index f4742936c..2c2d0903e 100644 --- a/linux/drivers/media/video/mt9m001.c +++ b/linux/drivers/media/video/mt9m001.c @@ -119,16 +119,16 @@ static int mt9m001_init(struct soc_camera_device *icd) { int ret; - /* Disable chip, synchronous option update */ dev_dbg(icd->vdev->parent, "%s\n", __func__); ret = reg_write(icd, MT9M001_RESET, 1); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_RESET, 0); - if (ret >= 0) + /* Disable chip, synchronous option update */ + if (!ret) ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); - return ret >= 0 ? 0 : -EIO; + return ret; } static int mt9m001_release(struct soc_camera_device *icd) @@ -267,24 +267,24 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, /* Blanking and start values - default... */ ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); /* The caller provides a supported format, as verified per * call to icd->try_fmt_cap() */ - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_ROW_START, rect->top); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, rect->height + icd->y_skip_top - 1); - if (ret >= 0 && mt9m001->autoexposure) { + if (!ret && mt9m001->autoexposure) { ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, rect->height + icd->y_skip_top + vblank); - if (ret >= 0) { + if (!ret) { const struct v4l2_queryctrl *qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); @@ -295,7 +295,7 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, } } - return ret < 0 ? ret : 0; + return ret; } static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c index 1ff36edd7..d9b229579 100644 --- a/linux/drivers/media/video/mt9v022.c +++ b/linux/drivers/media/video/mt9v022.c @@ -141,22 +141,22 @@ static int mt9v022_init(struct soc_camera_device *icd) * plus snapshot mode to disable scan for now */ mt9v022->chip_control |= 0x10; ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); - if (ret >= 0) - reg_write(icd, MT9V022_READ_MODE, 0x300); + if (!ret) + ret = reg_write(icd, MT9V022_READ_MODE, 0x300); /* All defaults */ - if (ret >= 0) + if (!ret) /* AEC, AGC on */ ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); - if (ret >= 0) + if (!ret) /* default - auto */ ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); - return ret >= 0 ? 0 : -EIO; + return ret; } static int mt9v022_release(struct soc_camera_device *icd) @@ -352,21 +352,21 @@ static int mt9v022_set_fmt_cap(struct soc_camera_device *icd, rect->height + icd->y_skip_top + 43); } /* Setup frame format: defaults apart from width and height */ - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_ROW_START, rect->top); - if (ret >= 0) + if (!ret) /* Default 94, Phytec driver says: * "width + horizontal blank >= 660" */ ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, rect->width > 660 - 43 ? 43 : 660 - rect->width); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, rect->height + icd->y_skip_top); @@ -717,7 +717,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) icd->num_formats = 1; } - if (ret >= 0) + if (!ret) ret = soc_camera_video_start(icd); if (ret < 0) goto eisis; -- cgit v1.2.3 From 4da232f764389ccafbe28832bf57aeae316d465f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 14 Aug 2008 17:03:49 +0200 Subject: mt9m111: style cleanup Fix a typo in Kconfig, simplify error checking, further minor cleanup. Signed-off-by: Guennadi Liakhovetski Tested-by: Robert Jarzmik --- drivers/media/video/Kconfig | 2 +- drivers/media/video/mt9m111.c | 86 ++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 45 deletions(-) --- linux/drivers/media/video/Kconfig | 2 +- linux/drivers/media/video/mt9m111.c | 86 ++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 45 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index c6516d42c..f8f7b3b44 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -810,7 +810,7 @@ config MT9M001_PCA9536_SWITCH extender to switch between 8 and 10 bit datawidth modes config SOC_CAMERA_MT9M111 - tristate "mt9m001 support" + tristate "mt9m111 support" depends on SOC_CAMERA && I2C help This driver supports MT9M111 cameras from Micron diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c index 0c88e5d6d..d99932631 100644 --- a/linux/drivers/media/video/mt9m111.c +++ b/linux/drivers/media/video/mt9m111.c @@ -173,7 +173,7 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg) return -EINVAL; ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); - if (ret >= 0) + if (!ret) lastpage = page; return ret; } @@ -200,7 +200,7 @@ static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, int ret; ret = reg_page_map_set(client, reg); - if (ret >= 0) + if (!ret) ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), swab16(data)); dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); @@ -246,7 +246,7 @@ static int mt9m111_set_context(struct soc_camera_device *icd, static int mt9m111_setup_rect(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0, is_raw_format; + int ret, is_raw_format; int width = mt9m111->width; int height = mt9m111->height; @@ -256,32 +256,31 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd) else is_raw_format = 0; - if (ret >= 0) - ret = reg_write(COLUMN_START, mt9m111->left); - if (ret >= 0) + ret = reg_write(COLUMN_START, mt9m111->left); + if (!ret) ret = reg_write(ROW_START, mt9m111->top); if (is_raw_format) { - if (ret >= 0) + if (!ret) ret = reg_write(WINDOW_WIDTH, width); - if (ret >= 0) + if (!ret) ret = reg_write(WINDOW_HEIGHT, height); } else { - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XSIZE_B, width); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YSIZE_B, height); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XSIZE_A, width); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YSIZE_A, height); } @@ -293,7 +292,7 @@ static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) int ret; ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); - if (ret >= 0) + if (!ret) ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); return ret; } @@ -305,7 +304,6 @@ static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) { - return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); } @@ -356,7 +354,7 @@ static int mt9m111_enable(struct soc_camera_device *icd) int ret; ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); - if (ret >= 0) + if (!ret) mt9m111->powered = 1; return ret; } @@ -367,7 +365,7 @@ static int mt9m111_disable(struct soc_camera_device *icd) int ret; ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); - if (ret >= 0) + if (!ret) mt9m111->powered = 0; return ret; } @@ -377,9 +375,9 @@ static int mt9m111_reset(struct soc_camera_device *icd) int ret; ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); - if (ret >= 0) + if (!ret) ret = reg_set(RESET, MT9M111_RESET_RESET_SOC); - if (ret >= 0) + if (!ret) ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE | MT9M111_RESET_RESET_SOC); return ret; @@ -410,7 +408,7 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0; + int ret; switch (pixfmt) { case V4L2_PIX_FMT_SBGGR8: @@ -433,7 +431,7 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) ret = -EINVAL; } - if (ret >= 0) + if (!ret) mt9m111->pixfmt = pixfmt; return ret; @@ -443,7 +441,7 @@ static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, __u32 pixfmt, struct v4l2_rect *rect) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0; + int ret; mt9m111->left = rect->left; mt9m111->top = rect->top; @@ -455,9 +453,9 @@ static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, mt9m111->height); ret = mt9m111_setup_rect(icd); - if (ret >= 0) + if (!ret) ret = mt9m111_set_pixfmt(icd, pixfmt); - return ret < 0 ? ret : 0; + return ret; } static int mt9m111_try_fmt_cap(struct soc_camera_device *icd, @@ -644,7 +642,7 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) val = (1 << 10) | (1 << 9) | (gain / 4); else if ((gain >= 64) && (gain < 64 * 2)) - val = (1<<9) | (gain / 2); + val = (1 << 9) | (gain / 2); else val = gain; @@ -661,7 +659,7 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) else ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); - if (ret >= 0) + if (!ret) mt9m111->autoexposure = on; return ret; @@ -711,7 +709,7 @@ static int mt9m111_set_control(struct soc_camera_device *icd, { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); const struct v4l2_queryctrl *qctrl; - int ret = 0; + int ret; qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); @@ -739,7 +737,7 @@ static int mt9m111_set_control(struct soc_camera_device *icd, ret = -EINVAL; } - return ret < 0 ? -EIO : 0; + return ret; } int mt9m111_restore_state(struct soc_camera_device *icd) @@ -763,10 +761,10 @@ static int mt9m111_resume(struct soc_camera_device *icd) if (mt9m111->powered) { ret = mt9m111_enable(icd); - if (ret >= 0) - mt9m111_reset(icd); - if (ret >= 0) - mt9m111_restore_state(icd); + if (!ret) + ret = mt9m111_reset(icd); + if (!ret) + ret = mt9m111_restore_state(icd); } return ret; } @@ -778,15 +776,15 @@ static int mt9m111_init(struct soc_camera_device *icd) mt9m111->context = HIGHPOWER; ret = mt9m111_enable(icd); - if (ret >= 0) - mt9m111_reset(icd); - if (ret >= 0) - mt9m111_set_context(icd, mt9m111->context); - if (ret >= 0) - mt9m111_set_autoexposure(icd, mt9m111->autoexposure); - if (ret < 0) + if (!ret) + ret = mt9m111_reset(icd); + if (!ret) + ret = mt9m111_set_context(icd, mt9m111->context); + if (!ret) + ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); + if (ret) dev_err(&icd->dev, "mt9m111 init failed: %d\n", ret); - return ret ? -EIO : 0; + return ret; } static int mt9m111_release(struct soc_camera_device *icd) @@ -797,7 +795,7 @@ static int mt9m111_release(struct soc_camera_device *icd) if (ret < 0) dev_err(&icd->dev, "mt9m111 release failed: %d\n", ret); - return ret ? -EIO : 0; + return ret; } /* -- cgit v1.2.3 From 6413c9eb617e2eebe283211c0422e46bbd7289bb Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Thu, 14 Aug 2008 17:04:11 +0200 Subject: soc-camera: Move .power and .reset from soc_camera host to sensor driver Make .power and .reset callbacks per camera instead of per host, also move their invocation to camera drivers. Signed-off-by: Stefan Herbrechtsmeier Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/mt9m001.c | 33 +++++++++++++++++++++++++-- drivers/media/video/mt9m111.c | 15 ++++++++++++ drivers/media/video/mt9v022.c | 24 +++++++++++++++++++- drivers/media/video/pxa_camera.c | 24 -------------------- drivers/media/video/sh_mobile_ceu_camera.c | 5 ---- include/asm-arm/arch-pxa/camera.h | 2 - include/media/sh_mobile_ceu.h | 2 - include/media/soc_camera.h | 3 ++ 8 files changed, 71 insertions(+), 37 deletions(-) --- linux/drivers/media/video/mt9m001.c | 33 +++++++++++++++++++++--- linux/drivers/media/video/mt9m111.c | 15 +++++++++++ linux/drivers/media/video/mt9v022.c | 24 ++++++++++++++++- linux/drivers/media/video/pxa_camera.c | 24 ----------------- linux/drivers/media/video/sh_mobile_ceu_camera.c | 5 ---- linux/include/asm-arm/arch-pxa/camera.h | 2 -- linux/include/media/sh_mobile_ceu.h | 2 -- linux/include/media/soc_camera.h | 3 +++ 8 files changed, 71 insertions(+), 37 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c index 2c2d0903e..228183c54 100644 --- a/linux/drivers/media/video/mt9m001.c +++ b/linux/drivers/media/video/mt9m001.c @@ -117,13 +117,33 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg, static int mt9m001_init(struct soc_camera_device *icd) { + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + struct soc_camera_link *icl = mt9m001->client->dev.platform_data; int ret; dev_dbg(icd->vdev->parent, "%s\n", __func__); - ret = reg_write(icd, MT9M001_RESET, 1); - if (!ret) - ret = reg_write(icd, MT9M001_RESET, 0); + if (icl->power) { + ret = icl->power(&mt9m001->client->dev, 1); + if (ret < 0) { + dev_err(icd->vdev->parent, + "Platform failed to power-on the camera.\n"); + return ret; + } + } + + /* The camera could have been already on, we reset it additionally */ + if (icl->reset) + ret = icl->reset(&mt9m001->client->dev); + else + ret = -ENODEV; + + if (ret < 0) { + /* Either no platform reset, or platform reset failed */ + ret = reg_write(icd, MT9M001_RESET, 1); + if (!ret) + ret = reg_write(icd, MT9M001_RESET, 0); + } /* Disable chip, synchronous option update */ if (!ret) ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); @@ -133,8 +153,15 @@ static int mt9m001_init(struct soc_camera_device *icd) static int mt9m001_release(struct soc_camera_device *icd) { + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + struct soc_camera_link *icl = mt9m001->client->dev.platform_data; + /* Disable the chip */ reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); + + if (icl->power) + icl->power(&mt9m001->client->dev, 0); + return 0; } diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c index d99932631..4844486d7 100644 --- a/linux/drivers/media/video/mt9m111.c +++ b/linux/drivers/media/video/mt9m111.c @@ -351,8 +351,18 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) static int mt9m111_enable(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct soc_camera_link *icl = mt9m111->client->dev.platform_data; int ret; + if (icl->power) { + ret = icl->power(&mt9m111->client->dev, 1); + if (ret < 0) { + dev_err(icd->vdev->parent, + "Platform failed to power-on the camera.\n"); + return ret; + } + } + ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); if (!ret) mt9m111->powered = 1; @@ -362,11 +372,16 @@ static int mt9m111_enable(struct soc_camera_device *icd) static int mt9m111_disable(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct soc_camera_link *icl = mt9m111->client->dev.platform_data; int ret; ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); if (!ret) mt9m111->powered = 0; + + if (icl->power) + icl->power(&mt9m111->client->dev, 0); + return ret; } diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c index d9b229579..0320d006f 100644 --- a/linux/drivers/media/video/mt9v022.c +++ b/linux/drivers/media/video/mt9v022.c @@ -134,8 +134,25 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg, static int mt9v022_init(struct soc_camera_device *icd) { struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + struct soc_camera_link *icl = mt9v022->client->dev.platform_data; int ret; + if (icl->power) { + ret = icl->power(&mt9v022->client->dev, 1); + if (ret < 0) { + dev_err(icd->vdev->parent, + "Platform failed to power-on the camera.\n"); + return ret; + } + } + + /* + * The camera could have been already on, we hard-reset it additionally, + * if available. Soft reset is done in video_probe(). + */ + if (icl->reset) + icl->reset(&mt9v022->client->dev); + /* Almost the default mode: master, parallel, simultaneous, and an * undocumented bit 0x200, which is present in table 7, but not in 8, * plus snapshot mode to disable scan for now */ @@ -161,7 +178,12 @@ static int mt9v022_init(struct soc_camera_device *icd) static int mt9v022_release(struct soc_camera_device *icd) { - /* Nothing? */ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + struct soc_camera_link *icl = mt9v022->client->dev.platform_data; + + if (icl->power) + icl->power(&mt9v022->client->dev, 0); + return 0; } diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index ead87ddaf..6c869fb23 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -629,17 +629,6 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) pdata->init(pcdev->dev); } - if (pdata && pdata->power) { - dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__); - pdata->power(pcdev->dev, 1); - } - - if (pdata && pdata->reset) { - dev_dbg(pcdev->dev, "%s: Releasing camera reset\n", - __func__); - pdata->reset(pcdev->dev, 1); - } - CICR0 = 0x3FF; /* disable all interrupts */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) @@ -660,20 +649,7 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) { - struct pxacamera_platform_data *board = pcdev->pdata; - clk_disable(pcdev->clk); - - if (board && board->reset) { - dev_dbg(pcdev->dev, "%s: Asserting camera reset\n", - __func__); - board->reset(pcdev->dev, 0); - } - - if (board && board->power) { - dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__); - board->power(pcdev->dev, 0); - } } static irqreturn_t pxa_camera_irq(int irq, void *data) diff --git a/linux/drivers/media/video/sh_mobile_ceu_camera.c b/linux/drivers/media/video/sh_mobile_ceu_camera.c index 318754e73..76838091d 100644 --- a/linux/drivers/media/video/sh_mobile_ceu_camera.c +++ b/linux/drivers/media/video/sh_mobile_ceu_camera.c @@ -304,9 +304,6 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) "SuperH Mobile CEU driver attached to camera %d\n", icd->devnum); - if (pcdev->pdata->enable_camera) - pcdev->pdata->enable_camera(); - ret = icd->ops->init(icd); if (ret) goto err; @@ -333,8 +330,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) ceu_write(pcdev, CEIER, 0); ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ icd->ops->release(icd); - if (pcdev->pdata->disable_camera) - pcdev->pdata->disable_camera(); dev_info(&icd->dev, "SuperH Mobile CEU driver detached from camera %d\n", diff --git a/linux/include/asm-arm/arch-pxa/camera.h b/linux/include/asm-arm/arch-pxa/camera.h index 39516ced8..31abe6d51 100644 --- a/linux/include/asm-arm/arch-pxa/camera.h +++ b/linux/include/asm-arm/arch-pxa/camera.h @@ -36,8 +36,6 @@ struct pxacamera_platform_data { int (*init)(struct device *); - int (*power)(struct device *, int); - int (*reset)(struct device *, int); unsigned long flags; unsigned long mclk_10khz; diff --git a/linux/include/media/sh_mobile_ceu.h b/linux/include/media/sh_mobile_ceu.h index 234a4711d..b5dbefea3 100644 --- a/linux/include/media/sh_mobile_ceu.h +++ b/linux/include/media/sh_mobile_ceu.h @@ -5,8 +5,6 @@ struct sh_mobile_ceu_info { unsigned long flags; /* SOCAM_... */ - void (*enable_camera)(void); - void (*disable_camera)(void); }; #endif /* __ASM_SH_MOBILE_CEU_H__ */ diff --git a/linux/include/media/soc_camera.h b/linux/include/media/soc_camera.h index d548de326..c5de7bb19 100644 --- a/linux/include/media/soc_camera.h +++ b/linux/include/media/soc_camera.h @@ -83,6 +83,9 @@ struct soc_camera_link { int bus_id; /* GPIO number to switch between 8 and 10 bit modes */ unsigned int gpio; + /* Optional callbacks to power on or off and reset the sensor */ + int (*power)(struct device *, int); + int (*reset)(struct device *); }; static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) -- cgit v1.2.3 From 9c75e8157d1db6438ae8f801ceebb25e78a48812 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 12:50:23 +0200 Subject: dpc7146: remove dpc7146 demonstration board driver From: Hans Verkuil Old driver for the dpc7146 demonstration board that is no longer relevant. The last time this was tested on actual hardware was probably around 2002. Since this is a driver for a demonstration board the decision was made (after discussing this with the original author, Michael Hunold) to remove it rather than spending a lot of effort continually updating this driver to stay in sync with the latest internal V4L2 or I2C API. Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Michael Hunold --- linux/drivers/media/video/Kconfig | 15 -- linux/drivers/media/video/Makefile | 1 - linux/drivers/media/video/dpc7146.c | 409 ------------------------------------ 3 files changed, 425 deletions(-) delete mode 100644 linux/drivers/media/video/dpc7146.c (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 4c96b690a..61735004e 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -709,21 +709,6 @@ config VIDEO_MXB To compile this driver as a module, choose M here: the module will be called mxb. -config VIDEO_DPC - tristate "Philips-Semiconductors 'dpc7146 demonstration board'" - depends on PCI && VIDEO_V4L1 && I2C - select VIDEO_SAA7146_VV - select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO - ---help--- - This is a video4linux driver for the 'dpc7146 demonstration - board' by Philips-Semiconductors. It's the reference design - for SAA7146 bases boards, so if you have some unsupported - saa7146 based, analog video card, chances are good that it - will work with this skeleton driver. - - To compile this driver as a module, choose M here: the - module will be called dpc7146. - config VIDEO_HEXIUM_ORION tristate "Hexium HV-PCI6 and Orion frame grabber" depends on PCI && VIDEO_V4L2 && I2C diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index bf429b023..3512b715a 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -83,7 +83,6 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ obj-$(CONFIG_VIDEO_MXB) += mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o -obj-$(CONFIG_VIDEO_DPC) += dpc7146.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_VIDEO_TUNER) += tuner.o diff --git a/linux/drivers/media/video/dpc7146.c b/linux/drivers/media/video/dpc7146.c deleted file mode 100644 index 4bfb3076b..000000000 --- a/linux/drivers/media/video/dpc7146.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - dpc7146.c - v4l2 driver for the dpc7146 demonstration board - - Copyright (C) 2000-2003 Michael Hunold - - 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. -*/ - -#define DEBUG_VARIABLE debug - -#include -#include /* for saa7111a */ -#include "compat.h" - -#define I2C_SAA7111A 0x24 - -/* All unused bytes are reserverd. */ -#define SAA711X_CHIP_VERSION 0x00 -#define SAA711X_ANALOG_INPUT_CONTROL_1 0x02 -#define SAA711X_ANALOG_INPUT_CONTROL_2 0x03 -#define SAA711X_ANALOG_INPUT_CONTROL_3 0x04 -#define SAA711X_ANALOG_INPUT_CONTROL_4 0x05 -#define SAA711X_HORIZONTAL_SYNC_START 0x06 -#define SAA711X_HORIZONTAL_SYNC_STOP 0x07 -#define SAA711X_SYNC_CONTROL 0x08 -#define SAA711X_LUMINANCE_CONTROL 0x09 -#define SAA711X_LUMINANCE_BRIGHTNESS 0x0A -#define SAA711X_LUMINANCE_CONTRAST 0x0B -#define SAA711X_CHROMA_SATURATION 0x0C -#define SAA711X_CHROMA_HUE_CONTROL 0x0D -#define SAA711X_CHROMA_CONTROL 0x0E -#define SAA711X_FORMAT_DELAY_CONTROL 0x10 -#define SAA711X_OUTPUT_CONTROL_1 0x11 -#define SAA711X_OUTPUT_CONTROL_2 0x12 -#define SAA711X_OUTPUT_CONTROL_3 0x13 -#define SAA711X_V_GATE_1_START 0x15 -#define SAA711X_V_GATE_1_STOP 0x16 -#define SAA711X_V_GATE_1_MSB 0x17 -#define SAA711X_TEXT_SLICER_STATUS 0x1A -#define SAA711X_DECODED_BYTES_OF_TS_1 0x1B -#define SAA711X_DECODED_BYTES_OF_TS_2 0x1C -#define SAA711X_STATUS_BYTE 0x1F - -#define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) - -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "debug verbosity"); - -static int dpc_num; - -#define DPC_INPUTS 2 -static struct v4l2_input dpc_inputs[DPC_INPUTS] = { - { 0, "Port A", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, - { 1, "Port B", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, -}; - -#define DPC_AUDIOS 0 - -static struct saa7146_extension_ioctls ioctls[] = { - { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_S_STD, SAA7146_AFTER }, - { 0, 0 } -}; - -struct dpc -{ - struct video_device *video_dev; - struct video_device *vbi_dev; - - struct i2c_adapter i2c_adapter; - struct i2c_client *saa7111a; - - int cur_input; /* current input */ -}; - -static int dpc_check_clients(struct device *dev, void *data) -{ - struct dpc* dpc = data; - struct i2c_client *client = i2c_verify_client(dev); - - if( !client ) - return 0; - - if( I2C_SAA7111A == client->addr ) - dpc->saa7111a = client; - - return 0; -} - -/* fixme: add vbi stuff here */ -static int dpc_probe(struct saa7146_dev* dev) -{ - struct dpc* dpc = NULL; - - dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL); - if( NULL == dpc ) { - printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n"); - return -ENOMEM; - } - - /* FIXME: enable i2c-port pins, video-port-pins - video port pins should be enabled here ?! */ - saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); - - dpc->i2c_adapter = (struct i2c_adapter) { - .class = I2C_CLASS_TV_ANALOG, - .name = "dpc7146", - }; - saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); - if(i2c_add_adapter(&dpc->i2c_adapter) < 0) { - DEB_S(("cannot register i2c-device. skipping.\n")); - kfree(dpc); - return -EFAULT; - } - - /* loop through all i2c-devices on the bus and look who is there */ - device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients); - - /* check if all devices are present */ - if (!dpc->saa7111a) { - DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); - i2c_del_adapter(&dpc->i2c_adapter); - kfree(dpc); - return -ENODEV; - } - - /* all devices are present, probe was successful */ - DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); - - /* we store the pointer in our private data field */ - dev->ext_priv = dpc; - - return 0; -} - -/* bring hardware to a sane state. this has to be done, just in case someone - wants to capture from this device before it has been properly initialized. - the capture engine would badly fail, because no valid signal arrives on the - saa7146, thus leading to timeouts and stuff. */ -static int dpc_init_done(struct saa7146_dev* dev) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - DEB_D(("dpc_v4l2.o: dpc_init_done called.\n")); - - /* initialize the helper ics to useful values */ - i2c_smbus_write_byte_data(dpc->saa7111a, 0x00, 0x11); - - i2c_smbus_write_byte_data(dpc->saa7111a, 0x02, 0xc0); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x03, 0x30); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x04, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x05, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x06, 0xde); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x07, 0xad); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x08, 0xa8); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x09, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0a, 0x80); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0b, 0x47); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0c, 0x40); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0d, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0e, 0x03); - - i2c_smbus_write_byte_data(dpc->saa7111a, 0x10, 0xd0); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x11, 0x1c); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x12, 0xc1); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x13, 0x30); - - i2c_smbus_write_byte_data(dpc->saa7111a, 0x1f, 0x81); - - return 0; -} - -static struct saa7146_ext_vv vv_data; - -/* this function only gets called when the probing was successful */ -static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - DEB_D(("dpc_v4l2.o: dpc_attach called.\n")); - - /* checking for i2c-devices can be omitted here, because we - already did this in "dpc_vl42_probe" */ - - saa7146_vv_init(dev,&vv_data); - if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) { - ERR(("cannot register capture v4l2 device. skipping.\n")); - return -1; - } - - /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ - if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { - if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) { - ERR(("cannot register vbi v4l2 device. skipping.\n")); - } - } - - i2c_use_client(dpc->saa7111a); - - printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num); - dpc_num++; - - /* the rest */ - dpc->cur_input = 0; - dpc_init_done(dev); - - return 0; -} - -static int dpc_detach(struct saa7146_dev* dev) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - DEB_EE(("dev:%p\n",dev)); - - i2c_release_client(dpc->saa7111a); - - saa7146_unregister_device(&dpc->video_dev,dev); - if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { - saa7146_unregister_device(&dpc->vbi_dev,dev); - } - saa7146_vv_release(dev); - - dpc_num--; - - i2c_del_adapter(&dpc->i2c_adapter); - kfree(dpc); - return 0; -} - -#ifdef axa -int dpc_vbi_bypass(struct saa7146_dev* dev) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - int i = 1; - - /* switch bypass in saa7111a */ - if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) { - printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n"); - return -1; - } - - return 0; -} -#endif - -static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) -{ - struct saa7146_dev *dev = fh->dev; - struct dpc* dpc = (struct dpc*)dev->ext_priv; -/* - struct saa7146_vv *vv = dev->vv_data; -*/ - switch(cmd) - { - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); - - if( i->index < 0 || i->index >= DPC_INPUTS) { - return -EINVAL; - } - - memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input)); - - DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index)); - return 0; - } - case VIDIOC_G_INPUT: - { - int *input = (int *)arg; - *input = dpc->cur_input; - - DEB_D(("dpc_v4l2.o: VIDIOC_G_INPUT: %d\n",*input)); - return 0; - } - case VIDIOC_S_INPUT: - { - int input = *(int *)arg; - - if (input < 0 || input >= DPC_INPUTS) { - return -EINVAL; - } - - dpc->cur_input = input; - - /* fixme: switch input here, switch audio, too! */ -// saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); - printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n"); - - return 0; - } - default: -/* - DEB_D(("dpc_v4l2.o: v4l2_ioctl does not handle this ioctl.\n")); -*/ - return -ENOIOCTLCMD; - } - return 0; -} - -static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) -{ - return 0; -} - -static struct saa7146_standard standard[] = { - { - .name = "PAL", .id = V4L2_STD_PAL, - .v_offset = 0x17, .v_field = 288, - .h_offset = 0x14, .h_pixels = 680, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x16, .v_field = 240, - .h_offset = 0x06, .h_pixels = 708, - .v_max_out = 480, .h_max_out = 640, - }, { - .name = "SECAM", .id = V4L2_STD_SECAM, - .v_offset = 0x14, .v_field = 288, - .h_offset = 0x14, .h_pixels = 720, - .v_max_out = 576, .h_max_out = 768, - } -}; - -static struct saa7146_extension extension; - -static struct saa7146_pci_extension_data dpc = { - .ext_priv = "Multimedia eXtension Board", - .ext = &extension, -}; - -static struct pci_device_id pci_tbl[] = { - { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, - .subvendor = 0x0000, - .subdevice = 0x0000, - .driver_data = (unsigned long)&dpc, - }, { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_ext_vv vv_data = { - .inputs = DPC_INPUTS, - .capabilities = V4L2_CAP_VBI_CAPTURE, - .stds = &standard[0], - .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), - .std_callback = &std_callback, - .ioctls = &ioctls[0], - .ioctl = dpc_ioctl, -}; - -static struct saa7146_extension extension = { - .name = "dpc7146 demonstration board", - .flags = SAA7146_USE_I2C_IRQ, - - .pci_tbl = &pci_tbl[0], - .module = THIS_MODULE, - - .probe = dpc_probe, - .attach = dpc_attach, - .detach = dpc_detach, - - .irq_mask = 0, - .irq_func = NULL, -}; - -static int __init dpc_init_module(void) -{ - if( 0 != saa7146_register_extension(&extension)) { - DEB_S(("failed to register extension.\n")); - return -ENODEV; - } - - return 0; -} - -static void __exit dpc_cleanup_module(void) -{ - saa7146_unregister_extension(&extension); -} - -module_init(dpc_init_module); -module_exit(dpc_cleanup_module); - -MODULE_DESCRIPTION("video4linux-2 driver for the 'dpc7146 demonstration board'"); -MODULE_AUTHOR("Michael Hunold "); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 59bb2ab87f97424a41cf69511ff79ae8a5ea08b9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 12:56:12 +0200 Subject: tuner-3036: remove driver From: Hans Verkuil This driver is for VERY old i2c-over-parallel port teletext receiver boxes. Rather then spending effort on converting this driver to V4L2, and since it is extremely unlikely that anyone still uses one of these devices, it was decided to drop it (after discussing this as well with the original author, Phil Blundell). Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Phil Blundell --- linux/drivers/media/video/Kconfig | 7 -- linux/drivers/media/video/Makefile | 1 - linux/drivers/media/video/tuner-3036.c | 215 --------------------------------- 3 files changed, 223 deletions(-) delete mode 100644 linux/drivers/media/video/tuner-3036.c (limited to 'linux') diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 61735004e..c315885a6 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -579,13 +579,6 @@ config VIDEO_SAA5249 To compile this driver as a module, choose M here: the module will be called saa5249. -config TUNER_3036 - tristate "SAB3036 tuner" - depends on I2C && VIDEO_V4L1 - help - Say Y here to include support for Philips SAB3036 compatible tuners. - If in doubt, say N. - config VIDEO_VINO tristate "SGI Vino Video For Linux (EXPERIMENTAL)" depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 3512b715a..22d98ee61 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -83,7 +83,6 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ obj-$(CONFIG_VIDEO_MXB) += mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o -obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_VIDEO_TUNER) += tuner.o diff --git a/linux/drivers/media/video/tuner-3036.c b/linux/drivers/media/video/tuner-3036.c deleted file mode 100644 index 8b87d75f4..000000000 --- a/linux/drivers/media/video/tuner-3036.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Driver for Philips SAB3036 "CITAC" tuner control chip. - * - * Author: Phil Blundell - * - * The SAB3036 is just about different enough from the chips that - * tuner.c copes with to make it not worth the effort to crowbar - * the support into that file. So instead we have a separate driver. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "compat.h" -#include -#include - -#include - -static int debug; /* insmod parameter */ -static int this_adap; - -static struct i2c_client client_template; - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x60, 0x61, I2C_CLIENT_END }; -static unsigned short ignore = I2C_CLIENT_END; - -static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_i2c, - .probe = &ignore, - .ignore = &ignore, -}; - -/* ---------------------------------------------------------------------- */ - -static unsigned char -tuner_getstatus (struct i2c_client *c) -{ - unsigned char byte; - if (i2c_master_recv(c, &byte, 1) != 1) - printk(KERN_ERR "tuner-3036: I/O error.\n"); - return byte; -} - -#define TUNER_FL 0x80 - -static int -tuner_islocked (struct i2c_client *c) -{ - return (tuner_getstatus(c) & TUNER_FL); -} - -/* ---------------------------------------------------------------------- */ - -static void -set_tv_freq(struct i2c_client *c, int freq) -{ - u16 div = ((freq * 20) / 16); - unsigned long give_up = jiffies + HZ; - unsigned char buffer[2]; - - if (debug) - printk(KERN_DEBUG "tuner: setting frequency %dMHz, divisor %x\n", freq / 16, div); - - /* Select high tuning current */ - buffer[0] = 0x29; - buffer[1] = 0x3e; - - if (i2c_master_send(c, buffer, 2) != 2) - printk("tuner: i2c i/o error 1\n"); - - buffer[0] = 0x80 | ((div>>8) & 0x7f); - buffer[1] = div & 0xff; - - if (i2c_master_send(c, buffer, 2) != 2) - printk("tuner: i2c i/o error 2\n"); - - while (!tuner_islocked(c) && time_before(jiffies, give_up)) - schedule(); - - if (!tuner_islocked(c)) - printk(KERN_WARNING "tuner: failed to achieve PLL lock\n"); - - /* Select low tuning current and engage AFC */ - buffer[0] = 0x29; - buffer[1] = 0xb2; - - if (i2c_master_send(c, buffer, 2) != 2) - printk("tuner: i2c i/o error 3\n"); - - if (debug) - printk(KERN_DEBUG "tuner: status %02x\n", tuner_getstatus(c)); -} - -/* ---------------------------------------------------------------------- */ - -static int -tuner_attach(struct i2c_adapter *adap, int addr, int kind) -{ - static unsigned char buffer[] = { 0x29, 0x32, 0x2a, 0, 0x2b, 0 }; - - struct i2c_client *client; - - if (this_adap > 0) - return -1; - this_adap++; - - client_template.adapter = adap; - client_template.addr = addr; - - client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - memcpy(client, &client_template, sizeof(struct i2c_client)); - - printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client)); - - i2c_attach_client(client); - - if (i2c_master_send(client, buffer, 2) != 2) - printk("tuner: i2c i/o error 1\n"); - if (i2c_master_send(client, buffer+2, 2) != 2) - printk("tuner: i2c i/o error 2\n"); - if (i2c_master_send(client, buffer+4, 2) != 2) - printk("tuner: i2c i/o error 3\n"); - return 0; -} - -static int -tuner_detach(struct i2c_client *c) -{ - return 0; -} - -static int -tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - int *iarg = (int*)arg; - - switch (cmd) - { - case VIDIOCSFREQ: - set_tv_freq(client, *iarg); - break; - - default: - return -EINVAL; - } - return 0; -} - -static int -tuner_probe(struct i2c_adapter *adap) -{ - this_adap = 0; - if (adap->id == I2C_HW_B_LP) - return i2c_probe(adap, &addr_data, tuner_attach); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static struct i2c_driver -i2c_driver_tuner = -{ - .driver = { - .name = "sab3036", - }, - .id = I2C_DRIVERID_SAB3036, - .attach_adapter = tuner_probe, - .detach_client = tuner_detach, - .command = tuner_command -}; - -static struct i2c_client client_template = -{ - .driver = &i2c_driver_tuner, - .name = "SAB3036", -}; - -static int __init -tuner3036_init(void) -{ - return i2c_add_driver(&i2c_driver_tuner); -} - -static void __exit -tuner3036_exit(void) -{ - i2c_del_driver(&i2c_driver_tuner); -} - -MODULE_DESCRIPTION("SAB3036 tuner driver"); -MODULE_AUTHOR("Philip Blundell "); -MODULE_LICENSE("GPL"); - -module_param(debug, int, 0); -MODULE_PARM_DESC(debug,"Enable debugging output"); - -module_init(tuner3036_init); -module_exit(tuner3036_exit); -- cgit v1.2.3 From 4a0132136258611e6d3bc1dbe7411503faa638ad Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 13:33:14 +0200 Subject: i2c-id: remove obsolete SAB3036 driver ID From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/include/linux/i2c-id.h | 1 - 1 file changed, 1 deletion(-) (limited to 'linux') diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h index 4862398e0..bc35aec9d 100644 --- a/linux/include/linux/i2c-id.h +++ b/linux/include/linux/i2c-id.h @@ -42,7 +42,6 @@ #define I2C_DRIVERID_MGATVO 23 /* Matrox TVOut */ #define I2C_DRIVERID_SAA5249 24 /* SAA5249 and compatibles */ #define I2C_DRIVERID_PCF8583 25 /* real time clock */ -#define I2C_DRIVERID_SAB3036 26 /* SAB3036 tuner */ #define I2C_DRIVERID_TDA7432 27 /* Stereo sound processor */ #define I2C_DRIVERID_TVMIXER 28 /* Mixer driver for tv cards */ #define I2C_DRIVERID_TVAUDIO 29 /* Generic TV sound driver */ -- cgit v1.2.3 From 58df9dfb0cd0e6afde3ae7a49f84d4f216bc3cbf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 15:55:33 +0200 Subject: aci: remove obsolete sources From: Hans Verkuil The aci.c and aci.h files were copied from the kernel for a Miro radio card. That driver has been removed, so these supported sources can also be removed. In addition some remaining traces of the Miro driver were also deleted. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/radio/Kconfig | 32 -- linux/sound/oss/aci.c | 713 -------------------------------------- linux/sound/oss/aci.h | 57 --- 3 files changed, 802 deletions(-) delete mode 100644 linux/sound/oss/aci.c delete mode 100644 linux/sound/oss/aci.h (limited to 'linux') diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig index 01ee71e82..1b41b3f77 100644 --- a/linux/drivers/media/radio/Kconfig +++ b/linux/drivers/media/radio/Kconfig @@ -195,38 +195,6 @@ config RADIO_MAESTRO To compile this driver as a module, choose M here: the module will be called radio-maestro. -config RADIO_MIROPCM20 - tristate "miroSOUND PCM20 radio" - depends on ISA && VIDEO_V4L1 && SOUND_ACI_MIXER - ---help--- - Choose Y here if you have this FM radio card. You also need to say Y - to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound") - for this to work. - - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - . - - To compile this driver as a module, choose M here: the - module will be called miropcm20. - -config RADIO_MIROPCM20_RDS - tristate "miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)" - depends on RADIO_MIROPCM20 && EXPERIMENTAL - ---help--- - Choose Y here if you want to see RDS/RBDS information like - RadioText, Programme Service name, Clock Time and date, Programme - Type and Traffic Announcement/Programme identification. - - It's not possible to read the raw RDS packets from the device, so - the driver cant provide an V4L interface for this. But the - availability of RDS is reported over V4L by the basic driver - already. Here RDS can be read from files in /dev/v4l/rds. - - To compile this driver as a module, choose M here: the - module will be called miropcm20-rds. - config RADIO_SF16FMI tristate "SF16FMI Radio" depends on ISA && VIDEO_V4L2 diff --git a/linux/sound/oss/aci.c b/linux/sound/oss/aci.c deleted file mode 100644 index 4c407b77f..000000000 --- a/linux/sound/oss/aci.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Audio Command Interface (ACI) driver (sound/aci.c) - * - * ACI is a protocol used to communicate with the microcontroller on - * some sound cards produced by miro, e.g. the miroSOUND PCM12 and - * PCM20. The ACI has been developed for miro by Norberto Pellicci - * . Special thanks to both him and miro for - * providing the ACI specification. - * - * The main function of the ACI is to control the mixer and to get a - * product identification. On the PCM20, ACI also controls the radio - * tuner on this card, this is supported in the Video for Linux - * miropcm20 driver. - * - - * This is a fullfeatured implementation. Unsupported features - * are bugs... (: - * - * It is not longer necessary to load the mad16 module first. The - * user is currently responsible to set the mad16 mixer correctly. - * - * To toggle the solo mode for full duplex operation just use the OSS - * record switch for the pcm ('wave') controller. Robert - * - - * - * Revision history: - * - * 1995-11-10 Markus Kuhn - * First version written. - * 1995-12-31 Markus Kuhn - * Second revision, general code cleanup. - * 1996-05-16 Hannu Savolainen - * Integrated with other parts of the driver. - * 1996-05-28 Markus Kuhn - * Initialize CS4231A mixer, make ACI first mixer, - * use new private mixer API for solo mode. - * 1998-08-18 Ruurd Reitsma - * Small modification to export ACI functions and - * complete modularisation. - * 2000-06-20 Robert Siemer - * Don't initialize the CS4231A mixer anymore, so the code is - * working again, and other small changes to fit in todays - * kernels. - * 2000-08-26 Robert Siemer - * Clean up and rewrite for 2.4.x. Maybe it's SMP safe now... (: - * ioctl bugfix, and integration of solo-mode into OSS-API, - * added (OSS-limited) equalizer support, return value bugfix, - * changed param aci_reset to reset, new params: ide, wss. - * 2001-04-20 Robert Siemer - * even more cleanups... - * 2001-10-08 Arnaldo Carvalho de Melo - * Get rid of check_region, .bss optimizations, use set_current_state - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include "sound_config.h" -#include "compat.h" - -int aci_port; /* as determined by bit 4 in the OPTi 929 MC4 register */ -static int aci_idcode[2]; /* manufacturer and product ID */ -int aci_version; /* ACI firmware version */ - -EXPORT_SYMBOL(aci_port); -EXPORT_SYMBOL(aci_version); - -#include "aci.h" - - -static int aci_solo; /* status bit of the card that can't be * - * checked with ACI versions prior to 0xb0 */ -static int aci_amp; /* status bit for power-amp/line-out level - but I have no docs about what is what... */ -static int aci_micpreamp=3; /* microphone preamp-level that can't be * - * checked with ACI versions prior to 0xb0 */ - -static int mixer_device; -static struct mutex aci_mutex; - -#ifdef MODULE -static int reset; -module_param(reset, bool, 0); -MODULE_PARM_DESC(reset,"When set to 1, reset aci mixer."); -#else -static int reset = 1; -#endif - -static int ide=-1; -module_param(ide, int, 0); -MODULE_PARM_DESC(ide,"1 enable, 0 disable ide-port - untested" - " default: do nothing"); -static int wss=-1; -module_param(wss, int, 0); -MODULE_PARM_DESC(wss,"change between ACI/WSS-mixer; use 0 and 1 - untested" - " default: do nothing; for PCM1-pro only"); - -#ifdef DEBUG -static void print_bits(unsigned char c) -{ - int j; - printk(KERN_DEBUG "aci: "); - - for (j=7; j>=0; j--) { - printk("%d", (c >> j) & 0x1); - } - - printk("\n"); -} -#endif - -/* - * This busy wait code normally requires less than 15 loops and - * practically always less than 100 loops on my i486/DX2 66 MHz. - * - * Warning: Waiting on the general status flag after reseting the MUTE - * function can take a VERY long time, because the PCM12 does some kind - * of fade-in effect. For this reason, access to the MUTE function has - * not been implemented at all. - * - * - The OSS interface has no mute option. It takes about 3 seconds to - * fade-in on my PCM20. busy_wait() handles it great now... Robert - */ - -static int busy_wait(void) -{ - #define MINTIME 500 - long timeout; - unsigned char byte; - - for (timeout = 1; timeout <= MINTIME+30; timeout++) { - if (((byte=inb(BUSY_REGISTER)) & 1) == 0) { - if (timeout >= MINTIME) - printk(KERN_DEBUG "aci: Got READYFLAG in round %ld.\n", timeout-MINTIME); - return byte; - } - if (timeout >= MINTIME) { - long out=10*HZ; - switch (timeout-MINTIME) { - case 0 ... 9: - out /= 10; - case 10 ... 19: - out /= 10; - case 20 ... 30: - out /= 10; - default: - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(out); - break; - } - } - } - printk(KERN_WARNING "aci: busy_wait() time out.\n"); - return -EBUSY; -} - -/* The four ACI command types are fucked up. [-: - * implied is: 1w - special case for INIT - * write is: 2w1r - * read is: x(1w1r) where x is 1 or 2 (1 CHECK_SIG, 1 CHECK_STER, - * 1 VERSION, 2 IDCODE) - * the command is only in the first write, rest is protocol overhead - * - * indexed is technically a write and used for STATUS - * and the special case for TUNE is: 3w1r - * - * Here the new general sheme: TUNE --> aci_rw_cmd(x, y, z) - * indexed and write --> aci_rw_cmd(x, y, -1) - * implied and read (x=1) --> aci_rw_cmd(x, -1, -1) - * - * Read (x>=2) is not implemented (only used during initialization). - * Use aci_idcode[2] and aci_version... Robert - */ - -/* Some notes for error detection: theoretically it is possible. - * But it doubles the I/O-traffic from ww(r) to wwwrw(r) in the normal - * case and doesn't seem to be designed for that... Robert - */ - -static inline int aci_rawwrite(unsigned char byte) -{ - if (busy_wait() >= 0) { -#ifdef DEBUG - printk(KERN_DEBUG "aci_rawwrite(%d)\n", byte); -#endif - outb(byte, COMMAND_REGISTER); - return 0; - } else - return -EBUSY; -} - -static inline int aci_rawread(void) -{ - unsigned char byte; - - if (busy_wait() >= 0) { - byte=inb(STATUS_REGISTER); -#ifdef DEBUG - printk(KERN_DEBUG "%d = aci_rawread()\n", byte); -#endif - return byte; - } else - return -EBUSY; -} - - -int aci_rw_cmd(int write1, int write2, int write3) -{ - int write[] = {write1, write2, write3}; - int read = -EINTR, i; - - if (mutex_lock_interruptible(&aci_mutex)) - goto out; - - for (i=0; i<3; i++) { - if (write[i]< 0 || write[i] > 255) - break; - else { - read = aci_rawwrite(write[i]); - if (read < 0) - goto out_up; - } - - } - - read = aci_rawread(); -out_up: mutex_unlock(&aci_mutex); -out: return read; -} - -EXPORT_SYMBOL(aci_rw_cmd); - -static int setvolume(int __user *arg, - unsigned char left_index, unsigned char right_index) -{ - int vol, ret, uservol, buf; - - __get_user(uservol, arg); - - /* left channel */ - vol = uservol & 0xff; - if (vol > 100) - vol = 100; - vol = SCALE(100, 0x20, vol); - if ((buf=aci_write_cmd(left_index, 0x20 - vol))<0) - return buf; - ret = SCALE(0x20, 100, vol); - - - /* right channel */ - vol = (uservol >> 8) & 0xff; - if (vol > 100) - vol = 100; - vol = SCALE(100, 0x20, vol); - if ((buf=aci_write_cmd(right_index, 0x20 - vol))<0) - return buf; - ret |= SCALE(0x20, 100, vol) << 8; - - __put_user(ret, arg); - - return 0; -} - -static int getvolume(int __user *arg, - unsigned char left_index, unsigned char right_index) -{ - int vol; - int buf; - - /* left channel */ - if ((buf=aci_indexed_cmd(ACI_STATUS, left_index))<0) - return buf; - vol = SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0); - - /* right channel */ - if ((buf=aci_indexed_cmd(ACI_STATUS, right_index))<0) - return buf; - vol |= SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0) << 8; - - __put_user(vol, arg); - - return 0; -} - - -/* The equalizer is somewhat strange on the ACI. From -12dB to +12dB - * write: 0xff..down.to..0x80==0x00..up.to..0x7f - */ - -static inline unsigned int eq_oss2aci(unsigned int vol) -{ - int boost=0; - unsigned int ret; - - if (vol > 100) - vol = 100; - if (vol > 50) { - vol -= 51; - boost=1; - } - if (boost) - ret=SCALE(49, 0x7e, vol)+1; - else - ret=0xff - SCALE(50, 0x7f, vol); - return ret; -} - -static inline unsigned int eq_aci2oss(unsigned int vol) -{ - if (vol < 0x80) - return SCALE(0x7f, 50, vol) + 50; - else - return SCALE(0x7f, 50, 0xff-vol); -} - - -static int setequalizer(int __user *arg, - unsigned char left_index, unsigned char right_index) -{ - int buf; - unsigned int vol; - - __get_user(vol, arg); - - /* left channel */ - if ((buf=aci_write_cmd(left_index, eq_oss2aci(vol & 0xff)))<0) - return buf; - - /* right channel */ - if ((buf=aci_write_cmd(right_index, eq_oss2aci((vol>>8) & 0xff)))<0) - return buf; - - /* the ACI equalizer is more precise */ - return 0; -} - -static int getequalizer(int __user *arg, - unsigned char left_index, unsigned char right_index) -{ - int buf; - unsigned int vol; - - /* left channel */ - if ((buf=aci_indexed_cmd(ACI_STATUS, left_index))<0) - return buf; - vol = eq_aci2oss(buf); - - /* right channel */ - if ((buf=aci_indexed_cmd(ACI_STATUS, right_index))<0) - return buf; - vol |= eq_aci2oss(buf) << 8; - - __put_user(vol, arg); - - return 0; -} - -static int aci_mixer_ioctl (int dev, unsigned int cmd, void __user * arg) -{ - int vol, buf; - int __user *p = arg; - - switch (cmd) { - case SOUND_MIXER_WRITE_VOLUME: - return setvolume(p, 0x01, 0x00); - case SOUND_MIXER_WRITE_CD: - return setvolume(p, 0x3c, 0x34); - case SOUND_MIXER_WRITE_MIC: - return setvolume(p, 0x38, 0x30); - case SOUND_MIXER_WRITE_LINE: - return setvolume(p, 0x39, 0x31); - case SOUND_MIXER_WRITE_SYNTH: - return setvolume(p, 0x3b, 0x33); - case SOUND_MIXER_WRITE_PCM: - return setvolume(p, 0x3a, 0x32); - case MIXER_WRITE(SOUND_MIXER_RADIO): /* fall through */ - case SOUND_MIXER_WRITE_LINE1: /* AUX1 or radio */ - return setvolume(p, 0x3d, 0x35); - case SOUND_MIXER_WRITE_LINE2: /* AUX2 */ - return setvolume(p, 0x3e, 0x36); - case SOUND_MIXER_WRITE_BASS: /* set band one and two */ - if (aci_idcode[1]=='C') { - if ((buf=setequalizer(p, 0x48, 0x40)) || - (buf=setequalizer(p, 0x49, 0x41))); - return buf; - } - break; - case SOUND_MIXER_WRITE_TREBLE: /* set band six and seven */ - if (aci_idcode[1]=='C') { - if ((buf=setequalizer(p, 0x4d, 0x45)) || - (buf=setequalizer(p, 0x4e, 0x46))); - return buf; - } - break; - case SOUND_MIXER_WRITE_IGAIN: /* MIC pre-amp */ - if (aci_idcode[1]=='B' || aci_idcode[1]=='C') { - __get_user(vol, p); - vol = vol & 0xff; - if (vol > 100) - vol = 100; - vol = SCALE(100, 3, vol); - if ((buf=aci_write_cmd(ACI_WRITE_IGAIN, vol))<0) - return buf; - aci_micpreamp = vol; - vol = SCALE(3, 100, vol); - vol |= (vol << 8); - __put_user(vol, p); - return 0; - } - break; - case SOUND_MIXER_WRITE_OGAIN: /* Power-amp/line-out level */ - if (aci_idcode[1]=='A' || aci_idcode[1]=='B') { - __get_user(buf, p); - buf = buf & 0xff; - if (buf > 50) - vol = 1; - else - vol = 0; - if ((buf=aci_write_cmd(ACI_SET_POWERAMP, vol))<0) - return buf; - aci_amp = vol; - if (aci_amp) - buf = (100 || 100<<8); - else - buf = 0; - __put_user(buf, p); - return 0; - } - break; - case SOUND_MIXER_WRITE_RECSRC: - /* handle solo mode control */ - __get_user(buf, p); - /* unset solo when RECSRC for PCM is requested */ - if (aci_idcode[1]=='B' || aci_idcode[1]=='C') { - vol = !(buf & SOUND_MASK_PCM); - if ((buf=aci_write_cmd(ACI_SET_SOLOMODE, vol))<0) - return buf; - aci_solo = vol; - } - buf = (SOUND_MASK_CD| SOUND_MASK_MIC| SOUND_MASK_LINE| - SOUND_MASK_SYNTH| SOUND_MASK_LINE2); - if (aci_idcode[1] == 'C') /* PCM20 radio */ - buf |= SOUND_MASK_RADIO; - else - buf |= SOUND_MASK_LINE1; - if (!aci_solo) - buf |= SOUND_MASK_PCM; - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_DEVMASK: - buf = (SOUND_MASK_VOLUME | SOUND_MASK_CD | - SOUND_MASK_MIC | SOUND_MASK_LINE | - SOUND_MASK_SYNTH | SOUND_MASK_PCM | - SOUND_MASK_LINE2); - switch (aci_idcode[1]) { - case 'C': /* PCM20 radio */ - buf |= (SOUND_MASK_RADIO | SOUND_MASK_IGAIN | - SOUND_MASK_BASS | SOUND_MASK_TREBLE); - break; - case 'B': /* PCM12 */ - buf |= (SOUND_MASK_LINE1 | SOUND_MASK_IGAIN | - SOUND_MASK_OGAIN); - break; - case 'A': /* PCM1-pro */ - buf |= (SOUND_MASK_LINE1 | SOUND_MASK_OGAIN); - break; - default: - buf |= SOUND_MASK_LINE1; - } - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_STEREODEVS: - buf = (SOUND_MASK_VOLUME | SOUND_MASK_CD | - SOUND_MASK_MIC | SOUND_MASK_LINE | - SOUND_MASK_SYNTH | SOUND_MASK_PCM | - SOUND_MASK_LINE2); - switch (aci_idcode[1]) { - case 'C': /* PCM20 radio */ - buf |= (SOUND_MASK_RADIO | - SOUND_MASK_BASS | SOUND_MASK_TREBLE); - break; - default: - buf |= SOUND_MASK_LINE1; - } - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_RECMASK: - buf = (SOUND_MASK_CD| SOUND_MASK_MIC| SOUND_MASK_LINE| - SOUND_MASK_SYNTH| SOUND_MASK_LINE2| SOUND_MASK_PCM); - if (aci_idcode[1] == 'C') /* PCM20 radio */ - buf |= SOUND_MASK_RADIO; - else - buf |= SOUND_MASK_LINE1; - - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_RECSRC: - buf = (SOUND_MASK_CD | SOUND_MASK_MIC | SOUND_MASK_LINE | - SOUND_MASK_SYNTH | SOUND_MASK_LINE2); - /* do we need aci_solo or can I get it from the ACI? */ - switch (aci_idcode[1]) { - case 'B': /* PCM12 */ - case 'C': /* PCM20 radio */ - if (aci_version >= 0xb0) { - if ((vol=aci_rw_cmd(ACI_STATUS, - ACI_S_GENERAL, -1))<0) - return vol; - if (vol & 0x20) - buf |= SOUND_MASK_PCM; - } - else - if (!aci_solo) - buf |= SOUND_MASK_PCM; - break; - default: - buf |= SOUND_MASK_PCM; - } - if (aci_idcode[1] == 'C') /* PCM20 radio */ - buf |= SOUND_MASK_RADIO; - else - buf |= SOUND_MASK_LINE1; - - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_CAPS: - __put_user(0, p); - return 0; - case SOUND_MIXER_READ_VOLUME: - return getvolume(p, 0x04, 0x03); - case SOUND_MIXER_READ_CD: - return getvolume(p, 0x0a, 0x09); - case SOUND_MIXER_READ_MIC: - return getvolume(p, 0x06, 0x05); - case SOUND_MIXER_READ_LINE: - return getvolume(p, 0x08, 0x07); - case SOUND_MIXER_READ_SYNTH: - return getvolume(p, 0x0c, 0x0b); - case SOUND_MIXER_READ_PCM: - return getvolume(p, 0x0e, 0x0d); - case MIXER_READ(SOUND_MIXER_RADIO): /* fall through */ - case SOUND_MIXER_READ_LINE1: /* AUX1 */ - return getvolume(p, 0x11, 0x10); - case SOUND_MIXER_READ_LINE2: /* AUX2 */ - return getvolume(p, 0x13, 0x12); - case SOUND_MIXER_READ_BASS: /* get band one */ - if (aci_idcode[1]=='C') { - return getequalizer(p, 0x23, 0x22); - } - break; - case SOUND_MIXER_READ_TREBLE: /* get band seven */ - if (aci_idcode[1]=='C') { - return getequalizer(p, 0x2f, 0x2e); - } - break; - case SOUND_MIXER_READ_IGAIN: /* MIC pre-amp */ - if (aci_idcode[1]=='B' || aci_idcode[1]=='C') { - /* aci_micpreamp or ACI? */ - if (aci_version >= 0xb0) { - if ((buf=aci_indexed_cmd(ACI_STATUS, - ACI_S_READ_IGAIN))<0) - return buf; - } - else - buf=aci_micpreamp; - vol = SCALE(3, 100, buf <= 3 ? buf : 3); - vol |= vol << 8; - __put_user(vol, p); - return 0; - } - break; - case SOUND_MIXER_READ_OGAIN: - if (aci_amp) - buf = (100 || 100<<8); - else - buf = 0; - __put_user(buf, p); - return 0; - } - return -EINVAL; -} - -static struct mixer_operations aci_mixer_operations = -{ - .owner = THIS_MODULE, - .id = "ACI", - .ioctl = aci_mixer_ioctl -}; - -/* - * There is also an internal mixer in the codec (CS4231A or AD1845), - * that deserves no purpose in an ACI based system which uses an - * external ACI controlled stereo mixer. Make sure that this codec - * mixer has the AUX1 input selected as the recording source, that the - * input gain is set near maximum and that the other channels going - * from the inputs to the codec output are muted. - */ - -static int __init attach_aci(void) -{ - char *boardname; - int i, rc = -EBUSY; - - mutex_init(&aci_mutex); - - outb(0xE3, 0xf8f); /* Write MAD16 password */ - aci_port = (inb(0xf90) & 0x10) ? - 0x344: 0x354; /* Get aci_port from MC4_PORT */ - - if (!request_region(aci_port, 3, "sound mixer (ACI)")) { - printk(KERN_NOTICE - "aci: I/O area 0x%03x-0x%03x already used.\n", - aci_port, aci_port+2); - goto out; - } - - /* force ACI into a known state */ - rc = -EFAULT; - for (i=0; i<3; i++) - if (aci_rw_cmd(ACI_ERROR_OP, -1, -1)<0) - goto out_release_region; - - /* official this is one aci read call: */ - rc = -EFAULT; - if ((aci_idcode[0]=aci_rw_cmd(ACI_READ_IDCODE, -1, -1))<0 || - (aci_idcode[1]=aci_rw_cmd(ACI_READ_IDCODE, -1, -1))<0) { - printk(KERN_ERR "aci: Failed to read idcode on 0x%03x.\n", - aci_port); - goto out_release_region; - } - - if ((aci_version=aci_rw_cmd(ACI_READ_VERSION, -1, -1))<0) { - printk(KERN_ERR "aci: Failed to read version on 0x%03x.\n", - aci_port); - goto out_release_region; - } - - if (aci_idcode[0] == 'm') { - /* It looks like a miro sound card. */ - switch (aci_idcode[1]) { - case 'A': - boardname = "PCM1 pro / early PCM12"; - break; - case 'B': - boardname = "PCM12"; - break; - case 'C': - boardname = "PCM20 radio"; - break; - default: - boardname = "unknown miro"; - } - } else { - printk(KERN_WARNING "aci: Warning: unsupported card! - " - "no hardware, no specs...\n"); - boardname = "unknown Cardinal Technologies"; - } - - printk(KERN_INFO " at 0x%03x\n", - aci_version, - aci_idcode[0], aci_idcode[1], - aci_idcode[0], aci_idcode[1], - boardname, aci_port); - - rc = -EBUSY; - if (reset) { - /* first write()s after reset fail with my PCM20 */ - if (aci_rw_cmd(ACI_INIT, -1, -1)<0 || - aci_rw_cmd(ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP)<0 || - aci_rw_cmd(ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP)<0) - goto out_release_region; - } - - /* the PCM20 is muted after reset (and reboot) */ - if (aci_rw_cmd(ACI_SET_MUTE, 0x00, -1)<0) - goto out_release_region; - - if (ide>=0) - if (aci_rw_cmd(ACI_SET_IDE, !ide, -1)<0) - goto out_release_region; - - if (wss>=0 && aci_idcode[1]=='A') - if (aci_rw_cmd(ACI_SET_WSS, !!wss, -1)<0) - goto out_release_region; - - mixer_device = sound_install_mixer(MIXER_DRIVER_VERSION, boardname, - &aci_mixer_operations, - sizeof(aci_mixer_operations), NULL); - rc = 0; - if (mixer_device < 0) { - printk(KERN_ERR "aci: Failed to install mixer.\n"); - rc = mixer_device; - goto out_release_region; - } /* else Maybe initialize the CS4231A mixer here... */ -out: return rc; -out_release_region: - release_region(aci_port, 3); - goto out; -} - -static void __exit unload_aci(void) -{ - sound_unload_mixerdev(mixer_device); - release_region(aci_port, 3); -} - -module_init(attach_aci); -module_exit(unload_aci); -MODULE_LICENSE("GPL"); diff --git a/linux/sound/oss/aci.h b/linux/sound/oss/aci.h deleted file mode 100644 index 20102ee08..000000000 --- a/linux/sound/oss/aci.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _ACI_H_ -#define _ACI_H_ - -extern int aci_port; -extern int aci_version; /* ACI firmware version */ -extern int aci_rw_cmd(int write1, int write2, int write3); - -#define aci_indexed_cmd(a, b) aci_rw_cmd(a, b, -1) -#define aci_write_cmd(a, b) aci_rw_cmd(a, b, -1) -#define aci_read_cmd(a) aci_rw_cmd(a,-1, -1) - -#define COMMAND_REGISTER (aci_port) /* write register */ -#define STATUS_REGISTER (aci_port + 1) /* read register */ -#define BUSY_REGISTER (aci_port + 2) /* also used for rds */ - -#define RDS_REGISTER BUSY_REGISTER - -#define ACI_SET_MUTE 0x0d -#define ACI_SET_POWERAMP 0x0f -#define ACI_SET_TUNERMUTE 0xa3 -#define ACI_SET_TUNERMONO 0xa4 -#define ACI_SET_IDE 0xd0 -#define ACI_SET_WSS 0xd1 -#define ACI_SET_SOLOMODE 0xd2 -#define ACI_WRITE_IGAIN 0x03 -#define ACI_WRITE_TUNE 0xa7 -#define ACI_READ_TUNERSTEREO 0xa8 -#define ACI_READ_TUNERSTATION 0xa9 -#define ACI_READ_VERSION 0xf1 -#define ACI_READ_IDCODE 0xf2 -#define ACI_INIT 0xff -#define ACI_STATUS 0xf0 -#define ACI_S_GENERAL 0x00 -#define ACI_S_READ_IGAIN 0x21 -#define ACI_ERROR_OP 0xdf - -/* - * The following macro SCALE can be used to scale one integer volume - * value into another one using only integer arithmetic. If the input - * value x is in the range 0 <= x <= xmax, then the result will be in - * the range 0 <= SCALE(xmax,ymax,x) <= ymax. - * - * This macro has for all xmax, ymax > 0 and all 0 <= x <= xmax the - * following nice properties: - * - * - SCALE(xmax,ymax,xmax) = ymax - * - SCALE(xmax,ymax,0) = 0 - * - SCALE(xmax,ymax,SCALE(ymax,xmax,SCALE(xmax,ymax,x))) = SCALE(xmax,ymax,x) - * - * In addition, the rounding error is minimal and nicely distributed. - * The proofs are left as an exercise to the reader. - */ - -#define SCALE(xmax,ymax,x) (((x)*(ymax)+(xmax)/2)/(xmax)) - - -#endif /* _ACI_H_ */ -- cgit v1.2.3 From 995c07b049f1633deb6e269cc0e7978b8c0dff4e Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 17 Aug 2008 22:13:31 -0400 Subject: cx18: Add missing lock for when the irq handler manipulates the queues From: Andy Walls cx18: Add missing lock for when the irq handler manipulates the queues. This was a potential source of stream queue corruption. Also changed the name of cx18_queue_find_buf() to cx18_queue_get_buf_irq(). Priority: high Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-irq.c | 2 +- linux/drivers/media/video/cx18/cx18-queue.c | 23 +++++++++++++---------- linux/drivers/media/video/cx18/cx18-queue.h | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx18/cx18-irq.c b/linux/drivers/media/video/cx18/cx18-irq.c index 654664783..b9cf609ee 100644 --- a/linux/drivers/media/video/cx18/cx18-irq.c +++ b/linux/drivers/media/video/cx18/cx18-irq.c @@ -61,7 +61,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) CX18_WARN("Ack struct = %d for %s\n", mb->args[2], s->name); id = read_enc(off); - buf = cx18_queue_find_buf(s, id, read_enc(off + 4)); + buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4)); CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); if (buf) { cx18_buf_sync_for_cpu(s, buf); diff --git a/linux/drivers/media/video/cx18/cx18-queue.c b/linux/drivers/media/video/cx18/cx18-queue.c index 6990b77c6..8a4dd821f 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.c +++ b/linux/drivers/media/video/cx18/cx18-queue.c @@ -78,12 +78,13 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) return buf; } -struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, +struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, u32 bytesused) { struct cx18 *cx = s->cx; struct list_head *p; + spin_lock(&s->qlock); list_for_each(p, &s->q_free.list) { struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); @@ -92,17 +93,19 @@ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, continue; buf->bytesused = bytesused; /* the transport buffers are handled differently, - so there is no need to move them to the full queue */ - if (s->type == CX18_ENC_STREAM_TYPE_TS) - return buf; - s->q_free.buffers--; - s->q_free.length -= s->buf_size; - s->q_full.buffers++; - s->q_full.length += s->buf_size; - s->q_full.bytesused += buf->bytesused; - list_move_tail(&buf->list, &s->q_full.list); + they are not moved to the full queue */ + if (s->type != CX18_ENC_STREAM_TYPE_TS) { + s->q_free.buffers--; + s->q_free.length -= s->buf_size; + s->q_full.buffers++; + s->q_full.length += s->buf_size; + s->q_full.bytesused += buf->bytesused; + list_move_tail(&buf->list, &s->q_full.list); + } + spin_unlock(&s->qlock); return buf; } + spin_unlock(&s->qlock); CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); return NULL; } diff --git a/linux/drivers/media/video/cx18/cx18-queue.h b/linux/drivers/media/video/cx18/cx18-queue.h index 91423b986..7f93bb13c 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.h +++ b/linux/drivers/media/video/cx18/cx18-queue.h @@ -46,7 +46,7 @@ void cx18_queue_init(struct cx18_queue *q); void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, struct cx18_queue *q); struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); -struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, +struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, u32 bytesused); void cx18_flush_queues(struct cx18_stream *s); -- cgit v1.2.3 From 2315f8eef1304343666da0b452b8ec290aa32132 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 Aug 2008 09:46:12 +0200 Subject: pxa: fix build error for 2.6.27. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/pxa_camera.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index ead87ddaf..4ddd26d6c 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -36,8 +36,13 @@ #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) +#include +#include +#else #include #include +#endif #define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5) #define PXA_CAM_DRV_NAME "pxa27x-camera" -- cgit v1.2.3 From 4589075f331c3f32641ecd0313fe4728a9f75940 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 Aug 2008 09:48:42 +0200 Subject: usbvideo: add proper error check and add release function From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/usbvideo/usbvideo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/usbvideo/usbvideo.c b/linux/drivers/media/video/usbvideo/usbvideo.c index 5bda83f7d..4b28a6dfb 100644 --- a/linux/drivers/media/video/usbvideo/usbvideo.c +++ b/linux/drivers/media/video/usbvideo/usbvideo.c @@ -1006,6 +1006,10 @@ allocate_done: EXPORT_SYMBOL(usbvideo_AllocateDevice); +static void usbvideo_dummy_release(struct video_device *vfd) +{ +} + int usbvideo_RegisterVideoDevice(struct uvd *uvd) { char tmp1[20], tmp2[20]; /* Buffers for printing */ @@ -1039,7 +1043,8 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) return -EINVAL; } uvd->vdev.parent = &uvd->dev->dev; - if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { + uvd->vdev.release = usbvideo_dummy_release; + if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { err("%s: video_register_device failed", __func__); return -EPIPE; } -- 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 From 87eb1f67e4981f3a09825012f16af0107a7adb45 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 21 Aug 2008 21:37:10 -0400 Subject: sms1xxx: fix typo in license header From: Michael Krufky This should have read, "GNU General Public License version 2" rather than, "GNU General Public License version 3" This was actually a typo mass-blunder -- this is not a change in licence, as the code was always GPLv2. Priority: high Signed-off-by: Uri Shkolnik Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 2 +- linux/drivers/media/dvb/siano/sms-cards.h | 2 +- linux/drivers/media/dvb/siano/smscoreapi.c | 2 +- linux/drivers/media/dvb/siano/smscoreapi.h | 2 +- linux/drivers/media/dvb/siano/smsdvb.c | 2 +- linux/drivers/media/dvb/siano/smsusb.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index e7a8ac0c4..cc5efb643 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -4,7 +4,7 @@ * Copyright (c) 2008 Michael Krufky * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as + * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * Software distributed under the License is distributed on an "AS IS" diff --git a/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index 83b39bc20..c8f3da6f9 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/drivers/media/dvb/siano/sms-cards.h @@ -4,7 +4,7 @@ * Copyright (c) 2008 Michael Krufky * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as + * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * Software distributed under the License is distributed on an "AS IS" diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 4781997f6..700a0a6a7 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -8,7 +8,7 @@ * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as + * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * Software distributed under the License is distributed on an "AS IS" diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index dbedc315f..3bba565d7 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -6,7 +6,7 @@ * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as + * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * Software distributed under the License is distributed on an "AS IS" diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index e64478b4e..f2a6c6f9e 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -6,7 +6,7 @@ * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as + * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * Software distributed under the License is distributed on an "AS IS" diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 40582bf70..a50ea8259 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -6,7 +6,7 @@ * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as + * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * Software distributed under the License is distributed on an "AS IS" -- cgit v1.2.3 From 0fab8808e0c1e7746e9f4a87b0eea1c45a6a47a5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Aug 2008 02:40:30 +0300 Subject: dvb: drx397xD: checkpatch.pl cleanups From: Felipe Balbi This driver sure needs some rework. For now, let's try to clean it up a bit before start reimplementing anything. checkpatch.pl still not happy with this driver after this patch, but the most annoying errors are gone, comments now use C-style only, labels are well placed and some other minor fixes. Some more clean up patches will come as I work on this driver. Please review it carefully. Priority: normal Cc: Mauro Carvalho Chehab Cc: Henk Vergonet Signed-off-by: Felipe Balbi [mchehab@infradead.org: Manually fixed some conflicts with a previous patch] Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/drx397xD.c | 250 ++++++++++++++------------- 1 file changed, 133 insertions(+), 117 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/drx397xD.c b/linux/drivers/media/dvb/frontends/drx397xD.c index f1ea891d7..2ff10e29e 100644 --- a/linux/drivers/media/dvb/frontends/drx397xD.c +++ b/linux/drivers/media/dvb/frontends/drx397xD.c @@ -39,35 +39,32 @@ static const char mod_name[] = "drx397xD"; #define F_SET_0D0h 1 #define F_SET_0D4h 2 -typedef enum fw_ix { +enum fw_ix { #define _FW_ENTRY(a, b) b #include "drx397xD_fw.h" -} fw_ix_t; +}; /* chip specifics */ struct drx397xD_state { struct i2c_adapter *i2c; struct dvb_frontend frontend; struct drx397xD_config config; - fw_ix_t chip_rev; + enum fw_ix chip_rev; int flags; u32 bandwidth_parm; /* internal bandwidth conversions */ u32 f_osc; /* w90: actual osc frequency [Hz] */ }; -/******************************************************************************* - * Firmware - ******************************************************************************/ - +/* Firmware */ static const char *blob_name[] = { #define _BLOB_ENTRY(a, b) a #include "drx397xD_fw.h" }; -typedef enum blob_ix { +enum blob_ix { #define _BLOB_ENTRY(a, b) b #include "drx397xD_fw.h" -} blob_ix_t; +}; static struct { const char *name; @@ -86,7 +83,7 @@ static struct { }; /* use only with writer lock aquired */ -static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix) +static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix) { memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); if (fw[ix].file) @@ -95,7 +92,7 @@ static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix) static void drx_release_fw(struct drx397xD_state *s) { - fw_ix_t ix = s->chip_rev; + enum fw_ix ix = s->chip_rev; pr_debug("%s\n", __func__); @@ -108,7 +105,7 @@ static void drx_release_fw(struct drx397xD_state *s) write_unlock(&fw[ix].lock); } -static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix) +static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix) { const u8 *data; size_t size, len; @@ -176,26 +173,28 @@ static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix) goto exit_corrupt; } } while (i < size); - exit_corrupt: + +exit_corrupt: printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name); - exit_err: +exit_err: _drx_release_fw(s, ix); fw[ix].refcnt--; - exit_ok: +exit_ok: fw[ix].refcnt++; write_unlock(&fw[ix].lock); + return rc; } -/******************************************************************************* - * i2c bus IO - ******************************************************************************/ - -static int write_fw(struct drx397xD_state *s, blob_ix_t ix) +/* i2c bus IO */ +static int write_fw(struct drx397xD_state *s, enum blob_ix ix) { - struct i2c_msg msg = {.addr = s->config.demod_address,.flags = 0 }; const u8 *data; int len, rc = 0, i = 0; + struct i2c_msg msg = { + .addr = s->config.demod_address, + .flags = 0 + }; if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) { pr_debug("%s drx_fw_ix_t out of range\n", __func__); @@ -230,8 +229,9 @@ static int write_fw(struct drx397xD_state *s, blob_ix_t ix) goto exit_rc; } } - exit_rc: +exit_rc: read_unlock(&fw[s->chip_rev].lock); + return 0; } @@ -243,17 +243,16 @@ static int _read16(struct drx397xD_state *s, u32 i2c_adr) u16 v; struct i2c_msg msg[2] = { { - .addr = s->config.demod_address, - .flags = 0, - .buf = a, - .len = sizeof(a) - } - , { - .addr = s->config.demod_address, - .flags = I2C_M_RD, - .buf = (u8 *) & v, - .len = sizeof(v) - } + .addr = s->config.demod_address, + .flags = 0, + .buf = a, + .len = sizeof(a) + }, { + .addr = s->config.demod_address, + .flags = I2C_M_RD, + .buf = (u8 *) &v, + .len = sizeof(v) + } }; *(u32 *) a = i2c_adr; @@ -278,27 +277,27 @@ static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val) }; *(u32 *) a = i2c_adr; - *(u16 *) & a[4] = val; + *(u16 *) &a[4] = val; rc = i2c_transfer(s->i2c, &msg, 1); if (rc != 1) return -EIO; + return 0; } -#define WR16(ss,adr, val) \ +#define WR16(ss, adr, val) \ _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val)) -#define WR16_E0(ss,adr, val) \ +#define WR16_E0(ss, adr, val) \ _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val)) -#define RD16(ss,adr) \ +#define RD16(ss, adr) \ _read16(ss, I2C_ADR_C0(adr)) -#define EXIT_RC( cmd ) if ( (rc = (cmd)) < 0) goto exit_rc - -/******************************************************************************* - * Tuner callback - ******************************************************************************/ +#define EXIT_RC(cmd) \ + if ((rc = (cmd)) < 0) \ + goto exit_rc +/* Tuner callback */ static int PLL_Set(struct drx397xD_state *s, struct dvb_frontend_parameters *fep, int *df_tuner) { @@ -332,10 +331,7 @@ static int PLL_Set(struct drx397xD_state *s, return 0; } -/******************************************************************************* - * Demodulator helper functions - ******************************************************************************/ - +/* Demodulator helper functions */ static int SC_WaitForReady(struct drx397xD_state *s) { int cnt = 1000; @@ -348,6 +344,7 @@ static int SC_WaitForReady(struct drx397xD_state *s) if (rc == 0) return 0; } + return -1; } @@ -362,6 +359,7 @@ static int SC_SendCommand(struct drx397xD_state *s, int cmd) rc = RD16(s, 0x820042); if ((rc & 0xffff) == 0xffff) return -1; + return 0; } @@ -384,6 +382,7 @@ static int HI_Command(struct drx397xD_state *s, u16 cmd) if (rc < 0) return rc; } while (--cnt); + return rc; } @@ -393,13 +392,14 @@ static int HI_CfgCommand(struct drx397xD_state *s) pr_debug("%s\n", __func__); WR16(s, 0x420033, 0x3973); - WR16(s, 0x420034, s->config.w50); // code 4, log 4 - WR16(s, 0x420035, s->config.w52); // code 15, log 9 + WR16(s, 0x420034, s->config.w50); /* code 4, log 4 */ + WR16(s, 0x420035, s->config.w52); /* code 15, log 9 */ WR16(s, 0x420036, s->config.demod_address << 1); - WR16(s, 0x420037, s->config.w56); // code (set_i2c ?? initX 1 ), log 1 -// WR16(s, 0x420033, 0x3973); + WR16(s, 0x420037, s->config.w56); /* code (set_i2c ?? initX 1 ), log 1 */ + /* WR16(s, 0x420033, 0x3973); */ if ((s->config.w56 & 8) == 0) return HI_Command(s, 3); + return WR16(s, 0x420032, 0x3); } @@ -469,7 +469,7 @@ static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc) i = slowIncrDecLUT_15272[rem / 28]; EXIT_RC(WR16(s, 0x0c2002b, i)); rc = WR16(s, 0x0c2002c, i); - exit_rc: +exit_rc: return rc; } @@ -499,7 +499,7 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc) rc &= ~2; break; case 0: - // loc_8000659 + /* loc_8000659 */ s->config.w9C &= ~2; EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); EXIT_RC(RD16(s, 0x0c20010)); @@ -523,7 +523,8 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc) rc |= 2; } rc = WR16(s, 0x0c20013, rc); - exit_rc: + +exit_rc: return rc; } @@ -603,7 +604,8 @@ static int CorrectSysClockDeviation(struct drx397xD_state *s) s->config.f_osc * 1000, clk - s->config.f_osc * 1000); } rc = WR16(s, 0x08200e8, 0); - exit_rc: + +exit_rc: return rc; } @@ -621,17 +623,17 @@ static int ConfigureMPEGOutput(struct drx397xD_state *s, int type) si &= ~1; bp = 0x200; } - if (s->config.w9A == 0) { + if (s->config.w9A == 0) si |= 0x80; - } else { + else si &= ~0x80; - } EXIT_RC(WR16(s, 0x2150045, 0)); EXIT_RC(WR16(s, 0x2150010, si)); EXIT_RC(WR16(s, 0x2150011, bp)); rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0)); - exit_rc: + +exit_rc: return rc; } @@ -695,7 +697,7 @@ static int drx_tune(struct drx397xD_state *s, } loc_800111A: #endif - set_tuner: +set_tuner: rc = PLL_Set(s, fep, &df_tuner); if (rc < 0) { @@ -872,16 +874,16 @@ static int drx_tune(struct drx397xD_state *s, rc = WR16(s, 0x2010012, 0); if (rc < 0) goto exit_rc; - // QPSK QAM16 QAM64 - ebx = 0x19f; // 62 - ebp = 0x1fb; // 15 - v20 = 0x16a; // 62 - v1E = 0x195; // 62 - v16 = 0x1bb; // 15 - v14 = 0x1ef; // 15 - v12 = 5; // 16 - v10 = 5; // 16 - v0E = 5; // 16 + /* QPSK QAM16 QAM64 */ + ebx = 0x19f; /* 62 */ + ebp = 0x1fb; /* 15 */ + v20 = 0x16a; /* 62 */ + v1E = 0x195; /* 62 */ + v16 = 0x1bb; /* 15 */ + v14 = 0x1ef; /* 15 */ + v12 = 5; /* 16 */ + v10 = 5; /* 16 */ + v0E = 5; /* 16 */ } switch (fep->u.ofdm.constellation) { @@ -1034,17 +1036,17 @@ static int drx_tune(struct drx397xD_state *s, case BANDWIDTH_8_MHZ: /* 0 */ case BANDWIDTH_AUTO: rc = WR16(s, 0x0c2003f, 0x32); - s->bandwidth_parm = ebx = 0x8b8249; // 9142857 + s->bandwidth_parm = ebx = 0x8b8249; edx = 0; break; case BANDWIDTH_7_MHZ: rc = WR16(s, 0x0c2003f, 0x3b); - s->bandwidth_parm = ebx = 0x7a1200; // 8000000 + s->bandwidth_parm = ebx = 0x7a1200; edx = 0x4807; break; case BANDWIDTH_6_MHZ: rc = WR16(s, 0x0c2003f, 0x47); - s->bandwidth_parm = ebx = 0x68a1b6; // 6857142 + s->bandwidth_parm = ebx = 0x68a1b6; edx = 0x0f07; break; }; @@ -1102,8 +1104,11 @@ static int drx_tune(struct drx397xD_state *s, WR16(s, 0x0820040, 1); SC_SendCommand(s, 1); -// rc = WR16(s, 0x2150000, 1); -// if (rc < 0) goto exit_rc; +#if 0 + rc = WR16(s, 0x2150000, 1); + if (rc < 0) + goto exit_rc; +#endif rc = WR16(s, 0x2150000, 2); rc = WR16(s, 0x2150016, a); @@ -1111,7 +1116,8 @@ static int drx_tune(struct drx397xD_state *s, rc = WR16(s, 0x2150036, 0); rc = WR16(s, 0x2150000, 1); s->config.d60 = 2; - exit_rc: + +exit_rc: return rc; } @@ -1144,18 +1150,18 @@ static int drx397x_init(struct dvb_frontend *fe) /* HI_CfgCommand */ s->config.w50 = 4; - s->config.w52 = 9; // 0xf; + s->config.w52 = 9; - s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */ - s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */ - s->config.w92 = 12000; // 20000; + s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */ + s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */ + s->config.w92 = 12000; s->config.w9C = 0x000e; s->config.w9E = 0x0000; /* ConfigureMPEGOutput params */ s->config.wA0 = 4; - s->config.w98 = 1; // 0; + s->config.w98 = 1; s->config.w9A = 1; /* get chip revision */ @@ -1312,7 +1318,7 @@ static int drx397x_init(struct dvb_frontend *fe) rc = WR16(s, 0x0c20012, 1); } - write_DRXD_InitFE_1: +write_DRXD_InitFE_1: rc = write_fw(s, DRXD_InitFE_1); if (rc < 0) @@ -1390,7 +1396,8 @@ static int drx397x_init(struct dvb_frontend *fe) #endif s->config.d60 = 1; s->config.d48 = 1; - error: + +error: return rc; } @@ -1405,7 +1412,8 @@ static int drx397x_set_frontend(struct dvb_frontend *fe, { struct drx397xD_state *s = fe->demodulator_priv; - s->config.s20d24 = 1; // 0; + s->config.s20d24 = 1; + return drx_tune(s, params); } @@ -1416,18 +1424,21 @@ static int drx397x_get_tune_settings(struct dvb_frontend *fe, fe_tune_settings->min_delay_ms = 10000; fe_tune_settings->step_size = 0; fe_tune_settings->max_drift = 0; + return 0; } -static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status) +static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct drx397xD_state *s = fe->demodulator_priv; int lockstat; GetLockStatus(s, &lockstat); +#if 0 /* TODO */ -// if (lockstat & 1) -// CorrectSysClockDeviation(s); + if (lockstat & 1) + CorrectSysClockDeviation(s); +#endif *status = 0; if (lockstat & 2) { @@ -1435,9 +1446,8 @@ static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status) ConfigureMPEGOutput(s, 1); *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; } - if (lockstat & 4) { + if (lockstat & 4) *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - } return 0; } @@ -1445,16 +1455,18 @@ static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status) static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber) { *ber = 0; + return 0; } -static int drx397x_read_snr(struct dvb_frontend *fe, u16 * snr) +static int drx397x_read_snr(struct dvb_frontend *fe, u16 *snr) { *snr = 0; + return 0; } -static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength) +static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct drx397xD_state *s = fe->demodulator_priv; int rc; @@ -1480,6 +1492,7 @@ static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength) * The following does the same but with less rounding errors: */ *strength = ~(7720 + (rc * 30744 >> 10)); + return 0; } @@ -1487,6 +1500,7 @@ static int drx397x_read_ucblocks(struct dvb_frontend *fe, unsigned int *ucblocks) { *ucblocks = 0; + return 0; } @@ -1515,22 +1529,22 @@ static struct dvb_frontend_ops drx397x_ops = { .frequency_max = 855250000, .frequency_stepsize = 166667, .frequency_tolerance = 0, - .caps = /* 0x0C01B2EAE */ - FE_CAN_FEC_1_2 | // = 0x2, - FE_CAN_FEC_2_3 | // = 0x4, - FE_CAN_FEC_3_4 | // = 0x8, - FE_CAN_FEC_5_6 | // = 0x20, - FE_CAN_FEC_7_8 | // = 0x80, - FE_CAN_FEC_AUTO | // = 0x200, - FE_CAN_QPSK | // = 0x400, - FE_CAN_QAM_16 | // = 0x800, - FE_CAN_QAM_64 | // = 0x2000, - FE_CAN_QAM_AUTO | // = 0x10000, - FE_CAN_TRANSMISSION_MODE_AUTO | // = 0x20000, - FE_CAN_GUARD_INTERVAL_AUTO | // = 0x80000, - FE_CAN_HIERARCHY_AUTO | // = 0x100000, - FE_CAN_RECOVER | // = 0x40000000, - FE_CAN_MUTE_TS // = 0x80000000 + .caps = /* 0x0C01B2EAE */ + FE_CAN_FEC_1_2 | /* = 0x2, */ + FE_CAN_FEC_2_3 | /* = 0x4, */ + FE_CAN_FEC_3_4 | /* = 0x8, */ + FE_CAN_FEC_5_6 | /* = 0x20, */ + FE_CAN_FEC_7_8 | /* = 0x80, */ + FE_CAN_FEC_AUTO | /* = 0x200, */ + FE_CAN_QPSK | /* = 0x400, */ + FE_CAN_QAM_16 | /* = 0x800, */ + FE_CAN_QAM_64 | /* = 0x2000, */ + FE_CAN_QAM_AUTO | /* = 0x10000, */ + FE_CAN_TRANSMISSION_MODE_AUTO | /* = 0x20000, */ + FE_CAN_GUARD_INTERVAL_AUTO | /* = 0x80000, */ + FE_CAN_HIERARCHY_AUTO | /* = 0x100000, */ + FE_CAN_RECOVER | /* = 0x40000000, */ + FE_CAN_MUTE_TS /* = 0x80000000 */ }, .release = drx397x_release, @@ -1551,33 +1565,35 @@ static struct dvb_frontend_ops drx397x_ops = { struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config, struct i2c_adapter *i2c) { - struct drx397xD_state *s = NULL; + struct drx397xD_state *state; /* allocate memory for the internal state */ - s = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL); - if (s == NULL) + state = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL); + if (!state) goto error; /* setup the state */ - s->i2c = i2c; - memcpy(&s->config, config, sizeof(struct drx397xD_config)); + state->i2c = i2c; + memcpy(&state->config, config, sizeof(struct drx397xD_config)); /* check if the demod is there */ if (RD16(s, 0x2410019) < 0) goto error; /* create dvb_frontend */ - memcpy(&s->frontend.ops, &drx397x_ops, sizeof(struct dvb_frontend_ops)); - s->frontend.demodulator_priv = s; + memcpy(&state->frontend.ops, &drx397x_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = s; + + return &state->frontend; +error: + kfree(state); - return &s->frontend; - error: - kfree(s); return NULL; } +EXPORT_SYMBOL(drx397xD_attach); MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend"); MODULE_AUTHOR("Henk Vergonet"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(drx397xD_attach); -- cgit v1.2.3 From 5c9ae10b02888a111c93293606406542f9fa8d8a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Aug 2008 16:44:50 -0700 Subject: drx397xD.c sparse annotations From: Harvey Harrison Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/drx397xD.c | 14 +++++++------- linux/drivers/media/dvb/frontends/drx397xD.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/drx397xD.c b/linux/drivers/media/dvb/frontends/drx397xD.c index 2ff10e29e..3f9f19c70 100644 --- a/linux/drivers/media/dvb/frontends/drx397xD.c +++ b/linux/drivers/media/dvb/frontends/drx397xD.c @@ -236,11 +236,11 @@ exit_rc: } /* Function is not endian safe, use the RD16 wrapper below */ -static int _read16(struct drx397xD_state *s, u32 i2c_adr) +static int _read16(struct drx397xD_state *s, __le32 i2c_adr) { int rc; u8 a[4]; - u16 v; + __le16 v; struct i2c_msg msg[2] = { { .addr = s->config.demod_address, @@ -250,12 +250,12 @@ static int _read16(struct drx397xD_state *s, u32 i2c_adr) }, { .addr = s->config.demod_address, .flags = I2C_M_RD, - .buf = (u8 *) &v, + .buf = (u8 *)&v, .len = sizeof(v) } }; - *(u32 *) a = i2c_adr; + *(__le32 *) a = i2c_adr; rc = i2c_transfer(s->i2c, msg, 2); if (rc != 2) @@ -265,7 +265,7 @@ static int _read16(struct drx397xD_state *s, u32 i2c_adr) } /* Function is not endian safe, use the WR16.. wrappers below */ -static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val) +static int _write16(struct drx397xD_state *s, __le32 i2c_adr, __le16 val) { u8 a[6]; int rc; @@ -276,8 +276,8 @@ static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val) .len = sizeof(a) }; - *(u32 *) a = i2c_adr; - *(u16 *) &a[4] = val; + *(__le32 *)a = i2c_adr; + *(__le16 *)&a[4] = val; rc = i2c_transfer(s->i2c, &msg, 1); if (rc != 1) diff --git a/linux/drivers/media/dvb/frontends/drx397xD.h b/linux/drivers/media/dvb/frontends/drx397xD.h index 2ad1ea0cc..ba05d1729 100644 --- a/linux/drivers/media/dvb/frontends/drx397xD.h +++ b/linux/drivers/media/dvb/frontends/drx397xD.h @@ -28,7 +28,7 @@ #define DRX_F_OFFSET 36000000 #define I2C_ADR_C0(x) \ -( (u32)cpu_to_le32( \ +( cpu_to_le32( \ (u32)( \ (((u32)(x) & (u32)0x000000ffUL) ) | \ (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ @@ -38,7 +38,7 @@ ) #define I2C_ADR_E0(x) \ -( (u32)cpu_to_le32( \ +( cpu_to_le32( \ (u32)( \ (((u32)(x) & (u32)0x000000ffUL) ) | \ (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ -- cgit v1.2.3 From 3e8019525a28bf5d9993fb2dfcff38f82ad071bb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Aug 2008 16:44:50 -0700 Subject: link tuner before saa7134 From: Simon Arlott If saa7134_init is run before v4l2_i2c_drv_init (tuner), then saa7134_board_init2 will try to set the tuner type for devices that don't exist yet. This moves tuner to before all of the device-specific drivers so that it's loaded early enough on boot. Signed-off-by: Simon Arlott Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 5656cfecf..bcd23e3cb 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -20,6 +20,8 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o endif +obj-$(CONFIG_VIDEO_TUNER) += tuner.o + obj-$(CONFIG_VIDEO_BT848) += bt8xx/ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o @@ -84,8 +86,6 @@ obj-$(CONFIG_VIDEO_MXB) += mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o -obj-$(CONFIG_VIDEO_TUNER) += tuner.o - obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o -- cgit v1.2.3 From af1ffad29ae870b4615122850f829047d43dd0a8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Aug 2008 16:44:51 -0700 Subject: V4L1: make PMS not autoprobe when builtin. From: Rene Herman The old Mediavision Pro Movie Studio legacy ISA V4L1 driver was found to hang the boot during Ingo Molnar's testing of randconfig kernels. Have it require a "pms.enable=1" kernel parameter to enable the driver when builtin which avoids such problems. This is a deprecated and, very likely, unused driver. Nothing changes modular behaviour moreover. Signed-off-by: Rene Herman Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/pms.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/pms.c b/linux/drivers/media/video/pms.c index e36b39b44..7db7872d8 100644 --- a/linux/drivers/media/video/pms.c +++ b/linux/drivers/media/video/pms.c @@ -1020,10 +1020,22 @@ static int init_mediavision(void) * Initialization and module stuff */ +#ifndef MODULE +static int enable; +module_param(enable, int, 0); +#endif + static int __init init_pms_cards(void) { printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n"); +#ifndef MODULE + if (!enable) { + printk(KERN_INFO "Not enabled\n"); + return -ENODEV; + } +#endif + data_port = io_port +1; if(init_mediavision()) -- cgit v1.2.3 From 61a6c2d6e99d7429de76ca63c732ac70765fead3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Aug 2008 16:44:52 -0700 Subject: 1-make-pms-not-autoprobe-when-builtin update From: Rene Herman On 10-08-08 23:37, Alan Cox wrote: > > Would probably make the printk "pms: not enabled, use pms.enable=1 to > probe" > > So you know > a) What is wittering about not being probed > b) How to undo it. > > But thats trivia really. Signed-off-by: Rene Herman Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/pms.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pms.c b/linux/drivers/media/video/pms.c index 7db7872d8..8c51ee442 100644 --- a/linux/drivers/media/video/pms.c +++ b/linux/drivers/media/video/pms.c @@ -1031,7 +1031,8 @@ static int __init init_pms_cards(void) #ifndef MODULE if (!enable) { - printk(KERN_INFO "Not enabled\n"); + printk(KERN_INFO "PMS: not enabled, use pms.enable=1 to " + "probe\n"); return -ENODEV; } #endif -- cgit v1.2.3 From f9948d885abdee5a90558d69e2976377caede63f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Aug 2008 16:44:53 -0700 Subject: Use DIV_ROUND_UP From: Julia Lawall The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) / (d)) but is perhaps more readable. An extract of the semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @haskernel@ @@ @depends on haskernel@ expression n,d; @@ ( - (n + d - 1) / d + DIV_ROUND_UP(n,d) | - (n + (d - 1)) / d + DIV_ROUND_UP(n,d) ) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP((n),d) + DIV_ROUND_UP(n,d) @depends on haskernel@ expression n,d; @@ - DIV_ROUND_UP(n,(d)) + DIV_ROUND_UP(n,d) // Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/bw-qcam.c | 4 ++-- linux/drivers/media/video/uvc/uvc_video.c | 2 +- linux/drivers/media/video/zoran_device.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/bw-qcam.c b/linux/drivers/media/video/bw-qcam.c index df2b25b69..393113875 100644 --- a/linux/drivers/media/video/bw-qcam.c +++ b/linux/drivers/media/video/bw-qcam.c @@ -496,7 +496,7 @@ static void qc_set(struct qcam_device *q) val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * q->transfer_scale; } - val = (val + val2 - 1) / val2; + val = DIV_ROUND_UP(val, val2); qc_command(q, 0x13); qc_command(q, val); @@ -652,7 +652,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l transperline = q->width * q->bpp; divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * q->transfer_scale; - transperline = (transperline + divisor - 1) / divisor; + transperline = DIV_ROUND_UP(transperline, divisor); for (i = 0, yield = yieldlines; i < linestotrans; i++) { diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index 6854ac78a..03dc3a519 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -655,7 +655,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, if (size > UVC_MAX_FRAME_SIZE) return -EINVAL; - npackets = (size + psize - 1) / psize; + npackets = DIV_ROUND_UP(size, psize); if (npackets > UVC_MAX_ISO_PACKETS) npackets = UVC_MAX_ISO_PACKETS; diff --git a/linux/drivers/media/video/zoran_device.c b/linux/drivers/media/video/zoran_device.c index b0a014d09..e57da2d6f 100644 --- a/linux/drivers/media/video/zoran_device.c +++ b/linux/drivers/media/video/zoran_device.c @@ -378,7 +378,7 @@ zr36057_set_vfe (struct zoran *zr, /* horizontal */ VidWinWid = video_width; - X = (VidWinWid * 64 + tvn->Wa - 1) / tvn->Wa; + X = DIV_ROUND_UP(VidWinWid * 64, tvn->Wa); We = (VidWinWid * 64) / X; HorDcm = 64 - X; hcrop1 = 2 * ((tvn->Wa - We) / 4); @@ -404,7 +404,7 @@ zr36057_set_vfe (struct zoran *zr, /* Vertical */ DispMode = !(video_height > BUZ_MAX_HEIGHT / 2); VidWinHt = DispMode ? video_height : video_height / 2; - Y = (VidWinHt * 64 * 2 + tvn->Ha - 1) / tvn->Ha; + Y = DIV_ROUND_UP(VidWinHt * 64 * 2, tvn->Ha); He = (VidWinHt * 64) / Y; VerDcm = 64 - Y; vcrop1 = (tvn->Ha / 2 - He) / 2; -- cgit v1.2.3 From 9774032a256c5068759be0d9f4a1413caf020dd1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 22 Aug 2008 13:31:59 -0300 Subject: drx397xD: fix compilation error caused by changeset 71046dfb0853 From: Mauro Carvalho Chehab Priority: Normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/drx397xD.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/drx397xD.c b/linux/drivers/media/dvb/frontends/drx397xD.c index 3f9f19c70..7a2b2d461 100644 --- a/linux/drivers/media/dvb/frontends/drx397xD.c +++ b/linux/drivers/media/dvb/frontends/drx397xD.c @@ -1577,13 +1577,13 @@ struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config, memcpy(&state->config, config, sizeof(struct drx397xD_config)); /* check if the demod is there */ - if (RD16(s, 0x2410019) < 0) + if (RD16(state, 0x2410019) < 0) goto error; /* create dvb_frontend */ memcpy(&state->frontend.ops, &drx397x_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = s; + state->frontend.demodulator_priv = state; return &state->frontend; error: -- cgit v1.2.3 From 82e3269e7afdf7d14b85b98871b0c771ba006cbb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Aug 2008 13:38:01 -0700 Subject: pvrusb2: use proper byteorder interface From: Harvey Harrison ___swab32 is an internal detail of the implementation. Signed-off-by: Harvey Harrison Acked-By: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 419a473cf..881610b60 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1324,8 +1324,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) memcpy(fw_ptr, fw_entry->data + fw_done, bcnt); /* Usbsnoop log shows that we must swap bytes... */ for (icnt = 0; icnt < bcnt/4 ; icnt++) - ((u32 *)fw_ptr)[icnt] = - ___swab32(((u32 *)fw_ptr)[icnt]); + ((u32 *)fw_ptr)[icnt] = swab32(((u32 *)fw_ptr)[icnt]); ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, &actual_length, HZ); -- cgit v1.2.3 From 5ccd3bef0a3b936847eb1cdf0d7e496022b560c2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 Aug 2008 21:50:59 +0200 Subject: mt9m111: fix compile error and warning when compiling for kernel 2.6.25. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/mt9m111.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c index 4844486d7..e4ec7538d 100644 --- a/linux/drivers/media/video/mt9m111.c +++ b/linux/drivers/media/video/mt9m111.c @@ -879,8 +879,12 @@ static void mt9m111_video_remove(struct soc_camera_device *icd) soc_camera_video_stop(&mt9m111->icd); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +static int mt9m111_probe(struct i2c_client *client) +#else static int mt9m111_probe(struct i2c_client *client, const struct i2c_device_id *did) +#endif { struct mt9m111 *mt9m111; struct soc_camera_device *icd; @@ -940,11 +944,13 @@ static int mt9m111_remove(struct i2c_client *client) return 0; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) static const struct i2c_device_id mt9m111_id[] = { { "mt9m111", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, mt9m111_id); +#endif static struct i2c_driver mt9m111_i2c_driver = { .driver = { @@ -952,7 +958,9 @@ static struct i2c_driver mt9m111_i2c_driver = { }, .probe = mt9m111_probe, .remove = mt9m111_remove, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) .id_table = mt9m111_id, +#endif }; static int __init mt9m111_mod_init(void) -- cgit v1.2.3 From 4bae6a4ce417bb0832eaf13e586c1658ddf07253 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 Aug 2008 22:01:45 +0200 Subject: v4l2: fix a bunch of compile warnings. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/common/saa7146_core.c | 2 +- linux/drivers/media/dvb/b2c2/flexcop-dma.c | 2 +- linux/drivers/media/video/btcx-risc.c | 2 +- linux/drivers/media/video/saa7134/saa7134-core.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index 7bcf1eb14..9bce837f3 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -234,7 +234,7 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt) int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt) { __le32 *cpu; - dma_addr_t dma_addr; + dma_addr_t dma_addr = 0; cpu = pci_alloc_consistent(pci, PAGE_SIZE, &dma_addr); if (NULL == cpu) { diff --git a/linux/drivers/media/dvb/b2c2/flexcop-dma.c b/linux/drivers/media/dvb/b2c2/flexcop-dma.c index 1df246a7f..02a0f07a1 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-dma.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-dma.c @@ -10,7 +10,7 @@ int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size) { u8 *tcpu; - dma_addr_t tdma; + dma_addr_t tdma = 0; if (size % 2) { err("dma buffersize has to be even."); diff --git a/linux/drivers/media/video/btcx-risc.c b/linux/drivers/media/video/btcx-risc.c index e0e1158ce..3a935fbc3 100644 --- a/linux/drivers/media/video/btcx-risc.c +++ b/linux/drivers/media/video/btcx-risc.c @@ -65,7 +65,7 @@ int btcx_riscmem_alloc(struct pci_dev *pci, unsigned int size) { __le32 *cpu; - dma_addr_t dma; + dma_addr_t dma = 0; if (NULL != risc->cpu && risc->size < size) btcx_riscmem_free(pci,risc); diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 62c9322aa..117f33946 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -264,7 +264,7 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf) int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) { __le32 *cpu; - dma_addr_t dma_addr; + dma_addr_t dma_addr = 0; cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); if (NULL == cpu) -- cgit v1.2.3 From ab19cb308e86c5aeb0531bbbf5bfb2c09d3423a3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 Aug 2008 22:12:08 +0200 Subject: v4l-dvb: fix compile warnings. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/dvb/frontends/nxt200x.c | 4 ++-- linux/drivers/media/dvb/frontends/or51211.c | 2 +- linux/drivers/media/video/vino.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/dvb/frontends/nxt200x.c b/linux/drivers/media/dvb/frontends/nxt200x.c index a079fa824..846350bc4 100644 --- a/linux/drivers/media/dvb/frontends/nxt200x.c +++ b/linux/drivers/media/dvb/frontends/nxt200x.c @@ -81,7 +81,7 @@ static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len return 0; } -static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len) +static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len) { int err; struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len }; @@ -112,7 +112,7 @@ static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, return 0; } -static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len) +static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len) { u8 reg2 [] = { reg }; diff --git a/linux/drivers/media/dvb/frontends/or51211.c b/linux/drivers/media/dvb/frontends/or51211.c index 6afe12aac..16cf2fdd5 100644 --- a/linux/drivers/media/dvb/frontends/or51211.c +++ b/linux/drivers/media/dvb/frontends/or51211.c @@ -88,7 +88,7 @@ static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf, return 0; } -static u8 i2c_readbytes (struct or51211_state* state, u8 reg, u8* buf, int len) +static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len) { int err; struct i2c_msg msg; diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c index 9ada3fff2..1e61b3e5a 100644 --- a/linux/drivers/media/video/vino.c +++ b/linux/drivers/media/video/vino.c @@ -809,7 +809,7 @@ static void vino_free_buffer_with_count(struct vino_framebuffer *fb, dprintk("vino_free_buffer_with_count(): count = %d\n", count); for (i = 0; i < count; i++) { - ClearPageReserved(virt_to_page(fb->desc_table.virtual[i])); + ClearPageReserved(virt_to_page((void *)fb->desc_table.virtual[i])); dma_unmap_single(NULL, fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], PAGE_SIZE, DMA_FROM_DEVICE); @@ -887,7 +887,7 @@ static int vino_allocate_buffer(struct vino_framebuffer *fb, dma_data_addr + VINO_PAGE_SIZE * j; } - SetPageReserved(virt_to_page(fb->desc_table.virtual[i])); + SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i])); } /* page_count needs to be set anyway, because the descriptor table has @@ -974,7 +974,7 @@ static int vino_prepare_user_buffer(struct vino_framebuffer *fb, dma_data_addr + VINO_PAGE_SIZE * j; } - SetPageReserved(virt_to_page(fb->desc_table.virtual[i])); + SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i])); } /* page_count needs to be set anyway, because the descriptor table has -- cgit v1.2.3