13c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 23c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi/drivers/dmm32at.c 33c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani Diamond Systems mm32at code for a Comedi driver 43c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 53c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani COMEDI - Linux Control and Measurement Device Interface 63c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani Copyright (C) 2000 David A. Schleef <ds@schleef.org> 73c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 83c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani This program is free software; you can redistribute it and/or modify 93c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani it under the terms of the GNU General Public License as published by 103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani the Free Software Foundation; either version 2 of the License, or 113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani (at your option) any later version. 123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani This program is distributed in the hope that it will be useful, 143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani but WITHOUT ANY WARRANTY; without even the implied warranty of 153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani GNU General Public License for more details. 173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani*/ 183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniDriver: dmm32at 203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniDescription: Diamond Systems mm32at driver. 213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniDevices: 223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniAuthor: Perry J. Piplani <perry.j.piplani@nasa.gov> 233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniUpdated: Fri Jun 4 09:13:24 CDT 2004 243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniStatus: experimental 253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniThis driver is for the Diamond Systems MM-32-AT board 273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanihttp://www.diamondsystems.com/products/diamondmm32at It is being used 283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanion serveral projects inside NASA, without problems so far. For analog 293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplaniinput commands, TRIG_EXT is not yet supported at all.. 303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniConfiguration Options: 323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi_config /dev/comedi0 dmm32at baseaddr,irq 333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani*/ 343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 35ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h> 36ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/delay.h> 3725436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h> 383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#include "../comedidev.h" 393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4027020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten#include "comedi_fc.h" 4127020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten 423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* Board register addresses */ 433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CONV 0x00 443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AILSB 0x00 453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AUXDOUT 0x01 463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AIMSB 0x01 473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AILOW 0x02 483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AIHIGH 0x03 493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DACSTAT 0x04 51bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten#define DMM32AT_DACLSB_REG 0x04 52bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten#define DMM32AT_DACMSB_REG 0x05 53bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten#define DMM32AT_DACMSB_CHAN(x) ((x) << 6) 543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_FIFOCNTRL 0x07 563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_FIFOSTAT 0x07 573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CNTRL 0x08 593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AISTAT 0x08 603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_INTCLOCK 0x09 623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CNTRDIO 0x0a 643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AICONF 0x0b 663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AIRBACK 0x0b 673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLK1 0x0d 693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLK2 0x0e 703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKCT 0x0f 713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOA 0x0c 733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOB 0x0d 743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOC 0x0e 753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOCONF 0x0f 763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* Board register values. */ 783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_DACSTAT 0x04 */ 803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DACBUSY 0x80 813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_FIFOCNTRL 0x07 */ 833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_FIFORESET 0x02 843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCANENABLE 0x04 853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_CNTRL 0x08 */ 873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RESET 0x20 883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_INTRESET 0x08 893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKACC 0x00 903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOACC 0x01 913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_AISTAT 0x08 */ 933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_STATUS 0x80 943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_INTCLOCK 0x09 */ 963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_ADINT 0x80 973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKSEL 0x03 983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_CNTRDIO 0x0a */ 1003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_FREQ12 0x80 1013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_AICONF 0x0b */ 1033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RANGE_U10 0x0c 1043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RANGE_U5 0x0d 1053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RANGE_B10 0x08 1063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RANGE_B5 0x00 1073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCINT_20 0x00 1083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCINT_15 0x10 1093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCINT_10 0x20 1103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCINT_5 0x30 1113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_CLKCT 0x0f */ 1133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKCT1 0x56 /* mode3 counter 1 - write low byte only */ 1143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKCT2 0xb6 /* mode3 counter 2 - write high and low byte */ 1153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_DIOCONF 0x0f */ 1173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIENABLE 0x80 1183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIRA 0x10 1193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIRB 0x02 1203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIRCL 0x01 1213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIRCH 0x08 1223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* board AI ranges in comedi structure */ 1249ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange dmm32at_airanges = { 12545ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten 4, { 12645ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten UNI_RANGE(10), 12745ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten UNI_RANGE(5), 12845ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten BIP_RANGE(10), 12945ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten BIP_RANGE(5) 13045ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten } 1313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani}; 1323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* register values for above ranges */ 1343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanistatic const unsigned char dmm32at_rangebits[] = { 1353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani DMM32AT_RANGE_U10, 1363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani DMM32AT_RANGE_U5, 1373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani DMM32AT_RANGE_B10, 1383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani DMM32AT_RANGE_B5, 1393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani}; 1403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* only one of these ranges is valid, as set by a jumper on the 1423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * board. The application should only use the range set by the jumper 1433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 1449ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange dmm32at_aoranges = { 14545ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten 4, { 14645ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten UNI_RANGE(10), 14745ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten UNI_RANGE(5), 14845ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten BIP_RANGE(10), 14945ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten BIP_RANGE(5) 15045ddfc5a51f0ea179bcb82a4170c33ceed46c4b2H Hartley Sweeten } 1513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani}; 1523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 15339d31e09a0cc299e01b8acb66b60fbcc453b9c8bBill Pembertonstruct dmm32at_private { 1543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int data; 1553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int ai_inuse; 1563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned int ai_scans_left; 1573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char dio_config; 15839d31e09a0cc299e01b8acb66b60fbcc453b9c8bBill Pemberton}; 1593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 160f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweetenstatic int dmm32at_ai_status(struct comedi_device *dev, 161f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten struct comedi_subdevice *s, 162f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten struct comedi_insn *insn, 163f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten unsigned long context) 164f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten{ 165f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten unsigned char status; 166f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten 167f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten status = inb(dev->iobase + context); 168f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten if ((status & DMM32AT_STATUS) == 0) 169f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten return 0; 170f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten return -EBUSY; 171f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten} 172f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten 1730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dmm32at_ai_rinsn(struct comedi_device *dev, 1740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 1763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 177f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten int n; 1783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned int d; 1793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned short msb, lsb; 1803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char chan; 1813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int range; 182f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten int ret; 1833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get the channel and range number */ 1853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chan = CR_CHAN(insn->chanspec) & (s->n_chan - 1); 1873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani range = CR_RANGE(insn->chanspec); 1883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* zero scan and fifo control and reset fifo */ 19029f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL); 1913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* write the ai channel range regs */ 19329f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(chan, dev->iobase + DMM32AT_AILOW); 19429f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(chan, dev->iobase + DMM32AT_AIHIGH); 1953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the range bits */ 19629f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AICONF); 1973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* wait for circuit to settle */ 199f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten ret = comedi_timeout(dev, s, insn, dmm32at_ai_status, DMM32AT_AIRBACK); 200f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten if (ret) 201f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten return ret; 2023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* convert n samples */ 2043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (n = 0; n < insn->n; n++) { 2053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* trigger conversion */ 20629f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(0xff, dev->iobase + DMM32AT_CONV); 207f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten 2083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* wait for conversion to end */ 209f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten ret = comedi_timeout(dev, s, insn, dmm32at_ai_status, 210f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten DMM32AT_AISTAT); 211f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten if (ret) 212f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten return ret; 2133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* read data */ 21599953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten lsb = inb(dev->iobase + DMM32AT_AILSB); 21699953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten msb = inb(dev->iobase + DMM32AT_AIMSB); 2173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* invert sign bit to make range unsigned, this is an 21925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi idiosyncrasy of the diamond board, it return 2203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani conversions as a signed value, i.e. -32768 to 2213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 32767, flipping the bit and interpreting it as 2223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani signed gives you a range of 0 to 65535 which is 2233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani used by comedi */ 2243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani d = ((msb ^ 0x0080) << 8) + lsb; 2253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani data[n] = d; 2273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 2283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* return the number of samples read/written */ 2303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return n; 2313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 2323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 233a207c12f62e8b53e1e1600ca384b13a39a9feed2H Hartley Sweetenstatic int dmm32at_ns_to_timer(unsigned int *ns, unsigned int flags) 23447ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten{ 23547ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten /* trivial timer */ 23647ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten return *ns; 23747ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten} 23847ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten 239869149961951afccb103d43217282756b17f2f96H Hartley Sweetenstatic int dmm32at_ai_check_chanlist(struct comedi_device *dev, 240869149961951afccb103d43217282756b17f2f96H Hartley Sweeten struct comedi_subdevice *s, 241869149961951afccb103d43217282756b17f2f96H Hartley Sweeten struct comedi_cmd *cmd) 242869149961951afccb103d43217282756b17f2f96H Hartley Sweeten{ 243869149961951afccb103d43217282756b17f2f96H Hartley Sweeten unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); 244869149961951afccb103d43217282756b17f2f96H Hartley Sweeten unsigned int range0 = CR_RANGE(cmd->chanlist[0]); 245869149961951afccb103d43217282756b17f2f96H Hartley Sweeten int i; 246869149961951afccb103d43217282756b17f2f96H Hartley Sweeten 247869149961951afccb103d43217282756b17f2f96H Hartley Sweeten for (i = 1; i < cmd->chanlist_len; i++) { 248869149961951afccb103d43217282756b17f2f96H Hartley Sweeten unsigned int chan = CR_CHAN(cmd->chanlist[i]); 249869149961951afccb103d43217282756b17f2f96H Hartley Sweeten unsigned int range = CR_RANGE(cmd->chanlist[i]); 250869149961951afccb103d43217282756b17f2f96H Hartley Sweeten 251869149961951afccb103d43217282756b17f2f96H Hartley Sweeten if (chan != (chan0 + i) % s->n_chan) { 252869149961951afccb103d43217282756b17f2f96H Hartley Sweeten dev_dbg(dev->class_dev, 253869149961951afccb103d43217282756b17f2f96H Hartley Sweeten "entries in chanlist must be consecutive channels, counting upwards\n"); 254869149961951afccb103d43217282756b17f2f96H Hartley Sweeten return -EINVAL; 255869149961951afccb103d43217282756b17f2f96H Hartley Sweeten } 256869149961951afccb103d43217282756b17f2f96H Hartley Sweeten if (range != range0) { 257869149961951afccb103d43217282756b17f2f96H Hartley Sweeten dev_dbg(dev->class_dev, 258869149961951afccb103d43217282756b17f2f96H Hartley Sweeten "entries in chanlist must all have the same gain\n"); 259869149961951afccb103d43217282756b17f2f96H Hartley Sweeten return -EINVAL; 260869149961951afccb103d43217282756b17f2f96H Hartley Sweeten } 261869149961951afccb103d43217282756b17f2f96H Hartley Sweeten } 262869149961951afccb103d43217282756b17f2f96H Hartley Sweeten 263869149961951afccb103d43217282756b17f2f96H Hartley Sweeten return 0; 264869149961951afccb103d43217282756b17f2f96H Hartley Sweeten} 265869149961951afccb103d43217282756b17f2f96H Hartley Sweeten 2660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dmm32at_ai_cmdtest(struct comedi_device *dev, 2670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 2693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 2703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int err = 0; 271d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten unsigned int arg; 2723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 27327020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten /* Step 1 : check if triggers are trivially valid */ 2743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 27527020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); 27627020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->scan_begin_src, 27727020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten TRIG_TIMER /*| TRIG_EXT */); 27827020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->convert_src, 27927020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten TRIG_TIMER /*| TRIG_EXT */); 28027020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 28127020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 2823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 2843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 1; 2853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 28627020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten /* Step 2a : make sure trigger sources are unique */ 2873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 28827020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); 28927020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten err |= cfc_check_trigger_is_unique(cmd->convert_src); 29027020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten err |= cfc_check_trigger_is_unique(cmd->stop_src); 29127020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten 29227020ffed9166d65ce1e5b523051d13bfa2329b0H Hartley Sweeten /* Step 2b : and mutually compatible */ 2933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 2953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 2; 2963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 297e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten /* Step 3: check if arguments are trivially valid */ 298e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten 299e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 3003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define MAX_SCAN_SPEED 1000000 /* in nanoseconds */ 3023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define MIN_SCAN_SPEED 1000000000 /* in nanoseconds */ 3033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_begin_src == TRIG_TIMER) { 305e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 306e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten MAX_SCAN_SPEED); 307e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 308e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten MIN_SCAN_SPEED); 3093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 3103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* external trigger */ 3113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* should be level/edge, hi/lo specification here */ 3123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* should specify multiple external triggers */ 313e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); 3143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 315e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten 3163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->convert_src == TRIG_TIMER) { 3173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->convert_arg >= 17500) 3183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg = 20000; 3193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else if (cmd->convert_arg >= 12500) 3203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg = 15000; 3213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else if (cmd->convert_arg >= 7500) 3223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg = 10000; 3233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else 3243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg = 5000; 3253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 3263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* external trigger */ 3273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* see above */ 328e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9); 3293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 3303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 331e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 332e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten 3333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->stop_src == TRIG_COUNT) { 334e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0xfffffff0); 335e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); 3363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 3373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* TRIG_NONE */ 338e43ed5fa1435e3ae8a2a5727ea30581640f9e18dH Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 3393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 3403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 3423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 3; 3433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* step 4: fix up any arguments */ 3453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_begin_src == TRIG_TIMER) { 347d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten arg = cmd->scan_begin_arg; 348a207c12f62e8b53e1e1600ca384b13a39a9feed2H Hartley Sweeten dmm32at_ns_to_timer(&arg, cmd->flags); 349d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg); 3503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 3513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->convert_src == TRIG_TIMER) { 352d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten arg = cmd->convert_arg; 353a207c12f62e8b53e1e1600ca384b13a39a9feed2H Hartley Sweeten dmm32at_ns_to_timer(&arg, cmd->flags); 354d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg); 355d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten 356d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten if (cmd->scan_begin_src == TRIG_TIMER) { 357d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten arg = cmd->convert_arg * cmd->scan_end_arg; 358d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 359d579392a3fab9acd63123f4167abd822600777a4H Hartley Sweeten arg); 3603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 3613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 3623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 3643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 4; 3653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 366869149961951afccb103d43217282756b17f2f96H Hartley Sweeten /* Step 5: check channel list if it exists */ 367869149961951afccb103d43217282756b17f2f96H Hartley Sweeten if (cmd->chanlist && cmd->chanlist_len > 0) 368869149961951afccb103d43217282756b17f2f96H Hartley Sweeten err |= dmm32at_ai_check_chanlist(dev, s, cmd); 3693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 3713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 5; 3723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 0; 3743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 3753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 37647ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweetenstatic void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec) 37747ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten{ 37847ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten unsigned char lo1, lo2, hi2; 37947ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten unsigned short both2; 38047ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten 38147ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten /* based on 10mhz clock */ 38247ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten lo1 = 200; 38347ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten both2 = nansec / 20000; 38447ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten hi2 = (both2 & 0xff00) >> 8; 38547ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten lo2 = both2 & 0x00ff; 38647ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten 38747ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten /* set the counter frequency to 10mhz */ 38829f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(0, dev->iobase + DMM32AT_CNTRDIO); 38947ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten 39047ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten /* get access to the clock regs */ 39129f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_CLKACC, dev->iobase + DMM32AT_CNTRL); 39247ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten 39347ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten /* write the counter 1 control word and low byte to counter */ 39429f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_CLKCT1, dev->iobase + DMM32AT_CLKCT); 39529f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(lo1, dev->iobase + DMM32AT_CLK1); 39647ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten 39747ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten /* write the counter 2 control word and low byte then to counter */ 39829f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_CLKCT2, dev->iobase + DMM32AT_CLKCT); 39929f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(lo2, dev->iobase + DMM32AT_CLK2); 40029f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(hi2, dev->iobase + DMM32AT_CLK2); 40147ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten 40247ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten /* enable the ai conversion interrupt and the clock to start scans */ 40329f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_ADINT | DMM32AT_CLKSEL, dev->iobase + DMM32AT_INTCLOCK); 40447ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten} 40547ae6a72597c29745fc18d693fe00bc8a537cfdfH Hartley Sweeten 406da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 4073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 4083eff01744009de100f03a1dc2e3d5f98da2235e5H Hartley Sweeten struct dmm32at_private *devpriv = dev->private; 409ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 410f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten int range; 411f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten unsigned char chanlo, chanhi; 412f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten int ret; 4133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!cmd->chanlist) 4153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -EINVAL; 4163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get the channel list and range */ 4183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanlo = CR_CHAN(cmd->chanlist[0]) & (s->n_chan - 1); 4193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanhi = chanlo + cmd->chanlist_len - 1; 4203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (chanhi >= s->n_chan) 4213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -EINVAL; 4223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani range = CR_RANGE(cmd->chanlist[0]); 4233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* reset fifo */ 42529f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL); 4263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set scan enable */ 42829f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_SCANENABLE, dev->iobase + DMM32AT_FIFOCNTRL); 4293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* write the ai channel range regs */ 43129f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(chanlo, dev->iobase + DMM32AT_AILOW); 43229f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(chanhi, dev->iobase + DMM32AT_AIHIGH); 4333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the range bits */ 43529f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AICONF); 4363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* reset the interrupt just in case */ 43829f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_INTRESET, dev->iobase + DMM32AT_CNTRL); 4393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->stop_src == TRIG_COUNT) 4413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->ai_scans_left = cmd->stop_arg; 4423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else { /* TRIG_NONE */ 44327bf0bc906e80fdb531524dab22a7851a4c21698Mark devpriv->ai_scans_left = 0xffffffff; /* indicates TRIG_NONE to 44427bf0bc906e80fdb531524dab22a7851a4c21698Mark * isr */ 4453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 4463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 447f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten /* 448f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten * wait for circuit to settle 449f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten * we don't have the 'insn' here but it's not needed 450f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten */ 451f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten ret = comedi_timeout(dev, s, NULL, dmm32at_ai_status, DMM32AT_AIRBACK); 452f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten if (ret) 453f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten return ret; 4543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (devpriv->ai_scans_left > 1) { 4563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* start the clock and enable the interrupts */ 4573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm32at_setaitimer(dev, cmd->scan_begin_arg); 4583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 4593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* start the interrups and initiate a single scan */ 46029f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_ADINT, dev->iobase + DMM32AT_INTCLOCK); 46129f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(0xff, dev->iobase + DMM32AT_CONV); 4623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 4633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 0; 4653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 4673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dmm32at_ai_cancel(struct comedi_device *dev, 4690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 4703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 4713eff01744009de100f03a1dc2e3d5f98da2235e5H Hartley Sweeten struct dmm32at_private *devpriv = dev->private; 4723eff01744009de100f03a1dc2e3d5f98da2235e5H Hartley Sweeten 4733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->ai_scans_left = 1; 4743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 0; 4753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 4763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 47770265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t dmm32at_isr(int irq, void *d) 4783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 4793eff01744009de100f03a1dc2e3d5f98da2235e5H Hartley Sweeten struct comedi_device *dev = d; 4803eff01744009de100f03a1dc2e3d5f98da2235e5H Hartley Sweeten struct dmm32at_private *devpriv = dev->private; 4813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char intstat; 4823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned int samp; 4833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned short msb, lsb; 4843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int i; 4853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!dev->attached) { 4872d60dd4a75bf1ddd60629c4d3fc5279205e701e2H Hartley Sweeten dev_err(dev->class_dev, "spurious interrupt\n"); 4883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return IRQ_HANDLED; 4893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 4903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 49199953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten intstat = inb(dev->iobase + DMM32AT_INTCLOCK); 4923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (intstat & DMM32AT_ADINT) { 49434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->read_subdev; 495ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 4963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 0; i < cmd->chanlist_len; i++) { 4983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* read data */ 49999953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten lsb = inb(dev->iobase + DMM32AT_AILSB); 50099953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten msb = inb(dev->iobase + DMM32AT_AIMSB); 5013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* invert sign bit to make range unsigned */ 5033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani samp = ((msb ^ 0x0080) << 8) + lsb; 5043672effdeae5395d661a2103f69082146ef949fcIan Abbott comedi_buf_put(s, samp); 5053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (devpriv->ai_scans_left != 0xffffffff) { /* TRIG_COUNT */ 5083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->ai_scans_left--; 5093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (devpriv->ai_scans_left == 0) { 5103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* disable further interrupts and clocks */ 51129f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(0x0, dev->iobase + DMM32AT_INTCLOCK); 5123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the buffer to be flushed with an EOF */ 5133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->async->events |= COMEDI_CB_EOA; 5143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* flush the buffer */ 5183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi_event(dev, s); 5193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* reset the interrupt */ 52229f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_INTRESET, dev->iobase + DMM32AT_CNTRL); 5233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return IRQ_HANDLED; 5243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 5253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 526f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweetenstatic int dmm32at_ao_eoc(struct comedi_device *dev, 527f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten struct comedi_subdevice *s, 528f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten struct comedi_insn *insn, 529f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten unsigned long context) 530f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten{ 531f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten unsigned char status; 532f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten 533f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten status = inb(dev->iobase + DMM32AT_DACSTAT); 534f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten if ((status & DMM32AT_DACBUSY) == 0) 535f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten return 0; 536f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten return -EBUSY; 537f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten} 538f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten 539bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweetenstatic int dmm32at_ao_insn_write(struct comedi_device *dev, 540bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten struct comedi_subdevice *s, 541bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten struct comedi_insn *insn, 542bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten unsigned int *data) 5433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 544bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten unsigned int chan = CR_CHAN(insn->chanspec); 545bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten int i; 5463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 0; i < insn->n; i++) { 548b328ad30759bf3134175242cf7ea9a81b1ef02a5H Hartley Sweeten unsigned int val = data[i]; 549b328ad30759bf3134175242cf7ea9a81b1ef02a5H Hartley Sweeten int ret; 5503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 551bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten /* write LSB then MSB + chan to load DAC */ 552bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten outb(val & 0xff, dev->iobase + DMM32AT_DACLSB_REG); 553bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten outb((val >> 8) | DMM32AT_DACMSB_CHAN(chan), 554bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten dev->iobase + DMM32AT_DACMSB_REG); 5553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* wait for circuit to settle */ 557f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten ret = comedi_timeout(dev, s, insn, dmm32at_ao_eoc, 0); 558f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten if (ret) 559f7b3d79a622c97483c8d0e6e4bbd5207929259d9H Hartley Sweeten return ret; 56065e2618fd3bbe9c3776048212dc15ddc7fe61451H Hartley Sweeten 561bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten /* dummy read to update DAC */ 562bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten inb(dev->iobase + DMM32AT_DACMSB_REG); 5633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 564b328ad30759bf3134175242cf7ea9a81b1ef02a5H Hartley Sweeten s->readback[chan] = val; 5653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 567bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten return insn->n; 5683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 5693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dmm32at_dio_insn_bits(struct comedi_device *dev, 5710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 572b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten struct comedi_insn *insn, 573b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten unsigned int *data) 5743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 5753eff01744009de100f03a1dc2e3d5f98da2235e5H Hartley Sweeten struct dmm32at_private *devpriv = dev->private; 576b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten unsigned int mask; 577b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten unsigned int val; 578b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten 579b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten mask = comedi_dio_update_state(s, data); 580b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten if (mask) { 581b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten /* get access to the DIO regs */ 582b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL); 583b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten 584b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten /* if either part of dio is set for output */ 585b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) || 586b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) { 587b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten val = (s->state & 0x00ff0000) >> 16; 588b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten outb(val, dev->iobase + DMM32AT_DIOC); 589b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten } 590b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten if ((devpriv->dio_config & DMM32AT_DIRB) == 0) { 591b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten val = (s->state & 0x0000ff00) >> 8; 592b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten outb(val, dev->iobase + DMM32AT_DIOB); 593b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten } 594b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten if ((devpriv->dio_config & DMM32AT_DIRA) == 0) { 595b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten val = (s->state & 0x000000ff); 596b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten outb(val, dev->iobase + DMM32AT_DIOA); 597b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten } 5983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 600b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten val = inb(dev->iobase + DMM32AT_DIOA); 601b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten val |= inb(dev->iobase + DMM32AT_DIOB) << 8; 602b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten val |= inb(dev->iobase + DMM32AT_DIOC) << 16; 603b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten s->state = val; 6043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 605b3ff824a81e8978deb56f6d163479c1a0a606037H Hartley Sweeten data[1] = val; 6063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 607a2714e3e42e746d6c8525c35fdcc58fb60c2830dH Hartley Sweeten return insn->n; 6083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 6093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dmm32at_dio_insn_config(struct comedi_device *dev, 6110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 61249b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten struct comedi_insn *insn, 61349b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten unsigned int *data) 6143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 6153eff01744009de100f03a1dc2e3d5f98da2235e5H Hartley Sweeten struct dmm32at_private *devpriv = dev->private; 61649b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten unsigned int chan = CR_CHAN(insn->chanspec); 61749b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten unsigned int mask; 6183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char chanbit; 61949b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten int ret; 6203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 62149b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten if (chan < 8) { 62249b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten mask = 0x0000ff; 6233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanbit = DMM32AT_DIRA; 62449b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten } else if (chan < 16) { 62549b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten mask = 0x00ff00; 6263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanbit = DMM32AT_DIRB; 62749b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten } else if (chan < 20) { 62849b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten mask = 0x0f0000; 6293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanbit = DMM32AT_DIRCL; 63049b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten } else { 63149b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten mask = 0xf00000; 6323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanbit = DMM32AT_DIRCH; 63349b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten } 6343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 63549b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten ret = comedi_dio_insn_config(dev, s, insn, data, mask); 63649b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten if (ret) 63749b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten return ret; 6383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 63949b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten if (data[0] == INSN_CONFIG_DIO_OUTPUT) 6403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->dio_config &= ~chanbit; 64120962c10c19862c58c03eec2434279a5d104c40eAndrea Gelmini else 6423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->dio_config |= chanbit; 6433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get access to the DIO regs */ 64429f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL); 6453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the DIO's to the new configuration setting */ 64629f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(devpriv->dio_config, dev->iobase + DMM32AT_DIOCONF); 6473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 64849b71ebab2b40ffec19007e8b4dba6b8f8622f46H Hartley Sweeten return insn->n; 6493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 6503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6514f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweetenstatic int dmm32at_attach(struct comedi_device *dev, 6524f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten struct comedi_devconfig *it) 6534f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten{ 6543eff01744009de100f03a1dc2e3d5f98da2235e5H Hartley Sweeten struct dmm32at_private *devpriv; 6554f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten int ret; 6564f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten struct comedi_subdevice *s; 6574f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten unsigned char aihi, ailo, fifostat, aistat, intstat, airback; 6584f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 65988634cd820850241aafb9c1ecc822c5a4c361c0cH Hartley Sweeten ret = comedi_request_region(dev, it->options[0], 0x10); 6602dd11a812aa908b3a8f2f88cce9f0c24c34c3cabH Hartley Sweeten if (ret) 6612dd11a812aa908b3a8f2f88cce9f0c24c34c3cabH Hartley Sweeten return ret; 6624f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6634f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* the following just makes sure the board is there and gets 6644f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten it to a known state */ 6654f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6664f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* reset the board */ 66729f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_RESET, dev->iobase + DMM32AT_CNTRL); 6684f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6694f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* allow a millisecond to reset */ 6704f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten udelay(1000); 6714f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6724f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* zero scan and fifo control */ 67329f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(0x0, dev->iobase + DMM32AT_FIFOCNTRL); 6744f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6754f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* zero interrupt and clock control */ 67629f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(0x0, dev->iobase + DMM32AT_INTCLOCK); 6774f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6784f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* write a test channel range, the high 3 bits should drop */ 67929f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(0x80, dev->iobase + DMM32AT_AILOW); 68029f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(0xff, dev->iobase + DMM32AT_AIHIGH); 6814f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6824f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* set the range at 10v unipolar */ 68329f747c21e4318cc41efa82dac217da9ee8d5533H Hartley Sweeten outb(DMM32AT_RANGE_U10, dev->iobase + DMM32AT_AICONF); 6844f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6854f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* should take 10 us to settle, here's a hundred */ 6864f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten udelay(100); 6874f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6884f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* read back the values */ 68999953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten ailo = inb(dev->iobase + DMM32AT_AILOW); 69099953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten aihi = inb(dev->iobase + DMM32AT_AIHIGH); 69199953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten fifostat = inb(dev->iobase + DMM32AT_FIFOSTAT); 69299953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten aistat = inb(dev->iobase + DMM32AT_AISTAT); 69399953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten intstat = inb(dev->iobase + DMM32AT_INTCLOCK); 69499953ea1ec780c22bacf065fc7c9750f0182c0f4H Hartley Sweeten airback = inb(dev->iobase + DMM32AT_AIRBACK); 6954f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 6964f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) || 6974f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) { 69845d351031e1326a4d0a988c776f23673f7e1ffd2H Hartley Sweeten dev_err(dev->class_dev, "board detection failed\n"); 6994f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten return -EIO; 7004f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten } 7014f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 7020c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten if (it->options[1]) { 7030c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten ret = request_irq(it->options[1], dmm32at_isr, 0, 7040c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten dev->board_name, dev); 7050c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten if (ret == 0) 7060c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten dev->irq = it->options[1]; 7074f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten } 7084f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 7090bdab509bf9c6d838dc0a3b1d68bbf841fc20b5aH Hartley Sweeten devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 710c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten if (!devpriv) 711c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten return -ENOMEM; 7124f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 7134f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten ret = comedi_alloc_subdevices(dev, 3); 7144f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten if (ret) 7154f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten return ret; 7164f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 7172930d0ba656d035d01a2cac37b6fe1250df16c28H Hartley Sweeten s = &dev->subdevices[0]; 7184f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* analog input subdevice */ 7194f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten s->type = COMEDI_SUBD_AI; 7204f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* we support single-ended (ground) and differential */ 7210c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; 7222792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->n_chan = 32; 7232792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->maxdata = 0xffff; 7242792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->range_table = &dmm32at_airanges; 7254f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten s->insn_read = dmm32at_ai_rinsn; 7260c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten if (dev->irq) { 7270c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten dev->read_subdev = s; 7280c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten s->subdev_flags |= SDF_CMD_READ; 7290c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten s->len_chanlist = 32; 7300c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten s->do_cmd = dmm32at_ai_cmd; 7310c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten s->do_cmdtest = dmm32at_ai_cmdtest; 7320c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten s->cancel = dmm32at_ai_cancel; 7330c2e55324199d89aaea816ce7a76571c3f88d158H Hartley Sweeten } 7344f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 7352930d0ba656d035d01a2cac37b6fe1250df16c28H Hartley Sweeten s = &dev->subdevices[1]; 7364f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* analog output subdevice */ 7374f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten s->type = COMEDI_SUBD_AO; 7384f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten s->subdev_flags = SDF_WRITABLE; 7392792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->n_chan = 4; 7402792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->maxdata = 0x0fff; 7412792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->range_table = &dmm32at_aoranges; 742bf8e3e3ad467f9e63069d19e56baf40644b7ec03H Hartley Sweeten s->insn_write = dmm32at_ao_insn_write; 743b328ad30759bf3134175242cf7ea9a81b1ef02a5H Hartley Sweeten s->insn_read = comedi_readback_insn_read; 744b328ad30759bf3134175242cf7ea9a81b1ef02a5H Hartley Sweeten 745b328ad30759bf3134175242cf7ea9a81b1ef02a5H Hartley Sweeten ret = comedi_alloc_subdev_readback(s); 746b328ad30759bf3134175242cf7ea9a81b1ef02a5H Hartley Sweeten if (ret) 747b328ad30759bf3134175242cf7ea9a81b1ef02a5H Hartley Sweeten return ret; 7484f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 7492930d0ba656d035d01a2cac37b6fe1250df16c28H Hartley Sweeten s = &dev->subdevices[2]; 7504f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten /* digital i/o subdevice */ 7512792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten 7522792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten /* get access to the DIO regs */ 7532792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL); 7542792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten /* set the DIO's to the defualt input setting */ 7552792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten devpriv->dio_config = DMM32AT_DIRA | DMM32AT_DIRB | 7562792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten DMM32AT_DIRCL | DMM32AT_DIRCH | DMM32AT_DIENABLE; 7572792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten outb(devpriv->dio_config, dev->iobase + DMM32AT_DIOCONF); 7582792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten 7592792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten /* set up the subdevice */ 7602792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->type = COMEDI_SUBD_DIO; 7612792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 7622792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->n_chan = 24; 7632792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->maxdata = 1; 7642792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->state = 0; 7652792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->range_table = &range_digital; 7662792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->insn_bits = dmm32at_dio_insn_bits; 7672792182816be376391c2cfc142bfd32f3ab8c5cdH Hartley Sweeten s->insn_config = dmm32at_dio_insn_config; 7684f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 7699b35db028f7f5c375ab9cef095ea48250d4c15ffH Hartley Sweeten return 0; 7704f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten} 7714f793db33dc3bab1b77a540386a662fbfd595e08H Hartley Sweeten 77217f49dd46c5db2912d2dd985f400f6237fd30255H Hartley Sweetenstatic struct comedi_driver dmm32at_driver = { 77317f49dd46c5db2912d2dd985f400f6237fd30255H Hartley Sweeten .driver_name = "dmm32at", 77417f49dd46c5db2912d2dd985f400f6237fd30255H Hartley Sweeten .module = THIS_MODULE, 77517f49dd46c5db2912d2dd985f400f6237fd30255H Hartley Sweeten .attach = dmm32at_attach, 7763d1fe3f785c80e17f62acf8f92570ae9210bd588H Hartley Sweeten .detach = comedi_legacy_detach, 77717f49dd46c5db2912d2dd985f400f6237fd30255H Hartley Sweeten}; 77817f49dd46c5db2912d2dd985f400f6237fd30255H Hartley Sweetenmodule_comedi_driver(dmm32at_driver); 77990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 78090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 78190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 78290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 783