50 #include <linux/kernel.h>
51 #include <linux/module.h>
53 #include <linux/slab.h>
54 #include <linux/input.h>
56 #include <linux/fcntl.h>
57 #include <linux/compiler.h>
60 #include "../comedidev.h"
63 #define BULK_TIMEOUT 1000
66 #define FIRMWARE "usbduxsigma_firmware.bin"
67 #define USBDUXSUB_FIRMWARE 0xA0
68 #define VENDOR_DIR_IN 0xC0
69 #define VENDOR_DIR_OUT 0x40
72 #define USBDUXSUB_CPUCS 0xE600
79 #define USBDUXSUB_MINOR 32
91 #define COMMAND_OUT_EP 1
94 #define COMMAND_IN_EP 8
100 #define MIN_PWM_PERIOD ((long)(1E9/300))
103 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
106 #define NUMCHANNELS 16
109 #define SIZEADIN ((sizeof(int32_t)))
115 #define SIZEINBUF (((NUMCHANNELS+1)*SIZEADIN))
118 #define SIZEINSNBUF 16
121 #define NUMOUTCHANNELS 8
124 #define SIZEDAOUT ((sizeof(uint8_t)+sizeof(int16_t)))
131 #define SIZEOUTBUF ((8*SIZEDAOUT))
137 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
140 #define NUMOFINBUFFERSFULL 5
143 #define NUMOFOUTBUFFERSFULL 5
147 #define NUMOFINBUFFERSHIGH 10
151 #define NUMOFOUTBUFFERSHIGH 10
173 static const struct comedi_lrange range_usbdux_ai_range = { 1, {
179 static const struct comedi_lrange range_usbdux_ao_range = { 1, {
199 struct usb_device *
usbdev;
270 static int usbduxsub_unlink_InURBs(
struct usbduxsub *usbduxsub_tmp)
275 if (usbduxsub_tmp && usbduxsub_tmp->
urbIn) {
277 if (usbduxsub_tmp->
urbIn[i]) {
283 "comedi: usbdux: unlinked InURB %d, err=%d\n",
295 static int usbdux_ai_stop(
struct usbduxsub *this_usbduxsub,
int do_unlink)
299 if (!this_usbduxsub) {
300 pr_err(
"comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
307 ret = usbduxsub_unlink_InURBs(this_usbduxsub);
334 if (!(this_usbduxsub->
probed)) {
335 up(&this_usbduxsub->
sem);
339 res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->
ai_cmd_running);
340 up(&this_usbduxsub->
sem);
345 static void usbduxsub_ai_IsocIrq(
struct urb *
urb)
352 unsigned int dio_state;
355 this_comedidev = urb->context;
357 this_usbduxsub = this_comedidev->
private;
362 switch (urb->status) {
373 "comedi%d: usbdux: CRC error in ISO IN stream.\n",
390 usbdux_ai_stop(this_usbduxsub, 0);
399 "Non-zero urb status received in ai intr "
400 "context: %d\n", urb->status);
405 usbdux_ai_stop(this_usbduxsub, 0);
422 urb->dev = this_usbduxsub->
usbdev;
428 "comedi_: urb resubmit failed in int-context!"
433 "buggy USB host controller or bug in IRQ "
439 usbdux_ai_stop(this_usbduxsub, 0);
460 usbdux_ai_stop(this_usbduxsub, 0);
468 n = s->
async->cmd.chanlist_len;
469 for (i = 0; i <
n; i++) {
480 usbdux_ai_stop(this_usbduxsub, 0);
489 static int usbduxsub_unlink_OutURBs(
struct usbduxsub *usbduxsub_tmp)
494 if (usbduxsub_tmp && usbduxsub_tmp->
urbOut) {
496 if (usbduxsub_tmp->
urbOut[i])
500 "comedi: usbdux: unlinked OutURB %d: res=%d\n",
510 static int usbdux_ao_stop(
struct usbduxsub *this_usbduxsub,
int do_unlink)
519 ret = usbduxsub_unlink_OutURBs(this_usbduxsub);
538 if (!(this_usbduxsub->
probed)) {
539 up(&this_usbduxsub->
sem);
543 res = usbdux_ao_stop(this_usbduxsub, this_usbduxsub->
ao_cmd_running);
544 up(&this_usbduxsub->
sem);
548 static void usbduxsub_ao_IsocIrq(
struct urb *urb)
557 this_comedidev = urb->context;
559 this_usbduxsub = this_comedidev->
private;
563 switch (urb->status) {
577 usbdux_ao_stop(this_usbduxsub, 0);
585 "comedi_: Non-zero urb status received in ao "
586 "intr context: %d\n", urb->status);
591 usbdux_ao_stop(this_usbduxsub, 0);
612 usbdux_ao_stop(this_usbduxsub, 0);
620 ((
uint8_t *) (urb->transfer_buffer))[0] =
621 s->
async->cmd.chanlist_len;
622 for (i = 0; i < s->
async->cmd.chanlist_len; i++) {
629 (&(((
uint8_t *) urb->transfer_buffer)[i * 2 + 1]));
638 "comedi: buffer underflow\n");
648 urb->dev = this_usbduxsub->
usbdev;
658 urb->number_of_packets = 1;
659 urb->iso_frame_desc[0].offset = 0;
661 urb->iso_frame_desc[0].status = 0;
665 "comedi_: ao urb resubm failed in int-cont. "
669 "buggy USB host controller or bug in "
676 usbdux_ao_stop(this_usbduxsub, 0);
684 uint8_t local_transfer_buffer[16];
687 local_transfer_buffer[0] = 0;
690 usb_sndctrlpipe(usbduxsub->
usbdev, 0),
700 local_transfer_buffer,
707 "comedi_: control msg failed (start)\n");
713 static int usbduxsub_stop(
struct usbduxsub *usbduxsub)
717 uint8_t local_transfer_buffer[16];
720 local_transfer_buffer[0] = 1;
722 usb_sndctrlpipe(usbduxsub->
usbdev, 0),
730 0x0000, local_transfer_buffer,
737 "comedi_: control msg failed (stop)\n");
743 static int usbduxsub_upload(
struct usbduxsub *usbduxsub,
744 uint8_t *local_transfer_buffer,
745 unsigned int startAddr,
unsigned int len)
750 usb_sndctrlpipe(usbduxsub->
usbdev, 0),
760 local_transfer_buffer,
768 "comedi_: upload failed\n");
775 #define FIRMWARE_MAX_LEN 0x4000
777 static int firmwareUpload(
struct usbduxsub *usbduxsub,
778 const u8 *firmwareBinary,
int sizeFirmware)
788 "usbduxsigma firmware binary it too large for FX2.\n");
796 "comedi_: mem alloc for firmware failed\n");
800 ret = usbduxsub_stop(usbduxsub);
803 "comedi_: can not stop firmware\n");
808 ret = usbduxsub_upload(usbduxsub, fwBuf, 0, sizeFirmware);
811 "comedi_: firmware upload failed\n");
815 ret = usbduxsub_start(usbduxsub);
818 "comedi_: can not start firmware\n");
826 static int usbduxsub_submit_InURBs(
struct usbduxsub *usbduxsub)
839 usbduxsub->
urbIn[
i]->status = 0;
840 usbduxsub->
urbIn[
i]->transfer_flags = URB_ISO_ASAP;
842 "comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n",
844 (usbduxsub->
urbIn[i]->context),
845 (usbduxsub->
urbIn[i]->dev),
846 (usbduxsub->
urbIn[i]->interval));
850 "comedi_: ai: usb_submit_urb(%d) error %d\n",
858 static int usbduxsub_submit_OutURBs(
struct usbduxsub *usbduxsub)
867 "comedi_: submitting out-urb[%d]\n", i);
871 usbduxsub->
urbOut[
i]->status = 0;
872 usbduxsub->
urbOut[
i]->transfer_flags = URB_ISO_ASAP;
876 "comedi_: ao: usb_submit_urb(%d) error %d\n",
884 static int chanToInterval(
int nChannels)
900 struct usbduxsub *this_usbduxsub = dev->
private;
902 unsigned int tmpTimer;
904 if (!(this_usbduxsub->
probed))
908 "comedi%d: usbdux_ai_cmdtest\n", dev->
minor);
923 err |= cfc_check_trigger_is_unique(cmd->
start_src);
924 err |= cfc_check_trigger_is_unique(cmd->
stop_src);
1011 static void create_adc_command(
unsigned int chan,
1016 (*muxsg0) = (*muxsg0) | (1 << chan);
1018 (*muxsg1) = (*muxsg1) | (1 << (chan-8));
1024 #define SENDADCOMMANDS 0
1025 #define SENDDACOMMANDS 1
1026 #define SENDDIOCONFIGCOMMAND 2
1027 #define SENDDIOBITSCOMMAND 3
1028 #define SENDSINGLEAD 4
1030 #define SENDPWMOFF 8
1032 static int send_dux_commands(
struct usbduxsub *this_usbduxsub,
int cmd_type)
1037 #ifdef NOISY_DUX_DEBUGBUG
1045 usb_sndbulkpipe(this_usbduxsub->
usbdev,
1051 "could not transmit dux_command to the usb-device, "
1052 "err=%d\n", this_usbduxsub->
comedidev->minor, result);
1057 static int receive_dux_commands(
struct usbduxsub *this_usbduxsub,
int command)
1063 for (i = 0; i <
RETRIES; i++) {
1065 usb_rcvbulkpipe(this_usbduxsub->
usbdev,
1071 "insn: USB error %d "
1072 "while receiving DUX command"
1077 if (this_usbduxsub->
insnBuffer[0] == command)
1083 "wrong data returned from firmware: want %d, got %d.\n",
1084 this_usbduxsub->
comedidev->minor, command,
1093 struct usbduxsub *this_usbduxsub = dev->
private;
1094 if (!this_usbduxsub)
1098 if (!(this_usbduxsub->
probed)) {
1099 up(&this_usbduxsub->
sem);
1103 "comedi%d: usbdux_ai_inttrig\n", dev->
minor);
1107 "comedi%d: usbdux_ai_inttrig: invalid trignum\n",
1109 up(&this_usbduxsub->
sem);
1114 ret = usbduxsub_submit_InURBs(this_usbduxsub);
1117 "comedi%d: usbdux_ai_inttrig: "
1118 "urbSubmit: err=%d\n", dev->
minor, ret);
1120 up(&this_usbduxsub->
sem);
1126 "comedi%d: ai_inttrig but acqu is already running\n",
1129 up(&this_usbduxsub->
sem);
1138 struct usbduxsub *this_usbduxsub = dev->
private;
1144 if (!this_usbduxsub)
1148 "comedi%d: usbdux_ai_cmd\n", dev->
minor);
1153 if (!(this_usbduxsub->
probed)) {
1154 up(&this_usbduxsub->
sem);
1159 "ai_cmd not possible. Another ai_cmd is running.\n",
1161 up(&this_usbduxsub->
sem);
1165 s->
async->cur_chan = 0;
1181 create_adc_command(chan, &muxsg0, &muxsg1);
1184 "comedi%d: channel list too long\n",
1194 "comedi %d: sending commands to the usb device: size=%u\n",
1199 up(&this_usbduxsub->
sem);
1219 if (this_usbduxsub->
ai_timer < 1) {
1221 "timer=%d, scan_begin_arg=%d. "
1222 "Not properly tested by cmdtest?\n", dev->
minor,
1224 up(&this_usbduxsub->
sem);
1242 ret = usbduxsub_submit_InURBs(this_usbduxsub);
1246 up(&this_usbduxsub->
sem);
1254 s->
async->inttrig = usbdux_ai_inttrig;
1256 up(&this_usbduxsub->
sem);
1269 struct usbduxsub *this_usbduxsub = dev->
private;
1274 if (!this_usbduxsub)
1278 "comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
1282 if (!(this_usbduxsub->
probed)) {
1283 up(&this_usbduxsub->
sem);
1288 "comedi%d: ai_insn_read not possible. "
1289 "Async Command is running.\n", dev->
minor);
1290 up(&this_usbduxsub->
sem);
1305 create_adc_command(chan, &muxsg0, &muxsg1);
1314 up(&this_usbduxsub->
sem);
1318 for (i = 0; i < insn->
n; i++) {
1319 err = receive_dux_commands(this_usbduxsub,
SENDSINGLEAD);
1321 up(&this_usbduxsub->
sem);
1328 one = one & 0x00ffffff;
1330 one = one ^ 0x00800000;
1333 up(&this_usbduxsub->
sem);
1340 static int usbdux_getstatusinfo(
struct comedi_device *dev,
int chan)
1342 struct usbduxsub *this_usbduxsub = dev->
private;
1347 if (!this_usbduxsub)
1352 "comedi%d: status read not possible. "
1353 "Async Command is running.\n", dev->
minor);
1368 sysred = sysred | 1;
1369 }
else if (chan == 2) {
1371 sysred = sysred | 4;
1372 }
else if (chan == 3) {
1374 sysred = sysred | 8;
1375 }
else if (chan == 4) {
1377 sysred = sysred | 16;
1378 }
else if (chan == 5) {
1380 sysred = sysred | 32;
1392 err = receive_dux_commands(this_usbduxsub,
SENDSINGLEAD);
1399 one = one & 0x00ffffff;
1400 one = one ^ 0x00800000;
1419 struct usbduxsub *this_usbduxsub = dev->
private;
1421 if (!this_usbduxsub)
1425 if (!(this_usbduxsub->
probed)) {
1426 up(&this_usbduxsub->
sem);
1429 for (i = 0; i < insn->
n; i++)
1430 data[i] = this_usbduxsub->
outBuffer[chan];
1432 up(&this_usbduxsub->
sem);
1442 struct usbduxsub *this_usbduxsub = dev->
private;
1444 if (!this_usbduxsub)
1448 "comedi%d: ao_insn_write\n", dev->
minor);
1451 if (!(this_usbduxsub->
probed)) {
1452 up(&this_usbduxsub->
sem);
1457 "comedi%d: ao_insn_write: "
1458 "ERROR: asynchronous ao_cmd is running\n", dev->
minor);
1459 up(&this_usbduxsub->
sem);
1463 for (i = 0; i < insn->
n; i++) {
1465 "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
1466 dev->
minor, chan, i, data[i]);
1476 up(&this_usbduxsub->
sem);
1480 up(&this_usbduxsub->
sem);
1489 struct usbduxsub *this_usbduxsub = dev->
private;
1491 if (!this_usbduxsub)
1496 if (!(this_usbduxsub->
probed)) {
1502 "comedi%d: usbdux_ao_inttrig: invalid trignum\n",
1509 ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1512 "comedi%d: usbdux_ao_inttrig: submitURB: "
1513 "err=%d\n", dev->
minor, ret);
1520 "comedi%d: ao_inttrig but acqu is already running.\n",
1525 up(&this_usbduxsub->
sem);
1533 struct usbduxsub *this_usbduxsub = dev->
private;
1537 if (!this_usbduxsub)
1540 if (!(this_usbduxsub->
probed))
1544 "comedi%d: usbdux_ao_cmdtest\n", dev->
minor);
1571 err |= cfc_check_trigger_is_unique(cmd->
start_src);
1572 err |= cfc_check_trigger_is_unique(cmd->
stop_src);
1626 "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, "
1639 unsigned int chan,
gain;
1641 struct usbduxsub *this_usbduxsub = dev->
private;
1643 if (!this_usbduxsub)
1647 if (!(this_usbduxsub->
probed)) {
1648 up(&this_usbduxsub->
sem);
1652 "comedi%d: %s\n", dev->
minor, __func__);
1655 s->
async->cur_chan = 0;
1661 "comedi%d: %s: channel list too long\n",
1662 dev->
minor, __func__);
1667 "comedi%d: dac command for ch %d is %x\n",
1682 "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
1683 "convert_src=%d, convert_arg=%d\n", dev->
minor,
1687 "comedi%d: ao_timer=%d (ms)\n",
1689 if (this_usbduxsub->
ao_timer < 1) {
1691 "comedi%d: usbdux: ao_timer=%d, "
1692 "scan_begin_arg=%d. "
1693 "Not properly tested by cmdtest?\n",
1696 up(&this_usbduxsub->
sem);
1725 ret = usbduxsub_submit_OutURBs(this_usbduxsub);
1729 up(&this_usbduxsub->
sem);
1737 s->
async->inttrig = usbdux_ao_inttrig;
1740 up(&this_usbduxsub->
sem);
1744 static int usbdux_dio_insn_config(
struct comedi_device *dev,
1781 struct usbduxsub *this_usbduxsub = dev->
private;
1784 if (!this_usbduxsub)
1789 if (!(this_usbduxsub->
probed)) {
1790 up(&this_usbduxsub->
sem);
1796 s->
state &= ~data[0];
1797 s->
state |= data[0] & data[1];
1810 up(&this_usbduxsub->
sem);
1815 up(&this_usbduxsub->
sem);
1819 data[1] = (((
unsigned int)(this_usbduxsub->
insnBuffer[1]))&0xff) |
1820 ((((
unsigned int)(this_usbduxsub->
insnBuffer[2]))&0xff) << 8) |
1821 ((((
unsigned int)(this_usbduxsub->
insnBuffer[3]))&0xff) << 16);
1825 up(&this_usbduxsub->
sem);
1832 static int usbduxsub_unlink_PwmURBs(
struct usbduxsub *usbduxsub_tmp)
1836 if (usbduxsub_tmp && usbduxsub_tmp->
urbPwm) {
1837 if (usbduxsub_tmp->
urbPwm)
1840 "comedi: unlinked PwmURB: res=%d\n", err);
1848 static int usbdux_pwm_stop(
struct usbduxsub *this_usbduxsub,
int do_unlink)
1852 if (!this_usbduxsub)
1857 ret = usbduxsub_unlink_PwmURBs(this_usbduxsub);
1868 struct usbduxsub *this_usbduxsub = dev->
private;
1872 res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->
pwm_cmd_running);
1875 "comedi %d: sending pwm off command to the usb device.\n",
1877 res = send_dux_commands(this_usbduxsub,
SENDPWMOFF);
1884 static void usbduxsub_pwm_irq(
struct urb *urb)
1887 struct usbduxsub *this_usbduxsub;
1894 this_comedidev = urb->context;
1896 this_usbduxsub = this_comedidev->
private;
1900 switch (urb->status) {
1914 usbdux_pwm_stop(this_usbduxsub, 0);
1922 "comedi_: Non-zero urb status received in "
1923 "pwm intr context: %d\n", urb->status);
1924 usbdux_pwm_stop(this_usbduxsub, 0);
1933 urb->transfer_buffer_length = this_usbduxsub->
sizePwmBuf;
1934 urb->dev = this_usbduxsub->
usbdev;
1940 "comedi_: pwm urb resubm failed in int-cont. "
1944 "buggy USB host controller or bug in "
1948 usbdux_pwm_stop(this_usbduxsub, 0);
1953 static int usbduxsub_submit_PwmURBs(
struct usbduxsub *usbduxsub)
1963 usb_fill_bulk_urb(usbduxsub->
urbPwm,
1966 usbduxsub->
urbPwm->transfer_buffer,
1973 "comedi_: usbduxsigma: pwm: usb_submit_urb error %d\n",
1983 struct usbduxsub *this_usbduxsub = dev->
private;
1988 "comedi%d: illegal period setting for pwm.\n",
1992 fx2delay = period / ((
int)(6 * 512 * (1.0 / 0.033))) - 6;
1993 if (fx2delay > 255) {
1995 "comedi%d: period %d for pwm is too low.\n",
1996 dev->
minor, period);
2000 this_usbduxsub->
pwmDelay = fx2delay;
2003 __func__, period, fx2delay);
2012 struct usbduxsub *this_usbduxsub = dev->
private;
2015 dev->
minor, __func__);
2023 ret = send_dux_commands(this_usbduxsub,
SENDPWMON);
2028 for (i = 0; i < this_usbduxsub->
sizePwmBuf; i++)
2029 ((
char *)(this_usbduxsub->
urbPwm->transfer_buffer))[
i] = 0;
2032 ret = usbduxsub_submit_PwmURBs(this_usbduxsub);
2045 struct usbduxsub *this_usbduxsub = dev->
private;
2052 if (!this_usbduxsub)
2062 pBuf = (
char *)(this_usbduxsub->
urbPwm->transfer_buffer);
2063 for (i = 0; i < szbuf; i++) {
2066 c = c & (~pwm_mask);
2073 c = c & (~sgn_mask);
2087 struct usbduxsub *this_usbduxsub = dev->
private;
2089 if (!this_usbduxsub)
2092 if ((insn->
n) != 1) {
2105 return usbdux_pwm_pattern(dev, s,
CR_CHAN(insn->
chanspec), data[0], 0);
2121 struct usbduxsub *this_usbduxsub = dev->
private;
2126 "comedi%d: %s: pwm on\n", dev->
minor, __func__);
2133 return usbdux_pwm_start(dev, s);
2136 "comedi%d: %s: pwm off\n", dev->
minor, __func__);
2137 return usbdux_pwm_cancel(dev, s);
2147 "comedi%d: %s: setting period\n", dev->
minor,
2149 return usbdux_pwm_period(dev, s, data[1]);
2156 return usbdux_pwm_pattern(dev, s,
2173 static void tidy_up(
struct usbduxsub *usbduxsub_tmp)
2185 usbduxsub_tmp->
probed = 0;
2187 if (usbduxsub_tmp->
urbIn) {
2190 usbduxsub_unlink_InURBs(usbduxsub_tmp);
2193 kfree(usbduxsub_tmp->
urbIn[i]->transfer_buffer);
2194 usbduxsub_tmp->
urbIn[
i]->transfer_buffer =
NULL;
2202 if (usbduxsub_tmp->
urbOut) {
2205 usbduxsub_unlink_OutURBs(usbduxsub_tmp);
2208 if (usbduxsub_tmp->
urbOut[i]->transfer_buffer) {
2209 kfree(usbduxsub_tmp->
2210 urbOut[i]->transfer_buffer);
2211 usbduxsub_tmp->
urbOut[
i]->transfer_buffer =
2214 if (usbduxsub_tmp->
urbOut[i]) {
2223 if (usbduxsub_tmp->
urbPwm) {
2226 usbduxsub_unlink_PwmURBs(usbduxsub_tmp);
2229 usbduxsub_tmp->
urbPwm->transfer_buffer =
NULL;
2249 static int usbduxsigma_attach_common(
struct comedi_device *dev,
2250 struct usbduxsub *uds)
2294 s->
do_cmd = usbdux_ai_cmd;
2295 s->
cancel = usbdux_ai_cancel;
2321 s->
do_cmd = usbdux_ao_cmd;
2322 s->
cancel = usbdux_ao_cancel;
2353 offset = usbdux_getstatusinfo(dev, 0);
2356 "Communication to USBDUXSIGMA failed! Check firmware and cabling.");
2358 "comedi%d: attached, ADC_zero = %x\n", dev->
minor, offset);
2362 static int usbduxsigma_attach_usb(
struct comedi_device *dev,
2366 struct usbduxsub *uds;
2369 down(&start_stop_sem);
2370 uds = usb_get_intfdata(uinterf);
2371 if (!uds || !uds->
probed) {
2373 "usbduxsigma: error: attach_usb failed, not connected\n");
2377 "usbduxsigma: error: attach_usb failed, already attached\n");
2380 ret = usbduxsigma_attach_common(dev, uds);
2381 up(&start_stop_sem);
2399 .driver_name =
"usbduxsigma",
2401 .attach_usb = usbduxsigma_attach_usb,
2402 .detach = usbduxsigma_detach,
2405 static void usbdux_firmware_request_complete_handler(
const struct firmware *
fw,
2408 struct usbduxsub *usbduxsub_tmp =
context;
2414 "Firmware complete handler without firmware!\n");
2422 ret = firmwareUpload(usbduxsub_tmp, fw->
data, fw->
size);
2426 "Could not upload firmware (err=%d)\n", ret);
2434 static int usbduxsigma_usb_probe(
struct usb_interface *uinterf,
2437 struct usb_device *
udev = interface_to_usbdev(uinterf);
2438 struct device *dev = &uinterf->dev;
2443 dev_dbg(dev,
"comedi_: usbdux_: "
2444 "finding a free structure for the usb-device\n");
2446 down(&start_stop_sem);
2450 if (!(usbduxsub[i].probed)) {
2458 dev_err(dev,
"Too many usbduxsigma-devices connected.\n");
2459 up(&start_stop_sem);
2462 dev_dbg(dev,
"comedi_: usbdux: "
2463 "usbduxsub[%d] is ready to connect to comedi.\n", index);
2465 sema_init(&(usbduxsub[index].
sem), 1);
2472 usbduxsub[
index].
ifnum = uinterf->altsetting->desc.bInterfaceNumber;
2475 usb_set_intfdata(uinterf, &(usbduxsub[index]));
2477 dev_dbg(dev,
"comedi_: usbdux: ifnum=%d\n", usbduxsub[index].ifnum);
2485 if (!usbduxsub[index].dac_commands) {
2486 dev_err(dev,
"comedi_: usbduxsigma: "
2487 "error alloc space for dac commands\n");
2488 tidy_up(&(usbduxsub[index]));
2489 up(&start_stop_sem);
2494 if (!usbduxsub[index].dux_commands) {
2495 dev_err(dev,
"comedi_: usbduxsigma: "
2496 "error alloc space for dux commands\n");
2497 tidy_up(&(usbduxsub[index]));
2498 up(&start_stop_sem);
2503 if (!(usbduxsub[index].inBuffer)) {
2504 dev_err(dev,
"comedi_: usbduxsigma: "
2505 "could not alloc space for inBuffer\n");
2506 tidy_up(&(usbduxsub[index]));
2507 up(&start_stop_sem);
2512 if (!(usbduxsub[index].insnBuffer)) {
2513 dev_err(dev,
"comedi_: usbduxsigma: "
2514 "could not alloc space for insnBuffer\n");
2515 tidy_up(&(usbduxsub[index]));
2516 up(&start_stop_sem);
2521 if (!(usbduxsub[index].outBuffer)) {
2522 dev_err(dev,
"comedi_: usbduxsigma: "
2523 "could not alloc space for outBuffer\n");
2524 tidy_up(&(usbduxsub[index]));
2525 up(&start_stop_sem);
2530 usbduxsub[index].ifnum, 3);
2532 dev_err(dev,
"comedi_: usbduxsigma%d: "
2533 "could not set alternate setting 3 in high speed.\n",
2535 tidy_up(&(usbduxsub[index]));
2536 up(&start_stop_sem);
2539 if (usbduxsub[index].high_speed)
2545 kzalloc(
sizeof(
struct urb *) * usbduxsub[index].numOfInBuffers,
2547 if (!(usbduxsub[index].urbIn)) {
2548 dev_err(dev,
"comedi_: usbduxsigma: "
2549 "Could not alloc. urbIn array\n");
2550 tidy_up(&(usbduxsub[index]));
2551 up(&start_stop_sem);
2557 if (usbduxsub[index].urbIn[i] ==
NULL) {
2558 dev_err(dev,
"comedi_: usbduxsigma%d: "
2559 "Could not alloc. urb(%d)\n", index, i);
2560 tidy_up(&(usbduxsub[index]));
2561 up(&start_stop_sem);
2569 usb_rcvisocpipe(usbduxsub[index].usbdev,
ISOINEP);
2570 usbduxsub[
index].
urbIn[
i]->transfer_flags = URB_ISO_ASAP;
2574 dev_err(dev,
"comedi_: usbduxsigma%d: "
2575 "could not alloc. transb.\n", index);
2576 tidy_up(&(usbduxsub[index]));
2577 up(&start_stop_sem);
2580 usbduxsub[
index].
urbIn[
i]->complete = usbduxsub_ai_IsocIrq;
2583 usbduxsub[
index].
urbIn[
i]->iso_frame_desc[0].offset = 0;
2584 usbduxsub[
index].
urbIn[
i]->iso_frame_desc[0].length =
2589 if (usbduxsub[index].high_speed)
2595 kzalloc(
sizeof(
struct urb *) * usbduxsub[index].numOfOutBuffers,
2597 if (!(usbduxsub[index].urbOut)) {
2598 dev_err(dev,
"comedi_: usbduxsigma: "
2599 "Could not alloc. urbOut array\n");
2600 tidy_up(&(usbduxsub[index]));
2601 up(&start_stop_sem);
2607 if (usbduxsub[index].urbOut[i] ==
NULL) {
2608 dev_err(dev,
"comedi_: usbduxsigma%d: "
2609 "Could not alloc. urb(%d)\n", index, i);
2610 tidy_up(&(usbduxsub[index]));
2611 up(&start_stop_sem);
2619 usb_sndisocpipe(usbduxsub[index].usbdev,
ISOOUTEP);
2620 usbduxsub[
index].
urbOut[
i]->transfer_flags = URB_ISO_ASAP;
2624 dev_err(dev,
"comedi_: usbduxsigma%d: "
2625 "could not alloc. transb.\n", index);
2626 tidy_up(&(usbduxsub[index]));
2627 up(&start_stop_sem);
2630 usbduxsub[
index].
urbOut[
i]->complete = usbduxsub_ao_IsocIrq;
2634 usbduxsub[
index].
urbOut[
i]->iso_frame_desc[0].offset = 0;
2637 if (usbduxsub[index].high_speed) {
2647 if (usbduxsub[index].high_speed) {
2651 if (usbduxsub[index].urbPwm ==
NULL) {
2652 dev_err(dev,
"comedi_: usbduxsigma%d: "
2653 "Could not alloc. pwm urb\n", index);
2654 tidy_up(&(usbduxsub[index]));
2655 up(&start_stop_sem);
2659 kzalloc(usbduxsub[index].sizePwmBuf,
GFP_KERNEL);
2660 if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
2661 dev_err(dev,
"comedi_: usbduxsigma%d: "
2662 "could not alloc. transb. for pwm\n", index);
2663 tidy_up(&(usbduxsub[index]));
2664 up(&start_stop_sem);
2678 up(&start_stop_sem);
2686 usbdux_firmware_request_complete_handler
2690 dev_err(dev,
"Could not load firmware (err=%d)\n", ret);
2694 dev_info(dev,
"comedi_: successfully initialised.\n");
2701 struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf);
2702 struct usb_device *udev = interface_to_usbdev(intf);
2704 if (!usbduxsub_tmp) {
2706 "comedi_: disconnect called with null pointer.\n");
2709 if (usbduxsub_tmp->
usbdev != udev) {
2710 dev_err(&intf->dev,
"comedi_: BUG! wrong ptr!\n");
2715 usbdux_ai_stop(usbduxsub_tmp, 1);
2718 usbdux_ao_stop(usbduxsub_tmp, 1);
2720 down(&start_stop_sem);
2722 tidy_up(usbduxsub_tmp);
2723 up(&usbduxsub_tmp->
sem);
2724 up(&start_stop_sem);
2725 dev_info(&intf->dev,
"comedi_: disconnected from the usb\n");
2728 static const struct usb_device_id usbduxsigma_usb_table[] = {
2729 { USB_DEVICE(0x13d8, 0x0020) },
2730 { USB_DEVICE(0x13d8, 0x0021) },
2731 { USB_DEVICE(0x13d8, 0x0022) },
2736 static struct usb_driver usbduxsigma_usb_driver = {
2737 .name =
"usbduxsigma",
2738 .probe = usbduxsigma_usb_probe,
2739 .disconnect = usbduxsigma_usb_disconnect,
2740 .id_table = usbduxsigma_usb_table,