1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * comedi/drivers/pcl812.c 4 * 5 * Author: Michal Dobes <dobes@tesnet.cz> 6 * 7 * hardware driver for Advantech cards 8 * card: PCL-812, PCL-812PG, PCL-813, PCL-813B 9 * driver: pcl812, pcl812pg, pcl813, pcl813b 10 * and for ADlink cards 11 * card: ACL-8112DG, ACL-8112HG, ACL-8112PG, ACL-8113, ACL-8216 12 * driver: acl8112dg, acl8112hg, acl8112pg, acl8113, acl8216 13 * and for ICP DAS cards 14 * card: ISO-813, A-821PGH, A-821PGL, A-821PGL-NDA, A-822PGH, A-822PGL, 15 * driver: iso813, a821pgh, a-821pgl, a-821pglnda, a822pgh, a822pgl, 16 * card: A-823PGH, A-823PGL, A-826PG 17 * driver: a823pgh, a823pgl, a826pg 18 */ 19 20 /* 21 * Driver: pcl812 22 * Description: Advantech PCL-812/PG, PCL-813/B, 23 * ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216, 24 * ICP DAS A-821PGH/PGL/PGL-NDA, A-822PGH/PGL, A-823PGH/PGL, A-826PG, 25 * ICP DAS ISO-813 26 * Author: Michal Dobes <dobes@tesnet.cz> 27 * Devices: [Advantech] PCL-812 (pcl812), PCL-812PG (pcl812pg), 28 * PCL-813 (pcl813), PCL-813B (pcl813b), [ADLink] ACL-8112DG (acl8112dg), 29 * ACL-8112HG (acl8112hg), ACL-8113 (acl-8113), ACL-8216 (acl8216), 30 * [ICP] ISO-813 (iso813), A-821PGH (a821pgh), A-821PGL (a821pgl), 31 * A-821PGL-NDA (a821pclnda), A-822PGH (a822pgh), A-822PGL (a822pgl), 32 * A-823PGH (a823pgh), A-823PGL (a823pgl), A-826PG (a826pg) 33 * Updated: Mon, 06 Aug 2007 12:03:15 +0100 34 * Status: works (I hope. My board fire up under my hands 35 * and I cann't test all features.) 36 * 37 * This driver supports insn and cmd interfaces. Some boards support only insn 38 * because their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813). 39 * Data transfer over DMA is supported only when you measure only one 40 * channel, this is too hardware limitation of these boards. 41 * 42 * Options for PCL-812: 43 * [0] - IO Base 44 * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15) 45 * [2] - DMA (0=disable, 1, 3) 46 * [3] - 0=trigger source is internal 8253 with 2MHz clock 47 * 1=trigger source is external 48 * [4] - 0=A/D input range is +/-10V 49 * 1=A/D input range is +/-5V 50 * 2=A/D input range is +/-2.5V 51 * 3=A/D input range is +/-1.25V 52 * 4=A/D input range is +/-0.625V 53 * 5=A/D input range is +/-0.3125V 54 * [5] - 0=D/A outputs 0-5V (internal reference -5V) 55 * 1=D/A outputs 0-10V (internal reference -10V) 56 * 2=D/A outputs unknown (external reference) 57 * 58 * Options for PCL-812PG, ACL-8112PG: 59 * [0] - IO Base 60 * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15) 61 * [2] - DMA (0=disable, 1, 3) 62 * [3] - 0=trigger source is internal 8253 with 2MHz clock 63 * 1=trigger source is external 64 * [4] - 0=A/D have max +/-5V input 65 * 1=A/D have max +/-10V input 66 * [5] - 0=D/A outputs 0-5V (internal reference -5V) 67 * 1=D/A outputs 0-10V (internal reference -10V) 68 * 2=D/A outputs unknown (external reference) 69 * 70 * Options for ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH, ACL-8216, A-826PG: 71 * [0] - IO Base 72 * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15) 73 * [2] - DMA (0=disable, 1, 3) 74 * [3] - 0=trigger source is internal 8253 with 2MHz clock 75 * 1=trigger source is external 76 * [4] - 0=A/D channels are S.E. 77 * 1=A/D channels are DIFF 78 * [5] - 0=D/A outputs 0-5V (internal reference -5V) 79 * 1=D/A outputs 0-10V (internal reference -10V) 80 * 2=D/A outputs unknown (external reference) 81 * 82 * Options for A-821PGL/PGH: 83 * [0] - IO Base 84 * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7) 85 * [2] - 0=A/D channels are S.E. 86 * 1=A/D channels are DIFF 87 * [3] - 0=D/A output 0-5V (internal reference -5V) 88 * 1=D/A output 0-10V (internal reference -10V) 89 * 90 * Options for A-821PGL-NDA: 91 * [0] - IO Base 92 * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7) 93 * [2] - 0=A/D channels are S.E. 94 * 1=A/D channels are DIFF 95 * 96 * Options for PCL-813: 97 * [0] - IO Base 98 * 99 * Options for PCL-813B: 100 * [0] - IO Base 101 * [1] - 0= bipolar inputs 102 * 1= unipolar inputs 103 * 104 * Options for ACL-8113, ISO-813: 105 * [0] - IO Base 106 * [1] - 0= 10V bipolar inputs 107 * 1= 10V unipolar inputs 108 * 2= 20V bipolar inputs 109 * 3= 20V unipolar inputs 110 */ 111 112 #include <linux/module.h> 113 #include <linux/interrupt.h> 114 #include <linux/gfp.h> 115 #include <linux/delay.h> 116 #include <linux/io.h> 117 118 #include "../comedidev.h" 119 120 #include "comedi_isadma.h" 121 #include "comedi_8254.h" 122 123 /* 124 * Register I/O map 125 */ 126 #define PCL812_TIMER_BASE 0x00 127 #define PCL812_AI_LSB_REG 0x04 128 #define PCL812_AI_MSB_REG 0x05 129 #define PCL812_AI_MSB_DRDY BIT(4) 130 #define PCL812_AO_LSB_REG(x) (0x04 + ((x) * 2)) 131 #define PCL812_AO_MSB_REG(x) (0x05 + ((x) * 2)) 132 #define PCL812_DI_LSB_REG 0x06 133 #define PCL812_DI_MSB_REG 0x07 134 #define PCL812_STATUS_REG 0x08 135 #define PCL812_STATUS_DRDY BIT(5) 136 #define PCL812_RANGE_REG 0x09 137 #define PCL812_MUX_REG 0x0a 138 #define PCL812_MUX_CHAN(x) ((x) << 0) 139 #define PCL812_MUX_CS0 BIT(4) 140 #define PCL812_MUX_CS1 BIT(5) 141 #define PCL812_CTRL_REG 0x0b 142 #define PCL812_CTRL_TRIG(x) (((x) & 0x7) << 0) 143 #define PCL812_CTRL_DISABLE_TRIG PCL812_CTRL_TRIG(0) 144 #define PCL812_CTRL_SOFT_TRIG PCL812_CTRL_TRIG(1) 145 #define PCL812_CTRL_PACER_DMA_TRIG PCL812_CTRL_TRIG(2) 146 #define PCL812_CTRL_PACER_EOC_TRIG PCL812_CTRL_TRIG(6) 147 #define PCL812_SOFTTRIG_REG 0x0c 148 #define PCL812_DO_LSB_REG 0x0d 149 #define PCL812_DO_MSB_REG 0x0e 150 151 #define MAX_CHANLIST_LEN 256 /* length of scan list */ 152 153 static const struct comedi_lrange range_pcl812pg_ai = { 154 5, { 155 BIP_RANGE(5), 156 BIP_RANGE(2.5), 157 BIP_RANGE(1.25), 158 BIP_RANGE(0.625), 159 BIP_RANGE(0.3125) 160 } 161 }; 162 163 static const struct comedi_lrange range_pcl812pg2_ai = { 164 5, { 165 BIP_RANGE(10), 166 BIP_RANGE(5), 167 BIP_RANGE(2.5), 168 BIP_RANGE(1.25), 169 BIP_RANGE(0.625) 170 } 171 }; 172 173 static const struct comedi_lrange range812_bipolar1_25 = { 174 1, { 175 BIP_RANGE(1.25) 176 } 177 }; 178 179 static const struct comedi_lrange range812_bipolar0_625 = { 180 1, { 181 BIP_RANGE(0.625) 182 } 183 }; 184 185 static const struct comedi_lrange range812_bipolar0_3125 = { 186 1, { 187 BIP_RANGE(0.3125) 188 } 189 }; 190 191 static const struct comedi_lrange range_pcl813b_ai = { 192 4, { 193 BIP_RANGE(5), 194 BIP_RANGE(2.5), 195 BIP_RANGE(1.25), 196 BIP_RANGE(0.625) 197 } 198 }; 199 200 static const struct comedi_lrange range_pcl813b2_ai = { 201 4, { 202 UNI_RANGE(10), 203 UNI_RANGE(5), 204 UNI_RANGE(2.5), 205 UNI_RANGE(1.25) 206 } 207 }; 208 209 static const struct comedi_lrange range_iso813_1_ai = { 210 5, { 211 BIP_RANGE(5), 212 BIP_RANGE(2.5), 213 BIP_RANGE(1.25), 214 BIP_RANGE(0.625), 215 BIP_RANGE(0.3125) 216 } 217 }; 218 219 static const struct comedi_lrange range_iso813_1_2_ai = { 220 5, { 221 UNI_RANGE(10), 222 UNI_RANGE(5), 223 UNI_RANGE(2.5), 224 UNI_RANGE(1.25), 225 UNI_RANGE(0.625) 226 } 227 }; 228 229 static const struct comedi_lrange range_iso813_2_ai = { 230 4, { 231 BIP_RANGE(5), 232 BIP_RANGE(2.5), 233 BIP_RANGE(1.25), 234 BIP_RANGE(0.625) 235 } 236 }; 237 238 static const struct comedi_lrange range_iso813_2_2_ai = { 239 4, { 240 UNI_RANGE(10), 241 UNI_RANGE(5), 242 UNI_RANGE(2.5), 243 UNI_RANGE(1.25) 244 } 245 }; 246 247 static const struct comedi_lrange range_acl8113_1_ai = { 248 4, { 249 BIP_RANGE(5), 250 BIP_RANGE(2.5), 251 BIP_RANGE(1.25), 252 BIP_RANGE(0.625) 253 } 254 }; 255 256 static const struct comedi_lrange range_acl8113_1_2_ai = { 257 4, { 258 UNI_RANGE(10), 259 UNI_RANGE(5), 260 UNI_RANGE(2.5), 261 UNI_RANGE(1.25) 262 } 263 }; 264 265 static const struct comedi_lrange range_acl8113_2_ai = { 266 3, { 267 BIP_RANGE(5), 268 BIP_RANGE(2.5), 269 BIP_RANGE(1.25) 270 } 271 }; 272 273 static const struct comedi_lrange range_acl8113_2_2_ai = { 274 3, { 275 UNI_RANGE(10), 276 UNI_RANGE(5), 277 UNI_RANGE(2.5) 278 } 279 }; 280 281 static const struct comedi_lrange range_acl8112dg_ai = { 282 9, { 283 BIP_RANGE(5), 284 BIP_RANGE(2.5), 285 BIP_RANGE(1.25), 286 BIP_RANGE(0.625), 287 UNI_RANGE(10), 288 UNI_RANGE(5), 289 UNI_RANGE(2.5), 290 UNI_RANGE(1.25), 291 BIP_RANGE(10) 292 } 293 }; 294 295 static const struct comedi_lrange range_acl8112hg_ai = { 296 12, { 297 BIP_RANGE(5), 298 BIP_RANGE(0.5), 299 BIP_RANGE(0.05), 300 BIP_RANGE(0.005), 301 UNI_RANGE(10), 302 UNI_RANGE(1), 303 UNI_RANGE(0.1), 304 UNI_RANGE(0.01), 305 BIP_RANGE(10), 306 BIP_RANGE(1), 307 BIP_RANGE(0.1), 308 BIP_RANGE(0.01) 309 } 310 }; 311 312 static const struct comedi_lrange range_a821pgh_ai = { 313 4, { 314 BIP_RANGE(5), 315 BIP_RANGE(0.5), 316 BIP_RANGE(0.05), 317 BIP_RANGE(0.005) 318 } 319 }; 320 321 enum pcl812_boardtype { 322 BOARD_PCL812PG = 0, /* and ACL-8112PG */ 323 BOARD_PCL813B = 1, 324 BOARD_PCL812 = 2, 325 BOARD_PCL813 = 3, 326 BOARD_ISO813 = 5, 327 BOARD_ACL8113 = 6, 328 BOARD_ACL8112 = 7, /* ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH */ 329 BOARD_ACL8216 = 8, /* and ICP DAS A-826PG */ 330 BOARD_A821 = 9, /* PGH, PGL, PGL/NDA versions */ 331 }; 332 333 struct pcl812_board { 334 const char *name; 335 enum pcl812_boardtype board_type; 336 int n_aichan; 337 int n_aochan; 338 unsigned int ai_ns_min; 339 const struct comedi_lrange *rangelist_ai; 340 unsigned int irq_bits; 341 unsigned int has_dma:1; 342 unsigned int has_16bit_ai:1; 343 unsigned int has_mpc508_mux:1; 344 unsigned int has_dio:1; 345 }; 346 347 static const struct pcl812_board boardtypes[] = { 348 { 349 .name = "pcl812", 350 .board_type = BOARD_PCL812, 351 .n_aichan = 16, 352 .n_aochan = 2, 353 .ai_ns_min = 33000, 354 .rangelist_ai = &range_bipolar10, 355 .irq_bits = 0xdcfc, 356 .has_dma = 1, 357 .has_dio = 1, 358 }, { 359 .name = "pcl812pg", 360 .board_type = BOARD_PCL812PG, 361 .n_aichan = 16, 362 .n_aochan = 2, 363 .ai_ns_min = 33000, 364 .rangelist_ai = &range_pcl812pg_ai, 365 .irq_bits = 0xdcfc, 366 .has_dma = 1, 367 .has_dio = 1, 368 }, { 369 .name = "acl8112pg", 370 .board_type = BOARD_PCL812PG, 371 .n_aichan = 16, 372 .n_aochan = 2, 373 .ai_ns_min = 10000, 374 .rangelist_ai = &range_pcl812pg_ai, 375 .irq_bits = 0xdcfc, 376 .has_dma = 1, 377 .has_dio = 1, 378 }, { 379 .name = "acl8112dg", 380 .board_type = BOARD_ACL8112, 381 .n_aichan = 16, /* 8 differential */ 382 .n_aochan = 2, 383 .ai_ns_min = 10000, 384 .rangelist_ai = &range_acl8112dg_ai, 385 .irq_bits = 0xdcfc, 386 .has_dma = 1, 387 .has_mpc508_mux = 1, 388 .has_dio = 1, 389 }, { 390 .name = "acl8112hg", 391 .board_type = BOARD_ACL8112, 392 .n_aichan = 16, /* 8 differential */ 393 .n_aochan = 2, 394 .ai_ns_min = 10000, 395 .rangelist_ai = &range_acl8112hg_ai, 396 .irq_bits = 0xdcfc, 397 .has_dma = 1, 398 .has_mpc508_mux = 1, 399 .has_dio = 1, 400 }, { 401 .name = "a821pgl", 402 .board_type = BOARD_A821, 403 .n_aichan = 16, /* 8 differential */ 404 .n_aochan = 1, 405 .ai_ns_min = 10000, 406 .rangelist_ai = &range_pcl813b_ai, 407 .irq_bits = 0x000c, 408 .has_dio = 1, 409 }, { 410 .name = "a821pglnda", 411 .board_type = BOARD_A821, 412 .n_aichan = 16, /* 8 differential */ 413 .ai_ns_min = 10000, 414 .rangelist_ai = &range_pcl813b_ai, 415 .irq_bits = 0x000c, 416 }, { 417 .name = "a821pgh", 418 .board_type = BOARD_A821, 419 .n_aichan = 16, /* 8 differential */ 420 .n_aochan = 1, 421 .ai_ns_min = 10000, 422 .rangelist_ai = &range_a821pgh_ai, 423 .irq_bits = 0x000c, 424 .has_dio = 1, 425 }, { 426 .name = "a822pgl", 427 .board_type = BOARD_ACL8112, 428 .n_aichan = 16, /* 8 differential */ 429 .n_aochan = 2, 430 .ai_ns_min = 10000, 431 .rangelist_ai = &range_acl8112dg_ai, 432 .irq_bits = 0xdcfc, 433 .has_dma = 1, 434 .has_dio = 1, 435 }, { 436 .name = "a822pgh", 437 .board_type = BOARD_ACL8112, 438 .n_aichan = 16, /* 8 differential */ 439 .n_aochan = 2, 440 .ai_ns_min = 10000, 441 .rangelist_ai = &range_acl8112hg_ai, 442 .irq_bits = 0xdcfc, 443 .has_dma = 1, 444 .has_dio = 1, 445 }, { 446 .name = "a823pgl", 447 .board_type = BOARD_ACL8112, 448 .n_aichan = 16, /* 8 differential */ 449 .n_aochan = 2, 450 .ai_ns_min = 8000, 451 .rangelist_ai = &range_acl8112dg_ai, 452 .irq_bits = 0xdcfc, 453 .has_dma = 1, 454 .has_dio = 1, 455 }, { 456 .name = "a823pgh", 457 .board_type = BOARD_ACL8112, 458 .n_aichan = 16, /* 8 differential */ 459 .n_aochan = 2, 460 .ai_ns_min = 8000, 461 .rangelist_ai = &range_acl8112hg_ai, 462 .irq_bits = 0xdcfc, 463 .has_dma = 1, 464 .has_dio = 1, 465 }, { 466 .name = "pcl813", 467 .board_type = BOARD_PCL813, 468 .n_aichan = 32, 469 .rangelist_ai = &range_pcl813b_ai, 470 }, { 471 .name = "pcl813b", 472 .board_type = BOARD_PCL813B, 473 .n_aichan = 32, 474 .rangelist_ai = &range_pcl813b_ai, 475 }, { 476 .name = "acl8113", 477 .board_type = BOARD_ACL8113, 478 .n_aichan = 32, 479 .rangelist_ai = &range_acl8113_1_ai, 480 }, { 481 .name = "iso813", 482 .board_type = BOARD_ISO813, 483 .n_aichan = 32, 484 .rangelist_ai = &range_iso813_1_ai, 485 }, { 486 .name = "acl8216", 487 .board_type = BOARD_ACL8216, 488 .n_aichan = 16, /* 8 differential */ 489 .n_aochan = 2, 490 .ai_ns_min = 10000, 491 .rangelist_ai = &range_pcl813b2_ai, 492 .irq_bits = 0xdcfc, 493 .has_dma = 1, 494 .has_16bit_ai = 1, 495 .has_mpc508_mux = 1, 496 .has_dio = 1, 497 }, { 498 .name = "a826pg", 499 .board_type = BOARD_ACL8216, 500 .n_aichan = 16, /* 8 differential */ 501 .n_aochan = 2, 502 .ai_ns_min = 10000, 503 .rangelist_ai = &range_pcl813b2_ai, 504 .irq_bits = 0xdcfc, 505 .has_dma = 1, 506 .has_16bit_ai = 1, 507 .has_dio = 1, 508 }, 509 }; 510 511 struct pcl812_private { 512 struct comedi_isadma *dma; 513 unsigned char range_correction; /* =1 we must add 1 to range number */ 514 unsigned int last_ai_chanspec; 515 unsigned char mode_reg_int; /* stored INT number for some cards */ 516 unsigned int ai_poll_ptr; /* how many samples transfer poll */ 517 unsigned int max_812_ai_mode0_rangewait; /* settling time for gain */ 518 unsigned int use_diff:1; 519 unsigned int use_mpc508:1; 520 unsigned int use_ext_trg:1; 521 unsigned int ai_dma:1; 522 unsigned int ai_eos:1; 523 }; 524 525 static void pcl812_ai_setup_dma(struct comedi_device *dev, 526 struct comedi_subdevice *s, 527 unsigned int unread_samples) 528 { 529 struct pcl812_private *devpriv = dev->private; 530 struct comedi_isadma *dma = devpriv->dma; 531 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma]; 532 unsigned int bytes; 533 unsigned int max_samples; 534 unsigned int nsamples; 535 536 comedi_isadma_disable(dma->chan); 537 538 /* if using EOS, adapt DMA buffer to one scan */ 539 bytes = devpriv->ai_eos ? comedi_bytes_per_scan(s) : desc->maxsize; 540 max_samples = comedi_bytes_to_samples(s, bytes); 541 542 /* 543 * Determine dma size based on the buffer size plus the number of 544 * unread samples and the number of samples remaining in the command. 545 */ 546 nsamples = comedi_nsamples_left(s, max_samples + unread_samples); 547 if (nsamples > unread_samples) { 548 nsamples -= unread_samples; 549 desc->size = comedi_samples_to_bytes(s, nsamples); 550 comedi_isadma_program(desc); 551 } 552 } 553 554 static void pcl812_ai_set_chan_range(struct comedi_device *dev, 555 unsigned int chanspec, char wait) 556 { 557 struct pcl812_private *devpriv = dev->private; 558 unsigned int chan = CR_CHAN(chanspec); 559 unsigned int range = CR_RANGE(chanspec); 560 unsigned int mux = 0; 561 562 if (chanspec == devpriv->last_ai_chanspec) 563 return; 564 565 devpriv->last_ai_chanspec = chanspec; 566 567 if (devpriv->use_mpc508) { 568 if (devpriv->use_diff) { 569 mux |= PCL812_MUX_CS0 | PCL812_MUX_CS1; 570 } else { 571 if (chan < 8) 572 mux |= PCL812_MUX_CS0; 573 else 574 mux |= PCL812_MUX_CS1; 575 } 576 } 577 578 outb(mux | PCL812_MUX_CHAN(chan), dev->iobase + PCL812_MUX_REG); 579 outb(range + devpriv->range_correction, dev->iobase + PCL812_RANGE_REG); 580 581 if (wait) 582 /* 583 * XXX this depends on selected range and can be very long for 584 * some high gain ranges! 585 */ 586 udelay(devpriv->max_812_ai_mode0_rangewait); 587 } 588 589 static void pcl812_ai_clear_eoc(struct comedi_device *dev) 590 { 591 /* writing any value clears the interrupt request */ 592 outb(0, dev->iobase + PCL812_STATUS_REG); 593 } 594 595 static void pcl812_ai_soft_trig(struct comedi_device *dev) 596 { 597 /* writing any value triggers a software conversion */ 598 outb(255, dev->iobase + PCL812_SOFTTRIG_REG); 599 } 600 601 static unsigned int pcl812_ai_get_sample(struct comedi_device *dev, 602 struct comedi_subdevice *s) 603 { 604 unsigned int val; 605 606 val = inb(dev->iobase + PCL812_AI_MSB_REG) << 8; 607 val |= inb(dev->iobase + PCL812_AI_LSB_REG); 608 609 return val & s->maxdata; 610 } 611 612 static int pcl812_ai_eoc(struct comedi_device *dev, 613 struct comedi_subdevice *s, 614 struct comedi_insn *insn, 615 unsigned long context) 616 { 617 unsigned int status; 618 619 if (s->maxdata > 0x0fff) { 620 status = inb(dev->iobase + PCL812_STATUS_REG); 621 if ((status & PCL812_STATUS_DRDY) == 0) 622 return 0; 623 } else { 624 status = inb(dev->iobase + PCL812_AI_MSB_REG); 625 if ((status & PCL812_AI_MSB_DRDY) == 0) 626 return 0; 627 } 628 return -EBUSY; 629 } 630 631 static int pcl812_ai_cmdtest(struct comedi_device *dev, 632 struct comedi_subdevice *s, struct comedi_cmd *cmd) 633 { 634 const struct pcl812_board *board = dev->board_ptr; 635 struct pcl812_private *devpriv = dev->private; 636 int err = 0; 637 unsigned int flags; 638 639 /* Step 1 : check if triggers are trivially valid */ 640 641 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW); 642 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); 643 644 if (devpriv->use_ext_trg) 645 flags = TRIG_EXT; 646 else 647 flags = TRIG_TIMER; 648 err |= comedi_check_trigger_src(&cmd->convert_src, flags); 649 650 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 651 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 652 653 if (err) 654 return 1; 655 656 /* Step 2a : make sure trigger sources are unique */ 657 658 err |= comedi_check_trigger_is_unique(cmd->stop_src); 659 660 /* Step 2b : and mutually compatible */ 661 662 if (err) 663 return 2; 664 665 /* Step 3: check if arguments are trivially valid */ 666 667 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); 668 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 669 670 if (cmd->convert_src == TRIG_TIMER) { 671 err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 672 board->ai_ns_min); 673 } else { /* TRIG_EXT */ 674 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); 675 } 676 677 err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1); 678 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, 679 cmd->chanlist_len); 680 681 if (cmd->stop_src == TRIG_COUNT) 682 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); 683 else /* TRIG_NONE */ 684 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); 685 686 if (err) 687 return 3; 688 689 /* step 4: fix up any arguments */ 690 691 if (cmd->convert_src == TRIG_TIMER) { 692 unsigned int arg = cmd->convert_arg; 693 694 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); 695 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); 696 } 697 698 if (err) 699 return 4; 700 701 return 0; 702 } 703 704 static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 705 { 706 struct pcl812_private *devpriv = dev->private; 707 struct comedi_isadma *dma = devpriv->dma; 708 struct comedi_cmd *cmd = &s->async->cmd; 709 unsigned int ctrl = 0; 710 unsigned int i; 711 712 pcl812_ai_set_chan_range(dev, cmd->chanlist[0], 1); 713 714 if (dma) { /* check if we can use DMA transfer */ 715 devpriv->ai_dma = 1; 716 for (i = 1; i < cmd->chanlist_len; i++) 717 if (cmd->chanlist[0] != cmd->chanlist[i]) { 718 /* we cann't use DMA :-( */ 719 devpriv->ai_dma = 0; 720 break; 721 } 722 } else { 723 devpriv->ai_dma = 0; 724 } 725 726 devpriv->ai_poll_ptr = 0; 727 728 /* don't we want wake up every scan? */ 729 if (cmd->flags & CMDF_WAKE_EOS) { 730 devpriv->ai_eos = 1; 731 732 /* DMA is useless for this situation */ 733 if (cmd->chanlist_len == 1) 734 devpriv->ai_dma = 0; 735 } 736 737 if (devpriv->ai_dma) { 738 /* setup and enable dma for the first buffer */ 739 dma->cur_dma = 0; 740 pcl812_ai_setup_dma(dev, s, 0); 741 } 742 743 switch (cmd->convert_src) { 744 case TRIG_TIMER: 745 comedi_8254_update_divisors(dev->pacer); 746 comedi_8254_pacer_enable(dev->pacer, 1, 2, true); 747 break; 748 } 749 750 if (devpriv->ai_dma) 751 ctrl |= PCL812_CTRL_PACER_DMA_TRIG; 752 else 753 ctrl |= PCL812_CTRL_PACER_EOC_TRIG; 754 outb(devpriv->mode_reg_int | ctrl, dev->iobase + PCL812_CTRL_REG); 755 756 return 0; 757 } 758 759 static bool pcl812_ai_next_chan(struct comedi_device *dev, 760 struct comedi_subdevice *s) 761 { 762 struct comedi_cmd *cmd = &s->async->cmd; 763 764 if (cmd->stop_src == TRIG_COUNT && 765 s->async->scans_done >= cmd->stop_arg) { 766 s->async->events |= COMEDI_CB_EOA; 767 return false; 768 } 769 770 return true; 771 } 772 773 static void pcl812_handle_eoc(struct comedi_device *dev, 774 struct comedi_subdevice *s) 775 { 776 struct comedi_cmd *cmd = &s->async->cmd; 777 unsigned int chan = s->async->cur_chan; 778 unsigned int next_chan; 779 unsigned short val; 780 781 if (pcl812_ai_eoc(dev, s, NULL, 0)) { 782 dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n"); 783 s->async->events |= COMEDI_CB_ERROR; 784 return; 785 } 786 787 val = pcl812_ai_get_sample(dev, s); 788 comedi_buf_write_samples(s, &val, 1); 789 790 /* Set up next channel. Added by abbotti 2010-01-20, but untested. */ 791 next_chan = s->async->cur_chan; 792 if (cmd->chanlist[chan] != cmd->chanlist[next_chan]) 793 pcl812_ai_set_chan_range(dev, cmd->chanlist[next_chan], 0); 794 795 pcl812_ai_next_chan(dev, s); 796 } 797 798 static void transfer_from_dma_buf(struct comedi_device *dev, 799 struct comedi_subdevice *s, 800 unsigned short *ptr, 801 unsigned int bufptr, unsigned int len) 802 { 803 unsigned int i; 804 unsigned short val; 805 806 for (i = len; i; i--) { 807 val = ptr[bufptr++]; 808 comedi_buf_write_samples(s, &val, 1); 809 810 if (!pcl812_ai_next_chan(dev, s)) 811 break; 812 } 813 } 814 815 static void pcl812_handle_dma(struct comedi_device *dev, 816 struct comedi_subdevice *s) 817 { 818 struct pcl812_private *devpriv = dev->private; 819 struct comedi_isadma *dma = devpriv->dma; 820 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma]; 821 unsigned int nsamples; 822 int bufptr; 823 824 nsamples = comedi_bytes_to_samples(s, desc->size) - 825 devpriv->ai_poll_ptr; 826 bufptr = devpriv->ai_poll_ptr; 827 devpriv->ai_poll_ptr = 0; 828 829 /* restart dma with the next buffer */ 830 dma->cur_dma = 1 - dma->cur_dma; 831 pcl812_ai_setup_dma(dev, s, nsamples); 832 833 transfer_from_dma_buf(dev, s, desc->virt_addr, bufptr, nsamples); 834 } 835 836 static irqreturn_t pcl812_interrupt(int irq, void *d) 837 { 838 struct comedi_device *dev = d; 839 struct comedi_subdevice *s = dev->read_subdev; 840 struct pcl812_private *devpriv = dev->private; 841 842 if (!dev->attached) { 843 pcl812_ai_clear_eoc(dev); 844 return IRQ_HANDLED; 845 } 846 847 if (devpriv->ai_dma) 848 pcl812_handle_dma(dev, s); 849 else 850 pcl812_handle_eoc(dev, s); 851 852 pcl812_ai_clear_eoc(dev); 853 854 comedi_handle_events(dev, s); 855 return IRQ_HANDLED; 856 } 857 858 static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) 859 { 860 struct pcl812_private *devpriv = dev->private; 861 struct comedi_isadma *dma = devpriv->dma; 862 struct comedi_isadma_desc *desc; 863 unsigned long flags; 864 unsigned int poll; 865 int ret; 866 867 /* poll is valid only for DMA transfer */ 868 if (!devpriv->ai_dma) 869 return 0; 870 871 spin_lock_irqsave(&dev->spinlock, flags); 872 873 poll = comedi_isadma_poll(dma); 874 poll = comedi_bytes_to_samples(s, poll); 875 if (poll > devpriv->ai_poll_ptr) { 876 desc = &dma->desc[dma->cur_dma]; 877 transfer_from_dma_buf(dev, s, desc->virt_addr, 878 devpriv->ai_poll_ptr, 879 poll - devpriv->ai_poll_ptr); 880 /* new buffer position */ 881 devpriv->ai_poll_ptr = poll; 882 883 ret = comedi_buf_n_bytes_ready(s); 884 } else { 885 /* no new samples */ 886 ret = 0; 887 } 888 889 spin_unlock_irqrestore(&dev->spinlock, flags); 890 891 return ret; 892 } 893 894 static int pcl812_ai_cancel(struct comedi_device *dev, 895 struct comedi_subdevice *s) 896 { 897 struct pcl812_private *devpriv = dev->private; 898 899 if (devpriv->ai_dma) 900 comedi_isadma_disable(devpriv->dma->chan); 901 902 outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG, 903 dev->iobase + PCL812_CTRL_REG); 904 comedi_8254_pacer_enable(dev->pacer, 1, 2, false); 905 pcl812_ai_clear_eoc(dev); 906 return 0; 907 } 908 909 static int pcl812_ai_insn_read(struct comedi_device *dev, 910 struct comedi_subdevice *s, 911 struct comedi_insn *insn, 912 unsigned int *data) 913 { 914 struct pcl812_private *devpriv = dev->private; 915 int ret = 0; 916 int i; 917 918 outb(devpriv->mode_reg_int | PCL812_CTRL_SOFT_TRIG, 919 dev->iobase + PCL812_CTRL_REG); 920 921 pcl812_ai_set_chan_range(dev, insn->chanspec, 1); 922 923 for (i = 0; i < insn->n; i++) { 924 pcl812_ai_clear_eoc(dev); 925 pcl812_ai_soft_trig(dev); 926 927 ret = comedi_timeout(dev, s, insn, pcl812_ai_eoc, 0); 928 if (ret) 929 break; 930 931 data[i] = pcl812_ai_get_sample(dev, s); 932 } 933 outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG, 934 dev->iobase + PCL812_CTRL_REG); 935 pcl812_ai_clear_eoc(dev); 936 937 return ret ? ret : insn->n; 938 } 939 940 static int pcl812_ao_insn_write(struct comedi_device *dev, 941 struct comedi_subdevice *s, 942 struct comedi_insn *insn, 943 unsigned int *data) 944 { 945 unsigned int chan = CR_CHAN(insn->chanspec); 946 unsigned int val = s->readback[chan]; 947 int i; 948 949 for (i = 0; i < insn->n; i++) { 950 val = data[i]; 951 outb(val & 0xff, dev->iobase + PCL812_AO_LSB_REG(chan)); 952 outb((val >> 8) & 0x0f, dev->iobase + PCL812_AO_MSB_REG(chan)); 953 } 954 s->readback[chan] = val; 955 956 return insn->n; 957 } 958 959 static int pcl812_di_insn_bits(struct comedi_device *dev, 960 struct comedi_subdevice *s, 961 struct comedi_insn *insn, 962 unsigned int *data) 963 { 964 data[1] = inb(dev->iobase + PCL812_DI_LSB_REG) | 965 (inb(dev->iobase + PCL812_DI_MSB_REG) << 8); 966 967 return insn->n; 968 } 969 970 static int pcl812_do_insn_bits(struct comedi_device *dev, 971 struct comedi_subdevice *s, 972 struct comedi_insn *insn, 973 unsigned int *data) 974 { 975 if (comedi_dio_update_state(s, data)) { 976 outb(s->state & 0xff, dev->iobase + PCL812_DO_LSB_REG); 977 outb((s->state >> 8), dev->iobase + PCL812_DO_MSB_REG); 978 } 979 980 data[1] = s->state; 981 982 return insn->n; 983 } 984 985 static void pcl812_reset(struct comedi_device *dev) 986 { 987 const struct pcl812_board *board = dev->board_ptr; 988 struct pcl812_private *devpriv = dev->private; 989 unsigned int chan; 990 991 /* disable analog input trigger */ 992 outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG, 993 dev->iobase + PCL812_CTRL_REG); 994 pcl812_ai_clear_eoc(dev); 995 996 /* 997 * Invalidate last_ai_chanspec then set analog input to 998 * known channel/range. 999 */ 1000 devpriv->last_ai_chanspec = CR_PACK(16, 0, 0); 1001 pcl812_ai_set_chan_range(dev, CR_PACK(0, 0, 0), 0); 1002 1003 /* set analog output channels to 0V */ 1004 for (chan = 0; chan < board->n_aochan; chan++) { 1005 outb(0, dev->iobase + PCL812_AO_LSB_REG(chan)); 1006 outb(0, dev->iobase + PCL812_AO_MSB_REG(chan)); 1007 } 1008 1009 /* set all digital outputs low */ 1010 if (board->has_dio) { 1011 outb(0, dev->iobase + PCL812_DO_MSB_REG); 1012 outb(0, dev->iobase + PCL812_DO_LSB_REG); 1013 } 1014 } 1015 1016 static void pcl812_set_ai_range_table(struct comedi_device *dev, 1017 struct comedi_subdevice *s, 1018 struct comedi_devconfig *it) 1019 { 1020 const struct pcl812_board *board = dev->board_ptr; 1021 struct pcl812_private *devpriv = dev->private; 1022 1023 switch (board->board_type) { 1024 case BOARD_PCL812PG: 1025 if (it->options[4] == 1) 1026 s->range_table = &range_pcl812pg2_ai; 1027 else 1028 s->range_table = board->rangelist_ai; 1029 break; 1030 case BOARD_PCL812: 1031 switch (it->options[4]) { 1032 case 0: 1033 s->range_table = &range_bipolar10; 1034 break; 1035 case 1: 1036 s->range_table = &range_bipolar5; 1037 break; 1038 case 2: 1039 s->range_table = &range_bipolar2_5; 1040 break; 1041 case 3: 1042 s->range_table = &range812_bipolar1_25; 1043 break; 1044 case 4: 1045 s->range_table = &range812_bipolar0_625; 1046 break; 1047 case 5: 1048 s->range_table = &range812_bipolar0_3125; 1049 break; 1050 default: 1051 s->range_table = &range_bipolar10; 1052 break; 1053 } 1054 break; 1055 case BOARD_PCL813B: 1056 if (it->options[1] == 1) 1057 s->range_table = &range_pcl813b2_ai; 1058 else 1059 s->range_table = board->rangelist_ai; 1060 break; 1061 case BOARD_ISO813: 1062 switch (it->options[1]) { 1063 case 0: 1064 s->range_table = &range_iso813_1_ai; 1065 break; 1066 case 1: 1067 s->range_table = &range_iso813_1_2_ai; 1068 break; 1069 case 2: 1070 s->range_table = &range_iso813_2_ai; 1071 devpriv->range_correction = 1; 1072 break; 1073 case 3: 1074 s->range_table = &range_iso813_2_2_ai; 1075 devpriv->range_correction = 1; 1076 break; 1077 default: 1078 s->range_table = &range_iso813_1_ai; 1079 break; 1080 } 1081 break; 1082 case BOARD_ACL8113: 1083 switch (it->options[1]) { 1084 case 0: 1085 s->range_table = &range_acl8113_1_ai; 1086 break; 1087 case 1: 1088 s->range_table = &range_acl8113_1_2_ai; 1089 break; 1090 case 2: 1091 s->range_table = &range_acl8113_2_ai; 1092 devpriv->range_correction = 1; 1093 break; 1094 case 3: 1095 s->range_table = &range_acl8113_2_2_ai; 1096 devpriv->range_correction = 1; 1097 break; 1098 default: 1099 s->range_table = &range_acl8113_1_ai; 1100 break; 1101 } 1102 break; 1103 default: 1104 s->range_table = board->rangelist_ai; 1105 break; 1106 } 1107 } 1108 1109 static void pcl812_alloc_dma(struct comedi_device *dev, unsigned int dma_chan) 1110 { 1111 struct pcl812_private *devpriv = dev->private; 1112 1113 /* only DMA channels 3 and 1 are valid */ 1114 if (!(dma_chan == 3 || dma_chan == 1)) 1115 return; 1116 1117 /* DMA uses two 8K buffers */ 1118 devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan, 1119 PAGE_SIZE * 2, COMEDI_ISADMA_READ); 1120 } 1121 1122 static void pcl812_free_dma(struct comedi_device *dev) 1123 { 1124 struct pcl812_private *devpriv = dev->private; 1125 1126 if (devpriv) 1127 comedi_isadma_free(devpriv->dma); 1128 } 1129 1130 static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) 1131 { 1132 const struct pcl812_board *board = dev->board_ptr; 1133 struct pcl812_private *devpriv; 1134 struct comedi_subdevice *s; 1135 int n_subdevices; 1136 int subdev; 1137 int ret; 1138 1139 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1140 if (!devpriv) 1141 return -ENOMEM; 1142 1143 ret = comedi_request_region(dev, it->options[0], 0x10); 1144 if (ret) 1145 return ret; 1146 1147 if (board->irq_bits) { 1148 dev->pacer = comedi_8254_init(dev->iobase + PCL812_TIMER_BASE, 1149 I8254_OSC_BASE_2MHZ, 1150 I8254_IO8, 0); 1151 if (!dev->pacer) 1152 return -ENOMEM; 1153 1154 if ((1 << it->options[1]) & board->irq_bits) { 1155 ret = request_irq(it->options[1], pcl812_interrupt, 0, 1156 dev->board_name, dev); 1157 if (ret == 0) 1158 dev->irq = it->options[1]; 1159 } 1160 } 1161 1162 /* we need an IRQ to do DMA on channel 3 or 1 */ 1163 if (dev->irq && board->has_dma) 1164 pcl812_alloc_dma(dev, it->options[2]); 1165 1166 /* differential analog inputs? */ 1167 switch (board->board_type) { 1168 case BOARD_A821: 1169 if (it->options[2] == 1) 1170 devpriv->use_diff = 1; 1171 break; 1172 case BOARD_ACL8112: 1173 case BOARD_ACL8216: 1174 if (it->options[4] == 1) 1175 devpriv->use_diff = 1; 1176 break; 1177 default: 1178 break; 1179 } 1180 1181 n_subdevices = 1; /* all boardtypes have analog inputs */ 1182 if (board->n_aochan > 0) 1183 n_subdevices++; 1184 if (board->has_dio) 1185 n_subdevices += 2; 1186 1187 ret = comedi_alloc_subdevices(dev, n_subdevices); 1188 if (ret) 1189 return ret; 1190 1191 subdev = 0; 1192 1193 /* Analog Input subdevice */ 1194 s = &dev->subdevices[subdev]; 1195 s->type = COMEDI_SUBD_AI; 1196 s->subdev_flags = SDF_READABLE; 1197 if (devpriv->use_diff) { 1198 s->subdev_flags |= SDF_DIFF; 1199 s->n_chan = board->n_aichan / 2; 1200 } else { 1201 s->subdev_flags |= SDF_GROUND; 1202 s->n_chan = board->n_aichan; 1203 } 1204 s->maxdata = board->has_16bit_ai ? 0xffff : 0x0fff; 1205 1206 pcl812_set_ai_range_table(dev, s, it); 1207 1208 s->insn_read = pcl812_ai_insn_read; 1209 1210 if (dev->irq) { 1211 dev->read_subdev = s; 1212 s->subdev_flags |= SDF_CMD_READ; 1213 s->len_chanlist = MAX_CHANLIST_LEN; 1214 s->do_cmdtest = pcl812_ai_cmdtest; 1215 s->do_cmd = pcl812_ai_cmd; 1216 s->poll = pcl812_ai_poll; 1217 s->cancel = pcl812_ai_cancel; 1218 } 1219 1220 devpriv->use_mpc508 = board->has_mpc508_mux; 1221 1222 subdev++; 1223 1224 /* analog output */ 1225 if (board->n_aochan > 0) { 1226 s = &dev->subdevices[subdev]; 1227 s->type = COMEDI_SUBD_AO; 1228 s->subdev_flags = SDF_WRITABLE | SDF_GROUND; 1229 s->n_chan = board->n_aochan; 1230 s->maxdata = 0xfff; 1231 switch (board->board_type) { 1232 case BOARD_A821: 1233 if (it->options[3] == 1) 1234 s->range_table = &range_unipolar10; 1235 else 1236 s->range_table = &range_unipolar5; 1237 break; 1238 case BOARD_PCL812: 1239 case BOARD_ACL8112: 1240 case BOARD_PCL812PG: 1241 case BOARD_ACL8216: 1242 switch (it->options[5]) { 1243 case 1: 1244 s->range_table = &range_unipolar10; 1245 break; 1246 case 2: 1247 s->range_table = &range_unknown; 1248 break; 1249 default: 1250 s->range_table = &range_unipolar5; 1251 break; 1252 } 1253 break; 1254 default: 1255 s->range_table = &range_unipolar5; 1256 break; 1257 } 1258 s->insn_write = pcl812_ao_insn_write; 1259 1260 ret = comedi_alloc_subdev_readback(s); 1261 if (ret) 1262 return ret; 1263 1264 subdev++; 1265 } 1266 1267 if (board->has_dio) { 1268 /* Digital Input subdevice */ 1269 s = &dev->subdevices[subdev]; 1270 s->type = COMEDI_SUBD_DI; 1271 s->subdev_flags = SDF_READABLE; 1272 s->n_chan = 16; 1273 s->maxdata = 1; 1274 s->range_table = &range_digital; 1275 s->insn_bits = pcl812_di_insn_bits; 1276 subdev++; 1277 1278 /* Digital Output subdevice */ 1279 s = &dev->subdevices[subdev]; 1280 s->type = COMEDI_SUBD_DO; 1281 s->subdev_flags = SDF_WRITABLE; 1282 s->n_chan = 16; 1283 s->maxdata = 1; 1284 s->range_table = &range_digital; 1285 s->insn_bits = pcl812_do_insn_bits; 1286 subdev++; 1287 } 1288 1289 switch (board->board_type) { 1290 case BOARD_ACL8216: 1291 case BOARD_PCL812PG: 1292 case BOARD_PCL812: 1293 case BOARD_ACL8112: 1294 devpriv->max_812_ai_mode0_rangewait = 1; 1295 if (it->options[3] > 0) 1296 /* we use external trigger */ 1297 devpriv->use_ext_trg = 1; 1298 break; 1299 case BOARD_A821: 1300 devpriv->max_812_ai_mode0_rangewait = 1; 1301 devpriv->mode_reg_int = (dev->irq << 4) & 0xf0; 1302 break; 1303 case BOARD_PCL813B: 1304 case BOARD_PCL813: 1305 case BOARD_ISO813: 1306 case BOARD_ACL8113: 1307 /* maybe there must by greatest timeout */ 1308 devpriv->max_812_ai_mode0_rangewait = 5; 1309 break; 1310 } 1311 1312 pcl812_reset(dev); 1313 1314 return 0; 1315 } 1316 1317 static void pcl812_detach(struct comedi_device *dev) 1318 { 1319 pcl812_free_dma(dev); 1320 comedi_legacy_detach(dev); 1321 } 1322 1323 static struct comedi_driver pcl812_driver = { 1324 .driver_name = "pcl812", 1325 .module = THIS_MODULE, 1326 .attach = pcl812_attach, 1327 .detach = pcl812_detach, 1328 .board_name = &boardtypes[0].name, 1329 .num_names = ARRAY_SIZE(boardtypes), 1330 .offset = sizeof(struct pcl812_board), 1331 }; 1332 module_comedi_driver(pcl812_driver); 1333 1334 MODULE_AUTHOR("Comedi https://www.comedi.org"); 1335 MODULE_DESCRIPTION("Comedi low-level driver"); 1336 MODULE_LICENSE("GPL"); 1337