/* 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 decoder must be allowed to run
before we can safely begin using its streaming output. */ #define TIME_MSEC_DECODER_STABILIZATION_WAIT 300
/* This defines a minimum interval that the encoder must remain quiet
before we are allowed to configure it. */ #define TIME_MSEC_ENCODER_WAIT 50
/* 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
/* US Broadcast channel 3 (61.25 MHz), to help with testing */ staticint default_tv_freq = 61250000L; /* 104.3 MHz, a usable FM station for my area */ staticint 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");
staticint ctrl_get_cropcapbl(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->bounds.left; return 0;
}
staticint ctrl_get_cropcapbt(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->bounds.top; return 0;
}
staticint ctrl_get_cropcapbw(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->bounds.width; return 0;
}
staticint ctrl_get_cropcapbh(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->bounds.height; return 0;
}
staticint ctrl_get_cropcapdl(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->defrect.left; return 0;
}
staticint ctrl_get_cropcapdt(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->defrect.top; return 0;
}
staticint ctrl_get_cropcapdw(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->defrect.width; return 0;
}
staticint ctrl_get_cropcapdh(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->defrect.height; return 0;
}
staticint ctrl_get_cropcappan(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->pixelaspect.numerator; return 0;
}
staticint ctrl_get_cropcappad(struct pvr2_ctrl *cptr, int *val)
{ struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; int stat = pvr2_hdw_check_cropcap(cptr->hdw); if (stat != 0) { return stat;
}
*val = cap->pixelaspect.denominator; return 0;
}
staticint ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
{ /* Actual maximum depends on the video standard in effect. */ if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
*vp = 480;
} else {
*vp = 576;
} return 0;
}
staticint ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
{ int ret; struct pvr2_hdw *hdw = cptr->hdw; 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 = cptr->info->v4l_id;
c1.value = v;
ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
hdw->state_encoder_run, &cs,
VIDIOC_S_EXT_CTRLS); if (ret == -EBUSY) { /* Oops. cx2341x is telling us it's not safe to change this control while we're capturing. Make a note of this fact so that the pipeline will be stopped the next time controls are committed. Then go on ahead and store this
change anyway. */
ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
0, &cs,
VIDIOC_S_EXT_CTRLS); if (!ret) hdw->enc_unsafe_stale = !0;
} if (ret) return ret;
hdw->enc_stale = !0; return 0;
}
staticunsignedint ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
{ struct v4l2_queryctrl qctrl = {}; struct pvr2_ctl_info *info;
qctrl.id = cptr->info->v4l_id;
cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl); /* Strip out the const so we can adjust a function pointer. It's OK to do this here because we know this is a dynamically created control, so the underlying storage for the info pointer is (a) private to us, and (b) not in read-only storage. Either we do this or we significantly complicate the underlying control
implementation. */
info = (struct pvr2_ctl_info *)(cptr->info); if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) { if (info->set_value) {
info->set_value = NULL;
}
} else { if (!(info->set_value)) {
info->set_value = ctrl_cx2341x_set;
}
} return qctrl.flags;
}
/* Set the currently tuned frequency and account for all possible
driver-core side effects of this action. */ staticvoid pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsignedlong val)
{ if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) { if (hdw->freqSelector) { /* Swing over to radio frequency selection */
hdw->freqSelector = 0;
hdw->freqDirty = !0;
} if (hdw->freqValRadio != val) {
hdw->freqValRadio = val;
hdw->freqSlotRadio = 0;
hdw->freqDirty = !0;
}
} else { if (!(hdw->freqSelector)) { /* Swing over to television frequency selection */
hdw->freqSelector = 1;
hdw->freqDirty = !0;
} if (hdw->freqValTelevision != val) {
hdw->freqValTelevision = val;
hdw->freqSlotTelevision = 0;
hdw->freqDirty = !0;
}
}
}
int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
{ return hdw->unit_number;
}
/* Attempt to locate one of the given set of files. Messages are logged appropriate to what has been found. The return value will be 0 or greater on success (it will be the index of the file name found) and fw_entry will be filled in. Otherwise a negative error is returned on failure. If the return value is -ENOENT then no viable firmware file
could be located. */ staticint pvr2_locate_firmware(struct pvr2_hdw *hdw, conststruct firmware **fw_entry, constchar *fwtypename, unsignedint fwcount, constchar *fwnames[])
{ unsignedint idx; int ret = -EINVAL; for (idx = 0; idx < fwcount; idx++) {
ret = request_firmware(fw_entry,
fwnames[idx],
&hdw->usb_dev->dev); if (!ret) {
trace_firmware("Located %s firmware: %s; uploading...",
fwtypename,
fwnames[idx]); return idx;
} if (ret == -ENOENT) continue;
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "request_firmware fatal error with code=%d",ret); return ret;
}
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "***WARNING*** Device %s firmware seems to be missing.",
fwtypename);
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Did you install the pvrusb2 firmware files in their proper location?"); if (fwcount == 1) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "request_firmware unable to locate %s file %s",
fwtypename,fwnames[0]);
} else {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "request_firmware unable to locate one of the following %s files:",
fwtypename); for (idx = 0; idx < fwcount; idx++) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "request_firmware: Failed to find %s",
fwnames[idx]);
}
} return ret;
}
/* * pvr2_upload_firmware1(). * * Send the 8051 firmware to the device. After the upload, arrange for * device to re-enumerate. * * NOTE : the pointer to the firmware data given by request_firmware() * is not suitable for an usb transaction. *
*/ staticint pvr2_upload_firmware1(struct pvr2_hdw *hdw)
{ conststruct firmware *fw_entry = NULL; void *fw_ptr; unsignedint pipe; unsignedint fwsize; int ret;
u16 address;
if (!hdw->hdw_desc->fx2_firmware.cnt) {
hdw->fw1_state = FW1_STATE_OK;
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Connected device type defines no firmware to upload; ignoring firmware"); return -ENOTTY;
}
hdw->fw1_state = FW1_STATE_FAILED; // default result
trace_firmware("pvr2_upload_firmware1");
ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
hdw->hdw_desc->fx2_firmware.cnt,
hdw->hdw_desc->fx2_firmware.lst); if (ret < 0) { if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING; return ret;
}
/* We should have written fwsize bytes */ if (ret == fwsize) {
hdw->fw1_state = FW1_STATE_RELOAD; return 0;
}
return -EIO;
}
/* * pvr2_upload_firmware2() * * This uploads encoder firmware on endpoint 2. *
*/
int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
{ conststruct firmware *fw_entry = NULL; void *fw_ptr; unsignedint pipe, fw_len, fw_done, bcnt, icnt; int actual_length; int ret = 0; int fwidx; staticconstchar *fw_files[] = {
CX2341X_FIRM_ENC_FILENAME,
};
if (hdw->hdw_desc->flag_skip_cx23416_firmware) { return 0;
}
trace_firmware("pvr2_upload_firmware2");
ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
ARRAY_SIZE(fw_files), fw_files); if (ret < 0) return ret;
fwidx = ret;
ret = 0; /* Since we're about to completely reinitialize the encoder, invalidate our cached copy of its configuration state. Next
time we configure the encoder, then we'll fully configure it. */
hdw->enc_cur_valid = 0;
/* Encoder is about to be reset so note that as far as we're
concerned now, the encoder has never been run. */
timer_delete_sync(&hdw->encoder_run_timer); if (hdw->state_encoder_runok) {
hdw->state_encoder_runok = 0;
trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
}
/* First prepare firmware loading */
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*/
ret |= pvr2_hdw_cmd_deep_reset(hdw);
ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
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_issue_simple_cmd(hdw,FX2CMD_FWPOST1);
ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
if (fw_len % sizeof(u32)) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "size of %s firmware must be a multiple of %zu bytes",
fw_files[fwidx],sizeof(u32));
release_firmware(fw_entry);
ret = -EINVAL; goto done;
}
fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); if (fw_ptr == NULL){
release_firmware(fw_entry);
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "failed to allocate memory for firmware2 upload");
ret = -ENOMEM; goto done;
}
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... */ /* Some background info: The data being swapped here is a firmware image destined for the mpeg encoder chip that lives at the other end of a USB endpoint. The encoder chip always talks in 32 bit chunks and its storage is organized into 32 bit words. However from the file system to the encoder chip everything is purely a byte stream. The firmware file's contents are always 32 bit swapped from what the encoder expects. Thus the need always exists to swap the bytes regardless of the endian type of the host processor and therefore swab32() makes
the most sense. */ 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, 1000);
ret |= (actual_length != bcnt); if (ret) break;
fw_done += bcnt;
}
trace_firmware("upload of %s : %i / %i ",
fw_files[fwidx],fw_done,fw_len);
kfree(fw_ptr);
release_firmware(fw_entry);
if (ret) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "firmware2 upload transfer failure"); goto done;
}
/* Finish upload */
ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
if (ret) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "firmware2 upload post-proc failure");
}
done: if (hdw->hdw_desc->signal_routing_scheme ==
PVR2_ROUTING_SCHEME_GOTVIEW) { /* Ensure that GPIO 11 is set to output for GOTVIEW
hardware. */
pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0);
} return ret;
}
staticint pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
{ /* Even though we really only care about the video decoder chip at this point, we'll broadcast stream on/off to all sub-devices anyway, just in case somebody else wants to hear the
command... */
pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s",
(enablefl ? "on" : "off"));
v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl);
v4l2_device_call_all(&hdw->v4l2_dev, 0, audio, s_stream, enablefl); if (hdw->decoder_client_id) { /* We get here if the encoder has been noticed. Otherwise we'll issue a warning to the user (which should
normally never happen). */ return 0;
} if (!hdw->flag_decoder_missed) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "***WARNING*** No decoder present");
hdw->flag_decoder_missed = !0;
trace_stbit("flag_decoder_missed",
hdw->flag_decoder_missed);
} return -EIO;
}
int pvr2_hdw_get_state(struct pvr2_hdw *hdw)
{ return hdw->master_state;
}
int pvr2_hdw_untrip(struct pvr2_hdw *hdw)
{ int fl;
LOCK_TAKE(hdw->big_lock); do {
fl = pvr2_hdw_untrip_unlocked(hdw);
} while (0); LOCK_GIVE(hdw->big_lock); if (fl) pvr2_hdw_state_sched(hdw); return 0;
}
int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
{ return hdw->state_pipeline_req != 0;
}
int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
{ int ret,st;
LOCK_TAKE(hdw->big_lock);
pvr2_hdw_untrip_unlocked(hdw); if (!enable_flag != !hdw->state_pipeline_req) {
hdw->state_pipeline_req = enable_flag != 0;
pvr2_trace(PVR2_TRACE_START_STOP, "/*--TRACE_STREAM--*/ %s",
enable_flag ? "enable" : "disable");
}
pvr2_hdw_state_sched(hdw);
LOCK_GIVE(hdw->big_lock); if ((ret = pvr2_hdw_wait(hdw,0)) < 0) return ret; if (enable_flag) { while ((st = hdw->master_state) != PVR2_STATE_RUN) { if (st != PVR2_STATE_READY) return -EIO; if ((ret = pvr2_hdw_wait(hdw,st)) < 0) return ret;
}
} return 0;
}
int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
{ int fl;
LOCK_TAKE(hdw->big_lock); if ((fl = (hdw->desired_stream_type != config)) != 0) {
hdw->desired_stream_type = config;
hdw->state_pipeline_config = 0;
trace_stbit("state_pipeline_config",
hdw->state_pipeline_config);
pvr2_hdw_state_sched(hdw);
}
LOCK_GIVE(hdw->big_lock); if (fl) return 0; return pvr2_hdw_wait(hdw,0);
}
static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
{ int unit_number = hdw->unit_number; int tp = 0; if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
tp = video_std[unit_number]; if (tp) return tp;
} return 0;
}
staticunsignedint get_default_error_tolerance(struct pvr2_hdw *hdw)
{ int unit_number = hdw->unit_number; int tp = 0; if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
tp = tolerance[unit_number];
} return tp;
}
staticint pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
{ /* Try a harmless request to fetch the eeprom's address over endpoint 1. See what happens. Only the full FX2 image can respond to this. If this probe fails then likely the FX2
firmware needs be loaded. */ int result;
LOCK_TAKE(hdw->ctl_lock); do {
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); if (result < 0) break;
} while(0); LOCK_GIVE(hdw->ctl_lock); if (result) {
pvr2_trace(PVR2_TRACE_INIT, "Probe of device endpoint 1 result status %d",
result);
} else {
pvr2_trace(PVR2_TRACE_INIT, "Probe of device endpoint 1 succeeded");
} return result == 0;
}
struct pvr2_std_hack {
v4l2_std_id pat; /* Pattern to match */
v4l2_std_id msk; /* Which bits we care about */
v4l2_std_id std; /* What additional standards or default to set */
};
/* This data structure labels specific combinations of standards from tveeprom that we'll try to recognize. If we recognize one, then assume a specified default standard to use. This is here because tveeprom only tells us about available standards not the intended default standard (if any) for the device in question. We guess the default based on what has been reported as available. Note that this is only for guessing a default - which can always be overridden explicitly - and if the user has otherwise named a default then that default will always be used in
place of this table. */ staticconststruct pvr2_std_hack std_eeprom_maps[] = {
{ /* PAL(B/G) */
.pat = V4L2_STD_B|V4L2_STD_GH,
.std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G,
},
{ /* NTSC(M) */
.pat = V4L2_STD_MN,
.std = V4L2_STD_NTSC_M,
},
{ /* PAL(I) */
.pat = V4L2_STD_PAL_I,
.std = V4L2_STD_PAL_I,
},
{ /* SECAM(L/L') */
.pat = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
.std = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
},
{ /* PAL(D/D1/K) */
.pat = V4L2_STD_DK,
.std = V4L2_STD_PAL_D|V4L2_STD_PAL_D1|V4L2_STD_PAL_K,
},
};
bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
pvr2_trace(PVR2_TRACE_STD, "Supported video standard(s) reported available in hardware: %.*s",
bcnt,buf);
hdw->std_mask_avail = hdw->std_mask_eeprom;
std2 = (std1|std3) & ~hdw->std_mask_avail; if (std2) {
bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
pvr2_trace(PVR2_TRACE_STD, "Expanding supported video standards to include: %.*s",
bcnt,buf);
hdw->std_mask_avail |= std2;
}
staticvoid pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw)
{ /* Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit of nuttiness for cx25840 causes that module to correctly set up its video scaling. This is really a problem in the cx25840 module itself, but we work around it here. The problem has not been seen in ivtv because there VBI is supported and set up. We don't do VBI here (at least not yet) and thus we never attempted to even set it up.
*/ struct v4l2_format fmt; if (hdw->decoder_client_id != PVR2_CLIENT_ID_CX25840) { /* We're not using a cx25840 so don't enable the hack */ return;
}
mid = cd->module_id;
fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL; if (!fname) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Module ID %u for device %s has no name? The driver might have a configuration problem.",
mid,
hdw->hdw_desc->description); return -EINVAL;
}
pvr2_trace(PVR2_TRACE_INIT, "Module ID %u (%s) for device %s being loaded...",
mid, fname,
hdw->hdw_desc->description);
i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list,
ARRAY_SIZE(i2caddr)); if (!i2ccnt && ((p = (mid < ARRAY_SIZE(module_i2c_addresses)) ?
module_i2c_addresses[mid] : NULL) != NULL)) { /* Second chance: Try default i2c address list */
i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, p,
ARRAY_SIZE(i2caddr)); if (i2ccnt) {
pvr2_trace(PVR2_TRACE_INIT, "Module ID %u: Using default i2c address list",
mid);
}
}
if (!i2ccnt) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Module ID %u (%s) for device %s: No i2c addresses. The driver might have a configuration problem.",
mid, fname, hdw->hdw_desc->description); return -EINVAL;
}
if (i2ccnt == 1) {
pvr2_trace(PVR2_TRACE_INIT, "Module ID %u: Setting up with specified i2c address 0x%x",
mid, i2caddr[0]);
sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
fname, i2caddr[0], NULL);
} else {
pvr2_trace(PVR2_TRACE_INIT, "Module ID %u: Setting up with address probe list",
mid);
sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
fname, 0, i2caddr);
}
if (!sd) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Module ID %u (%s) for device %s failed to load. Possible missing sub-device kernel module or initialization failure within module.",
mid, fname, hdw->hdw_desc->description); return -EIO;
}
/* Tag this sub-device instance with the module ID we know about. In other places we'll use that tag to determine if the instance
requires special handling. */
sd->grp_id = mid;
cm = &hdw->hdw_desc->client_modules; for (idx = 0; idx < cm->cnt; idx++) {
request_module(cm->lst[idx]);
}
ct = &hdw->hdw_desc->client_table; for (idx = 0; idx < ct->cnt; idx++) { if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0;
} if (!okFl) {
hdw->flag_modulefail = !0;
pvr2_hdw_render_useless(hdw);
}
}
staticvoid pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
{ int ret; unsignedint idx; struct pvr2_ctrl *cptr; int reloadFl = 0; if (hdw->hdw_desc->fx2_firmware.cnt) { if (!reloadFl) {
reloadFl =
(hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
== 0); if (reloadFl) {
pvr2_trace(PVR2_TRACE_INIT, "USB endpoint config looks strange; possibly firmware needs to be loaded");
}
} if (!reloadFl) {
reloadFl = !pvr2_hdw_check_firmware(hdw); if (reloadFl) {
pvr2_trace(PVR2_TRACE_INIT, "Check for FX2 firmware failed; possibly firmware needs to be loaded");
}
} if (reloadFl) { if (pvr2_upload_firmware1(hdw) != 0) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failure uploading firmware1");
} return;
}
}
hdw->fw1_state = FW1_STATE_OK;
if (!pvr2_hdw_dev_ok(hdw)) return;
hdw->force_dirty = !0;
if (!hdw->hdw_desc->flag_no_powerup) {
pvr2_hdw_cmd_powerup(hdw); if (!pvr2_hdw_dev_ok(hdw)) return;
}
/* Take the IR chip out of reset, if appropriate */ if (hdw->ir_scheme_active == 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;
/* Reset demod only on Hauppauge 160xxx platform */ if (le16_to_cpu(hdw->usb_dev->descriptor.idVendor) == 0x2040 &&
(le16_to_cpu(hdw->usb_dev->descriptor.idProduct) == 0x7502 ||
le16_to_cpu(hdw->usb_dev->descriptor.idProduct) == 0x7510)) {
pr_info("%s(): resetting 160xxx demod\n", __func__); /* TODO: not sure this is proper place to reset once only */
pvr2_issue_simple_cmd(hdw,
FX2CMD_HCW_DEMOD_RESET_PIN |
(1 << 8) |
((0) << 16));
usleep_range(10000, 10500);
pvr2_issue_simple_cmd(hdw,
FX2CMD_HCW_DEMOD_RESET_PIN |
(1 << 8) |
((1) << 16));
usleep_range(10000, 10500);
}
pvr2_hdw_load_modules(hdw); if (!pvr2_hdw_dev_ok(hdw)) return;
for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
cptr = hdw->controls + idx; if (cptr->info->skip_init) continue; if (!cptr->info->set_value) continue;
cptr->info->set_value(cptr,~0,cptr->info->default_value);
}
pvr2_hdw_cx25840_vbi_hack(hdw);
/* Set up special default values for the television and radio frequencies here. It's not really important what these defaults are, but I set them to something usable in the Chicago area just
to make driver testing a little easier. */
// Do not use pvr2_reset_ctl_endpoints() here. It is not // thread-safe against the normal pvr2_send_request() mechanism. // (We should make it thread safe).
if (hdw->hdw_desc->flag_has_hauppauge_rom) {
ret = pvr2_hdw_get_eeprom_addr(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; if (ret < 0) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Unable to determine location of eeprom, skipping");
} else {
hdw->eeprom_addr = ret;
pvr2_eeprom_analyze(hdw); if (!pvr2_hdw_dev_ok(hdw)) return;
}
} else {
hdw->tuner_type = hdw->hdw_desc->default_tuner_type;
hdw->tuner_updated = !0;
hdw->std_mask_eeprom = V4L2_STD_ALL;
}
if (!get_default_tuner_type(hdw)) {
pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_setup: Tuner type overridden to %d",
hdw->tuner_type);
}
if (!pvr2_hdw_dev_ok(hdw)) return;
if (hdw->hdw_desc->signal_routing_scheme ==
PVR2_ROUTING_SCHEME_GOTVIEW) { /* Ensure that GPIO 11 is set to output for GOTVIEW
hardware. */
pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0);
}
pvr2_hdw_commit_setup(hdw);
hdw->vid_stream = pvr2_stream_create(); if (!pvr2_hdw_dev_ok(hdw)) return;
pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_setup: video stream is %p",hdw->vid_stream); if (hdw->vid_stream) {
idx = get_default_error_tolerance(hdw); if (idx) {
pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_setup: video stream %p setting tolerance %u",
hdw->vid_stream,idx);
}
pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
PVR2_VID_ENDPOINT,idx);
}
if (!pvr2_hdw_dev_ok(hdw)) return;
hdw->flag_init_ok = !0;
pvr2_hdw_state_sched(hdw);
}
/* Set up the structure and attempt to put the device into a usable state. This can be a time-consuming operation, which is why it is not done
internally as part of the create() step. */ staticvoid pvr2_hdw_setup(struct pvr2_hdw *hdw)
{
pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw); do {
pvr2_hdw_setup_low(hdw);
pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
hdw,pvr2_hdw_dev_ok(hdw),hdw->flag_init_ok); if (pvr2_hdw_dev_ok(hdw)) { if (hdw->flag_init_ok) {
pvr2_trace(
PVR2_TRACE_INFO, "Device initialization completed successfully."); break;
} if (hdw->fw1_state == FW1_STATE_RELOAD) {
pvr2_trace(
PVR2_TRACE_INFO, "Device microcontroller firmware (re)loaded; it should now reset and reconnect."); break;
}
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "Device initialization was not successful."); if (hdw->fw1_state == FW1_STATE_MISSING) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "Giving up since device microcontroller firmware appears to be missing."); break;
}
} if (hdw->flag_modulefail) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "***WARNING*** pvrusb2 driver initialization failed due to the failure of one or more sub-device kernel modules.");
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "You need to resolve the failing condition before this driver can function. There should be some earlier messages giving more information about the problem."); break;
} if (procreload) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "Attempting pvrusb2 recovery by reloading primary firmware.");
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "If this works, device should disconnect and reconnect in a sane state.");
hdw->fw1_state = FW1_STATE_UNKNOWN;
pvr2_upload_firmware1(hdw);
} else {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "***WARNING*** pvrusb2 device hardware appears to be jammed and I can't clear it.");
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "You might need to power cycle the pvrusb2 device in order to recover.");
}
} while (0);
pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
}
/* Perform second stage initialization. Set callback pointer first so that we can avoid a possible initialization race (if the kernel thread runs
before the callback has been set). */ int pvr2_hdw_initialize(struct pvr2_hdw *hdw, void (*callback_func)(void *), void *callback_data)
{
LOCK_TAKE(hdw->big_lock); do { if (hdw->flag_disconnected) { /* Handle a race here: If we're already disconnected by this point, then give up. If we get past this then we'll remain connected for the duration of initialization since the entire initialization sequence is now protected by the
big_lock. */ break;
}
hdw->state_data = callback_data;
hdw->state_func = callback_func;
pvr2_hdw_setup(hdw);
} while (0); LOCK_GIVE(hdw->big_lock); return hdw->flag_init_ok;
}
/* Create, set up, and return a structure for interacting with the
underlying hardware. */ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, conststruct usb_device_id *devid)
{ unsignedint idx,cnt1,cnt2,m; struct pvr2_hdw *hdw = NULL; int valid_std_mask; struct pvr2_ctrl *cptr; struct usb_device *usb_dev; conststruct pvr2_device_desc *hdw_desc;
__u8 ifnum; struct v4l2_queryctrl qctrl; struct pvr2_ctl_info *ciptr;
if (hdw_desc == NULL) {
pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_create: No device description pointer, unable to continue.");
pvr2_trace(PVR2_TRACE_INIT, "If you have a new device type, please contact Mike Isely <isely@pobox.com> to get it included in the driver"); goto fail;
}
hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
hdw,hdw_desc->description);
pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s",
hdw_desc->description); if (hdw_desc->flag_is_experimental) {
pvr2_trace(PVR2_TRACE_INFO, "**********");
pvr2_trace(PVR2_TRACE_INFO, "***WARNING*** Support for this device (%s) is experimental.",
hdw_desc->description);
pvr2_trace(PVR2_TRACE_INFO, "Important functionality might not be entirely working.");
pvr2_trace(PVR2_TRACE_INFO, "Please consider contacting the driver author to help with further stabilization of the driver.");
pvr2_trace(PVR2_TRACE_INFO, "**********");
} if (!hdw) goto fail;
/* Calculate which inputs are OK */
m = 0; if (hdw_desc->flag_has_analogtuner) m |= 1 << PVR2_CVAL_INPUT_TV; if (hdw_desc->digital_control_scheme != PVR2_DIGITAL_SCHEME_NONE) {
m |= 1 << PVR2_CVAL_INPUT_DTV;
} if (hdw_desc->flag_has_svideo) m |= 1 << PVR2_CVAL_INPUT_SVIDEO; if (hdw_desc->flag_has_composite) m |= 1 << PVR2_CVAL_INPUT_COMPOSITE; if (hdw_desc->flag_has_fmradio) m |= 1 << PVR2_CVAL_INPUT_RADIO;
hdw->input_avail_mask = m;
hdw->input_allowed_mask = hdw->input_avail_mask;
/* If not a hybrid device, pathway_state never changes. So
initialize it here to what it should forever be. */ if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_DTV))) {
hdw->pathway_state = PVR2_PATHWAY_ANALOG;
} elseif (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_TV))) {
hdw->pathway_state = PVR2_PATHWAY_DIGITAL;
}
/* Remove _all_ associations between this driver and the underlying USB
layer. */ staticvoid pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
{ if (hdw->flag_disconnected) return;
pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw); if (hdw->ctl_read_urb) {
usb_kill_urb(hdw->ctl_read_urb);
usb_free_urb(hdw->ctl_read_urb);
hdw->ctl_read_urb = NULL;
} if (hdw->ctl_write_urb) {
usb_kill_urb(hdw->ctl_write_urb);
usb_free_urb(hdw->ctl_write_urb);
hdw->ctl_write_urb = NULL;
} if (hdw->ctl_read_buffer) {
kfree(hdw->ctl_read_buffer);
hdw->ctl_read_buffer = NULL;
} if (hdw->ctl_write_buffer) {
kfree(hdw->ctl_write_buffer);
hdw->ctl_write_buffer = NULL;
}
hdw->flag_disconnected = !0; /* If we don't do this, then there will be a dangling struct device reference to our disappearing device persisting inside the V4L
core... */
v4l2_device_disconnect(&hdw->v4l2_dev);
hdw->usb_dev = NULL;
hdw->usb_intf = NULL;
pvr2_hdw_render_useless(hdw);
}
int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
{ return (hdw && hdw->flag_ok);
}
/* Called when hardware has been unplugged */ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
{
pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
LOCK_TAKE(hdw->big_lock);
pvr2_i2c_core_done(hdw);
LOCK_TAKE(hdw->ctl_lock);
pvr2_hdw_remove_usb_stuff(hdw);
LOCK_GIVE(hdw->ctl_lock);
LOCK_GIVE(hdw->big_lock);
}
/* Get the number of defined controls */ unsignedint pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
{ return hdw->control_cnt;
}
/* Retrieve a control handle given its index (0..count-1) */ struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw, unsignedint idx)
{ if (idx >= hdw->control_cnt) return NULL; return hdw->controls + idx;
}
/* Retrieve a control handle given its index (0..count-1) */ struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw, unsignedint ctl_id)
{ struct pvr2_ctrl *cptr; unsignedint idx; int i;
/* This could be made a lot more efficient, but for now... */ for (idx = 0; idx < hdw->control_cnt; idx++) {
cptr = hdw->controls + idx;
i = cptr->info->internal_id; if (i && (i == ctl_id)) return cptr;
} return NULL;
}
/* Given a V4L ID, retrieve the control structure associated with it. */ struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsignedint ctl_id)
{ struct pvr2_ctrl *cptr; unsignedint idx; int i;
/* This could be made a lot more efficient, but for now... */ for (idx = 0; idx < hdw->control_cnt; idx++) {
cptr = hdw->controls + idx;
i = cptr->info->v4l_id; if (i && (i == ctl_id)) return cptr;
} return NULL;
}
/* Given a V4L ID for its immediate predecessor, retrieve the control
structure associated with it. */ struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw, unsignedint ctl_id)
{ struct pvr2_ctrl *cptr,*cp2; unsignedint idx; int i;
/* This could be made a lot more efficient, but for now... */
cp2 = NULL; for (idx = 0; idx < hdw->control_cnt; idx++) {
cptr = hdw->controls + idx;
i = cptr->info->v4l_id; if (!i) continue; if (i <= ctl_id) continue; if (cp2 && (cp2->info->v4l_id < i)) continue;
cp2 = cptr;
} return cp2; return NULL;
}
staticconstchar *get_ctrl_typename(enum pvr2_ctl_type tp)
{ switch (tp) { case pvr2_ctl_int: return"integer"; case pvr2_ctl_enum: return"enum"; case pvr2_ctl_bool: return"boolean"; case pvr2_ctl_bitmask: return"bitmask";
} return"";
}
staticvoid pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id, constchar *name, int val)
{ struct v4l2_control ctrl; struct v4l2_subdev *sd;
/* Execute whatever commands are required to update the state of all the
sub-devices so that they match our current control values. */ staticvoid pvr2_subdev_update(struct pvr2_hdw *hdw)
{ struct v4l2_subdev *sd; unsignedint id;
pvr2_subdev_update_func fp;
if (hdw->srate_dirty || hdw->force_dirty) {
u32 val;
pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d",
hdw->srate_val); switch (hdw->srate_val) { default: case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
val = 48000; break; case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
val = 44100; break; case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
val = 32000; break;
}
v4l2_device_call_all(&hdw->v4l2_dev, 0,
audio, s_clock_freq, val);
}
/* Unable to set crop parameters; there is apparently no equivalent
for VIDIOC_S_CROP */
v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
id = sd->grp_id; if (id >= ARRAY_SIZE(pvr2_module_update_functions)) continue;
fp = pvr2_module_update_functions[id]; if (!fp) continue;
(*fp)(hdw, sd);
}
if (hdw->tuner_signal_stale || hdw->cropcap_stale) {
pvr2_hdw_status_poll(hdw);
}
}
/* Figure out if we need to commit control changes. If so, mark internal state flags to indicate this fact and return true. Otherwise do nothing
else and return false. */ staticint pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
{ unsignedint idx; struct pvr2_ctrl *cptr; int value; int commit_flag = hdw->force_dirty; char buf[100]; unsignedint bcnt,ccnt;
for (idx = 0; idx < hdw->control_cnt; idx++) {
cptr = hdw->controls + idx; if (!cptr->info->is_dirty) continue; if (!cptr->info->is_dirty(cptr)) continue;
commit_flag = !0;
/* Perform all operations needed to commit all control changes. This must be performed in synchronization with the pipeline state and is thus expected to be called as part of the driver's worker thread. Return true if commit successful, otherwise return false to indicate that
commit isn't possible at this time. */ staticint pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
{ unsignedint idx; struct pvr2_ctrl *cptr; int disruptive_change;
if (hdw->input_dirty && hdw->state_pathway_ok &&
(((hdw->input_val == PVR2_CVAL_INPUT_DTV) ?
PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) !=
hdw->pathway_state)) { /* Change of mode being asked for... */
hdw->state_pathway_ok = 0;
trace_stbit("state_pathway_ok", hdw->state_pathway_ok);
} if (!hdw->state_pathway_ok) { /* Can't commit anything until pathway is ok. */ return 0;
}
/* Handle some required side effects when the video standard is
changed.... */ if (hdw->std_dirty) { 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);
}
}
/* The broadcast decoder can only scale down, so if * res_*_dirty && crop window < output format ==> enlarge crop. * * The mpeg encoder receives fields of res_hor_val dots and * res_ver_val halflines. Limits: hor<=720, ver<=576.
*/ if (hdw->res_hor_dirty && hdw->cropw_val < hdw->res_hor_val) {
hdw->cropw_val = hdw->res_hor_val;
hdw->cropw_dirty = !0;
} elseif (hdw->cropw_dirty) {
hdw->res_hor_dirty = !0; /* must rescale */
hdw->res_hor_val = min(720, hdw->cropw_val);
} if (hdw->res_ver_dirty && hdw->croph_val < hdw->res_ver_val) {
hdw->croph_val = hdw->res_ver_val;
hdw->croph_dirty = !0;
} elseif (hdw->croph_dirty) { int nvres = hdw->std_mask_cur & V4L2_STD_525_60 ? 480 : 576;
hdw->res_ver_dirty = !0;
hdw->res_ver_val = min(nvres, hdw->croph_val);
}
/* If any of the below has changed, then we can't do the update while the pipeline is running. Pipeline must be paused first and decoder -> encoder connection be made quiescent before we
can proceed. */
disruptive_change =
(hdw->std_dirty ||
hdw->enc_unsafe_stale ||
hdw->srate_dirty ||
hdw->res_ver_dirty ||
hdw->res_hor_dirty ||
hdw->cropw_dirty ||
hdw->croph_dirty ||
hdw->input_dirty ||
(hdw->active_stream_type != hdw->desired_stream_type)); if (disruptive_change && !hdw->state_pipeline_idle) { /* Pipeline is not idle; we can't proceed. Arrange to cause pipeline to stop so that we can try this again
later.... */
hdw->state_pipeline_pause = !0; return 0;
}
if (hdw->srate_dirty) { /* Write new sample rate into control structure since * the master copy is stale. We must track srate * separate from the mpeg control structure because
* other logic also uses this value. */ 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_AUDIO_SAMPLING_FREQ;
c1.value = hdw->srate_val;
cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
}
if (hdw->active_stream_type != hdw->desired_stream_type) { /* Handle any side effects of stream config here */
hdw->active_stream_type = hdw->desired_stream_type;
}
if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
hdw->state_encoder_run) { /* If encoder isn't running or it can't be touched, then this will get worked out later when we start the
encoder. */ if (pvr2_encoder_adjust(hdw) < 0) return !0;
}
hdw->state_pipeline_config = !0; /* Hardware state may have changed in a way to cause the cropping capabilities to have changed. So mark it stale, which will
cause a later re-fetch. */
trace_stbit("state_pipeline_config",hdw->state_pipeline_config); return !0;
}
int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
{ int fl;
LOCK_TAKE(hdw->big_lock);
fl = pvr2_hdw_commit_setup(hdw);
LOCK_GIVE(hdw->big_lock); if (!fl) return 0; return pvr2_hdw_wait(hdw,0);
}
staticvoid pvr2_hdw_worker_poll(struct work_struct *work)
{ int fl = 0; struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,workpoll);
LOCK_TAKE(hdw->big_lock); do {
fl = pvr2_hdw_state_eval(hdw);
} while (0); LOCK_GIVE(hdw->big_lock); if (fl && hdw->state_func) {
hdw->state_func(hdw->state_data);
}
}
/* Return information about cropping capabilities */ int pvr2_hdw_get_cropcap(struct pvr2_hdw *hdw, struct v4l2_cropcap *pp)
{ int stat = 0;
LOCK_TAKE(hdw->big_lock);
stat = pvr2_hdw_check_cropcap(hdw); if (!stat) {
memcpy(pp, &hdw->cropcap_info, sizeof(hdw->cropcap_info));
}
LOCK_GIVE(hdw->big_lock); return stat;
}
/* Return information about the tuner */ int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
{
LOCK_TAKE(hdw->big_lock); do { if (hdw->tuner_signal_stale) {
pvr2_hdw_status_poll(hdw);
}
memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
} while (0);
LOCK_GIVE(hdw->big_lock); return 0;
}
/* Get handle to video output stream */ struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
{ return hp->vid_stream;
}
void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
{ int nr = pvr2_hdw_get_unit_number(hdw);
LOCK_TAKE(hdw->big_lock); do {
pr_info("pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status);
pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
pvr2_hdw_state_log_state(hdw);
pr_info("pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
} while (0);
LOCK_GIVE(hdw->big_lock);
}
/* Grab EEPROM contents, needed for direct method. */ #define EEPROM_SIZE 8192 #define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__) static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw)
{ struct i2c_msg msg[2];
u8 *eeprom;
u8 iadd[2];
u8 addr;
u16 eepromSize; unsignedint offs; int ret; int mode16 = 0; unsigned pcnt,tcnt;
eeprom = kzalloc(EEPROM_SIZE, GFP_KERNEL); if (!eeprom) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failed to allocate memory required to read eeprom"); return NULL;
}
trace_eeprom("Value for eeprom addr from controller was 0x%x",
hdw->eeprom_addr);
addr = hdw->eeprom_addr; /* Seems that if the high bit is set, then the *real* eeprom address is shifted right now bit position (noticed this in
newer PVR USB2 hardware) */ if (addr & 0x80) addr >>= 1;
/* FX2 documentation states that a 16bit-addressed eeprom is expected if the I2C address is an odd number (yeah, this is
strange but it's what they do) */
mode16 = (addr & 1);
eepromSize = (mode16 ? EEPROM_SIZE : 256);
trace_eeprom("Examining %d byte eeprom at location 0x%x using %d bit addressing",
eepromSize, addr,
mode16 ? 16 : 8);
/* We have to do the actual eeprom data fetch ourselves, because (1) we're only fetching part of the eeprom, and (2) if we were getting the whole thing our I2C driver can't grab it in one
pass - which is what tveeprom is otherwise going to attempt */ for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
pcnt = 16; if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
offs = tcnt + (eepromSize - EEPROM_SIZE); if (mode16) {
iadd[0] = offs >> 8;
iadd[1] = offs;
} else {
iadd[0] = offs;
}
msg[1].len = pcnt;
msg[1].buf = eeprom+tcnt; if ((ret = i2c_transfer(&hdw->i2c_adap,
msg,ARRAY_SIZE(msg))) != 2) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "eeprom fetch set offs err=%d",ret);
kfree(eeprom); return NULL;
}
} return eeprom;
}
void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int mode, int enable_flag)
{ int ret;
u16 address; unsignedint pipe;
LOCK_TAKE(hdw->big_lock); do { if ((hdw->fw_buffer == NULL) == !enable_flag) break;
if (!enable_flag) {
pvr2_trace(PVR2_TRACE_FIRMWARE, "Cleaning up after CPU firmware fetch");
kfree(hdw->fw_buffer);
hdw->fw_buffer = NULL;
hdw->fw_size = 0; if (hdw->fw_cpu_flag) { /* Now release the CPU. It will disconnect
and reconnect later. */
pvr2_hdw_cpureset_assert(hdw,0);
} break;
}
hdw->fw_cpu_flag = (mode != 2); if (hdw->fw_cpu_flag) {
hdw->fw_size = (mode == 1) ? 0x4000 : 0x2000;
pvr2_trace(PVR2_TRACE_FIRMWARE, "Preparing to suck out CPU firmware (size=%u)",
hdw->fw_size);
hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL); if (!hdw->fw_buffer) {
hdw->fw_size = 0; break;
}
/* We have to hold the CPU during firmware upload. */
pvr2_hdw_cpureset_assert(hdw,1);
/* download the firmware from address 0000-1fff in 2048
(=0x800) bytes chunk. */
pvr2_trace(PVR2_TRACE_FIRMWARE, "Done grabbing CPU firmware");
} else {
pvr2_trace(PVR2_TRACE_FIRMWARE, "Sucking down EEPROM contents");
hdw->fw_buffer = pvr2_full_eeprom_fetch(hdw); if (!hdw->fw_buffer) {
pvr2_trace(PVR2_TRACE_FIRMWARE, "EEPROM content suck failed."); break;
}
hdw->fw_size = EEPROM_SIZE;
pvr2_trace(PVR2_TRACE_FIRMWARE, "Done sucking down EEPROM contents");
}
} while (0);
LOCK_GIVE(hdw->big_lock);
}
/* Return true if we're in a mode for retrieval CPU firmware */ int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
{ return hdw->fw_buffer != NULL;
}
int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsignedint offs, char *buf,unsignedint cnt)
{ int ret = -EINVAL;
LOCK_TAKE(hdw->big_lock); do { if (!buf) break; if (!cnt) break;
if (!hdw->fw_buffer) {
ret = -EIO; break;
}
if (offs >= hdw->fw_size) {
pvr2_trace(PVR2_TRACE_FIRMWARE, "Read firmware data offs=%d EOF",
offs);
ret = 0; break;
}
if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
hdw->ctl_timeout_flag = !0; if (hdw->ctl_write_pend_flag)
usb_unlink_urb(hdw->ctl_write_urb); if (hdw->ctl_read_pend_flag)
usb_unlink_urb(hdw->ctl_read_urb);
}
}
/* Issue a command and get a response from the device. This extended version includes a probe flag (which if set means that device errors should not be logged or treated as fatal) and a timeout in jiffies.
This can be used to non-lethally probe the health of endpoint 1. */ staticint pvr2_send_request_ex(struct pvr2_hdw *hdw, unsignedint timeout,int probe_fl, void *write_data,unsignedint write_len, void *read_data,unsignedint read_len)
{ unsignedint idx; int status = 0; struct hdw_timer timer = {
.hdw = hdw,
};
if (!hdw->ctl_lock_held) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Attempted to execute control transfer without lock!!"); return -EDEADLK;
} if (!hdw->flag_ok && !probe_fl) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Attempted to execute control transfer when device not ok"); return -EIO;
} if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) { if (!probe_fl) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Attempted to execute control transfer when USB is disconnected");
} return -ENOTTY;
}
/* Ensure that we have sane parameters */ if (!write_data) write_len = 0; if (!read_data) read_len = 0; if (write_len > PVR2_CTL_BUFFSIZE) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "Attempted to execute %d byte control-write transfer (limit=%d)",
write_len,PVR2_CTL_BUFFSIZE); return -EINVAL;
} if (read_len > PVR2_CTL_BUFFSIZE) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "Attempted to execute %d byte control-read transfer (limit=%d)",
write_len,PVR2_CTL_BUFFSIZE); return -EINVAL;
} if ((!write_len) && (!read_len)) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "Attempted to execute null control transfer?"); return -EINVAL;
}
if (write_len && write_data) {
hdw->cmd_debug_state = 2; /* Transfer write data to internal buffer */ for (idx = 0; idx < write_len; idx++) {
hdw->ctl_write_buffer[idx] =
((unsignedchar *)write_data)[idx];
} /* Initiate a write request */
usb_fill_bulk_urb(hdw->ctl_write_urb,
hdw->usb_dev,
usb_sndbulkpipe(hdw->usb_dev,
PVR2_CTL_WRITE_ENDPOINT),
hdw->ctl_write_buffer,
write_len,
pvr2_ctl_write_complete,
hdw);
hdw->ctl_write_urb->actual_length = 0;
hdw->ctl_write_pend_flag = !0; if (usb_urb_ep_type_check(hdw->ctl_write_urb)) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "Invalid write control endpoint"); return -EINVAL;
}
status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); if (status < 0) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failed to submit write-control URB status=%d",
status);
hdw->ctl_write_pend_flag = 0; goto done;
}
}
if (read_len) {
hdw->cmd_debug_state = 3;
memset(hdw->ctl_read_buffer,0x43,read_len); /* Initiate a read request */
usb_fill_bulk_urb(hdw->ctl_read_urb,
hdw->usb_dev,
usb_rcvbulkpipe(hdw->usb_dev,
PVR2_CTL_READ_ENDPOINT),
hdw->ctl_read_buffer,
read_len,
pvr2_ctl_read_complete,
hdw);
hdw->ctl_read_urb->actual_length = 0;
hdw->ctl_read_pend_flag = !0; if (usb_urb_ep_type_check(hdw->ctl_read_urb)) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS, "Invalid read control endpoint"); return -EINVAL;
}
status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); if (status < 0) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failed to submit read-control URB status=%d",
status);
hdw->ctl_read_pend_flag = 0; goto done;
}
}
/* Start timer */
add_timer(&timer.timer);
/* Now wait for all I/O to complete */
hdw->cmd_debug_state = 4; while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
wait_for_completion(&hdw->ctl_done);
}
hdw->cmd_debug_state = 5;
/* Stop timer */
timer_delete_sync(&timer.timer);
hdw->cmd_debug_state = 6;
status = 0;
if (hdw->ctl_timeout_flag) {
status = -ETIMEDOUT; if (!probe_fl) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Timed out control-write");
} goto done;
}
if (write_len) { /* Validate results of write request */ if ((hdw->ctl_write_urb->status != 0) &&
(hdw->ctl_write_urb->status != -ENOENT) &&
(hdw->ctl_write_urb->status != -ESHUTDOWN) &&
(hdw->ctl_write_urb->status != -ECONNRESET)) { /* USB subsystem is reporting some kind of failure
on the write */
status = hdw->ctl_write_urb->status; if (!probe_fl) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "control-write URB failure, status=%d",
status);
} goto done;
} if (hdw->ctl_write_urb->actual_length < write_len) { /* Failed to write enough data */
status = -EIO; if (!probe_fl) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "control-write URB short, expected=%d got=%d",
write_len,
hdw->ctl_write_urb->actual_length);
} goto done;
}
} if (read_len && read_data) { /* Validate results of read request */ if ((hdw->ctl_read_urb->status != 0) &&
(hdw->ctl_read_urb->status != -ENOENT) &&
(hdw->ctl_read_urb->status != -ESHUTDOWN) &&
(hdw->ctl_read_urb->status != -ECONNRESET)) { /* USB subsystem is reporting some kind of failure
on the read */
status = hdw->ctl_read_urb->status; if (!probe_fl) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "control-read URB failure, status=%d",
status);
} goto done;
} if (hdw->ctl_read_urb->actual_length < read_len) { /* Failed to read enough data */
status = -EIO; if (!probe_fl) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "control-read URB short, expected=%d got=%d",
read_len,
hdw->ctl_read_urb->actual_length);
} goto done;
} /* Transfer retrieved data out from internal buffer */ for (idx = 0; idx < read_len; idx++) {
((unsignedchar *)read_data)[idx] =
hdw->ctl_read_buffer[idx];
}
}
ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
*data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
LOCK_GIVE(hdw->ctl_lock);
return ret;
}
void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
{ if (!hdw->flag_ok) return;
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Device being rendered inoperable"); if (hdw->vid_stream) {
pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
}
hdw->flag_ok = 0;
trace_stbit("flag_ok",hdw->flag_ok);
pvr2_hdw_state_sched(hdw);
}
void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
{ int ret;
pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
ret = usb_lock_device_for_reset(hdw->usb_dev,NULL); if (ret == 0) {
ret = usb_reset_device(hdw->usb_dev);
usb_unlock_device(hdw->usb_dev);
} else {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failed to lock USB device ret=%d",ret);
} if (init_pause_msec) {
pvr2_trace(PVR2_TRACE_INFO, "Waiting %u msec for hardware to settle",
init_pause_msec);
msleep(init_pause_msec);
}
/* Write the CPUCS register on the 8051. The lsb of the register
is the reset bit; a 1 asserts reset while a 0 clears it. */
pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,1000); if (ret < 0) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS, "cpureset_assert(%d) error=%d",val,ret);
pvr2_hdw_render_useless(hdw);
}
kfree(da);
}
int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
{ return pvr2_issue_simple_cmd(hdw,FX2CMD_DEEP_RESET);
}
int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
{ return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_ON);
}
staticvoid pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl)
{ int cmode; /* Compare digital/analog desired setting with current setting. If
they don't match, fix it... */
cmode = (digitalFl ? PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG); if (cmode == hdw->pathway_state) { /* They match; nothing to do */ return;
}
switch (hdw->hdw_desc->digital_control_scheme) { case PVR2_DIGITAL_SCHEME_HAUPPAUGE:
pvr2_hdw_cmd_hcw_demod_reset(hdw,digitalFl); if (cmode == PVR2_PATHWAY_ANALOG) { /* If moving to analog mode, also force the decoder to reset. If no decoder is attached, then it's ok to ignore this because if/when the decoder
attaches, it will reset itself at that time. */
pvr2_hdw_cmd_decoder_reset(hdw);
} break; case PVR2_DIGITAL_SCHEME_ONAIR: /* Supposedly we should always have the power on whether in digital or analog mode. But for now do what appears to
work... */
pvr2_hdw_cmd_onair_fe_power_ctrl(hdw,digitalFl); break; default: break;
}
staticvoid pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff)
{ /* change some GPIO data * * note: bit d7 of dir appears to control the LED, * so we shut it off here. *
*/ if (onoff) {
pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000481);
} else {
pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000401);
}
pvr2_hdw_gpio_chg_out(hdw, 0xffffffff, 0x00000000);
}
/* Stop / start video stream transport */ staticint pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
{ int ret;
/* If we're in analog mode, then just issue the usual analog
command. */ if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) { return pvr2_issue_simple_cmd(hdw,
(runFl ?
FX2CMD_STREAMING_ON :
FX2CMD_STREAMING_OFF)); /*Note: Not reached */
}
if (hdw->pathway_state != PVR2_PATHWAY_DIGITAL) { /* Whoops, we don't know what mode we're in... */ return -EINVAL;
}
/* To get here we have to be in digital mode. The mechanism here is unfortunately different for different vendors. So we switch on the device's digital scheme attribute in order to figure out
what to do. */ switch (hdw->hdw_desc->digital_control_scheme) { case PVR2_DIGITAL_SCHEME_HAUPPAUGE: return pvr2_issue_simple_cmd(hdw,
(runFl ?
FX2CMD_HCW_DTV_STREAMING_ON :
FX2CMD_HCW_DTV_STREAMING_OFF)); case PVR2_DIGITAL_SCHEME_ONAIR:
ret = pvr2_issue_simple_cmd(hdw,
(runFl ?
FX2CMD_STREAMING_ON :
FX2CMD_STREAMING_OFF)); if (ret) return ret; return pvr2_hdw_cmd_onair_digital_path_ctrl(hdw,runFl); default: return -EINVAL;
}
}
/* Evaluate whether or not state_pathway_ok can change */ staticint state_eval_pathway_ok(struct pvr2_hdw *hdw)
{ if (hdw->state_pathway_ok) { /* Nothing to do if pathway is already ok */ return 0;
} if (!hdw->state_pipeline_idle) { /* Not allowed to change anything if pipeline is not idle */ return 0;
}
pvr2_hdw_cmd_modeswitch(hdw,hdw->input_val == PVR2_CVAL_INPUT_DTV);
hdw->state_pathway_ok = !0;
trace_stbit("state_pathway_ok",hdw->state_pathway_ok); return !0;
}
/* Evaluate whether or not state_encoder_ok can change */ staticint state_eval_encoder_ok(struct pvr2_hdw *hdw)
{ if (hdw->state_encoder_ok) return 0; if (hdw->flag_tripped) return 0; if (hdw->state_encoder_run) return 0; if (hdw->state_encoder_config) return 0; if (hdw->state_decoder_run) return 0; if (hdw->state_usbstream_run) return 0; if (hdw->pathway_state == PVR2_PATHWAY_DIGITAL) { if (!hdw->hdw_desc->flag_digital_requires_cx23416) return 0;
} elseif (hdw->pathway_state != PVR2_PATHWAY_ANALOG) { return 0;
}
/* Evaluate whether or not state_encoder_config can change */ staticint state_eval_encoder_config(struct pvr2_hdw *hdw)
{ if (hdw->state_encoder_config) { if (hdw->state_encoder_ok) { if (hdw->state_pipeline_req &&
!hdw->state_pipeline_pause) return 0;
}
hdw->state_encoder_config = 0;
hdw->state_encoder_waitok = 0;
trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok); /* paranoia - solve race if timer just completed */
timer_delete_sync(&hdw->encoder_wait_timer);
} else { if (!hdw->state_pathway_ok ||
(hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
!hdw->state_encoder_ok ||
!hdw->state_pipeline_idle ||
hdw->state_pipeline_pause ||
!hdw->state_pipeline_req ||
!hdw->state_pipeline_config) { /* We must reset the enforced wait interval if anything has happened that might have disturbed
the encoder. This should be a rare case. */ if (timer_pending(&hdw->encoder_wait_timer)) {
timer_delete_sync(&hdw->encoder_wait_timer);
} if (hdw->state_encoder_waitok) { /* Must clear the state - therefore we did something to a state bit and must also
return true. */
hdw->state_encoder_waitok = 0;
trace_stbit("state_encoder_waitok",
hdw->state_encoder_waitok); return !0;
} return 0;
} if (!hdw->state_encoder_waitok) { if (!timer_pending(&hdw->encoder_wait_timer)) { /* waitok flag wasn't set and timer isn't running. Check flag once more to avoid a race then start the timer. This is the point when we measure out a minimal quiet interval before doing something to
the encoder. */ if (!hdw->state_encoder_waitok) {
hdw->encoder_wait_timer.expires =
jiffies + msecs_to_jiffies(
TIME_MSEC_ENCODER_WAIT);
add_timer(&hdw->encoder_wait_timer);
}
} /* We can't continue until we know we have been quiet for the interval measured by this
timer. */ return 0;
}
pvr2_encoder_configure(hdw); if (hdw->state_encoder_ok) hdw->state_encoder_config = !0;
}
trace_stbit("state_encoder_config",hdw->state_encoder_config); return !0;
}
/* Return true if the encoder should not be running. */ staticint state_check_disable_encoder_run(struct pvr2_hdw *hdw)
{ if (!hdw->state_encoder_ok) { /* Encoder isn't healthy at the moment, so stop it. */ return !0;
} if (!hdw->state_pathway_ok) { /* Mode is not understood at the moment (i.e. it wants to
change), so encoder must be stopped. */ return !0;
}
switch (hdw->pathway_state) { case PVR2_PATHWAY_ANALOG: if (!hdw->state_decoder_run) { /* We're in analog mode and the decoder is not running; thus the encoder should be stopped as
well. */ return !0;
} break; case PVR2_PATHWAY_DIGITAL: if (hdw->state_encoder_runok) { /* This is a funny case. We're in digital mode so really the encoder should be stopped. However if it really is running, only kill it after runok has been set. This gives a chance for the onair quirk to function (encoder must run briefly first, at least once, before onair
digital streaming can work). */ return !0;
} break; default: /* Unknown mode; so encoder should be stopped. */ return !0;
}
/* If we get here, we haven't found a reason to stop the
encoder. */ return 0;
}
/* Return true if the encoder should be running. */ staticint state_check_enable_encoder_run(struct pvr2_hdw *hdw)
{ if (!hdw->state_encoder_ok) { /* Don't run the encoder if it isn't healthy... */ return 0;
} if (!hdw->state_pathway_ok) { /* Don't run the encoder if we don't (yet) know what mode
we need to be in... */ return 0;
}
switch (hdw->pathway_state) { case PVR2_PATHWAY_ANALOG: if (hdw->state_decoder_run && hdw->state_decoder_ready) { /* In analog mode, if the decoder is running, then
run the encoder. */ return !0;
} break; case PVR2_PATHWAY_DIGITAL: if ((hdw->hdw_desc->digital_control_scheme ==
PVR2_DIGITAL_SCHEME_ONAIR) &&
!hdw->state_encoder_runok) { /* This is a quirk. OnAir hardware won't stream digital until the encoder has been run at least once, for a minimal period of time (empiricially measured to be 1/4 second). So if we're on OnAir hardware and the encoder has never been run at all, then start the encoder. Normal state machine logic in the driver will
automatically handle the remaining bits. */ return !0;
} break; default: /* For completeness (unknown mode; encoder won't run ever) */ break;
} /* If we get here, then we haven't found any reason to run the
encoder, so don't run it. */ return 0;
}
/* Evaluate whether or not state_encoder_run can change */ staticint state_eval_encoder_run(struct pvr2_hdw *hdw)
{ if (hdw->state_encoder_run) { if (!state_check_disable_encoder_run(hdw)) return 0; if (hdw->state_encoder_ok) {
timer_delete_sync(&hdw->encoder_run_timer); if (pvr2_encoder_stop(hdw) < 0) return !0;
}
hdw->state_encoder_run = 0;
} else { if (!state_check_enable_encoder_run(hdw)) return 0; if (pvr2_encoder_start(hdw) < 0) return !0;
hdw->state_encoder_run = !0; if (!hdw->state_encoder_runok) {
hdw->encoder_run_timer.expires = jiffies +
msecs_to_jiffies(TIME_MSEC_ENCODER_OK);
add_timer(&hdw->encoder_run_timer);
}
}
trace_stbit("state_encoder_run",hdw->state_encoder_run); return !0;
}
/* Timeout function for encoder run timer. */ staticvoid pvr2_hdw_encoder_run_timeout(struct timer_list *t)
{ struct pvr2_hdw *hdw = timer_container_of(hdw, t, encoder_run_timer); if (!hdw->state_encoder_runok) {
hdw->state_encoder_runok = !0;
trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
hdw->state_stale = !0;
schedule_work(&hdw->workpoll);
}
}
/* Evaluate whether or not state_decoder_run can change */ staticint state_eval_decoder_run(struct pvr2_hdw *hdw)
{ if (hdw->state_decoder_run) { if (hdw->state_encoder_ok) { if (hdw->state_pipeline_req &&
!hdw->state_pipeline_pause &&
hdw->state_pathway_ok) return 0;
} if (!hdw->flag_decoder_missed) {
pvr2_decoder_enable(hdw,0);
}
hdw->state_decoder_quiescent = 0;
hdw->state_decoder_run = 0; /* paranoia - solve race if timer(s) just completed */
timer_delete_sync(&hdw->quiescent_timer); /* Kill the stabilization timer, in case we're killing the encoder before the previous stabilization interval has
been properly timed. */
timer_delete_sync(&hdw->decoder_stabilization_timer);
hdw->state_decoder_ready = 0;
} else { if (!hdw->state_decoder_quiescent) { if (!timer_pending(&hdw->quiescent_timer)) { /* We don't do something about the quiescent timer until right here because we also want to catch cases where the decoder was already not running (like after initialization) as opposed to knowing that we had just stopped it. The second flag check is here to cover a race - the timer could have run and set this flag just after the previous check
but before we did the pending check. */ if (!hdw->state_decoder_quiescent) {
hdw->quiescent_timer.expires =
jiffies + msecs_to_jiffies(
TIME_MSEC_DECODER_WAIT);
add_timer(&hdw->quiescent_timer);
}
} /* Don't allow decoder to start again until it has been quiesced first. This little detail should
hopefully further stabilize the encoder. */ return 0;
} if (!hdw->state_pathway_ok ||
(hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
!hdw->state_pipeline_req ||
hdw->state_pipeline_pause ||
!hdw->state_pipeline_config ||
!hdw->state_encoder_config ||
!hdw->state_encoder_ok) return 0;
timer_delete_sync(&hdw->quiescent_timer); if (hdw->flag_decoder_missed) return 0; if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
hdw->state_decoder_quiescent = 0;
hdw->state_decoder_ready = 0;
hdw->state_decoder_run = !0; if (hdw->decoder_client_id == PVR2_CLIENT_ID_SAA7115) {
hdw->decoder_stabilization_timer.expires =
jiffies + msecs_to_jiffies(
TIME_MSEC_DECODER_STABILIZATION_WAIT);
add_timer(&hdw->decoder_stabilization_timer);
} else {
hdw->state_decoder_ready = !0;
}
}
trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
trace_stbit("state_decoder_run",hdw->state_decoder_run);
trace_stbit("state_decoder_ready", hdw->state_decoder_ready); return !0;
}
/* Evaluate whether or not state_usbstream_run can change */ staticint state_eval_usbstream_run(struct pvr2_hdw *hdw)
{ if (hdw->state_usbstream_run) { int fl = !0; if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
fl = (hdw->state_encoder_ok &&
hdw->state_encoder_run);
} elseif ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
(hdw->hdw_desc->flag_digital_requires_cx23416)) {
fl = hdw->state_encoder_ok;
} if (fl &&
hdw->state_pipeline_req &&
!hdw->state_pipeline_pause &&
hdw->state_pathway_ok) { return 0;
}
pvr2_hdw_cmd_usbstream(hdw,0);
hdw->state_usbstream_run = 0;
} else { if (!hdw->state_pipeline_req ||
hdw->state_pipeline_pause ||
!hdw->state_pathway_ok) return 0; if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) { if (!hdw->state_encoder_ok ||
!hdw->state_encoder_run) return 0;
} elseif ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
(hdw->hdw_desc->flag_digital_requires_cx23416)) { if (!hdw->state_encoder_ok) return 0; if (hdw->state_encoder_run) return 0; if (hdw->hdw_desc->digital_control_scheme ==
PVR2_DIGITAL_SCHEME_ONAIR) { /* OnAir digital receivers won't stream unless the analog encoder has run first. Why? I have no idea. But don't even try until we know the analog side is
known to have run. */ if (!hdw->state_encoder_runok) return 0;
}
} if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0;
hdw->state_usbstream_run = !0;
}
trace_stbit("state_usbstream_run",hdw->state_usbstream_run); return !0;
}
/* Attempt to configure pipeline, if needed */ staticint state_eval_pipeline_config(struct pvr2_hdw *hdw)
{ if (hdw->state_pipeline_config ||
hdw->state_pipeline_pause) return 0;
pvr2_hdw_commit_execute(hdw); return !0;
}
/* Update pipeline idle and pipeline pause tracking states based on other inputs. This must be called whenever the other relevant inputs have
changed. */ staticint state_update_pipeline_state(struct pvr2_hdw *hdw)
{ unsignedint st; int updatedFl = 0; /* Update pipeline state */
st = !(hdw->state_encoder_run ||
hdw->state_decoder_run ||
hdw->state_usbstream_run ||
(!hdw->state_decoder_quiescent)); if (!st != !hdw->state_pipeline_idle) {
hdw->state_pipeline_idle = st;
updatedFl = !0;
} if (hdw->state_pipeline_idle && hdw->state_pipeline_pause) {
hdw->state_pipeline_pause = 0;
updatedFl = !0;
} return updatedFl;
}
typedefint (*state_eval_func)(struct pvr2_hdw *);
/* Set of functions to be run to evaluate various states in the driver. */ staticconst state_eval_func eval_funcs[] = {
state_eval_pathway_ok,
state_eval_pipeline_config,
state_eval_encoder_ok,
state_eval_encoder_config,
state_eval_decoder_run,
state_eval_encoder_run,
state_eval_usbstream_run,
};
/* Process various states and return true if we did anything interesting. */ staticint pvr2_hdw_state_update(struct pvr2_hdw *hdw)
{ unsignedint i; int state_updated = 0; int check_flag;
if (!hdw->state_stale) return 0; if ((hdw->fw1_state != FW1_STATE_OK) ||
!hdw->flag_ok) {
hdw->state_stale = 0; return !0;
} /* This loop is the heart of the entire driver. It keeps trying to evaluate various bits of driver state until nothing changes for one full iteration. Each "bit of state" tracks some global aspect of the driver, e.g. whether decoder should run, if pipeline is configured, usb streaming is on, etc. We separately evaluate each of those questions based on other driver state to
arrive at the correct running configuration. */ do {
check_flag = 0;
state_update_pipeline_state(hdw); /* Iterate over each bit of state */ for (i = 0; (i<ARRAY_SIZE(eval_funcs)) && hdw->flag_ok; i++) { if ((*eval_funcs[i])(hdw)) {
check_flag = !0;
state_updated = !0;
state_update_pipeline_state(hdw);
}
}
} while (check_flag && hdw->flag_ok);
hdw->state_stale = 0;
trace_stbit("state_stale",hdw->state_stale); return state_updated;
}
/* Evaluate and update the driver's current state, taking various actions
as appropriate for the update. */ staticint pvr2_hdw_state_eval(struct pvr2_hdw *hdw)
{ unsignedint st; int state_updated = 0; int callback_flag = 0; int analog_mode;
pvr2_trace(PVR2_TRACE_STBITS, "Drive state check START"); if (pvrusb2_debug & PVR2_TRACE_STBITS) {
pvr2_hdw_state_log_state(hdw);
}
/* Process all state and get back over disposition */
state_updated = pvr2_hdw_state_update(hdw);
/* Update master state based upon all other states. */ if (!hdw->flag_ok) {
st = PVR2_STATE_DEAD;
} elseif (hdw->fw1_state != FW1_STATE_OK) {
st = PVR2_STATE_COLD;
} elseif ((analog_mode ||
hdw->hdw_desc->flag_digital_requires_cx23416) &&
!hdw->state_encoder_ok) {
st = PVR2_STATE_WARM;
} elseif (hdw->flag_tripped ||
(analog_mode && hdw->flag_decoder_missed)) {
st = PVR2_STATE_ERROR;
} elseif (hdw->state_usbstream_run &&
(!analog_mode ||
(hdw->state_encoder_run && hdw->state_decoder_run))) {
st = PVR2_STATE_RUN;
} else {
st = PVR2_STATE_READY;
} if (hdw->master_state != st) {
pvr2_trace(PVR2_TRACE_STATE, "Device state change from %s to %s",
pvr2_get_state_name(hdw->master_state),
pvr2_get_state_name(st));
pvr2_led_ctrl(hdw,st == PVR2_STATE_RUN);
hdw->master_state = st;
state_updated = !0;
callback_flag = !0;
} if (state_updated) { /* Trigger anyone waiting on any state changes here. */
wake_up(&hdw->state_wait_data);
}
if (pvrusb2_debug & PVR2_TRACE_STBITS) {
pvr2_hdw_state_log_state(hdw);
}
pvr2_trace(PVR2_TRACE_STBITS, "Drive state check DONE callback=%d",callback_flag);
return callback_flag;
}
/* Cause kernel thread to check / update driver state */ staticvoid pvr2_hdw_state_sched(struct pvr2_hdw *hdw)
{ if (hdw->state_stale) return;
hdw->state_stale = !0;
trace_stbit("state_stale",hdw->state_stale);
schedule_work(&hdw->workpoll);
}
int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
{ return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
}
int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
{ return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
}
int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
{ return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
}
int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
{
u32 cval,nval; int ret; if (~msk) {
ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval); if (ret) return ret;
nval = (cval & ~msk) | (val & msk);
pvr2_trace(PVR2_TRACE_GPIO, "GPIO direction changing 0x%x:0x%x from 0x%x to 0x%x",
msk,val,cval,nval);
} else {
nval = val;
pvr2_trace(PVR2_TRACE_GPIO, "GPIO direction changing to 0x%x",nval);
} return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
}
int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
{
u32 cval,nval; int ret; if (~msk) {
ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval); if (ret) return ret;
nval = (cval & ~msk) | (val & msk);
pvr2_trace(PVR2_TRACE_GPIO, "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
msk,val,cval,nval);
} else {
nval = val;
pvr2_trace(PVR2_TRACE_GPIO, "GPIO output changing to 0x%x",nval);
} return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
}
void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
{ struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
memset(vtp, 0, sizeof(*vtp));
vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
hdw->tuner_signal_stale = 0; /* Note: There apparently is no replacement for VIDIOC_CROPCAP using v4l2-subdev - therefore we can't support that AT ALL right now. (Of course, no sub-drivers seem to implement it either.
But now it's a chicken and egg problem...) */
v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner, vtp);
pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll type=%u strength=%u audio=0x%x cap=0x%x low=%u hi=%u",
vtp->type,
vtp->signal, vtp->rxsubchans, vtp->capability,
vtp->rangelow, vtp->rangehigh);
/* We have to do this to avoid getting into constant polling if
there's nobody to answer a poll of cropcap info. */
hdw->cropcap_stale = 0;
}
/* Handle side effects - if we switch to a mode that needs the RF tuner, then select the right frequency choice as well and mark
it dirty. */ if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
hdw->freqSelector = 0;
hdw->freqDirty = !0;
} elseif ((hdw->input_val == PVR2_CVAL_INPUT_TV) ||
(hdw->input_val == PVR2_CVAL_INPUT_DTV)) {
hdw->freqSelector = 1;
hdw->freqDirty = !0;
} return 0;
}
int pvr2_hdw_set_input_allowed(struct pvr2_hdw *hdw, unsignedint change_mask, unsignedint change_val)
{ int ret = 0; unsignedint nv,m,idx;
LOCK_TAKE(hdw->big_lock); do {
nv = hdw->input_allowed_mask & ~change_mask;
nv |= (change_val & change_mask);
nv &= hdw->input_avail_mask; if (!nv) { /* No legal modes left; return error instead. */
ret = -EPERM; break;
}
hdw->input_allowed_mask = nv; if ((1UL << hdw->input_val) & hdw->input_allowed_mask) { /* Current mode is still in the allowed mask, so
we're done. */ break;
} /* Select and switch to a mode that is still in the allowed
mask */ if (!hdw->input_allowed_mask) { /* Nothing legal; give up */ break;
}
m = hdw->input_allowed_mask; for (idx = 0; idx < (sizeof(m) << 3); idx++) { if (!((1UL << idx) & m)) continue;
pvr2_hdw_set_input(hdw,idx); break;
}
} while (0);
LOCK_GIVE(hdw->big_lock); return ret;
}
/* Find I2C address of eeprom */ staticint pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
{ int result;
LOCK_TAKE(hdw->ctl_lock); do {
hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
result = pvr2_send_request(hdw,
hdw->cmd_buffer,1,
hdw->cmd_buffer,1); if (result < 0) break;
result = hdw->cmd_buffer[0];
} while(0); LOCK_GIVE(hdw->ctl_lock); return result;
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.152Bemerkung:
(vorverarbeitet am 2026-04-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.