cb_das16_cs.c revision eb14120f743d29744d9475bffec56ff4ad43a749
1f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 2f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi/drivers/das16cs.c 3f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef Driver for Computer Boards PC-CARD DAS16/16. 4f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 5f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef COMEDI - Linux Control and Measurement Device Interface 6f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef Copyright (C) 2000, 2001, 2002 David A. Schleef <ds@schleef.org> 7f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 8f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef This program is free software; you can redistribute it and/or modify 9f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef it under the terms of the GNU General Public License as published by 10f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef the Free Software Foundation; either version 2 of the License, or 11f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef (at your option) any later version. 12f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 13f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef This program is distributed in the hope that it will be useful, 14f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef but WITHOUT ANY WARRANTY; without even the implied warranty of 15f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef GNU General Public License for more details. 17f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 18f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef You should have received a copy of the GNU General Public License 19f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef along with this program; if not, write to the Free Software 20f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 22f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 23f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 24f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefDriver: cb_das16_cs 25f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefDescription: Computer Boards PC-CARD DAS16/16 26f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefDevices: [ComputerBoards] PC-CARD DAS16/16 (cb_das16_cs), PC-CARD DAS16/16-AO 27f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefAuthor: ds 28f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefUpdated: Mon, 04 Nov 2002 20:04:21 -0800 29f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefStatus: experimental 30f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 31f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 32f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 33f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 3425436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h> 355a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 36f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include "../comedidev.h" 37f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <linux/delay.h> 38f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <linux/pci.h> 39f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 40f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <pcmcia/cs_types.h> 41f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <pcmcia/cs.h> 42f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <pcmcia/cistpl.h> 43f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <pcmcia/ds.h> 44f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 45f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include "8253.h" 46f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 47f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_SIZE 18 48f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 49f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_ADC_DATA 0 50f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_DIO_MUX 2 51f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_MISC1 4 52f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_MISC2 6 53f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_CTR0 8 54f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_CTR1 10 55f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_CTR2 12 56f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_CTR_CONTROL 14 57f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_DIO 16 58f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 593281a63d0b1eecbb21848c3e123c2fc0cd1d4a80Bill Pembertonstruct das16cs_board { 60f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef const char *name; 61f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int device_id; 62f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int n_ao_chans; 633281a63d0b1eecbb21848c3e123c2fc0cd1d4a80Bill Pemberton}; 643281a63d0b1eecbb21848c3e123c2fc0cd1d4a80Bill Pembertonstatic const struct das16cs_board das16cs_boards[] = { 65f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x0000, /* unknown */ 670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "PC-CARD DAS16/16", 680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_ao_chans = 0, 690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 70f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x0039, 720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "PC-CARD DAS16/16-AO", 730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_ao_chans = 2, 740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 75f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x4009, 770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "PCM-DAS16s/16", 780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_ao_chans = 0, 790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 80f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 81f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 82b6ac161364eccce1bea4a23a9de395883e90d7abStoyan Gaydarov#define n_boards ARRAY_SIZE(das16cs_boards) 833281a63d0b1eecbb21848c3e123c2fc0cd1d4a80Bill Pemberton#define thisboard ((const struct das16cs_board *)dev->board_ptr) 84f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 85bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pembertonstruct das16cs_private { 86f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link; 87f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 88790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int ao_readback[2]; 89f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short status1; 90f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short status2; 91bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pemberton}; 92bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pemberton#define devpriv ((struct das16cs_private *)dev->private) 93f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_attach(struct comedi_device *dev, 950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 96da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_detach(struct comedi_device *dev); 97139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_das16cs = { 9868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "cb_das16_cs", 9968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 10068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = das16cs_attach, 10168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = das16cs_detach, 102f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 103f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 104f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic struct pcmcia_device *cur_dev = NULL; 105f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 1069ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange das16cs_ai_range = { 4, { 1070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-10, 10), 1080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-5, 5), 1090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-2.5, 2.5), 1100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-1.25, 1.25), 1110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 112f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 113f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 11470265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das16cs_interrupt(int irq, void *d); 1150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_rinsn(struct comedi_device *dev, 1160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 1180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_cmd(struct comedi_device *dev, 1190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 1200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_cmdtest(struct comedi_device *dev, 1210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd); 1230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_winsn(struct comedi_device *dev, 1240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 1260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_rinsn(struct comedi_device *dev, 1270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 1290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_bits(struct comedi_device *dev, 1300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 1320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_config(struct comedi_device *dev, 1330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 1350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 1360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_read(struct comedi_device *dev, 1370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 1390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 1400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_config(struct comedi_device *dev, 1410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 1430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 144814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton 1450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic const struct das16cs_board *das16cs_probe(struct comedi_device *dev, 1460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct pcmcia_device *link) 147f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 148f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 149f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 150f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < n_boards; i++) { 15155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (das16cs_boards[i].device_id == link->card_id) 152f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return das16cs_boards + i; 153f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 154f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 155f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("unknown board!\n"); 156f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 157f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return NULL; 158f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 159f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 1600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_attach(struct comedi_device *dev, 1610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 162f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 163f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link; 16434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 165f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int ret; 166f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 167f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 168f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("comedi%d: cb_das16_cs: ", dev->minor); 169f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 170f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link = cur_dev; /* XXX hack */ 171f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!link) 172f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EIO; 173f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 174f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->iobase = link->io.BasePort1; 175f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("I/O base=0x%04lx ", dev->iobase); 176f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 177f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("fingerprint:\n"); 178f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < 48; i += 2) { 179f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("%04x ", inw(dev->iobase + i)); 180f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 181f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("\n"); 182f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 183eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski ret = request_irq(link->irq, das16cs_interrupt, 1845f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman IRQF_SHARED, "cb_das16_cs", dev); 185f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (ret < 0) { 186f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return ret; 187f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 188eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski dev->irq = link->irq; 189f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("irq=%u ", dev->irq); 190f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 191f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->board_ptr = das16cs_probe(dev, link); 192f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!dev->board_ptr) 193f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EIO; 194f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 195f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->board_name = thisboard->name; 196f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 197bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pemberton if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) 198f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 199f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 200f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (alloc_subdevices(dev, 4) < 0) 201f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 202f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 203f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 0; 204f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->read_subdev = s; 205f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* analog input subdevice */ 206f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_AI; 207f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 208f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 16; 209f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xffff; 210f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &das16cs_ai_range; 211f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->len_chanlist = 16; 212f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = das16cs_ai_rinsn; 213f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->do_cmd = das16cs_ai_cmd; 214f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->do_cmdtest = das16cs_ai_cmdtest; 215f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 216f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 1; 217f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* analog output subdevice */ 218f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (thisboard->n_ao_chans) { 219f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_AO; 220f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_WRITABLE; 221f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = thisboard->n_ao_chans; 222f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xffff; 223f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_bipolar10; 224f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_write = &das16cs_ao_winsn; 225f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = &das16cs_ao_rinsn; 226f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 227f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 228f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 2; 229f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* digital i/o subdevice */ 230f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (1) { 231f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_DIO; 232f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 233f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 8; 234f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 1; 235f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_digital; 236f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_bits = das16cs_dio_insn_bits; 237f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_config = das16cs_dio_insn_config; 238f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 239f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_UNUSED; 240f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 241f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 242f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 3; 243f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* timer subdevice */ 244f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (0) { 245f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_TIMER; 246f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 247f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 1; 248f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xff; 249f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_unknown; 250f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = das16cs_timer_insn_read; 251f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_config = das16cs_timer_insn_config; 252f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 253f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_UNUSED; 254f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 255f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 256f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("attached\n"); 257f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 258f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 1; 259f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 260f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 261da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_detach(struct comedi_device *dev) 262f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 263f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("comedi%d: das16cs: remove\n", dev->minor); 264f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 265f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (dev->irq) { 2665f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 267f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 268f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 269f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 270f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 271f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 27270265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das16cs_interrupt(int irq, void *d) 273f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 2742696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* struct comedi_device *dev = d; */ 275f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return IRQ_HANDLED; 276f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 277f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 278f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 279f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * "instructions" read/write data in "one-shot" or "software-triggered" 280f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * mode. 281f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 2820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_rinsn(struct comedi_device *dev, 2830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 285f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 286f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 287f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int to; 288f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int aref; 289f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int range; 290f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan; 291f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 }; 292f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 293f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef chan = CR_CHAN(insn->chanspec); 294f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef aref = CR_AREF(insn->chanspec); 295f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef range = CR_RANGE(insn->chanspec); 296f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 297f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(chan, dev->iobase + 2); 298f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 299f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status1 &= ~0xf320; 300f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status1 |= (aref == AREF_DIFF) ? 0 : 0x0020; 301f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status1, dev->iobase + 4); 302f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 303f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 &= ~0xff00; 304f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= range_bits[range]; 305f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status2, dev->iobase + 6); 306f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 307f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) { 308f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(0, dev->iobase); 309f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 310f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define TIMEOUT 1000 311f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (to = 0; to < TIMEOUT; to++) { 312f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (inw(dev->iobase + 4) & 0x0080) 313f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 314f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 315f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (to == TIMEOUT) { 316f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("cb_das16_cs: ai timeout\n"); 317f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ETIME; 318f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 319f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[i] = (unsigned short)inw(dev->iobase + 0); 320f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 321f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 322f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 323f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 324f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 325da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 326f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 327f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 328f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 329f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 3300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_cmdtest(struct comedi_device *dev, 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 3320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 333f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 334f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int err = 0; 335f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int tmp; 336f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 337f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* cmdtest tests a particular command to see if it is valid. 338f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * Using the cmdtest ioctl, a user can create a valid cmd 339f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * and then have it executes by the cmd ioctl. 340f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * 341f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * cmdtest returns 1,2,3,4 or 0, depending on which tests 342f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * the command passes. */ 343f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 344f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 1: make sure trigger sources are trivially valid */ 345f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 346f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->start_src; 347f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->start_src &= TRIG_NOW; 348f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->start_src || tmp != cmd->start_src) 349f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 350f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 351f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_begin_src; 352f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 353f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 354f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 355f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 356f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->convert_src; 357f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 358f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->convert_src || tmp != cmd->convert_src) 359f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 360f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 361f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_end_src; 362f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_end_src &= TRIG_COUNT; 363f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 364f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 365f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 366f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->stop_src; 367f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 368f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->stop_src || tmp != cmd->stop_src) 369f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 370f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 371f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 372f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 1; 373f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 374f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 2: make sure trigger sources are unique and mutually compatible */ 375f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 376828684f9a6e096f9150bad523c43b75d74b9baddDirk Hohndel /* note that mutual compatibility is not an issue here */ 377f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src != TRIG_TIMER && 3780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_EXT) 379f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 380f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 381f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 382f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 383f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 384f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 385f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 386f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 2; 387f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 388f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 3: make sure arguments are trivially compatible */ 389f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 390f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->start_arg != 0) { 391f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->start_arg = 0; 392f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 393f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 394f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define MAX_SPEED 10000 /* in nanoseconds */ 395f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define MIN_SPEED 1000000000 /* in nanoseconds */ 396f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 397f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 398f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg < MAX_SPEED) { 399f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = MAX_SPEED; 400f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 401f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 402f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg > MIN_SPEED) { 403f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = MIN_SPEED; 404f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 405f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 406f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 407f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* external trigger */ 408f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* should be level/edge, hi/lo specification here */ 409f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* should specify multiple external triggers */ 410f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg > 9) { 411f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = 9; 412f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 413f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 414f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 415f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src == TRIG_TIMER) { 416f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg < MAX_SPEED) { 417f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = MAX_SPEED; 418f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 419f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 420f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg > MIN_SPEED) { 421f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = MIN_SPEED; 422f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 423f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 424f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 425f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* external trigger */ 426f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* see above */ 427f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg > 9) { 428f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = 9; 429f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 430f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 431f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 432f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 433f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_end_arg != cmd->chanlist_len) { 434f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_end_arg = cmd->chanlist_len; 435f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 436f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 437f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_src == TRIG_COUNT) { 438f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_arg > 0x00ffffff) { 439f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_arg = 0x00ffffff; 440f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 441f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 442f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 443f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* TRIG_NONE */ 444f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_arg != 0) { 445f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_arg = 0; 446f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 447f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 448f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 449f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 450f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 451f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 3; 452f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 453f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 4: fix up any arguments */ 454f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 455f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 45648b1aff5b93521c5ad90842bef52b218ac50a4abIan Abbott unsigned int div1 = 0, div2 = 0; 457f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 458f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_begin_arg; 459f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef i8253_cascade_ns_to_timer(100, &div1, &div2, 4600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &cmd->scan_begin_arg, 4610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 462f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (tmp != cmd->scan_begin_arg) 463f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 464f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 465f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src == TRIG_TIMER) { 46648b1aff5b93521c5ad90842bef52b218ac50a4abIan Abbott unsigned int div1 = 0, div2 = 0; 467f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 468f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->convert_arg; 469f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef i8253_cascade_ns_to_timer(100, &div1, &div2, 4700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &cmd->scan_begin_arg, 4710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 472f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (tmp != cmd->convert_arg) 473f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 474f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER && 4750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_arg < 4760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_arg * cmd->scan_end_arg) { 477f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = 4780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_arg * cmd->scan_end_arg; 479f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 480f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 481f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 482f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 483f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 484f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 4; 485f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 486f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 487f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 488f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 4890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_winsn(struct comedi_device *dev, 4900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 492f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 493f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 494f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 495f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short status1; 496f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short d; 497f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int bit; 498f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 499f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) { 500f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->ao_readback[chan] = data[i]; 501f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef d = data[i]; 502f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 503f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status1, dev->iobase + 4); 5045f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 505f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 506f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 = devpriv->status1 & ~0xf; 507f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (chan) 508f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 |= 0x0001; 509f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef else 510f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 |= 0x0008; 511f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 512f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1);*/ 513f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1, dev->iobase + 4); 5145f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 515f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 516f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (bit = 15; bit >= 0; bit--) { 517f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int b = (d >> bit) & 0x1; 518f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef b <<= 1; 519f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1 | b | 0x0000);*/ 520f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | b | 0x0000, dev->iobase + 4); 5215f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 522f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1 | b | 0x0004);*/ 523f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | b | 0x0004, dev->iobase + 4); 5245f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 525f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 526f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* make high both DAC0CS and DAC1CS to load 527f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef new data and update analog output*/ 528f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | 0x9, dev->iobase + 4); 529f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 530f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 531f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 532f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 533f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 534f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* AO subdevices should have a read insn as well as a write insn. 535f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * Usually this means copying a value stored in devpriv. */ 5360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_rinsn(struct comedi_device *dev, 5370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 539f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 540f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 541f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 542f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 543f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) 544f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[i] = devpriv->ao_readback[chan]; 545f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 546f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 547f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 548f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 549f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* DIO devices are slightly special. Although it is possible to 550f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * implement the insn_read/insn_write interface, it is much more 551f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * useful to applications if you implement the insn_bits interface. 552f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * This allows packed reading/writing of the DIO channels. The 553f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * comedi core can convert between insn_bits and insn_read/write */ 5540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_bits(struct comedi_device *dev, 5550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 557f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 558f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (insn->n != 2) 559f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 560f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 561f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (data[0]) { 562f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->state &= ~data[0]; 563f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->state |= data[0] & data[1]; 564f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 565f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(s->state, dev->iobase + 16); 566f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 567f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 568f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* on return, data[1] contains the value of the digital 569f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * input and output lines. */ 570f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[1] = inw(dev->iobase + 16); 571f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 572f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 2; 573f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 574f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 5750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_config(struct comedi_device *dev, 5760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 578f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 579f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 580f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int bits; 581f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 582f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (chan < 4) 583f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef bits = 0x0f; 584f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef else 585f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef bits = 0xf0; 586f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 587f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef switch (data[0]) { 588f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef case INSN_CONFIG_DIO_OUTPUT: 589f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->io_bits |= bits; 590f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 591f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef case INSN_CONFIG_DIO_INPUT: 592f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->io_bits &= bits; 593f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 594f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef case INSN_CONFIG_DIO_QUERY: 595f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[1] = 5960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; 597f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return insn->n; 598f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 599f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef default: 600f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 601f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 602f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 603f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 604f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 &= ~0x00c0; 605f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0; 606f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= (s->io_bits & 0x0f) ? 0x0040 : 0; 607f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 608f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status2, dev->iobase + 6); 609f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 610f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return insn->n; 611f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 612f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 6130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_read(struct comedi_device *dev, 6140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 6150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 616f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 617f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 618f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 619f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 6200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_config(struct comedi_device *dev, 6210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 6220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 6230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 624f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 625f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 626f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 627f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 628f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* PCMCIA stuff */ 629f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 630f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================== 631f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 632f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The following pcmcia code for the pcm-das08 is adapted from the 633f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dummy_cs.c driver of the Linux PCMCIA Card Services package. 634f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 635f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The initial developer of the original code is David A. Hinds 636f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 637f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 638f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 639f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef======================================================================*/ 640f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 641f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) 642f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 643f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_config(struct pcmcia_device *link); 644f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_release(struct pcmcia_device *link); 645f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev); 646f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_resume(struct pcmcia_device *p_dev); 647f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 648f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 649f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The attach() and detach() entry points are used to create and destroy 650f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef "instances" of the driver, where each instance represents everything 651f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef needed to manage one actual PCMCIA card. 652f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 653f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 654f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_attach(struct pcmcia_device *); 655f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_detach(struct pcmcia_device *); 656f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 657f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 658f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef You'll also need to prototype all the functions that will actually 659f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef be used to talk to your device. See 'memory_cs' for a good example 660f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef of a fully self-sufficient driver; the other drivers rely more or 661f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef less on other parts of the kernel. 662f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 663f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 664f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 665f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The dev_info variable is the "key" that is used to match up this 666f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef device driver with appropriate cards, through the card configuration 667f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef database. 668f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 669f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 670f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic dev_info_t dev_info = "cb_das16_cs"; 671f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 672d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pembertonstruct local_info_t { 673f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link; 674f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev_node_t node; 675f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int stop; 676f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct bus_operations *bus; 677d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton}; 678f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 679f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================== 680f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 681f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_attach() creates an "instance" of the driver, allocating 682f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local data structures for one device. The device is registered 683f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef with Card Services. 684f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 685f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The dev_link structure is initialized, but we don't actually 686f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef configure the card at this point -- we wait until we receive a 687f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef card insertion event. 688f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 689f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef======================================================================*/ 690f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 691f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_attach(struct pcmcia_device *link) 692f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 693d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local; 694f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 69555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n"); 696f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 697f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Allocate space for private device-specific data */ 698d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); 699f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!local) 700f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 701f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->link = link; 702f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->priv = local; 703f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 704f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Initialize the pcmcia_device structure */ 705f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Attributes = 0; 706f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.IntType = INT_MEMORY_AND_IO; 707f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 708f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cur_dev = link; 709f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 710f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_config(link); 711f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 712f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 713f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_attach */ 714f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 715f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_detach(struct pcmcia_device *link) 716f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 71755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); 718f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 719f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->dev_node) { 7200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ((struct local_info_t *)link->priv)->stop = 1; 721f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_release(link); 722f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 723d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton /* This points to the parent struct local_info_t struct */ 724f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->priv) 725f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef kfree(link->priv); 726f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_detach */ 727f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 728f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 72955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, 73055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski cistpl_cftable_entry_t *cfg, 73155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski cistpl_cftable_entry_t *dflt, 73255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski unsigned int vcc, 73355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski void *priv_data) 73455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski{ 73555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (cfg->index == 0) 73655a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski return -EINVAL; 737f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 73855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski /* Do we need to allocate an interrupt? */ 739eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski p_dev->conf.Attributes |= CONF_ENABLE_IRQ; 74055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski 74155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski /* IO window settings */ 74255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; 74355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 74455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; 74555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 74655a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (!(io->flags & CISTPL_IO_8BIT)) 74755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 74855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (!(io->flags & CISTPL_IO_16BIT)) 74955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 75055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 75155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.BasePort1 = io->win[0].base; 75255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.NumPorts1 = io->win[0].len; 75355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (io->nwin > 1) { 75455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.Attributes2 = p_dev->io.Attributes1; 75555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.BasePort2 = io->win[1].base; 75655a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski p_dev->io.NumPorts2 = io->win[1].len; 757f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 75855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski /* This reserves IO space but doesn't actually enable it */ 75955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski return pcmcia_request_io(p_dev, &p_dev->io); 76055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski } 761f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 76255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski return 0; 76355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski} 76455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski 76555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic void das16cs_pcmcia_config(struct pcmcia_device *link) 76655a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski{ 76755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski struct local_info_t *dev = link->priv; 76855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski int ret; 769f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 77055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); 771c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 77255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL); 77355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (ret) { 77455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_warn(&link->dev, "no configuration found\n"); 77555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski goto failed; 776f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 777f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 778eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski if (!link->irq) 779eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski goto failed; 780eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski 781f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 782f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef This actually configures the PCMCIA socket -- setting up 783f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef the I/O windows and the interrupt mapping, and putting the 784f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef card and host interface into "Memory and IO" mode. 785f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 78655a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski ret = pcmcia_request_configuration(link, &link->conf); 78755a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (ret) 78855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski goto failed; 789f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 790f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 791f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef At this point, the dev_node_t structure(s) need to be 792f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef initialized and arranged in a linked list at link->dev. 793f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 794f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef sprintf(dev->node.dev_name, "cb_das16_cs"); 795f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->node.major = dev->node.minor = 0; 796f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->dev_node = &dev->node; 797f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 798f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Finally, report what we've done */ 799f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(KERN_INFO "%s: index 0x%02x", 8000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral dev->node.dev_name, link->conf.ConfigIndex); 801f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->conf.Attributes & CONF_ENABLE_IRQ) 802eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski printk(", irq %u", link->irq); 803f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->io.NumPorts1) 804f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(", io 0x%04x-0x%04x", link->io.BasePort1, 8050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral link->io.BasePort1 + link->io.NumPorts1 - 1); 806f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->io.NumPorts2) 807f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(" & 0x%04x-0x%04x", link->io.BasePort2, 8080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral link->io.BasePort2 + link->io.NumPorts2 - 1); 809f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("\n"); 810f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 811f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return; 812f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 81355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskifailed: 814f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_release(link); 815f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_config */ 816f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 817f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_release(struct pcmcia_device *link) 818f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 81955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_release\n"); 820f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_disable_device(link); 821f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_release */ 822f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 823f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_suspend(struct pcmcia_device *link) 824f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 825d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local = link->priv; 826f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 827f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Mark the device as stopped, to block IO until later */ 828f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 1; 829f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 830f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 831f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_suspend */ 832f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 833f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_resume(struct pcmcia_device *link) 834f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 835d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local = link->priv; 836f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 837f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 0; 838f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 839f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_resume */ 840f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 841f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================*/ 842f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 843f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic struct pcmcia_device_id das16cs_id_table[] = { 844f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039), 845f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009), 846f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_NULL 847f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 848f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 849f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefMODULE_DEVICE_TABLE(pcmcia, das16cs_id_table); 850f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 851f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstruct pcmcia_driver das16cs_driver = { 852f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .probe = das16cs_pcmcia_attach, 853f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .remove = das16cs_pcmcia_detach, 854f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .suspend = das16cs_pcmcia_suspend, 855f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .resume = das16cs_pcmcia_resume, 856f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .id_table = das16cs_id_table, 857f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .owner = THIS_MODULE, 858f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .drv = { 8590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = dev_info, 860f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef }, 861f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 862f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 863f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int __init init_das16cs_pcmcia_cs(void) 864f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 865f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_register_driver(&das16cs_driver); 866f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 867f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 868f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 869f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void __exit exit_das16cs_pcmcia_cs(void) 870f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 87155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski pr_debug("das16cs_pcmcia_cs: unloading\n"); 872f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_unregister_driver(&das16cs_driver); 873f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 874f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 875f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefint __init init_module(void) 876f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 877f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int ret; 878f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 879f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef ret = init_das16cs_pcmcia_cs(); 880f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (ret < 0) 881f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return ret; 882f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 883f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return comedi_driver_register(&driver_das16cs); 884f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 885f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 886f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefvoid __exit cleanup_module(void) 887f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 888f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef exit_das16cs_pcmcia_cs(); 889f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_driver_unregister(&driver_das16cs); 890f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 891f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 892f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#else 893f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefCOMEDI_INITCLEANUP(driver_das16cs); 8942696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#endif /* CONFIG_PCMCIA */ 895