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 102036f419529d4dd83a1d46de04551d60994d1f372Ravishankar karkala Mallikarjunayyastatic struct pcmcia_device *cur_dev; 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 153cc780e8f92e1576e4ac867e5d26d22ffbc39ddd8Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "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 166cc780e8f92e1576e4ac867e5d26d22ffbc39ddd8Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "comedi%d: cb_das16_cs: attached\n", 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; 173cc780e8f92e1576e4ac867e5d26d22ffbc39ddd8Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "I/O base=0x%04lx\n", dev->iobase); 174f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 175cc780e8f92e1576e4ac867e5d26d22ffbc39ddd8Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "fingerprint:\n"); 1767b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong for (i = 0; i < 48; i += 2) 177cc780e8f92e1576e4ac867e5d26d22ffbc39ddd8Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "%04x\n", inw(dev->iobase + i)); 1787b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong 179f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 180eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski ret = request_irq(link->irq, das16cs_interrupt, 1815f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman IRQF_SHARED, "cb_das16_cs", dev); 1827b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong if (ret < 0) 183f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return ret; 1847b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong 185eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski dev->irq = link->irq; 186c8d1a126924fcbc1d61ceb830226e0c7afdcc841Greg Kroah-Hartman 187cc780e8f92e1576e4ac867e5d26d22ffbc39ddd8Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "irq=%u\n", dev->irq); 188f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 189f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->board_ptr = das16cs_probe(dev, link); 190f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!dev->board_ptr) 191f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EIO; 192f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 193f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->board_name = thisboard->name; 194f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 195bfae362ab6a9737e67a07ff82632a16181bb2d3cBill Pemberton if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) 196f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 197f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 198f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (alloc_subdevices(dev, 4) < 0) 199f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 200f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 201f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 0; 202f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dev->read_subdev = s; 203f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* analog input subdevice */ 204f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_AI; 205f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 206f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 16; 207f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xffff; 208f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &das16cs_ai_range; 209f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->len_chanlist = 16; 210f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = das16cs_ai_rinsn; 211f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->do_cmd = das16cs_ai_cmd; 212f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->do_cmdtest = das16cs_ai_cmdtest; 213f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 214f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 1; 215f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* analog output subdevice */ 216f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (thisboard->n_ao_chans) { 217f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_AO; 218f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_WRITABLE; 219f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = thisboard->n_ao_chans; 220f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xffff; 221f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_bipolar10; 222f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_write = &das16cs_ao_winsn; 223f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = &das16cs_ao_rinsn; 224f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 225f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 226f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 2; 227f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* digital i/o subdevice */ 228f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (1) { 229f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_DIO; 230f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 231f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 8; 232f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 1; 233f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_digital; 234f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_bits = das16cs_dio_insn_bits; 235f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_config = das16cs_dio_insn_config; 236f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 237f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_UNUSED; 238f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 239f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 240f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s = dev->subdevices + 3; 241f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* timer subdevice */ 242f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (0) { 243f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_TIMER; 244f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 245f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->n_chan = 1; 246f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->maxdata = 0xff; 247f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->range_table = &range_unknown; 248f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_read = das16cs_timer_insn_read; 249f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->insn_config = das16cs_timer_insn_config; 250f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 251f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->type = COMEDI_SUBD_UNUSED; 252f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 253f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 254f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 255f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 1; 256f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 257f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 258da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_detach(struct comedi_device *dev) 259f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 260cc780e8f92e1576e4ac867e5d26d22ffbc39ddd8Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "comedi%d: das16cs: remove\n", dev->minor); 261f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 2627b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong if (dev->irq) 2635f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman free_irq(dev->irq, dev); 2647b8f2d1a2ece4180ac5fe418bf915efe728583a8Jason Wong 265f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 266f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 267f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 268f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 26970265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t das16cs_interrupt(int irq, void *d) 270f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 2712696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* struct comedi_device *dev = d; */ 272f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return IRQ_HANDLED; 273f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 274f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 275f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 276f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * "instructions" read/write data in "one-shot" or "software-triggered" 277f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * mode. 278f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef */ 2790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_rinsn(struct comedi_device *dev, 2800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 282f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 283f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 284f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int to; 285f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int aref; 286f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int range; 287f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan; 288f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 }; 289f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 290f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef chan = CR_CHAN(insn->chanspec); 291f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef aref = CR_AREF(insn->chanspec); 292f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef range = CR_RANGE(insn->chanspec); 293f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 294f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(chan, dev->iobase + 2); 295f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 296f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status1 &= ~0xf320; 297f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status1 |= (aref == AREF_DIFF) ? 0 : 0x0020; 298f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status1, dev->iobase + 4); 299f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 300f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 &= ~0xff00; 301f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= range_bits[range]; 302f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status2, dev->iobase + 6); 303f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 304f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) { 305f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(0, dev->iobase); 306f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 307f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define TIMEOUT 1000 308f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (to = 0; to < TIMEOUT; to++) { 309f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (inw(dev->iobase + 4) & 0x0080) 310f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 311f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 312f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (to == TIMEOUT) { 313cc780e8f92e1576e4ac867e5d26d22ffbc39ddd8Ravishankar karkala Mallikarjunayya dev_dbg(dev->hw_dev, "cb_das16_cs: ai timeout\n"); 314f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ETIME; 315f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 316f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[i] = (unsigned short)inw(dev->iobase + 0); 317f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 318f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 319f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 320f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 321f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 322da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int das16cs_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 323f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 324f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 325f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 326f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 3270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ai_cmdtest(struct comedi_device *dev, 3280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 3290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 330f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 331f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int err = 0; 332f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int tmp; 333f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 334f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* cmdtest tests a particular command to see if it is valid. 335f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * Using the cmdtest ioctl, a user can create a valid cmd 336f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * and then have it executes by the cmd ioctl. 337f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * 338f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * cmdtest returns 1,2,3,4 or 0, depending on which tests 339f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * the command passes. */ 340f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 341f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 1: make sure trigger sources are trivially valid */ 342f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 343f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->start_src; 344f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->start_src &= TRIG_NOW; 345f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->start_src || tmp != cmd->start_src) 346f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 347f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 348f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_begin_src; 349f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 350f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 351f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 352f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 353f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->convert_src; 354f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 355f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->convert_src || tmp != cmd->convert_src) 356f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 357f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 358f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_end_src; 359f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_end_src &= TRIG_COUNT; 360f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 361f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 362f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 363f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->stop_src; 364f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 365f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!cmd->stop_src || tmp != cmd->stop_src) 366f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 367f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 368f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 369f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 1; 370f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 371589cabe1b13576b85419d73ba87e50f7f80463fbChristopher Rice /* step 2: make sure trigger sources are unique and 372589cabe1b13576b85419d73ba87e50f7f80463fbChristopher Rice * mutually compatible */ 373f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 374828684f9a6e096f9150bad523c43b75d74b9baddDirk Hohndel /* note that mutual compatibility is not an issue here */ 375f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src != TRIG_TIMER && 3760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_src != TRIG_EXT) 377f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 378f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 379f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 380f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 381f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 382f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 383f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 384f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 2; 385f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 386f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 3: make sure arguments are trivially compatible */ 387f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 388f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->start_arg != 0) { 389f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->start_arg = 0; 390f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 391f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 392f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define MAX_SPEED 10000 /* in nanoseconds */ 393f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#define MIN_SPEED 1000000000 /* in nanoseconds */ 394f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 395f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 396f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg < MAX_SPEED) { 397f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = MAX_SPEED; 398f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 399f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 400f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg > MIN_SPEED) { 401f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = MIN_SPEED; 402f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 403f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 404f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 405f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* external trigger */ 406f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* should be level/edge, hi/lo specification here */ 407f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* should specify multiple external triggers */ 408f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_arg > 9) { 409f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = 9; 410f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 411f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 412f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 413f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src == TRIG_TIMER) { 414f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg < MAX_SPEED) { 415f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = MAX_SPEED; 416f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 417f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 418f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg > MIN_SPEED) { 419f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = MIN_SPEED; 420f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 421f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 422f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 423f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* external trigger */ 424f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* see above */ 425f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_arg > 9) { 426f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->convert_arg = 9; 427f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 428f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 429f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 430f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 431f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_end_arg != cmd->chanlist_len) { 432f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_end_arg = cmd->chanlist_len; 433f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 434f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 435f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_src == TRIG_COUNT) { 436f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_arg > 0x00ffffff) { 437f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_arg = 0x00ffffff; 438f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 439f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 440f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } else { 441f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* TRIG_NONE */ 442f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->stop_arg != 0) { 443f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->stop_arg = 0; 444f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 445f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 446f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 447f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 448f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 449f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 3; 450f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 451f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* step 4: fix up any arguments */ 452f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 453f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER) { 45448b1aff5b93521c5ad90842bef52b218ac50a4abIan Abbott unsigned int div1 = 0, div2 = 0; 455f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 456f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->scan_begin_arg; 457f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef i8253_cascade_ns_to_timer(100, &div1, &div2, 4580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &cmd->scan_begin_arg, 4590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 460f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (tmp != cmd->scan_begin_arg) 461f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 462f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 463f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->convert_src == TRIG_TIMER) { 46448b1aff5b93521c5ad90842bef52b218ac50a4abIan Abbott unsigned int div1 = 0, div2 = 0; 465f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 466f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef tmp = cmd->convert_arg; 467f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef i8253_cascade_ns_to_timer(100, &div1, &div2, 4680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral &cmd->scan_begin_arg, 4690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 470f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (tmp != cmd->convert_arg) 471f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 472f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (cmd->scan_begin_src == TRIG_TIMER && 4730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_arg < 4740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_arg * cmd->scan_end_arg) { 475f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cmd->scan_begin_arg = 4760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_arg * cmd->scan_end_arg; 477f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef err++; 478f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 479f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 480f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 481f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (err) 482f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 4; 483f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 484f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 485f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 486f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 4870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_winsn(struct comedi_device *dev, 4880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 490f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 491f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 492f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 493f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short status1; 494f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef unsigned short d; 495f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int bit; 496f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 497f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) { 498f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->ao_readback[chan] = data[i]; 499f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef d = data[i]; 500f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 501f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status1, dev->iobase + 4); 5025f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 503f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 504f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 = devpriv->status1 & ~0xf; 505f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (chan) 506f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 |= 0x0001; 507f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef else 508f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef status1 |= 0x0008; 509f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 510589cabe1b13576b85419d73ba87e50f7f80463fbChristopher Rice/* printk("0x%04x\n",status1);*/ 511f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1, dev->iobase + 4); 5125f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 513f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 514f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (bit = 15; bit >= 0; bit--) { 515f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int b = (d >> bit) & 0x1; 516f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef b <<= 1; 517f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1 | b | 0x0000);*/ 518f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | b | 0x0000, dev->iobase + 4); 5195f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 520f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* printk("0x%04x\n",status1 | b | 0x0004);*/ 521f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | b | 0x0004, dev->iobase + 4); 5225f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman udelay(1); 523f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 524f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* make high both DAC0CS and DAC1CS to load 525f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef new data and update analog output*/ 526f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(status1 | 0x9, dev->iobase + 4); 527f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 528f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 529f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 530f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 531f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 532f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* AO subdevices should have a read insn as well as a write insn. 533f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * Usually this means copying a value stored in devpriv. */ 5340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_ao_rinsn(struct comedi_device *dev, 5350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 537f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 538f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int i; 539f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 540f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 541f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef for (i = 0; i < insn->n; i++) 542f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[i] = devpriv->ao_readback[chan]; 543f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 544f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return i; 545f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 546f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 547f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* DIO devices are slightly special. Although it is possible to 548f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * implement the insn_read/insn_write interface, it is much more 549f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * useful to applications if you implement the insn_bits interface. 550f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * This allows packed reading/writing of the DIO channels. The 551f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * comedi core can convert between insn_bits and insn_read/write */ 5520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_bits(struct comedi_device *dev, 5530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 555f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 556f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (insn->n != 2) 557f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 558f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 559f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (data[0]) { 560f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->state &= ~data[0]; 561f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->state |= data[0] & data[1]; 562f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 563f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(s->state, dev->iobase + 16); 564f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 565f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 566f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* on return, data[1] contains the value of the digital 567f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef * input and output lines. */ 568f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[1] = inw(dev->iobase + 16); 569f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 570f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 2; 571f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 572f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 5730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_dio_insn_config(struct comedi_device *dev, 5740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 5750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 576f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 577f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int chan = CR_CHAN(insn->chanspec); 578f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int bits; 579f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 580f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (chan < 4) 581f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef bits = 0x0f; 582f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef else 583f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef bits = 0xf0; 584f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 585f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef switch (data[0]) { 586f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef case INSN_CONFIG_DIO_OUTPUT: 587f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->io_bits |= bits; 588f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 589f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef case INSN_CONFIG_DIO_INPUT: 590f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef s->io_bits &= bits; 591f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 592f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef case INSN_CONFIG_DIO_QUERY: 593f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef data[1] = 5940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; 595f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return insn->n; 596f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 597f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef default: 598f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 599f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef break; 600f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 601f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 602f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 &= ~0x00c0; 603f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0; 604f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef devpriv->status2 |= (s->io_bits & 0x0f) ? 0x0040 : 0; 605f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 606f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef outw(devpriv->status2, dev->iobase + 6); 607f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 608f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return insn->n; 609f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 610f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 6110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_read(struct comedi_device *dev, 6120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 6130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 614f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 615f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 616f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 617f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 6180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int das16cs_timer_insn_config(struct comedi_device *dev, 6190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 6200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, 6210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int *data) 622f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 623f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -EINVAL; 624f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 625f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 626f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* PCMCIA stuff */ 627f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 628f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================== 629f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 630f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The following pcmcia code for the pcm-das08 is adapted from the 631f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef dummy_cs.c driver of the Linux PCMCIA Card Services package. 632f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 633f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The initial developer of the original code is David A. Hinds 634f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 635f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 636f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 637f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef======================================================================*/ 638f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 639f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) 640f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 641f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_config(struct pcmcia_device *link); 642f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_release(struct pcmcia_device *link); 643f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev); 644f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_resume(struct pcmcia_device *p_dev); 645f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 646f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 647f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The attach() and detach() entry points are used to create and destroy 648f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef "instances" of the driver, where each instance represents everything 649f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef needed to manage one actual PCMCIA card. 650f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 651f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 652f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_attach(struct pcmcia_device *); 653f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_detach(struct pcmcia_device *); 654f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 655f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/* 656f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef You'll also need to prototype all the functions that will actually 657f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef be used to talk to your device. See 'memory_cs' for a good example 658f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef of a fully self-sufficient driver; the other drivers rely more or 659f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef less on other parts of the kernel. 660f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef*/ 661f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 662d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pembertonstruct local_info_t { 663f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct pcmcia_device *link; 664f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int stop; 665f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef struct bus_operations *bus; 666d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton}; 667f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 668f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================== 669f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 670f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_attach() creates an "instance" of the driver, allocating 671f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local data structures for one device. The device is registered 672f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef with Card Services. 673f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 674f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef The dev_link structure is initialized, but we don't actually 675f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef configure the card at this point -- we wait until we receive a 676f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef card insertion event. 677f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 678f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef======================================================================*/ 679f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 680f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_attach(struct pcmcia_device *link) 681f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 682d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local; 683f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 68455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n"); 685f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 686f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Allocate space for private device-specific data */ 687d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); 688f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (!local) 689f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return -ENOMEM; 690f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->link = link; 691f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef link->priv = local; 692f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 693f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef cur_dev = link; 694f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 695f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_config(link); 696f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 697f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 698f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_attach */ 699f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 700f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_detach(struct pcmcia_device *link) 701f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 70255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_detach\n"); 703f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 704eb8804f654a512a1a4e2f189d1bbaa41565e46b5Javier Martinez Canillas ((struct local_info_t *)link->priv)->stop = 1; 705eb8804f654a512a1a4e2f189d1bbaa41565e46b5Javier Martinez Canillas das16cs_pcmcia_release(link); 706d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton /* This points to the parent struct local_info_t struct */ 707f25bd6bfdf9bccd8164c151b027f9c14ec07960bDan Carpenter kfree(link->priv); 708f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_detach */ 709f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 710f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 71155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, 71255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski void *priv_data) 71355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski{ 71400990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski if (p_dev->config_index == 0) 71555a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski return -EINVAL; 716f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 71700990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski return pcmcia_request_io(p_dev); 71855a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski} 71955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski 72055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskistatic void das16cs_pcmcia_config(struct pcmcia_device *link) 72155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski{ 72255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski int ret; 723f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 72455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); 725c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton 72600990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski /* Do we need to allocate an interrupt? */ 72700990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; 72800990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski 72955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL); 73055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (ret) { 73155a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_warn(&link->dev, "no configuration found\n"); 73255a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski goto failed; 733f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef } 734f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 735eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski if (!link->irq) 736eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski goto failed; 737eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski 7381ac71e5a35eebee60cdcf15b3980bd94498f037bDominik Brodowski ret = pcmcia_enable_device(link); 73955a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski if (ret) 74055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski goto failed; 741f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 742f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return; 743f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 74455a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowskifailed: 745f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef das16cs_pcmcia_release(link); 746f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_config */ 747f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 748f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void das16cs_pcmcia_release(struct pcmcia_device *link) 749f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 75055a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski dev_dbg(&link->dev, "das16cs_pcmcia_release\n"); 751f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_disable_device(link); 752f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_release */ 753f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 754f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_suspend(struct pcmcia_device *link) 755f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 756d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local = link->priv; 757f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 758f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef /* Mark the device as stopped, to block IO until later */ 759f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 1; 760f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 761f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 762f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_suspend */ 763f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 764f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int das16cs_pcmcia_resume(struct pcmcia_device *link) 765f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 766d2755d518620bfa3ab6d25aed4048a2d35868e3dBill Pemberton struct local_info_t *local = link->priv; 767f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 768f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef local->stop = 0; 769f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 770f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} /* das16cs_pcmcia_resume */ 771f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 772f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef/*====================================================================*/ 773f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 7742202a5a7490a9de282846ea8d4a56d0249e09033Joe Perchesstatic const struct pcmcia_device_id das16cs_id_table[] = { 775f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039), 776f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009), 777f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef PCMCIA_DEVICE_NULL 778f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 779f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 780f0922ec52c3f575aef2860b52dbb246274aec03fDavid SchleefMODULE_DEVICE_TABLE(pcmcia, das16cs_id_table); 7816c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_AUTHOR("David A. Schleef <ds@schleef.org>"); 7826c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_DESCRIPTION("Comedi driver for Computer Boards PC-CARD DAS16/16"); 7836c7f81967b8984e6fb6b1f04c63f32d90a15c479Alexander KurzMODULE_LICENSE("GPL"); 784f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 785f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstruct pcmcia_driver das16cs_driver = { 786f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .probe = das16cs_pcmcia_attach, 787f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .remove = das16cs_pcmcia_detach, 788f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .suspend = das16cs_pcmcia_suspend, 789f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .resume = das16cs_pcmcia_resume, 790f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .id_table = das16cs_id_table, 791f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef .owner = THIS_MODULE, 7922e9b981a7c63ee8278df6823f8389d69dad1a499Dominik Brodowski .name = "cb_das16_cs", 793f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef}; 794f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 795f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic int __init init_das16cs_pcmcia_cs(void) 796f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 797f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_register_driver(&das16cs_driver); 798f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return 0; 799f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 800f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 801f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefstatic void __exit exit_das16cs_pcmcia_cs(void) 802f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 80355a19b39acb8888af8e9cfe5b762d03c52fdb48cDominik Brodowski pr_debug("das16cs_pcmcia_cs: unloading\n"); 804f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef pcmcia_unregister_driver(&das16cs_driver); 805f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 806f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 807f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefint __init init_module(void) 808f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 809f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef int ret; 810f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 811f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef ret = init_das16cs_pcmcia_cs(); 812f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef if (ret < 0) 813f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return ret; 814f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 815f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef return comedi_driver_register(&driver_das16cs); 816f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 817f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 818f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleefvoid __exit cleanup_module(void) 819f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef{ 820f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef exit_das16cs_pcmcia_cs(); 821f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef comedi_driver_unregister(&driver_das16cs); 822f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef} 823f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef 824f0922ec52c3f575aef2860b52dbb246274aec03fDavid Schleef#else 8257114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_das16cs_init_module(void) 8267114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 8277114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas return comedi_driver_register(&driver_das16cs); 8287114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 8297114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 8307114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_das16cs_cleanup_module(void) 8317114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 8327114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas comedi_driver_unregister(&driver_das16cs); 8337114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 8347114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 8357114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_das16cs_init_module); 8367114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_das16cs_cleanup_module); 8372696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#endif /* CONFIG_PCMCIA */ 838