staging: delete non-required instances of include <linux/init.h>
[deliverable/linux.git] / drivers / staging / comedi / drivers / usbdux.c
1 /*
2 comedi/drivers/usbdux.c
3 Copyright (C) 2003-2007 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 Driver: usbdux
17 Description: University of Stirling USB DAQ & INCITE Technology Limited
18 Devices: [ITL] USB-DUX (usbdux.o)
19 Author: Bernd Porr <BerndPorr@f2s.com>
20 Updated: 8 Dec 2008
21 Status: Stable
22 Configuration options:
23 You have to upload firmware with the -i option. The
24 firmware is usually installed under /usr/share/usb or
25 /usr/local/share/usb or /lib/firmware.
26
27 Connection scheme for the counter at the digital port:
28 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
29 The sampling rate of the counter is approximately 500Hz.
30
31 Please note that under USB2.0 the length of the channel list determines
32 the max sampling rate. If you sample only one channel you get 8kHz
33 sampling rate. If you sample two channels you get 4kHz and so on.
34 */
35 /*
36 * I must give credit here to Chris Baugher who
37 * wrote the driver for AT-MIO-16d. I used some parts of this
38 * driver. I also must give credits to David Brownell
39 * who supported me with the USB development.
40 *
41 * Bernd Porr
42 *
43 *
44 * Revision history:
45 * 0.94: D/A output should work now with any channel list combinations
46 * 0.95: .owner commented out for kernel vers below 2.4.19
47 * sanity checks in ai/ao_cmd
48 * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
49 * attach final USB IDs
50 * moved memory allocation completely to the corresponding comedi
51 * functions firmware upload is by fxload and no longer by comedi (due to
52 * enumeration)
53 * 0.97: USB IDs received, adjusted table
54 * 0.98: SMP, locking, memory alloc: moved all usb memory alloc
55 * to the usb subsystem and moved all comedi related memory
56 * alloc to comedi.
57 * | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
58 * 0.99: USB 2.0: changed protocol to isochronous transfer
59 * IRQ transfer is too buggy and too risky in 2.0
60 * for the high speed ISO transfer is now a working version
61 * available
62 * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
63 * chipsets miss out IRQs. Deeper buffering is needed.
64 * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
65 * rate.
66 * Firmware vers 1.00 is needed for this.
67 * Two 16 bit up/down/reset counter with a sampling rate of 1kHz
68 * And loads of cleaning up, in particular streamlining the
69 * bulk transfers.
70 * 1.1: moved EP4 transfers to EP1 to make space for a PWM output on EP4
71 * 1.2: added PWM support via EP4
72 * 2.0: PWM seems to be stable and is not interfering with the other functions
73 * 2.1: changed PWM API
74 * 2.2: added firmware kernel request to fix an udev problem
75 * 2.3: corrected a bug in bulk timeouts which were far too short
76 * 2.4: fixed a bug which causes the driver to hang when it ran out of data.
77 * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
78 *
79 */
80
81 #include <linux/kernel.h>
82 #include <linux/module.h>
83 #include <linux/slab.h>
84 #include <linux/input.h>
85 #include <linux/usb.h>
86 #include <linux/fcntl.h>
87 #include <linux/compiler.h>
88
89 #include "../comedidev.h"
90
91 #include "comedi_fc.h"
92
93 /* constants for firmware upload and download */
94 #define USBDUX_FIRMWARE "usbdux_firmware.bin"
95 #define USBDUX_FIRMWARE_MAX_LEN 0x2000
96 #define USBDUX_FIRMWARE_CMD 0xa0
97 #define VENDOR_DIR_IN 0xc0
98 #define VENDOR_DIR_OUT 0x40
99 #define USBDUX_CPU_CS 0xe600
100
101 /* usbdux bulk transfer commands */
102 #define USBDUX_CMD_MULT_AI 0
103 #define USBDUX_CMD_AO 1
104 #define USBDUX_CMD_DIO_CFG 2
105 #define USBDUX_CMD_DIO_BITS 3
106 #define USBDUX_CMD_SINGLE_AI 4
107 #define USBDUX_CMD_TIMER_RD 5
108 #define USBDUX_CMD_TIMER_WR 6
109 #define USBDUX_CMD_PWM_ON 7
110 #define USBDUX_CMD_PWM_OFF 8
111
112 #define USBDUX_NUM_AO_CHAN 4
113
114 /* timeout for the USB-transfer in ms */
115 #define BULK_TIMEOUT 1000
116
117 /* 300Hz max frequ under PWM */
118 #define MIN_PWM_PERIOD ((long)(1E9/300))
119
120 /* Default PWM frequency */
121 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
122
123 /* Size of one A/D value */
124 #define SIZEADIN ((sizeof(uint16_t)))
125
126 /*
127 * Size of the input-buffer IN BYTES
128 * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
129 */
130 #define SIZEINBUF ((8*SIZEADIN))
131
132 /* 16 bytes. */
133 #define SIZEINSNBUF 16
134
135 /* size of one value for the D/A converter: channel and value */
136 #define SIZEDAOUT ((sizeof(uint8_t)+sizeof(uint16_t)))
137
138 /*
139 * Size of the output-buffer in bytes
140 * Actually only the first 4 triplets are used but for the
141 * high speed mode we need to pad it to 8 (microframes).
142 */
143 #define SIZEOUTBUF ((8*SIZEDAOUT))
144
145 /*
146 * Size of the buffer for the dux commands: just now max size is determined
147 * by the analogue out + command byte + panic bytes...
148 */
149 #define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2))
150
151 /* Number of in-URBs which receive the data: min=2 */
152 #define NUMOFINBUFFERSFULL 5
153
154 /* Number of out-URBs which send the data: min=2 */
155 #define NUMOFOUTBUFFERSFULL 5
156
157 /* Number of in-URBs which receive the data: min=5 */
158 /* must have more buffers due to buggy USB ctr */
159 #define NUMOFINBUFFERSHIGH 10
160
161 /* Number of out-URBs which send the data: min=5 */
162 /* must have more buffers due to buggy USB ctr */
163 #define NUMOFOUTBUFFERSHIGH 10
164
165 /* number of retries to get the right dux command */
166 #define RETRIES 10
167
168 static const struct comedi_lrange range_usbdux_ai_range = {
169 4, {
170 BIP_RANGE(4.096),
171 BIP_RANGE(4.096 / 2),
172 UNI_RANGE(4.096),
173 UNI_RANGE(4.096 / 2)
174 }
175 };
176
177 static const struct comedi_lrange range_usbdux_ao_range = {
178 2, {
179 BIP_RANGE(4.096),
180 UNI_RANGE(4.096)
181 }
182 };
183
184 struct usbdux_private {
185 /* actual number of in-buffers */
186 int n_ai_urbs;
187 /* actual number of out-buffers */
188 int n_ao_urbs;
189 /* ISO-transfer handling: buffers */
190 struct urb **ai_urbs;
191 struct urb **ao_urbs;
192 /* pwm-transfer handling */
193 struct urb *pwm_urb;
194 /* PWM period */
195 unsigned int pwm_period;
196 /* PWM internal delay for the GPIF in the FX2 */
197 uint8_t pwm_delay;
198 /* size of the PWM buffer which holds the bit pattern */
199 int pwm_buf_sz;
200 /* input buffer for the ISO-transfer */
201 uint16_t *in_buf;
202 /* input buffer for single insn */
203 uint16_t *insn_buf;
204
205 uint8_t ao_chanlist[USBDUX_NUM_AO_CHAN];
206 unsigned int ao_readback[USBDUX_NUM_AO_CHAN];
207
208 unsigned int high_speed:1;
209 unsigned int ai_cmd_running:1;
210 unsigned int ai_continous:1;
211 unsigned int ao_cmd_running:1;
212 unsigned int ao_continous:1;
213 unsigned int pwm_cmd_running:1;
214
215 /* number of samples to acquire */
216 int ai_sample_count;
217 int ao_sample_count;
218 /* time between samples in units of the timer */
219 unsigned int ai_timer;
220 unsigned int ao_timer;
221 /* counter between aquisitions */
222 unsigned int ai_counter;
223 unsigned int ao_counter;
224 /* interval in frames/uframes */
225 unsigned int ai_interval;
226 /* commands */
227 uint8_t *dux_commands;
228 struct semaphore sem;
229 };
230
231 static void usbdux_unlink_urbs(struct urb **urbs, int num_urbs)
232 {
233 int i;
234
235 for (i = 0; i < num_urbs; i++)
236 usb_kill_urb(urbs[i]);
237 }
238
239 static void usbdux_ai_stop(struct comedi_device *dev, int do_unlink)
240 {
241 struct usbdux_private *devpriv = dev->private;
242
243 if (do_unlink && devpriv->ai_urbs)
244 usbdux_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs);
245
246 devpriv->ai_cmd_running = 0;
247 }
248
249 static int usbdux_ai_cancel(struct comedi_device *dev,
250 struct comedi_subdevice *s)
251 {
252 struct usbdux_private *devpriv = dev->private;
253
254 /* prevent other CPUs from submitting new commands just now */
255 down(&devpriv->sem);
256 /* unlink only if the urb really has been submitted */
257 usbdux_ai_stop(dev, devpriv->ai_cmd_running);
258 up(&devpriv->sem);
259
260 return 0;
261 }
262
263 /* analogue IN - interrupt service routine */
264 static void usbduxsub_ai_isoc_irq(struct urb *urb)
265 {
266 struct comedi_device *dev = urb->context;
267 struct comedi_subdevice *s = dev->read_subdev;
268 struct usbdux_private *devpriv = dev->private;
269 int i, err, n;
270
271 /* first we test if something unusual has just happened */
272 switch (urb->status) {
273 case 0:
274 /* copy the result in the transfer buffer */
275 memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
276 break;
277 case -EILSEQ:
278 /* error in the ISOchronous data */
279 /* we don't copy the data into the transfer buffer */
280 /* and recycle the last data byte */
281 dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
282 break;
283
284 case -ECONNRESET:
285 case -ENOENT:
286 case -ESHUTDOWN:
287 case -ECONNABORTED:
288 /* happens after an unlink command */
289 if (devpriv->ai_cmd_running) {
290 s->async->events |= COMEDI_CB_EOA;
291 s->async->events |= COMEDI_CB_ERROR;
292 comedi_event(dev, s);
293 /* stop the transfer w/o unlink */
294 usbdux_ai_stop(dev, 0);
295 }
296 return;
297
298 default:
299 /* a real error on the bus */
300 /* pass error to comedi if we are really running a command */
301 if (devpriv->ai_cmd_running) {
302 dev_err(dev->class_dev,
303 "Non-zero urb status received in ai intr context: %d\n",
304 urb->status);
305 s->async->events |= COMEDI_CB_EOA;
306 s->async->events |= COMEDI_CB_ERROR;
307 comedi_event(dev, s);
308 /* don't do an unlink here */
309 usbdux_ai_stop(dev, 0);
310 }
311 return;
312 }
313
314 /*
315 * at this point we are reasonably sure that nothing dodgy has happened
316 * are we running a command?
317 */
318 if (unlikely(!devpriv->ai_cmd_running)) {
319 /*
320 * not running a command, do not continue execution if no
321 * asynchronous command is running in particular not resubmit
322 */
323 return;
324 }
325
326 urb->dev = comedi_to_usb_dev(dev);
327
328 /* resubmit the urb */
329 err = usb_submit_urb(urb, GFP_ATOMIC);
330 if (unlikely(err < 0)) {
331 dev_err(dev->class_dev,
332 "urb resubmit failed in int-context! err=%d\n", err);
333 if (err == -EL2NSYNC)
334 dev_err(dev->class_dev,
335 "buggy USB host controller or bug in IRQ handler!\n");
336 s->async->events |= COMEDI_CB_EOA;
337 s->async->events |= COMEDI_CB_ERROR;
338 comedi_event(dev, s);
339 /* don't do an unlink here */
340 usbdux_ai_stop(dev, 0);
341 return;
342 }
343
344 devpriv->ai_counter--;
345 if (likely(devpriv->ai_counter > 0))
346 return;
347
348 /* timer zero, transfer measurements to comedi */
349 devpriv->ai_counter = devpriv->ai_timer;
350
351 /* test, if we transmit only a fixed number of samples */
352 if (!devpriv->ai_continous) {
353 /* not continuous, fixed number of samples */
354 devpriv->ai_sample_count--;
355 /* all samples received? */
356 if (devpriv->ai_sample_count < 0) {
357 /* prevent a resubmit next time */
358 usbdux_ai_stop(dev, 0);
359 /* say comedi that the acquistion is over */
360 s->async->events |= COMEDI_CB_EOA;
361 comedi_event(dev, s);
362 return;
363 }
364 }
365 /* get the data from the USB bus and hand it over to comedi */
366 n = s->async->cmd.chanlist_len;
367 for (i = 0; i < n; i++) {
368 unsigned int range = CR_RANGE(s->async->cmd.chanlist[i]);
369 uint16_t val = le16_to_cpu(devpriv->in_buf[i]);
370
371 /* bipolar data is two's-complement */
372 if (comedi_range_is_bipolar(s, range))
373 val ^= ((s->maxdata + 1) >> 1);
374
375 /* transfer data */
376 err = comedi_buf_put(s->async, val);
377 if (unlikely(err == 0)) {
378 /* buffer overflow */
379 usbdux_ai_stop(dev, 0);
380 return;
381 }
382 }
383 /* tell comedi that data is there */
384 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
385 comedi_event(dev, s);
386 }
387
388 static void usbdux_ao_stop(struct comedi_device *dev, int do_unlink)
389 {
390 struct usbdux_private *devpriv = dev->private;
391
392 if (do_unlink && devpriv->ao_urbs)
393 usbdux_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs);
394
395 devpriv->ao_cmd_running = 0;
396 }
397
398 static int usbdux_ao_cancel(struct comedi_device *dev,
399 struct comedi_subdevice *s)
400 {
401 struct usbdux_private *devpriv = dev->private;
402
403 /* prevent other CPUs from submitting a command just now */
404 down(&devpriv->sem);
405 /* unlink only if it is really running */
406 usbdux_ao_stop(dev, devpriv->ao_cmd_running);
407 up(&devpriv->sem);
408
409 return 0;
410 }
411
412 static void usbduxsub_ao_isoc_irq(struct urb *urb)
413 {
414 struct comedi_device *dev = urb->context;
415 struct comedi_subdevice *s = dev->write_subdev;
416 struct usbdux_private *devpriv = dev->private;
417 uint8_t *datap;
418 int len;
419 int ret;
420 int i;
421
422 switch (urb->status) {
423 case 0:
424 /* success */
425 break;
426
427 case -ECONNRESET:
428 case -ENOENT:
429 case -ESHUTDOWN:
430 case -ECONNABORTED:
431 /* after an unlink command, unplug, ... etc */
432 /* no unlink needed here. Already shutting down. */
433 if (devpriv->ao_cmd_running) {
434 s->async->events |= COMEDI_CB_EOA;
435 comedi_event(dev, s);
436 usbdux_ao_stop(dev, 0);
437 }
438 return;
439
440 default:
441 /* a real error */
442 if (devpriv->ao_cmd_running) {
443 dev_err(dev->class_dev,
444 "Non-zero urb status received in ao intr context: %d\n",
445 urb->status);
446 s->async->events |= COMEDI_CB_ERROR;
447 s->async->events |= COMEDI_CB_EOA;
448 comedi_event(dev, s);
449 /* we do an unlink if we are in the high speed mode */
450 usbdux_ao_stop(dev, 0);
451 }
452 return;
453 }
454
455 /* are we actually running? */
456 if (!devpriv->ao_cmd_running)
457 return;
458
459 /* normal operation: executing a command in this subdevice */
460 devpriv->ao_counter--;
461 if ((int)devpriv->ao_counter <= 0) {
462 /* timer zero */
463 devpriv->ao_counter = devpriv->ao_timer;
464
465 /* handle non continous acquisition */
466 if (!devpriv->ao_continous) {
467 /* fixed number of samples */
468 devpriv->ao_sample_count--;
469 if (devpriv->ao_sample_count < 0) {
470 /* all samples transmitted */
471 usbdux_ao_stop(dev, 0);
472 s->async->events |= COMEDI_CB_EOA;
473 comedi_event(dev, s);
474 /* no resubmit of the urb */
475 return;
476 }
477 }
478
479 /* transmit data to the USB bus */
480 datap = urb->transfer_buffer;
481 len = s->async->cmd.chanlist_len;
482 *datap++ = len;
483 for (i = 0; i < s->async->cmd.chanlist_len; i++) {
484 unsigned int chan = devpriv->ao_chanlist[i];
485 unsigned short val;
486
487 ret = comedi_buf_get(s->async, &val);
488 if (ret < 0) {
489 dev_err(dev->class_dev, "buffer underflow\n");
490 s->async->events |= (COMEDI_CB_EOA |
491 COMEDI_CB_OVERFLOW);
492 }
493 /* pointer to the DA */
494 *datap++ = val & 0xff;
495 *datap++ = (val >> 8) & 0xff;
496 *datap++ = chan;
497 devpriv->ao_readback[chan] = val;
498
499 s->async->events |= COMEDI_CB_BLOCK;
500 comedi_event(dev, s);
501 }
502 }
503 urb->transfer_buffer_length = SIZEOUTBUF;
504 urb->dev = comedi_to_usb_dev(dev);
505 urb->status = 0;
506 if (devpriv->ao_cmd_running) {
507 if (devpriv->high_speed)
508 urb->interval = 8; /* uframes */
509 else
510 urb->interval = 1; /* frames */
511 urb->number_of_packets = 1;
512 urb->iso_frame_desc[0].offset = 0;
513 urb->iso_frame_desc[0].length = SIZEOUTBUF;
514 urb->iso_frame_desc[0].status = 0;
515 ret = usb_submit_urb(urb, GFP_ATOMIC);
516 if (ret < 0) {
517 dev_err(dev->class_dev,
518 "ao urb resubm failed in int-cont. ret=%d",
519 ret);
520 if (ret == EL2NSYNC)
521 dev_err(dev->class_dev,
522 "buggy USB host controller or bug in IRQ handling!\n");
523
524 s->async->events |= COMEDI_CB_EOA;
525 s->async->events |= COMEDI_CB_ERROR;
526 comedi_event(dev, s);
527 /* don't do an unlink here */
528 usbdux_ao_stop(dev, 0);
529 }
530 }
531 }
532
533 static int usbdux_submit_urbs(struct comedi_device *dev,
534 struct urb **urbs, int num_urbs,
535 int input_urb)
536 {
537 struct usb_device *usb = comedi_to_usb_dev(dev);
538 struct usbdux_private *devpriv = dev->private;
539 struct urb *urb;
540 int ret;
541 int i;
542
543 /* Submit all URBs and start the transfer on the bus */
544 for (i = 0; i < num_urbs; i++) {
545 urb = urbs[i];
546
547 /* in case of a resubmission after an unlink... */
548 if (input_urb)
549 urb->interval = devpriv->ai_interval;
550 urb->context = dev;
551 urb->dev = usb;
552 urb->status = 0;
553 urb->transfer_flags = URB_ISO_ASAP;
554
555 ret = usb_submit_urb(urb, GFP_ATOMIC);
556 if (ret)
557 return ret;
558 }
559 return 0;
560 }
561
562 static int usbdux_ai_cmdtest(struct comedi_device *dev,
563 struct comedi_subdevice *s, struct comedi_cmd *cmd)
564 {
565 struct usbdux_private *this_usbduxsub = dev->private;
566 int err = 0, i;
567 unsigned int tmp_timer;
568
569 /* Step 1 : check if triggers are trivially valid */
570
571 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
572 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
573 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
574 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
575 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
576
577 if (err)
578 return 1;
579
580 /* Step 2a : make sure trigger sources are unique */
581
582 err |= cfc_check_trigger_is_unique(cmd->start_src);
583 err |= cfc_check_trigger_is_unique(cmd->stop_src);
584
585 /* Step 2b : and mutually compatible */
586
587 if (err)
588 return 2;
589
590 /* Step 3: check if arguments are trivially valid */
591
592 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
593
594 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
595 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
596
597 if (cmd->scan_begin_src == TRIG_TIMER) {
598 if (this_usbduxsub->high_speed) {
599 /*
600 * In high speed mode microframes are possible.
601 * However, during one microframe we can roughly
602 * sample one channel. Thus, the more channels
603 * are in the channel list the more time we need.
604 */
605 i = 1;
606 /* find a power of 2 for the number of channels */
607 while (i < (cmd->chanlist_len))
608 i = i * 2;
609
610 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
611 1000000 / 8 * i);
612 /* now calc the real sampling rate with all the
613 * rounding errors */
614 tmp_timer =
615 ((unsigned int)(cmd->scan_begin_arg / 125000)) *
616 125000;
617 } else {
618 /* full speed */
619 /* 1kHz scans every USB frame */
620 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
621 1000000);
622 /*
623 * calc the real sampling rate with the rounding errors
624 */
625 tmp_timer = ((unsigned int)(cmd->scan_begin_arg /
626 1000000)) * 1000000;
627 }
628 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
629 tmp_timer);
630 }
631
632 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
633
634 if (cmd->stop_src == TRIG_COUNT) {
635 /* any count is allowed */
636 } else {
637 /* TRIG_NONE */
638 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
639 }
640
641 if (err)
642 return 3;
643
644 return 0;
645 }
646
647 /*
648 * creates the ADC command for the MAX1271
649 * range is the range value from comedi
650 */
651 static uint8_t create_adc_command(unsigned int chan, unsigned int range)
652 {
653 uint8_t p = (range <= 1);
654 uint8_t r = ((range % 2) == 0);
655
656 return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
657 }
658
659 static int send_dux_commands(struct comedi_device *dev, unsigned int cmd_type)
660 {
661 struct usb_device *usb = comedi_to_usb_dev(dev);
662 struct usbdux_private *devpriv = dev->private;
663 int nsent;
664
665 devpriv->dux_commands[0] = cmd_type;
666
667 return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1),
668 devpriv->dux_commands, SIZEOFDUXBUFFER,
669 &nsent, BULK_TIMEOUT);
670 }
671
672 static int receive_dux_commands(struct comedi_device *dev, unsigned int command)
673 {
674 struct usb_device *usb = comedi_to_usb_dev(dev);
675 struct usbdux_private *devpriv = dev->private;
676 int ret;
677 int nrec;
678 int i;
679
680 for (i = 0; i < RETRIES; i++) {
681 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8),
682 devpriv->insn_buf, SIZEINSNBUF,
683 &nrec, BULK_TIMEOUT);
684 if (ret < 0)
685 return ret;
686 if (le16_to_cpu(devpriv->insn_buf[0]) == command)
687 return ret;
688 }
689 /* command not received */
690 return -EFAULT;
691 }
692
693 static int usbdux_ai_inttrig(struct comedi_device *dev,
694 struct comedi_subdevice *s,
695 unsigned int trignum)
696 {
697 struct usbdux_private *devpriv = dev->private;
698 int ret = -EINVAL;
699
700 down(&devpriv->sem);
701
702 if (trignum != 0)
703 goto ai_trig_exit;
704
705 if (!devpriv->ai_cmd_running) {
706 devpriv->ai_cmd_running = 1;
707 ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
708 devpriv->n_ai_urbs, 1);
709 if (ret < 0) {
710 devpriv->ai_cmd_running = 0;
711 goto ai_trig_exit;
712 }
713 s->async->inttrig = NULL;
714 } else {
715 ret = -EBUSY;
716 }
717
718 ai_trig_exit:
719 up(&devpriv->sem);
720 return ret;
721 }
722
723 static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
724 {
725 struct usbdux_private *devpriv = dev->private;
726 struct comedi_cmd *cmd = &s->async->cmd;
727 int len = cmd->chanlist_len;
728 int ret = -EBUSY;
729 int i;
730
731 /* block other CPUs from starting an ai_cmd */
732 down(&devpriv->sem);
733
734 if (devpriv->ai_cmd_running)
735 goto ai_cmd_exit;
736
737 /* set current channel of the running acquisition to zero */
738 s->async->cur_chan = 0;
739
740 devpriv->dux_commands[1] = len;
741 for (i = 0; i < len; ++i) {
742 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
743 unsigned int range = CR_RANGE(cmd->chanlist[i]);
744
745 devpriv->dux_commands[i + 2] = create_adc_command(chan, range);
746 }
747
748 ret = send_dux_commands(dev, USBDUX_CMD_MULT_AI);
749 if (ret < 0)
750 goto ai_cmd_exit;
751
752 if (devpriv->high_speed) {
753 /*
754 * every channel gets a time window of 125us. Thus, if we
755 * sample all 8 channels we need 1ms. If we sample only one
756 * channel we need only 125us
757 */
758 devpriv->ai_interval = 1;
759 /* find a power of 2 for the interval */
760 while (devpriv->ai_interval < len)
761 devpriv->ai_interval *= 2;
762
763 devpriv->ai_timer = cmd->scan_begin_arg /
764 (125000 * devpriv->ai_interval);
765 } else {
766 /* interval always 1ms */
767 devpriv->ai_interval = 1;
768 devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
769 }
770 if (devpriv->ai_timer < 1) {
771 ret = -EINVAL;
772 goto ai_cmd_exit;
773 }
774
775 devpriv->ai_counter = devpriv->ai_timer;
776
777 if (cmd->stop_src == TRIG_COUNT) {
778 /* data arrives as one packet */
779 devpriv->ai_sample_count = cmd->stop_arg;
780 devpriv->ai_continous = 0;
781 } else {
782 /* continous acquisition */
783 devpriv->ai_continous = 1;
784 devpriv->ai_sample_count = 0;
785 }
786
787 if (cmd->start_src == TRIG_NOW) {
788 /* enable this acquisition operation */
789 devpriv->ai_cmd_running = 1;
790 ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
791 devpriv->n_ai_urbs, 1);
792 if (ret < 0) {
793 devpriv->ai_cmd_running = 0;
794 /* fixme: unlink here?? */
795 goto ai_cmd_exit;
796 }
797 s->async->inttrig = NULL;
798 } else {
799 /* TRIG_INT */
800 /* don't enable the acquision operation */
801 /* wait for an internal signal */
802 s->async->inttrig = usbdux_ai_inttrig;
803 }
804
805 ai_cmd_exit:
806 up(&devpriv->sem);
807
808 return ret;
809 }
810
811 /* Mode 0 is used to get a single conversion on demand */
812 static int usbdux_ai_insn_read(struct comedi_device *dev,
813 struct comedi_subdevice *s,
814 struct comedi_insn *insn,
815 unsigned int *data)
816 {
817 struct usbdux_private *devpriv = dev->private;
818 unsigned int chan = CR_CHAN(insn->chanspec);
819 unsigned int range = CR_RANGE(insn->chanspec);
820 unsigned int val;
821 int ret = -EBUSY;
822 int i;
823
824 down(&devpriv->sem);
825
826 if (devpriv->ai_cmd_running)
827 goto ai_read_exit;
828
829 /* set command for the first channel */
830 devpriv->dux_commands[1] = create_adc_command(chan, range);
831
832 /* adc commands */
833 ret = send_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
834 if (ret < 0)
835 goto ai_read_exit;
836
837 for (i = 0; i < insn->n; i++) {
838 ret = receive_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
839 if (ret < 0)
840 goto ai_read_exit;
841
842 val = le16_to_cpu(devpriv->insn_buf[1]);
843
844 /* bipolar data is two's-complement */
845 if (comedi_range_is_bipolar(s, range))
846 val ^= ((s->maxdata + 1) >> 1);
847
848 data[i] = val;
849 }
850
851 ai_read_exit:
852 up(&devpriv->sem);
853
854 return ret ? ret : insn->n;
855 }
856
857 static int usbdux_ao_insn_read(struct comedi_device *dev,
858 struct comedi_subdevice *s,
859 struct comedi_insn *insn,
860 unsigned int *data)
861 {
862 struct usbdux_private *devpriv = dev->private;
863 unsigned int chan = CR_CHAN(insn->chanspec);
864 int i;
865
866 down(&devpriv->sem);
867 for (i = 0; i < insn->n; i++)
868 data[i] = devpriv->ao_readback[chan];
869 up(&devpriv->sem);
870
871 return insn->n;
872 }
873
874 static int usbdux_ao_insn_write(struct comedi_device *dev,
875 struct comedi_subdevice *s,
876 struct comedi_insn *insn,
877 unsigned int *data)
878 {
879 struct usbdux_private *devpriv = dev->private;
880 unsigned int chan = CR_CHAN(insn->chanspec);
881 unsigned int val = devpriv->ao_readback[chan];
882 uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
883 int ret = -EBUSY;
884 int i;
885
886 down(&devpriv->sem);
887
888 if (devpriv->ao_cmd_running)
889 goto ao_write_exit;
890
891 /* number of channels: 1 */
892 devpriv->dux_commands[1] = 1;
893 /* channel number */
894 devpriv->dux_commands[4] = chan << 6;
895
896 for (i = 0; i < insn->n; i++) {
897 val = data[i];
898
899 /* one 16 bit value */
900 *p = cpu_to_le16(val);
901
902 ret = send_dux_commands(dev, USBDUX_CMD_AO);
903 if (ret < 0)
904 goto ao_write_exit;
905 }
906 devpriv->ao_readback[chan] = val;
907
908 ao_write_exit:
909 up(&devpriv->sem);
910
911 return ret ? ret : insn->n;
912 }
913
914 static int usbdux_ao_inttrig(struct comedi_device *dev,
915 struct comedi_subdevice *s,
916 unsigned int trignum)
917 {
918 struct usbdux_private *devpriv = dev->private;
919 int ret = -EINVAL;
920
921 down(&devpriv->sem);
922
923 if (trignum != 0)
924 goto ao_trig_exit;
925
926 if (!devpriv->ao_cmd_running) {
927 devpriv->ao_cmd_running = 1;
928 ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
929 devpriv->n_ao_urbs, 0);
930 if (ret < 0) {
931 devpriv->ao_cmd_running = 0;
932 goto ao_trig_exit;
933 }
934 s->async->inttrig = NULL;
935 } else {
936 ret = -EBUSY;
937 }
938
939 ao_trig_exit:
940 up(&devpriv->sem);
941 return ret;
942 }
943
944 static int usbdux_ao_cmdtest(struct comedi_device *dev,
945 struct comedi_subdevice *s, struct comedi_cmd *cmd)
946 {
947 struct usbdux_private *this_usbduxsub = dev->private;
948 int err = 0;
949 unsigned int flags;
950
951 if (!this_usbduxsub)
952 return -EFAULT;
953
954 /* Step 1 : check if triggers are trivially valid */
955
956 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
957
958 if (0) { /* (this_usbduxsub->high_speed) */
959 /* the sampling rate is set by the coversion rate */
960 flags = TRIG_FOLLOW;
961 } else {
962 /* start a new scan (output at once) with a timer */
963 flags = TRIG_TIMER;
964 }
965 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
966
967 if (0) { /* (this_usbduxsub->high_speed) */
968 /*
969 * in usb-2.0 only one conversion it transmitted
970 * but with 8kHz/n
971 */
972 flags = TRIG_TIMER;
973 } else {
974 /*
975 * all conversion events happen simultaneously with
976 * a rate of 1kHz/n
977 */
978 flags = TRIG_NOW;
979 }
980 err |= cfc_check_trigger_src(&cmd->convert_src, flags);
981
982 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
983 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
984
985 if (err)
986 return 1;
987
988 /* Step 2a : make sure trigger sources are unique */
989
990 err |= cfc_check_trigger_is_unique(cmd->start_src);
991 err |= cfc_check_trigger_is_unique(cmd->stop_src);
992
993 /* Step 2b : and mutually compatible */
994
995 if (err)
996 return 2;
997
998 /* Step 3: check if arguments are trivially valid */
999
1000 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1001
1002 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
1003 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1004
1005 if (cmd->scan_begin_src == TRIG_TIMER)
1006 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1007 1000000);
1008
1009 /* not used now, is for later use */
1010 if (cmd->convert_src == TRIG_TIMER)
1011 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000);
1012
1013 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1014
1015 if (cmd->stop_src == TRIG_COUNT) {
1016 /* any count is allowed */
1017 } else {
1018 /* TRIG_NONE */
1019 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1020 }
1021
1022 if (err)
1023 return 3;
1024
1025 return 0;
1026 }
1027
1028 static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1029 {
1030 struct usbdux_private *devpriv = dev->private;
1031 struct comedi_cmd *cmd = &s->async->cmd;
1032 int ret = -EBUSY;
1033 int i;
1034
1035 down(&devpriv->sem);
1036
1037 if (devpriv->ao_cmd_running)
1038 goto ao_cmd_exit;
1039
1040 /* set current channel of the running acquisition to zero */
1041 s->async->cur_chan = 0;
1042
1043 for (i = 0; i < cmd->chanlist_len; ++i) {
1044 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
1045
1046 devpriv->ao_chanlist[i] = chan << 6;
1047 }
1048
1049 /* we count in steps of 1ms (125us) */
1050 /* 125us mode not used yet */
1051 if (0) { /* (devpriv->high_speed) */
1052 /* 125us */
1053 /* timing of the conversion itself: every 125 us */
1054 devpriv->ao_timer = cmd->convert_arg / 125000;
1055 } else {
1056 /* 1ms */
1057 /* timing of the scan: we get all channels at once */
1058 devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
1059 if (devpriv->ao_timer < 1) {
1060 ret = -EINVAL;
1061 goto ao_cmd_exit;
1062 }
1063 }
1064
1065 devpriv->ao_counter = devpriv->ao_timer;
1066
1067 if (cmd->stop_src == TRIG_COUNT) {
1068 /* not continuous */
1069 /* counter */
1070 /* high speed also scans everything at once */
1071 if (0) { /* (devpriv->high_speed) */
1072 devpriv->ao_sample_count = cmd->stop_arg *
1073 cmd->scan_end_arg;
1074 } else {
1075 /* there's no scan as the scan has been */
1076 /* perf inside the FX2 */
1077 /* data arrives as one packet */
1078 devpriv->ao_sample_count = cmd->stop_arg;
1079 }
1080 devpriv->ao_continous = 0;
1081 } else {
1082 /* continous acquisition */
1083 devpriv->ao_continous = 1;
1084 devpriv->ao_sample_count = 0;
1085 }
1086
1087 if (cmd->start_src == TRIG_NOW) {
1088 /* enable this acquisition operation */
1089 devpriv->ao_cmd_running = 1;
1090 ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
1091 devpriv->n_ao_urbs, 0);
1092 if (ret < 0) {
1093 devpriv->ao_cmd_running = 0;
1094 /* fixme: unlink here?? */
1095 goto ao_cmd_exit;
1096 }
1097 s->async->inttrig = NULL;
1098 } else {
1099 /* TRIG_INT */
1100 /* submit the urbs later */
1101 /* wait for an internal signal */
1102 s->async->inttrig = usbdux_ao_inttrig;
1103 }
1104
1105 ao_cmd_exit:
1106 up(&devpriv->sem);
1107
1108 return ret;
1109 }
1110
1111 static int usbdux_dio_insn_config(struct comedi_device *dev,
1112 struct comedi_subdevice *s,
1113 struct comedi_insn *insn,
1114 unsigned int *data)
1115 {
1116 int ret;
1117
1118 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1119 if (ret)
1120 return ret;
1121
1122 /*
1123 * We don't tell the firmware here as it would take 8 frames
1124 * to submit the information. We do it in the insn_bits.
1125 */
1126 return insn->n;
1127 }
1128
1129 static int usbdux_dio_insn_bits(struct comedi_device *dev,
1130 struct comedi_subdevice *s,
1131 struct comedi_insn *insn,
1132 unsigned int *data)
1133 {
1134
1135 struct usbdux_private *devpriv = dev->private;
1136 int ret;
1137
1138 down(&devpriv->sem);
1139
1140 comedi_dio_update_state(s, data);
1141
1142 /* Always update the hardware. See the (*insn_config). */
1143 devpriv->dux_commands[1] = s->io_bits;
1144 devpriv->dux_commands[2] = s->state;
1145
1146 /*
1147 * This command also tells the firmware to return
1148 * the digital input lines.
1149 */
1150 ret = send_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1151 if (ret < 0)
1152 goto dio_exit;
1153 ret = receive_dux_commands(dev, USBDUX_CMD_DIO_BITS);
1154 if (ret < 0)
1155 goto dio_exit;
1156
1157 data[1] = le16_to_cpu(devpriv->insn_buf[1]);
1158
1159 dio_exit:
1160 up(&devpriv->sem);
1161
1162 return ret ? ret : insn->n;
1163 }
1164
1165 static int usbdux_counter_read(struct comedi_device *dev,
1166 struct comedi_subdevice *s,
1167 struct comedi_insn *insn,
1168 unsigned int *data)
1169 {
1170 struct usbdux_private *devpriv = dev->private;
1171 unsigned int chan = CR_CHAN(insn->chanspec);
1172 int ret = 0;
1173 int i;
1174
1175 down(&devpriv->sem);
1176
1177 for (i = 0; i < insn->n; i++) {
1178 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1179 if (ret < 0)
1180 goto counter_read_exit;
1181 ret = receive_dux_commands(dev, USBDUX_CMD_TIMER_RD);
1182 if (ret < 0)
1183 goto counter_read_exit;
1184
1185 data[i] = le16_to_cpu(devpriv->insn_buf[chan + 1]);
1186 }
1187
1188 counter_read_exit:
1189 up(&devpriv->sem);
1190
1191 return ret ? ret : insn->n;
1192 }
1193
1194 static int usbdux_counter_write(struct comedi_device *dev,
1195 struct comedi_subdevice *s,
1196 struct comedi_insn *insn,
1197 unsigned int *data)
1198 {
1199 struct usbdux_private *devpriv = dev->private;
1200 unsigned int chan = CR_CHAN(insn->chanspec);
1201 uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
1202 int ret = 0;
1203 int i;
1204
1205 down(&devpriv->sem);
1206
1207 devpriv->dux_commands[1] = chan;
1208
1209 for (i = 0; i < insn->n; i++) {
1210 *p = cpu_to_le16(data[i]);
1211
1212 ret = send_dux_commands(dev, USBDUX_CMD_TIMER_WR);
1213 if (ret < 0)
1214 break;
1215 }
1216
1217 up(&devpriv->sem);
1218
1219 return ret ? ret : insn->n;
1220 }
1221
1222 static int usbdux_counter_config(struct comedi_device *dev,
1223 struct comedi_subdevice *s,
1224 struct comedi_insn *insn, unsigned int *data)
1225 {
1226 /* nothing to do so far */
1227 return 2;
1228 }
1229
1230 static void usbduxsub_unlink_pwm_urbs(struct comedi_device *dev)
1231 {
1232 struct usbdux_private *devpriv = dev->private;
1233
1234 usb_kill_urb(devpriv->pwm_urb);
1235 }
1236
1237 static void usbdux_pwm_stop(struct comedi_device *dev, int do_unlink)
1238 {
1239 struct usbdux_private *devpriv = dev->private;
1240
1241 if (do_unlink)
1242 usbduxsub_unlink_pwm_urbs(dev);
1243
1244 devpriv->pwm_cmd_running = 0;
1245 }
1246
1247 static int usbdux_pwm_cancel(struct comedi_device *dev,
1248 struct comedi_subdevice *s)
1249 {
1250 struct usbdux_private *devpriv = dev->private;
1251 int ret;
1252
1253 down(&devpriv->sem);
1254 /* unlink only if it is really running */
1255 usbdux_pwm_stop(dev, devpriv->pwm_cmd_running);
1256 ret = send_dux_commands(dev, USBDUX_CMD_PWM_OFF);
1257 up(&devpriv->sem);
1258
1259 return ret;
1260 }
1261
1262 static void usbduxsub_pwm_irq(struct urb *urb)
1263 {
1264 struct comedi_device *dev = urb->context;
1265 struct usbdux_private *devpriv = dev->private;
1266 int ret;
1267
1268 switch (urb->status) {
1269 case 0:
1270 /* success */
1271 break;
1272
1273 case -ECONNRESET:
1274 case -ENOENT:
1275 case -ESHUTDOWN:
1276 case -ECONNABORTED:
1277 /*
1278 * after an unlink command, unplug, ... etc
1279 * no unlink needed here. Already shutting down.
1280 */
1281 if (devpriv->pwm_cmd_running)
1282 usbdux_pwm_stop(dev, 0);
1283
1284 return;
1285
1286 default:
1287 /* a real error */
1288 if (devpriv->pwm_cmd_running) {
1289 dev_err(dev->class_dev,
1290 "Non-zero urb status received in pwm intr context: %d\n",
1291 urb->status);
1292 usbdux_pwm_stop(dev, 0);
1293 }
1294 return;
1295 }
1296
1297 /* are we actually running? */
1298 if (!devpriv->pwm_cmd_running)
1299 return;
1300
1301 urb->transfer_buffer_length = devpriv->pwm_buf_sz;
1302 urb->dev = comedi_to_usb_dev(dev);
1303 urb->status = 0;
1304 if (devpriv->pwm_cmd_running) {
1305 ret = usb_submit_urb(urb, GFP_ATOMIC);
1306 if (ret < 0) {
1307 dev_err(dev->class_dev,
1308 "pwm urb resubm failed in int-cont. ret=%d",
1309 ret);
1310 if (ret == EL2NSYNC)
1311 dev_err(dev->class_dev,
1312 "buggy USB host controller or bug in IRQ handling!\n");
1313
1314 /* don't do an unlink here */
1315 usbdux_pwm_stop(dev, 0);
1316 }
1317 }
1318 }
1319
1320 static int usbduxsub_submit_pwm_urbs(struct comedi_device *dev)
1321 {
1322 struct usb_device *usb = comedi_to_usb_dev(dev);
1323 struct usbdux_private *devpriv = dev->private;
1324 struct urb *urb = devpriv->pwm_urb;
1325
1326 /* in case of a resubmission after an unlink... */
1327 usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4),
1328 urb->transfer_buffer,
1329 devpriv->pwm_buf_sz,
1330 usbduxsub_pwm_irq,
1331 dev);
1332
1333 return usb_submit_urb(urb, GFP_ATOMIC);
1334 }
1335
1336 static int usbdux_pwm_period(struct comedi_device *dev,
1337 struct comedi_subdevice *s,
1338 unsigned int period)
1339 {
1340 struct usbdux_private *devpriv = dev->private;
1341 int fx2delay = 255;
1342
1343 if (period < MIN_PWM_PERIOD) {
1344 return -EAGAIN;
1345 } else {
1346 fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
1347 if (fx2delay > 255)
1348 return -EAGAIN;
1349 }
1350 devpriv->pwm_delay = fx2delay;
1351 devpriv->pwm_period = period;
1352
1353 return 0;
1354 }
1355
1356 static int usbdux_pwm_start(struct comedi_device *dev,
1357 struct comedi_subdevice *s)
1358 {
1359 struct usbdux_private *devpriv = dev->private;
1360 int ret = 0;
1361
1362 down(&devpriv->sem);
1363
1364 if (devpriv->pwm_cmd_running)
1365 goto pwm_start_exit;
1366
1367 devpriv->dux_commands[1] = devpriv->pwm_delay;
1368 ret = send_dux_commands(dev, USBDUX_CMD_PWM_ON);
1369 if (ret < 0)
1370 goto pwm_start_exit;
1371
1372 /* initialise the buffer */
1373 memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
1374
1375 devpriv->pwm_cmd_running = 1;
1376 ret = usbduxsub_submit_pwm_urbs(dev);
1377 if (ret < 0)
1378 devpriv->pwm_cmd_running = 0;
1379
1380 pwm_start_exit:
1381 up(&devpriv->sem);
1382
1383 return ret;
1384 }
1385
1386 static void usbdux_pwm_pattern(struct comedi_device *dev,
1387 struct comedi_subdevice *s,
1388 unsigned int chan,
1389 unsigned int value,
1390 unsigned int sign)
1391 {
1392 struct usbdux_private *devpriv = dev->private;
1393 char pwm_mask = (1 << chan); /* DIO bit for the PWM data */
1394 char sgn_mask = (16 << chan); /* DIO bit for the sign */
1395 char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
1396 int szbuf = devpriv->pwm_buf_sz;
1397 int i;
1398
1399 for (i = 0; i < szbuf; i++) {
1400 char c = *buf;
1401
1402 c &= ~pwm_mask;
1403 if (i < value)
1404 c |= pwm_mask;
1405 if (!sign)
1406 c &= ~sgn_mask;
1407 else
1408 c |= sgn_mask;
1409 *buf++ = c;
1410 }
1411 }
1412
1413 static int usbdux_pwm_write(struct comedi_device *dev,
1414 struct comedi_subdevice *s,
1415 struct comedi_insn *insn,
1416 unsigned int *data)
1417 {
1418 unsigned int chan = CR_CHAN(insn->chanspec);
1419
1420 /*
1421 * It doesn't make sense to support more than one value here
1422 * because it would just overwrite the PWM buffer.
1423 */
1424 if (insn->n != 1)
1425 return -EINVAL;
1426
1427 /*
1428 * The sign is set via a special INSN only, this gives us 8 bits
1429 * for normal operation, sign is 0 by default.
1430 */
1431 usbdux_pwm_pattern(dev, s, chan, data[0], 0);
1432
1433 return insn->n;
1434 }
1435
1436 static int usbdux_pwm_config(struct comedi_device *dev,
1437 struct comedi_subdevice *s,
1438 struct comedi_insn *insn,
1439 unsigned int *data)
1440 {
1441 struct usbdux_private *devpriv = dev->private;
1442 unsigned int chan = CR_CHAN(insn->chanspec);
1443
1444 switch (data[0]) {
1445 case INSN_CONFIG_ARM:
1446 /*
1447 * if not zero the PWM is limited to a certain time which is
1448 * not supported here
1449 */
1450 if (data[1] != 0)
1451 return -EINVAL;
1452 return usbdux_pwm_start(dev, s);
1453 case INSN_CONFIG_DISARM:
1454 return usbdux_pwm_cancel(dev, s);
1455 case INSN_CONFIG_GET_PWM_STATUS:
1456 data[1] = devpriv->pwm_cmd_running;
1457 return 0;
1458 case INSN_CONFIG_PWM_SET_PERIOD:
1459 return usbdux_pwm_period(dev, s, data[1]);
1460 case INSN_CONFIG_PWM_GET_PERIOD:
1461 data[1] = devpriv->pwm_period;
1462 return 0;
1463 case INSN_CONFIG_PWM_SET_H_BRIDGE:
1464 /*
1465 * data[1] = value
1466 * data[2] = sign (for a relay)
1467 */
1468 usbdux_pwm_pattern(dev, s, chan, data[1], (data[2] != 0));
1469 return 0;
1470 case INSN_CONFIG_PWM_GET_H_BRIDGE:
1471 /* values are not kept in this driver, nothing to return here */
1472 return -EINVAL;
1473 }
1474 return -EINVAL;
1475 }
1476
1477 static int usbdux_firmware_upload(struct comedi_device *dev,
1478 const u8 *data, size_t size,
1479 unsigned long context)
1480 {
1481 struct usb_device *usb = comedi_to_usb_dev(dev);
1482 uint8_t *buf;
1483 uint8_t *tmp;
1484 int ret;
1485
1486 if (!data)
1487 return 0;
1488
1489 if (size > USBDUX_FIRMWARE_MAX_LEN) {
1490 dev_err(dev->class_dev,
1491 "usbdux firmware binary it too large for FX2.\n");
1492 return -ENOMEM;
1493 }
1494
1495 /* we generate a local buffer for the firmware */
1496 buf = kmemdup(data, size, GFP_KERNEL);
1497 if (!buf)
1498 return -ENOMEM;
1499
1500 /* we need a malloc'ed buffer for usb_control_msg() */
1501 tmp = kmalloc(1, GFP_KERNEL);
1502 if (!tmp) {
1503 kfree(buf);
1504 return -ENOMEM;
1505 }
1506
1507 /* stop the current firmware on the device */
1508 *tmp = 1; /* 7f92 to one */
1509 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1510 USBDUX_FIRMWARE_CMD,
1511 VENDOR_DIR_OUT,
1512 USBDUX_CPU_CS, 0x0000,
1513 tmp, 1,
1514 BULK_TIMEOUT);
1515 if (ret < 0) {
1516 dev_err(dev->class_dev, "can not stop firmware\n");
1517 goto done;
1518 }
1519
1520 /* upload the new firmware to the device */
1521 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1522 USBDUX_FIRMWARE_CMD,
1523 VENDOR_DIR_OUT,
1524 0, 0x0000,
1525 buf, size,
1526 BULK_TIMEOUT);
1527 if (ret < 0) {
1528 dev_err(dev->class_dev, "firmware upload failed\n");
1529 goto done;
1530 }
1531
1532 /* start the new firmware on the device */
1533 *tmp = 0; /* 7f92 to zero */
1534 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
1535 USBDUX_FIRMWARE_CMD,
1536 VENDOR_DIR_OUT,
1537 USBDUX_CPU_CS, 0x0000,
1538 tmp, 1,
1539 BULK_TIMEOUT);
1540 if (ret < 0)
1541 dev_err(dev->class_dev, "can not start firmware\n");
1542
1543 done:
1544 kfree(tmp);
1545 kfree(buf);
1546 return ret;
1547 }
1548
1549 static int usbdux_alloc_usb_buffers(struct comedi_device *dev)
1550 {
1551 struct usb_device *usb = comedi_to_usb_dev(dev);
1552 struct usbdux_private *devpriv = dev->private;
1553 struct urb *urb;
1554 int i;
1555
1556 devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
1557 devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
1558 devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
1559 devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(void *),
1560 GFP_KERNEL);
1561 devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(void *),
1562 GFP_KERNEL);
1563 if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf ||
1564 !devpriv->ai_urbs || !devpriv->ao_urbs)
1565 return -ENOMEM;
1566
1567 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1568 /* one frame: 1ms */
1569 urb = usb_alloc_urb(1, GFP_KERNEL);
1570 if (!urb)
1571 return -ENOMEM;
1572 devpriv->ai_urbs[i] = urb;
1573
1574 urb->dev = usb;
1575 urb->context = dev;
1576 urb->pipe = usb_rcvisocpipe(usb, 6);
1577 urb->transfer_flags = URB_ISO_ASAP;
1578 urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
1579 if (!urb->transfer_buffer)
1580 return -ENOMEM;
1581
1582 urb->complete = usbduxsub_ai_isoc_irq;
1583 urb->number_of_packets = 1;
1584 urb->transfer_buffer_length = SIZEINBUF;
1585 urb->iso_frame_desc[0].offset = 0;
1586 urb->iso_frame_desc[0].length = SIZEINBUF;
1587 }
1588
1589 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1590 /* one frame: 1ms */
1591 urb = usb_alloc_urb(1, GFP_KERNEL);
1592 if (!urb)
1593 return -ENOMEM;
1594 devpriv->ao_urbs[i] = urb;
1595
1596 urb->dev = usb;
1597 urb->context = dev;
1598 urb->pipe = usb_sndisocpipe(usb, 2);
1599 urb->transfer_flags = URB_ISO_ASAP;
1600 urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
1601 if (!urb->transfer_buffer)
1602 return -ENOMEM;
1603
1604 urb->complete = usbduxsub_ao_isoc_irq;
1605 urb->number_of_packets = 1;
1606 urb->transfer_buffer_length = SIZEOUTBUF;
1607 urb->iso_frame_desc[0].offset = 0;
1608 urb->iso_frame_desc[0].length = SIZEOUTBUF;
1609 if (devpriv->high_speed)
1610 urb->interval = 8; /* uframes */
1611 else
1612 urb->interval = 1; /* frames */
1613 }
1614
1615 /* pwm */
1616 if (devpriv->pwm_buf_sz) {
1617 urb = usb_alloc_urb(0, GFP_KERNEL);
1618 if (!urb)
1619 return -ENOMEM;
1620 devpriv->pwm_urb = urb;
1621
1622 /* max bulk ep size in high speed */
1623 urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz,
1624 GFP_KERNEL);
1625 if (!urb->transfer_buffer)
1626 return -ENOMEM;
1627 }
1628
1629 return 0;
1630 }
1631
1632 static void usbdux_free_usb_buffers(struct comedi_device *dev)
1633 {
1634 struct usbdux_private *devpriv = dev->private;
1635 struct urb *urb;
1636 int i;
1637
1638 urb = devpriv->pwm_urb;
1639 if (urb) {
1640 kfree(urb->transfer_buffer);
1641 usb_free_urb(urb);
1642 }
1643 if (devpriv->ao_urbs) {
1644 for (i = 0; i < devpriv->n_ao_urbs; i++) {
1645 urb = devpriv->ao_urbs[i];
1646 if (urb) {
1647 kfree(urb->transfer_buffer);
1648 usb_free_urb(urb);
1649 }
1650 }
1651 kfree(devpriv->ao_urbs);
1652 }
1653 if (devpriv->ai_urbs) {
1654 for (i = 0; i < devpriv->n_ai_urbs; i++) {
1655 urb = devpriv->ai_urbs[i];
1656 if (urb) {
1657 kfree(urb->transfer_buffer);
1658 usb_free_urb(urb);
1659 }
1660 }
1661 kfree(devpriv->ai_urbs);
1662 }
1663 kfree(devpriv->insn_buf);
1664 kfree(devpriv->in_buf);
1665 kfree(devpriv->dux_commands);
1666 }
1667
1668 static int usbdux_auto_attach(struct comedi_device *dev,
1669 unsigned long context_unused)
1670 {
1671 struct usb_interface *intf = comedi_to_usb_interface(dev);
1672 struct usb_device *usb = comedi_to_usb_dev(dev);
1673 struct usbdux_private *devpriv;
1674 struct comedi_subdevice *s;
1675 int ret;
1676
1677 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1678 if (!devpriv)
1679 return -ENOMEM;
1680
1681 sema_init(&devpriv->sem, 1);
1682
1683 usb_set_intfdata(intf, devpriv);
1684
1685 devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
1686 if (devpriv->high_speed) {
1687 devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
1688 devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
1689 devpriv->pwm_buf_sz = 512;
1690 } else {
1691 devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
1692 devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
1693 }
1694
1695 ret = usbdux_alloc_usb_buffers(dev);
1696 if (ret)
1697 return ret;
1698
1699 /* setting to alternate setting 3: enabling iso ep and bulk ep. */
1700 ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber,
1701 3);
1702 if (ret < 0) {
1703 dev_err(dev->class_dev,
1704 "could not set alternate setting 3 in high speed\n");
1705 return ret;
1706 }
1707
1708 ret = comedi_load_firmware(dev, &usb->dev, USBDUX_FIRMWARE,
1709 usbdux_firmware_upload, 0);
1710 if (ret < 0)
1711 return ret;
1712
1713 ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 5 : 4);
1714 if (ret)
1715 return ret;
1716
1717 /* Analog Input subdevice */
1718 s = &dev->subdevices[0];
1719 dev->read_subdev = s;
1720 s->type = COMEDI_SUBD_AI;
1721 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
1722 s->n_chan = 8;
1723 s->maxdata = 0x0fff;
1724 s->len_chanlist = 8;
1725 s->range_table = &range_usbdux_ai_range;
1726 s->insn_read = usbdux_ai_insn_read;
1727 s->do_cmdtest = usbdux_ai_cmdtest;
1728 s->do_cmd = usbdux_ai_cmd;
1729 s->cancel = usbdux_ai_cancel;
1730
1731 /* Analog Output subdevice */
1732 s = &dev->subdevices[1];
1733 dev->write_subdev = s;
1734 s->type = COMEDI_SUBD_AO;
1735 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1736 s->n_chan = USBDUX_NUM_AO_CHAN;
1737 s->maxdata = 0x0fff;
1738 s->len_chanlist = s->n_chan;
1739 s->range_table = &range_usbdux_ao_range;
1740 s->do_cmdtest = usbdux_ao_cmdtest;
1741 s->do_cmd = usbdux_ao_cmd;
1742 s->cancel = usbdux_ao_cancel;
1743 s->insn_read = usbdux_ao_insn_read;
1744 s->insn_write = usbdux_ao_insn_write;
1745
1746 /* Digital I/O subdevice */
1747 s = &dev->subdevices[2];
1748 s->type = COMEDI_SUBD_DIO;
1749 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1750 s->n_chan = 8;
1751 s->maxdata = 1;
1752 s->range_table = &range_digital;
1753 s->insn_bits = usbdux_dio_insn_bits;
1754 s->insn_config = usbdux_dio_insn_config;
1755
1756 /* Counter subdevice */
1757 s = &dev->subdevices[3];
1758 s->type = COMEDI_SUBD_COUNTER;
1759 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1760 s->n_chan = 4;
1761 s->maxdata = 0xffff;
1762 s->insn_read = usbdux_counter_read;
1763 s->insn_write = usbdux_counter_write;
1764 s->insn_config = usbdux_counter_config;
1765
1766 if (devpriv->high_speed) {
1767 /* PWM subdevice */
1768 s = &dev->subdevices[4];
1769 s->type = COMEDI_SUBD_PWM;
1770 s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
1771 s->n_chan = 8;
1772 s->maxdata = devpriv->pwm_buf_sz;
1773 s->insn_write = usbdux_pwm_write;
1774 s->insn_config = usbdux_pwm_config;
1775
1776 usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
1777 }
1778
1779 return 0;
1780 }
1781
1782 static void usbdux_detach(struct comedi_device *dev)
1783 {
1784 struct usb_interface *intf = comedi_to_usb_interface(dev);
1785 struct usbdux_private *devpriv = dev->private;
1786
1787 usb_set_intfdata(intf, NULL);
1788
1789 if (!devpriv)
1790 return;
1791
1792 down(&devpriv->sem);
1793
1794 /* force unlink all urbs */
1795 usbdux_pwm_stop(dev, 1);
1796 usbdux_ao_stop(dev, 1);
1797 usbdux_ai_stop(dev, 1);
1798
1799 usbdux_free_usb_buffers(dev);
1800
1801 up(&devpriv->sem);
1802 }
1803
1804 static struct comedi_driver usbdux_driver = {
1805 .driver_name = "usbdux",
1806 .module = THIS_MODULE,
1807 .auto_attach = usbdux_auto_attach,
1808 .detach = usbdux_detach,
1809 };
1810
1811 static int usbdux_usb_probe(struct usb_interface *intf,
1812 const struct usb_device_id *id)
1813 {
1814 return comedi_usb_auto_config(intf, &usbdux_driver, 0);
1815 }
1816
1817 static const struct usb_device_id usbdux_usb_table[] = {
1818 { USB_DEVICE(0x13d8, 0x0001) },
1819 { USB_DEVICE(0x13d8, 0x0002) },
1820 { }
1821 };
1822 MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
1823
1824 static struct usb_driver usbdux_usb_driver = {
1825 .name = "usbdux",
1826 .probe = usbdux_usb_probe,
1827 .disconnect = comedi_usb_auto_unconfig,
1828 .id_table = usbdux_usb_table,
1829 };
1830 module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
1831
1832 MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1833 MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
1834 MODULE_LICENSE("GPL");
1835 MODULE_FIRMWARE(USBDUX_FIRMWARE);
This page took 0.07064 seconds and 5 git commands to generate.