Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 141463
b: refs/heads/master
c: 6742c0a
h: refs/heads/master
i:
  141461: 3ba1f55
  141459: 82a5806
  141455: b56469e
v: v3
  • Loading branch information
Bernd Porr authored and Greg Kroah-Hartman committed Apr 3, 2009
1 parent c815acc commit b3c96ef
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 85 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c28264dac4348b1514a9a0abcf0014c6b460637f
refs/heads/master: 6742c0af2ef2d8ff70e379ebf8a8541190ff44e6
168 changes: 100 additions & 68 deletions trunk/drivers/staging/comedi/drivers/usbdux.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#define DRIVER_VERSION "v2.1"
#define DRIVER_VERSION "v2.2"
#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
#define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"
/*
Expand All @@ -25,8 +25,8 @@ Driver: usbdux
Description: University of Stirling USB DAQ & INCITE Technology Limited
Devices: [ITL] USB-DUX (usbdux.o)
Author: Bernd Porr <BerndPorr@f2s.com>
Updated: 25 Nov 2007
Status: Testing
Updated: 8 Dec 2008
Status: Stable
Configuration options:
You have to upload firmware with the -i option. The
firmware is usually installed under /usr/share/usb or
Expand Down Expand Up @@ -79,6 +79,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
* 1.2: added PWM suport via EP4
* 2.0: PWM seems to be stable and is not interfering with the other functions
* 2.1: changed PWM API
* 2.2: added firmware kernel request to fix an udev problem
*
*/

Expand All @@ -94,6 +95,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
#include <linux/smp_lock.h>
#include <linux/fcntl.h>
#include <linux/compiler.h>
#include <linux/firmware.h>

#include "../comedidev.h"

Expand Down Expand Up @@ -718,31 +720,29 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
int errcode = 0;
uint8_t local_transfer_buffer[16];

if (usbduxsub->probed) {
/* 7f92 to zero */
local_transfer_buffer[0] = 0;
errcode = usb_control_msg(usbduxsub->usbdev,
/* create a pipe for a control transfer */
usb_sndctrlpipe(usbduxsub->usbdev, 0),
/* bRequest, "Firmware" */
USBDUXSUB_FIRMWARE,
/* bmRequestType */
VENDOR_DIR_OUT,
/* Value */
USBDUXSUB_CPUCS,
/* Index */
0x0000,
/* address of the transfer buffer */
local_transfer_buffer,
/* Length */
1,
/* Timeout */
EZTIMEOUT);
if (errcode < 0) {
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (start)\n");
return errcode;
}
/* 7f92 to zero */
local_transfer_buffer[0] = 0;
errcode = usb_control_msg(usbduxsub->usbdev,
/* create a pipe for a control transfer */
usb_sndctrlpipe(usbduxsub->usbdev, 0),
/* bRequest, "Firmware" */
USBDUXSUB_FIRMWARE,
/* bmRequestType */
VENDOR_DIR_OUT,
/* Value */
USBDUXSUB_CPUCS,
/* Index */
0x0000,
/* address of the transfer buffer */
local_transfer_buffer,
/* Length */
1,
/* Timeout */
EZTIMEOUT);
if (errcode < 0) {
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (start)\n");
return errcode;
}
return 0;
}
Expand All @@ -752,28 +752,27 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
int errcode = 0;

uint8_t local_transfer_buffer[16];
if (usbduxsub->probed) {
/* 7f92 to one */
local_transfer_buffer[0] = 1;
errcode = usb_control_msg(usbduxsub->usbdev,
usb_sndctrlpipe(usbduxsub->usbdev, 0),
/* bRequest, "Firmware" */
USBDUXSUB_FIRMWARE,
/* bmRequestType */
VENDOR_DIR_OUT,
/* Value */
USBDUXSUB_CPUCS,
/* Index */
0x0000, local_transfer_buffer,
/* Length */
1,
/* Timeout */
EZTIMEOUT);
if (errcode < 0) {
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (stop)\n");
return errcode;
}

/* 7f92 to one */
local_transfer_buffer[0] = 1;
errcode = usb_control_msg(usbduxsub->usbdev,
usb_sndctrlpipe(usbduxsub->usbdev, 0),
/* bRequest, "Firmware" */
USBDUXSUB_FIRMWARE,
/* bmRequestType */
VENDOR_DIR_OUT,
/* Value */
USBDUXSUB_CPUCS,
/* Index */
0x0000, local_transfer_buffer,
/* Length */
1,
/* Timeout */
EZTIMEOUT);
if (errcode < 0) {
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (stop)\n");
return errcode;
}
return 0;
}
Expand All @@ -784,13 +783,7 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
{
int errcode;

if (usbduxsub->probed) {
dev_dbg(&usbduxsub->interface->dev,
"comedi%d: usbdux: uploading %d bytes"
" to addr %d, first byte=%d.\n",
usbduxsub->comedidev->minor, len,
startAddr, local_transfer_buffer[0]);
errcode = usb_control_msg(usbduxsub->usbdev,
errcode = usb_control_msg(usbduxsub->usbdev,
usb_sndctrlpipe(usbduxsub->usbdev, 0),
/* brequest, firmware */
USBDUXSUB_FIRMWARE,
Expand All @@ -806,16 +799,12 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
len,
/* timeout */
EZTIMEOUT);
dev_dbg(&usbduxsub->interface->dev,
"comedi_: result=%d\n", errcode);
if (errcode < 0) {
dev_err(&usbduxsub->interface->dev,
"comedi_: upload failed\n");
return errcode;
}
} else {
/* no device on the bus for this index */
return -EFAULT;
dev_dbg(&usbduxsub->interface->dev,
"comedi_: result=%d\n", errcode);
if (errcode < 0) {
dev_err(&usbduxsub->interface->dev,
"comedi_: upload failed\n");
return errcode;
}
return 0;
}
Expand Down Expand Up @@ -2292,7 +2281,7 @@ static unsigned hex2unsigned(char *h)
#define FIRMWARE_MAX_LEN 0x2000

/* taken from David Brownell's fxload and adjusted for this driver */
static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
static int read_firmware(struct usbduxsub *usbduxsub, const void *firmwarePtr,
long size)
{
struct device *dev = &usbduxsub->interface->dev;
Expand Down Expand Up @@ -2399,6 +2388,34 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
return res;
}

static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
void *context)
{
struct usbduxsub *usbduxsub_tmp = context;
struct usb_device *usbdev = usbduxsub_tmp->usbdev;
int ret;

if (fw == NULL) {
dev_err(&usbdev->dev,
"Firmware complete handler without firmware!\n");
return;
}

/*
* we need to upload the firmware here because fw will be
* freed once we've left this function
*/
ret = read_firmware(usbduxsub_tmp, fw->data, fw->size);

if (ret) {
dev_err(&usbdev->dev,
"Could not upload firmware (err=%d)\n",
ret);
return;
}
comedi_usb_auto_config(usbdev, BOARDNAME);
}

/* allocate memory for the urbs and initialise them */
static int usbduxsub_probe(struct usb_interface *uinterf,
const struct usb_device_id *id)
Expand All @@ -2407,6 +2424,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
struct device *dev = &uinterf->dev;
int i;
int index;
int ret;

dev_dbg(dev, "comedi_: usbdux_: "
"finding a free structure for the usb-device\n");
Expand Down Expand Up @@ -2641,6 +2659,19 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
/* we've reached the bottom of the function */
usbduxsub[index].probed = 1;
up(&start_stop_sem);

ret = request_firmware_nowait(THIS_MODULE,
FW_ACTION_HOTPLUG,
"usbdux_firmware.hex",
&udev->dev,
usbduxsub + index,
usbdux_firmware_request_complete_handler);

if (ret) {
dev_err(dev, "Could not load firmware (err=%d)\n", ret);
return ret;
}

dev_info(dev, "comedi_: usbdux%d "
"has been successfully initialised.\n", index);
/* success */
Expand All @@ -2662,6 +2693,7 @@ static void usbduxsub_disconnect(struct usb_interface *intf)
"comedi_: BUG! called with wrong ptr!!!\n");
return;
}
comedi_usb_auto_unconfig(udev);
down(&start_stop_sem);
down(&usbduxsub_tmp->sem);
tidy_up(usbduxsub_tmp);
Expand Down
Loading

0 comments on commit b3c96ef

Please sign in to comment.