diff options
Diffstat (limited to 'drivers/media/video/dabusb.c')
-rw-r--r-- | drivers/media/video/dabusb.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c index 8d1f8ee2a533..48f4b92a8f8b 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/media/video/dabusb.c | |||
@@ -38,9 +38,10 @@ | |||
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/usb.h> | 39 | #include <linux/usb.h> |
40 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
41 | #include <linux/firmware.h> | ||
42 | #include <linux/ihex.h> | ||
41 | 43 | ||
42 | #include "dabusb.h" | 44 | #include "dabusb.h" |
43 | #include "dabfirmware.h" | ||
44 | 45 | ||
45 | /* | 46 | /* |
46 | * Version Information | 47 | * Version Information |
@@ -297,7 +298,8 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) | |||
297 | return ret; | 298 | return ret; |
298 | } | 299 | } |
299 | /* --------------------------------------------------------------------- */ | 300 | /* --------------------------------------------------------------------- */ |
300 | static int dabusb_writemem (pdabusb_t s, int pos, unsigned char *data, int len) | 301 | static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data, |
302 | int len) | ||
301 | { | 303 | { |
302 | int ret; | 304 | int ret; |
303 | unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL); | 305 | unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL); |
@@ -324,24 +326,35 @@ static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit) | |||
324 | static int dabusb_loadmem (pdabusb_t s, const char *fname) | 326 | static int dabusb_loadmem (pdabusb_t s, const char *fname) |
325 | { | 327 | { |
326 | int ret; | 328 | int ret; |
327 | PINTEL_HEX_RECORD ptr = firmware; | 329 | const struct ihex_binrec *rec; |
330 | const struct firmware *fw; | ||
328 | 331 | ||
329 | dbg("Enter dabusb_loadmem (internal)"); | 332 | dbg("Enter dabusb_loadmem (internal)"); |
330 | 333 | ||
334 | ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev); | ||
335 | if (ret) { | ||
336 | err("Failed to load \"dabusb/firmware.fw\": %d\n", ret); | ||
337 | goto out; | ||
338 | } | ||
331 | ret = dabusb_8051_reset (s, 1); | 339 | ret = dabusb_8051_reset (s, 1); |
332 | while (ptr->Type == 0) { | ||
333 | 340 | ||
334 | dbg("dabusb_writemem: %04X %p %d)", ptr->Address, ptr->Data, ptr->Length); | 341 | for (rec = (const struct ihex_binrec *)fw->data; rec; |
342 | rec = ihex_next_binrec(rec)) { | ||
343 | dbg("dabusb_writemem: %04X %p %d)", be32_to_cpu(rec->addr), | ||
344 | rec->data, be16_to_cpu(rec->len)); | ||
335 | 345 | ||
336 | ret = dabusb_writemem (s, ptr->Address, ptr->Data, ptr->Length); | 346 | ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data, |
347 | be16_to_cpu(rec->len)); | ||
337 | if (ret < 0) { | 348 | if (ret < 0) { |
338 | err("dabusb_writemem failed (%d %04X %p %d)", ret, ptr->Address, ptr->Data, ptr->Length); | 349 | err("dabusb_writemem failed (%d %04X %p %d)", ret, |
350 | be32_to_cpu(rec->addr), rec->data, | ||
351 | be16_to_cpu(rec->len)); | ||
339 | break; | 352 | break; |
340 | } | 353 | } |
341 | ptr++; | ||
342 | } | 354 | } |
343 | ret = dabusb_8051_reset (s, 0); | 355 | ret = dabusb_8051_reset (s, 0); |
344 | 356 | release_firmware(fw); | |
357 | out: | ||
345 | dbg("dabusb_loadmem: exit"); | 358 | dbg("dabusb_loadmem: exit"); |
346 | 359 | ||
347 | return ret; | 360 | return ret; |
@@ -376,9 +389,9 @@ static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b) | |||
376 | static int dabusb_fpga_download (pdabusb_t s, const char *fname) | 389 | static int dabusb_fpga_download (pdabusb_t s, const char *fname) |
377 | { | 390 | { |
378 | pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL); | 391 | pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL); |
392 | const struct firmware *fw; | ||
379 | unsigned int blen, n; | 393 | unsigned int blen, n; |
380 | int ret; | 394 | int ret; |
381 | unsigned char *buf = bitstream; | ||
382 | 395 | ||
383 | dbg("Enter dabusb_fpga_download (internal)"); | 396 | dbg("Enter dabusb_fpga_download (internal)"); |
384 | 397 | ||
@@ -387,10 +400,16 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) | |||
387 | return -ENOMEM; | 400 | return -ENOMEM; |
388 | } | 401 | } |
389 | 402 | ||
403 | ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev); | ||
404 | if (ret) { | ||
405 | err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret); | ||
406 | return ret; | ||
407 | } | ||
408 | |||
390 | b->pipe = 1; | 409 | b->pipe = 1; |
391 | ret = dabusb_fpga_clear (s, b); | 410 | ret = dabusb_fpga_clear (s, b); |
392 | mdelay (10); | 411 | mdelay (10); |
393 | blen = buf[73] + (buf[72] << 8); | 412 | blen = fw->data[73] + (fw->data[72] << 8); |
394 | 413 | ||
395 | dbg("Bitstream len: %i", blen); | 414 | dbg("Bitstream len: %i", blen); |
396 | 415 | ||
@@ -402,7 +421,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) | |||
402 | for (n = 0; n <= blen + 60; n += 60) { | 421 | for (n = 0; n <= blen + 60; n += 60) { |
403 | // some cclks for startup | 422 | // some cclks for startup |
404 | b->size = 64; | 423 | b->size = 64; |
405 | memcpy (b->data + 4, buf + 74 + n, 60); | 424 | memcpy (b->data + 4, fw->data + 74 + n, 60); |
406 | ret = dabusb_bulk (s, b); | 425 | ret = dabusb_bulk (s, b); |
407 | if (ret < 0) { | 426 | if (ret < 0) { |
408 | err("dabusb_bulk failed."); | 427 | err("dabusb_bulk failed."); |
@@ -413,6 +432,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) | |||
413 | 432 | ||
414 | ret = dabusb_fpga_init (s, b); | 433 | ret = dabusb_fpga_init (s, b); |
415 | kfree (b); | 434 | kfree (b); |
435 | release_firmware(fw); | ||
416 | 436 | ||
417 | dbg("exit dabusb_fpga_download"); | 437 | dbg("exit dabusb_fpga_download"); |
418 | 438 | ||