/* 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 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) {
--> --------------------
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.