From 6fb73d771159f2d1c9936d769ee42b3a7be3086a Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 21 Jan 2007 22:44:03 -0600 Subject: pvrusb2: Add comment for why G_TUNER only looks at index zero From: Mike Isely Mauro and I had fixed this bug at the same time. It's a silly one-liner, but my version of the fix included a comment explaining why it was needed. So I'm putting up this version of the fix. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 621a0dd31..ac7ead462 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -367,8 +367,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; - if (vt->index != 0) - break; + if (vt->index != 0) break; /* Only answer for the 1st tuner */ pvr2_hdw_execute_tuner_poll(hdw); ret = pvr2_hdw_get_tuner_status(hdw,vt); -- cgit v1.2.3 From 659ced75da379c72af9c077030331a1aaa990a46 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 21 Jan 2007 23:17:55 -0600 Subject: pvrusb2: Use macro names for FX2 commands From: Michael Krufky This is a maintainability cleanup; use nice names for all the FX2 commands instead of raw bytes. This way we can easily find where we issue FX commands. Signed-off-by: Michael Krufky Signed-off-by: Mike Isely --- .../drivers/media/video/pvrusb2/pvrusb2-encoder.c | 6 +++-- .../drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h | 28 ++++++++++++++++++++++ linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 18 +++++++------- .../drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 7 +++--- 4 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 95e45be08..80a624d0f 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -27,6 +27,7 @@ #include "pvrusb2-encoder.h" #include "pvrusb2-hdw-internal.h" #include "pvrusb2-debug.h" +#include "pvrusb2-fx2-cmd.h" @@ -58,7 +59,7 @@ static int pvr2_encoder_write_words(struct pvr2_hdw *hdw, chunkCnt = 8; if (chunkCnt > dlen) chunkCnt = dlen; memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); - hdw->cmd_buffer[0] = 0x01; + hdw->cmd_buffer[0] = FX2CMD_MEM_WRITE_DWORD; for (idx = 0; idx < chunkCnt; idx++) { hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs; PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7), @@ -99,7 +100,8 @@ static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,int statusFl, chunkCnt = 16; if (chunkCnt > dlen) chunkCnt = dlen; memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); - hdw->cmd_buffer[0] = statusFl ? 0x02 : 0x28; + hdw->cmd_buffer[0] = + (statusFl ? FX2CMD_MEM_READ_DWORD : FX2CMD_MEM_READ_64BYTES); hdw->cmd_buffer[7] = 0x44 + offs; ret = pvr2_send_request(hdw, hdw->cmd_buffer,8, diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h new file mode 100644 index 000000000..556628ad4 --- /dev/null +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h @@ -0,0 +1,28 @@ +#ifndef _PVRUSB2_FX2_CMD_H_ +#define _PVRUSB2_FX2_CMD_H_ + +#define FX2CMD_MEM_WRITE_DWORD 0x01 +#define FX2CMD_MEM_READ_DWORD 0x02 + +#define FX2CMD_MEM_READ_64BYTES 0x28 + +#define FX2CMD_REG_WRITE 0x04 +#define FX2CMD_REG_READ 0x05 + +#define FX2CMD_I2C_WRITE 0x08 +#define FX2CMD_I2C_READ 0x09 + +#define FX2CMD_GET_USB_SPEED 0x0b + +#define FX2CMD_STREAMING_ON 0x36 +#define FX2CMD_STREAMING_OFF 0x37 + +#define FX2CMD_POWER_OFF 0xdc +#define FX2CMD_POWER_ON 0xde + +#define FX2CMD_DEEP_RESET 0xdd + +#define FX2CMD_GET_EEPROM_ADDR 0xeb +#define FX2CMD_GET_IR_CODE 0xec + +#endif /* _PVRUSB2_FX2_CMD_H_ */ diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index b07bd58ea..589c094f1 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -37,6 +37,7 @@ #include "pvrusb2-hdw-internal.h" #include "pvrusb2-encoder.h" #include "pvrusb2-debug.h" +#include "pvrusb2-fx2-cmd.h" #define TV_MIN_FREQ 55250000L #define TV_MAX_FREQ 850000000L @@ -1674,7 +1675,7 @@ static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw) firmware needs be loaded. */ int result; LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0xeb; + hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR; result = pvr2_send_request_ex(hdw,HZ*1,!0, hdw->cmd_buffer,1, hdw->cmd_buffer,1); @@ -2565,7 +2566,7 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) { int result; LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0x0b; + hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED; result = pvr2_send_request(hdw, hdw->cmd_buffer,1, hdw->cmd_buffer,1); @@ -3089,7 +3090,7 @@ int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) LOCK_TAKE(hdw->ctl_lock); - hdw->cmd_buffer[0] = 0x04; /* write register prefix */ + hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */ PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data); hdw->cmd_buffer[5] = 0; hdw->cmd_buffer[6] = (reg >> 8) & 0xff; @@ -3110,7 +3111,7 @@ static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data) LOCK_TAKE(hdw->ctl_lock); - hdw->cmd_buffer[0] = 0x05; /* read register prefix */ + hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */ hdw->cmd_buffer[1] = 0; hdw->cmd_buffer[2] = 0; hdw->cmd_buffer[3] = 0; @@ -3234,7 +3235,7 @@ int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) LOCK_TAKE(hdw->ctl_lock); do { pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); hdw->flag_ok = !0; - hdw->cmd_buffer[0] = 0xdd; + hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET; status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); } while (0); LOCK_GIVE(hdw->ctl_lock); return status; @@ -3246,7 +3247,7 @@ int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) int status; LOCK_TAKE(hdw->ctl_lock); do { pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup"); - hdw->cmd_buffer[0] = 0xde; + hdw->cmd_buffer[0] = FX2CMD_POWER_ON; status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); } while (0); LOCK_GIVE(hdw->ctl_lock); return status; @@ -3279,7 +3280,8 @@ static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) { int status; LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37); + hdw->cmd_buffer[0] = + (runFl ? FX2CMD_STREAMING_ON : FX2CMD_STREAMING_OFF); status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); } while (0); LOCK_GIVE(hdw->ctl_lock); if (!status) { @@ -3378,7 +3380,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) { int result; LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0xeb; + hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR; result = pvr2_send_request(hdw, hdw->cmd_buffer,1, hdw->cmd_buffer,1); diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 4a4f1d64b..05c39d25f 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -23,6 +23,7 @@ #include "pvrusb2-i2c-core.h" #include "pvrusb2-hdw-internal.h" #include "pvrusb2-debug.h" +#include "pvrusb2-fx2-cmd.h" #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) @@ -70,7 +71,7 @@ static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); /* Set up command buffer for an I2C write */ - hdw->cmd_buffer[0] = 0x08; /* write prefix */ + hdw->cmd_buffer[0] = FX2CMD_I2C_WRITE; /* write prefix */ hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */ hdw->cmd_buffer[2] = length; /* length of what follows */ if (length) memcpy(hdw->cmd_buffer + 3, data, length); @@ -139,7 +140,7 @@ static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); /* Set up command buffer for an I2C write followed by a read */ - hdw->cmd_buffer[0] = 0x09; /* read prefix */ + hdw->cmd_buffer[0] = FX2CMD_I2C_READ; /* read prefix */ hdw->cmd_buffer[1] = dlen; /* arg length */ hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one more byte (status). */ @@ -296,7 +297,7 @@ static int i2c_24xxx_ir(struct pvr2_hdw *hdw, /* Issue a command to the FX2 to read the IR receiver. */ LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0xec; + hdw->cmd_buffer[0] = FX2CMD_GET_IR_CODE; stat = pvr2_send_request(hdw, hdw->cmd_buffer,1, hdw->cmd_buffer,4); -- cgit v1.2.3 From 3d22ccad1a2aa5805380d65da1c56b9bf8286f6a Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 21 Jan 2007 23:18:54 -0600 Subject: pvrusb2: Add boilerplate to new header file From: Mike Isely Signed-off-by: Mike Isely --- .../drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h index 556628ad4..c6aa9751a 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h @@ -1,3 +1,24 @@ +/* + * + * $Id$ + * + * Copyright (C) 2007 Michael Krufky + * + * 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 + * + * 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 _PVRUSB2_FX2_CMD_H_ #define _PVRUSB2_FX2_CMD_H_ @@ -26,3 +47,13 @@ #define FX2CMD_GET_IR_CODE 0xec #endif /* _PVRUSB2_FX2_CMD_H_ */ + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 75 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ -- cgit v1.2.3 From aafc760ef56b4f913b2d26e8774e1b030d83f2f4 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 22 Jan 2007 18:31:53 -0800 Subject: Restore VIDIOC_INT_[SG]_REGISTER calls From: Trent Piepho Add support for these ioctls to the video_ioctl2 system and the cx88 driver. Signed-off-by: Trent Piepho --- linux/drivers/media/video/cx88/cx88-video.c | 17 ++++++++++++----- linux/drivers/media/video/videodev.c | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index 8a33b7e16..3ce9759c3 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -1666,10 +1666,12 @@ static int vidioc_s_frequency (struct file *file, void *priv, cx88_set_freq (core,f); } -#if 0 //ifdef CONFIG_VIDEO_ADV_DEBUG -static int vidioc_g_register (struct file *file, void *priv, - v4l2_register *reg) +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int vidioc_g_register (struct file *file, void *fh, + struct v4l2_register *reg) { + struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; + if (reg->i2c_id != 0) return -EINVAL; /* cx2388x has a 24-bit register space */ @@ -1678,8 +1680,9 @@ static int vidioc_g_register (struct file *file, void *priv, } static int vidioc_s_register (struct file *file, void *fh, - v4l2_register *reg) + struct v4l2_register *reg) { + struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core; if (reg->i2c_id != 0) return -EINVAL; @@ -1966,8 +1969,12 @@ static struct video_device cx8800_video_template = .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = vidioc_g_register, + .vidioc_s_register = vidioc_s_register, +#endif .tvnorms = CX88_NORMS, - .current_norm = V4L2_STD_NTSC_M, + .current_norm = V4L2_STD_NTSC_M, }; static struct file_operations radio_fops = diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index b0009fe0f..4789d7f2f 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -1477,6 +1477,22 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_log_status(file, fh); break; } +#ifdef CONFIG_VIDEO_ADV_DEBUG + case VIDIOC_INT_G_REGISTER: + { + struct v4l2_register *p=arg; + if (vfd->vidioc_g_register) + ret=vfd->vidioc_g_register(file, fh, p); + break; + } + case VIDIOC_INT_S_REGISTER: + { + struct v4l2_register *p=arg; + if (vfd->vidioc_s_register) + ret=vfd->vidioc_s_register(file, fh, p); + break; + } +#endif } /* switch */ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { -- cgit v1.2.3 From fec39e8fa9bf392d8bd4efad9143535f3b8fdf39 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 23 Jan 2007 21:04:13 -0200 Subject: Buf_qbuf: fix: videobuf_queue->stream corruption and lockup From: Oleg Nesterov We are doing ->buf_prepare(buf) before adding buf to q->stream list. This means that videobuf_qbuf() should not try to re-add a STATE_PREPARED buffer. Signed-off-by: Oleg Nesterov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/video-buf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/video-buf.c b/linux/drivers/media/video/video-buf.c index 6d6a74c60..4e359bc33 100644 --- a/linux/drivers/media/video/video-buf.c +++ b/linux/drivers/media/video/video-buf.c @@ -706,6 +706,7 @@ videobuf_qbuf(struct videobuf_queue *q, goto done; } if (buf->state == STATE_QUEUED || + buf->state == STATE_PREPARED || buf->state == STATE_ACTIVE) { dprintk(1,"qbuf: buffer is already queued or active.\n"); goto done; -- cgit v1.2.3 From 0f5b64e7c37c66e5cd7693eb7f9fc011e62eee33 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 23 Jan 2007 17:38:13 -0800 Subject: Make VIDIOC_INT_[SG]_REGISTER ioctls no longer internal only From: Trent Piepho The direct register access ioctls were defined as kernel internal only, but they are very useful for debugging hardware from userspace and are used as such. Officially export them. VIDIOC_INT_[SG]_REGISTER is renamed to VIDIOC_DBG_[SG]_REGISTER Definition of ioctl and struct v4l2_register is moved from v4l2-common.h to videodev2.h. Types used in struct v4l2_register are changed to the userspace exportable versions (u32 -> __u32, etc). Use of VIDIOC_DBG_S_REGISTER requires CAP_SYS_ADMIN permission, so move the check into the video_ioctl2() dispatcher so it doesn't need to be duplicated in each driver's call-back function. CAP_SYS_ADMIN check is added to pvrusb2 (which doesn't use video_ioctl2). Signed-off-by: Trent Piepho --- linux/drivers/media/video/cx25840/cx25840-core.c | 4 ++-- linux/drivers/media/video/cx88/cx88-video.c | 2 -- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 6 +++--- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h | 2 +- linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 14 +++++++++----- linux/drivers/media/video/saa7115.c | 4 ++-- linux/drivers/media/video/saa7127.c | 4 ++-- linux/drivers/media/video/tvp5150.c | 4 ++-- linux/drivers/media/video/upd64031a.c | 4 ++-- linux/drivers/media/video/upd64083.c | 4 ++-- linux/drivers/media/video/usbvision/usbvision-video.c | 12 ++++++------ linux/drivers/media/video/v4l2-common.c | 11 ++++++----- linux/drivers/media/video/videodev.c | 8 +++++--- 13 files changed, 42 insertions(+), 37 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index bd6a3d8fb..9aaaa482d 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -639,7 +639,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, #ifdef CONFIG_VIDEO_ADV_DEBUG /* ioctls to allow direct access to the * cx25840 registers for testing */ - case VIDIOC_INT_G_REGISTER: + case VIDIOC_DBG_G_REGISTER: { struct v4l2_register *reg = arg; @@ -649,7 +649,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, break; } - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index 3ce9759c3..ee3ef610e 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -1686,8 +1686,6 @@ static int vidioc_s_register (struct file *file, void *fh, if (reg->i2c_id != 0) return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; cx_write(reg->reg&0xffffff, reg->val); return 0; } diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index b07bd58ea..3b2d2f6ff 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -3390,7 +3390,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) int pvr2_hdw_register_access(struct pvr2_hdw *hdw, - u32 chip_id,unsigned long reg_id, + u32 chip_id, u32 reg_id, int setFl,u32 *val_ptr) { #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -3408,8 +3408,8 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw, cp = list_entry(item,struct pvr2_i2c_client,list); if (cp->client->driver->id != chip_id) continue; stat = pvr2_i2c_client_cmd( - cp,(setFl ? VIDIOC_INT_S_REGISTER : - VIDIOC_INT_G_REGISTER),&req); + cp,(setFl ? VIDIOC_DBG_S_REGISTER : + VIDIOC_DBG_G_REGISTER),&req); if (!setFl) *val_ptr = req.val; okFl = !0; break; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h index ab99bea88..9785ffcce 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -231,7 +231,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *, setFl - true to set the register, false to read it val_ptr - storage location for source / result. */ int pvr2_hdw_register_access(struct pvr2_hdw *, - u32 chip_id,unsigned long reg_id, + u32 chip_id,u32 reg_id, int setFl,u32 *val_ptr); /* The following entry points are all lower level things you normally don't diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 621a0dd31..e692ad5f7 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -739,16 +739,20 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, break; } #ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_S_REGISTER: + if (!capable(CAP_SYS_ADMIN)) { + ret = -EPERM; + break; + } /* fall through */ + case VIDIOC_DBG_G_REGISTER: { u32 val; struct v4l2_register *req = (struct v4l2_register *)arg; - if (cmd == VIDIOC_INT_S_REGISTER) val = req->val; + if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val; ret = pvr2_hdw_register_access( hdw,req->i2c_id,req->reg, - cmd == VIDIOC_INT_S_REGISTER,&val); - if (cmd == VIDIOC_INT_G_REGISTER) req->val = val; + cmd == VIDIOC_DBG_S_REGISTER,&val); + if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val; break; } #endif diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 462c5dd7f..cc8ea90fd 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -1428,7 +1428,7 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar } #ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: + case VIDIOC_DBG_G_REGISTER: { struct v4l2_register *reg = arg; @@ -1438,7 +1438,7 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar break; } - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; diff --git a/linux/drivers/media/video/saa7127.c b/linux/drivers/media/video/saa7127.c index f23f2799b..70d898697 100644 --- a/linux/drivers/media/video/saa7127.c +++ b/linux/drivers/media/video/saa7127.c @@ -626,7 +626,7 @@ static int saa7127_command(struct i2c_client *client, break; #ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: + case VIDIOC_DBG_G_REGISTER: { struct v4l2_register *reg = arg; @@ -636,7 +636,7 @@ static int saa7127_command(struct i2c_client *client, break; } - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index 1eb6e96bd..582c8542f 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -1046,7 +1046,7 @@ static int tvp5150_command(struct i2c_client *c, #endif #ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: + case VIDIOC_DBG_G_REGISTER: { struct v4l2_register *reg = arg; @@ -1056,7 +1056,7 @@ static int tvp5150_command(struct i2c_client *c, break; } - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; diff --git a/linux/drivers/media/video/upd64031a.c b/linux/drivers/media/video/upd64031a.c index 66254bad4..a35a21301 100644 --- a/linux/drivers/media/video/upd64031a.c +++ b/linux/drivers/media/video/upd64031a.c @@ -170,7 +170,7 @@ static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void * break; #ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: + case VIDIOC_DBG_G_REGISTER: { struct v4l2_register *reg = arg; @@ -180,7 +180,7 @@ static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void * break; } - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; u8 addr = reg->reg & 0xff; diff --git a/linux/drivers/media/video/upd64083.c b/linux/drivers/media/video/upd64083.c index 861d9b114..6b512c5d6 100644 --- a/linux/drivers/media/video/upd64083.c +++ b/linux/drivers/media/video/upd64083.c @@ -147,7 +147,7 @@ static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *a break; #ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: + case VIDIOC_DBG_G_REGISTER: { struct v4l2_register *reg = arg; @@ -157,7 +157,7 @@ static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *a break; } - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; u8 addr = reg->reg & 0xff; diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index d5e1b6b21..f23abaa27 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -560,7 +560,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, #ifdef CONFIG_VIDEO_ADV_DEBUG /* ioctls to allow direct acces to the NT100x registers */ - case VIDIOC_INT_G_REGISTER: + case VIDIOC_DBG_G_REGISTER: { struct v4l2_register *reg = arg; int errCode; @@ -570,17 +570,17 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, /* NT100x has a 8-bit register space */ errCode = usbvision_read_reg(usbvision, reg->reg&0xff); if (errCode < 0) { - err("%s: VIDIOC_INT_G_REGISTER failed: error %d", __FUNCTION__, errCode); + err("%s: VIDIOC_DBG_G_REGISTER failed: error %d", __FUNCTION__, errCode); } else { reg->val=(unsigned char)errCode; - PDEBUG(DBG_IOCTL, "VIDIOC_INT_G_REGISTER reg=0x%02X, value=0x%02X", + PDEBUG(DBG_IOCTL, "VIDIOC_DBG_G_REGISTER reg=0x%02X, value=0x%02X", (unsigned int)reg->reg, reg->val); errCode = 0; // No error } return errCode; } - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; int errCode; @@ -591,10 +591,10 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, return -EPERM; errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); if (errCode < 0) { - err("%s: VIDIOC_INT_S_REGISTER failed: error %d", __FUNCTION__, errCode); + err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", __FUNCTION__, errCode); } else { - PDEBUG(DBG_IOCTL, "VIDIOC_INT_S_REGISTER reg=0x%02X, value=0x%02X", + PDEBUG(DBG_IOCTL, "VIDIOC_DBG_S_REGISTER reg=0x%02X, value=0x%02X", (unsigned int)reg->reg, reg->val); errCode = 0; } diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 8fa62d5b4..231e671c1 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -421,9 +421,10 @@ static const char *v4l2_int_ioctls[] = { [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", [_IOC_NR(TDA9887_SET_CONFIG)] = "TDA9887_SET_CONFIG", + [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", + [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", + [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE", - [_IOC_NR(VIDIOC_INT_S_REGISTER)] = "VIDIOC_INT_S_REGISTER", - [_IOC_NR(VIDIOC_INT_G_REGISTER)] = "VIDIOC_INT_G_REGISTER", [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", @@ -785,11 +786,11 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) p->id,p->index,p->name); break; } - case VIDIOC_INT_G_REGISTER: - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_G_REGISTER: + case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *p=arg; - printk ("%s: i2c_id=%d, reg=%lu, val=%d\n", s, + printk ("%s: i2c_id=%d, reg=%d, val=%d\n", s, p->i2c_id,p->reg,p->val); break; diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index 4789d7f2f..476b3c143 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -1478,17 +1478,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, break; } #ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: + case VIDIOC_DBG_G_REGISTER: { struct v4l2_register *p=arg; if (vfd->vidioc_g_register) ret=vfd->vidioc_g_register(file, fh, p); break; } - case VIDIOC_INT_S_REGISTER: + case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *p=arg; - if (vfd->vidioc_s_register) + if (!capable(CAP_SYS_ADMIN)) + ret=-EPERM; + else if (vfd->vidioc_s_register) ret=vfd->vidioc_s_register(file, fh, p); break; } -- cgit v1.2.3 From 28765436e28b9c83d4b3f34dbaaa88c96aa2b324 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 25 Jan 2007 00:49:58 +0100 Subject: dvb-ttpci: Set phys, bustype, version, vendor and product for input device From: Matthias Schwarzott Add phys-string, bustype, version, vendor and product to help udev and others using EVIOCPHYS ioctl to identify the input device node. Code taken (with little changes) from budget-ci.c Signed-off-by: Matthias Schwarzott Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/av7110_ir.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/ttpci/av7110_ir.c b/linux/drivers/media/dvb/ttpci/av7110_ir.c index e4544ea2b..344ec1243 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_ir.c +++ b/linux/drivers/media/dvb/ttpci/av7110_ir.c @@ -16,6 +16,7 @@ static int av_cnt; static struct av7110 *av_list[4]; static struct input_dev *input_dev; +static char input_phys[32]; static u8 delay_timer_finished; @@ -231,8 +232,28 @@ int __devinit av7110_ir_init(struct av7110 *av7110) if (!input_dev) return -ENOMEM; + snprintf(input_phys, sizeof(input_phys), + "pci-%s/ir0", pci_name(av7110->dev->pci)); + input_dev->name = "DVB on-card IR receiver"; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + input_dev->phys = input_phys; + input_dev->id.bustype = BUS_PCI; + input_dev->id.version = 1; + if (av7110->dev->pci->subsystem_vendor) { + input_dev->id.vendor = av7110->dev->pci->subsystem_vendor; + input_dev->id.product = av7110->dev->pci->subsystem_device; + } else { + input_dev->id.vendor = av7110->dev->pci->vendor; + input_dev->id.product = av7110->dev->pci->device; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) + input_dev->cdev.dev = &av7110->dev->pci->dev; +#else + input_dev->dev = &av7110->dev->pci->dev; +#endif +#endif set_bit(EV_KEY, input_dev->evbit); set_bit(EV_REP, input_dev->evbit); input_register_keys(); -- cgit v1.2.3 From a17249c51910dd58481bf09e5eff56d6ec9d0dd4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Jan 2007 06:00:01 -0200 Subject: Make vivi driver to use vmalloced pointers From: Mauro Carvalho Chehab Before this patch, vivi were simulating a scatter gather DMA transfer. While this is academic, showing how stuff really works on a real PCI device, this means a non-optimized code. There are only two memory models that vivi implements: 1) kernel alloced memory. This is also used by read() method. On this case, a vmalloc32 buffer is allocated at kernel; 2) userspace allocated memory. This is used by most userspace apps. video-buf will store this pointer. a simple copy_to_user is enough to transfer data. The third memory model scenario supported by video-buf is overlay mode. This model is not implemented on vivi and unlikely to be implemented on newer drivers, since now, most userspace apps do some post-processing (like de-interlacing). After this patch, some cleanups may be done at video-buf.c to avoid allocating pages, when the driver doesn't need a PCI buffer. This is the case of vivi and usb drivers. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/video-buf.c | 3 ++ linux/drivers/media/video/vivi.c | 83 ++++++++++++++++++++++++++++++----- 2 files changed, 75 insertions(+), 11 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/video-buf.c b/linux/drivers/media/video/video-buf.c index 4e359bc33..a2251c7e3 100644 --- a/linux/drivers/media/video/video-buf.c +++ b/linux/drivers/media/video/video-buf.c @@ -149,6 +149,8 @@ int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction, dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n", data,size,dma->nr_pages); + dma->varea = (void *) data; + down_read(¤t->mm->mmap_sem); err = get_user_pages(current,current->mm, data & PAGE_MASK, dma->nr_pages, @@ -286,6 +288,7 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma) vfree(dma->vmalloc); dma->vmalloc = NULL; + dma->varea = NULL; if (dma->bus_addr) { dma->bus_addr = 0; diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index ddedd7fbb..1756ff277 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -150,7 +150,9 @@ struct vivi_buffer { struct vivi_fmt *fmt; +#ifdef CONFIG_VIVI_SCATTER struct sg_to_addr *to_addr; +#endif }; struct vivi_dmaqueue { @@ -239,6 +241,7 @@ static u8 bars[8][3] = { #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 #define TSTAMP_MIN_X 64 +#ifdef CONFIG_VIVI_SCATTER static void prep_to_addr(struct sg_to_addr to_addr[], struct videobuf_buffer *vb) { @@ -271,14 +274,24 @@ static int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) return (p1); } +#endif +#ifdef CONFIG_VIVI_SCATTER static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, int hmax, int line, char *timestr) +#else +static void gen_line(char *basep,int inipos,int wmax, + int hmax, int line, char *timestr) +#endif { - int w,i,j,pos=inipos,pgpos,oldpg,y; - char *p,*s,*basep; - struct page *pg; + int w,i,j,pos=inipos,y; + char *p,*s; u8 chr,r,g,b,color; +#ifdef CONFIG_VIVI_SCATTER + int pgpos,oldpg; + char *basep; + struct page *pg; + unsigned long flags; spinlock_t spinlock; @@ -289,6 +302,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, pg=pfn_to_page(sg_dma_address(to_addr[oldpg].sg) >> PAGE_SHIFT); spin_lock_irqsave(&spinlock,flags); basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset; +#endif /* We will just duplicate the second pixel at the packet */ wmax/=2; @@ -300,6 +314,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, b=bars[w*7/wmax][2]; for (color=0;color<4;color++) { +#ifdef CONFIG_VIVI_SCATTER pgpos=get_addr_pos(pos,pages,to_addr); if (pgpos!=oldpg) { pg=pfn_to_page(sg_dma_address(to_addr[pgpos].sg) >> PAGE_SHIFT); @@ -308,6 +323,9 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, oldpg=pgpos; } p=basep+pos-to_addr[pgpos].pos; +#else + p=basep+pos; +#endif switch (color) { case 0: @@ -352,6 +370,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, pos=inipos+j*2; for (color=0;color<4;color++) { +#ifdef CONFIG_VIVI_SCATTER pgpos=get_addr_pos(pos,pages,to_addr); if (pgpos!=oldpg) { pg=pfn_to_page(sg_dma_address( @@ -365,6 +384,9 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, oldpg=pgpos; } p=basep+pos-to_addr[pgpos].pos; +#else + p=basep+pos; +#endif y=TO_Y(r,g,b); @@ -401,19 +423,27 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, #endif end: +#ifdef CONFIG_VIVI_SCATTER kunmap_atomic(basep, KM_BOUNCE_READ); spin_unlock_irqrestore(&spinlock,flags); - +#else + return; +#endif } static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) { int h,pos=0; int hmax = buf->vb.height; int wmax = buf->vb.width; - struct videobuf_buffer *vb=&buf->vb; - struct sg_to_addr *to_addr=buf->to_addr; struct timeval ts; +#ifdef CONFIG_VIVI_SCATTER + struct sg_to_addr *to_addr=buf->to_addr; + struct videobuf_buffer *vb=&buf->vb; +#else + char *tmpbuf; +#endif +#ifdef CONFIG_VIVI_SCATTER /* Test if DMA mapping is ready */ if (!sg_dma_address(&vb->dma.sglist[0])) return; @@ -422,9 +452,27 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) /* Check if there is enough memory */ BUG_ON(buf->vb.dma.nr_pages << PAGE_SHIFT < (buf->vb.width*buf->vb.height)*2); +#else + if (buf->vb.dma.varea) { + tmpbuf=kmalloc (wmax*2, GFP_KERNEL); + } else { + tmpbuf=buf->vb.dma.vmalloc; + } + +#endif for (h=0;hdma.nr_pages,wmax,hmax,h,dev->timestr); +#else + if (buf->vb.dma.varea) { + gen_line(tmpbuf,0,wmax,hmax,h,dev->timestr); + /* FIXME: replacing to __copy_to_user */ + copy_to_user(buf->vb.dma.varea+pos,tmpbuf,wmax*2); + } else { + gen_line(tmpbuf,pos,wmax,hmax,h,dev->timestr); + } +#endif pos += wmax*2; } @@ -450,7 +498,7 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) dev->h,dev->m,dev->s,(dev->us+500)/1000); dprintk(2,"vivifill at %s: Buffer 0x%08lx size= %d\n",dev->timestr, - (unsigned long)buf->vb.dma.vmalloc,pos); + (unsigned long)buf->vb.dma.varea,pos); /* Advice that buffer was filled */ buf->vb.state = STATE_DONE; @@ -753,9 +801,11 @@ static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) if (in_interrupt()) BUG(); +#ifdef CONFIG_VIVI_SCATTER /*FIXME: Maybe a spinlock is required here */ kfree(buf->to_addr); buf->to_addr=NULL; +#endif videobuf_waiton(&buf->vb,0,0); videobuf_dma_unmap(vq, &buf->vb.dma); @@ -801,11 +851,12 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, buf->vb.state = STATE_PREPARED; +#ifdef CONFIG_VIVI_SCATTER if (NULL == (buf->to_addr = kmalloc(sizeof(*buf->to_addr) * vb->dma.nr_pages,GFP_KERNEL))) { rc=-ENOMEM; goto fail; } - +#endif return 0; fail: @@ -870,6 +921,7 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb free_buffer(vq,buf); } +#ifdef CONFIG_VIVI_SCATTER static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents, int direction) { @@ -902,6 +954,7 @@ static int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist, int nr_pages, // flush_write_buffers(); return 0; } +#endif static struct videobuf_queue_ops vivi_video_qops = { .buf_setup = buffer_setup, @@ -910,9 +963,9 @@ static struct videobuf_queue_ops vivi_video_qops = { .buf_release = buffer_release, /* Non-pci handling routines */ - .vb_map_sg = vivi_map_sg, - .vb_dma_sync_sg = vivi_dma_sync_sg, - .vb_unmap_sg = vivi_unmap_sg, +// .vb_map_sg = vivi_map_sg, +// .vb_dma_sync_sg = vivi_dma_sync_sg, +// .vb_unmap_sg = vivi_unmap_sg, }; /* ------------------------------------------------------------------ @@ -1296,11 +1349,19 @@ static int vivi_open(struct inode *inode, struct file *file) sprintf(dev->timestr,"%02d:%02d:%02d:%03d", dev->h,dev->m,dev->s,(dev->us+500)/1000); +#ifdef CONFIG_VIVI_SCATTER + videobuf_queue_init(&fh->vb_vidq,VIDEOBUF_DMA_SCATTER, &vivi_video_qops, + NULL, NULL, + fh->type, + V4L2_FIELD_INTERLACED, + sizeof(struct vivi_buffer),fh); +#else videobuf_queue_init(&fh->vb_vidq, &vivi_video_qops, NULL, NULL, fh->type, V4L2_FIELD_INTERLACED, sizeof(struct vivi_buffer),fh); +#endif return 0; } -- cgit v1.2.3 From 4bd72eba3f05017ab8ed5804badea8f707c66a63 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Jan 2007 09:09:32 -0200 Subject: Convert radio-aztech to use video_ioctl2 From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-aztech.c | 240 ++++++++++++++++--------------- 1 file changed, 122 insertions(+), 118 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/radio/radio-aztech.c b/linux/drivers/media/radio/radio-aztech.c index a59a6d209..c112b56e6 100644 --- a/linux/drivers/media/radio/radio-aztech.c +++ b/linux/drivers/media/radio/radio-aztech.c @@ -185,136 +185,129 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) return 0; } -static int az_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +static int vidioc_querycap (struct file *file, void *priv, + struct v4l2_capability *v) +{ + strlcpy(v->driver, "radio-aztech", sizeof (v->driver)); + strlcpy(v->card, "Aztech Radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; +} + +static int vidioc_g_tuner (struct file *file, void *priv, + struct v4l2_tuner *v) { struct video_device *dev = video_devdata(file); struct az_device *az = dev->priv; - switch(cmd) - { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *v = arg; - memset(v,0,sizeof(*v)); - strlcpy(v->driver, "radio-aztech", sizeof (v->driver)); - strlcpy(v->card, "Aztech Radio", sizeof (v->card)); - sprintf(v->bus_info,"ISA"); - v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER; + if (v->index > 0) + return -EINVAL; - return 0; - } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *v = arg; - - if (v->index > 0) - return -EINVAL; - - memset(v,0,sizeof(*v)); - strcpy(v->name, "FM"); - v->type = V4L2_TUNER_RADIO; - - v->rangelow=(87*16000); - v->rangehigh=(108*16000); - v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; - v->capability=V4L2_TUNER_CAP_LOW; - if(az_getstereo(az)) - v->audmode = V4L2_TUNER_MODE_STEREO; - else - v->audmode = V4L2_TUNER_MODE_MONO; - v->signal=0xFFFF*az_getsigstr(az); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; - return 0; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *v = arg; + v->rangelow=(87*16000); + v->rangehigh=(108*16000); + v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; + v->capability=V4L2_TUNER_CAP_LOW; + if(az_getstereo(az)) + v->audmode = V4L2_TUNER_MODE_STEREO; + else + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal=0xFFFF*az_getsigstr(az); - if (v->index > 0) - return -EINVAL; + return 0; +} - return 0; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; - az->curfreq = f->frequency; - az_setfreq(az, az->curfreq); - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; +static int vidioc_s_tuner (struct file *file, void *priv, + struct v4l2_tuner *v) +{ + if (v->index > 0) + return -EINVAL; - f->type = V4L2_TUNER_RADIO; - f->frequency = az->curfreq; + return 0; +} - return 0; - } +static int vidioc_s_frequency (struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct video_device *dev = video_devdata(file); + struct az_device *az = dev->priv; - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - int i; - - for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { - if (qc->id && qc->id == radio_qctrl[i].id) { - memcpy(qc, &(radio_qctrl[i]), - sizeof(*qc)); - return (0); - } - } - return -EINVAL; - } - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl= arg; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (az->curvol==0) - ctrl->value=1; - else - ctrl->value=0; - return (0); - case V4L2_CID_AUDIO_VOLUME: - ctrl->value=az->curvol * 6554; - return (0); - } - return -EINVAL; - } - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl= arg; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value) { - az_setvol(az,0); - } else { - az_setvol(az,az->curvol); - } - return (0); - case V4L2_CID_AUDIO_VOLUME: - az_setvol(az,ctrl->value); - return (0); - } - return -EINVAL; + az->curfreq = f->frequency; + az_setfreq(az, az->curfreq); + return 0; +} + +static int vidioc_g_frequency (struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct video_device *dev = video_devdata(file); + struct az_device *az = dev->priv; + + f->type = V4L2_TUNER_RADIO; + f->frequency = az->curfreq; + + return 0; +} + +static int vidioc_queryctrl (struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return (0); } + } + return -EINVAL; +} - default: - return v4l_compat_translate_ioctl(inode,file,cmd,arg, - az_do_ioctl); +static int vidioc_g_ctrl (struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct video_device *dev = video_devdata(file); + struct az_device *az = dev->priv; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (az->curvol==0) + ctrl->value=1; + else + ctrl->value=0; + return (0); + case V4L2_CID_AUDIO_VOLUME: + ctrl->value=az->curvol * 6554; + return (0); } + return -EINVAL; } -static int az_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int vidioc_s_ctrl (struct file *file, void *priv, + struct v4l2_control *ctrl) { - return video_usercopy(inode, file, cmd, arg, az_do_ioctl); + struct video_device *dev = video_devdata(file); + struct az_device *az = dev->priv; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + az_setvol(az,0); + } else { + az_setvol(az,az->curvol); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + az_setvol(az,ctrl->value); + return (0); + } + return -EINVAL; } static struct az_device aztech_unit; @@ -323,20 +316,31 @@ static struct file_operations aztech_fops = { .owner = THIS_MODULE, .open = video_exclusive_open, .release = video_exclusive_release, - .ioctl = az_ioctl, + .ioctl = video_ioctl2, .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; static struct video_device aztech_radio= { - .owner = THIS_MODULE, - .name = "Aztech radio", - .type = VID_TYPE_TUNER, - .hardware = 0, - .fops = &aztech_fops, + .owner = THIS_MODULE, + .name = "Aztech radio", + .type = VID_TYPE_TUNER, + .hardware = 0, + .fops = &aztech_fops, + .vidioc_querycap = vidioc_querycap, + .vidioc_g_tuner = vidioc_g_tuner, + .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_frequency = vidioc_g_frequency, + .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, }; +module_param_named(debug,aztech_radio.debug, int, 0644); +MODULE_PARM_DESC(debug,"activates debug info"); + static int __init aztech_init(void) { if(io==-1) -- cgit v1.2.3 From 7ee29011905386554334af7a069f6cefcfebf216 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Jan 2007 10:04:34 -0200 Subject: Convert radio-maxiradio to use video_ioctl2 From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-maxiradio.c | 252 +++++++++++++--------------- 1 file changed, 120 insertions(+), 132 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index 151f14232..686ea2e82 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -27,7 +27,9 @@ * BUGS: * - card unmutes if you change frequency * - * Converted to V4L2 API by Mauro Carvalho Chehab + * (c) 2006, 2007 by Mauro Carvalho Chehab : + * - Conversion to V4L2 API + * - Uses video_ioctl2 for parsing and to add debug support */ @@ -91,24 +93,14 @@ module_param(radio_nr, int, 0); #define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) -static int radio_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); - static struct file_operations maxiradio_fops = { .owner = THIS_MODULE, .open = video_exclusive_open, .release = video_exclusive_release, - .ioctl = radio_ioctl, + .ioctl = video_ioctl2, .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; -static struct video_device maxiradio_radio = -{ - .owner = THIS_MODULE, - .name = "Maxi Radio FM2000 radio", - .type = VID_TYPE_TUNER, - .fops = &maxiradio_fops, -}; static struct radio_device { @@ -189,155 +181,144 @@ static int get_tune(__u16 io) } -static inline int radio_function(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +static int vidioc_querycap (struct file *file, void *priv, + struct v4l2_capability *v) +{ + strlcpy(v->driver, "radio-maxiradio", sizeof (v->driver)); + strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + + return 0; +} + +static int vidioc_g_tuner (struct file *file, void *priv, + struct v4l2_tuner *v) { struct video_device *dev = video_devdata(file); struct radio_device *card=dev->priv; - switch(cmd) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *v = arg; - memset(v,0,sizeof(*v)); - strlcpy(v->driver, "radio-maxiradio", sizeof (v->driver)); - strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof (v->card)); - sprintf(v->bus_info,"ISA"); - v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER; + if (v->index > 0) + return -EINVAL; - return 0; - } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *v = arg; + memset(v,0,sizeof(*v)); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; - if (v->index > 0) - return -EINVAL; + v->rangelow=FREQ_LO; + v->rangehigh=FREQ_HI; + v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; + v->capability=V4L2_TUNER_CAP_LOW; + if(get_stereo(card->io)) + v->audmode = V4L2_TUNER_MODE_STEREO; + else + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal=0xffff*get_tune(card->io); - memset(v,0,sizeof(*v)); - strcpy(v->name, "FM"); - v->type = V4L2_TUNER_RADIO; + return 0; +} - v->rangelow=FREQ_LO; - v->rangehigh=FREQ_HI; - v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; - v->capability=V4L2_TUNER_CAP_LOW; - if(get_stereo(card->io)) - v->audmode = V4L2_TUNER_MODE_STEREO; - else - v->audmode = V4L2_TUNER_MODE_MONO; - v->signal=0xffff*get_tune(card->io); +static int vidioc_s_tuner (struct file *file, void *priv, + struct v4l2_tuner *v) +{ + if (v->index > 0) + return -EINVAL; - return 0; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *v = arg; + return 0; +} - if (v->index > 0) - return -EINVAL; +static int vidioc_s_frequency (struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct video_device *dev = video_devdata(file); + struct radio_device *card=dev->priv; - return 0; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; + if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) + return -EINVAL; - if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) - return -EINVAL; + card->freq = f->frequency; + set_freq(card->io, FREQ2BITS(card->freq)); + msleep(125); - card->freq = f->frequency; - set_freq(card->io, FREQ2BITS(card->freq)); - msleep(125); - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; + return 0; +} - f->type = V4L2_TUNER_RADIO; - f->frequency = card->freq; +static int vidioc_g_frequency (struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct video_device *dev = video_devdata(file); + struct radio_device *card=dev->priv; - return 0; - } - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - int i; - - for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { - if (qc->id && qc->id == radio_qctrl[i].id) { - memcpy(qc, &(radio_qctrl[i]), - sizeof(*qc)); - return (0); - } - } - return -EINVAL; - } - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl= arg; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value=card->muted; - return (0); - } - return -EINVAL; - } - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl= arg; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - card->muted = ctrl->value; - if(card->muted) - turn_power(card->io, 0); - else - set_freq(card->io, FREQ2BITS(card->freq)); - return 0; - } - return -EINVAL; - } + f->type = V4L2_TUNER_RADIO; + f->frequency = card->freq; - default: - return v4l_compat_translate_ioctl(inode,file,cmd,arg, - radio_function); + return 0; +} -#if 0 /* Probably, this is useless */ - case VIDIOCGUNIT: { - struct video_unit *v = arg; +static int vidioc_queryctrl (struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + int i; - v->video=VIDEO_NO_UNIT; - v->vbi=VIDEO_NO_UNIT; - v->radio=dev->minor; - v->audio=0; - v->teletext=VIDEO_NO_UNIT; - return 0; + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), sizeof(*qc)); + return (0); } -#endif } + return -EINVAL; } -static int radio_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int vidioc_g_ctrl (struct file *file, void *priv, + struct v4l2_control *ctrl) { struct video_device *dev = video_devdata(file); struct radio_device *card=dev->priv; - int ret; - mutex_lock(&card->lock); - ret = video_usercopy(inode, file, cmd, arg, radio_function); - mutex_unlock(&card->lock); - return ret; + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + ctrl->value=card->muted; + return (0); + } + return -EINVAL; } -MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net"); -MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio."); -MODULE_LICENSE("GPL"); +static int vidioc_s_ctrl (struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct video_device *dev = video_devdata(file); + struct radio_device *card=dev->priv; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + card->muted = ctrl->value; + if(card->muted) + turn_power(card->io, 0); + else + set_freq(card->io, FREQ2BITS(card->freq)); + return 0; + } + return -EINVAL; +} +static struct video_device maxiradio_radio = +{ + .owner = THIS_MODULE, + .name = "Maxi Radio FM2000 radio", + .type = VID_TYPE_TUNER, + .fops = &maxiradio_fops, + + .vidioc_querycap = vidioc_querycap, + .vidioc_g_tuner = vidioc_g_tuner, + .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_frequency = vidioc_g_frequency, + .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, + +}; static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -409,3 +390,10 @@ static void __exit maxiradio_radio_exit(void) module_init(maxiradio_radio_init); module_exit(maxiradio_radio_exit); + +MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net"); +MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio."); +MODULE_LICENSE("GPL"); + +module_param_named(debug,maxiradio_radio.debug, int, 0644); +MODULE_PARM_DESC(debug,"activates debug info"); -- cgit v1.2.3 From c369e78082f650bc897742b3b0d3ef65a52653bd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Jan 2007 16:00:45 -0200 Subject: Implement VIDIOC_[GS]_AUDIO on maxiradio From: Mauro Carvalho Chehab v4l1-compat requires those two ioctls to translate VIDIOC[SG]RADIO into V4L2 calls. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-maxiradio.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index 686ea2e82..14b74365d 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -228,6 +228,26 @@ static int vidioc_s_tuner (struct file *file, void *priv, return 0; } +static int vidioc_g_audio (struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; + return 0; +} + +static int vidioc_s_audio (struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index != 0) + return -EINVAL; + + return 0; +} + static int vidioc_s_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { @@ -312,6 +332,8 @@ static struct video_device maxiradio_radio = .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_audio = vidioc_g_audio, + .vidioc_s_audio = vidioc_s_audio, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, .vidioc_queryctrl = vidioc_queryctrl, -- cgit v1.2.3 From adac799136b064fd08852b7ea1ef826b3ed7a7bc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Jan 2007 16:10:31 -0200 Subject: Implement VIDIOC_[GS]_AUDIO on aztech From: Mauro Carvalho Chehab v4l1-compat requires those two ioctls to translate VIDIOC[SG]RADIO into V4L2 calls. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-aztech.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/radio/radio-aztech.c b/linux/drivers/media/radio/radio-aztech.c index c112b56e6..198eec12c 100644 --- a/linux/drivers/media/radio/radio-aztech.c +++ b/linux/drivers/media/radio/radio-aztech.c @@ -231,6 +231,26 @@ static int vidioc_s_tuner (struct file *file, void *priv, return 0; } +static int vidioc_g_audio (struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; + return 0; +} + +static int vidioc_s_audio (struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index != 0) + return -EINVAL; + + return 0; +} + static int vidioc_s_frequency (struct file *file, void *priv, struct v4l2_frequency *f) { @@ -331,6 +351,8 @@ static struct video_device aztech_radio= .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_audio = vidioc_g_audio, + .vidioc_s_audio = vidioc_s_audio, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, .vidioc_queryctrl = vidioc_queryctrl, -- cgit v1.2.3 From 58c028064ba2932404e856febb7b05779d9da39d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 25 Jan 2007 17:48:13 -0200 Subject: Implements VIDIOC_[S|G]_INPUT on radio-aztech and radio-maxiradio From: Mauro Carvalho Chehab fmtools use VIDIOCSTUNER, with, in turn, calls VIDIOC_S_INPUT on v4l1-compat. So, those ioctls are required for V4L1 to work properly. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-aztech.c | 32 +++++++++++++++++++++-------- linux/drivers/media/radio/radio-maxiradio.c | 16 +++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/radio/radio-aztech.c b/linux/drivers/media/radio/radio-aztech.c index 198eec12c..e622f3c91 100644 --- a/linux/drivers/media/radio/radio-aztech.c +++ b/linux/drivers/media/radio/radio-aztech.c @@ -186,7 +186,7 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency) } static int vidioc_querycap (struct file *file, void *priv, - struct v4l2_capability *v) + struct v4l2_capability *v) { strlcpy(v->driver, "radio-aztech", sizeof (v->driver)); strlcpy(v->card, "Aztech Radio", sizeof (v->card)); @@ -197,7 +197,7 @@ static int vidioc_querycap (struct file *file, void *priv, } static int vidioc_g_tuner (struct file *file, void *priv, - struct v4l2_tuner *v) + struct v4l2_tuner *v) { struct video_device *dev = video_devdata(file); struct az_device *az = dev->priv; @@ -223,7 +223,7 @@ static int vidioc_g_tuner (struct file *file, void *priv, static int vidioc_s_tuner (struct file *file, void *priv, - struct v4l2_tuner *v) + struct v4l2_tuner *v) { if (v->index > 0) return -EINVAL; @@ -242,6 +242,20 @@ static int vidioc_g_audio (struct file *file, void *priv, return 0; } +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +{ + if (i != 0) + return -EINVAL; + return 0; +} + + static int vidioc_s_audio (struct file *file, void *priv, struct v4l2_audio *a) { @@ -252,7 +266,7 @@ static int vidioc_s_audio (struct file *file, void *priv, } static int vidioc_s_frequency (struct file *file, void *priv, - struct v4l2_frequency *f) + struct v4l2_frequency *f) { struct video_device *dev = video_devdata(file); struct az_device *az = dev->priv; @@ -263,7 +277,7 @@ static int vidioc_s_frequency (struct file *file, void *priv, } static int vidioc_g_frequency (struct file *file, void *priv, - struct v4l2_frequency *f) + struct v4l2_frequency *f) { struct video_device *dev = video_devdata(file); struct az_device *az = dev->priv; @@ -275,7 +289,7 @@ static int vidioc_g_frequency (struct file *file, void *priv, } static int vidioc_queryctrl (struct file *file, void *priv, - struct v4l2_queryctrl *qc) + struct v4l2_queryctrl *qc) { int i; @@ -290,7 +304,7 @@ static int vidioc_queryctrl (struct file *file, void *priv, } static int vidioc_g_ctrl (struct file *file, void *priv, - struct v4l2_control *ctrl) + struct v4l2_control *ctrl) { struct video_device *dev = video_devdata(file); struct az_device *az = dev->priv; @@ -310,7 +324,7 @@ static int vidioc_g_ctrl (struct file *file, void *priv, } static int vidioc_s_ctrl (struct file *file, void *priv, - struct v4l2_control *ctrl) + struct v4l2_control *ctrl) { struct video_device *dev = video_devdata(file); struct az_device *az = dev->priv; @@ -353,6 +367,8 @@ static struct video_device aztech_radio= .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_audio = vidioc_g_audio, .vidioc_s_audio = vidioc_s_audio, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, .vidioc_queryctrl = vidioc_queryctrl, diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index 14b74365d..69e2b01a8 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -239,6 +239,20 @@ static int vidioc_g_audio (struct file *file, void *priv, return 0; } +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +{ + if (i != 0) + return -EINVAL; + return 0; +} + + static int vidioc_s_audio (struct file *file, void *priv, struct v4l2_audio *a) { @@ -334,6 +348,8 @@ static struct video_device maxiradio_radio = .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_audio = vidioc_g_audio, .vidioc_s_audio = vidioc_s_audio, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, .vidioc_queryctrl = vidioc_queryctrl, -- cgit v1.2.3 From a73c67dd5303662e84d02a4bfeaaf23f12daa0c0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 26 Jan 2007 08:07:12 -0200 Subject: Make it coherent with vidioc_g_tuner From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-maxiradio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index 69e2b01a8..bcb8b4d0e 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -234,7 +234,7 @@ static int vidioc_g_audio (struct file *file, void *priv, if (a->index > 1) return -EINVAL; - strcpy(a->name, "Radio"); + strcpy(a->name, "FM"); a->capability = V4L2_AUDCAP_STEREO; return 0; } -- cgit v1.2.3 From 0ef45ee3c01a3ceda41697593a278285008e2a5b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 26 Jan 2007 08:23:44 -0200 Subject: Add some debug info, depending on debug level From: Mauro Carvalho Chehab With debug>0, it will show mute/unmute and set frequency events with debug>=4, it will show get frequency events Also, some kernel CodingStyle fixes were done. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-maxiradio.c | 72 ++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 16 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index bcb8b4d0e..b0efc8a35 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -49,10 +49,18 @@ #include #include -#define DRIVER_VERSION "0.76" +#define DRIVER_VERSION "0.77" #include /* for KERNEL_VERSION MACRO */ -#define RADIO_VERSION KERNEL_VERSION(0,7,6) +#define RADIO_VERSION KERNEL_VERSION(0,7,7) + +static struct video_device maxiradio_radio; + +#define dprintk(num, fmt, arg...) \ + do { \ + if (maxiradio_radio.debug >= num) \ + printk(KERN_DEBUG "%s: " fmt, \ + maxiradio_radio.name, ## arg); } while (0) static struct v4l2_queryctrl radio_qctrl[] = { { @@ -87,8 +95,9 @@ module_param(radio_nr, int, 0); #define FREQ_IF 171200 /* 10.7*16000 */ #define FREQ_STEP 200 /* 12.5*16 */ -#define FREQ2BITS(x) ((( (unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\ - /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */ +/* (x==fmhz*16*1000) -> bits */ +#define FREQ2BITS(x) ((( (unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1)) \ + /(FREQ_STEP<<2))<<2) #define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) @@ -121,7 +130,7 @@ static struct radio_device static void outbit(unsigned long bit, __u16 io) { - if(bit != 0) + if (bit != 0) { outb( power|wren|data ,io); udelay(4); outb( power|wren|data|clk ,io); udelay(4); @@ -137,14 +146,20 @@ static void outbit(unsigned long bit, __u16 io) static void turn_power(__u16 io, int p) { - if(p != 0) outb(power, io); else outb(0,io); + if (p != 0) { + dprintk(1, "Radio powered on\n"); + outb(power, io); + } else { + dprintk(1, "Radio powered off\n"); + outb(0,io); + } } - -static void set_freq(__u16 io, __u32 data) +static void set_freq(__u16 io, __u32 freq) { unsigned long int si; int bl; + int data = FREQ2BITS(freq); /* TEA5757 shift register bits (see pdf) */ @@ -163,20 +178,31 @@ static void set_freq(__u16 io, __u32 data) outbit(0,io); // 16 search level si = 0x8000; - for(bl = 1; bl <= 16 ; bl++) { outbit(data & si,io); si >>=1; } + for (bl = 1; bl <= 16 ; bl++) { + outbit(data & si,io); + si >>=1; + } - outb(power,io); + dprintk(1, "Radio freq set to %d.%02d MHz\n", + freq / 16000, + freq % 16000 * 100 / 16000); + + turn_power(io, 1); } static int get_stereo(__u16 io) { - outb(power,io); udelay(4); + outb(power,io); + udelay(4); + return !(inb(io) & mo_st); } static int get_tune(__u16 io) { - outb(power+clk,io); udelay(4); + outb(power+clk,io); + udelay(4); + return !(inb(io) & mo_st); } @@ -242,6 +268,7 @@ static int vidioc_g_audio (struct file *file, void *priv, static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) { *i = 0; + return 0; } @@ -249,6 +276,7 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) { if (i != 0) return -EINVAL; + return 0; } @@ -268,11 +296,17 @@ static int vidioc_s_frequency (struct file *file, void *priv, struct video_device *dev = video_devdata(file); struct radio_device *card=dev->priv; - if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) + if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) { + dprintk(1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n", + f->frequency / 16000, + f->frequency % 16000 * 100 / 16000, + FREQ_LO / 16000, FREQ_HI / 16000); + return -EINVAL; + } card->freq = f->frequency; - set_freq(card->io, FREQ2BITS(card->freq)); + set_freq(card->io, card->freq); msleep(125); return 0; @@ -287,6 +321,10 @@ static int vidioc_g_frequency (struct file *file, void *priv, f->type = V4L2_TUNER_RADIO; f->frequency = card->freq; + dprintk(4, "radio freq is %d.%02d MHz", + f->frequency / 16000, + f->frequency % 16000 * 100 / 16000); + return 0; } @@ -301,6 +339,7 @@ static int vidioc_queryctrl (struct file *file, void *priv, return (0); } } + return -EINVAL; } @@ -315,6 +354,7 @@ static int vidioc_g_ctrl (struct file *file, void *priv, ctrl->value=card->muted; return (0); } + return -EINVAL; } @@ -330,9 +370,10 @@ static int vidioc_s_ctrl (struct file *file, void *priv, if(card->muted) turn_power(card->io, 0); else - set_freq(card->io, FREQ2BITS(card->freq)); + set_freq(card->io, card->freq); return 0; } + return -EINVAL; } @@ -355,7 +396,6 @@ static struct video_device maxiradio_radio = .vidioc_queryctrl = vidioc_queryctrl, .vidioc_g_ctrl = vidioc_g_ctrl, .vidioc_s_ctrl = vidioc_s_ctrl, - }; static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) -- cgit v1.2.3 From 2388ccb87f6cc5371a4aeb1de8a95334456e0a60 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 26 Jan 2007 08:33:07 -0200 Subject: Properly initialize mute and radio frequency From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-maxiradio.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index b0efc8a35..05d6aaef2 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -125,8 +125,10 @@ static struct radio_device #else struct semaphore lock; #endif -} radio_unit = {0, 0, 0, 0, }; - +} radio_unit = { + .muted =1, + .freq = FREQ_LO, +}; static void outbit(unsigned long bit, __u16 io) { @@ -413,7 +415,7 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d mutex_init(&radio_unit.lock); maxiradio_radio.priv = &radio_unit; - if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { + if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { printk("radio-maxiradio: can't register device!"); goto err_out_free_region; } -- cgit v1.2.3 From e0a51e2cfdd82572fdd034849b77ea060a346932 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 26 Jan 2007 09:30:05 -0200 Subject: Fix: dma free is being called with wrong arguments From: Michael Schimek Functions buffer_release() in bttv-driver.c and vbi_buffer_release() in bttv-vbi.c are ending with: bttv_dma_free(&fh->cap,fh->btv,buf); For vbi it seems to be wrong. Both functions should end with: bttv_dma_free(q,fh->btv,buf); Thanks to Peter Schlaf for pointing this. Signed-off-by: Michael H. Schimek Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/bt8xx/bttv-driver.c | 2 +- linux/drivers/media/video/bt8xx/bttv-vbi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index 118c6e800..4c813a4da 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -1905,7 +1905,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); struct bttv_fh *fh = q->priv_data; - bttv_dma_free(&fh->cap,fh->btv,buf); + bttv_dma_free(q,fh->btv,buf); } static struct videobuf_queue_ops bttv_video_qops = { diff --git a/linux/drivers/media/video/bt8xx/bttv-vbi.c b/linux/drivers/media/video/bt8xx/bttv-vbi.c index cac2273f7..689d79404 100644 --- a/linux/drivers/media/video/bt8xx/bttv-vbi.c +++ b/linux/drivers/media/video/bt8xx/bttv-vbi.c @@ -225,7 +225,7 @@ static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); dprintk("free %p\n",vb); - bttv_dma_free(&fh->cap,fh->btv,buf); + bttv_dma_free(q,fh->btv,buf); } struct videobuf_queue_ops bttv_vbi_qops = { -- cgit v1.2.3 From 8772195a9bcb958673b4770e8f26978663658f42 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sun, 28 Jan 2007 01:13:06 +0100 Subject: dvb-ttpci: Fixed unregistering the vbi device From: Oliver Endriss Fixed unregistering the vbi device for cards without analog tuner. Thanks to Marco Schluessler for pointing out this bug. Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/av7110.h | 1 - linux/drivers/media/dvb/ttpci/av7110_v4l.c | 9 ++------- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h index c1fe289d3..5fcdaa402 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.h +++ b/linux/drivers/media/dvb/ttpci/av7110.h @@ -39,7 +39,6 @@ #define ANALOG_TUNER_VES1820 1 #define ANALOG_TUNER_STV0297 2 -#define ANALOG_TUNER_VBI 0x100 extern int av7110_debug; diff --git a/linux/drivers/media/dvb/ttpci/av7110_v4l.c b/linux/drivers/media/dvb/ttpci/av7110_v4l.c index 10cfe3131..3c6f5fcdc 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/linux/drivers/media/dvb/ttpci/av7110_v4l.c @@ -818,20 +818,15 @@ int av7110_init_v4l(struct av7110 *av7110) saa7146_vv_release(dev); return -ENODEV; } - if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { + if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) ERR(("cannot register vbi v4l2 device. skipping.\n")); - } else { - if (av7110->analog_tuner_flags) - av7110->analog_tuner_flags |= ANALOG_TUNER_VBI; - } return 0; } int av7110_exit_v4l(struct av7110 *av7110) { saa7146_unregister_device(&av7110->v4l_dev, av7110->dev); - if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI) - saa7146_unregister_device(&av7110->vbi_dev, av7110->dev); + saa7146_unregister_device(&av7110->vbi_dev, av7110->dev); return 0; } -- cgit v1.2.3 From e47971a164355e16e5be9d82f5977b5525d2fe57 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 28 Jan 2007 12:38:55 -0600 Subject: pvrusb2: Control protocol cleanup From: Mike Isely Several special-case FX2 commands were being issued through pvr2_write_u16() and pvr2_write_8(), but there's really nothing special case about them. These date from a very early time in the driver development. This patch removes these functions and replaces their use with calls to pvr2_send_request. Signed-off-by: Mike Isely --- .../drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h | 3 ++ linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 50 ++++++---------------- 2 files changed, 15 insertions(+), 38 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h index c6aa9751a..ffbc6d096 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h @@ -29,6 +29,7 @@ #define FX2CMD_REG_WRITE 0x04 #define FX2CMD_REG_READ 0x05 +#define FX2CMD_MEMSEL 0x06 #define FX2CMD_I2C_WRITE 0x08 #define FX2CMD_I2C_READ 0x09 @@ -38,6 +39,8 @@ #define FX2CMD_STREAMING_ON 0x36 #define FX2CMD_STREAMING_OFF 0x37 +#define FX2CMD_FWPOST1 0x52 + #define FX2CMD_POWER_OFF 0xdc #define FX2CMD_POWER_ON 0xde diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 87384848b..7e6ac85b6 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -272,8 +272,6 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, unsigned int timeout,int probe_fl, void *write_data,unsigned int write_len, void *read_data,unsigned int read_len); -static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res); -static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res); static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) { @@ -1258,8 +1256,13 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ - ret |= pvr2_write_u8(hdw, 0x52, 0); - ret |= pvr2_write_u16(hdw, 0x0600, 0); + LOCK_TAKE(hdw->ctl_lock); do { + hdw->cmd_buffer[0] = FX2CMD_FWPOST1; + ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); + hdw->cmd_buffer[0] = FX2CMD_MEMSEL; + hdw->cmd_buffer[1] = 0; + ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0); + } while (0); LOCK_GIVE(hdw->ctl_lock); if (ret) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, @@ -1321,7 +1324,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ - ret |= pvr2_write_u16(hdw, 0x0600, 0); + LOCK_TAKE(hdw->ctl_lock); do { + hdw->cmd_buffer[0] = FX2CMD_MEMSEL; + hdw->cmd_buffer[1] = 0; + ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0); + } while (0); LOCK_GIVE(hdw->ctl_lock); if (ret) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, @@ -3129,39 +3136,6 @@ static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data) } -static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res) -{ - int ret; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = (data >> 8) & 0xff; - hdw->cmd_buffer[1] = data & 0xff; - - ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res) -{ - int ret; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = data; - - ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw) { if (!hdw->flag_ok) return; -- cgit v1.2.3 From 4d697b98a476c4492c271bd489c71a3faf55558d Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 28 Jan 2007 12:41:12 -0600 Subject: pvrusb2: encoder comm protocol cleanup From: Mike Isely Update the implementation of the communication protocol for operating the encoder, using updated knowledge about the encoder. Signed-off-by: Mike Isely --- .../drivers/media/video/pvrusb2/pvrusb2-encoder.c | 150 +++++++++++++-------- 1 file changed, 92 insertions(+), 58 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 80a624d0f..66217093b 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -36,34 +36,41 @@ #define IVTV_MBOX_DRIVER_DONE 0x00000002 #define IVTV_MBOX_DRIVER_BUSY 0x00000001 +#define MBOX_BASE 0x44 + static int pvr2_encoder_write_words(struct pvr2_hdw *hdw, + unsigned int offs, const u32 *data, unsigned int dlen) { - unsigned int idx; + unsigned int idx,addr; + unsigned int bAddr; int ret; - unsigned int offs = 0; unsigned int chunkCnt; /* Format: First byte must be 0x01. Remaining 32 bit words are - spread out into chunks of 7 bytes each, little-endian ordered, - offset at zero within each 2 blank bytes following and a - single byte that is 0x44 plus the offset of the word. Repeat - request for additional words, with offset adjusted - accordingly. + spread out into chunks of 7 bytes each, with the first 4 bytes + being the data word (little endian), and the next 3 bytes + being the address where that data word is to be written (big + endian). Repeat request for additional words, with offset + adjusted accordingly. */ while (dlen) { chunkCnt = 8; if (chunkCnt > dlen) chunkCnt = dlen; memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); - hdw->cmd_buffer[0] = FX2CMD_MEM_WRITE_DWORD; + bAddr = 0; + hdw->cmd_buffer[bAddr++] = FX2CMD_MEM_WRITE_DWORD; for (idx = 0; idx < chunkCnt; idx++) { - hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs; - PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7), - data[idx]); + addr = idx + offs; + hdw->cmd_buffer[bAddr+6] = (addr & 0xffu); + hdw->cmd_buffer[bAddr+5] = ((addr>>8) & 0xffu); + hdw->cmd_buffer[bAddr+4] = ((addr>>16) & 0xffu); + PVR2_DECOMPOSE_LE(hdw->cmd_buffer, bAddr,data[idx]); + bAddr += 7; } ret = pvr2_send_request(hdw, hdw->cmd_buffer,1+(chunkCnt*7), @@ -78,34 +85,42 @@ static int pvr2_encoder_write_words(struct pvr2_hdw *hdw, } -static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,int statusFl, +static int pvr2_encoder_read_words(struct pvr2_hdw *hdw, + unsigned int offs, u32 *data, unsigned int dlen) { unsigned int idx; int ret; - unsigned int offs = 0; unsigned int chunkCnt; /* Format: First byte must be 0x02 (status check) or 0x28 (read back block of 32 bit words). Next 6 bytes must be zero, - followed by a single byte of 0x44+offset for portion to be - read. Returned data is packed set of 32 bits words that were - read. + followed by a single byte of MBOX_BASE+offset for portion to + be read. Returned data is packed set of 32 bits words that + were read. */ while (dlen) { chunkCnt = 16; if (chunkCnt > dlen) chunkCnt = dlen; - memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); + if (chunkCnt < 16) chunkCnt = 1; hdw->cmd_buffer[0] = - (statusFl ? FX2CMD_MEM_READ_DWORD : FX2CMD_MEM_READ_64BYTES); - hdw->cmd_buffer[7] = 0x44 + offs; + ((chunkCnt == 1) ? + FX2CMD_MEM_READ_DWORD : FX2CMD_MEM_READ_64BYTES); + hdw->cmd_buffer[1] = 0; + hdw->cmd_buffer[2] = 0; + hdw->cmd_buffer[3] = 0; + hdw->cmd_buffer[4] = 0; + hdw->cmd_buffer[5] = ((offs>>16) & 0xffu); + hdw->cmd_buffer[6] = ((offs>>8) & 0xffu); + hdw->cmd_buffer[7] = (offs & 0xffu); ret = pvr2_send_request(hdw, hdw->cmd_buffer,8, - hdw->cmd_buffer,chunkCnt * 4); + hdw->cmd_buffer, + (chunkCnt == 1 ? 4 : 16 * 4)); if (ret) return ret; for (idx = 0; idx < chunkCnt; idx++) { @@ -132,6 +147,8 @@ static int pvr2_encoder_cmd(void *ctxt, u32 *argp) { unsigned int poll_count; + unsigned int try_count = 0; + int retry_flag; int ret = 0; unsigned int idx; /* These sizes look to be limited by the FX2 firmware implementation */ @@ -164,14 +181,15 @@ static int pvr2_encoder_cmd(void *ctxt, /* The encoder seems to speak entirely using blocks 32 bit words. - In ivtv driver terms, this is a mailbox which we populate with - data and watch what the hardware does with it. The first word - is a set of flags used to control the transaction, the second - word is the command to execute, the third byte is zero (ivtv - driver suggests that this is some kind of return value), and - the fourth byte is a specified timeout (windows driver always - uses 0x00060000 except for one case when it is zero). All - successive words are the argument words for the command. + In ivtv driver terms, this is a mailbox at MBOX_BASE which we + populate with data and watch what the hardware does with it. + The first word is a set of flags used to control the + transaction, the second word is the command to execute, the + third byte is zero (ivtv driver suggests that this is some + kind of return value), and the fourth byte is a specified + timeout (windows driver always uses 0x00060000 except for one + case when it is zero). All successive words are the argument + words for the command. First, write out the entire set of words, with the first word being zero. @@ -180,13 +198,10 @@ static int pvr2_encoder_cmd(void *ctxt, IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which probably means "go"). - Next, read back 16 words as status. Check the first word, + Next, read back the return count words. Check the first word, which should have IVTV_MBOX_FIRMWARE_DONE set. If however that bit is not set, then the command isn't done so repeat the - read. - - Next, read back 32 words and compare with the original - arugments. Hopefully they will match. + read until it is set. Finally, write out just the first word again, but set it to 0x0 this time (which probably means "idle"). @@ -216,6 +231,9 @@ static int pvr2_encoder_cmd(void *ctxt, LOCK_TAKE(hdw->ctl_lock); do { + retry_flag = 0; + try_count++; + ret = 0; wrData[0] = 0; wrData[1] = cmd; wrData[2] = 0; @@ -227,48 +245,64 @@ static int pvr2_encoder_cmd(void *ctxt, wrData[idx+4] = 0; } - ret = pvr2_encoder_write_words(hdw,wrData,idx); + ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,idx); if (ret) break; wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY; - ret = pvr2_encoder_write_words(hdw,wrData,1); + ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1); if (ret) break; poll_count = 0; while (1) { - if (poll_count < 10000000) poll_count++; - ret = pvr2_encoder_read_words(hdw,!0,rdData,1); - if (ret) break; + poll_count++; + ret = pvr2_encoder_read_words(hdw,MBOX_BASE,rdData, + arg_cnt_recv+4); + if (ret) { + break; + } if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) { break; } - if (poll_count == 100) { + if (rdData[0] && (poll_count < 1000)) continue; + if (!rdData[0]) { + retry_flag = !0; + pvr2_trace( + PVR2_TRACE_ERROR_LEGS, + "Encoder timed out waiting for us" + "; arranging to retry"); + } else { pvr2_trace( PVR2_TRACE_ERROR_LEGS, "***WARNING*** device's encoder" " appears to be stuck" " (status=0%08x)",rdData[0]); + } + pvr2_trace( + PVR2_TRACE_ERROR_LEGS, + "Encoder command: 0x%02x",cmd); + for (idx = 4; idx < arg_cnt_send; idx++) { pvr2_trace( PVR2_TRACE_ERROR_LEGS, - "Encoder command: 0x%02x",cmd); - for (idx = 4; idx < arg_cnt_send; idx++) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Encoder arg%d: 0x%08x", - idx-3,wrData[idx]); - } - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Giving up waiting." - " It is likely that" - " this is a bad idea..."); - ret = -EBUSY; - break; + "Encoder arg%d: 0x%08x", + idx-3,wrData[idx]); } + ret = -EBUSY; + break; + } + if (retry_flag) { + if (try_count < 20) continue; + pvr2_trace( + PVR2_TRACE_ERROR_LEGS, + "Too many retries..."); + ret = -EBUSY; + } + if (ret) { + pvr2_trace( + PVR2_TRACE_ERROR_LEGS, + "Giving up on command." + " It is likely that" + " this is a bad idea..."); + break; } - if (ret) break; wrData[0] = 0x7; - ret = pvr2_encoder_read_words( - hdw,0,rdData, ARRAY_SIZE(rdData)); - if (ret) break; #if 0 for (idx = 0; idx < args; idx++) { if (rdData[idx] != wrData[idx]) { @@ -285,7 +319,7 @@ static int pvr2_encoder_cmd(void *ctxt, } wrData[0] = 0x0; - ret = pvr2_encoder_write_words(hdw,wrData,1); + ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1); if (ret) break; } while(0); LOCK_GIVE(hdw->ctl_lock); -- cgit v1.2.3 From 8b4ce16d98330197e98a4fba5c0e753fd03de634 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 28 Jan 2007 12:42:56 -0600 Subject: pvrusb2: video corruption fixes From: Mike Isely Tweak the encoder setup in order to stop it from corrupting the video data when there is a disruption in the data flow (e.g. a channel change). Signed-off-by: Mike Isely --- .../drivers/media/video/pvrusb2/pvrusb2-encoder.c | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 66217093b..07bbe5c02 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -354,6 +354,73 @@ static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd, return pvr2_encoder_cmd(hdw,cmd,args,0,data); } + +/* This implements some extra setup for the encoder that seems to be + specific to the PVR USB2 hardware. */ +int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) +{ + int ret = 0; + int encMisc3Arg = 0; + +#ifdef notdef + /* This inexplicable bit happens in the Hauppage windows + driver (for both 24xxx and 29xxx devices). However I + currently see no difference in behavior with or without + this stuff. Leave this here as a note of its existence, + but don't use it. */ + LOCK_TAKE(hdw->ctl_lock); do { + u32 dat[1]; + dat[0] = 0x80000640; + pvr2_encoder_write_words(hdw,0x01fe,dat,1); + pvr2_encoder_write_words(hdw,0x023e,dat,1); + } while(0); LOCK_GIVE(hdw->ctl_lock); +#endif + + /* Mike Isely 26-Jan-2006 The windows driver + sends the following list of ENC_MISC commands (for both + 24xxx and 29xxx devices). Meanings are not entirely clear, + however without the ENC_MISC(3,1) command then we risk + random perpetual video corruption whenever the video input + breaks up for a moment (like when switching channels). */ + + +#ifdef notdef + /* This ENC_MISC(5,0) command seems to hurt 29xxx sync + performance on channel changes, but is not a problem on + 24xxx devices. */ + ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0); +#endif + + /* This ENC_MISC(3,encMisc3Arg) command is critical - without + it there will eventually be video corruption. Also, the + 29xxx case is strange - the Windows driver is passing 1 + regardless of device type but if we have 1 for 29xxx device + the video turns sluggish. */ + switch (hdw->hdw_type) { + case PVR2_HDW_TYPE_24XXX: encMisc3Arg = 1; break; + case PVR2_HDW_TYPE_29XXX: encMisc3Arg = 0; break; + default: break; + } + ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3, + encMisc3Arg,0,0); + + ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0); + +#ifdef notdef + /* This ENC_MISC(4,1) command is poisonous, so it is commented + out. But I'm leaving it here anyway to document its + existence in the Windows driver. The effect of this + command is that apps displaying the stream become sluggish + with stuttering video. */ + ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0); +#endif + + ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0); + ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0); + + return ret; +} + int pvr2_encoder_configure(struct pvr2_hdw *hdw) { int ret; @@ -368,6 +435,8 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) ret = 0; + ret |= pvr2_encoder_prep_config(hdw); + if (!ret) ret = pvr2_encoder_vcmd( hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0xf0, 0xf0); -- cgit v1.2.3 From fa3c54d7157ced7633dabdf681c21f139976f384 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 28 Jan 2007 13:08:36 -0600 Subject: pvrusb2: VIDIOC_DBG_[S|G]_REGISTER fixups From: Mike Isely Support 64 bit register IDs internally. Only allow root access to this API (for both set and get). Note that actual 64 bit access only becomes possible once the definition for v4l2_register is updated, but this change clears the way for it from the viewpoint of the pvrusb2 driver. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 4 +++- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h | 2 +- linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 4 ---- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 7e6ac85b6..06a840a47 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -3366,7 +3366,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) int pvr2_hdw_register_access(struct pvr2_hdw *hdw, - u32 chip_id, u32 reg_id, + u32 chip_id, u64 reg_id, int setFl,u32 *val_ptr) { #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -3376,6 +3376,8 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw, int stat = 0; int okFl = 0; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; + req.i2c_id = chip_id; req.reg = reg_id; if (setFl) req.val = *val_ptr; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 9785ffcce..aa45114ba 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -231,7 +231,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *, setFl - true to set the register, false to read it val_ptr - storage location for source / result. */ int pvr2_hdw_register_access(struct pvr2_hdw *, - u32 chip_id,u32 reg_id, + u32 chip_id,u64 reg_id, int setFl,u32 *val_ptr); /* The following entry points are all lower level things you normally don't diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 9bc03cfda..165c00f44 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -739,10 +739,6 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, } #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_S_REGISTER: - if (!capable(CAP_SYS_ADMIN)) { - ret = -EPERM; - break; - } /* fall through */ case VIDIOC_DBG_G_REGISTER: { u32 val; -- cgit v1.2.3 From 89d170b32b5620e4c3be940b825188493bd8f597 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 30 Jan 2007 17:47:18 -0800 Subject: Change VIDIOC_DBG_[SG]_REGISTER ioctls' register address to 64 bits From: Trent Piepho Maybe someday there will be a device with a register address space > 32-bits, or maybe an i2c device which uses a protocol > 4 bytes long to address its registers. Signed-off-by: Trent Piepho --- linux/drivers/media/video/v4l2-common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 231e671c1..26669ebde 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -786,15 +786,17 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) p->id,p->index,p->name); break; } +#ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *p=arg; - printk ("%s: i2c_id=%d, reg=%d, val=%d\n", s, - p->i2c_id,p->reg,p->val); + printk ("%s: i2c_id=%d, reg=%llu, val=%u\n", s, + p->i2c_id,(unsigned long long)p->reg,p->val); break; } +#endif case VIDIOC_REQBUFS: { struct v4l2_requestbuffers *p=arg; -- cgit v1.2.3 From 0b945b64fba3381dfc97c66722fe76193f0008d3 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 30 Jan 2007 18:25:41 -0800 Subject: Add checks for CAP_SYS_ADMIN to VIDIOC_DBG_G_REGISTER From: Trent Piepho Before, root privileges were only needed to set hardware registers, not to read them. On some hardware, reading from the wrong place at the wrong time can hang the machine. So, to be consistent, root privileges are required to read registers on all hardware. Signed-off-by: Trent Piepho --- linux/drivers/media/video/cx25840/cx25840-core.c | 14 +++----- linux/drivers/media/video/saa7115.c | 14 +++----- linux/drivers/media/video/saa7127.c | 14 +++----- linux/drivers/media/video/tvp5150.c | 14 +++----- linux/drivers/media/video/upd64031a.c | 16 +++------ linux/drivers/media/video/upd64083.c | 16 +++------ .../media/video/usbvision/usbvision-video.c | 40 ++++++++-------------- linux/drivers/media/video/videodev.c | 4 ++- 8 files changed, 41 insertions(+), 91 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index 9aaaa482d..b06553a1f 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -640,15 +640,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, /* ioctls to allow direct access to the * cx25840 registers for testing */ case VIDIOC_DBG_G_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_CX25840) - return -EINVAL; - reg->val = cx25840_read(client, reg->reg & 0x0fff); - break; - } - case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; @@ -657,7 +648,10 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff); + if (cmd == VIDIOC_DBG_G_REGISTER) + reg->val = cx25840_read(client, reg->reg & 0x0fff); + else + cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff); break; } #endif diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index cc8ea90fd..71e1cab45 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -1429,15 +1429,6 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_SAA711X) - return -EINVAL; - reg->val = saa711x_read(client, reg->reg & 0xff); - break; - } - case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; @@ -1446,7 +1437,10 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - saa711x_write(client, reg->reg & 0xff, reg->val & 0xff); + if (cmd == VIDIOC_DBG_G_REGISTER) + reg->val = saa711x_read(client, reg->reg & 0xff); + else + saa711x_write(client, reg->reg & 0xff, reg->val & 0xff); break; } #endif diff --git a/linux/drivers/media/video/saa7127.c b/linux/drivers/media/video/saa7127.c index 70d898697..e1e697579 100644 --- a/linux/drivers/media/video/saa7127.c +++ b/linux/drivers/media/video/saa7127.c @@ -627,15 +627,6 @@ static int saa7127_command(struct i2c_client *client, #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_SAA7127) - return -EINVAL; - reg->val = saa7127_read(client, reg->reg & 0xff); - break; - } - case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; @@ -644,7 +635,10 @@ static int saa7127_command(struct i2c_client *client, return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - saa7127_write(client, reg->reg & 0xff, reg->val & 0xff); + if (cmd == VIDIOC_DBG_G_REGISTER) + reg->val = saa7127_read(client, reg->reg & 0xff); + else + saa7127_write(client, reg->reg & 0xff, reg->val & 0xff); break; } #endif diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index 582c8542f..46b97d9b1 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -1047,15 +1047,6 @@ static int tvp5150_command(struct i2c_client *c, #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_TVP5150) - return -EINVAL; - reg->val = tvp5150_read(c, reg->reg & 0xff); - break; - } - case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; @@ -1064,7 +1055,10 @@ static int tvp5150_command(struct i2c_client *c, return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff); + if (cmd == VIDIOC_DBG_G_REGISTER) + reg->val = tvp5150_read(c, reg->reg & 0xff); + else + tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff); break; } #endif diff --git a/linux/drivers/media/video/upd64031a.c b/linux/drivers/media/video/upd64031a.c index a35a21301..ae0a843ff 100644 --- a/linux/drivers/media/video/upd64031a.c +++ b/linux/drivers/media/video/upd64031a.c @@ -171,26 +171,18 @@ static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void * #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_UPD64031A) - return -EINVAL; - reg->val = upd64031a_read(client, reg->reg & 0xff); - break; - } - case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; - u8 addr = reg->reg & 0xff; - u8 val = reg->val & 0xff; if (reg->i2c_id != I2C_DRIVERID_UPD64031A) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - upd64031a_write(client, addr, val); + if (cmd == VIDIOC_DBG_G_REGISTER) + reg->val = upd64031a_read(client, reg->reg & 0xff); + else + upd64031a_write(client, reg->reg & 0xff, reg->val & 0xff); break; } #endif diff --git a/linux/drivers/media/video/upd64083.c b/linux/drivers/media/video/upd64083.c index 6b512c5d6..61be85abd 100644 --- a/linux/drivers/media/video/upd64083.c +++ b/linux/drivers/media/video/upd64083.c @@ -148,26 +148,18 @@ static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *a #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_UPD64083) - return -EINVAL; - reg->val = upd64083_read(client, reg->reg & 0xff); - break; - } - case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; - u8 addr = reg->reg & 0xff; - u8 val = reg->val & 0xff; if (reg->i2c_id != I2C_DRIVERID_UPD64083) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - upd64083_write(client, addr, val); + if (cmd == VIDIOC_DBG_G_REGISTER) + reg->val = upd64083_read(client, reg->reg & 0xff); + else + upd64083_write(client, reg->reg & 0xff, reg->val & 0xff); break; } #endif diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index f23abaa27..2b8895d99 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -561,25 +561,6 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, #ifdef CONFIG_VIDEO_ADV_DEBUG /* ioctls to allow direct acces to the NT100x registers */ case VIDIOC_DBG_G_REGISTER: - { - struct v4l2_register *reg = arg; - int errCode; - - if (reg->i2c_id != 0) - return -EINVAL; - /* NT100x has a 8-bit register space */ - errCode = usbvision_read_reg(usbvision, reg->reg&0xff); - if (errCode < 0) { - err("%s: VIDIOC_DBG_G_REGISTER failed: error %d", __FUNCTION__, errCode); - } - else { - reg->val=(unsigned char)errCode; - PDEBUG(DBG_IOCTL, "VIDIOC_DBG_G_REGISTER reg=0x%02X, value=0x%02X", - (unsigned int)reg->reg, reg->val); - errCode = 0; // No error - } - return errCode; - } case VIDIOC_DBG_S_REGISTER: { struct v4l2_register *reg = arg; @@ -589,15 +570,22 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); + /* NT100x has a 8-bit register space */ + if (cmd == VIDIOC_DBG_G_REGISTER) + errCode = usbvision_read_reg(usbvision, reg->reg&0xff); + else + errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); if (errCode < 0) { - err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", __FUNCTION__, errCode); - } - else { - PDEBUG(DBG_IOCTL, "VIDIOC_DBG_S_REGISTER reg=0x%02X, value=0x%02X", - (unsigned int)reg->reg, reg->val); - errCode = 0; + err("%s: VIDIOC_DBG_%c_REGISTER failed: error %d", __FUNCTION__, + cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S', errCode); + return errCode; } + if (cmd == VIDIOC_DBG_S_REGISTER) + reg->val = (u8)errCode; + + PDEBUG(DBG_IOCTL, "VIDIOC_DBG_%c_REGISTER reg=0x%02X, value=0x%02X", + cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S', + (unsigned int)reg->reg, reg->val); return 0; } #endif diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index 476b3c143..707757237 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -1481,7 +1481,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_DBG_G_REGISTER: { struct v4l2_register *p=arg; - if (vfd->vidioc_g_register) + if (!capable(CAP_SYS_ADMIN)) + ret=-EPERM; + else if (vfd->vidioc_g_register) ret=vfd->vidioc_g_register(file, fh, p); break; } -- cgit v1.2.3 From fca7ef71fcb220fb867d2f6d7e2e691adfa51906 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 30 Jan 2007 18:25:46 -0800 Subject: compat: Handle input_register_device() change and some others From: Trent Piepho input_register_device() was changed to return an error code instead of being void in 2.6.15. Handle it with a macro wrapper in config.h. For this to work, linux/input.h must be included before config.h. This required some trivial header re-ordering in budget-ci.c and ttusb_dec.c. In kernel 2.6.15-rc1 a helper function called setup_timer() was added to linux/timer.h. Add to compat.h, but require that linux/timer.h be included first to give the definition of struct timer_list. A new 4GB DMA zone, __GFP_DMA32, was added in 2.6.15-rc2. Alias it to __GFP_DMA on older kernels. Handle another 2.6.15 "input_dev->dev to input_dev->cdev.dev" change for some recently added code in cinergyT2.c. Signed-off-by: Trent Piepho --- linux/drivers/media/dvb/cinergyT2/cinergyT2.c | 4 ++++ linux/drivers/media/dvb/ttpci/budget-ci.c | 8 ++------ linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c | 10 +++++----- linux/drivers/media/video/ir-kbd-i2c.c | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c index 0de98c3eb..4b092d7c2 100644 --- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -868,7 +868,11 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor; input_dev->id.product = cinergyt2->udev->descriptor.idProduct; input_dev->id.version = 1; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) input_dev->cdev.dev = &cinergyt2->udev->dev; +#else + input_dev->dev = &cinergyt2->udev->dev; +#endif err = input_register_device(input_dev); if (err) { diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index b100cb485..045d25541 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -29,8 +29,6 @@ * the project's page is at http://www.linuxtv.org/dvb/ */ -#include "budget.h" - #include #include #include @@ -39,6 +37,8 @@ #include #include +#include "budget.h" + #include "dvb_ca_en50221.h" #include "stv0299.h" #include "stv0297.h" @@ -267,15 +267,11 @@ static int msp430_ir_init(struct budget_ci *budget_ci) input_dev->timer.function = msp430_ir_keyup; input_dev->timer.data = (unsigned long) &budget_ci->ir; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) error = input_register_device(input_dev); if (error) { printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); goto out2; } -#else - input_register_device(input_dev); -#endif tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, (unsigned long) budget_ci); diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c index b1598680d..74a710019 100644 --- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -20,11 +20,6 @@ * */ -#include "compat.h" -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) -#include -#endif - #include #include #include @@ -38,6 +33,11 @@ #include #include +#include "compat.h" +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) +#include +#endif + #include "dmxdev.h" #include "dvb_demux.h" #include "dvb_filter.h" diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index 95566ff19..380766944 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -41,9 +41,9 @@ #include #include -#include "compat.h" #include #include +#include "compat.h" /* ----------------------------------------------------------------------- */ /* insmod parameters */ -- cgit v1.2.3 From ad0ae8dc8ffa884e357e5bf55c4808e24848559e Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 30 Jan 2007 18:26:01 -0800 Subject: Remove obsolete alias defines of CONFIG_* settings From: Trent Piepho The out of tree v4l-dvb build system didn't always override the kernel's configuration settings with v4l-dvb's settings correctly. To work around this, makefiles would define some new macro based on the setting of a config variable. e.g. the pwc Makefile would define CONFIG_PWC_DEBUG if CONFIG_USB_PWC_DEBUG (which is defined via Kconfig) was set. The v4l-dvb build system should now always override correctly, and this is no longer necessary. This patch gets ride of these extra defines and just uses the CONFIG_* settings directly. Signed-off-by: Trent Piepho --- linux/drivers/media/video/Makefile | 1 - linux/drivers/media/video/cx88/Makefile | 5 ----- linux/drivers/media/video/cx88/cx88-dvb.c | 10 +++++----- linux/drivers/media/video/cx88/cx88-i2c.c | 2 +- linux/drivers/media/video/cx88/cx88.h | 6 +++--- linux/drivers/media/video/pwc/Makefile | 8 -------- linux/drivers/media/video/pwc/pwc-if.c | 8 ++++---- linux/drivers/media/video/pwc/pwc-v4l.c | 2 +- linux/drivers/media/video/pwc/pwc.h | 9 ++------- linux/drivers/media/video/saa7134/Makefile | 4 ---- linux/drivers/media/video/saa7134/saa7134.h | 4 ++-- 11 files changed, 18 insertions(+), 41 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 9b1f3f06b..44ccaed40 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -113,4 +113,3 @@ obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/ obj-$(CONFIG_VIDEO_VIVI) += vivi.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT diff --git a/linux/drivers/media/video/cx88/Makefile b/linux/drivers/media/video/cx88/Makefile index 639c3b659..532cee35e 100644 --- a/linux/drivers/media/video/cx88/Makefile +++ b/linux/drivers/media/video/cx88/Makefile @@ -12,8 +12,3 @@ obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o EXTRA_CFLAGS += -Idrivers/media/video EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends - -extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 -extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1 - -EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c index 779317cc2..70f7f45a8 100644 --- a/linux/drivers/media/video/cx88/cx88-dvb.c +++ b/linux/drivers/media/video/cx88/cx88-dvb.c @@ -36,7 +36,7 @@ #include "mt352.h" #include "mt352_priv.h" -#ifdef HAVE_VP3054_I2C +#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) # include "cx88-vp3054-i2c.h" #endif #include "zl10353.h" @@ -201,7 +201,7 @@ static struct mt352_config dvico_fusionhdtv_dual = { .demod_init = dvico_dual_demod_init, }; -#ifdef HAVE_VP3054_I2C +#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) { static u8 clock_config [] = { 0x89, 0x38, 0x38 }; @@ -544,7 +544,7 @@ static int dvb_register(struct cx8802_dev *dev) } break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: -#ifdef HAVE_VP3054_I2C +#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_fmd1216me; dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, @@ -797,7 +797,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB)) goto fail_core; -#ifdef HAVE_VP3054_I2C +#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) err = vp3054_i2c_probe(dev); if (0 != err) goto fail_core; @@ -826,7 +826,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) /* dvb */ videobuf_dvb_unregister(&dev->dvb); -#ifdef HAVE_VP3054_I2C +#if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) vp3054_i2c_remove(dev); #endif diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c index da24a0a56..2f60c957b 100644 --- a/linux/drivers/media/video/cx88/cx88-i2c.c +++ b/linux/drivers/media/video/cx88/cx88-i2c.c @@ -154,7 +154,7 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) if (0 != core->i2c_rc) return; -#ifdef HAVE_VIDEO_BUF_DVB +#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) { if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h index 5bb190eb2..ddd2c2fe9 100644 --- a/linux/drivers/media/video/cx88/cx88.h +++ b/linux/drivers/media/video/cx88/cx88.h @@ -31,7 +31,7 @@ #include #include #include -#ifdef HAVE_VIDEO_BUF_DVB +#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) #include #endif #include "compat.h" @@ -321,7 +321,7 @@ struct cx88_core { unsigned int tuner_formats; /* config info -- dvb */ -#ifdef HAVE_VIDEO_BUF_DVB +#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) struct dvb_pll_desc *pll_desc; unsigned int pll_addr; int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); @@ -497,7 +497,7 @@ struct cx8802_dev { int width; int height; -#ifdef HAVE_VIDEO_BUF_DVB +#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) /* for dvb only */ struct videobuf_dvb dvb; void* fe_handle; diff --git a/linux/drivers/media/video/pwc/Makefile b/linux/drivers/media/video/pwc/Makefile index 9db2260d1..f5c8ec261 100644 --- a/linux/drivers/media/video/pwc/Makefile +++ b/linux/drivers/media/video/pwc/Makefile @@ -2,11 +2,3 @@ pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-v4l.o pwc-uncompress.o pwc-objs += pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o obj-$(CONFIG_USB_PWC) += pwc.o - -ifeq ($(CONFIG_USB_PWC_DEBUG),y) -EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=1 -else -EXTRA_CFLAGS += -DCONFIG_PWC_DEBUG=0 -endif - - diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c index 39aca8e12..444148f02 100644 --- a/linux/drivers/media/video/pwc/pwc-if.c +++ b/linux/drivers/media/video/pwc/pwc-if.c @@ -128,7 +128,7 @@ static int default_size = PSZ_QCIF; static int default_fps = 10; static int default_fbufs = 3; /* Default number of frame buffers */ int pwc_mbufs = 2; /* Default number of mmap() buffers */ -#if CONFIG_PWC_DEBUG +#ifdef CONFIG_USB_PWC_DEBUG int pwc_trace = PWC_DEBUG_LEVEL; #endif static int power_save = 0; @@ -1088,7 +1088,7 @@ static void pwc_remove_sysfs_files(struct video_device *vdev) video_device_remove_file(vdev, &class_device_attr_button); } -#if CONFIG_PWC_DEBUG +#ifdef CONFIG_USB_PWC_DEBUG static const char *pwc_sensor_type_to_string(unsigned int sensor_type) { switch(sensor_type) { @@ -1887,7 +1887,7 @@ module_param(size, charp, 0444); module_param(fps, int, 0444); module_param(fbufs, int, 0444); module_param(mbufs, int, 0444); -#if CONFIG_PWC_DEBUG +#ifdef CONFIG_USB_PWC_DEBUG module_param_named(trace, pwc_trace, int, 0644); #endif module_param(power_save, int, 0444); @@ -1965,7 +1965,7 @@ static int __init usb_pwc_init(void) default_fbufs = fbufs; PWC_DEBUG_MODULE("Number of frame buffers set to %d.\n", default_fbufs); } -#if CONFIG_PWC_DEBUG +#ifdef CONFIG_USB_PWC_DEBUG if (pwc_trace >= 0) { PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace); } diff --git a/linux/drivers/media/video/pwc/pwc-v4l.c b/linux/drivers/media/video/pwc/pwc-v4l.c index bd918b87c..2d5bb48f3 100644 --- a/linux/drivers/media/video/pwc/pwc-v4l.c +++ b/linux/drivers/media/video/pwc/pwc-v4l.c @@ -352,7 +352,7 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file, if (pdev == NULL) return -EFAULT; -#if CONFIG_PWC_DEBUG +#ifdef CONFIG_USB_PWC_DEBUG if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) v4l_printk_ioctl(cmd); #endif diff --git a/linux/drivers/media/video/pwc/pwc.h b/linux/drivers/media/video/pwc/pwc.h index 7e9c4237d..e778a2b8c 100644 --- a/linux/drivers/media/video/pwc/pwc.h +++ b/linux/drivers/media/video/pwc/pwc.h @@ -39,11 +39,6 @@ #include "pwc-uncompress.h" #include -/* Turn some debugging options on/off */ -#ifndef CONFIG_PWC_DEBUG -#define CONFIG_PWC_DEBUG 1 -#endif - /* Version block */ #define PWC_MAJOR 10 #define PWC_MINOR 0 @@ -76,7 +71,7 @@ #define PWC_DEBUG_TRACE(fmt, args...) PWC_DEBUG(TRACE, fmt, ##args) -#if CONFIG_PWC_DEBUG +#ifdef CONFIG_USB_PWC_DEBUG #define PWC_DEBUG_LEVEL (PWC_DEBUG_LEVEL_MODULE) @@ -270,7 +265,7 @@ extern "C" { #endif /* Global variables */ -#if CONFIG_PWC_DEBUG +#ifdef CONFIG_USB_PWC_DEBUG extern int pwc_trace; #endif extern int pwc_mbufs; diff --git a/linux/drivers/media/video/saa7134/Makefile b/linux/drivers/media/video/saa7134/Makefile index 89a1565b4..c85c8a8ec 100644 --- a/linux/drivers/media/video/saa7134/Makefile +++ b/linux/drivers/media/video/saa7134/Makefile @@ -14,7 +14,3 @@ obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o EXTRA_CFLAGS += -Idrivers/media/video EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends - -extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 - -EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 764bd4e71..42fa1c7b7 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -48,7 +48,7 @@ #include #include #endif -#ifdef HAVE_VIDEO_BUF_DVB +#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) #include #endif @@ -555,7 +555,7 @@ struct saa7134_dev { struct work_struct empress_workqueue; int empress_started; -#ifdef HAVE_VIDEO_BUF_DVB +#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) /* SAA7134_MPEG_DVB only */ struct videobuf_dvb dvb; int (*original_demod_sleep)(struct dvb_frontend* fe); -- cgit v1.2.3 From 21cff97b36ee2df7ef06430191da60bcfbfe05f1 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 31 Jan 2007 18:27:55 +0100 Subject: saa7146_vv: pass correct memory size to pci_free_consistent From: Marco Schluessler Pass correct memory size to pci_free_consistent. Signed-off-by: Marco Schluessler Signed-off-by: Oliver Endriss --- linux/drivers/media/common/saa7146_fops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c index da82d6823..6b429ff37 100644 --- a/linux/drivers/media/common/saa7146_fops.c +++ b/linux/drivers/media/common/saa7146_fops.c @@ -509,7 +509,7 @@ int saa7146_vv_release(struct saa7146_dev* dev) DEB_EE(("dev:%p\n",dev)); - pci_free_consistent(dev->pci, SAA7146_RPS_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); + pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); kfree(vv); dev->vv_data = NULL; dev->vv_callback = NULL; -- cgit v1.2.3 From 409d9f8dedae8011ee2694296dc8ffe61812a4a2 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 31 Jan 2007 18:32:29 +0100 Subject: dvb-ttpci: call saa7146_vv_release() on exit From: Marco Schluessler Call saa7146_vv_release() on exit. Signed-off-by: Marco Schluessler Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/av7110_v4l.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/ttpci/av7110_v4l.c b/linux/drivers/media/dvb/ttpci/av7110_v4l.c index 3c6f5fcdc..0510a80f2 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/linux/drivers/media/dvb/ttpci/av7110_v4l.c @@ -825,8 +825,13 @@ int av7110_init_v4l(struct av7110 *av7110) int av7110_exit_v4l(struct av7110 *av7110) { + struct saa7146_dev* dev = av7110->dev; + saa7146_unregister_device(&av7110->v4l_dev, av7110->dev); saa7146_unregister_device(&av7110->vbi_dev, av7110->dev); + + saa7146_vv_release(dev); + return 0; } -- cgit v1.2.3 From 36c59f9e8c39e5cb43d2da21c017075ea9cfa6a1 Mon Sep 17 00:00:00 2001 From: <> Date: Fri, 2 Feb 2007 13:24:56 -0200 Subject: Http://linuxtv.org/hg/~mcisely/pvrusb2 From: Mauro Carvalho Chehab Follows the same coding style for commented code The latest patch series added a different way of commenting unused patches: #ifdef notdef But V4L/DVB coding style uses, instead: #if 0 This have also the advantage of not sending to mainstream those development codes that doesn't make sense at a production environment, while keeping them under development trees. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mike isely --- linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 07bbe5c02..b46316fb3 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -362,7 +362,7 @@ int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) int ret = 0; int encMisc3Arg = 0; -#ifdef notdef +#if 0 /* This inexplicable bit happens in the Hauppage windows driver (for both 24xxx and 29xxx devices). However I currently see no difference in behavior with or without @@ -384,7 +384,7 @@ int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) breaks up for a moment (like when switching channels). */ -#ifdef notdef +#if 0 /* This ENC_MISC(5,0) command seems to hurt 29xxx sync performance on channel changes, but is not a problem on 24xxx devices. */ @@ -406,7 +406,7 @@ int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0); -#ifdef notdef +#if 0 /* This ENC_MISC(4,1) command is poisonous, so it is commented out. But I'm leaving it here anyway to document its existence in the Windows driver. The effect of this -- cgit v1.2.3 From eeb2d15e79aeabf08344067463107020c173a427 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 21 Jan 2007 21:22:18 -0500 Subject: dvb-usb: Register the bus, vendor and product IDs for remote device From: Chris Rankin This patch writes the USB vendor and product IDs into the /sys/class/input/inputX/id/ files, so that udev can find them. A rule like this does the trick for me: KERNEL="event*", SYSFS{../id/vendor}=="2040", SYSFS{../id/product}=="9301", SYMLINK+="input/dvb-remote" Signed-off-by: Chris Rankin Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 1a86adbfa..1bee5dfad 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -125,6 +125,9 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) input_dev->keycodemax = KEY_MAX; input_dev->name = "IR-receiver inside an USB DVB receiver"; input_dev->phys = d->rc_phys; + input_dev->id.bustype = BUS_USB; + input_dev->id.vendor = d->udev->descriptor.idVendor; + input_dev->id.product = d->udev->descriptor.idProduct; usb_to_input_id(d->udev, &input_dev->id); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) input_dev->cdev.dev = &d->udev->dev; -- cgit v1.2.3 From 689e43512980c5225bd47090dbf7690a250ae8f0 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 22 Jan 2007 16:33:07 -0500 Subject: proper vendor/device ID for the CinergyT2 input device From: Tino Keitel I noticed that udev does not create a symlink for the CinergyT2 remote input device in /dev/input/by-id, which is required if I want to have a unique device name for lircd. The attached patch tries to achive this. However, udev still omits the input device for /dev/input/by-id symlinks. I think something is still not reported correctly. Signed-off-by: Tino Keitel Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/cinergyT2/cinergyT2.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c index 9c0eff865..0de98c3eb 100644 --- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -864,6 +864,11 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) set_bit(rc_keys[i + 2], input_dev->keybit); input_dev->keycodesize = 0; input_dev->keycodemax = 0; + input_dev->id.bustype = BUS_USB; + input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor; + input_dev->id.product = cinergyt2->udev->descriptor.idProduct; + input_dev->id.version = 1; + input_dev->cdev.dev = &cinergyt2->udev->dev; err = input_register_device(input_dev); if (err) { -- cgit v1.2.3 From 77011ec8224d6aed14d6c68980dbda0b2fe3540c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 23 Sep 2006 19:00:41 -0400 Subject: dvb-usb: Initial support for MSI Mega Sky 580 based on Uli m9206 From: Aapo Tahkola Currently, the driver works in bulk mode supporting both USB 2.0 and 1.0 with and without hardware pid filters. The ULi m9205 also supports isochronous transfer mode, but I have dropped support for it because it depends on firmware and does not work on all USB host chips. Further, I have no firmware with remote controller support for this mode. Signed-off-by: Aapo Tahkola Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 10 + linux/drivers/media/dvb/dvb-usb/Makefile | 3 + linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 + linux/drivers/media/dvb/dvb-usb/megasky.c | 696 ++++++++++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/megasky.h | 10 + 5 files changed, 721 insertions(+) create mode 100644 linux/drivers/media/dvb/dvb-usb/megasky.c create mode 100644 linux/drivers/media/dvb/dvb-usb/megasky.h (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index ad5214360..5f2a0c1dc 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -109,6 +109,16 @@ config DVB_USB_CXUSB Medion MD95700 hybrid USB2.0 device. DViCO FusionHDTV (Bluebird) USB2.0 devices +config DVB_USB_MEGASKY + tristate "MSI Mega Sky 580 DVB-T USB2.0 support" + depends on DVB_USB + select DVB_MT352 + help + Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. + Currently, only devices with a product id of + "DTV USB MINI" (in cold state) are supported. + Firmware required. + config DVB_USB_DIGITV tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" depends on DVB_USB diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile index 154d593bb..d1e4f1cd8 100644 --- a/linux/drivers/media/dvb/dvb-usb/Makefile +++ b/linux/drivers/media/dvb/dvb-usb/Makefile @@ -30,6 +30,9 @@ obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2 dvb-usb-umt-010-objs = umt-010.o obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o +dvb-usb-megasky-objs = megasky.o +obj-$(CONFIG_DVB_USB_MEGASKY) += dvb-usb-megasky.o + dvb-usb-digitv-objs = digitv.o obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 299382dcb..713ec5a82 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -29,6 +29,7 @@ #define USB_VID_LEADTEK 0x0413 #define USB_VID_LITEON 0x04ca #define USB_VID_MEDION 0x1660 +#define USB_VID_MSI 0x0db0 #define USB_VID_PINNACLE 0x2304 #define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_TWINHAN 0x1822 @@ -119,6 +120,7 @@ #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54 #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM 0xdb55 #define USB_PID_MEDION_MD95700 0x0932 +#define USB_PID_MSI_MEGASKY580 0x5580 #define USB_PID_KYE_DVB_T_COLD 0x701e #define USB_PID_KYE_DVB_T_WARM 0x701f #define USB_PID_PCTV_200E 0x020e diff --git a/linux/drivers/media/dvb/dvb-usb/megasky.c b/linux/drivers/media/dvb/dvb-usb/megasky.c new file mode 100644 index 000000000..73e309cb8 --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/megasky.c @@ -0,0 +1,696 @@ +/* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver + * + * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "megasky.h" + +#include "mt352.h" +#include "mt352_priv.h" + +/* debug */ +int dvb_usb_megasky_debug; +module_param_named(debug,dvb_usb_megasky_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); + +static struct dvb_usb_rc_key megasky_rc_keys [] = { + { 0x0, 0x12, KEY_POWER }, + { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */ + { 0x0, 0x02, KEY_CHANNELUP }, + { 0x0, 0x05, KEY_CHANNELDOWN }, + { 0x0, 0x03, KEY_VOLUMEUP }, + { 0x0, 0x06, KEY_VOLUMEDOWN }, + { 0x0, 0x04, KEY_MUTE }, + { 0x0, 0x07, KEY_OK }, /* TS */ + { 0x0, 0x08, KEY_STOP }, + { 0x0, 0x09, KEY_MENU }, /* swap */ + { 0x0, 0x0a, KEY_REWIND }, + { 0x0, 0x1b, KEY_PAUSE }, + { 0x0, 0x1f, KEY_FASTFORWARD }, + { 0x0, 0x0c, KEY_RECORD }, + { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */ + { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */ +}; + +static inline int m9206_read(struct usb_device *udev, u8 request, u16 value, u16 index, void *data, int size) +{ + int ret; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + request, USB_TYPE_VENDOR | USB_DIR_IN, + value, index, data, size, 2000); + if (ret < 0) + return ret; + + if (ret != size) + return -EIO; + + return 0; +} + +static inline int m9206_write(struct usb_device *udev, u8 request, u16 value, u16 index) +{ + int ret; + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + request, USB_TYPE_VENDOR | USB_DIR_OUT, + value, index, NULL, 0, 2000); + msleep(3); + + return ret; +} + +static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + int i, ret = 0; + u8 rc_state[2]; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + if ((ret = m9206_read(d->udev, 0x22, 0x0, 0xff51, rc_state, 1)) != 0) + goto unlock; + + if ((ret = m9206_read(d->udev, 0x22, 0x0, 0xff52, rc_state + 1, 1)) != 0) + goto unlock; + + for (i = 0; i < ARRAY_SIZE(megasky_rc_keys); i++) + if (megasky_rc_keys[i].data == rc_state[1]) { + *event = megasky_rc_keys[i].event; + + switch(rc_state[0]) { + case 0x80: + *state = REMOTE_NO_KEY_PRESSED; + goto unlock; + + case 0x93: + case 0x92: + *state = REMOTE_KEY_PRESSED; + goto unlock; + + case 0x91: + *state = REMOTE_KEY_REPEAT; + goto unlock; + + default: + deb_rc("Unexpected rc response %x\n", rc_state[0]); + *state = REMOTE_NO_KEY_PRESSED; + goto unlock; + } + } + + if (rc_state[1] != 0) + deb_rc("Unknown rc key %x\n", rc_state[1]); + + *state = REMOTE_NO_KEY_PRESSED; + + unlock: + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +/* I2C */ + +static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i; + int ret = 0; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + if (num > 2) + return -EINVAL; + + for (i = 0; i < num; i++) { + u8 w_len; + + if ((ret = m9206_write(d->udev, 0x23, msg[i].addr, 0x80)) != 0) + goto unlock; + + if ((ret = m9206_write(d->udev, 0x23, msg[i].buf[0], 0x0)) != 0) + goto unlock; + + if (i + 1 < num && msg[i + 1].flags & I2C_M_RD) { + if (msg[i].addr == 0x1e) + w_len = 0x1f; + else + w_len = 0xc5; + + if ((ret = m9206_write(d->udev, 0x23, w_len, 0x80)) != 0) + goto unlock; + + if ((ret = m9206_read(d->udev, 0x23, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0) + goto unlock; + + i++; + } else { + if (msg[i].len != 2) + return -EINVAL; + + if ((ret = m9206_write(d->udev, 0x23, msg[i].buf[1], 0x40)) != 0) + goto unlock; + } + } + ret = i; + unlock: + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +static u32 m9206_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm m9206_i2c_algo = { + .master_xfer = m9206_i2c_xfer, + .functionality = m9206_i2c_func, +}; + +/* Callbacks for DVB USB */ +static int megasky_identify_state (struct usb_device *udev, + struct dvb_usb_properties *props, + struct dvb_usb_device_description **desc, + int *cold) +{ + struct usb_host_interface *alt; + + alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1); + *cold = (alt == NULL) ? 1 : 0; + + return 0; +} + +static int megasky_mt352_demod_init(struct dvb_frontend *fe) +{ + int i; + static u8 buf1[] = { + CONFIG, 0x3d, + CLOCK_CTL, 0x30, + RESET, 0x80, + ADC_CTL_1, 0x40, + AGC_TARGET, 0x1c, + AGC_CTL, 0x20, + 0x69, 0x00, + 0x6a, 0xff, + 0x6b, 0xff, + 0x6c, 0x40, + 0x6d, 0xff, + 0x6e, 0x00, + 0x6f, 0x40, + 0x70, 0x40, + 0x93, 0x1a, + 0xb5, 0x7a, + ACQ_CTL, 0x50, + INPUT_FREQ_1, 0x31, + INPUT_FREQ_0, 0x05, + }; + + for (i = 0; i < ARRAY_SIZE(buf1); i += 2) + mt352_write(fe, &buf1[i], 2); + + deb_rc("Demod init!\n"); + + return 0; +} + +struct mt352_state; + + +#define W 0 +#define R 1 +/* Not actual hw limits. */ +#define QT1010_MIN_STEP 2000000 +#define QT1010_MIN_FREQ 48000000 + +int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) +{ + int i; + int div, mod; + struct { + u8 read, reg, value; + } rd[46] = { { W, 0x01, 0x80 }, + { W, 0x02, 0x3f }, + { W, 0x05, 0xff }, /* c */ + { W, 0x06, 0x44 }, + { W, 0x07, 0xff }, /* c */ + { W, 0x08, 0x08 }, + { W, 0x09, 0xff }, /* c */ + { W, 0x0a, 0xff }, /* c */ + { W, 0x0b, 0xff }, /* c */ + { W, 0x0c, 0xe1 }, + { W, 0x1a, 0xff }, /* 10 c */ + { W, 0x1b, 0x00 }, + { W, 0x1c, 0x89 }, + { W, 0x11, 0xff }, /* c */ + { W, 0x12, 0x91 }, + { W, 0x22, 0xff }, /* c */ + { W, 0x1e, 0x00 }, + { W, 0x1e, 0xd0 }, + { R, 0x22, 0xff }, /* c read */ + { W, 0x1e, 0x00 }, + { R, 0x05, 0xff }, /* 20 c read */ + { R, 0x22, 0xff }, /* c read */ + { W, 0x23, 0xd0 }, + { W, 0x1e, 0x00 }, + { W, 0x1e, 0xe0 }, + { R, 0x23, 0xff }, /* c read */ + { W, 0x1e, 0x00 }, + { W, 0x24, 0xd0 }, + { W, 0x1e, 0x00 }, + { W, 0x1e, 0xf0 }, + { R, 0x24, 0xff }, /* 30 c read */ + { W, 0x1e, 0x00 }, + { W, 0x14, 0x7f }, + { W, 0x15, 0x7f }, + { W, 0x05, 0xff }, /* c */ + { W, 0x06, 0x00 }, + { W, 0x15, 0x1f }, + { W, 0x16, 0xff }, + { W, 0x18, 0xff }, + { W, 0x1f, 0xff }, /* c */ + { W, 0x20, 0xff }, /* 40 c */ + { W, 0x21, 0x53 }, + { W, 0x25, 0xbd }, + { W, 0x26, 0x15 }, + { W, 0x02, 0x00 }, + { W, 0x01, 0x00 }, + }; + struct i2c_msg msg; + struct dvb_usb_device *d = fe->dvb->priv; + unsigned long freq = params->frequency; + + if (freq % QT1010_MIN_STEP) + deb_rc("frequency not supported.\n"); + + (void) buf; + (void) buf_len; + + div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; + mod = (div + 16 - 9) % 16; + + /* 0x5 */ + if (div >= 377) + rd[2].value = 0x74; + else if (div >= 265) + rd[2].value = 0x54; + else if (div >= 121) + rd[2].value = 0x34; + else + rd[2].value = 0x14; + + /* 0x7 */ + rd[4].value = (((freq - QT1010_MIN_FREQ) / 1000000) * 9975 + 12960000) / 320000; + + /* 09 */ + if (mod < 4) + rd[6].value = 0x1d; + else + rd[6].value = 0x1c; + + /* 0a */ + if (mod < 2) + rd[7].value = 0x09; + else if (mod < 4) + rd[7].value = 0x08; + else if (mod < 6) + rd[7].value = 0x0f; + else if (mod < 8) + rd[7].value = 0x0e; + else if (mod < 10) + rd[7].value = 0x0d; + else if (mod < 12) + rd[7].value = 0x0c; + else if (mod < 14) + rd[7].value = 0x0b; + else + rd[7].value = 0x0a; + + /* 0b */ + if (div & 1) + rd[8].value = 0x45; + else + rd[8].value = 0x44; + + /* 1a */ + if (div & 1) + rd[10].value = 0x78; + else + rd[10].value = 0xf8; + + /* 11 */ + if (div >= 265) + rd[13].value = 0xf9; + else if (div >= 121) + rd[13].value = 0xfd; + else + rd[13].value = 0xf9; + + /* 22 */ + if (div < 201) + rd[15].value = 0xd0; + else if (div < 217) + rd[15].value = 0xd3; + else if (div < 233) + rd[15].value = 0xd6; + else if (div < 249) + rd[15].value = 0xd9; + else if (div < 265) + rd[15].value = 0xda; + else + rd[15].value = 0xd0; + + /* 05 */ + if (div >= 377) + rd[34].value = 0x70; + else if (div >= 265) + rd[34].value = 0x50; + else if (div >= 121) + rd[34].value = 0x30; + else + rd[34].value = 0x10; + + /* 1f */ + if (mod < 4) + rd[39].value = 0x64; + else if (mod < 6) + rd[39].value = 0x66; + else if (mod < 8) + rd[39].value = 0x67; + else if (mod < 12) + rd[39].value = 0x68; + else if (mod < 14) + rd[39].value = 0x69; + else + rd[39].value = 0x6a; + + /* 20 */ + if (mod < 4) + rd[40].value = 0x10; + else if (mod < 6) + rd[40].value = 0x11; + else if (mod < 10) + rd[40].value = 0x12; + else if (mod < 12) + rd[40].value = 0x13; + else if (mod < 14) + rd[40].value = 0x14; + else + rd[40].value = 0x15; + + deb_rc("Now tuning... "); + for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { + if (rd[i].read) + continue; + + msg.flags = 0; + msg.len = 2; + msg.addr = 0xc4; + msg.buf = &rd[i].reg; + + if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { + deb_rc("tuner write failed\n"); + return -EIO; + } + } + deb_rc("done\n"); + + return 0; +} +#undef W +#undef R + +static struct mt352_config megasky_mt352_config = { + .demod_address = 0x1e, + .demod_init = megasky_mt352_demod_init, +}; + +static int megasky_frontend_attach(struct dvb_usb_device *d) +{ + deb_rc("megasky_frontend_attach!\n"); + + if ((d->fe = mt352_attach(&megasky_mt352_config, &d->i2c_adap)) != NULL) { + d->fe->ops.tuner_ops.calc_regs = qt1010_set_params; + return 0; + } + return -EIO; +} + +/* DVB USB Driver stuff */ +static struct dvb_usb_properties megasky_properties; + +static int megasky_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct dvb_usb_device *d; + struct usb_host_interface *alt; + int ret; + + if ((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) { + deb_rc("probed!\n"); + + alt = usb_altnum_to_altsetting(intf, 1); + if (alt == NULL) { + deb_rc("not alt found!\n"); + return -ENODEV; + } + + ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); + if (ret < 0) + return ret; + + deb_rc("Changed to alternate setting!\n"); + + /* Remote controller init. */ + if ((ret = m9206_write(d->udev, 0x22, 0xa8, 0xff55)) != 0) + return ret; + + if ((ret = m9206_write(d->udev, 0x22, 0x51, 0xff54)) != 0) + return ret; + } + return ret; +} + +static struct usb_device_id megasky_table [] = { + { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, megasky_table); + +static int set_filter(struct dvb_usb_device *d, int type, int idx, int pid) +{ + int ret = 0; + + if (pid >= 0x8000) + return -EINVAL; + + pid |= 0x8000; + + if ((ret = m9206_write(d->udev, 0x25, pid, (type << 8) | (idx * 4) )) != 0) + return ret; + + if ((ret = m9206_write(d->udev, 0x25, 0, (type << 8) | (idx * 4) )) != 0) + return ret; + + return ret; +} + +static int m9206_pid_filter_ctrl(struct dvb_usb_device *d, int onoff) +{ + int ret = 0; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + deb_rc("filtering %s\n", onoff ? "on" : "off"); + if (onoff == 0) { + if ((ret = set_filter(d, 0x81, 1, 0x00)) != 0) + goto unlock; + + if ((ret = set_filter(d, 0x82, 0, 0x02f5)) != 0) + goto unlock; + } + unlock: + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +static int m9206_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff) +{ + int ret = 0; + + if (pid == 8192) + return m9206_pid_filter_ctrl(d, !onoff); + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + deb_rc("filter %d, pid %x, %s\n", index, pid, onoff ? "on" : "off"); + if (onoff == 0) + pid = 0; + + if ((ret = set_filter(d, 0x81, 1, 0x01)) != 0) + goto unlock; + + if ((ret = set_filter(d, 0x81, index + 2, pid)) != 0) + goto unlock; + + if ((ret = set_filter(d, 0x82, 0, 0x02f5)) != 0) + goto unlock; + + unlock: + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +static int m9206_firmware_download(struct usb_device *udev, const struct firmware *fw) +{ + u16 value, index, size; + u8 read[4], *buff; + int i, pass, ret = 0; + + buff = kmalloc(65536, GFP_KERNEL); + + if ((ret = m9206_read(udev, 0x25, 0x0, 0x8000, read, 4)) != 0) + goto done; + deb_rc("%x %x %x %x\n", read[0], read[1], read[2], read[3]); + + if ((ret = m9206_read(udev, 0x30, 0x0, 0x0, read, 1)) != 0) + goto done; + deb_rc("%x\n", read[0]); + + for (pass = 0; pass < 2; pass++) { + for (i = 0; i + (sizeof(u16) * 3) < fw->size;) { + value = le16_to_cpu(*(u16 *)(fw->data + i)); + i += sizeof(u16); + + index = le16_to_cpu(*(u16 *)(fw->data + i)); + i += sizeof(u16); + + size = le16_to_cpu(*(u16 *)(fw->data + i)); + i += sizeof(u16); + + if (pass == 1) { + /* Will stall if using fw->data ... */ + memcpy(buff, fw->data + i, size); + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0), + 0x30, USB_TYPE_VENDOR | USB_DIR_OUT, + value, index, buff, size, 20); + if (ret != size) { + deb_rc("error while uploading fw!\n"); + ret = -EIO; + goto done; + } + msleep(3); + } + i += size; + } + if (i != fw->size) { + ret = -EINVAL; + goto done; + } + } + + msleep(36); + + /* m9206 will disconnect itself from the bus after this. */ + (void) m9206_write(udev, 0x22, 0x01, 0xff69); + deb_rc("firmware uploaded!\n"); + + done: + kfree(buff); + + return ret; +} + +static struct dvb_usb_properties megasky_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_HAS_PID_FILTER | + DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_NEED_PID_FILTERING, + .pid_filter_count = 8, + + .usb_ctrl = DEVICE_SPECIFIC, + .firmware = "dvb-usb-megasky-02.fw", + .download_firmware = m9206_firmware_download, + + .pid_filter = m9206_pid_filter, + .pid_filter_ctrl = m9206_pid_filter_ctrl, + .frontend_attach = megasky_frontend_attach, + + .rc_interval = 200, + .rc_key_map = megasky_rc_keys, + .rc_key_map_size = ARRAY_SIZE(megasky_rc_keys), + .rc_query = m9206_rc_query, + + .size_of_priv = 0, + + .identify_state = megasky_identify_state, + .i2c_algo = &m9206_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + .urb = { + .type = DVB_USB_BULK, + .count = 8, + .endpoint = 0x81, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + .num_device_descs = 1, + .devices = { + { "MSI Mega Sky 580 DVB-T USB2.0", + { &megasky_table[0], NULL }, + { NULL }, + }, + { NULL }, + } +}; + +static struct usb_driver megasky_driver = { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, +#endif + .name = "dvb_usb_megasky", + .probe = megasky_probe, + .disconnect = dvb_usb_device_exit, + .id_table = megasky_table, +}; + +/* module stuff */ +static int __init megasky_module_init(void) +{ + int ret; + + if ((ret = usb_register(&megasky_driver))) { + err("usb_register failed. Error number %d", ret); + return ret; + } + + return 0; +} + +static void __exit megasky_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&megasky_driver); +} + +module_init (megasky_module_init); +module_exit (megasky_module_exit); + +MODULE_AUTHOR("Aapo Tahkola "); +MODULE_DESCRIPTION("Driver for MSI Mega Sky 580 DVB-T USB2.0"); +MODULE_VERSION("0.1"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/dvb-usb/megasky.h b/linux/drivers/media/dvb/dvb-usb/megasky.h new file mode 100644 index 000000000..6f14ae74e --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/megasky.h @@ -0,0 +1,10 @@ +#ifndef _DVB_USB_MEGASKY_H_ +#define _DVB_USB_MEGASKY_H_ + +#define DVB_USB_LOG_PREFIX "megasky" +#include "dvb-usb.h" + +extern int dvb_usb_megasky_debug; +#define deb_rc(args...) dprintk(dvb_usb_megasky_debug,0x01,args) + +#endif -- cgit v1.2.3 From 4130b2e25e1fcf65e8213ae458fd4788114632ea Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 23 Sep 2006 19:00:42 -0400 Subject: dvb-usb: rename megasky.[ch] to m920x.[ch] From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Makefile | 4 +- linux/drivers/media/dvb/dvb-usb/m920x.c | 696 ++++++++++++++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/m920x.h | 10 + linux/drivers/media/dvb/dvb-usb/megasky.c | 696 ------------------------------ linux/drivers/media/dvb/dvb-usb/megasky.h | 10 - 5 files changed, 708 insertions(+), 708 deletions(-) create mode 100644 linux/drivers/media/dvb/dvb-usb/m920x.c create mode 100644 linux/drivers/media/dvb/dvb-usb/m920x.h delete mode 100644 linux/drivers/media/dvb/dvb-usb/megasky.c delete mode 100644 linux/drivers/media/dvb/dvb-usb/megasky.h (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile index d1e4f1cd8..e2eed102e 100644 --- a/linux/drivers/media/dvb/dvb-usb/Makefile +++ b/linux/drivers/media/dvb/dvb-usb/Makefile @@ -30,8 +30,8 @@ obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2 dvb-usb-umt-010-objs = umt-010.o obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o -dvb-usb-megasky-objs = megasky.o -obj-$(CONFIG_DVB_USB_MEGASKY) += dvb-usb-megasky.o +dvb-usb-m920x-objs = m920x.o +obj-$(CONFIG_DVB_USB_MEGASKY) += dvb-usb-m920x.o dvb-usb-digitv-objs = digitv.o obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c new file mode 100644 index 000000000..915b6453a --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -0,0 +1,696 @@ +/* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver + * + * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "m920x.h" + +#include "mt352.h" +#include "mt352_priv.h" + +/* debug */ +int dvb_usb_megasky_debug; +module_param_named(debug,dvb_usb_megasky_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); + +static struct dvb_usb_rc_key megasky_rc_keys [] = { + { 0x0, 0x12, KEY_POWER }, + { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */ + { 0x0, 0x02, KEY_CHANNELUP }, + { 0x0, 0x05, KEY_CHANNELDOWN }, + { 0x0, 0x03, KEY_VOLUMEUP }, + { 0x0, 0x06, KEY_VOLUMEDOWN }, + { 0x0, 0x04, KEY_MUTE }, + { 0x0, 0x07, KEY_OK }, /* TS */ + { 0x0, 0x08, KEY_STOP }, + { 0x0, 0x09, KEY_MENU }, /* swap */ + { 0x0, 0x0a, KEY_REWIND }, + { 0x0, 0x1b, KEY_PAUSE }, + { 0x0, 0x1f, KEY_FASTFORWARD }, + { 0x0, 0x0c, KEY_RECORD }, + { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */ + { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */ +}; + +static inline int m9206_read(struct usb_device *udev, u8 request, u16 value, u16 index, void *data, int size) +{ + int ret; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + request, USB_TYPE_VENDOR | USB_DIR_IN, + value, index, data, size, 2000); + if (ret < 0) + return ret; + + if (ret != size) + return -EIO; + + return 0; +} + +static inline int m9206_write(struct usb_device *udev, u8 request, u16 value, u16 index) +{ + int ret; + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + request, USB_TYPE_VENDOR | USB_DIR_OUT, + value, index, NULL, 0, 2000); + msleep(3); + + return ret; +} + +static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + int i, ret = 0; + u8 rc_state[2]; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + if ((ret = m9206_read(d->udev, 0x22, 0x0, 0xff51, rc_state, 1)) != 0) + goto unlock; + + if ((ret = m9206_read(d->udev, 0x22, 0x0, 0xff52, rc_state + 1, 1)) != 0) + goto unlock; + + for (i = 0; i < ARRAY_SIZE(megasky_rc_keys); i++) + if (megasky_rc_keys[i].data == rc_state[1]) { + *event = megasky_rc_keys[i].event; + + switch(rc_state[0]) { + case 0x80: + *state = REMOTE_NO_KEY_PRESSED; + goto unlock; + + case 0x93: + case 0x92: + *state = REMOTE_KEY_PRESSED; + goto unlock; + + case 0x91: + *state = REMOTE_KEY_REPEAT; + goto unlock; + + default: + deb_rc("Unexpected rc response %x\n", rc_state[0]); + *state = REMOTE_NO_KEY_PRESSED; + goto unlock; + } + } + + if (rc_state[1] != 0) + deb_rc("Unknown rc key %x\n", rc_state[1]); + + *state = REMOTE_NO_KEY_PRESSED; + + unlock: + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +/* I2C */ + +static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i; + int ret = 0; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + if (num > 2) + return -EINVAL; + + for (i = 0; i < num; i++) { + u8 w_len; + + if ((ret = m9206_write(d->udev, 0x23, msg[i].addr, 0x80)) != 0) + goto unlock; + + if ((ret = m9206_write(d->udev, 0x23, msg[i].buf[0], 0x0)) != 0) + goto unlock; + + if (i + 1 < num && msg[i + 1].flags & I2C_M_RD) { + if (msg[i].addr == 0x1e) + w_len = 0x1f; + else + w_len = 0xc5; + + if ((ret = m9206_write(d->udev, 0x23, w_len, 0x80)) != 0) + goto unlock; + + if ((ret = m9206_read(d->udev, 0x23, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0) + goto unlock; + + i++; + } else { + if (msg[i].len != 2) + return -EINVAL; + + if ((ret = m9206_write(d->udev, 0x23, msg[i].buf[1], 0x40)) != 0) + goto unlock; + } + } + ret = i; + unlock: + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +static u32 m9206_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm m9206_i2c_algo = { + .master_xfer = m9206_i2c_xfer, + .functionality = m9206_i2c_func, +}; + +/* Callbacks for DVB USB */ +static int megasky_identify_state (struct usb_device *udev, + struct dvb_usb_properties *props, + struct dvb_usb_device_description **desc, + int *cold) +{ + struct usb_host_interface *alt; + + alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1); + *cold = (alt == NULL) ? 1 : 0; + + return 0; +} + +static int megasky_mt352_demod_init(struct dvb_frontend *fe) +{ + int i; + static u8 buf1[] = { + CONFIG, 0x3d, + CLOCK_CTL, 0x30, + RESET, 0x80, + ADC_CTL_1, 0x40, + AGC_TARGET, 0x1c, + AGC_CTL, 0x20, + 0x69, 0x00, + 0x6a, 0xff, + 0x6b, 0xff, + 0x6c, 0x40, + 0x6d, 0xff, + 0x6e, 0x00, + 0x6f, 0x40, + 0x70, 0x40, + 0x93, 0x1a, + 0xb5, 0x7a, + ACQ_CTL, 0x50, + INPUT_FREQ_1, 0x31, + INPUT_FREQ_0, 0x05, + }; + + for (i = 0; i < ARRAY_SIZE(buf1); i += 2) + mt352_write(fe, &buf1[i], 2); + + deb_rc("Demod init!\n"); + + return 0; +} + +struct mt352_state; + + +#define W 0 +#define R 1 +/* Not actual hw limits. */ +#define QT1010_MIN_STEP 2000000 +#define QT1010_MIN_FREQ 48000000 + +int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) +{ + int i; + int div, mod; + struct { + u8 read, reg, value; + } rd[46] = { { W, 0x01, 0x80 }, + { W, 0x02, 0x3f }, + { W, 0x05, 0xff }, /* c */ + { W, 0x06, 0x44 }, + { W, 0x07, 0xff }, /* c */ + { W, 0x08, 0x08 }, + { W, 0x09, 0xff }, /* c */ + { W, 0x0a, 0xff }, /* c */ + { W, 0x0b, 0xff }, /* c */ + { W, 0x0c, 0xe1 }, + { W, 0x1a, 0xff }, /* 10 c */ + { W, 0x1b, 0x00 }, + { W, 0x1c, 0x89 }, + { W, 0x11, 0xff }, /* c */ + { W, 0x12, 0x91 }, + { W, 0x22, 0xff }, /* c */ + { W, 0x1e, 0x00 }, + { W, 0x1e, 0xd0 }, + { R, 0x22, 0xff }, /* c read */ + { W, 0x1e, 0x00 }, + { R, 0x05, 0xff }, /* 20 c read */ + { R, 0x22, 0xff }, /* c read */ + { W, 0x23, 0xd0 }, + { W, 0x1e, 0x00 }, + { W, 0x1e, 0xe0 }, + { R, 0x23, 0xff }, /* c read */ + { W, 0x1e, 0x00 }, + { W, 0x24, 0xd0 }, + { W, 0x1e, 0x00 }, + { W, 0x1e, 0xf0 }, + { R, 0x24, 0xff }, /* 30 c read */ + { W, 0x1e, 0x00 }, + { W, 0x14, 0x7f }, + { W, 0x15, 0x7f }, + { W, 0x05, 0xff }, /* c */ + { W, 0x06, 0x00 }, + { W, 0x15, 0x1f }, + { W, 0x16, 0xff }, + { W, 0x18, 0xff }, + { W, 0x1f, 0xff }, /* c */ + { W, 0x20, 0xff }, /* 40 c */ + { W, 0x21, 0x53 }, + { W, 0x25, 0xbd }, + { W, 0x26, 0x15 }, + { W, 0x02, 0x00 }, + { W, 0x01, 0x00 }, + }; + struct i2c_msg msg; + struct dvb_usb_device *d = fe->dvb->priv; + unsigned long freq = params->frequency; + + if (freq % QT1010_MIN_STEP) + deb_rc("frequency not supported.\n"); + + (void) buf; + (void) buf_len; + + div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; + mod = (div + 16 - 9) % 16; + + /* 0x5 */ + if (div >= 377) + rd[2].value = 0x74; + else if (div >= 265) + rd[2].value = 0x54; + else if (div >= 121) + rd[2].value = 0x34; + else + rd[2].value = 0x14; + + /* 0x7 */ + rd[4].value = (((freq - QT1010_MIN_FREQ) / 1000000) * 9975 + 12960000) / 320000; + + /* 09 */ + if (mod < 4) + rd[6].value = 0x1d; + else + rd[6].value = 0x1c; + + /* 0a */ + if (mod < 2) + rd[7].value = 0x09; + else if (mod < 4) + rd[7].value = 0x08; + else if (mod < 6) + rd[7].value = 0x0f; + else if (mod < 8) + rd[7].value = 0x0e; + else if (mod < 10) + rd[7].value = 0x0d; + else if (mod < 12) + rd[7].value = 0x0c; + else if (mod < 14) + rd[7].value = 0x0b; + else + rd[7].value = 0x0a; + + /* 0b */ + if (div & 1) + rd[8].value = 0x45; + else + rd[8].value = 0x44; + + /* 1a */ + if (div & 1) + rd[10].value = 0x78; + else + rd[10].value = 0xf8; + + /* 11 */ + if (div >= 265) + rd[13].value = 0xf9; + else if (div >= 121) + rd[13].value = 0xfd; + else + rd[13].value = 0xf9; + + /* 22 */ + if (div < 201) + rd[15].value = 0xd0; + else if (div < 217) + rd[15].value = 0xd3; + else if (div < 233) + rd[15].value = 0xd6; + else if (div < 249) + rd[15].value = 0xd9; + else if (div < 265) + rd[15].value = 0xda; + else + rd[15].value = 0xd0; + + /* 05 */ + if (div >= 377) + rd[34].value = 0x70; + else if (div >= 265) + rd[34].value = 0x50; + else if (div >= 121) + rd[34].value = 0x30; + else + rd[34].value = 0x10; + + /* 1f */ + if (mod < 4) + rd[39].value = 0x64; + else if (mod < 6) + rd[39].value = 0x66; + else if (mod < 8) + rd[39].value = 0x67; + else if (mod < 12) + rd[39].value = 0x68; + else if (mod < 14) + rd[39].value = 0x69; + else + rd[39].value = 0x6a; + + /* 20 */ + if (mod < 4) + rd[40].value = 0x10; + else if (mod < 6) + rd[40].value = 0x11; + else if (mod < 10) + rd[40].value = 0x12; + else if (mod < 12) + rd[40].value = 0x13; + else if (mod < 14) + rd[40].value = 0x14; + else + rd[40].value = 0x15; + + deb_rc("Now tuning... "); + for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { + if (rd[i].read) + continue; + + msg.flags = 0; + msg.len = 2; + msg.addr = 0xc4; + msg.buf = &rd[i].reg; + + if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { + deb_rc("tuner write failed\n"); + return -EIO; + } + } + deb_rc("done\n"); + + return 0; +} +#undef W +#undef R + +static struct mt352_config megasky_mt352_config = { + .demod_address = 0x1e, + .demod_init = megasky_mt352_demod_init, +}; + +static int megasky_frontend_attach(struct dvb_usb_device *d) +{ + deb_rc("megasky_frontend_attach!\n"); + + if ((d->fe = mt352_attach(&megasky_mt352_config, &d->i2c_adap)) != NULL) { + d->fe->ops.tuner_ops.calc_regs = qt1010_set_params; + return 0; + } + return -EIO; +} + +/* DVB USB Driver stuff */ +static struct dvb_usb_properties megasky_properties; + +static int megasky_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct dvb_usb_device *d; + struct usb_host_interface *alt; + int ret; + + if ((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) { + deb_rc("probed!\n"); + + alt = usb_altnum_to_altsetting(intf, 1); + if (alt == NULL) { + deb_rc("not alt found!\n"); + return -ENODEV; + } + + ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); + if (ret < 0) + return ret; + + deb_rc("Changed to alternate setting!\n"); + + /* Remote controller init. */ + if ((ret = m9206_write(d->udev, 0x22, 0xa8, 0xff55)) != 0) + return ret; + + if ((ret = m9206_write(d->udev, 0x22, 0x51, 0xff54)) != 0) + return ret; + } + return ret; +} + +static struct usb_device_id megasky_table [] = { + { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, megasky_table); + +static int set_filter(struct dvb_usb_device *d, int type, int idx, int pid) +{ + int ret = 0; + + if (pid >= 0x8000) + return -EINVAL; + + pid |= 0x8000; + + if ((ret = m9206_write(d->udev, 0x25, pid, (type << 8) | (idx * 4) )) != 0) + return ret; + + if ((ret = m9206_write(d->udev, 0x25, 0, (type << 8) | (idx * 4) )) != 0) + return ret; + + return ret; +} + +static int m9206_pid_filter_ctrl(struct dvb_usb_device *d, int onoff) +{ + int ret = 0; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + deb_rc("filtering %s\n", onoff ? "on" : "off"); + if (onoff == 0) { + if ((ret = set_filter(d, 0x81, 1, 0x00)) != 0) + goto unlock; + + if ((ret = set_filter(d, 0x82, 0, 0x02f5)) != 0) + goto unlock; + } + unlock: + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +static int m9206_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff) +{ + int ret = 0; + + if (pid == 8192) + return m9206_pid_filter_ctrl(d, !onoff); + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + deb_rc("filter %d, pid %x, %s\n", index, pid, onoff ? "on" : "off"); + if (onoff == 0) + pid = 0; + + if ((ret = set_filter(d, 0x81, 1, 0x01)) != 0) + goto unlock; + + if ((ret = set_filter(d, 0x81, index + 2, pid)) != 0) + goto unlock; + + if ((ret = set_filter(d, 0x82, 0, 0x02f5)) != 0) + goto unlock; + + unlock: + mutex_unlock(&d->i2c_mutex); + + return ret; +} + +static int m9206_firmware_download(struct usb_device *udev, const struct firmware *fw) +{ + u16 value, index, size; + u8 read[4], *buff; + int i, pass, ret = 0; + + buff = kmalloc(65536, GFP_KERNEL); + + if ((ret = m9206_read(udev, 0x25, 0x0, 0x8000, read, 4)) != 0) + goto done; + deb_rc("%x %x %x %x\n", read[0], read[1], read[2], read[3]); + + if ((ret = m9206_read(udev, 0x30, 0x0, 0x0, read, 1)) != 0) + goto done; + deb_rc("%x\n", read[0]); + + for (pass = 0; pass < 2; pass++) { + for (i = 0; i + (sizeof(u16) * 3) < fw->size;) { + value = le16_to_cpu(*(u16 *)(fw->data + i)); + i += sizeof(u16); + + index = le16_to_cpu(*(u16 *)(fw->data + i)); + i += sizeof(u16); + + size = le16_to_cpu(*(u16 *)(fw->data + i)); + i += sizeof(u16); + + if (pass == 1) { + /* Will stall if using fw->data ... */ + memcpy(buff, fw->data + i, size); + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0), + 0x30, USB_TYPE_VENDOR | USB_DIR_OUT, + value, index, buff, size, 20); + if (ret != size) { + deb_rc("error while uploading fw!\n"); + ret = -EIO; + goto done; + } + msleep(3); + } + i += size; + } + if (i != fw->size) { + ret = -EINVAL; + goto done; + } + } + + msleep(36); + + /* m9206 will disconnect itself from the bus after this. */ + (void) m9206_write(udev, 0x22, 0x01, 0xff69); + deb_rc("firmware uploaded!\n"); + + done: + kfree(buff); + + return ret; +} + +static struct dvb_usb_properties megasky_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_HAS_PID_FILTER | + DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_NEED_PID_FILTERING, + .pid_filter_count = 8, + + .usb_ctrl = DEVICE_SPECIFIC, + .firmware = "dvb-usb-megasky-02.fw", + .download_firmware = m9206_firmware_download, + + .pid_filter = m9206_pid_filter, + .pid_filter_ctrl = m9206_pid_filter_ctrl, + .frontend_attach = megasky_frontend_attach, + + .rc_interval = 200, + .rc_key_map = megasky_rc_keys, + .rc_key_map_size = ARRAY_SIZE(megasky_rc_keys), + .rc_query = m9206_rc_query, + + .size_of_priv = 0, + + .identify_state = megasky_identify_state, + .i2c_algo = &m9206_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + .urb = { + .type = DVB_USB_BULK, + .count = 8, + .endpoint = 0x81, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + .num_device_descs = 1, + .devices = { + { "MSI Mega Sky 580 DVB-T USB2.0", + { &megasky_table[0], NULL }, + { NULL }, + }, + { NULL }, + } +}; + +static struct usb_driver megasky_driver = { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, +#endif + .name = "dvb_usb_megasky", + .probe = megasky_probe, + .disconnect = dvb_usb_device_exit, + .id_table = megasky_table, +}; + +/* module stuff */ +static int __init megasky_module_init(void) +{ + int ret; + + if ((ret = usb_register(&megasky_driver))) { + err("usb_register failed. Error number %d", ret); + return ret; + } + + return 0; +} + +static void __exit megasky_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&megasky_driver); +} + +module_init (megasky_module_init); +module_exit (megasky_module_exit); + +MODULE_AUTHOR("Aapo Tahkola "); +MODULE_DESCRIPTION("Driver for MSI Mega Sky 580 DVB-T USB2.0"); +MODULE_VERSION("0.1"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.h b/linux/drivers/media/dvb/dvb-usb/m920x.h new file mode 100644 index 000000000..6f14ae74e --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/m920x.h @@ -0,0 +1,10 @@ +#ifndef _DVB_USB_MEGASKY_H_ +#define _DVB_USB_MEGASKY_H_ + +#define DVB_USB_LOG_PREFIX "megasky" +#include "dvb-usb.h" + +extern int dvb_usb_megasky_debug; +#define deb_rc(args...) dprintk(dvb_usb_megasky_debug,0x01,args) + +#endif diff --git a/linux/drivers/media/dvb/dvb-usb/megasky.c b/linux/drivers/media/dvb/dvb-usb/megasky.c deleted file mode 100644 index 73e309cb8..000000000 --- a/linux/drivers/media/dvb/dvb-usb/megasky.c +++ /dev/null @@ -1,696 +0,0 @@ -/* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver - * - * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "megasky.h" - -#include "mt352.h" -#include "mt352_priv.h" - -/* debug */ -int dvb_usb_megasky_debug; -module_param_named(debug,dvb_usb_megasky_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); - -static struct dvb_usb_rc_key megasky_rc_keys [] = { - { 0x0, 0x12, KEY_POWER }, - { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */ - { 0x0, 0x02, KEY_CHANNELUP }, - { 0x0, 0x05, KEY_CHANNELDOWN }, - { 0x0, 0x03, KEY_VOLUMEUP }, - { 0x0, 0x06, KEY_VOLUMEDOWN }, - { 0x0, 0x04, KEY_MUTE }, - { 0x0, 0x07, KEY_OK }, /* TS */ - { 0x0, 0x08, KEY_STOP }, - { 0x0, 0x09, KEY_MENU }, /* swap */ - { 0x0, 0x0a, KEY_REWIND }, - { 0x0, 0x1b, KEY_PAUSE }, - { 0x0, 0x1f, KEY_FASTFORWARD }, - { 0x0, 0x0c, KEY_RECORD }, - { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */ - { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */ -}; - -static inline int m9206_read(struct usb_device *udev, u8 request, u16 value, u16 index, void *data, int size) -{ - int ret; - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - request, USB_TYPE_VENDOR | USB_DIR_IN, - value, index, data, size, 2000); - if (ret < 0) - return ret; - - if (ret != size) - return -EIO; - - return 0; -} - -static inline int m9206_write(struct usb_device *udev, u8 request, u16 value, u16 index) -{ - int ret; - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - request, USB_TYPE_VENDOR | USB_DIR_OUT, - value, index, NULL, 0, 2000); - msleep(3); - - return ret; -} - -static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - int i, ret = 0; - u8 rc_state[2]; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - if ((ret = m9206_read(d->udev, 0x22, 0x0, 0xff51, rc_state, 1)) != 0) - goto unlock; - - if ((ret = m9206_read(d->udev, 0x22, 0x0, 0xff52, rc_state + 1, 1)) != 0) - goto unlock; - - for (i = 0; i < ARRAY_SIZE(megasky_rc_keys); i++) - if (megasky_rc_keys[i].data == rc_state[1]) { - *event = megasky_rc_keys[i].event; - - switch(rc_state[0]) { - case 0x80: - *state = REMOTE_NO_KEY_PRESSED; - goto unlock; - - case 0x93: - case 0x92: - *state = REMOTE_KEY_PRESSED; - goto unlock; - - case 0x91: - *state = REMOTE_KEY_REPEAT; - goto unlock; - - default: - deb_rc("Unexpected rc response %x\n", rc_state[0]); - *state = REMOTE_NO_KEY_PRESSED; - goto unlock; - } - } - - if (rc_state[1] != 0) - deb_rc("Unknown rc key %x\n", rc_state[1]); - - *state = REMOTE_NO_KEY_PRESSED; - - unlock: - mutex_unlock(&d->i2c_mutex); - - return ret; -} - -/* I2C */ - -static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; - int ret = 0; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - if (num > 2) - return -EINVAL; - - for (i = 0; i < num; i++) { - u8 w_len; - - if ((ret = m9206_write(d->udev, 0x23, msg[i].addr, 0x80)) != 0) - goto unlock; - - if ((ret = m9206_write(d->udev, 0x23, msg[i].buf[0], 0x0)) != 0) - goto unlock; - - if (i + 1 < num && msg[i + 1].flags & I2C_M_RD) { - if (msg[i].addr == 0x1e) - w_len = 0x1f; - else - w_len = 0xc5; - - if ((ret = m9206_write(d->udev, 0x23, w_len, 0x80)) != 0) - goto unlock; - - if ((ret = m9206_read(d->udev, 0x23, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0) - goto unlock; - - i++; - } else { - if (msg[i].len != 2) - return -EINVAL; - - if ((ret = m9206_write(d->udev, 0x23, msg[i].buf[1], 0x40)) != 0) - goto unlock; - } - } - ret = i; - unlock: - mutex_unlock(&d->i2c_mutex); - - return ret; -} - -static u32 m9206_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm m9206_i2c_algo = { - .master_xfer = m9206_i2c_xfer, - .functionality = m9206_i2c_func, -}; - -/* Callbacks for DVB USB */ -static int megasky_identify_state (struct usb_device *udev, - struct dvb_usb_properties *props, - struct dvb_usb_device_description **desc, - int *cold) -{ - struct usb_host_interface *alt; - - alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1); - *cold = (alt == NULL) ? 1 : 0; - - return 0; -} - -static int megasky_mt352_demod_init(struct dvb_frontend *fe) -{ - int i; - static u8 buf1[] = { - CONFIG, 0x3d, - CLOCK_CTL, 0x30, - RESET, 0x80, - ADC_CTL_1, 0x40, - AGC_TARGET, 0x1c, - AGC_CTL, 0x20, - 0x69, 0x00, - 0x6a, 0xff, - 0x6b, 0xff, - 0x6c, 0x40, - 0x6d, 0xff, - 0x6e, 0x00, - 0x6f, 0x40, - 0x70, 0x40, - 0x93, 0x1a, - 0xb5, 0x7a, - ACQ_CTL, 0x50, - INPUT_FREQ_1, 0x31, - INPUT_FREQ_0, 0x05, - }; - - for (i = 0; i < ARRAY_SIZE(buf1); i += 2) - mt352_write(fe, &buf1[i], 2); - - deb_rc("Demod init!\n"); - - return 0; -} - -struct mt352_state; - - -#define W 0 -#define R 1 -/* Not actual hw limits. */ -#define QT1010_MIN_STEP 2000000 -#define QT1010_MIN_FREQ 48000000 - -int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) -{ - int i; - int div, mod; - struct { - u8 read, reg, value; - } rd[46] = { { W, 0x01, 0x80 }, - { W, 0x02, 0x3f }, - { W, 0x05, 0xff }, /* c */ - { W, 0x06, 0x44 }, - { W, 0x07, 0xff }, /* c */ - { W, 0x08, 0x08 }, - { W, 0x09, 0xff }, /* c */ - { W, 0x0a, 0xff }, /* c */ - { W, 0x0b, 0xff }, /* c */ - { W, 0x0c, 0xe1 }, - { W, 0x1a, 0xff }, /* 10 c */ - { W, 0x1b, 0x00 }, - { W, 0x1c, 0x89 }, - { W, 0x11, 0xff }, /* c */ - { W, 0x12, 0x91 }, - { W, 0x22, 0xff }, /* c */ - { W, 0x1e, 0x00 }, - { W, 0x1e, 0xd0 }, - { R, 0x22, 0xff }, /* c read */ - { W, 0x1e, 0x00 }, - { R, 0x05, 0xff }, /* 20 c read */ - { R, 0x22, 0xff }, /* c read */ - { W, 0x23, 0xd0 }, - { W, 0x1e, 0x00 }, - { W, 0x1e, 0xe0 }, - { R, 0x23, 0xff }, /* c read */ - { W, 0x1e, 0x00 }, - { W, 0x24, 0xd0 }, - { W, 0x1e, 0x00 }, - { W, 0x1e, 0xf0 }, - { R, 0x24, 0xff }, /* 30 c read */ - { W, 0x1e, 0x00 }, - { W, 0x14, 0x7f }, - { W, 0x15, 0x7f }, - { W, 0x05, 0xff }, /* c */ - { W, 0x06, 0x00 }, - { W, 0x15, 0x1f }, - { W, 0x16, 0xff }, - { W, 0x18, 0xff }, - { W, 0x1f, 0xff }, /* c */ - { W, 0x20, 0xff }, /* 40 c */ - { W, 0x21, 0x53 }, - { W, 0x25, 0xbd }, - { W, 0x26, 0x15 }, - { W, 0x02, 0x00 }, - { W, 0x01, 0x00 }, - }; - struct i2c_msg msg; - struct dvb_usb_device *d = fe->dvb->priv; - unsigned long freq = params->frequency; - - if (freq % QT1010_MIN_STEP) - deb_rc("frequency not supported.\n"); - - (void) buf; - (void) buf_len; - - div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; - mod = (div + 16 - 9) % 16; - - /* 0x5 */ - if (div >= 377) - rd[2].value = 0x74; - else if (div >= 265) - rd[2].value = 0x54; - else if (div >= 121) - rd[2].value = 0x34; - else - rd[2].value = 0x14; - - /* 0x7 */ - rd[4].value = (((freq - QT1010_MIN_FREQ) / 1000000) * 9975 + 12960000) / 320000; - - /* 09 */ - if (mod < 4) - rd[6].value = 0x1d; - else - rd[6].value = 0x1c; - - /* 0a */ - if (mod < 2) - rd[7].value = 0x09; - else if (mod < 4) - rd[7].value = 0x08; - else if (mod < 6) - rd[7].value = 0x0f; - else if (mod < 8) - rd[7].value = 0x0e; - else if (mod < 10) - rd[7].value = 0x0d; - else if (mod < 12) - rd[7].value = 0x0c; - else if (mod < 14) - rd[7].value = 0x0b; - else - rd[7].value = 0x0a; - - /* 0b */ - if (div & 1) - rd[8].value = 0x45; - else - rd[8].value = 0x44; - - /* 1a */ - if (div & 1) - rd[10].value = 0x78; - else - rd[10].value = 0xf8; - - /* 11 */ - if (div >= 265) - rd[13].value = 0xf9; - else if (div >= 121) - rd[13].value = 0xfd; - else - rd[13].value = 0xf9; - - /* 22 */ - if (div < 201) - rd[15].value = 0xd0; - else if (div < 217) - rd[15].value = 0xd3; - else if (div < 233) - rd[15].value = 0xd6; - else if (div < 249) - rd[15].value = 0xd9; - else if (div < 265) - rd[15].value = 0xda; - else - rd[15].value = 0xd0; - - /* 05 */ - if (div >= 377) - rd[34].value = 0x70; - else if (div >= 265) - rd[34].value = 0x50; - else if (div >= 121) - rd[34].value = 0x30; - else - rd[34].value = 0x10; - - /* 1f */ - if (mod < 4) - rd[39].value = 0x64; - else if (mod < 6) - rd[39].value = 0x66; - else if (mod < 8) - rd[39].value = 0x67; - else if (mod < 12) - rd[39].value = 0x68; - else if (mod < 14) - rd[39].value = 0x69; - else - rd[39].value = 0x6a; - - /* 20 */ - if (mod < 4) - rd[40].value = 0x10; - else if (mod < 6) - rd[40].value = 0x11; - else if (mod < 10) - rd[40].value = 0x12; - else if (mod < 12) - rd[40].value = 0x13; - else if (mod < 14) - rd[40].value = 0x14; - else - rd[40].value = 0x15; - - deb_rc("Now tuning... "); - for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { - if (rd[i].read) - continue; - - msg.flags = 0; - msg.len = 2; - msg.addr = 0xc4; - msg.buf = &rd[i].reg; - - if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { - deb_rc("tuner write failed\n"); - return -EIO; - } - } - deb_rc("done\n"); - - return 0; -} -#undef W -#undef R - -static struct mt352_config megasky_mt352_config = { - .demod_address = 0x1e, - .demod_init = megasky_mt352_demod_init, -}; - -static int megasky_frontend_attach(struct dvb_usb_device *d) -{ - deb_rc("megasky_frontend_attach!\n"); - - if ((d->fe = mt352_attach(&megasky_mt352_config, &d->i2c_adap)) != NULL) { - d->fe->ops.tuner_ops.calc_regs = qt1010_set_params; - return 0; - } - return -EIO; -} - -/* DVB USB Driver stuff */ -static struct dvb_usb_properties megasky_properties; - -static int megasky_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct dvb_usb_device *d; - struct usb_host_interface *alt; - int ret; - - if ((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) { - deb_rc("probed!\n"); - - alt = usb_altnum_to_altsetting(intf, 1); - if (alt == NULL) { - deb_rc("not alt found!\n"); - return -ENODEV; - } - - ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); - if (ret < 0) - return ret; - - deb_rc("Changed to alternate setting!\n"); - - /* Remote controller init. */ - if ((ret = m9206_write(d->udev, 0x22, 0xa8, 0xff55)) != 0) - return ret; - - if ((ret = m9206_write(d->udev, 0x22, 0x51, 0xff54)) != 0) - return ret; - } - return ret; -} - -static struct usb_device_id megasky_table [] = { - { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, megasky_table); - -static int set_filter(struct dvb_usb_device *d, int type, int idx, int pid) -{ - int ret = 0; - - if (pid >= 0x8000) - return -EINVAL; - - pid |= 0x8000; - - if ((ret = m9206_write(d->udev, 0x25, pid, (type << 8) | (idx * 4) )) != 0) - return ret; - - if ((ret = m9206_write(d->udev, 0x25, 0, (type << 8) | (idx * 4) )) != 0) - return ret; - - return ret; -} - -static int m9206_pid_filter_ctrl(struct dvb_usb_device *d, int onoff) -{ - int ret = 0; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - deb_rc("filtering %s\n", onoff ? "on" : "off"); - if (onoff == 0) { - if ((ret = set_filter(d, 0x81, 1, 0x00)) != 0) - goto unlock; - - if ((ret = set_filter(d, 0x82, 0, 0x02f5)) != 0) - goto unlock; - } - unlock: - mutex_unlock(&d->i2c_mutex); - - return ret; -} - -static int m9206_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff) -{ - int ret = 0; - - if (pid == 8192) - return m9206_pid_filter_ctrl(d, !onoff); - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - deb_rc("filter %d, pid %x, %s\n", index, pid, onoff ? "on" : "off"); - if (onoff == 0) - pid = 0; - - if ((ret = set_filter(d, 0x81, 1, 0x01)) != 0) - goto unlock; - - if ((ret = set_filter(d, 0x81, index + 2, pid)) != 0) - goto unlock; - - if ((ret = set_filter(d, 0x82, 0, 0x02f5)) != 0) - goto unlock; - - unlock: - mutex_unlock(&d->i2c_mutex); - - return ret; -} - -static int m9206_firmware_download(struct usb_device *udev, const struct firmware *fw) -{ - u16 value, index, size; - u8 read[4], *buff; - int i, pass, ret = 0; - - buff = kmalloc(65536, GFP_KERNEL); - - if ((ret = m9206_read(udev, 0x25, 0x0, 0x8000, read, 4)) != 0) - goto done; - deb_rc("%x %x %x %x\n", read[0], read[1], read[2], read[3]); - - if ((ret = m9206_read(udev, 0x30, 0x0, 0x0, read, 1)) != 0) - goto done; - deb_rc("%x\n", read[0]); - - for (pass = 0; pass < 2; pass++) { - for (i = 0; i + (sizeof(u16) * 3) < fw->size;) { - value = le16_to_cpu(*(u16 *)(fw->data + i)); - i += sizeof(u16); - - index = le16_to_cpu(*(u16 *)(fw->data + i)); - i += sizeof(u16); - - size = le16_to_cpu(*(u16 *)(fw->data + i)); - i += sizeof(u16); - - if (pass == 1) { - /* Will stall if using fw->data ... */ - memcpy(buff, fw->data + i, size); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0), - 0x30, USB_TYPE_VENDOR | USB_DIR_OUT, - value, index, buff, size, 20); - if (ret != size) { - deb_rc("error while uploading fw!\n"); - ret = -EIO; - goto done; - } - msleep(3); - } - i += size; - } - if (i != fw->size) { - ret = -EINVAL; - goto done; - } - } - - msleep(36); - - /* m9206 will disconnect itself from the bus after this. */ - (void) m9206_write(udev, 0x22, 0x01, 0xff69); - deb_rc("firmware uploaded!\n"); - - done: - kfree(buff); - - return ret; -} - -static struct dvb_usb_properties megasky_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_HAS_PID_FILTER | - DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_NEED_PID_FILTERING, - .pid_filter_count = 8, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-megasky-02.fw", - .download_firmware = m9206_firmware_download, - - .pid_filter = m9206_pid_filter, - .pid_filter_ctrl = m9206_pid_filter_ctrl, - .frontend_attach = megasky_frontend_attach, - - .rc_interval = 200, - .rc_key_map = megasky_rc_keys, - .rc_key_map_size = ARRAY_SIZE(megasky_rc_keys), - .rc_query = m9206_rc_query, - - .size_of_priv = 0, - - .identify_state = megasky_identify_state, - .i2c_algo = &m9206_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - .urb = { - .type = DVB_USB_BULK, - .count = 8, - .endpoint = 0x81, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, - .num_device_descs = 1, - .devices = { - { "MSI Mega Sky 580 DVB-T USB2.0", - { &megasky_table[0], NULL }, - { NULL }, - }, - { NULL }, - } -}; - -static struct usb_driver megasky_driver = { -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) - .owner = THIS_MODULE, -#endif - .name = "dvb_usb_megasky", - .probe = megasky_probe, - .disconnect = dvb_usb_device_exit, - .id_table = megasky_table, -}; - -/* module stuff */ -static int __init megasky_module_init(void) -{ - int ret; - - if ((ret = usb_register(&megasky_driver))) { - err("usb_register failed. Error number %d", ret); - return ret; - } - - return 0; -} - -static void __exit megasky_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&megasky_driver); -} - -module_init (megasky_module_init); -module_exit (megasky_module_exit); - -MODULE_AUTHOR("Aapo Tahkola "); -MODULE_DESCRIPTION("Driver for MSI Mega Sky 580 DVB-T USB2.0"); -MODULE_VERSION("0.1"); -MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/dvb-usb/megasky.h b/linux/drivers/media/dvb/dvb-usb/megasky.h deleted file mode 100644 index 6f14ae74e..000000000 --- a/linux/drivers/media/dvb/dvb-usb/megasky.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _DVB_USB_MEGASKY_H_ -#define _DVB_USB_MEGASKY_H_ - -#define DVB_USB_LOG_PREFIX "megasky" -#include "dvb-usb.h" - -extern int dvb_usb_megasky_debug; -#define deb_rc(args...) dprintk(dvb_usb_megasky_debug,0x01,args) - -#endif -- cgit v1.2.3 From 060e944993ec36070b3f84e4f6f09bba076d01de Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 23 Sep 2006 19:01:29 -0400 Subject: m920x: cleanups after rename from megasky.[ch] From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 4 +- linux/drivers/media/dvb/dvb-usb/Makefile | 2 +- linux/drivers/media/dvb/dvb-usb/m920x.c | 70 ++++++++++++++++---------------- linux/drivers/media/dvb/dvb-usb/m920x.h | 10 ++--- 4 files changed, 43 insertions(+), 43 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 5f2a0c1dc..e120d9871 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -109,8 +109,8 @@ config DVB_USB_CXUSB Medion MD95700 hybrid USB2.0 device. DViCO FusionHDTV (Bluebird) USB2.0 devices -config DVB_USB_MEGASKY - tristate "MSI Mega Sky 580 DVB-T USB2.0 support" +config DVB_USB_M920X + tristate "Uli m920x DVB-T USB2.0 support" depends on DVB_USB select DVB_MT352 help diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile index e2eed102e..815e27898 100644 --- a/linux/drivers/media/dvb/dvb-usb/Makefile +++ b/linux/drivers/media/dvb/dvb-usb/Makefile @@ -31,7 +31,7 @@ dvb-usb-umt-010-objs = umt-010.o obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o dvb-usb-m920x-objs = m920x.o -obj-$(CONFIG_DVB_USB_MEGASKY) += dvb-usb-m920x.o +obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o dvb-usb-digitv-objs = digitv.o obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 915b6453a..4820fd07d 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -8,14 +8,15 @@ * * see Documentation/dvb/README.dvb-usb for more information */ + #include "m920x.h" #include "mt352.h" #include "mt352_priv.h" /* debug */ -int dvb_usb_megasky_debug; -module_param_named(debug,dvb_usb_megasky_debug, int, 0644); +int dvb_usb_m920x_debug; +module_param_named(debug,dvb_usb_m920x_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); static struct dvb_usb_rc_key megasky_rc_keys [] = { @@ -194,25 +195,25 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe) { int i; static u8 buf1[] = { - CONFIG, 0x3d, - CLOCK_CTL, 0x30, - RESET, 0x80, - ADC_CTL_1, 0x40, - AGC_TARGET, 0x1c, - AGC_CTL, 0x20, - 0x69, 0x00, - 0x6a, 0xff, - 0x6b, 0xff, - 0x6c, 0x40, - 0x6d, 0xff, - 0x6e, 0x00, - 0x6f, 0x40, - 0x70, 0x40, - 0x93, 0x1a, - 0xb5, 0x7a, - ACQ_CTL, 0x50, - INPUT_FREQ_1, 0x31, - INPUT_FREQ_0, 0x05, + CONFIG, 0x3d, + CLOCK_CTL, 0x30, + RESET, 0x80, + ADC_CTL_1, 0x40, + AGC_TARGET, 0x1c, + AGC_CTL, 0x20, + 0x69, 0x00, + 0x6a, 0xff, + 0x6b, 0xff, + 0x6c, 0x40, + 0x6d, 0xff, + 0x6e, 0x00, + 0x6f, 0x40, + 0x70, 0x40, + 0x93, 0x1a, + 0xb5, 0x7a, + ACQ_CTL, 0x50, + INPUT_FREQ_1, 0x31, + INPUT_FREQ_0, 0x05, }; for (i = 0; i < ARRAY_SIZE(buf1); i += 2) @@ -225,7 +226,6 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe) struct mt352_state; - #define W 0 #define R 1 /* Not actual hw limits. */ @@ -479,11 +479,11 @@ static int megasky_probe(struct usb_interface *intf, const struct usb_device_id return ret; } -static struct usb_device_id megasky_table [] = { +static struct usb_device_id m920x_table [] = { { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, { } /* Terminating entry */ }; -MODULE_DEVICE_TABLE (usb, megasky_table); +MODULE_DEVICE_TABLE (usb, m920x_table); static int set_filter(struct dvb_usb_device *d, int type, int idx, int pid) { @@ -651,29 +651,29 @@ static struct dvb_usb_properties megasky_properties = { .num_device_descs = 1, .devices = { { "MSI Mega Sky 580 DVB-T USB2.0", - { &megasky_table[0], NULL }, + { &m920x_table[0], NULL }, { NULL }, }, { NULL }, } }; -static struct usb_driver megasky_driver = { +static struct usb_driver m920x_driver = { #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, #endif - .name = "dvb_usb_megasky", + .name = "dvb_usb_m920x", .probe = megasky_probe, .disconnect = dvb_usb_device_exit, - .id_table = megasky_table, + .id_table = m920x_table, }; /* module stuff */ -static int __init megasky_module_init(void) +static int __init m920x_module_init(void) { int ret; - if ((ret = usb_register(&megasky_driver))) { + if ((ret = usb_register(&m920x_driver))) { err("usb_register failed. Error number %d", ret); return ret; } @@ -681,16 +681,16 @@ static int __init megasky_module_init(void) return 0; } -static void __exit megasky_module_exit(void) +static void __exit m920x_module_exit(void) { /* deregister this driver from the USB subsystem */ - usb_deregister(&megasky_driver); + usb_deregister(&m920x_driver); } -module_init (megasky_module_init); -module_exit (megasky_module_exit); +module_init (m920x_module_init); +module_exit (m920x_module_exit); MODULE_AUTHOR("Aapo Tahkola "); -MODULE_DESCRIPTION("Driver for MSI Mega Sky 580 DVB-T USB2.0"); +MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / Uli m920x"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.h b/linux/drivers/media/dvb/dvb-usb/m920x.h index 6f14ae74e..fdb967aa3 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.h +++ b/linux/drivers/media/dvb/dvb-usb/m920x.h @@ -1,10 +1,10 @@ -#ifndef _DVB_USB_MEGASKY_H_ -#define _DVB_USB_MEGASKY_H_ +#ifndef _DVB_USB_M920X_H_ +#define _DVB_USB_M920X_H_ -#define DVB_USB_LOG_PREFIX "megasky" +#define DVB_USB_LOG_PREFIX "m920x" #include "dvb-usb.h" -extern int dvb_usb_megasky_debug; -#define deb_rc(args...) dprintk(dvb_usb_megasky_debug,0x01,args) +extern int dvb_usb_m920x_debug; +#define deb_rc(args...) dprintk(dvb_usb_m920x_debug,0x01,args) #endif -- cgit v1.2.3 From 64af2f151592da0ffb146d2867db3ebae0b66572 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 23 Sep 2006 19:01:29 -0400 Subject: m920x: update megasky driver for recent changes in the dvb tree From: Michael Krufky update code to use dvb_attach() update code to reflect recent changes to the dvb_usb framework Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 +- linux/drivers/media/dvb/dvb-usb/m920x.c | 83 +++++++++++++++++---------------- 2 files changed, 45 insertions(+), 40 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index e120d9871..e18eb7b3f 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -112,7 +112,7 @@ config DVB_USB_CXUSB config DVB_USB_M920X tristate "Uli m920x DVB-T USB2.0 support" depends on DVB_USB - select DVB_MT352 + select DVB_MT352 if !DVB_FE_CUSTOMISE help Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. Currently, only devices with a product id of diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 4820fd07d..aa53bc498 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -179,7 +179,7 @@ static struct i2c_algorithm m9206_i2c_algo = { /* Callbacks for DVB USB */ static int megasky_identify_state (struct usb_device *udev, - struct dvb_usb_properties *props, + struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold) { @@ -434,19 +434,19 @@ static struct mt352_config megasky_mt352_config = { .demod_init = megasky_mt352_demod_init, }; -static int megasky_frontend_attach(struct dvb_usb_device *d) +static int megasky_frontend_attach(struct dvb_usb_adapter *adap) { deb_rc("megasky_frontend_attach!\n"); - if ((d->fe = mt352_attach(&megasky_mt352_config, &d->i2c_adap)) != NULL) { - d->fe->ops.tuner_ops.calc_regs = qt1010_set_params; + if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) != NULL) { + adap->fe->ops.tuner_ops.calc_regs = qt1010_set_params; return 0; } return -EIO; } /* DVB USB Driver stuff */ -static struct dvb_usb_properties megasky_properties; +static struct dvb_usb_device_properties megasky_properties; static int megasky_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -485,7 +485,7 @@ static struct usb_device_id m920x_table [] = { }; MODULE_DEVICE_TABLE (usb, m920x_table); -static int set_filter(struct dvb_usb_device *d, int type, int idx, int pid) +static int set_filter(struct dvb_usb_adapter *adap, int type, int idx, int pid) { int ret = 0; @@ -494,61 +494,61 @@ static int set_filter(struct dvb_usb_device *d, int type, int idx, int pid) pid |= 0x8000; - if ((ret = m9206_write(d->udev, 0x25, pid, (type << 8) | (idx * 4) )) != 0) + if ((ret = m9206_write(adap->dev->udev, 0x25, pid, (type << 8) | (idx * 4) )) != 0) return ret; - if ((ret = m9206_write(d->udev, 0x25, 0, (type << 8) | (idx * 4) )) != 0) + if ((ret = m9206_write(adap->dev->udev, 0x25, 0, (type << 8) | (idx * 4) )) != 0) return ret; return ret; } -static int m9206_pid_filter_ctrl(struct dvb_usb_device *d, int onoff) +static int m9206_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) { int ret = 0; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) return -EAGAIN; deb_rc("filtering %s\n", onoff ? "on" : "off"); if (onoff == 0) { - if ((ret = set_filter(d, 0x81, 1, 0x00)) != 0) + if ((ret = set_filter(adap, 0x81, 1, 0x00)) != 0) goto unlock; - if ((ret = set_filter(d, 0x82, 0, 0x02f5)) != 0) + if ((ret = set_filter(adap, 0x82, 0, 0x02f5)) != 0) goto unlock; } unlock: - mutex_unlock(&d->i2c_mutex); + mutex_unlock(&adap->dev->i2c_mutex); return ret; } -static int m9206_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff) +static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) { int ret = 0; if (pid == 8192) - return m9206_pid_filter_ctrl(d, !onoff); + return m9206_pid_filter_ctrl(adap, !onoff); - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) return -EAGAIN; deb_rc("filter %d, pid %x, %s\n", index, pid, onoff ? "on" : "off"); if (onoff == 0) pid = 0; - if ((ret = set_filter(d, 0x81, 1, 0x01)) != 0) + if ((ret = set_filter(adap, 0x81, 1, 0x01)) != 0) goto unlock; - if ((ret = set_filter(d, 0x81, index + 2, pid)) != 0) + if ((ret = set_filter(adap, 0x81, index + 2, pid)) != 0) goto unlock; - if ((ret = set_filter(d, 0x82, 0, 0x02f5)) != 0) + if ((ret = set_filter(adap, 0x82, 0, 0x02f5)) != 0) goto unlock; unlock: - mutex_unlock(&d->i2c_mutex); + mutex_unlock(&adap->dev->i2c_mutex); return ret; } @@ -614,19 +614,11 @@ static int m9206_firmware_download(struct usb_device *udev, const struct firmwar return ret; } -static struct dvb_usb_properties megasky_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_HAS_PID_FILTER | - DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_NEED_PID_FILTERING, - .pid_filter_count = 8, - +static struct dvb_usb_device_properties megasky_properties = { .usb_ctrl = DEVICE_SPECIFIC, .firmware = "dvb-usb-megasky-02.fw", .download_firmware = m9206_firmware_download, - .pid_filter = m9206_pid_filter, - .pid_filter_ctrl = m9206_pid_filter_ctrl, - .frontend_attach = megasky_frontend_attach, - .rc_interval = 200, .rc_key_map = megasky_rc_keys, .rc_key_map_size = ARRAY_SIZE(megasky_rc_keys), @@ -635,19 +627,32 @@ static struct dvb_usb_properties megasky_properties = { .size_of_priv = 0, .identify_state = megasky_identify_state, + .num_adapters = 1, + .adapter = {{ + .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | + DVB_USB_ADAP_NEED_PID_FILTERING, + .pid_filter_count = 8, + .pid_filter = m9206_pid_filter, + .pid_filter_ctrl = m9206_pid_filter_ctrl, + + .frontend_attach = megasky_frontend_attach, + + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x81, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + }}, .i2c_algo = &m9206_i2c_algo, .generic_bulk_ctrl_endpoint = 0x01, - .urb = { - .type = DVB_USB_BULK, - .count = 8, - .endpoint = 0x81, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, + .num_device_descs = 1, .devices = { { "MSI Mega Sky 580 DVB-T USB2.0", -- cgit v1.2.3 From f2f612b275408e919235c937e61c6992b71f6723 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 23 Sep 2006 19:13:12 -0400 Subject: m920x: trivial cleanups From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index aa53bc498..4213beda8 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -178,10 +178,10 @@ static struct i2c_algorithm m9206_i2c_algo = { }; /* Callbacks for DVB USB */ -static int megasky_identify_state (struct usb_device *udev, - struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, - int *cold) +static int megasky_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, + int *cold) { struct usb_host_interface *alt; @@ -448,7 +448,7 @@ static int megasky_frontend_attach(struct dvb_usb_adapter *adap) /* DVB USB Driver stuff */ static struct dvb_usb_device_properties megasky_properties; -static int megasky_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int m920x_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct dvb_usb_device *d; struct usb_host_interface *alt; @@ -668,7 +668,7 @@ static struct usb_driver m920x_driver = { .owner = THIS_MODULE, #endif .name = "dvb_usb_m920x", - .probe = megasky_probe, + .probe = m920x_probe, .disconnect = dvb_usb_device_exit, .id_table = m920x_table, }; -- cgit v1.2.3 From 8d754c26a4d9b88654352d8600fd622c1f7060d2 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 23 Sep 2006 19:40:20 -0400 Subject: m920x: break out qt1010 tuner code into a separate file From: Michael Krufky qt1010 is a tuner used in some other devices, so this code should be put into a separate file so that it could be reused by other drivers. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 204 +------------------------- linux/drivers/media/dvb/frontends/qt1010.h | 221 +++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+), 203 deletions(-) create mode 100644 linux/drivers/media/dvb/frontends/qt1010.h (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 4213beda8..2a7bb3808 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -13,6 +13,7 @@ #include "mt352.h" #include "mt352_priv.h" +#include "qt1010.h" /* debug */ int dvb_usb_m920x_debug; @@ -226,209 +227,6 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe) struct mt352_state; -#define W 0 -#define R 1 -/* Not actual hw limits. */ -#define QT1010_MIN_STEP 2000000 -#define QT1010_MIN_FREQ 48000000 - -int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) -{ - int i; - int div, mod; - struct { - u8 read, reg, value; - } rd[46] = { { W, 0x01, 0x80 }, - { W, 0x02, 0x3f }, - { W, 0x05, 0xff }, /* c */ - { W, 0x06, 0x44 }, - { W, 0x07, 0xff }, /* c */ - { W, 0x08, 0x08 }, - { W, 0x09, 0xff }, /* c */ - { W, 0x0a, 0xff }, /* c */ - { W, 0x0b, 0xff }, /* c */ - { W, 0x0c, 0xe1 }, - { W, 0x1a, 0xff }, /* 10 c */ - { W, 0x1b, 0x00 }, - { W, 0x1c, 0x89 }, - { W, 0x11, 0xff }, /* c */ - { W, 0x12, 0x91 }, - { W, 0x22, 0xff }, /* c */ - { W, 0x1e, 0x00 }, - { W, 0x1e, 0xd0 }, - { R, 0x22, 0xff }, /* c read */ - { W, 0x1e, 0x00 }, - { R, 0x05, 0xff }, /* 20 c read */ - { R, 0x22, 0xff }, /* c read */ - { W, 0x23, 0xd0 }, - { W, 0x1e, 0x00 }, - { W, 0x1e, 0xe0 }, - { R, 0x23, 0xff }, /* c read */ - { W, 0x1e, 0x00 }, - { W, 0x24, 0xd0 }, - { W, 0x1e, 0x00 }, - { W, 0x1e, 0xf0 }, - { R, 0x24, 0xff }, /* 30 c read */ - { W, 0x1e, 0x00 }, - { W, 0x14, 0x7f }, - { W, 0x15, 0x7f }, - { W, 0x05, 0xff }, /* c */ - { W, 0x06, 0x00 }, - { W, 0x15, 0x1f }, - { W, 0x16, 0xff }, - { W, 0x18, 0xff }, - { W, 0x1f, 0xff }, /* c */ - { W, 0x20, 0xff }, /* 40 c */ - { W, 0x21, 0x53 }, - { W, 0x25, 0xbd }, - { W, 0x26, 0x15 }, - { W, 0x02, 0x00 }, - { W, 0x01, 0x00 }, - }; - struct i2c_msg msg; - struct dvb_usb_device *d = fe->dvb->priv; - unsigned long freq = params->frequency; - - if (freq % QT1010_MIN_STEP) - deb_rc("frequency not supported.\n"); - - (void) buf; - (void) buf_len; - - div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; - mod = (div + 16 - 9) % 16; - - /* 0x5 */ - if (div >= 377) - rd[2].value = 0x74; - else if (div >= 265) - rd[2].value = 0x54; - else if (div >= 121) - rd[2].value = 0x34; - else - rd[2].value = 0x14; - - /* 0x7 */ - rd[4].value = (((freq - QT1010_MIN_FREQ) / 1000000) * 9975 + 12960000) / 320000; - - /* 09 */ - if (mod < 4) - rd[6].value = 0x1d; - else - rd[6].value = 0x1c; - - /* 0a */ - if (mod < 2) - rd[7].value = 0x09; - else if (mod < 4) - rd[7].value = 0x08; - else if (mod < 6) - rd[7].value = 0x0f; - else if (mod < 8) - rd[7].value = 0x0e; - else if (mod < 10) - rd[7].value = 0x0d; - else if (mod < 12) - rd[7].value = 0x0c; - else if (mod < 14) - rd[7].value = 0x0b; - else - rd[7].value = 0x0a; - - /* 0b */ - if (div & 1) - rd[8].value = 0x45; - else - rd[8].value = 0x44; - - /* 1a */ - if (div & 1) - rd[10].value = 0x78; - else - rd[10].value = 0xf8; - - /* 11 */ - if (div >= 265) - rd[13].value = 0xf9; - else if (div >= 121) - rd[13].value = 0xfd; - else - rd[13].value = 0xf9; - - /* 22 */ - if (div < 201) - rd[15].value = 0xd0; - else if (div < 217) - rd[15].value = 0xd3; - else if (div < 233) - rd[15].value = 0xd6; - else if (div < 249) - rd[15].value = 0xd9; - else if (div < 265) - rd[15].value = 0xda; - else - rd[15].value = 0xd0; - - /* 05 */ - if (div >= 377) - rd[34].value = 0x70; - else if (div >= 265) - rd[34].value = 0x50; - else if (div >= 121) - rd[34].value = 0x30; - else - rd[34].value = 0x10; - - /* 1f */ - if (mod < 4) - rd[39].value = 0x64; - else if (mod < 6) - rd[39].value = 0x66; - else if (mod < 8) - rd[39].value = 0x67; - else if (mod < 12) - rd[39].value = 0x68; - else if (mod < 14) - rd[39].value = 0x69; - else - rd[39].value = 0x6a; - - /* 20 */ - if (mod < 4) - rd[40].value = 0x10; - else if (mod < 6) - rd[40].value = 0x11; - else if (mod < 10) - rd[40].value = 0x12; - else if (mod < 12) - rd[40].value = 0x13; - else if (mod < 14) - rd[40].value = 0x14; - else - rd[40].value = 0x15; - - deb_rc("Now tuning... "); - for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { - if (rd[i].read) - continue; - - msg.flags = 0; - msg.len = 2; - msg.addr = 0xc4; - msg.buf = &rd[i].reg; - - if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { - deb_rc("tuner write failed\n"); - return -EIO; - } - } - deb_rc("done\n"); - - return 0; -} -#undef W -#undef R - static struct mt352_config megasky_mt352_config = { .demod_address = 0x1e, .demod_init = megasky_mt352_demod_init, diff --git a/linux/drivers/media/dvb/frontends/qt1010.h b/linux/drivers/media/dvb/frontends/qt1010.h new file mode 100644 index 000000000..e526e3c23 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/qt1010.h @@ -0,0 +1,221 @@ +/* + * qt1010.h - DVB-T Tuner support + * + * 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. + */ + +#ifndef _QT1010_H_ +#define _QT1010_H_ + +#define QT1010_W 0 +#define QT1010_R 1 +/* Not actual hw limits. */ +#define QT1010_MIN_STEP 2000000 +#define QT1010_MIN_FREQ 48000000 + +static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) +{ + int i; + int div, mod; + struct { + u8 read, reg, value; + } rd[46] = { { QT1010_W, 0x01, 0x80 }, + { QT1010_W, 0x02, 0x3f }, + { QT1010_W, 0x05, 0xff }, /* c */ + { QT1010_W, 0x06, 0x44 }, + { QT1010_W, 0x07, 0xff }, /* c */ + { QT1010_W, 0x08, 0x08 }, + { QT1010_W, 0x09, 0xff }, /* c */ + { QT1010_W, 0x0a, 0xff }, /* c */ + { QT1010_W, 0x0b, 0xff }, /* c */ + { QT1010_W, 0x0c, 0xe1 }, + { QT1010_W, 0x1a, 0xff }, /* 10 c */ + { QT1010_W, 0x1b, 0x00 }, + { QT1010_W, 0x1c, 0x89 }, + { QT1010_W, 0x11, 0xff }, /* c */ + { QT1010_W, 0x12, 0x91 }, + { QT1010_W, 0x22, 0xff }, /* c */ + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x1e, 0xd0 }, + { QT1010_R, 0x22, 0xff }, /* c read */ + { QT1010_W, 0x1e, 0x00 }, + { QT1010_R, 0x05, 0xff }, /* 20 c read */ + { QT1010_R, 0x22, 0xff }, /* c read */ + { QT1010_W, 0x23, 0xd0 }, + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x1e, 0xe0 }, + { QT1010_R, 0x23, 0xff }, /* c read */ + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x24, 0xd0 }, + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x1e, 0xf0 }, + { QT1010_R, 0x24, 0xff }, /* 30 c read */ + { QT1010_W, 0x1e, 0x00 }, + { QT1010_W, 0x14, 0x7f }, + { QT1010_W, 0x15, 0x7f }, + { QT1010_W, 0x05, 0xff }, /* c */ + { QT1010_W, 0x06, 0x00 }, + { QT1010_W, 0x15, 0x1f }, + { QT1010_W, 0x16, 0xff }, + { QT1010_W, 0x18, 0xff }, + { QT1010_W, 0x1f, 0xff }, /* c */ + { QT1010_W, 0x20, 0xff }, /* 40 c */ + { QT1010_W, 0x21, 0x53 }, + { QT1010_W, 0x25, 0xbd }, + { QT1010_W, 0x26, 0x15 }, + { QT1010_W, 0x02, 0x00 }, + { QT1010_W, 0x01, 0x00 }, + }; + struct i2c_msg msg; + struct dvb_usb_device *d = fe->dvb->priv; + unsigned long freq = params->frequency; + + if (freq % QT1010_MIN_STEP) + printk("frequency not supported.\n"); + + (void) buf; + (void) buf_len; + + div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; + mod = (div + 16 - 9) % 16; + + /* 0x5 */ + if (div >= 377) + rd[2].value = 0x74; + else if (div >= 265) + rd[2].value = 0x54; + else if (div >= 121) + rd[2].value = 0x34; + else + rd[2].value = 0x14; + + /* 0x7 */ + rd[4].value = (((freq - QT1010_MIN_FREQ) / 1000000) * 9975 + 12960000) / 320000; + + /* 09 */ + if (mod < 4) + rd[6].value = 0x1d; + else + rd[6].value = 0x1c; + + /* 0a */ + if (mod < 2) + rd[7].value = 0x09; + else if (mod < 4) + rd[7].value = 0x08; + else if (mod < 6) + rd[7].value = 0x0f; + else if (mod < 8) + rd[7].value = 0x0e; + else if (mod < 10) + rd[7].value = 0x0d; + else if (mod < 12) + rd[7].value = 0x0c; + else if (mod < 14) + rd[7].value = 0x0b; + else + rd[7].value = 0x0a; + + /* 0b */ + if (div & 1) + rd[8].value = 0x45; + else + rd[8].value = 0x44; + + /* 1a */ + if (div & 1) + rd[10].value = 0x78; + else + rd[10].value = 0xf8; + + /* 11 */ + if (div >= 265) + rd[13].value = 0xf9; + else if (div >= 121) + rd[13].value = 0xfd; + else + rd[13].value = 0xf9; + + /* 22 */ + if (div < 201) + rd[15].value = 0xd0; + else if (div < 217) + rd[15].value = 0xd3; + else if (div < 233) + rd[15].value = 0xd6; + else if (div < 249) + rd[15].value = 0xd9; + else if (div < 265) + rd[15].value = 0xda; + else + rd[15].value = 0xd0; + + /* 05 */ + if (div >= 377) + rd[34].value = 0x70; + else if (div >= 265) + rd[34].value = 0x50; + else if (div >= 121) + rd[34].value = 0x30; + else + rd[34].value = 0x10; + + /* 1f */ + if (mod < 4) + rd[39].value = 0x64; + else if (mod < 6) + rd[39].value = 0x66; + else if (mod < 8) + rd[39].value = 0x67; + else if (mod < 12) + rd[39].value = 0x68; + else if (mod < 14) + rd[39].value = 0x69; + else + rd[39].value = 0x6a; + + /* 20 */ + if (mod < 4) + rd[40].value = 0x10; + else if (mod < 6) + rd[40].value = 0x11; + else if (mod < 10) + rd[40].value = 0x12; + else if (mod < 12) + rd[40].value = 0x13; + else if (mod < 14) + rd[40].value = 0x14; + else + rd[40].value = 0x15; + + for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { + if (rd[i].read) + continue; + + msg.flags = 0; + msg.len = 2; + msg.addr = 0xc4; + msg.buf = &rd[i].reg; + + if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { + printk("tuner write failed\n"); + return -EIO; + } + } + + return 0; +} + +#endif -- cgit v1.2.3 From e5609737e9b7d74fd2daec8a4a6f5c354ed7e29b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 27 Sep 2006 23:47:51 -0400 Subject: m920x: misc updates and fixes From: Aapo Tahkola - hardware pid filtering no longer enabled unless in usb 1.x mode - more responsive rc handling - some minor bug fixes and code refolding - m9206_write delay dropped (doesn't seem to be needed) Signed-off-by: Aapo Tahkola Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 213 +++++++++++++++++------------ linux/drivers/media/dvb/dvb-usb/m920x.h | 18 +++ linux/drivers/media/dvb/frontends/qt1010.h | 7 +- 3 files changed, 145 insertions(+), 93 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 2a7bb3808..3c7f639e6 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -62,23 +62,36 @@ static inline int m9206_write(struct usb_device *udev, u8 request, u16 value, u1 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, USB_TYPE_VENDOR | USB_DIR_OUT, value, index, NULL, 0, 2000); - msleep(3); + return ret; +} + +static int m9206_rc_init(struct usb_device *udev) +{ + int ret = 0; + + /* Remote controller init. */ + if ((ret = m9206_write(udev, M9206_CORE, 0xa8, M9206_RC_INIT2)) != 0) + return ret; + + if ((ret = m9206_write(udev, M9206_CORE, 0x51, M9206_RC_INIT1)) != 0) + return ret; return ret; } static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { + struct m9206_state *m = d->priv; int i, ret = 0; u8 rc_state[2]; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; - if ((ret = m9206_read(d->udev, 0x22, 0x0, 0xff51, rc_state, 1)) != 0) + if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0) goto unlock; - if ((ret = m9206_read(d->udev, 0x22, 0x0, 0xff52, rc_state + 1, 1)) != 0) + if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0) goto unlock; for (i = 0; i < ARRAY_SIZE(megasky_rc_keys); i++) @@ -92,11 +105,14 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) case 0x93: case 0x92: + m->rep_count = 0; *state = REMOTE_KEY_PRESSED; goto unlock; case 0x91: - *state = REMOTE_KEY_REPEAT; + /* For comfort. */ + if (++m->rep_count > 2) + *state = REMOTE_KEY_REPEAT; goto unlock; default: @@ -125,6 +141,12 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu int i; int ret = 0; + /* Need to access d->adapter[0] */ + if (d->num_adapters_initialized != 1) { + deb_rc("Impossible happened!\n"); + return -EINVAL; + } + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; @@ -134,22 +156,23 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu for (i = 0; i < num; i++) { u8 w_len; - if ((ret = m9206_write(d->udev, 0x23, msg[i].addr, 0x80)) != 0) + if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].addr, 0x80)) != 0) goto unlock; - if ((ret = m9206_write(d->udev, 0x23, msg[i].buf[0], 0x0)) != 0) + if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[0], 0x0)) != 0) goto unlock; if (i + 1 < num && msg[i + 1].flags & I2C_M_RD) { - if (msg[i].addr == 0x1e) - w_len = 0x1f; - else + /* Possibly device dependant */ + if (msg[i].addr == d->adapter[0].pll_addr) w_len = 0xc5; + else + w_len = 0x1f; - if ((ret = m9206_write(d->udev, 0x23, w_len, 0x80)) != 0) + if ((ret = m9206_write(d->udev, M9206_I2C, w_len, 0x80)) != 0) goto unlock; - if ((ret = m9206_read(d->udev, 0x23, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0) + if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0) goto unlock; i++; @@ -157,7 +180,7 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu if (msg[i].len != 2) return -EINVAL; - if ((ret = m9206_write(d->udev, 0x23, msg[i].buf[1], 0x40)) != 0) + if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[1], 0x40)) != 0) goto unlock; } } @@ -194,31 +217,23 @@ static int megasky_identify_state(struct usb_device *udev, static int megasky_mt352_demod_init(struct dvb_frontend *fe) { - int i; - static u8 buf1[] = { - CONFIG, 0x3d, - CLOCK_CTL, 0x30, - RESET, 0x80, - ADC_CTL_1, 0x40, - AGC_TARGET, 0x1c, - AGC_CTL, 0x20, - 0x69, 0x00, - 0x6a, 0xff, - 0x6b, 0xff, - 0x6c, 0x40, - 0x6d, 0xff, - 0x6e, 0x00, - 0x6f, 0x40, - 0x70, 0x40, - 0x93, 0x1a, - 0xb5, 0x7a, - ACQ_CTL, 0x50, - INPUT_FREQ_1, 0x31, - INPUT_FREQ_0, 0x05, - }; - - for (i = 0; i < ARRAY_SIZE(buf1); i += 2) - mt352_write(fe, &buf1[i], 2); + u8 config[] = { CONFIG, 0x3d }; + u8 clock[] = { CLOCK_CTL, 0x30 }; + u8 reset[] = { RESET, 0x80 }; + u8 adc_ctl[] = { ADC_CTL_1, 0x40 }; + u8 agc[] = { AGC_TARGET, 0x1c, 0x20 }; + u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 }; + u8 unk1[] = { 0x93, 0x1a }; + u8 unk2[] = { 0xb5, 0x7a }; + + mt352_write(fe, config, ARRAY_SIZE(config)); + mt352_write(fe, clock, ARRAY_SIZE(clock)); + mt352_write(fe, reset, ARRAY_SIZE(reset)); + mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl)); + mt352_write(fe, agc, ARRAY_SIZE(agc)); + mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc)); + mt352_write(fe, unk1, ARRAY_SIZE(unk1)); + mt352_write(fe, unk2, ARRAY_SIZE(unk2)); deb_rc("Demod init!\n"); @@ -229,6 +244,7 @@ struct mt352_state; static struct mt352_config megasky_mt352_config = { .demod_address = 0x1e, + .no_tuner = 1, .demod_init = megasky_mt352_demod_init, }; @@ -237,22 +253,39 @@ static int megasky_frontend_attach(struct dvb_usb_adapter *adap) deb_rc("megasky_frontend_attach!\n"); if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) != NULL) { - adap->fe->ops.tuner_ops.calc_regs = qt1010_set_params; return 0; } return -EIO; } +static int megasky_tuner_attach(struct dvb_usb_adapter *adap) +{ + adap->pll_addr = 0xc4; + adap->pll_desc = NULL; + adap->fe->ops.tuner_ops.set_params = qt1010_set_params; + + return 0; +} + /* DVB USB Driver stuff */ static struct dvb_usb_device_properties megasky_properties; static int m920x_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *udev = interface_to_usbdev(intf); struct dvb_usb_device *d; struct usb_host_interface *alt; + struct dvb_usb_device_properties props; int ret; - if ((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) { + memcpy(&props, &megasky_properties, sizeof(struct dvb_usb_device_properties)); + + /* Hardware pid filtering isn't quite perfect so dont use unless have to. */ + if (udev->speed == USB_SPEED_FULL) + props.caps |= DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF; + + if ((ret = dvb_usb_device_init(intf, &props, THIS_MODULE, &d)) == 0) { deb_rc("probed!\n"); alt = usb_altnum_to_altsetting(intf, 1); @@ -267,11 +300,7 @@ static int m920x_probe(struct usb_interface *intf, const struct usb_device_id *i deb_rc("Changed to alternate setting!\n"); - /* Remote controller init. */ - if ((ret = m9206_write(d->udev, 0x22, 0xa8, 0xff55)) != 0) - return ret; - - if ((ret = m9206_write(d->udev, 0x22, 0x51, 0xff54)) != 0) + if ((ret = m9206_rc_init(d->udev)) != 0) return ret; } return ret; @@ -292,63 +321,71 @@ static int set_filter(struct dvb_usb_adapter *adap, int type, int idx, int pid) pid |= 0x8000; - if ((ret = m9206_write(adap->dev->udev, 0x25, pid, (type << 8) | (idx * 4) )) != 0) + if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0) return ret; - if ((ret = m9206_write(adap->dev->udev, 0x25, 0, (type << 8) | (idx * 4) )) != 0) + if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0) return ret; return ret; } -static int m9206_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) +static int m9206_update_filters(struct dvb_usb_adapter *adap) { - int ret = 0; + struct m9206_state *m = adap->dev->priv; + int enabled = m->filtering_enabled; + int i, ret = 0, filter = 0; - if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) - return -EAGAIN; + for (i = 0; i < M9206_MAX_FILTERS; i++) + if (m->filters[i] == 8192) + enabled = 0; - deb_rc("filtering %s\n", onoff ? "on" : "off"); - if (onoff == 0) { - if ((ret = set_filter(adap, 0x81, 1, 0x00)) != 0) - goto unlock; + /* Disable all filters */ + if ((ret = set_filter(adap, 0x81, 1, enabled)) != 0) + return ret; - if ((ret = set_filter(adap, 0x82, 0, 0x02f5)) != 0) - goto unlock; + for (i = 0; i < M9206_MAX_FILTERS; i++) + if ((ret = set_filter(adap, 0x81, i + 2, 0)) != 0) + return ret; + + if ((ret = set_filter(adap, 0x82, 0, 0x0)) != 0) + return ret; + + /* Set */ + if (enabled) { + for (i = 0; i < M9206_MAX_FILTERS; i++) { + if (m->filters[i] == 0) + continue; + + if ((ret = set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0) + return ret; + + filter++; + } } - unlock: - mutex_unlock(&adap->dev->i2c_mutex); + + if ((ret = set_filter(adap, 0x82, 0, 0x02f5)) != 0) + return ret; return ret; } -static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) +static int m9206_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) { - int ret = 0; - - if (pid == 8192) - return m9206_pid_filter_ctrl(adap, !onoff); - - if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) - return -EAGAIN; + struct m9206_state *m = adap->dev->priv; - deb_rc("filter %d, pid %x, %s\n", index, pid, onoff ? "on" : "off"); - if (onoff == 0) - pid = 0; + m->filtering_enabled = onoff ? 1 : 0; - if ((ret = set_filter(adap, 0x81, 1, 0x01)) != 0) - goto unlock; - - if ((ret = set_filter(adap, 0x81, index + 2, pid)) != 0) - goto unlock; + return m9206_update_filters(adap); +} - if ((ret = set_filter(adap, 0x82, 0, 0x02f5)) != 0) - goto unlock; +static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) +{ + struct m9206_state *m = adap->dev->priv; - unlock: - mutex_unlock(&adap->dev->i2c_mutex); + m->filters[index] = onoff ? pid : 0; - return ret; + return m9206_update_filters(adap); } static int m9206_firmware_download(struct usb_device *udev, const struct firmware *fw) @@ -359,11 +396,11 @@ static int m9206_firmware_download(struct usb_device *udev, const struct firmwar buff = kmalloc(65536, GFP_KERNEL); - if ((ret = m9206_read(udev, 0x25, 0x0, 0x8000, read, 4)) != 0) + if ((ret = m9206_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0) goto done; deb_rc("%x %x %x %x\n", read[0], read[1], read[2], read[3]); - if ((ret = m9206_read(udev, 0x30, 0x0, 0x0, read, 1)) != 0) + if ((ret = m9206_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0) goto done; deb_rc("%x\n", read[0]); @@ -383,7 +420,8 @@ static int m9206_firmware_download(struct usb_device *udev, const struct firmwar memcpy(buff, fw->data + i, size); ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0), - 0x30, USB_TYPE_VENDOR | USB_DIR_OUT, + M9206_FW, + USB_TYPE_VENDOR | USB_DIR_OUT, value, index, buff, size, 20); if (ret != size) { deb_rc("error while uploading fw!\n"); @@ -403,7 +441,7 @@ static int m9206_firmware_download(struct usb_device *udev, const struct firmwar msleep(36); /* m9206 will disconnect itself from the bus after this. */ - (void) m9206_write(udev, 0x22, 0x01, 0xff69); + (void) m9206_write(udev, M9206_CORE, 0x01, M9206_FW_GO); deb_rc("firmware uploaded!\n"); done: @@ -417,24 +455,23 @@ static struct dvb_usb_device_properties megasky_properties = { .firmware = "dvb-usb-megasky-02.fw", .download_firmware = m9206_firmware_download, - .rc_interval = 200, + .rc_interval = 100, .rc_key_map = megasky_rc_keys, .rc_key_map_size = ARRAY_SIZE(megasky_rc_keys), .rc_query = m9206_rc_query, - .size_of_priv = 0, + .size_of_priv = sizeof(struct m9206_state), .identify_state = megasky_identify_state, .num_adapters = 1, .adapter = {{ - .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | - DVB_USB_ADAP_NEED_PID_FILTERING, + .caps = DVB_USB_IS_AN_I2C_ADAPTER, .pid_filter_count = 8, .pid_filter = m9206_pid_filter, .pid_filter_ctrl = m9206_pid_filter_ctrl, .frontend_attach = megasky_frontend_attach, + .tuner_attach = megasky_tuner_attach, .stream = { .type = USB_BULK, diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.h b/linux/drivers/media/dvb/dvb-usb/m920x.h index fdb967aa3..709b7d205 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.h +++ b/linux/drivers/media/dvb/dvb-usb/m920x.h @@ -7,4 +7,22 @@ extern int dvb_usb_m920x_debug; #define deb_rc(args...) dprintk(dvb_usb_m920x_debug,0x01,args) +#define M9206_CORE 0x22 +#define M9206_RC_STATE 0xff51 +#define M9206_RC_KEY 0xff52 +#define M9206_RC_INIT1 0xff54 +#define M9206_RC_INIT2 0xff55 +#define M9206_FW_GO 0xff69 + +#define M9206_I2C 0x23 +#define M9206_FILTER 0x25 +#define M9206_FW 0x30 + +#define M9206_MAX_FILTERS 8 +struct m9206_state { + u16 filters[M9206_MAX_FILTERS]; + int filtering_enabled; + int rep_count; +}; + #endif diff --git a/linux/drivers/media/dvb/frontends/qt1010.h b/linux/drivers/media/dvb/frontends/qt1010.h index e526e3c23..3a566085f 100644 --- a/linux/drivers/media/dvb/frontends/qt1010.h +++ b/linux/drivers/media/dvb/frontends/qt1010.h @@ -25,7 +25,7 @@ #define QT1010_MIN_STEP 2000000 #define QT1010_MIN_FREQ 48000000 -static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) +static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { int i; int div, mod; @@ -85,9 +85,6 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame if (freq % QT1010_MIN_STEP) printk("frequency not supported.\n"); - (void) buf; - (void) buf_len; - div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; mod = (div + 16 - 9) % 16; @@ -206,7 +203,7 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame msg.flags = 0; msg.len = 2; - msg.addr = 0xc4; + msg.addr = d->adapter[0].pll_addr; msg.buf = &rd[i].reg; if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { -- cgit v1.2.3 From 6640030077783c0cfa63707b7834cadbc2a752ec Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 28 Sep 2006 00:46:49 -0400 Subject: m920x: more cleanups From: Michael Krufky Some cleanups and suggestions from Patrick Boettcher. Dropped the mutex in m9206_rc_query using #if 0, because M9206_CORE, M9206_I2C, M9206_FILTER and M9206_FW can be accessed concurrently. Thanks to both Aapo Tahkola and Patrick Boettcher. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 105 +++++++++++++++----------------- linux/drivers/media/dvb/dvb-usb/m920x.h | 12 ++-- 2 files changed, 55 insertions(+), 62 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 3c7f639e6..a7d42934d 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -16,7 +16,7 @@ #include "qt1010.h" /* debug */ -int dvb_usb_m920x_debug; +static int dvb_usb_m920x_debug; module_param_named(debug,dvb_usb_m920x_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); @@ -85,8 +85,10 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) int i, ret = 0; u8 rc_state[2]; +#if 0 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; +#endif if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0) goto unlock; @@ -128,7 +130,9 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) *state = REMOTE_NO_KEY_PRESSED; unlock: +#if 0 mutex_unlock(&d->i2c_mutex); +#endif return ret; } @@ -240,8 +244,6 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe) return 0; } -struct mt352_state; - static struct mt352_config megasky_mt352_config = { .demod_address = 0x1e, .no_tuner = 1, @@ -267,52 +269,7 @@ static int megasky_tuner_attach(struct dvb_usb_adapter *adap) return 0; } -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties megasky_properties; - -static int m920x_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct dvb_usb_device *d; - struct usb_host_interface *alt; - struct dvb_usb_device_properties props; - int ret; - - memcpy(&props, &megasky_properties, sizeof(struct dvb_usb_device_properties)); - - /* Hardware pid filtering isn't quite perfect so dont use unless have to. */ - if (udev->speed == USB_SPEED_FULL) - props.caps |= DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF; - - if ((ret = dvb_usb_device_init(intf, &props, THIS_MODULE, &d)) == 0) { - deb_rc("probed!\n"); - - alt = usb_altnum_to_altsetting(intf, 1); - if (alt == NULL) { - deb_rc("not alt found!\n"); - return -ENODEV; - } - - ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); - if (ret < 0) - return ret; - - deb_rc("Changed to alternate setting!\n"); - - if ((ret = m9206_rc_init(d->udev)) != 0) - return ret; - } - return ret; -} - -static struct usb_device_id m920x_table [] = { - { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, m920x_table); - -static int set_filter(struct dvb_usb_adapter *adap, int type, int idx, int pid) +static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx, int pid) { int ret = 0; @@ -341,14 +298,14 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap) enabled = 0; /* Disable all filters */ - if ((ret = set_filter(adap, 0x81, 1, enabled)) != 0) + if ((ret = m9206_set_filter(adap, 0x81, 1, enabled)) != 0) return ret; for (i = 0; i < M9206_MAX_FILTERS; i++) - if ((ret = set_filter(adap, 0x81, i + 2, 0)) != 0) + if ((ret = m9206_set_filter(adap, 0x81, i + 2, 0)) != 0) return ret; - if ((ret = set_filter(adap, 0x82, 0, 0x0)) != 0) + if ((ret = m9206_set_filter(adap, 0x82, 0, 0x0)) != 0) return ret; /* Set */ @@ -357,14 +314,14 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap) if (m->filters[i] == 0) continue; - if ((ret = set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0) + if ((ret = m9206_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0) return ret; filter++; } } - if ((ret = set_filter(adap, 0x82, 0, 0x02f5)) != 0) + if ((ret = m9206_set_filter(adap, 0x82, 0, 0x02f5)) != 0) return ret; return ret; @@ -450,6 +407,42 @@ static int m9206_firmware_download(struct usb_device *udev, const struct firmwar return ret; } +/* DVB USB Driver stuff */ +static struct dvb_usb_device_properties megasky_properties; + +static int m920x_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct dvb_usb_device *d; + struct usb_host_interface *alt; + int ret; + + if ((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) { + deb_rc("probed!\n"); + + alt = usb_altnum_to_altsetting(intf, 1); + if (alt == NULL) { + deb_rc("not alt found!\n"); + return -ENODEV; + } + + ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); + if (ret < 0) + return ret; + + deb_rc("Changed to alternate setting!\n"); + + if ((ret = m9206_rc_init(d->udev)) != 0) + return ret; + } + return ret; +} + +static struct usb_device_id m920x_table [] = { + { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, m920x_table); + static struct dvb_usb_device_properties megasky_properties = { .usb_ctrl = DEVICE_SPECIFIC, .firmware = "dvb-usb-megasky-02.fw", @@ -465,7 +458,9 @@ static struct dvb_usb_device_properties megasky_properties = { .identify_state = megasky_identify_state, .num_adapters = 1, .adapter = {{ - .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 8, .pid_filter = m9206_pid_filter, .pid_filter_ctrl = m9206_pid_filter_ctrl, diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.h b/linux/drivers/media/dvb/dvb-usb/m920x.h index 709b7d205..597df11e6 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.h +++ b/linux/drivers/media/dvb/dvb-usb/m920x.h @@ -4,15 +4,14 @@ #define DVB_USB_LOG_PREFIX "m920x" #include "dvb-usb.h" -extern int dvb_usb_m920x_debug; #define deb_rc(args...) dprintk(dvb_usb_m920x_debug,0x01,args) #define M9206_CORE 0x22 -#define M9206_RC_STATE 0xff51 -#define M9206_RC_KEY 0xff52 -#define M9206_RC_INIT1 0xff54 -#define M9206_RC_INIT2 0xff55 -#define M9206_FW_GO 0xff69 +#define M9206_RC_STATE 0xff51 +#define M9206_RC_KEY 0xff52 +#define M9206_RC_INIT1 0xff54 +#define M9206_RC_INIT2 0xff55 +#define M9206_FW_GO 0xff69 #define M9206_I2C 0x23 #define M9206_FILTER 0x25 @@ -24,5 +23,4 @@ struct m9206_state { int filtering_enabled; int rep_count; }; - #endif -- cgit v1.2.3 From c40096038d501a3afa1722d4290477ae37557964 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 28 Sep 2006 12:48:03 -0400 Subject: m920x: more trivial cleanups From: Patrick Boettcher - Removed some needless brances - Removed an unneeded check for adapter[0] - Removed unneeded declaration of .generic_bulk_ctrl_endpoint = 0x01 Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index a7d42934d..6fc71843b 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -145,12 +145,6 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu int i; int ret = 0; - /* Need to access d->adapter[0] */ - if (d->num_adapters_initialized != 1) { - deb_rc("Impossible happened!\n"); - return -EINVAL; - } - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; @@ -254,9 +248,8 @@ static int megasky_frontend_attach(struct dvb_usb_adapter *adap) { deb_rc("megasky_frontend_attach!\n"); - if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) != NULL) { + if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) != NULL) return 0; - } return -EIO; } @@ -481,8 +474,6 @@ static struct dvb_usb_device_properties megasky_properties = { }}, .i2c_algo = &m9206_i2c_algo, - .generic_bulk_ctrl_endpoint = 0x01, - .num_device_descs = 1, .devices = { { "MSI Mega Sky 580 DVB-T USB2.0", -- cgit v1.2.3 From 1dbb128dceee78e8bcaada93e52d992c104737d0 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 28 Sep 2006 13:47:21 -0400 Subject: m920x: move qt1010_tuner_attach function into qt1010.h From: Michael Krufky The megasky_tuner_attach function is not specific to this device. This patch renames it to qt1010_tuner_attach and moves it into the qt1010 header file. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 11 +---------- linux/drivers/media/dvb/frontends/qt1010.h | 8 ++++++++ 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 6fc71843b..c10944a4f 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -253,15 +253,6 @@ static int megasky_frontend_attach(struct dvb_usb_adapter *adap) return -EIO; } -static int megasky_tuner_attach(struct dvb_usb_adapter *adap) -{ - adap->pll_addr = 0xc4; - adap->pll_desc = NULL; - adap->fe->ops.tuner_ops.set_params = qt1010_set_params; - - return 0; -} - static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx, int pid) { int ret = 0; @@ -459,7 +450,7 @@ static struct dvb_usb_device_properties megasky_properties = { .pid_filter_ctrl = m9206_pid_filter_ctrl, .frontend_attach = megasky_frontend_attach, - .tuner_attach = megasky_tuner_attach, + .tuner_attach = qt1010_tuner_attach, .stream = { .type = USB_BULK, diff --git a/linux/drivers/media/dvb/frontends/qt1010.h b/linux/drivers/media/dvb/frontends/qt1010.h index 3a566085f..59ee1cd03 100644 --- a/linux/drivers/media/dvb/frontends/qt1010.h +++ b/linux/drivers/media/dvb/frontends/qt1010.h @@ -215,4 +215,12 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame return 0; } +static int qt1010_tuner_attach(struct dvb_usb_adapter *adap) +{ + adap->pll_addr = 0xc4; + adap->pll_desc = NULL; + adap->fe->ops.tuner_ops.set_params = qt1010_set_params; + + return 0; +} #endif -- cgit v1.2.3 From 39f8c8cf4eedd31a816f6cc20e8f3f4f13199758 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 15:46:33 -0400 Subject: m920x: fix build in hg tree / other trivial fixes From: Michael Krufky - removed extra newline - removed NULL entry - fixed versions.txt Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index c10944a4f..e44b52414 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -138,7 +138,6 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) } /* I2C */ - static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); @@ -471,7 +470,6 @@ static struct dvb_usb_device_properties megasky_properties = { { &m920x_table[0], NULL }, { NULL }, }, - { NULL }, } }; -- cgit v1.2.3 From 47b47d371e02c3585268e06325bf27bc3ec27dcc Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 7 Oct 2006 00:06:54 -0400 Subject: qt1010: correct hardlockup when an app access the DVB dongle From: Jan Nijs This patch changes qt1010.h to use dvb_usb_device struct instead of a dvb_usb_adapter for accessing the private area of the driver. Without this patch my PC hard locks when an application tries to access the DVB tuner. Signed-off-by: Jan Nijs Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/qt1010.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/qt1010.h b/linux/drivers/media/dvb/frontends/qt1010.h index 59ee1cd03..8196985e4 100644 --- a/linux/drivers/media/dvb/frontends/qt1010.h +++ b/linux/drivers/media/dvb/frontends/qt1010.h @@ -79,7 +79,7 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame { QT1010_W, 0x01, 0x00 }, }; struct i2c_msg msg; - struct dvb_usb_device *d = fe->dvb->priv; + struct dvb_usb_adapter *adap = fe->dvb->priv; unsigned long freq = params->frequency; if (freq % QT1010_MIN_STEP) @@ -203,10 +203,10 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame msg.flags = 0; msg.len = 2; - msg.addr = d->adapter[0].pll_addr; + msg.addr = adap->dev->adapter[0].pll_addr; msg.buf = &rd[i].reg; - if (i2c_transfer(&d->i2c_adap, &msg, 1) != 1) { + if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { printk("tuner write failed\n"); return -EIO; } -- cgit v1.2.3 From 2198c7842c8114359ee495795d1fc624d8514321 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 7 Oct 2006 14:03:04 -0400 Subject: m920x: correct oops when loading module From: Michael Krufky move .caps from the adapter properties to the device properties. Thanks to Martin Schwier for confirming this fix. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index e44b52414..911570387 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -427,6 +427,9 @@ static struct usb_device_id m920x_table [] = { MODULE_DEVICE_TABLE (usb, m920x_table); static struct dvb_usb_device_properties megasky_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .usb_ctrl = DEVICE_SPECIFIC, .firmware = "dvb-usb-megasky-02.fw", .download_firmware = m9206_firmware_download, @@ -441,9 +444,6 @@ static struct dvb_usb_device_properties megasky_properties = { .identify_state = megasky_identify_state, .num_adapters = 1, .adapter = {{ - .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - .pid_filter_count = 8, .pid_filter = m9206_pid_filter, .pid_filter_ctrl = m9206_pid_filter_ctrl, -- cgit v1.2.3 From 8eeef355ce44f48579df26ffb53f713e45f9169a Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 21 Jan 2007 13:56:10 -0500 Subject: dvb: add new qt1010 tuner module From: Antti Palosaari QT1010: - old qt1010-code totally rewritten and put in own kernel module - same enhancements as my earlier QT1010 125kHz patch - tuner initialization - register 1f calculation - register 20 calculation - register 25 calculation m920x: (MSI Megasky) - use new QT1010 module instead of old code Signed-off-by: Antti Palosaari Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 13 +- linux/drivers/media/dvb/frontends/Kconfig | 7 + linux/drivers/media/dvb/frontends/Makefile | 1 + linux/drivers/media/dvb/frontends/qt1010.c | 455 ++++++++++++++++++++++++ linux/drivers/media/dvb/frontends/qt1010.h | 233 ++---------- linux/drivers/media/dvb/frontends/qt1010_priv.h | 105 ++++++ 6 files changed, 610 insertions(+), 204 deletions(-) create mode 100644 linux/drivers/media/dvb/frontends/qt1010.c create mode 100644 linux/drivers/media/dvb/frontends/qt1010_priv.h (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 911570387..108450ef0 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -390,6 +390,17 @@ static int m9206_firmware_download(struct usb_device *udev, const struct firmwar return ret; } +static struct qt1010_config megasky_qt1010_config = { + .i2c_address = 0xc4 +}; + +static int megasky_tuner_attach(struct dvb_usb_adapter *adap) +{ + return dvb_attach(qt1010_attach, + adap->fe, &adap->dev->i2c_adap, + &megasky_qt1010_config) == NULL ? -ENODEV : 0; +} + /* DVB USB Driver stuff */ static struct dvb_usb_device_properties megasky_properties; @@ -449,7 +460,7 @@ static struct dvb_usb_device_properties megasky_properties = { .pid_filter_ctrl = m9206_pid_filter_ctrl, .frontend_attach = megasky_frontend_attach, - .tuner_attach = qt1010_tuner_attach, + .tuner_attach = megasky_tuner_attach, .stream = { .type = USB_BULK, diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index af314bb1d..22c2cf2ce 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -290,6 +290,13 @@ config DVB_TDA826X help A DVB-S silicon tuner module. Say Y when you want to support this tuner. +config DVB_TUNER_QT1010 + tristate "Quantek QT1010 silicon tuner" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A driver for the silicon tuner QT1010 from Quantek. + config DVB_TUNER_MT2060 tristate "Microtune MT2060 silicon IF tuner" depends on I2C diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index 3fa6e5d32..a646d9969 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -38,5 +38,6 @@ obj-$(CONFIG_DVB_ISL6421) += isl6421.o obj-$(CONFIG_DVB_TDA10086) += tda10086.o obj-$(CONFIG_DVB_TDA826X) += tda826x.o obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o +obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o obj-$(CONFIG_DVB_TUA6100) += tua6100.o obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o diff --git a/linux/drivers/media/dvb/frontends/qt1010.c b/linux/drivers/media/dvb/frontends/qt1010.c new file mode 100644 index 000000000..60931f83f --- /dev/null +++ b/linux/drivers/media/dvb/frontends/qt1010.c @@ -0,0 +1,455 @@ +/* + * Driver for Quantek QT1010 silicon tuner + * + * Copyright (C) 2006 Antti Palosaari + * Aapo Tahkola + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "qt1010.h" +#include "qt1010_priv.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); + +#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "QT1010: " args); printk("\n"); }} while (0) + +/* read single register */ +static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val) +{ + struct i2c_msg msg[2] = { + { .addr = priv->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, + { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 }, + }; + + if (i2c_transfer(priv->i2c, msg, 2) != 2) { + printk(KERN_WARNING "qt1010 I2C read failed\n"); + return -EREMOTEIO; + } + return 0; +} + +/* write single register */ +static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val) +{ + u8 buf[2] = { reg, val }; + struct i2c_msg msg = { + .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2 + }; + + if (i2c_transfer(priv->i2c, &msg, 1) != 1) { + printk(KERN_WARNING "qt1010 I2C write failed\n"); + return -EREMOTEIO; + } + return 0; +} + +/* dump all registers */ +static void qt1010_dump_regs(struct qt1010_priv *priv) +{ + char buf[52], buf2[4]; + u8 reg, val; + + for (reg = 0; ; reg++) { + if (reg % 16 == 0) { + if (reg) + printk("%s\n", buf); + sprintf(buf, "%02x: ", reg); + } + if (qt1010_readreg(priv, reg, &val) == 0) + sprintf(buf2, "%02x ", val); + else + strcpy(buf2, "-- "); + strcat(buf, buf2); + if (reg == 0x2f) + break; + } + printk("%s\n", buf); +} + +static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +{ + struct qt1010_priv *priv; + int err; + u32 freq, div, mod1, mod2; + u8 i, tmpval, reg05; + qt1010_i2c_oper_t rd[48] = { + { QT1010_WR, 0x01, 0x80 }, + { QT1010_WR, 0x02, 0x3f }, + { QT1010_WR, 0x05, 0xff }, /* 02 c write */ + { QT1010_WR, 0x06, 0x44 }, + { QT1010_WR, 0x07, 0xff }, /* 04 c write */ + { QT1010_WR, 0x08, 0x08 }, + { QT1010_WR, 0x09, 0xff }, /* 06 c write */ + { QT1010_WR, 0x0a, 0xff }, /* 07 c write */ + { QT1010_WR, 0x0b, 0xff }, /* 08 c write */ + { QT1010_WR, 0x0c, 0xe1 }, + { QT1010_WR, 0x1a, 0xff }, /* 10 c write */ + { QT1010_WR, 0x1b, 0x00 }, + { QT1010_WR, 0x1c, 0x89 }, + { QT1010_WR, 0x11, 0xff }, /* 13 c write */ + { QT1010_WR, 0x12, 0xff }, /* 14 c write */ + { QT1010_WR, 0x22, 0xff }, /* 15 c write */ + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, 0xd0 }, + { QT1010_RD, 0x22, 0xff }, /* 16 c read */ + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_RD, 0x05, 0xff }, /* 20 c read */ + { QT1010_RD, 0x22, 0xff }, /* 21 c read */ + { QT1010_WR, 0x23, 0xd0 }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, 0xe0 }, + { QT1010_RD, 0x23, 0xff }, /* 25 c read */ + { QT1010_RD, 0x23, 0xff }, /* 26 c read */ + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x24, 0xd0 }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, 0xf0 }, + { QT1010_RD, 0x24, 0xff }, /* 31 c read */ + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x14, 0x7f }, + { QT1010_WR, 0x15, 0x7f }, + { QT1010_WR, 0x05, 0xff }, /* 35 c write */ + { QT1010_WR, 0x06, 0x00 }, + { QT1010_WR, 0x15, 0x1f }, + { QT1010_WR, 0x16, 0xff }, + { QT1010_WR, 0x18, 0xff }, + { QT1010_WR, 0x1f, 0xff }, /* 40 c write */ + { QT1010_WR, 0x20, 0xff }, /* 41 c write */ + { QT1010_WR, 0x21, 0x53 }, + { QT1010_WR, 0x25, 0xff }, /* 43 c write */ + { QT1010_WR, 0x26, 0x15 }, + { QT1010_WR, 0x00, 0xff }, /* 45 c write */ + { QT1010_WR, 0x02, 0x00 }, + { QT1010_WR, 0x01, 0x00 } + }; + +#define FREQ1 32000000 /* 32 MHz */ +#define FREQ2 4000000 /* 4 MHz Quartz oscillator in the stick? */ + + priv = fe->tuner_priv; + freq = params->frequency; + div = (freq + QT1010_OFFSET) / QT1010_STEP; + freq = (div * QT1010_STEP) - QT1010_OFFSET; + mod1 = (freq + QT1010_OFFSET) % FREQ1; + mod2 = (freq + QT1010_OFFSET) % FREQ2; + priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; + priv->frequency = freq; + + /* reg 05 base value */ + if (freq < 290000000) reg05 = 0x14; /* 290 MHz */ + else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */ + else if (freq < 802000000) reg05 = 0x54; /* 802 MHz */ + else reg05 = 0x74; + + /* 0x5 */ + rd[2].val = reg05; + + /* 07 - set frequency: 32 MHz scale */ + rd[4].val = (freq + QT1010_OFFSET) / FREQ1; + + /* 09 - changes every 8/24 MHz */ + if (mod1 < 8000000) rd[6].val = 0x1d; + else rd[6].val = 0x1c; + + /* 0a - set frequency: 4 MHz scale (max 28 MHz) */ + if (mod1 < 1*FREQ2) rd[7].val = 0x09; /* +0 MHz */ + else if (mod1 < 2*FREQ2) rd[7].val = 0x08; /* +4 MHz */ + else if (mod1 < 3*FREQ2) rd[7].val = 0x0f; /* +8 MHz */ + else if (mod1 < 4*FREQ2) rd[7].val = 0x0e; /* +12 MHz */ + else if (mod1 < 5*FREQ2) rd[7].val = 0x0d; /* +16 MHz */ + else if (mod1 < 6*FREQ2) rd[7].val = 0x0c; /* +20 MHz */ + else if (mod1 < 7*FREQ2) rd[7].val = 0x0b; /* +24 MHz */ + else rd[7].val = 0x0a; /* +28 MHz */ + + /* 0b - changes every 2/2 MHz */ + if (mod2 < 2000000) rd[8].val = 0x45; + else rd[8].val = 0x44; + + /* 1a - set frequency: 125 kHz scale (max 3875 kHz)*/ + tmpval = 0x78; /* byte, overflows intentionally */ + rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08); + + /* 11 */ + rd[13].val = 0xfd; /* TODO: correct value calculation */ + + /* 12 */ + rd[14].val = 0x91; /* TODO: correct value calculation */ + + /* 22 */ + if (freq < 450000000) rd[15].val = 0xd0; /* 450 MHz */ + else if (freq < 482000000) rd[15].val = 0xd1; /* 482 MHz */ + else if (freq < 514000000) rd[15].val = 0xd4; /* 514 MHz */ + else if (freq < 546000000) rd[15].val = 0xd7; /* 546 MHz */ + else if (freq < 610000000) rd[15].val = 0xda; /* 610 MHz */ + else rd[15].val = 0xd0; + + /* 05 */ + rd[35].val = (reg05 & 0xf0); + + /* 1f */ + if (mod1 < 8000000) tmpval = 0x00; + else if (mod1 < 12000000) tmpval = 0x01; + else if (mod1 < 16000000) tmpval = 0x02; + else if (mod1 < 24000000) tmpval = 0x03; + else if (mod1 < 28000000) tmpval = 0x04; + else tmpval = 0x05; + rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval); + + /* 20 */ + if (mod1 < 8000000) tmpval = 0x00; + else if (mod1 < 12000000) tmpval = 0x01; + else if (mod1 < 20000000) tmpval = 0x02; + else if (mod1 < 24000000) tmpval = 0x03; + else if (mod1 < 28000000) tmpval = 0x04; + else tmpval = 0x05; + rd[41].val = (priv->reg20_init_val + 0x0d + tmpval); + + /* 25 */ + rd[43].val = priv->reg25_init_val; + + /* 00 */ + rd[45].val = 0x92; /* TODO: correct value calculation */ + + dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x 1a:%02x 11:%02x " \ + "12:%02x 22:%02x 05:%02x 1f:%02x 20:%02x 25:%02x 00:%02x", \ + freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \ + rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \ + rd[40].val, rd[41].val, rd[43].val, rd[45].val); + + for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { + if (rd[i].oper == QT1010_WR) { + err = qt1010_writereg(priv, rd[i].reg, rd[i].val); + } else { /* read is required to proper locking */ + err = qt1010_readreg(priv, rd[i].reg, &tmpval); + } + if (err) return err; + } + + if (debug) + qt1010_dump_regs(priv); + + return 0; +} + +static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_init_val, u8 *retval) +{ + u8 i, val1, val2; + int err; + + qt1010_i2c_oper_t i2c_data[] = { + { QT1010_WR, reg, reg_init_val }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, oper }, + { QT1010_RD, reg, 0xff } + }; + + for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + if (i2c_data[i].oper == QT1010_WR) { + err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + } else { + err = qt1010_readreg(priv, i2c_data[i].reg, &val2); + } + if (err) return err; + } + + do { + val1 = val2; + err = qt1010_readreg(priv, reg, &val2); + if (err) return err; + dprintk("compare reg:%02x %02x %02x", reg, val1, val2); + } while (val1 != val2); + *retval = val1; + + return qt1010_writereg(priv, 0x1e, 0x00); +} + + +static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retval) +{ + u8 i, val; + int err; + qt1010_i2c_oper_t i2c_data[] = { + { QT1010_WR, 0x07, reg_init_val }, + { QT1010_WR, 0x22, 0xd0 }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x1e, 0xd0 }, + { QT1010_RD, 0x22, 0xff }, + { QT1010_WR, 0x1e, 0x00 }, + { QT1010_WR, 0x22, 0xff } + }; + for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + if (i2c_data[i].oper == QT1010_WR) { + err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + } else { + err = qt1010_readreg(priv, i2c_data[i].reg, &val); + } + if (err) return err; + } + *retval = val; + return 0; +} + +static int qt1010_init(struct dvb_frontend *fe) +{ + struct qt1010_priv *priv = fe->tuner_priv; + struct dvb_frontend_parameters params; + int err; + u8 i, tmpval, *valptr = NULL; + + qt1010_i2c_oper_t i2c_data[] = { + { QT1010_WR, 0x01, 0x80 }, + { QT1010_WR, 0x0d, 0x84 }, + { QT1010_WR, 0x0e, 0xb7 }, + { QT1010_WR, 0x2a, 0x23 }, + { QT1010_WR, 0x2c, 0xdc }, + { QT1010_M1, 0x25, 0x40 }, /* get reg 25 init value */ + { QT1010_M1, 0x81, 0xff }, /* get reg 25 init value */ + { QT1010_WR, 0x2b, 0x70 }, + { QT1010_WR, 0x2a, 0x23 }, + { QT1010_M1, 0x26, 0x08 }, + { QT1010_M1, 0x82, 0xff }, + { QT1010_WR, 0x05, 0x14 }, + { QT1010_WR, 0x06, 0x44 }, + { QT1010_WR, 0x07, 0x28 }, + { QT1010_WR, 0x08, 0x0b }, + { QT1010_WR, 0x11, 0xfd }, + { QT1010_M1, 0x22, 0x0d }, + { QT1010_M1, 0xd0, 0xff }, + { QT1010_WR, 0x06, 0x40 }, + { QT1010_WR, 0x16, 0xf0 }, + { QT1010_WR, 0x02, 0x38 }, + { QT1010_WR, 0x03, 0x18 }, + { QT1010_WR, 0x20, 0xe0 }, + { QT1010_M1, 0x1f, 0x20 }, /* get reg 1f init value */ + { QT1010_M1, 0x84, 0xff }, /* get reg 1f init value */ + { QT1010_RD, 0x20, 0x20 }, /* get reg 20 init value */ + { QT1010_WR, 0x03, 0x19 }, + { QT1010_WR, 0x02, 0x3f }, + { QT1010_WR, 0x21, 0x53 }, + { QT1010_RD, 0x21, 0xff }, + { QT1010_WR, 0x11, 0xfd }, + { QT1010_WR, 0x05, 0x34 }, + { QT1010_WR, 0x06, 0x44 }, + { QT1010_WR, 0x08, 0x08 } + }; + + for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + switch (i2c_data[i].oper) { + case QT1010_WR: + err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + break; + case QT1010_RD: + if (i2c_data[i].val == 0x20) valptr = &priv->reg20_init_val; + else valptr = &tmpval; + err = qt1010_readreg(priv, i2c_data[i].reg, valptr); + break; + case QT1010_M1: + if (i2c_data[i].val == 0x25) valptr = &priv->reg25_init_val; + else if (i2c_data[i].val == 0x1f) valptr = &priv->reg1f_init_val; + else valptr = &tmpval; + err = qt1010_init_meas1(priv, i2c_data[i+1].reg, i2c_data[i].reg, + i2c_data[i].val, valptr); + i++; + break; + } + if (err) return err; + } + + for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */ + if ((err = qt1010_init_meas2(priv, i, &tmpval))) + return err; + + params.frequency = 545000000; /* Sigmatek DVB-110 545000000 */ + /* MSI Megasky 580 GL861 533000000 */ + return qt1010_set_params(fe, ¶ms); +} + +static int qt1010_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} + +static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct qt1010_priv *priv = fe->tuner_priv; + *frequency = priv->frequency; + return 0; +} + +static int qt1010_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct qt1010_priv *priv = fe->tuner_priv; + *bandwidth = priv->bandwidth; + return 0; +} + +static const struct dvb_tuner_ops qt1010_tuner_ops = { + .info = { + .name = "Quantek QT1010", + .frequency_min = QT1010_MIN_FREQ, + .frequency_max = QT1010_MAX_FREQ, + .frequency_step = QT1010_STEP, + }, + + .release = qt1010_release, + .init = qt1010_init, + /* TODO: implement sleep */ + + .set_params = qt1010_set_params, + .get_frequency = qt1010_get_frequency, + .get_bandwidth = qt1010_get_bandwidth +}; + +struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct qt1010_config *cfg) +{ + struct qt1010_priv *priv = NULL; + u8 id; + + priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + priv->cfg = cfg; + priv->i2c = i2c; + +#if 0 + qt1010_dump_regs(priv); +#endif + + /* Try to detect tuner chip. Probably this is not correct register. */ + if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) { + kfree(priv); + return NULL; + } + + printk(KERN_INFO "Quantek QT1010 successfully identified.\n"); + memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops, sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = priv; + return fe; +} +EXPORT_SYMBOL(qt1010_attach); + +MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver"); +MODULE_AUTHOR("Antti Palosaari "); +MODULE_AUTHOR("Aapo Tahkola "); +MODULE_VERSION("0.1"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/qt1010.h b/linux/drivers/media/dvb/frontends/qt1010.h index 8196985e4..3ab4aa045 100644 --- a/linux/drivers/media/dvb/frontends/qt1010.h +++ b/linux/drivers/media/dvb/frontends/qt1010.h @@ -1,5 +1,8 @@ /* - * qt1010.h - DVB-T Tuner support + * Driver for Quantek QT1010 silicon tuner + * + * Copyright (C) 2006 Antti Palosaari + * Aapo Tahkola * * 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 @@ -16,211 +19,35 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef _QT1010_H_ -#define _QT1010_H_ - -#define QT1010_W 0 -#define QT1010_R 1 -/* Not actual hw limits. */ -#define QT1010_MIN_STEP 2000000 -#define QT1010_MIN_FREQ 48000000 - -static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - int i; - int div, mod; - struct { - u8 read, reg, value; - } rd[46] = { { QT1010_W, 0x01, 0x80 }, - { QT1010_W, 0x02, 0x3f }, - { QT1010_W, 0x05, 0xff }, /* c */ - { QT1010_W, 0x06, 0x44 }, - { QT1010_W, 0x07, 0xff }, /* c */ - { QT1010_W, 0x08, 0x08 }, - { QT1010_W, 0x09, 0xff }, /* c */ - { QT1010_W, 0x0a, 0xff }, /* c */ - { QT1010_W, 0x0b, 0xff }, /* c */ - { QT1010_W, 0x0c, 0xe1 }, - { QT1010_W, 0x1a, 0xff }, /* 10 c */ - { QT1010_W, 0x1b, 0x00 }, - { QT1010_W, 0x1c, 0x89 }, - { QT1010_W, 0x11, 0xff }, /* c */ - { QT1010_W, 0x12, 0x91 }, - { QT1010_W, 0x22, 0xff }, /* c */ - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x1e, 0xd0 }, - { QT1010_R, 0x22, 0xff }, /* c read */ - { QT1010_W, 0x1e, 0x00 }, - { QT1010_R, 0x05, 0xff }, /* 20 c read */ - { QT1010_R, 0x22, 0xff }, /* c read */ - { QT1010_W, 0x23, 0xd0 }, - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x1e, 0xe0 }, - { QT1010_R, 0x23, 0xff }, /* c read */ - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x24, 0xd0 }, - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x1e, 0xf0 }, - { QT1010_R, 0x24, 0xff }, /* 30 c read */ - { QT1010_W, 0x1e, 0x00 }, - { QT1010_W, 0x14, 0x7f }, - { QT1010_W, 0x15, 0x7f }, - { QT1010_W, 0x05, 0xff }, /* c */ - { QT1010_W, 0x06, 0x00 }, - { QT1010_W, 0x15, 0x1f }, - { QT1010_W, 0x16, 0xff }, - { QT1010_W, 0x18, 0xff }, - { QT1010_W, 0x1f, 0xff }, /* c */ - { QT1010_W, 0x20, 0xff }, /* 40 c */ - { QT1010_W, 0x21, 0x53 }, - { QT1010_W, 0x25, 0xbd }, - { QT1010_W, 0x26, 0x15 }, - { QT1010_W, 0x02, 0x00 }, - { QT1010_W, 0x01, 0x00 }, - }; - struct i2c_msg msg; - struct dvb_usb_adapter *adap = fe->dvb->priv; - unsigned long freq = params->frequency; - - if (freq % QT1010_MIN_STEP) - printk("frequency not supported.\n"); - - div = (freq - QT1010_MIN_FREQ) / QT1010_MIN_STEP; - mod = (div + 16 - 9) % 16; - - /* 0x5 */ - if (div >= 377) - rd[2].value = 0x74; - else if (div >= 265) - rd[2].value = 0x54; - else if (div >= 121) - rd[2].value = 0x34; - else - rd[2].value = 0x14; - - /* 0x7 */ - rd[4].value = (((freq - QT1010_MIN_FREQ) / 1000000) * 9975 + 12960000) / 320000; - - /* 09 */ - if (mod < 4) - rd[6].value = 0x1d; - else - rd[6].value = 0x1c; - - /* 0a */ - if (mod < 2) - rd[7].value = 0x09; - else if (mod < 4) - rd[7].value = 0x08; - else if (mod < 6) - rd[7].value = 0x0f; - else if (mod < 8) - rd[7].value = 0x0e; - else if (mod < 10) - rd[7].value = 0x0d; - else if (mod < 12) - rd[7].value = 0x0c; - else if (mod < 14) - rd[7].value = 0x0b; - else - rd[7].value = 0x0a; - - /* 0b */ - if (div & 1) - rd[8].value = 0x45; - else - rd[8].value = 0x44; - - /* 1a */ - if (div & 1) - rd[10].value = 0x78; - else - rd[10].value = 0xf8; +#ifndef QT1010_H +#define QT1010_H - /* 11 */ - if (div >= 265) - rd[13].value = 0xf9; - else if (div >= 121) - rd[13].value = 0xfd; - else - rd[13].value = 0xf9; +#include "dvb_frontend.h" - /* 22 */ - if (div < 201) - rd[15].value = 0xd0; - else if (div < 217) - rd[15].value = 0xd3; - else if (div < 233) - rd[15].value = 0xd6; - else if (div < 249) - rd[15].value = 0xd9; - else if (div < 265) - rd[15].value = 0xda; - else - rd[15].value = 0xd0; +struct qt1010_config { + u8 i2c_address; +}; - /* 05 */ - if (div >= 377) - rd[34].value = 0x70; - else if (div >= 265) - rd[34].value = 0x50; - else if (div >= 121) - rd[34].value = 0x30; - else - rd[34].value = 0x10; - - /* 1f */ - if (mod < 4) - rd[39].value = 0x64; - else if (mod < 6) - rd[39].value = 0x66; - else if (mod < 8) - rd[39].value = 0x67; - else if (mod < 12) - rd[39].value = 0x68; - else if (mod < 14) - rd[39].value = 0x69; - else - rd[39].value = 0x6a; - - /* 20 */ - if (mod < 4) - rd[40].value = 0x10; - else if (mod < 6) - rd[40].value = 0x11; - else if (mod < 10) - rd[40].value = 0x12; - else if (mod < 12) - rd[40].value = 0x13; - else if (mod < 14) - rd[40].value = 0x14; - else - rd[40].value = 0x15; - - for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { - if (rd[i].read) - continue; - - msg.flags = 0; - msg.len = 2; - msg.addr = adap->dev->adapter[0].pll_addr; - msg.buf = &rd[i].reg; - - if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { - printk("tuner write failed\n"); - return -EIO; - } - } - - return 0; -} - -static int qt1010_tuner_attach(struct dvb_usb_adapter *adap) +/** + * Attach a qt1010 tuner to the supplied frontend structure. + * + * @param fe frontend to attach to + * @param i2c i2c adapter to use + * @param cfg tuner hw based configuration + * @return fe pointer on success, NULL on failure + */ +#if defined(CONFIG_DVB_TUNER_QT1010) || (defined(CONFIG_DVB_TUNER_QT1010_MODULE) && defined(MODULE)) +extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct qt1010_config *cfg); +#else +static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + struct qt1010_config *cfg) { - adap->pll_addr = 0xc4; - adap->pll_desc = NULL; - adap->fe->ops.tuner_ops.set_params = qt1010_set_params; - - return 0; + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + return NULL; } +#endif // CONFIG_DVB_TUNER_QT1010 + #endif diff --git a/linux/drivers/media/dvb/frontends/qt1010_priv.h b/linux/drivers/media/dvb/frontends/qt1010_priv.h new file mode 100644 index 000000000..090cf475f --- /dev/null +++ b/linux/drivers/media/dvb/frontends/qt1010_priv.h @@ -0,0 +1,105 @@ +/* + * Driver for Quantek QT1010 silicon tuner + * + * Copyright (C) 2006 Antti Palosaari + * Aapo Tahkola + * + * 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. + */ + +#ifndef QT1010_PRIV_H +#define QT1010_PRIV_H + +/* +reg def meaning +=== === ======= +00 00 ? +01 a0 ? operation start/stop; start=80, stop=00 +02 00 ? +03 19 ? +04 00 ? +05 00 ? maybe band selection +06 00 ? +07 2b set frequency: 32 MHz scale, n*32 MHz +08 0b ? +09 10 ? changes every 8/24 MHz; values 1d/1c +0a 08 set frequency: 4 MHz scale, n*4 MHz +0b 41 ? changes every 2/2 MHz; values 45/45 +0c e1 ? +0d 94 ? +0e b6 ? +0f 2c ? +10 10 ? +11 f1 ? maybe device specified adjustment +12 11 ? maybe device specified adjustment +13 3f ? +14 1f ? +15 3f ? +16 ff ? +17 ff ? +18 f7 ? +19 80 ? +1a d0 set frequency: 125 kHz scale, n*125 kHz +1b 00 ? +1c 89 ? +1d 00 ? +1e 00 ? looks like operation register; write cmd here, read result from 1f-26 +1f 20 ? chip initialization +20 e0 ? chip initialization +21 20 ? +22 d0 ? +23 d0 ? +24 d0 ? +25 40 ? chip initialization +26 08 ? +27 29 ? +28 55 ? +29 39 ? +2a 13 ? +2b 01 ? +2c ea ? +2d 00 ? +2e 00 ? not used? +2f 00 ? not used? +*/ + +#define QT1010_STEP 125000 /* 125 kHz used by Windows drivers, + hw could be more precise but we don't + know how to use */ +#define QT1010_MIN_FREQ 48000000 /* 48 MHz */ +#define QT1010_MAX_FREQ 860000000 /* 860 MHz */ +#define QT1010_OFFSET 1246000000 /* 1246 MHz */ + +#define QT1010_WR 0 +#define QT1010_RD 1 +#define QT1010_M1 3 + +typedef struct { + u8 oper, reg, val; +} qt1010_i2c_oper_t; + +struct qt1010_priv { + struct qt1010_config *cfg; + struct i2c_adapter *i2c; + + u8 reg1f_init_val; + u8 reg20_init_val; + u8 reg25_init_val; + + u32 frequency; + u32 bandwidth; +}; + +#endif -- cgit v1.2.3 From 2fdc02b3b8f76a1268956fad1c4e32facd5a61cf Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 21 Jan 2007 13:56:46 -0500 Subject: kconfig: qt1010 should be selected by m920x From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index e18eb7b3f..861a02939 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -113,6 +113,7 @@ config DVB_USB_M920X tristate "Uli m920x DVB-T USB2.0 support" depends on DVB_USB select DVB_MT352 if !DVB_FE_CUSTOMISE + select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE help Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. Currently, only devices with a product id of -- cgit v1.2.3 From 22779dda1dcad43567d722ca5c412c07bbe2f67f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 21 Jan 2007 13:57:20 -0500 Subject: m920x: Fix tuner identification bug with qt1010 module From: Aapo Tahkola Fixes qt1010 identification bug with megasky caused by the Quantek QT1010 tuner module patch. Signed-off-by: Aapo Tahkola Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 46 +++++++++++++++++++++++---------- linux/drivers/media/dvb/dvb-usb/m920x.h | 9 +++++++ 2 files changed, 41 insertions(+), 14 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 108450ef0..b65ba6ee1 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -141,6 +141,7 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); + struct m9206_state *m = d->priv; int i; int ret = 0; @@ -151,8 +152,6 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu return -EINVAL; for (i = 0; i < num; i++) { - u8 w_len; - if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].addr, 0x80)) != 0) goto unlock; @@ -160,13 +159,19 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu goto unlock; if (i + 1 < num && msg[i + 1].flags & I2C_M_RD) { - /* Possibly device dependant */ - if (msg[i].addr == d->adapter[0].pll_addr) - w_len = 0xc5; - else - w_len = 0x1f; + int i2c_i; + + for (i2c_i = 0; i2c_i < M9206_I2C_MAX; i2c_i++) + if (msg[i].addr == m->i2c_r[i2c_i].addr) + break; - if ((ret = m9206_write(d->udev, M9206_I2C, w_len, 0x80)) != 0) + if (i2c_i >= M9206_I2C_MAX) { + deb_rc("No magic for i2c addr!\n"); + ret = -EINVAL; + goto unlock; + } + + if ((ret = m9206_write(d->udev, M9206_I2C, m->i2c_r[i2c_i].magic, 0x80)) != 0) goto unlock; if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0) @@ -245,11 +250,17 @@ static struct mt352_config megasky_mt352_config = { static int megasky_frontend_attach(struct dvb_usb_adapter *adap) { + struct m9206_state *m = adap->dev->priv; + deb_rc("megasky_frontend_attach!\n"); - if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) != NULL) - return 0; - return -EIO; + m->i2c_r[M9206_I2C_DEMOD].addr = megasky_mt352_config.demod_address; + m->i2c_r[M9206_I2C_DEMOD].magic = 0x1f; + + if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL) + return -EIO; + + return 0; } static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx, int pid) @@ -396,9 +407,16 @@ static struct qt1010_config megasky_qt1010_config = { static int megasky_tuner_attach(struct dvb_usb_adapter *adap) { - return dvb_attach(qt1010_attach, - adap->fe, &adap->dev->i2c_adap, - &megasky_qt1010_config) == NULL ? -ENODEV : 0; + struct m9206_state *m = adap->dev->priv; + + m->i2c_r[M9206_I2C_TUNER].addr = megasky_qt1010_config.i2c_address; + m->i2c_r[M9206_I2C_TUNER].magic = 0xc5; + + if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, + &megasky_qt1010_config) == NULL) + return -ENODEV; + + return 0; } /* DVB USB Driver stuff */ diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.h b/linux/drivers/media/dvb/dvb-usb/m920x.h index 597df11e6..c354196ff 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.h +++ b/linux/drivers/media/dvb/dvb-usb/m920x.h @@ -18,9 +18,18 @@ #define M9206_FW 0x30 #define M9206_MAX_FILTERS 8 + +#define M9206_I2C_TUNER 0 +#define M9206_I2C_DEMOD 1 +#define M9206_I2C_MAX 2 + struct m9206_state { u16 filters[M9206_MAX_FILTERS]; int filtering_enabled; int rep_count; + struct { + unsigned char addr; + unsigned char magic; + }i2c_r[M9206_I2C_MAX]; }; #endif -- cgit v1.2.3 From e9f51c1596685e652f88d6bbd9173bb0d0676ae0 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 21 Jan 2007 13:57:48 -0500 Subject: whitespace / 80-column cleanups From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index b65ba6ee1..495e92f4c 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -39,7 +39,8 @@ static struct dvb_usb_rc_key megasky_rc_keys [] = { { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */ }; -static inline int m9206_read(struct usb_device *udev, u8 request, u16 value, u16 index, void *data, int size) +static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\ + u16 index, void *data, int size) { int ret; @@ -55,7 +56,8 @@ static inline int m9206_read(struct usb_device *udev, u8 request, u16 value, u16 return 0; } -static inline int m9206_write(struct usb_device *udev, u8 request, u16 value, u16 index) +static inline int m9206_write(struct usb_device *udev, u8 request, + u16 value, u16 index) { int ret; @@ -138,7 +140,8 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) } /* I2C */ -static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) +static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct m9206_state *m = d->priv; @@ -263,7 +266,8 @@ static int megasky_frontend_attach(struct dvb_usb_adapter *adap) return 0; } -static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx, int pid) +static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx, + int pid) { int ret = 0; @@ -330,7 +334,8 @@ static int m9206_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) return m9206_update_filters(adap); } -static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) +static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, + int onoff) { struct m9206_state *m = adap->dev->priv; @@ -339,7 +344,8 @@ static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, in return m9206_update_filters(adap); } -static int m9206_firmware_download(struct usb_device *udev, const struct firmware *fw) +static int m9206_firmware_download(struct usb_device *udev, + const struct firmware *fw) { u16 value, index, size; u8 read[4], *buff; @@ -422,7 +428,8 @@ static int megasky_tuner_attach(struct dvb_usb_adapter *adap) /* DVB USB Driver stuff */ static struct dvb_usb_device_properties megasky_properties; -static int m920x_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int m920x_probe(struct usb_interface *intf, + const struct usb_device_id *id) { struct dvb_usb_device *d; struct usb_host_interface *alt; @@ -437,7 +444,8 @@ static int m920x_probe(struct usb_interface *intf, const struct usb_device_id *i return -ENODEV; } - ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); + ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, + alt->desc.bAlternateSetting); if (ret < 0) return ret; -- cgit v1.2.3 From 9896ec9a5dcc113b607c4649ca18dc05d2993928 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 23 Jan 2007 13:00:42 -0500 Subject: m920x: group tuner / demod callback functions together From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 125 ++++++++++++++++---------------- 1 file changed, 63 insertions(+), 62 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 495e92f4c..1f0d21c7d 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -206,65 +206,6 @@ static struct i2c_algorithm m9206_i2c_algo = { .functionality = m9206_i2c_func, }; -/* Callbacks for DVB USB */ -static int megasky_identify_state(struct usb_device *udev, - struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, - int *cold) -{ - struct usb_host_interface *alt; - - alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1); - *cold = (alt == NULL) ? 1 : 0; - - return 0; -} - -static int megasky_mt352_demod_init(struct dvb_frontend *fe) -{ - u8 config[] = { CONFIG, 0x3d }; - u8 clock[] = { CLOCK_CTL, 0x30 }; - u8 reset[] = { RESET, 0x80 }; - u8 adc_ctl[] = { ADC_CTL_1, 0x40 }; - u8 agc[] = { AGC_TARGET, 0x1c, 0x20 }; - u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 }; - u8 unk1[] = { 0x93, 0x1a }; - u8 unk2[] = { 0xb5, 0x7a }; - - mt352_write(fe, config, ARRAY_SIZE(config)); - mt352_write(fe, clock, ARRAY_SIZE(clock)); - mt352_write(fe, reset, ARRAY_SIZE(reset)); - mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl)); - mt352_write(fe, agc, ARRAY_SIZE(agc)); - mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc)); - mt352_write(fe, unk1, ARRAY_SIZE(unk1)); - mt352_write(fe, unk2, ARRAY_SIZE(unk2)); - - deb_rc("Demod init!\n"); - - return 0; -} - -static struct mt352_config megasky_mt352_config = { - .demod_address = 0x1e, - .no_tuner = 1, - .demod_init = megasky_mt352_demod_init, -}; - -static int megasky_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct m9206_state *m = adap->dev->priv; - - deb_rc("megasky_frontend_attach!\n"); - - m->i2c_r[M9206_I2C_DEMOD].addr = megasky_mt352_config.demod_address; - m->i2c_r[M9206_I2C_DEMOD].magic = 0x1f; - - if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL) - return -EIO; - - return 0; -} static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx, int pid) @@ -407,11 +348,71 @@ static int m9206_firmware_download(struct usb_device *udev, return ret; } +/* Callbacks for DVB USB */ +static int megasky_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, + int *cold) +{ + struct usb_host_interface *alt; + + alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1); + *cold = (alt == NULL) ? 1 : 0; + + return 0; +} + +static int megasky_mt352_demod_init(struct dvb_frontend *fe) +{ + u8 config[] = { CONFIG, 0x3d }; + u8 clock[] = { CLOCK_CTL, 0x30 }; + u8 reset[] = { RESET, 0x80 }; + u8 adc_ctl[] = { ADC_CTL_1, 0x40 }; + u8 agc[] = { AGC_TARGET, 0x1c, 0x20 }; + u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 }; + u8 unk1[] = { 0x93, 0x1a }; + u8 unk2[] = { 0xb5, 0x7a }; + + mt352_write(fe, config, ARRAY_SIZE(config)); + mt352_write(fe, clock, ARRAY_SIZE(clock)); + mt352_write(fe, reset, ARRAY_SIZE(reset)); + mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl)); + mt352_write(fe, agc, ARRAY_SIZE(agc)); + mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc)); + mt352_write(fe, unk1, ARRAY_SIZE(unk1)); + mt352_write(fe, unk2, ARRAY_SIZE(unk2)); + + deb_rc("Demod init!\n"); + + return 0; +} + +static struct mt352_config megasky_mt352_config = { + .demod_address = 0x1e, + .no_tuner = 1, + .demod_init = megasky_mt352_demod_init, +}; + +static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct m9206_state *m = adap->dev->priv; + + deb_rc("megasky_frontend_attach!\n"); + + m->i2c_r[M9206_I2C_DEMOD].addr = megasky_mt352_config.demod_address; + m->i2c_r[M9206_I2C_DEMOD].magic = 0x1f; + + if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL) + return -EIO; + + return 0; +} + static struct qt1010_config megasky_qt1010_config = { .i2c_address = 0xc4 }; -static int megasky_tuner_attach(struct dvb_usb_adapter *adap) +static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap) { struct m9206_state *m = adap->dev->priv; @@ -485,8 +486,8 @@ static struct dvb_usb_device_properties megasky_properties = { .pid_filter = m9206_pid_filter, .pid_filter_ctrl = m9206_pid_filter_ctrl, - .frontend_attach = megasky_frontend_attach, - .tuner_attach = megasky_tuner_attach, + .frontend_attach = megasky_mt352_frontend_attach, + .tuner_attach = megasky_qt1010_tuner_attach, .stream = { .type = USB_BULK, -- cgit v1.2.3 From 7f9be719c75fb28bd77aeeda2df201b14554a4fd Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 23 Jan 2007 13:34:10 -0500 Subject: m920x: move filter caps from device caps to adapter caps From: Michael Krufky Move filter caps from device caps to adapter caps for the megasky driver. This fixes usb1.1 operation. Signed-off-by: Aapo Tahkola Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/m920x.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 1f0d21c7d..1a411316f 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -465,8 +465,7 @@ static struct usb_device_id m920x_table [] = { MODULE_DEVICE_TABLE (usb, m920x_table); static struct dvb_usb_device_properties megasky_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER | DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, .firmware = "dvb-usb-megasky-02.fw", @@ -482,6 +481,9 @@ static struct dvb_usb_device_properties megasky_properties = { .identify_state = megasky_identify_state, .num_adapters = 1, .adapter = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 8, .pid_filter = m9206_pid_filter, .pid_filter_ctrl = m9206_pid_filter_ctrl, -- cgit v1.2.3 From 85a1b28958980ffaa7ce4564aa1c9a713b9453fb Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:09:30 -0400 Subject: dvb-usb: initial support for MSI Mega Sky 580 DVB-T based on GL861 From: Carl Lundqvist This patch adds support for MSI Mega Sky 580 / GL861 DVB-T USB2.0 Notes: Except for the 2 lines added to zl10353.c, zl10353_reset_attach needs to be changed. If I read the code correctly setting parallel_ts will take care of the 3rd byte, but the 2nd byte needs to be 0x0b instead of 0x03 too. I guess these changes needs to be done only for this device, not sure how to do that. The zl10353 changes have been split apart from this patch, into the next patch, soon to follow. Signed-off-by: Carl Lundqvist Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 8 + linux/drivers/media/dvb/dvb-usb/Makefile | 3 + linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + linux/drivers/media/dvb/dvb-usb/gl861.c | 238 ++++++++++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/gl861.h | 16 ++ 5 files changed, 266 insertions(+) create mode 100644 linux/drivers/media/dvb/dvb-usb/gl861.c create mode 100644 linux/drivers/media/dvb/dvb-usb/gl861.h (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 861a02939..c0a899a04 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -120,6 +120,14 @@ config DVB_USB_M920X "DTV USB MINI" (in cold state) are supported. Firmware required. +config DVB_USB_GL861 + tristate "Genesys Logic GL861 USB2.0 support" + depends on DVB_USB + select DVB_ZL10353 + help + Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0 + receiver with USB ID 0db0:5581. + config DVB_USB_DIGITV tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" depends on DVB_USB diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile index 815e27898..53b63c584 100644 --- a/linux/drivers/media/dvb/dvb-usb/Makefile +++ b/linux/drivers/media/dvb/dvb-usb/Makefile @@ -33,6 +33,9 @@ obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o dvb-usb-m920x-objs = m920x.o obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o +dvb-usb-gl861-objs = gl861.o +obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o + dvb-usb-digitv-objs = digitv.o obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 713ec5a82..0414ee354 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -121,6 +121,7 @@ #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM 0xdb55 #define USB_PID_MEDION_MD95700 0x0932 #define USB_PID_MSI_MEGASKY580 0x5580 +#define USB_PID_MSI_MEGASKY55801 0x5581 #define USB_PID_KYE_DVB_T_COLD 0x701e #define USB_PID_KYE_DVB_T_WARM 0x701f #define USB_PID_PCTV_200E 0x020e diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c new file mode 100644 index 000000000..52c8d082e --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -0,0 +1,238 @@ +/* DVB USB compliant linux driver for GL861 USB2.0 devices. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "gl861.h" + +#include "zl10353.h" +#include "qt1010.h" + +/* debug */ +int dvb_usb_gl861_debug; +module_param_named(debug,dvb_usb_gl861_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); + +static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, + u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) +{ + u16 index; + u16 value = addr << 8; + int wo = (rbuf == NULL || rlen == 0); /* write-only */ + u8 req, type; + + if (wo) { + req = GL861_REQ_I2C_WRITE; + type = GL861_WRITE; + } else { /* rw */ + req = GL861_REQ_I2C_READ; + type = GL861_READ; + } + + switch (wlen) { + case 1: + index = wbuf[0]; + break; + case 2: + index = wbuf[0]; + value = value + wbuf[1]; + break; + default: + warn("wlen = %x, aborting.", wlen); + return -EINVAL; + } + + return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type, + value, index, rbuf, rlen, 2000); +} + +/* I2C */ +static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + if (num > 2) + return -EINVAL; + + for (i = 0; i < num; i++) { + /* write/read request */ + if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, + msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) + break; + i++; + } else + if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, + msg[i].len, NULL, 0) < 0) + break; + } + + mutex_unlock(&d->i2c_mutex); + return i; +} + +static u32 gl861_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm gl861_i2c_algo = { + .master_xfer = gl861_i2c_xfer, + .functionality = gl861_i2c_func, +}; + +/* Callbacks for DVB USB */ +static int gl861_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, + int *cold) +{ + *cold = 0; + + return 0; +} + +static struct zl10353_config gl861_zl10353_config = { + .demod_address = 0x1e, + .no_tuner = 1, +/* + .parallel_ts = 1, +*/ +}; + +static int gl861_frontend_attach(struct dvb_usb_adapter *adap) +{ + if ((adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config, + &adap->dev->i2c_adap)) != NULL) { + return 0; + } + + return -EIO; +} + +static int gl861_tuner_attach(struct dvb_usb_adapter *adap) +{ + adap->pll_addr = 0xc4; + adap->pll_desc = NULL; + adap->fe->ops.tuner_ops.set_params = qt1010_set_params; + + return 0; +} + +/* DVB USB Driver stuff */ +static struct dvb_usb_device_properties gl861_properties; + +static int gl861_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct dvb_usb_device *d; + struct usb_host_interface *alt; + int ret; + + if (intf->num_altsetting < 2) + return -ENODEV; + + if ((ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, + &d)) == 0) { + alt = usb_altnum_to_altsetting(intf, 0); + + if (alt == NULL) { + deb_rc("not alt found!\n"); + return -ENODEV; + } + + ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, + alt->desc.bAlternateSetting); + } + + return ret; +} + +static struct usb_device_id gl861_table [] = { + { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY55801) }, + {} /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, gl861_table); + +static struct dvb_usb_device_properties gl861_properties = { + .usb_ctrl = DEVICE_SPECIFIC, + + .size_of_priv = 0, + + .identify_state = gl861_identify_state, + .num_adapters = 1, + .adapter = {{ + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .frontend_attach = gl861_frontend_attach, + .tuner_attach = gl861_tuner_attach, + + .stream = { + .type = USB_BULK, + .count = 7, + .endpoint = 0x81, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + }}, + .i2c_algo = &gl861_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + + .num_device_descs = 1, + .devices = { + { "MSI Mega Sky 55801 DVB-T USB2.0", + { &gl861_table[0], NULL }, + { NULL }, + }, + { NULL }, + } +}; + +static struct usb_driver gl861_driver = { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, +#endif + .name = "gl861", + .probe = gl861_probe, + .disconnect = dvb_usb_device_exit, + .id_table = gl861_table, +}; + +/* module stuff */ +static int __init gl861_module_init(void) +{ + int ret; + + if ((ret = usb_register(&gl861_driver))) { + err("usb_register failed. Error number %d", ret); + return ret; + } + + return 0; +} + +static void __exit gl861_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&gl861_driver); +} + +module_init (gl861_module_init); +module_exit (gl861_module_exit); + +MODULE_AUTHOR("comabug@gmail.com"); +MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.h b/linux/drivers/media/dvb/dvb-usb/gl861.h new file mode 100644 index 000000000..df97fcf50 --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/gl861.h @@ -0,0 +1,16 @@ +#ifndef _DVB_USB_GL861_H_ +#define _DVB_USB_GL861_H_ + +#define DVB_USB_LOG_PREFIX "gl861" +#include "dvb-usb.h" + +extern int dvb_usb_gl861_debug; +#define deb_rc(args...) dprintk(dvb_usb_gl861_debug,0x01,args) + +#define GL861_WRITE 0x40 +#define GL861_READ 0xc0 + +#define GL861_REQ_I2C_WRITE 0x01 +#define GL861_REQ_I2C_READ 0x02 + +#endif -- cgit v1.2.3 From 58122726623885c7548d03374bcc76aecba35c98 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:12:14 -0400 Subject: dvb-usb: rename USB_PID_MSI_MEGASKY55801 to USB_PID_MSI_MEGASKY580_55801 From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 +- linux/drivers/media/dvb/dvb-usb/gl861.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 0414ee354..c3a42c193 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -121,7 +121,7 @@ #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM 0xdb55 #define USB_PID_MEDION_MD95700 0x0932 #define USB_PID_MSI_MEGASKY580 0x5580 -#define USB_PID_MSI_MEGASKY55801 0x5581 +#define USB_PID_MSI_MEGASKY580_55801 0x5581 #define USB_PID_KYE_DVB_T_COLD 0x701e #define USB_PID_KYE_DVB_T_WARM 0x701f #define USB_PID_PCTV_200E 0x020e diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index 52c8d082e..65d356253 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -157,7 +157,7 @@ static int gl861_probe(struct usb_interface *intf, } static struct usb_device_id gl861_table [] = { - { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY55801) }, + { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, gl861_table); -- cgit v1.2.3 From f41eb681f439e809c87295a1a8afcc14414c4ed8 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:12:55 -0400 Subject: gl861: select DVB_ZL10353 if !DVB_FE_CUSTOMISE From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index c0a899a04..ca8258ef5 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -123,7 +123,7 @@ config DVB_USB_M920X config DVB_USB_GL861 tristate "Genesys Logic GL861 USB2.0 support" depends on DVB_USB - select DVB_ZL10353 + select DVB_ZL10353 if !DVB_FE_CUSTOMISE help Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0 receiver with USB ID 0db0:5581. -- cgit v1.2.3 From 75525f873b2c1038c6ce90b2ea90cb820c37da71 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:14:07 -0400 Subject: gl861: fix MODULE_AUTHOR From: Michael Krufky The author's email address is already in the MODULE_AUTHOR field. This patch adds his name as well. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index 65d356253..72365df66 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -232,7 +232,7 @@ static void __exit gl861_module_exit(void) module_init (gl861_module_init); module_exit (gl861_module_exit); -MODULE_AUTHOR("comabug@gmail.com"); +MODULE_AUTHOR("Carl Lundqvist "); MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861"); MODULE_VERSION("1.0"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 9fa186ab3b18c5c021d632eea27fa378af8f86c8 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:15:26 -0400 Subject: gl861: fix driver_name From: Michael Krufky rename driver_name from "gl861" to "dvb_usb_gl861" Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index 72365df66..c280472d4 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -204,7 +204,7 @@ static struct usb_driver gl861_driver = { #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) .owner = THIS_MODULE, #endif - .name = "gl861", + .name = "dvb_usb_gl861", .probe = gl861_probe, .disconnect = dvb_usb_device_exit, .id_table = gl861_table, -- cgit v1.2.3 From 15c6d2444114bfb9a1921efab57d20dc1fa1f97c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:16:44 -0400 Subject: gl861: hide disabled code from upstream patch system From: Michael Krufky enclose disabled code inside an #if 0 block, instead of /* comments */ Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index c280472d4..66a231607 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -103,9 +103,9 @@ static int gl861_identify_state(struct usb_device *udev, static struct zl10353_config gl861_zl10353_config = { .demod_address = 0x1e, .no_tuner = 1, -/* +#if 0 .parallel_ts = 1, -*/ +#endif }; static int gl861_frontend_attach(struct dvb_usb_adapter *adap) -- cgit v1.2.3 From b688d4937dd26829c0f8addf8747c022a76dc374 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:17:24 -0400 Subject: gl861: remove unneeded "extern int" declaration From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.h | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.h b/linux/drivers/media/dvb/dvb-usb/gl861.h index df97fcf50..72a51afd5 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.h +++ b/linux/drivers/media/dvb/dvb-usb/gl861.h @@ -4,7 +4,6 @@ #define DVB_USB_LOG_PREFIX "gl861" #include "dvb-usb.h" -extern int dvb_usb_gl861_debug; #define deb_rc(args...) dprintk(dvb_usb_gl861_debug,0x01,args) #define GL861_WRITE 0x40 -- cgit v1.2.3 From 7c8509f620b67d34f8633a889c45ffea818e644e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:19:30 -0400 Subject: gl861: use qt1010_tuner_attach function from qt1010.h From: Michael Krufky The gl861_tuner_attach function is not specific to this device. This patch removes gl861_tuner_attach, and replaces it with qt1010_tuner_attach from the qt1010 header file. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index 66a231607..c97db23a7 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -118,15 +118,6 @@ static int gl861_frontend_attach(struct dvb_usb_adapter *adap) return -EIO; } -static int gl861_tuner_attach(struct dvb_usb_adapter *adap) -{ - adap->pll_addr = 0xc4; - adap->pll_desc = NULL; - adap->fe->ops.tuner_ops.set_params = qt1010_set_params; - - return 0; -} - /* DVB USB Driver stuff */ static struct dvb_usb_device_properties gl861_properties; @@ -173,7 +164,7 @@ static struct dvb_usb_device_properties gl861_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .frontend_attach = gl861_frontend_attach, - .tuner_attach = gl861_tuner_attach, + .tuner_attach = qt1010_tuner_attach, .stream = { .type = USB_BULK, -- cgit v1.2.3 From 04b6642b3ddf3c823d96c7ea7cb75684a31b0416 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:20:37 -0400 Subject: gl861: remove NULL entry from gl861_properties From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index c97db23a7..a35b5e052 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -187,7 +187,6 @@ static struct dvb_usb_device_properties gl861_properties = { { &gl861_table[0], NULL }, { NULL }, }, - { NULL }, } }; -- cgit v1.2.3 From 4a8e6969b11f8e93a0edaa438aa8611a77254cf3 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Oct 2006 16:21:13 -0400 Subject: gl861: whitespace cleanups From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 41 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index a35b5e052..dc90903f3 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -17,7 +17,7 @@ module_param_named(debug,dvb_usb_gl861_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); static int gl861_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) { u16 index; u16 value = addr << 8; @@ -33,25 +33,25 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, } switch (wlen) { - case 1: - index = wbuf[0]; - break; - case 2: - index = wbuf[0]; - value = value + wbuf[1]; - break; - default: - warn("wlen = %x, aborting.", wlen); - return -EINVAL; + case 1: + index = wbuf[0]; + break; + case 2: + index = wbuf[0]; + value = value + wbuf[1]; + break; + default: + warn("wlen = %x, aborting.", wlen); + return -EINVAL; } return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type, - value, index, rbuf, rlen, 2000); + value, index, rbuf, rlen, 2000); } /* I2C */ static int gl861_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; @@ -66,12 +66,12 @@ static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], /* write/read request */ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) + msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) break; i++; } else if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, NULL, 0) < 0) + msg[i].len, NULL, 0) < 0) break; } @@ -111,7 +111,7 @@ static struct zl10353_config gl861_zl10353_config = { static int gl861_frontend_attach(struct dvb_usb_adapter *adap) { if ((adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config, - &adap->dev->i2c_adap)) != NULL) { + &adap->dev->i2c_adap)) != NULL) { return 0; } @@ -122,7 +122,7 @@ static int gl861_frontend_attach(struct dvb_usb_adapter *adap) static struct dvb_usb_device_properties gl861_properties; static int gl861_probe(struct usb_interface *intf, - const struct usb_device_id *id) + const struct usb_device_id *id) { struct dvb_usb_device *d; struct usb_host_interface *alt; @@ -131,8 +131,7 @@ static int gl861_probe(struct usb_interface *intf, if (intf->num_altsetting < 2) return -ENODEV; - if ((ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, - &d)) == 0) { + if ((ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, &d)) == 0) { alt = usb_altnum_to_altsetting(intf, 0); if (alt == NULL) { @@ -141,7 +140,7 @@ static int gl861_probe(struct usb_interface *intf, } ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, - alt->desc.bAlternateSetting); + alt->desc.bAlternateSetting); } return ret; @@ -149,7 +148,7 @@ static int gl861_probe(struct usb_interface *intf, static struct usb_device_id gl861_table [] = { { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801) }, - {} /* Terminating entry */ + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, gl861_table); -- cgit v1.2.3 From a02c6e1964c4396a8595b8892d035cf56852d7f5 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 7 Oct 2006 00:25:53 -0400 Subject: gl861: correct oops when loading module From: Jan Nijs This patch moves the DVB_USB_IS_AN_I2C_ADAPTER flag from the adapter properties to the device properties. Without this patch I get an OOPS when the gl861 driver tries to access any registers. Signed-off-by: Jan Nijs Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index dc90903f3..daa6e3001 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -153,6 +153,7 @@ static struct usb_device_id gl861_table [] = { MODULE_DEVICE_TABLE (usb, gl861_table); static struct dvb_usb_device_properties gl861_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, .size_of_priv = 0, @@ -160,7 +161,6 @@ static struct dvb_usb_device_properties gl861_properties = { .identify_state = gl861_identify_state, .num_adapters = 1, .adapter = {{ - .caps = DVB_USB_IS_AN_I2C_ADAPTER, .frontend_attach = gl861_frontend_attach, .tuner_attach = qt1010_tuner_attach, -- cgit v1.2.3 From 6c927dc4a6d7c842fac1be81497c3cca15d9b0ff Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 7 Oct 2006 15:29:54 -0400 Subject: gl861: correct address of the bulk endpoint From: Jan Nijs The megasky 580 based on gl861 has three endpoints: - 0x81 BULK/ISOC IN MPEG2 TS - 0x83 INT IN remote control receiver - 0x02 BULK OUT bulk control endpoint It doesn't look like the bulk endpoint is used, but better to have the correct one in the config. Signed-off-by: Jan Nijs Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index daa6e3001..792d38971 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -178,7 +178,7 @@ static struct dvb_usb_device_properties gl861_properties = { }}, .i2c_algo = &gl861_i2c_algo, - .generic_bulk_ctrl_endpoint = 0x01, + .generic_bulk_ctrl_endpoint = 0x02, .num_device_descs = 1, .devices = { -- cgit v1.2.3 From a9c3eaf02a1ecd06111ad3ef3e02e9f9ea39d4e8 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 9 Oct 2006 00:11:07 -0400 Subject: gl861: remove unneeded declaration of .generic_bulk_ctrl_endpoint From: Michael Krufky generic_bulk_ctrl_endpoint isn't being used in this device, so this is not needed here. Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index 792d38971..98b046ef6 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -178,8 +178,6 @@ static struct dvb_usb_device_properties gl861_properties = { }}, .i2c_algo = &gl861_i2c_algo, - .generic_bulk_ctrl_endpoint = 0x02, - .num_device_descs = 1, .devices = { { "MSI Mega Sky 55801 DVB-T USB2.0", -- cgit v1.2.3 From 6a8e81ba68edf37c36d45eea7896219aac3f0b54 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 9 Oct 2006 11:49:17 -0400 Subject: gl861: use parallel_ts From: Carl Lundqvist - use parallel_ts - Now this driver works. - correct typo in MODULE_VERSION Signed-off-by: Carl Lundqvist Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/gl861.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index 98b046ef6..5a4d7edb3 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -103,9 +103,7 @@ static int gl861_identify_state(struct usb_device *udev, static struct zl10353_config gl861_zl10353_config = { .demod_address = 0x1e, .no_tuner = 1, -#if 0 .parallel_ts = 1, -#endif }; static int gl861_frontend_attach(struct dvb_usb_adapter *adap) @@ -221,5 +219,5 @@ module_exit (gl861_module_exit); MODULE_AUTHOR("Carl Lundqvist "); MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861"); -MODULE_VERSION("1.0"); +MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 0eddb48804a90a6c9484a36576d3f792922a5e5d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 5 Nov 2006 14:05:38 -0500 Subject: Initial support for Sigmatek DVB-110 DVB-T From: Antti Palosaari This patch adds driver for Sigmatek DVB-110 USB DVB-T stick. Stick has based on hardware of Qtuantek QT1010 tuner, Zarlink ZL10353 (Intel CE 6353) demodulator and Alcor Micro AU6610 DVB-T USB controller. HW is rather similar as used in MSI Megasky GL861. Currently, the driver works only in USB 2.0. In my understanding USB 1.1 is also supported by hw but I cannot test it due to lack of USB 1.1 port. Device supports only isochronous mode transfers. There is also eeprom in usb controller(at least in address range 0x80 - 0xbf) for storing data, eg. firmware. Anyway, firmware loading is not used / required by the device. There seems to be at least one unknown I2C device in address 0xa0, probably remote control or GPIO. Windows drivers reads registers from 0x00 to 0x07 from this unknown address. Driver is based on gl861 module. Tuner has a lot of problems to lock with megasky qt1010 module with this hardware with some broadcasting standards. Signed-off-by: Antti Palosaari Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 7 + linux/drivers/media/dvb/dvb-usb/Makefile | 3 + linux/drivers/media/dvb/dvb-usb/au6610.c | 245 ++++++++++++++++++++++++++ linux/drivers/media/dvb/dvb-usb/au6610.h | 19 ++ linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 + 5 files changed, 276 insertions(+) create mode 100644 linux/drivers/media/dvb/dvb-usb/au6610.c create mode 100644 linux/drivers/media/dvb/dvb-usb/au6610.h (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index ca8258ef5..6cbbaade7 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -128,6 +128,13 @@ config DVB_USB_GL861 Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0 receiver with USB ID 0db0:5581. +config DVB_USB_AU6610 + tristate "Alcor Micro AU6610 USB2.0 support" + depends on DVB_USB + select DVB_ZL10353 if !DVB_FE_CUSTOMISE + help + Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver. + config DVB_USB_DIGITV tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" depends on DVB_USB diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile index 53b63c584..40f28f559 100644 --- a/linux/drivers/media/dvb/dvb-usb/Makefile +++ b/linux/drivers/media/dvb/dvb-usb/Makefile @@ -36,6 +36,9 @@ obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o dvb-usb-gl861-objs = gl861.o obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o +dvb-usb-au6610-objs = au6610.o +obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o + dvb-usb-digitv-objs = digitv.o obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o diff --git a/linux/drivers/media/dvb/dvb-usb/au6610.c b/linux/drivers/media/dvb/dvb-usb/au6610.c new file mode 100644 index 000000000..fbe40f2d6 --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/au6610.c @@ -0,0 +1,245 @@ +/* DVB USB compliant linux driver for Sigmatek DVB-110 DVB-T USB2.0 receiver + * + * Copyright (C) 2006 Antti Palosaari (crope@iki.fi) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ + +#include "au6610.h" + +#include "zl10353.h" +#include "qt1010.h" + +/* debug */ +static int dvb_usb_au6610_debug; +module_param_named(debug, dvb_usb_au6610_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); + + +static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, + u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) +{ + int ret; + u16 index; + u8 usb_buf[6]; /* enough for all known requests, read returns 5 and write 6 bytes */ + + switch (wlen) { + case 1: + index = wbuf[0] << 8; + break; + case 2: + index = wbuf[0] << 8; + index += wbuf[1]; + break; + default: + warn("wlen = %x, aborting.", wlen); + return -EINVAL; + } + + ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, + USB_TYPE_VENDOR | USB_DIR_IN, addr, index, usb_buf, + sizeof(usb_buf), AU6610_USB_TIMEOUT); + + if (ret < 0) + return ret; + + switch (operation) { + case AU6610_REQ_I2C_READ: + case AU6610_REQ_USB_READ: + /* requested value is always 5th byte in buffer */ + rbuf[0] = usb_buf[4]; + } + + return ret; +} + +static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) +{ + u8 request; + u8 wo = (rbuf == NULL || rlen == 0); /* write-only */ + + if (wo) { + request = AU6610_REQ_I2C_WRITE; + } else { /* rw */ + request = AU6610_REQ_I2C_READ; + } + + return au6610_usb_msg(d, request, addr, wbuf, wlen, rbuf, rlen); +} + + +/* I2C */ +static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + if (num > 2) + return -EINVAL; + + for (i = 0; i < num; i++) { + /* write/read request */ + if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { + if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf, + msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) + break; + i++; + } else if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf, + msg[i].len, NULL, 0) < 0) + break; + } + + mutex_unlock(&d->i2c_mutex); + return i; +} + + +static u32 au6610_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm au6610_i2c_algo = { + .master_xfer = au6610_i2c_xfer, + .functionality = au6610_i2c_func, +}; + +/* Callbacks for DVB USB */ +static int au6610_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, + int *cold) +{ + *cold = 0; + return 0; +} + +static struct zl10353_config au6610_zl10353_config = { + .demod_address = 0x1e, + .no_tuner = 1, + .parallel_ts = 1, +}; + + +static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) +{ + if ((adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config, + &adap->dev->i2c_adap)) != NULL) { + return 0; + } + + return -EIO; +} + +/* DVB USB Driver stuff */ +static struct dvb_usb_device_properties au6610_properties; + +static int au6610_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct dvb_usb_device *d; + struct usb_host_interface *alt; + int ret; + + if (intf->num_altsetting < AU6610_ALTSETTING_COUNT) + return -ENODEV; + + if ((ret = dvb_usb_device_init(intf, &au6610_properties, THIS_MODULE, &d)) == 0) { + alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING); + + if (alt == NULL) { + deb_rc("no alt found!\n"); + return -ENODEV; + } + ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, + alt->desc.bAlternateSetting); + } + + return ret; +} + + +static struct usb_device_id au6610_table [] = { + { USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, au6610_table); + +static struct dvb_usb_device_properties au6610_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, + .size_of_priv = 0, + .identify_state = au6610_identify_state, + .num_adapters = 1, + .adapter = { + { + .frontend_attach = au6610_zl10353_frontend_attach, + .tuner_attach = qt1010_tuner_attach, + + .stream = { + .type = USB_ISOC, + .count = 5, + .endpoint = 0x82, + .u = { + .isoc = { + .framesperurb = 40, + .framesize = 942, /* maximum packet size */ + .interval = 1.25, /* 125 us */ + } + } + }, + } + }, + .i2c_algo = &au6610_i2c_algo, + .num_device_descs = 1, + .devices = { + { + "Sigmatek DVB-110 DVB-T USB2.0", + { &au6610_table[0], NULL }, + { NULL }, + }, + } +}; + +static struct usb_driver au6610_driver = { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, +#endif + .name = "dvb_usb_au6610", + .probe = au6610_probe, + .disconnect = dvb_usb_device_exit, + .id_table = au6610_table, +}; + +/* module stuff */ +static int __init au6610_module_init(void) +{ + int ret; + + if ((ret = usb_register(&au6610_driver))) { + err("usb_register failed. Error number %d", ret); + return ret; + } + + return 0; +} + +static void __exit au6610_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&au6610_driver); +} + +module_init (au6610_module_init); +module_exit (au6610_module_exit); + +MODULE_AUTHOR("Antti Palosaari "); +MODULE_DESCRIPTION("Driver Sigmatek DVB-110 DVB-T USB2.0 / AU6610"); +MODULE_VERSION("0.1"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/dvb-usb/au6610.h b/linux/drivers/media/dvb/dvb-usb/au6610.h new file mode 100644 index 000000000..4161b054c --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/au6610.h @@ -0,0 +1,19 @@ +#ifndef _DVB_USB_AU6610_H_ +#define _DVB_USB_AU6610_H_ + +#define DVB_USB_LOG_PREFIX "au6610" +#include "dvb-usb.h" + +#define deb_rc(args...) dprintk(dvb_usb_au6610_debug,0x01,args) + +#define AU6610_REQ_I2C_WRITE 0x14 +#define AU6610_REQ_I2C_READ 0x13 +#define AU6610_REQ_USB_WRITE 0x16 +#define AU6610_REQ_USB_READ 0x15 + +#define AU6610_USB_TIMEOUT 1000 + +#define AU6610_ALTSETTING_COUNT 6 +#define AU6610_ALTSETTING 5 + +#endif diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index c3a42c193..148386aba 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -11,6 +11,7 @@ /* Vendor IDs */ #define USB_VID_ADSTECH 0x06e1 +#define USB_VID_ALCOR_MICRO 0x058f #define USB_VID_ANCHOR 0x0547 #define USB_VID_AVERMEDIA 0x07ca #define USB_VID_COMPRO 0x185b @@ -137,6 +138,7 @@ #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 #define USB_PID_GENPIX_8PSK_COLD 0x0200 #define USB_PID_GENPIX_8PSK_WARM 0x0201 +#define USB_PID_SIGMATEK_DVB_110 0x6610 #endif -- cgit v1.2.3 From 6248490f36dcd34b30bfac7604948350acd6d8dc Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 21 Jan 2007 13:56:10 -0500 Subject: dvb: add new qt1010 tuner module From: Antti Palosaari gl861: (MSI Megasky) - hack for enable ZL10353 / QT1010 I2C gate - use new QT1010 module instead of old code au6610: (Sigmatek DVB-110) - hack for enable ZL10353 / QT1010 I2C gate - use new QT1010 module instead of old code Tested successfully with au6610 and gl861 devices against fi-Yllas frequencies. Now it locks perfectly with both devices. There is a "hack" to enable probable i2c gate in zl10535 demodulator. QT1010 doesn't respond to any i2c messages before we write 0x1a to demodulator register 0x62. In my understanding this should be fixed to demodulator code. Signed-off-by: Antti Palosaari Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/au6610.c | 29 +++++++++++++++++++++++++---- linux/drivers/media/dvb/dvb-usb/gl861.c | 25 ++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 5 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/au6610.c b/linux/drivers/media/dvb/dvb-usb/au6610.c index fbe40f2d6..df4b2a31c 100644 --- a/linux/drivers/media/dvb/dvb-usb/au6610.c +++ b/linux/drivers/media/dvb/dvb-usb/au6610.c @@ -1,6 +1,6 @@ /* DVB USB compliant linux driver for Sigmatek DVB-110 DVB-T USB2.0 receiver * - * Copyright (C) 2006 Antti Palosaari (crope@iki.fi) + * Copyright (C) 2006 Antti Palosaari * * 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 @@ -19,7 +19,6 @@ static int dvb_usb_au6610_debug; module_param_named(debug, dvb_usb_au6610_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); - static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { @@ -127,7 +126,6 @@ static struct zl10353_config au6610_zl10353_config = { .parallel_ts = 1, }; - static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) { if ((adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config, @@ -138,6 +136,29 @@ static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) return -EIO; } +static struct qt1010_config au6610_qt1010_config = { + .i2c_address = 0xc4 +}; + +static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) +{ + /* TODO FIXME; probably I2C gate. + QT1010 tuner does not respond before we write 0x1a to ZL10353 demodulator + register 0x62. This ought to be done somewhere in demodulator initialization. + This solution is temporary hack. */ + u8 buf[2] = { 0x62, 0x1a }; + struct i2c_msg msg = { + .addr = au6610_zl10353_config.demod_address, .flags = 0, .buf = buf, .len = 2 + }; + if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { + printk(KERN_WARNING "au6610 tuner attach failed\n"); + return -EREMOTEIO; + } + return dvb_attach(qt1010_attach, + adap->fe, &adap->dev->i2c_adap, + &au6610_qt1010_config) == NULL ? -ENODEV : 0; +} + /* DVB USB Driver stuff */ static struct dvb_usb_device_properties au6610_properties; @@ -180,7 +201,7 @@ static struct dvb_usb_device_properties au6610_properties = { .adapter = { { .frontend_attach = au6610_zl10353_frontend_attach, - .tuner_attach = qt1010_tuner_attach, + .tuner_attach = au6610_qt1010_tuner_attach, .stream = { .type = USB_ISOC, diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index 5a4d7edb3..3f8e3ea9b 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -116,6 +116,29 @@ static int gl861_frontend_attach(struct dvb_usb_adapter *adap) return -EIO; } +static struct qt1010_config gl861_qt1010_config = { + .i2c_address = 0xc4 +}; + +static int gl861_tuner_attach(struct dvb_usb_adapter *adap) +{ + /* TODO FIXME; probably I2C gate. + QT1010 tuner does not respond before we write 0x1a to ZL10353 demodulator + register 0x62. This ought to be done somewhere in demodulator initialization. + This solution is temporary hack. */ + u8 buf[2] = { 0x62, 0x1a }; + struct i2c_msg msg = { + .addr = gl861_zl10353_config.demod_address, .flags = 0, .buf = buf, .len = 2 + }; + if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { + printk(KERN_WARNING "gl861 tuner attach failed\n"); + return -EREMOTEIO; + } + return dvb_attach(qt1010_attach, + adap->fe, &adap->dev->i2c_adap, + &gl861_qt1010_config) == NULL ? -ENODEV : 0; +} + /* DVB USB Driver stuff */ static struct dvb_usb_device_properties gl861_properties; @@ -161,7 +184,7 @@ static struct dvb_usb_device_properties gl861_properties = { .adapter = {{ .frontend_attach = gl861_frontend_attach, - .tuner_attach = qt1010_tuner_attach, + .tuner_attach = gl861_tuner_attach, .stream = { .type = USB_BULK, -- cgit v1.2.3 From 4ac5362bfd6a7d7afd8c941f572488b7e77f2dec Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 21 Jan 2007 13:56:46 -0500 Subject: kconfig: qt1010 should be selected by gl861 and au6610 From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 6cbbaade7..80f67a51b 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -124,6 +124,7 @@ config DVB_USB_GL861 tristate "Genesys Logic GL861 USB2.0 support" depends on DVB_USB select DVB_ZL10353 if !DVB_FE_CUSTOMISE + select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE help Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0 receiver with USB ID 0db0:5581. @@ -132,6 +133,7 @@ config DVB_USB_AU6610 tristate "Alcor Micro AU6610 USB2.0 support" depends on DVB_USB select DVB_ZL10353 if !DVB_FE_CUSTOMISE + select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE help Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver. -- cgit v1.2.3 From 1dc3b28ac0db8c9d98fcccf87829beef1751a448 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 21 Jan 2007 13:57:48 -0500 Subject: whitespace / 80-column cleanups From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/au6610.c | 29 +++++++++++++++++------------ linux/drivers/media/dvb/dvb-usb/gl861.c | 11 ++++++----- 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/au6610.c b/linux/drivers/media/dvb/dvb-usb/au6610.c index df4b2a31c..0592faac4 100644 --- a/linux/drivers/media/dvb/dvb-usb/au6610.c +++ b/linux/drivers/media/dvb/dvb-usb/au6610.c @@ -24,8 +24,8 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, { int ret; u16 index; - u8 usb_buf[6]; /* enough for all known requests, read returns 5 and write 6 bytes */ - + u8 usb_buf[6]; /* enough for all known requests, + read returns 5 and write 6 bytes */ switch (wlen) { case 1: index = wbuf[0] << 8; @@ -40,7 +40,7 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, } ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, - USB_TYPE_VENDOR | USB_DIR_IN, addr, index, usb_buf, + USB_TYPE_VENDOR|USB_DIR_IN, addr, index, usb_buf, sizeof(usb_buf), AU6610_USB_TIMEOUT); if (ret < 0) @@ -56,7 +56,8 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, return ret; } -static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) +static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr, + u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { u8 request; u8 wo = (rbuf == NULL || rlen == 0); /* write-only */ @@ -72,7 +73,8 @@ static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen, /* I2C */ -static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) +static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i; @@ -87,7 +89,8 @@ static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n /* write/read request */ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) + msg[i].len, msg[i+1].buf, + msg[i+1].len) < 0) break; i++; } else if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf, @@ -143,13 +146,14 @@ static struct qt1010_config au6610_qt1010_config = { static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) { /* TODO FIXME; probably I2C gate. - QT1010 tuner does not respond before we write 0x1a to ZL10353 demodulator - register 0x62. This ought to be done somewhere in demodulator initialization. + QT1010 tuner does not respond before we write 0x1a to ZL10353 demod + register 0x62. This ought to be done somewhere in demod initialization. This solution is temporary hack. */ + u8 buf[2] = { 0x62, 0x1a }; - struct i2c_msg msg = { - .addr = au6610_zl10353_config.demod_address, .flags = 0, .buf = buf, .len = 2 - }; + struct i2c_msg msg = { .addr = au6610_zl10353_config.demod_address, + .flags = 0, .buf = buf, .len = 2 }; + if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { printk(KERN_WARNING "au6610 tuner attach failed\n"); return -EREMOTEIO; @@ -162,7 +166,8 @@ static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) /* DVB USB Driver stuff */ static struct dvb_usb_device_properties au6610_properties; -static int au6610_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int au6610_probe(struct usb_interface *intf, + const struct usb_device_id *id) { struct dvb_usb_device *d; struct usb_host_interface *alt; diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index 3f8e3ea9b..f45cfeee7 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -123,13 +123,14 @@ static struct qt1010_config gl861_qt1010_config = { static int gl861_tuner_attach(struct dvb_usb_adapter *adap) { /* TODO FIXME; probably I2C gate. - QT1010 tuner does not respond before we write 0x1a to ZL10353 demodulator - register 0x62. This ought to be done somewhere in demodulator initialization. + QT1010 tuner does not respond before we write 0x1a to ZL10353 demod + register 0x62. This ought to be done somewhere in demod initialization. This solution is temporary hack. */ + u8 buf[2] = { 0x62, 0x1a }; - struct i2c_msg msg = { - .addr = gl861_zl10353_config.demod_address, .flags = 0, .buf = buf, .len = 2 - }; + struct i2c_msg msg = { .addr = gl861_zl10353_config.demod_address, + .flags = 0, .buf = buf, .len = 2 }; + if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { printk(KERN_WARNING "gl861 tuner attach failed\n"); return -EREMOTEIO; -- cgit v1.2.3 From 9419425f19b35bd57aa09dd9365786a03480b24b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 27 Jan 2007 14:41:35 -0500 Subject: qt1010: use i2c_gate_ctrl where appropriate From: Antti Palosaari This patch adds calls to i2c_gate_ctrl in the qt1010 dvb tuner module, while removing the temporary hack in au6610 and gl861. Tested successfully against fi-Oulu frequencies with MSI Megasky 580 GL861 and Sigmatek DVB-110 AU6610. Signed-off-by: Antti Palosaari Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/au6610.c | 13 ------------- linux/drivers/media/dvb/dvb-usb/gl861.c | 13 ------------- linux/drivers/media/dvb/frontends/qt1010.c | 16 +++++++++++++++- 3 files changed, 15 insertions(+), 27 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/au6610.c b/linux/drivers/media/dvb/dvb-usb/au6610.c index 0592faac4..91079891d 100644 --- a/linux/drivers/media/dvb/dvb-usb/au6610.c +++ b/linux/drivers/media/dvb/dvb-usb/au6610.c @@ -145,19 +145,6 @@ static struct qt1010_config au6610_qt1010_config = { static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) { - /* TODO FIXME; probably I2C gate. - QT1010 tuner does not respond before we write 0x1a to ZL10353 demod - register 0x62. This ought to be done somewhere in demod initialization. - This solution is temporary hack. */ - - u8 buf[2] = { 0x62, 0x1a }; - struct i2c_msg msg = { .addr = au6610_zl10353_config.demod_address, - .flags = 0, .buf = buf, .len = 2 }; - - if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { - printk(KERN_WARNING "au6610 tuner attach failed\n"); - return -EREMOTEIO; - } return dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &au6610_qt1010_config) == NULL ? -ENODEV : 0; diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index f45cfeee7..30eb4586c 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -122,19 +122,6 @@ static struct qt1010_config gl861_qt1010_config = { static int gl861_tuner_attach(struct dvb_usb_adapter *adap) { - /* TODO FIXME; probably I2C gate. - QT1010 tuner does not respond before we write 0x1a to ZL10353 demod - register 0x62. This ought to be done somewhere in demod initialization. - This solution is temporary hack. */ - - u8 buf[2] = { 0x62, 0x1a }; - struct i2c_msg msg = { .addr = gl861_zl10353_config.demod_address, - .flags = 0, .buf = buf, .len = 2 }; - - if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { - printk(KERN_WARNING "gl861 tuner attach failed\n"); - return -EREMOTEIO; - } return dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &gl861_qt1010_config) == NULL ? -ENODEV : 0; diff --git a/linux/drivers/media/dvb/frontends/qt1010.c b/linux/drivers/media/dvb/frontends/qt1010.c index 60931f83f..db93776ce 100644 --- a/linux/drivers/media/dvb/frontends/qt1010.c +++ b/linux/drivers/media/dvb/frontends/qt1010.c @@ -149,6 +149,9 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; priv->frequency = freq; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + /* reg 05 base value */ if (freq < 290000000) reg05 = 0x14; /* 290 MHz */ else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */ @@ -242,6 +245,9 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame if (debug) qt1010_dump_regs(priv); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + return 0; } @@ -277,7 +283,6 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_i return qt1010_writereg(priv, 0x1e, 0x00); } - static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retval) { u8 i, val; @@ -347,6 +352,9 @@ static int qt1010_init(struct dvb_frontend *fe) { QT1010_WR, 0x08, 0x08 } }; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { switch (i2c_data[i].oper) { case QT1010_WR: @@ -430,6 +438,9 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, priv->cfg = cfg; priv->i2c = i2c; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + #if 0 qt1010_dump_regs(priv); #endif @@ -440,6 +451,9 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, return NULL; } + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + printk(KERN_INFO "Quantek QT1010 successfully identified.\n"); memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops, sizeof(struct dvb_tuner_ops)); -- cgit v1.2.3 From cb465b59328a8a1bee9c305b99af64f0f1501d4e Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Fri, 2 Feb 2007 23:12:53 +0100 Subject: budget-ci: Add separate configuration data for subsystem 0x13c2:0x1012 From: Oliver Endriss Fixed problem reported by Teemu Suikki: After a device with subsystem 0x13c2:0x1012 has been installed, devices with subsystem id 0x13c2:0x1011 did not work anymore. Reason: The driver for 0x13c2:0x1012 modified shared configuration data. Fix: Use separate configuration data for those devices. Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/budget-ci.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index 045d25541..f86ba0010 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -884,6 +884,17 @@ static struct tda1004x_config philips_tdm1316l_config = { .request_firmware = philips_tdm1316l_request_firmware, }; +static struct tda1004x_config philips_tdm1316l_config_invert = { + + .demod_address = 0x8, + .invert = 1, + .invert_oclk = 0, + .xtal_freq = TDA10046_XTAL_4M, + .agc_config = TDA10046_AGC_DEFAULT, + .if_freq = TDA10046_FREQ_3617, + .request_firmware = philips_tdm1316l_request_firmware, +}; + static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; @@ -1107,9 +1118,8 @@ static void frontend_init(struct budget_ci *budget_ci) case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt)) budget_ci->tuner_pll_address = 0x60; - philips_tdm1316l_config.invert = 1; budget_ci->budget.dvb_frontend = - dvb_attach(tda10046_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap); + dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; -- cgit v1.2.3 From b5f5fe52acd6950d39ed7bade847af37031ae213 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 3 Feb 2007 00:49:54 +0100 Subject: Fix cx2584x revision reporting. From: Hans Verkuil Revisions >= 23 were always reported as revision 23. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx25840/cx25840-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index b06553a1f..a1a4907af 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -908,9 +908,11 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, return 0; } + /* Note: revision '(device_id & 0x0f) == 2' was never built. The + marking skips from 0x1 == 22 to 0x3 == 23. */ v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", (device_id & 0xfff0) >> 4, - (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, + (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f), address << 1, adapter->name); i2c_set_clientdata(client, state); -- cgit v1.2.3 From 1bc102264989e1835b7cb712a20692c8b22d3abd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 3 Feb 2007 10:35:07 +0100 Subject: Fix CC handling in VIDIOC_INT_G_VBI_DATA From: Hans Verkuil When capturing a 60 Hz input the internal field ID is inverted. The VIDIOC_INT_G_VBI_DATA didn't take that into account and so returned XDS instead of CC and vice versa. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7115.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 71e1cab45..6163a68e3 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -1399,6 +1399,9 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar { struct v4l2_sliced_vbi_data *data = arg; + /* Note: the internal field ID is inverted for NTSC, + so data->field 0 maps to the saa7115 even field, + whereas for PAL it maps to the saa7115 odd field. */ switch (data->id) { case V4L2_SLICED_WSS_625: if (saa711x_read(client, 0x6b) & 0xc0) @@ -1409,17 +1412,17 @@ static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *ar case V4L2_SLICED_CAPTION_525: if (data->field == 0) { /* CC */ - if (saa711x_read(client, 0x66) & 0xc0) + if (saa711x_read(client, 0x66) & 0x30) return -EIO; - data->data[0] = saa711x_read(client, 0x67); - data->data[1] = saa711x_read(client, 0x68); + data->data[0] = saa711x_read(client, 0x69); + data->data[1] = saa711x_read(client, 0x6a); return 0; } /* XDS */ - if (saa711x_read(client, 0x66) & 0x30) + if (saa711x_read(client, 0x66) & 0xc0) return -EIO; - data->data[0] = saa711x_read(client, 0x69); - data->data[1] = saa711x_read(client, 0x6a); + data->data[0] = saa711x_read(client, 0x67); + data->data[1] = saa711x_read(client, 0x68); return 0; default: return -EINVAL; -- cgit v1.2.3 From 4ddabb0e021ea79119db35f5f848fb9220077e20 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sat, 3 Feb 2007 18:47:14 +0100 Subject: budget-av: Call saa7146_vv_release on exit From: Marco Schluessler Call saa7146_vv_release on exit. Signed-off-by: Marco Schluessler Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/budget-av.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index 89ab4b591..3035b224c 100644 --- a/linux/drivers/media/dvb/ttpci/budget-av.c +++ b/linux/drivers/media/dvb/ttpci/budget-av.c @@ -1089,6 +1089,8 @@ static int budget_av_detach(struct saa7146_dev *dev) msleep(200); saa7146_unregister_device(&budget_av->vd, dev); + + saa7146_vv_release(dev); } if (budget_av->budget.ci_present) @@ -1145,6 +1147,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { /* fixme: proper cleanup here */ ERR(("cannot register capture v4l2 device.\n")); + saa7146_vv_release(dev); return err; } -- cgit v1.2.3 From a1082a831b2f317f6eadd4e9b500c53e0457c94b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 5 Feb 2007 14:24:04 -0500 Subject: Backed out changeset a829a6ca77529b26451610ec6368ceeaa8103ebd From: Chris Rankin Due to usb_to_input_id(), this change was completely unnecessary. These three lines are trying to do exactly what usb_to_input_id() does already. Remove them. Signed-off-by: Chris Rankin Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 1bee5dfad..1a86adbfa 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -125,9 +125,6 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) input_dev->keycodemax = KEY_MAX; input_dev->name = "IR-receiver inside an USB DVB receiver"; input_dev->phys = d->rc_phys; - input_dev->id.bustype = BUS_USB; - input_dev->id.vendor = d->udev->descriptor.idVendor; - input_dev->id.product = d->udev->descriptor.idProduct; usb_to_input_id(d->udev, &input_dev->id); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) input_dev->cdev.dev = &d->udev->dev; -- cgit v1.2.3 From cfdafbfa99ae8858be9853b49f8140d159c85d57 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 5 Feb 2007 20:56:22 +0100 Subject: cx25840 request_firmware failed due to wrong device. From: Hans Verkuil Due to changes in the /sys directory structure a bug in the cx25840 firmware load surfaced in 2.6.20: the device passed to request_firmware was wrong: instead of the i2c device the i2c adapter was passed. Because of this an attemp was made to create a kobject with the adapter name inside the adapter directory, but a kobject with that name already exists. Now pass the i2c device itself so that the correct /sys directory is used. This way the firmware can be loaded again. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cx25840/cx25840-firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/cx25840/cx25840-firmware.c b/linux/drivers/media/video/cx25840/cx25840-firmware.c index e14e0bc1f..1b730b155 100644 --- a/linux/drivers/media/video/cx25840/cx25840-firmware.c +++ b/linux/drivers/media/video/cx25840/cx25840-firmware.c @@ -39,7 +39,7 @@ #define FWSEND 48 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) -#define FWDEV(x) &((x)->adapter->dev) +#define FWDEV(x) &((x)->dev) #else #define FWDEV(x) (x)->name #endif -- cgit v1.2.3 From a3318fa68e690e504facbbb034973611802f26c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 21:29:07 -0200 Subject: Avoid race when deregistering the IR control for dvb-usb From: Chris Rankin The work item function is dvb_usb_read_remote_control(): INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d); and the last piece of work it does is: schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); Hence you need to call "cancel_rearming_delayed_work()" and not "cancel_delayed_work()", correct? I certainly haven't seen this oops reoccur since I applied this patch. Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 1bee5dfad..7b899cd6b 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -174,7 +174,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) int dvb_usb_remote_exit(struct dvb_usb_device *d) { if (d->state & DVB_USB_STATE_REMOTE) { - cancel_delayed_work(&d->rc_query_work); + cancel_rearming_delayed_work(&d->rc_query_work); flush_scheduled_work(); input_unregister_device(d->rc_input_dev); } -- cgit v1.2.3 From be873fa9b4193699c481d44898632ab73b9b33e2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 22:46:54 -0200 Subject: Remove the unused kernel config option VIDEO_VIDEOBUF From: Robert P. J. Day Signed-off-by: Robert P. J. Day Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/Kconfig | 4 ---- 1 file changed, 4 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/common/Kconfig b/linux/drivers/media/common/Kconfig index f33e5d973..c120114c2 100644 --- a/linux/drivers/media/common/Kconfig +++ b/linux/drivers/media/common/Kconfig @@ -5,8 +5,4 @@ config VIDEO_SAA7146 config VIDEO_SAA7146_VV tristate select VIDEO_BUF - select VIDEO_VIDEOBUF select VIDEO_SAA7146 - -config VIDEO_VIDEOBUF - tristate -- cgit v1.2.3 From aaa0e2fbc9f0083923be1e72016aee926e30a1fb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 22:50:36 -0200 Subject: Frontends/: make 4 functions static From: Adrian Bunk This patch makes four needlessly global functions static. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/stv0299.c | 2 +- linux/drivers/media/dvb/frontends/tda10021.c | 2 +- linux/drivers/media/dvb/frontends/tda1004x.c | 2 +- linux/drivers/media/dvb/frontends/zl10353.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/stv0299.c b/linux/drivers/media/dvb/frontends/stv0299.c index 93483769e..18768d2f6 100644 --- a/linux/drivers/media/dvb/frontends/stv0299.c +++ b/linux/drivers/media/dvb/frontends/stv0299.c @@ -92,7 +92,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) return (ret != 1) ? -EREMOTEIO : 0; } -int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len) +static int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len) { struct stv0299_state* state = fe->demodulator_priv; diff --git a/linux/drivers/media/dvb/frontends/tda10021.c b/linux/drivers/media/dvb/frontends/tda10021.c index 8b7bbdf2e..f34f82fa9 100644 --- a/linux/drivers/media/dvb/frontends/tda10021.c +++ b/linux/drivers/media/dvb/frontends/tda10021.c @@ -201,7 +201,7 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate return 0; } -int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len) +static int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len) { struct tda10021_state* state = fe->demodulator_priv; diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c index 00e4bcd9f..f4a9cf9d2 100644 --- a/linux/drivers/media/dvb/frontends/tda1004x.c +++ b/linux/drivers/media/dvb/frontends/tda1004x.c @@ -579,7 +579,7 @@ static int tda1004x_decode_fec(int tdafec) return -1; } -int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) +static int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) { struct tda1004x_state* state = fe->demodulator_priv; diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index 51d50dcf5..c05f2c0e1 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -56,7 +56,7 @@ static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) return 0; } -int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) +static int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) { int err, i; for (i = 0; i < ilen - 1; i++) -- cgit v1.2.3 From 6344857b3efe147943968b446b545e21cf3e7e87 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 22:51:14 -0200 Subject: VIDEO_BUF depends on PCI From: Andrew Morton m68k allmodconfig: drivers/media/video/video-buf.c: In function 'videobuf_queue_pci': drivers/media/video/video-buf.c:396: error: 'pci_map_sg' undeclared (first use in this function) drivers/media/video/video-buf.c:396: error: (Each undeclared identifier is reported only once drivers/media/video/video-buf.c:396: error: for each function it appears in.) drivers/media/video/video-buf.c:399: error: 'pci_dma_sync_sg_for_cpu' undeclared (first use in this function) drivers/media/video/video-buf.c:401: error: 'pci_unmap_sg' undeclared (first use in this function) drivers/media/video/video-buf.c: In function 'videobuf_pci_dma_map': Acked-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/Kconfig | 1 + linux/drivers/media/video/Kconfig | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig index 87410dbd3..91d25798a 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -70,6 +70,7 @@ config VIDEO_TUNER depends on I2C config VIDEO_BUF + depends on PCI tristate config VIDEO_BUF_DVB diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 57357db31..7a6105153 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -342,7 +342,7 @@ endmenu # encoder / decoder chips config VIDEO_VIVI tristate "Virtual Video Driver" - depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 + depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI select VIDEO_BUF default n ---help--- -- cgit v1.2.3 From 3373fc4cf4a1eb5f99208906aaa15e4c006af5bd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 22:52:04 -0200 Subject: Convert to generic boolean-values From: Richard Knutsson Signed-off-by: Richard Knutsson Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa5246a.c | 10 +++--- linux/drivers/media/video/saa5246a.h | 9 ++---- linux/drivers/media/video/saa5249.c | 41 +++++++++++-------------- linux/drivers/media/video/saa7134/saa7134-i2c.c | 24 +++++++-------- linux/drivers/media/video/saa7134/saa7134.h | 6 ---- 5 files changed, 37 insertions(+), 53 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/saa5246a.c b/linux/drivers/media/video/saa5246a.c index 8de0cbc87..752ab1651 100644 --- a/linux/drivers/media/video/saa5246a.c +++ b/linux/drivers/media/video/saa5246a.c @@ -122,7 +122,7 @@ static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind) for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0])); - t->is_searching[pgbuf] = FALSE; + t->is_searching[pgbuf] = false; } vd->priv=t; @@ -209,7 +209,7 @@ static int i2c_senddata(struct saa5246a_device *t, ...) /* Get count number of bytes from I²C-device at address adr, store them in buf. * Start & stop handshaking is done by this routine, ack will be sent after the - * last byte to inhibit further sending of data. If uaccess is TRUE, data is + * last byte to inhibit further sending of data. If uaccess is 'true', data is * written to user-space with put_user. Returns -1 if I²C-device didn't send * acknowledge, 0 otherwise */ @@ -349,7 +349,7 @@ static int saa5246a_request_page(struct saa5246a_device *t, return -EIO; } - t->is_searching[req->pgbuf] = TRUE; + t->is_searching[req->pgbuf] = true; return 0; } @@ -463,7 +463,7 @@ static inline int saa5246a_get_status(struct saa5246a_device *t, } } if (!info->hamming && !info->notfound) - t->is_searching[dau_no] = FALSE; + t->is_searching[dau_no] = false; return 0; } @@ -575,7 +575,7 @@ static inline int saa5246a_stop_dau(struct saa5246a_device *t, { return -EIO; } - t->is_searching[dau_no] = FALSE; + t->is_searching[dau_no] = false; return 0; } diff --git a/linux/drivers/media/video/saa5246a.h b/linux/drivers/media/video/saa5246a.h index 7b9111230..64394c036 100644 --- a/linux/drivers/media/video/saa5246a.h +++ b/linux/drivers/media/video/saa5246a.h @@ -41,23 +41,18 @@ #define POS_HEADER_START 7 #define POS_HEADER_END 31 -/* Returns TRUE if the part of the videotext page described with req contains +/* Returns 'true' if the part of the videotext page described with req contains (at least parts of) the time field */ #define REQ_CONTAINS_TIME(p_req) \ ((p_req)->start <= POS_TIME_END && \ (p_req)->end >= POS_TIME_START) -/* Returns TRUE if the part of the videotext page described with req contains +/* Returns 'true' if the part of the videotext page described with req contains (at least parts of) the page header */ #define REQ_CONTAINS_HEADER(p_req) \ ((p_req)->start <= POS_HEADER_END && \ (p_req)->end >= POS_HEADER_START) -#ifndef FALSE -#define FALSE 0 -#define TRUE 1 -#endif - /*****************************************************************************/ /* Mode register numbers of the SAA5246A */ /*****************************************************************************/ diff --git a/linux/drivers/media/video/saa5249.c b/linux/drivers/media/video/saa5249.c index 04ca4c336..040b521f0 100644 --- a/linux/drivers/media/video/saa5249.c +++ b/linux/drivers/media/video/saa5249.c @@ -131,11 +131,6 @@ struct saa5249_device /* General defines and debugging support */ -#ifndef FALSE -#define FALSE 0 -#define TRUE 1 -#endif - #define RESCHED do { cond_resched(); } while(0) static struct video_device saa_template; /* Declared near bottom */ @@ -193,9 +188,9 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs)); memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat)); t->vdau[pgbuf].expire = 0; - t->vdau[pgbuf].clrfound = TRUE; - t->vdau[pgbuf].stopped = TRUE; - t->is_searching[pgbuf] = FALSE; + t->vdau[pgbuf].clrfound = true; + t->vdau[pgbuf].stopped = true; + t->is_searching[pgbuf] = false; } vd->priv=t; @@ -308,7 +303,7 @@ static int i2c_senddata(struct saa5249_device *t, ...) /* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop * handshaking is done by this routine, ack will be sent after the last byte to inhibit further - * sending of data. If uaccess is TRUE, data is written to user-space with put_user. + * sending of data. If uaccess is 'true', data is written to user-space with put_user. * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise */ @@ -327,7 +322,7 @@ static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) static int do_saa5249_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { - static int virtual_mode = FALSE; + static int virtual_mode = false; struct video_device *vd = video_devdata(file); struct saa5249_device *t=vd->priv; @@ -350,7 +345,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) return -EINVAL; memset(t->vdau[req->pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); - t->vdau[req->pgbuf].clrfound = TRUE; + t->vdau[req->pgbuf].clrfound = true; return 0; } @@ -360,7 +355,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) return -EINVAL; - t->vdau[req->pgbuf].clrfound = TRUE; + t->vdau[req->pgbuf].clrfound = true; return 0; } @@ -386,9 +381,9 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, t->vdau[req->pgbuf].sregs[4] = (req->pagemask & HR_UNIT ? 0x10 : 0) | (req->hour & 0xf); t->vdau[req->pgbuf].sregs[5] = (req->pagemask & MIN_TEN ? 0x10 : 0) | (req->minute / 0x10); t->vdau[req->pgbuf].sregs[6] = (req->pagemask & MIN_UNIT ? 0x10 : 0) | (req->minute & 0xf); - t->vdau[req->pgbuf].stopped = FALSE; - t->vdau[req->pgbuf].clrfound = TRUE; - t->is_searching[req->pgbuf] = TRUE; + t->vdau[req->pgbuf].stopped = false; + t->vdau[req->pgbuf].clrfound = true; + t->is_searching[req->pgbuf] = true; return 0; } @@ -440,7 +435,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40)) return -EIO; } - t->vdau[req->pgbuf].clrfound = FALSE; + t->vdau[req->pgbuf].clrfound = false; memcpy(t->vdau[req->pgbuf].laststat, infobits, sizeof(infobits)); } else @@ -484,7 +479,7 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, return -EFAULT; if (!info.hamming && !info.notfound) { - t->is_searching[req->pgbuf] = FALSE; + t->is_searching[req->pgbuf] = false; } return 0; } @@ -540,8 +535,8 @@ static int do_saa5249_ioctl(struct inode *inode, struct file *file, if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) return -EINVAL; - t->vdau[req->pgbuf].stopped = TRUE; - t->is_searching[req->pgbuf] = FALSE; + t->vdau[req->pgbuf].stopped = true; + t->is_searching[req->pgbuf] = false; return 0; } @@ -670,11 +665,11 @@ static int saa5249_open(struct inode *inode, struct file *file) memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs)); memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat)); t->vdau[pgbuf].expire = 0; - t->vdau[pgbuf].clrfound = TRUE; - t->vdau[pgbuf].stopped = TRUE; - t->is_searching[pgbuf] = FALSE; + t->vdau[pgbuf].clrfound = true; + t->vdau[pgbuf].stopped = true; + t->is_searching[pgbuf] = false; } - t->virtual_mode=FALSE; + t->virtual_mode = false; return 0; fail: diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c index 0f572899c..8b070d617 100644 --- a/linux/drivers/media/video/saa7134/saa7134-i2c.c +++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c @@ -121,9 +121,9 @@ static inline int i2c_is_error(enum i2c_status status) case ARB_LOST: case SEQ_ERR: case ST_ERR: - return TRUE; + return true; default: - return FALSE; + return false; } } @@ -132,9 +132,9 @@ static inline int i2c_is_idle(enum i2c_status status) switch (status) { case IDLE: case DONE_STOP: - return TRUE; + return true; default: - return FALSE; + return false; } } @@ -142,9 +142,9 @@ static inline int i2c_is_busy(enum i2c_status status) { switch (status) { case BUSY: - return TRUE; + return true; default: - return FALSE; + return false; } } @@ -160,8 +160,8 @@ static int i2c_is_busy_wait(struct saa7134_dev *dev) saa_wait(I2C_WAIT_DELAY); } if (I2C_WAIT_RETRY == count) - return FALSE; - return TRUE; + return false; + return true; } static int i2c_reset(struct saa7134_dev *dev) @@ -172,7 +172,7 @@ static int i2c_reset(struct saa7134_dev *dev) d2printk(KERN_DEBUG "%s: i2c reset\n",dev->name); status = i2c_get_status(dev); if (!i2c_is_error(status)) - return TRUE; + return true; i2c_set_status(dev,status); for (count = 0; count < I2C_WAIT_RETRY; count++) { @@ -182,13 +182,13 @@ static int i2c_reset(struct saa7134_dev *dev) udelay(I2C_WAIT_DELAY); } if (I2C_WAIT_RETRY == count) - return FALSE; + return false; if (!i2c_is_idle(status)) - return FALSE; + return false; i2c_set_attr(dev,NOP); - return TRUE; + return true; } static inline int i2c_send_byte(struct saa7134_dev *dev, diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 42fa1c7b7..6ca439741 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -52,12 +52,6 @@ #include #endif -#ifndef TRUE -# define TRUE (1==1) -#endif -#ifndef FALSE -# define FALSE (1==0) -#endif #define UNSET (-1U) /* ----------------------------------------------------------- */ -- cgit v1.2.3 From 8f938cbe5d449f5497d2cc698324d6c5c421eec1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 22:52:36 -0200 Subject: Cafe_ccic.c fix warning From: Jonathan Corbet Quiet a spurious gcc warning. Signed-off-by: Jonathan Corbet Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cafe_ccic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c index 68f2326dc..a8d0cb910 100644 --- a/linux/drivers/media/video/cafe_ccic.c +++ b/linux/drivers/media/video/cafe_ccic.c @@ -1201,7 +1201,7 @@ static int cafe_vidioc_reqbufs(struct file *filp, void *priv, struct v4l2_requestbuffers *req) { struct cafe_camera *cam = filp->private_data; - int ret; + int ret = 0; /* Silence warning */ /* * Make sure it's something we can do. User pointers could be -- cgit v1.2.3 From 8b41e1f9f274a2fef5a0364ca4a8acff2201c374 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 22:53:04 -0200 Subject: Cx88-video.c: remove struct radionorms From: Adrian Bunk This patch removes the unused struct radionorms. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx88/cx88-video.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index ee3ef610e..43c89eec9 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -102,8 +102,6 @@ static LIST_HEAD(cx8800_devlist); /* ------------------------------------------------------------------- */ /* static data */ -v4l2_std_id radionorms[] = { 0 }; - static struct cx8800_fmt formats[] = { { .name = "8 bpp, gray", -- cgit v1.2.3 From 1ad4a611a7ec56d90892541521d3d5bd293f2814 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 22:53:31 -0200 Subject: From: Adrian Bunk v4l_printk_ioctl_arg() is no longer used. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 26669ebde..f31a1bb61 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -290,11 +290,13 @@ char *v4l2_type_names[] = { [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "slicec-vbi-out", }; +#if 0 static char *v4l2_memory_names[] = { [V4L2_MEMORY_MMAP] = "mmap", [V4L2_MEMORY_USERPTR] = "userptr", [V4L2_MEMORY_OVERLAY] = "overlay", }; +#endif /* 0 */ #define prt_names(a,arr) (((a)>=0)&&((a)field,v4l2_field_names), fmt->bytesperline,fmt->sizeimage,fmt->colorspace); }; +#endif /* 0 */ /* Common ioctl debug function. This function can be used by external ioctl messages as well as internal V4L ioctl */ @@ -488,6 +492,7 @@ void v4l_printk_ioctl(unsigned int cmd) } } +#if 0 /* Common ioctl debug function. This function can be used by external ioctl messages as well as internal V4L ioctl and its arguments */ @@ -1071,6 +1076,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) } } } +#endif /* 0 */ /* ----------------------------------------------------------------- */ @@ -1579,7 +1585,6 @@ EXPORT_SYMBOL(v4l2_prio_check); EXPORT_SYMBOL(v4l2_field_names); EXPORT_SYMBOL(v4l2_type_names); EXPORT_SYMBOL(v4l_printk_ioctl); -EXPORT_SYMBOL(v4l_printk_ioctl_arg); EXPORT_SYMBOL(v4l2_ctrl_next); EXPORT_SYMBOL(v4l2_ctrl_check); -- cgit v1.2.3 From 1a5af409063c762b8d19699c214a1dce5b7a0360 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 22:55:07 -0200 Subject: Radio/: Convert to generic boolean-values From: Richard Knutsson Signed-off-by: Richard Knutsson Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-gemtek-pci.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/radio/radio-gemtek-pci.c b/linux/drivers/media/radio/radio-gemtek-pci.c index 75f2756c1..760cfebc8 100644 --- a/linux/drivers/media/radio/radio-gemtek-pci.c +++ b/linux/drivers/media/radio/radio-gemtek-pci.c @@ -90,14 +90,6 @@ static struct v4l2_queryctrl radio_qctrl[] = { #define GEMTEK_PCI_RANGE_HIGH (108*16000) #endif -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - struct gemtek_pci_card { struct video_device *videodev; @@ -147,12 +139,12 @@ static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) static inline void gemtek_pci_nil( u32 port, u8 *last_byte ) { - __gemtek_pci_cmd( 0x00, port, last_byte, FALSE ); + __gemtek_pci_cmd( 0x00, port, last_byte, false ); } static inline void gemtek_pci_cmd( u16 cmd, u32 port, u8 *last_byte ) { - __gemtek_pci_cmd( cmd, port, last_byte, TRUE ); + __gemtek_pci_cmd( cmd, port, last_byte, true ); } static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long frequency ) @@ -185,14 +177,14 @@ static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long static inline void gemtek_pci_mute( struct gemtek_pci_card *card ) { outb( 0x1f, card->iobase ); - card->mute = TRUE; + card->mute = true; } static inline void gemtek_pci_unmute( struct gemtek_pci_card *card ) { if ( card->mute ) { gemtek_pci_setfrequency( card, card->current_frequency ); - card->mute = FALSE; + card->mute = false; } } @@ -260,7 +252,7 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, gemtek_pci_setfrequency( card, f->frequency ); card->current_frequency = f->frequency; - card->mute = FALSE; + card->mute = false; return 0; } case VIDIOC_QUERYCTRL: -- cgit v1.2.3 From f904628e6435f1e218b065888a4f90d7709bee7b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 6 Feb 2007 22:59:18 -0200 Subject: DVB: Use ARRAY_SIZE macro when appropriate From: Ahmed S. Darwish Use ARRAY_SIZE macro already defined in kernel.h Signed-off-by: Ahmed S. Darwish Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/bt8xx/dst.c | 2 +- linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c | 3 ++- linux/drivers/media/dvb/frontends/cx24110.c | 4 ++-- linux/drivers/media/dvb/frontends/cx24123.c | 6 +++--- linux/drivers/media/dvb/ttpci/av7110_ir.c | 3 ++- 5 files changed, 10 insertions(+), 8 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/bt8xx/dst.c b/linux/drivers/media/dvb/bt8xx/dst.c index 9f72b7000..0393a3d19 100644 --- a/linux/drivers/media/dvb/bt8xx/dst.c +++ b/linux/drivers/media/dvb/bt8xx/dst.c @@ -1161,7 +1161,7 @@ static int dst_get_device_id(struct dst_state *state) } } - if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) { + if (i >= ARRAY_SIZE(dst_tlist)) { dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]); dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in"); use_dst_type = DST_TYPE_IS_SAT; diff --git a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 254d9d1b5..43ba7cadb 100644 --- a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -214,7 +215,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend freq = 2150000; /* satellite IF is 950..2150MHz */ /* decide which VCO to use for the input frequency */ - for(i=1;(ibands[i]);i++) + for(i=0;(ibands[i]);i++) ; /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz, and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult, @@ -361,7 +361,7 @@ static int cx24110_initfe(struct dvb_frontend* fe) dprintk("%s: init chip\n", __FUNCTION__); - for(i=0;iVCAarg = cx24123_AGC_vals[0].VCAprogdata; @@ -527,7 +527,7 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa vco_div = cx24123_bandselect_vals[0].VCOdivider; /* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */ - for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) + for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) { if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { @@ -669,7 +669,7 @@ static int cx24123_initfe(struct dvb_frontend* fe) dprintk("%s: init frontend\n",__FUNCTION__); /* Configure the demod to a good set of defaults */ - for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) + for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++) cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); /* Set the LNB polarity */ diff --git a/linux/drivers/media/dvb/ttpci/av7110_ir.c b/linux/drivers/media/dvb/ttpci/av7110_ir.c index 344ec1243..54460acab 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_ir.c +++ b/linux/drivers/media/dvb/ttpci/av7110_ir.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "av7110.h" @@ -218,7 +219,7 @@ int __devinit av7110_ir_init(struct av7110 *av7110) static struct proc_dir_entry *e; int err; - if (av_cnt >= sizeof av_list/sizeof av_list[0]) + if (av_cnt >= ARRAY_SIZE(av_list)) return -ENOSPC; av7110_setup_irc_config(av7110, 0x0001); -- cgit v1.2.3 From 024dad545b3f3b99b27943b729899634f136fcbe Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 7 Feb 2007 09:44:27 -0200 Subject: Reverting patch d1bfc4440540ee9f86bff20850ed205d0ddad1bf From: Mauro Carvalho Chehab Patch broke pvrusb2 driver. Reverting it. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx25840/cx25840-firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/cx25840/cx25840-firmware.c b/linux/drivers/media/video/cx25840/cx25840-firmware.c index 1b730b155..e14e0bc1f 100644 --- a/linux/drivers/media/video/cx25840/cx25840-firmware.c +++ b/linux/drivers/media/video/cx25840/cx25840-firmware.c @@ -39,7 +39,7 @@ #define FWSEND 48 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) -#define FWDEV(x) &((x)->dev) +#define FWDEV(x) &((x)->adapter->dev) #else #define FWDEV(x) (x)->name #endif -- cgit v1.2.3 From 8fb5e6d4dfb44d620ca67d50e1df0b8e1214e01d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 7 Feb 2007 11:13:11 -0200 Subject: Usbvision: dynamic allocation for frames From: Thierry MERLE - fix decoder route output - dynamic frame buffer allocation Signed-off-by: Thierry MERLE Signed-off-by: Mauro Carvalho Chehab --- .../drivers/media/video/usbvision/usbvision-core.c | 35 ++++++++----- .../media/video/usbvision/usbvision-video.c | 57 +++++++++++++--------- linux/drivers/media/video/usbvision/usbvision.h | 3 +- 3 files changed, 60 insertions(+), 35 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c index db466ea0d..0671b309e 100644 --- a/linux/drivers/media/video/usbvision/usbvision-core.c +++ b/linux/drivers/media/video/usbvision/usbvision-core.c @@ -1916,28 +1916,33 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width, /* * usbvision_frames_alloc - * allocate the maximum frames this driver can manage + * allocate the required frames */ -int usbvision_frames_alloc(struct usb_usbvision *usbvision) +int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames) { int i; - /* Allocate memory for the frame buffers */ - usbvision->max_frame_size = MAX_FRAME_SIZE; - usbvision->fbuf_size = USBVISION_NUMFRAMES * usbvision->max_frame_size; - usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size); + /*needs to be page aligned cause the buffers can be mapped individually! */ + usbvision->max_frame_size = PAGE_ALIGN(usbvision->curwidth * + usbvision->curheight * + usbvision->palette.bytes_per_pixel); - if(usbvision->fbuf == NULL) { - err("%s: unable to allocate %d bytes for fbuf ", - __FUNCTION__, usbvision->fbuf_size); - return -ENOMEM; + /* Try to do my best to allocate the frames the user want in the remaining memory */ + usbvision->num_frames = number_of_frames; + while (usbvision->num_frames > 0) { + usbvision->fbuf_size = usbvision->num_frames * usbvision->max_frame_size; + if((usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size))) { + break; + } + usbvision->num_frames--; } + spin_lock_init(&usbvision->queue_lock); init_waitqueue_head(&usbvision->wait_frame); init_waitqueue_head(&usbvision->wait_stream); /* Allocate all buffers */ - for (i = 0; i < USBVISION_NUMFRAMES; i++) { + for (i = 0; i < usbvision->num_frames; i++) { usbvision->frame[i].index = i; usbvision->frame[i].grabstate = FrameState_Unused; usbvision->frame[i].data = usbvision->fbuf + @@ -1951,7 +1956,8 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision) usbvision->frame[i].height = usbvision->curheight; usbvision->frame[i].bytes_read = 0; } - return 0; + PDEBUG(DBG_FUNC, "allocated %d frames (%d bytes per frame)",usbvision->num_frames,usbvision->max_frame_size); + return usbvision->num_frames; } /* @@ -1961,9 +1967,13 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision) void usbvision_frames_free(struct usb_usbvision *usbvision) { /* Have to free all that memory */ + PDEBUG(DBG_FUNC, "free %d frames",usbvision->num_frames); + if (usbvision->fbuf != NULL) { usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size); usbvision->fbuf = NULL; + + usbvision->num_frames = 0; } } /* @@ -2612,6 +2622,7 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel) RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs); usbvision->ctl_input = channel; route.input = SAA7115_COMPOSITE1; + route.output = 0; call_i2c_clients(usbvision, VIDIOC_INT_S_VIDEO_ROUTING,&route); call_i2c_clients(usbvision, VIDIOC_S_INPUT, &usbvision->ctl_input); diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index 2b8895d99..8d32c44ed 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -412,19 +412,14 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) if (usbvision->user) errCode = -EBUSY; else { - /* Allocate memory for the frame buffers */ - errCode = usbvision_frames_alloc(usbvision); - if(!errCode) { - /* Allocate memory for the scratch ring buffer */ - errCode = usbvision_scratch_alloc(usbvision); - if ((!errCode) && (isocMode==ISOC_MODE_COMPRESS)) { - /* Allocate intermediate decompression buffers only if needed */ - errCode = usbvision_decompress_alloc(usbvision); - } + /* Allocate memory for the scratch ring buffer */ + errCode = usbvision_scratch_alloc(usbvision); + if (isocMode==ISOC_MODE_COMPRESS) { + /* Allocate intermediate decompression buffers only if needed */ + errCode = usbvision_decompress_alloc(usbvision); } if (errCode) { /* Deallocate all buffers if trouble */ - usbvision_frames_free(usbvision); usbvision_scratch_free(usbvision); usbvision_decompress_free(usbvision); } @@ -506,6 +501,7 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) usbvision_decompress_free(usbvision); usbvision_frames_free(usbvision); + usbvision_empty_framequeues(usbvision); usbvision_scratch_free(usbvision); usbvision->user--; @@ -850,7 +846,9 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, return ret; } + usbvision_frames_free(usbvision); usbvision_empty_framequeues(usbvision); + vr->count = usbvision_frames_alloc(usbvision,vr->count); usbvision->curFrame = NULL; @@ -867,7 +865,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { return -EINVAL; } - if(vb->index>=USBVISION_NUMFRAMES) { + if(vb->index>=usbvision->num_frames) { return -EINVAL; } // Updating the corresponding frame state @@ -881,7 +879,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, vb->flags |= V4L2_BUF_FLAG_MAPPED; vb->memory = V4L2_MEMORY_MMAP; - vb->m.offset = vb->index*usbvision->max_frame_size; + vb->m.offset = vb->index*PAGE_ALIGN(usbvision->max_frame_size); vb->memory = V4L2_MEMORY_MMAP; vb->field = V4L2_FIELD_NONE; @@ -900,7 +898,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { return -EINVAL; } - if(vb->index>=USBVISION_NUMFRAMES) { + if(vb->index>=usbvision->num_frames) { return -EINVAL; } @@ -1070,6 +1068,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, if ((ret = usbvision_stream_interrupt(usbvision))) return ret; } + usbvision_frames_free(usbvision); usbvision_empty_framequeues(usbvision); usbvision->curFrame = NULL; @@ -1130,12 +1129,24 @@ static ssize_t usbvision_v4l2_read(struct file *file, char *buf, if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL)) return -EFAULT; - /* no stream is running, make it running ! */ - usbvision->streaming = Stream_On; - call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL); + /* This entry point is compatible with the mmap routines so that a user can do either + VIDIOC_QBUF/VIDIOC_DQBUF to get frames or call read on the device. */ + if(!usbvision->num_frames) { + /* First, allocate some frames to work with if this has not been done with + VIDIOC_REQBUF */ + usbvision_frames_free(usbvision); + usbvision_empty_framequeues(usbvision); + usbvision_frames_alloc(usbvision,USBVISION_NUMFRAMES); + } + + if(usbvision->streaming != Stream_On) { + /* no stream is running, make it running ! */ + usbvision->streaming = Stream_On; + call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL); + } - /* First, enqueue as many frames as possible (like a user of VIDIOC_QBUF would do) */ - for(i=0;inum_frames;i++) { frame = &usbvision->frame[i]; if(frame->grabstate == FrameState_Unused) { /* Mark it as ready and enqueue frame */ @@ -1212,6 +1223,8 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) struct video_device *dev = video_devdata(file); struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); + PDEBUG(DBG_MMAP, "mmap"); + down(&usbvision->lock); if (!USBVISION_IS_OPERATIONAL(usbvision)) { @@ -1220,16 +1233,16 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) } if (!(vma->vm_flags & VM_WRITE) || - size != PAGE_ALIGN(usbvision->curwidth*usbvision->curheight*usbvision->palette.bytes_per_pixel)) { + size != PAGE_ALIGN(usbvision->max_frame_size)) { up(&usbvision->lock); return -EINVAL; } - for (i = 0; i < USBVISION_NUMFRAMES; i++) { - if (((usbvision->max_frame_size*i) >> PAGE_SHIFT) == vma->vm_pgoff) + for (i = 0; i < usbvision->num_frames; i++) { + if (((PAGE_ALIGN(usbvision->max_frame_size)*i) >> PAGE_SHIFT) == vma->vm_pgoff) break; } - if (i == USBVISION_NUMFRAMES) { + if (i == usbvision->num_frames) { PDEBUG(DBG_MMAP, "mmap: user supplied mapping address is out of range"); up(&usbvision->lock); return -EINVAL; diff --git a/linux/drivers/media/video/usbvision/usbvision.h b/linux/drivers/media/video/usbvision/usbvision.h index 04ef1a062..0376b0b0f 100644 --- a/linux/drivers/media/video/usbvision/usbvision.h +++ b/linux/drivers/media/video/usbvision/usbvision.h @@ -425,6 +425,7 @@ struct usb_usbvision { wait_queue_head_t wait_stream; /* Processes waiting */ struct usbvision_frame *curFrame; // pointer to current frame, set by usbvision_find_header struct usbvision_frame frame[USBVISION_NUMFRAMES]; // frame buffer + int num_frames; // number of frames allocated struct usbvision_sbuf sbuf[USBVISION_NUMSBUF]; // S buffering volatile int remove_pending; /* If set then about to exit */ @@ -515,7 +516,7 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg); int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg, unsigned char value); -int usbvision_frames_alloc(struct usb_usbvision *usbvision); +int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames); void usbvision_frames_free(struct usb_usbvision *usbvision); int usbvision_scratch_alloc(struct usb_usbvision *usbvision); void usbvision_scratch_free(struct usb_usbvision *usbvision); -- cgit v1.2.3 From 27f3314c1778f6156b14b46271691acf379a9ae6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 7 Feb 2007 11:14:38 -0200 Subject: Usbvision: set alternate interface modification From: Thierry MERLE - usb alternate selection modified to get the biggest endpoint packet size. - fix sysfs get values for brightness/contrast/hue/saturation Signed-off-by: Thierry MERLE Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/usbvision/Kconfig | 2 +- .../drivers/media/video/usbvision/usbvision-core.c | 33 ++++++++++-- .../media/video/usbvision/usbvision-video.c | 58 ++++++++++++++++++---- linux/drivers/media/video/usbvision/usbvision.h | 7 ++- 4 files changed, 83 insertions(+), 17 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/usbvision/Kconfig b/linux/drivers/media/video/usbvision/Kconfig index fc24ef05b..c43a5d899 100644 --- a/linux/drivers/media/video/usbvision/Kconfig +++ b/linux/drivers/media/video/usbvision/Kconfig @@ -1,6 +1,6 @@ config VIDEO_USBVISION tristate "USB video devices based on Nogatech NT1003/1004/1005" - depends on I2C && VIDEO_V4L2 + depends on I2C && VIDEO_V4L2 && USB select VIDEO_TUNER select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO ---help--- diff --git a/linux/drivers/media/video/usbvision/usbvision-core.c b/linux/drivers/media/video/usbvision/usbvision-core.c index 0671b309e..54b9ce08e 100644 --- a/linux/drivers/media/video/usbvision/usbvision-core.c +++ b/linux/drivers/media/video/usbvision/usbvision-core.c @@ -2442,6 +2442,32 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format) return USBVISION_IS_OPERATIONAL(usbvision); } +int usbvision_set_alternate(struct usb_usbvision *dev) +{ + int errCode, prev_alt = dev->ifaceAlt; + int i; + + dev->ifaceAlt=0; + for(i=0;i< dev->num_alt; i++) + if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->ifaceAlt]) + dev->ifaceAlt=i; + + if (dev->ifaceAlt != prev_alt) { + dev->isocPacketSize = dev->alt_max_pkt_size[dev->ifaceAlt]; + PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize); + errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt); + if (errCode < 0) { + err ("cannot change alternate number to %d (error=%i)", + dev->ifaceAlt, errCode); + return errCode; + } + } + + PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isocPacketSize); + + return 0; +} + /* * usbvision_init_isoc() * @@ -2459,15 +2485,13 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) scratch_reset(usbvision); /* Alternate interface 1 is is the biggest frame size */ - errCode = usb_set_interface(dev, usbvision->iface, usbvision->ifaceAltActive); + errCode = usbvision_set_alternate(usbvision); if (errCode < 0) { usbvision->last_error = errCode; return -EBUSY; } regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F; - usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1; - PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize); usbvision->usb_bandwidth = regValue >> 1; PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth); @@ -2594,8 +2618,9 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) if (!usbvision->remove_pending) { /* Set packet size to 0 */ + usbvision->ifaceAlt=0; errCode = usb_set_interface(usbvision->dev, usbvision->iface, - usbvision->ifaceAltInactive); + usbvision->ifaceAlt); if (errCode < 0) { err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode); usbvision->last_error = errCode; diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index 8d32c44ed..e49064de8 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -241,7 +241,7 @@ static ssize_t show_hue(struct class_device *cd, char *buf) ctrl.value = 0; if(usbvision->user) call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); - return sprintf(buf, "%d\n", ctrl.value >> 8); + return sprintf(buf, "%d\n", ctrl.value); } static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); @@ -254,7 +254,7 @@ static ssize_t show_contrast(struct class_device *cd, char *buf) ctrl.value = 0; if(usbvision->user) call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); - return sprintf(buf, "%d\n", ctrl.value >> 8); + return sprintf(buf, "%d\n", ctrl.value); } static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); @@ -267,7 +267,7 @@ static ssize_t show_brightness(struct class_device *cd, char *buf) ctrl.value = 0; if(usbvision->user) call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); - return sprintf(buf, "%d\n", ctrl.value >> 8); + return sprintf(buf, "%d\n", ctrl.value); } static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); @@ -280,7 +280,7 @@ static ssize_t show_saturation(struct class_device *cd, char *buf) ctrl.value = 0; if(usbvision->user) call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl); - return sprintf(buf, "%d\n", ctrl.value >> 8); + return sprintf(buf, "%d\n", ctrl.value); } static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); @@ -817,8 +817,8 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_G_CTRL: { struct v4l2_control *ctrl = arg; - PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value); call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); + PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value); return 0; } case VIDIOC_S_CTRL: @@ -1317,6 +1317,13 @@ static int usbvision_radio_open(struct inode *inode, struct file *file) } } + /* Alternate interface 1 is is the biggest frame size */ + errCode = usbvision_set_alternate(usbvision); + if (errCode < 0) { + usbvision->last_error = errCode; + return -EBUSY; + } + // If so far no errors then we shall start the radio usbvision->radio = 1; call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type); @@ -1357,6 +1364,11 @@ static int usbvision_radio_close(struct inode *inode, struct file *file) down(&usbvision->lock); + /* Set packet size to 0 */ + usbvision->ifaceAlt=0; + errCode = usb_set_interface(usbvision->dev, usbvision->iface, + usbvision->ifaceAlt); + usbvision_audio_off(usbvision); usbvision->radio=0; usbvision->user--; @@ -1951,16 +1963,18 @@ static void *usbvision_probe(struct usb_device *dev, unsigned int ifnum, #else static int __devinit usbvision_probe(struct usb_interface *intf, const struct usb_device_id *devid) { - struct usb_device *dev = interface_to_usbdev(intf); + struct usb_device *dev = usb_get_dev(interface_to_usbdev(intf)); + struct usb_interface *uif; __u8 ifnum = intf->altsetting->desc.bInterfaceNumber; const struct usb_host_interface *interface; #endif struct usb_usbvision *usbvision = NULL; const struct usb_endpoint_descriptor *endpoint; - int model; + int model,i; PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); + /* Is it an USBVISION video dev? */ model = 0; for(model = 0; usbvision_device_data[model].idVendor; model++) { @@ -1989,7 +2003,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) { err("%s: USBVision interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum); - err("%s: USBVision Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes); + err("%s: USBVision Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes); return NULL; } if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { @@ -1999,6 +2013,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us MOD_INC_USE_COUNT; + /* Allocate the usbvision device structure so that we can set some variables */ if ((usbvision = usbvision_alloc(dev)) == NULL) { err("%s: couldn't allocate USBVision struct", __FUNCTION__); MOD_DEC_USE_COUNT; @@ -2017,7 +2032,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us endpoint = &interface->endpoint[1].desc; if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) { err("%s: interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum); - err("%s: Endpoint attribures %d", __FUNCTION__, endpoint->bmAttributes); + err("%s: Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes); return -ENODEV; } if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { @@ -2045,6 +2060,28 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us down(&usbvision->lock); + /* compute alternate max packet sizes */ + uif = dev->actconfig->interface[0]; + + usbvision->num_alt=uif->num_altsetting; + PDEBUG(DBG_PROBE, "Alternate settings: %i",usbvision->num_alt); + usbvision->alt_max_pkt_size = kmalloc(32* + usbvision->num_alt,GFP_KERNEL); + if (usbvision->alt_max_pkt_size == NULL) { + err("usbvision: out of memory!\n"); + return -ENOMEM; + } + + for (i = 0; i < usbvision->num_alt ; i++) { + u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. + wMaxPacketSize); + usbvision->alt_max_pkt_size[i] = + (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); + PDEBUG(DBG_PROBE, "Alternate setting %i, max size= %i",i, + usbvision->alt_max_pkt_size[i]); + } + + usbvision->nr = usbvision_nr++; usbvision->have_tuner = usbvision_device_data[model].Tuner; @@ -2057,8 +2094,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us usbvision->DevModel = model; usbvision->remove_pending = 0; usbvision->iface = ifnum; - usbvision->ifaceAltInactive = 0; - usbvision->ifaceAltActive = 1; + usbvision->ifaceAlt = 0; usbvision->video_endp = endpoint->bEndpointAddress; usbvision->isocPacketSize = 0; usbvision->usb_bandwidth = 0; diff --git a/linux/drivers/media/video/usbvision/usbvision.h b/linux/drivers/media/video/usbvision/usbvision.h index 0376b0b0f..bee7d06bc 100644 --- a/linux/drivers/media/video/usbvision/usbvision.h +++ b/linux/drivers/media/video/usbvision/usbvision.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -396,8 +397,11 @@ struct usb_usbvision { /* Device structure */ struct usb_device *dev; + /* usb transfer */ + int num_alt; /* Number of alternative settings */ + unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ unsigned char iface; /* Video interface number */ - unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */ + unsigned char ifaceAlt; /* Alt settings */ unsigned char Vin_Reg2_Preset; struct semaphore lock; struct timer_list powerOffTimer; @@ -527,6 +531,7 @@ int usbvision_setup(struct usb_usbvision *usbvision,int format); int usbvision_init_isoc(struct usb_usbvision *usbvision); int usbvision_restart_isoc(struct usb_usbvision *usbvision); void usbvision_stop_isoc(struct usb_usbvision *usbvision); +int usbvision_set_alternate(struct usb_usbvision *dev); int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel); int usbvision_audio_off(struct usb_usbvision *usbvision); -- cgit v1.2.3 From 16038adbfd2d767838c091b2513a1bcfb0272859 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 7 Feb 2007 19:33:08 -0200 Subject: CodingStyle cleanups From: Ahmed S. Darwish After commited at the tree, Ahmed re-sent his patch with some codingstyle cleanups. This diff-patch will be folded with the first one at -git. Signed-off-by: Ahmed S. Darwish Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c | 2 +- linux/drivers/media/dvb/frontends/cx24110.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 43ba7cadb..de7701f0f 100644 --- a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -215,7 +215,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend freq = 2150000; /* satellite IF is 950..2150MHz */ /* decide which VCO to use for the input frequency */ - for(i=1;(ibands[i]);i++) + for(i = 0; (i < ARRAY_SIZE(bands)) && (srate>bands[i]); i++) ; /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz, and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult, @@ -361,7 +361,7 @@ static int cx24110_initfe(struct dvb_frontend* fe) dprintk("%s: init chip\n", __FUNCTION__); - for(i=0;i Date: Wed, 7 Feb 2007 22:48:57 -0600 Subject: pvrusb2: Fix printk format typo From: Mike Isely Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index b46316fb3..edca79f87 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -273,7 +273,7 @@ static int pvr2_encoder_cmd(void *ctxt, PVR2_TRACE_ERROR_LEGS, "***WARNING*** device's encoder" " appears to be stuck" - " (status=0%08x)",rdData[0]); + " (status=0x%08x)",rdData[0]); } pvr2_trace( PVR2_TRACE_ERROR_LEGS, -- cgit v1.2.3 From 089ee87c9105e3e8e9fa7e429e909b4d2d53e912 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 7 Feb 2007 22:50:30 -0600 Subject: pvrusb2: Follow coding style convention for "#if 0" blocks From: Mike Isely Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index edca79f87..fb0a9ca67 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -362,7 +362,7 @@ int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) int ret = 0; int encMisc3Arg = 0; -#if 0 +#if 0 /* keep */ /* This inexplicable bit happens in the Hauppage windows driver (for both 24xxx and 29xxx devices). However I currently see no difference in behavior with or without @@ -384,7 +384,7 @@ int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) breaks up for a moment (like when switching channels). */ -#if 0 +#if 0 /* keep */ /* This ENC_MISC(5,0) command seems to hurt 29xxx sync performance on channel changes, but is not a problem on 24xxx devices. */ @@ -406,7 +406,7 @@ int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0); -#if 0 +#if 0 /* keep */ /* This ENC_MISC(4,1) command is poisonous, so it is commented out. But I'm leaving it here anyway to document its existence in the Windows driver. The effect of this -- cgit v1.2.3 From 7ffd80e0bf37ad9003d52fe6170a1b81fd224b26 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 7 Feb 2007 23:02:53 -0600 Subject: pvrusb2: Be more forgiving about encoder firmware size From: Mike Isely The pvrusb2 driver previously rejected encoder firmware whose size was not a multiple of 8192. But this is a false check because it's possible to find cx23416 firmware whose size doesn't conform to this limit. So change the firmware loader implementation to be more forgiving of the image size. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 33 ++++++++++++++----------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 06a840a47..d80136377 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1219,7 +1219,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) { const struct firmware *fw_entry = NULL; void *fw_ptr; - unsigned int pipe, fw_len, fw_done; + unsigned int pipe, fw_len, fw_done, bcnt, icnt; int actual_length; int ret = 0; int fwidx; @@ -1275,11 +1275,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) fw_len = fw_entry->size; - if (fw_len % FIRMWARE_CHUNK_SIZE) { + if (fw_len % sizeof(u32)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "size of %s firmware" - " must be a multiple of 8192B", - fw_files[fwidx]); + " must be a multiple of %u bytes", + fw_files[fwidx],sizeof(u32)); release_firmware(fw_entry); return -1; } @@ -1294,18 +1294,21 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT); - for (fw_done = 0 ; (fw_done < fw_len) && !ret ; - fw_done += FIRMWARE_CHUNK_SIZE ) { - int i; - memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE); - /* Usbsnoop log shows that we must swap bytes... */ - for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++) - ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]); - - ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr, - FIRMWARE_CHUNK_SIZE, + fw_done = 0; + for (fw_done = 0; fw_done < fw_len;) { + bcnt = fw_len - fw_done; + if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE; + 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]); + + ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, &actual_length, HZ); - ret |= (actual_length != FIRMWARE_CHUNK_SIZE); + ret |= (actual_length != bcnt); + if (ret) break; + fw_done += bcnt; } trace_firmware("upload of %s : %i / %i ", -- cgit v1.2.3 From 67966b941b963c8db2bdd6a59445d473c04db968 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Wed, 7 Feb 2007 23:04:36 -0600 Subject: pvrusb2: Register I2C adapter (more) correctly From: Mike Isely An I2C adapter needs to register an association with the actual parent device. Until 2.6.20, not doing this was a benign problem; now it causes an ugly warning in the system log. This 1-line patch corrects that oversight. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 05c39d25f..215fbf473 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -1090,6 +1090,7 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap)); memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo)); strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name)); + hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) strlcpy(hdw->i2c_algo.name,hdw->name,sizeof(hdw->i2c_algo.name)); #endif -- cgit v1.2.3 From d1bc6812d76b02a59a3f18a6511610e747915e8b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Feb 2007 15:32:43 -0200 Subject: kthread API conversion for dvb_frontend and av7110 From: Herbert Poetzl dvb kernel_thread to kthread API port. It is running fine here, including module load/unload and software suspend (which doesn't work as expected with or without this patch :). I didn't convert the dvb_ca_en50221 as I do not have such an interface, but if the conversion process is fine with the v4l-dvb maintainers, it should not be a problem to send a patch for that too ... Signed-off-by: Herbert Poetzl Signed-off-by: Andrew Morton Acked-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 69 +++++++++---------------- linux/drivers/media/dvb/ttpci/av7110.c | 29 +++++------ linux/drivers/media/dvb/ttpci/av7110.h | 1 - 3 files changed, 37 insertions(+), 62 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index fc65d9a25..283830bb7 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -41,6 +41,7 @@ #include #endif #include +#include #include #include "dvb_frontend.h" @@ -105,7 +106,7 @@ struct dvb_frontend_private { struct semaphore sem; struct list_head list_head; wait_queue_head_t wait_queue; - pid_t thread_pid; + struct task_struct *thread; unsigned long release_jiffies; unsigned int exit; unsigned int wakeup; @@ -513,19 +514,11 @@ static int dvb_frontend_thread(void *data) struct dvb_frontend *fe = data; struct dvb_frontend_private *fepriv = fe->frontend_priv; unsigned long timeout; - char name [15]; fe_status_t s; struct dvb_frontend_parameters *params; dprintk("%s\n", __FUNCTION__); - snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num); - - lock_kernel(); - daemonize(name); - sigfillset(¤t->blocked); - unlock_kernel(); - fepriv->check_wrapped = 0; fepriv->quality = 0; fepriv->delay = 3*HZ; @@ -539,15 +532,17 @@ static int dvb_frontend_thread(void *data) up(&fepriv->sem); /* is locked when we enter the thread... */ timeout = wait_event_interruptible_timeout(fepriv->wait_queue, - dvb_frontend_should_wakeup(fe), - fepriv->delay); - if (0 != dvb_frontend_is_exiting(fe)) { + dvb_frontend_should_wakeup(fe) || kthread_should_stop(), + fepriv->delay); + + if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { /* got signal or quitting */ break; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) - try_to_freeze(); + if (try_to_freeze()) + continue; #else if (current->flags & PF_FREEZE) { refrigerator (PF_FREEZE); @@ -602,7 +597,7 @@ static int dvb_frontend_thread(void *data) fe->ops.sleep(fe); } - fepriv->thread_pid = 0; + fepriv->thread = NULL; mb(); dvb_frontend_wakeup(fe); @@ -611,7 +606,6 @@ static int dvb_frontend_thread(void *data) static void dvb_frontend_stop(struct dvb_frontend *fe) { - unsigned long ret; struct dvb_frontend_private *fepriv = fe->frontend_priv; dprintk ("%s\n", __FUNCTION__); @@ -619,33 +613,17 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) fepriv->exit = 1; mb(); - if (!fepriv->thread_pid) + if (!fepriv->thread) return; - /* check if the thread is really alive */ - if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) { - printk("dvb_frontend_stop: thread PID %d already died\n", - fepriv->thread_pid); - /* make sure the mutex was not held by the thread */ - init_MUTEX (&fepriv->sem); - return; - } - - /* wake up the frontend thread, so it notices that fe->exit == 1 */ - dvb_frontend_wakeup(fe); - - /* wait until the frontend thread has exited */ - ret = wait_event_interruptible(fepriv->wait_queue,0 == fepriv->thread_pid); - if (-ERESTARTSYS != ret) { - fepriv->state = FESTATE_IDLE; - return; - } + kthread_stop(fepriv->thread); + init_MUTEX (&fepriv->sem); fepriv->state = FESTATE_IDLE; /* paranoia check in case a signal arrived */ - if (fepriv->thread_pid) - printk("dvb_frontend_stop: warning: thread PID %d won't exit\n", - fepriv->thread_pid); + if (fepriv->thread) + printk("dvb_frontend_stop: warning: thread %p won't exit\n", + fepriv->thread); } s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime) @@ -695,10 +673,11 @@ static int dvb_frontend_start(struct dvb_frontend *fe) { int ret; struct dvb_frontend_private *fepriv = fe->frontend_priv; + struct task_struct *fe_thread; dprintk ("%s\n", __FUNCTION__); - if (fepriv->thread_pid) { + if (fepriv->thread) { if (!fepriv->exit) return 0; else @@ -712,18 +691,18 @@ static int dvb_frontend_start(struct dvb_frontend *fe) fepriv->state = FESTATE_IDLE; fepriv->exit = 0; - fepriv->thread_pid = 0; + fepriv->thread = NULL; mb(); - ret = kernel_thread (dvb_frontend_thread, fe, 0); - - if (ret < 0) { - printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret); + fe_thread = kthread_run(dvb_frontend_thread, fe, + "kdvb-fe-%i", fe->dvb->num); + if (IS_ERR(fe_thread)) { + ret = PTR_ERR(fe_thread); + printk("dvb_frontend_start: failed to start kthread (%d)\n", ret); up(&fepriv->sem); return ret; } - fepriv->thread_pid = ret; - + fepriv->thread = fe_thread; return 0; } diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 8440fd655..04c442286 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -51,6 +51,7 @@ #include #include #include +#include #include @@ -223,11 +224,10 @@ static void recover_arm(struct av7110 *av7110) static void av7110_arm_sync(struct av7110 *av7110) { - av7110->arm_rmmod = 1; - wake_up_interruptible(&av7110->arm_wait); + if (av7110->arm_thread) + kthread_stop(av7110->arm_thread); - while (av7110->arm_thread) - msleep(1); + av7110->arm_thread = NULL; } static int arm_thread(void *data) @@ -238,17 +238,11 @@ static int arm_thread(void *data) dprintk(4, "%p\n",av7110); - lock_kernel(); - daemonize("arm_mon"); - sigfillset(¤t->blocked); - unlock_kernel(); - - av7110->arm_thread = current; - for (;;) { timeout = wait_event_interruptible_timeout(av7110->arm_wait, - av7110->arm_rmmod, 5 * HZ); - if (-ERESTARTSYS == timeout || av7110->arm_rmmod) { + kthread_should_stop(), 5 * HZ); + + if (-ERESTARTSYS == timeout || kthread_should_stop()) { /* got signal or told to quit*/ break; } @@ -276,7 +270,6 @@ static int arm_thread(void *data) av7110->arm_errors = 0; } - av7110->arm_thread = NULL; return 0; } @@ -2338,6 +2331,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, const int length = TS_WIDTH * TS_HEIGHT; struct pci_dev *pdev = dev->pci; struct av7110 *av7110; + struct task_struct *thread; int ret, count = 0; dprintk(4, "dev: %p\n", dev); @@ -2622,9 +2616,12 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. " "System might be unstable!\n", FW_VERSION(av7110->arm_app)); - ret = kernel_thread(arm_thread, (void *) av7110, 0); - if (ret < 0) + thread = kthread_run(arm_thread, (void *) av7110, "arm_mon"); + if (IS_ERR(thread)) { + ret = PTR_ERR(thread); goto err_stop_arm_9; + } + av7110->arm_thread = thread; /* set initial volume in mixer struct */ av7110->mixer.volume_left = volume; diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h index 5fcdaa402..cfec01b36 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.h +++ b/linux/drivers/media/dvb/ttpci/av7110.h @@ -220,7 +220,6 @@ struct av7110 { struct task_struct *arm_thread; wait_queue_head_t arm_wait; u16 arm_loops; - int arm_rmmod; void *debi_virt; dma_addr_t debi_bus; -- cgit v1.2.3 From bd9e31ab6498eb6f6ca6d3310aee24d406f82082 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Feb 2007 15:36:57 -0200 Subject: kthread api conversion for dvb_frontend and av7110 fix From: akpm@linux-foundation.org avoid double-up(), pointed out by Oliver. Signed-off-by: Andrew Morton Acked-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 283830bb7..f39e3504d 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -530,7 +530,7 @@ static int dvb_frontend_thread(void *data) while (1) { up(&fepriv->sem); /* is locked when we enter the thread... */ - +restart: timeout = wait_event_interruptible_timeout(fepriv->wait_queue, dvb_frontend_should_wakeup(fe) || kthread_should_stop(), fepriv->delay); @@ -542,7 +542,7 @@ static int dvb_frontend_thread(void *data) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) if (try_to_freeze()) - continue; + goto restart; #else if (current->flags & PF_FREEZE) { refrigerator (PF_FREEZE); -- cgit v1.2.3 From 637cf08abf2ad06f3fde39c829238ffafe036151 Mon Sep 17 00:00:00 2001 From: Chris Pascoe Date: Sat, 10 Feb 2007 11:17:57 -0200 Subject: Experimental support for zl10353 signal strength/BER/uncorrectable count From: Chris Pascoe After studying many hours worth of register dumps of MT352 and ZL10353 fed with identically damaged RF signals I have made an educated guess at which registers contain the AGC level, bit error rate and uncorrectable error count values. Implement the IOCTLs that return these values to userspace. Signed-off-by: Chris Pascoe --- linux/drivers/media/dvb/frontends/zl10353.c | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index c05f2c0e1..d7e3d807f 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -217,6 +217,29 @@ static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status) return 0; } +static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct zl10353_state *state = fe->demodulator_priv; + + *ber = zl10353_read_register(state, 0x11) << 16 | + zl10353_read_register(state, 0x12) << 8 | + zl10353_read_register(state, 0x13); + + return 0; +} + +static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct zl10353_state *state = fe->demodulator_priv; + + u16 signal = zl10353_read_register(state, 0x0a) << 10 | + zl10353_read_register(state, 0x0b) << 2 | 3; + + *strength = ~signal; + + return 0; +} + static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) { struct zl10353_state *state = fe->demodulator_priv; @@ -233,6 +256,16 @@ static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) return 0; } +static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct zl10353_state *state = fe->demodulator_priv; + + *ucblocks = zl10353_read_register(state, 0x14) << 8 | + zl10353_read_register(state, 0x15); + + return 0; +} + static int zl10353_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *fe_tune_settings) @@ -335,7 +368,10 @@ static struct dvb_frontend_ops zl10353_ops = { .get_tune_settings = zl10353_get_tune_settings, .read_status = zl10353_read_status, + .read_ber = zl10353_read_ber, + .read_signal_strength = zl10353_read_signal_strength, .read_snr = zl10353_read_snr, + .read_ucblocks = zl10353_read_ucblocks, }; #if 1 -- cgit v1.2.3 From fa24f03ffa4270665b8176fa306b84962cc78b74 Mon Sep 17 00:00:00 2001 From: Chris Pascoe Date: Sat, 10 Feb 2007 11:19:08 -0200 Subject: zl10353: add i2c_gate_ctrl support From: Antti Palosaari Implement I2C gate control for Megasky GL861 and SigmaTek AU6610 support. Signed-off-by: Chris Pascoe Signed-off-by: Antti Palosaari --- linux/drivers/media/dvb/frontends/zl10353.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index d7e3d807f..ac6b13e47 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -146,14 +146,16 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, zl10353_single_write(fe, 0x66, 0xE9); zl10353_single_write(fe, 0x6C, 0xCD); zl10353_single_write(fe, 0x6D, 0x7E); - zl10353_single_write(fe, 0x62, 0x0A); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); // if there is no attached secondary tuner, we call set_params to program // a potential tuner attached somewhere else if (state->config.no_tuner) { if (fe->ops.tuner_ops.set_params) { fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); } } @@ -304,6 +306,16 @@ static int zl10353_init(struct dvb_frontend *fe) return 0; } +static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) +{ + u8 val = 0x0a; + + if (enable) + val |= 0x10; + + return zl10353_single_write(fe, 0x62, val); +} + static void zl10353_release(struct dvb_frontend *fe) { struct zl10353_state *state = fe->demodulator_priv; @@ -362,6 +374,7 @@ static struct dvb_frontend_ops zl10353_ops = { .init = zl10353_init, .sleep = zl10353_sleep, + .i2c_gate_ctrl = zl10353_i2c_gate_ctrl, .write = zl10353_write, .set_frontend = zl10353_set_parameters, -- cgit v1.2.3 From a45e480ff17686d2396e05141c3dc110eac44152 Mon Sep 17 00:00:00 2001 From: Chris Pascoe Date: Sat, 10 Feb 2007 11:19:11 -0200 Subject: zl10353: Implement TRL nominal rate calculation From: Antti Palosaari Implement trl nominal rate calculation to Zarlink ZL10353 demod, based on calculation used in Zarlink MT352. This adds support for 6 and 8MHz bandwidth transponders. Signed-off-by: Antti Palosaari Signed-off-by: Chris Pascoe --- linux/drivers/media/dvb/frontends/zl10353.c | 48 ++++++++++++++++++++++-- linux/drivers/media/dvb/frontends/zl10353.h | 3 ++ linux/drivers/media/dvb/frontends/zl10353_priv.h | 29 ++++++++------ 3 files changed, 65 insertions(+), 15 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index ac6b13e47..2cee1c143 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -38,6 +38,12 @@ struct zl10353_state { struct zl10353_config config; }; +static int debug; +#define dprintk(args...) \ + do { \ + if (debug) printk(KERN_DEBUG "zl10353: " args); \ + } while (0) + #if 1 static int debug_regs = 0; #endif @@ -117,6 +123,36 @@ static void zl10353_dump_regs(struct dvb_frontend *fe) } #endif +static void zl10353_calc_nominal_rate(struct dvb_frontend *fe, + enum fe_bandwidth bandwidth, + u16 *nominal_rate) +{ + u32 adc_clock = 22528; /* 20.480 MHz on the board(!?) */ + u8 bw; + struct zl10353_state *state = fe->demodulator_priv; + + if (state->config.adc_clock) + adc_clock = state->config.adc_clock; + + switch (bandwidth) { + case BANDWIDTH_6_MHZ: + bw = 6; + break; + case BANDWIDTH_7_MHZ: + bw = 7; + break; + case BANDWIDTH_8_MHZ: + default: + bw = 8; + break; + } + + *nominal_rate = (64 * bw * (1<<16) / (7 * 8) * 4000 / adc_clock + 2) / 4; + + dprintk("%s: bw %d, adc_clock %d => 0x%x\n", + __FUNCTION__, bw, adc_clock, *nominal_rate); +} + static int zl10353_sleep(struct dvb_frontend *fe) { static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 }; @@ -129,7 +165,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { struct zl10353_state *state = fe->demodulator_priv; - + u16 nominal_rate; u8 pllbuf[6] = { 0x67 }; /* These settings set "auto-everything" and start the FSM. */ @@ -142,8 +178,11 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, zl10353_single_write(fe, 0x56, 0x28); zl10353_single_write(fe, 0x89, 0x20); zl10353_single_write(fe, 0x5E, 0x00); - zl10353_single_write(fe, 0x65, 0x5A); - zl10353_single_write(fe, 0x66, 0xE9); + + zl10353_calc_nominal_rate(fe, param->u.ofdm.bandwidth, &nominal_rate); + zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate)); + zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate)); + zl10353_single_write(fe, 0x6C, 0xCD); zl10353_single_write(fe, 0x6D, 0x7E); if (fe->ops.i2c_gate_ctrl) @@ -387,6 +426,9 @@ static struct dvb_frontend_ops zl10353_ops = { .read_ucblocks = zl10353_read_ucblocks, }; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + #if 1 module_param(debug_regs, int, 0644); MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off)."); diff --git a/linux/drivers/media/dvb/frontends/zl10353.h b/linux/drivers/media/dvb/frontends/zl10353.h index 0bc010973..cb274dc12 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.h +++ b/linux/drivers/media/dvb/frontends/zl10353.h @@ -29,6 +29,9 @@ struct zl10353_config /* demodulator's I2C address */ u8 demod_address; + /* frequencies in kHz */ + int adc_clock; // default: 22528 + /* set if no pll is connected to the secondary i2c bus */ int no_tuner; diff --git a/linux/drivers/media/dvb/frontends/zl10353_priv.h b/linux/drivers/media/dvb/frontends/zl10353_priv.h index b72224bd7..d2186927f 100644 --- a/linux/drivers/media/dvb/frontends/zl10353_priv.h +++ b/linux/drivers/media/dvb/frontends/zl10353_priv.h @@ -24,19 +24,24 @@ #define ID_ZL10353 0x14 +#define msb(x) (((x) >> 8) & 0xff) +#define lsb(x) ((x) & 0xff) + enum zl10353_reg_addr { - INTERRUPT_0 = 0x00, - INTERRUPT_1 = 0x01, - INTERRUPT_2 = 0x02, - INTERRUPT_3 = 0x03, - INTERRUPT_4 = 0x04, - INTERRUPT_5 = 0x05, - STATUS_6 = 0x06, - STATUS_7 = 0x07, - STATUS_8 = 0x08, - STATUS_9 = 0x09, - SNR = 0x10, - CHIP_ID = 0x7F, + INTERRUPT_0 = 0x00, + INTERRUPT_1 = 0x01, + INTERRUPT_2 = 0x02, + INTERRUPT_3 = 0x03, + INTERRUPT_4 = 0x04, + INTERRUPT_5 = 0x05, + STATUS_6 = 0x06, + STATUS_7 = 0x07, + STATUS_8 = 0x08, + STATUS_9 = 0x09, + SNR = 0x10, + TRL_NOMINAL_RATE_1 = 0x65, + TRL_NOMINAL_RATE_0 = 0x66, + CHIP_ID = 0x7F, }; #endif /* _ZL10353_PRIV_ */ -- cgit v1.2.3 From 90c4407a4023f4e54f115280d745512e8419ddf4 Mon Sep 17 00:00:00 2001 From: Chris Pascoe Date: Sat, 10 Feb 2007 11:19:16 -0200 Subject: zl10353: register definitions update From: Chris Pascoe Update the descriptions of "discovered" registers on the zl10353, using the equivalaent mt352 register names. Signed-off-by: Chris Pascoe --- linux/drivers/media/dvb/frontends/zl10353.c | 14 +++++++------- linux/drivers/media/dvb/frontends/zl10353_priv.h | 7 +++++++ 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index 2cee1c143..be9f858b7 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -262,9 +262,9 @@ static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber) { struct zl10353_state *state = fe->demodulator_priv; - *ber = zl10353_read_register(state, 0x11) << 16 | - zl10353_read_register(state, 0x12) << 8 | - zl10353_read_register(state, 0x13); + *ber = zl10353_read_register(state, RS_ERR_CNT_2) << 16 | + zl10353_read_register(state, RS_ERR_CNT_1) << 8 | + zl10353_read_register(state, RS_ERR_CNT_0); return 0; } @@ -273,8 +273,8 @@ static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct zl10353_state *state = fe->demodulator_priv; - u16 signal = zl10353_read_register(state, 0x0a) << 10 | - zl10353_read_register(state, 0x0b) << 2 | 3; + u16 signal = zl10353_read_register(state, AGC_GAIN_1) << 10 | + zl10353_read_register(state, AGC_GAIN_0) << 2 | 3; *strength = ~signal; @@ -301,8 +301,8 @@ static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct zl10353_state *state = fe->demodulator_priv; - *ucblocks = zl10353_read_register(state, 0x14) << 8 | - zl10353_read_register(state, 0x15); + *ucblocks = zl10353_read_register(state, RS_UBC_1) << 8 | + zl10353_read_register(state, RS_UBC_0); return 0; } diff --git a/linux/drivers/media/dvb/frontends/zl10353_priv.h b/linux/drivers/media/dvb/frontends/zl10353_priv.h index d2186927f..4962434b3 100644 --- a/linux/drivers/media/dvb/frontends/zl10353_priv.h +++ b/linux/drivers/media/dvb/frontends/zl10353_priv.h @@ -38,7 +38,14 @@ enum zl10353_reg_addr { STATUS_7 = 0x07, STATUS_8 = 0x08, STATUS_9 = 0x09, + AGC_GAIN_1 = 0x0A, + AGC_GAIN_0 = 0x0B, SNR = 0x10, + RS_ERR_CNT_2 = 0x11, + RS_ERR_CNT_1 = 0x12, + RS_ERR_CNT_0 = 0x13, + RS_UBC_1 = 0x14, + RS_UBC_0 = 0x15, TRL_NOMINAL_RATE_1 = 0x65, TRL_NOMINAL_RATE_0 = 0x66, CHIP_ID = 0x7F, -- cgit v1.2.3 From b992a5329b3e48767b3bbfbc0ade73f9f560a552 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 12 Feb 2007 18:05:57 -0200 Subject: Backport header fix from kernel From: Mauro Carvalho Chehab kernel-sync: Original patch from Al Viro usbvision missing __user Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/usbvision/usbvision-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c index e49064de8..1d0d61469 100644 --- a/linux/drivers/media/video/usbvision/usbvision-video.c +++ b/linux/drivers/media/video/usbvision/usbvision-video.c @@ -1112,7 +1112,7 @@ static long usbvision_v4l2_read(struct video_device *dev, char *buf, { struct usb_usbvision *usbvision = (struct usb_usbvision *) dev; #else -static ssize_t usbvision_v4l2_read(struct file *file, char *buf, +static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct video_device *dev = video_devdata(file); -- cgit v1.2.3 From 0173038bafb808d93f88b3f0b043696b04cc2ded Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 13 Feb 2007 07:00:55 -0200 Subject: Backport: removal of duplicated symbol From: Mauro Carvalho Chehab kernel-sync: As pointed by Al Viro, ir_codes_pinnacle_grey had already defined KEY_RECORD on position 0x27. Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/ir-keymaps.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index 43b4aece3..78cdc2d2e 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -699,7 +699,6 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { [ 0x29 ] = KEY_TEXT, [ 0x2a ] = KEY_MEDIA, [ 0x18 ] = KEY_EPG, - [ 0x27 ] = KEY_RECORD, }; EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey); -- cgit v1.2.3 From cd02f1c774cfec232d5db61834ddf960bcac0713 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Tue, 13 Feb 2007 13:31:07 +0100 Subject: dvb-ttpci: use i2c gate ctrl from stv0297 frontend driver From: Marco Schluessler Use i2c gate ctrl from stv0297 frontend driver. Signed-off-by: Marco Schluessler Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/av7110_v4l.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/ttpci/av7110_v4l.c b/linux/drivers/media/dvb/ttpci/av7110_v4l.c index 0510a80f2..3795432ad 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/linux/drivers/media/dvb/ttpci/av7110_v4l.c @@ -141,17 +141,6 @@ static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data) return 0; } -static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data) -{ - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 }; - - if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) - return -1; - return 0; -} - - static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4]) { struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 }; @@ -194,6 +183,7 @@ static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq) static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq) { + struct av7110 *av7110 = (struct av7110*)dev->ext_priv; u32 div; u8 data[4]; @@ -214,8 +204,8 @@ static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq) else return -EINVAL; - stv0297_writereg(dev, 0x1C, 0x87, 0x78); - stv0297_writereg(dev, 0x1C, 0x86, 0xc8); + if (av7110->fe->ops.i2c_gate_ctrl) + av7110->fe->ops.i2c_gate_ctrl(av7110->fe, 1); return tuner_write(dev, 0x63, data); } -- cgit v1.2.3 From 0e9bb1fbb3ec45410ffcea8ffe3f883f7a5b5f0d Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Tue, 13 Feb 2007 13:39:58 +0100 Subject: budget-ci: IR handling fixups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: David Härdeman Changeset 6562d27de0d7 by Oliver Endriss changed the budget-ci driver to use interrupt mode for i2c transfers. This also meant that a new bunch of IR bytes that were previously lost are now received, which allowed me to better understand how the MSP430 chip works. Unfortunately it also means that the current driver gets some assumptions wrong and might generate double keypresses for one IR command. The attached patch fixes this by throwing away the repeat bytes and by associating the correct command and device bytes. Signed-off-by: David Härdeman Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/ttpci/budget-ci.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index f86ba0010..7cb60e37b 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -130,6 +130,7 @@ static void msp430_ir_interrupt(unsigned long data) int toggle; static int prev_toggle = -1; static u32 ir_key; + static int state = 0; u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; /* @@ -138,21 +139,34 @@ static void msp430_ir_interrupt(unsigned long data) * type1: X1CCCCCC, C = command bits (0 - 63) * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit * - * More than one command byte may be generated before the device byte - * Only when we have both, a correct keypress is generated + * Each signal from the remote control can generate one or more command + * bytes and one or more device bytes. For the repeated bytes, the + * highest bit (X) is set. The first command byte is always generated + * before the first device byte. Other than that, no specific order + * seems to apply. + * + * Only when we have a command and device byte, a keypress is + * generated. */ + if (ir_debug) + printk("budget_ci: received byte 0x%02x\n", command); + + /* Is this a repeated byte? */ + if (command & 0x80) + return; + /* Is this a RC5 command byte? */ if (command & 0x40) { - if (ir_debug) - printk("budget_ci: received command byte 0x%02x\n", command); + state = 1; ir_key = command & 0x3f; return; } /* It's a RC5 device byte */ - if (ir_debug) - printk("budget_ci: received device byte 0x%02x\n", command); + if (!state) + return; + state = 0; device = command & 0x1f; toggle = command & 0x20; -- cgit v1.2.3 From 9178eac040383ea6cd91d6a58aab3fc598aecf77 Mon Sep 17 00:00:00 2001 From: Marcel Siegert Date: Tue, 13 Feb 2007 13:46:55 +0100 Subject: dvbdev: fix illegal re-usage of fileoperations struct From: Marcel Siegert Arjan van de Ven reported an illegal re-usage of the fileoperations struct if more than one dvb device(e.g. frontend) is present. this patch fixes this issue. it allocates a new fileoperations struct each time a device is registered and copies the default template fileops. Signed-off-by: Marcel Siegert --- linux/drivers/media/dvb/dvb-core/dvbdev.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 498b1e1be..4035f8efa 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -211,12 +211,14 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, const struct dvb_device *template, void *priv, int type) { struct dvb_device *dvbdev; + struct file_operations *dvbdevfops; + int id; if (mutex_lock_interruptible(&dvbdev_register_lock)) return -ERESTARTSYS; - if ((id = dvbdev_get_free_id (adap, type)) < 0) { + if ((id = dvbdev_get_free_id (adap, type)) < 0){ mutex_unlock(&dvbdev_register_lock); *pdvbdev = NULL; printk ("%s: could get find free device id...\n", __FUNCTION__); @@ -225,7 +227,15 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL); - if (!dvbdev) { + if (!dvbdev){ + mutex_unlock(&dvbdev_register_lock); + return -ENOMEM; + } + + dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL); + + if (!dvbdevfops){ + kfree (dvbdev); mutex_unlock(&dvbdev_register_lock); return -ENOMEM; } @@ -235,7 +245,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvbdev->id = id; dvbdev->adapter = adap; dvbdev->priv = priv; + dvbdev->fops = dvbdevfops; + memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); dvbdev->fops->owner = adap->module; list_add_tail (&dvbdev->list_head, &adap->device_list); @@ -263,6 +275,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev) dvbdev->type, dvbdev->id))); list_del (&dvbdev->list_head); + kfree (dvbdev->fops); kfree (dvbdev); } EXPORT_SYMBOL(dvb_unregister_device); -- cgit v1.2.3 From 20d8868b63eaf291899c3de7da4d51d27a9d814d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 13 Feb 2007 14:46:13 -0500 Subject: qt1010: fix compiler warning From: Marco Schluessler In function 'qt1010_init': warning: 'err' might be used uninitialized in this function Signed-off-by: Marco Schluessler Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/qt1010.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/qt1010.c b/linux/drivers/media/dvb/frontends/qt1010.c index db93776ce..0b9ba0639 100644 --- a/linux/drivers/media/dvb/frontends/qt1010.c +++ b/linux/drivers/media/dvb/frontends/qt1010.c @@ -312,7 +312,7 @@ static int qt1010_init(struct dvb_frontend *fe) { struct qt1010_priv *priv = fe->tuner_priv; struct dvb_frontend_parameters params; - int err; + int err = 0; u8 i, tmpval, *valptr = NULL; qt1010_i2c_oper_t i2c_data[] = { -- cgit v1.2.3 From 317ece2780f0dd285881ab8cd703bc0759f58b58 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 13 Feb 2007 15:53:46 -0500 Subject: qt1010: use ARRAY_SIZE macro when appropriate From: Michael Krufky Use ARRAY_SIZE macro already defined in kernel.h Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/qt1010.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/qt1010.c b/linux/drivers/media/dvb/frontends/qt1010.c index 0b9ba0639..128ffa39e 100644 --- a/linux/drivers/media/dvb/frontends/qt1010.c +++ b/linux/drivers/media/dvb/frontends/qt1010.c @@ -233,7 +233,7 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \ rd[40].val, rd[41].val, rd[43].val, rd[45].val); - for (i = 0; i < sizeof(rd) / sizeof(*rd); i++) { + for (i = 0; i < ARRAY_SIZE(rd); i++) { if (rd[i].oper == QT1010_WR) { err = qt1010_writereg(priv, rd[i].reg, rd[i].val); } else { /* read is required to proper locking */ @@ -263,7 +263,7 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_i { QT1010_RD, reg, 0xff } }; - for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { if (i2c_data[i].oper == QT1010_WR) { err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); } else { @@ -296,7 +296,7 @@ static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retva { QT1010_WR, 0x1e, 0x00 }, { QT1010_WR, 0x22, 0xff } }; - for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { if (i2c_data[i].oper == QT1010_WR) { err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); } else { @@ -355,7 +355,7 @@ static int qt1010_init(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ - for (i = 0; i < sizeof(i2c_data) / sizeof(*i2c_data); i++) { + for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { switch (i2c_data[i].oper) { case QT1010_WR: err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); -- cgit v1.2.3 From efdf3d14b32ace1c65033b4b82ecfe05d8e59a2a Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Tue, 13 Feb 2007 22:01:56 +0100 Subject: stv0297: Enable BER/UNC counting From: Hartmut Birr Enable BER/UNC counting for the stv0297 frontend. The idea for this patch comes from stv0297_cs.c. Signed-off-by: Hartmut Birr Signed-off-by: Oliver Endriss --- linux/drivers/media/dvb/frontends/stv0297.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/stv0297.c b/linux/drivers/media/dvb/frontends/stv0297.c index 2f45fff3a..96f85b2a5 100644 --- a/linux/drivers/media/dvb/frontends/stv0297.c +++ b/linux/drivers/media/dvb/frontends/stv0297.c @@ -35,6 +35,7 @@ struct stv0297_state { const struct stv0297_config *config; struct dvb_frontend frontend; + unsigned long last_ber; unsigned long base_freq; }; @@ -310,6 +311,8 @@ static int stv0297_init(struct dvb_frontend *fe) stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); msleep(200); + state->last_ber = 0; + return 0; } @@ -340,11 +343,13 @@ static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) struct stv0297_state *state = fe->demodulator_priv; u8 BER[3]; - stv0297_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes - mdelay(25); // Hopefully got 4096 Bytes stv0297_readregs(state, 0xA0, BER, 3); - mdelay(25); - *ber = (BER[2] << 8 | BER[1]) / (8 * 4096); + if (!(BER[0] & 0x80)) { + state->last_ber = BER[2] << 8 | BER[1]; + stv0297_writereg_mask(state, 0xA0, 0x80, 0x80); + } + + *ber = state->last_ber; return 0; } @@ -376,9 +381,14 @@ static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) { struct stv0297_state *state = fe->demodulator_priv; + stv0297_writereg_mask(state, 0xDF, 0x03, 0x03); /* freeze the counters */ + *ucblocks = (stv0297_readreg(state, 0xD5) << 8) | stv0297_readreg(state, 0xD4); + stv0297_writereg_mask(state, 0xDF, 0x03, 0x02); /* clear the counters */ + stv0297_writereg_mask(state, 0xDF, 0x03, 0x01); /* re-enable the counters */ + return 0; } @@ -648,6 +658,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, /* setup the state */ state->config = config; state->i2c = i2c; + state->last_ber = 0; state->base_freq = 0; /* check if the demod is there */ -- cgit v1.2.3 From 9e17f31052de3afbff0bb6ba7217d73f9b920ba9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 13 Feb 2007 16:26:26 -0500 Subject: qt1010: whitespace / 80 column cleanups From: Michael Krufky Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/frontends/qt1010.c | 69 +++++++++++++++++++----------- 1 file changed, 44 insertions(+), 25 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/dvb/frontends/qt1010.c b/linux/drivers/media/dvb/frontends/qt1010.c index 128ffa39e..6ad39074e 100644 --- a/linux/drivers/media/dvb/frontends/qt1010.c +++ b/linux/drivers/media/dvb/frontends/qt1010.c @@ -25,14 +25,19 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); -#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "QT1010: " args); printk("\n"); }} while (0) +#define dprintk(args...) \ + do { \ + if (debug) printk(KERN_DEBUG "QT1010: " args); \ + } while (0) /* read single register */ static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val) { struct i2c_msg msg[2] = { - { .addr = priv->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 }, + { .addr = priv->cfg->i2c_address, + .flags = 0, .buf = ®, .len = 1 }, + { .addr = priv->cfg->i2c_address, + .flags = I2C_M_RD, .buf = val, .len = 1 }, }; if (i2c_transfer(priv->i2c, msg, 2) != 2) { @@ -46,9 +51,8 @@ static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val) static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val) { u8 buf[2] = { reg, val }; - struct i2c_msg msg = { - .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2 - }; + struct i2c_msg msg = { .addr = priv->cfg->i2c_address, + .flags = 0, .buf = buf, .len = 2 }; if (i2c_transfer(priv->i2c, &msg, 1) != 1) { printk(KERN_WARNING "qt1010 I2C write failed\n"); @@ -80,7 +84,8 @@ static void qt1010_dump_regs(struct qt1010_priv *priv) printk("%s\n", buf); } -static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int qt1010_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) { struct qt1010_priv *priv; int err; @@ -146,7 +151,8 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame freq = (div * QT1010_STEP) - QT1010_OFFSET; mod1 = (freq + QT1010_OFFSET) % FREQ1; mod2 = (freq + QT1010_OFFSET) % FREQ2; - priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; + priv->bandwidth = + (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; priv->frequency = freq; if (fe->ops.i2c_gate_ctrl) @@ -227,8 +233,9 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame /* 00 */ rd[45].val = 0x92; /* TODO: correct value calculation */ - dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x 1a:%02x 11:%02x " \ - "12:%02x 22:%02x 05:%02x 1f:%02x 20:%02x 25:%02x 00:%02x", \ + dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \ + "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \ + "20:%02x 25:%02x 00:%02x", \ freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \ rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \ rd[40].val, rd[41].val, rd[43].val, rd[45].val); @@ -251,7 +258,8 @@ static int qt1010_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame return 0; } -static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_init_val, u8 *retval) +static int qt1010_init_meas1(struct qt1010_priv *priv, + u8 oper, u8 reg, u8 reg_init_val, u8 *retval) { u8 i, val1, val2; int err; @@ -265,7 +273,8 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_i for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { if (i2c_data[i].oper == QT1010_WR) { - err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + err = qt1010_writereg(priv, i2c_data[i].reg, + i2c_data[i].val); } else { err = qt1010_readreg(priv, i2c_data[i].reg, &val2); } @@ -283,7 +292,8 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_i return qt1010_writereg(priv, 0x1e, 0x00); } -static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retval) +static u8 qt1010_init_meas2(struct qt1010_priv *priv, + u8 reg_init_val, u8 *retval) { u8 i, val; int err; @@ -298,7 +308,8 @@ static u8 qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retva }; for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { if (i2c_data[i].oper == QT1010_WR) { - err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + err = qt1010_writereg(priv, i2c_data[i].reg, + i2c_data[i].val); } else { err = qt1010_readreg(priv, i2c_data[i].reg, &val); } @@ -358,19 +369,26 @@ static int qt1010_init(struct dvb_frontend *fe) for (i = 0; i < ARRAY_SIZE(i2c_data); i++) { switch (i2c_data[i].oper) { case QT1010_WR: - err = qt1010_writereg(priv, i2c_data[i].reg, i2c_data[i].val); + err = qt1010_writereg(priv, i2c_data[i].reg, + i2c_data[i].val); break; case QT1010_RD: - if (i2c_data[i].val == 0x20) valptr = &priv->reg20_init_val; - else valptr = &tmpval; + if (i2c_data[i].val == 0x20) + valptr = &priv->reg20_init_val; + else + valptr = &tmpval; err = qt1010_readreg(priv, i2c_data[i].reg, valptr); break; case QT1010_M1: - if (i2c_data[i].val == 0x25) valptr = &priv->reg25_init_val; - else if (i2c_data[i].val == 0x1f) valptr = &priv->reg1f_init_val; - else valptr = &tmpval; - err = qt1010_init_meas1(priv, i2c_data[i+1].reg, i2c_data[i].reg, - i2c_data[i].val, valptr); + if (i2c_data[i].val == 0x25) + valptr = &priv->reg25_init_val; + else if (i2c_data[i].val == 0x1f) + valptr = &priv->reg1f_init_val; + else + valptr = &tmpval; + err = qt1010_init_meas1(priv, i2c_data[i+1].reg, + i2c_data[i].reg, + i2c_data[i].val, valptr); i++; break; } @@ -435,8 +453,8 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, if (priv == NULL) return NULL; - priv->cfg = cfg; - priv->i2c = i2c; + priv->cfg = cfg; + priv->i2c = i2c; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ @@ -455,7 +473,8 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ printk(KERN_INFO "Quantek QT1010 successfully identified.\n"); - memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops, sizeof(struct dvb_tuner_ops)); + memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops, + sizeof(struct dvb_tuner_ops)); fe->tuner_priv = priv; return fe; -- cgit v1.2.3 From 37a0fae25a0ca580206640b2b019182a3800e6a6 Mon Sep 17 00:00:00 2001 From: Marcel Siegert Date: Tue, 13 Feb 2007 22:44:49 +0100 Subject: fix compiler warning in vivi.c From: Marcel Siegert the result of copy_to_user was not used, so the compiler complained now a warning will be issued if copy_to_user fails Signed-off-by: Marcel Siegert --- linux/drivers/media/video/vivi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 1756ff277..798e711f4 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -468,7 +468,8 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) if (buf->vb.dma.varea) { gen_line(tmpbuf,0,wmax,hmax,h,dev->timestr); /* FIXME: replacing to __copy_to_user */ - copy_to_user(buf->vb.dma.varea+pos,tmpbuf,wmax*2); + if (copy_to_user(buf->vb.dma.varea+pos,tmpbuf,wmax*2)!=0) + dprintk(2,"vivifill copy_to_user failed.\n"); } else { gen_line(tmpbuf,pos,wmax,hmax,h,dev->timestr); } -- cgit v1.2.3 From 576a4462214a9b98c55dd518697ebd0c07f6ea37 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 15 Feb 2007 07:40:34 +0100 Subject: Fix cx25840 firmware loading. From: Hans Verkuil Due to changes in the i2c handling in 2.6.20 this cx25840 bug surfaced, causing the firmware load to fail for the ivtv driver. The correct sequence is to first attach the i2c client, then use the client's device to load the firmware. Signed-off-by: Hans Verkuil Acked-by: Mike Isely --- linux/drivers/media/video/cx25840/cx25840-core.c | 4 ++-- linux/drivers/media/video/cx25840/cx25840-firmware.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers') diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index a1a4907af..fc1e7da7c 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -924,13 +924,13 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, state->vbi_line_offset = 8; state->id = id; + i2c_attach_client(client); + if (state->is_cx25836) cx25836_initialize(client); else cx25840_initialize(client, 1); - i2c_attach_client(client); - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) MOD_INC_USE_COUNT; #endif diff --git a/linux/drivers/media/video/cx25840/cx25840-firmware.c b/linux/drivers/media/video/cx25840/cx25840-firmware.c index e14e0bc1f..1b730b155 100644 --- a/linux/drivers/media/video/cx25840/cx25840-firmware.c +++ b/linux/drivers/media/video/cx25840/cx25840-firmware.c @@ -39,7 +39,7 @@ #define FWSEND 48 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) -#define FWDEV(x) &((x)->adapter->dev) +#define FWDEV(x) &((x)->dev) #else #define FWDEV(x) (x)->name #endif -- cgit v1.2.3