148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/* 279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * das6402.c 379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Comedi driver for DAS6402 compatible boards 479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Copyright(c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com> 579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * 679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Rewrite of an experimental driver by: 779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Copyright (C) 1999 Oystein Svendsen <svendsen@pvv.org> 879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * 979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * This program is free software; you can redistribute it and/or modify 1079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * it under the terms of the GNU General Public License as published by 1179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * the Free Software Foundation; either version 2 of the License, or 1279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * (at your option) any later version. 1379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * 1479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * This program is distributed in the hope that it will be useful, 1579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * but WITHOUT ANY WARRANTY; without even the implied warranty of 1679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * GNU General Public License for more details. 1848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen */ 1948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 2048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/* 2179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Driver: das6402 2279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Description: Keithley Metrabyte DAS6402 (& compatibles) 2379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Devices: (Keithley Metrabyte) DAS6402-12 (das6402-12) 2479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * (Keithley Metrabyte) DAS6402-16 (das6402-16) 2579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Author: H Hartley Sweeten <hsweeten@visionengravers.com> 2679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Updated: Fri, 14 Mar 2014 10:18:43 -0700 2779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Status: unknown 2879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * 2979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Configuration Options: 3079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * [0] - I/O base address 3179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * [1] - IRQ (optional, needed for async command support) 3279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten */ 3348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 3479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#include <linux/module.h> 3579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#include <linux/interrupt.h> 3648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 3779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#include "../comedidev.h" 3879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#include "8253.h" 3948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 4048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen/* 4179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Register I/O map 4279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten */ 4379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_AI_DATA_REG 0x00 4479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_AI_MUX_REG 0x02 4579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_AI_MUX_LO(x) (((x) & 0x3f) << 0) 4679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_AI_MUX_HI(x) (((x) & 0x3f) << 8) 4779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_DI_DO_REG 0x03 4879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_AO_DATA_REG(x) (0x04 + ((x) * 2)) 4979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_AO_LSB_REG(x) (0x04 + ((x) * 2)) 5079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_AO_MSB_REG(x) (0x05 + ((x) * 2)) 5179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_REG 0x08 5279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_FFNE (1 << 0) 5379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_FHALF (1 << 1) 5479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_FFULL (1 << 2) 5579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_XINT (1 << 3) 5679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_INT (1 << 4) 5779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_XTRIG (1 << 5) 5879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_INDGT (1 << 6) 5979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_10MHZ (1 << 7) 6079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_W_CLRINT (1 << 0) 6179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_W_CLRXTR (1 << 1) 6279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_W_CLRXIN (1 << 2) 6379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_W_EXTEND (1 << 4) 6479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_W_ARMED (1 << 5) 6579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_W_POSTMODE (1 << 6) 6679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_STATUS_W_10MHZ (1 << 7) 6779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_CTRL_REG 0x09 6879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_CTRL_SOFT_TRIG (0 << 0) 6979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_CTRL_EXT_FALL_TRIG (1 << 0) 7079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_CTRL_EXT_RISE_TRIG (2 << 0) 7179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_CTRL_PACER_TRIG (3 << 0) 7279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_CTRL_BURSTEN (1 << 2) 7379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_CTRL_XINTE (1 << 3) 7479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_CTRL_IRQ(x) ((x) << 4) 7579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_CTRL_INTE (1 << 7) 7679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_TRIG_REG 0x0a 7779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_TRIG_TGEN (1 << 0) 7879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_TRIG_TGSEL (1 << 1) 7979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_TRIG_TGPOL (1 << 2) 8079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_TRIG_PRETRIG (1 << 3) 8179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_AO_RANGE(_chan, _range) ((_range) << ((_chan) ? 6 : 4)) 8279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_AO_RANGE_MASK(_chan) (3 << ((_chan) ? 6 : 4)) 8379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_REG 0x0b 8479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_RANGE(x) ((x) << 0) 8579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_POLLED (0 << 2) 8679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_FIFONEPTY (1 << 2) 8779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_FIFOHFULL (2 << 2) 8879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_EOB (3 << 2) 8979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_ENHANCED (1 << 4) 9079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_SE (1 << 5) 9179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_UNI (1 << 6) 9279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_DMA1 (0 << 7) 9379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_MODE_DMA3 (1 << 7) 9479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten#define DAS6402_TIMER_BASE 0x0c 9579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 9679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic const struct comedi_lrange das6402_ai_ranges = { 9779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 8, { 9879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten BIP_RANGE(10), 9979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten BIP_RANGE(5), 10079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten BIP_RANGE(2.5), 10179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten BIP_RANGE(1.25), 10279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten UNI_RANGE(10), 10379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten UNI_RANGE(5), 10479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten UNI_RANGE(2.5), 10579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten UNI_RANGE(1.25) 10679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 10779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten}; 10848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 10979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten/* 11079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * Analog output ranges are programmable on the DAS6402/12. 11179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * For the DAS6402/16 the range bits have no function, the 11279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * DAC ranges are selected by switches on the board. 11379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten */ 11479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic const struct comedi_lrange das6402_ao_ranges = { 11579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 4, { 11679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten BIP_RANGE(5), 11779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten BIP_RANGE(10), 11879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten UNI_RANGE(5), 11979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten UNI_RANGE(10) 12079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 12179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten}; 12248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 12379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstruct das6402_boardinfo { 12479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten const char *name; 12579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int maxdata; 12679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten}; 12748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 128bee2d6a82cc31ebcc44a0ec9484ec1670c07ca6aMichele Curtistatic struct das6402_boardinfo das6402_boards[] = { 12979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten { 13079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten .name = "das6402-12", 13179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten .maxdata = 0x0fff, 13279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten }, { 13379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten .name = "das6402-16", 13479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten .maxdata = 0xffff, 13579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten }, 13679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten}; 13748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 138c7b8bb98a46e475ae848642cf60160fc7135cd52Bill Pembertonstruct das6402_private { 13979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int irq; 14079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 14179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int count; 14279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int divider1; 14379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int divider2; 14448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 14579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int ao_range; 146c7b8bb98a46e475ae848642cf60160fc7135cd52Bill Pemberton}; 14748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 14879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic void das6402_set_mode(struct comedi_device *dev, 14979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int mode) 15071e7271b15d55d8ab668745f680d03044bcf7db0H Hartley Sweeten{ 15179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(DAS6402_MODE_ENHANCED | mode, dev->iobase + DAS6402_MODE_REG); 15271e7271b15d55d8ab668745f680d03044bcf7db0H Hartley Sweeten} 15348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 15479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic void das6402_set_extended(struct comedi_device *dev, 15579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int val) 15648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{ 15779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(DAS6402_STATUS_W_EXTEND, dev->iobase + DAS6402_STATUS_REG); 15879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(DAS6402_STATUS_W_EXTEND | val, dev->iobase + DAS6402_STATUS_REG); 15979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(val, dev->iobase + DAS6402_STATUS_REG); 16048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen} 16148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 16279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic void das6402_clear_all_interrupts(struct comedi_device *dev) 16379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 16479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(DAS6402_STATUS_W_CLRINT | 16579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten DAS6402_STATUS_W_CLRXTR | 16679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten DAS6402_STATUS_W_CLRXIN, dev->iobase + DAS6402_STATUS_REG); 16779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 16879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 16979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic void das6402_ai_clear_eoc(struct comedi_device *dev) 17079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 17179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(DAS6402_STATUS_W_CLRINT, dev->iobase + DAS6402_STATUS_REG); 17279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 17379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 17479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic void das6402_enable_counter(struct comedi_device *dev, bool load) 17548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{ 1769a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweeten struct das6402_private *devpriv = dev->private; 17779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned long timer_iobase = dev->iobase + DAS6402_TIMER_BASE; 17848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 17979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (load) { 18079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten i8254_set_mode(timer_iobase, 0, 0, I8254_MODE0 | I8254_BINARY); 18179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten i8254_set_mode(timer_iobase, 0, 1, I8254_MODE2 | I8254_BINARY); 18279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten i8254_set_mode(timer_iobase, 0, 2, I8254_MODE2 | I8254_BINARY); 18348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 18479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten i8254_write(timer_iobase, 0, 0, devpriv->count); 18579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten i8254_write(timer_iobase, 0, 1, devpriv->divider1); 18679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten i8254_write(timer_iobase, 0, 2, devpriv->divider2); 18748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 18879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } else { 18979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten i8254_set_mode(timer_iobase, 0, 0, I8254_MODE0 | I8254_BINARY); 19079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten i8254_set_mode(timer_iobase, 0, 1, I8254_MODE0 | I8254_BINARY); 19179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten i8254_set_mode(timer_iobase, 0, 2, I8254_MODE0 | I8254_BINARY); 19248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen } 19379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 19448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 19579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic irqreturn_t das6402_interrupt(int irq, void *d) 19679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 19779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_device *dev = d; 19879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 19979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_clear_all_interrupts(dev); 20048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 20148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen return IRQ_HANDLED; 20248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen} 20348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 20479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic int das6402_ai_cmd(struct comedi_device *dev, 20579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_subdevice *s) 20648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{ 20779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return -EINVAL; 20879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 20948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 21079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic int das6402_ai_cmdtest(struct comedi_device *dev, 21179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_subdevice *s, 21279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_cmd *cmd) 21379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 21479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return -EINVAL; 21548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen} 21648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 2170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das6402_ai_cancel(struct comedi_device *dev, 2180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 21948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{ 22079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG); 22179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 22279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return 0; 22379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 22479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 22579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic void das6402_ai_soft_trig(struct comedi_device *dev) 22679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 22779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outw(0, dev->iobase + DAS6402_AI_DATA_REG); 22879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 22979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 23079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic int das6402_ai_eoc(struct comedi_device *dev, 23179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_subdevice *s, 23279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_insn *insn, 23379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned long context) 23479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 23579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int status; 23679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 23779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten status = inb(dev->iobase + DAS6402_STATUS_REG); 23879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (status & DAS6402_STATUS_FFNE) 23979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return 0; 24079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return -EBUSY; 24179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 24279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 24379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic int das6402_ai_insn_read(struct comedi_device *dev, 24479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_subdevice *s, 24579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_insn *insn, 24679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int *data) 24779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 24879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int chan = CR_CHAN(insn->chanspec); 24979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int range = CR_RANGE(insn->chanspec); 25079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int aref = CR_AREF(insn->chanspec); 25179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int val; 25279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten int ret; 25379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten int i; 25479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 25579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val = DAS6402_MODE_RANGE(range) | DAS6402_MODE_POLLED; 25679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (aref == AREF_DIFF) { 25779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (chan > s->n_chan / 2) 25879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return -EINVAL; 25979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } else { 26079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val |= DAS6402_MODE_SE; 26179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 26279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (comedi_range_is_unipolar(s, range)) 26379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val |= DAS6402_MODE_UNI; 26479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 26579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* enable software conversion trigger */ 26679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG); 26779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 26879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_set_mode(dev, val); 26979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 27079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* load the mux for single channel conversion */ 27179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outw(DAS6402_AI_MUX_HI(chan) | DAS6402_AI_MUX_LO(chan), 27279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten dev->iobase + DAS6402_AI_MUX_REG); 27379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 27479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten for (i = 0; i < insn->n; i++) { 27579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_ai_clear_eoc(dev); 27679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_ai_soft_trig(dev); 27779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 27879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten ret = comedi_timeout(dev, s, insn, das6402_ai_eoc, 0); 27979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (ret) 28079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten break; 28179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 28279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val = inw(dev->iobase + DAS6402_AI_DATA_REG); 28379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 28479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (s->maxdata == 0x0fff) 28579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val >>= 4; 28679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 28779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten data[i] = val; 28879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 28979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 29079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_ai_clear_eoc(dev); 29179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 29279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return insn->n; 29379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 29479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 29579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic int das6402_ao_insn_write(struct comedi_device *dev, 29679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_subdevice *s, 29779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_insn *insn, 29879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int *data) 29979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 3009a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweeten struct das6402_private *devpriv = dev->private; 30179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int chan = CR_CHAN(insn->chanspec); 30279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int range = CR_RANGE(insn->chanspec); 30379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int val; 30479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten int i; 30579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 30679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* set the range for this channel */ 30779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val = devpriv->ao_range; 30879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val &= ~DAS6402_AO_RANGE_MASK(chan); 30979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val |= DAS6402_AO_RANGE(chan, range); 31079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (val != devpriv->ao_range) { 31179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten devpriv->ao_range = val; 31279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(val, dev->iobase + DAS6402_TRIG_REG); 31379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 3149a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweeten 31548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen /* 31679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * The DAS6402/16 has a jumper to select either individual 31779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * update (UPDATE) or simultaneous updating (XFER) of both 31879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * DAC's. In UPDATE mode, when the MSB is written, that DAC 31979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * is updated. In XFER mode, after both DAC's are loaded, 32079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * a read cycle of any DAC register will update both DAC's 32179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * simultaneously. 32279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * 32379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * If you have XFER mode enabled a (*insn_read) will need 32479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * to be performed in order to update the DAC's with the 32579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * last value written. 32648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen */ 32779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten for (i = 0; i < insn->n; i++) { 32879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val = data[i]; 32979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 3303dd0b514d95b2063c211d5b00940202921cce3eaH Hartley Sweeten s->readback[chan] = val; 33179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 33279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (s->maxdata == 0x0fff) { 33379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* 33479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * DAS6402/12 has the two 8-bit DAC registers, left 33579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * justified (the 4 LSB bits are don't care). Data 33679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * can be written as one word. 33779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten */ 33879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten val <<= 4; 33979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outw(val, dev->iobase + DAS6402_AO_DATA_REG(chan)); 34079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } else { 34179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* 34279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * DAS6402/16 uses both 8-bit DAC registers and needs 34379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * to be written LSB then MSB. 34479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten */ 34579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(val & 0xff, 34679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten dev->iobase + DAS6402_AO_LSB_REG(chan)); 34779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb((val >> 8) & 0xff, 34879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten dev->iobase + DAS6402_AO_LSB_REG(chan)); 34979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 35079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 35148f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 35279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return insn->n; 35348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen} 35448f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 35579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic int das6402_ao_insn_read(struct comedi_device *dev, 35679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_subdevice *s, 35779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_insn *insn, 35879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int *data) 35948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{ 36079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int chan = CR_CHAN(insn->chanspec); 3619a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweeten 36279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* 36379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * If XFER mode is enabled, reading any DAC register 36479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten * will update both DAC's simultaneously. 36579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten */ 36679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten inw(dev->iobase + DAS6402_AO_LSB_REG(chan)); 36748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 3683dd0b514d95b2063c211d5b00940202921cce3eaH Hartley Sweeten return comedi_readback_insn_read(dev, s, insn, data); 36979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 37048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 37179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic int das6402_di_insn_bits(struct comedi_device *dev, 37279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_subdevice *s, 37379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_insn *insn, 37479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int *data) 37579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 37679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten data[1] = inb(dev->iobase + DAS6402_DI_DO_REG); 37748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 37879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return insn->n; 37948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen} 38048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 38179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic int das6402_do_insn_bits(struct comedi_device *dev, 38279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_subdevice *s, 38379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct comedi_insn *insn, 38479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten unsigned int *data) 38548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{ 38679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (comedi_dio_update_state(s, data)) 38779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(s->state, dev->iobase + DAS6402_DI_DO_REG); 38848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 38979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten data[1] = s->state; 39048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 39179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return insn->n; 39279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten} 39348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 39479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweetenstatic void das6402_reset(struct comedi_device *dev) 39579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten{ 39679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten struct das6402_private *devpriv = dev->private; 39748f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 39879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* enable "Enhanced" mode */ 39979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(DAS6402_MODE_ENHANCED, dev->iobase + DAS6402_MODE_REG); 40048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 40179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* enable 10MHz pacer clock */ 40279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_set_extended(dev, DAS6402_STATUS_W_10MHZ); 40348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 40479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* enable software conversion trigger */ 40579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG); 40648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 40779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* default ADC to single-ended unipolar 10V inputs */ 40879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_set_mode(dev, DAS6402_MODE_RANGE(0) | 40979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten DAS6402_MODE_POLLED | 41079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten DAS6402_MODE_SE | 41179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten DAS6402_MODE_UNI); 41248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 41379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* default mux for single channel conversion (channel 0) */ 41479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outw(DAS6402_AI_MUX_HI(0) | DAS6402_AI_MUX_LO(0), 41579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten dev->iobase + DAS6402_AI_MUX_REG); 41648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 41779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* set both DAC's for unipolar 5V output range */ 41879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten devpriv->ao_range = DAS6402_AO_RANGE(0, 2) | DAS6402_AO_RANGE(1, 2); 41979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(devpriv->ao_range, dev->iobase + DAS6402_TRIG_REG); 42048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 42179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* set both DAC's to 0V */ 42279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outw(0, dev->iobase + DAS6402_AO_DATA_REG(0)); 42379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outw(0, dev->iobase + DAS6402_AO_DATA_REG(0)); 42479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten inw(dev->iobase + DAS6402_AO_LSB_REG(0)); 42548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 42679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_enable_counter(dev, false); 42779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 42879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* set all digital outputs low */ 42979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten outb(0, dev->iobase + DAS6402_DI_DO_REG); 43079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 43179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_clear_all_interrupts(dev); 43248f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen} 43348f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 4340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das6402_attach(struct comedi_device *dev, 4350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 43648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen{ 43719924ce0c1fab868671d2fb845e402ab1bd848e3Ian Abbott const struct das6402_boardinfo *board = dev->board_ptr; 4389a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweeten struct das6402_private *devpriv; 43934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 44079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten int ret; 4419a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweeten 4420bdab509bf9c6d838dc0a3b1d68bbf841fc20b5aH Hartley Sweeten devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 443c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten if (!devpriv) 444c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten return -ENOMEM; 44548f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 44679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten ret = comedi_request_region(dev, it->options[0], 0x10); 4478b6c56949ffa83dbc2a6e8fa3f98b10a19372207H Hartley Sweeten if (ret) 44848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen return ret; 44948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 45079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten das6402_reset(dev); 45179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 45279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* IRQs 2,3,5,6,7, 10,11,15 are valid for "enhanced" mode */ 45379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if ((1 << it->options[1]) & 0x8cec) { 45479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten ret = request_irq(it->options[1], das6402_interrupt, 0, 45579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten dev->board_name, dev); 45679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (ret == 0) { 45779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten dev->irq = it->options[1]; 45879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 45979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten switch (dev->irq) { 46079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten case 10: 46179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten devpriv->irq = 4; 46279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten break; 46379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten case 11: 46479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten devpriv->irq = 1; 46579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten break; 46679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten case 15: 46779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten devpriv->irq = 6; 46879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten break; 46979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten default: 47079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten devpriv->irq = dev->irq; 47179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten break; 47279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 47379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 47479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 47579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 47679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten ret = comedi_alloc_subdevices(dev, 4); 47779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (ret) 47879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten return ret; 47979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 48079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* Analog Input subdevice */ 48192cfef5d90148f1a91fba528971ed6ae39b1c14bH Hartley Sweeten s = &dev->subdevices[0]; 48279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->type = COMEDI_SUBD_AI; 48379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; 48479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->n_chan = 64; 48579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->maxdata = board->maxdata; 48679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->range_table = &das6402_ai_ranges; 48779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->insn_read = das6402_ai_insn_read; 48879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten if (dev->irq) { 48979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten dev->read_subdev = s; 49079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->subdev_flags |= SDF_CMD_READ; 49179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->len_chanlist = s->n_chan; 49279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->do_cmdtest = das6402_ai_cmdtest; 49379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->do_cmd = das6402_ai_cmd; 49479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->cancel = das6402_ai_cancel; 49579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten } 49648f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 49779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* Analog Output subdevice */ 49879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s = &dev->subdevices[1]; 49979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->type = COMEDI_SUBD_AO; 50079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->subdev_flags = SDF_WRITEABLE; 50179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->n_chan = 2; 50279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->maxdata = board->maxdata; 50379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->range_table = &das6402_ao_ranges; 50479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->insn_write = das6402_ao_insn_write; 50579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->insn_read = das6402_ao_insn_read; 50679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 5073dd0b514d95b2063c211d5b00940202921cce3eaH Hartley Sweeten ret = comedi_alloc_subdev_readback(s); 5083dd0b514d95b2063c211d5b00940202921cce3eaH Hartley Sweeten if (ret) 5093dd0b514d95b2063c211d5b00940202921cce3eaH Hartley Sweeten return ret; 5103dd0b514d95b2063c211d5b00940202921cce3eaH Hartley Sweeten 51179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* Digital Input subdevice */ 51279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s = &dev->subdevices[2]; 51379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->type = COMEDI_SUBD_DI; 51479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->subdev_flags = SDF_READABLE; 51579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->n_chan = 8; 51679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->maxdata = 1; 51779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->range_table = &range_digital; 51879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->insn_bits = das6402_di_insn_bits; 51979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten 52079e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten /* Digital Input subdevice */ 52179e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s = &dev->subdevices[3]; 52279e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->type = COMEDI_SUBD_DO; 52379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->subdev_flags = SDF_WRITEABLE; 52479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->n_chan = 8; 52579e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->maxdata = 1; 52679e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->range_table = &range_digital; 52779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten s->insn_bits = das6402_do_insn_bits; 52848f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen 52948f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen return 0; 53048f16b6aeafdfb77b1698173f225b20b825eebf7Oystein Svendsen} 53190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 53271e7271b15d55d8ab668745f680d03044bcf7db0H Hartley Sweetenstatic struct comedi_driver das6402_driver = { 53371e7271b15d55d8ab668745f680d03044bcf7db0H Hartley Sweeten .driver_name = "das6402", 53471e7271b15d55d8ab668745f680d03044bcf7db0H Hartley Sweeten .module = THIS_MODULE, 53571e7271b15d55d8ab668745f680d03044bcf7db0H Hartley Sweeten .attach = das6402_attach, 5363d1fe3f785c80e17f62acf8f92570ae9210bd588H Hartley Sweeten .detach = comedi_legacy_detach, 53779e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten .board_name = &das6402_boards[0].name, 53879e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten .num_names = ARRAY_SIZE(das6402_boards), 53979e5e6addbb18bf56075f0ff552094a28636dd03H Hartley Sweeten .offset = sizeof(struct das6402_boardinfo), 54071e7271b15d55d8ab668745f680d03044bcf7db0H Hartley Sweeten}; 54171e7271b15d55d8ab668745f680d03044bcf7db0H Hartley Sweetenmodule_comedi_driver(das6402_driver) 54271e7271b15d55d8ab668745f680d03044bcf7db0H Hartley Sweeten 54379e5e6addbb18bf56075f0ff552094a28636dd03H Hartley SweetenMODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); 54479e5e6addbb18bf56075f0ff552094a28636dd03H Hartley SweetenMODULE_DESCRIPTION("Comedi driver for DAS6402 compatible boards"); 54590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 546