Merge remote-tracking branch 'asoc/fix/max98357a' into asoc-linus
[linux-2.6-block.git] / drivers / staging / comedi / drivers / usbduxfast.c
CommitLineData
f47c697d 1/*
533de0f8 2 * Copyright (C) 2004-2014 Bernd Porr, mail@berndporr.me.uk
4e8ad0dc
MK
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
4e8ad0dc 13 */
f47c697d 14
533de0f8
BP
15/*
16 * Driver: usbduxfast
17 * Description: University of Stirling USB DAQ & INCITE Technology Limited
504a1aa7 18 * Devices: [ITL] USB-DUX-FAST (usbduxfast)
533de0f8
BP
19 * Author: Bernd Porr <mail@berndporr.me.uk>
20 * Updated: 10 Oct 2014
21 * Status: stable
22 */
23
f47c697d
BP
24/*
25 * I must give credit here to Chris Baugher who
26 * wrote the driver for AT-MIO-16d. I used some parts of this
27 * driver. I also must give credits to David Brownell
28 * who supported me with the USB development.
29 *
30 * Bernd Porr
31 *
32 *
33 * Revision history:
34 * 0.9: Dropping the first data packet which seems to be from the last transfer.
35 * Buffer overflows in the FX2 are handed over to comedi.
36 * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
4e8ad0dc
MK
37 * Added insn command basically for testing. Sample rate is
38 * 1MHz/16ch=62.5kHz
f47c697d
BP
39 * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
40 * 0.99a: added external trigger.
6742c0af
BP
41 * 1.00: added firmware kernel request to the driver which fixed
42 * udev coldplug problem
f47c697d
BP
43 */
44
45#include <linux/kernel.h>
46#include <linux/module.h>
f47c697d
BP
47#include <linux/slab.h>
48#include <linux/input.h>
f47c697d
BP
49#include <linux/fcntl.h>
50#include <linux/compiler.h>
51#include "comedi_fc.h"
d3f83952 52#include "../comedi_usb.h"
f47c697d 53
4e8ad0dc
MK
54/*
55 * timeout for the USB-transfer
56 */
57#define EZTIMEOUT 30
f47c697d 58
4e8ad0dc
MK
59/*
60 * constants for "firmware" upload and download
61 */
e74f7fc5 62#define FIRMWARE "usbduxfast_firmware.bin"
dcd29f56 63#define FIRMWARE_MAX_LEN 0x2000
4e8ad0dc
MK
64#define USBDUXFASTSUB_FIRMWARE 0xA0
65#define VENDOR_DIR_IN 0xC0
66#define VENDOR_DIR_OUT 0x40
f47c697d 67
4e8ad0dc 68/*
f69b0d64 69 * internal addresses of the 8051 processor
4e8ad0dc
MK
70 */
71#define USBDUXFASTSUB_CPUCS 0xE600
f47c697d 72
4e8ad0dc
MK
73/*
74 * max lenghth of the transfer-buffer for software upload
75 */
76#define TB_LEN 0x2000
f47c697d 77
4e8ad0dc
MK
78/*
79 * input endpoint number
80 */
81#define BULKINEP 6
f47c697d 82
4e8ad0dc
MK
83/*
84 * endpoint for the A/D channellist: bulk OUT
85 */
86#define CHANNELLISTEP 4
f47c697d 87
4e8ad0dc
MK
88/*
89 * number of channels
90 */
91#define NUMCHANNELS 32
f47c697d 92
4e8ad0dc
MK
93/*
94 * size of the waveform descriptor
95 */
96#define WAVESIZE 0x20
f47c697d 97
4e8ad0dc
MK
98/*
99 * size of one A/D value
100 */
101#define SIZEADIN (sizeof(int16_t))
f47c697d 102
4e8ad0dc
MK
103/*
104 * size of the input-buffer IN BYTES
105 */
106#define SIZEINBUF 512
f47c697d 107
4e8ad0dc
MK
108/*
109 * 16 bytes
110 */
111#define SIZEINSNBUF 512
f47c697d 112
4e8ad0dc
MK
113/*
114 * size of the buffer for the dux commands in bytes
115 */
5659e24a 116#define SIZEOFDUXBUF 256
f47c697d 117
4e8ad0dc
MK
118/*
119 * number of in-URBs which receive the data: min=5
120 */
121#define NUMOFINBUFFERSHIGH 10
f47c697d 122
4e8ad0dc
MK
123/*
124 * min delay steps for more than one channel
125 * basically when the mux gives up ;-)
126 *
127 * steps at 30MHz in the FX2
128 */
129#define MIN_SAMPLING_PERIOD 9
f47c697d 130
4e8ad0dc
MK
131/*
132 * max number of 1/30MHz delay steps
133 */
134#define MAX_SAMPLING_PERIOD 500
f47c697d 135
4e8ad0dc
MK
136/*
137 * number of received packets to ignore before we start handing data
138 * over to comedi, it's quad buffering and we have to ignore 4 packets
139 */
140#define PACKETS_TO_IGNORE 4
f47c697d 141
4e8ad0dc
MK
142/*
143 * comedi constants
144 */
9ced1de6 145static const struct comedi_lrange range_usbduxfast_ai_range = {
67b3b78f
HS
146 2, {
147 BIP_RANGE(0.75),
148 BIP_RANGE(0.5)
149 }
f47c697d
BP
150};
151
152/*
153 * private structure of one subdevice
4e8ad0dc
MK
154 *
155 * this is the structure which holds all the data of this driver
156 * one sub device just now: A/D
f47c697d 157 */
7aa41c3c 158struct usbduxfast_private {
da58c263 159 struct urb *urb; /* BULK-transfer handling: urb */
5659e24a 160 uint8_t *duxbuf;
ef8e0840 161 int8_t *inbuf;
4e8ad0dc 162 short int ai_cmd_running; /* asynchronous command is running */
0a85b6f0
MT
163 int ignore; /* counter which ignores the first
164 buffers */
f47c697d 165 struct semaphore sem;
4e8ad0dc 166};
f47c697d 167
4e8ad0dc
MK
168/*
169 * bulk transfers to usbduxfast
170 */
f47c697d
BP
171#define SENDADCOMMANDS 0
172#define SENDINITEP6 1
173
665ff8d3 174static int usbduxfast_send_cmd(struct comedi_device *dev, int cmd_type)
f47c697d 175{
0a92de24 176 struct usb_device *usb = comedi_to_usb_dev(dev);
da63c39c 177 struct usbduxfast_private *devpriv = dev->private;
665ff8d3
HS
178 int nsent;
179 int ret;
0a3b8b64 180
5659e24a 181 devpriv->duxbuf[0] = cmd_type;
0a3b8b64 182
665ff8d3 183 ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, CHANNELLISTEP),
5659e24a
HS
184 devpriv->duxbuf, SIZEOFDUXBUF,
185 &nsent, 10000);
665ff8d3 186 if (ret < 0)
106af997 187 dev_err(dev->class_dev,
5659e24a 188 "could not transmit command to the usb-device, err=%d\n",
665ff8d3
HS
189 ret);
190 return ret;
f47c697d
BP
191}
192
17fdeba0
HS
193static void usbduxfast_cmd_data(struct comedi_device *dev, int index,
194 uint8_t len, uint8_t op, uint8_t out,
195 uint8_t log)
196{
197 struct usbduxfast_private *devpriv = dev->private;
198
199 /* Set the GPIF bytes, the first byte is the command byte */
200 devpriv->duxbuf[1 + 0x00 + index] = len;
201 devpriv->duxbuf[1 + 0x08 + index] = op;
202 devpriv->duxbuf[1 + 0x10 + index] = out;
203 devpriv->duxbuf[1 + 0x18 + index] = log;
204}
205
32fa46b9 206static int usbduxfast_ai_stop(struct comedi_device *dev, int do_unlink)
f47c697d 207{
da63c39c 208 struct usbduxfast_private *devpriv = dev->private;
f47c697d 209
32fa46b9 210 /* stop aquistion */
7aa41c3c 211 devpriv->ai_cmd_running = 0;
f47c697d 212
32fa46b9
HS
213 if (do_unlink && devpriv->urb) {
214 /* kill the running transfer */
215 usb_kill_urb(devpriv->urb);
216 }
f47c697d 217
32fa46b9 218 return 0;
f47c697d
BP
219}
220
0a85b6f0
MT
221static int usbduxfast_ai_cancel(struct comedi_device *dev,
222 struct comedi_subdevice *s)
f47c697d 223{
7aa41c3c 224 struct usbduxfast_private *devpriv = dev->private;
4e8ad0dc 225 int ret;
f47c697d 226
ce976fdb 227 if (!devpriv)
f47c697d 228 return -EFAULT;
ce976fdb 229
7aa41c3c 230 down(&devpriv->sem);
da63c39c 231 ret = usbduxfast_ai_stop(dev, 1);
7aa41c3c 232 up(&devpriv->sem);
f47c697d 233
4e8ad0dc 234 return ret;
f47c697d
BP
235}
236
7c88f9f4
HS
237static void usbduxfast_ai_handle_urb(struct comedi_device *dev,
238 struct comedi_subdevice *s,
239 struct urb *urb)
240{
241 struct usbduxfast_private *devpriv = dev->private;
242 struct comedi_async *async = s->async;
243 struct comedi_cmd *cmd = &async->cmd;
244 int ret;
245
246 if (devpriv->ignore) {
247 devpriv->ignore--;
248 } else {
c39e050d 249 unsigned int nsamples;
7c88f9f4 250
c39e050d 251 nsamples = comedi_bytes_to_samples(s, urb->actual_length);
979f9996 252 nsamples = comedi_nsamples_left(s, nsamples);
f81ac41b 253 comedi_buf_write_samples(s, urb->transfer_buffer, nsamples);
979f9996
HS
254
255 if (cmd->stop_src == TRIG_COUNT &&
256 async->scans_done >= cmd->stop_arg)
257 async->events |= COMEDI_CB_EOA;
7c88f9f4
HS
258 }
259
260 /* if command is still running, resubmit urb for BULK transfer */
261 if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
262 urb->dev = comedi_to_usb_dev(dev);
263 urb->status = 0;
264 ret = usb_submit_urb(urb, GFP_ATOMIC);
265 if (ret < 0) {
266 dev_err(dev->class_dev, "urb resubm failed: %d", ret);
267 async->events |= COMEDI_CB_ERROR;
268 }
269 }
270}
271
f8eb27e0 272static void usbduxfast_ai_interrupt(struct urb *urb)
f47c697d 273{
f8eb27e0
HS
274 struct comedi_device *dev = urb->context;
275 struct comedi_subdevice *s = dev->read_subdev;
276 struct comedi_async *async = s->async;
277 struct usbduxfast_private *devpriv = dev->private;
7c88f9f4
HS
278
279 /* exit if not running a command, do not resubmit urb */
280 if (!devpriv->ai_cmd_running)
f47c697d 281 return;
f47c697d 282
f47c697d
BP
283 switch (urb->status) {
284 case 0:
7c88f9f4 285 usbduxfast_ai_handle_urb(dev, s, urb);
f47c697d
BP
286 break;
287
f47c697d
BP
288 case -ECONNRESET:
289 case -ENOENT:
290 case -ESHUTDOWN:
291 case -ECONNABORTED:
7c88f9f4 292 /* after an unlink command, unplug, ... etc */
f8eb27e0 293 async->events |= COMEDI_CB_ERROR;
7c88f9f4 294 break;
f47c697d
BP
295
296 default:
7c88f9f4 297 /* a real error */
42f4acdf
HS
298 dev_err(dev->class_dev,
299 "non-zero urb status received in ai intr context: %d\n",
300 urb->status);
f8eb27e0 301 async->events |= COMEDI_CB_ERROR;
7c88f9f4 302 break;
f47c697d
BP
303 }
304
4e8ad0dc 305 /*
7c88f9f4
HS
306 * comedi_handle_events() cannot be used in this driver. The (*cancel)
307 * operation would unlink the urb.
4e8ad0dc 308 */
7c88f9f4 309 if (async->events & COMEDI_CB_CANCEL_MASK)
da63c39c 310 usbduxfast_ai_stop(dev, 0);
7c88f9f4
HS
311
312 comedi_event(dev, s);
f47c697d
BP
313}
314
ebe9f1cf 315static int usbduxfast_submit_urb(struct comedi_device *dev)
f47c697d 316{
0a92de24 317 struct usb_device *usb = comedi_to_usb_dev(dev);
da63c39c 318 struct usbduxfast_private *devpriv = dev->private;
4e8ad0dc 319 int ret;
f47c697d 320
7aa41c3c 321 if (!devpriv)
f47c697d 322 return -EFAULT;
4e8ad0dc 323
da58c263 324 usb_fill_bulk_urb(devpriv->urb, usb, usb_rcvbulkpipe(usb, BULKINEP),
ef8e0840 325 devpriv->inbuf, SIZEINBUF,
da63c39c 326 usbduxfast_ai_interrupt, dev);
f47c697d 327
da58c263 328 ret = usb_submit_urb(devpriv->urb, GFP_ATOMIC);
4e8ad0dc 329 if (ret) {
106af997 330 dev_err(dev->class_dev, "usb_submit_urb error %d\n", ret);
4e8ad0dc 331 return ret;
f47c697d
BP
332 }
333 return 0;
334}
335
71b5f4f1 336static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
0a85b6f0
MT
337 struct comedi_subdevice *s,
338 struct comedi_cmd *cmd)
f47c697d 339{
27020ffe 340 int err = 0;
4e8ad0dc 341 long int steps, tmp;
bbb2d2d6 342 int min_sample_period;
4e8ad0dc 343
27020ffe 344 /* Step 1 : check if triggers are trivially valid */
f47c697d 345
27020ffe
HS
346 err |= cfc_check_trigger_src(&cmd->start_src,
347 TRIG_NOW | TRIG_EXT | TRIG_INT);
348 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
9ebe26cf 349 TRIG_FOLLOW | TRIG_EXT);
27020ffe
HS
350 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
351 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
352 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
f47c697d
BP
353
354 if (err)
355 return 1;
356
27020ffe 357 /* Step 2a : make sure trigger sources are unique */
f47c697d 358
27020ffe
HS
359 err |= cfc_check_trigger_is_unique(cmd->start_src);
360 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
361 err |= cfc_check_trigger_is_unique(cmd->convert_src);
362 err |= cfc_check_trigger_is_unique(cmd->stop_src);
363
364 /* Step 2b : and mutually compatible */
f47c697d 365
4e8ad0dc 366 /* can't have external stop and start triggers at once */
f47c697d 367 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
27020ffe 368 err |= -EINVAL;
f47c697d
BP
369
370 if (err)
371 return 2;
372
9309c477 373 /* Step 3: check if arguments are trivially valid */
f47c697d 374
95194590 375 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
f47c697d 376
4e8ad0dc 377 if (!cmd->chanlist_len)
9309c477 378 err |= -EINVAL;
4e8ad0dc 379
9309c477 380 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
f47c697d 381
4e8ad0dc 382 if (cmd->chanlist_len == 1)
bbb2d2d6 383 min_sample_period = 1;
4e8ad0dc 384 else
bbb2d2d6 385 min_sample_period = MIN_SAMPLING_PERIOD;
f47c697d
BP
386
387 if (cmd->convert_src == TRIG_TIMER) {
388 steps = cmd->convert_arg * 30;
bbb2d2d6
HS
389 if (steps < (min_sample_period * 1000))
390 steps = min_sample_period * 1000;
4e8ad0dc
MK
391
392 if (steps > (MAX_SAMPLING_PERIOD * 1000))
f47c697d 393 steps = MAX_SAMPLING_PERIOD * 1000;
4e8ad0dc
MK
394
395 /* calc arg again */
f47c697d 396 tmp = steps / 30;
9309c477 397 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, tmp);
f47c697d
BP
398 }
399
4e8ad0dc 400 /* stop source */
f47c697d
BP
401 switch (cmd->stop_src) {
402 case TRIG_COUNT:
9309c477 403 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
f47c697d
BP
404 break;
405 case TRIG_NONE:
9309c477 406 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
f47c697d 407 break;
4e8ad0dc
MK
408 /*
409 * TRIG_EXT doesn't care since it doesn't trigger
410 * off a numbered channel
411 */
f47c697d
BP
412 default:
413 break;
414 }
415
416 if (err)
417 return 3;
418
419 /* step 4: fix up any arguments */
420
421 return 0;
422
423}
424
71b5f4f1 425static int usbduxfast_ai_inttrig(struct comedi_device *dev,
0a85b6f0 426 struct comedi_subdevice *s,
95194590 427 unsigned int trig_num)
f47c697d 428{
7aa41c3c 429 struct usbduxfast_private *devpriv = dev->private;
95194590 430 struct comedi_cmd *cmd = &s->async->cmd;
f47c697d 431 int ret;
4e8ad0dc 432
7aa41c3c 433 if (!devpriv)
f47c697d 434 return -EFAULT;
4e8ad0dc 435
95194590
HS
436 if (trig_num != cmd->start_arg)
437 return -EINVAL;
438
7aa41c3c 439 down(&devpriv->sem);
f47c697d 440
7aa41c3c
HS
441 if (!devpriv->ai_cmd_running) {
442 devpriv->ai_cmd_running = 1;
ebe9f1cf 443 ret = usbduxfast_submit_urb(dev);
f47c697d 444 if (ret < 0) {
106af997 445 dev_err(dev->class_dev, "urbSubmit: err=%d\n", ret);
7aa41c3c
HS
446 devpriv->ai_cmd_running = 0;
447 up(&devpriv->sem);
f47c697d
BP
448 return ret;
449 }
450 s->async->inttrig = NULL;
451 } else {
106af997 452 dev_err(dev->class_dev, "ai is already running\n");
f47c697d 453 }
7aa41c3c 454 up(&devpriv->sem);
f47c697d
BP
455 return 1;
456}
457
0a85b6f0
MT
458static int usbduxfast_ai_cmd(struct comedi_device *dev,
459 struct comedi_subdevice *s)
f47c697d 460{
7aa41c3c 461 struct usbduxfast_private *devpriv = dev->private;
ea6d0d4c 462 struct comedi_cmd *cmd = &s->async->cmd;
f47c697d
BP
463 unsigned int chan, gain, rngmask = 0xff;
464 int i, j, ret;
f47c697d
BP
465 int result;
466 long steps, steps_tmp;
467
7aa41c3c 468 if (!devpriv)
f47c697d 469 return -EFAULT;
4e8ad0dc 470
7aa41c3c 471 down(&devpriv->sem);
7aa41c3c 472 if (devpriv->ai_cmd_running) {
106af997 473 dev_err(dev->class_dev, "ai_cmd not possible\n");
7aa41c3c 474 up(&devpriv->sem);
f47c697d
BP
475 return -EBUSY;
476 }
f47c697d 477
4e8ad0dc
MK
478 /*
479 * ignore the first buffers from the device if there
480 * is an error condition
481 */
7aa41c3c 482 devpriv->ignore = PACKETS_TO_IGNORE;
f47c697d 483
a5e99e12
HS
484 gain = CR_RANGE(cmd->chanlist[0]);
485 for (i = 0; i < cmd->chanlist_len; ++i) {
486 chan = CR_CHAN(cmd->chanlist[i]);
487 if (chan != i) {
488 dev_err(dev->class_dev,
489 "channels are not consecutive\n");
490 up(&devpriv->sem);
491 return -EINVAL;
492 }
493 if ((gain != CR_RANGE(cmd->chanlist[i]))
494 && (cmd->chanlist_len > 3)) {
495 dev_err(dev->class_dev,
496 "gain must be the same for all channels\n");
497 up(&devpriv->sem);
498 return -EINVAL;
499 }
500 if (i >= NUMCHANNELS) {
501 dev_err(dev->class_dev, "chanlist too long\n");
502 break;
f47c697d
BP
503 }
504 }
505 steps = 0;
4e8ad0dc 506 if (cmd->convert_src == TRIG_TIMER)
f47c697d 507 steps = (cmd->convert_arg * 30) / 1000;
4e8ad0dc 508
f47c697d 509 if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
0a00ab99 510 dev_err(dev->class_dev,
106af997 511 "steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
0a00ab99 512 steps, cmd->scan_begin_arg);
7aa41c3c 513 up(&devpriv->sem);
f47c697d
BP
514 return -EINVAL;
515 }
516 if (steps > MAX_SAMPLING_PERIOD) {
106af997 517 dev_err(dev->class_dev, "sampling rate too low\n");
7aa41c3c 518 up(&devpriv->sem);
f47c697d
BP
519 return -EINVAL;
520 }
521 if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
0a85b6f0 522 && (cmd->chanlist_len != 16)) {
0a00ab99 523 dev_err(dev->class_dev,
106af997 524 "TRIG_EXT only with 1 or 16 channels possible\n");
7aa41c3c 525 up(&devpriv->sem);
f47c697d
BP
526 return -EINVAL;
527 }
f47c697d
BP
528
529 switch (cmd->chanlist_len) {
f47c697d 530 case 1:
4e8ad0dc
MK
531 /*
532 * one channel
533 */
534
f47c697d
BP
535 if (CR_RANGE(cmd->chanlist[0]) > 0)
536 rngmask = 0xff - 0x04;
537 else
538 rngmask = 0xff;
539
4e8ad0dc
MK
540 /*
541 * for external trigger: looping in this state until
542 * the RDY0 pin becomes zero
543 */
544
545 /* we loop here until ready has been set */
546 if (cmd->start_src == TRIG_EXT) {
547 /* branch back to state 0 */
4e8ad0dc 548 /* deceision state w/o data */
4e8ad0dc 549 /* RDY0 = 0 */
17fdeba0 550 usbduxfast_cmd_data(dev, 0, 0x01, 0x01, rngmask, 0x00);
4e8ad0dc 551 } else { /* we just proceed to state 1 */
17fdeba0 552 usbduxfast_cmd_data(dev, 0, 0x01, 0x00, rngmask, 0x00);
f47c697d
BP
553 }
554
555 if (steps < MIN_SAMPLING_PERIOD) {
4e8ad0dc 556 /* for fast single channel aqu without mux */
f47c697d 557 if (steps <= 1) {
4e8ad0dc
MK
558 /*
559 * we just stay here at state 1 and rexecute
560 * the same state this gives us 30MHz sampling
561 * rate
562 */
563
564 /* branch back to state 1 */
4e8ad0dc 565 /* deceision state with data */
4e8ad0dc 566 /* doesn't matter */
17fdeba0
HS
567 usbduxfast_cmd_data(dev, 1,
568 0x89, 0x03, rngmask, 0xff);
f47c697d 569 } else {
4e8ad0dc
MK
570 /*
571 * we loop through two states: data and delay
572 * max rate is 15MHz
573 */
4e8ad0dc 574 /* data */
4e8ad0dc 575 /* doesn't matter */
17fdeba0
HS
576 usbduxfast_cmd_data(dev, 1, steps - 1,
577 0x02, rngmask, 0x00);
578
4e8ad0dc 579 /* branch back to state 1 */
4e8ad0dc 580 /* deceision state w/o data */
4e8ad0dc 581 /* doesn't matter */
17fdeba0
HS
582 usbduxfast_cmd_data(dev, 2,
583 0x09, 0x01, rngmask, 0xff);
f47c697d
BP
584 }
585 } else {
4e8ad0dc
MK
586 /*
587 * we loop through 3 states: 2x delay and 1x data
588 * this gives a min sampling rate of 60kHz
589 */
f47c697d 590
4e8ad0dc 591 /* we have 1 state with duration 1 */
f47c697d
BP
592 steps = steps - 1;
593
4e8ad0dc 594 /* do the first part of the delay */
17fdeba0
HS
595 usbduxfast_cmd_data(dev, 1,
596 steps / 2, 0x00, rngmask, 0x00);
4e8ad0dc
MK
597
598 /* and the second part */
17fdeba0
HS
599 usbduxfast_cmd_data(dev, 2, steps - steps / 2,
600 0x00, rngmask, 0x00);
4e8ad0dc
MK
601
602 /* get the data and branch back */
603
604 /* branch back to state 1 */
4e8ad0dc 605 /* deceision state w data */
4e8ad0dc 606 /* doesn't matter */
17fdeba0
HS
607 usbduxfast_cmd_data(dev, 3,
608 0x09, 0x03, rngmask, 0xff);
f47c697d
BP
609 }
610 break;
611
612 case 2:
4e8ad0dc
MK
613 /*
614 * two channels
615 * commit data to the FIFO
616 */
617
f47c697d
BP
618 if (CR_RANGE(cmd->chanlist[0]) > 0)
619 rngmask = 0xff - 0x04;
620 else
621 rngmask = 0xff;
f47c697d 622
4e8ad0dc 623 /* data */
17fdeba0 624 usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
4e8ad0dc
MK
625
626 /* we have 1 state with duration 1: state 0 */
f47c697d
BP
627 steps_tmp = steps - 1;
628
629 if (CR_RANGE(cmd->chanlist[1]) > 0)
630 rngmask = 0xff - 0x04;
631 else
632 rngmask = 0xff;
4e8ad0dc
MK
633
634 /* do the first part of the delay */
4e8ad0dc 635 /* count */
17fdeba0
HS
636 usbduxfast_cmd_data(dev, 1, steps_tmp / 2,
637 0x00, 0xfe & rngmask, 0x00);
4e8ad0dc
MK
638
639 /* and the second part */
17fdeba0
HS
640 usbduxfast_cmd_data(dev, 2, steps_tmp - steps_tmp / 2,
641 0x00, rngmask, 0x00);
4e8ad0dc 642
4e8ad0dc 643 /* data */
17fdeba0 644 usbduxfast_cmd_data(dev, 3, 0x01, 0x02, rngmask, 0x00);
4e8ad0dc
MK
645
646 /*
647 * we have 2 states with duration 1: step 6 and
648 * the IDLE state
649 */
f47c697d
BP
650 steps_tmp = steps - 2;
651
652 if (CR_RANGE(cmd->chanlist[0]) > 0)
653 rngmask = 0xff - 0x04;
654 else
655 rngmask = 0xff;
4e8ad0dc
MK
656
657 /* do the first part of the delay */
4e8ad0dc 658 /* reset */
17fdeba0
HS
659 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
660 0x00, (0xff - 0x02) & rngmask, 0x00);
4e8ad0dc
MK
661
662 /* and the second part */
17fdeba0
HS
663 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
664 0x00, rngmask, 0x00);
665
666 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
f47c697d
BP
667 break;
668
669 case 3:
4e8ad0dc
MK
670 /*
671 * three channels
672 */
f47c697d 673 for (j = 0; j < 1; j++) {
17fdeba0
HS
674 int index = j * 2;
675
f47c697d
BP
676 if (CR_RANGE(cmd->chanlist[j]) > 0)
677 rngmask = 0xff - 0x04;
678 else
679 rngmask = 0xff;
4e8ad0dc
MK
680 /*
681 * commit data to the FIFO and do the first part
682 * of the delay
683 */
4e8ad0dc 684 /* data */
4e8ad0dc 685 /* no change */
17fdeba0
HS
686 usbduxfast_cmd_data(dev, index, steps / 2,
687 0x02, rngmask, 0x00);
f47c697d
BP
688
689 if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
690 rngmask = 0xff - 0x04;
691 else
692 rngmask = 0xff;
4e8ad0dc
MK
693
694 /* do the second part of the delay */
4e8ad0dc 695 /* no data */
4e8ad0dc 696 /* count */
17fdeba0
HS
697 usbduxfast_cmd_data(dev, index + 1, steps - steps / 2,
698 0x00, 0xfe & rngmask, 0x00);
f47c697d
BP
699 }
700
4e8ad0dc 701 /* 2 steps with duration 1: the idele step and step 6: */
f47c697d 702 steps_tmp = steps - 2;
4e8ad0dc
MK
703
704 /* commit data to the FIFO and do the first part of the delay */
4e8ad0dc 705 /* data */
17fdeba0
HS
706 usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
707 0x02, rngmask, 0x00);
f47c697d
BP
708
709 if (CR_RANGE(cmd->chanlist[0]) > 0)
710 rngmask = 0xff - 0x04;
711 else
712 rngmask = 0xff;
4e8ad0dc
MK
713
714 /* do the second part of the delay */
4e8ad0dc 715 /* no data */
4e8ad0dc 716 /* reset */
17fdeba0
HS
717 usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
718 0x00, (0xff - 0x02) & rngmask, 0x00);
4e8ad0dc 719
17fdeba0 720 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
99284f25 721 break;
f47c697d
BP
722
723 case 16:
724 if (CR_RANGE(cmd->chanlist[0]) > 0)
725 rngmask = 0xff - 0x04;
726 else
727 rngmask = 0xff;
4e8ad0dc
MK
728
729 if (cmd->start_src == TRIG_EXT) {
730 /*
731 * we loop here until ready has been set
732 */
733
734 /* branch back to state 0 */
4e8ad0dc 735 /* deceision state w/o data */
4e8ad0dc 736 /* reset */
4e8ad0dc 737 /* RDY0 = 0 */
17fdeba0
HS
738 usbduxfast_cmd_data(dev, 0, 0x01, 0x01,
739 (0xff - 0x02) & rngmask, 0x00);
4e8ad0dc
MK
740 } else {
741 /*
742 * we just proceed to state 1
743 */
744
745 /* 30us reset pulse */
4e8ad0dc 746 /* reset */
17fdeba0
HS
747 usbduxfast_cmd_data(dev, 0, 0xff, 0x00,
748 (0xff - 0x02) & rngmask, 0x00);
f47c697d
BP
749 }
750
4e8ad0dc 751 /* commit data to the FIFO */
4e8ad0dc 752 /* data */
17fdeba0 753 usbduxfast_cmd_data(dev, 1, 0x01, 0x02, rngmask, 0x00);
f47c697d 754
4e8ad0dc 755 /* we have 2 states with duration 1 */
f47c697d
BP
756 steps = steps - 2;
757
4e8ad0dc 758 /* do the first part of the delay */
17fdeba0
HS
759 usbduxfast_cmd_data(dev, 2, steps / 2,
760 0x00, 0xfe & rngmask, 0x00);
4e8ad0dc
MK
761
762 /* and the second part */
17fdeba0
HS
763 usbduxfast_cmd_data(dev, 3, steps - steps / 2,
764 0x00, rngmask, 0x00);
4e8ad0dc
MK
765
766 /* branch back to state 1 */
4e8ad0dc 767 /* deceision state w/o data */
4e8ad0dc 768 /* doesn't matter */
17fdeba0 769 usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
f47c697d
BP
770
771 break;
772
773 default:
0a00ab99 774 dev_err(dev->class_dev, "unsupported combination of channels\n");
7aa41c3c 775 up(&devpriv->sem);
f47c697d
BP
776 return -EFAULT;
777 }
778
4e8ad0dc 779 /* 0 means that the AD commands are sent */
665ff8d3 780 result = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
f47c697d 781 if (result < 0) {
7aa41c3c 782 up(&devpriv->sem);
f47c697d
BP
783 return result;
784 }
71cf2b4a 785
f47c697d 786 if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
4e8ad0dc 787 /* enable this acquisition operation */
7aa41c3c 788 devpriv->ai_cmd_running = 1;
ebe9f1cf 789 ret = usbduxfast_submit_urb(dev);
f47c697d 790 if (ret < 0) {
7aa41c3c 791 devpriv->ai_cmd_running = 0;
4e8ad0dc 792 /* fixme: unlink here?? */
7aa41c3c 793 up(&devpriv->sem);
f47c697d
BP
794 return ret;
795 }
796 s->async->inttrig = NULL;
95194590 797 } else { /* TRIG_INT */
f47c697d
BP
798 s->async->inttrig = usbduxfast_ai_inttrig;
799 }
7aa41c3c 800 up(&devpriv->sem);
f47c697d
BP
801
802 return 0;
803}
804
4e8ad0dc
MK
805/*
806 * Mode 0 is used to get a single conversion on demand.
807 */
71b5f4f1 808static int usbduxfast_ai_insn_read(struct comedi_device *dev,
0a85b6f0 809 struct comedi_subdevice *s,
dabf2aa3
HS
810 struct comedi_insn *insn,
811 unsigned int *data)
f47c697d 812{
0a92de24 813 struct usb_device *usb = comedi_to_usb_dev(dev);
7aa41c3c 814 struct usbduxfast_private *devpriv = dev->private;
dabf2aa3
HS
815 unsigned int chan = CR_CHAN(insn->chanspec);
816 unsigned int range = CR_RANGE(insn->chanspec);
817 uint8_t rngmask = range ? (0xff - 0x04) : 0xff;
f47c697d 818 int i, j, n, actual_length;
dabf2aa3 819 int ret;
ba6205d6 820
7aa41c3c 821 down(&devpriv->sem);
dabf2aa3 822
7aa41c3c 823 if (devpriv->ai_cmd_running) {
0a00ab99 824 dev_err(dev->class_dev,
106af997 825 "ai_insn_read not possible, async cmd is running\n");
7aa41c3c 826 up(&devpriv->sem);
f47c697d
BP
827 return -EBUSY;
828 }
f47c697d 829
dabf2aa3 830 /* set command for the first channel */
4e8ad0dc
MK
831
832 /* commit data to the FIFO */
4e8ad0dc 833 /* data */
17fdeba0 834 usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
4e8ad0dc
MK
835
836 /* do the first part of the delay */
17fdeba0
HS
837 usbduxfast_cmd_data(dev, 1, 0x0c, 0x00, 0xfe & rngmask, 0x00);
838 usbduxfast_cmd_data(dev, 2, 0x01, 0x00, 0xfe & rngmask, 0x00);
839 usbduxfast_cmd_data(dev, 3, 0x01, 0x00, 0xfe & rngmask, 0x00);
840 usbduxfast_cmd_data(dev, 4, 0x01, 0x00, 0xfe & rngmask, 0x00);
4e8ad0dc
MK
841
842 /* second part */
17fdeba0
HS
843 usbduxfast_cmd_data(dev, 5, 0x0c, 0x00, rngmask, 0x00);
844 usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
f47c697d 845
dabf2aa3
HS
846 ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
847 if (ret < 0) {
7aa41c3c 848 up(&devpriv->sem);
dabf2aa3 849 return ret;
f47c697d 850 }
ba6205d6 851
f47c697d 852 for (i = 0; i < PACKETS_TO_IGNORE; i++) {
dabf2aa3 853 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
ef8e0840 854 devpriv->inbuf, SIZEINBUF,
88676359 855 &actual_length, 10000);
dabf2aa3 856 if (ret < 0) {
106af997 857 dev_err(dev->class_dev, "insn timeout, no data\n");
7aa41c3c 858 up(&devpriv->sem);
dabf2aa3 859 return ret;
f47c697d
BP
860 }
861 }
dabf2aa3 862
f47c697d 863 for (i = 0; i < insn->n;) {
dabf2aa3 864 ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
ef8e0840 865 devpriv->inbuf, SIZEINBUF,
88676359 866 &actual_length, 10000);
dabf2aa3
HS
867 if (ret < 0) {
868 dev_err(dev->class_dev, "insn data error: %d\n", ret);
7aa41c3c 869 up(&devpriv->sem);
dabf2aa3 870 return ret;
f47c697d
BP
871 }
872 n = actual_length / sizeof(uint16_t);
873 if ((n % 16) != 0) {
106af997 874 dev_err(dev->class_dev, "insn data packet corrupted\n");
7aa41c3c 875 up(&devpriv->sem);
f47c697d
BP
876 return -EINVAL;
877 }
878 for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
ef8e0840 879 data[i] = ((uint16_t *) (devpriv->inbuf))[j];
f47c697d
BP
880 i++;
881 }
882 }
dabf2aa3 883
7aa41c3c 884 up(&devpriv->sem);
dabf2aa3
HS
885
886 return insn->n;
f47c697d
BP
887}
888
dcd29f56
HS
889static int usbduxfast_attach_common(struct comedi_device *dev)
890{
891 struct usbduxfast_private *devpriv = dev->private;
892 struct comedi_subdevice *s;
893 int ret;
894
895 down(&devpriv->sem);
896
897 ret = comedi_alloc_subdevices(dev, 1);
898 if (ret) {
899 up(&devpriv->sem);
900 return ret;
901 }
902
903 /* Analog Input subdevice */
904 s = &dev->subdevices[0];
905 dev->read_subdev = s;
906 s->type = COMEDI_SUBD_AI;
907 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
908 s->n_chan = 16;
909 s->len_chanlist = 16;
910 s->insn_read = usbduxfast_ai_insn_read;
911 s->do_cmdtest = usbduxfast_ai_cmdtest;
912 s->do_cmd = usbduxfast_ai_cmd;
913 s->cancel = usbduxfast_ai_cancel;
914 s->maxdata = 0x1000;
915 s->range_table = &range_usbduxfast_ai_range;
916
917 up(&devpriv->sem);
918
919 return 0;
920}
f47c697d 921
1b4997e6 922static int usbduxfast_upload_firmware(struct comedi_device *dev,
f9eb8a3b
HS
923 const u8 *data, size_t size,
924 unsigned long context)
f47c697d 925{
0a92de24 926 struct usb_device *usb = comedi_to_usb_dev(dev);
1b4997e6 927 uint8_t *buf;
fbe38a8b 928 unsigned char *tmp;
106af997 929 int ret;
f47c697d 930
f9eb8a3b 931 if (!data)
81874ff7 932 return 0;
f47c697d 933
f9eb8a3b 934 if (size > FIRMWARE_MAX_LEN) {
106af997 935 dev_err(dev->class_dev, "firmware binary too large for FX2\n");
81874ff7
BP
936 return -ENOMEM;
937 }
4e8ad0dc 938
81874ff7 939 /* we generate a local buffer for the firmware */
f9eb8a3b 940 buf = kmemdup(data, size, GFP_KERNEL);
1b4997e6 941 if (!buf)
81874ff7 942 return -ENOMEM;
f47c697d 943
fbe38a8b
HS
944 /* we need a malloc'ed buffer for usb_control_msg() */
945 tmp = kmalloc(1, GFP_KERNEL);
946 if (!tmp) {
947 kfree(buf);
948 return -ENOMEM;
949 }
950
951 /* stop the current firmware on the device */
952 *tmp = 1; /* 7f92 to one */
953 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
954 USBDUXFASTSUB_FIRMWARE,
955 VENDOR_DIR_OUT,
956 USBDUXFASTSUB_CPUCS, 0x0000,
957 tmp, 1,
958 EZTIMEOUT);
81874ff7 959 if (ret < 0) {
106af997 960 dev_err(dev->class_dev, "can not stop firmware\n");
1b4997e6 961 goto done;
81874ff7 962 }
f47c697d 963
fbe38a8b
HS
964 /* upload the new firmware to the device */
965 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
966 USBDUXFASTSUB_FIRMWARE,
967 VENDOR_DIR_OUT,
968 0, 0x0000,
f9eb8a3b 969 buf, size,
fbe38a8b 970 EZTIMEOUT);
81874ff7 971 if (ret < 0) {
106af997 972 dev_err(dev->class_dev, "firmware upload failed\n");
1b4997e6 973 goto done;
f47c697d 974 }
fbe38a8b
HS
975
976 /* start the new firmware on the device */
977 *tmp = 0; /* 7f92 to zero */
978 ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
979 USBDUXFASTSUB_FIRMWARE,
980 VENDOR_DIR_OUT,
981 USBDUXFASTSUB_CPUCS, 0x0000,
982 tmp, 1,
983 EZTIMEOUT);
1b4997e6 984 if (ret < 0)
106af997 985 dev_err(dev->class_dev, "can not start firmware\n");
1b4997e6
HS
986
987done:
fbe38a8b 988 kfree(tmp);
1b4997e6
HS
989 kfree(buf);
990 return ret;
f47c697d
BP
991}
992
2d719c9c
HS
993static int usbduxfast_auto_attach(struct comedi_device *dev,
994 unsigned long context_unused)
f47c697d 995{
2d719c9c 996 struct usb_interface *intf = comedi_to_usb_interface(dev);
0a92de24 997 struct usb_device *usb = comedi_to_usb_dev(dev);
2d719c9c 998 struct usbduxfast_private *devpriv;
6742c0af 999 int ret;
f47c697d 1000
e4a8ecc0 1001 if (usb->speed != USB_SPEED_HIGH) {
106af997 1002 dev_err(dev->class_dev,
0a00ab99 1003 "This driver needs USB 2.0 to operate. Aborting...\n");
88676359 1004 return -ENODEV;
f47c697d 1005 }
64bf88bf 1006
0bdab509 1007 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
2d719c9c
HS
1008 if (!devpriv)
1009 return -ENOMEM;
f47c697d 1010
ca88c09f 1011 sema_init(&devpriv->sem, 1);
a35fd8a1 1012 usb_set_intfdata(intf, devpriv);
f47c697d 1013
5659e24a
HS
1014 devpriv->duxbuf = kmalloc(SIZEOFDUXBUF, GFP_KERNEL);
1015 if (!devpriv->duxbuf)
88676359 1016 return -ENOMEM;
ca88c09f 1017
a4f2e0f9 1018 ret = usb_set_interface(usb,
01245e7a 1019 intf->altsetting->desc.bInterfaceNumber, 1);
2d719c9c 1020 if (ret < 0) {
106af997 1021 dev_err(dev->class_dev,
ca88c09f 1022 "could not switch to alternate setting 1\n");
88676359 1023 return -ENODEV;
f47c697d 1024 }
ca88c09f 1025
da58c263
HS
1026 devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
1027 if (!devpriv->urb) {
106af997 1028 dev_err(dev->class_dev, "Could not alloc. urb\n");
88676359 1029 return -ENOMEM;
f47c697d 1030 }
ca88c09f 1031
ef8e0840
HS
1032 devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
1033 if (!devpriv->inbuf)
88676359 1034 return -ENOMEM;
ca88c09f 1035
f9eb8a3b
HS
1036 ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
1037 usbduxfast_upload_firmware, 0);
1038 if (ret)
6742c0af 1039 return ret;
6742c0af 1040
2d719c9c
HS
1041 return usbduxfast_attach_common(dev);
1042}
1043
1044static void usbduxfast_detach(struct comedi_device *dev)
1045{
a71a65b1 1046 struct usb_interface *intf = comedi_to_usb_interface(dev);
2d719c9c
HS
1047 struct usbduxfast_private *devpriv = dev->private;
1048
38bf7ba8
HS
1049 if (!devpriv)
1050 return;
1051
1052 down(&devpriv->sem);
1053
a71a65b1 1054 usb_set_intfdata(intf, NULL);
38bf7ba8 1055
da58c263 1056 if (devpriv->urb) {
38bf7ba8 1057 /* waits until a running transfer is over */
da58c263 1058 usb_kill_urb(devpriv->urb);
38bf7ba8 1059
ef8e0840
HS
1060 kfree(devpriv->inbuf);
1061 devpriv->inbuf = NULL;
38bf7ba8 1062
da58c263
HS
1063 usb_free_urb(devpriv->urb);
1064 devpriv->urb = NULL;
2d719c9c 1065 }
38bf7ba8 1066
5659e24a
HS
1067 kfree(devpriv->duxbuf);
1068 devpriv->duxbuf = NULL;
38bf7ba8
HS
1069
1070 devpriv->ai_cmd_running = 0;
1071
1072 up(&devpriv->sem);
2d719c9c
HS
1073}
1074
1075static struct comedi_driver usbduxfast_driver = {
1076 .driver_name = "usbduxfast",
1077 .module = THIS_MODULE,
1078 .auto_attach = usbduxfast_auto_attach,
1079 .detach = usbduxfast_detach,
1080};
1081
1082static int usbduxfast_usb_probe(struct usb_interface *intf,
1083 const struct usb_device_id *id)
1084{
a35fd8a1 1085 return comedi_usb_auto_config(intf, &usbduxfast_driver, 0);
f47c697d
BP
1086}
1087
4c8ba916 1088static const struct usb_device_id usbduxfast_usb_table[] = {
4e8ad0dc 1089 /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
4c8ba916
HS
1090 { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
1091 { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
1092 { }
f47c697d 1093};
4c8ba916 1094MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
f47c697d 1095
cb9513ad 1096static struct usb_driver usbduxfast_usb_driver = {
4c8ba916
HS
1097 .name = "usbduxfast",
1098 .probe = usbduxfast_usb_probe,
0c4ab671 1099 .disconnect = comedi_usb_auto_unconfig,
4c8ba916 1100 .id_table = usbduxfast_usb_table,
f47c697d 1101};
cb9513ad 1102module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
f47c697d 1103
4c8ba916
HS
1104MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
1105MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
f47c697d 1106MODULE_LICENSE("GPL");
e74f7fc5 1107MODULE_FIRMWARE(FIRMWARE);