]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/staging/comedi/drivers/usbdux.c
staging: comedi: drivers: use comedi_fc.h cmdtest helpers
[karo-tx-linux.git] / drivers / staging / comedi / drivers / usbdux.c
index 848c7ec06976dfdebb68fdea580e6fc1333ede33..b536bba74351178f6ae939f666ab4b7c4781bb78 100644 (file)
@@ -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);