addi_apci_2032.c revision 5c2d4cba9586ddc3505f51bddf935ddc65a0e0bb
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 615c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbottstruct apci2032_int_private { 625c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott spinlock_t spinlock; 635c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott bool active; 645c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott unsigned char enabled_isns; 655c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott}; 665c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 67d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweetenstatic int apci2032_do_insn_bits(struct comedi_device *dev, 68d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_subdevice *s, 69d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_insn *insn, 70d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int *data) 71d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 72d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int mask = data[0]; 73d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int bits = data[1]; 74d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 757180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten s->state = inl(dev->iobase + APCI2032_DO_REG); 76d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten if (mask) { 77d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten s->state &= ~mask; 78d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten s->state |= (bits & mask); 79d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 807180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(s->state, dev->iobase + APCI2032_DO_REG); 81d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten } 82d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 83d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten data[1] = s->state; 84d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 85d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return insn->n; 86d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 87d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 8823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten/* 8923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * The watchdog subdevice is configured with two INSN_CONFIG instructions: 9023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * 9123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * Enable the watchdog and set the reload timeout: 9223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * data[0] = INSN_CONFIG_ARM 9323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * data[1] = timeout reload value 9423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * 9523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * Disable the watchdog: 9623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * data[0] = INSN_CONFIG_DISARM 9723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten */ 9823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstatic int apci2032_wdog_insn_config(struct comedi_device *dev, 99d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_subdevice *s, 100d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_insn *insn, 101d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int *data) 102d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 10323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct apci2032_private *devpriv = dev->private; 10423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten unsigned int reload; 10523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 10623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten switch (data[0]) { 10723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten case INSN_CONFIG_ARM: 10823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten devpriv->wdog_ctrl = APCI2032_WDOG_CTRL_ENABLE; 10923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten reload = data[1] & s->maxdata; 11023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten outw(reload, dev->iobase + APCI2032_WDOG_RELOAD_REG); 11123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 11223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten /* Time base is 20ms, let the user know the timeout */ 11323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n", 11423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 20 * reload + 20); 11523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten break; 11623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten case INSN_CONFIG_DISARM: 11723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten devpriv->wdog_ctrl = 0; 11823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten break; 11923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten default: 120d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return -EINVAL; 121d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten } 122d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 12323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten outw(devpriv->wdog_ctrl, dev->iobase + APCI2032_WDOG_CTRL_REG); 12423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 125d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return insn->n; 126d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 127d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 12823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstatic int apci2032_wdog_insn_write(struct comedi_device *dev, 12923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct comedi_subdevice *s, 13023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct comedi_insn *insn, 13123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten unsigned int *data) 132d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 13323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct apci2032_private *devpriv = dev->private; 13423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten int i; 13523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 13623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten if (devpriv->wdog_ctrl == 0) { 13723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten dev_warn(dev->class_dev, "watchdog is disabled\n"); 138d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return -EINVAL; 139d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten } 14023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 14123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten /* "ping" the watchdog */ 14223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten for (i = 0; i < insn->n; i++) { 14323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten outw(devpriv->wdog_ctrl | APCI2032_WDOG_CTRL_SW_TRIG, 14423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten dev->iobase + APCI2032_WDOG_CTRL_REG); 14523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten } 14623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 147d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return insn->n; 148d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 149d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 15023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstatic int apci2032_wdog_insn_read(struct comedi_device *dev, 151d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_subdevice *s, 152d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten struct comedi_insn *insn, 153d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten unsigned int *data) 154d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 1557b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten int i; 1567b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten 1577b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten for (i = 0; i < insn->n; i++) 1587b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten data[i] = inl(dev->iobase + APCI2032_WDOG_STATUS_REG); 1597b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten 160d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten return insn->n; 161d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 162d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 16305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic int apci2032_int_insn_bits(struct comedi_device *dev, 16405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s, 16505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_insn *insn, 16605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten unsigned int *data) 167b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten{ 168b652bd83a0528c43e935cb6f2f8df024b7a85c5eIan Abbott data[1] = inl(dev->iobase + APCI2032_INT_STATUS_REG) & 3; 16905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return insn->n; 17005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten} 171b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 1725c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbottstatic void apci2032_int_stop(struct comedi_device *dev, 1735c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott struct comedi_subdevice *s) 1745c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott{ 1755c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott struct apci2032_int_private *subpriv = s->private; 1765c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 1775c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott subpriv->active = false; 1785c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott subpriv->enabled_isns = 0; 1795c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG); 1805c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott} 1815c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 18205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic int apci2032_int_cmdtest(struct comedi_device *dev, 18305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s, 18405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_cmd *cmd) 18505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten{ 18605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten int err = 0; 187b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 18805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Step 1 : check if triggers are trivially valid */ 189b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 19005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); 1915c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); 1925c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); 19305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 19405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); 195b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 19605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (err) 19705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 1; 198b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 19905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Step 2a : make sure trigger sources are unique */ 20005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Step 2b : and mutually compatible */ 20105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 20205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (err) 20305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 2; 20405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 20505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Step 3: check if arguments are trivially valid */ 20605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 20705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 2085c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 20905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); 2105c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 21105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 21205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 21305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (err) 21405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 3; 21505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 21605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* step 4: ignored */ 21705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 21805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (err) 21905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 4; 22005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 22105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 0; 222b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten} 223b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten 22405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic int apci2032_int_cmd(struct comedi_device *dev, 22505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s) 226d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 22705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_cmd *cmd = &s->async->cmd; 2285c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott struct apci2032_int_private *subpriv = s->private; 2295c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott unsigned char enabled_isns; 2305c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott unsigned int n; 2315c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott unsigned long flags; 2325c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 2335c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott enabled_isns = 0; 2345c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott for (n = 0; n < cmd->chanlist_len; n++) 2355c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott enabled_isns |= 1 << CR_CHAN(cmd->chanlist[n]); 23605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 2375c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott spin_lock_irqsave(&subpriv->spinlock, flags); 2385c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott subpriv->enabled_isns = enabled_isns; 2395c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott subpriv->active = true; 2405c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott outl(subpriv->enabled_isns, dev->iobase + APCI2032_INT_CTRL_REG); 2415c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott spin_unlock_irqrestore(&subpriv->spinlock, flags); 24205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 24305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 0; 244d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 2457180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten 24605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic int apci2032_int_cancel(struct comedi_device *dev, 24705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s) 248d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{ 2495c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott struct apci2032_int_private *subpriv = s->private; 2505c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott unsigned long flags; 2515c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 2525c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott spin_lock_irqsave(&subpriv->spinlock, flags); 2535c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott if (subpriv->active) 2545c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott apci2032_int_stop(dev, s); 2555c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott spin_unlock_irqrestore(&subpriv->spinlock, flags); 256d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten 25705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return 0; 258d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten} 259317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten 26005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweetenstatic irqreturn_t apci2032_interrupt(int irq, void *d) 26125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{ 26205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_device *dev = d; 26305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten struct comedi_subdevice *s = dev->read_subdev; 2645c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott struct apci2032_int_private *subpriv; 26505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten unsigned int val; 2665c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott bool do_event = false; 26705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 2680774c2b5c1e0025cb016393d8552171c0ec55c39Ian Abbott if (!dev->attached) 2690774c2b5c1e0025cb016393d8552171c0ec55c39Ian Abbott return IRQ_NONE; 2700774c2b5c1e0025cb016393d8552171c0ec55c39Ian Abbott 27105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Check if VCC OR CC interrupt has occurred */ 27205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten val = inl(dev->iobase + APCI2032_STATUS_REG) & APCI2032_STATUS_IRQ; 27305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (!val) 27405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return IRQ_NONE; 27505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 2765c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott subpriv = s->private; 2775c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott spin_lock(&subpriv->spinlock); 2785c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 279b652bd83a0528c43e935cb6f2f8df024b7a85c5eIan Abbott val = inl(dev->iobase + APCI2032_INT_STATUS_REG) & 3; 280ef6543dbad12c1086f3bc3565d8266352521d8a3Ian Abbott /* Disable triggered interrupt sources. */ 281ef6543dbad12c1086f3bc3565d8266352521d8a3Ian Abbott outl(~val & 3, dev->iobase + APCI2032_INT_CTRL_REG); 282ef6543dbad12c1086f3bc3565d8266352521d8a3Ian Abbott /* 283ef6543dbad12c1086f3bc3565d8266352521d8a3Ian Abbott * Note: We don't reenable the triggered interrupt sources because they 284ef6543dbad12c1086f3bc3565d8266352521d8a3Ian Abbott * are level-sensitive, hardware error status interrupt sources and 285ef6543dbad12c1086f3bc3565d8266352521d8a3Ian Abbott * they'd keep triggering interrupts repeatedly. 286ef6543dbad12c1086f3bc3565d8266352521d8a3Ian Abbott */ 28705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 2885c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott if (subpriv->active && (val & subpriv->enabled_isns) != 0) { 2895c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott unsigned short bits; 2905c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott unsigned int n, len; 2915c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott unsigned int *chanlist; 2925c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 2935c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott /* Bits in scan data correspond to indices in channel list. */ 2945c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott bits = 0; 2955c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott len = s->async->cmd.chanlist_len; 2965c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott chanlist = &s->async->cmd.chanlist[0]; 2975c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott for (n = 0; n < len; n++) 2985c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott if ((val & (1U << CR_CHAN(chanlist[n]))) != 0) 2995c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott bits |= 1U << n; 3005c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 3015c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott if (comedi_buf_put(s->async, bits)) { 3025c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; 3035c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott } else { 3045c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott apci2032_int_stop(dev, s); 3055c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott s->async->events |= COMEDI_CB_OVERFLOW; 3065c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott } 3075c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott do_event = true; 3085c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott } 3095c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 3105c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott spin_unlock(&subpriv->spinlock); 3115c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott if (do_event) 3125c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott comedi_event(dev, s); 31305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 31405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten return IRQ_HANDLED; 31525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten} 31625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 317791c9792ff2d12a02f0ab1c47fd7f7a94828b05bH Hartley Sweetenstatic int apci2032_reset(struct comedi_device *dev) 31825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{ 3197180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(0x0, dev->iobase + APCI2032_DO_REG); 3207180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG); 3217180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(0x0, dev->iobase + APCI2032_WDOG_CTRL_REG); 3227180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten outl(0x0, dev->iobase + APCI2032_WDOG_RELOAD_REG); 32325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 32425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten return 0; 32525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten} 32625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 32725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweetenstatic int apci2032_auto_attach(struct comedi_device *dev, 32825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten unsigned long context_unused) 32925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{ 33025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten struct pci_dev *pcidev = comedi_to_pci_dev(dev); 33123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten struct apci2032_private *devpriv; 33225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten struct comedi_subdevice *s; 3330c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten int ret; 33425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 335c0c3c7dfc1fd5c970b9893e68796314e8551124fH Hartley Sweeten dev->board_name = dev->driver->driver_name; 33625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 33723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); 33823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten if (!devpriv) 33923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten return -ENOMEM; 34023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten dev->private = devpriv; 34123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten 34225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten ret = comedi_pci_enable(pcidev, dev->board_name); 34325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (ret) 34425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten return ret; 34570ff406599a5debfa6e5ef243e5e093f63a9ed69H Hartley Sweeten dev->iobase = pci_resource_start(pcidev, 1); 3460774c2b5c1e0025cb016393d8552171c0ec55c39Ian Abbott apci2032_reset(dev); 34725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 34825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (pcidev->irq > 0) { 34905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten ret = request_irq(pcidev->irq, apci2032_interrupt, 35005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten IRQF_SHARED, dev->board_name, dev); 35125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (ret == 0) 35225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten dev->irq = pcidev->irq; 35325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten } 35425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 35505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten ret = comedi_alloc_subdevices(dev, 3); 35625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (ret) 35725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten return ret; 35825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 3590c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten /* Initialize the digital output subdevice */ 36025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten s = &dev->subdevices[0]; 361cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->type = COMEDI_SUBD_DO; 362cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->subdev_flags = SDF_WRITEABLE; 363cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->n_chan = 32; 364cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->maxdata = 1; 365cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->range_table = &range_digital; 366cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->insn_bits = apci2032_do_insn_bits; 36725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 3680c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten /* Initialize the watchdog subdevice */ 3690c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten s = &dev->subdevices[1]; 370cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->type = COMEDI_SUBD_TIMER; 371cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->subdev_flags = SDF_WRITEABLE; 372cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->n_chan = 1; 373cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->maxdata = 0xff; 374cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->insn_write = apci2032_wdog_insn_write; 375cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->insn_read = apci2032_wdog_insn_read; 376cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten s->insn_config = apci2032_wdog_insn_config; 37725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 37805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten /* Initialize the interrupt subdevice */ 37905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s = &dev->subdevices[2]; 38005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten if (dev->irq) { 3815c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott struct apci2032_int_private *subpriv; 3825c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott 38305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten dev->read_subdev = s; 3845c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); 3855c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott if (!subpriv) 3865c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott return -ENOMEM; 3875c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott spin_lock_init(&subpriv->spinlock); 3885c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott s->private = subpriv; 389b82fe57c4d059a8ff1190ead1693d66b868353b2Ian Abbott s->type = COMEDI_SUBD_DI; 390b82fe57c4d059a8ff1190ead1693d66b868353b2Ian Abbott s->subdev_flags = SDF_READABLE | SDF_CMD_READ; 391b82fe57c4d059a8ff1190ead1693d66b868353b2Ian Abbott s->n_chan = 2; 3925c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott s->len_chanlist = 2; 39305fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->maxdata = 1; 39405fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->range_table = &range_digital; 39505fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->insn_bits = apci2032_int_insn_bits; 39605fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->do_cmdtest = apci2032_int_cmdtest; 39705fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->do_cmd = apci2032_int_cmd; 39805fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->cancel = apci2032_int_cancel; 39905fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten } else { 40005fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten s->type = COMEDI_SUBD_UNUSED; 40105fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten } 40205fcdcede016a74ce7350af94aede6a49eebd5c9H Hartley Sweeten 40325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten return 0; 40425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten} 40525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 40625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweetenstatic void apci2032_detach(struct comedi_device *dev) 40725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{ 40825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten struct pci_dev *pcidev = comedi_to_pci_dev(dev); 40925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 410dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten if (dev->iobase) 411dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten apci2032_reset(dev); 412dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten if (dev->irq) 413dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten free_irq(dev->irq, dev); 4145c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott if (dev->read_subdev) 4155c2d4cba9586ddc3505f51bddf935ddc65a0e0bbIan Abbott kfree(dev->read_subdev->private); 41625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (pcidev) { 41725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten if (dev->iobase) 41825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten comedi_pci_disable(pcidev); 41925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten } 42025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten} 42125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten 42220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct comedi_driver apci2032_driver = { 42320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .driver_name = "addi_apci_2032", 42420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .module = THIS_MODULE, 42525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten .auto_attach = apci2032_auto_attach, 42625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten .detach = apci2032_detach, 42720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}; 42820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 429a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int apci2032_pci_probe(struct pci_dev *dev, 43020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten const struct pci_device_id *ent) 43120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{ 43220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten return comedi_pci_auto_config(dev, &apci2032_driver); 43320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten} 43420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 43553b800198592b0ff96577ecc5f116f7d902a4362Bill Pembertonstatic void apci2032_pci_remove(struct pci_dev *dev) 43620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{ 43720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten comedi_pci_auto_unconfig(dev); 43820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten} 43920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 44020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = { 441317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) }, 442317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten { 0 } 443317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten}; 44420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley SweetenMODULE_DEVICE_TABLE(pci, apci2032_pci_table); 445317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten 44620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct pci_driver apci2032_pci_driver = { 44720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .name = "addi_apci_2032", 44820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .id_table = apci2032_pci_table, 44920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .probe = apci2032_pci_probe, 450a471eace7baa40cdf16d3f26b2f78ddce613ca8fBill Pemberton .remove = apci2032_pci_remove, 45120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}; 45220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenmodule_comedi_pci_driver(apci2032_driver, apci2032_pci_driver); 45390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 45490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 45590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 45690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 457