diff options
author | H Hartley Sweeten <hartleys@visionengravers.com> | 2012-09-19 19:21:29 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-21 12:24:16 -0400 |
commit | 1e12ca3407850641fc72adb620eee8a8e6dd8c90 (patch) | |
tree | 5ba3851762c8df597d73d2ac8366fbacffd22d6f | |
parent | 5a0f2260897621cc0118cd16801b171acd06c31c (diff) |
staging: comedi: me_daq: use request_firmware()
This driver requires loading a firmware file for the fpga. This
is currently being done by passing the firmware data using the
COMEDI_DEVCONFIG ioctl through the attach() hook in the driver.
This does not work for auto-configured PCI devices due to the
firmware loading options not being set in the comedi_devconfig
parameter passed to the driver.
Change the driver so it gets the firmware using request_firmware()
and ignore any firmware options passed in the comedi_devconfig.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/comedi/drivers/me_daq.c | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index c68c407feb56..eeb493d12a05 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c | |||
@@ -41,20 +41,14 @@ Configuration options: | |||
41 | 41 | ||
42 | If bus/slot is not specified, the first available PCI | 42 | If bus/slot is not specified, the first available PCI |
43 | device will be used. | 43 | device will be used. |
44 | |||
45 | The 2600 requires a firmware upload, which can be accomplished | ||
46 | using the -i or --init-data option of comedi_config. | ||
47 | The firmware can be | ||
48 | found in the comedi_nonfree_firmware tarball available | ||
49 | from http://www.comedi.org | ||
50 | |||
51 | */ | 44 | */ |
52 | 45 | ||
53 | #include <linux/interrupt.h> | 46 | #include <linux/interrupt.h> |
54 | #include <linux/sched.h> | 47 | #include <linux/sched.h> |
48 | #include <linux/firmware.h> | ||
55 | #include "../comedidev.h" | 49 | #include "../comedidev.h" |
56 | 50 | ||
57 | /*#include "me2600_fw.h" */ | 51 | #define ME2600_FIRMWARE "me2600_firmware.bin" |
58 | 52 | ||
59 | #define ME_DRIVER_NAME "me_daq" | 53 | #define ME_DRIVER_NAME "me_daq" |
60 | 54 | ||
@@ -524,8 +518,7 @@ static int me_ao_insn_read(struct comedi_device *dev, | |||
524 | 518 | ||
525 | /* Xilinx firmware download for card: ME-2600i */ | 519 | /* Xilinx firmware download for card: ME-2600i */ |
526 | static int me2600_xilinx_download(struct comedi_device *dev, | 520 | static int me2600_xilinx_download(struct comedi_device *dev, |
527 | unsigned char *me2600_firmware, | 521 | const u8 *data, size_t size) |
528 | unsigned int length) | ||
529 | { | 522 | { |
530 | unsigned int value; | 523 | unsigned int value; |
531 | unsigned int file_length; | 524 | unsigned int file_length; |
@@ -552,19 +545,20 @@ static int me2600_xilinx_download(struct comedi_device *dev, | |||
552 | * Byte 8-11: date | 545 | * Byte 8-11: date |
553 | * Byte 12-15: reserved | 546 | * Byte 12-15: reserved |
554 | */ | 547 | */ |
555 | if (length < 16) | 548 | if (size < 16) |
556 | return -EINVAL; | 549 | return -EINVAL; |
557 | file_length = (((unsigned int)me2600_firmware[0] & 0xff) << 24) + | 550 | |
558 | (((unsigned int)me2600_firmware[1] & 0xff) << 16) + | 551 | file_length = (((unsigned int)data[0] & 0xff) << 24) + |
559 | (((unsigned int)me2600_firmware[2] & 0xff) << 8) + | 552 | (((unsigned int)data[1] & 0xff) << 16) + |
560 | ((unsigned int)me2600_firmware[3] & 0xff); | 553 | (((unsigned int)data[2] & 0xff) << 8) + |
554 | ((unsigned int)data[3] & 0xff); | ||
561 | 555 | ||
562 | /* | 556 | /* |
563 | * Loop for writing firmware byte by byte to xilinx | 557 | * Loop for writing firmware byte by byte to xilinx |
564 | * Firmware data start at offfset 16 | 558 | * Firmware data start at offfset 16 |
565 | */ | 559 | */ |
566 | for (i = 0; i < file_length; i++) | 560 | for (i = 0; i < file_length; i++) |
567 | writeb((me2600_firmware[16 + i] & 0xff), | 561 | writeb((data[16 + i] & 0xff), |
568 | dev_private->me_regbase + 0x0); | 562 | dev_private->me_regbase + 0x0); |
569 | 563 | ||
570 | /* Write 5 dummy values to xilinx */ | 564 | /* Write 5 dummy values to xilinx */ |
@@ -590,6 +584,22 @@ static int me2600_xilinx_download(struct comedi_device *dev, | |||
590 | return 0; | 584 | return 0; |
591 | } | 585 | } |
592 | 586 | ||
587 | static int me2600_upload_firmware(struct comedi_device *dev) | ||
588 | { | ||
589 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); | ||
590 | const struct firmware *fw; | ||
591 | int ret; | ||
592 | |||
593 | ret = request_firmware(&fw, ME2600_FIRMWARE, &pcidev->dev); | ||
594 | if (ret) | ||
595 | return ret; | ||
596 | |||
597 | ret = me2600_xilinx_download(dev, fw->data, fw->size); | ||
598 | release_firmware(fw); | ||
599 | |||
600 | return ret; | ||
601 | } | ||
602 | |||
593 | /* Reset device */ | 603 | /* Reset device */ |
594 | static int me_reset(struct comedi_device *dev) | 604 | static int me_reset(struct comedi_device *dev) |
595 | { | 605 | { |
@@ -735,23 +745,13 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
735 | dev->minor); | 745 | dev->minor); |
736 | return -ENOMEM; | 746 | return -ENOMEM; |
737 | } | 747 | } |
748 | |||
738 | /* Download firmware and reset card */ | 749 | /* Download firmware and reset card */ |
739 | if (board->device_id == ME2600_DEVICE_ID) { | 750 | if (board->device_id == ME2600_DEVICE_ID) { |
740 | unsigned char *aux_data; | 751 | result = me2600_upload_firmware(dev); |
741 | int aux_len; | 752 | if (result < 0) |
742 | 753 | return result; | |
743 | aux_data = comedi_aux_data(it->options, 0); | ||
744 | aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; | ||
745 | |||
746 | if (!aux_data || aux_len < 1) { | ||
747 | comedi_error(dev, "You must provide me2600 firmware " | ||
748 | "using the --init-data option of " | ||
749 | "comedi_config"); | ||
750 | return -EINVAL; | ||
751 | } | ||
752 | me2600_xilinx_download(dev, aux_data, aux_len); | ||
753 | } | 754 | } |
754 | |||
755 | me_reset(dev); | 755 | me_reset(dev); |
756 | 756 | ||
757 | error = comedi_alloc_subdevices(dev, 3); | 757 | error = comedi_alloc_subdevices(dev, 3); |
@@ -851,3 +851,4 @@ module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver); | |||
851 | MODULE_AUTHOR("Comedi http://www.comedi.org"); | 851 | MODULE_AUTHOR("Comedi http://www.comedi.org"); |
852 | MODULE_DESCRIPTION("Comedi low-level driver"); | 852 | MODULE_DESCRIPTION("Comedi low-level driver"); |
853 | MODULE_LICENSE("GPL"); | 853 | MODULE_LICENSE("GPL"); |
854 | MODULE_FIRMWARE(ME2600_FIRMWARE); | ||