11f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks/* 21f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * comedi/drivers/ni_daq_700.c 31f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * Driver for DAQCard-700 DIO only 41f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * copied from 8255 51f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * 61f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * COMEDI - Linux Control and Measurement Device Interface 71f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * Copyright (C) 1998 David A. Schleef <ds@schleef.org> 81f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * 91f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * This program is free software; you can redistribute it and/or modify 101f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * it under the terms of the GNU General Public License as published by 111f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * the Free Software Foundation; either version 2 of the License, or 121f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * (at your option) any later version. 131f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * 141f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * This program is distributed in the hope that it will be useful, 151f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * but WITHOUT ANY WARRANTY; without even the implied warranty of 161f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 171f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * GNU General Public License for more details. 181f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * 191f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * You should have received a copy of the GNU General Public License 201f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * along with this program; if not, write to the Free Software 211f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 221f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * 231f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks */ 241f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 251f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks/* 261f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksDriver: ni_daq_700 271f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksDescription: National Instruments PCMCIA DAQCard-700 DIO only 281f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksAuthor: Fred Brooks <nsaspook@nsaspook.com>, 291f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es> 301f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksDevices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700) 311f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksStatus: works 321f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksUpdated: Thu, 21 Feb 2008 12:07:20 +0000 331f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 341f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksThe daqcard-700 appears in Comedi as a single digital I/O subdevice with 351f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks16 channels. The channel 0 corresponds to the daqcard-700's output 361f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksport, bit 0; channel 8 corresponds to the input port, bit 0. 371f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 381f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksDirection configuration: channels 0-7 output, 8-15 input (8225 device 391f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksemu as port A output, port B input, port C N/A). 401f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 411f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksIRQ is assigned but not used. 421f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks*/ 431f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4425436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h> 455a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 461f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#include "../comedidev.h" 471f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 481f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#include <linux/ioport.h> 491f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 501f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#include <pcmcia/cistpl.h> 511f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#include <pcmcia/cisreg.h> 521f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#include <pcmcia/ds.h> 531f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 54ee4d07d8e1c72043299ac4118fbdee0ad883e966Ravishankarstatic struct pcmcia_device *pcmcia_cur_dev; 551f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 562696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DIO700_SIZE 8 /* size of io region used by board */ 571f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int dio700_attach(struct comedi_device *dev, 590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 60da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dio700_detach(struct comedi_device *dev); 611f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 621f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksenum dio700_bustype { pcmcia_bustype }; 631f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 644cab3740734fb8582fa68f899105790c05935b55Bill Pembertonstruct dio700_board { 651f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks const char *name; 662696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton int device_id; /* device id for pcmcia board */ 672696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton enum dio700_bustype bustype; /* PCMCIA */ 682696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton int have_dio; /* have daqcard-700 dio */ 692696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* function pointers so we can use inb/outb or readb/writeb */ 702696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* as appropriate */ 711f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks unsigned int (*read_byte) (unsigned int address); 721f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks void (*write_byte) (unsigned int byte, unsigned int address); 734cab3740734fb8582fa68f899105790c05935b55Bill Pemberton}; 741f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 754cab3740734fb8582fa68f899105790c05935b55Bill Pembertonstatic const struct dio700_board dio700_boards[] = { 761f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks { 770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "daqcard-700", 789a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe /* 0x10b is manufacturer id, 0x4743 is device id */ 799a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe .device_id = 0x4743, 800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .bustype = pcmcia_bustype, 810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .have_dio = 1, 820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 831f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks { 840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "ni_daq_700", 859a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe /* 0x10b is manufacturer id, 0x4743 is device id */ 869a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe .device_id = 0x4743, 870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .bustype = pcmcia_bustype, 880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .have_dio = 1, 890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 901f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks}; 911f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 921f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks/* 931f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks * Useful for shorthand access to the particular board structure 941f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks */ 954cab3740734fb8582fa68f899105790c05935b55Bill Pemberton#define thisboard ((const struct dio700_board *)dev->board_ptr) 961f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 97adf328432473a9baf2b7b0a50864d9736890fa8aBill Pembertonstruct dio700_private { 98adf328432473a9baf2b7b0a50864d9736890fa8aBill Pemberton 991f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks int data; /* number of data points left to be taken */ 100adf328432473a9baf2b7b0a50864d9736890fa8aBill Pemberton}; 101adf328432473a9baf2b7b0a50864d9736890fa8aBill Pemberton 102adf328432473a9baf2b7b0a50864d9736890fa8aBill Pemberton#define devpriv ((struct dio700_private *)dev->private) 1031f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 104139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_dio700 = { 10568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "ni_daq_700", 10668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 10768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = dio700_attach, 10868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = dio700_detach, 1098629efa4cbf6f89a54a85af4b8bc31762af01800Bill Pemberton .num_names = ARRAY_SIZE(dio700_boards), 11068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .board_name = &dio700_boards[0].name, 11168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .offset = sizeof(struct dio700_board), 1121f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks}; 1131f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1141f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks/* the real driver routines */ 1151f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1161f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#define _700_SIZE 8 1171f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1181f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#define _700_DATA 0 1191f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1201f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#define DIO_W 0x04 1211f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#define DIO_R 0x05 1221f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1231f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstruct subdev_700_struct { 1241f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks unsigned long cb_arg; 1251f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks int (*cb_func) (int, int, int, unsigned long); 1261f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks int have_irq; 1271f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks}; 1281f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1291f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#define CALLBACK_ARG (((struct subdev_700_struct *)s->private)->cb_arg) 1301f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#define CALLBACK_FUNC (((struct subdev_700_struct *)s->private)->cb_func) 1311f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#define subdevpriv ((struct subdev_700_struct *)s->private) 1321f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 133da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void do_config(struct comedi_device *dev, struct comedi_subdevice *s); 1341f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 135da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonvoid subdev_700_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) 1361f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 137790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton short d; 1381f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1391f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks d = CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG); 1401f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1411f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks comedi_buf_put(s->async, d); 1421f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->async->events |= COMEDI_CB_EOS; 1431f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1441f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks comedi_event(dev, s); 1451f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 146ee21350fae9333acc11e3b1b77c887fd94e450f5Robert BabilonEXPORT_SYMBOL(subdev_700_interrupt); 1471f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1481f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic int subdev_700_cb(int dir, int port, int data, unsigned long arg) 1491f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 1501f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* port is always A for output and B for input (8255 emu) */ 1511f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks unsigned long iobase = arg; 1521f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1531f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (dir) { 1541f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks outb(data, iobase + DIO_W); 1551f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 1561f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } else { 1571f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return inb(iobase + DIO_R); 1581f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 1591f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 1601f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int subdev_700_insn(struct comedi_device *dev, 1620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, struct comedi_insn *insn, 1630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 1641f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 1651f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (data[0]) { 1661f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->state &= ~data[0]; 1671f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->state |= (data[0] & data[1]); 1681f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1691f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (data[0] & 0xff) 1701f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks CALLBACK_FUNC(1, _700_DATA, s->state & 0xff, 1710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral CALLBACK_ARG); 1721f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 1731f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1741f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks data[1] = s->state & 0xff; 1751f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks data[1] |= CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG) << 8; 1761f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1771f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 2; 1781f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 1791f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int subdev_700_insn_config(struct comedi_device *dev, 1810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 1831f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 1841f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 1851f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks switch (data[0]) { 1861f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks case INSN_CONFIG_DIO_INPUT: 1871f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks break; 1881f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks case INSN_CONFIG_DIO_OUTPUT: 1891f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks break; 1901f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks case INSN_CONFIG_DIO_QUERY: 1911f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks data[1] = 1920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (s-> 1930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT : 1940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral COMEDI_INPUT; 1951f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return insn->n; 1961f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks break; 1971f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks default: 1981f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return -EINVAL; 1991f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 2001f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2011f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 1; 2021f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 2031f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 204da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void do_config(struct comedi_device *dev, struct comedi_subdevice *s) 2051f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ /* use powerup defaults */ 2061f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return; 2071f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 2081f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int subdev_700_cmdtest(struct comedi_device *dev, 2100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 2121f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 2131f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks int err = 0; 2141f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks unsigned int tmp; 2151f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2161f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* step 1 */ 2171f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2181f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks tmp = cmd->start_src; 2191f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->start_src &= TRIG_NOW; 2201f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (!cmd->start_src || tmp != cmd->start_src) 2211f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2221f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2231f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks tmp = cmd->scan_begin_src; 2241f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->scan_begin_src &= TRIG_EXT; 2251f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 2261f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2271f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2281f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks tmp = cmd->convert_src; 2291f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->convert_src &= TRIG_FOLLOW; 2301f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (!cmd->convert_src || tmp != cmd->convert_src) 2311f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2321f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2331f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks tmp = cmd->scan_end_src; 2341f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->scan_end_src &= TRIG_COUNT; 2351f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 2361f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2371f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2381f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks tmp = cmd->stop_src; 2391f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->stop_src &= TRIG_NONE; 2401f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (!cmd->stop_src || tmp != cmd->stop_src) 2411f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2421f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2431f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (err) 2441f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 1; 2451f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2461f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* step 2 */ 2471f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2481f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (err) 2491f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 2; 2501f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2511f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* step 3 */ 2521f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2531f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (cmd->start_arg != 0) { 2541f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->start_arg = 0; 2551f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2561f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 2571f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (cmd->scan_begin_arg != 0) { 2581f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->scan_begin_arg = 0; 2591f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2601f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 2611f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (cmd->convert_arg != 0) { 2621f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->convert_arg = 0; 2631f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2641f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 2651f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (cmd->scan_end_arg != 1) { 2661f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->scan_end_arg = 1; 2671f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2681f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 2691f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (cmd->stop_arg != 0) { 2701f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks cmd->stop_arg = 0; 2711f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks err++; 2721f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 2731f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2741f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (err) 2751f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 3; 2761f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2771f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* step 4 */ 2781f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2791f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (err) 2801f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 4; 2811f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2821f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 2831f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 2841f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 285da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int subdev_700_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 2861f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 2871f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* FIXME */ 2881f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2891f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 2901f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 2911f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int subdev_700_cancel(struct comedi_device *dev, 2930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 2941f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 2951f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* FIXME */ 2961f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 2971f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 2981f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 2991f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralint subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s, 3010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral int (*cb) (int, int, int, unsigned long), unsigned long arg) 3021f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 3031f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->type = COMEDI_SUBD_DIO; 3041f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 3051f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->n_chan = 16; 3061f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->range_table = &range_digital; 3071f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->maxdata = 1; 3081f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3091f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->private = kmalloc(sizeof(struct subdev_700_struct), GFP_KERNEL); 3101f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (!s->private) 3111f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return -ENOMEM; 3121f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3131f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks CALLBACK_ARG = arg; 3149a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe if (cb == NULL) 3151f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks CALLBACK_FUNC = subdev_700_cb; 3169a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe else 3171f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks CALLBACK_FUNC = cb; 3189a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe 3191f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->insn_bits = subdev_700_insn; 3201f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->insn_config = subdev_700_insn_config; 3211f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3221f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->state = 0; 3231f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->io_bits = 0x00ff; 3241f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks do_config(dev, s); 3251f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3261f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 3271f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 328ee21350fae9333acc11e3b1b77c887fd94e450f5Robert BabilonEXPORT_SYMBOL(subdev_700_init); 3291f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 330da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonint subdev_700_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral int (*cb) (int, int, int, unsigned long), 3320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned long arg) 3331f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 3341f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks int ret; 3351f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3361f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks ret = subdev_700_init(dev, s, cb, arg); 3371f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (ret < 0) 3381f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return ret; 3391f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3401f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->do_cmdtest = subdev_700_cmdtest; 3411f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->do_cmd = subdev_700_cmd; 3421f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s->cancel = subdev_700_cancel; 3431f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3441f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks subdevpriv->have_irq = 1; 3451f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3461f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 3471f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 348ee21350fae9333acc11e3b1b77c887fd94e450f5Robert BabilonEXPORT_SYMBOL(subdev_700_init_irq); 3491f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 350da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonvoid subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) 3511f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 3529a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe if (s->private) 3539a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe if (subdevpriv->have_irq) 3541f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3559a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe kfree(s->private); 3561f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 3571f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksEXPORT_SYMBOL(subdev_700_cleanup); 3581f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 359da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) 3601f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 36134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 3621f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks unsigned long iobase = 0; 3631f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#ifdef incomplete 3641f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks unsigned int irq = 0; 3651f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#endif 3661f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks struct pcmcia_device *link; 3671f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3681f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* allocate and initialize dev->private */ 369adf328432473a9baf2b7b0a50864d9736890fa8aBill Pemberton if (alloc_private(dev, sizeof(struct dio700_private)) < 0) 3701f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return -ENOMEM; 3711f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3722696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* get base address, irq etc. based on bustype */ 3731f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks switch (thisboard->bustype) { 3741f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks case pcmcia_bustype: 3751f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks link = pcmcia_cur_dev; /* XXX hack */ 3761f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (!link) 3771f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return -EIO; 3789a017a910346afd88ec2e065989903bf211a7d37Dominik Brodowski iobase = link->resource[0]->start; 3791f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#ifdef incomplete 380eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski irq = link->irq; 3811f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#endif 3821f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks break; 3831f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks default: 384ee4d07d8e1c72043299ac4118fbdee0ad883e966Ravishankar printk(KERN_ERR "bug! couldn't determine board type\n"); 3851f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return -EINVAL; 3861f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks break; 3871f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 388ee4d07d8e1c72043299ac4118fbdee0ad883e966Ravishankar printk(KERN_ERR "comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor, 3890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral thisboard->name, iobase); 3901f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#ifdef incomplete 3919a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe if (irq) 3921f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks printk(", irq %u", irq); 3939a16a92c11e82a0a80b4847343cfb8b5c54ed6b6Graham M Howe 3941f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#endif 3951f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3961f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks printk("\n"); 3971f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 3981f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (iobase == 0) { 399ee4d07d8e1c72043299ac4118fbdee0ad883e966Ravishankar printk(KERN_ERR "io base address is zero!\n"); 4001f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return -EINVAL; 4011f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 4021f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4031f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks dev->iobase = iobase; 4041f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4051f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#ifdef incomplete 4061f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* grab our IRQ */ 4071f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks dev->irq = irq; 4081f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks#endif 4091f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4101f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks dev->board_name = thisboard->name; 4111f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4121f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (alloc_subdevices(dev, 1) < 0) 4131f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return -ENOMEM; 4141f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4151f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* DAQCard-700 dio */ 4161f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks s = dev->subdevices + 0; 4171f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks subdev_700_init(dev, s, NULL, dev->iobase); 4181f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4191f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 4201f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks}; 4211f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 422da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dio700_detach(struct comedi_device *dev) 4231f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 424ee4d07d8e1c72043299ac4118fbdee0ad883e966Ravishankar printk(KERN_ERR "comedi%d: ni_daq_700: cs-remove\n", dev->minor); 4251f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4261f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (dev->subdevices) 4271f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks subdev_700_cleanup(dev, dev->subdevices + 0); 4281f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4291f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (thisboard->bustype != pcmcia_bustype && dev->iobase) 4301f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks release_region(dev->iobase, DIO700_SIZE); 4311f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (dev->irq) 4325f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 4331f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4341f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 4351f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks}; 4361f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4371f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic void dio700_config(struct pcmcia_device *link); 4381f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic void dio700_release(struct pcmcia_device *link); 4391f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic int dio700_cs_suspend(struct pcmcia_device *p_dev); 4401f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic int dio700_cs_resume(struct pcmcia_device *p_dev); 4411f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4421f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic int dio700_cs_attach(struct pcmcia_device *); 4431f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic void dio700_cs_detach(struct pcmcia_device *); 4441f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 44530570f0dee2b0e3ede09e08eb5dfd514317a7587Bill Pembertonstruct local_info_t { 4461f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks struct pcmcia_device *link; 4471f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks int stop; 4481f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks struct bus_operations *bus; 44930570f0dee2b0e3ede09e08eb5dfd514317a7587Bill Pemberton}; 4501f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4511f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic int dio700_cs_attach(struct pcmcia_device *link) 4521f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 45330570f0dee2b0e3ede09e08eb5dfd514317a7587Bill Pemberton struct local_info_t *local; 4541f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4551f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks printk(KERN_INFO "ni_daq_700: cs-attach\n"); 4561f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 45755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "dio700_cs_attach()\n"); 4581f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4591f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* Allocate space for private device-specific data */ 46030570f0dee2b0e3ede09e08eb5dfd514317a7587Bill Pemberton local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); 4611f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (!local) 4621f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return -ENOMEM; 4631f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks local->link = link; 4641f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks link->priv = local; 4651f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4661f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks pcmcia_cur_dev = link; 4671f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4681f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks dio700_config(link); 4691f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4701f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 4711f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} /* dio700_cs_attach */ 4721f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4731f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic void dio700_cs_detach(struct pcmcia_device *link) 4741f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 4751f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4761f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks printk(KERN_INFO "ni_daq_700: cs-detach!\n"); 4771f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 47855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "dio700_cs_detach\n"); 4791f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 480cdc268b4a029d489798db10d10fea72b7a415ab9Javier Martinez Canillas ((struct local_info_t *)link->priv)->stop = 1; 481cdc268b4a029d489798db10d10fea72b7a415ab9Javier Martinez Canillas dio700_release(link); 4821f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 48330570f0dee2b0e3ede09e08eb5dfd514317a7587Bill Pemberton /* This points to the parent struct local_info_t struct */ 484f25bd6bfdf9bccd8164c151b027f9c14ec07960bDan Carpenter kfree(link->priv); 4851f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 4861f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} /* dio700_cs_detach */ 4871f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 48855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, 48955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski void *priv_data) 4901f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 49100990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski if (p_dev->config_index == 0) 49200990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski return -EINVAL; 493c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 49400990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski return pcmcia_request_io(p_dev); 49555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski} 4961f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 49755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic void dio700_config(struct pcmcia_device *link) 49855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski{ 49955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski int ret; 5001f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 50155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski printk(KERN_INFO "ni_daq_700: cs-config\n"); 5021f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 50355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "dio700_config\n"); 504c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 50500990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO | 50600990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski CONF_AUTO_SET_IO; 507440eed43e2a95bb842488755683716814da10f2bDominik Brodowski 5080f52e86ded65749c6037473013ad77b2afa4f68dDominik Brodowski ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, NULL); 50955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (ret) { 51055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_warn(&link->dev, "no configuration found\n"); 51155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski goto failed; 5121f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks } 5131f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 514eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski if (!link->irq) 515eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski goto failed; 5161f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5171ac71e5a35eebee60cdcf15b3980bd94498f037bDominik Brodowski ret = pcmcia_enable_device(link); 51855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (ret != 0) 51955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski goto failed; 5201f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5211f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return; 5221f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 52355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskifailed: 5241f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks printk(KERN_INFO "ni_daq_700 cs failed"); 5251f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks dio700_release(link); 5261f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5271f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} /* dio700_config */ 5281f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5291f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic void dio700_release(struct pcmcia_device *link) 5301f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 53155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "dio700_release\n"); 5321f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5331f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks pcmcia_disable_device(link); 5341f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} /* dio700_release */ 5351f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5361f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic int dio700_cs_suspend(struct pcmcia_device *link) 5371f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 53830570f0dee2b0e3ede09e08eb5dfd514317a7587Bill Pemberton struct local_info_t *local = link->priv; 5391f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5401f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* Mark the device as stopped, to block IO until later */ 5411f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks local->stop = 1; 5421f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 5431f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} /* dio700_cs_suspend */ 5441f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5451f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic int dio700_cs_resume(struct pcmcia_device *link) 5461f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 54730570f0dee2b0e3ede09e08eb5dfd514317a7587Bill Pemberton struct local_info_t *local = link->priv; 5481f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5491f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks local->stop = 0; 5501f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 5511f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} /* dio700_cs_resume */ 5521f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5531f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks/*====================================================================*/ 5541f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5552202a5a7490a9de282846ea8d4a56d0249e09033Joe Perchesstatic const struct pcmcia_device_id dio700_cs_ids[] = { 5561f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks /* N.B. These IDs should match those in dio700_boards */ 5571f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743), /* daqcard-700 */ 5581f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks PCMCIA_DEVICE_NULL 5591f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks}; 5601f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5616c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander Kurz 5621f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred BrooksMODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids); 5636c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_AUTHOR("Fred Brooks <nsaspook@nsaspook.com>"); 5646c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_DESCRIPTION("Comedi driver for National Instruments " 5656c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander Kurz "PCMCIA DAQCard-700 DIO"); 5666c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_LICENSE("GPL"); 5671f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5681f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstruct pcmcia_driver dio700_cs_driver = { 5691f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks .probe = dio700_cs_attach, 5701f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks .remove = dio700_cs_detach, 5711f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks .suspend = dio700_cs_suspend, 5721f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks .resume = dio700_cs_resume, 5731f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks .id_table = dio700_cs_ids, 5741f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks .owner = THIS_MODULE, 5752e9b981a7c63ee8278df6823f8389d69dad1a499Dominik Brodowski .name = "ni_daq_700", 5761f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks}; 5771f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5781f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic int __init init_dio700_cs(void) 5791f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 5801f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks pcmcia_register_driver(&dio700_cs_driver); 5811f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return 0; 5821f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 5831f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5841f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksstatic void __exit exit_dio700_cs(void) 5851f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 58655a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski pr_debug("ni_daq_700: unloading\n"); 5871f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks pcmcia_unregister_driver(&dio700_cs_driver); 5881f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 5890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 5901f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksint __init init_module(void) 5911f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 5921f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks int ret; 5931f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5941f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks ret = init_dio700_cs(); 5951f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks if (ret < 0) 5961f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return ret; 5971f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 5981f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks return comedi_driver_register(&driver_dio700); 5991f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 6001f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks 6011f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooksvoid __exit cleanup_module(void) 6021f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks{ 6031f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks exit_dio700_cs(); 6041f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks comedi_driver_unregister(&driver_dio700); 6051f9bbbe2ad29901057e9bc97e29415052aaa8aaaFred Brooks} 606