summaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/drivers
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2012-09-14 16:34:16 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-17 12:09:06 (GMT)
commit9fb5c14ceba8841ece02b5185501e1d999a2bcf6 (patch)
tree85ab8f81c0bba43a961d63ff5ace8cb5acbdafa8 /drivers/staging/comedi/drivers
parent6b26ecf0479e660e878014030b1f6e53d3787d75 (diff)
downloadlinux-fsl-qoriq-9fb5c14ceba8841ece02b5185501e1d999a2bcf6.tar.xz
staging: comedi: ni_pcidio: use request_firmware()
The PCI-6534 needs three firmware files loading to work with the driver. That is currently done by passing the firmware data using the `COMEDI_DEVCONFIG` ioctl that uses the comedi `attach()` hook in the driver. This doesn't work for auto-configured PCI devices (which also currently use the `attach()` hook in this driver, but doesn't have the firmware-loading options set in the `struct comedi_devconfig *` parameter). Change the driver to request the firmware files using `request_firmware()`, ignoring any firmware-loading options set in the `struct comedi_devconfig`. The PCI-6534 has a main FPGA which needs to be loaded first, and two "scarabs". Scarab A is loaded with firmware to support digital input mode, and scarab B is loaded with firmware to support digital output mode. I don't think the order of loading the scarab firmwares matters as long as they are loaded with the correct firmware files. This update loads scarab B first, whereas the original code loaded scarab A first. The firmware files are loaded in the following order: A) main FPGA: "ni6534a.bin" (FW_PCI_6534_MAIN) B) scarab B: "niscrb02.bin" (FW_PCI_6534_SCARAB_DO) C) scarab A: "niscrb01.bin" (FW_PCI_6534_SCARAB_DI) The required firmware files can be found in the "comedi-nonfree-firmware" tar-ball at <http://www.comedi.org/download/comedi-nonfree-firmware-2007.06.22.tar.gz>. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi/drivers')
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c61
1 files changed, 36 insertions, 25 deletions
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 4f76daf..a655ab9 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -57,6 +57,7 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/firmware.h>
#include "../comedidev.h"
#include "mite.h"
@@ -230,6 +231,14 @@ static inline unsigned secondary_DMAChannel_bits(unsigned channel)
#define Protocol_Register_8 88 /* 32 bit */
#define StartDelay Protocol_Register_8
+/* Firmware files for PCI-6524 */
+#define FW_PCI_6534_MAIN "ni6534a.bin"
+#define FW_PCI_6534_SCARAB_DI "niscrb01.bin"
+#define FW_PCI_6534_SCARAB_DO "niscrb02.bin"
+MODULE_FIRMWARE(FW_PCI_6534_MAIN);
+MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DI);
+MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DO);
+
enum pci_6534_firmware_registers { /* 16 bit */
Firmware_Control_Register = 0x100,
Firmware_Status_Register = 0x104,
@@ -977,10 +986,12 @@ static int ni_pcidio_change(struct comedi_device *dev,
}
static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
- u8 *data, int data_len)
+ const u8 *data, size_t data_len)
{
static const int timeout = 1000;
- int i, j;
+ int i;
+ size_t j;
+
writew(0x80 | fpga_index,
devpriv->mite->daq_io_addr + Firmware_Control_Register);
writew(0xc0 | fpga_index,
@@ -1062,34 +1073,34 @@ static void pci_6534_init_main_fpga(struct comedi_device *dev)
writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
}
-static int pci_6534_upload_firmware(struct comedi_device *dev, int options[])
+static int pci_6534_upload_firmware(struct comedi_device *dev)
{
int ret;
- void *main_fpga_data, *scarab_a_data, *scarab_b_data;
- int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len;
+ const struct firmware *fw;
+ static const char *const fw_file[3] = {
+ FW_PCI_6534_SCARAB_DI, /* loaded into scarab A for DI */
+ FW_PCI_6534_SCARAB_DO, /* loaded into scarab B for DO */
+ FW_PCI_6534_MAIN, /* loaded into main FPGA */
+ };
+ int n;
- if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0)
- return 0;
ret = pci_6534_reset_fpgas(dev);
if (ret < 0)
return ret;
- main_fpga_data = comedi_aux_data(options, 0);
- main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
- ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len);
- if (ret < 0)
- return ret;
- pci_6534_init_main_fpga(dev);
- scarab_a_data = comedi_aux_data(options, 1);
- scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
- ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len);
- if (ret < 0)
- return ret;
- scarab_b_data = comedi_aux_data(options, 2);
- scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
- ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len);
- if (ret < 0)
- return ret;
- return 0;
+ /* load main FPGA first, then the two scarabs */
+ for (n = 2; n >= 0; n--) {
+ ret = request_firmware(&fw, fw_file[n],
+ &devpriv->mite->pcidev->dev);
+ if (ret == 0) {
+ ret = pci_6534_load_fpga(dev, n, fw->data, fw->size);
+ if (ret == 0 && n == 2)
+ pci_6534_init_main_fpga(dev);
+ release_firmware(fw);
+ }
+ if (ret < 0)
+ break;
+ }
+ return ret;
}
static int nidio_find_device(struct comedi_device *dev, int bus, int slot)
@@ -1147,7 +1158,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->board_name = this_board->name;
irq = mite_irq(devpriv->mite);
if (this_board->uses_firmware) {
- ret = pci_6534_upload_firmware(dev, it->options);
+ ret = pci_6534_upload_firmware(dev);
if (ret < 0)
return ret;
}