3 * Anders Gnistrup <ex18@kalman.iau.dtu.dk>
5 * COMEDI - Linux Control and Measurement Device Interface
6 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
21 * Description: unknown
22 * Author: Anders Gnistrup <ex18@kalman.iau.dtu.dk>
23 * Devices: [unknown] FL512 (fl512)
26 * Digital I/O is not supported.
28 * Configuration options:
29 * [0] - I/O port base address
32 #include <linux/module.h>
33 #include "../comedidev.h"
35 #include <linux/delay.h>
40 #define FL512_AI_LSB_REG 0x02
41 #define FL512_AI_MSB_REG 0x03
42 #define FL512_AI_MUX_REG 0x02
43 #define FL512_AI_START_CONV_REG 0x03
44 #define FL512_AO_DATA_REG(x) (0x04 + ((x) * 2))
45 #define FL512_AO_TRIG_REG(x) (0x04 + ((x) * 2))
47 static const struct comedi_lrange range_fl512
= {
59 static int fl512_ai_insn_read(struct comedi_device
*dev
,
60 struct comedi_subdevice
*s
,
61 struct comedi_insn
*insn
,
64 unsigned int chan
= CR_CHAN(insn
->chanspec
);
68 outb(chan
, dev
->iobase
+ FL512_AI_MUX_REG
);
70 for (i
= 0; i
< insn
->n
; i
++) {
71 outb(0, dev
->iobase
+ FL512_AI_START_CONV_REG
);
73 /* XXX should test "done" flag instead of delay */
74 usleep_range(30, 100);
76 val
= inb(dev
->iobase
+ FL512_AI_LSB_REG
);
77 val
|= (inb(dev
->iobase
+ FL512_AI_MSB_REG
) << 8);
86 static int fl512_ao_insn_write(struct comedi_device
*dev
,
87 struct comedi_subdevice
*s
,
88 struct comedi_insn
*insn
,
91 unsigned int chan
= CR_CHAN(insn
->chanspec
);
92 unsigned int val
= s
->readback
[chan
];
95 for (i
= 0; i
< insn
->n
; i
++) {
98 /* write LSB, MSB then trigger conversion */
99 outb(val
& 0x0ff, dev
->iobase
+ FL512_AO_DATA_REG(chan
));
100 outb((val
>> 8) & 0xf, dev
->iobase
+ FL512_AO_DATA_REG(chan
));
101 inb(dev
->iobase
+ FL512_AO_TRIG_REG(chan
));
103 s
->readback
[chan
] = val
;
108 static int fl512_attach(struct comedi_device
*dev
, struct comedi_devconfig
*it
)
110 struct comedi_subdevice
*s
;
113 ret
= comedi_request_region(dev
, it
->options
[0], 0x10);
117 ret
= comedi_alloc_subdevices(dev
, 2);
121 /* Analog Input subdevice */
122 s
= &dev
->subdevices
[0];
123 s
->type
= COMEDI_SUBD_AI
;
124 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
;
127 s
->range_table
= &range_fl512
;
128 s
->insn_read
= fl512_ai_insn_read
;
130 /* Analog Output subdevice */
131 s
= &dev
->subdevices
[1];
132 s
->type
= COMEDI_SUBD_AO
;
133 s
->subdev_flags
= SDF_WRITABLE
;
136 s
->range_table
= &range_fl512
;
137 s
->insn_write
= fl512_ao_insn_write
;
139 return comedi_alloc_subdev_readback(s
);
142 static struct comedi_driver fl512_driver
= {
143 .driver_name
= "fl512",
144 .module
= THIS_MODULE
,
145 .attach
= fl512_attach
,
146 .detach
= comedi_legacy_detach
,
148 module_comedi_driver(fl512_driver
);
150 MODULE_AUTHOR("Comedi http://www.comedi.org");
151 MODULE_DESCRIPTION("Comedi low-level driver");
152 MODULE_LICENSE("GPL");