40 #include <linux/kernel.h>
42 #include <linux/module.h>
44 #include <linux/slab.h>
45 #include <linux/input.h>
47 #include <linux/fcntl.h>
48 #include <linux/compiler.h>
50 #include "../comedidev.h"
60 #define FIRMWARE "usbduxfast_firmware.bin"
61 #define USBDUXFASTSUB_FIRMWARE 0xA0
62 #define VENDOR_DIR_IN 0xC0
63 #define VENDOR_DIR_OUT 0x40
68 #define USBDUXFASTSUB_CPUCS 0xE600
83 #define CHANNELLISTEP 4
88 #define NUMCHANNELS 32
98 #define SIZEADIN (sizeof(int16_t))
103 #define SIZEINBUF 512
108 #define SIZEINSNBUF 512
113 #define SIZEOFDUXBUFFER 256
118 #define NUMOFINBUFFERSHIGH 10
123 #define NUMUSBDUXFAST 16
136 #define MIN_SAMPLING_PERIOD 9
141 #define MAX_SAMPLING_PERIOD 500
147 #define PACKETS_TO_IGNORE 4
152 static const struct comedi_lrange range_usbduxfast_ai_range = {
198 #define SENDADCOMMANDS 0
199 #define SENDINITEP6 1
201 static int send_dux_commands(
struct usbduxfastsub_s *udfs,
int cmd_type)
207 #ifdef CONFIG_COMEDI_DEBUG
220 "the usb-device, err=%d\n", udfs->
comedidev->minor, tmp);
233 if (udfs && udfs->
urbIn) {
239 #ifdef CONFIG_COMEDI_DEBUG
250 static int usbduxfast_ai_stop(
struct usbduxfastsub_s *udfs,
int do_unlink)
258 #ifdef CONFIG_COMEDI_DEBUG
266 ret = usbduxfastsub_unlink_InURBs(udfs);
282 #ifdef CONFIG_COMEDI_DEBUG
296 ret = usbduxfast_ai_stop(udfs, 1);
306 static void usbduxfastsub_ai_Irq(
struct urb *
urb)
321 this_comedidev = urb->context;
322 if (!this_comedidev) {
328 udfs = this_comedidev->
private;
331 "subdev is a NULL pointer!\n");
352 switch (urb->status) {
369 usbduxfast_ai_stop(udfs, 0);
373 printk(
"comedi%d: usbduxfast: non-zero urb status received in "
374 "ai intr context: %d\n",
379 usbduxfast_ai_stop(udfs, 0);
383 p = urb->transfer_buffer;
387 n = urb->actual_length /
sizeof(
uint16_t);
394 urb->transfer_buffer,
397 usbduxfast_ai_stop(udfs, 0);
410 usbduxfast_ai_stop(udfs, 0);
435 usbduxfast_ai_stop(udfs, 0);
442 unsigned char local_transfer_buffer[16];
445 local_transfer_buffer[0] = 0;
453 local_transfer_buffer,
457 printk(
"comedi_: usbduxfast_: control msg failed (start)\n");
467 unsigned char local_transfer_buffer[16];
470 local_transfer_buffer[0] = 1;
477 local_transfer_buffer, 1,
489 unsigned char *local_transfer_buffer,
490 unsigned int startAddr,
unsigned int len)
494 #ifdef CONFIG_COMEDI_DEBUG
497 startAddr, local_transfer_buffer[0]);
506 local_transfer_buffer,
510 #ifdef CONFIG_COMEDI_DEBUG
534 #ifdef CONFIG_COMEDI_DEBUG
560 #ifdef CONFIG_COMEDI_DEBUG
563 "scan_begin_arg=%u\n",
568 err |= cfc_check_trigger_src(&cmd->
start_src,
581 err |= cfc_check_trigger_is_unique(cmd->
start_src);
583 err |= cfc_check_trigger_is_unique(cmd->
convert_src);
584 err |= cfc_check_trigger_is_unique(cmd->
stop_src);
617 if (steps < (minSamplPer * 1000))
618 steps = minSamplPer * 1000;
667 unsigned int trignum)
680 #ifdef CONFIG_COMEDI_DEBUG
686 " trignum\n", dev->
minor);
692 ret = usbduxfastsub_submit_InURBs(udfs);
695 "urbSubmit: err=%d\n", dev->
minor, ret);
703 " running\n", dev->
minor);
713 #define LENBASE (1+0x00)
714 #define OPBASE (1+0x08)
715 #define OUTBASE (1+0x10)
716 #define LOGBASE (1+0x18)
722 unsigned int chan,
gain, rngmask = 0xff;
726 long steps, steps_tmp;
728 #ifdef CONFIG_COMEDI_DEBUG
742 " is running.\n", dev->
minor);
747 s->
async->cur_chan = 0;
761 "only consecutive channels.\n",
769 " the same for all channels.\n",
776 " long\n", dev->
minor);
784 "scan_begin_src==TRIG_TIMER not valid.\n", dev->
minor);
793 "scan_begin_arg=%d. Not properly tested by cmdtest?\n",
800 "too low.\n", dev->
minor);
807 " with 1 or 16 channels possible.\n", dev->
minor);
811 #ifdef CONFIG_COMEDI_DEBUG
823 rngmask = 0xff - 0x04;
926 rngmask = 0xff - 0x04;
937 steps_tmp = steps - 1;
940 rngmask = 0xff - 0x04;
967 steps_tmp = steps - 2;
970 rngmask = 0xff - 0x04;
997 for (j = 0; j < 1; j++) {
999 rngmask = 0xff - 0x04;
1014 rngmask = 0xff - 0x04;
1030 steps_tmp = steps - 2;
1040 rngmask = 0xff - 0x04;
1059 rngmask = 0xff - 0x04;
1074 (0xFF - 0x02) & rngmask;
1087 (0xFF - 0x02) & rngmask;
1125 "channels\n", dev->
minor);
1130 #ifdef CONFIG_COMEDI_DEBUG
1138 "Aborting...\n", dev->
minor);
1146 "(cmd->stop_arg)*(cmd->scan_end_arg)<1, "
1147 "aborting.\n", dev->
minor);
1161 ret = usbduxfastsub_submit_InURBs(udfs);
1175 s->
async->inttrig = usbduxfast_ai_inttrig;
1185 static int usbduxfast_ai_insn_read(
struct comedi_device *dev,
1189 int i,
j,
n, actual_length;
1200 #ifdef CONFIG_COMEDI_DEBUG
1202 "insn->subdev=%d\n", dev->
minor, insn->
n, insn->
subdev);
1211 "Command is running.\n", dev->
minor);
1221 rngmask = 0xff - 0x04;
1264 #ifdef CONFIG_COMEDI_DEBUG
1272 "Aborting...\n", dev->
minor);
1276 #ifdef CONFIG_COMEDI_DEBUG
1285 &actual_length, 10000);
1294 for (i = 0; i < insn->
n;) {
1298 &actual_length, 10000);
1305 n = actual_length /
sizeof(
uint16_t);
1306 if ((n % 16) != 0) {
1308 "corrupted.\n", dev->
minor);
1312 for (j = chan; (j <
n) && (i < insn->n); j = j + 16) {
1321 #define FIRMWARE_MAX_LEN 0x2000
1324 const u8 *firmwareBinary,
int sizeFirmware)
1329 if (!firmwareBinary)
1334 "comedi_: usbduxfast firmware binary it too large for FX2.\n");
1342 "comedi_: mem alloc for firmware failed\n");
1346 ret = usbduxfastsub_stop(usbduxfastsub);
1349 "comedi_: can not stop firmware\n");
1354 ret = usbduxfastsub_upload(usbduxfastsub, fwBuf, 0, sizeFirmware);
1357 "comedi_: firmware upload failed\n");
1361 ret = usbduxfastsub_start(usbduxfastsub);
1364 "comedi_: can not start firmware\n");
1374 #ifdef CONFIG_COMEDI_DEBUG
1407 static int usbduxfast_attach_common(
struct comedi_device *dev,
1444 s->
do_cmd = usbduxfast_ai_cmd;
1445 s->
cancel = usbduxfast_ai_cancel;
1464 down(&start_stop_sem);
1465 udfs = usb_get_intfdata(uinterf);
1466 if (!udfs || !udfs->
probed) {
1468 "usbduxfast: error: attach_usb failed, not connected\n");
1472 "usbduxfast: error: attach_usb failed, already attached\n");
1475 ret = usbduxfast_attach_common(dev, udfs);
1476 up(&start_stop_sem);
1486 down(&start_stop_sem);
1490 up(&start_stop_sem);
1496 .driver_name =
"usbduxfast",
1498 .attach_usb = usbduxfast_attach_usb,
1499 .detach = usbduxfast_detach,
1502 static void usbduxfast_firmware_request_complete_handler(
const struct firmware
1516 ret = firmwareUpload(usbduxfastsub_tmp, fw->
data, fw->
size);
1520 "Could not upload firmware (err=%d)\n", ret);
1529 static int usbduxfast_usb_probe(
struct usb_interface *uinterf,
1532 struct usb_device *
udev = interface_to_usbdev(uinterf);
1539 "USB 2.0 to operate. Aborting...\n");
1542 #ifdef CONFIG_COMEDI_DEBUG
1544 "the usb-device\n");
1546 down(&start_stop_sem);
1550 if (!usbduxfastsub[i].probed) {
1559 up(&start_stop_sem);
1562 #ifdef CONFIG_COMEDI_DEBUG
1564 "connect to comedi.\n", index);
1567 sema_init(&(usbduxfastsub[index].
sem), 1);
1572 usbduxfastsub[
index].interface = uinterf;
1574 usbduxfastsub[
index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
1579 usb_set_intfdata(uinterf, &(usbduxfastsub[index]));
1581 #ifdef CONFIG_COMEDI_DEBUG
1583 usbduxfastsub[index].ifnum);
1588 if (!usbduxfastsub[index].dux_commands) {
1591 tidy_up(&(usbduxfastsub[index]));
1592 up(&start_stop_sem);
1597 if (!usbduxfastsub[index].insnBuffer) {
1599 "for insnBuffer\n");
1600 tidy_up(&(usbduxfastsub[index]));
1601 up(&start_stop_sem);
1606 usbduxfastsub[index].ifnum, 1);
1609 "alternate setting 1.\n", index);
1610 tidy_up(&(usbduxfastsub[index]));
1611 up(&start_stop_sem);
1615 if (!usbduxfastsub[index].urbIn) {
1618 tidy_up(&(usbduxfastsub[index]));
1619 up(&start_stop_sem);
1625 "transb.\n", index);
1626 tidy_up(&(usbduxfastsub[index]));
1627 up(&start_stop_sem);
1631 usbduxfastsub[
index].probed = 1;
1632 up(&start_stop_sem);
1639 usbduxfastsub + index,
1640 usbduxfast_firmware_request_complete_handler);
1643 dev_err(&udev->dev,
"could not load firmware (err=%d)\n", ret);
1648 "initialized.\n", index);
1656 struct usb_device *udev = interface_to_usbdev(intf);
1663 if (udfs->
usbdev != udev) {
1671 down(&start_stop_sem);
1675 up(&start_stop_sem);
1677 #ifdef CONFIG_COMEDI_DEBUG
1682 static const struct usb_device_id usbduxfast_usb_table[] = {
1684 { USB_DEVICE(0x13d8, 0x0010) },
1685 { USB_DEVICE(0x13d8, 0x0011) },
1690 static struct usb_driver usbduxfast_usb_driver = {
1691 #ifdef COMEDI_HAVE_USB_DRIVER_OWNER
1694 .name =
"usbduxfast",
1695 .probe = usbduxfast_usb_probe,
1696 .disconnect = usbduxfast_usb_disconnect,
1697 .id_table = usbduxfast_usb_table,