From 2c53b88064110d742bdc97cc928fc83aadcc69c6 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 28 Apr 2007 18:00:18 -0500 Subject: pvrusb2: use mutex instead of semaphore From: Matthias Kaehlcke the pvrusb2 driver use a semaphore as mutex. use the mutex API instead of the (binary) semaphore Signed-off-by: Matthias Kaehlcke Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 1a08edac2..52078f4d0 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -84,7 +84,7 @@ static struct pvr2_string_table pvr2_client_lists[] = { }; static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL}; -static DECLARE_MUTEX(pvr2_unit_sem); +static DEFINE_MUTEX(pvr2_unit_mtx); static int ctlchg = 0; static int initusbreset = 1; @@ -2103,14 +2103,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL); if (!hdw->ctl_read_urb) goto fail; - down(&pvr2_unit_sem); do { + mutex_lock(&pvr2_unit_mtx); do { for (idx = 0; idx < PVR_NUM; idx++) { if (unit_pointers[idx]) continue; hdw->unit_number = idx; unit_pointers[idx] = hdw; break; } - } while (0); up(&pvr2_unit_sem); + } while (0); mutex_unlock(&pvr2_unit_mtx); cnt1 = 0; cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); @@ -2213,13 +2213,13 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) } pvr2_i2c_core_done(hdw); pvr2_hdw_remove_usb_stuff(hdw); - down(&pvr2_unit_sem); do { + mutex_lock(&pvr2_unit_mtx); do { if ((hdw->unit_number >= 0) && (hdw->unit_number < PVR_NUM) && (unit_pointers[hdw->unit_number] == hdw)) { unit_pointers[hdw->unit_number] = NULL; } - } while (0); up(&pvr2_unit_sem); + } while (0); mutex_unlock(&pvr2_unit_mtx); kfree(hdw->controls); kfree(hdw->mpeg_ctrl_info); kfree(hdw->std_defs); -- cgit v1.2.3 From d4f778181491264d5a7fab04d2304a38011f8876 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 28 Apr 2007 18:04:48 -0500 Subject: pvrusb2: kill unnecessary attribute->owner From: Tejun Heo [Mike Isely: This is the pvrusb2 affected part of a much larger patch in the kernel from Tejun Heo] sysfs is now completely out of driver/module lifetime game. After deletion, a sysfs node doesn't access anything outside sysfs proper, so there's no reason to hold onto the attribute owners. Note that often the wrong modules were accounted for as owners leading to accessing removed modules. This patch kills now unnecessary attribute->owner. Note that with this change, userland holding a sysfs node does not prevent the backing module from being unloaded. For more info regarding lifetime rule cleanup, please read the following message. http://article.gmane.org/gmane.linux.kernel/510293 Signed-off-by: Tejun Heo Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index e5b7aeeed..e28cc23ea 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -519,40 +519,32 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) } sfp->item_last = cip; - cip->attr_name.attr.owner = THIS_MODULE; cip->attr_name.attr.name = "name"; cip->attr_name.attr.mode = S_IRUGO; cip->attr_name.show = fp->show_name; - cip->attr_type.attr.owner = THIS_MODULE; cip->attr_type.attr.name = "type"; cip->attr_type.attr.mode = S_IRUGO; cip->attr_type.show = fp->show_type; - cip->attr_min.attr.owner = THIS_MODULE; cip->attr_min.attr.name = "min_val"; cip->attr_min.attr.mode = S_IRUGO; cip->attr_min.show = fp->show_min; - cip->attr_max.attr.owner = THIS_MODULE; cip->attr_max.attr.name = "max_val"; cip->attr_max.attr.mode = S_IRUGO; cip->attr_max.show = fp->show_max; - cip->attr_val.attr.owner = THIS_MODULE; cip->attr_val.attr.name = "cur_val"; cip->attr_val.attr.mode = S_IRUGO; - cip->attr_custom.attr.owner = THIS_MODULE; cip->attr_custom.attr.name = "custom_val"; cip->attr_custom.attr.mode = S_IRUGO; - cip->attr_enum.attr.owner = THIS_MODULE; cip->attr_enum.attr.name = "enum_val"; cip->attr_enum.attr.mode = S_IRUGO; cip->attr_enum.show = fp->show_enum; - cip->attr_bits.attr.owner = THIS_MODULE; cip->attr_bits.attr.name = "bit_val"; cip->attr_bits.attr.mode = S_IRUGO; cip->attr_bits.show = fp->show_bits; @@ -617,12 +609,10 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) dip = kzalloc(sizeof(*dip),GFP_KERNEL); if (!dip) return; - dip->attr_debugcmd.attr.owner = THIS_MODULE; dip->attr_debugcmd.attr.name = "debugcmd"; dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP; dip->attr_debugcmd.show = debugcmd_show; dip->attr_debugcmd.store = debugcmd_store; - dip->attr_debuginfo.attr.owner = THIS_MODULE; dip->attr_debuginfo.attr.name = "debuginfo"; dip->attr_debuginfo.attr.mode = S_IRUGO; dip->attr_debuginfo.show = debuginfo_show; @@ -812,7 +802,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp, return; } - sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE; sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; sfp->attr_v4l_minor_number.show = v4l_minor_number_show; @@ -826,7 +815,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp, sfp->v4l_minor_number_created_ok = !0; } - sfp->attr_v4l_radio_minor_number.attr.owner = THIS_MODULE; sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number"; sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO; sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show; @@ -840,7 +828,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp, sfp->v4l_radio_minor_number_created_ok = !0; } - sfp->attr_unit_number.attr.owner = THIS_MODULE; sfp->attr_unit_number.attr.name = "unit_number"; sfp->attr_unit_number.attr.mode = S_IRUGO; sfp->attr_unit_number.show = unit_number_show; @@ -853,7 +840,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp, sfp->unit_number_created_ok = !0; } - sfp->attr_bus_info.attr.owner = THIS_MODULE; sfp->attr_bus_info.attr.name = "bus_info_str"; sfp->attr_bus_info.attr.mode = S_IRUGO; sfp->attr_bus_info.show = bus_info_show; -- cgit v1.2.3 From ef76e05c4f054b0abe4ef6191adfac147cea7f82 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 28 Apr 2007 18:08:33 -0500 Subject: pvrusb2: Improve handling of PAL-60 video standard From: Mike Isely This patch originated with Servaas Vandenberghe and has been further developed a bit (to preserve saa7115 behavior). These changes allow for correct operation of PAL-60 video (Servaas tested this against a PAL-B/G tuner with the video standard overridden as a module option). Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index a7424f847..4abee970c 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -424,22 +424,29 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) int pvr2_encoder_configure(struct pvr2_hdw *hdw) { int ret; + int val; pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure" " (cx2341x module)"); hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING; hdw->enc_ctl_state.width = hdw->res_hor_val; hdw->enc_ctl_state.height = hdw->res_ver_val; - hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & - (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ? + hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ? 0 : 1); ret = 0; ret |= pvr2_encoder_prep_config(hdw); + /* saa7115: 0xf0 */ + val = 0xf0; + if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { + /* ivtv cx25840: 0x140 */ + val = 0x140; + } + if (!ret) ret = pvr2_encoder_vcmd( hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, - 0xf0, 0xf0); + val, val); /* setup firmware to notify us about some events (don't know why...) */ if (!ret) ret = pvr2_encoder_vcmd( -- cgit v1.2.3 From 7bf5d2440102f97e3ac056b30f29c3eff34ed093 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 28 Apr 2007 18:11:03 -0500 Subject: pvrusb2: Implement ability to disable IR receiver From: Mike Isely Anyone using multiple PVR USB2 devices really only want one of them acting as the actual IR receiver. Implemented here is a new per-instance module option (ir_mode) which is a flag to enable the IR receiver. The default is enabled. IR reception is disabled by blocking access to the IR receiver chip in the device. Signed-off-by: Mike Isely --- .../drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 22a02dd76..1a9563aa5 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -23,6 +23,7 @@ #include "pvrusb2-hdw-internal.h" #include "pvrusb2-debug.h" #include "pvrusb2-fx2-cmd.h" +#include "pvrusb2.h" #include "compat.h" #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) @@ -39,6 +40,10 @@ static unsigned int i2c_scan = 0; module_param(i2c_scan, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); +static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 }; +module_param_array(ir_mode, int, NULL, 0444); +MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); + static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp, unsigned int detail, char *buf,unsigned int maxlen); @@ -348,6 +353,15 @@ static int i2c_hack_wm8775(struct pvr2_hdw *hdw, return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); } +/* This is an entry point designed to always fail any attempt to perform a + transfer. We use this to cause certain I2C addresses to not be + probed. */ +static int i2c_black_hole(struct pvr2_hdw *hdw, + u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) +{ + return -EIO; +} + /* This is a special entry point that is entered if an I2C operation is attempted to a cx25840 chip on model 24xxx hardware. This chip can sometimes wedge itself. Worse still, when this happens msp3400 can @@ -1080,10 +1094,17 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) } /* However, deal with various special cases for 24xxx hardware. */ + if (ir_mode[hdw->unit_number] == 0) { + printk(KERN_INFO "%s: IR disabled\n",hdw->name); + hdw->i2c_func[0x18] = i2c_black_hole; + } else if (ir_mode[hdw->unit_number] == 1) { + if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { + hdw->i2c_func[0x18] = i2c_24xxx_ir; + } + } if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { hdw->i2c_func[0x1b] = i2c_hack_wm8775; hdw->i2c_func[0x44] = i2c_hack_cx25840; - hdw->i2c_func[0x18] = i2c_24xxx_ir; } // Configure the adapter and set up everything else related to it. -- cgit v1.2.3 From e7e951a35230e610d3bebb4e00168ecf8bc47760 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 29 Apr 2007 14:27:30 -0500 Subject: Improve / fix support for PAL-60 in cx25840 From: Servaas Vandenberghe This causes the cx25840 module to treat V4L2_STD_PAL_60 similar to other 60Hz timings, and it fixes a wrongly-named variable (timings are independant of color system). Signed-off-by: Mike Isely Acked-by: Hans Verkuil --- linux/drivers/media/video/cx25840/cx25840-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index c401c1ee7..9d40a2b95 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -566,7 +566,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) { struct v4l2_pix_format *pix; int HSC, VSC, Vsrc, Hsrc, filter, Vlines; - int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); + int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); switch (fmt->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -578,7 +578,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; - Vlines = pix->height + (is_pal ? 4 : 7); + Vlines = pix->height + (is_50Hz ? 4 : 7); if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { -- cgit v1.2.3