aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers/usbdux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/drivers/usbdux.c')
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c205
1 files changed, 55 insertions, 150 deletions
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 848c7ec06976..b536bba74351 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -98,10 +98,13 @@ sampling rate. If you sample two channels you get 4kHz and so on.
#include "../comedidev.h"
+#include "comedi_fc.h"
+
/* timeout for the USB-transfer in ms*/
#define BULK_TIMEOUT 1000
/* constants for "firmware" upload and download */
+#define FIRMWARE "usbdux_firmware.bin"
#define USBDUXSUB_FIRMWARE 0xA0
#define VENDOR_DIR_IN 0xC0
#define VENDOR_DIR_OUT 0x40
@@ -403,7 +406,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
/* the private structure of the subdevice is struct usbduxsub */
this_usbduxsub = this_comedidev->private;
/* subdevice which is the AD converter */
- s = this_comedidev->subdevices + SUBDEV_AD;
+ s = &this_comedidev->subdevices[SUBDEV_AD];
/* first we test if something unusual has just happened */
switch (urb->status) {
@@ -603,7 +606,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
/* the private structure of the subdevice is struct usbduxsub */
this_usbduxsub = this_comedidev->private;
- s = this_comedidev->subdevices + SUBDEV_DA;
+ s = &this_comedidev->subdevices[SUBDEV_DA];
switch (urb->status) {
case 0:
@@ -928,9 +931,9 @@ static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub)
static int usbdux_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
- int err = 0, tmp, i;
- unsigned int tmpTimer;
struct usbduxsub *this_usbduxsub = dev->private;
+ int err = 0, i;
+ unsigned int tmpTimer;
if (!(this_usbduxsub->probed))
return -ENODEV;
@@ -938,51 +941,23 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
dev_dbg(&this_usbduxsub->interface->dev,
"comedi%d: usbdux_ai_cmdtest\n", dev->minor);
- /* make sure triggers are valid */
- /* Only immediate triggers are allowed */
- tmp = cmd->start_src;
- cmd->start_src &= TRIG_NOW | TRIG_INT;
- if (!cmd->start_src || tmp != cmd->start_src)
- err++;
-
- /* trigger should happen timed */
- tmp = cmd->scan_begin_src;
- /* start a new _scan_ with a timer */
- cmd->scan_begin_src &= TRIG_TIMER;
- if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
- err++;
+ /* Step 1 : check if triggers are trivially valid */
- /* scanning is continuous */
- tmp = cmd->convert_src;
- cmd->convert_src &= TRIG_NOW;
- if (!cmd->convert_src || tmp != cmd->convert_src)
- err++;
-
- /* issue a trigger when scan is finished and start a new scan */
- tmp = cmd->scan_end_src;
- cmd->scan_end_src &= TRIG_COUNT;
- if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
- err++;
-
- /* trigger at the end of count events or not, stop condition or not */
- tmp = cmd->stop_src;
- cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
- if (!cmd->stop_src || tmp != cmd->stop_src)
- err++;
+ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
+ err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
+ err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
if (err)
return 1;
- /*
- * step 2: make sure trigger sources are unique and mutually compatible
- * note that mutual compatibility is not an issue here
- */
- if (cmd->scan_begin_src != TRIG_FOLLOW &&
- cmd->scan_begin_src != TRIG_EXT &&
- cmd->scan_begin_src != TRIG_TIMER)
- err++;
- if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
- err++;
+ /* Step 2a : make sure trigger sources are unique */
+
+ err |= cfc_check_trigger_is_unique(cmd->start_src);
+ err |= cfc_check_trigger_is_unique(cmd->stop_src);
+
+ /* Step 2b : and mutually compatible */
if (err)
return 2;
@@ -1487,8 +1462,9 @@ static int usbdux_ao_inttrig(struct comedi_device *dev,
static int usbdux_ao_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
- int err = 0, tmp;
struct usbduxsub *this_usbduxsub = dev->private;
+ int err = 0;
+ unsigned int flags;
if (!this_usbduxsub)
return -EFAULT;
@@ -1499,69 +1475,46 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev,
dev_dbg(&this_usbduxsub->interface->dev,
"comedi%d: usbdux_ao_cmdtest\n", dev->minor);
- /* make sure triggers are valid */
- /* Only immediate triggers are allowed */
- tmp = cmd->start_src;
- cmd->start_src &= TRIG_NOW | TRIG_INT;
- if (!cmd->start_src || tmp != cmd->start_src)
- err++;
+ /* Step 1 : check if triggers are trivially valid */
+
+ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
- /* trigger should happen timed */
- tmp = cmd->scan_begin_src;
- /* just now we scan also in the high speed mode every frame */
- /* this is due to ehci driver limitations */
if (0) { /* (this_usbduxsub->high_speed) */
- /* start immediately a new scan */
/* the sampling rate is set by the coversion rate */
- cmd->scan_begin_src &= TRIG_FOLLOW;
+ flags = TRIG_FOLLOW;
} else {
/* start a new scan (output at once) with a timer */
- cmd->scan_begin_src &= TRIG_TIMER;
+ flags = TRIG_TIMER;
}
- if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
- err++;
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
- /* scanning is continuous */
- tmp = cmd->convert_src;
- /* we always output at 1kHz just now all channels at once */
if (0) { /* (this_usbduxsub->high_speed) */
/*
- * in usb-2.0 only one conversion it transmitted but with 8kHz/n
+ * in usb-2.0 only one conversion it transmitted
+ * but with 8kHz/n
*/
- cmd->convert_src &= TRIG_TIMER;
+ flags = TRIG_TIMER;
} else {
- /* all conversion events happen simultaneously with a rate of
- * 1kHz/n */
- cmd->convert_src &= TRIG_NOW;
+ /*
+ * all conversion events happen simultaneously with
+ * a rate of 1kHz/n
+ */
+ flags = TRIG_NOW;
}
- if (!cmd->convert_src || tmp != cmd->convert_src)
- err++;
-
- /* issue a trigger when scan is finished and start a new scan */
- tmp = cmd->scan_end_src;
- cmd->scan_end_src &= TRIG_COUNT;
- if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
- err++;
+ err |= cfc_check_trigger_src(&cmd->convert_src, flags);
- /* trigger at the end of count events or not, stop condition or not */
- tmp = cmd->stop_src;
- cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
- if (!cmd->stop_src || tmp != cmd->stop_src)
- err++;
+ err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
if (err)
return 1;
- /*
- * step 2: make sure trigger sources are unique and mutually compatible
- * note that mutual compatibility is not an issue here
- */
- if (cmd->scan_begin_src != TRIG_FOLLOW &&
- cmd->scan_begin_src != TRIG_EXT &&
- cmd->scan_begin_src != TRIG_TIMER)
- err++;
- if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
- err++;
+ /* Step 2a : make sure trigger sources are unique */
+
+ err |= cfc_check_trigger_is_unique(cmd->start_src);
+ err |= cfc_check_trigger_is_unique(cmd->stop_src);
+
+ /* Step 2b : and mutually compatible */
if (err)
return 2;
@@ -1946,7 +1899,7 @@ static void usbduxsub_pwm_irq(struct urb *urb)
/* the private structure of the subdevice is struct usbduxsub */
this_usbduxsub = this_comedidev->private;
- s = this_comedidev->subdevices + SUBDEV_DA;
+ s = &this_comedidev->subdevices[SUBDEV_DA];
switch (urb->status) {
case 0:
@@ -2292,10 +2245,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
usbduxsub_tmp->pwm_cmd_running = 0;
}
-/* common part of attach and attach_usb */
static int usbdux_attach_common(struct comedi_device *dev,
- struct usbduxsub *udev,
- void *aux_data, int aux_len)
+ struct usbduxsub *udev)
{
int ret;
struct comedi_subdevice *s = NULL;
@@ -2305,10 +2256,6 @@ static int usbdux_attach_common(struct comedi_device *dev,
/* pointer back to the corresponding comedi device */
udev->comedidev = dev;
- /* trying to upload the firmware into the chip */
- if (aux_data)
- firmwareUpload(udev, aux_data, aux_len);
-
dev->board_name = "usbdux";
/* set number of subdevices */
@@ -2330,7 +2277,7 @@ static int usbdux_attach_common(struct comedi_device *dev,
dev->private = udev;
/* the first subdevice is the A/D converter */
- s = dev->subdevices + SUBDEV_AD;
+ s = &dev->subdevices[SUBDEV_AD];
/* the URBs get the comedi subdevice */
/* which is responsible for reading */
/* this is the subdevice which reads data */
@@ -2357,7 +2304,7 @@ static int usbdux_attach_common(struct comedi_device *dev,
s->range_table = (&range_usbdux_ai_range);
/* analog out */
- s = dev->subdevices + SUBDEV_DA;
+ s = &dev->subdevices[SUBDEV_DA];
/* analog out */
s->type = COMEDI_SUBD_AO;
/* backward pointer */
@@ -2383,7 +2330,7 @@ static int usbdux_attach_common(struct comedi_device *dev,
s->insn_write = usbdux_ao_insn_write;
/* digital I/O */
- s = dev->subdevices + SUBDEV_DIO;
+ s = &dev->subdevices[SUBDEV_DIO];
s->type = COMEDI_SUBD_DIO;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
s->n_chan = 8;
@@ -2395,7 +2342,7 @@ static int usbdux_attach_common(struct comedi_device *dev,
s->private = NULL;
/* counter */
- s = dev->subdevices + SUBDEV_COUNTER;
+ s = &dev->subdevices[SUBDEV_COUNTER];
s->type = COMEDI_SUBD_COUNTER;
s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
s->n_chan = 4;
@@ -2406,7 +2353,7 @@ static int usbdux_attach_common(struct comedi_device *dev,
if (udev->high_speed) {
/* timer / pwm */
- s = dev->subdevices + SUBDEV_PWM;
+ s = &dev->subdevices[SUBDEV_PWM];
s->type = COMEDI_SUBD_PWM;
s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
s->n_chan = 8;
@@ -2428,48 +2375,6 @@ static int usbdux_attach_common(struct comedi_device *dev,
return 0;
}
-/* is called when comedi-config is called */
-static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- int ret;
- int index;
- int i;
- void *aux_data;
- int aux_len;
-
- dev->private = NULL;
-
- aux_data = comedi_aux_data(it->options, 0);
- aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
- if (aux_data == NULL)
- aux_len = 0;
- else if (aux_len == 0)
- aux_data = NULL;
-
- down(&start_stop_sem);
- /* find a valid device which has been detected by the probe function of
- * the usb */
- index = -1;
- for (i = 0; i < NUMUSBDUX; i++) {
- if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) {
- index = i;
- break;
- }
- }
-
- if (index < 0) {
- printk(KERN_ERR
- "comedi%d: usbdux: error: attach failed, no usbdux devs connected to the usb bus.\n",
- dev->minor);
- ret = -ENODEV;
- } else
- ret = usbdux_attach_common(dev, &usbduxsub[index],
- aux_data, aux_len);
- up(&start_stop_sem);
- return ret;
-}
-
-/* is called from comedi_usb_auto_config() */
static int usbdux_attach_usb(struct comedi_device *dev,
struct usb_interface *uinterf)
{
@@ -2491,7 +2396,7 @@ static int usbdux_attach_usb(struct comedi_device *dev,
dev->minor);
ret = -ENODEV;
} else
- ret = usbdux_attach_common(dev, this_usbduxsub, NULL, 0);
+ ret = usbdux_attach_common(dev, this_usbduxsub);
up(&start_stop_sem);
return ret;
}
@@ -2512,9 +2417,8 @@ static void usbdux_detach(struct comedi_device *dev)
static struct comedi_driver usbdux_driver = {
.driver_name = "usbdux",
.module = THIS_MODULE,
- .attach = usbdux_attach,
- .detach = usbdux_detach,
.attach_usb = usbdux_attach_usb,
+ .detach = usbdux_detach,
};
static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
@@ -2791,7 +2695,7 @@ static int usbdux_usb_probe(struct usb_interface *uinterf,
ret = request_firmware_nowait(THIS_MODULE,
FW_ACTION_HOTPLUG,
- "usbdux_firmware.bin",
+ FIRMWARE,
&udev->dev,
GFP_KERNEL,
usbduxsub + index,
@@ -2850,3 +2754,4 @@ module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE);