diff options
Diffstat (limited to 'linux/drivers/media')
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-context.c | 6 | ||||
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-debug.h | 53 | ||||
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c | 16 | ||||
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 1 | ||||
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c | 302 | ||||
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h | 12 | ||||
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 12 | ||||
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-main.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-std.c | 8 |
9 files changed, 305 insertions, 106 deletions
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-context.c b/linux/drivers/media/video/pvrusb2/pvrusb2-context.c index a7684d9d3..80e2e5ea1 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-context.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-context.c @@ -34,8 +34,10 @@ static void pvr2_context_destroy(struct pvr2_context *mp) { if (mp->hdw) pvr2_hdw_destroy(mp->hdw); pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp); - flush_workqueue(mp->workqueue); - destroy_workqueue(mp->workqueue); + if (mp->workqueue) { + flush_workqueue(mp->workqueue); + destroy_workqueue(mp->workqueue); + } kfree(mp); } diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-debug.h b/linux/drivers/media/video/pvrusb2/pvrusb2-debug.h index d95a8588e..da6441b88 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-debug.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-debug.h @@ -26,32 +26,33 @@ extern int pvrusb2_debug; /* These are listed in *rough* order of decreasing usefulness and increasing noise level. */ -#define PVR2_TRACE_INFO (1 << 0) // Normal messages -#define PVR2_TRACE_ERROR_LEGS (1 << 1) // error messages -#define PVR2_TRACE_TOLERANCE (1 << 2) // track tolerance-affected errors -#define PVR2_TRACE_TRAP (1 << 3) // Trap & report misbehavior from app -#define PVR2_TRACE_INIT (1 << 4) // misc initialization steps -#define PVR2_TRACE_START_STOP (1 << 5) // Streaming start / stop -#define PVR2_TRACE_CTL (1 << 6) // commit of control changes -#define PVR2_TRACE_DEBUG (1 << 7) // Temporary debug code -#define PVR2_TRACE_EEPROM (1 << 8) // eeprom parsing / report -#define PVR2_TRACE_STRUCT (1 << 9) // internal struct creation -#define PVR2_TRACE_OPEN_CLOSE (1 << 10) // application open / close -#define PVR2_TRACE_CREG (1 << 11) // Main critical region entry / exit -#define PVR2_TRACE_SYSFS (1 << 12) // Sysfs driven I/O -#define PVR2_TRACE_FIRMWARE (1 << 13) // firmware upload actions -#define PVR2_TRACE_CHIPS (1 << 14) // chip broadcast operation -#define PVR2_TRACE_I2C (1 << 15) // I2C related stuff -#define PVR2_TRACE_I2C_CMD (1 << 16) // Software commands to I2C modules -#define PVR2_TRACE_I2C_CORE (1 << 17) // I2C core debugging -#define PVR2_TRACE_I2C_TRAF (1 << 18) // I2C traffic through the adapter -#define PVR2_TRACE_V4LIOCTL (1 << 19) // v4l ioctl details -#define PVR2_TRACE_ENCODER (1 << 20) // mpeg2 encoder operation -#define PVR2_TRACE_BUF_POOL (1 << 21) // Track buffer pool management -#define PVR2_TRACE_BUF_FLOW (1 << 22) // Track buffer flow in system -#define PVR2_TRACE_DATA_FLOW (1 << 23) // Track data flow -#define PVR2_TRACE_DEBUGIFC (1 << 24) // Debug interface actions -#define PVR2_TRACE_GPIO (1 << 25) // GPIO state bit changes +#define PVR2_TRACE_INFO (1 << 0) /* Normal messages */ +#define PVR2_TRACE_ERROR_LEGS (1 << 1) /* error messages */ +#define PVR2_TRACE_TOLERANCE (1 << 2) /* track tolerance-affected errors */ +#define PVR2_TRACE_TRAP (1 << 3) /* Trap & report app misbehavior */ +#define PVR2_TRACE_STD (1 << 4) /* Log video standard stuff */ +#define PVR2_TRACE_INIT (1 << 5) /* misc initialization steps */ +#define PVR2_TRACE_START_STOP (1 << 6) /* Streaming start / stop */ +#define PVR2_TRACE_CTL (1 << 7) /* commit of control changes */ +#define PVR2_TRACE_DEBUG (1 << 8) /* Temporary debug code */ +#define PVR2_TRACE_EEPROM (1 << 9) /* eeprom parsing / report */ +#define PVR2_TRACE_STRUCT (1 << 10) /* internal struct creation */ +#define PVR2_TRACE_OPEN_CLOSE (1 << 11) /* application open / close */ +#define PVR2_TRACE_CREG (1 << 12) /* Main critical region entry / exit */ +#define PVR2_TRACE_SYSFS (1 << 13) /* Sysfs driven I/O */ +#define PVR2_TRACE_FIRMWARE (1 << 14) /* firmware upload actions */ +#define PVR2_TRACE_CHIPS (1 << 15) /* chip broadcast operation */ +#define PVR2_TRACE_I2C (1 << 16) /* I2C related stuff */ +#define PVR2_TRACE_I2C_CMD (1 << 17) /* Software commands to I2C modules */ +#define PVR2_TRACE_I2C_CORE (1 << 18) /* I2C core debugging */ +#define PVR2_TRACE_I2C_TRAF (1 << 19) /* I2C traffic through the adapter */ +#define PVR2_TRACE_V4LIOCTL (1 << 20) /* v4l ioctl details */ +#define PVR2_TRACE_ENCODER (1 << 21) /* mpeg2 encoder operation */ +#define PVR2_TRACE_BUF_POOL (1 << 22) /* Track buffer pool management */ +#define PVR2_TRACE_BUF_FLOW (1 << 23) /* Track buffer flow in system */ +#define PVR2_TRACE_DATA_FLOW (1 << 24) /* Track data flow */ +#define PVR2_TRACE_DEBUGIFC (1 << 25) /* Debug interface actions */ +#define PVR2_TRACE_GPIO (1 << 26) /* GPIO state bit changes */ #endif /* __PVRUSB2_HDW_INTERNAL_H */ diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index e9da9bb8f..6f135f4a2 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c @@ -397,10 +397,22 @@ static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, count -= scnt; buf += scnt; if (!wptr) return -EINVAL; if (debugifc_match_keyword(wptr,wlen,"fetch")) { - pvr2_hdw_cpufw_set_enabled(hdw,!0); + scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); + if (scnt && wptr) { + count -= scnt; buf += scnt; + if (debugifc_match_keyword(wptr,wlen,"prom")) { + pvr2_hdw_cpufw_set_enabled(hdw,!0,!0); + } else if (debugifc_match_keyword(wptr,wlen, + "ram")) { + pvr2_hdw_cpufw_set_enabled(hdw,0,!0); + } else { + return -EINVAL; + } + } + pvr2_hdw_cpufw_set_enabled(hdw,0,!0); return 0; } else if (debugifc_match_keyword(wptr,wlen,"done")) { - pvr2_hdw_cpufw_set_enabled(hdw,0); + pvr2_hdw_cpufw_set_enabled(hdw,0,0); return 0; } else { return -EINVAL; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index e8ee1bf73..d8ac8e783 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -254,6 +254,7 @@ struct pvr2_hdw { // CPU firmware info (used to help find / save firmware data) char *fw_buffer; unsigned int fw_size; + int fw_cpu_flag; /* True if we are dealing with the CPU */ // Which subsystem pieces have been enabled / configured unsigned long subsys_enabled_mask; diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 80ea51959..3b51cdef8 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -45,7 +45,7 @@ struct usb_device_id pvr2_device_table[] = { [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) }, [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) }, - { } + { USB_DEVICE(0, 0) }, }; MODULE_DEVICE_TABLE(usb, pvr2_device_table); @@ -1153,6 +1153,13 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) fw_files_24xxx, ARRAY_SIZE(fw_files_24xxx) }, }; + + if ((hdw->hdw_type >= ARRAY_SIZE(fw_file_defs)) || + (!fw_file_defs[hdw->hdw_type].lst)) { + hdw->fw1_state = FW1_STATE_OK; + return 0; + } + hdw->fw1_state = FW1_STATE_FAILED; // default result trace_firmware("pvr2_upload_firmware1"); @@ -1234,6 +1241,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) CX2341X_FIRM_ENC_FILENAME, }; + if ((hdw->hdw_type != PVR2_HDW_TYPE_29XXX) && + (hdw->hdw_type != PVR2_HDW_TYPE_24XXX)) { + return 0; + } + trace_firmware("pvr2_upload_firmware2"); ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder", @@ -1709,6 +1721,44 @@ static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw) 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. */ +const static struct 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, + }, +}; + static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) { char buf[40]; @@ -1718,7 +1768,7 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) std1 = get_default_standard(hdw); bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom); - pvr2_trace(PVR2_TRACE_INIT, + pvr2_trace(PVR2_TRACE_STD, "Supported video standard(s) reported by eeprom: %.*s", bcnt,buf); @@ -1727,7 +1777,7 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) std2 = std1 & ~hdw->std_mask_avail; if (std2) { bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2); - pvr2_trace(PVR2_TRACE_INIT, + pvr2_trace(PVR2_TRACE_STD, "Expanding supported video standards" " to include: %.*s", bcnt,buf); @@ -1738,7 +1788,7 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) if (std1) { bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1); - pvr2_trace(PVR2_TRACE_INIT, + pvr2_trace(PVR2_TRACE_STD, "Initial video standard forced to %.*s", bcnt,buf); hdw->std_mask_cur = std1; @@ -1747,12 +1797,33 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) return; } + { + unsigned int idx; + for (idx = 0; idx < ARRAY_SIZE(std_eeprom_maps); idx++) { + if (std_eeprom_maps[idx].msk ? + ((std_eeprom_maps[idx].pat ^ + hdw->std_mask_eeprom) & + std_eeprom_maps[idx].msk) : + (std_eeprom_maps[idx].pat != + hdw->std_mask_eeprom)) continue; + bcnt = pvr2_std_id_to_str(buf,sizeof(buf), + std_eeprom_maps[idx].std); + pvr2_trace(PVR2_TRACE_STD, + "Initial video standard guessed as %.*s", + bcnt,buf); + hdw->std_mask_cur = std_eeprom_maps[idx].std; + hdw->std_dirty = !0; + pvr2_hdw_internal_find_stdenum(hdw); + return; + } + } + if (hdw->std_enum_cnt > 1) { // Autoselect the first listed standard hdw->std_enum_cur = 1; hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id; hdw->std_dirty = !0; - pvr2_trace(PVR2_TRACE_INIT, + pvr2_trace(PVR2_TRACE_STD, "Initial video standard auto-selected to %s", hdw->std_defs[hdw->std_enum_cur-1].name); return; @@ -1769,29 +1840,35 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) unsigned int idx; struct pvr2_ctrl *cptr; int reloadFl = 0; - 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 ((hdw->hdw_type == PVR2_HDW_TYPE_29XXX) || + (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) { + 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) { + 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"); + if (reloadFl) { + if (pvr2_upload_firmware1(hdw) != 0) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Failure uploading firmware1"); + } + return; } - return; } hdw->fw1_state = FW1_STATE_OK; @@ -1800,17 +1877,25 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) } if (!pvr2_hdw_dev_ok(hdw)) return; - for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) { - request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]); + if (hdw->hdw_type < ARRAY_SIZE(pvr2_client_lists)) { + for (idx = 0; + idx < pvr2_client_lists[hdw->hdw_type].cnt; + idx++) { + request_module( + pvr2_client_lists[hdw->hdw_type].lst[idx]); + } } - pvr2_hdw_cmd_powerup(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; + if ((hdw->hdw_type == PVR2_HDW_TYPE_29XXX) || + (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) { + pvr2_hdw_cmd_powerup(hdw); + if (!pvr2_hdw_dev_ok(hdw)) return; - if (pvr2_upload_firmware2(hdw)){ - pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!"); - pvr2_hdw_render_useless(hdw); - return; + if (pvr2_upload_firmware2(hdw)){ + pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!"); + pvr2_hdw_render_useless(hdw); + return; + } } // This step MUST happen after the earlier powerup step. @@ -2199,6 +2284,7 @@ static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw) /* Destroy hardware interaction structure */ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) { + if (!hdw) return; pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw); if (hdw->fw_buffer) { kfree(hdw->fw_buffer); @@ -2643,7 +2729,85 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) } while (0); LOCK_GIVE(hdw->big_lock); } -void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag) + +/* 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; + unsigned int offs; + int ret; + int mode16 = 0; + unsigned pcnt,tcnt; + eeprom = kmalloc(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); + + msg[0].addr = addr; + msg[0].flags = 0; + msg[0].len = mode16 ? 2 : 1; + msg[0].buf = iadd; + msg[1].addr = addr; + msg[1].flags = I2C_M_RD; + + /* 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 */ + memset(eeprom,0,EEPROM_SIZE); + 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 prom_flag, + int enable_flag) { int ret; u16 address; @@ -2657,37 +2821,59 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag) kfree(hdw->fw_buffer); hdw->fw_buffer = NULL; hdw->fw_size = 0; - /* Now release the CPU. It will disconnect and - reconnect later. */ - pvr2_hdw_cpureset_assert(hdw,0); + if (hdw->fw_cpu_flag) { + /* Now release the CPU. It will disconnect + and reconnect later. */ + pvr2_hdw_cpureset_assert(hdw,0); + } break; } - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Preparing to suck out CPU firmware"); - hdw->fw_size = 0x2000; - hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL); - if (!hdw->fw_buffer) { - hdw->fw_size = 0; - break; - } + hdw->fw_cpu_flag = (prom_flag == 0); + if (hdw->fw_cpu_flag) { + pvr2_trace(PVR2_TRACE_FIRMWARE, + "Preparing to suck out CPU firmware"); + hdw->fw_size = 0x2000; + 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); + /* 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. */ + /* download the firmware from address 0000-1fff in 2048 + (=0x800) bytes chunk. */ - pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware"); - pipe = usb_rcvctrlpipe(hdw->usb_dev, 0); - for(address = 0; address < hdw->fw_size; address += 0x800) { - ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0, - address,0, - hdw->fw_buffer+address,0x800,HZ); - if (ret < 0) break; - } + pvr2_trace(PVR2_TRACE_FIRMWARE, + "Grabbing CPU firmware"); + pipe = usb_rcvctrlpipe(hdw->usb_dev, 0); + for(address = 0; address < hdw->fw_size; + address += 0x800) { + ret = usb_control_msg(hdw->usb_dev,pipe, + 0xa0,0xc0, + address,0, + hdw->fw_buffer+address, + 0x800,HZ); + if (ret < 0) break; + } - pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware"); + 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); } diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 772af7376..6bc05192a 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -206,11 +206,13 @@ void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *); -/* Enable / disable retrieval of CPU firmware. This must be enabled before - pvr2_hdw_cpufw_get() will function. Note that doing this may prevent - the device from running (and leaving this mode may imply a device - reset). */ -void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, int enable_flag); +/* Enable / disable retrieval of CPU firmware or prom contents. This must + be enabled before pvr2_hdw_cpufw_get() will function. Note that doing + this may prevent the device from running (and leaving this mode may + imply a device reset). */ +void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, + int prom_flag, + int enable_flag); /* Return true if we're in a mode for retrieval CPU firmware */ int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *); diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 1a9563aa5..018c5d6b7 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -464,10 +464,6 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, ret = -EINVAL; goto done; } - if ((msgs[0].flags & I2C_M_NOSTART)) { - trace_i2c("i2c refusing I2C_M_NOSTART"); - goto done; - } if (msgs[0].addr < PVR2_I2C_FUNC_CNT) { funcp = hdw->i2c_func[msgs[0].addr]; } @@ -569,14 +565,12 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, cnt = msgs[idx].len; printk(KERN_INFO "pvrusb2 i2c xfer %u/%u:" - " addr=0x%x len=%d %s%s", + " addr=0x%x len=%d %s", idx+1,num, msgs[idx].addr, cnt, (msgs[idx].flags & I2C_M_RD ? - "read" : "write"), - (msgs[idx].flags & I2C_M_NOSTART ? - " nostart" : "")); + "read" : "write")); if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) { if (cnt > 8) cnt = 8; printk(" ["); @@ -609,7 +603,7 @@ static int pvr2_i2c_control(struct i2c_adapter *adapter, static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA; + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; } static int pvr2_i2c_core_singleton(struct i2c_client *cp, diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c index e44896894..73be66dd3 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -42,6 +42,7 @@ #define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \ PVR2_TRACE_INFO| \ + PVR2_TRACE_STD| \ PVR2_TRACE_TOLERANCE| \ PVR2_TRACE_TRAP| \ 0) diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-std.c b/linux/drivers/media/video/pvrusb2/pvrusb2-std.c index 926b6bfca..dd49a60ec 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-std.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-std.c @@ -299,7 +299,7 @@ static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id) std->id = id; bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id); std->name[bcnt] = 0; - pvr2_trace(PVR2_TRACE_INIT,"Set up standard idx=%u name=%s", + pvr2_trace(PVR2_TRACE_STD,"Set up standard idx=%u name=%s", std->index,std->name); return !0; } @@ -321,11 +321,11 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, v4l2_std_id idmsk,cmsk,fmsk; struct v4l2_standard *stddefs; - if (pvrusb2_debug & PVR2_TRACE_INIT) { + if (pvrusb2_debug & PVR2_TRACE_STD) { char buf[50]; bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id); pvr2_trace( - PVR2_TRACE_INIT,"Mapping standards mask=0x%x (%.*s)", + PVR2_TRACE_STD,"Mapping standards mask=0x%x (%.*s)", (int)id,bcnt,buf); } @@ -356,7 +356,7 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, bcnt,buf); } - pvr2_trace(PVR2_TRACE_INIT,"Setting up %u unique standard(s)", + pvr2_trace(PVR2_TRACE_STD,"Setting up %u unique standard(s)", std_cnt); if (!std_cnt) return NULL; // paranoia |