1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261#include <linux/pci.h>
262#include <linux/interrupt.h>
263#include <linux/slab.h>
264
265#include "../comedidev.h"
266
267#include "comedi_fc.h"
268#include "8253.h"
269
270#define DIO200_DRIVER_NAME "amplc_dio200"
271
272#define DO_ISA IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA)
273#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI)
274
275
276#define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
277#define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
278#define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011
279#define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012
280#define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014
281
282
283#define CR_C_LO_IO 0x01
284#define CR_B_IO 0x02
285#define CR_B_MODE 0x04
286#define CR_C_HI_IO 0x08
287#define CR_A_IO 0x10
288#define CR_A_MODE(a) ((a)<<5)
289#define CR_CW 0x80
290
291
292#define DIO200_IO_SIZE 0x20
293#define DIO200_PCIE_IO_SIZE 0x4000
294#define DIO200_XCLK_SCE 0x18
295#define DIO200_YCLK_SCE 0x19
296#define DIO200_ZCLK_SCE 0x1a
297#define DIO200_XGAT_SCE 0x1b
298#define DIO200_YGAT_SCE 0x1c
299#define DIO200_ZGAT_SCE 0x1d
300#define DIO200_INT_SCE 0x1e
301
302#define DIO200_ENHANCE 0x20
303#define DIO200_VERSION 0x24
304#define DIO200_TS_CONFIG 0x600
305#define DIO200_TS_COUNT 0x602
306
307
308
309
310
311
312
313
314
315static unsigned char clk_gat_sce(unsigned int which, unsigned int chan,
316 unsigned int source)
317{
318 return (which << 5) | (chan << 3) |
319 ((source & 030) << 3) | (source & 007);
320}
321
322static unsigned char clk_sce(unsigned int which, unsigned int chan,
323 unsigned int source)
324{
325 return clk_gat_sce(which, chan, source);
326}
327
328static unsigned char gat_sce(unsigned int which, unsigned int chan,
329 unsigned int source)
330{
331 return clk_gat_sce(which, chan, source);
332}
333
334
335
336
337static const unsigned int clock_period[32] = {
338 [1] = 100,
339 [2] = 1000,
340 [3] = 10000,
341 [4] = 100000,
342 [5] = 1000000,
343 [11] = 50,
344
345};
346
347
348
349
350#define TS_CONFIG_RESET 0x100
351#define TS_CONFIG_CLK_SRC_MASK 0x0FF
352#define TS_CONFIG_MAX_CLK_SRC 2
353
354
355
356
357static const unsigned int ts_clock_period[TS_CONFIG_MAX_CLK_SRC + 1] = {
358 1,
359 1000,
360 1000000,
361};
362
363
364
365
366enum dio200_regtype { no_regtype = 0, io_regtype, mmio_regtype };
367struct dio200_region {
368 union {
369 unsigned long iobase;
370 unsigned char __iomem *membase;
371 } u;
372 enum dio200_regtype regtype;
373};
374
375
376
377
378
379enum dio200_bustype { isa_bustype, pci_bustype };
380
381enum dio200_model {
382 pc212e_model,
383 pc214e_model,
384 pc215e_model, pci215_model, pcie215_model,
385 pc218e_model,
386 pcie236_model,
387 pc272e_model, pci272_model,
388 pcie296_model,
389};
390
391enum dio200_layout_idx {
392#if DO_ISA
393 pc212_layout,
394 pc214_layout,
395#endif
396 pc215_layout,
397#if DO_ISA
398 pc218_layout,
399#endif
400 pc272_layout,
401#if DO_PCI
402 pcie215_layout,
403 pcie236_layout,
404 pcie296_layout,
405#endif
406};
407
408struct dio200_board {
409 const char *name;
410 unsigned short devid;
411 enum dio200_bustype bustype;
412 enum dio200_model model;
413 enum dio200_layout_idx layout;
414 unsigned char mainbar;
415 unsigned char mainshift;
416 unsigned int mainsize;
417};
418
419static const struct dio200_board dio200_boards[] = {
420#if DO_ISA
421 {
422 .name = "pc212e",
423 .bustype = isa_bustype,
424 .model = pc212e_model,
425 .layout = pc212_layout,
426 .mainsize = DIO200_IO_SIZE,
427 },
428 {
429 .name = "pc214e",
430 .bustype = isa_bustype,
431 .model = pc214e_model,
432 .layout = pc214_layout,
433 .mainsize = DIO200_IO_SIZE,
434 },
435 {
436 .name = "pc215e",
437 .bustype = isa_bustype,
438 .model = pc215e_model,
439 .layout = pc215_layout,
440 .mainsize = DIO200_IO_SIZE,
441 },
442 {
443 .name = "pc218e",
444 .bustype = isa_bustype,
445 .model = pc218e_model,
446 .layout = pc218_layout,
447 .mainsize = DIO200_IO_SIZE,
448 },
449 {
450 .name = "pc272e",
451 .bustype = isa_bustype,
452 .model = pc272e_model,
453 .layout = pc272_layout,
454 .mainsize = DIO200_IO_SIZE,
455 },
456#endif
457#if DO_PCI
458 {
459 .name = "pci215",
460 .devid = PCI_DEVICE_ID_AMPLICON_PCI215,
461 .bustype = pci_bustype,
462 .model = pci215_model,
463 .layout = pc215_layout,
464 .mainbar = 2,
465 .mainsize = DIO200_IO_SIZE,
466 },
467 {
468 .name = "pci272",
469 .devid = PCI_DEVICE_ID_AMPLICON_PCI272,
470 .bustype = pci_bustype,
471 .model = pci272_model,
472 .layout = pc272_layout,
473 .mainbar = 2,
474 .mainsize = DIO200_IO_SIZE,
475 },
476 {
477 .name = "pcie215",
478 .devid = PCI_DEVICE_ID_AMPLICON_PCIE215,
479 .bustype = pci_bustype,
480 .model = pcie215_model,
481 .layout = pcie215_layout,
482 .mainbar = 1,
483 .mainshift = 3,
484 .mainsize = DIO200_PCIE_IO_SIZE,
485 },
486 {
487 .name = "pcie236",
488 .devid = PCI_DEVICE_ID_AMPLICON_PCIE236,
489 .bustype = pci_bustype,
490 .model = pcie236_model,
491 .layout = pcie236_layout,
492 .mainbar = 1,
493 .mainshift = 3,
494 .mainsize = DIO200_PCIE_IO_SIZE,
495 },
496 {
497 .name = "pcie296",
498 .devid = PCI_DEVICE_ID_AMPLICON_PCIE296,
499 .bustype = pci_bustype,
500 .model = pcie296_model,
501 .layout = pcie296_layout,
502 .mainbar = 1,
503 .mainshift = 3,
504 .mainsize = DIO200_PCIE_IO_SIZE,
505 },
506#endif
507};
508
509
510
511
512
513
514enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
515
516#define DIO200_MAX_SUBDEVS 8
517#define DIO200_MAX_ISNS 6
518
519struct dio200_layout {
520 unsigned short n_subdevs;
521 unsigned char sdtype[DIO200_MAX_SUBDEVS];
522 unsigned char sdinfo[DIO200_MAX_SUBDEVS];
523 char has_int_sce;
524 char has_clk_gat_sce;
525 char has_enhancements;
526};
527
528static const struct dio200_layout dio200_layouts[] = {
529#if DO_ISA
530 [pc212_layout] = {
531 .n_subdevs = 6,
532 .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254,
533 sd_8254,
534 sd_intr},
535 .sdinfo = {0x00, 0x08, 0x0C, 0x10, 0x14,
536 0x3F},
537 .has_int_sce = 1,
538 .has_clk_gat_sce = 1,
539 },
540 [pc214_layout] = {
541 .n_subdevs = 4,
542 .sdtype = {sd_8255, sd_8255, sd_8254,
543 sd_intr},
544 .sdinfo = {0x00, 0x08, 0x10, 0x01},
545 .has_int_sce = 0,
546 .has_clk_gat_sce = 0,
547 },
548#endif
549 [pc215_layout] = {
550 .n_subdevs = 5,
551 .sdtype = {sd_8255, sd_8255, sd_8254,
552 sd_8254,
553 sd_intr},
554 .sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F},
555 .has_int_sce = 1,
556 .has_clk_gat_sce = 1,
557 },
558#if DO_ISA
559 [pc218_layout] = {
560 .n_subdevs = 7,
561 .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254,
562 sd_8254,
563 sd_intr},
564 .sdinfo = {0x00, 0x04, 0x08, 0x0C, 0x10,
565 0x14,
566 0x3F},
567 .has_int_sce = 1,
568 .has_clk_gat_sce = 1,
569 },
570#endif
571 [pc272_layout] = {
572 .n_subdevs = 4,
573 .sdtype = {sd_8255, sd_8255, sd_8255,
574 sd_intr},
575 .sdinfo = {0x00, 0x08, 0x10, 0x3F},
576 .has_int_sce = 1,
577 .has_clk_gat_sce = 0,
578 },
579#if DO_PCI
580 [pcie215_layout] = {
581 .n_subdevs = 8,
582 .sdtype = {sd_8255, sd_none, sd_8255, sd_none,
583 sd_8254, sd_8254, sd_timer, sd_intr},
584 .sdinfo = {0x00, 0x00, 0x08, 0x00,
585 0x10, 0x14, 0x00, 0x3F},
586 .has_int_sce = 1,
587 .has_clk_gat_sce = 1,
588 .has_enhancements = 1,
589 },
590 [pcie236_layout] = {
591 .n_subdevs = 8,
592 .sdtype = {sd_8255, sd_none, sd_none, sd_none,
593 sd_8254, sd_8254, sd_timer, sd_intr},
594 .sdinfo = {0x00, 0x00, 0x00, 0x00,
595 0x10, 0x14, 0x00, 0x3F},
596 .has_int_sce = 1,
597 .has_clk_gat_sce = 1,
598 .has_enhancements = 1,
599 },
600 [pcie296_layout] = {
601 .n_subdevs = 8,
602 .sdtype = {sd_8255, sd_8255, sd_8255, sd_8255,
603 sd_8254, sd_8254, sd_timer, sd_intr},
604 .sdinfo = {0x00, 0x04, 0x08, 0x0C,
605 0x10, 0x14, 0x00, 0x3F},
606 .has_int_sce = 1,
607 .has_clk_gat_sce = 1,
608 .has_enhancements = 1,
609 },
610#endif
611};
612
613
614
615
616
617struct dio200_private {
618 struct dio200_region io;
619 int intr_sd;
620};
621
622struct dio200_subdev_8254 {
623 unsigned int ofs;
624 unsigned int clk_sce_ofs;
625 unsigned int gat_sce_ofs;
626 int which;
627 unsigned int clock_src[3];
628 unsigned int gate_src[3];
629 spinlock_t spinlock;
630};
631
632struct dio200_subdev_8255 {
633 unsigned int ofs;
634};
635
636struct dio200_subdev_intr {
637 unsigned int ofs;
638 spinlock_t spinlock;
639 int active;
640 unsigned int valid_isns;
641 unsigned int enabled_isns;
642 unsigned int stopcount;
643 int continuous;
644};
645
646static inline const struct dio200_layout *
647dio200_board_layout(const struct dio200_board *board)
648{
649 return &dio200_layouts[board->layout];
650}
651
652static inline const struct dio200_layout *
653dio200_dev_layout(struct comedi_device *dev)
654{
655 return dio200_board_layout(comedi_board(dev));
656}
657
658static inline bool is_pci_board(const struct dio200_board *board)
659{
660 return DO_PCI && board->bustype == pci_bustype;
661}
662
663static inline bool is_isa_board(const struct dio200_board *board)
664{
665 return DO_ISA && board->bustype == isa_bustype;
666}
667
668
669
670
671static unsigned char dio200_read8(struct comedi_device *dev,
672 unsigned int offset)
673{
674 const struct dio200_board *thisboard = comedi_board(dev);
675 struct dio200_private *devpriv = dev->private;
676
677 offset <<= thisboard->mainshift;
678 if (devpriv->io.regtype == io_regtype)
679 return inb(devpriv->io.u.iobase + offset);
680 else
681 return readb(devpriv->io.u.membase + offset);
682}
683
684
685
686
687static void dio200_write8(struct comedi_device *dev, unsigned int offset,
688 unsigned char val)
689{
690 const struct dio200_board *thisboard = comedi_board(dev);
691 struct dio200_private *devpriv = dev->private;
692
693 offset <<= thisboard->mainshift;
694 if (devpriv->io.regtype == io_regtype)
695 outb(val, devpriv->io.u.iobase + offset);
696 else
697 writeb(val, devpriv->io.u.membase + offset);
698}
699
700
701
702
703static unsigned int dio200_read32(struct comedi_device *dev,
704 unsigned int offset)
705{
706 const struct dio200_board *thisboard = comedi_board(dev);
707 struct dio200_private *devpriv = dev->private;
708
709 offset <<= thisboard->mainshift;
710 if (devpriv->io.regtype == io_regtype)
711 return inl(devpriv->io.u.iobase + offset);
712 else
713 return readl(devpriv->io.u.membase + offset);
714}
715
716
717
718
719static void dio200_write32(struct comedi_device *dev, unsigned int offset,
720 unsigned int val)
721{
722 const struct dio200_board *thisboard = comedi_board(dev);
723 struct dio200_private *devpriv = dev->private;
724
725 offset <<= thisboard->mainshift;
726 if (devpriv->io.regtype == io_regtype)
727 outl(val, devpriv->io.u.iobase + offset);
728 else
729 writel(val, devpriv->io.u.membase + offset);
730}
731
732
733
734
735static const struct dio200_board *
736dio200_find_pci_board(struct pci_dev *pci_dev)
737{
738 unsigned int i;
739
740 for (i = 0; i < ARRAY_SIZE(dio200_boards); i++)
741 if (is_pci_board(&dio200_boards[i]) &&
742 pci_dev->device == dio200_boards[i].devid)
743 return &dio200_boards[i];
744 return NULL;
745}
746
747
748
749
750
751static int
752dio200_request_region(struct comedi_device *dev,
753 unsigned long from, unsigned long extent)
754{
755 if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
756 dev_err(dev->class_dev, "I/O port conflict (%#lx,%lu)!\n",
757 from, extent);
758 return -EIO;
759 }
760 return 0;
761}
762
763
764
765
766static int
767dio200_subdev_intr_insn_bits(struct comedi_device *dev,
768 struct comedi_subdevice *s,
769 struct comedi_insn *insn, unsigned int *data)
770{
771 const struct dio200_layout *layout = dio200_dev_layout(dev);
772 struct dio200_subdev_intr *subpriv = s->private;
773
774 if (layout->has_int_sce) {
775
776 data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
777 } else {
778
779 data[0] = 0;
780 }
781
782 return insn->n;
783}
784
785
786
787
788static void dio200_stop_intr(struct comedi_device *dev,
789 struct comedi_subdevice *s)
790{
791 const struct dio200_layout *layout = dio200_dev_layout(dev);
792 struct dio200_subdev_intr *subpriv = s->private;
793
794 subpriv->active = 0;
795 subpriv->enabled_isns = 0;
796 if (layout->has_int_sce)
797 dio200_write8(dev, subpriv->ofs, 0);
798}
799
800
801
802
803static int dio200_start_intr(struct comedi_device *dev,
804 struct comedi_subdevice *s)
805{
806 unsigned int n;
807 unsigned isn_bits;
808 const struct dio200_layout *layout = dio200_dev_layout(dev);
809 struct dio200_subdev_intr *subpriv = s->private;
810 struct comedi_cmd *cmd = &s->async->cmd;
811 int retval = 0;
812
813 if (!subpriv->continuous && subpriv->stopcount == 0) {
814
815 s->async->events |= COMEDI_CB_EOA;
816 subpriv->active = 0;
817 retval = 1;
818 } else {
819
820 isn_bits = 0;
821 if (cmd->chanlist) {
822 for (n = 0; n < cmd->chanlist_len; n++)
823 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
824 }
825 isn_bits &= subpriv->valid_isns;
826
827 subpriv->enabled_isns = isn_bits;
828 if (layout->has_int_sce)
829 dio200_write8(dev, subpriv->ofs, isn_bits);
830 }
831
832 return retval;
833}
834
835
836
837
838static int
839dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
840 unsigned int trignum)
841{
842 struct dio200_subdev_intr *subpriv;
843 unsigned long flags;
844 int event = 0;
845
846 if (trignum != 0)
847 return -EINVAL;
848
849 subpriv = s->private;
850
851 spin_lock_irqsave(&subpriv->spinlock, flags);
852 s->async->inttrig = NULL;
853 if (subpriv->active)
854 event = dio200_start_intr(dev, s);
855
856 spin_unlock_irqrestore(&subpriv->spinlock, flags);
857
858 if (event)
859 comedi_event(dev, s);
860
861 return 1;
862}
863
864
865
866
867
868static int dio200_handle_read_intr(struct comedi_device *dev,
869 struct comedi_subdevice *s)
870{
871 const struct dio200_layout *layout = dio200_dev_layout(dev);
872 struct dio200_subdev_intr *subpriv = s->private;
873 unsigned triggered;
874 unsigned intstat;
875 unsigned cur_enabled;
876 unsigned int oldevents;
877 unsigned long flags;
878
879 triggered = 0;
880
881 spin_lock_irqsave(&subpriv->spinlock, flags);
882 oldevents = s->async->events;
883 if (layout->has_int_sce) {
884
885
886
887
888
889
890
891
892
893
894 cur_enabled = subpriv->enabled_isns;
895 while ((intstat = (dio200_read8(dev, subpriv->ofs) &
896 subpriv->valid_isns & ~triggered)) != 0) {
897 triggered |= intstat;
898 cur_enabled &= ~triggered;
899 dio200_write8(dev, subpriv->ofs, cur_enabled);
900 }
901 } else {
902
903
904
905
906 triggered = subpriv->enabled_isns;
907 }
908
909 if (triggered) {
910
911
912
913
914
915
916 cur_enabled = subpriv->enabled_isns;
917 if (layout->has_int_sce)
918 dio200_write8(dev, subpriv->ofs, cur_enabled);
919
920 if (subpriv->active) {
921
922
923
924
925
926
927
928 if (triggered & subpriv->enabled_isns) {
929
930 short val;
931 unsigned int n, ch, len;
932
933 val = 0;
934 len = s->async->cmd.chanlist_len;
935 for (n = 0; n < len; n++) {
936 ch = CR_CHAN(s->async->cmd.chanlist[n]);
937 if (triggered & (1U << ch))
938 val |= (1U << n);
939 }
940
941 if (comedi_buf_put(s->async, val)) {
942 s->async->events |= (COMEDI_CB_BLOCK |
943 COMEDI_CB_EOS);
944 } else {
945
946 dio200_stop_intr(dev, s);
947 s->async->events |= COMEDI_CB_ERROR
948 | COMEDI_CB_OVERFLOW;
949 comedi_error(dev, "buffer overflow");
950 }
951
952
953 if (!subpriv->continuous) {
954
955 if (subpriv->stopcount > 0) {
956 subpriv->stopcount--;
957 if (subpriv->stopcount == 0) {
958 s->async->events |=
959 COMEDI_CB_EOA;
960 dio200_stop_intr(dev,
961 s);
962 }
963 }
964 }
965 }
966 }
967 }
968 spin_unlock_irqrestore(&subpriv->spinlock, flags);
969
970 if (oldevents != s->async->events)
971 comedi_event(dev, s);
972
973 return (triggered != 0);
974}
975
976
977
978
979static int dio200_subdev_intr_cancel(struct comedi_device *dev,
980 struct comedi_subdevice *s)
981{
982 struct dio200_subdev_intr *subpriv = s->private;
983 unsigned long flags;
984
985 spin_lock_irqsave(&subpriv->spinlock, flags);
986 if (subpriv->active)
987 dio200_stop_intr(dev, s);
988
989 spin_unlock_irqrestore(&subpriv->spinlock, flags);
990
991 return 0;
992}
993
994
995
996
997static int
998dio200_subdev_intr_cmdtest(struct comedi_device *dev,
999 struct comedi_subdevice *s, struct comedi_cmd *cmd)
1000{
1001 int err = 0;
1002
1003
1004
1005 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1006 err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
1007 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1008 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1009 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1010
1011 if (err)
1012 return 1;
1013
1014
1015
1016 err |= cfc_check_trigger_is_unique(cmd->start_src);
1017 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1018
1019
1020
1021 if (err)
1022 return 2;
1023
1024
1025
1026 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1027 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1028 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
1029 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1030
1031 switch (cmd->stop_src) {
1032 case TRIG_COUNT:
1033
1034 break;
1035 case TRIG_NONE:
1036 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1037 break;
1038 default:
1039 break;
1040 }
1041
1042 if (err)
1043 return 3;
1044
1045
1046
1047
1048
1049 return 0;
1050}
1051
1052
1053
1054
1055static int dio200_subdev_intr_cmd(struct comedi_device *dev,
1056 struct comedi_subdevice *s)
1057{
1058 struct comedi_cmd *cmd = &s->async->cmd;
1059 struct dio200_subdev_intr *subpriv = s->private;
1060 unsigned long flags;
1061 int event = 0;
1062
1063 spin_lock_irqsave(&subpriv->spinlock, flags);
1064 subpriv->active = 1;
1065
1066
1067 switch (cmd->stop_src) {
1068 case TRIG_COUNT:
1069 subpriv->continuous = 0;
1070 subpriv->stopcount = cmd->stop_arg;
1071 break;
1072 default:
1073
1074 subpriv->continuous = 1;
1075 subpriv->stopcount = 0;
1076 break;
1077 }
1078
1079
1080 switch (cmd->start_src) {
1081 case TRIG_INT:
1082 s->async->inttrig = dio200_inttrig_start_intr;
1083 break;
1084 default:
1085
1086 event = dio200_start_intr(dev, s);
1087 break;
1088 }
1089 spin_unlock_irqrestore(&subpriv->spinlock, flags);
1090
1091 if (event)
1092 comedi_event(dev, s);
1093
1094 return 0;
1095}
1096
1097
1098
1099
1100static int
1101dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
1102 unsigned int offset, unsigned valid_isns)
1103{
1104 const struct dio200_layout *layout = dio200_dev_layout(dev);
1105 struct dio200_subdev_intr *subpriv;
1106
1107 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1108 if (!subpriv)
1109 return -ENOMEM;
1110
1111 subpriv->ofs = offset;
1112 subpriv->valid_isns = valid_isns;
1113 spin_lock_init(&subpriv->spinlock);
1114
1115 if (layout->has_int_sce)
1116
1117 dio200_write8(dev, subpriv->ofs, 0);
1118
1119 s->private = subpriv;
1120 s->type = COMEDI_SUBD_DI;
1121 s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1122 if (layout->has_int_sce) {
1123 s->n_chan = DIO200_MAX_ISNS;
1124 s->len_chanlist = DIO200_MAX_ISNS;
1125 } else {
1126
1127 s->n_chan = 1;
1128 s->len_chanlist = 1;
1129 }
1130 s->range_table = &range_digital;
1131 s->maxdata = 1;
1132 s->insn_bits = dio200_subdev_intr_insn_bits;
1133 s->do_cmdtest = dio200_subdev_intr_cmdtest;
1134 s->do_cmd = dio200_subdev_intr_cmd;
1135 s->cancel = dio200_subdev_intr_cancel;
1136
1137 return 0;
1138}
1139
1140
1141
1142
1143static void
1144dio200_subdev_intr_cleanup(struct comedi_device *dev,
1145 struct comedi_subdevice *s)
1146{
1147 struct dio200_subdev_intr *subpriv = s->private;
1148 kfree(subpriv);
1149}
1150
1151
1152
1153
1154static irqreturn_t dio200_interrupt(int irq, void *d)
1155{
1156 struct comedi_device *dev = d;
1157 struct dio200_private *devpriv = dev->private;
1158 struct comedi_subdevice *s;
1159 int handled;
1160
1161 if (!dev->attached)
1162 return IRQ_NONE;
1163
1164 if (devpriv->intr_sd >= 0) {
1165 s = &dev->subdevices[devpriv->intr_sd];
1166 handled = dio200_handle_read_intr(dev, s);
1167 } else {
1168 handled = 0;
1169 }
1170
1171 return IRQ_RETVAL(handled);
1172}
1173
1174
1175
1176
1177static unsigned int
1178dio200_subdev_8254_read_chan(struct comedi_device *dev,
1179 struct comedi_subdevice *s, unsigned int chan)
1180{
1181 struct dio200_subdev_8254 *subpriv = s->private;
1182 unsigned int val;
1183
1184
1185 val = chan << 6;
1186 dio200_write8(dev, subpriv->ofs + i8254_control_reg, val);
1187
1188 val = dio200_read8(dev, subpriv->ofs + chan);
1189 val += dio200_read8(dev, subpriv->ofs + chan) << 8;
1190 return val;
1191}
1192
1193
1194
1195
1196static void
1197dio200_subdev_8254_write_chan(struct comedi_device *dev,
1198 struct comedi_subdevice *s, unsigned int chan,
1199 unsigned int count)
1200{
1201 struct dio200_subdev_8254 *subpriv = s->private;
1202
1203
1204 dio200_write8(dev, subpriv->ofs + chan, count & 0xff);
1205 dio200_write8(dev, subpriv->ofs + chan, (count >> 8) & 0xff);
1206}
1207
1208
1209
1210
1211static void
1212dio200_subdev_8254_set_mode(struct comedi_device *dev,
1213 struct comedi_subdevice *s, unsigned int chan,
1214 unsigned int mode)
1215{
1216 struct dio200_subdev_8254 *subpriv = s->private;
1217 unsigned int byte;
1218
1219 byte = chan << 6;
1220 byte |= 0x30;
1221 byte |= (mode & 0xf);
1222 dio200_write8(dev, subpriv->ofs + i8254_control_reg, byte);
1223}
1224
1225
1226
1227
1228static unsigned int
1229dio200_subdev_8254_status(struct comedi_device *dev,
1230 struct comedi_subdevice *s, unsigned int chan)
1231{
1232 struct dio200_subdev_8254 *subpriv = s->private;
1233
1234
1235 dio200_write8(dev, subpriv->ofs + i8254_control_reg,
1236 0xe0 | (2 << chan));
1237
1238 return dio200_read8(dev, subpriv->ofs + chan);
1239}
1240
1241
1242
1243
1244static int
1245dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
1246 struct comedi_insn *insn, unsigned int *data)
1247{
1248 struct dio200_subdev_8254 *subpriv = s->private;
1249 int chan = CR_CHAN(insn->chanspec);
1250 unsigned int n;
1251 unsigned long flags;
1252
1253 for (n = 0; n < insn->n; n++) {
1254 spin_lock_irqsave(&subpriv->spinlock, flags);
1255 data[n] = dio200_subdev_8254_read_chan(dev, s, chan);
1256 spin_unlock_irqrestore(&subpriv->spinlock, flags);
1257 }
1258 return insn->n;
1259}
1260
1261
1262
1263
1264static int
1265dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
1266 struct comedi_insn *insn, unsigned int *data)
1267{
1268 struct dio200_subdev_8254 *subpriv = s->private;
1269 int chan = CR_CHAN(insn->chanspec);
1270 unsigned int n;
1271 unsigned long flags;
1272
1273 for (n = 0; n < insn->n; n++) {
1274 spin_lock_irqsave(&subpriv->spinlock, flags);
1275 dio200_subdev_8254_write_chan(dev, s, chan, data[n]);
1276 spin_unlock_irqrestore(&subpriv->spinlock, flags);
1277 }
1278 return insn->n;
1279}
1280
1281
1282
1283
1284static int
1285dio200_subdev_8254_set_gate_src(struct comedi_device *dev,
1286 struct comedi_subdevice *s,
1287 unsigned int counter_number,
1288 unsigned int gate_src)
1289{
1290 const struct dio200_layout *layout = dio200_dev_layout(dev);
1291 struct dio200_subdev_8254 *subpriv = s->private;
1292 unsigned char byte;
1293
1294 if (!layout->has_clk_gat_sce)
1295 return -1;
1296 if (counter_number > 2)
1297 return -1;
1298 if (gate_src > (layout->has_enhancements ? 31 : 7))
1299 return -1;
1300
1301 subpriv->gate_src[counter_number] = gate_src;
1302 byte = gat_sce(subpriv->which, counter_number, gate_src);
1303 dio200_write8(dev, subpriv->gat_sce_ofs, byte);
1304
1305 return 0;
1306}
1307
1308
1309
1310
1311static int
1312dio200_subdev_8254_get_gate_src(struct comedi_device *dev,
1313 struct comedi_subdevice *s,
1314 unsigned int counter_number)
1315{
1316 const struct dio200_layout *layout = dio200_dev_layout(dev);
1317 struct dio200_subdev_8254 *subpriv = s->private;
1318
1319 if (!layout->has_clk_gat_sce)
1320 return -1;
1321 if (counter_number > 2)
1322 return -1;
1323
1324 return subpriv->gate_src[counter_number];
1325}
1326
1327
1328
1329
1330static int
1331dio200_subdev_8254_set_clock_src(struct comedi_device *dev,
1332 struct comedi_subdevice *s,
1333 unsigned int counter_number,
1334 unsigned int clock_src)
1335{
1336 const struct dio200_layout *layout = dio200_dev_layout(dev);
1337 struct dio200_subdev_8254 *subpriv = s->private;
1338 unsigned char byte;
1339
1340 if (!layout->has_clk_gat_sce)
1341 return -1;
1342 if (counter_number > 2)
1343 return -1;
1344 if (clock_src > (layout->has_enhancements ? 31 : 7))
1345 return -1;
1346
1347 subpriv->clock_src[counter_number] = clock_src;
1348 byte = clk_sce(subpriv->which, counter_number, clock_src);
1349 dio200_write8(dev, subpriv->clk_sce_ofs, byte);
1350
1351 return 0;
1352}
1353
1354
1355
1356
1357static int
1358dio200_subdev_8254_get_clock_src(struct comedi_device *dev,
1359 struct comedi_subdevice *s,
1360 unsigned int counter_number,
1361 unsigned int *period_ns)
1362{
1363 const struct dio200_layout *layout = dio200_dev_layout(dev);
1364 struct dio200_subdev_8254 *subpriv = s->private;
1365 unsigned clock_src;
1366
1367 if (!layout->has_clk_gat_sce)
1368 return -1;
1369 if (counter_number > 2)
1370 return -1;
1371
1372 clock_src = subpriv->clock_src[counter_number];
1373 *period_ns = clock_period[clock_src];
1374 return clock_src;
1375}
1376
1377
1378
1379
1380static int
1381dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
1382 struct comedi_insn *insn, unsigned int *data)
1383{
1384 struct dio200_subdev_8254 *subpriv = s->private;
1385 int ret = 0;
1386 int chan = CR_CHAN(insn->chanspec);
1387 unsigned long flags;
1388
1389 spin_lock_irqsave(&subpriv->spinlock, flags);
1390 switch (data[0]) {
1391 case INSN_CONFIG_SET_COUNTER_MODE:
1392 if (data[1] > (I8254_MODE5 | I8254_BINARY))
1393 ret = -EINVAL;
1394 else
1395 dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
1396 break;
1397 case INSN_CONFIG_8254_READ_STATUS:
1398 data[1] = dio200_subdev_8254_status(dev, s, chan);
1399 break;
1400 case INSN_CONFIG_SET_GATE_SRC:
1401 ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
1402 if (ret < 0)
1403 ret = -EINVAL;
1404 break;
1405 case INSN_CONFIG_GET_GATE_SRC:
1406 ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
1407 if (ret < 0) {
1408 ret = -EINVAL;
1409 break;
1410 }
1411 data[2] = ret;
1412 break;
1413 case INSN_CONFIG_SET_CLOCK_SRC:
1414 ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
1415 if (ret < 0)
1416 ret = -EINVAL;
1417 break;
1418 case INSN_CONFIG_GET_CLOCK_SRC:
1419 ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
1420 if (ret < 0) {
1421 ret = -EINVAL;
1422 break;
1423 }
1424 data[1] = ret;
1425 break;
1426 default:
1427 ret = -EINVAL;
1428 break;
1429 }
1430 spin_unlock_irqrestore(&subpriv->spinlock, flags);
1431 return ret < 0 ? ret : insn->n;
1432}
1433
1434
1435
1436
1437static int
1438dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
1439 unsigned int offset)
1440{
1441 const struct dio200_layout *layout = dio200_dev_layout(dev);
1442 struct dio200_subdev_8254 *subpriv;
1443 unsigned int chan;
1444
1445 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1446 if (!subpriv)
1447 return -ENOMEM;
1448
1449 s->private = subpriv;
1450 s->type = COMEDI_SUBD_COUNTER;
1451 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1452 s->n_chan = 3;
1453 s->maxdata = 0xFFFF;
1454 s->insn_read = dio200_subdev_8254_read;
1455 s->insn_write = dio200_subdev_8254_write;
1456 s->insn_config = dio200_subdev_8254_config;
1457
1458 spin_lock_init(&subpriv->spinlock);
1459 subpriv->ofs = offset;
1460 if (layout->has_clk_gat_sce) {
1461
1462
1463 subpriv->clk_sce_ofs = DIO200_XCLK_SCE + (offset >> 3);
1464 subpriv->gat_sce_ofs = DIO200_XGAT_SCE + (offset >> 3);
1465 subpriv->which = (offset >> 2) & 1;
1466 }
1467
1468
1469 for (chan = 0; chan < 3; chan++) {
1470 dio200_subdev_8254_set_mode(dev, s, chan,
1471 I8254_MODE0 | I8254_BINARY);
1472 if (layout->has_clk_gat_sce) {
1473
1474 dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
1475
1476 dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
1477 }
1478 }
1479
1480 return 0;
1481}
1482
1483
1484
1485
1486static void
1487dio200_subdev_8254_cleanup(struct comedi_device *dev,
1488 struct comedi_subdevice *s)
1489{
1490 struct dio200_subdev_intr *subpriv = s->private;
1491 kfree(subpriv);
1492}
1493
1494
1495
1496
1497static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
1498 struct comedi_subdevice *s)
1499{
1500 struct dio200_subdev_8255 *subpriv = s->private;
1501 int config;
1502
1503 config = CR_CW;
1504
1505 if (!(s->io_bits & 0x0000ff))
1506 config |= CR_A_IO;
1507 if (!(s->io_bits & 0x00ff00))
1508 config |= CR_B_IO;
1509 if (!(s->io_bits & 0x0f0000))
1510 config |= CR_C_LO_IO;
1511 if (!(s->io_bits & 0xf00000))
1512 config |= CR_C_HI_IO;
1513 dio200_write8(dev, subpriv->ofs + 3, config);
1514}
1515
1516
1517
1518
1519static int dio200_subdev_8255_bits(struct comedi_device *dev,
1520 struct comedi_subdevice *s,
1521 struct comedi_insn *insn, unsigned int *data)
1522{
1523 struct dio200_subdev_8255 *subpriv = s->private;
1524
1525 if (data[0]) {
1526 s->state &= ~data[0];
1527 s->state |= (data[0] & data[1]);
1528 if (data[0] & 0xff)
1529 dio200_write8(dev, subpriv->ofs, s->state & 0xff);
1530 if (data[0] & 0xff00)
1531 dio200_write8(dev, subpriv->ofs + 1,
1532 (s->state >> 8) & 0xff);
1533 if (data[0] & 0xff0000)
1534 dio200_write8(dev, subpriv->ofs + 2,
1535 (s->state >> 16) & 0xff);
1536 }
1537 data[1] = dio200_read8(dev, subpriv->ofs);
1538 data[1] |= dio200_read8(dev, subpriv->ofs + 1) << 8;
1539 data[1] |= dio200_read8(dev, subpriv->ofs + 2) << 16;
1540 return 2;
1541}
1542
1543
1544
1545
1546static int dio200_subdev_8255_config(struct comedi_device *dev,
1547 struct comedi_subdevice *s,
1548 struct comedi_insn *insn,
1549 unsigned int *data)
1550{
1551 unsigned int mask;
1552 unsigned int bits;
1553
1554 mask = 1 << CR_CHAN(insn->chanspec);
1555 if (mask & 0x0000ff)
1556 bits = 0x0000ff;
1557 else if (mask & 0x00ff00)
1558 bits = 0x00ff00;
1559 else if (mask & 0x0f0000)
1560 bits = 0x0f0000;
1561 else
1562 bits = 0xf00000;
1563 switch (data[0]) {
1564 case INSN_CONFIG_DIO_INPUT:
1565 s->io_bits &= ~bits;
1566 break;
1567 case INSN_CONFIG_DIO_OUTPUT:
1568 s->io_bits |= bits;
1569 break;
1570 case INSN_CONFIG_DIO_QUERY:
1571 data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
1572 return insn->n;
1573 break;
1574 default:
1575 return -EINVAL;
1576 }
1577 dio200_subdev_8255_set_dir(dev, s);
1578 return 1;
1579}
1580
1581
1582
1583
1584
1585
1586static int dio200_subdev_8255_init(struct comedi_device *dev,
1587 struct comedi_subdevice *s,
1588 unsigned int offset)
1589{
1590 struct dio200_subdev_8255 *subpriv;
1591
1592 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1593 if (!subpriv)
1594 return -ENOMEM;
1595 subpriv->ofs = offset;
1596 s->private = subpriv;
1597 s->type = COMEDI_SUBD_DIO;
1598 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1599 s->n_chan = 24;
1600 s->range_table = &range_digital;
1601 s->maxdata = 1;
1602 s->insn_bits = dio200_subdev_8255_bits;
1603 s->insn_config = dio200_subdev_8255_config;
1604 s->state = 0;
1605 s->io_bits = 0;
1606 dio200_subdev_8255_set_dir(dev, s);
1607 return 0;
1608}
1609
1610
1611
1612
1613static void dio200_subdev_8255_cleanup(struct comedi_device *dev,
1614 struct comedi_subdevice *s)
1615{
1616 struct dio200_subdev_8255 *subpriv = s->private;
1617
1618 kfree(subpriv);
1619}
1620
1621
1622
1623
1624static int dio200_subdev_timer_read(struct comedi_device *dev,
1625 struct comedi_subdevice *s,
1626 struct comedi_insn *insn,
1627 unsigned int *data)
1628{
1629 unsigned int n;
1630
1631 for (n = 0; n < insn->n; n++)
1632 data[n] = dio200_read32(dev, DIO200_TS_COUNT);
1633 return n;
1634}
1635
1636
1637
1638
1639static void dio200_subdev_timer_reset(struct comedi_device *dev,
1640 struct comedi_subdevice *s)
1641{
1642 unsigned int clock;
1643
1644 clock = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
1645 dio200_write32(dev, DIO200_TS_CONFIG, clock | TS_CONFIG_RESET);
1646 dio200_write32(dev, DIO200_TS_CONFIG, clock);
1647}
1648
1649
1650
1651
1652static void dio200_subdev_timer_get_clock_src(struct comedi_device *dev,
1653 struct comedi_subdevice *s,
1654 unsigned int *src,
1655 unsigned int *period)
1656{
1657 unsigned int clk;
1658
1659 clk = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
1660 *src = clk;
1661 *period = (clk < ARRAY_SIZE(ts_clock_period)) ?
1662 ts_clock_period[clk] : 0;
1663}
1664
1665
1666
1667
1668static int dio200_subdev_timer_set_clock_src(struct comedi_device *dev,
1669 struct comedi_subdevice *s,
1670 unsigned int src)
1671{
1672 if (src > TS_CONFIG_MAX_CLK_SRC)
1673 return -EINVAL;
1674 dio200_write32(dev, DIO200_TS_CONFIG, src);
1675 return 0;
1676}
1677
1678
1679
1680
1681static int dio200_subdev_timer_config(struct comedi_device *dev,
1682 struct comedi_subdevice *s,
1683 struct comedi_insn *insn,
1684 unsigned int *data)
1685{
1686 int ret = 0;
1687
1688 switch (data[0]) {
1689 case INSN_CONFIG_RESET:
1690 dio200_subdev_timer_reset(dev, s);
1691 break;
1692 case INSN_CONFIG_SET_CLOCK_SRC:
1693 ret = dio200_subdev_timer_set_clock_src(dev, s, data[1]);
1694 if (ret < 0)
1695 ret = -EINVAL;
1696 break;
1697 case INSN_CONFIG_GET_CLOCK_SRC:
1698 dio200_subdev_timer_get_clock_src(dev, s, &data[1], &data[2]);
1699 break;
1700 default:
1701 ret = -EINVAL;
1702 break;
1703 }
1704 return ret < 0 ? ret : insn->n;
1705}
1706
1707
1708
1709
1710
1711
1712static int dio200_subdev_timer_init(struct comedi_device *dev,
1713 struct comedi_subdevice *s)
1714{
1715 s->type = COMEDI_SUBD_TIMER;
1716 s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
1717 s->n_chan = 1;
1718 s->maxdata = 0xFFFFFFFF;
1719 s->insn_read = dio200_subdev_timer_read;
1720 s->insn_config = dio200_subdev_timer_config;
1721 return 0;
1722}
1723
1724
1725
1726
1727static void dio200_subdev_timer_cleanup(struct comedi_device *dev,
1728 struct comedi_subdevice *s)
1729{
1730
1731}
1732
1733
1734
1735
1736
1737static int dio200_pcie_board_setup(struct comedi_device *dev)
1738{
1739 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1740 void __iomem *brbase;
1741 resource_size_t brlen;
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753 brlen = pci_resource_len(pcidev, 0);
1754 if (brlen < 0x4000 ||
1755 !(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) {
1756 dev_err(dev->class_dev, "error! bad PCI region!\n");
1757 return -EINVAL;
1758 }
1759 brbase = ioremap_nocache(pci_resource_start(pcidev, 0), brlen);
1760 if (!brbase) {
1761 dev_err(dev->class_dev, "error! failed to map registers!\n");
1762 return -ENOMEM;
1763 }
1764 writel(0x80, brbase + 0x50);
1765 iounmap(brbase);
1766
1767 dio200_write8(dev, DIO200_ENHANCE, 1);
1768 return 0;
1769}
1770
1771static void dio200_report_attach(struct comedi_device *dev, unsigned int irq)
1772{
1773 const struct dio200_board *thisboard = comedi_board(dev);
1774 struct dio200_private *devpriv = dev->private;
1775 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1776 char tmpbuf[60];
1777 int tmplen;
1778
1779 if (is_isa_board(thisboard))
1780 tmplen = scnprintf(tmpbuf, sizeof(tmpbuf),
1781 "(base %#lx) ", devpriv->io.u.iobase);
1782 else if (is_pci_board(thisboard))
1783 tmplen = scnprintf(tmpbuf, sizeof(tmpbuf),
1784 "(pci %s) ", pci_name(pcidev));
1785 else
1786 tmplen = 0;
1787 if (irq)
1788 tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen,
1789 "(irq %u%s) ", irq,
1790 (dev->irq ? "" : " UNAVAILABLE"));
1791 else
1792 tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen,
1793 "(no irq) ");
1794 dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf);
1795}
1796
1797static int dio200_common_attach(struct comedi_device *dev, unsigned int irq,
1798 unsigned long req_irq_flags)
1799{
1800 const struct dio200_board *thisboard = comedi_board(dev);
1801 struct dio200_private *devpriv = dev->private;
1802 const struct dio200_layout *layout = dio200_board_layout(thisboard);
1803 struct comedi_subdevice *s;
1804 int sdx;
1805 unsigned int n;
1806 int ret;
1807
1808 devpriv->intr_sd = -1;
1809 dev->board_name = thisboard->name;
1810
1811 ret = comedi_alloc_subdevices(dev, layout->n_subdevs);
1812 if (ret)
1813 return ret;
1814
1815 for (n = 0; n < dev->n_subdevices; n++) {
1816 s = &dev->subdevices[n];
1817 switch (layout->sdtype[n]) {
1818 case sd_8254:
1819
1820 ret = dio200_subdev_8254_init(dev, s,
1821 layout->sdinfo[n]);
1822 if (ret < 0)
1823 return ret;
1824 break;
1825 case sd_8255:
1826
1827 ret = dio200_subdev_8255_init(dev, s,
1828 layout->sdinfo[n]);
1829 if (ret < 0)
1830 return ret;
1831 break;
1832 case sd_intr:
1833
1834 if (irq) {
1835 ret = dio200_subdev_intr_init(dev, s,
1836 DIO200_INT_SCE,
1837 layout->sdinfo[n]
1838 );
1839 if (ret < 0)
1840 return ret;
1841 devpriv->intr_sd = n;
1842 } else {
1843 s->type = COMEDI_SUBD_UNUSED;
1844 }
1845 break;
1846 case sd_timer:
1847
1848 if (DO_PCI) {
1849 ret = dio200_subdev_timer_init(dev, s);
1850 if (ret < 0)
1851 return ret;
1852 } else {
1853 s->type = COMEDI_SUBD_UNUSED;
1854 }
1855 break;
1856 default:
1857 s->type = COMEDI_SUBD_UNUSED;
1858 break;
1859 }
1860 }
1861 sdx = devpriv->intr_sd;
1862 if (sdx >= 0 && sdx < dev->n_subdevices)
1863 dev->read_subdev = &dev->subdevices[sdx];
1864 if (irq) {
1865 if (request_irq(irq, dio200_interrupt, req_irq_flags,
1866 DIO200_DRIVER_NAME, dev) >= 0) {
1867 dev->irq = irq;
1868 } else {
1869 dev_warn(dev->class_dev,
1870 "warning! irq %u unavailable!\n", irq);
1871 }
1872 }
1873 dio200_report_attach(dev, irq);
1874 return 1;
1875}
1876
1877
1878
1879
1880
1881
1882
1883static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1884{
1885 const struct dio200_board *thisboard = comedi_board(dev);
1886 struct dio200_private *devpriv;
1887 int ret;
1888
1889 dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach\n");
1890
1891 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1892 if (!devpriv)
1893 return -ENOMEM;
1894 dev->private = devpriv;
1895
1896
1897 if (is_isa_board(thisboard)) {
1898 unsigned long iobase;
1899 unsigned int irq;
1900
1901 iobase = it->options[0];
1902 irq = it->options[1];
1903 ret = dio200_request_region(dev, iobase, thisboard->mainsize);
1904 if (ret < 0)
1905 return ret;
1906 devpriv->io.u.iobase = iobase;
1907 devpriv->io.regtype = io_regtype;
1908 return dio200_common_attach(dev, irq, 0);
1909 } else if (is_pci_board(thisboard)) {
1910 dev_err(dev->class_dev,
1911 "Manual configuration of PCI board '%s' is not supported\n",
1912 thisboard->name);
1913 return -EIO;
1914 } else {
1915 dev_err(dev->class_dev, DIO200_DRIVER_NAME
1916 ": BUG! cannot determine board type!\n");
1917 return -EINVAL;
1918 }
1919}
1920
1921
1922
1923
1924
1925
1926static int dio200_auto_attach(struct comedi_device *dev,
1927 unsigned long context_unused)
1928{
1929 struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
1930 const struct dio200_board *thisboard;
1931 struct dio200_private *devpriv;
1932 resource_size_t base, len;
1933 unsigned int bar;
1934 int ret;
1935
1936 if (!DO_PCI)
1937 return -EINVAL;
1938
1939 dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach pci %s\n",
1940 pci_name(pci_dev));
1941
1942 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1943 if (!devpriv)
1944 return -ENOMEM;
1945 dev->private = devpriv;
1946
1947 dev->board_ptr = dio200_find_pci_board(pci_dev);
1948 if (dev->board_ptr == NULL) {
1949 dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
1950 return -EINVAL;
1951 }
1952 thisboard = comedi_board(dev);
1953 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1954 if (ret < 0) {
1955 dev_err(dev->class_dev,
1956 "error! cannot enable PCI device and request regions!\n");
1957 return ret;
1958 }
1959 bar = thisboard->mainbar;
1960 base = pci_resource_start(pci_dev, bar);
1961 len = pci_resource_len(pci_dev, bar);
1962 if (len < thisboard->mainsize) {
1963 dev_err(dev->class_dev, "error! PCI region size too small!\n");
1964 return -EINVAL;
1965 }
1966 if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) {
1967 devpriv->io.u.membase = ioremap_nocache(base, len);
1968 if (!devpriv->io.u.membase) {
1969 dev_err(dev->class_dev,
1970 "error! cannot remap registers\n");
1971 return -ENOMEM;
1972 }
1973 devpriv->io.regtype = mmio_regtype;
1974 } else {
1975 devpriv->io.u.iobase = (unsigned long)base;
1976 devpriv->io.regtype = io_regtype;
1977 }
1978 switch (thisboard->model) {
1979 case pcie215_model:
1980 case pcie236_model:
1981 case pcie296_model:
1982 ret = dio200_pcie_board_setup(dev);
1983 if (ret < 0)
1984 return ret;
1985 break;
1986 default:
1987 break;
1988 }
1989 return dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED);
1990}
1991
1992static void dio200_detach(struct comedi_device *dev)
1993{
1994 const struct dio200_board *thisboard = comedi_board(dev);
1995 struct dio200_private *devpriv = dev->private;
1996 const struct dio200_layout *layout;
1997 unsigned n;
1998
1999 if (!thisboard || !devpriv)
2000 return;
2001 if (dev->irq)
2002 free_irq(dev->irq, dev);
2003 if (dev->subdevices) {
2004 layout = dio200_board_layout(thisboard);
2005 for (n = 0; n < dev->n_subdevices; n++) {
2006 struct comedi_subdevice *s = &dev->subdevices[n];
2007 switch (layout->sdtype[n]) {
2008 case sd_8254:
2009 dio200_subdev_8254_cleanup(dev, s);
2010 break;
2011 case sd_8255:
2012 dio200_subdev_8255_cleanup(dev, s);
2013 break;
2014 case sd_intr:
2015 dio200_subdev_intr_cleanup(dev, s);
2016 break;
2017 case sd_timer:
2018
2019 if (DO_PCI)
2020 dio200_subdev_timer_cleanup(dev, s);
2021 break;
2022 default:
2023 break;
2024 }
2025 }
2026 }
2027 if (is_isa_board(thisboard)) {
2028 if (devpriv->io.regtype == io_regtype)
2029 release_region(devpriv->io.u.iobase,
2030 thisboard->mainsize);
2031 } else if (is_pci_board(thisboard)) {
2032 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2033 if (pcidev) {
2034 if (devpriv->io.regtype != no_regtype) {
2035 if (devpriv->io.regtype == mmio_regtype)
2036 iounmap(devpriv->io.u.membase);
2037 comedi_pci_disable(pcidev);
2038 }
2039 }
2040 }
2041}
2042
2043
2044
2045
2046
2047
2048
2049static struct comedi_driver amplc_dio200_driver = {
2050 .driver_name = DIO200_DRIVER_NAME,
2051 .module = THIS_MODULE,
2052 .attach = dio200_attach,
2053 .auto_attach = dio200_auto_attach,
2054 .detach = dio200_detach,
2055 .board_name = &dio200_boards[0].name,
2056 .offset = sizeof(struct dio200_board),
2057 .num_names = ARRAY_SIZE(dio200_boards),
2058};
2059
2060#if DO_PCI
2061static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
2062 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) },
2063 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) },
2064 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236) },
2065 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215) },
2066 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296) },
2067 {0}
2068};
2069
2070MODULE_DEVICE_TABLE(pci, dio200_pci_table);
2071
2072static int amplc_dio200_pci_probe(struct pci_dev *dev,
2073 const struct pci_device_id
2074 *ent)
2075{
2076 return comedi_pci_auto_config(dev, &lc_dio200_driver);
2077}
2078
2079static struct pci_driver amplc_dio200_pci_driver = {
2080 .name = DIO200_DRIVER_NAME,
2081 .id_table = dio200_pci_table,
2082 .probe = &lc_dio200_pci_probe,
2083 .remove = comedi_pci_auto_unconfig,
2084};
2085module_comedi_pci_driver(amplc_dio200_driver, amplc_dio200_pci_driver);
2086#else
2087module_comedi_driver(amplc_dio200_driver);
2088#endif
2089
2090MODULE_AUTHOR("Comedi http://www.comedi.org");
2091MODULE_DESCRIPTION("Comedi low-level driver");
2092MODULE_LICENSE("GPL");
2093