]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/dt9812.c
Staging: comedi: dt9812: fix up a lot of coding style issues
[~andy/linux] / drivers / staging / comedi / drivers / dt9812.c
1 /*
2  * comedi/drivers/dt9812.c
3  *   COMEDI driver for DataTranslation DT9812 USB module
4  *
5  * Copyright (C) 2005 Anders Blomdell <anders.blomdell@control.lth.se>
6  *
7  * COMEDI - Linux Control and Measurement Device Interface
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13
14  *  This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  */
24
25 /*
26 Driver: dt9812
27 Description: Data Translation DT9812 USB module
28 Author: anders.blomdell@control.lth.se (Anders Blomdell)
29 Status: in development
30 Devices: [Data Translation] DT9812 (dt9812)
31 Updated: Sun Nov 20 20:18:34 EST 2005
32
33 This driver works, but bulk transfers not implemented. Might be a starting point
34 for someone else. I found out too late that USB has too high latencies (>1 ms)
35 for my needs.
36 */
37
38 /*
39  * Nota Bene:
40  *   1. All writes to command pipe has to be 32 bytes (ISP1181B SHRTP=0 ?)
41  *   2. The DDK source (as of sep 2005) is in error regarding the
42  *      input MUX bits (example code says P4, but firmware schematics
43  *      says P1).
44  */
45
46 #include <linux/kernel.h>
47 #include <linux/errno.h>
48 #include <linux/init.h>
49 #include <linux/slab.h>
50 #include <linux/module.h>
51 #include <linux/kref.h>
52 #include <linux/uaccess.h>
53 #include <linux/usb.h>
54
55 #include "../comedidev.h"
56 #include "dt9812.h"
57
58 #define DT9812_NUM_SLOTS        16
59
60 static DECLARE_MUTEX(dt9812_mutex);
61
62 static struct usb_device_id dt9812_table[] = {
63         {USB_DEVICE(0x0867, 0x9812)},
64         { }                     /* Terminating entry */
65 };
66
67 MODULE_DEVICE_TABLE(usb, dt9812_table);
68
69 typedef struct usb_dt9812 {
70         struct slot_dt9812 *slot;
71         struct usb_device *udev;
72         struct usb_interface *interface;
73         u16 vendor;
74         u16 product;
75         u16 device;
76         u32 serial;
77         struct {
78                 __u8 addr;
79                 size_t size;
80         } message_pipe, command_write, command_read, write_stream, read_stream;
81         struct kref kref;
82         u16 analog_out_shadow[2];
83         u8 digital_out_shadow;
84 } usb_dt9812_t;
85
86 typedef struct comedi_dt9812 {
87         struct slot_dt9812 *slot;
88         u32 serial;
89 } comedi_dt9812_t;
90
91 typedef struct slot_dt9812 {
92         struct semaphore mutex;
93         u32 serial;
94         usb_dt9812_t *usb;
95         comedi_dt9812_t *comedi;
96 } slot_dt9812_t;
97
98 static const comedi_lrange dt9812_10_ain_range = { 1, {
99                         BIP_RANGE(10),
100         }
101 };
102
103 static const comedi_lrange dt9812_2pt5_ain_range = { 1, {
104                         UNI_RANGE(2.5),
105         }
106 };
107
108 static const comedi_lrange dt9812_10_aout_range = { 1, {
109                         BIP_RANGE(10),
110         }
111 };
112
113 static const comedi_lrange dt9812_2pt5_aout_range = { 1, {
114                         UNI_RANGE(2.5),
115         }
116 };
117
118 static slot_dt9812_t dt9812[DT9812_NUM_SLOTS];
119
120 /* Useful shorthand access to private data */
121 #define devpriv ((comedi_dt9812_t *)dev->private)
122
123 static inline usb_dt9812_t *to_dt9812_dev(struct kref *d)
124 {
125         return container_of(d, usb_dt9812_t, kref);
126 }
127
128 static void dt9812_delete(struct kref *kref)
129 {
130         usb_dt9812_t *dev = to_dt9812_dev(kref);
131
132         usb_put_dev(dev->udev);
133         kfree(dev);
134 }
135
136 static int dt9812_read_info(usb_dt9812_t *dev, int offset, void *buf,
137                             size_t buf_size)
138 {
139         dt9812_usb_cmd_t cmd;
140         int count, retval;
141
142         cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
143         cmd.u.flash_data_info.address =
144                 cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
145         cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size);
146
147         /* DT9812 only responds to 32 byte writes!! */
148         count = 32;
149         retval = usb_bulk_msg(dev->udev,
150                               usb_sndbulkpipe(dev->udev,
151                                               dev->command_write.addr),
152                               &cmd, 32, &count, HZ * 1);
153         if (retval)
154                 return retval;
155         retval = usb_bulk_msg(dev->udev,
156                               usb_rcvbulkpipe(dev->udev,
157                                               dev->command_read.addr),
158                               buf, buf_size, &count, HZ * 1);
159         return retval;
160 }
161
162 static int dt9812_read_multiple_registers(usb_dt9812_t *dev, int reg_count,
163                                           u8 *address, u8 *value)
164 {
165         dt9812_usb_cmd_t cmd;
166         int i, count, retval;
167
168         cmd.cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG);
169         cmd.u.read_multi_info.count = reg_count;
170         for (i = 0; i < reg_count; i++)
171                 cmd.u.read_multi_info.address[i] = address[i];
172
173         /* DT9812 only responds to 32 byte writes!! */
174         count = 32;
175         retval = usb_bulk_msg(dev->udev,
176                               usb_sndbulkpipe(dev->udev,
177                                               dev->command_write.addr),
178                               &cmd, 32, &count, HZ * 1);
179         if (retval)
180                 return retval;
181         retval = usb_bulk_msg(dev->udev,
182                               usb_rcvbulkpipe(dev->udev,
183                                               dev->command_read.addr),
184                               value, reg_count, &count, HZ * 1);
185         return retval;
186 }
187
188 static int dt9812_write_multiple_registers(usb_dt9812_t *dev, int reg_count,
189                                            u8 *address, u8 *value)
190 {
191         dt9812_usb_cmd_t cmd;
192         int i, count, retval;
193
194         cmd.cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG);
195         cmd.u.read_multi_info.count = reg_count;
196         for (i = 0; i < reg_count; i++) {
197                 cmd.u.write_multi_info.write[i].address = address[i];
198                 cmd.u.write_multi_info.write[i].value = value[i];
199         }
200         /* DT9812 only responds to 32 byte writes!! */
201         retval = usb_bulk_msg(dev->udev,
202                               usb_sndbulkpipe(dev->udev,
203                                               dev->command_write.addr),
204                               &cmd, 32, &count, HZ * 1);
205         return retval;
206 }
207
208 static int dt9812_rmw_multiple_registers(usb_dt9812_t *dev, int reg_count,
209                                          dt9812_rmw_byte_t rmw[])
210 {
211         dt9812_usb_cmd_t cmd;
212         int i, count, retval;
213
214         cmd.cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG);
215         cmd.u.rmw_multi_info.count = reg_count;
216         for (i = 0; i < reg_count; i++)
217                 cmd.u.rmw_multi_info.rmw[i] = rmw[i];
218
219         /* DT9812 only responds to 32 byte writes!! */
220         retval = usb_bulk_msg(dev->udev,
221                               usb_sndbulkpipe(dev->udev,
222                                               dev->command_write.addr),
223                               &cmd, 32, &count, HZ * 1);
224         return retval;
225 }
226
227 static int dt9812_digital_in(slot_dt9812_t *slot, u8 *bits)
228 {
229         int result = -ENODEV;
230
231         down(&slot->mutex);
232         if (slot->usb) {
233                 u8 reg[2] = { F020_SFR_P3, F020_SFR_P1 };
234                 u8 value[2];
235
236                 result = dt9812_read_multiple_registers(slot->usb, 2, reg,
237                                                         value);
238                 if (result == 0) {
239                         /*
240                          * bits 0-6 in F020_SFR_P3 are bits 0-6 in the digital
241                          * input port bit 3 in F020_SFR_P1 is bit 7 in the
242                          * digital input port
243                          */
244                         *bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4);
245                         /* printk("%2.2x, %2.2x -> %2.2x\n",
246                                   value[0], value[1], *bits); */
247                 }
248         }
249         up(&slot->mutex);
250
251         return result;
252 }
253
254 static int dt9812_digital_out(slot_dt9812_t *slot, u8 bits)
255 {
256         int result = -ENODEV;
257
258         down(&slot->mutex);
259         if (slot->usb) {
260                 u8 reg[1];
261                 u8 value[1];
262
263                 reg[0] = F020_SFR_P2;
264                 value[0] = bits;
265                 result = dt9812_write_multiple_registers(slot->usb, 1, reg,
266                                                          value);
267                 slot->usb->digital_out_shadow = bits;
268         }
269         up(&slot->mutex);
270         return result;
271 }
272
273 static int dt9812_digital_out_shadow(slot_dt9812_t *slot, u8 *bits)
274 {
275         int result = -ENODEV;
276
277         down(&slot->mutex);
278         if (slot->usb) {
279                 *bits = slot->usb->digital_out_shadow;
280                 result = 0;
281         }
282         up(&slot->mutex);
283         return result;
284 }
285
286 static void dt9812_configure_mux(usb_dt9812_t *dev, dt9812_rmw_byte_t *rmw,
287                                  int channel)
288 {
289         if (dev->device == DT9812_DEVID_DT9812_10) {
290                 /* In the DT9812/10V MUX is selected by P1.5-7 */
291                 rmw->address = F020_SFR_P1;
292                 rmw->and_mask = 0xe0;
293                 rmw->or_value = channel << 5;
294         } else {
295                 /* In the DT9812/2.5V, internal mux is selected by bits 0:2 */
296                 rmw->address = F020_SFR_AMX0SL;
297                 rmw->and_mask = 0xff;
298                 rmw->or_value = channel & 0x07;
299         }
300 }
301
302 static void dt9812_configure_gain(usb_dt9812_t *dev, dt9812_rmw_byte_t *rmw,
303                                   dt9812_gain_t gain)
304 {
305         if (dev->device == DT9812_DEVID_DT9812_10) {
306                 /* In the DT9812/10V, there is an external gain of 0.5 */
307                 gain <<= 1;
308         }
309
310         rmw->address = F020_SFR_ADC0CF;
311         rmw->and_mask = F020_MASK_ADC0CF_AMP0GN2 |
312                         F020_MASK_ADC0CF_AMP0GN1 |
313                         F020_MASK_ADC0CF_AMP0GN0;
314         switch (gain) {
315                 /*
316                  * 000 -> Gain =  1
317                  * 001 -> Gain =  2
318                  * 010 -> Gain =  4
319                  * 011 -> Gain =  8
320                  * 10x -> Gain = 16
321                  * 11x -> Gain =  0.5
322                  */
323         case DT9812_GAIN_0PT5:
324                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 ||
325                                 F020_MASK_ADC0CF_AMP0GN1;
326                 break;
327         case DT9812_GAIN_1:
328                 rmw->or_value = 0x00;
329                 break;
330         case DT9812_GAIN_2:
331                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN0;
332                 break;
333         case DT9812_GAIN_4:
334                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN1;
335                 break;
336         case DT9812_GAIN_8:
337                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 ||
338                                 F020_MASK_ADC0CF_AMP0GN0;
339                 break;
340         case DT9812_GAIN_16:
341                 rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
342                 break;
343         default:
344                 err("Illegal gain %d\n", gain);
345
346         }
347 }
348
349 static int dt9812_analog_in(slot_dt9812_t *slot, int channel, u16 *value,
350                             dt9812_gain_t gain)
351 {
352         dt9812_rmw_byte_t rmw[3];
353         u8 reg[3] = {
354                 F020_SFR_ADC0CN,
355                 F020_SFR_ADC0H,
356                 F020_SFR_ADC0L
357         };
358         u8 val[3];
359         int result = -ENODEV;
360
361         down(&slot->mutex);
362         if (!slot->usb)
363                 goto exit;
364
365         /* 1 select the gain */
366         dt9812_configure_gain(slot->usb, &rmw[0], gain);
367
368         /* 2 set the MUX to select the channel */
369         dt9812_configure_mux(slot->usb, &rmw[1], channel);
370
371         /* 3 start conversion */
372         rmw[2].address = F020_SFR_ADC0CN;
373         rmw[2].and_mask = 0xff;
374         rmw[2].or_value = F020_MASK_ADC0CN_AD0EN | F020_MASK_ADC0CN_AD0BUSY;
375
376         result = dt9812_rmw_multiple_registers(slot->usb, 3, rmw);
377         if (result)
378                 goto exit;
379
380         /* read the status and ADC */
381         result = dt9812_read_multiple_registers(slot->usb, 3, reg, val);
382         if (result)
383                 goto exit;
384         /*
385          * An ADC conversion takes 16 SAR clocks cycles, i.e. about 9us.
386          * Therefore, between the instant that AD0BUSY was set via
387          * dt9812_rmw_multiple_registers and the read of AD0BUSY via
388          * dt9812_read_multiple_registers, the conversion should be complete
389          * since these two operations require two USB transactions each taking
390          * at least a millisecond to complete.  However, lets make sure that
391          * conversion is finished.
392          */
393         if ((val[0] & (F020_MASK_ADC0CN_AD0INT | F020_MASK_ADC0CN_AD0BUSY)) ==
394             F020_MASK_ADC0CN_AD0INT) {
395                 switch (slot->usb->device) {
396                 case DT9812_DEVID_DT9812_10:
397                         /*
398                          * For DT9812-10V the personality module set the
399                          * encoding to 2's complement. Hence, convert it before
400                          * returning it
401                          */
402                         *value = ((val[1] << 8) | val[2]) + 0x800;
403                         break;
404                 case DT9812_DEVID_DT9812_2PT5:
405                         *value = (val[1] << 8) | val[2];
406                         break;
407                 }
408         }
409
410 exit:
411         up(&slot->mutex);
412         return result;
413 }
414
415 static int dt9812_analog_out_shadow(slot_dt9812_t *slot, int channel,
416                                     u16 *value)
417 {
418         int result = -ENODEV;
419
420         down(&slot->mutex);
421         if (slot->usb) {
422                 *value = slot->usb->analog_out_shadow[channel];
423                 result = 0;
424         }
425         up(&slot->mutex);
426
427         return result;
428 }
429
430 static int dt9812_analog_out(slot_dt9812_t *slot, int channel, u16 value)
431 {
432         int result = -ENODEV;
433
434         down(&slot->mutex);
435         if (slot->usb) {
436                 dt9812_rmw_byte_t rmw[3];
437
438                 switch (channel) {
439                 case 0:
440                         /* 1. Set DAC mode */
441                         rmw[0].address = F020_SFR_DAC0CN;
442                         rmw[0].and_mask = 0xff;
443                         rmw[0].or_value = F020_MASK_DACxCN_DACxEN;
444
445                         /* 2 load low byte of DAC value first */
446                         rmw[1].address = F020_SFR_DAC0L;
447                         rmw[1].and_mask = 0xff;
448                         rmw[1].or_value = value & 0xff;
449
450                         /* 3 load high byte of DAC value next to latch the
451                            12-bit value */
452                         rmw[2].address = F020_SFR_DAC0H;
453                         rmw[2].and_mask = 0xff;
454                         rmw[2].or_value = (value >> 8) & 0xf;
455                         break;
456
457                 case 1:
458                         /* 1. Set DAC mode */
459                         rmw[0].address = F020_SFR_DAC1CN;
460                         rmw[0].and_mask = 0xff;
461                         rmw[0].or_value = F020_MASK_DACxCN_DACxEN;
462
463                         /* 2 load low byte of DAC value first */
464                         rmw[1].address = F020_SFR_DAC1L;
465                         rmw[1].and_mask = 0xff;
466                         rmw[1].or_value = value & 0xff;
467
468                         /* 3 load high byte of DAC value next to latch the
469                            12-bit value */
470                         rmw[2].address = F020_SFR_DAC1H;
471                         rmw[2].and_mask = 0xff;
472                         rmw[2].or_value = (value >> 8) & 0xf;
473                         break;
474                 }
475                 result = dt9812_rmw_multiple_registers(slot->usb, 3, rmw);
476                 slot->usb->analog_out_shadow[channel] = value;
477         }
478         up(&slot->mutex);
479
480         return result;
481 }
482
483 /*
484  * USB framework functions
485  */
486
487 static int dt9812_probe(struct usb_interface *interface,
488                         const struct usb_device_id *id)
489 {
490         int retval = -ENOMEM;
491         usb_dt9812_t *dev = NULL;
492         struct usb_host_interface *iface_desc;
493         struct usb_endpoint_descriptor *endpoint;
494         int i;
495         u8 fw;
496
497         /* allocate memory for our device state and initialize it */
498         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
499         if (dev == NULL) {
500                 dev_err(&interface->dev, "Out of memory\n");
501                 goto error;
502         }
503         kref_init(&dev->kref);
504
505         dev->udev = usb_get_dev(interface_to_usbdev(interface));
506         dev->interface = interface;
507
508         /* Check endpoints */
509         iface_desc = interface->cur_altsetting;
510
511         if (iface_desc->desc.bNumEndpoints != 5) {
512                 err("Wrong number of endpints.");
513                 retval = -ENODEV;
514                 goto error;
515         }
516
517         for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
518                 int direction = -1;
519                 endpoint = &iface_desc->endpoint[i].desc;
520                 switch (i) {
521                 case 0:
522                         direction = USB_DIR_IN;
523                         dev->message_pipe.addr = endpoint->bEndpointAddress;
524                         dev->message_pipe.size =
525                                         le16_to_cpu(endpoint->wMaxPacketSize);
526
527                         break;
528                 case 1:
529                         direction = USB_DIR_OUT;
530                         dev->command_write.addr = endpoint->bEndpointAddress;
531                         dev->command_write.size =
532                                         le16_to_cpu(endpoint->wMaxPacketSize);
533                         break;
534                 case 2:
535                         direction = USB_DIR_IN;
536                         dev->command_read.addr = endpoint->bEndpointAddress;
537                         dev->command_read.size =
538                                         le16_to_cpu(endpoint->wMaxPacketSize);
539                         break;
540                 case 3:
541                         direction = USB_DIR_OUT;
542                         dev->write_stream.addr = endpoint->bEndpointAddress;
543                         dev->write_stream.size =
544                                         le16_to_cpu(endpoint->wMaxPacketSize);
545                         break;
546                 case 4:
547                         direction = USB_DIR_IN;
548                         dev->read_stream.addr = endpoint->bEndpointAddress;
549                         dev->read_stream.size =
550                                         le16_to_cpu(endpoint->wMaxPacketSize);
551                         break;
552                 }
553                 if ((endpoint->bEndpointAddress & USB_DIR_IN) != direction) {
554                         dev_err(&interface->dev,
555                                 "Endpoint has wrong direction.\n");
556                         retval = -ENODEV;
557                         goto error;
558                 }
559         }
560         if (dt9812_read_info(dev, 0, &fw, sizeof(fw)) != 0) {
561                 /*
562                  * Seems like a configuration reset is necessary if driver is
563                  * reloaded while device is attached
564                  */
565                 int i;
566
567                 usb_reset_configuration(dev->udev);
568                 for (i = 0; i < 10; i++) {
569                         retval = dt9812_read_info(dev, 1, &fw, sizeof(fw));
570                         if (retval == 0) {
571                                 dev_info(&interface->dev,
572                                          "usb_reset_configuration succeded "
573                                          "after %d iterations\n", i);
574                                 break;
575                         }
576                 }
577         }
578
579         if (dt9812_read_info(dev, 1, &dev->vendor, sizeof(dev->vendor)) != 0) {
580                 err("Failed to read vendor.");
581                 retval = -ENODEV;
582                 goto error;
583         }
584         if (dt9812_read_info(dev, 3, &dev->product,
585                              sizeof(dev->product)) != 0) {
586                 err("Failed to read product.");
587                 retval = -ENODEV;
588                 goto error;
589         }
590         if (dt9812_read_info(dev, 5, &dev->device, sizeof(dev->device)) != 0) {
591                 err("Failed to read device.");
592                 retval = -ENODEV;
593                 goto error;
594         }
595         if (dt9812_read_info(dev, 7, &dev->serial, sizeof(dev->serial)) != 0) {
596                 err("Failed to read serial.");
597                 retval = -ENODEV;
598                 goto error;
599         }
600
601         dev->vendor = le16_to_cpu(dev->vendor);
602         dev->product = le16_to_cpu(dev->product);
603         dev->device = le16_to_cpu(dev->device);
604         dev->serial = le32_to_cpu(dev->serial);
605         switch (dev->device) {
606         case DT9812_DEVID_DT9812_10:
607                 dev->analog_out_shadow[0] = 0x0800;
608                 dev->analog_out_shadow[1] = 0x800;
609                 break;
610         case DT9812_DEVID_DT9812_2PT5:
611                 dev->analog_out_shadow[0] = 0x0000;
612                 dev->analog_out_shadow[1] = 0x0000;
613                 break;
614         }
615         dev->digital_out_shadow = 0;
616
617         /* save our data pointer in this interface device */
618         usb_set_intfdata(interface, dev);
619
620         /* let the user know what node this device is now attached to */
621         dev_info(&interface->dev, "USB DT9812 (%4.4x.%4.4x.%4.4x) #0x%8.8x\n",
622                  dev->vendor, dev->product, dev->device, dev->serial);
623
624         down(&dt9812_mutex);
625         {
626                 /* Find a slot for the USB device */
627                 slot_dt9812_t *first = NULL;
628                 slot_dt9812_t *best = NULL;
629
630                 for (i = 0; i < DT9812_NUM_SLOTS; i++) {
631                         if (!first && !dt9812[i].usb && dt9812[i].serial == 0)
632                                 first = &dt9812[i];
633                         if (!best && dt9812[i].serial == dev->serial)
634                                 best = &dt9812[i];
635                 }
636
637                 if (!best)
638                         best = first;
639
640                 if (best) {
641                         down(&best->mutex);
642                         best->usb = dev;
643                         dev->slot = best;
644                         up(&best->mutex);
645                 }
646         }
647         up(&dt9812_mutex);
648
649         return 0;
650
651 error:
652         if (dev)
653                 kref_put(&dev->kref, dt9812_delete);
654         return retval;
655 }
656
657 static void dt9812_disconnect(struct usb_interface *interface)
658 {
659         usb_dt9812_t *dev;
660         int minor = interface->minor;
661
662         down(&dt9812_mutex);
663         dev = usb_get_intfdata(interface);
664         if (dev->slot) {
665                 down(&dev->slot->mutex);
666                 dev->slot->usb = NULL;
667                 up(&dev->slot->mutex);
668                 dev->slot = NULL;
669         }
670         usb_set_intfdata(interface, NULL);
671         up(&dt9812_mutex);
672
673         /* queue final destruction */
674         kref_put(&dev->kref, dt9812_delete);
675
676         dev_info(&interface->dev, "USB Dt9812 #%d now disconnected\n", minor);
677 }
678
679 static struct usb_driver dt9812_usb_driver = {
680 #ifdef COMEDI_HAVE_USB_DRIVER_OWNER
681         .owner = THIS_MODULE,
682 #endif
683         .name = "dt9812",
684         .probe = dt9812_probe,
685         .disconnect = dt9812_disconnect,
686         .id_table = dt9812_table,
687 };
688
689 /*
690  * Comedi functions
691  */
692
693 static void dt9812_comedi_open(comedi_device *dev)
694 {
695         down(&devpriv->slot->mutex);
696         if (devpriv->slot->usb) {
697                 /* We have an attached device, fill in current range info */
698                 comedi_subdevice *s;
699
700                 s = &dev->subdevices[0];
701                 s->n_chan = 8;
702                 s->maxdata = 1;
703
704                 s = &dev->subdevices[1];
705                 s->n_chan = 8;
706                 s->maxdata = 1;
707
708                 s = &dev->subdevices[2];
709                 s->n_chan = 8;
710                 switch (devpriv->slot->usb->device) {
711                 case 0:{
712                                 s->maxdata = 4095;
713                                 s->range_table = &dt9812_10_ain_range;
714                         }
715                         break;
716                 case 1:{
717                                 s->maxdata = 4095;
718                                 s->range_table = &dt9812_2pt5_ain_range;
719                         }
720                         break;
721                 }
722
723                 s = &dev->subdevices[3];
724                 s->n_chan = 2;
725                 switch (devpriv->slot->usb->device) {
726                 case 0:{
727                                 s->maxdata = 4095;
728                                 s->range_table = &dt9812_10_aout_range;
729                         }
730                         break;
731                 case 1:{
732                                 s->maxdata = 4095;
733                                 s->range_table = &dt9812_2pt5_aout_range;
734                         }
735                         break;
736                 }
737         }
738         up(&devpriv->slot->mutex);
739 }
740
741 static int dt9812_di_rinsn(comedi_device *dev, comedi_subdevice *s,
742                            comedi_insn *insn, lsampl_t *data)
743 {
744         int n;
745         u8 bits = 0;
746
747         dt9812_digital_in(devpriv->slot, &bits);
748         for (n = 0; n < insn->n; n++)
749                 data[n] = ((1 << insn->chanspec) & bits) != 0;
750         return n;
751 }
752
753 static int dt9812_do_winsn(comedi_device *dev, comedi_subdevice *s,
754                            comedi_insn *insn, lsampl_t *data)
755 {
756         int n;
757         u8 bits = 0;
758
759         dt9812_digital_out_shadow(devpriv->slot, &bits);
760         for (n = 0; n < insn->n; n++) {
761                 u8 mask = 1 << insn->chanspec;
762
763                 bits &= ~mask;
764                 if (data[n])
765                         bits |= mask;
766         }
767         dt9812_digital_out(devpriv->slot, bits);
768         return n;
769 }
770
771 static int dt9812_ai_rinsn(comedi_device *dev, comedi_subdevice *s,
772                            comedi_insn *insn, lsampl_t *data)
773 {
774         int n;
775
776         for (n = 0; n < insn->n; n++) {
777                 u16 value = 0;
778
779                 dt9812_analog_in(devpriv->slot, insn->chanspec, &value,
780                                  DT9812_GAIN_1);
781                 data[n] = value;
782         }
783         return n;
784 }
785
786 static int dt9812_ao_rinsn(comedi_device *dev, comedi_subdevice *s,
787                            comedi_insn *insn, lsampl_t *data)
788 {
789         int n;
790         u16 value;
791
792         for (n = 0; n < insn->n; n++) {
793                 value = 0;
794                 dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value);
795                 data[n] = value;
796         }
797         return n;
798 }
799
800 static int dt9812_ao_winsn(comedi_device *dev, comedi_subdevice *s,
801                            comedi_insn *insn, lsampl_t *data)
802 {
803         int n;
804
805         for (n = 0; n < insn->n; n++)
806                 dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]);
807         return n;
808 }
809
810 static int dt9812_attach(comedi_device *dev, comedi_devconfig *it)
811 {
812         int i;
813         comedi_subdevice *s;
814
815         dev->board_name = "dt9812";
816
817         if (alloc_private(dev, sizeof(comedi_dt9812_t)) < 0)
818                 return -ENOMEM;
819
820         /*
821          * Special open routine, since USB unit may be unattached at
822          * comedi_config time, hence range can not be determined
823          */
824         dev->open = dt9812_comedi_open;
825
826         devpriv->serial = it->options[0];
827
828         /* Allocate subdevices */
829         if (alloc_subdevices(dev, 4) < 0)
830                 return -ENOMEM;
831
832         /* digital input subdevice */
833         s = dev->subdevices + 0;
834         s->type = COMEDI_SUBD_DI;
835         s->subdev_flags = SDF_READABLE;
836         s->n_chan = 0;
837         s->maxdata = 1;
838         s->range_table = &range_digital;
839         s->insn_read = &dt9812_di_rinsn;
840
841         /* digital output subdevice */
842         s = dev->subdevices + 1;
843         s->type = COMEDI_SUBD_DO;
844         s->subdev_flags = SDF_WRITEABLE;
845         s->n_chan = 0;
846         s->maxdata = 1;
847         s->range_table = &range_digital;
848         s->insn_write = &dt9812_do_winsn;
849
850         /* analog input subdevice */
851         s = dev->subdevices + 2;
852         s->type = COMEDI_SUBD_AI;
853         s->subdev_flags = SDF_READABLE | SDF_GROUND;
854         s->n_chan = 0;
855         s->maxdata = 1;
856         s->range_table = 0;
857         s->insn_read = &dt9812_ai_rinsn;
858
859         /* analog output subdevice */
860         s = dev->subdevices + 3;
861         s->type = COMEDI_SUBD_AO;
862         s->subdev_flags = SDF_WRITEABLE;
863         s->n_chan = 0;
864         s->maxdata = 1;
865         s->range_table = 0;
866         s->insn_write = &dt9812_ao_winsn;
867         s->insn_read = &dt9812_ao_rinsn;
868
869         printk(KERN_INFO "comedi%d: successfully attached to dt9812.\n",
870                dev->minor);
871
872         down(&dt9812_mutex);
873         /* Find a slot for the comedi device */
874         {
875                 slot_dt9812_t *first = NULL;
876                 slot_dt9812_t *best = NULL;
877                 for (i = 0; i < DT9812_NUM_SLOTS; i++) {
878                         if (!first && !dt9812[i].comedi) {
879                                 /* First free slot from comedi side */
880                                 first = &dt9812[i];
881                         }
882                         if (!best &&
883                             dt9812[i].usb &&
884                             dt9812[i].usb->serial == devpriv->serial) {
885                                 /* We have an attaced device with matching ID */
886                                 best = &dt9812[i];
887                         }
888                 }
889                 if (!best)
890                         best = first;
891                 if (best) {
892                         down(&best->mutex);
893                         best->comedi = devpriv;
894                         best->serial = devpriv->serial;
895                         devpriv->slot = best;
896                         up(&best->mutex);
897                 }
898         }
899         up(&dt9812_mutex);
900
901         return 0;
902 }
903
904 static int dt9812_detach(comedi_device *dev)
905 {
906         return 0;
907 }
908
909 static comedi_driver dt9812_comedi_driver = {
910         .module = THIS_MODULE,
911         .driver_name = "dt9812",
912         .attach = dt9812_attach,
913         .detach = dt9812_detach,
914 };
915
916 static int __init usb_dt9812_init(void)
917 {
918         int result, i;
919
920         /* Initialize all driver slots */
921         for (i = 0; i < DT9812_NUM_SLOTS; i++) {
922                 init_MUTEX(&dt9812[i].mutex);
923                 dt9812[i].serial = 0;
924                 dt9812[i].usb = NULL;
925                 dt9812[i].comedi = NULL;
926         }
927         dt9812[12].serial = 0x0;
928
929         /* register with the USB subsystem */
930         result = usb_register(&dt9812_usb_driver);
931         if (result) {
932                 printk(KERN_ERR KBUILD_MODNAME
933                        ": usb_register failed. Error number %d\n", result);
934                 return result;
935         }
936         /* register with comedi */
937         result = comedi_driver_register(&dt9812_comedi_driver);
938         if (result) {
939                 usb_deregister(&dt9812_usb_driver);
940                 err("comedi_driver_register failed. Error number %d", result);
941         }
942
943         return result;
944 }
945
946 static void __exit usb_dt9812_exit(void)
947 {
948         /* unregister with comedi */
949         comedi_driver_unregister(&dt9812_comedi_driver);
950
951         /* deregister this driver with the USB subsystem */
952         usb_deregister(&dt9812_usb_driver);
953 }
954
955 module_init(usb_dt9812_init);
956 module_exit(usb_dt9812_exit);
957
958 MODULE_AUTHOR("Anders Blomdell <anders.blomdell@control.lth.se>");
959 MODULE_DESCRIPTION("Comedi DT9812 driver");
960 MODULE_LICENSE("GPL");