1d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel/*
2d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    comedi/drivers/ni_daq_dio24.c
3d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    Driver for National Instruments PCMCIA DAQ-Card DIO-24
4d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es>
5d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
6d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    PCMCIA crap at end of file is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
7d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    from the pcmcia package.
8d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
9d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
10d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
11d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
12d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    This program is free software; you can redistribute it and/or modify
13d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    it under the terms of the GNU General Public License as published by
14d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    the Free Software Foundation; either version 2 of the License, or
15d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    (at your option) any later version.
16d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
17d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    This program is distributed in the hope that it will be useful,
18d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    but WITHOUT ANY WARRANTY; without even the implied warranty of
19d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    GNU General Public License for more details.
21d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
22d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    You should have received a copy of the GNU General Public License
23d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    along with this program; if not, write to the Free Software
24d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
26d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel************************************************************************
27d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel*/
28d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel/*
29d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino CastelDriver: ni_daq_dio24
30d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino CastelDescription: National Instruments PCMCIA DAQ-Card DIO-24
31d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino CastelAuthor: Daniel Vecino Castel <dvecino@able.es>
32d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino CastelDevices: [National Instruments] PCMCIA DAQ-Card DIO-24 (ni_daq_dio24)
33d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino CastelStatus: ?
34d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino CastelUpdated: Thu, 07 Nov 2002 21:53:06 -0800
35d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
36d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino CastelThis is just a wrapper around the 8255.o driver to properly handle
37d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelthe PCMCIA interface.
38d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel*/
39d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    /* #define LABPC_DEBUG *//*  enable debugging messages */
41d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#undef LABPC_DEBUG
42d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
4325436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h>
445a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
45d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#include "../comedidev.h"
46d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
47d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#include <linux/ioport.h>
48d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
49d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#include "8255.h"
50d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
51d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#include <pcmcia/cistpl.h>
52d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#include <pcmcia/cisreg.h>
53d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#include <pcmcia/ds.h>
54d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
5573b12a5bc0d3b37bd57227b88065ad7024b1720eRavishankar karkala Mallikarjunayyastatic struct pcmcia_device *pcmcia_cur_dev;
56d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
572696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DIO24_SIZE 4		/*  size of io region used by board */
58d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
59da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it);
60da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dio24_detach(struct comedi_device *dev);
61d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
62d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelenum dio24_bustype { pcmcia_bustype };
63d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
64cf4c8d1b8f59ae5591bba0936f378e52df09aa04Bill Pembertonstruct dio24_board_struct {
65d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	const char *name;
662696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int device_id;		/*  device id for pcmcia board */
672696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	enum dio24_bustype bustype;	/*  PCMCIA */
682696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int have_dio;		/*  have 8255 chip */
692696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	/*  function pointers so we can use inb/outb or readb/writeb as appropriate */
70d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	unsigned int (*read_byte) (unsigned int address);
71d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	void (*write_byte) (unsigned int byte, unsigned int address);
72cf4c8d1b8f59ae5591bba0936f378e52df09aa04Bill Pemberton};
73d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
74cf4c8d1b8f59ae5591bba0936f378e52df09aa04Bill Pembertonstatic const struct dio24_board_struct dio24_boards[] = {
75d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	{
760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "daqcard-dio24",
770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .device_id = 0x475c,	/*  0x10b is manufacturer id, 0x475c is device id */
780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .bustype = pcmcia_bustype,
790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .have_dio = 1,
800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
81d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	{
820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "ni_daq_dio24",
830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .device_id = 0x475c,	/*  0x10b is manufacturer id, 0x475c is device id */
840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .bustype = pcmcia_bustype,
850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .have_dio = 1,
860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
87d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel};
88d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
89d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel/*
90d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel * Useful for shorthand access to the particular board structure
91d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel */
92cf4c8d1b8f59ae5591bba0936f378e52df09aa04Bill Pemberton#define thisboard ((const struct dio24_board_struct *)dev->board_ptr)
93d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
94344d23e931fdb982489753e5189d9c60ffbdfd67Bill Pembertonstruct dio24_private {
95344d23e931fdb982489753e5189d9c60ffbdfd67Bill Pemberton
96d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	int data;		/* number of data points left to be taken */
97344d23e931fdb982489753e5189d9c60ffbdfd67Bill Pemberton};
98344d23e931fdb982489753e5189d9c60ffbdfd67Bill Pemberton
99344d23e931fdb982489753e5189d9c60ffbdfd67Bill Pemberton#define devpriv ((struct dio24_private *)dev->private)
100d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
101139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_dio24 = {
10268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.driver_name = "ni_daq_dio24",
10368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.module = THIS_MODULE,
10468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.attach = dio24_attach,
10568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.detach = dio24_detach,
1068629efa4cbf6f89a54a85af4b8bc31762af01800Bill Pemberton	.num_names = ARRAY_SIZE(dio24_boards),
10768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.board_name = &dio24_boards[0].name,
10868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.offset = sizeof(struct dio24_board_struct),
109d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel};
110d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
111da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it)
112d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
11334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
114d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	unsigned long iobase = 0;
115d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#ifdef incomplete
116d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	unsigned int irq = 0;
117d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#endif
118d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	struct pcmcia_device *link;
119d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
120d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	/* allocate and initialize dev->private */
121344d23e931fdb982489753e5189d9c60ffbdfd67Bill Pemberton	if (alloc_private(dev, sizeof(struct dio24_private)) < 0)
122d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		return -ENOMEM;
123d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
1242696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	/*  get base address, irq etc. based on bustype */
125d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	switch (thisboard->bustype) {
126d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	case pcmcia_bustype:
127d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		link = pcmcia_cur_dev;	/* XXX hack */
128d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		if (!link)
129d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel			return -EIO;
1309a017a910346afd88ec2e065989903bf211a7d37Dominik Brodowski		iobase = link->resource[0]->start;
131d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#ifdef incomplete
132eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski		irq = link->irq;
133d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#endif
134d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		break;
135d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	default:
1361aa301e83b275c9493ea232d1cb1a7edccc40c14Ravishankar karkala Mallikarjunayya		pr_err("bug! couldn't determine board type\n");
137d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		return -EINVAL;
138d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		break;
139d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	}
1401aa301e83b275c9493ea232d1cb1a7edccc40c14Ravishankar karkala Mallikarjunayya	pr_debug("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
1411aa301e83b275c9493ea232d1cb1a7edccc40c14Ravishankar karkala Mallikarjunayya		 thisboard->name, iobase);
142d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#ifdef incomplete
143ef7908ebc3f81bc85c22ebe5e91c85caeeeac544Ravishankar karkala Mallikarjunayya	if (irq)
1441aa301e83b275c9493ea232d1cb1a7edccc40c14Ravishankar karkala Mallikarjunayya		pr_debug("irq %u\n", irq);
145d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#endif
146d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
147d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	if (iobase == 0) {
1481aa301e83b275c9493ea232d1cb1a7edccc40c14Ravishankar karkala Mallikarjunayya		pr_err("io base address is zero!\n");
149d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		return -EINVAL;
150d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	}
151d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
152d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	dev->iobase = iobase;
153d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
154d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#ifdef incomplete
155d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	/* grab our IRQ */
156d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	dev->irq = irq;
157d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel#endif
158d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
159d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	dev->board_name = thisboard->name;
160d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
161d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	if (alloc_subdevices(dev, 1) < 0)
162d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		return -ENOMEM;
163d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
164d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	/* 8255 dio */
165d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	s = dev->subdevices + 0;
166d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	subdev_8255_init(dev, s, NULL, dev->iobase);
167d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
168d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	return 0;
169d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel};
170d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
171da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int dio24_detach(struct comedi_device *dev)
172d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
1731aa301e83b275c9493ea232d1cb1a7edccc40c14Ravishankar karkala Mallikarjunayya	dev_info(dev->hw_dev, "comedi%d: ni_daq_dio24: remove\n", dev->minor);
174d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
175d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	if (dev->subdevices)
176d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		subdev_8255_cleanup(dev, dev->subdevices + 0);
177d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
178d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	if (thisboard->bustype != pcmcia_bustype && dev->iobase)
179d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		release_region(dev->iobase, DIO24_SIZE);
180d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	if (dev->irq)
1815f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		free_irq(dev->irq, dev);
182d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
183d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	return 0;
184d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel};
185d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
186d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic void dio24_config(struct pcmcia_device *link);
187d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic void dio24_release(struct pcmcia_device *link);
188d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic int dio24_cs_suspend(struct pcmcia_device *p_dev);
189d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic int dio24_cs_resume(struct pcmcia_device *p_dev);
190d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
191d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic int dio24_cs_attach(struct pcmcia_device *);
192d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic void dio24_cs_detach(struct pcmcia_device *);
193d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
1942ec9f875f8f60c9102f97fba23e9abe9ed4480a6Bill Pembertonstruct local_info_t {
195d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	struct pcmcia_device *link;
196d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	int stop;
197d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	struct bus_operations *bus;
1982ec9f875f8f60c9102f97fba23e9abe9ed4480a6Bill Pemberton};
199d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
200d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic int dio24_cs_attach(struct pcmcia_device *link)
201d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
2022ec9f875f8f60c9102f97fba23e9abe9ed4480a6Bill Pemberton	struct local_info_t *local;
203d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
204d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
205d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
20655a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski	dev_dbg(&link->dev, "dio24_cs_attach()\n");
207d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
208d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	/* Allocate space for private device-specific data */
2092ec9f875f8f60c9102f97fba23e9abe9ed4480a6Bill Pemberton	local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
210d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	if (!local)
211d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		return -ENOMEM;
212d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	local->link = link;
213d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	link->priv = local;
214d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
215d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	pcmcia_cur_dev = link;
216d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
217d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	dio24_config(link);
218d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
219d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	return 0;
220d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}				/* dio24_cs_attach */
221d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
222d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic void dio24_cs_detach(struct pcmcia_device *link)
223d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
224d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
225d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
226d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
22755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski	dev_dbg(&link->dev, "dio24_cs_detach\n");
228d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
22978950591e42a9c5069308f24e4cff73ae4d37472Javier Martinez Canillas	((struct local_info_t *)link->priv)->stop = 1;
23078950591e42a9c5069308f24e4cff73ae4d37472Javier Martinez Canillas	dio24_release(link);
231d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
232d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	/* This points to the parent local_info_t struct */
233f25bd6bfdf9bccd8164c151b027f9c14ec07960bDan Carpenter	kfree(link->priv);
234d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
235d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}				/* dio24_cs_detach */
236d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
23755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
23855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski				void *priv_data)
239d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
24000990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski	if (p_dev->config_index == 0)
24100990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski		return -EINVAL;
242c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton
24300990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski	return pcmcia_request_io(p_dev);
24455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski}
245d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
24655a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic void dio24_config(struct pcmcia_device *link)
24755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski{
24855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski	int ret;
249d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
25055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
251d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
25255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski	dev_dbg(&link->dev, "dio24_config\n");
253c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton
25400990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO |
25500990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski		CONF_AUTO_SET_IO;
256440eed43e2a95bb842488755683716814da10f2bDominik Brodowski
2570f52e86ded65749c6037473013ad77b2afa4f68dDominik Brodowski	ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, NULL);
25855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski	if (ret) {
25955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski		dev_warn(&link->dev, "no configuration found\n");
26055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski		goto failed;
261d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	}
262d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
263eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski	if (!link->irq)
264eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski		goto failed;
265d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
2661ac71e5a35eebee60cdcf15b3980bd94498f037bDominik Brodowski	ret = pcmcia_enable_device(link);
26755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski	if (ret)
26855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski		goto failed;
269d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
270d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	return;
271d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
27255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskifailed:
273d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	printk(KERN_INFO "Fallo");
274d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	dio24_release(link);
275d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
276d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}				/* dio24_config */
277d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
278d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic void dio24_release(struct pcmcia_device *link)
279d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
28055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski	dev_dbg(&link->dev, "dio24_release\n");
281d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
282d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	pcmcia_disable_device(link);
283d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}				/* dio24_release */
284d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
285d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic int dio24_cs_suspend(struct pcmcia_device *link)
286d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
2872ec9f875f8f60c9102f97fba23e9abe9ed4480a6Bill Pemberton	struct local_info_t *local = link->priv;
288d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
289d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	/* Mark the device as stopped, to block IO until later */
290d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	local->stop = 1;
291d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	return 0;
292d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}				/* dio24_cs_suspend */
293d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
294d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic int dio24_cs_resume(struct pcmcia_device *link)
295d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
2962ec9f875f8f60c9102f97fba23e9abe9ed4480a6Bill Pemberton	struct local_info_t *local = link->priv;
297d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
298d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	local->stop = 0;
299d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	return 0;
300d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}				/* dio24_cs_resume */
301d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
302d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel/*====================================================================*/
303d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
3042202a5a7490a9de282846ea8d4a56d0249e09033Joe Perchesstatic const struct pcmcia_device_id dio24_cs_ids[] = {
305d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	/* N.B. These IDs should match those in dio24_boards */
306d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c),	/* daqcard-dio24 */
307d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	PCMCIA_DEVICE_NULL
308d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel};
309d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
310d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino CastelMODULE_DEVICE_TABLE(pcmcia, dio24_cs_ids);
3116c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_AUTHOR("Daniel Vecino Castel <dvecino@able.es>");
3126c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_DESCRIPTION("Comedi driver for National Instruments "
3136c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander Kurz		   "PCMCIA DAQ-Card DIO-24");
3146c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_LICENSE("GPL");
315d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
316d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstruct pcmcia_driver dio24_cs_driver = {
317d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	.probe = dio24_cs_attach,
318d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	.remove = dio24_cs_detach,
319d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	.suspend = dio24_cs_suspend,
320d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	.resume = dio24_cs_resume,
321d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	.id_table = dio24_cs_ids,
322d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	.owner = THIS_MODULE,
3232e9b981a7c63ee8278df6823f8389d69dad1a499Dominik Brodowski	.name = "ni_daq_dio24",
324d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel};
325d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
326d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic int __init init_dio24_cs(void)
327d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
328d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	printk("ni_daq_dio24: HOLA SOY YO!\n");
329d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	pcmcia_register_driver(&dio24_cs_driver);
330d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	return 0;
331d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}
332d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
333d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelstatic void __exit exit_dio24_cs(void)
334d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
335d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	pcmcia_unregister_driver(&dio24_cs_driver);
336d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}
337d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
338d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelint __init init_module(void)
339d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
340d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	int ret;
341d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
342d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	ret = init_dio24_cs();
343d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	if (ret < 0)
344d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel		return ret;
345d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
346d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	return comedi_driver_register(&driver_dio24);
347d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}
348d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel
349d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castelvoid __exit cleanup_module(void)
350d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel{
351d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	exit_dio24_cs();
352d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel	comedi_driver_unregister(&driver_dio24);
353d1d3cb329ce442c168eba3cd896488ef3a84026fDaniel Vecino Castel}
354