113 #include "../comedidev.h"
124 #define boardPCL812PG 0
125 #define boardPCL813B 1
126 #define boardPCL812 2
127 #define boardPCL813 3
128 #define boardISO813 5
129 #define boardACL8113 6
130 #define boardACL8112 7
131 #define boardACL8216 8
134 #define PCLx1x_IORANGE 16
136 #define PCL812_CTR0 0
137 #define PCL812_CTR1 1
138 #define PCL812_CTR2 2
139 #define PCL812_CTRCTL 3
140 #define PCL812_AD_LO 4
141 #define PCL812_DA1_LO 4
142 #define PCL812_AD_HI 5
143 #define PCL812_DA1_HI 5
144 #define PCL812_DA2_LO 6
145 #define PCL812_DI_LO 6
146 #define PCL812_DA2_HI 7
147 #define PCL812_DI_HI 7
148 #define PCL812_CLRINT 8
149 #define PCL812_GAIN 9
150 #define PCL812_MUX 10
151 #define PCL812_MODE 11
152 #define PCL812_CNTENABLE 10
153 #define PCL812_SOFTTRIG 12
154 #define PCL812_DO_LO 13
155 #define PCL812_DO_HI 14
157 #define PCL812_DRDY 0x10
159 #define ACL8216_STATUS 8
161 #define ACL8216_DRDY 0x20
163 #define MAX_CHANLIST_LEN 256
174 static const struct comedi_lrange range_pcl812pg2_ai = { 5, {
183 static const struct comedi_lrange range812_bipolar1_25 = { 1, {
188 static const struct comedi_lrange range812_bipolar0_625 = { 1, {
194 static const struct comedi_lrange range812_bipolar0_3125 = { 1, {
225 static const struct comedi_lrange range_iso813_1_2_ai = { 5, {
242 static const struct comedi_lrange range_iso813_2_2_ai = { 4, {
250 static const struct comedi_lrange range_acl8113_1_ai = { 4, {
258 static const struct comedi_lrange range_acl8113_1_2_ai = { 4, {
266 static const struct comedi_lrange range_acl8113_2_ai = { 3, {
273 static const struct comedi_lrange range_acl8113_2_2_ai = { 3, {
280 static const struct comedi_lrange range_acl8112dg_ai = { 9, {
293 static const struct comedi_lrange range_acl8112hg_ai = { 12, {
372 #define devpriv ((struct pcl812_private *)dev->private)
378 unsigned int divisor1,
unsigned int divisor2);
381 unsigned int rangechan,
char wait);
397 setup_range_channel(dev, s, insn->
chanspec, 1);
398 for (n = 0; n < insn->
n; n++) {
410 (
"comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
435 setup_range_channel(dev, s, insn->
chanspec, 1);
436 for (n = 0; n < insn->
n; n++) {
447 (
"comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
471 for (i = 0; i < insn->
n; i++) {
472 outb((data[i] & 0xff),
474 outb((data[i] >> 8) & 0x0f,
476 devpriv->ao_readback[chan] = data[
i];
492 for (i = 0; i < insn->
n; i++)
493 data[i] =
devpriv->ao_readback[chan];
519 s->
state &= ~data[0];
520 s->
state |= data[0] & data[1];
538 int tmp, divisor1, divisor2;
549 err |= cfc_check_trigger_src(&cmd->
convert_src, flags);
559 err |= cfc_check_trigger_is_unique(cmd->
stop_src);
642 unsigned int divisor1 = 0, divisor2 = 0,
i, dma_flags,
bytes;
667 &divisor1, &divisor2,
672 start_pacer(dev, -1, 0, 0);
678 setup_range_channel(dev, s,
devpriv->ai_chanlist[0], 1);
682 for (i = 1; i <
devpriv->ai_n_chan; i++)
704 s->
async->cur_chan = 0;
741 bytes /
devpriv->dmabytestomove[0];
745 bytes %
devpriv->dmabytestomove[0];
746 if (
devpriv->dma_runs_to_end == 0)
772 start_pacer(dev, 1, divisor1, divisor2);
787 static irqreturn_t interrupt_pcl812_ai_int(
int irq,
void *
d)
790 unsigned int mask, timeout;
793 unsigned int next_chan;
795 s->
async->events = 0;
820 (
"comedi%d: pcl812: (%s at 0x%lx) "
821 "A/D cmd IRQ without DRDY!\n",
823 pcl812_ai_cancel(dev, s);
834 next_chan = s->
async->cur_chan + 1;
835 if (next_chan >=
devpriv->ai_n_chan)
838 devpriv->ai_chanlist[next_chan])
839 setup_range_channel(dev, s,
devpriv->ai_chanlist[next_chan], 0);
843 s->
async->cur_chan = next_chan;
844 if (next_chan == 0) {
846 if (!(
devpriv->ai_neverending))
849 pcl812_ai_cancel(dev, s);
863 unsigned int bufptr,
unsigned int len)
867 s->
async->events = 0;
868 for (i = len;
i; i--) {
872 s->
async->cur_chan++;
874 s->
async->cur_chan = 0;
879 pcl812_ai_cancel(dev, s);
892 static irqreturn_t interrupt_pcl812_ai_dma(
int irq,
void *d)
896 unsigned long dma_flags;
913 if (
devpriv->dma_runs_to_end) {
930 transfer_from_dma_buf(dev, s, ptr, bufptr, len);
938 static irqreturn_t interrupt_pcl812(
int irq,
void *d)
947 return interrupt_pcl812_ai_dma(irq, d);
949 return interrupt_pcl812_ai_int(irq, d);
958 unsigned int top1, top2,
i;
965 for (i = 0; i < 10; i++) {
974 spin_unlock_irqrestore(&dev->
spinlock, flags);
980 top2 = top1 -
devpriv->ai_poll_ptr;
982 spin_unlock_irqrestore(&dev->
spinlock, flags);
986 transfer_from_dma_buf(dev, s,
993 spin_unlock_irqrestore(&dev->
spinlock, flags);
995 return s->
async->buf_write_count - s->
async->buf_read_count;
1003 unsigned int rangechan,
char wait)
1005 unsigned char chan_reg =
CR_CHAN(rangechan);
1007 unsigned char gain_reg =
CR_RANGE(rangechan) +
1010 if ((chan_reg ==
devpriv->old_chan_reg)
1011 && (gain_reg ==
devpriv->old_gain_reg))
1014 devpriv->old_chan_reg = chan_reg;
1015 devpriv->old_gain_reg = gain_reg;
1019 chan_reg = chan_reg | 0x30;
1021 if (chan_reg & 0x80)
1023 chan_reg = chan_reg | 0x20;
1026 chan_reg = chan_reg | 0x10;
1046 unsigned int divisor1,
unsigned int divisor2)
1092 start_pacer(dev, -1, 0, 0);
1119 start_pacer(dev, -1, 0, 0);
1142 unsigned long pages;
1151 printk(
"I/O port conflict\n");
1158 free_resources(dev);
1168 if (((1 << irq) & board->
IRQbits) == 0) {
1170 (
", IRQ %u is out of allowed range, "
1171 "DISABLING IT", irq);
1175 (irq, interrupt_pcl812, 0,
"pcl812", dev)) {
1177 (
", unable to allocate IRQ %u, "
1178 "DISABLING IT", irq);
1195 if (((1 << dma) & board->
DMAbits) == 0) {
1196 printk(
", DMA is out of allowed range, FAIL!\n");
1210 printk(
", unable to allocate DMA buffer, FAIL!\n");
1215 free_resources(dev);
1224 free_resources(dev);
1245 free_resources(dev);
1292 s->
cancel = pcl812_ai_cancel;
1297 s->
do_cmd = pcl812_ai_cmd;
1298 s->
poll = pcl812_ai_poll;
1329 (
", incorrect range number %d, changing "
1330 "to 0 (+/-10V)", it->
options[4]);
1349 devpriv->range_correction = 1;
1353 devpriv->range_correction = 1;
1359 (
", incorrect range number %d, "
1360 "changing to 0 ", it->
options[1]);
1374 devpriv->range_correction = 1;
1378 devpriv->range_correction = 1;
1384 (
", incorrect range number %d, "
1385 "changing to 0 ", it->
options[1]);
1454 devpriv->max_812_ai_mode0_rangewait = 1;
1459 devpriv->max_812_ai_mode0_rangewait = 1;
1460 devpriv->mode_reg_int = (irq << 4) & 0xf0;
1467 devpriv->max_812_ai_mode0_rangewait = 5;
1481 free_resources(dev);
1500 {
"a821pgl",
boardA821, 16, 8, 1, 16, 16, 0x0fff,
1503 {
"a821pglnda",
boardA821, 16, 8, 0, 0, 0, 0x0fff,
1504 10000, 500, &range_pcl813b_ai,
NULL,
1506 {
"a821pgh",
boardA821, 16, 8, 1, 16, 16, 0x0fff,
1522 0, 0, &range_pcl813b_ai,
NULL,
1525 0, 0, &range_pcl813b_ai,
NULL,
1528 0, 0, &range_acl8113_1_ai,
NULL,
1531 0, 0, &range_iso813_1_ai,
NULL,
1542 .driver_name =
"pcl812",
1544 .attach = pcl812_attach,
1545 .detach = pcl812_detach,
1546 .board_name = &boardtypes[0].
name,