171f81efb22bc68533fe7a25e98361413d446850aChase Southwood/* 271f81efb22bc68533fe7a25e98361413d446850aChase Southwood * addi_apci_1564.c 371f81efb22bc68533fe7a25e98361413d446850aChase Southwood * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. 471f81efb22bc68533fe7a25e98361413d446850aChase Southwood * 571f81efb22bc68533fe7a25e98361413d446850aChase Southwood * ADDI-DATA GmbH 671f81efb22bc68533fe7a25e98361413d446850aChase Southwood * Dieselstrasse 3 771f81efb22bc68533fe7a25e98361413d446850aChase Southwood * D-77833 Ottersweier 871f81efb22bc68533fe7a25e98361413d446850aChase Southwood * Tel: +19(0)7223/9493-0 971f81efb22bc68533fe7a25e98361413d446850aChase Southwood * Fax: +49(0)7223/9493-92 1071f81efb22bc68533fe7a25e98361413d446850aChase Southwood * http://www.addi-data.com 1171f81efb22bc68533fe7a25e98361413d446850aChase Southwood * info@addi-data.com 1271f81efb22bc68533fe7a25e98361413d446850aChase Southwood * 1371f81efb22bc68533fe7a25e98361413d446850aChase Southwood * This program is free software; you can redistribute it and/or modify it under 1471f81efb22bc68533fe7a25e98361413d446850aChase Southwood * the terms of the GNU General Public License as published by the Free Software 1571f81efb22bc68533fe7a25e98361413d446850aChase Southwood * Foundation; either version 2 of the License, or (at your option) any later 1671f81efb22bc68533fe7a25e98361413d446850aChase Southwood * version. 1771f81efb22bc68533fe7a25e98361413d446850aChase Southwood * 1871f81efb22bc68533fe7a25e98361413d446850aChase Southwood * This program is distributed in the hope that it will be useful, but WITHOUT 1971f81efb22bc68533fe7a25e98361413d446850aChase Southwood * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 2071f81efb22bc68533fe7a25e98361413d446850aChase Southwood * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 2171f81efb22bc68533fe7a25e98361413d446850aChase Southwood * details. 2271f81efb22bc68533fe7a25e98361413d446850aChase Southwood */ 2371f81efb22bc68533fe7a25e98361413d446850aChase Southwood 24ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h> 2533782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten#include <linux/pci.h> 2699acc5ae9b9e544adb0921c16640293010360566Chase Southwood#include <linux/interrupt.h> 2799acc5ae9b9e544adb0921c16640293010360566Chase Southwood#include <linux/sched.h> 2833782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten 293d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "../comedidev.h" 303d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "comedi_fc.h" 31860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood#include "amcc_s5933.h" 32f94f771cc667bdf9ab6a4869bcd19de41c180602Chase Southwood#include "addi_watchdog.h" 333d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten 344c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwoodstruct apci1564_private { 354c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood unsigned int amcc_iobase; /* base of AMCC I/O registers */ 361e15687ea472614d48416c53bebcf213c07a5532Chase Southwood unsigned int mode1; /* riding-edge/high level channels */ 371e15687ea472614d48416c53bebcf213c07a5532Chase Southwood unsigned int mode2; /* falling-edge/low level channels */ 381e15687ea472614d48416c53bebcf213c07a5532Chase Southwood unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */ 394c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood unsigned char timer_select_mode; 404c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood unsigned char mode_select_register; 414c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood struct task_struct *tsk_current; 424c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood}; 434c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood 44bf6a1578c10a4f3ef94a3c744267f18f9c3642bdH Hartley Sweeten#include "addi-data/hwdrv_apci1564.c" 45317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten 461e15687ea472614d48416c53bebcf213c07a5532Chase Southwoodstatic int apci1564_reset(struct comedi_device *dev) 471e15687ea472614d48416c53bebcf213c07a5532Chase Southwood{ 481e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct apci1564_private *devpriv = dev->private; 491e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 501e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Disable the input interrupts and reset status register */ 511e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); 521e15687ea472614d48416c53bebcf213c07a5532Chase Southwood inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG); 531e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG); 541e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG); 551e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 561e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Reset the output channels and disable interrupts */ 571e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DO_REG); 581e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG); 591e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 601e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Reset the watchdog registers */ 611e15687ea472614d48416c53bebcf213c07a5532Chase Southwood addi_watchdog_reset(devpriv->amcc_iobase + APCI1564_WDOG_REG); 621e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 631e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Reset the timer registers */ 641e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); 651e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG); 661e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 671e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Reset the counter registers */ 6885d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER1)); 6985d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER2)); 7085d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER3)); 7185d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood outl(0x0, dev->iobase + APCI1564_COUNTER_CTRL_REG(APCI1564_COUNTER4)); 721e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 731e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return 0; 741e15687ea472614d48416c53bebcf213c07a5532Chase Southwood} 751e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 76860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwoodstatic irqreturn_t apci1564_interrupt(int irq, void *d) 77b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood{ 78860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood struct comedi_device *dev = d; 79860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood struct apci1564_private *devpriv = dev->private; 80860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood struct comedi_subdevice *s = dev->read_subdev; 81b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood unsigned int status; 82b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood unsigned int ctrl; 83b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood unsigned int chan; 84860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 85860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood /* check interrupt is from this device */ 86860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & 87860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood INTCSR_INTR_ASSERTED) == 0) 88860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood return IRQ_NONE; 89860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 90b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood status = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); 91b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood if (status & APCI1564_DI_INT_ENABLE) { 92860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood /* disable the interrupt */ 93b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood outl(status & APCI1564_DI_INT_DISABLE, 94b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); 95860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 96b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG) 97b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood & 0xffff; 98860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood comedi_buf_put(s, s->state); 99860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; 100860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood comedi_event(dev, s); 101860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 102860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood /* enable the interrupt */ 103b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood outl(status, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); 104860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood } 105860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 106b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood status = inl(devpriv->amcc_iobase + APCI1564_TIMER_IRQ_REG); 107b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood if (status & 0x01) { 108b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood /* Disable Timer Interrupt */ 109b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood ctrl = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); 110b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); 111860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 112b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood /* Send a signal to from kernel to user space */ 113b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood send_sig(SIGIO, devpriv->tsk_current, 0); 114860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 115b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood /* Enable Timer Interrupt */ 116b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood outl(ctrl, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); 117860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood } 118860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 119b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood for (chan = 0; chan < 4; chan++) { 12085d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood status = inl(dev->iobase + APCI1564_COUNTER_IRQ_REG(chan)); 121b11771aa4c22074df2b804c02433c5357514f5c5Chase Southwood if (status & 0x01) { 122860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood /* Disable Counter Interrupt */ 12385d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood ctrl = inl(dev->iobase + 12485d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood APCI1564_COUNTER_CTRL_REG(chan)); 12585d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood outl(0x0, dev->iobase + 12685d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood APCI1564_COUNTER_CTRL_REG(chan)); 127860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 128860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood /* Send a signal to from kernel to user space */ 129860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood send_sig(SIGIO, devpriv->tsk_current, 0); 130860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 131860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood /* Enable Counter Interrupt */ 13285d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood outl(ctrl, dev->iobase + 13385d7c9ab5129e96d25b455d7bf45066c376e8e2dChase Southwood APCI1564_COUNTER_CTRL_REG(chan)); 134860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood } 135860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood } 136860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood 137860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood return IRQ_HANDLED; 138b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood} 139b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 14036682e575c7db04549ae504dd13896dd31c5a014Chase Southwoodstatic int apci1564_di_insn_bits(struct comedi_device *dev, 14136682e575c7db04549ae504dd13896dd31c5a014Chase Southwood struct comedi_subdevice *s, 14236682e575c7db04549ae504dd13896dd31c5a014Chase Southwood struct comedi_insn *insn, 14336682e575c7db04549ae504dd13896dd31c5a014Chase Southwood unsigned int *data) 14436682e575c7db04549ae504dd13896dd31c5a014Chase Southwood{ 1454c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood struct apci1564_private *devpriv = dev->private; 14636682e575c7db04549ae504dd13896dd31c5a014Chase Southwood 1474c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood data[1] = inl(devpriv->amcc_iobase + APCI1564_DI_REG); 14836682e575c7db04549ae504dd13896dd31c5a014Chase Southwood 14936682e575c7db04549ae504dd13896dd31c5a014Chase Southwood return insn->n; 15036682e575c7db04549ae504dd13896dd31c5a014Chase Southwood} 15136682e575c7db04549ae504dd13896dd31c5a014Chase Southwood 15296211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwoodstatic int apci1564_do_insn_bits(struct comedi_device *dev, 15396211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood struct comedi_subdevice *s, 15496211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood struct comedi_insn *insn, 15596211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood unsigned int *data) 15696211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood{ 1574c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood struct apci1564_private *devpriv = dev->private; 15896211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood 1594c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood s->state = inl(devpriv->amcc_iobase + APCI1564_DO_REG); 16096211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood 16196211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood if (comedi_dio_update_state(s, data)) 1624c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood outl(s->state, devpriv->amcc_iobase + APCI1564_DO_REG); 16396211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood 16496211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood data[1] = s->state; 16596211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood 16696211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood return insn->n; 16796211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood} 16896211ca58a5d43e6cb527b2a110fbc5df4d15949Chase Southwood 1696347fc88ec4453934a5428e21051ff95cad01180Chase Southwoodstatic int apci1564_diag_insn_bits(struct comedi_device *dev, 1706347fc88ec4453934a5428e21051ff95cad01180Chase Southwood struct comedi_subdevice *s, 1716347fc88ec4453934a5428e21051ff95cad01180Chase Southwood struct comedi_insn *insn, 1726347fc88ec4453934a5428e21051ff95cad01180Chase Southwood unsigned int *data) 1736347fc88ec4453934a5428e21051ff95cad01180Chase Southwood{ 1746347fc88ec4453934a5428e21051ff95cad01180Chase Southwood struct apci1564_private *devpriv = dev->private; 1756347fc88ec4453934a5428e21051ff95cad01180Chase Southwood 1766347fc88ec4453934a5428e21051ff95cad01180Chase Southwood data[1] = inl(devpriv->amcc_iobase + APCI1564_DO_INT_STATUS_REG) & 3; 1776347fc88ec4453934a5428e21051ff95cad01180Chase Southwood 1786347fc88ec4453934a5428e21051ff95cad01180Chase Southwood return insn->n; 1796347fc88ec4453934a5428e21051ff95cad01180Chase Southwood} 1806347fc88ec4453934a5428e21051ff95cad01180Chase Southwood 1811e15687ea472614d48416c53bebcf213c07a5532Chase Southwood/* 1821e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * Change-Of-State (COS) interrupt configuration 1831e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * 1841e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * Channels 0 to 15 are interruptible. These channels can be configured 1851e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * to generate interrupts based on AND/OR logic for the desired channels. 1861e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * 1871e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * OR logic 1881e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * - reacts to rising or falling edges 1891e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * - interrupt is generated when any enabled channel 1901e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * meet the desired interrupt condition 1911e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * 1921e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * AND logic 1931e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * - reacts to changes in level of the selected inputs 1941e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * - interrupt is generated when all enabled channels 1951e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * meet the desired interrupt condition 1961e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * - after an interrupt, a change in level must occur on 1971e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * the selected inputs to release the IRQ logic 1981e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * 1991e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * The COS interrupt must be configured before it can be enabled. 2001e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * 2011e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * data[0] : INSN_CONFIG_DIGITAL_TRIG 2021e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * data[1] : trigger number (= 0) 2031e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * data[2] : configuration operation: 2041e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts 2051e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts 2061e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts 2071e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * data[3] : left-shift for data[4] and data[5] 2081e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * data[4] : rising-edge/high level channels 2091e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * data[5] : falling-edge/low level channels 2101e15687ea472614d48416c53bebcf213c07a5532Chase Southwood */ 2111e15687ea472614d48416c53bebcf213c07a5532Chase Southwoodstatic int apci1564_cos_insn_config(struct comedi_device *dev, 2121e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct comedi_subdevice *s, 2131e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct comedi_insn *insn, 2141e15687ea472614d48416c53bebcf213c07a5532Chase Southwood unsigned int *data) 215b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood{ 2164c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood struct apci1564_private *devpriv = dev->private; 2171e15687ea472614d48416c53bebcf213c07a5532Chase Southwood unsigned int shift, oldmask; 2181e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 2191e15687ea472614d48416c53bebcf213c07a5532Chase Southwood switch (data[0]) { 2201e15687ea472614d48416c53bebcf213c07a5532Chase Southwood case INSN_CONFIG_DIGITAL_TRIG: 2211e15687ea472614d48416c53bebcf213c07a5532Chase Southwood if (data[1] != 0) 2221e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return -EINVAL; 2231e15687ea472614d48416c53bebcf213c07a5532Chase Southwood shift = data[3]; 2241e15687ea472614d48416c53bebcf213c07a5532Chase Southwood oldmask = (1U << shift) - 1; 2251e15687ea472614d48416c53bebcf213c07a5532Chase Southwood switch (data[2]) { 2261e15687ea472614d48416c53bebcf213c07a5532Chase Southwood case COMEDI_DIGITAL_TRIG_DISABLE: 2271e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->ctrl = 0; 2281e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode1 = 0; 2291e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode2 = 0; 230f89ced89d8c0d155e8d802612e3860a440d04afeChase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); 231f89ced89d8c0d155e8d802612e3860a440d04afeChase Southwood inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG); 232f89ced89d8c0d155e8d802612e3860a440d04afeChase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG); 233f89ced89d8c0d155e8d802612e3860a440d04afeChase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG); 2341e15687ea472614d48416c53bebcf213c07a5532Chase Southwood break; 2351e15687ea472614d48416c53bebcf213c07a5532Chase Southwood case COMEDI_DIGITAL_TRIG_ENABLE_EDGES: 2361e15687ea472614d48416c53bebcf213c07a5532Chase Southwood if (devpriv->ctrl != (APCI1564_DI_INT_ENABLE | 2371e15687ea472614d48416c53bebcf213c07a5532Chase Southwood APCI1564_DI_INT_OR)) { 2381e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* switching to 'OR' mode */ 2391e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->ctrl = APCI1564_DI_INT_ENABLE | 2401e15687ea472614d48416c53bebcf213c07a5532Chase Southwood APCI1564_DI_INT_OR; 2411e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* wipe old channels */ 2421e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode1 = 0; 2431e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode2 = 0; 2441e15687ea472614d48416c53bebcf213c07a5532Chase Southwood } else { 2451e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* preserve unspecified channels */ 2461e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode1 &= oldmask; 2471e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode2 &= oldmask; 2481e15687ea472614d48416c53bebcf213c07a5532Chase Southwood } 2491e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* configure specified channels */ 2501e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode1 |= data[4] << shift; 2511e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode2 |= data[5] << shift; 2521e15687ea472614d48416c53bebcf213c07a5532Chase Southwood break; 2531e15687ea472614d48416c53bebcf213c07a5532Chase Southwood case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: 2541e15687ea472614d48416c53bebcf213c07a5532Chase Southwood if (devpriv->ctrl != (APCI1564_DI_INT_ENABLE | 2551e15687ea472614d48416c53bebcf213c07a5532Chase Southwood APCI1564_DI_INT_AND)) { 2561e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* switching to 'AND' mode */ 2571e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->ctrl = APCI1564_DI_INT_ENABLE | 2581e15687ea472614d48416c53bebcf213c07a5532Chase Southwood APCI1564_DI_INT_AND; 2591e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* wipe old channels */ 2601e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode1 = 0; 2611e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode2 = 0; 2621e15687ea472614d48416c53bebcf213c07a5532Chase Southwood } else { 2631e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* preserve unspecified channels */ 2641e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode1 &= oldmask; 2651e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode2 &= oldmask; 2661e15687ea472614d48416c53bebcf213c07a5532Chase Southwood } 2671e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* configure specified channels */ 2681e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode1 |= data[4] << shift; 2691e15687ea472614d48416c53bebcf213c07a5532Chase Southwood devpriv->mode2 |= data[5] << shift; 2701e15687ea472614d48416c53bebcf213c07a5532Chase Southwood break; 2711e15687ea472614d48416c53bebcf213c07a5532Chase Southwood default: 2721e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return -EINVAL; 2731e15687ea472614d48416c53bebcf213c07a5532Chase Southwood } 2741e15687ea472614d48416c53bebcf213c07a5532Chase Southwood break; 2751e15687ea472614d48416c53bebcf213c07a5532Chase Southwood default: 2761e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return -EINVAL; 2771e15687ea472614d48416c53bebcf213c07a5532Chase Southwood } 2781e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return insn->n; 2791e15687ea472614d48416c53bebcf213c07a5532Chase Southwood} 280aed3f9d498babd9cf4f0656e4a415cd25c725aa3Chase Southwood 2811e15687ea472614d48416c53bebcf213c07a5532Chase Southwoodstatic int apci1564_cos_insn_bits(struct comedi_device *dev, 2821e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct comedi_subdevice *s, 2831e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct comedi_insn *insn, 2841e15687ea472614d48416c53bebcf213c07a5532Chase Southwood unsigned int *data) 2851e15687ea472614d48416c53bebcf213c07a5532Chase Southwood{ 2861e15687ea472614d48416c53bebcf213c07a5532Chase Southwood data[1] = s->state; 287aed3f9d498babd9cf4f0656e4a415cd25c725aa3Chase Southwood 2881e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return 0; 2891e15687ea472614d48416c53bebcf213c07a5532Chase Southwood} 290aed3f9d498babd9cf4f0656e4a415cd25c725aa3Chase Southwood 2911e15687ea472614d48416c53bebcf213c07a5532Chase Southwoodstatic int apci1564_cos_cmdtest(struct comedi_device *dev, 2921e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct comedi_subdevice *s, 2931e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct comedi_cmd *cmd) 2941e15687ea472614d48416c53bebcf213c07a5532Chase Southwood{ 2951e15687ea472614d48416c53bebcf213c07a5532Chase Southwood int err = 0; 296aed3f9d498babd9cf4f0656e4a415cd25c725aa3Chase Southwood 2971e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Step 1 : check if triggers are trivially valid */ 298aed3f9d498babd9cf4f0656e4a415cd25c725aa3Chase Southwood 2991e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); 3001e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); 3011e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); 3021e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 3031e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); 304aed3f9d498babd9cf4f0656e4a415cd25c725aa3Chase Southwood 3051e15687ea472614d48416c53bebcf213c07a5532Chase Southwood if (err) 3061e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return 1; 3071e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3081e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Step 2a : make sure trigger sources are unique */ 3091e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Step 2b : and mutually compatible */ 3101e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3111e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Step 3: check if arguments are trivially valid */ 3121e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3131e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 3141e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 3151e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); 3161e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 3171e15687ea472614d48416c53bebcf213c07a5532Chase Southwood err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 3181e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3191e15687ea472614d48416c53bebcf213c07a5532Chase Southwood if (err) 3201e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return 3; 3211e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 322cc67b0167a366f4b13935fe05abd58d396c30375H Hartley Sweeten /* Step 4: fix up any arguments */ 3231e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 324cc67b0167a366f4b13935fe05abd58d396c30375H Hartley Sweeten /* Step 5: check channel list if it exists */ 3251e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3261e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return 0; 3271e15687ea472614d48416c53bebcf213c07a5532Chase Southwood} 3281e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3291e15687ea472614d48416c53bebcf213c07a5532Chase Southwood/* 3301e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * Change-Of-State (COS) 'do_cmd' operation 3311e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * 3321e15687ea472614d48416c53bebcf213c07a5532Chase Southwood * Enable the COS interrupt as configured by apci1564_cos_insn_config(). 3331e15687ea472614d48416c53bebcf213c07a5532Chase Southwood */ 3341e15687ea472614d48416c53bebcf213c07a5532Chase Southwoodstatic int apci1564_cos_cmd(struct comedi_device *dev, 3351e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct comedi_subdevice *s) 3361e15687ea472614d48416c53bebcf213c07a5532Chase Southwood{ 3371e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct apci1564_private *devpriv = dev->private; 3381e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3391e15687ea472614d48416c53bebcf213c07a5532Chase Southwood if (!devpriv->ctrl) { 3401e15687ea472614d48416c53bebcf213c07a5532Chase Southwood dev_warn(dev->class_dev, 3411e15687ea472614d48416c53bebcf213c07a5532Chase Southwood "Interrupts disabled due to mode configuration!\n"); 3421e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return -EINVAL; 3431e15687ea472614d48416c53bebcf213c07a5532Chase Southwood } 3441e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3451e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(devpriv->mode1, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG); 3461e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(devpriv->mode2, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG); 3471e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(devpriv->ctrl, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); 3481e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3491e15687ea472614d48416c53bebcf213c07a5532Chase Southwood return 0; 3501e15687ea472614d48416c53bebcf213c07a5532Chase Southwood} 3511e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3521e15687ea472614d48416c53bebcf213c07a5532Chase Southwoodstatic int apci1564_cos_cancel(struct comedi_device *dev, 3531e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct comedi_subdevice *s) 3541e15687ea472614d48416c53bebcf213c07a5532Chase Southwood{ 3551e15687ea472614d48416c53bebcf213c07a5532Chase Southwood struct apci1564_private *devpriv = dev->private; 3561e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 3571e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); 3581e15687ea472614d48416c53bebcf213c07a5532Chase Southwood inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG); 3591e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG); 3601e15687ea472614d48416c53bebcf213c07a5532Chase Southwood outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG); 361b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 362b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood return 0; 363b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood} 364b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 36543ba213156dba3afb4c8367da16c3d90aa87d2f8H Hartley Sweetenstatic int apci1564_auto_attach(struct comedi_device *dev, 366b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood unsigned long context_unused) 367b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood{ 368b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood struct pci_dev *pcidev = comedi_to_pci_dev(dev); 3694c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood struct apci1564_private *devpriv; 370b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood struct comedi_subdevice *s; 3719f2dbefb0ddb548b9a062f6ca729534efc15b0d6Chase Southwood int ret; 372b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 373b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 374b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood if (!devpriv) 375b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood return -ENOMEM; 376b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 377b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood ret = comedi_pci_enable(dev); 378b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood if (ret) 379b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood return ret; 380b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 381128f798918c398b5ae84e5734c3b5df8c35d5d94Chase Southwood dev->iobase = pci_resource_start(pcidev, 1); 3824c95a2b6b531e2caae211803d0ef88600c5d5f06Chase Southwood devpriv->amcc_iobase = pci_resource_start(pcidev, 0); 383b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 384aed3f9d498babd9cf4f0656e4a415cd25c725aa3Chase Southwood apci1564_reset(dev); 385aed3f9d498babd9cf4f0656e4a415cd25c725aa3Chase Southwood 386b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood if (pcidev->irq > 0) { 387860ba36cbeadee9064e2925be11dfb8368b9b25dChase Southwood ret = request_irq(pcidev->irq, apci1564_interrupt, IRQF_SHARED, 388b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood dev->board_name, dev); 389b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood if (ret == 0) 390b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood dev->irq = pcidev->irq; 391b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood } 392b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 3936347fc88ec4453934a5428e21051ff95cad01180Chase Southwood ret = comedi_alloc_subdevices(dev, 6); 394b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood if (ret) 395b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood return ret; 396b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 397b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood /* Allocate and Initialise DI Subdevice Structures */ 3989f2dbefb0ddb548b9a062f6ca729534efc15b0d6Chase Southwood s = &dev->subdevices[0]; 3996caf60158821699e772a9545b030c7254519078eChase Southwood s->type = COMEDI_SUBD_DI; 4006caf60158821699e772a9545b030c7254519078eChase Southwood s->subdev_flags = SDF_READABLE; 4016caf60158821699e772a9545b030c7254519078eChase Southwood s->n_chan = 32; 4026caf60158821699e772a9545b030c7254519078eChase Southwood s->maxdata = 1; 4036caf60158821699e772a9545b030c7254519078eChase Southwood s->range_table = &range_digital; 4046caf60158821699e772a9545b030c7254519078eChase Southwood s->insn_bits = apci1564_di_insn_bits; 405cffd83b6d1e6e403a77c5babf1443cdfd1a080efChase Southwood 406b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood /* Allocate and Initialise DO Subdevice Structures */ 4079f2dbefb0ddb548b9a062f6ca729534efc15b0d6Chase Southwood s = &dev->subdevices[1]; 4086caf60158821699e772a9545b030c7254519078eChase Southwood s->type = COMEDI_SUBD_DO; 4096caf60158821699e772a9545b030c7254519078eChase Southwood s->subdev_flags = SDF_WRITEABLE; 4106caf60158821699e772a9545b030c7254519078eChase Southwood s->n_chan = 32; 4116caf60158821699e772a9545b030c7254519078eChase Southwood s->maxdata = 1; 4126caf60158821699e772a9545b030c7254519078eChase Southwood s->range_table = &range_digital; 4136caf60158821699e772a9545b030c7254519078eChase Southwood s->insn_bits = apci1564_do_insn_bits; 414b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 4151e15687ea472614d48416c53bebcf213c07a5532Chase Southwood /* Change-Of-State (COS) interrupt subdevice */ 4161496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood s = &dev->subdevices[2]; 4171e15687ea472614d48416c53bebcf213c07a5532Chase Southwood if (dev->irq) { 4181e15687ea472614d48416c53bebcf213c07a5532Chase Southwood dev->read_subdev = s; 4196caf60158821699e772a9545b030c7254519078eChase Southwood s->type = COMEDI_SUBD_DI; 4206caf60158821699e772a9545b030c7254519078eChase Southwood s->subdev_flags = SDF_READABLE | SDF_CMD_READ; 4216caf60158821699e772a9545b030c7254519078eChase Southwood s->n_chan = 1; 4226caf60158821699e772a9545b030c7254519078eChase Southwood s->maxdata = 1; 4236caf60158821699e772a9545b030c7254519078eChase Southwood s->range_table = &range_digital; 4246caf60158821699e772a9545b030c7254519078eChase Southwood s->len_chanlist = 1; 4256caf60158821699e772a9545b030c7254519078eChase Southwood s->insn_config = apci1564_cos_insn_config; 4266caf60158821699e772a9545b030c7254519078eChase Southwood s->insn_bits = apci1564_cos_insn_bits; 4276caf60158821699e772a9545b030c7254519078eChase Southwood s->do_cmdtest = apci1564_cos_cmdtest; 4286caf60158821699e772a9545b030c7254519078eChase Southwood s->do_cmd = apci1564_cos_cmd; 4296caf60158821699e772a9545b030c7254519078eChase Southwood s->cancel = apci1564_cos_cancel; 4301e15687ea472614d48416c53bebcf213c07a5532Chase Southwood } else { 4316caf60158821699e772a9545b030c7254519078eChase Southwood s->type = COMEDI_SUBD_UNUSED; 4321e15687ea472614d48416c53bebcf213c07a5532Chase Southwood } 4331e15687ea472614d48416c53bebcf213c07a5532Chase Southwood 4341496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood /* Allocate and Initialise Timer Subdevice Structures */ 4351496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood s = &dev->subdevices[3]; 4366caf60158821699e772a9545b030c7254519078eChase Southwood s->type = COMEDI_SUBD_TIMER; 4376caf60158821699e772a9545b030c7254519078eChase Southwood s->subdev_flags = SDF_WRITEABLE; 4386caf60158821699e772a9545b030c7254519078eChase Southwood s->n_chan = 1; 4396caf60158821699e772a9545b030c7254519078eChase Southwood s->maxdata = 0; 4406caf60158821699e772a9545b030c7254519078eChase Southwood s->len_chanlist = 1; 4416caf60158821699e772a9545b030c7254519078eChase Southwood s->range_table = &range_digital; 4426caf60158821699e772a9545b030c7254519078eChase Southwood s->insn_write = apci1564_timer_write; 4436caf60158821699e772a9545b030c7254519078eChase Southwood s->insn_read = apci1564_timer_read; 4446caf60158821699e772a9545b030c7254519078eChase Southwood s->insn_config = apci1564_timer_config; 4451496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood 4461496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood /* Initialize the watchdog subdevice */ 4471496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood s = &dev->subdevices[4]; 4481496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood ret = addi_watchdog_init(s, devpriv->amcc_iobase + APCI1564_WDOG_REG); 4491496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood if (ret) 4501496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood return ret; 4511496e5961113860e97e8fc39c4fdc0e83c1fbcabChase Southwood 4526347fc88ec4453934a5428e21051ff95cad01180Chase Southwood /* Initialize the diagnostic status subdevice */ 4536347fc88ec4453934a5428e21051ff95cad01180Chase Southwood s = &dev->subdevices[5]; 4546caf60158821699e772a9545b030c7254519078eChase Southwood s->type = COMEDI_SUBD_DI; 4556caf60158821699e772a9545b030c7254519078eChase Southwood s->subdev_flags = SDF_READABLE; 4566caf60158821699e772a9545b030c7254519078eChase Southwood s->n_chan = 2; 4576caf60158821699e772a9545b030c7254519078eChase Southwood s->maxdata = 1; 4586caf60158821699e772a9545b030c7254519078eChase Southwood s->range_table = &range_digital; 4596caf60158821699e772a9545b030c7254519078eChase Southwood s->insn_bits = apci1564_diag_insn_bits; 4606347fc88ec4453934a5428e21051ff95cad01180Chase Southwood 461b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood return 0; 462b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood} 463b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood 464b30c3e824ebaa142bf7361c567612727d24af717Chase Southwoodstatic void apci1564_detach(struct comedi_device *dev) 46543ba213156dba3afb4c8367da16c3d90aa87d2f8H Hartley Sweeten{ 46671893bb077a61c7b590bf7780422407a01a409c0Chase Southwood if (dev->iobase) 46771893bb077a61c7b590bf7780422407a01a409c0Chase Southwood apci1564_reset(dev); 468aac307f9dd5ce1fe651140a036ab4b0a0571b54aH Hartley Sweeten comedi_pci_detach(dev); 46943ba213156dba3afb4c8367da16c3d90aa87d2f8H Hartley Sweeten} 47043ba213156dba3afb4c8367da16c3d90aa87d2f8H Hartley Sweeten 47120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct comedi_driver apci1564_driver = { 47220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .driver_name = "addi_apci_1564", 47320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .module = THIS_MODULE, 47443ba213156dba3afb4c8367da16c3d90aa87d2f8H Hartley Sweeten .auto_attach = apci1564_auto_attach, 475b30c3e824ebaa142bf7361c567612727d24af717Chase Southwood .detach = apci1564_detach, 47620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}; 47720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 478a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int apci1564_pci_probe(struct pci_dev *dev, 479b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten const struct pci_device_id *id) 48020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{ 481b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten return comedi_pci_auto_config(dev, &apci1564_driver, id->driver_data); 48220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten} 48320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 48441e043fcfa2236bb2c4a8335eb09f4c8cee224b3Jingoo Hanstatic const struct pci_device_id apci1564_pci_table[] = { 485317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006) }, 486317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten { 0 } 487317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten}; 48820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley SweetenMODULE_DEVICE_TABLE(pci, apci1564_pci_table); 489317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten 49020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct pci_driver apci1564_pci_driver = { 49120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .name = "addi_apci_1564", 49220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .id_table = apci1564_pci_table, 49320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .probe = apci1564_pci_probe, 4949901a4d75d007686e8f6473189cafc4b216b7449Peter Huewe .remove = comedi_pci_auto_unconfig, 49520a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}; 49620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenmodule_comedi_pci_driver(apci1564_driver, apci1564_pci_driver); 49790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 49890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 499b5ebcaa8d3405e14ca431257fd6c6cdc30df13c5Georg GastMODULE_DESCRIPTION("ADDI-DATA APCI-1564, 32 channel DI / 32 channel DO boards"); 50090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 501