Commit 1e12ca34 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

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: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5a0f2260
...@@ -41,20 +41,14 @@ Configuration options: ...@@ -41,20 +41,14 @@ Configuration options:
If bus/slot is not specified, the first available PCI If bus/slot is not specified, the first available PCI
device will be used. device will be used.
The 2600 requires a firmware upload, which can be accomplished
using the -i or --init-data option of comedi_config.
The firmware can be
found in the comedi_nonfree_firmware tarball available
from http://www.comedi.org
*/ */
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/firmware.h>
#include "../comedidev.h" #include "../comedidev.h"
/*#include "me2600_fw.h" */ #define ME2600_FIRMWARE "me2600_firmware.bin"
#define ME_DRIVER_NAME "me_daq" #define ME_DRIVER_NAME "me_daq"
...@@ -524,8 +518,7 @@ static int me_ao_insn_read(struct comedi_device *dev, ...@@ -524,8 +518,7 @@ static int me_ao_insn_read(struct comedi_device *dev,
/* Xilinx firmware download for card: ME-2600i */ /* Xilinx firmware download for card: ME-2600i */
static int me2600_xilinx_download(struct comedi_device *dev, static int me2600_xilinx_download(struct comedi_device *dev,
unsigned char *me2600_firmware, const u8 *data, size_t size)
unsigned int length)
{ {
unsigned int value; unsigned int value;
unsigned int file_length; unsigned int file_length;
...@@ -552,19 +545,20 @@ static int me2600_xilinx_download(struct comedi_device *dev, ...@@ -552,19 +545,20 @@ static int me2600_xilinx_download(struct comedi_device *dev,
* Byte 8-11: date * Byte 8-11: date
* Byte 12-15: reserved * Byte 12-15: reserved
*/ */
if (length < 16) if (size < 16)
return -EINVAL; return -EINVAL;
file_length = (((unsigned int)me2600_firmware[0] & 0xff) << 24) +
(((unsigned int)me2600_firmware[1] & 0xff) << 16) + file_length = (((unsigned int)data[0] & 0xff) << 24) +
(((unsigned int)me2600_firmware[2] & 0xff) << 8) + (((unsigned int)data[1] & 0xff) << 16) +
((unsigned int)me2600_firmware[3] & 0xff); (((unsigned int)data[2] & 0xff) << 8) +
((unsigned int)data[3] & 0xff);
/* /*
* Loop for writing firmware byte by byte to xilinx * Loop for writing firmware byte by byte to xilinx
* Firmware data start at offfset 16 * Firmware data start at offfset 16
*/ */
for (i = 0; i < file_length; i++) for (i = 0; i < file_length; i++)
writeb((me2600_firmware[16 + i] & 0xff), writeb((data[16 + i] & 0xff),
dev_private->me_regbase + 0x0); dev_private->me_regbase + 0x0);
/* Write 5 dummy values to xilinx */ /* Write 5 dummy values to xilinx */
...@@ -590,6 +584,22 @@ static int me2600_xilinx_download(struct comedi_device *dev, ...@@ -590,6 +584,22 @@ static int me2600_xilinx_download(struct comedi_device *dev,
return 0; return 0;
} }
static int me2600_upload_firmware(struct comedi_device *dev)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct firmware *fw;
int ret;
ret = request_firmware(&fw, ME2600_FIRMWARE, &pcidev->dev);
if (ret)
return ret;
ret = me2600_xilinx_download(dev, fw->data, fw->size);
release_firmware(fw);
return ret;
}
/* Reset device */ /* Reset device */
static int me_reset(struct comedi_device *dev) static int me_reset(struct comedi_device *dev)
{ {
...@@ -735,23 +745,13 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -735,23 +745,13 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->minor); dev->minor);
return -ENOMEM; return -ENOMEM;
} }
/* Download firmware and reset card */ /* Download firmware and reset card */
if (board->device_id == ME2600_DEVICE_ID) { if (board->device_id == ME2600_DEVICE_ID) {
unsigned char *aux_data; result = me2600_upload_firmware(dev);
int aux_len; if (result < 0)
return result;
aux_data = comedi_aux_data(it->options, 0);
aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
if (!aux_data || aux_len < 1) {
comedi_error(dev, "You must provide me2600 firmware "
"using the --init-data option of "
"comedi_config");
return -EINVAL;
}
me2600_xilinx_download(dev, aux_data, aux_len);
} }
me_reset(dev); me_reset(dev);
error = comedi_alloc_subdevices(dev, 3); error = comedi_alloc_subdevices(dev, 3);
...@@ -851,3 +851,4 @@ module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver); ...@@ -851,3 +851,4 @@ module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_FIRMWARE(ME2600_FIRMWARE);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment