diff options
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-hdw.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 0a868888f389..f051c6aa7f1f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -40,6 +39,23 @@ #define TV_MIN_FREQ 55250000L #define TV_MAX_FREQ 850000000L +/* This defines a minimum interval that the decoder must remain quiet + before we are allowed to start it running. */ +#define TIME_MSEC_DECODER_WAIT 50 + +/* This defines a minimum interval that the encoder must remain quiet + before we are allowed to configure it. I had this originally set to + 50msec, but Martin Dauskardt <martin.dauskardt@gmx.de> reports that + things work better when it's set to 100msec. */ +#define TIME_MSEC_ENCODER_WAIT 100 + +/* This defines the minimum interval that the encoder must successfully run + before we consider that the encoder has run at least once since its + firmware has been loaded. This measurement is in important for cases + where we can't do something until we know that the encoder has been run + at least once. */ +#define TIME_MSEC_ENCODER_OK 250 + static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL}; static DEFINE_MUTEX(pvr2_unit_mtx); @@ -67,6 +83,16 @@ MODULE_PARM_DESC(video_std,"specify initial video standard"); module_param_array(tolerance, int, NULL, 0444); MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); +/* US Broadcast channel 7 (175.25 MHz) */ +static int default_tv_freq = 175250000L; +/* 104.3 MHz, a usable FM station for my area */ +static int default_radio_freq = 104300000L; + +module_param_named(tv_freq, default_tv_freq, int, 0444); +MODULE_PARM_DESC(tv_freq, "specify initial television frequency"); +module_param_named(radio_freq, default_radio_freq, int, 0444); +MODULE_PARM_DESC(radio_freq, "specify initial radio frequency"); + #define PVR2_CTL_WRITE_ENDPOINT 0x01 #define PVR2_CTL_READ_ENDPOINT 0x81 @@ -224,6 +250,7 @@ struct pvr2_fx2cmd_descdef { static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = { {FX2CMD_MEM_WRITE_DWORD, "write encoder dword"}, {FX2CMD_MEM_READ_DWORD, "read encoder dword"}, + {FX2CMD_HCW_ZILOG_RESET, "zilog IR reset control"}, {FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"}, {FX2CMD_REG_WRITE, "write encoder register"}, {FX2CMD_REG_READ, "read encoder register"}, @@ -1685,6 +1712,14 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) if (!pvr2_hdw_dev_ok(hdw)) return; } + /* Take the IR chip out of reset, if appropriate */ + if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) { + pvr2_issue_simple_cmd(hdw, + FX2CMD_HCW_ZILOG_RESET | + (1 << 8) | + ((0) << 16)); + } + // This step MUST happen after the earlier powerup step. pvr2_i2c_core_init(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; @@ -1701,10 +1736,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) are, but I set them to something usable in the Chicago area just to make driver testing a little easier. */ - /* US Broadcast channel 7 (175.25 MHz) */ - hdw->freqValTelevision = 175250000L; - /* 104.3 MHz, a usable FM station for my area */ - hdw->freqValRadio = 104300000L; + hdw->freqValTelevision = default_tv_freq; + hdw->freqValRadio = default_radio_freq; // Do not use pvr2_reset_ctl_endpoints() here. It is not // thread-safe against the normal pvr2_send_request() mechanism. @@ -1989,7 +2022,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, case V4L2_CTRL_TYPE_MENU: ciptr->type = pvr2_ctl_enum; ciptr->def.type_enum.value_names = - cx2341x_ctrl_get_menu(ciptr->v4l_id); + cx2341x_ctrl_get_menu(&hdw->enc_ctl_state, + ciptr->v4l_id); for (cnt1 = 0; ciptr->def.type_enum.value_names[cnt1] != NULL; cnt1++) { } @@ -2428,22 +2462,38 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) struct pvr2_ctrl *cptr; int disruptive_change; - /* When video standard changes, reset the hres and vres values - - but if the user has pending changes there, then let the changes - take priority. */ + /* Handle some required side effects when the video standard is + changed.... */ if (hdw->std_dirty) { - /* Rewrite the vertical resolution to be appropriate to the - video standard that has been selected. */ int nvres; + int gop_size; if (hdw->std_mask_cur & V4L2_STD_525_60) { nvres = 480; + gop_size = 15; } else { nvres = 576; + gop_size = 12; } + /* Rewrite the vertical resolution to be appropriate to the + video standard that has been selected. */ if (nvres != hdw->res_ver_val) { hdw->res_ver_val = nvres; hdw->res_ver_dirty = !0; } + /* Rewrite the GOP size to be appropriate to the video + standard that has been selected. */ + if (gop_size != hdw->enc_ctl_state.video_gop_size) { + struct v4l2_ext_controls cs; + struct v4l2_ext_control c1; + memset(&cs, 0, sizeof(cs)); + memset(&c1, 0, sizeof(c1)); + cs.controls = &c1; + cs.count = 1; + c1.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE; + c1.value = gop_size; + cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs, + VIDIOC_S_EXT_CTRLS); + } } if (hdw->input_dirty && hdw->state_pathway_ok && @@ -3421,7 +3471,7 @@ static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl) } -void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff) +static void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff) { /* change some GPIO data * @@ -3601,7 +3651,9 @@ static int state_eval_encoder_config(struct pvr2_hdw *hdw) the encoder. */ if (!hdw->state_encoder_waitok) { hdw->encoder_wait_timer.expires = - jiffies + (HZ*50/1000); + jiffies + + (HZ * TIME_MSEC_ENCODER_WAIT + / 1000); add_timer(&hdw->encoder_wait_timer); } } @@ -3725,7 +3777,7 @@ static int state_eval_encoder_run(struct pvr2_hdw *hdw) hdw->state_encoder_run = !0; if (!hdw->state_encoder_runok) { hdw->encoder_run_timer.expires = - jiffies + (HZ*250/1000); + jiffies + (HZ * TIME_MSEC_ENCODER_OK / 1000); add_timer(&hdw->encoder_run_timer); } } @@ -3800,7 +3852,9 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw) but before we did the pending check. */ if (!hdw->state_decoder_quiescent) { hdw->quiescent_timer.expires = - jiffies + (HZ*50/1000); + jiffies + + (HZ * TIME_MSEC_DECODER_WAIT + / 1000); add_timer(&hdw->quiescent_timer); } } |