dmm32at.c revision ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3f
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 You should have received a copy of the GNU General Public License 193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani along with this program; if not, write to the Free Software 203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani*/ 233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniDriver: dmm32at 253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniDescription: Diamond Systems mm32at driver. 263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniDevices: 273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniAuthor: Perry J. Piplani <perry.j.piplani@nasa.gov> 283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniUpdated: Fri Jun 4 09:13:24 CDT 2004 293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniStatus: experimental 303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniThis driver is for the Diamond Systems MM-32-AT board 323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanihttp://www.diamondsystems.com/products/diamondmm32at It is being used 333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanion serveral projects inside NASA, without problems so far. For analog 343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplaniinput commands, TRIG_EXT is not yet supported at all.. 353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniConfiguration Options: 373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi_config /dev/comedi0 dmm32at baseaddr,irq 383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani*/ 393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * The previous block comment is used to automatically generate 423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * documentation in Comedi and Comedilib. The fields: 433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * 443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Driver: the name of the driver 453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Description: a short phrase describing the driver. Don't list boards. 463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Devices: a full list of the boards that attempt to be supported by 473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * the driver. Format is "(manufacturer) board name [comedi name]", 483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * where comedi_name is the name that is used to configure the board. 49139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pemberton * See the comment near board_name: in the struct comedi_driver structure 503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * below. If (manufacturer) or [comedi name] is missing, the previous 513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * value is used. 523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Author: you 533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Updated: date when the _documentation_ was last updated. Use 'date -R' 543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * to get a value for this. 553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Status: a one-word description of the status. Valid values are: 563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * works - driver works correctly on most boards supported, and 573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * passes comedi_test. 583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * unknown - unknown. Usually put there by ds. 593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * experimental - may not work in any particular release. Author 603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * probably wants assistance testing it. 613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * bitrotten - driver has not been update in a long time, probably 623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * doesn't work, and probably is missing support for significant 633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Comedi interface features. 643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * untested - author probably wrote it "blind", and is believed to 653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * work, but no confirmation. 663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * 673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * These headers should be followed by a blank line, and any comments 683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * you wish to say about the driver. The comment area is the place 693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * to put any known bugs, limitations, unsupported features, supported 703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * command triggers, whether or not commands are supported on particular 713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * subdevices, etc. 723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * 733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Somewhere in the comment should be information about configuration 743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * options that are used with comedi_config. 753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#include "../comedidev.h" 783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#include <linux/ioport.h> 793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* Board register addresses */ 813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_MEMSIZE 0x10 833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CONV 0x00 853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AILSB 0x00 863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AUXDOUT 0x01 873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AIMSB 0x01 883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AILOW 0x02 893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AIHIGH 0x03 903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DACLSB 0x04 923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DACSTAT 0x04 933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DACMSB 0x05 943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_FIFOCNTRL 0x07 963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_FIFOSTAT 0x07 973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CNTRL 0x08 993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AISTAT 0x08 1003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_INTCLOCK 0x09 1023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CNTRDIO 0x0a 1043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AICONF 0x0b 1063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_AIRBACK 0x0b 1073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLK1 0x0d 1093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLK2 0x0e 1103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKCT 0x0f 1113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOA 0x0c 1133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOB 0x0d 1143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOC 0x0e 1153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOCONF 0x0f 1163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define dmm_inb(cdev,reg) inb((cdev->iobase)+reg) 1183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define dmm_outb(cdev,reg,valu) outb(valu,(cdev->iobase)+reg) 1193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* Board register values. */ 1213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_DACSTAT 0x04 */ 1233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DACBUSY 0x80 1243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_FIFOCNTRL 0x07 */ 1263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_FIFORESET 0x02 1273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCANENABLE 0x04 1283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_CNTRL 0x08 */ 1303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RESET 0x20 1313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_INTRESET 0x08 1323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKACC 0x00 1333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIOACC 0x01 1343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_AISTAT 0x08 */ 1363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_STATUS 0x80 1373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_INTCLOCK 0x09 */ 1393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_ADINT 0x80 1403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKSEL 0x03 1413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_CNTRDIO 0x0a */ 1433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_FREQ12 0x80 1443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_AICONF 0x0b */ 1463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RANGE_U10 0x0c 1473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RANGE_U5 0x0d 1483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RANGE_B10 0x08 1493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_RANGE_B5 0x00 1503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCINT_20 0x00 1513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCINT_15 0x10 1523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCINT_10 0x20 1533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_SCINT_5 0x30 1543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_CLKCT 0x0f */ 1563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKCT1 0x56 /* mode3 counter 1 - write low byte only */ 1573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_CLKCT2 0xb6 /* mode3 counter 2 - write high and low byte */ 1583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DMM32AT_DIOCONF 0x0f */ 1603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIENABLE 0x80 1613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIRA 0x10 1623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIRB 0x02 1633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIRCL 0x01 1643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define DMM32AT_DIRCH 0x08 1653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* board AI ranges in comedi structure */ 1679ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange dmm32at_airanges = { 1683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4, 1693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani { 1703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani UNI_RANGE(10), 1713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani UNI_RANGE(5), 1723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani BIP_RANGE(10), 1733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani BIP_RANGE(5), 1743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 1753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani}; 1763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* register values for above ranges */ 1783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanistatic const unsigned char dmm32at_rangebits[] = { 1793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani DMM32AT_RANGE_U10, 1803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani DMM32AT_RANGE_U5, 1813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani DMM32AT_RANGE_B10, 1823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani DMM32AT_RANGE_B5, 1833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani}; 1843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* only one of these ranges is valid, as set by a jumper on the 1863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * board. The application should only use the range set by the jumper 1873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 1889ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange dmm32at_aoranges = { 1893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4, 1903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani { 1913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani UNI_RANGE(10), 1923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani UNI_RANGE(5), 1933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani BIP_RANGE(10), 1943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani BIP_RANGE(5), 1953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 1963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani}; 1973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 1983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 1993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Board descriptions for two imaginary boards. Describing the 2003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * boards in this way is optional, and completely driver-dependent. 2013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Some drivers use arrays such as this, other do not. 2023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 2033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanitypedef struct dmm32at_board_struct { 2043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani const char *name; 2053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int ai_chans; 2063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int ai_bits; 2079ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton const struct comedi_lrange *ai_ranges; 2083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int ao_chans; 2093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int ao_bits; 2109ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton const struct comedi_lrange *ao_ranges; 2113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int have_dio; 2123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int dio_chans; 2133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} dmm32at_board; 2143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanistatic const dmm32at_board dmm32at_boards[] = { 2153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani { 2163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani name: "dmm32at", 2173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ai_chans:32, 2183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ai_bits: 16, 2193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ai_ranges:&dmm32at_airanges, 2203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ao_chans:4, 2213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ao_bits: 12, 2223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ao_ranges:&dmm32at_aoranges, 2233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani have_dio:1, 2243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dio_chans:24, 2253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani }, 2263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani}; 2273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 2293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Useful for shorthand access to the particular board structure 2303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 2313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define thisboard ((const dmm32at_board *)dev->board_ptr) 2323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* this structure is for data unique to this hardware driver. If 2343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * several hardware drivers keep similar information in this structure, 23571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton * feel free to suggest moving the variable to the struct comedi_device struct. 2363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 2373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanitypedef struct { 2383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int data; 2403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int ai_inuse; 2413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned int ai_scans_left; 2423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* Used for AO readback */ 244790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int ao_readback[4]; 2453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char dio_config; 2463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} dmm32at_private; 2483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 2503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * most drivers define the following macro to make it easy to 2513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * access the private structure. 2523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 2533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define devpriv ((dmm32at_private *)dev->private) 2543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 256139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pemberton * The struct comedi_driver structure tells the Comedi core module 2573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * which functions to call to configure/deconfigure (attach/detach) 2583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * the board, and also about the kernel module that contains 2593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * the device code. 2603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 26171b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int dmm32at_attach(struct comedi_device * dev, comedi_devconfig * it); 26271b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int dmm32at_detach(struct comedi_device * dev); 263139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_dmm32at = { 2643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani driver_name:"dmm32at", 2653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani module:THIS_MODULE, 2663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani attach:dmm32at_attach, 2673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani detach:dmm32at_detach, 2683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* It is not necessary to implement the following members if you are 2693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * writing a driver for a ISA PnP or PCI card */ 2703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* Most drivers will support multiple types of boards by 2713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * having an array of board structures. These were defined 2723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * in dmm32at_boards[] above. Note that the element 'name' 2733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * was first in the structure -- Comedi uses this fact to 2743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * extract the name of the board without knowing any details 2753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * about the structure except for its length. 2763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * When a device is attached (by comedi_config), the name 2773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * of the device is given to Comedi, and Comedi tries to 2783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * match it by going through the list of board names. If 2793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * there is a match, the address of the pointer is put 2803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * into dev->board_ptr and driver->attach() is called. 2813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * 2823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Note that these are not necessary if you can determine 2833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * the type of board in software. ISA PnP, PCI, and PCMCIA 2843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * devices are such boards. 2853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 2863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani board_name:&dmm32at_boards[0].name, 2873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani offset:sizeof(dmm32at_board), 2883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani num_names:sizeof(dmm32at_boards) / sizeof(dmm32at_board), 2893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani}; 2903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 2913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* prototypes for driver functions below */ 29234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 293790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 29434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s, 295790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 29634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 297790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 29834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s, 299790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 30034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s, 301790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 30234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, 303ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd * cmd); 30434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s); 30534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s); 3063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanistatic int dmm32at_ns_to_timer(unsigned int *ns, int round); 3073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanistatic irqreturn_t dmm32at_isr(int irq, void *d PT_REGS_ARG); 30871b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonvoid dmm32at_setaitimer(struct comedi_device * dev, unsigned int nansec); 3093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 3113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Attach is called by the Comedi core to configure the driver 3123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * for a particular board. If you specified a board_name array 3133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * in the driver structure, dev->board_ptr contains that 3143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * address. 3153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 31671b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int dmm32at_attach(struct comedi_device * dev, comedi_devconfig * it) 3173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 3183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int ret; 31934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 3203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char aihi, ailo, fifostat, aistat, intstat, airback; 3213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned long iobase; 3223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned int irq; 3233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani iobase = it->options[0]; 3253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani irq = it->options[1]; 3263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("comedi%d: dmm32at: attaching\n", dev->minor); 3283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("dmm32at: probing at address 0x%04lx, irq %u\n", iobase, irq); 3293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* register address space */ 3313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!request_region(iobase, DMM32AT_MEMSIZE, thisboard->name)) { 3323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("I/O port conflict\n"); 3333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -EIO; 3343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 3353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dev->iobase = iobase; 3363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* the following just makes sure the board is there and gets 3383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani it to a known state */ 3393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* reset the board */ 3413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_RESET); 3423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* allow a millisecond to reset */ 3443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani udelay(1000); 3453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* zero scan and fifo control */ 3473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_FIFOCNTRL, 0x0); 3483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* zero interrupt and clock control */ 3503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_INTCLOCK, 0x0); 3513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* write a test channel range, the high 3 bits should drop */ 3533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_AILOW, 0x80); 3543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_AIHIGH, 0xff); 3553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the range at 10v unipolar */ 3573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_AICONF, DMM32AT_RANGE_U10); 3583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* should take 10 us to settle, here's a hundred */ 3603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani udelay(100); 3613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* read back the values */ 3633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ailo = dmm_inb(dev, DMM32AT_AILOW); 3643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani aihi = dmm_inb(dev, DMM32AT_AIHIGH); 3653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani fifostat = dmm_inb(dev, DMM32AT_FIFOSTAT); 3663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani aistat = dmm_inb(dev, DMM32AT_AISTAT); 3673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani intstat = dmm_inb(dev, DMM32AT_INTCLOCK); 3683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani airback = dmm_inb(dev, DMM32AT_AIRBACK); 3693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n", 3713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ailo, aihi, fifostat); 3723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n", 3733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani aistat, intstat, airback); 3743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) || 3763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) { 3773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("dmmat32: board detection failed\n"); 3783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -EIO; 3793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 3803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* board is there, register interrupt */ 3823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (irq) { 3833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ret = comedi_request_irq(irq, dmm32at_isr, 0, thisboard->name, 3843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dev); 3853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (ret < 0) { 3863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("irq conflict\n"); 3873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return ret; 3883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 3893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dev->irq = irq; 3903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 3913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 3933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * If you can probe the device to determine what device in a series 3943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * it is, this is the place to do it. Otherwise, dev->board_ptr 3953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * should already be initialized. 3963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 3973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani //dev->board_ptr = dmm32at_probe(dev); 3983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 3993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 4003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Initialize dev->board_name. Note that we can use the "thisboard" 4013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * macro now, since we just initialized it in the last line. 4023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 4033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dev->board_name = thisboard->name; 4043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 4063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Allocate the private structure area. alloc_private() is a 4073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * convenient macro defined in comedidev.h. 4083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 4093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (alloc_private(dev, sizeof(dmm32at_private)) < 0) 4103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -ENOMEM; 4113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 4133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Allocate the subdevice structures. alloc_subdevice() is a 4143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * convenient macro defined in comedidev.h. 4153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 4163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (alloc_subdevices(dev, 3) < 0) 4173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -ENOMEM; 4183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s = dev->subdevices + 0; 4203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dev->read_subdev = s; 4213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* analog input subdevice */ 4223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->type = COMEDI_SUBD_AI; 4233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* we support single-ended (ground) and differential */ 4243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 4253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->n_chan = thisboard->ai_chans; 4263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->maxdata = (1 << thisboard->ai_bits) - 1; 4273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->range_table = thisboard->ai_ranges; 4283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->len_chanlist = 32; /* This is the maximum chanlist length that 4293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani the board can handle */ 4303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->insn_read = dmm32at_ai_rinsn; 4313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->do_cmd = dmm32at_ai_cmd; 4323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->do_cmdtest = dmm32at_ai_cmdtest; 4333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->cancel = dmm32at_ai_cancel; 4343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s = dev->subdevices + 1; 4363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* analog output subdevice */ 4373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->type = COMEDI_SUBD_AO; 4383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->subdev_flags = SDF_WRITABLE; 4393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->n_chan = thisboard->ao_chans; 4403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->maxdata = (1 << thisboard->ao_bits) - 1; 4413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->range_table = thisboard->ao_ranges; 4423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->insn_write = dmm32at_ao_winsn; 4433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->insn_read = dmm32at_ao_rinsn; 4443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s = dev->subdevices + 2; 4463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* digital i/o subdevice */ 4473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (thisboard->have_dio) { 4483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get access to the DIO regs */ 4503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC); 4513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the DIO's to the defualt input setting */ 4523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->dio_config = DMM32AT_DIRA | DMM32AT_DIRB | 4533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani DMM32AT_DIRCL | DMM32AT_DIRCH | DMM32AT_DIENABLE; 4543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config); 4553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set up the subdevice */ 4573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->type = COMEDI_SUBD_DIO; 4583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 4593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->n_chan = thisboard->dio_chans; 4603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->maxdata = 1; 4613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->state = 0; 4623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->range_table = &range_digital; 4633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->insn_bits = dmm32at_dio_insn_bits; 4643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->insn_config = dmm32at_dio_insn_config; 4653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 4663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->type = COMEDI_SUBD_UNUSED; 4673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 4683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* success */ 4703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("comedi%d: dmm32at: attached\n", dev->minor); 4713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 1; 4733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 4753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 4773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * _detach is called to deconfigure a device. It should deallocate 4783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * resources. 4793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * This function is also called when _attach() fails, so it should be 4803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * careful not to release resources that were not necessarily 4813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * allocated by _attach(). dev->private and dev->subdevices are 4823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * deallocated automatically by the core. 4833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 48471b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int dmm32at_detach(struct comedi_device * dev) 4853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 4863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("comedi%d: dmm32at: remove\n", dev->minor); 4873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (dev->irq) 4883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi_free_irq(dev->irq, dev); 4893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (dev->iobase) 4903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani release_region(dev->iobase, DMM32AT_MEMSIZE); 4913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 0; 4933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 4943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 4953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 4963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * "instructions" read/write data in "one-shot" or "software-triggered" 4973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * mode. 4983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 4993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 50034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 501790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 5023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 5033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int n, i; 5043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned int d; 5053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char status; 5063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned short msb, lsb; 5073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char chan; 5083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int range; 5093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get the channel and range number */ 5113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chan = CR_CHAN(insn->chanspec) & (s->n_chan - 1); 5133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani range = CR_RANGE(insn->chanspec); 5143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani //printk("channel=0x%02x, range=%d\n",chan,range); 5163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* zero scan and fifo control and reset fifo */ 5183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_FIFORESET); 5193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* write the ai channel range regs */ 5213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_AILOW, chan); 5223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_AIHIGH, chan); 5233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the range bits */ 5243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_AICONF, dmm32at_rangebits[range]); 5253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* wait for circuit to settle */ 5273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 0; i < 40000; i++) { 5283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani status = dmm_inb(dev, DMM32AT_AIRBACK); 5293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if ((status & DMM32AT_STATUS) == 0) 5303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani break; 5313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (i == 40000) { 5333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("timeout\n"); 5343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -ETIMEDOUT; 5353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* convert n samples */ 5383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (n = 0; n < insn->n; n++) { 5393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* trigger conversion */ 5403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CONV, 0xff); 5413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* wait for conversion to end */ 5423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 0; i < 40000; i++) { 5433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani status = dmm_inb(dev, DMM32AT_AISTAT); 5443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if ((status & DMM32AT_STATUS) == 0) 5453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani break; 5463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (i == 40000) { 5483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("timeout\n"); 5493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -ETIMEDOUT; 5503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* read data */ 5533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani lsb = dmm_inb(dev, DMM32AT_AILSB); 5543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani msb = dmm_inb(dev, DMM32AT_AIMSB); 5553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* invert sign bit to make range unsigned, this is an 5573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani idiosyncracy of the diamond board, it return 5583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani conversions as a signed value, i.e. -32768 to 5593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 32767, flipping the bit and interpreting it as 5603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani signed gives you a range of 0 to 65535 which is 5613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani used by comedi */ 5623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani d = ((msb ^ 0x0080) << 8) + lsb; 5633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani data[n] = d; 5653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 5663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* return the number of samples read/written */ 5683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return n; 5693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 5703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 57134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, 572ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd * cmd) 5733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 5743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int err = 0; 5753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int tmp; 5763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int start_chan, gain, i; 5773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani //printk("dmmat32 in command test\n"); 5793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* cmdtest tests a particular command to see if it is valid. 5813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Using the cmdtest ioctl, a user can create a valid cmd 5823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * and then have it executes by the cmd ioctl. 5833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * 5843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * cmdtest returns 1,2,3,4 or 0, depending on which tests 5853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * the command passes. */ 5863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* step 1: make sure trigger sources are trivially valid */ 5883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani tmp = cmd->start_src; 5903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->start_src &= TRIG_NOW; 5913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!cmd->start_src || tmp != cmd->start_src) 5923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 5933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani tmp = cmd->scan_begin_src; 5953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->scan_begin_src &= TRIG_TIMER /*| TRIG_EXT */ ; 5963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 5973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 5983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 5993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani tmp = cmd->convert_src; 6003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_src &= TRIG_TIMER /*| TRIG_EXT */ ; 6013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!cmd->convert_src || tmp != cmd->convert_src) 6023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani tmp = cmd->scan_end_src; 6053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->scan_end_src &= TRIG_COUNT; 6063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 6073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani tmp = cmd->stop_src; 6103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 6113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!cmd->stop_src || tmp != cmd->stop_src) 6123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 6153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 1; 6163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* step 2: make sure trigger sources are unique and mutually compatible */ 6183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* note that mutual compatiblity is not an issue here */ 6203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_begin_src != TRIG_TIMER && 6213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->scan_begin_src != TRIG_EXT) 6223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 6243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 6263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 6293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 2; 6303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* step 3: make sure arguments are trivially compatible */ 6323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->start_arg != 0) { 6343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->start_arg = 0; 6353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define MAX_SCAN_SPEED 1000000 /* in nanoseconds */ 6383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani#define MIN_SCAN_SPEED 1000000000 /* in nanoseconds */ 6393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_begin_src == TRIG_TIMER) { 6413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_begin_arg < MAX_SCAN_SPEED) { 6423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->scan_begin_arg = MAX_SCAN_SPEED; 6433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_begin_arg > MIN_SCAN_SPEED) { 6463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->scan_begin_arg = MIN_SCAN_SPEED; 6473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 6503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* external trigger */ 6513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* should be level/edge, hi/lo specification here */ 6523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* should specify multiple external triggers */ 6533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_begin_arg > 9) { 6543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->scan_begin_arg = 9; 6553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->convert_src == TRIG_TIMER) { 6593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->convert_arg >= 17500) 6603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg = 20000; 6613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else if (cmd->convert_arg >= 12500) 6623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg = 15000; 6633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else if (cmd->convert_arg >= 7500) 6643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg = 10000; 6653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else 6663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg = 5000; 6673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 6693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* external trigger */ 6703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* see above */ 6713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->convert_arg > 9) { 6723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg = 9; 6733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_end_arg != cmd->chanlist_len) { 6783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->scan_end_arg = cmd->chanlist_len; 6793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->stop_src == TRIG_COUNT) { 6823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->stop_arg > 0xfffffff0) { 6833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->stop_arg = 0xfffffff0; 6843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->stop_arg == 0) { 6873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->stop_arg = 1; 6883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 6913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* TRIG_NONE */ 6923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->stop_arg != 0) { 6933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->stop_arg = 0; 6943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 6953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 6973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 6983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 6993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 3; 7003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* step 4: fix up any arguments */ 7023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_begin_src == TRIG_TIMER) { 7043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani tmp = cmd->scan_begin_arg; 7053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm32at_ns_to_timer(&cmd->scan_begin_arg, 7063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->flags & TRIG_ROUND_MASK); 7073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (tmp != cmd->scan_begin_arg) 7083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 7093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 7103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->convert_src == TRIG_TIMER) { 7113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani tmp = cmd->convert_arg; 7123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm32at_ns_to_timer(&cmd->convert_arg, 7133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->flags & TRIG_ROUND_MASK); 7143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (tmp != cmd->convert_arg) 7153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 7163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->scan_begin_src == TRIG_TIMER && 7173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->scan_begin_arg < 7183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg * cmd->scan_end_arg) { 7193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->scan_begin_arg = 7203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani cmd->convert_arg * cmd->scan_end_arg; 7213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 7223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 7233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 7243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 7263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 4; 7273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* step 5 check the channel list, the channel list for this 7293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani board must be consecutive and gains must be the same */ 7303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->chanlist) { 7323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani gain = CR_RANGE(cmd->chanlist[0]); 7333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani start_chan = CR_CHAN(cmd->chanlist[0]); 7343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 1; i < cmd->chanlist_len; i++) { 7353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (CR_CHAN(cmd->chanlist[i]) != 7363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani (start_chan + i) % s->n_chan) { 7373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi_error(dev, 7383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani "entries in chanlist must be consecutive channels, counting upwards\n"); 7393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 7403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 7413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (CR_RANGE(cmd->chanlist[i]) != gain) { 7423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi_error(dev, 7433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani "entries in chanlist must all have the same gain\n"); 7443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani err++; 7453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 7463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 7473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 7483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (err) 7503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 5; 7513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 0; 7533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 7543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 75534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s) 7563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 757ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 7583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int i, range; 7593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char chanlo, chanhi, status; 7603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!cmd->chanlist) 7623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -EINVAL; 7633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get the channel list and range */ 7653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanlo = CR_CHAN(cmd->chanlist[0]) & (s->n_chan - 1); 7663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanhi = chanlo + cmd->chanlist_len - 1; 7673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (chanhi >= s->n_chan) 7683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -EINVAL; 7693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani range = CR_RANGE(cmd->chanlist[0]); 7703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* reset fifo */ 7723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_FIFORESET); 7733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set scan enable */ 7753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_SCANENABLE); 7763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* write the ai channel range regs */ 7783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_AILOW, chanlo); 7793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_AIHIGH, chanhi); 7803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the range bits */ 7823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_AICONF, dmm32at_rangebits[range]); 7833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* reset the interrupt just in case */ 7853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_INTRESET); 7863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (cmd->stop_src == TRIG_COUNT) 7883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->ai_scans_left = cmd->stop_arg; 7893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else { /* TRIG_NONE */ 7903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->ai_scans_left = 0xffffffff; /* indicates TRIG_NONE to isr */ 7913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 7923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 7933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* wait for circuit to settle */ 7943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 0; i < 40000; i++) { 7953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani status = dmm_inb(dev, DMM32AT_AIRBACK); 7963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if ((status & DMM32AT_STATUS) == 0) 7973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani break; 7983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 7993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (i == 40000) { 8003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("timeout\n"); 8013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -ETIMEDOUT; 8023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 8033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (devpriv->ai_scans_left > 1) { 8053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* start the clock and enable the interrupts */ 8063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm32at_setaitimer(dev, cmd->scan_begin_arg); 8073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 8083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* start the interrups and initiate a single scan */ 8093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_INTCLOCK, DMM32AT_ADINT); 8103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CONV, 0xff); 8113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 8123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* printk("dmmat32 in command\n"); */ 8143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* for(i=0;i<cmd->chanlist_len;i++) */ 8163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* comedi_buf_put(s->async,i*100); */ 8173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* s->async->events |= COMEDI_CB_EOA; */ 8193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* comedi_event(dev, s); */ 8203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 0; 8223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 8243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 82534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s) 8263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 8273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->ai_scans_left = 1; 8283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 0; 8293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 8303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanistatic irqreturn_t dmm32at_isr(int irq, void *d PT_REGS_ARG) 8323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 8333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char intstat; 8343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned int samp; 8353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned short msb, lsb; 8363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int i; 83771b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton struct comedi_device *dev = d; 8383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (!dev->attached) { 8403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi_error(dev, "spurious interrupt"); 8413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return IRQ_HANDLED; 8423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 8433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani intstat = dmm_inb(dev, DMM32AT_INTCLOCK); 8453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (intstat & DMM32AT_ADINT) { 84734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s = dev->read_subdev; 848ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd *cmd = &s->async->cmd; 8493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 0; i < cmd->chanlist_len; i++) { 8513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* read data */ 8523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani lsb = dmm_inb(dev, DMM32AT_AILSB); 8533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani msb = dmm_inb(dev, DMM32AT_AIMSB); 8543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* invert sign bit to make range unsigned */ 8563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani samp = ((msb ^ 0x0080) << 8) + lsb; 8573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi_buf_put(s->async, samp); 8583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 8593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (devpriv->ai_scans_left != 0xffffffff) { /* TRIG_COUNT */ 8613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->ai_scans_left--; 8623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (devpriv->ai_scans_left == 0) { 8633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* disable further interrupts and clocks */ 8643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_INTCLOCK, 0x0); 8653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the buffer to be flushed with an EOF */ 8663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->async->events |= COMEDI_CB_EOA; 8673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 8683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 8703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* flush the buffer */ 8713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani comedi_event(dev, s); 8723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 8733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* reset the interrupt */ 8753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_INTRESET); 8763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return IRQ_HANDLED; 8773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 8783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* This function doesn't require a particular form, this is just 8803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * what happens to be used in some of the drivers. It should 8813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * convert ns nanoseconds to a counter value suitable for programming 8823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * the device. Also, it should adjust ns so that it cooresponds to 8833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * the actual time that the device will use. */ 8843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplanistatic int dmm32at_ns_to_timer(unsigned int *ns, int round) 8853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 8863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* trivial timer */ 8873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* if your timing is done through two cascaded timers, the 8883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * i8253_cascade_ns_to_timer() function in 8253.h can be 8893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * very helpful. There are also i8254_load() and i8254_mm_load() 8903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * which can be used to load values into the ubiquitous 8254 counters 8913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 8923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 8933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return *ns; 8943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 8953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 89634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s, 897790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 8983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 8993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int i; 9003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int chan = CR_CHAN(insn->chanspec); 9013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char hi, lo, status; 9023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* Writing a list of values to an AO channel is probably not 9043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * very useful, but that's how the interface is defined. */ 9053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 0; i < insn->n; i++) { 9063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->ao_readback[chan] = data[i]; 9083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9093c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get the low byte */ 9103c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani lo = data[i] & 0x00ff; 9113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* high byte also contains channel number */ 9123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani hi = (data[i] >> 8) + chan * (1 << 6); 9133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani //printk("writing 0x%02x 0x%02x\n",hi,lo); 9143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* write the low and high values to the board */ 9153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_DACLSB, lo); 9163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_DACMSB, hi); 9173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* wait for circuit to settle */ 9193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 0; i < 40000; i++) { 9203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani status = dmm_inb(dev, DMM32AT_DACSTAT); 9213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if ((status & DMM32AT_DACBUSY) == 0) 9223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani break; 9233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 9243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (i == 40000) { 9253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani printk("timeout\n"); 9263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -ETIMEDOUT; 9273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 9283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* dummy read to update trigger the output */ 9293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani status = dmm_inb(dev, DMM32AT_DACMSB); 9303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 9323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* return the number of samples read/written */ 9343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return i; 9353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 9363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* AO subdevices should have a read insn as well as a write insn. 9383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * Usually this means copying a value stored in devpriv. */ 93934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 940790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 9413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 9423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int i; 9433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int chan = CR_CHAN(insn->chanspec); 9443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani for (i = 0; i < insn->n; i++) 9463c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani data[i] = devpriv->ao_readback[chan]; 9473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return i; 9493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 9503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* DIO devices are slightly special. Although it is possible to 9523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * implement the insn_read/insn_write interface, it is much more 9533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * useful to applications if you implement the insn_bits interface. 9543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * This allows packed reading/writing of the DIO channels. The 9553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * comedi core can convert between insn_bits and insn_read/write */ 95634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s, 957790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 9583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 9593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char diobits; 9603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (insn->n != 2) 9623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -EINVAL; 9633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* The insn data is a mask in data[0] and the new data 9653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * in data[1], each channel cooresponding to a bit. */ 9663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (data[0]) { 9673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->state &= ~data[0]; 9683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->state |= data[0] & data[1]; 9693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* Write out the new digital output lines */ 9703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani //outw(s->state,dev->iobase + DMM32AT_DIO); 9713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 9723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get access to the DIO regs */ 9743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC); 9753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* if either part of dio is set for output */ 9773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) || 9783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) { 9793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani diobits = (s->state & 0x00ff0000) >> 16; 9803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_DIOC, diobits); 9813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 9823c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if ((devpriv->dio_config & DMM32AT_DIRB) == 0) { 9833c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani diobits = (s->state & 0x0000ff00) >> 8; 9843c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_DIOB, diobits); 9853c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 9863c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if ((devpriv->dio_config & DMM32AT_DIRA) == 0) { 9873c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani diobits = (s->state & 0x000000ff); 9883c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_DIOA, diobits); 9893c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 9903c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9913c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* now read the state back in */ 9923c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->state = dmm_inb(dev, DMM32AT_DIOC); 9933c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->state <<= 8; 9943c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->state |= dmm_inb(dev, DMM32AT_DIOB); 9953c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->state <<= 8; 9963c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani s->state |= dmm_inb(dev, DMM32AT_DIOA); 9973c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani data[1] = s->state; 9983c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 9993c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* on return, data[1] contains the value of the digital 10003c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * input and output lines. */ 10013c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani //data[1]=inw(dev->iobase + DMM32AT_DIO); 10023c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* or we could just return the software copy of the output values if 10033c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * it was a purely digital output subdevice */ 10043c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani //data[1]=s->state; 10053c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10063c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 2; 10073c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 10083c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 100934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int dmm32at_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s, 1010790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 10113c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 10123c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char chanbit; 10133c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani int chan = CR_CHAN(insn->chanspec); 10143c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10153c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (insn->n != 1) 10163c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return -EINVAL; 10173c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10183c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (chan < 8) 10193c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanbit = DMM32AT_DIRA; 10203c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else if (chan < 16) 10213c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanbit = DMM32AT_DIRB; 10223c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else if (chan < 20) 10233c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanbit = DMM32AT_DIRCL; 10243c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani else 10253c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani chanbit = DMM32AT_DIRCH; 10263c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10273c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* The input or output configuration of each digital line is 10283c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * configured by a special insn_config instruction. chanspec 10293c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * contains the channel to be changed, and data[0] contains the 10303c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * value COMEDI_INPUT or COMEDI_OUTPUT. */ 10313c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10323c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* if output clear the bit, otherwise set it */ 10333c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani if (data[0] == COMEDI_OUTPUT) { 10343c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->dio_config &= ~chanbit; 10353c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } else { 10363c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani devpriv->dio_config |= chanbit; 10373c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani } 10383c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get access to the DIO regs */ 10393c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC); 10403c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the DIO's to the new configuration setting */ 10413c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config); 10423c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10433c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani return 1; 10443c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 10453c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 104671b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonvoid dmm32at_setaitimer(struct comedi_device * dev, unsigned int nansec) 10473c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani{ 10483c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned char lo1, lo2, hi2; 10493c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani unsigned short both2; 10503c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10513c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* based on 10mhz clock */ 10523c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani lo1 = 200; 10533c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani both2 = nansec / 20000; 10543c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani hi2 = (both2 & 0xff00) >> 8; 10553c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani lo2 = both2 & 0x00ff; 10563c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10573c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* set the counter frequency to 10mhz */ 10583c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CNTRDIO, 0); 10593c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10603c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* get access to the clock regs */ 10613c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_CLKACC); 10623c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10633c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* write the counter 1 control word and low byte to counter */ 10643c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CLKCT, DMM32AT_CLKCT1); 10653c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CLK1, lo1); 10663c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10673c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* write the counter 2 control word and low byte then to counter */ 10683c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CLKCT, DMM32AT_CLKCT2); 10693c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CLK2, lo2); 10703c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_CLK2, hi2); 10713c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10723c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani /* enable the ai conversion interrupt and the clock to start scans */ 10733c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani dmm_outb(dev, DMM32AT_INTCLOCK, DMM32AT_ADINT | DMM32AT_CLKSEL); 10743c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10753c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani} 10763c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani 10773c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani/* 10783c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * A convenient macro that defines init_module() and cleanup_module(), 10793c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani * as necessary. 10803c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. Piplani */ 10813c501880ac4436ad2db5feed6e7d7548e13d539fPerry J. PiplaniCOMEDI_INITCLEANUP(driver_dmm32at); 1082