summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2/pvrusb2-hdw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-hdw.c')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c84
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);
}
}