cb_das16_cs.c revision 2202a5a7490a9de282846ea8d4a56d0249e09033
1f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 2f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi/drivers/das16cs.c 3f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef Driver for Computer Boards PC-CARD DAS16/16. 4f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 5f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef COMEDI - Linux Control and Measurement Device Interface 6f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef Copyright (C) 2000, 2001, 2002 David A. Schleef <ds@schleef.org> 7f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 8f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef This program is free software; you can redistribute it and/or modify 9f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef it under the terms of the GNU General Public License as published by 10f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef the Free Software Foundation; either version 2 of the License, or 11f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef (at your option) any later version. 12f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 13f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef This program is distributed in the hope that it will be useful, 14f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef but WITHOUT ANY WARRANTY; without even the implied warranty of 15f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef GNU General Public License for more details. 17f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 18f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef You should have received a copy of the GNU General Public License 19f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef along with this program; if not, write to the Free Software 20f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 22f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 23f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 24f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefDriver: cb_das16_cs 25f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefDescription: Computer Boards PC-CARD DAS16/16 26f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefDevices: [ComputerBoards] PC-CARD DAS16/16 (cb_das16_cs), PC-CARD DAS16/16-AO 27f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefAuthor: ds 28f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefUpdated: Mon, 04 Nov 2002 20:04:21 -0800 29f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefStatus: experimental 30f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 31f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 32f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 33f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 3425436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h> 355a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 36f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include "../comedidev.h" 37f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <linux/delay.h> 38f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <linux/pci.h> 39f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 40f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#include <pcmcia/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 { 640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x0000, /* unknown */ 650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "PC-CARD DAS16/16", 660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_ao_chans = 0, 670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 68f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x0039, 700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "PC-CARD DAS16/16-AO", 710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_ao_chans = 2, 720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 73f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef { 740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x4009, 750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "PCM-DAS16s/16", 760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .n_ao_chans = 0, 770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 78f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 79f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 80b6ac161364eccce1bea4a23a9de395883e90d7abStoyan Gaydarov#define n_boards ARRAY_SIZE(das16cs_boards) 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 920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_attach(struct comedi_device *dev, 930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 94da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_detach(struct comedi_device *dev); 95139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_das16cs = { 9668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "cb_das16_cs", 9768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 9868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = das16cs_attach, 9968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = das16cs_detach, 100f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 101f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 102f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic struct pcmcia_device *cur_dev = NULL; 103f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 1049ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange das16cs_ai_range = { 4, { 1050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-10, 10), 1060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-5, 5), 1070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-2.5, 2.5), 1080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral RANGE(-1.25, 1.25), 1090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 110f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 111f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 11270265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das16cs_interrupt(int irq, void *d); 1130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_rinsn(struct comedi_device *dev, 1140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 1160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_cmd(struct comedi_device *dev, 1170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s); 1180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_cmdtest(struct comedi_device *dev, 1190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd); 1210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_winsn(struct comedi_device *dev, 1220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 1240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_rinsn(struct comedi_device *dev, 1250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 1270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_bits(struct comedi_device *dev, 1280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 1300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_config(struct comedi_device *dev, 1310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 1330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 1340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_read(struct comedi_device *dev, 1350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 1370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 1380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_config(struct comedi_device *dev, 1390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 1400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 1410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data); 142814900c904140cfe7f3e48cabec06b3eec57e0eaBill Pemberton 1430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic const struct das16cs_board *das16cs_probe(struct comedi_device *dev, 1440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct pcmcia_device *link) 145f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 146f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 147f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 148f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < n_boards; i++) { 14955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (das16cs_boards[i].device_id == link->card_id) 150f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return das16cs_boards + i; 151f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 152f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 153f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("unknown board!\n"); 154f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 155f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return NULL; 156f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 157f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 1580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_attach(struct comedi_device *dev, 1590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 160f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 161f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link; 16234c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 163f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int ret; 164f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 165f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 166f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("comedi%d: cb_das16_cs: ", dev->minor); 167f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 168f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link = cur_dev; /* XXX hack */ 169f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!link) 170f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EIO; 171f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 172859171ca92f2865453b4b2e17bf679c67044a833Joe Perches dev->iobase = link->resource[0]->start; 173f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("I/O base=0x%04lx ", dev->iobase); 174f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 175f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("fingerprint:\n"); 1767b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong for (i = 0; i < 48; i += 2) 177f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("%04x ", inw(dev->iobase + i)); 1787b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong 179f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("\n"); 180f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 181eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski ret = request_irq(link->irq, das16cs_interrupt, 1825f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman IRQF_SHARED, "cb_das16_cs", dev); 1837b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong if (ret < 0) 184f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return ret; 1857b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong 186eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski dev->irq = link->irq; 187c8d1a126924fcbc1d61ceb830226e0c7afdcc841Greg Kroah-Hartman 188f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("irq=%u ", dev->irq); 189f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 190f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->board_ptr = das16cs_probe(dev, link); 191f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!dev->board_ptr) 192f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EIO; 193f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 194f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->board_name = thisboard->name; 195f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 196bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pemberton if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) 197f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 198f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 199f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (alloc_subdevices(dev, 4) < 0) 200f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 201f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 202f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 0; 203f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->read_subdev = s; 204f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* analog input subdevice */ 205f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_AI; 206f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 207f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 16; 208f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xffff; 209f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &das16cs_ai_range; 210f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->len_chanlist = 16; 211f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = das16cs_ai_rinsn; 212f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->do_cmd = das16cs_ai_cmd; 213f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->do_cmdtest = das16cs_ai_cmdtest; 214f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 215f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 1; 216f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* analog output subdevice */ 217f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (thisboard->n_ao_chans) { 218f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_AO; 219f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_WRITABLE; 220f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = thisboard->n_ao_chans; 221f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xffff; 222f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_bipolar10; 223f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_write = &das16cs_ao_winsn; 224f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = &das16cs_ao_rinsn; 225f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 226f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 227f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 2; 228f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* digital i/o subdevice */ 229f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (1) { 230f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_DIO; 231f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 232f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 8; 233f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 1; 234f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_digital; 235f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_bits = das16cs_dio_insn_bits; 236f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_config = das16cs_dio_insn_config; 237f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 238f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_UNUSED; 239f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 240f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 241f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 3; 242f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* timer subdevice */ 243f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (0) { 244f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_TIMER; 245f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 246f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 1; 247f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xff; 248f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_unknown; 249f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = das16cs_timer_insn_read; 250f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_config = das16cs_timer_insn_config; 251f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 252f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_UNUSED; 253f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 254f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 255f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("attached\n"); 256f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 257f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 1; 258f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 259f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 260da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_detach(struct comedi_device *dev) 261f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 262f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("comedi%d: das16cs: remove\n", dev->minor); 263f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 2647b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong if (dev->irq) 2655f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 2667b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong 267f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 268f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 269f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 270f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 27170265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das16cs_interrupt(int irq, void *d) 272f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 2732696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* struct comedi_device *dev = d; */ 274f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return IRQ_HANDLED; 275f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 276f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 277f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 278f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * "instructions" read/write data in "one-shot" or "software-triggered" 279f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * mode. 280f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 2810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_rinsn(struct comedi_device *dev, 2820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 284f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 285f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 286f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int to; 287f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int aref; 288f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int range; 289f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan; 290f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 }; 291f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 292f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef chan = CR_CHAN(insn->chanspec); 293f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef aref = CR_AREF(insn->chanspec); 294f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef range = CR_RANGE(insn->chanspec); 295f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 296f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(chan, dev->iobase + 2); 297f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 298f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status1 &= ~0xf320; 299f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status1 |= (aref == AREF_DIFF) ? 0 : 0x0020; 300f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status1, dev->iobase + 4); 301f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 302f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 &= ~0xff00; 303f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= range_bits[range]; 304f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status2, dev->iobase + 6); 305f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 306f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) { 307f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(0, dev->iobase); 308f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 309f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define TIMEOUT 1000 310f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (to = 0; to < TIMEOUT; to++) { 311f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (inw(dev->iobase + 4) & 0x0080) 312f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 313f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 314f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (to == TIMEOUT) { 315f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef printk("cb_das16_cs: ai timeout\n"); 316f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ETIME; 317f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 318f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[i] = (unsigned short)inw(dev->iobase + 0); 319f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 320f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 321f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 322f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 323f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 324da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 325f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 326f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 327f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 328f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 3290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_cmdtest(struct comedi_device *dev, 3300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 332f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 333f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int err = 0; 334f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int tmp; 335f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 336f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* cmdtest tests a particular command to see if it is valid. 337f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * Using the cmdtest ioctl, a user can create a valid cmd 338f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * and then have it executes by the cmd ioctl. 339f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * 340f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * cmdtest returns 1,2,3,4 or 0, depending on which tests 341f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * the command passes. */ 342f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 343f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 1: make sure trigger sources are trivially valid */ 344f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 345f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->start_src; 346f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->start_src &= TRIG_NOW; 347f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->start_src || tmp != cmd->start_src) 348f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 349f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 350f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_begin_src; 351f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 352f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 353f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 354f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 355f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->convert_src; 356f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 357f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->convert_src || tmp != cmd->convert_src) 358f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 359f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 360f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_end_src; 361f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_end_src &= TRIG_COUNT; 362f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 363f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 364f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 365f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->stop_src; 366f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 367f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->stop_src || tmp != cmd->stop_src) 368f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 369f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 370f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 371f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 1; 372f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 373f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 2: make sure trigger sources are unique and mutually compatible */ 374f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 375828684f9a6e096f9150bad523c43b75d74b9baddDirk Hohndel /* note that mutual compatibility is not an issue here */ 376f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src != TRIG_TIMER && 3770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_EXT) 378f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 379f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 380f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 381f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 382f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 383f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 384f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 385f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 2; 386f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 387f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 3: make sure arguments are trivially compatible */ 388f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 389f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->start_arg != 0) { 390f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->start_arg = 0; 391f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 392f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 393f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define MAX_SPEED 10000 /* in nanoseconds */ 394f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define MIN_SPEED 1000000000 /* in nanoseconds */ 395f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 396f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 397f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg < MAX_SPEED) { 398f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = MAX_SPEED; 399f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 400f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 401f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg > MIN_SPEED) { 402f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = MIN_SPEED; 403f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 404f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 405f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 406f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* external trigger */ 407f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* should be level/edge, hi/lo specification here */ 408f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* should specify multiple external triggers */ 409f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg > 9) { 410f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = 9; 411f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 412f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 413f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 414f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src == TRIG_TIMER) { 415f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg < MAX_SPEED) { 416f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = MAX_SPEED; 417f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 418f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 419f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg > MIN_SPEED) { 420f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = MIN_SPEED; 421f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 422f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 423f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 424f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* external trigger */ 425f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* see above */ 426f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg > 9) { 427f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = 9; 428f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 429f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 430f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 431f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 432f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_end_arg != cmd->chanlist_len) { 433f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_end_arg = cmd->chanlist_len; 434f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 435f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 436f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_src == TRIG_COUNT) { 437f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_arg > 0x00ffffff) { 438f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_arg = 0x00ffffff; 439f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 440f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 441f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 442f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* TRIG_NONE */ 443f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_arg != 0) { 444f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_arg = 0; 445f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 446f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 447f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 448f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 449f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 450f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 3; 451f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 452f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 4: fix up any arguments */ 453f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 454f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 45548b1aff5b93521c5ad90842bef52b218ac50a4abIan Abbott unsigned int div1 = 0, div2 = 0; 456f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 457f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_begin_arg; 458f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef i8253_cascade_ns_to_timer(100, &div1, &div2, 4590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &cmd->scan_begin_arg, 4600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 461f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (tmp != cmd->scan_begin_arg) 462f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 463f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 464f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src == TRIG_TIMER) { 46548b1aff5b93521c5ad90842bef52b218ac50a4abIan Abbott unsigned int div1 = 0, div2 = 0; 466f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 467f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->convert_arg; 468f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef i8253_cascade_ns_to_timer(100, &div1, &div2, 4690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &cmd->scan_begin_arg, 4700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 471f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (tmp != cmd->convert_arg) 472f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 473f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER && 4740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_arg < 4750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_arg * cmd->scan_end_arg) { 476f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = 4770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_arg * cmd->scan_end_arg; 478f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 479f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 480f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 481f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 482f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 483f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 4; 484f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 485f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 486f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 487f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 4880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_winsn(struct comedi_device *dev, 4890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 491f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 492f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 493f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 494f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short status1; 495f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short d; 496f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int bit; 497f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 498f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) { 499f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->ao_readback[chan] = data[i]; 500f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef d = data[i]; 501f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 502f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status1, dev->iobase + 4); 5035f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 504f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 505f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 = devpriv->status1 & ~0xf; 506f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (chan) 507f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 |= 0x0001; 508f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef else 509f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 |= 0x0008; 510f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 511f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1);*/ 512f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1, dev->iobase + 4); 5135f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 514f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 515f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (bit = 15; bit >= 0; bit--) { 516f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int b = (d >> bit) & 0x1; 517f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef b <<= 1; 518f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1 | b | 0x0000);*/ 519f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | b | 0x0000, dev->iobase + 4); 5205f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 521f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1 | b | 0x0004);*/ 522f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | b | 0x0004, dev->iobase + 4); 5235f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 524f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 525f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* make high both DAC0CS and DAC1CS to load 526f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef new data and update analog output*/ 527f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | 0x9, dev->iobase + 4); 528f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 529f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 530f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 531f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 532f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 533f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* AO subdevices should have a read insn as well as a write insn. 534f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * Usually this means copying a value stored in devpriv. */ 5350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_rinsn(struct comedi_device *dev, 5360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 538f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 539f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 540f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 541f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 542f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) 543f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[i] = devpriv->ao_readback[chan]; 544f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 545f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 546f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 547f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 548f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* DIO devices are slightly special. Although it is possible to 549f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * implement the insn_read/insn_write interface, it is much more 550f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * useful to applications if you implement the insn_bits interface. 551f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * This allows packed reading/writing of the DIO channels. The 552f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * comedi core can convert between insn_bits and insn_read/write */ 5530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_bits(struct comedi_device *dev, 5540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 556f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 557f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (insn->n != 2) 558f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 559f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 560f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (data[0]) { 561f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->state &= ~data[0]; 562f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->state |= data[0] & data[1]; 563f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 564f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(s->state, dev->iobase + 16); 565f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 566f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 567f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* on return, data[1] contains the value of the digital 568f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * input and output lines. */ 569f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[1] = inw(dev->iobase + 16); 570f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 571f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 2; 572f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 573f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 5740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_config(struct comedi_device *dev, 5750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 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] = 5950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; 596f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return insn->n; 597f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 598f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef default: 599f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 600f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 601f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 602f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 603f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 &= ~0x00c0; 604f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0; 605f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= (s->io_bits & 0x0f) ? 0x0040 : 0; 606f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 607f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status2, dev->iobase + 6); 608f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 609f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return insn->n; 610f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 611f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 6120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_read(struct comedi_device *dev, 6130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 6140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 615f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 616f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 617f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 618f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 6190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_config(struct comedi_device *dev, 6200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 6210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 6220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 623f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 624f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 625f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 626f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 627f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* PCMCIA stuff */ 628f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 629f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================== 630f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 631f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The following pcmcia code for the pcm-das08 is adapted from the 632f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dummy_cs.c driver of the Linux PCMCIA Card Services package. 633f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 634f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The initial developer of the original code is David A. Hinds 635f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 636f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 637f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 638f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef======================================================================*/ 639f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 640f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) 641f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 642f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_config(struct pcmcia_device *link); 643f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_release(struct pcmcia_device *link); 644f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev); 645f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_resume(struct pcmcia_device *p_dev); 646f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 647f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 648f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The attach() and detach() entry points are used to create and destroy 649f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef "instances" of the driver, where each instance represents everything 650f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef needed to manage one actual PCMCIA card. 651f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 652f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 653f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_attach(struct pcmcia_device *); 654f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_detach(struct pcmcia_device *); 655f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 656f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 657f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef You'll also need to prototype all the functions that will actually 658f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef be used to talk to your device. See 'memory_cs' for a good example 659f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef of a fully self-sufficient driver; the other drivers rely more or 660f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef less on other parts of the kernel. 661f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 662f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 663d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pembertonstruct local_info_t { 664f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link; 665f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int stop; 666f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct bus_operations *bus; 667d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton}; 668f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 669f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================== 670f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 671f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_attach() creates an "instance" of the driver, allocating 672f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local data structures for one device. The device is registered 673f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef with Card Services. 674f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 675f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The dev_link structure is initialized, but we don't actually 676f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef configure the card at this point -- we wait until we receive a 677f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef card insertion event. 678f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 679f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef======================================================================*/ 680f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 681f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_attach(struct pcmcia_device *link) 682f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 683d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local; 684f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 68555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n"); 686f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 687f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Allocate space for private device-specific data */ 688d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); 689f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!local) 690f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 691f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->link = link; 692f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->priv = local; 693f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 694f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cur_dev = link; 695f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 696f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_config(link); 697f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 698f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 699f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_attach */ 700f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 701f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_detach(struct pcmcia_device *link) 702f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 70355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); 704f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 705eb8804f654a512a1a4e2f189d1bbaa41565e46b5Javier Martinez Canillas ((struct local_info_t *)link->priv)->stop = 1; 706eb8804f654a512a1a4e2f189d1bbaa41565e46b5Javier Martinez Canillas das16cs_pcmcia_release(link); 707d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton /* This points to the parent struct local_info_t struct */ 708f25bd6bfdf9bccd8164c151b027f9c14ec07960bDan Carpenter kfree(link->priv); 709f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_detach */ 710f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 711f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 71255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, 71355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski void *priv_data) 71455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski{ 71500990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski if (p_dev->config_index == 0) 71655a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski return -EINVAL; 717f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 71800990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski return pcmcia_request_io(p_dev); 71955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski} 72055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski 72155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic void das16cs_pcmcia_config(struct pcmcia_device *link) 72255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski{ 72355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski int ret; 724f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 72555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); 726c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 72700990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski /* Do we need to allocate an interrupt? */ 72800990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; 72900990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski 73055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL); 73155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (ret) { 73255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_warn(&link->dev, "no configuration found\n"); 73355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski goto failed; 734f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 735f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 736eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski if (!link->irq) 737eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski goto failed; 738eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski 7391ac71e5a35eebee60cdcf15b3980bd94498f037bDominik Brodowski ret = pcmcia_enable_device(link); 74055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (ret) 74155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski goto failed; 742f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 743f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return; 744f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 74555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskifailed: 746f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_release(link); 747f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_config */ 748f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 749f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_release(struct pcmcia_device *link) 750f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 75155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_release\n"); 752f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_disable_device(link); 753f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_release */ 754f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 755f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_suspend(struct pcmcia_device *link) 756f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 757d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local = link->priv; 758f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 759f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Mark the device as stopped, to block IO until later */ 760f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 1; 761f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 762f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 763f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_suspend */ 764f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 765f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_resume(struct pcmcia_device *link) 766f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 767d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local = link->priv; 768f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 769f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 0; 770f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 771f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_resume */ 772f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 773f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================*/ 774f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 7752202a5a7490a9de282846ea8d4a56d0249e09033Joe Perchesstatic const struct pcmcia_device_id das16cs_id_table[] = { 776f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039), 777f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009), 778f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_NULL 779f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 780f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 781f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefMODULE_DEVICE_TABLE(pcmcia, das16cs_id_table); 7826c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_AUTHOR("David A. Schleef <ds@schleef.org>"); 7836c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_DESCRIPTION("Comedi driver for Computer Boards PC-CARD DAS16/16"); 7846c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_LICENSE("GPL"); 785f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 786f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstruct pcmcia_driver das16cs_driver = { 787f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .probe = das16cs_pcmcia_attach, 788f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .remove = das16cs_pcmcia_detach, 789f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .suspend = das16cs_pcmcia_suspend, 790f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .resume = das16cs_pcmcia_resume, 791f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .id_table = das16cs_id_table, 792f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .owner = THIS_MODULE, 7932e9b981a7c63ee8278df6823f8389d69dad1a499Dominik Brodowski .name = "cb_das16_cs", 794f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 795f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 796f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int __init init_das16cs_pcmcia_cs(void) 797f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 798f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_register_driver(&das16cs_driver); 799f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 800f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 801f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 802f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void __exit exit_das16cs_pcmcia_cs(void) 803f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 80455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski pr_debug("das16cs_pcmcia_cs: unloading\n"); 805f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_unregister_driver(&das16cs_driver); 806f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 807f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 808f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefint __init init_module(void) 809f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 810f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int ret; 811f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 812f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef ret = init_das16cs_pcmcia_cs(); 813f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (ret < 0) 814f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return ret; 815f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 816f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return comedi_driver_register(&driver_das16cs); 817f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 818f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 819f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefvoid __exit cleanup_module(void) 820f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 821f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef exit_das16cs_pcmcia_cs(); 822f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_driver_unregister(&driver_das16cs); 823f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 824f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 825f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#else 8267114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_das16cs_init_module(void) 8277114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 8287114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas return comedi_driver_register(&driver_das16cs); 8297114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 8307114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 8317114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_das16cs_cleanup_module(void) 8327114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 8337114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas comedi_driver_unregister(&driver_das16cs); 8347114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 8357114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 8367114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_das16cs_init_module); 8377114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_das16cs_cleanup_module); 8382696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#endif /* CONFIG_PCMCIA */ 839