cb_das16_cs.c revision 68c3dbff9fc9f25872408d0e95980d41733d48d0
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 34f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include "../comedidev.h" 35f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <linux/delay.h> 36f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <linux/pci.h> 37f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 38f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <pcmcia/cs_types.h> 39f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <pcmcia/cs.h> 40f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <pcmcia/cistpl.h> 41f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <pcmcia/ds.h> 42f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 43f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include "8253.h" 44f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 45f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_SIZE 18 46f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 47f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_ADC_DATA 0 48f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_DIO_MUX 2 49f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_MISC1 4 50f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_MISC2 6 51f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_CTR0 8 52f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_CTR1 10 53f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_CTR2 12 54f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_CTR_CONTROL 14 55f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DAS16CS_DIO 16 56f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 573281a63d0b1eecbb21848c3e123c2fc0cd1d4a80Bill Pembertonstruct das16cs_board { 58f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef const char *name; 59f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int device_id; 60f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int n_ao_chans; 613281a63d0b1eecbb21848c3e123c2fc0cd1d4a80Bill Pemberton}; 623281a63d0b1eecbb21848c3e123c2fc0cd1d4a80Bill Pembertonstatic const struct das16cs_board das16cs_boards[] = { 63f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 6468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x0000,/* unknown */ 6568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "PC-CARD DAS16/16", 6668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .n_ao_chans = 0, 67f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef }, 68f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 6968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x0039, 7068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "PC-CARD DAS16/16-AO", 7168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .n_ao_chans = 2, 72f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef }, 73f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 7468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .device_id = 0x4009, 7568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .name = "PCM-DAS16s/16", 7668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .n_ao_chans = 0, 77f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef }, 78f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 79f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 80f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define n_boards (sizeof(das16cs_boards)/sizeof(das16cs_boards[0])) 813281a63d0b1eecbb21848c3e123c2fc0cd1d4a80Bill Pemberton#define thisboard ((const struct das16cs_board *)dev->board_ptr) 82f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 83bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pembertonstruct das16cs_private { 84f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link; 85f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 86790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton unsigned int ao_readback[2]; 87f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short status1; 88f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short status2; 89bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pemberton}; 90bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pemberton#define devpriv ((struct das16cs_private *)dev->private) 91f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 92da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it); 93da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_detach(struct comedi_device *dev); 94139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_das16cs = { 9568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "cb_das16_cs", 9668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 9768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = das16cs_attach, 9868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = das16cs_detach, 99f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 100f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 101f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic struct pcmcia_device *cur_dev = NULL; 102f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 1039ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange das16cs_ai_range = { 4, { 104f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef RANGE(-10, 10), 105f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef RANGE(-5, 5), 106f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef RANGE(-2.5, 2.5), 107f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef RANGE(-1.25, 1.25), 108f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 109f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 110f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 11170265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das16cs_interrupt(int irq, void *d); 11234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 11390035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data); 11434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s); 11534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, 116ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton struct comedi_cmd * cmd); 11734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s, 11890035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data); 11934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 12090035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data); 12134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s, 12290035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data); 12334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s, 12490035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data); 12534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_timer_insn_read(struct comedi_device * dev, struct comedi_subdevice * s, 12690035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data); 12734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_timer_insn_config(struct comedi_device * dev, struct comedi_subdevice * s, 12890035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton struct comedi_insn * insn, unsigned int * data); 129f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 13071b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int get_prodid(struct comedi_device * dev, struct pcmcia_device *link) 131f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 132f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple_t tuple; 133f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef u_short buf[128]; 134f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int prodid = 0; 135f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 136f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.TupleData = (cisdata_t *) buf; 137f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.TupleOffset = 0; 138f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.TupleDataMax = 255; 139f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.DesiredTuple = CISTPL_MANFID; 140f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.Attributes = TUPLE_RETURN_COMMON; 141f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((pcmcia_get_first_tuple(link, &tuple) == 0) && 142f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef (pcmcia_get_tuple_data(link, &tuple) == 0)) { 143f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef prodid = le16_to_cpu(buf[1]); 144f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 145f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 146f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return prodid; 147f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 148f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 1493281a63d0b1eecbb21848c3e123c2fc0cd1d4a80Bill Pembertonstatic const struct das16cs_board *das16cs_probe(struct comedi_device * dev, 150f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link) 151f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 152f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int id; 153f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 154f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 155f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef id = get_prodid(dev, link); 156f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 157f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < n_boards; i++) { 158f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (das16cs_boards[i].device_id == id) { 159f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return das16cs_boards + i; 160f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 161f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 162f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 163f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("unknown board!\n"); 164f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 165f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return NULL; 166f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 167f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 168da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) 169f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 170f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link; 17134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 172f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int ret; 173f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 174f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 175f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("comedi%d: cb_das16_cs: ", dev->minor); 176f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 177f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link = cur_dev; /* XXX hack */ 178f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!link) 179f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EIO; 180f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 181f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->iobase = link->io.BasePort1; 182f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("I/O base=0x%04lx ", dev->iobase); 183f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 184f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("fingerprint:\n"); 185f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < 48; i += 2) { 186f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("%04x ", inw(dev->iobase + i)); 187f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 188f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("\n"); 189f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 190f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef ret = comedi_request_irq(link->irq.AssignedIRQ, das16cs_interrupt, 191f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef IRQF_SHARED, "cb_das16_cs", dev); 192f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (ret < 0) { 193f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return ret; 194f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 195f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->irq = link->irq.AssignedIRQ; 196f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("irq=%u ", dev->irq); 197f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 198f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->board_ptr = das16cs_probe(dev, link); 199f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!dev->board_ptr) 200f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EIO; 201f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 202f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->board_name = thisboard->name; 203f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 204bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pemberton if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) 205f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 206f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 207f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (alloc_subdevices(dev, 4) < 0) 208f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 209f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 210f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 0; 211f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->read_subdev = s; 212f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* analog input subdevice */ 213f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_AI; 214f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 215f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 16; 216f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xffff; 217f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &das16cs_ai_range; 218f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->len_chanlist = 16; 219f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = das16cs_ai_rinsn; 220f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->do_cmd = das16cs_ai_cmd; 221f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->do_cmdtest = das16cs_ai_cmdtest; 222f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 223f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 1; 224f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* analog output subdevice */ 225f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (thisboard->n_ao_chans) { 226f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_AO; 227f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_WRITABLE; 228f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = thisboard->n_ao_chans; 229f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xffff; 230f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_bipolar10; 231f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_write = &das16cs_ao_winsn; 232f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = &das16cs_ao_rinsn; 233f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 234f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 235f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 2; 236f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* digital i/o subdevice */ 237f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (1) { 238f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_DIO; 239f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 240f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 8; 241f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 1; 242f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_digital; 243f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_bits = das16cs_dio_insn_bits; 244f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_config = das16cs_dio_insn_config; 245f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 246f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_UNUSED; 247f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 248f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 249f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 3; 250f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* timer subdevice */ 251f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (0) { 252f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_TIMER; 253f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 254f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 1; 255f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xff; 256f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_unknown; 257f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = das16cs_timer_insn_read; 258f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_config = das16cs_timer_insn_config; 259f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 260f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_UNUSED; 261f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 262f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 263f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("attached\n"); 264f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 265f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 1; 266f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 267f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 268da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_detach(struct comedi_device *dev) 269f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 270f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("comedi%d: das16cs: remove\n", dev->minor); 271f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 272f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (dev->irq) { 273f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_free_irq(dev->irq, dev); 274f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 275f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 276f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 277f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 278f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 27970265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das16cs_interrupt(int irq, void *d) 280f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 2812696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* struct comedi_device *dev = d; */ 282f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return IRQ_HANDLED; 283f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 284f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 285f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 286f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * "instructions" read/write data in "one-shot" or "software-triggered" 287f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * mode. 288f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 289da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, 290da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 291f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 292f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 293f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int to; 294f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int aref; 295f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int range; 296f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan; 297f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 }; 298f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 299f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef chan = CR_CHAN(insn->chanspec); 300f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef aref = CR_AREF(insn->chanspec); 301f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef range = CR_RANGE(insn->chanspec); 302f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 303f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(chan, dev->iobase + 2); 304f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 305f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status1 &= ~0xf320; 306f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status1 |= (aref == AREF_DIFF) ? 0 : 0x0020; 307f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status1, dev->iobase + 4); 308f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 309f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 &= ~0xff00; 310f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= range_bits[range]; 311f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status2, dev->iobase + 6); 312f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 313f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) { 314f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(0, dev->iobase); 315f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 316f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define TIMEOUT 1000 317f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (to = 0; to < TIMEOUT; to++) { 318f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (inw(dev->iobase + 4) & 0x0080) 319f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 320f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 321f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (to == TIMEOUT) { 322f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("cb_das16_cs: ai timeout\n"); 323f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ETIME; 324f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 325f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[i] = (unsigned short)inw(dev->iobase + 0); 326f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 327f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 328f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 329f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 330f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 331da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 332f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 333f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 334f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 335f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 336da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 337da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_cmd *cmd) 338f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 339f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int err = 0; 340f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int tmp; 341f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 342f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* cmdtest tests a particular command to see if it is valid. 343f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * Using the cmdtest ioctl, a user can create a valid cmd 344f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * and then have it executes by the cmd ioctl. 345f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * 346f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * cmdtest returns 1,2,3,4 or 0, depending on which tests 347f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * the command passes. */ 348f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 349f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 1: make sure trigger sources are trivially valid */ 350f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 351f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->start_src; 352f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->start_src &= TRIG_NOW; 353f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->start_src || tmp != cmd->start_src) 354f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 355f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 356f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_begin_src; 357f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 358f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 359f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 360f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 361f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->convert_src; 362f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 363f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->convert_src || tmp != cmd->convert_src) 364f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 365f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 366f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_end_src; 367f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_end_src &= TRIG_COUNT; 368f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 369f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 370f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 371f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->stop_src; 372f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 373f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->stop_src || tmp != cmd->stop_src) 374f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 375f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 376f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 377f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 1; 378f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 379f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 2: make sure trigger sources are unique and mutually compatible */ 380f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 381f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* note that mutual compatiblity is not an issue here */ 382f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src != TRIG_TIMER && 383f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_src != TRIG_EXT) 384f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 385f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 386f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 387f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 388f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 389f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 390f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 391f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 2; 392f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 393f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 3: make sure arguments are trivially compatible */ 394f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 395f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->start_arg != 0) { 396f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->start_arg = 0; 397f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 398f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 399f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define MAX_SPEED 10000 /* in nanoseconds */ 400f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define MIN_SPEED 1000000000 /* in nanoseconds */ 401f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 402f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 403f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg < MAX_SPEED) { 404f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = MAX_SPEED; 405f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 406f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 407f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg > MIN_SPEED) { 408f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = MIN_SPEED; 409f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 410f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 411f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 412f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* external trigger */ 413f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* should be level/edge, hi/lo specification here */ 414f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* should specify multiple external triggers */ 415f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg > 9) { 416f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = 9; 417f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 418f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 419f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 420f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src == TRIG_TIMER) { 421f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg < MAX_SPEED) { 422f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = MAX_SPEED; 423f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 424f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 425f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg > MIN_SPEED) { 426f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = MIN_SPEED; 427f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 428f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 429f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 430f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* external trigger */ 431f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* see above */ 432f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg > 9) { 433f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = 9; 434f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 435f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 436f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 437f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 438f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_end_arg != cmd->chanlist_len) { 439f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_end_arg = cmd->chanlist_len; 440f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 441f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 442f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_src == TRIG_COUNT) { 443f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_arg > 0x00ffffff) { 444f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_arg = 0x00ffffff; 445f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 446f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 447f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 448f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* TRIG_NONE */ 449f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_arg != 0) { 450f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_arg = 0; 451f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 452f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 453f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 454f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 455f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 456f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 3; 457f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 458f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 4: fix up any arguments */ 459f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 460f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 461f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned int div1, div2; 462f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 463f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_begin_arg; 464f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef i8253_cascade_ns_to_timer(100, &div1, &div2, 465f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK); 466f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (tmp != cmd->scan_begin_arg) 467f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 468f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 469f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src == TRIG_TIMER) { 470f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned int div1, div2; 471f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 472f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->convert_arg; 473f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef i8253_cascade_ns_to_timer(100, &div1, &div2, 474f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK); 475f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (tmp != cmd->convert_arg) 476f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 477f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER && 478f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg < 479f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg * cmd->scan_end_arg) { 480f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = 481f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg * cmd->scan_end_arg; 482f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 483f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 484f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 485f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 486f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 487f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 4; 488f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 489f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 490f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 491f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 492da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, 493da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 494f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 495f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 496f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 497f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short status1; 498f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short d; 499f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int bit; 500f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 501f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) { 502f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->ao_readback[chan] = data[i]; 503f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef d = data[i]; 504f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 505f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status1, dev->iobase + 4); 506f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_udelay(1); 507f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 508f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 = devpriv->status1 & ~0xf; 509f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (chan) 510f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 |= 0x0001; 511f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef else 512f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 |= 0x0008; 513f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 514f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1);*/ 515f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1, dev->iobase + 4); 516f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_udelay(1); 517f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 518f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (bit = 15; bit >= 0; bit--) { 519f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int b = (d >> bit) & 0x1; 520f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef b <<= 1; 521f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1 | b | 0x0000);*/ 522f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | b | 0x0000, dev->iobase + 4); 523f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_udelay(1); 524f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1 | b | 0x0004);*/ 525f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | b | 0x0004, dev->iobase + 4); 526f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_udelay(1); 527f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 528f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* make high both DAC0CS and DAC1CS to load 529f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef new data and update analog output*/ 530f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | 0x9, dev->iobase + 4); 531f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 532f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 533f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 534f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 535f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 536f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* AO subdevices should have a read insn as well as a write insn. 537f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * Usually this means copying a value stored in devpriv. */ 538da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, 539da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 540f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 541f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 542f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 543f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 544f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) 545f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[i] = devpriv->ao_readback[chan]; 546f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 547f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 548f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 549f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 550f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* DIO devices are slightly special. Although it is possible to 551f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * implement the insn_read/insn_write interface, it is much more 552f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * useful to applications if you implement the insn_bits interface. 553f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * This allows packed reading/writing of the DIO channels. The 554f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * comedi core can convert between insn_bits and insn_read/write */ 555da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, 556da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton 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 575da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, 576da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 577f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 578f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 579f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int bits; 580f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 581f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (chan < 4) 582f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef bits = 0x0f; 583f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef else 584f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef bits = 0xf0; 585f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 586f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef switch (data[0]) { 587f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef case INSN_CONFIG_DIO_OUTPUT: 588f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->io_bits |= bits; 589f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 590f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef case INSN_CONFIG_DIO_INPUT: 591f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->io_bits &= bits; 592f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 593f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef case INSN_CONFIG_DIO_QUERY: 594f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[1] = 595f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef (s-> 596f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 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 613da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_timer_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, 614da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 615f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 616f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 617f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 618f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 619da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_timer_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, 620da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton struct comedi_insn *insn, unsigned int *data) 621f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 622f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 623f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 624f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 625f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* PCMCIA stuff */ 626f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 627f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================== 628f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 629f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The following pcmcia code for the pcm-das08 is adapted from the 630f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dummy_cs.c driver of the Linux PCMCIA Card Services package. 631f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 632f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The initial developer of the original code is David A. Hinds 633f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 634f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 635f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 636f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef======================================================================*/ 637f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 638f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 639f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If 640f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef you do not define PCMCIA_DEBUG at all, all the debug code will be 641f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef left out. If you compile with PCMCIA_DEBUG=0, the debug code will 642f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef be present but disabled -- but it can then be enabled for specific 643f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef modules at load time with a 'pc_debug=#' option to insmod. 644f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 645f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) 646f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 647f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#ifdef PCMCIA_DEBUG 648f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int pc_debug = PCMCIA_DEBUG; 649f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefmodule_param(pc_debug, int, 0644); 650f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) 651f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic char *version = 652f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef "cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)"; 653f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#else 654f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define DEBUG(n, args...) 655f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#endif 656f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 657f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================*/ 658f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 659f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_config(struct pcmcia_device *link); 660f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_release(struct pcmcia_device *link); 661f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev); 662f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_resume(struct pcmcia_device *p_dev); 663f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 664f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 665f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The attach() and detach() entry points are used to create and destroy 666f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef "instances" of the driver, where each instance represents everything 667f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef needed to manage one actual PCMCIA card. 668f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 669f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 670f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_attach(struct pcmcia_device *); 671f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_detach(struct pcmcia_device *); 672f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 673f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 674f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef You'll also need to prototype all the functions that will actually 675f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef be used to talk to your device. See 'memory_cs' for a good example 676f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef of a fully self-sufficient driver; the other drivers rely more or 677f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef less on other parts of the kernel. 678f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 679f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 680f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 681f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The dev_info variable is the "key" that is used to match up this 682f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef device driver with appropriate cards, through the card configuration 683f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef database. 684f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 685f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 686f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic dev_info_t dev_info = "cb_das16_cs"; 687f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 688d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pembertonstruct local_info_t { 689f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link; 690f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev_node_t node; 691f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int stop; 692f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct bus_operations *bus; 693d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton}; 694f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 695f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================== 696f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 697f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_attach() creates an "instance" of the driver, allocating 698f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local data structures for one device. The device is registered 699f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef with Card Services. 700f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 701f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The dev_link structure is initialized, but we don't actually 702f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef configure the card at this point -- we wait until we receive a 703f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef card insertion event. 704f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 705f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef======================================================================*/ 706f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 707f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_attach(struct pcmcia_device *link) 708f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 709d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local; 710f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 711f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef DEBUG(0, "das16cs_pcmcia_attach()\n"); 712f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 713f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Allocate space for private device-specific data */ 714d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); 715f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!local) 716f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 717f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->link = link; 718f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->priv = local; 719f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 720f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Initialize the pcmcia_device structure */ 721f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Interrupt setup */ 722f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 723f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->irq.IRQInfo1 = IRQ_LEVEL_ID; 724f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->irq.Handler = NULL; 725f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 726f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Attributes = 0; 727f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.IntType = INT_MEMORY_AND_IO; 728f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 729f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cur_dev = link; 730f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 731f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_config(link); 732f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 733f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 734f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_attach */ 735f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 736f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_detach(struct pcmcia_device *link) 737f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 738f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link); 739f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 740f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->dev_node) { 741d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton ((struct local_info_t *) link->priv)->stop = 1; 742f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_release(link); 743f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 744d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton /* This points to the parent struct local_info_t struct */ 745f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->priv) 746f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef kfree(link->priv); 747f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_detach */ 748f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 749f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_config(struct pcmcia_device *link) 750f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 751d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *dev = link->priv; 752f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple_t tuple; 753f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cisparse_t parse; 754f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int last_fn, last_ret; 755f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef u_char buf[64]; 756f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cistpl_cftable_entry_t dflt = { 0 }; 757f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 758f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link); 759f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 760f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 761f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef This reads the card's CONFIG tuple to find its configuration 762f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef registers. 763f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 764f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.DesiredTuple = CISTPL_CONFIG; 765f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.Attributes = 0; 766f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.TupleData = buf; 767f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.TupleDataMax = sizeof(buf); 768f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.TupleOffset = 0; 769c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 770f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = GetFirstTuple; 771c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton last_ret = pcmcia_get_first_tuple(link, &tuple); 772c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (last_ret != 0) 773f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 774c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 775f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = GetTupleData; 776c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton last_ret = pcmcia_get_tuple_data(link, &tuple); 777c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (last_ret != 0) 778f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 779c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 780f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = ParseTuple; 781c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton last_ret = pcmcia_parse_tuple(&tuple, &parse); 782c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (last_ret != 0) 783f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 784c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 785f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.ConfigBase = parse.config.base; 786f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Present = parse.config.rmask[0]; 787f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 788f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 789f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef In this loop, we scan the CIS for configuration table entries, 790f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef each of which describes a valid card configuration, including 791f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef voltage, IO window, memory window, and interrupt settings. 792f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 793f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef We make no assumptions about the card to be configured: we use 794f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef just the information available in the CIS. In an ideal world, 795f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef this would work for any PCMCIA card, but it requires a complete 796f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef and accurate CIS. In practice, a driver usually "knows" most of 797f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef these things without consulting the CIS, and most client drivers 798f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef will only use the CIS to fill in implementation-defined details. 799f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 800f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 801f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = GetFirstTuple; 802c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 803c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton last_ret = pcmcia_get_first_tuple(link, &tuple); 804c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (last_ret) 805f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 806c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 807f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef while (1) { 808f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 809f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (pcmcia_get_tuple_data(link, &tuple)) 810f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto next_entry; 811de15d7fcd6452894e82657fb44b7b93c2afe97a4Ian Abbott if (pcmcia_parse_tuple(&tuple, &parse)) 812f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto next_entry; 813f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 814f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 815f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dflt = *cfg; 816f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cfg->index == 0) 817f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto next_entry; 818f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.ConfigIndex = cfg->index; 819f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 820f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Does this card need audio output? */ 821f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) { 822f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Attributes |= CONF_ENABLE_SPKR; 823f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Status = CCSR_AUDIO_ENA; 824f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 825f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 826f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Do we need to allocate an interrupt? */ 827f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) 828f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Attributes |= CONF_ENABLE_IRQ; 829f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 830f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* IO window settings */ 831f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.NumPorts1 = link->io.NumPorts2 = 0; 832f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 833f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 834f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 835f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!(io->flags & CISTPL_IO_8BIT)) 836f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 837f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!(io->flags & CISTPL_IO_16BIT)) 838f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 839f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 840f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.BasePort1 = io->win[0].base; 841f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.NumPorts1 = io->win[0].len; 842f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (io->nwin > 1) { 843f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.Attributes2 = link->io.Attributes1; 844f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.BasePort2 = io->win[1].base; 845f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.NumPorts2 = io->win[1].len; 846f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 847f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* This reserves IO space but doesn't actually enable it */ 848f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (pcmcia_request_io(link, &link->io)) 849f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto next_entry; 850f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 851f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 852f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* If we got this far, we're cool! */ 853f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 854f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 855f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef next_entry: 856f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = GetNextTuple; 857c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 858c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton last_ret = pcmcia_get_next_tuple(link, &tuple); 859c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (last_ret) 860f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 861f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 862f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 863f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 864f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef Allocate an interrupt line. Note that this does not assign a 865f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef handler to the interrupt, unless the 'Handler' member of the 866f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef irq structure is initialized. 867f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 868f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->conf.Attributes & CONF_ENABLE_IRQ) { 869f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = RequestIRQ; 870c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 871c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton last_ret = pcmcia_request_irq(link, &link->irq); 872c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (last_ret) 873f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 874f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 875f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 876f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef This actually configures the PCMCIA socket -- setting up 877f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef the I/O windows and the interrupt mapping, and putting the 878f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef card and host interface into "Memory and IO" mode. 879f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 880f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = RequestConfiguration; 881c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton last_ret = pcmcia_request_configuration(link, &link->conf); 882c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton if (last_ret) 883f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 884f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 885f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 886f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef At this point, the dev_node_t structure(s) need to be 887f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef initialized and arranged in a linked list at link->dev. 888f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 889f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef sprintf(dev->node.dev_name, "cb_das16_cs"); 890f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->node.major = dev->node.minor = 0; 891f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->dev_node = &dev->node; 892f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 893f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Finally, report what we've done */ 894f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(KERN_INFO "%s: index 0x%02x", 895f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->node.dev_name, link->conf.ConfigIndex); 896f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->conf.Attributes & CONF_ENABLE_IRQ) 897f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(", irq %u", link->irq.AssignedIRQ); 898f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->io.NumPorts1) 899f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(", io 0x%04x-0x%04x", link->io.BasePort1, 900f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.BasePort1 + link->io.NumPorts1 - 1); 901f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->io.NumPorts2) 902f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(" & 0x%04x-0x%04x", link->io.BasePort2, 903f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.BasePort2 + link->io.NumPorts2 - 1); 904f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("\n"); 905f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 906f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return; 907f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 908f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cs_failed: 909f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cs_error(link, last_fn, last_ret); 910f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_release(link); 911f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_config */ 912f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 913f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_release(struct pcmcia_device *link) 914f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 915f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link); 916f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_disable_device(link); 917f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_release */ 918f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 919f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_suspend(struct pcmcia_device *link) 920f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 921d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local = link->priv; 922f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 923f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Mark the device as stopped, to block IO until later */ 924f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 1; 925f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 926f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 927f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_suspend */ 928f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 929f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_resume(struct pcmcia_device *link) 930f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 931d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local = link->priv; 932f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 933f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 0; 934f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 935f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_resume */ 936f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 937f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================*/ 938f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 939f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic struct pcmcia_device_id das16cs_id_table[] = { 940f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039), 941f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009), 942f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_NULL 943f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 944f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 945f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefMODULE_DEVICE_TABLE(pcmcia, das16cs_id_table); 946f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 947f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstruct pcmcia_driver das16cs_driver = { 948f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .probe = das16cs_pcmcia_attach, 949f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .remove = das16cs_pcmcia_detach, 950f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .suspend = das16cs_pcmcia_suspend, 951f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .resume = das16cs_pcmcia_resume, 952f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .id_table = das16cs_id_table, 953f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .owner = THIS_MODULE, 954f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .drv = { 955f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .name = dev_info, 956f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef }, 957f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 958f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 959f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int __init init_das16cs_pcmcia_cs(void) 960f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 961f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef DEBUG(0, "%s\n", version); 962f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_register_driver(&das16cs_driver); 963f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 964f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 965f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 966f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void __exit exit_das16cs_pcmcia_cs(void) 967f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 968f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef DEBUG(0, "das16cs_pcmcia_cs: unloading\n"); 969f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_unregister_driver(&das16cs_driver); 970f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 971f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 972f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefint __init init_module(void) 973f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 974f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int ret; 975f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 976f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef ret = init_das16cs_pcmcia_cs(); 977f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (ret < 0) 978f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return ret; 979f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 980f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return comedi_driver_register(&driver_das16cs); 981f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 982f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 983f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefvoid __exit cleanup_module(void) 984f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 985f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef exit_das16cs_pcmcia_cs(); 986f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_driver_unregister(&driver_das16cs); 987f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 988f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 989f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#else 990f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefCOMEDI_INITCLEANUP(driver_das16cs); 9912696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#endif /* CONFIG_PCMCIA */ 992