summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-context.c6
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-debug.h53
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-debugifc.c16
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h1
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c302
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h12
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c12
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-main.c1
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-std.c8
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