V4L/DVB (8165): cx18: fix v4l-cx23418-dig.fw firmware load.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
Hans Verkuil 2008-06-28 08:03:02 -03:00 committed by Mauro Carvalho Chehab
parent c3cb4d95ae
commit f313da113f
1 changed files with 39 additions and 21 deletions

View File

@ -31,14 +31,18 @@ int cx18_av_loadfw(struct cx18 *cx)
u32 v; u32 v;
const u8 *ptr; const u8 *ptr;
int i; int i;
int retries = 0;
if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
CX18_ERR("unable to open firmware %s\n", FWFILE); CX18_ERR("unable to open firmware %s\n", FWFILE);
return -EINVAL; return -EINVAL;
} }
/* The firmware load often has byte errors, so allow for several
retries, both at byte level and at the firmware load level. */
while (retries < 5) {
cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); /* Byte 0 */ cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6);
/* Reset the Mako core (Register is undocumented.) */ /* Reset the Mako core (Register is undocumented.) */
cx18_av_write4(cx, 0x8100, 0x00010000); cx18_av_write4(cx, 0x8100, 0x00010000);
@ -50,22 +54,36 @@ int cx18_av_loadfw(struct cx18 *cx)
size = fw->size; size = fw->size;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
u32 dl_control = 0x0F000000 | ((u32)ptr[i] << 16); u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
u32 value = 0; u32 value = 0;
int retries; int retries;
for (retries = 0; retries < 5; retries++) { for (retries = 0; retries < 5; retries++) {
cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
udelay(10);
value = cx18_av_read4(cx, CXADEC_DL_CTL); value = cx18_av_read4(cx, CXADEC_DL_CTL);
if ((value & 0x3F00) == (dl_control & 0x3F00)) if (value == dl_control)
break; break;
/* Check if we can correct the byte by changing
the address. We can only write the lower
address byte of the address. */
if ((value & 0x3F00) != (dl_control & 0x3F00)) {
retries = 5;
break;
}
}
if (retries >= 5)
break;
}
if (i == size)
break;
retries++;
} }
if (retries >= 5) { if (retries >= 5) {
CX18_ERR("unable to load firmware %s\n", FWFILE); CX18_ERR("unable to load firmware %s\n", FWFILE);
release_firmware(fw); release_firmware(fw);
return -EIO; return -EIO;
} }
}
cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size); cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size);