cb_das16_cs.c revision 34c43922e62708d45e9660eee4b4f1fb7b4bf2c7
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 57f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleeftypedef struct das16cs_board_struct { 58f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef const char *name; 59f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int device_id; 60f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int n_ao_chans; 61f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} das16cs_board; 62f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic const das16cs_board das16cs_boards[] = { 63f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 64f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef device_id:0x0000,/* unknown */ 65f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef name: "PC-CARD DAS16/16", 66f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef n_ao_chans:0, 67f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef }, 68f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 69f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef device_id:0x0039, 70f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef name: "PC-CARD DAS16/16-AO", 71f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef n_ao_chans:2, 72f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef }, 73f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 74f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef device_id:0x4009, 75f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef name: "PCM-DAS16s/16", 76f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef n_ao_chans:0, 77f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef }, 78f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 79f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 80f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define n_boards (sizeof(das16cs_boards)/sizeof(das16cs_boards[0])) 81f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define thisboard ((const das16cs_board *)dev->board_ptr) 82f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 83f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleeftypedef struct { 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; 89f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} das16cs_private; 90f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define devpriv ((das16cs_private *)dev->private) 91f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 9271b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das16cs_attach(struct comedi_device * dev, comedi_devconfig * it); 9371b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das16cs_detach(struct comedi_device * dev); 94f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic comedi_driver driver_das16cs = { 95f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef driver_name:"cb_das16_cs", 96f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef module:THIS_MODULE, 97f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef attach:das16cs_attach, 98f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef detach:das16cs_detach, 99f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 100f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 101f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic struct pcmcia_device *cur_dev = NULL; 102f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 103f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic const 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 111f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG); 11234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 113790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton 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, 116f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_cmd * cmd); 11734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s, 118790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 11934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 120790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 12134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s, 122790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 12334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s, 124790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 12534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_timer_insn_read(struct comedi_device * dev, struct comedi_subdevice * s, 126790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data); 12734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_timer_insn_config(struct comedi_device * dev, struct comedi_subdevice * s, 128790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton 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 14971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic const 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 16871b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int das16cs_attach(struct comedi_device * dev, 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 204f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (alloc_private(dev, sizeof(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 26871b5f4f11971dea972832ad63a994c7e5b45db6bBill 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 279f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG) 280f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 28171b5f4f11971dea972832ad63a994c7e5b45db6bBill 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 */ 28934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 290790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton 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 33134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s) 332f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 333f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 334f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 335f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 33634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, 337f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 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 49234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s, 493790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton 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. */ 53834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s, 539790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton 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 */ 55534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s, 556790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton 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 57534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s, 576790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton 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 61334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_timer_insn_read(struct comedi_device * dev, struct comedi_subdevice * s, 614790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton comedi_insn * insn, unsigned int * data) 615f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 616f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 617f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 618f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 61934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int das16cs_timer_insn_config(struct comedi_device * dev, struct comedi_subdevice * s, 620790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton 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 688f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleeftypedef struct 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; 693f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} local_info_t; 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{ 709f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 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 */ 714f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local = kzalloc(sizeof(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) { 741f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef ((local_info_t *) link->priv)->stop = 1; 742f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_release(link); 743f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 744f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* This points to the parent 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{ 751f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 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; 769f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = GetFirstTuple; 770f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) 771f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 772f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = GetTupleData; 773f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) 774f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 775f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = ParseTuple; 776f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((last_ret = pcmcia_parse_tuple(link, &tuple, &parse)) != 0) 777f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 778f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.ConfigBase = parse.config.base; 779f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Present = parse.config.rmask[0]; 780f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 781f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 782f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef In this loop, we scan the CIS for configuration table entries, 783f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef each of which describes a valid card configuration, including 784f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef voltage, IO window, memory window, and interrupt settings. 785f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 786f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef We make no assumptions about the card to be configured: we use 787f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef just the information available in the CIS. In an ideal world, 788f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef this would work for any PCMCIA card, but it requires a complete 789f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef and accurate CIS. In practice, a driver usually "knows" most of 790f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef these things without consulting the CIS, and most client drivers 791f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef will only use the CIS to fill in implementation-defined details. 792f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 793f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 794f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = GetFirstTuple; 795f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) 796f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 797f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef while (1) { 798f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 799f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (pcmcia_get_tuple_data(link, &tuple)) 800f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto next_entry; 801f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (pcmcia_parse_tuple(link, &tuple, &parse)) 802f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto next_entry; 803f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 804f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 805f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dflt = *cfg; 806f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cfg->index == 0) 807f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto next_entry; 808f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.ConfigIndex = cfg->index; 809f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 810f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Does this card need audio output? */ 811f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) { 812f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Attributes |= CONF_ENABLE_SPKR; 813f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Status = CCSR_AUDIO_ENA; 814f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 815f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 816f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Do we need to allocate an interrupt? */ 817f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) 818f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->conf.Attributes |= CONF_ENABLE_IRQ; 819f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 820f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* IO window settings */ 821f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.NumPorts1 = link->io.NumPorts2 = 0; 822f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 823f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 824f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 825f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!(io->flags & CISTPL_IO_8BIT)) 826f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 827f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!(io->flags & CISTPL_IO_16BIT)) 828f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 829f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 830f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.BasePort1 = io->win[0].base; 831f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.NumPorts1 = io->win[0].len; 832f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (io->nwin > 1) { 833f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.Attributes2 = link->io.Attributes1; 834f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.BasePort2 = io->win[1].base; 835f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.NumPorts2 = io->win[1].len; 836f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 837f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* This reserves IO space but doesn't actually enable it */ 838f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (pcmcia_request_io(link, &link->io)) 839f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto next_entry; 840f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 841f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 842f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* If we got this far, we're cool! */ 843f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 844f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 845f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef next_entry: 846f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = GetNextTuple; 847f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) 848f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 849f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 850f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 851f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 852f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef Allocate an interrupt line. Note that this does not assign a 853f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef handler to the interrupt, unless the 'Handler' member of the 854f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef irq structure is initialized. 855f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 856f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->conf.Attributes & CONF_ENABLE_IRQ) { 857f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = RequestIRQ; 858f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) 859f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 860f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 861f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 862f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef This actually configures the PCMCIA socket -- setting up 863f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef the I/O windows and the interrupt mapping, and putting the 864f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef card and host interface into "Memory and IO" mode. 865f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 866f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef last_fn = RequestConfiguration; 867f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) 868f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef goto cs_failed; 869f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 870f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* 871f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef At this point, the dev_node_t structure(s) need to be 872f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef initialized and arranged in a linked list at link->dev. 873f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 874f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef sprintf(dev->node.dev_name, "cb_das16_cs"); 875f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->node.major = dev->node.minor = 0; 876f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->dev_node = &dev->node; 877f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 878f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Finally, report what we've done */ 879f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(KERN_INFO "%s: index 0x%02x", 880f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->node.dev_name, link->conf.ConfigIndex); 881f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->conf.Attributes & CONF_ENABLE_IRQ) 882f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(", irq %u", link->irq.AssignedIRQ); 883f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->io.NumPorts1) 884f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(", io 0x%04x-0x%04x", link->io.BasePort1, 885f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.BasePort1 + link->io.NumPorts1 - 1); 886f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (link->io.NumPorts2) 887f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk(" & 0x%04x-0x%04x", link->io.BasePort2, 888f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->io.BasePort2 + link->io.NumPorts2 - 1); 889f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("\n"); 890f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 891f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return; 892f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 893f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cs_failed: 894f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cs_error(link, last_fn, last_ret); 895f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_release(link); 896f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_config */ 897f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 898f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_release(struct pcmcia_device *link) 899f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 900f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link); 901f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_disable_device(link); 902f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_release */ 903f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 904f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_suspend(struct pcmcia_device *link) 905f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 906f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local_info_t *local = link->priv; 907f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 908f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Mark the device as stopped, to block IO until later */ 909f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 1; 910f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 911f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 912f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_suspend */ 913f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 914f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_resume(struct pcmcia_device *link) 915f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 916f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local_info_t *local = link->priv; 917f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 918f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 0; 919f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 920f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_resume */ 921f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 922f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================*/ 923f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 924f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic struct pcmcia_device_id das16cs_id_table[] = { 925f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039), 926f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009), 927f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_NULL 928f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 929f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 930f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefMODULE_DEVICE_TABLE(pcmcia, das16cs_id_table); 931f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 932f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstruct pcmcia_driver das16cs_driver = { 933f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .probe = das16cs_pcmcia_attach, 934f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .remove = das16cs_pcmcia_detach, 935f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .suspend = das16cs_pcmcia_suspend, 936f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .resume = das16cs_pcmcia_resume, 937f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .id_table = das16cs_id_table, 938f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .owner = THIS_MODULE, 939f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .drv = { 940f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .name = dev_info, 941f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef }, 942f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 943f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 944f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int __init init_das16cs_pcmcia_cs(void) 945f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 946f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef DEBUG(0, "%s\n", version); 947f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_register_driver(&das16cs_driver); 948f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 949f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 950f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 951f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void __exit exit_das16cs_pcmcia_cs(void) 952f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 953f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef DEBUG(0, "das16cs_pcmcia_cs: unloading\n"); 954f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_unregister_driver(&das16cs_driver); 955f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 956f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 957f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefint __init init_module(void) 958f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 959f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int ret; 960f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 961f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef ret = init_das16cs_pcmcia_cs(); 962f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (ret < 0) 963f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return ret; 964f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 965f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return comedi_driver_register(&driver_das16cs); 966f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 967f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 968f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefvoid __exit cleanup_module(void) 969f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 970f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef exit_das16cs_pcmcia_cs(); 971f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_driver_unregister(&driver_das16cs); 972f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 973f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 974f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#else 975f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefCOMEDI_INITCLEANUP(driver_das16cs); 976f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#endif //CONFIG_PCMCIA 977