From 79c5d3b305af947949689365801773a3aaa38eb9 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:35:33 -0600 Subject: Tweaks to pvrusb2 init sequence From: Mike Isely Rename a pvrusb2 function to reflect its true meaning, and tweak the driver initialization sequence so that the I2C adapter isn't started until after the hardware has been given a powerup command. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c | 2 +- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 11 +++++++---- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index bcfe468eb..f5c267123 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c @@ -362,7 +362,7 @@ int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, } else if (debugifc_match_keyword(wptr,wlen,"bus")) { pvr2_hdw_device_reset(hdw); } else if (debugifc_match_keyword(wptr,wlen,"soft")) { - return pvr2_hdw_cmd_soft_reset(hdw); + return pvr2_hdw_cmd_powerup(hdw); } else if (debugifc_match_keyword(wptr,wlen,"deep")) { return pvr2_hdw_cmd_deep_reset(hdw); } else if (debugifc_match_keyword(wptr,wlen,"firmware")) { diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index b87651e5a..6a729c4c7 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -617,7 +617,6 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) ret = 0; /* First prepare firmware loading */ - ret |= pvr2_hdw_cmd_soft_reset(hdw); ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/ ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/ @@ -1093,7 +1092,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) } if (!pvr2_hdw_dev_ok(hdw)) return; - pvr2_i2c_core_init(hdw); + pvr2_hdw_cmd_powerup(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; if (pvr2_upload_firmware2(hdw)){ @@ -1102,6 +1101,10 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) return; } + // This step MUST happen after the earlier powerup step. + pvr2_i2c_core_init(hdw); + if (!pvr2_hdw_dev_ok(hdw)) return; + for (idx = 0; idx < PVR2_CID_COUNT; idx++) { if (control_defs[idx].skip_init) continue; pvr2_hdw_set_ctl_value_internal( @@ -2405,11 +2408,11 @@ int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) } -int pvr2_hdw_cmd_soft_reset(struct pvr2_hdw *hdw) +int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) { int status; LOCK_TAKE(hdw->ctl_lock); do { - pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc soft reset"); + pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup"); hdw->cmd_buffer[0] = 0xde; status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); } while (0); LOCK_GIVE(hdw->ctl_lock); diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 667c95a27..69ad5e1b1 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -358,7 +358,7 @@ void pvr2_hdw_device_reset(struct pvr2_hdw *); int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *); /* Execute simple reset command */ -int pvr2_hdw_cmd_soft_reset(struct pvr2_hdw *); +int pvr2_hdw_cmd_powerup(struct pvr2_hdw *); /* Stop / start video stream transport */ int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); -- cgit v1.2.3 From 099cf0ca3267af67d3db7c4587001e7f5a3877b3 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:36:18 -0600 Subject: Use hex for printing I2C addresses in pvrusb2 From: Mike Isely Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (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 8ec637e5e..35224c678 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -88,7 +88,7 @@ static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ } } #if 0 - trace_i2c("i2c_write(%d) len=%d ret=%d stat=%d",i2c_addr,length,ret, + trace_i2c("i2c_write(0x%x) len=%d ret=%d stat=%d",i2c_addr,length,ret, hdw->cmd_buffer[0]); #endif @@ -146,7 +146,7 @@ static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ } #if 0 - trace_i2c("i2c_read(%d) wlen=%d rlen=%d ret=%d stat=%d", + trace_i2c("i2c_read(0x%x) wlen=%d rlen=%d ret=%d stat=%d", i2c_addr,dlen,rlen,ret,hdw->cmd_buffer[0]); #endif /* Copy back the result */ -- cgit v1.2.3 From 251aaed52d08d4fc485802f3a800c53de5a945ba Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:37:07 -0600 Subject: Fix screwed up indentation in pvrusb2-sysfs.c From: Mike Isely Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 88 +++++++++++------------ 1 file changed, 44 insertions(+), 44 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 a9710b52c..f82fd643c 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -364,50 +364,50 @@ CREATE_STORE_INSTANCE(store_val_int,ctl_id) \ CREATE_STORE_INSTANCE(store_val_enum,ctl_id) CREATE_BATCH(0) - CREATE_BATCH(1) - CREATE_BATCH(2) - CREATE_BATCH(3) - CREATE_BATCH(4) - CREATE_BATCH(5) - CREATE_BATCH(6) - CREATE_BATCH(7) - CREATE_BATCH(8) - CREATE_BATCH(9) - CREATE_BATCH(10) - CREATE_BATCH(11) - CREATE_BATCH(12) - CREATE_BATCH(13) - CREATE_BATCH(14) - CREATE_BATCH(15) - CREATE_BATCH(16) - CREATE_BATCH(17) - CREATE_BATCH(18) - CREATE_BATCH(19) - CREATE_BATCH(20) - CREATE_BATCH(21) - CREATE_BATCH(22) - CREATE_BATCH(23) - CREATE_BATCH(24) - CREATE_BATCH(25) - CREATE_BATCH(26) - CREATE_BATCH(27) - CREATE_BATCH(28) - CREATE_BATCH(29) - CREATE_BATCH(30) - CREATE_BATCH(31) - - struct pvr2_sysfs_func_set { - ssize_t (*show_name)(struct class_device *,char *); - ssize_t (*show_min)(struct class_device *,char *); - ssize_t (*show_max)(struct class_device *,char *); - ssize_t (*show_enum)(struct class_device *,char *); - ssize_t (*show_val_int)(struct class_device *,char *); - ssize_t (*show_val_enum)(struct class_device *,char *); - ssize_t (*store_val_int)(struct class_device *, - const char *,size_t); - ssize_t (*store_val_enum)(struct class_device *, - const char *,size_t); - }; +CREATE_BATCH(1) +CREATE_BATCH(2) +CREATE_BATCH(3) +CREATE_BATCH(4) +CREATE_BATCH(5) +CREATE_BATCH(6) +CREATE_BATCH(7) +CREATE_BATCH(8) +CREATE_BATCH(9) +CREATE_BATCH(10) +CREATE_BATCH(11) +CREATE_BATCH(12) +CREATE_BATCH(13) +CREATE_BATCH(14) +CREATE_BATCH(15) +CREATE_BATCH(16) +CREATE_BATCH(17) +CREATE_BATCH(18) +CREATE_BATCH(19) +CREATE_BATCH(20) +CREATE_BATCH(21) +CREATE_BATCH(22) +CREATE_BATCH(23) +CREATE_BATCH(24) +CREATE_BATCH(25) +CREATE_BATCH(26) +CREATE_BATCH(27) +CREATE_BATCH(28) +CREATE_BATCH(29) +CREATE_BATCH(30) +CREATE_BATCH(31) + +struct pvr2_sysfs_func_set { + ssize_t (*show_name)(struct class_device *,char *); + ssize_t (*show_min)(struct class_device *,char *); + ssize_t (*show_max)(struct class_device *,char *); + ssize_t (*show_enum)(struct class_device *,char *); + ssize_t (*show_val_int)(struct class_device *,char *); + ssize_t (*show_val_enum)(struct class_device *,char *); + ssize_t (*store_val_int)(struct class_device *, + const char *,size_t); + ssize_t (*store_val_enum)(struct class_device *, + const char *,size_t); +}; #define INIT_BATCH(ctl_id) \ [ctl_id] = { \ -- cgit v1.2.3 From acea6b43b12c290328f857fa981b2c8b3d598b45 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:37:54 -0600 Subject: Fix pvrusb2 compilation warning when building for amd64 From: Mike Isely Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 2 +- 1 file changed, 1 insertion(+), 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 35224c678..a89f3574f 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -56,7 +56,7 @@ static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ "Killing an I2C write to %u that is too large" " (desired=%u limit=%u)", i2c_addr, - length,(sizeof(hdw->cmd_buffer) - 3)); + length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3)); return -ENOTSUPP; } -- cgit v1.2.3 From 22184ee779d37f2c64b08ea427d939f0e2d58b37 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:40:16 -0600 Subject: Implement method in pvrusb2 to force the decoder to reset From: Mike Isely This change threads logic through the pvrusb2 to make it possible to command the decoder chip to reset itself. The method is decoder-agnostic; the part of the pvrusb2 which control's that chip's module has to provide the final hook. This just lays the foundation. Signed-off-by: Mike Isely --- .../drivers/media/video/pvrusb2/pvrusb2-debugifc.c | 2 ++ .../media/video/pvrusb2/pvrusb2-hdw-internal.h | 1 + linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 21 +++++++++++++++++++++ linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h | 3 +++ 4 files changed, 27 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index f5c267123..16e6ea317 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c @@ -367,6 +367,8 @@ int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, return pvr2_hdw_cmd_deep_reset(hdw); } else if (debugifc_match_keyword(wptr,wlen,"firmware")) { return pvr2_upload_firmware2(hdw); + } else if (debugifc_match_keyword(wptr,wlen,"decoder")) { + return pvr2_hdw_cmd_decoder_reset(hdw); } return -EINVAL; } else if (debugifc_match_keyword(wptr,wlen,"subsys_flags")) { diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index 1b161773b..05e44385b 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -74,6 +74,7 @@ struct pvr2_decoder_ctrl { void (*detach)(void *); void (*enable)(void *,int); int (*tuned)(void *); + void (*force_reset)(void *); }; #define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */ diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 6a729c4c7..16757a8fb 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2420,6 +2420,27 @@ int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) } +int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) +{ + if (!hdw->decoder_ctrl) { + pvr2_trace(PVR2_TRACE_INIT, + "Unable to reset decoder: nothing attached"); + return -ENOTTY; + } + + if (!hdw->decoder_ctrl->force_reset) { + pvr2_trace(PVR2_TRACE_INIT, + "Unable to reset decoder: not implemented"); + return -ENOTTY; + } + + pvr2_trace(PVR2_TRACE_INIT, + "Requesting decoder reset"); + hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt); + return 0; +} + + int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) { int status; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 69ad5e1b1..cf5231ee9 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -360,6 +360,9 @@ int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *); /* Execute simple reset command */ int pvr2_hdw_cmd_powerup(struct pvr2_hdw *); +/* Order decoder to reset */ +int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *); + /* Stop / start video stream transport */ int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); -- cgit v1.2.3 From 6aa6af1e4b4ce66a75dc8b20b4bd6670c4ecd0cf Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:41:46 -0600 Subject: New debug code in pvrusb2 for tracking requests From: Mike Isely Implement pvrusb2 code normally compiled-out which can print useful information about commands issued to the hardware. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 16757a8fb..ed5e81224 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2064,6 +2064,28 @@ int pvr2_send_request_ex(struct pvr2_hdw *hdw, return -EINVAL; } +#if 0 + printk(KERN_INFO "pvrusb2: REQUEST BEGIN writeCnt=%u readCnt=%u", + write_len,read_len); + if (probe_fl) { + printk(" "); + } + for (idx = 0; idx < write_len; idx++) { + if (idx > 5) { + printk(" ..."); + break; + } + if (idx) { + printk(" "); + } else { + printk(" ["); + } + printk("%02x",((unsigned char *)write_data)[idx]); + } + if (write_len) printk("]"); + printk("\n"); +#endif + hdw->cmd_debug_state = 1; if (write_len) { hdw->cmd_debug_code = ((unsigned char *)write_data)[0]; @@ -2233,6 +2255,26 @@ int pvr2_send_request_ex(struct pvr2_hdw *hdw, } done: +#if 0 + printk(KERN_INFO "pvrusb2: REQUEST END status=%d",status); + if (status >= 0) { + for (idx = 0; idx < read_len; idx++) { + if (idx > 5) { + printk(" ..."); + break; + } + if (idx) { + printk(" "); + } else { + printk(" ["); + } + printk("%02x",((unsigned char *)read_data)[idx]); + } + if (read_len) printk("]"); + } + printk("\n"); +#endif + hdw->cmd_debug_state = 0; if ((status < 0) && (!probe_fl)) { pvr2_hdw_render_useless_unlocked(hdw); -- cgit v1.2.3 From ba27877ce2c324e04a518371da0bf976308a314f Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:43:17 -0600 Subject: Fix pvrusb2 bug which prevented proper operation of tda9887 From: Mike Isely The pvrusb2 driver was not correctly identifying and handling the tda9887 module. This is the bug fix (code had been ifdef'ed out which should not have been). Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c index 2d97653d5..d537e380f 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c @@ -74,13 +74,11 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) return; } } -#ifdef PVR2_ENABLE_DRIVERID_TDA9887 if (id == I2C_DRIVERID_TDA9887) { if (pvr2_i2c_demod_setup(hdw,cp)) { return; } } -#endif } -- cgit v1.2.3 From 23fb60e03b25fa009ed530d83c5cb7463b96bdc9 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:45:28 -0600 Subject: pvrusb2 control commit handling fix From: Mike Isely When a control change is committed to the driver, certain other parts of the driver must be updated to track the change and deal with the effects of that change. Some controls in the driver use a function pointer to implement the commit, however we weren't doing the tracking there and we should have been. This is the fix. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index ed5e81224..231c314f4 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1490,11 +1490,15 @@ int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *hdw,unsigned int ctl_id) int pvr2_hdw_set_ctl_value_internal(struct pvr2_hdw *hdw, unsigned int ctl_id,int value) { + int ret; if (ctl_id >= PVR2_CID_COUNT) return -EINVAL; if (value < control_defs[ctl_id].min_value) return -EINVAL; if (value > control_defs[ctl_id].max_value) return -EINVAL; if (control_defs[ctl_id].set_func) { - return control_defs[ctl_id].set_func(hdw,ctl_id,value); + ret = control_defs[ctl_id].set_func(hdw,ctl_id,value); + pvr2_i2c_core_check_stale(hdw); + pvr2_i2c_core_sync(hdw); + return ret; } else if (control_defs[ctl_id].get_func) { /* If there's no "set" function yet there is still a "get" function, then treat this as a read-only value. */ -- cgit v1.2.3 From 8b44741ac5b22de76954864b0db14a8d4ed5db07 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:47:08 -0600 Subject: Adjust pvrusb2 stream on/off control handling From: Mike Isely Code in pvrusb2 which issues stream on/off commands was previously in a place specific to the saa7115. This change moves that function to a place where it can be used for other things (like controlling a future cx25840). Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c | 7 +++++++ linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h | 2 ++ linux/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c index 69864782b..7721e405e 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c @@ -239,6 +239,13 @@ const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = { }; +void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl) +{ + pvr2_i2c_client_cmd(cp, + (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),0); +} + + /* Stuff for Emacs to see, in order to encourage consistent editing style: *** Local Variables: *** diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h index fa0a3af7e..1666a3287 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h @@ -33,6 +33,8 @@ extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; +void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int); + #endif /* __PVRUSB2_CMD_V4L2_H */ /* diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/linux/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c index d0bc3682b..7078ac3ad 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c @@ -29,6 +29,7 @@ */ #include "pvrusb2-video-v4l.h" +#include "pvrusb2-i2c-cmd-v4l2.h" #include "pvrusb2-hdw-internal.h" @@ -173,8 +174,7 @@ static int decoder_detect(struct pvr2_i2c_client *cp) static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl) { pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl); - pvr2_i2c_client_cmd(ctxt->client, - (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),0); + pvr2_v4l2_cmd_stream(ctxt->client,fl); } -- cgit v1.2.3 From d0b804387be596a0e4ea8177236a9d8126ac3f81 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:48:19 -0600 Subject: Add more trace print for central I2C module commands in pvrusb2 From: Mike Isely This just adds some more trace print to make possible tracking of I2C commands being broadcast to support modules. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (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 a89f3574f..84903ccf5 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -322,15 +322,26 @@ static int pvr2_i2c_core_singleton(struct i2c_client *cp, int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg) { + int stat; if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { char buf[100]; unsigned int cnt; cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, buf,sizeof(buf)); pvr2_trace(PVR2_TRACE_I2C_CMD, - "i2c COMMAND to %.*s",cnt,buf); + "i2c COMMAND (code=%u 0x%x) to %.*s", + cmd,cmd,cnt,buf); } - return pvr2_i2c_core_singleton(cp->client,cmd,arg); + stat = pvr2_i2c_core_singleton(cp->client,cmd,arg); + if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { + char buf[100]; + unsigned int cnt; + cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, + buf,sizeof(buf)); + pvr2_trace(PVR2_TRACE_I2C_CMD, + "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat); + } + return stat; } int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg) -- cgit v1.2.3 From 441ebaf82f5bb501cb77fe2316de11be5d90952e Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:49:23 -0600 Subject: Advertise I2C functionality in pvrusb2 that's friendly to wm8775 From: Mike Isely Adjust pvrusb2 functionality bits so that wm8775 will attach to the adapter. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 2 +- 1 file changed, 1 insertion(+), 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 84903ccf5..2f7946195 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -296,7 +296,7 @@ static int pvr2_i2c_control(struct i2c_adapter *adapter, static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA; } static int pvr2_i2c_core_singleton(struct i2c_client *cp, -- cgit v1.2.3 From 91ae35c1daa731973eb99fd8d422e60a6cb4ea5d Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:53:15 -0600 Subject: Adjust cx23416 operation in pvrusb2 to work with model 24xxx hardware From: Mike Isely This applies some changes to the logic which controls the cx23416 in pvrusb2. This is required in order for newer model 24xxx hardware to operate correctly and is backwards compatible with older hardware. Signed-off-by: Mike Isely --- .../drivers/media/video/pvrusb2/pvrusb2-encoder.c | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 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 97931d3c4..553bd2d7b 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -294,24 +294,25 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) /* set stream output port. */ ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_OUTPUT_PORT, 2, - 0x01, 0x01); + 0x01, 0x02); /* set the Program Index Information. We want I,P,B frames (max 400) */ ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_PGM_INDEX_INFO, 2, 0x07, 0x0190); - /* NOTE : windows driver sends some 0xdc */ - - /* Mike Isely 19-Jun-2005 I've confirmed - that the Windows driver seems to issue these commands, but - right now I have no idea what these do (and neither does - the ivtv driver). But, if I leave them in, then mplayer - goes nuts with xrun errors. So for now we don't do this. - It sure would be nice to know what these are for. */ -#if 0 - ret |= pvr2_write_encoder_vcmd(hdw, 0xdc, 1, 5); - ret |= pvr2_write_encoder_vcmd(hdw, 0xdc, 2, 3, 1); - ret |= pvr2_write_encoder_vcmd(hdw, 0xdc, 1, 8); + /* NOTE : windows driver sends these */ + /* Mike Isely 7-Mar-2006 The windows driver + sends the following commands but if we do the same then + many apps are no longer able to read the video stream. + Leaving these out seems to do no harm at all, so they're + commented out for that reason. */ +#ifdef notdef + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3,1,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0); #endif /* Strange compared to ivtv data. */ -- cgit v1.2.3 From b7be9b51e990f64ff667725533d5403660cbdac1 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 16:55:50 -0600 Subject: Implement operation of cx2584x from within pvrusb2 From: Mike Isely This adds new logic to integrate the pvrusb2 driver with the V4L cx25840 module. Signed-off-by: Mike Isely --- .../media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 276 +++++++++++++++++++++ .../media/video/pvrusb2/pvrusb2-cx2584x-v4l.h | 54 ++++ .../media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c | 6 + 3 files changed, 336 insertions(+) create mode 100644 linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c create mode 100644 linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c new file mode 100644 index 000000000..df1eeefd5 --- /dev/null +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c @@ -0,0 +1,276 @@ +/* + * + * $Id$ + * + * Copyright (C) 2005 Mike Isely + * Copyright (C) 2004 Aurelien Alleaume + * + * 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 + * + */ + +/* + + This source file is specifically designed to interface with the + cx2584x, in kernels 2.6.16 or newer. + +*/ + +#include "pvrusb2-cx2584x-v4l.h" +#include "pvrusb2-video-v4l.h" +#include "pvrusb2-i2c-cmd-v4l2.h" + + +#include "pvrusb2-hdw-internal.h" +#include "pvrusb2-debug.h" +#include +#include +#include +#include +#include + +struct pvr2_v4l_cx2584x { + struct pvr2_i2c_handler handler; + struct pvr2_decoder_ctrl ctrl; + struct pvr2_i2c_client *client; + struct pvr2_hdw *hdw; + unsigned long stale_mask; +}; + + +static void set_input(struct pvr2_v4l_cx2584x *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + struct v4l2_audio inp; + int msk = 0; + + int v = 0; + + switch(hdw->controls[PVR2_CID_INPUT].value) { + case PVR2_CVAL_INPUT_TV: + msk = (8 << 16) | 7; + break; + case PVR2_CVAL_INPUT_COMPOSITE: + msk = (0 << 16) | 3; + break; + case PVR2_CVAL_INPUT_SVIDEO: + msk = (0 << 16) | 0x510; + break; + case PVR2_CVAL_INPUT_RADIO: + msk = 0; /* FIXME: Need to figure out radio */ + break; + default: + break; + } + + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input(val=%d msk=0x%x)", + hdw->controls[PVR2_CID_INPUT].value,msk); + + v = msk & 0x0000ffffu; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x S_INPUT val=0x%x",v); + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_INPUT,&v); + v = (msk >> 16) & 0x0000ffffu; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x S_AUDIO val=0x%x",v); + memset(&inp,0,sizeof(inp)); + inp.index = v; + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_AUDIO,&inp); +} + + +static int check_input(struct pvr2_v4l_cx2584x *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + return hdw->controls[PVR2_CID_INPUT].dirty != 0; +} + + +static void set_audio(struct pvr2_v4l_cx2584x *ctxt) +{ + u32 val; + struct pvr2_hdw *hdw = ctxt->hdw; + + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d", + hdw->controls[PVR2_CID_SRATE].value); + switch (hdw->controls[PVR2_CID_SRATE].value) { + default: + case PVR2_CVAL_SRATE_48: + val = 48000; + break; + case PVR2_CVAL_SRATE_44_1: + val = 44100; + break; + } + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); +} + + +static int check_audio(struct pvr2_v4l_cx2584x *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + return hdw->controls[PVR2_CID_SRATE].dirty != 0; +} + + +struct pvr2_v4l_cx2584x_ops { + void (*update)(struct pvr2_v4l_cx2584x *); + int (*check)(struct pvr2_v4l_cx2584x *); +}; + + +static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = { + { .update = set_input, .check = check_input}, + { .update = set_audio, .check = check_audio}, +}; + + +static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt) +{ + ctxt->client->handler = 0; + ctxt->hdw->decoder_ctrl = 0; + kfree(ctxt); +} + + +static int decoder_check(struct pvr2_v4l_cx2584x *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); + idx++) { + msk = 1 << idx; + if (ctxt->stale_mask & msk) continue; + if (decoder_ops[idx].check(ctxt)) { + ctxt->stale_mask |= msk; + } + } + return ctxt->stale_mask != 0; +} + + +static void decoder_update(struct pvr2_v4l_cx2584x *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); + idx++) { + msk = 1 << idx; + if (!(ctxt->stale_mask & msk)) continue; + ctxt->stale_mask &= ~msk; + decoder_ops[idx].update(ctxt); + } +} + + +static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl) +{ + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl); + pvr2_v4l2_cmd_stream(ctxt->client,fl); +} + + +static int decoder_detect(struct pvr2_i2c_client *cp) +{ + int ret; + /* Attempt to query the decoder - let's see if it will answer */ + struct v4l2_queryctrl qc; + + memset(&qc,0,sizeof(qc)); + + qc.id = V4L2_CID_BRIGHTNESS; + + ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc); + return ret == 0; /* Return true if it answered */ +} + + +static int decoder_is_tuned(struct pvr2_v4l_cx2584x *ctxt) +{ + struct v4l2_tuner vt; + int ret; + + memset(&vt,0,sizeof(vt)); + ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); + if (ret < 0) return -EINVAL; + return vt.signal ? 1 : 0; +} + + +static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt, + char *buf,unsigned int cnt) +{ + return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l"); +} + + +static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt) +{ + int ret; + ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0); + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret); +} + + +const static struct pvr2_i2c_handler_functions hfuncs = { + .detach = (void (*)(void *))decoder_detach, + .check = (int (*)(void *))decoder_check, + .update = (void (*)(void *))decoder_update, + .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, +}; + + +int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw, + struct pvr2_i2c_client *cp) +{ + struct pvr2_v4l_cx2584x *ctxt; + + if (hdw->decoder_ctrl) return 0; + if (cp->handler) return 0; + if (!decoder_detect(cp)) return 0; + + ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); + if (!ctxt) return 0; + memset(ctxt,0,sizeof(*ctxt)); + + ctxt->handler.func_data = ctxt; + ctxt->handler.func_table = &hfuncs; + ctxt->ctrl.ctxt = ctxt; + ctxt->ctrl.detach = (void (*)(void *))decoder_detach; + ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; + ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned; + ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset; + ctxt->client = cp; + ctxt->hdw = hdw; + ctxt->stale_mask = (1 << (sizeof(decoder_ops)/ + sizeof(decoder_ops[0]))) - 1; + hdw->decoder_ctrl = &ctxt->ctrl; + cp->handler = &ctxt->handler; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up", + cp->client->addr); + return !0; +} + + + + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 70 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h new file mode 100644 index 000000000..5dea8d7b3 --- /dev/null +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h @@ -0,0 +1,54 @@ +/* + * + * $Id$ + * + * Copyright (C) 2005 Mike Isely + * Copyright (C) 2004 Aurelien Alleaume + * + * 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_CX2584X_V4L_H +#define __PVRUSB2_CX2584X_V4L_H + +/* + + This module connects the pvrusb2 driver to the I2C chip level + driver which handles combined device audio & video processing. + This interface is used internally by the driver; higher level code + should only interact through the interface provided by + pvrusb2-hdw.h. + +*/ + +#include "compat.h" + + +#include "pvrusb2-i2c-core.h" + +int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); + + +#endif /* __PVRUSB2_CX2584X_V4L_H */ + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 70 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c index d537e380f..897e74d42 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c @@ -28,6 +28,7 @@ #include "pvrusb2-tuner.h" #include "pvrusb2-demod.h" #include "pvrusb2-video-v4l.h" +#include "pvrusb2-cx2584x-v4l.h" #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) @@ -69,6 +70,11 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) return; } } + if (id == I2C_DRIVERID_CX25840) { + if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) { + return; + } + } if (id == I2C_DRIVERID_SAA711X) { if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) { return; -- cgit v1.2.3 From b07b47fc9fabe18a4073a47397d4bad39ada93b9 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 17:01:11 -0600 Subject: Integrate pvrusb2 with wm8775 From: Mike Isely Implement new logic in pvrusb2 to operate wm8775, which is needed for new model 24xxx hardware which has a wm8775 inside it (which is used to digitize audio from composite and s-video input). Signed-off-by: Mike Isely --- .../media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c | 6 + linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.c | 171 +++++++++++++++++++++ linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.h | 54 +++++++ 3 files changed, 231 insertions(+) create mode 100644 linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.c create mode 100644 linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.h (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c index 897e74d42..fc9d76792 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c @@ -29,6 +29,7 @@ #include "pvrusb2-demod.h" #include "pvrusb2-video-v4l.h" #include "pvrusb2-cx2584x-v4l.h" +#include "pvrusb2-wm8775.h" #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) @@ -75,6 +76,11 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) return; } } + if (id == I2C_DRIVERID_WM8775) { + if (pvr2_i2c_wm8775_setup(hdw,cp)) { + return; + } + } if (id == I2C_DRIVERID_SAA711X) { if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) { return; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.c new file mode 100644 index 000000000..79334980c --- /dev/null +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.c @@ -0,0 +1,171 @@ +/* + * + * $Id$ + * + * Copyright (C) 2005 Mike Isely + * Copyright (C) 2004 Aurelien Alleaume + * + * 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 + * + */ + +/* + + This source file is specifically designed to interface with the + wm8775. + +*/ + +#include "pvrusb2-wm8775.h" +#include "pvrusb2-i2c-cmd-v4l2.h" + + +#include "pvrusb2-hdw-internal.h" +#include "pvrusb2-debug.h" +#include +#include +#include +#include + +struct pvr2_v4l_wm8775 { + struct pvr2_i2c_handler handler; + struct pvr2_i2c_client *client; + struct pvr2_hdw *hdw; + unsigned long stale_mask; +}; + + +static void set_input(struct pvr2_v4l_wm8775 *ctxt) +{ + struct v4l2_audio inp; + struct pvr2_hdw *hdw = ctxt->hdw; + int msk = 0; + + memset(&inp,0,sizeof(inp)); + + pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d msk=0x%x)", + hdw->controls[PVR2_CID_INPUT].value,msk); + + // Always point to input #1 no matter what + inp.index = 2; + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_AUDIO,&inp); +} + + +static int check_input(struct pvr2_v4l_wm8775 *ctxt) +{ + struct pvr2_hdw *hdw = ctxt->hdw; + return hdw->controls[PVR2_CID_INPUT].dirty != 0; +} + + +struct pvr2_v4l_wm8775_ops { + void (*update)(struct pvr2_v4l_wm8775 *); + int (*check)(struct pvr2_v4l_wm8775 *); +}; + + +static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = { + { .update = set_input, .check = check_input}, +}; + + +static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt, + char *buf,unsigned int cnt) +{ + return scnprintf(buf,cnt,"handler: pvrusb2-wm8775"); +} + + +static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt) +{ + ctxt->client->handler = 0; + kfree(ctxt); +} + + +static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]); + idx++) { + msk = 1 << idx; + if (ctxt->stale_mask & msk) continue; + if (wm8775_ops[idx].check(ctxt)) { + ctxt->stale_mask |= msk; + } + } + return ctxt->stale_mask != 0; +} + + +static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt) +{ + unsigned long msk; + unsigned int idx; + + for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]); + idx++) { + msk = 1 << idx; + if (!(ctxt->stale_mask & msk)) continue; + ctxt->stale_mask &= ~msk; + wm8775_ops[idx].update(ctxt); + } +} + + +const static struct pvr2_i2c_handler_functions hfuncs = { + .detach = (void (*)(void *))wm8775_detach, + .check = (int (*)(void *))wm8775_check, + .update = (void (*)(void *))wm8775_update, + .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe, +}; + + +int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) +{ + struct pvr2_v4l_wm8775 *ctxt; + + if (cp->handler) return 0; + + ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); + if (!ctxt) return 0; + memset(ctxt,0,sizeof(*ctxt)); + + ctxt->handler.func_data = ctxt; + ctxt->handler.func_table = &hfuncs; + ctxt->client = cp; + ctxt->hdw = hdw; + ctxt->stale_mask = (1 << (sizeof(wm8775_ops)/ + sizeof(wm8775_ops[0]))) - 1; + cp->handler = &ctxt->handler; + pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up", + cp->client->addr); + return !0; +} + + + + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 70 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.h new file mode 100644 index 000000000..15ee1e215 --- /dev/null +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-wm8775.h @@ -0,0 +1,54 @@ +/* + * + * $Id$ + * + * Copyright (C) 2005 Mike Isely + * Copyright (C) 2004 Aurelien Alleaume + * + * 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_WM8775_H +#define __PVRUSB2_WM8775_H + +/* + + This module connects the pvrusb2 driver to the I2C chip level + driver which performs analog -> digital audio conversion for + external audio inputs. This interface is used internally by the + driver; higher level code should only interact through the + interface provided by pvrusb2-hdw.h. + +*/ + +#include "compat.h" + + +#include "pvrusb2-i2c-core.h" + +int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); + + +#endif /* __PVRUSB2_WM8775_H */ + +/* + Stuff for Emacs to see, in order to encourage consistent editing style: + *** Local Variables: *** + *** mode: c *** + *** fill-column: 70 *** + *** tab-width: 8 *** + *** c-basic-offset: 8 *** + *** End: *** + */ -- cgit v1.2.3 From 52e19741ce48048ada5cc3b87c065dec5b100b8d Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 17:02:46 -0600 Subject: pvrusb2 request_module() adjustments From: Mike Isely Request new modules that pvrusb2 may need. This is a stop-gap; we need to do a better job of this. Also reorder the requests in the extremely feeble hope that we can avoid some initialization races in the hardware. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/pvrusb2-main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c index c554671af..c070fc195 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -130,11 +130,13 @@ static int __init pvr_init(void) /* Auto-load various support modules (with which we may indirectly interact) */ - request_module("tuner"); - request_module("tveeprom"); request_module("msp3400"); + request_module("cx25840"); request_module("saa7115"); + request_module("tuner"); + request_module("tveeprom"); request_module("tda9887"); + request_module("wm8775"); class_ptr = pvr2_sysfs_class_create(); -- cgit v1.2.3 From aba6cef68fb994d3bea36f80619c35c676de0cdb Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 17:43:14 -0600 Subject: Reduce FWSEND in cx25840 module due to certain I2C bus adapter limits From: Mike Isely The FWSEND parameter controls the size of the firmware chunks sent down the I2C bus to the chip. Previously this had been set to 1024 but unfortunately some I2C implementations can't transfer data in such big gulps. Specifically, the pvrusb2 driver has a hard limit of around 60 bytes, due to the encapsulation there of I2C traffic into USB messages. So we have to significantly reduce this parameter. Acked-by: Hans Verkuil Signed-off-by: Mike Isely --- linux/drivers/media/video/cx25840/cx25840-firmware.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'linux') diff --git a/linux/drivers/media/video/cx25840/cx25840-firmware.c b/linux/drivers/media/video/cx25840/cx25840-firmware.c index 96a45a4be..539de43dd 100644 --- a/linux/drivers/media/video/cx25840/cx25840-firmware.c +++ b/linux/drivers/media/video/cx25840/cx25840-firmware.c @@ -26,7 +26,17 @@ #include "cx25840-core.h" #define FWFILE "v4l-cx25840.fw" -#define FWSEND 1024 + +/* + * Mike Isely - The FWSEND parameter controls the + * size of the firmware chunks sent down the I2C bus to the chip. + * Previously this had been set to 1024 but unfortunately some I2C + * implementations can't transfer data in such big gulps. + * Specifically, the pvrusb2 driver has a hard limit of around 60 + * bytes, due to the encapsulation there of I2C traffic into USB + * messages. So we have to significantly reduce this parameter. + */ +#define FWSEND 48 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) #define FWDEV(x) &((x)->adapter->dev) -- cgit v1.2.3 From 6de66fc86dee706f81addaad380002538f65219c Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 22:18:49 -0600 Subject: Include additional pvrusb2 object files in build From: Mike Isely Some new sources have been added into pvrusb2 to deal with cx25840 and wm8775 modules in V4L. Need to add them to the build. Signed-off-by: Mike Isely --- linux/drivers/media/video/pvrusb2/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/Makefile b/linux/drivers/media/video/pvrusb2/Makefile index c83742fb1..4a37fe723 100644 --- a/linux/drivers/media/video/pvrusb2/Makefile +++ b/linux/drivers/media/video/pvrusb2/Makefile @@ -4,6 +4,7 @@ pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ pvrusb2-eeprom.o pvrusb2-tuner.o pvrusb2-demod.o \ pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \ pvrusb2-sysfs.o pvrusb2-context.o pvrusb2-io.o \ + pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \ pvrusb2-ioread.o pvrusb2-debugifc.o obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o -- cgit v1.2.3 From 2fc29f23f48a916f556d40ce8498ed27a0b1f0fc Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 25 Mar 2006 22:19:47 -0600 Subject: Update pvrusb2's cx25840 module handling to use new routing API From: Mike Isely Signed-off-by: Mike Isely --- .../media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'linux') diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index df1eeefd5..3cbce8eba 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c @@ -34,7 +34,7 @@ #include "pvrusb2-hdw-internal.h" #include "pvrusb2-debug.h" -#include +#include #include #include #include @@ -52,39 +52,39 @@ struct pvr2_v4l_cx2584x { static void set_input(struct pvr2_v4l_cx2584x *ctxt) { struct pvr2_hdw *hdw = ctxt->hdw; - struct v4l2_audio inp; - int msk = 0; + struct v4l2_routing route; + enum cx25840_video_input vid_input; + enum cx25840_audio_input aud_input; - int v = 0; + memset(&route,0,sizeof(route)); switch(hdw->controls[PVR2_CID_INPUT].value) { case PVR2_CVAL_INPUT_TV: - msk = (8 << 16) | 7; + vid_input = CX25840_COMPOSITE7; + aud_input = CX25840_AUDIO8; break; case PVR2_CVAL_INPUT_COMPOSITE: - msk = (0 << 16) | 3; + vid_input = CX25840_COMPOSITE3; + aud_input = CX25840_AUDIO_SERIAL; break; case PVR2_CVAL_INPUT_SVIDEO: - msk = (0 << 16) | 0x510; + vid_input = CX25840_SVIDEO1; + aud_input = CX25840_AUDIO_SERIAL; break; case PVR2_CVAL_INPUT_RADIO: - msk = 0; /* FIXME: Need to figure out radio */ - break; default: + // Just set it to be composite input for now... + vid_input = CX25840_COMPOSITE3; + aud_input = CX25840_AUDIO_SERIAL; break; } - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input(val=%d msk=0x%x)", - hdw->controls[PVR2_CID_INPUT].value,msk); - - v = msk & 0x0000ffffu; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x S_INPUT val=0x%x",v); - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_INPUT,&v); - v = (msk >> 16) & 0x0000ffffu; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x S_AUDIO val=0x%x",v); - memset(&inp,0,sizeof(inp)); - inp.index = v; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_AUDIO,&inp); + pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x", + vid_input,aud_input); + route.input = (u32)vid_input; + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); + route.input = (u32)aud_input; + pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); } -- cgit v1.2.3