Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[deliverable/linux.git] / drivers / staging / comedi / drivers / usbduxsigma.c
1 /*
2 * usbduxsigma.c
3 * Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16 /*
17 * Driver: usbduxsigma
18 * Description: University of Stirling USB DAQ & INCITE Technology Limited
19 * Devices: (ITL) USB-DUX [usbduxsigma]
20 * Author: Bernd Porr <BerndPorr@f2s.com>
21 * Updated: 8 Nov 2011
22 * Status: testing
23 */
24
25 /*
26 * I must give credit here to Chris Baugher who
27 * wrote the driver for AT-MIO-16d. I used some parts of this
28 * driver. I also must give credits to David Brownell
29 * who supported me with the USB development.
30 *
31 * Note: the raw data from the A/D converter is 24 bit big endian
32 * anything else is little endian to/from the dux board
33 *
34 *
35 * Revision history:
36 * 0.1: initial version
37 * 0.2: all basic functions implemented, digital I/O only for one port
38 * 0.3: proper vendor ID and driver name
39 * 0.4: fixed D/A voltage range
40 * 0.5: various bug fixes, health check at startup
41 * 0.6: corrected wrong input range
42 */
43
44 #include <linux/kernel.h>
45 #include <linux/module.h>
46 #include <linux/slab.h>
47 #include <linux/input.h>
48 #include <linux/usb.h>
49 #include <linux/fcntl.h>
50 #include <linux/compiler.h>
51 #include <asm/unaligned.h>
52
53 #include "comedi_fc.h"
54 #include "../comedidev.h"
55
56 /* timeout for the USB-transfer in ms*/
57 #define BULK_TIMEOUT 1000
58
59 /* constants for "firmware" upload and download */
60 #define FIRMWARE "usbduxsigma_firmware.bin"
61 #define FIRMWARE_MAX_LEN 0x4000
62 #define USBDUXSUB_FIRMWARE 0xa0
63 #define VENDOR_DIR_IN 0xc0
64 #define VENDOR_DIR_OUT 0x40
65
66 /* internal addresses of the 8051 processor */
67 #define USBDUXSUB_CPUCS 0xE600
68
69 /* 300Hz max frequ under PWM */
70 #define MIN_PWM_PERIOD ((long)(1E9/300))
71
72 /* Default PWM frequency */
73 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
74
75 /* Number of channels (16 AD and offset)*/
76 #define NUMCHANNELS 16
77
78 /* Size of one A/D value */
79 #define SIZEADIN ((sizeof(uint32_t)))
80
81 /*
82 * Size of the async input-buffer IN BYTES, the DIO state is transmitted
83 * as the first byte.
84 */
85 #define SIZEINBUF (((NUMCHANNELS+1)*SIZEADIN))
86
87 /* 16 bytes. */
88 #define SIZEINSNBUF 16
89
90 /* Number of DA channels */
91 #define NUMOUTCHANNELS 8
92
93 /* size of one value for the D/A converter: channel and value */
94 #define SIZEDAOUT ((sizeof(uint8_t)+sizeof(uint16_t)))
95
96 /*
97 * Size of the output-buffer in bytes
98 * Actually only the first 4 triplets are used but for the
99 * high speed mode we need to pad it to 8 (microframes).
100 */
101 #define SIZEOUTBUF ((8*SIZEDAOUT))
102
103 /*
104 * Size of the buffer for the dux commands: just now max size is determined
105 * by the analogue out + command byte + panic bytes...
106 */
107 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
108
109 /* Number of in-URBs which receive the data: min=2 */
110 #define NUMOFINBUFFERSFULL 5
111
112 /* Number of out-URBs which send the data: min=2 */
113 #define NUMOFOUTBUFFERSFULL 5
114
115 /* Number of in-URBs which receive the data: min=5 */
116 /* must have more buffers due to buggy USB ctr */
117 #define NUMOFINBUFFERSHIGH 10
118
119 /* Number of out-URBs which send the data: min=5 */
120 /* must have more buffers due to buggy USB ctr */
121 #define NUMOFOUTBUFFERSHIGH 10
122
123 /* number of retries to get the right dux command */
124 #define RETRIES 10
125
126 /* bulk transfer commands to usbduxsigma */
127 #define USBBUXSIGMA_AD_CMD 0
128 #define USBDUXSIGMA_DA_CMD 1
129 #define USBDUXSIGMA_DIO_CFG_CMD 2
130 #define USBDUXSIGMA_DIO_BITS_CMD 3
131 #define USBDUXSIGMA_SINGLE_AD_CMD 4
132 #define USBDUXSIGMA_PWM_ON_CMD 7
133 #define USBDUXSIGMA_PWM_OFF_CMD 8
134
135 static const struct comedi_lrange usbduxsigma_ai_range = {
136 1, {
137 BIP_RANGE(2.5 * 0x800000 / 0x780000 / 2.0)
138 }
139 };
140
141 struct usbduxsigma_private {
142 /* actual number of in-buffers */
143 int n_ai_urbs;
144 /* actual number of out-buffers */
145 int n_ao_urbs;
146 /* ISO-transfer handling: buffers */
147 struct urb **ai_urbs;
148 struct urb **ao_urbs;
149 /* pwm-transfer handling */
150 struct urb *pwm_urb;
151 /* PWM period */
152 unsigned int pwm_period;
153 /* PWM internal delay for the GPIF in the FX2 */
154 uint8_t pwm_delay;
155 /* size of the PWM buffer which holds the bit pattern */
156 int pwm_buf_sz;
157 /* input buffer for the ISO-transfer */
158 __be32 *in_buf;
159 /* input buffer for single insn */
160 uint8_t *insn_buf;
161
162 unsigned high_speed:1;
163 unsigned ai_cmd_running:1;
164 unsigned ao_cmd_running:1;
165 unsigned pwm_cmd_running:1;
166
167 /* number of samples to acquire */
168 int ai_sample_count;
169 int ao_sample_count;
170 /* time between samples in units of the timer */
171 unsigned int ai_timer;
172 unsigned int ao_timer;
173 /* counter between acquisitions */
174 unsigned int ai_counter;
175 unsigned int ao_counter;
176 /* interval in frames/uframes */
177 unsigned int ai_interval;
178 /* commands */
179 uint8_t *dux_commands;
180 struct semaphore sem;
181 };
182
183 static void usbduxsigma_unlink_urbs(struct urb **urbs, int num_urbs)
184 {
185 int i;
186
187 for (i = 0; i < num_urbs; i++)
188 usb_kill_urb(urbs[i]);
189 }
190
191 static void usbduxsigma_ai_stop(struct comedi_device *dev, int do_unlink)
192 {
193 struct usbduxsigma_private *devpriv = dev->private;
194
195 if (do_unlink && devpriv->ai_urbs)
196 usbduxsigma_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs);
197
198 devpriv->ai_cmd_running = 0;
199 }
200
201 static int usbduxsigma_ai_cancel(struct comedi_device *dev,
202 struct comedi_subdevice *s)
203 {
204 struct usbduxsigma_private *devpriv = dev->private;
205
206 down(&devpriv->sem);
207 /* unlink only if it is really running */
208 usbduxsigma_ai_stop(dev, devpriv->ai_cmd_running);
209 up(&devpriv->sem);
210
211 return 0;
212 }
213
214 static void usbduxsigma_ai_urb_complete(struct urb *urb)
215 {
216 struct comedi_device *dev = urb->context;
217 struct usbduxsigma_private *devpriv = dev->private;
218 struct comedi_subdevice *s = dev->read_subdev;
219 struct comedi_cmd *cmd = &s->async->cmd;
220 unsigned int dio_state;
221 uint32_t val;
222 int ret;
223 int i;
224
225 /* first we test if something unusual has just happened */
226 switch (urb->status) {
227 case 0:
228 /* copy the result in the transfer buffer */
229 memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
230 break;
231 case -EILSEQ:
232 /*
233 * error in the ISOchronous data
234 * we don't copy the data into the transfer buffer
235 * and recycle the last data byte
236 */
237 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
238
239 break;
240
241 case -ECONNRESET:
242 case -ENOENT:
243 case -ESHUTDOWN:
244 case -ECONNABORTED:
245 /* happens after an unlink command */
246 if (devpriv->ai_cmd_running) {
247 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
248 /* we are still running a command, tell comedi */
249 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
250 comedi_event(dev, s);
251 }
252 return;
253
254 default:
255 /*
256 * a real error on the bus
257 * pass error to comedi if we are really running a command
258 */
259 if (devpriv->ai_cmd_running) {
260 dev_err(dev->class_dev,
261 "%s: non-zero urb status (%d)\n",
262 __func__, urb->status);
263 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
264 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
265 comedi_event(dev, s);
266 }
267 return;
268 }
269
270 if (unlikely(!devpriv->ai_cmd_running))
271 return;
272
273 urb->dev = comedi_to_usb_dev(dev);
274
275 ret = usb_submit_urb(urb, GFP_ATOMIC);
276 if (unlikely(ret < 0)) {
277 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
278 __func__, ret);
279 if (ret == -EL2NSYNC)
280 dev_err(dev->class_dev,
281 "buggy USB host controller or bug in IRQ handler\n");
282 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
283 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
284 comedi_event(dev, s);
285 return;
286 }
287
288 /* get the state of the dio pins to allow external trigger */
289 dio_state = be32_to_cpu(devpriv->in_buf[0]);
290
291 devpriv->ai_counter--;
292 if (likely(devpriv->ai_counter > 0))
293 return;
294
295 /* timer zero, transfer measurements to comedi */
296 devpriv->ai_counter = devpriv->ai_timer;
297
298 if (cmd->stop_src == TRIG_COUNT) {
299 /* not continuous, fixed number of samples */
300 devpriv->ai_sample_count--;
301 if (devpriv->ai_sample_count < 0) {
302 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
303 /* acquistion is over, tell comedi */
304 s->async->events |= COMEDI_CB_EOA;
305 comedi_event(dev, s);
306 return;
307 }
308 }
309
310 /* get the data from the USB bus and hand it over to comedi */
311 for (i = 0; i < cmd->chanlist_len; i++) {
312 /* transfer data, note first byte is the DIO state */
313 val = be32_to_cpu(devpriv->in_buf[i+1]);
314 val &= 0x00ffffff; /* strip status byte */
315 val ^= 0x00800000; /* convert to unsigned */
316
317 ret = cfc_write_array_to_buffer(s, &val, sizeof(uint32_t));
318 if (unlikely(ret == 0)) {
319 /* buffer overflow */
320 usbduxsigma_ai_stop(dev, 0); /* w/o unlink */
321 return;
322 }
323 }
324 /* tell comedi that data is there */
325 s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
326 comedi_event(dev, s);
327 }
328
329 static void usbduxsigma_ao_stop(struct comedi_device *dev, int do_unlink)
330 {
331 struct usbduxsigma_private *devpriv = dev->private;
332
333 if (do_unlink && devpriv->ao_urbs)
334 usbduxsigma_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs);
335
336 devpriv->ao_cmd_running = 0;
337 }
338
339 static int usbduxsigma_ao_cancel(struct comedi_device *dev,
340 struct comedi_subdevice *s)
341 {
342 struct usbduxsigma_private *devpriv = dev->private;
343
344 down(&devpriv->sem);
345 /* unlink only if it is really running */
346 usbduxsigma_ao_stop(dev, devpriv->ao_cmd_running);
347 up(&devpriv->sem);
348
349 return 0;
350 }
351
352 static void usbduxsigma_ao_urb_complete(struct urb *urb)
353 {
354 struct comedi_device *dev = urb->context;
355 struct usbduxsigma_private *devpriv = dev->private;
356 struct comedi_subdevice *s = dev->write_subdev;
357 struct comedi_cmd *cmd = &s->async->cmd;
358 uint8_t *datap;
359 int ret;
360 int i;
361
362 switch (urb->status) {
363 case 0:
364 /* success */
365 break;
366
367 case -ECONNRESET:
368 case -ENOENT:
369 case -ESHUTDOWN:
370 case -ECONNABORTED:
371 /* happens after an unlink command */
372 if (devpriv->ao_cmd_running) {
373 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
374 s->async->events |= COMEDI_CB_EOA;
375 comedi_event(dev, s);
376 }
377 return;
378
379 default:
380 /* a real error */
381 if (devpriv->ao_cmd_running) {
382 dev_err(dev->class_dev,
383 "%s: non-zero urb status (%d)\n",
384 __func__, urb->status);
385 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
386 s->async->events |= (COMEDI_CB_ERROR | COMEDI_CB_EOA);
387 comedi_event(dev, s);
388 }
389 return;
390 }
391
392 if (!devpriv->ao_cmd_running)
393 return;
394
395 devpriv->ao_counter--;
396 if ((int)devpriv->ao_counter <= 0) {
397 /* timer zero, transfer from comedi */
398 devpriv->ao_counter = devpriv->ao_timer;
399
400 if (cmd->stop_src == TRIG_COUNT) {
401 /* not continuous, fixed number of samples */
402 devpriv->ao_sample_count--;
403 if (devpriv->ao_sample_count < 0) {
404 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
405 /* acquistion is over, tell comedi */
406 s->async->events |= COMEDI_CB_EOA;
407 comedi_event(dev, s);
408 return;
409 }
410 }
411
412 /* transmit data to the USB bus */
413 datap = urb->transfer_buffer;
414 *datap++ = cmd->chanlist_len;
415 for (i = 0; i < cmd->chanlist_len; i++) {
416 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
417 unsigned short val;
418
419 ret = comedi_buf_get(s, &val);
420 if (ret < 0) {
421 dev_err(dev->class_dev, "buffer underflow\n");
422 s->async->events |= (COMEDI_CB_EOA |
423 COMEDI_CB_OVERFLOW);
424 }
425 *datap++ = val;
426 *datap++ = chan;
427 s->readback[chan] = val;
428
429 s->async->events |= COMEDI_CB_BLOCK;
430 comedi_event(dev, s);
431 }
432 }
433
434 urb->transfer_buffer_length = SIZEOUTBUF;
435 urb->dev = comedi_to_usb_dev(dev);
436 urb->status = 0;
437 if (devpriv->high_speed)
438 urb->interval = 8; /* uframes */
439 else
440 urb->interval = 1; /* frames */
441 urb->number_of_packets = 1;
442 urb->iso_frame_desc[0].offset = 0;
443 urb->iso_frame_desc[0].length = SIZEOUTBUF;
444 urb->iso_frame_desc[0].status = 0;
445 ret = usb_submit_urb(urb, GFP_ATOMIC);
446 if (ret < 0) {
447 dev_err(dev->class_dev,
448 "%s: urb resubmit failed (%d)\n",
449 __func__, ret);
450 if (ret == -EL2NSYNC)
451 dev_err(dev->class_dev,
452 "buggy USB host controller or bug in IRQ handler\n");
453 usbduxsigma_ao_stop(dev, 0); /* w/o unlink */
454 s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
455 comedi_event(dev, s);
456 }
457 }
458
459 static int usbduxsigma_submit_urbs(struct comedi_device *dev,
460 struct urb **urbs, int num_urbs,
461 int input_urb)
462 {
463 struct usb_device *usb = comedi_to_usb_dev(dev);
464 struct usbduxsigma_private *devpriv = dev->private;
465 struct urb *urb;
466 int ret;
467 int i;
468
469 /* Submit all URBs and start the transfer on the bus */
470 for (i = 0; i < num_urbs; i++) {
471 urb = urbs[i];
472
473 /* in case of a resubmission after an unlink... */
474 if (input_urb)
475 urb->interval = devpriv->ai_interval;
476 urb->context = dev;
477 urb->dev = usb;
478 urb->status = 0;
479 urb->transfer_flags = URB_ISO_ASAP;
480
481 ret = usb_submit_urb(urb, GFP_ATOMIC);
482 if (ret)
483 return ret;
484 }
485 return 0;
486 }
487
488 static int usbduxsigma_chans_to_interval(int num_chan)
489 {
490 if (num_chan <= 2)
491 return 2; /* 4kHz */
492 if (num_chan <= 8)
493 return 4; /* 2kHz */
494 return 8; /* 1kHz */
495 }
496
497 static int usbduxsigma_ai_cmdtest(struct comedi_device *dev,
498 struct comedi_subdevice *s,
499 struct comedi_cmd *cmd)
500 {
501 struct usbduxsigma_private *devpriv = dev->private;
502 int high_speed = devpriv->high_speed;
503 int interval = usbduxsigma_chans_to_interval(cmd->chanlist_len);
504 int err = 0;
505
506 /* Step 1 : check if triggers are trivially valid */
507
508 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
509 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
510 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
511 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
512 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
513
514 if (err)
515 return 1;
516
517 /* Step 2a : make sure trigger sources are unique */
518
519 err |= cfc_check_trigger_is_unique(cmd->start_src);
520 err |= cfc_check_trigger_is_unique(cmd->stop_src);
521
522 /* Step 2b : and mutually compatible */
523
524 if (err)
525 return 2;
526
527 /* Step 3: check if arguments are trivially valid */
528
529 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
530
531 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
532 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
533
534 if (cmd->scan_begin_src == TRIG_TIMER) {
535 unsigned int tmp;
536
537 if (high_speed) {
538 /*
539 * In high speed mode microframes are possible.
540 * However, during one microframe we can roughly
541 * sample two channels. Thus, the more channels
542 * are in the channel list the more time we need.
543 */
544 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
545 (1000000 / 8 * interval));
546
547 tmp = (cmd->scan_begin_arg / 125000) * 125000;
548 } else {
549 /* full speed */
550 /* 1kHz scans every USB frame */
551 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
552 1000000);
553
554 tmp = (cmd->scan_begin_arg / 1000000) * 1000000;
555 }
556 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
557 }
558
559 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
560
561 if (cmd->stop_src == TRIG_COUNT)
562 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
563 else /* TRIG_NONE */
564 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
565
566 if (err)
567 return 3;
568
569 /* Step 4: fix up any arguments */
570
571 if (high_speed) {
572 /*
573 * every 2 channels get a time window of 125us. Thus, if we
574 * sample all 16 channels we need 1ms. If we sample only one
575 * channel we need only 125us
576 */
577 devpriv->ai_interval = interval;
578 devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval);
579 } else {
580 /* interval always 1ms */
581 devpriv->ai_interval = 1;
582 devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
583 }
584 if (devpriv->ai_timer < 1)
585 err |= -EINVAL;
586
587 if (cmd->stop_src == TRIG_COUNT) {
588 /* data arrives as one packet */
589 devpriv->ai_sample_count = cmd->stop_arg;
590 } else {
591 /* continuous acquisition */
592 devpriv->ai_sample_count = 0;
593 }
594
595 if (err)
596 return 4;
597
598 return 0;
599 }
600
601 /*
602 * creates the ADC command for the MAX1271
603 * range is the range value from comedi
604 */
605 static void create_adc_command(unsigned int chan,
606 uint8_t *muxsg0,
607 uint8_t *muxsg1)
608 {
609 if (chan < 8)
610 (*muxsg0) = (*muxsg0) | (1 << chan);
611 else if (chan < 16)
612 (*muxsg1) = (*muxsg1) | (1 << (chan-8));
613 }
614
615 static int usbbuxsigma_send_cmd(struct comedi_device *dev, int cmd_type)
616 {
617 struct usb_device *usb = comedi_to_usb_dev(dev);
618 struct usbduxsigma_private *devpriv = dev->private;
619 int nsent;
620
621 devpriv->dux_commands[0] = cmd_type;
622
623 return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1),
624 devpriv->dux_commands, SIZEOFDUXBUFFER,
625 &nsent, BULK_TIMEOUT);
626 }
627
628 static int usbduxsigma_receive_cmd(struct comedi_device *dev, int command)
629 {
630 struct usb_device *usb = comedi_to_usb_dev(dev);
631 struct usbduxsigma_private *devpriv = dev->private;
632 int nrec;
633 int ret;
634 int i;
635
636 for (i = 0; i < RETRIES; i++) {
637 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8),
638 devpriv->insn_buf, SIZEINSNBUF,
639 &nrec, BULK_TIMEOUT);
640 if (ret < 0)
641 return ret;
642
643 if (devpriv->insn_buf[0] == command)
644 return 0;
645 }
646 /*
647 * This is only reached if the data has been requested a
648 * couple of times and the command was not received.
649 */
650 return -EFAULT;
651 }
652
653 static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
654 struct comedi_subdevice *s,
655 unsigned int trig_num)
656 {
657 struct usbduxsigma_private *devpriv = dev->private;
658 struct comedi_cmd *cmd = &s->async->cmd;
659 int ret;
660
661 if (trig_num != cmd->start_arg)
662 return -EINVAL;
663
664 down(&devpriv->sem);
665 if (!devpriv->ai_cmd_running) {
666 devpriv->ai_cmd_running = 1;
667 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
668 devpriv->n_ai_urbs, 1);
669 if (ret < 0) {
670 devpriv->ai_cmd_running = 0;
671 up(&devpriv->sem);
672 return ret;
673 }
674 s->async->inttrig = NULL;
675 }
676 up(&devpriv->sem);
677
678 return 1;
679 }
680
681 static int usbduxsigma_ai_cmd(struct comedi_device *dev,
682 struct comedi_subdevice *s)
683 {
684 struct usbduxsigma_private *devpriv = dev->private;
685 struct comedi_cmd *cmd = &s->async->cmd;
686 unsigned int len = cmd->chanlist_len;
687 uint8_t muxsg0 = 0;
688 uint8_t muxsg1 = 0;
689 uint8_t sysred = 0;
690 int ret;
691 int i;
692
693 down(&devpriv->sem);
694
695 /* set current channel of the running acquisition to zero */
696 s->async->cur_chan = 0;
697 for (i = 0; i < len; i++) {
698 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
699
700 create_adc_command(chan, &muxsg0, &muxsg1);
701 }
702
703 devpriv->dux_commands[1] = len; /* num channels per time step */
704 devpriv->dux_commands[2] = 0x12; /* CONFIG0 */
705 devpriv->dux_commands[3] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
706 devpriv->dux_commands[4] = 0x00; /* CONFIG3: diff. channels off */
707 devpriv->dux_commands[5] = muxsg0;
708 devpriv->dux_commands[6] = muxsg1;
709 devpriv->dux_commands[7] = sysred;
710
711 ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD);
712 if (ret < 0) {
713 up(&devpriv->sem);
714 return ret;
715 }
716
717 devpriv->ai_counter = devpriv->ai_timer;
718
719 if (cmd->start_src == TRIG_NOW) {
720 /* enable this acquisition operation */
721 devpriv->ai_cmd_running = 1;
722 ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
723 devpriv->n_ai_urbs, 1);
724 if (ret < 0) {
725 devpriv->ai_cmd_running = 0;
726 up(&devpriv->sem);
727 return ret;
728 }
729 s->async->inttrig = NULL;
730 } else { /* TRIG_INT */
731 s->async->inttrig = usbduxsigma_ai_inttrig;
732 }
733
734 up(&devpriv->sem);
735
736 return 0;
737 }
738
739 static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
740 struct comedi_subdevice *s,
741 struct comedi_insn *insn,
742 unsigned int *data)
743 {
744 struct usbduxsigma_private *devpriv = dev->private;
745 unsigned int chan = CR_CHAN(insn->chanspec);
746 uint8_t muxsg0 = 0;
747 uint8_t muxsg1 = 0;
748 uint8_t sysred = 0;
749 int ret;
750 int i;
751
752 down(&devpriv->sem);
753 if (devpriv->ai_cmd_running) {
754 up(&devpriv->sem);
755 return -EBUSY;
756 }
757
758 create_adc_command(chan, &muxsg0, &muxsg1);
759
760 /* Mode 0 is used to get a single conversion on demand */
761 devpriv->dux_commands[1] = 0x16; /* CONFIG0: chopper on */
762 devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
763 devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
764 devpriv->dux_commands[4] = muxsg0;
765 devpriv->dux_commands[5] = muxsg1;
766 devpriv->dux_commands[6] = sysred;
767
768 /* adc commands */
769 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
770 if (ret < 0) {
771 up(&devpriv->sem);
772 return ret;
773 }
774
775 for (i = 0; i < insn->n; i++) {
776 uint32_t val;
777
778 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
779 if (ret < 0) {
780 up(&devpriv->sem);
781 return ret;
782 }
783
784 /* 32 bits big endian from the A/D converter */
785 val = be32_to_cpu(get_unaligned((__be32
786 *)(devpriv->insn_buf + 1)));
787 val &= 0x00ffffff; /* strip status byte */
788 val ^= 0x00800000; /* convert to unsigned */
789
790 data[i] = val;
791 }
792 up(&devpriv->sem);
793
794 return insn->n;
795 }
796
797 static int usbduxsigma_ao_insn_read(struct comedi_device *dev,
798 struct comedi_subdevice *s,
799 struct comedi_insn *insn,
800 unsigned int *data)
801 {
802 struct usbduxsigma_private *devpriv = dev->private;
803 int ret;
804
805 down(&devpriv->sem);
806 ret = comedi_readback_insn_read(dev, s, insn, data);
807 up(&devpriv->sem);
808
809 return ret;
810 }
811
812 static int usbduxsigma_ao_insn_write(struct comedi_device *dev,
813 struct comedi_subdevice *s,
814 struct comedi_insn *insn,
815 unsigned int *data)
816 {
817 struct usbduxsigma_private *devpriv = dev->private;
818 unsigned int chan = CR_CHAN(insn->chanspec);
819 int ret;
820 int i;
821
822 down(&devpriv->sem);
823 if (devpriv->ao_cmd_running) {
824 up(&devpriv->sem);
825 return -EBUSY;
826 }
827
828 for (i = 0; i < insn->n; i++) {
829 devpriv->dux_commands[1] = 1; /* num channels */
830 devpriv->dux_commands[2] = data[i]; /* value */
831 devpriv->dux_commands[3] = chan; /* channel number */
832 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DA_CMD);
833 if (ret < 0) {
834 up(&devpriv->sem);
835 return ret;
836 }
837 s->readback[chan] = data[i];
838 }
839 up(&devpriv->sem);
840
841 return insn->n;
842 }
843
844 static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
845 struct comedi_subdevice *s,
846 unsigned int trig_num)
847 {
848 struct usbduxsigma_private *devpriv = dev->private;
849 struct comedi_cmd *cmd = &s->async->cmd;
850 int ret;
851
852 if (trig_num != cmd->start_arg)
853 return -EINVAL;
854
855 down(&devpriv->sem);
856 if (!devpriv->ao_cmd_running) {
857 devpriv->ao_cmd_running = 1;
858 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
859 devpriv->n_ao_urbs, 0);
860 if (ret < 0) {
861 devpriv->ao_cmd_running = 0;
862 up(&devpriv->sem);
863 return ret;
864 }
865 s->async->inttrig = NULL;
866 }
867 up(&devpriv->sem);
868
869 return 1;
870 }
871
872 static int usbduxsigma_ao_cmdtest(struct comedi_device *dev,
873 struct comedi_subdevice *s,
874 struct comedi_cmd *cmd)
875 {
876 struct usbduxsigma_private *devpriv = dev->private;
877 int err = 0;
878 int high_speed;
879 unsigned int flags;
880
881 /* high speed conversions are not used yet */
882 high_speed = 0; /* (devpriv->high_speed) */
883
884 /* Step 1 : check if triggers are trivially valid */
885
886 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
887
888 if (high_speed) {
889 /*
890 * start immediately a new scan
891 * the sampling rate is set by the coversion rate
892 */
893 flags = TRIG_FOLLOW;
894 } else {
895 /* start a new scan (output at once) with a timer */
896 flags = TRIG_TIMER;
897 }
898 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
899
900 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
901 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
902 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
903
904 if (err) {
905 up(&devpriv->sem);
906 return 1;
907 }
908
909 /* Step 2a : make sure trigger sources are unique */
910
911 err |= cfc_check_trigger_is_unique(cmd->start_src);
912 err |= cfc_check_trigger_is_unique(cmd->stop_src);
913
914 /* Step 2b : and mutually compatible */
915
916 if (err)
917 return 2;
918
919 /* Step 3: check if arguments are trivially valid */
920
921 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
922
923 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
924 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
925
926 if (cmd->scan_begin_src == TRIG_TIMER)
927 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
928 1000000);
929
930 /* not used now, is for later use */
931 if (cmd->convert_src == TRIG_TIMER)
932 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
933
934 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
935
936 if (cmd->stop_src == TRIG_COUNT)
937 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
938 else /* TRIG_NONE */
939 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
940
941 if (err)
942 return 3;
943
944 /* Step 4: fix up any arguments */
945
946 /* we count in timer steps */
947 if (high_speed) {
948 /* timing of the conversion itself: every 125 us */
949 devpriv->ao_timer = cmd->convert_arg / 125000;
950 } else {
951 /*
952 * timing of the scan: every 1ms
953 * we get all channels at once
954 */
955 devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
956 }
957 if (devpriv->ao_timer < 1)
958 err |= -EINVAL;
959
960 if (cmd->stop_src == TRIG_COUNT) {
961 /* not continuous, use counter */
962 if (high_speed) {
963 /* high speed also scans everything at once */
964 devpriv->ao_sample_count = cmd->stop_arg *
965 cmd->scan_end_arg;
966 } else {
967 /*
968 * There's no scan as the scan has been
969 * handled inside the FX2. Data arrives as
970 * one packet.
971 */
972 devpriv->ao_sample_count = cmd->stop_arg;
973 }
974 } else {
975 /* continuous acquisition */
976 devpriv->ao_sample_count = 0;
977 }
978
979 if (err)
980 return 4;
981
982 return 0;
983 }
984
985 static int usbduxsigma_ao_cmd(struct comedi_device *dev,
986 struct comedi_subdevice *s)
987 {
988 struct usbduxsigma_private *devpriv = dev->private;
989 struct comedi_cmd *cmd = &s->async->cmd;
990 int ret;
991
992 down(&devpriv->sem);
993
994 /* set current channel of the running acquisition to zero */
995 s->async->cur_chan = 0;
996
997 devpriv->ao_counter = devpriv->ao_timer;
998
999 if (cmd->start_src == TRIG_NOW) {
1000 /* enable this acquisition operation */
1001 devpriv->ao_cmd_running = 1;
1002 ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
1003 devpriv->n_ao_urbs, 0);
1004 if (ret < 0) {
1005 devpriv->ao_cmd_running = 0;
1006 up(&devpriv->sem);
1007 return ret;
1008 }
1009 s->async->inttrig = NULL;
1010 } else { /* TRIG_INT */
1011 s->async->inttrig = usbduxsigma_ao_inttrig;
1012 }
1013
1014 up(&devpriv->sem);
1015
1016 return 0;
1017 }
1018
1019 static int usbduxsigma_dio_insn_config(struct comedi_device *dev,
1020 struct comedi_subdevice *s,
1021 struct comedi_insn *insn,
1022 unsigned int *data)
1023 {
1024 int ret;
1025
1026 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1027 if (ret)
1028 return ret;
1029
1030 /*
1031 * We don't tell the firmware here as it would take 8 frames
1032 * to submit the information. We do it in the (*insn_bits).
1033 */
1034 return insn->n;
1035 }
1036
1037 static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
1038 struct comedi_subdevice *s,
1039 struct comedi_insn *insn,
1040 unsigned int *data)
1041 {
1042 struct usbduxsigma_private *devpriv = dev->private;
1043 int ret;
1044
1045 down(&devpriv->sem);
1046
1047 comedi_dio_update_state(s, data);
1048
1049 /* Always update the hardware. See the (*insn_config). */
1050 devpriv->dux_commands[1] = s->io_bits & 0xff;
1051 devpriv->dux_commands[4] = s->state & 0xff;
1052 devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
1053 devpriv->dux_commands[5] = (s->state >> 8) & 0xff;
1054 devpriv->dux_commands[3] = (s->io_bits >> 16) & 0xff;
1055 devpriv->dux_commands[6] = (s->state >> 16) & 0xff;
1056
1057 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
1058 if (ret < 0)
1059 goto done;
1060 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
1061 if (ret < 0)
1062 goto done;
1063
1064 s->state = devpriv->insn_buf[1] |
1065 (devpriv->insn_buf[2] << 8) |
1066 (devpriv->insn_buf[3] << 16);
1067
1068 data[1] = s->state;
1069 ret = insn->n;
1070
1071 done:
1072 up(&devpriv->sem);
1073
1074 return ret;
1075 }
1076
1077 static void usbduxsigma_pwm_stop(struct comedi_device *dev, int do_unlink)
1078 {
1079 struct usbduxsigma_private *devpriv = dev->private;
1080
1081 if (do_unlink) {
1082 if (devpriv->pwm_urb)
1083 usb_kill_urb(devpriv->pwm_urb);
1084 }
1085
1086 devpriv->pwm_cmd_running = 0;
1087 }
1088
1089 static int usbduxsigma_pwm_cancel(struct comedi_device *dev,
1090 struct comedi_subdevice *s)
1091 {
1092 struct usbduxsigma_private *devpriv = dev->private;
1093
1094 /* unlink only if it is really running */
1095 usbduxsigma_pwm_stop(dev, devpriv->pwm_cmd_running);
1096
1097 return usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_OFF_CMD);
1098 }
1099
1100 static void usbduxsigma_pwm_urb_complete(struct urb *urb)
1101 {
1102 struct comedi_device *dev = urb->context;
1103 struct usbduxsigma_private *devpriv = dev->private;
1104 int ret;
1105
1106 switch (urb->status) {
1107 case 0:
1108 /* success */
1109 break;
1110
1111 case -ECONNRESET:
1112 case -ENOENT:
1113 case -ESHUTDOWN:
1114 case -ECONNABORTED:
1115 /* happens after an unlink command */
1116 if (devpriv->pwm_cmd_running)
1117 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
1118 return;
1119
1120 default:
1121 /* a real error */
1122 if (devpriv->pwm_cmd_running) {
1123 dev_err(dev->class_dev,
1124 "%s: non-zero urb status (%d)\n",
1125 __func__, urb->status);
1126 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
1127 }
1128 return;
1129 }
1130
1131 if (!devpriv->pwm_cmd_running)
1132 return;
1133
1134 urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1135 urb->dev = comedi_to_usb_dev(dev);
1136 urb->status = 0;
1137 ret = usb_submit_urb(urb, GFP_ATOMIC);
1138 if (ret < 0) {
1139 dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
1140 __func__, ret);
1141 if (ret == -EL2NSYNC)
1142 dev_err(dev->class_dev,
1143 "buggy USB host controller or bug in IRQ handler\n");
1144 usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
1145 }
1146 }
1147
1148 static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
1149 {
1150 struct usb_device *usb = comedi_to_usb_dev(dev);
1151 struct usbduxsigma_private *devpriv = dev->private;
1152 struct urb *urb = devpriv->pwm_urb;
1153
1154 /* in case of a resubmission after an unlink... */
1155 usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4),
1156 urb->transfer_buffer, devpriv->pwm_buf_sz,
1157 usbduxsigma_pwm_urb_complete, dev);
1158
1159 return usb_submit_urb(urb, GFP_ATOMIC);
1160 }
1161
1162 static int usbduxsigma_pwm_period(struct comedi_device *dev,
1163 struct comedi_subdevice *s,
1164 unsigned int period)
1165 {
1166 struct usbduxsigma_private *devpriv = dev->private;
1167 int fx2delay = 255;
1168
1169 if (period < MIN_PWM_PERIOD)
1170 return -EAGAIN;
1171
1172 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1173 if (fx2delay > 255)
1174 return -EAGAIN;
1175
1176 devpriv->pwm_delay = fx2delay;
1177 devpriv->pwm_period = period;
1178 return 0;
1179 }
1180
1181 static int usbduxsigma_pwm_start(struct comedi_device *dev,
1182 struct comedi_subdevice *s)
1183 {
1184 struct usbduxsigma_private *devpriv = dev->private;
1185 int ret;
1186
1187 if (devpriv->pwm_cmd_running)
1188 return 0;
1189
1190 devpriv->dux_commands[1] = devpriv->pwm_delay;
1191 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_ON_CMD);
1192 if (ret < 0)
1193 return ret;
1194
1195 memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1196
1197 devpriv->pwm_cmd_running = 1;
1198 ret = usbduxsigma_submit_pwm_urb(dev);
1199 if (ret < 0) {
1200 devpriv->pwm_cmd_running = 0;
1201 return ret;
1202 }
1203
1204 return 0;
1205 }
1206
1207 static void usbduxsigma_pwm_pattern(struct comedi_device *dev,
1208 struct comedi_subdevice *s,
1209 unsigned int chan,
1210 unsigned int value,
1211 unsigned int sign)
1212 {
1213 struct usbduxsigma_private *devpriv = dev->private;
1214 char pwm_mask = (1 << chan); /* DIO bit for the PWM data */
1215 char sgn_mask = (16 << chan); /* DIO bit for the sign */
1216 char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1217 int szbuf = devpriv->pwm_buf_sz;
1218 int i;
1219
1220 for (i = 0; i < szbuf; i++) {
1221 char c = *buf;
1222
1223 c &= ~pwm_mask;
1224 if (i < value)
1225 c |= pwm_mask;
1226 if (!sign)
1227 c &= ~sgn_mask;
1228 else
1229 c |= sgn_mask;
1230 *buf++ = c;
1231 }
1232 }
1233
1234 static int usbduxsigma_pwm_write(struct comedi_device *dev,
1235 struct comedi_subdevice *s,
1236 struct comedi_insn *insn,
1237 unsigned int *data)
1238 {
1239 unsigned int chan = CR_CHAN(insn->chanspec);
1240
1241 /*
1242 * It doesn't make sense to support more than one value here
1243 * because it would just overwrite the PWM buffer.
1244 */
1245 if (insn->n != 1)
1246 return -EINVAL;
1247
1248 /*
1249 * The sign is set via a special INSN only, this gives us 8 bits
1250 * for normal operation, sign is 0 by default.
1251 */
1252 usbduxsigma_pwm_pattern(dev, s, chan, data[0], 0);
1253
1254 return insn->n;
1255 }
1256
1257 static int usbduxsigma_pwm_config(struct comedi_device *dev,
1258 struct comedi_subdevice *s,
1259 struct comedi_insn *insn,
1260 unsigned int *data)
1261 {
1262 struct usbduxsigma_private *devpriv = dev->private;
1263 unsigned int chan = CR_CHAN(insn->chanspec);
1264
1265 switch (data[0]) {
1266 case INSN_CONFIG_ARM:
1267 /*
1268 * if not zero the PWM is limited to a certain time which is
1269 * not supported here
1270 */
1271 if (data[1] != 0)
1272 return -EINVAL;
1273 return usbduxsigma_pwm_start(dev, s);
1274 case INSN_CONFIG_DISARM:
1275 return usbduxsigma_pwm_cancel(dev, s);
1276 case INSN_CONFIG_GET_PWM_STATUS:
1277 data[1] = devpriv->pwm_cmd_running;
1278 return 0;
1279 case INSN_CONFIG_PWM_SET_PERIOD:
1280 return usbduxsigma_pwm_period(dev, s, data[1]);
1281 case INSN_CONFIG_PWM_GET_PERIOD:
1282 data[1] = devpriv->pwm_period;
1283 return 0;
1284 case INSN_CONFIG_PWM_SET_H_BRIDGE:
1285 /*
1286 * data[1] = value
1287 * data[2] = sign (for a relay)
1288 */
1289 usbduxsigma_pwm_pattern(dev, s, chan, data[1], (data[2] != 0));
1290 return 0;
1291 case INSN_CONFIG_PWM_GET_H_BRIDGE:
1292 /* values are not kept in this driver, nothing to return */
1293 return -EINVAL;
1294 }
1295 return -EINVAL;
1296 }
1297
1298 static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
1299 {
1300 struct usbduxsigma_private *devpriv = dev->private;
1301 uint8_t sysred;
1302 uint32_t val;
1303 int ret;
1304
1305 switch (chan) {
1306 default:
1307 case 0:
1308 sysred = 0; /* ADC zero */
1309 break;
1310 case 1:
1311 sysred = 1; /* ADC offset */
1312 break;
1313 case 2:
1314 sysred = 4; /* VCC */
1315 break;
1316 case 3:
1317 sysred = 8; /* temperature */
1318 break;
1319 case 4:
1320 sysred = 16; /* gain */
1321 break;
1322 case 5:
1323 sysred = 32; /* ref */
1324 break;
1325 }
1326
1327 devpriv->dux_commands[1] = 0x12; /* CONFIG0 */
1328 devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
1329 devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
1330 devpriv->dux_commands[4] = 0;
1331 devpriv->dux_commands[5] = 0;
1332 devpriv->dux_commands[6] = sysred;
1333 ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1334 if (ret < 0)
1335 return ret;
1336
1337 ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
1338 if (ret < 0)
1339 return ret;
1340
1341 /* 32 bits big endian from the A/D converter */
1342 val = be32_to_cpu(get_unaligned((__be32 *)(devpriv->insn_buf + 1)));
1343 val &= 0x00ffffff; /* strip status byte */
1344 val ^= 0x00800000; /* convert to unsigned */
1345
1346 return (int)val;
1347 }
1348
1349 static int usbduxsigma_firmware_upload(struct comedi_device *dev,
1350 const u8 *data, size_t size,
1351 unsigned long context)
1352 {
1353 struct usb_device *usb = comedi_to_usb_dev(dev);
1354 uint8_t *buf;
1355 uint8_t *tmp;
1356 int ret;
1357
1358 if (!data)
1359 return 0;
1360
1361 if (size > FIRMWARE_MAX_LEN) {
1362 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
1363 return -ENOMEM;
1364 }
1365
1366 /* we generate a local buffer for the firmware */
1367 buf = kmemdup(data, size, GFP_KERNEL);
1368 if (!buf)
1369 return -ENOMEM;
1370
1371 /* we need a malloc'ed buffer for usb_control_msg() */
1372 tmp = kmalloc(1, GFP_KERNEL);
1373 if (!tmp) {
1374 kfree(buf);
1375 return -ENOMEM;
1376 }
1377
1378 /* stop the current firmware on the device */
1379 *tmp = 1; /* 7f92 to one */
1380 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1381 USBDUXSUB_FIRMWARE,
1382 VENDOR_DIR_OUT,
1383 USBDUXSUB_CPUCS, 0x0000,
1384 tmp, 1,
1385 BULK_TIMEOUT);
1386 if (ret < 0) {
1387 dev_err(dev->class_dev, "can not stop firmware\n");
1388 goto done;
1389 }
1390
1391 /* upload the new firmware to the device */
1392 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1393 USBDUXSUB_FIRMWARE,
1394 VENDOR_DIR_OUT,
1395 0, 0x0000,
1396 buf, size,
1397 BULK_TIMEOUT);
1398 if (ret < 0) {
1399 dev_err(dev->class_dev, "firmware upload failed\n");
1400 goto done;
1401 }
1402
1403 /* start the new firmware on the device */
1404 *tmp = 0; /* 7f92 to zero */
1405 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1406 USBDUXSUB_FIRMWARE,
1407 VENDOR_DIR_OUT,
1408 USBDUXSUB_CPUCS, 0x0000,
1409 tmp, 1,
1410 BULK_TIMEOUT);
1411 if (ret < 0)
1412 dev_err(dev->class_dev, "can not start firmware\n");
1413
1414 done:
1415 kfree(tmp);
1416 kfree(buf);
1417 return ret;
1418 }
1419
1420 static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
1421 {
1422 struct usb_device *usb = comedi_to_usb_dev(dev);
1423 struct usbduxsigma_private *devpriv = dev->private;
1424 struct urb *urb;
1425 int i;
1426
1427 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1428 devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1429 devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1430 devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(urb), GFP_KERNEL);
1431 devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(urb), GFP_KERNEL);
1432 if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf ||
1433 !devpriv->ai_urbs || !devpriv->ao_urbs)
1434 return -ENOMEM;
1435
1436 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1437 /* one frame: 1ms */
1438 urb = usb_alloc_urb(1, GFP_KERNEL);
1439 if (!urb)
1440 return -ENOMEM;
1441 devpriv->ai_urbs[i] = urb;
1442 urb->dev = usb;
1443 /* will be filled later with a pointer to the comedi-device */
1444 /* and ONLY then the urb should be submitted */
1445 urb->context = NULL;
1446 urb->pipe = usb_rcvisocpipe(usb, 6);
1447 urb->transfer_flags = URB_ISO_ASAP;
1448 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1449 if (!urb->transfer_buffer)
1450 return -ENOMEM;
1451 urb->complete = usbduxsigma_ai_urb_complete;
1452 urb->number_of_packets = 1;
1453 urb->transfer_buffer_length = SIZEINBUF;
1454 urb->iso_frame_desc[0].offset = 0;
1455 urb->iso_frame_desc[0].length = SIZEINBUF;
1456 }
1457
1458 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1459 /* one frame: 1ms */
1460 urb = usb_alloc_urb(1, GFP_KERNEL);
1461 if (!urb)
1462 return -ENOMEM;
1463 devpriv->ao_urbs[i] = urb;
1464 urb->dev = usb;
1465 /* will be filled later with a pointer to the comedi-device */
1466 /* and ONLY then the urb should be submitted */
1467 urb->context = NULL;
1468 urb->pipe = usb_sndisocpipe(usb, 2);
1469 urb->transfer_flags = URB_ISO_ASAP;
1470 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1471 if (!urb->transfer_buffer)
1472 return -ENOMEM;
1473 urb->complete = usbduxsigma_ao_urb_complete;
1474 urb->number_of_packets = 1;
1475 urb->transfer_buffer_length = SIZEOUTBUF;
1476 urb->iso_frame_desc[0].offset = 0;
1477 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1478 if (devpriv->high_speed)
1479 urb->interval = 8; /* uframes */
1480 else
1481 urb->interval = 1; /* frames */
1482 }
1483
1484 if (devpriv->pwm_buf_sz) {
1485 urb = usb_alloc_urb(0, GFP_KERNEL);
1486 if (!urb)
1487 return -ENOMEM;
1488 devpriv->pwm_urb = urb;
1489
1490 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz,
1491 GFP_KERNEL);
1492 if (!urb->transfer_buffer)
1493 return -ENOMEM;
1494 }
1495
1496 return 0;
1497 }
1498
1499 static void usbduxsigma_free_usb_buffers(struct comedi_device *dev)
1500 {
1501 struct usbduxsigma_private *devpriv = dev->private;
1502 struct urb *urb;
1503 int i;
1504
1505 urb = devpriv->pwm_urb;
1506 if (urb) {
1507 kfree(urb->transfer_buffer);
1508 usb_free_urb(urb);
1509 }
1510 if (devpriv->ao_urbs) {
1511 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1512 urb = devpriv->ao_urbs[i];
1513 if (urb) {
1514 kfree(urb->transfer_buffer);
1515 usb_free_urb(urb);
1516 }
1517 }
1518 kfree(devpriv->ao_urbs);
1519 }
1520 if (devpriv->ai_urbs) {
1521 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1522 urb = devpriv->ai_urbs[i];
1523 if (urb) {
1524 kfree(urb->transfer_buffer);
1525 usb_free_urb(urb);
1526 }
1527 }
1528 kfree(devpriv->ai_urbs);
1529 }
1530 kfree(devpriv->insn_buf);
1531 kfree(devpriv->in_buf);
1532 kfree(devpriv->dux_commands);
1533 }
1534
1535 static int usbduxsigma_auto_attach(struct comedi_device *dev,
1536 unsigned long context_unused)
1537 {
1538 struct usb_interface *intf = comedi_to_usb_interface(dev);
1539 struct usb_device *usb = comedi_to_usb_dev(dev);
1540 struct usbduxsigma_private *devpriv;
1541 struct comedi_subdevice *s;
1542 int offset;
1543 int ret;
1544
1545 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1546 if (!devpriv)
1547 return -ENOMEM;
1548
1549 sema_init(&devpriv->sem, 1);
1550
1551 usb_set_intfdata(intf, devpriv);
1552
1553 devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1554 if (devpriv->high_speed) {
1555 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1556 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1557 devpriv->pwm_buf_sz = 512;
1558 } else {
1559 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1560 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1561 }
1562
1563 ret = usbduxsigma_alloc_usb_buffers(dev);
1564 if (ret)
1565 return ret;
1566
1567 /* setting to alternate setting 3: enabling iso ep and bulk ep. */
1568 ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber,
1569 3);
1570 if (ret < 0) {
1571 dev_err(dev->class_dev,
1572 "could not set alternate setting 3 in high speed\n");
1573 return ret;
1574 }
1575
1576 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1577 usbduxsigma_firmware_upload, 0);
1578 if (ret)
1579 return ret;
1580
1581 ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 4 : 3);
1582 if (ret)
1583 return ret;
1584
1585 /* Analog Input subdevice */
1586 s = &dev->subdevices[0];
1587 dev->read_subdev = s;
1588 s->type = COMEDI_SUBD_AI;
1589 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ | SDF_LSAMPL;
1590 s->n_chan = NUMCHANNELS;
1591 s->len_chanlist = NUMCHANNELS;
1592 s->maxdata = 0x00ffffff;
1593 s->range_table = &usbduxsigma_ai_range;
1594 s->insn_read = usbduxsigma_ai_insn_read;
1595 s->do_cmdtest = usbduxsigma_ai_cmdtest;
1596 s->do_cmd = usbduxsigma_ai_cmd;
1597 s->cancel = usbduxsigma_ai_cancel;
1598
1599 /* Analog Output subdevice */
1600 s = &dev->subdevices[1];
1601 dev->write_subdev = s;
1602 s->type = COMEDI_SUBD_AO;
1603 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1604 s->n_chan = 4;
1605 s->len_chanlist = s->n_chan;
1606 s->maxdata = 0x00ff;
1607 s->range_table = &range_unipolar2_5;
1608 s->insn_write = usbduxsigma_ao_insn_write;
1609 s->insn_read = usbduxsigma_ao_insn_read;
1610 s->do_cmdtest = usbduxsigma_ao_cmdtest;
1611 s->do_cmd = usbduxsigma_ao_cmd;
1612 s->cancel = usbduxsigma_ao_cancel;
1613
1614 ret = comedi_alloc_subdev_readback(s);
1615 if (ret)
1616 return ret;
1617
1618 /* Digital I/O subdevice */
1619 s = &dev->subdevices[2];
1620 s->type = COMEDI_SUBD_DIO;
1621 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1622 s->n_chan = 24;
1623 s->maxdata = 1;
1624 s->range_table = &range_digital;
1625 s->insn_bits = usbduxsigma_dio_insn_bits;
1626 s->insn_config = usbduxsigma_dio_insn_config;
1627
1628 if (devpriv->high_speed) {
1629 /* Timer / pwm subdevice */
1630 s = &dev->subdevices[3];
1631 s->type = COMEDI_SUBD_PWM;
1632 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1633 s->n_chan = 8;
1634 s->maxdata = devpriv->pwm_buf_sz;
1635 s->insn_write = usbduxsigma_pwm_write;
1636 s->insn_config = usbduxsigma_pwm_config;
1637
1638 usbduxsigma_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1639 }
1640
1641 offset = usbduxsigma_getstatusinfo(dev, 0);
1642 if (offset < 0) {
1643 dev_err(dev->class_dev,
1644 "Communication to USBDUXSIGMA failed! Check firmware and cabling.\n");
1645 return offset;
1646 }
1647
1648 dev_info(dev->class_dev, "ADC_zero = %x\n", offset);
1649
1650 return 0;
1651 }
1652
1653 static void usbduxsigma_detach(struct comedi_device *dev)
1654 {
1655 struct usb_interface *intf = comedi_to_usb_interface(dev);
1656 struct usbduxsigma_private *devpriv = dev->private;
1657
1658 usb_set_intfdata(intf, NULL);
1659
1660 if (!devpriv)
1661 return;
1662
1663 down(&devpriv->sem);
1664
1665 /* force unlink all urbs */
1666 usbduxsigma_ai_stop(dev, 1);
1667 usbduxsigma_ao_stop(dev, 1);
1668 usbduxsigma_pwm_stop(dev, 1);
1669
1670 usbduxsigma_free_usb_buffers(dev);
1671
1672 up(&devpriv->sem);
1673 }
1674
1675 static struct comedi_driver usbduxsigma_driver = {
1676 .driver_name = "usbduxsigma",
1677 .module = THIS_MODULE,
1678 .auto_attach = usbduxsigma_auto_attach,
1679 .detach = usbduxsigma_detach,
1680 };
1681
1682 static int usbduxsigma_usb_probe(struct usb_interface *intf,
1683 const struct usb_device_id *id)
1684 {
1685 return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);
1686 }
1687
1688 static const struct usb_device_id usbduxsigma_usb_table[] = {
1689 { USB_DEVICE(0x13d8, 0x0020) },
1690 { USB_DEVICE(0x13d8, 0x0021) },
1691 { USB_DEVICE(0x13d8, 0x0022) },
1692 { }
1693 };
1694 MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
1695
1696 static struct usb_driver usbduxsigma_usb_driver = {
1697 .name = "usbduxsigma",
1698 .probe = usbduxsigma_usb_probe,
1699 .disconnect = comedi_usb_auto_unconfig,
1700 .id_table = usbduxsigma_usb_table,
1701 };
1702 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
1703
1704 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1705 MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com");
1706 MODULE_LICENSE("GPL");
1707 MODULE_FIRMWARE(FIRMWARE);
This page took 0.068513 seconds and 5 git commands to generate.