GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / staging / comedi / drivers / dt9812.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * comedi/drivers/dt9812.c
4  *   COMEDI driver for DataTranslation DT9812 USB module
5  *
6  * Copyright (C) 2005 Anders Blomdell <anders.blomdell@control.lth.se>
7  *
8  * COMEDI - Linux Control and Measurement Device Interface
9  */
10
11 /*
12  * Driver: dt9812
13  * Description: Data Translation DT9812 USB module
14  * Devices: [Data Translation] DT9812 (dt9812)
15  * Author: anders.blomdell@control.lth.se (Anders Blomdell)
16  * Status: in development
17  * Updated: Sun Nov 20 20:18:34 EST 2005
18  *
19  * This driver works, but bulk transfers not implemented. Might be a
20  * starting point for someone else. I found out too late that USB has
21  * too high latencies (>1 ms) for my needs.
22  */
23
24 /*
25  * Nota Bene:
26  *   1. All writes to command pipe has to be 32 bytes (ISP1181B SHRTP=0 ?)
27  *   2. The DDK source (as of sep 2005) is in error regarding the
28  *      input MUX bits (example code says P4, but firmware schematics
29  *      says P1).
30  */
31
32 #include <linux/kernel.h>
33 #include <linux/module.h>
34 #include <linux/errno.h>
35 #include <linux/slab.h>
36 #include <linux/uaccess.h>
37
38 #include "../comedi_usb.h"
39
40 #define DT9812_DIAGS_BOARD_INFO_ADDR    0xFBFF
41 #define DT9812_MAX_WRITE_CMD_PIPE_SIZE  32
42 #define DT9812_MAX_READ_CMD_PIPE_SIZE   32
43
44 /* usb_bulk_msg() timout in milliseconds */
45 #define DT9812_USB_TIMEOUT              1000
46
47 /*
48  * See Silican Laboratories C8051F020/1/2/3 manual
49  */
50 #define F020_SFR_P4                     0x84
51 #define F020_SFR_P1                     0x90
52 #define F020_SFR_P2                     0xa0
53 #define F020_SFR_P3                     0xb0
54 #define F020_SFR_AMX0CF                 0xba
55 #define F020_SFR_AMX0SL                 0xbb
56 #define F020_SFR_ADC0CF                 0xbc
57 #define F020_SFR_ADC0L                  0xbe
58 #define F020_SFR_ADC0H                  0xbf
59 #define F020_SFR_DAC0L                  0xd2
60 #define F020_SFR_DAC0H                  0xd3
61 #define F020_SFR_DAC0CN                 0xd4
62 #define F020_SFR_DAC1L                  0xd5
63 #define F020_SFR_DAC1H                  0xd6
64 #define F020_SFR_DAC1CN                 0xd7
65 #define F020_SFR_ADC0CN                 0xe8
66
67 #define F020_MASK_ADC0CF_AMP0GN0        0x01
68 #define F020_MASK_ADC0CF_AMP0GN1        0x02
69 #define F020_MASK_ADC0CF_AMP0GN2        0x04
70
71 #define F020_MASK_ADC0CN_AD0EN          0x80
72 #define F020_MASK_ADC0CN_AD0INT         0x20
73 #define F020_MASK_ADC0CN_AD0BUSY        0x10
74
75 #define F020_MASK_DACXCN_DACXEN         0x80
76
77 enum {
78                                         /* A/D  D/A  DI  DO  CT */
79         DT9812_DEVID_DT9812_10,         /*  8    2   8   8   1  +/- 10V */
80         DT9812_DEVID_DT9812_2PT5,       /*  8    2   8   8   1  0-2.44V */
81 };
82
83 enum dt9812_gain {
84         DT9812_GAIN_0PT25 = 1,
85         DT9812_GAIN_0PT5 = 2,
86         DT9812_GAIN_1 = 4,
87         DT9812_GAIN_2 = 8,
88         DT9812_GAIN_4 = 16,
89         DT9812_GAIN_8 = 32,
90         DT9812_GAIN_16 = 64,
91 };
92
93 enum {
94         DT9812_LEAST_USB_FIRMWARE_CMD_CODE = 0,
95         /* Write Flash memory */
96         DT9812_W_FLASH_DATA = 0,
97         /* Read Flash memory misc config info */
98         DT9812_R_FLASH_DATA = 1,
99
100         /*
101          * Register read/write commands for processor
102          */
103
104         /* Read a single byte of USB memory */
105         DT9812_R_SINGLE_BYTE_REG = 2,
106         /* Write a single byte of USB memory */
107         DT9812_W_SINGLE_BYTE_REG = 3,
108         /* Multiple Reads of USB memory */
109         DT9812_R_MULTI_BYTE_REG = 4,
110         /* Multiple Writes of USB memory */
111         DT9812_W_MULTI_BYTE_REG = 5,
112         /* Read, (AND) with mask, OR value, then write (single) */
113         DT9812_RMW_SINGLE_BYTE_REG = 6,
114         /* Read, (AND) with mask, OR value, then write (multiple) */
115         DT9812_RMW_MULTI_BYTE_REG = 7,
116
117         /*
118          * Register read/write commands for SMBus
119          */
120
121         /* Read a single byte of SMBus */
122         DT9812_R_SINGLE_BYTE_SMBUS = 8,
123         /* Write a single byte of SMBus */
124         DT9812_W_SINGLE_BYTE_SMBUS = 9,
125         /* Multiple Reads of SMBus */
126         DT9812_R_MULTI_BYTE_SMBUS = 10,
127         /* Multiple Writes of SMBus */
128         DT9812_W_MULTI_BYTE_SMBUS = 11,
129
130         /*
131          * Register read/write commands for a device
132          */
133
134         /* Read a single byte of a device */
135         DT9812_R_SINGLE_BYTE_DEV = 12,
136         /* Write a single byte of a device */
137         DT9812_W_SINGLE_BYTE_DEV = 13,
138         /* Multiple Reads of a device */
139         DT9812_R_MULTI_BYTE_DEV = 14,
140         /* Multiple Writes of a device */
141         DT9812_W_MULTI_BYTE_DEV = 15,
142
143         /* Not sure if we'll need this */
144         DT9812_W_DAC_THRESHOLD = 16,
145
146         /* Set interrupt on change mask */
147         DT9812_W_INT_ON_CHANGE_MASK = 17,
148
149         /* Write (or Clear) the CGL for the ADC */
150         DT9812_W_CGL = 18,
151         /* Multiple Reads of USB memory */
152         DT9812_R_MULTI_BYTE_USBMEM = 19,
153         /* Multiple Writes to USB memory */
154         DT9812_W_MULTI_BYTE_USBMEM = 20,
155
156         /* Issue a start command to a given subsystem */
157         DT9812_START_SUBSYSTEM = 21,
158         /* Issue a stop command to a given subsystem */
159         DT9812_STOP_SUBSYSTEM = 22,
160
161         /* calibrate the board using CAL_POT_CMD */
162         DT9812_CALIBRATE_POT = 23,
163         /* set the DAC FIFO size */
164         DT9812_W_DAC_FIFO_SIZE = 24,
165         /* Write or Clear the CGL for the DAC */
166         DT9812_W_CGL_DAC = 25,
167         /* Read a single value from a subsystem */
168         DT9812_R_SINGLE_VALUE_CMD = 26,
169         /* Write a single value to a subsystem */
170         DT9812_W_SINGLE_VALUE_CMD = 27,
171         /* Valid DT9812_USB_FIRMWARE_CMD_CODE's will be less than this number */
172         DT9812_MAX_USB_FIRMWARE_CMD_CODE,
173 };
174
175 struct dt9812_flash_data {
176         __le16 numbytes;
177         __le16 address;
178 };
179
180 #define DT9812_MAX_NUM_MULTI_BYTE_RDS  \
181         ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(u8))
182
183 struct dt9812_read_multi {
184         u8 count;
185         u8 address[DT9812_MAX_NUM_MULTI_BYTE_RDS];
186 };
187
188 struct dt9812_write_byte {
189         u8 address;
190         u8 value;
191 };
192
193 #define DT9812_MAX_NUM_MULTI_BYTE_WRTS  \
194         ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \
195          sizeof(struct dt9812_write_byte))
196
197 struct dt9812_write_multi {
198         u8 count;
199         struct dt9812_write_byte write[DT9812_MAX_NUM_MULTI_BYTE_WRTS];
200 };
201
202 struct dt9812_rmw_byte {
203         u8 address;
204         u8 and_mask;
205         u8 or_value;
206 };
207
208 #define DT9812_MAX_NUM_MULTI_BYTE_RMWS  \
209         ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \
210          sizeof(struct dt9812_rmw_byte))
211
212 struct dt9812_rmw_multi {
213         u8 count;
214         struct dt9812_rmw_byte rmw[DT9812_MAX_NUM_MULTI_BYTE_RMWS];
215 };
216
217 struct dt9812_usb_cmd {
218         __le32 cmd;
219         union {
220                 struct dt9812_flash_data flash_data_info;
221                 struct dt9812_read_multi read_multi_info;
222                 struct dt9812_write_multi write_multi_info;
223                 struct dt9812_rmw_multi rmw_multi_info;
224         } u;
225 };
226
227 struct dt9812_private {
228         struct mutex mut;
229         struct {
230                 __u8 addr;
231                 size_t size;
232         } cmd_wr, cmd_rd;
233         u16 device;
234 };
235
236 static int dt9812_read_info(struct comedi_device *dev,
237                             int offset, void *buf, size_t buf_size)
238 {
239         struct usb_device *usb = comedi_to_usb_dev(dev);
240         struct dt9812_private *devpriv = dev->private;
241         struct dt9812_usb_cmd *cmd;
242         size_t tbuf_size;
243         int count, ret;
244         void *tbuf;
245
246         tbuf_size = max(sizeof(*cmd), buf_size);
247
248         tbuf = kzalloc(tbuf_size, GFP_KERNEL);
249         if (!tbuf)
250                 return -ENOMEM;
251
252         cmd = tbuf;
253
254         cmd->cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
255         cmd->u.flash_data_info.address =
256             cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
257         cmd->u.flash_data_info.numbytes = cpu_to_le16(buf_size);
258
259         /* DT9812 only responds to 32 byte writes!! */
260         ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
261                            cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT);
262         if (ret)
263                 goto out;
264
265         ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
266                            tbuf, buf_size, &count, DT9812_USB_TIMEOUT);
267         if (!ret) {
268                 if (count == buf_size)
269                         memcpy(buf, tbuf, buf_size);
270                 else
271                         ret = -EREMOTEIO;
272         }
273 out:
274         kfree(tbuf);
275
276         return ret;
277 }
278
279 static int dt9812_read_multiple_registers(struct comedi_device *dev,
280                                           int reg_count, u8 *address,
281                                           u8 *value)
282 {
283         struct usb_device *usb = comedi_to_usb_dev(dev);
284         struct dt9812_private *devpriv = dev->private;
285         struct dt9812_usb_cmd *cmd;
286         int i, count, ret;
287         size_t buf_size;
288         void *buf;
289
290         buf_size = max_t(size_t, sizeof(*cmd), reg_count);
291
292         buf = kzalloc(buf_size, GFP_KERNEL);
293         if (!buf)
294                 return -ENOMEM;
295
296         cmd = buf;
297
298         cmd->cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG);
299         cmd->u.read_multi_info.count = reg_count;
300         for (i = 0; i < reg_count; i++)
301                 cmd->u.read_multi_info.address[i] = address[i];
302
303         /* DT9812 only responds to 32 byte writes!! */
304         ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
305                            cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT);
306         if (ret)
307                 goto out;
308
309         ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
310                            buf, reg_count, &count, DT9812_USB_TIMEOUT);
311         if (!ret) {
312                 if (count == reg_count)
313                         memcpy(value, buf, reg_count);
314                 else
315                         ret = -EREMOTEIO;
316         }
317 out:
318         kfree(buf);
319
320         return ret;
321 }
322
323 static int dt9812_write_multiple_registers(struct comedi_device *dev,
324                                            int reg_count, u8 *address,
325                                            u8 *value)
326 {
327         struct usb_device *usb = comedi_to_usb_dev(dev);
328         struct dt9812_private *devpriv = dev->private;
329         struct dt9812_usb_cmd *cmd;
330         int i, count;
331         int ret;
332
333         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
334         if (!cmd)
335                 return -ENOMEM;
336
337         cmd->cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG);
338         cmd->u.read_multi_info.count = reg_count;
339         for (i = 0; i < reg_count; i++) {
340                 cmd->u.write_multi_info.write[i].address = address[i];
341                 cmd->u.write_multi_info.write[i].value = value[i];
342         }
343
344         /* DT9812 only responds to 32 byte writes!! */
345         ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
346                            cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT);
347         kfree(cmd);
348
349         return ret;
350 }
351
352 static int dt9812_rmw_multiple_registers(struct comedi_device *dev,
353                                          int reg_count,
354                                          struct dt9812_rmw_byte *rmw)
355 {
356         struct usb_device *usb = comedi_to_usb_dev(dev);
357         struct dt9812_private *devpriv = dev->private;
358         struct dt9812_usb_cmd *cmd;
359         int i, count;
360         int ret;
361
362         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
363         if (!cmd)
364                 return -ENOMEM;
365
366         cmd->cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG);
367         cmd->u.rmw_multi_info.count = reg_count;
368         for (i = 0; i < reg_count; i++)
369                 cmd->u.rmw_multi_info.rmw[i] = rmw[i];
370
371         /* DT9812 only responds to 32 byte writes!! */
372         ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
373                            cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT);
374         kfree(cmd);
375
376         return ret;
377 }
378
379 static int dt9812_digital_in(struct comedi_device *dev, u8 *bits)
380 {
381         struct dt9812_private *devpriv = dev->private;
382         u8 reg[2] = { F020_SFR_P3, F020_SFR_P1 };
383         u8 value[2];
384         int ret;
385
386         mutex_lock(&devpriv->mut);
387         ret = dt9812_read_multiple_registers(dev, 2, reg, value);
388         if (ret == 0) {
389                 /*
390                  * bits 0-6 in F020_SFR_P3 are bits 0-6 in the digital
391                  * input port bit 3 in F020_SFR_P1 is bit 7 in the
392                  * digital input port
393                  */
394                 *bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4);
395         }
396         mutex_unlock(&devpriv->mut);
397
398         return ret;
399 }
400
401 static int dt9812_digital_out(struct comedi_device *dev, u8 bits)
402 {
403         struct dt9812_private *devpriv = dev->private;
404         u8 reg[1] = { F020_SFR_P2 };
405         u8 value[1] = { bits };
406         int ret;
407
408         mutex_lock(&devpriv->mut);
409         ret = dt9812_write_multiple_registers(dev, 1, reg, value);
410         mutex_unlock(&devpriv->mut);
411
412         return ret;
413 }
414
415 static void dt9812_configure_mux(struct comedi_device *dev,
416                                  struct dt9812_rmw_byte *rmw, int channel)
417 {
418         struct dt9812_private *devpriv = dev->private;
419
420         if (devpriv->device == DT9812_DEVID_DT9812_10) {
421                 /* In the DT9812/10V MUX is selected by P1.5-7 */
422                 rmw->address = F020_SFR_P1;
423                 rmw->and_mask = 0xe0;
424                 rmw->or_value = channel << 5;
425         } else {
426                 /* In the DT9812/2.5V, internal mux is selected by bits 0:2 */
427                 rmw->address = F020_SFR_AMX0SL;
428                 rmw->and_mask = 0xff;
429                 rmw->or_value = channel & 0x07;
430         }
431 }
432
433 static void dt9812_configure_gain(struct comedi_device *dev,
434                                   struct dt9812_rmw_byte *rmw,
435                                   enum dt9812_gain gain)
436 {
437         struct dt9812_private *devpriv = dev->private;
438
439         /* In the DT9812/10V, there is an external gain of 0.5 */
440         if (devpriv->device == DT9812_DEVID_DT9812_10)
441                 gain <<= 1;
442
443         rmw->address = F020_SFR_ADC0CF;
444         rmw->and_mask = F020_MASK_ADC0CF_AMP0GN2 |
445                         F020_MASK_ADC0CF_AMP0GN1 |
446                         F020_MASK_ADC0CF_AMP0GN0;
447
448         switch (gain) {
449                 /*
450                  * 000 -> Gain =  1
451                  * 001 -> Gain =  2
452                  * 010 -> Gain =  4
453                  * 011 -> Gain =  8
454                  * 10x -> Gain = 16
455                  * 11x -> Gain =  0.5
456                  */
457         case DT9812_GAIN_0PT5:
458                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 |
459                                 F020_MASK_ADC0CF_AMP0GN1;
460                 break;
461         default:
462                 /* this should never happen, just use a gain of 1 */
463         case DT9812_GAIN_1:
464                 rmw->or_value = 0x00;
465                 break;
466         case DT9812_GAIN_2:
467                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN0;
468                 break;
469         case DT9812_GAIN_4:
470                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN1;
471                 break;
472         case DT9812_GAIN_8:
473                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 |
474                                 F020_MASK_ADC0CF_AMP0GN0;
475                 break;
476         case DT9812_GAIN_16:
477                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
478                 break;
479         }
480 }
481
482 static int dt9812_analog_in(struct comedi_device *dev,
483                             int channel, u16 *value, enum dt9812_gain gain)
484 {
485         struct dt9812_private *devpriv = dev->private;
486         struct dt9812_rmw_byte rmw[3];
487         u8 reg[3] = {
488                 F020_SFR_ADC0CN,
489                 F020_SFR_ADC0H,
490                 F020_SFR_ADC0L
491         };
492         u8 val[3];
493         int ret;
494
495         mutex_lock(&devpriv->mut);
496
497         /* 1 select the gain */
498         dt9812_configure_gain(dev, &rmw[0], gain);
499
500         /* 2 set the MUX to select the channel */
501         dt9812_configure_mux(dev, &rmw[1], channel);
502
503         /* 3 start conversion */
504         rmw[2].address = F020_SFR_ADC0CN;
505         rmw[2].and_mask = 0xff;
506         rmw[2].or_value = F020_MASK_ADC0CN_AD0EN | F020_MASK_ADC0CN_AD0BUSY;
507
508         ret = dt9812_rmw_multiple_registers(dev, 3, rmw);
509         if (ret)
510                 goto exit;
511
512         /* read the status and ADC */
513         ret = dt9812_read_multiple_registers(dev, 3, reg, val);
514         if (ret)
515                 goto exit;
516
517         /*
518          * An ADC conversion takes 16 SAR clocks cycles, i.e. about 9us.
519          * Therefore, between the instant that AD0BUSY was set via
520          * dt9812_rmw_multiple_registers and the read of AD0BUSY via
521          * dt9812_read_multiple_registers, the conversion should be complete
522          * since these two operations require two USB transactions each taking
523          * at least a millisecond to complete.  However, lets make sure that
524          * conversion is finished.
525          */
526         if ((val[0] & (F020_MASK_ADC0CN_AD0INT | F020_MASK_ADC0CN_AD0BUSY)) ==
527             F020_MASK_ADC0CN_AD0INT) {
528                 switch (devpriv->device) {
529                 case DT9812_DEVID_DT9812_10:
530                         /*
531                          * For DT9812-10V the personality module set the
532                          * encoding to 2's complement. Hence, convert it before
533                          * returning it
534                          */
535                         *value = ((val[1] << 8) | val[2]) + 0x800;
536                         break;
537                 case DT9812_DEVID_DT9812_2PT5:
538                         *value = (val[1] << 8) | val[2];
539                         break;
540                 }
541         }
542
543 exit:
544         mutex_unlock(&devpriv->mut);
545
546         return ret;
547 }
548
549 static int dt9812_analog_out(struct comedi_device *dev, int channel, u16 value)
550 {
551         struct dt9812_private *devpriv = dev->private;
552         struct dt9812_rmw_byte rmw[3];
553         int ret;
554
555         mutex_lock(&devpriv->mut);
556
557         switch (channel) {
558         case 0:
559                 /* 1. Set DAC mode */
560                 rmw[0].address = F020_SFR_DAC0CN;
561                 rmw[0].and_mask = 0xff;
562                 rmw[0].or_value = F020_MASK_DACXCN_DACXEN;
563
564                 /* 2. load lsb of DAC value first */
565                 rmw[1].address = F020_SFR_DAC0L;
566                 rmw[1].and_mask = 0xff;
567                 rmw[1].or_value = value & 0xff;
568
569                 /* 3. load msb of DAC value next to latch the 12-bit value */
570                 rmw[2].address = F020_SFR_DAC0H;
571                 rmw[2].and_mask = 0xff;
572                 rmw[2].or_value = (value >> 8) & 0xf;
573                 break;
574
575         case 1:
576                 /* 1. Set DAC mode */
577                 rmw[0].address = F020_SFR_DAC1CN;
578                 rmw[0].and_mask = 0xff;
579                 rmw[0].or_value = F020_MASK_DACXCN_DACXEN;
580
581                 /* 2. load lsb of DAC value first */
582                 rmw[1].address = F020_SFR_DAC1L;
583                 rmw[1].and_mask = 0xff;
584                 rmw[1].or_value = value & 0xff;
585
586                 /* 3. load msb of DAC value next to latch the 12-bit value */
587                 rmw[2].address = F020_SFR_DAC1H;
588                 rmw[2].and_mask = 0xff;
589                 rmw[2].or_value = (value >> 8) & 0xf;
590                 break;
591         }
592         ret = dt9812_rmw_multiple_registers(dev, 3, rmw);
593
594         mutex_unlock(&devpriv->mut);
595
596         return ret;
597 }
598
599 static int dt9812_di_insn_bits(struct comedi_device *dev,
600                                struct comedi_subdevice *s,
601                                struct comedi_insn *insn,
602                                unsigned int *data)
603 {
604         u8 bits = 0;
605         int ret;
606
607         ret = dt9812_digital_in(dev, &bits);
608         if (ret)
609                 return ret;
610
611         data[1] = bits;
612
613         return insn->n;
614 }
615
616 static int dt9812_do_insn_bits(struct comedi_device *dev,
617                                struct comedi_subdevice *s,
618                                struct comedi_insn *insn,
619                                unsigned int *data)
620 {
621         if (comedi_dio_update_state(s, data))
622                 dt9812_digital_out(dev, s->state);
623
624         data[1] = s->state;
625
626         return insn->n;
627 }
628
629 static int dt9812_ai_insn_read(struct comedi_device *dev,
630                                struct comedi_subdevice *s,
631                                struct comedi_insn *insn,
632                                unsigned int *data)
633 {
634         unsigned int chan = CR_CHAN(insn->chanspec);
635         u16 val = 0;
636         int ret;
637         int i;
638
639         for (i = 0; i < insn->n; i++) {
640                 ret = dt9812_analog_in(dev, chan, &val, DT9812_GAIN_1);
641                 if (ret)
642                         return ret;
643                 data[i] = val;
644         }
645
646         return insn->n;
647 }
648
649 static int dt9812_ao_insn_read(struct comedi_device *dev,
650                                struct comedi_subdevice *s,
651                                struct comedi_insn *insn,
652                                unsigned int *data)
653 {
654         struct dt9812_private *devpriv = dev->private;
655         int ret;
656
657         mutex_lock(&devpriv->mut);
658         ret = comedi_readback_insn_read(dev, s, insn, data);
659         mutex_unlock(&devpriv->mut);
660
661         return ret;
662 }
663
664 static int dt9812_ao_insn_write(struct comedi_device *dev,
665                                 struct comedi_subdevice *s,
666                                 struct comedi_insn *insn,
667                                 unsigned int *data)
668 {
669         unsigned int chan = CR_CHAN(insn->chanspec);
670         int i;
671
672         for (i = 0; i < insn->n; i++) {
673                 unsigned int val = data[i];
674                 int ret;
675
676                 ret = dt9812_analog_out(dev, chan, val);
677                 if (ret)
678                         return ret;
679
680                 s->readback[chan] = val;
681         }
682
683         return insn->n;
684 }
685
686 static int dt9812_find_endpoints(struct comedi_device *dev)
687 {
688         struct usb_interface *intf = comedi_to_usb_interface(dev);
689         struct usb_host_interface *host = intf->cur_altsetting;
690         struct dt9812_private *devpriv = dev->private;
691         struct usb_endpoint_descriptor *ep;
692         int i;
693
694         if (host->desc.bNumEndpoints != 5) {
695                 dev_err(dev->class_dev, "Wrong number of endpoints\n");
696                 return -ENODEV;
697         }
698
699         for (i = 0; i < host->desc.bNumEndpoints; ++i) {
700                 int dir = -1;
701
702                 ep = &host->endpoint[i].desc;
703                 switch (i) {
704                 case 0:
705                         /* unused message pipe */
706                         dir = USB_DIR_IN;
707                         break;
708                 case 1:
709                         dir = USB_DIR_OUT;
710                         devpriv->cmd_wr.addr = ep->bEndpointAddress;
711                         devpriv->cmd_wr.size = usb_endpoint_maxp(ep);
712                         break;
713                 case 2:
714                         dir = USB_DIR_IN;
715                         devpriv->cmd_rd.addr = ep->bEndpointAddress;
716                         devpriv->cmd_rd.size = usb_endpoint_maxp(ep);
717                         break;
718                 case 3:
719                         /* unused write stream */
720                         dir = USB_DIR_OUT;
721                         break;
722                 case 4:
723                         /* unused read stream */
724                         dir = USB_DIR_IN;
725                         break;
726                 }
727                 if ((ep->bEndpointAddress & USB_DIR_IN) != dir) {
728                         dev_err(dev->class_dev,
729                                 "Endpoint has wrong direction\n");
730                         return -ENODEV;
731                 }
732         }
733         return 0;
734 }
735
736 static int dt9812_reset_device(struct comedi_device *dev)
737 {
738         struct usb_device *usb = comedi_to_usb_dev(dev);
739         struct dt9812_private *devpriv = dev->private;
740         u32 serial;
741         u16 vendor;
742         u16 product;
743         u8 tmp8;
744         __le16 tmp16;
745         __le32 tmp32;
746         int ret;
747         int i;
748
749         ret = dt9812_read_info(dev, 0, &tmp8, sizeof(tmp8));
750         if (ret) {
751                 /*
752                  * Seems like a configuration reset is necessary if driver is
753                  * reloaded while device is attached
754                  */
755                 usb_reset_configuration(usb);
756                 for (i = 0; i < 10; i++) {
757                         ret = dt9812_read_info(dev, 1, &tmp8, sizeof(tmp8));
758                         if (ret == 0)
759                                 break;
760                 }
761                 if (ret) {
762                         dev_err(dev->class_dev,
763                                 "unable to reset configuration\n");
764                         return ret;
765                 }
766         }
767
768         ret = dt9812_read_info(dev, 1, &tmp16, sizeof(tmp16));
769         if (ret) {
770                 dev_err(dev->class_dev, "failed to read vendor id\n");
771                 return ret;
772         }
773         vendor = le16_to_cpu(tmp16);
774
775         ret = dt9812_read_info(dev, 3, &tmp16, sizeof(tmp16));
776         if (ret) {
777                 dev_err(dev->class_dev, "failed to read product id\n");
778                 return ret;
779         }
780         product = le16_to_cpu(tmp16);
781
782         ret = dt9812_read_info(dev, 5, &tmp16, sizeof(tmp16));
783         if (ret) {
784                 dev_err(dev->class_dev, "failed to read device id\n");
785                 return ret;
786         }
787         devpriv->device = le16_to_cpu(tmp16);
788
789         ret = dt9812_read_info(dev, 7, &tmp32, sizeof(tmp32));
790         if (ret) {
791                 dev_err(dev->class_dev, "failed to read serial number\n");
792                 return ret;
793         }
794         serial = le32_to_cpu(tmp32);
795
796         /* let the user know what node this device is now attached to */
797         dev_info(dev->class_dev, "USB DT9812 (%4.4x.%4.4x.%4.4x) #0x%8.8x\n",
798                  vendor, product, devpriv->device, serial);
799
800         if (devpriv->device != DT9812_DEVID_DT9812_10 &&
801             devpriv->device != DT9812_DEVID_DT9812_2PT5) {
802                 dev_err(dev->class_dev, "Unsupported device!\n");
803                 return -EINVAL;
804         }
805
806         return 0;
807 }
808
809 static int dt9812_auto_attach(struct comedi_device *dev,
810                               unsigned long context)
811 {
812         struct usb_interface *intf = comedi_to_usb_interface(dev);
813         struct dt9812_private *devpriv;
814         struct comedi_subdevice *s;
815         bool is_unipolar;
816         int ret;
817         int i;
818
819         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
820         if (!devpriv)
821                 return -ENOMEM;
822
823         mutex_init(&devpriv->mut);
824         usb_set_intfdata(intf, devpriv);
825
826         ret = dt9812_find_endpoints(dev);
827         if (ret)
828                 return ret;
829
830         ret = dt9812_reset_device(dev);
831         if (ret)
832                 return ret;
833
834         is_unipolar = (devpriv->device == DT9812_DEVID_DT9812_2PT5);
835
836         ret = comedi_alloc_subdevices(dev, 4);
837         if (ret)
838                 return ret;
839
840         /* Digital Input subdevice */
841         s = &dev->subdevices[0];
842         s->type         = COMEDI_SUBD_DI;
843         s->subdev_flags = SDF_READABLE;
844         s->n_chan       = 8;
845         s->maxdata      = 1;
846         s->range_table  = &range_digital;
847         s->insn_bits    = dt9812_di_insn_bits;
848
849         /* Digital Output subdevice */
850         s = &dev->subdevices[1];
851         s->type         = COMEDI_SUBD_DO;
852         s->subdev_flags = SDF_WRITABLE;
853         s->n_chan       = 8;
854         s->maxdata      = 1;
855         s->range_table  = &range_digital;
856         s->insn_bits    = dt9812_do_insn_bits;
857
858         /* Analog Input subdevice */
859         s = &dev->subdevices[2];
860         s->type         = COMEDI_SUBD_AI;
861         s->subdev_flags = SDF_READABLE | SDF_GROUND;
862         s->n_chan       = 8;
863         s->maxdata      = 0x0fff;
864         s->range_table  = is_unipolar ? &range_unipolar2_5 : &range_bipolar10;
865         s->insn_read    = dt9812_ai_insn_read;
866
867         /* Analog Output subdevice */
868         s = &dev->subdevices[3];
869         s->type         = COMEDI_SUBD_AO;
870         s->subdev_flags = SDF_WRITABLE;
871         s->n_chan       = 2;
872         s->maxdata      = 0x0fff;
873         s->range_table  = is_unipolar ? &range_unipolar2_5 : &range_bipolar10;
874         s->insn_write   = dt9812_ao_insn_write;
875         s->insn_read    = dt9812_ao_insn_read;
876
877         ret = comedi_alloc_subdev_readback(s);
878         if (ret)
879                 return ret;
880
881         for (i = 0; i < s->n_chan; i++)
882                 s->readback[i] = is_unipolar ? 0x0000 : 0x0800;
883
884         return 0;
885 }
886
887 static void dt9812_detach(struct comedi_device *dev)
888 {
889         struct usb_interface *intf = comedi_to_usb_interface(dev);
890         struct dt9812_private *devpriv = dev->private;
891
892         if (!devpriv)
893                 return;
894
895         mutex_lock(&devpriv->mut);
896
897         usb_set_intfdata(intf, NULL);
898
899         mutex_unlock(&devpriv->mut);
900 }
901
902 static struct comedi_driver dt9812_driver = {
903         .driver_name    = "dt9812",
904         .module         = THIS_MODULE,
905         .auto_attach    = dt9812_auto_attach,
906         .detach         = dt9812_detach,
907 };
908
909 static int dt9812_usb_probe(struct usb_interface *intf,
910                             const struct usb_device_id *id)
911 {
912         return comedi_usb_auto_config(intf, &dt9812_driver, id->driver_info);
913 }
914
915 static const struct usb_device_id dt9812_usb_table[] = {
916         { USB_DEVICE(0x0867, 0x9812) },
917         { }
918 };
919 MODULE_DEVICE_TABLE(usb, dt9812_usb_table);
920
921 static struct usb_driver dt9812_usb_driver = {
922         .name           = "dt9812",
923         .id_table       = dt9812_usb_table,
924         .probe          = dt9812_usb_probe,
925         .disconnect     = comedi_usb_auto_unconfig,
926 };
927 module_comedi_usb_driver(dt9812_driver, dt9812_usb_driver);
928
929 MODULE_AUTHOR("Anders Blomdell <anders.blomdell@control.lth.se>");
930 MODULE_DESCRIPTION("Comedi DT9812 driver");
931 MODULE_LICENSE("GPL");