ide: fix ioctl to pass requested transfer mode to ide_find_dma_mode instead of UDMA6
[cascardo/linux.git] / drivers / staging / comedi / drivers / me_daq.c
1 /*
2
3    comedi/drivers/me_daq.c
4
5    Hardware driver for Meilhaus data acquisition cards:
6
7      ME-2000i, ME-2600i, ME-3000vm1
8
9    Copyright (C) 2002 Michael Hillmann <hillmann@syscongroup.de>
10
11     This program is free software; you can redistribute it and/or modify
12     it under the terms of the GNU General Public License as published by
13     the Free Software Foundation; either version 2 of the License, or
14     (at your option) any later version.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     You should have received a copy of the GNU General Public License
22     along with this program; if not, write to the Free Software
23     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 /*
27 Driver: me_daq
28 Description: Meilhaus PCI data acquisition cards
29 Author: Michael Hillmann <hillmann@syscongroup.de>
30 Devices: [Meilhaus] ME-2600i (me_daq), ME-2000i
31 Status: experimental
32
33 Supports:
34
35     Analog Output
36
37 Configuration options:
38
39     [0] - PCI bus number (optional)
40     [1] - PCI slot number (optional)
41
42     If bus/slot is not specified, the first available PCI
43     device will be used.
44
45 The 2600 requires a firmware upload, which can be accomplished
46 using the -i or --init-data option of comedi_config.
47 The firmware can be
48 found in the comedi_nonfree_firmware tarball available
49 from http://www.comedi.org
50
51 */
52
53 #include <linux/interrupt.h>
54 #include "../comedidev.h"
55
56 #include "comedi_pci.h"
57
58 /*#include "me2600_fw.h" */
59
60 #define ME_DRIVER_NAME          "me_daq"
61
62 #define ME2000_DEVICE_ID        0x2000
63 #define ME2600_DEVICE_ID        0x2600
64
65 #define PLX_INTCSR              0x4C    /* PLX interrupt status register */
66 #define XILINX_DOWNLOAD_RESET   0x42    /* Xilinx registers */
67
68 #define ME_CONTROL_1                    0x0000  /* - | W */
69 #define   INTERRUPT_ENABLE              (1<<15)
70 #define   COUNTER_B_IRQ                 (1<<12)
71 #define   COUNTER_A_IRQ                 (1<<11)
72 #define   CHANLIST_READY_IRQ            (1<<10)
73 #define   EXT_IRQ                       (1<<9)
74 #define   ADFIFO_HALFFULL_IRQ           (1<<8)
75 #define   SCAN_COUNT_ENABLE             (1<<5)
76 #define   SIMULTANEOUS_ENABLE           (1<<4)
77 #define   TRIGGER_FALLING_EDGE          (1<<3)
78 #define   CONTINUOUS_MODE               (1<<2)
79 #define   DISABLE_ADC                   (0<<0)
80 #define   SOFTWARE_TRIGGERED_ADC        (1<<0)
81 #define   SCAN_TRIGGERED_ADC            (2<<0)
82 #define   EXT_TRIGGERED_ADC             (3<<0)
83 #define ME_ADC_START                    0x0000  /* R | - */
84 #define ME_CONTROL_2                    0x0002  /* - | W */
85 #define   ENABLE_ADFIFO                 (1<<10)
86 #define   ENABLE_CHANLIST               (1<<9)
87 #define   ENABLE_PORT_B                 (1<<7)
88 #define   ENABLE_PORT_A                 (1<<6)
89 #define   ENABLE_COUNTER_B              (1<<4)
90 #define   ENABLE_COUNTER_A              (1<<3)
91 #define   ENABLE_DAC                    (1<<1)
92 #define   BUFFERED_DAC                  (1<<0)
93 #define ME_DAC_UPDATE                   0x0002  /* R | - */
94 #define ME_STATUS                       0x0004  /* R | - */
95 #define   COUNTER_B_IRQ_PENDING         (1<<12)
96 #define   COUNTER_A_IRQ_PENDING         (1<<11)
97 #define   CHANLIST_READY_IRQ_PENDING    (1<<10)
98 #define   EXT_IRQ_PENDING               (1<<9)
99 #define   ADFIFO_HALFFULL_IRQ_PENDING   (1<<8)
100 #define   ADFIFO_FULL                   (1<<4)
101 #define   ADFIFO_HALFFULL               (1<<3)
102 #define   ADFIFO_EMPTY                  (1<<2)
103 #define   CHANLIST_FULL                 (1<<1)
104 #define   FST_ACTIVE                    (1<<0)
105 #define ME_RESET_INTERRUPT              0x0004  /* - | W */
106 #define ME_DIO_PORT_A                   0x0006  /* R | W */
107 #define ME_DIO_PORT_B                   0x0008  /* R | W */
108 #define ME_TIMER_DATA_0                 0x000A  /* - | W */
109 #define ME_TIMER_DATA_1                 0x000C  /* - | W */
110 #define ME_TIMER_DATA_2                 0x000E  /* - | W */
111 #define ME_CHANNEL_LIST                 0x0010  /* - | W */
112 #define   ADC_UNIPOLAR                  (1<<6)
113 #define   ADC_GAIN_0                    (0<<4)
114 #define   ADC_GAIN_1                    (1<<4)
115 #define   ADC_GAIN_2                    (2<<4)
116 #define   ADC_GAIN_3                    (3<<4)
117 #define ME_READ_AD_FIFO                 0x0010  /* R | - */
118 #define ME_DAC_CONTROL                  0x0012  /* - | W */
119 #define   DAC_UNIPOLAR_D                (0<<4)
120 #define   DAC_BIPOLAR_D                 (1<<4)
121 #define   DAC_UNIPOLAR_C                (0<<5)
122 #define   DAC_BIPOLAR_C                 (1<<5)
123 #define   DAC_UNIPOLAR_B                (0<<6)
124 #define   DAC_BIPOLAR_B                 (1<<6)
125 #define   DAC_UNIPOLAR_A                (0<<7)
126 #define   DAC_BIPOLAR_A                 (1<<7)
127 #define   DAC_GAIN_0_D                  (0<<8)
128 #define   DAC_GAIN_1_D                  (1<<8)
129 #define   DAC_GAIN_0_C                  (0<<9)
130 #define   DAC_GAIN_1_C                  (1<<9)
131 #define   DAC_GAIN_0_B                  (0<<10)
132 #define   DAC_GAIN_1_B                  (1<<10)
133 #define   DAC_GAIN_0_A                  (0<<11)
134 #define   DAC_GAIN_1_A                  (1<<11)
135 #define ME_DAC_CONTROL_UPDATE           0x0012  /* R | - */
136 #define ME_DAC_DATA_A                   0x0014  /* - | W */
137 #define ME_DAC_DATA_B                   0x0016  /* - | W */
138 #define ME_DAC_DATA_C                   0x0018  /* - | W */
139 #define ME_DAC_DATA_D                   0x001A  /* - | W */
140 #define ME_COUNTER_ENDDATA_A            0x001C  /* - | W */
141 #define ME_COUNTER_ENDDATA_B            0x001E  /* - | W */
142 #define ME_COUNTER_STARTDATA_A          0x0020  /* - | W */
143 #define ME_COUNTER_VALUE_A              0x0020  /* R | - */
144 #define ME_COUNTER_STARTDATA_B          0x0022  /* - | W */
145 #define ME_COUNTER_VALUE_B              0x0022  /* R | - */
146
147 /* Function prototypes */
148 static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it);
149 static int me_detach(struct comedi_device *dev);
150
151 static const struct comedi_lrange me2000_ai_range = {
152         8,
153         {
154          BIP_RANGE(10),
155          BIP_RANGE(5),
156          BIP_RANGE(2.5),
157          BIP_RANGE(1.25),
158          UNI_RANGE(10),
159          UNI_RANGE(5),
160          UNI_RANGE(2.5),
161          UNI_RANGE(1.25)
162          }
163 };
164
165 static const struct comedi_lrange me2600_ai_range = {
166         8,
167         {
168          BIP_RANGE(10),
169          BIP_RANGE(5),
170          BIP_RANGE(2.5),
171          BIP_RANGE(1.25),
172          UNI_RANGE(10),
173          UNI_RANGE(5),
174          UNI_RANGE(2.5),
175          UNI_RANGE(1.25)
176          }
177 };
178
179 static const struct comedi_lrange me2600_ao_range = {
180         3,
181         {
182          BIP_RANGE(10),
183          BIP_RANGE(5),
184          UNI_RANGE(10)
185          }
186 };
187
188 static DEFINE_PCI_DEVICE_TABLE(me_pci_table) = {
189         {
190         PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID, PCI_ANY_ID,
191                     PCI_ANY_ID, 0, 0, 0}, {
192         PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID, PCI_ANY_ID,
193                     PCI_ANY_ID, 0, 0, 0}, {
194         0}
195 };
196
197 MODULE_DEVICE_TABLE(pci, me_pci_table);
198
199 /* Board specification structure */
200 struct me_board {
201         const char *name;       /* driver name */
202         int device_id;
203         int ao_channel_nbr;     /* DA config */
204         int ao_resolution;
205         int ao_resolution_mask;
206         const struct comedi_lrange *ao_range_list;
207         int ai_channel_nbr;     /* AD config */
208         int ai_resolution;
209         int ai_resolution_mask;
210         const struct comedi_lrange *ai_range_list;
211         int dio_channel_nbr;    /* DIO config */
212 };
213
214 static const struct me_board me_boards[] = {
215         {
216          /* -- ME-2600i -- */
217          .name = ME_DRIVER_NAME,
218          .device_id = ME2600_DEVICE_ID,
219          /* Analog Output */
220          .ao_channel_nbr = 4,
221          .ao_resolution = 12,
222          .ao_resolution_mask = 0x0fff,
223          .ao_range_list = &me2600_ao_range,
224          .ai_channel_nbr = 16,
225          /* Analog Input */
226          .ai_resolution = 12,
227          .ai_resolution_mask = 0x0fff,
228          .ai_range_list = &me2600_ai_range,
229          .dio_channel_nbr = 32,
230          },
231         {
232          /* -- ME-2000i -- */
233          .name = ME_DRIVER_NAME,
234          .device_id = ME2000_DEVICE_ID,
235          /* Analog Output */
236          .ao_channel_nbr = 0,
237          .ao_resolution = 0,
238          .ao_resolution_mask = 0,
239          .ao_range_list = NULL,
240          .ai_channel_nbr = 16,
241          /* Analog Input */
242          .ai_resolution = 12,
243          .ai_resolution_mask = 0x0fff,
244          .ai_range_list = &me2000_ai_range,
245          .dio_channel_nbr = 32,
246          }
247 };
248
249 #define me_board_nbr (sizeof(me_boards)/sizeof(struct me_board))
250
251 static struct comedi_driver me_driver = {
252         .driver_name = ME_DRIVER_NAME,
253         .module = THIS_MODULE,
254         .attach = me_attach,
255         .detach = me_detach,
256 };
257
258 COMEDI_PCI_INITCLEANUP(me_driver, me_pci_table);
259
260 /* Private data structure */
261 struct me_private_data {
262         struct pci_dev *pci_device;
263         void __iomem *plx_regbase;      /* PLX configuration base address */
264         void __iomem *me_regbase;       /* Base address of the Meilhaus card */
265         unsigned long plx_regbase_size; /* Size of PLX configuration space */
266         unsigned long me_regbase_size;  /* Size of Meilhaus space */
267
268         unsigned short control_1;       /* Mirror of CONTROL_1 register */
269         unsigned short control_2;       /* Mirror of CONTROL_2 register */
270         unsigned short dac_control;     /* Mirror of the DAC_CONTROL register */
271         int ao_readback[4];     /* Mirror of analog output data */
272 };
273
274 #define dev_private ((struct me_private_data *)dev->private)
275
276 /*
277  * ------------------------------------------------------------------
278  *
279  * Helpful functions
280  *
281  * ------------------------------------------------------------------
282  */
283 static inline void sleep(unsigned sec)
284 {
285         current->state = TASK_INTERRUPTIBLE;
286         schedule_timeout(sec * HZ);
287 }
288
289 /*
290  * ------------------------------------------------------------------
291  *
292  * DIGITAL INPUT/OUTPUT SECTION
293  *
294  * ------------------------------------------------------------------
295  */
296 static int me_dio_insn_config(struct comedi_device *dev,
297                               struct comedi_subdevice *s,
298                               struct comedi_insn *insn, unsigned int *data)
299 {
300         int bits;
301         int mask = 1 << CR_CHAN(insn->chanspec);
302
303         /* calculate port */
304         if (mask & 0x0000ffff) {        /* Port A in use */
305                 bits = 0x0000ffff;
306
307                 /* Enable Port A */
308                 dev_private->control_2 |= ENABLE_PORT_A;
309                 writew(dev_private->control_2,
310                        dev_private->me_regbase + ME_CONTROL_2);
311         } else {                /* Port B in use */
312
313                 bits = 0xffff0000;
314
315                 /* Enable Port B */
316                 dev_private->control_2 |= ENABLE_PORT_B;
317                 writew(dev_private->control_2,
318                        dev_private->me_regbase + ME_CONTROL_2);
319         }
320
321         if (data[0]) {
322                 /* Config port as output */
323                 s->io_bits |= bits;
324         } else {
325                 /* Config port as input */
326                 s->io_bits &= ~bits;
327         }
328
329         return 1;
330 }
331
332 /* Digital instant input/outputs */
333 static int me_dio_insn_bits(struct comedi_device *dev,
334                             struct comedi_subdevice *s,
335                             struct comedi_insn *insn, unsigned int *data)
336 {
337         unsigned int mask = data[0];
338         s->state &= ~mask;
339         s->state |= (mask & data[1]);
340
341         mask &= s->io_bits;
342         if (mask & 0x0000ffff) {        /* Port A */
343                 writew((s->state & 0xffff),
344                        dev_private->me_regbase + ME_DIO_PORT_A);
345         } else {
346                 data[1] &= ~0x0000ffff;
347                 data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_A);
348         }
349
350         if (mask & 0xffff0000) {        /* Port B */
351                 writew(((s->state >> 16) & 0xffff),
352                        dev_private->me_regbase + ME_DIO_PORT_B);
353         } else {
354                 data[1] &= ~0xffff0000;
355                 data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_B) << 16;
356         }
357
358         return 2;
359 }
360
361 /*
362  * ------------------------------------------------------------------
363  *
364  * ANALOG INPUT SECTION
365  *
366  * ------------------------------------------------------------------
367  */
368
369 /* Analog instant input */
370 static int me_ai_insn_read(struct comedi_device *dev,
371                            struct comedi_subdevice *subdevice,
372                            struct comedi_insn *insn, unsigned int *data)
373 {
374         unsigned short value;
375         int chan = CR_CHAN((&insn->chanspec)[0]);
376         int rang = CR_RANGE((&insn->chanspec)[0]);
377         int aref = CR_AREF((&insn->chanspec)[0]);
378         int i;
379
380         /* stop any running conversion */
381         dev_private->control_1 &= 0xFFFC;
382         writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
383
384         /* clear chanlist and ad fifo */
385         dev_private->control_2 &= ~(ENABLE_ADFIFO | ENABLE_CHANLIST);
386         writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
387
388         /* reset any pending interrupt */
389         writew(0x00, dev_private->me_regbase + ME_RESET_INTERRUPT);
390
391         /* enable the chanlist and ADC fifo */
392         dev_private->control_2 |= (ENABLE_ADFIFO | ENABLE_CHANLIST);
393         writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
394
395         /* write to channel list fifo */
396         /* b3:b0 are the channel number */
397         value = chan & 0x0f;
398         /* b5:b4 are the channel gain */
399         value |= (rang & 0x03) << 4;
400         /* b6 channel polarity */
401         value |= (rang & 0x04) << 4;
402         /* b7 single or differential */
403         value |= ((aref & AREF_DIFF) ? 0x80 : 0);
404         writew(value & 0xff, dev_private->me_regbase + ME_CHANNEL_LIST);
405
406         /* set ADC mode to software trigger */
407         dev_private->control_1 |= SOFTWARE_TRIGGERED_ADC;
408         writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
409
410         /* start conversion by reading from ADC_START */
411         readw(dev_private->me_regbase + ME_ADC_START);
412
413         /* wait for ADC fifo not empty flag */
414         for (i = 100000; i > 0; i--)
415                 if (!(readw(dev_private->me_regbase + ME_STATUS) & 0x0004))
416                         break;
417
418         /* get value from ADC fifo */
419         if (i) {
420                 data[0] =
421                     (readw(dev_private->me_regbase +
422                            ME_READ_AD_FIFO) ^ 0x800) & 0x0FFF;
423         } else {
424                 printk(KERN_ERR "comedi%d: Cannot get single value\n",
425                        dev->minor);
426                 return -EIO;
427         }
428
429         /* stop any running conversion */
430         dev_private->control_1 &= 0xFFFC;
431         writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
432
433         return 1;
434 }
435
436 /*
437  * ------------------------------------------------------------------
438  *
439  * HARDWARE TRIGGERED ANALOG INPUT SECTION
440  *
441  * ------------------------------------------------------------------
442  */
443
444 /* Cancel analog input autoscan */
445 static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
446 {
447         /* disable interrupts */
448
449         /* stop any running conversion */
450         dev_private->control_1 &= 0xFFFC;
451         writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
452
453         return 0;
454 }
455
456 /* Test analog input command */
457 static int me_ai_do_cmd_test(struct comedi_device *dev,
458                              struct comedi_subdevice *s, struct comedi_cmd *cmd)
459 {
460         return 0;
461 }
462
463 /* Analog input command */
464 static int me_ai_do_cmd(struct comedi_device *dev,
465                         struct comedi_subdevice *subdevice)
466 {
467         return 0;
468 }
469
470 /*
471  * ------------------------------------------------------------------
472  *
473  * ANALOG OUTPUT SECTION
474  *
475  * ------------------------------------------------------------------
476  */
477
478 /* Analog instant output */
479 static int me_ao_insn_write(struct comedi_device *dev,
480                             struct comedi_subdevice *s,
481                             struct comedi_insn *insn, unsigned int *data)
482 {
483         int chan;
484         int rang;
485         int i;
486
487         /* Enable all DAC */
488         dev_private->control_2 |= ENABLE_DAC;
489         writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
490
491         /* and set DAC to "buffered" mode */
492         dev_private->control_2 |= BUFFERED_DAC;
493         writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
494
495         /* Set dac-control register */
496         for (i = 0; i < insn->n; i++) {
497                 chan = CR_CHAN((&insn->chanspec)[i]);
498                 rang = CR_RANGE((&insn->chanspec)[i]);
499
500                 /* clear bits for this channel */
501                 dev_private->dac_control &= ~(0x0880 >> chan);
502                 if (rang == 0)
503                         dev_private->dac_control |=
504                             ((DAC_BIPOLAR_A | DAC_GAIN_1_A) >> chan);
505                 else if (rang == 1)
506                         dev_private->dac_control |=
507                             ((DAC_BIPOLAR_A | DAC_GAIN_0_A) >> chan);
508         }
509         writew(dev_private->dac_control,
510                dev_private->me_regbase + ME_DAC_CONTROL);
511
512         /* Update dac-control register */
513         readw(dev_private->me_regbase + ME_DAC_CONTROL_UPDATE);
514
515         /* Set data register */
516         for (i = 0; i < insn->n; i++) {
517                 chan = CR_CHAN((&insn->chanspec)[i]);
518                 writew((data[0] & s->maxdata),
519                        dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1));
520                 dev_private->ao_readback[chan] = (data[0] & s->maxdata);
521         }
522
523         /* Update dac with data registers */
524         readw(dev_private->me_regbase + ME_DAC_UPDATE);
525
526         return i;
527 }
528
529 /* Analog output readback */
530 static int me_ao_insn_read(struct comedi_device *dev,
531                            struct comedi_subdevice *s, struct comedi_insn *insn,
532                            unsigned int *data)
533 {
534         int i;
535
536         for (i = 0; i < insn->n; i++) {
537                 data[i] =
538                     dev_private->ao_readback[CR_CHAN((&insn->chanspec)[i])];
539         }
540
541         return 1;
542 }
543
544 /*
545  * ------------------------------------------------------------------
546  *
547  * INITIALISATION SECTION
548  *
549  * ------------------------------------------------------------------
550  */
551
552 /* Xilinx firmware download for card: ME-2600i */
553 static int me2600_xilinx_download(struct comedi_device *dev,
554                                   unsigned char *me2600_firmware,
555                                   unsigned int length)
556 {
557         unsigned int value;
558         unsigned int file_length;
559         unsigned int i;
560
561         /* disable irq's on PLX */
562         writel(0x00, dev_private->plx_regbase + PLX_INTCSR);
563
564         /* First, make a dummy read to reset xilinx */
565         value = readw(dev_private->me_regbase + XILINX_DOWNLOAD_RESET);
566
567         /* Wait until reset is over */
568         sleep(1);
569
570         /* Write a dummy value to Xilinx */
571         writeb(0x00, dev_private->me_regbase + 0x0);
572         sleep(1);
573
574         /*
575          * Format of the firmware
576          * Build longs from the byte-wise coded header
577          * Byte 1-3:   length of the array
578          * Byte 4-7:   version
579          * Byte 8-11:  date
580          * Byte 12-15: reserved
581          */
582         if (length < 16)
583                 return -EINVAL;
584         file_length = (((unsigned int)me2600_firmware[0] & 0xff) << 24) +
585             (((unsigned int)me2600_firmware[1] & 0xff) << 16) +
586             (((unsigned int)me2600_firmware[2] & 0xff) << 8) +
587             ((unsigned int)me2600_firmware[3] & 0xff);
588
589         /*
590          * Loop for writing firmware byte by byte to xilinx
591          * Firmware data start at offfset 16
592          */
593         for (i = 0; i < file_length; i++)
594                 writeb((me2600_firmware[16 + i] & 0xff),
595                        dev_private->me_regbase + 0x0);
596
597         /* Write 5 dummy values to xilinx */
598         for (i = 0; i < 5; i++)
599                 writeb(0x00, dev_private->me_regbase + 0x0);
600
601         /* Test if there was an error during download -> INTB was thrown */
602         value = readl(dev_private->plx_regbase + PLX_INTCSR);
603         if (value & 0x20) {
604                 /* Disable interrupt */
605                 writel(0x00, dev_private->plx_regbase + PLX_INTCSR);
606                 printk(KERN_ERR "comedi%d: Xilinx download failed\n",
607                        dev->minor);
608                 return -EIO;
609         }
610
611         /* Wait until the Xilinx is ready for real work */
612         sleep(1);
613
614         /* Enable PLX-Interrupts */
615         writel(0x43, dev_private->plx_regbase + PLX_INTCSR);
616
617         return 0;
618 }
619
620 /* Reset device */
621 static int me_reset(struct comedi_device *dev)
622 {
623         /* Reset board */
624         writew(0x00, dev_private->me_regbase + ME_CONTROL_1);
625         writew(0x00, dev_private->me_regbase + ME_CONTROL_2);
626         writew(0x00, dev_private->me_regbase + ME_RESET_INTERRUPT);
627         writew(0x00, dev_private->me_regbase + ME_DAC_CONTROL);
628
629         /* Save values in the board context */
630         dev_private->dac_control = 0;
631         dev_private->control_1 = 0;
632         dev_private->control_2 = 0;
633
634         return 0;
635 }
636
637 /*
638  * Attach
639  *
640  * - Register PCI device
641  * - Declare device driver capability
642  */
643 static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
644 {
645         struct pci_dev *pci_device;
646         struct comedi_subdevice *subdevice;
647         struct me_board *board;
648         resource_size_t plx_regbase_tmp;
649         unsigned long plx_regbase_size_tmp;
650         resource_size_t me_regbase_tmp;
651         unsigned long me_regbase_size_tmp;
652         resource_size_t swap_regbase_tmp;
653         unsigned long swap_regbase_size_tmp;
654         resource_size_t regbase_tmp;
655         int result, error, i;
656
657         /* Allocate private memory */
658         if (alloc_private(dev, sizeof(struct me_private_data)) < 0)
659                 return -ENOMEM;
660
661         /* Probe the device to determine what device in the series it is. */
662         for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
663              pci_device != NULL;
664              pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
665                 if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
666                         for (i = 0; i < me_board_nbr; i++) {
667                                 if (me_boards[i].device_id ==
668                                     pci_device->device) {
669                                         /*
670                                          * was a particular bus/slot requested?
671                                          */
672                                         if ((it->options[0] != 0)
673                                             || (it->options[1] != 0)) {
674                                                 /*
675                                                  * are we on the wrong bus/slot?
676                                                  */
677                                                 if (pci_device->bus->number !=
678                                                     it->options[0]
679                                                     ||
680                                                     PCI_SLOT(pci_device->devfn)
681                                                     != it->options[1]) {
682                                                         continue;
683                                                 }
684                                         }
685
686                                         dev->board_ptr = me_boards + i;
687                                         board =
688                                             (struct me_board *)dev->board_ptr;
689                                         dev_private->pci_device = pci_device;
690                                         goto found;
691                                 }
692                         }
693                 }
694         }
695
696         printk(KERN_ERR
697                "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
698                dev->minor, it->options[0], it->options[1]);
699         return -EIO;
700
701 found:
702         printk(KERN_INFO "comedi%d: found %s at PCI bus %d, slot %d\n",
703                dev->minor, me_boards[i].name,
704                pci_device->bus->number, PCI_SLOT(pci_device->devfn));
705
706         /* Enable PCI device and request PCI regions */
707         if (comedi_pci_enable(pci_device, ME_DRIVER_NAME) < 0) {
708                 printk(KERN_ERR "comedi%d: Failed to enable PCI device and "
709                        "request regions\n", dev->minor);
710                 return -EIO;
711         }
712
713         /* Set data in device structure */
714         dev->board_name = board->name;
715
716         /* Read PLX register base address [PCI_BASE_ADDRESS #0]. */
717         plx_regbase_tmp = pci_resource_start(pci_device, 0);
718         plx_regbase_size_tmp = pci_resource_len(pci_device, 0);
719         dev_private->plx_regbase =
720             ioremap(plx_regbase_tmp, plx_regbase_size_tmp);
721         dev_private->plx_regbase_size = plx_regbase_size_tmp;
722         if (!dev_private->plx_regbase) {
723                 printk("comedi%d: Failed to remap I/O memory\n", dev->minor);
724                 return -ENOMEM;
725         }
726
727         /* Read Swap base address [PCI_BASE_ADDRESS #5]. */
728
729         swap_regbase_tmp = pci_resource_start(pci_device, 5);
730         swap_regbase_size_tmp = pci_resource_len(pci_device, 5);
731
732         if (!swap_regbase_tmp)
733                 printk(KERN_ERR "comedi%d: Swap not present\n", dev->minor);
734
735         /*---------------------------------------------- Workaround start ---*/
736         if (plx_regbase_tmp & 0x0080) {
737                 printk(KERN_ERR "comedi%d: PLX-Bug detected\n", dev->minor);
738
739                 if (swap_regbase_tmp) {
740                         regbase_tmp = plx_regbase_tmp;
741                         plx_regbase_tmp = swap_regbase_tmp;
742                         swap_regbase_tmp = regbase_tmp;
743
744                         result = pci_write_config_dword(pci_device,
745                                                         PCI_BASE_ADDRESS_0,
746                                                         plx_regbase_tmp);
747                         if (result != PCIBIOS_SUCCESSFUL)
748                                 return -EIO;
749
750                         result = pci_write_config_dword(pci_device,
751                                                         PCI_BASE_ADDRESS_5,
752                                                         swap_regbase_tmp);
753                         if (result != PCIBIOS_SUCCESSFUL)
754                                 return -EIO;
755                 } else {
756                         plx_regbase_tmp -= 0x80;
757                         result = pci_write_config_dword(pci_device,
758                                                         PCI_BASE_ADDRESS_0,
759                                                         plx_regbase_tmp);
760                         if (result != PCIBIOS_SUCCESSFUL)
761                                 return -EIO;
762                 }
763         }
764         /*--------------------------------------------- Workaround end -----*/
765
766         /* Read Meilhaus register base address [PCI_BASE_ADDRESS #2]. */
767
768         me_regbase_tmp = pci_resource_start(pci_device, 2);
769         me_regbase_size_tmp = pci_resource_len(pci_device, 2);
770         dev_private->me_regbase_size = me_regbase_size_tmp;
771         dev_private->me_regbase = ioremap(me_regbase_tmp, me_regbase_size_tmp);
772         if (!dev_private->me_regbase) {
773                 printk(KERN_ERR "comedi%d: Failed to remap I/O memory\n",
774                        dev->minor);
775                 return -ENOMEM;
776         }
777         /* Download firmware and reset card */
778         if (board->device_id == ME2600_DEVICE_ID) {
779                 unsigned char *aux_data;
780                 int aux_len;
781
782                 aux_data = comedi_aux_data(it->options, 0);
783                 aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
784
785                 if (!aux_data || aux_len < 1) {
786                         comedi_error(dev, "You must provide me2600 firmware "
787                                      "using the --init-data option of "
788                                      "comedi_config");
789                         return -EINVAL;
790                 }
791                 me2600_xilinx_download(dev, aux_data, aux_len);
792         }
793
794         me_reset(dev);
795
796         /* device driver capabilities */
797         error = alloc_subdevices(dev, 3);
798         if (error < 0)
799                 return error;
800
801         subdevice = dev->subdevices + 0;
802         subdevice->type = COMEDI_SUBD_AI;
803         subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ;
804         subdevice->n_chan = board->ai_channel_nbr;
805         subdevice->maxdata = board->ai_resolution_mask;
806         subdevice->len_chanlist = board->ai_channel_nbr;
807         subdevice->range_table = board->ai_range_list;
808         subdevice->cancel = me_ai_cancel;
809         subdevice->insn_read = me_ai_insn_read;
810         subdevice->do_cmdtest = me_ai_do_cmd_test;
811         subdevice->do_cmd = me_ai_do_cmd;
812
813         subdevice = dev->subdevices + 1;
814         subdevice->type = COMEDI_SUBD_AO;
815         subdevice->subdev_flags = SDF_WRITEABLE | SDF_COMMON;
816         subdevice->n_chan = board->ao_channel_nbr;
817         subdevice->maxdata = board->ao_resolution_mask;
818         subdevice->len_chanlist = board->ao_channel_nbr;
819         subdevice->range_table = board->ao_range_list;
820         subdevice->insn_read = me_ao_insn_read;
821         subdevice->insn_write = me_ao_insn_write;
822
823         subdevice = dev->subdevices + 2;
824         subdevice->type = COMEDI_SUBD_DIO;
825         subdevice->subdev_flags = SDF_READABLE | SDF_WRITEABLE;
826         subdevice->n_chan = board->dio_channel_nbr;
827         subdevice->maxdata = 1;
828         subdevice->len_chanlist = board->dio_channel_nbr;
829         subdevice->range_table = &range_digital;
830         subdevice->insn_bits = me_dio_insn_bits;
831         subdevice->insn_config = me_dio_insn_config;
832         subdevice->io_bits = 0;
833
834         printk(KERN_INFO "comedi%d: " ME_DRIVER_NAME " attached.\n",
835                dev->minor);
836         return 0;
837 }
838
839 /* Detach */
840 static int me_detach(struct comedi_device *dev)
841 {
842         if (dev_private) {
843                 if (dev_private->me_regbase) {
844                         me_reset(dev);
845                         iounmap(dev_private->me_regbase);
846                 }
847                 if (dev_private->plx_regbase)
848                         iounmap(dev_private->plx_regbase);
849                 if (dev_private->pci_device) {
850                         if (dev_private->plx_regbase_size)
851                                 comedi_pci_disable(dev_private->pci_device);
852
853                         pci_dev_put(dev_private->pci_device);
854                 }
855         }
856         return 0;
857 }