aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH Hartley Sweeten <hartleys@visionengravers.com>2012-09-19 19:21:29 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-21 12:24:16 -0400
commit1e12ca3407850641fc72adb620eee8a8e6dd8c90 (patch)
tree5ba3851762c8df597d73d2ac8366fbacffd22d6f
parent5a0f2260897621cc0118cd16801b171acd06c31c (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.c61
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
45The 2600 requires a firmware upload, which can be accomplished
46using the -i or --init-data option of comedi_config.
47The firmware can be
48found in the comedi_nonfree_firmware tarball available
49from 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 */
526static int me2600_xilinx_download(struct comedi_device *dev, 520static 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
587static 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 */
594static int me_reset(struct comedi_device *dev) 604static 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);
851MODULE_AUTHOR("Comedi http://www.comedi.org"); 851MODULE_AUTHOR("Comedi http://www.comedi.org");
852MODULE_DESCRIPTION("Comedi low-level driver"); 852MODULE_DESCRIPTION("Comedi low-level driver");
853MODULE_LICENSE("GPL"); 853MODULE_LICENSE("GPL");
854MODULE_FIRMWARE(ME2600_FIRMWARE);