addi_apci_2032.c revision 05fcdcede016a74ce7350af94aede6a49eebd5c9
1d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten/* 2d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * addi_apci_2032.c 3d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. 4d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Project manager: Eric Stolz 5d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * 6d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * ADDI-DATA GmbH 7d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Dieselstrasse 3 8d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * D-77833 Ottersweier 9d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Tel: +19(0)7223/9493-0 10d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Fax: +49(0)7223/9493-92 11d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * http://www.addi-data.com 12d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * info@addi-data.com 13d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * 14d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * This program is free software; you can redistribute it and/or modify it 15d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * under the terms of the GNU General Public License as published by the 16d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Free Software Foundation; either version 2 of the License, or (at your 17d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * option) any later version. 18d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * 19d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * This program is distributed in the hope that it will be useful, but WITHOUT 20d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 22d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * more details. 23d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * 24d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * You should have received a copy of the GNU General Public License along 25d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * with this program; if not, write to the Free Software Foundation, Inc., 26d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * 28d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * You should also find the complete GPL in the COPYING file accompanying 29d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * this source code. 30d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten */ 31d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 323d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "../comedidev.h" 333d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "comedi_fc.h" 343d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten 35d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten/* 36d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * PCI bar 1 I/O Register map 37d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten */ 387180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_DO_REG 0x00 397180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_CTRL_REG 0x04 407180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_CTRL_VCC_ENA (1 << 0) 417180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_CTRL_CC_ENA (1 << 1) 427180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_STATUS_REG 0x08 437180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_STATUS_VCC (1 << 0) 447180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_STATUS_CC (1 << 1) 457180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_STATUS_REG 0x0c 467180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_STATUS_IRQ (1 << 0) 477180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_REG 0x10 487180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_RELOAD_REG 0x14 497180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_TIMEBASE 0x18 507180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_CTRL_REG 0x1c 517180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_CTRL_ENABLE (1 << 0) 527180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_CTRL_SW_TRIG (1 << 9) 537180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_STATUS_REG 0x20 547180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_STATUS_ENABLED (1 << 0) 557180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_STATUS_SW_TRIG (1 << 1) 56d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 5723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstruct apci2032_private { 5823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten unsigned int wdog_ctrl; 5923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten}; 6023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 61d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweetenstatic int apci2032_do_insn_bits(struct comedi_device *dev, 62d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_subdevice *s, 63d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_insn *insn, 64d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int *data) 65d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 66d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int mask = data[0]; 67d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int bits = data[1]; 68d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 697180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten s->state = inl(dev->iobase + APCI2032_DO_REG); 70d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten if (mask) { 71d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten s->state &= ~mask; 72d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten s->state |= (bits & mask); 73d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 747180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(s->state, dev->iobase + APCI2032_DO_REG); 75d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten } 76d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 77d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten data[1] = s->state; 78d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 79d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return insn->n; 80d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 81d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 8223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten/* 8323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * The watchdog subdevice is configured with two INSN_CONFIG instructions: 8423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * 8523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * Enable the watchdog and set the reload timeout: 8623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * data[0] = INSN_CONFIG_ARM 8723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * data[1] = timeout reload value 8823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * 8923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * Disable the watchdog: 9023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * data[0] = INSN_CONFIG_DISARM 9123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten */ 9223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstatic int apci2032_wdog_insn_config(struct comedi_device *dev, 93d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_subdevice *s, 94d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_insn *insn, 95d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int *data) 96d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 9723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct apci2032_private *devpriv = dev->private; 9823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten unsigned int reload; 9923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 10023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten switch (data[0]) { 10123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten case INSN_CONFIG_ARM: 10223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten devpriv->wdog_ctrl = APCI2032_WDOG_CTRL_ENABLE; 10323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten reload = data[1] & s->maxdata; 10423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten outw(reload, dev->iobase + APCI2032_WDOG_RELOAD_REG); 10523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 10623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten /* Time base is 20ms, let the user know the timeout */ 10723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n", 10823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 20 * reload + 20); 10923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten break; 11023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten case INSN_CONFIG_DISARM: 11123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten devpriv->wdog_ctrl = 0; 11223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten break; 11323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten default: 114d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return -EINVAL; 115d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten } 116d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 11723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten outw(devpriv->wdog_ctrl, dev->iobase + APCI2032_WDOG_CTRL_REG); 11823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 119d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return insn->n; 120d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 121d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 12223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstatic int apci2032_wdog_insn_write(struct comedi_device *dev, 12323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct comedi_subdevice *s, 12423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct comedi_insn *insn, 12523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten unsigned int *data) 126d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 12723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct apci2032_private *devpriv = dev->private; 12823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten int i; 12923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 13023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten if (devpriv->wdog_ctrl == 0) { 13123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten dev_warn(dev->class_dev, "watchdog is disabled\n"); 132d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return -EINVAL; 133d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten } 13423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 13523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten /* "ping" the watchdog */ 13623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten for (i = 0; i < insn->n; i++) { 13723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten outw(devpriv->wdog_ctrl | APCI2032_WDOG_CTRL_SW_TRIG, 13823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten dev->iobase + APCI2032_WDOG_CTRL_REG); 13923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten } 14023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 141d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return insn->n; 142d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 143d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 14423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstatic int apci2032_wdog_insn_read(struct comedi_device *dev, 145d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_subdevice *s, 146d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_insn *insn, 147d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int *data) 148d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 1497b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten int i; 1507b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten 1517b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten for (i = 0; i < insn->n; i++) 1527b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten data[i] = inl(dev->iobase + APCI2032_WDOG_STATUS_REG); 1537b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten 154d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return insn->n; 155d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 156d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 15705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic int apci2032_int_insn_bits(struct comedi_device *dev, 15805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s, 15905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_insn *insn, 16005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten unsigned int *data) 161b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten{ 16205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten data[1] = s->state; 16305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return insn->n; 16405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten} 165b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 16605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic int apci2032_int_cmdtest(struct comedi_device *dev, 16705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s, 16805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_cmd *cmd) 16905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten{ 17005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten int err = 0; 171b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 17205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Step 1 : check if triggers are trivially valid */ 173b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 17405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); 17505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_OTHER); 17605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); 17705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 17805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); 179b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 18005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (err) 18105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 1; 182b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 18305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Step 2a : make sure trigger sources are unique */ 18405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Step 2b : and mutually compatible */ 18505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 18605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (err) 18705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 2; 18805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 18905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Step 3: check if arguments are trivially valid */ 19005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 19105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 19205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 19305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* 19405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten * 0 == no trigger 19505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten * 1 == trigger on VCC interrupt 19605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten * 2 == trigger on CC interrupt 19705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten * 3 == trigger on either VCC or CC interrupt 19805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten */ 19905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 3); 20005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 20105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); 20205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); 20305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 20405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 20505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (err) 20605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 3; 20705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 20805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* step 4: ignored */ 20905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 21005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (err) 21105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 4; 21205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 21305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 0; 214b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten} 215b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 21605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic int apci2032_int_cmd(struct comedi_device *dev, 21705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s) 218d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 21905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_cmd *cmd = &s->async->cmd; 22005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 22105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten outl(cmd->scan_begin_arg, dev->iobase + APCI2032_INT_CTRL_REG); 22205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 22305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 0; 224d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 2257180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten 22605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic int apci2032_int_cancel(struct comedi_device *dev, 22705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s) 228d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 22905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG); 230d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 23105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 0; 232d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 233317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten 23405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic irqreturn_t apci2032_interrupt(int irq, void *d) 23525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{ 23605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_device *dev = d; 23705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s = dev->read_subdev; 23805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten unsigned int val; 23905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 24005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Check if VCC OR CC interrupt has occurred */ 24105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten val = inl(dev->iobase + APCI2032_STATUS_REG) & APCI2032_STATUS_IRQ; 24205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (!val) 24305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return IRQ_NONE; 24405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 24505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->state = inl(dev->iobase + APCI2032_INT_STATUS_REG); 24605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG); 24705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 24805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten comedi_buf_put(s->async, s->state); 24905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; 25005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten comedi_event(dev, s); 25105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 25205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return IRQ_HANDLED; 25325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten} 25425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 255791c9792ff2d12a02f0ab1c47fd7f7a94828b05bH Hartley Sweetenstatic int apci2032_reset(struct comedi_device *dev) 25625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{ 2577180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(0x0, dev->iobase + APCI2032_DO_REG); 2587180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG); 2597180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(0x0, dev->iobase + APCI2032_WDOG_CTRL_REG); 2607180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(0x0, dev->iobase + APCI2032_WDOG_RELOAD_REG); 26125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 26225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten return 0; 26325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten} 26425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 26525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweetenstatic int apci2032_auto_attach(struct comedi_device *dev, 26625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten unsigned long context_unused) 26725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{ 26825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten struct pci_dev *pcidev = comedi_to_pci_dev(dev); 26923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct apci2032_private *devpriv; 27025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten struct comedi_subdevice *s; 2710c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten int ret; 27225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 273c0c3c7dfc1fd5c970b9893e68796314e8551124fH Hartley Sweeten dev->board_name = dev->driver->driver_name; 27425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 27523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); 27623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten if (!devpriv) 27723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten return -ENOMEM; 27823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten dev->private = devpriv; 27923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 28025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten ret = comedi_pci_enable(pcidev, dev->board_name); 28125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (ret) 28225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten return ret; 28370ff406599a5debfa6e5ef243e5e093f63a9ed69H Hartley Sweeten dev->iobase = pci_resource_start(pcidev, 1); 28425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 28525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (pcidev->irq > 0) { 28605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten ret = request_irq(pcidev->irq, apci2032_interrupt, 28705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten IRQF_SHARED, dev->board_name, dev); 28825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (ret == 0) 28925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten dev->irq = pcidev->irq; 29025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten } 29125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 29205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten ret = comedi_alloc_subdevices(dev, 3); 29325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (ret) 29425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten return ret; 29525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 2960c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten /* Initialize the digital output subdevice */ 29725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten s = &dev->subdevices[0]; 298cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->type = COMEDI_SUBD_DO; 299cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->subdev_flags = SDF_WRITEABLE; 300cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->n_chan = 32; 301cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->maxdata = 1; 302cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->range_table = &range_digital; 303cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->insn_bits = apci2032_do_insn_bits; 30425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 3050c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten /* Initialize the watchdog subdevice */ 3060c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten s = &dev->subdevices[1]; 307cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->type = COMEDI_SUBD_TIMER; 308cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->subdev_flags = SDF_WRITEABLE; 309cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->n_chan = 1; 310cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->maxdata = 0xff; 311cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->insn_write = apci2032_wdog_insn_write; 312cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->insn_read = apci2032_wdog_insn_read; 313cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->insn_config = apci2032_wdog_insn_config; 31425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 31505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Initialize the interrupt subdevice */ 31605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s = &dev->subdevices[2]; 31705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (dev->irq) { 31805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten dev->read_subdev = s; 31905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->type = COMEDI_SUBD_DI | SDF_CMD_READ; 32005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->subdev_flags = SDF_READABLE; 32105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->n_chan = 1; 32205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->maxdata = 1; 32305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->range_table = &range_digital; 32405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->insn_bits = apci2032_int_insn_bits; 32505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->do_cmdtest = apci2032_int_cmdtest; 32605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->do_cmd = apci2032_int_cmd; 32705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->cancel = apci2032_int_cancel; 32805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten } else { 32905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->type = COMEDI_SUBD_UNUSED; 33005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten } 33105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 332791c9792ff2d12a02f0ab1c47fd7f7a94828b05bH Hartley Sweeten apci2032_reset(dev); 33325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten return 0; 33425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten} 33525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 33625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweetenstatic void apci2032_detach(struct comedi_device *dev) 33725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{ 33825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten struct pci_dev *pcidev = comedi_to_pci_dev(dev); 33925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 340dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten if (dev->iobase) 341dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten apci2032_reset(dev); 342dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten if (dev->irq) 343dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten free_irq(dev->irq, dev); 34425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (pcidev) { 34525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (dev->iobase) 34625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten comedi_pci_disable(pcidev); 34725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten } 34825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten} 34925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 35020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct comedi_driver apci2032_driver = { 35120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .driver_name = "addi_apci_2032", 35220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .module = THIS_MODULE, 35325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten .auto_attach = apci2032_auto_attach, 35425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten .detach = apci2032_detach, 35520a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}; 35620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 357a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int apci2032_pci_probe(struct pci_dev *dev, 35820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten const struct pci_device_id *ent) 35920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{ 36020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten return comedi_pci_auto_config(dev, &apci2032_driver); 36120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten} 36220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 36353b800198592b0ff96577ecc5f116f7d902a4362Bill Pembertonstatic void apci2032_pci_remove(struct pci_dev *dev) 36420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{ 36520a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten comedi_pci_auto_unconfig(dev); 36620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten} 36720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 36820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = { 369317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) }, 370317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten { 0 } 371317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten}; 37220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley SweetenMODULE_DEVICE_TABLE(pci, apci2032_pci_table); 373317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten 37420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct pci_driver apci2032_pci_driver = { 37520a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .name = "addi_apci_2032", 37620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .id_table = apci2032_pci_table, 37720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .probe = apci2032_pci_probe, 378a471eace7baa40cdf16d3f26b2f78ddce613ca8fBill Pemberton .remove = apci2032_pci_remove, 37920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}; 38020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenmodule_comedi_pci_driver(apci2032_driver, apci2032_pci_driver); 38190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 38290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 38390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 38490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 385