1501d675db67e43cff47fa8138374679122baefb4David Schleef/* 2501d675db67e43cff47fa8138374679122baefb4David Schleef * comedi/drivers/pcl725.c 3501d675db67e43cff47fa8138374679122baefb4David Schleef * Driver for PCL725 and clones 4501d675db67e43cff47fa8138374679122baefb4David Schleef * David A. Schleef 5501d675db67e43cff47fa8138374679122baefb4David Schleef */ 6501d675db67e43cff47fa8138374679122baefb4David Schleef/* 7501d675db67e43cff47fa8138374679122baefb4David SchleefDriver: pcl725 8501d675db67e43cff47fa8138374679122baefb4David SchleefDescription: Advantech PCL-725 (& compatibles) 9501d675db67e43cff47fa8138374679122baefb4David SchleefAuthor: ds 10501d675db67e43cff47fa8138374679122baefb4David SchleefStatus: unknown 11501d675db67e43cff47fa8138374679122baefb4David SchleefDevices: [Advantech] PCL-725 (pcl725) 12501d675db67e43cff47fa8138374679122baefb4David Schleef*/ 13501d675db67e43cff47fa8138374679122baefb4David Schleef 14501d675db67e43cff47fa8138374679122baefb4David Schleef#include "../comedidev.h" 15501d675db67e43cff47fa8138374679122baefb4David Schleef 16501d675db67e43cff47fa8138374679122baefb4David Schleef#include <linux/ioport.h> 17501d675db67e43cff47fa8138374679122baefb4David Schleef 18501d675db67e43cff47fa8138374679122baefb4David Schleef#define PCL725_SIZE 2 19501d675db67e43cff47fa8138374679122baefb4David Schleef 20501d675db67e43cff47fa8138374679122baefb4David Schleef#define PCL725_DO 0 21501d675db67e43cff47fa8138374679122baefb4David Schleef#define PCL725_DI 1 22501d675db67e43cff47fa8138374679122baefb4David Schleef 230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pcl725_attach(struct comedi_device *dev, 240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 25da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_detach(struct comedi_device *dev); 26139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_pcl725 = { 2768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "pcl725", 2868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 2968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = pcl725_attach, 3068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = pcl725_detach, 31501d675db67e43cff47fa8138374679122baefb4David Schleef}; 32501d675db67e43cff47fa8138374679122baefb4David Schleef 337114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_pcl725_init_module(void) 347114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 357114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas return comedi_driver_register(&driver_pcl725); 367114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 377114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 387114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_pcl725_cleanup_module(void) 397114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{ 407114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas comedi_driver_unregister(&driver_pcl725); 417114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas} 427114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas 437114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_pcl725_init_module); 447114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_pcl725_cleanup_module); 45501d675db67e43cff47fa8138374679122baefb4David Schleef 46da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, 470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 48501d675db67e43cff47fa8138374679122baefb4David Schleef{ 49501d675db67e43cff47fa8138374679122baefb4David Schleef if (insn->n != 2) 50501d675db67e43cff47fa8138374679122baefb4David Schleef return -EINVAL; 51501d675db67e43cff47fa8138374679122baefb4David Schleef 52501d675db67e43cff47fa8138374679122baefb4David Schleef if (data[0]) { 53501d675db67e43cff47fa8138374679122baefb4David Schleef s->state &= ~data[0]; 54501d675db67e43cff47fa8138374679122baefb4David Schleef s->state |= (data[0] & data[1]); 55501d675db67e43cff47fa8138374679122baefb4David Schleef outb(s->state, dev->iobase + PCL725_DO); 56501d675db67e43cff47fa8138374679122baefb4David Schleef } 57501d675db67e43cff47fa8138374679122baefb4David Schleef 58501d675db67e43cff47fa8138374679122baefb4David Schleef data[1] = s->state; 59501d675db67e43cff47fa8138374679122baefb4David Schleef 60501d675db67e43cff47fa8138374679122baefb4David Schleef return 2; 61501d675db67e43cff47fa8138374679122baefb4David Schleef} 62501d675db67e43cff47fa8138374679122baefb4David Schleef 63da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_di_insn(struct comedi_device *dev, struct comedi_subdevice *s, 640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 65501d675db67e43cff47fa8138374679122baefb4David Schleef{ 66501d675db67e43cff47fa8138374679122baefb4David Schleef if (insn->n != 2) 67501d675db67e43cff47fa8138374679122baefb4David Schleef return -EINVAL; 68501d675db67e43cff47fa8138374679122baefb4David Schleef 69501d675db67e43cff47fa8138374679122baefb4David Schleef data[1] = inb(dev->iobase + PCL725_DI); 70501d675db67e43cff47fa8138374679122baefb4David Schleef 71501d675db67e43cff47fa8138374679122baefb4David Schleef return 2; 72501d675db67e43cff47fa8138374679122baefb4David Schleef} 73501d675db67e43cff47fa8138374679122baefb4David Schleef 74da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) 75501d675db67e43cff47fa8138374679122baefb4David Schleef{ 7634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 77501d675db67e43cff47fa8138374679122baefb4David Schleef unsigned long iobase; 78501d675db67e43cff47fa8138374679122baefb4David Schleef 79501d675db67e43cff47fa8138374679122baefb4David Schleef iobase = it->options[0]; 80acb60e915a68c44757e12c45a8cede11339b6172Benjamin Adolphi printk(KERN_INFO "comedi%d: pcl725: 0x%04lx ", dev->minor, iobase); 81501d675db67e43cff47fa8138374679122baefb4David Schleef if (!request_region(iobase, PCL725_SIZE, "pcl725")) { 82501d675db67e43cff47fa8138374679122baefb4David Schleef printk("I/O port conflict\n"); 83501d675db67e43cff47fa8138374679122baefb4David Schleef return -EIO; 84501d675db67e43cff47fa8138374679122baefb4David Schleef } 85501d675db67e43cff47fa8138374679122baefb4David Schleef dev->board_name = "pcl725"; 86501d675db67e43cff47fa8138374679122baefb4David Schleef dev->iobase = iobase; 87501d675db67e43cff47fa8138374679122baefb4David Schleef dev->irq = 0; 88501d675db67e43cff47fa8138374679122baefb4David Schleef 89501d675db67e43cff47fa8138374679122baefb4David Schleef if (alloc_subdevices(dev, 2) < 0) 90501d675db67e43cff47fa8138374679122baefb4David Schleef return -ENOMEM; 91501d675db67e43cff47fa8138374679122baefb4David Schleef 92501d675db67e43cff47fa8138374679122baefb4David Schleef s = dev->subdevices + 0; 93501d675db67e43cff47fa8138374679122baefb4David Schleef /* do */ 94501d675db67e43cff47fa8138374679122baefb4David Schleef s->type = COMEDI_SUBD_DO; 95501d675db67e43cff47fa8138374679122baefb4David Schleef s->subdev_flags = SDF_WRITABLE; 96501d675db67e43cff47fa8138374679122baefb4David Schleef s->maxdata = 1; 97501d675db67e43cff47fa8138374679122baefb4David Schleef s->n_chan = 8; 98501d675db67e43cff47fa8138374679122baefb4David Schleef s->insn_bits = pcl725_do_insn; 99501d675db67e43cff47fa8138374679122baefb4David Schleef s->range_table = &range_digital; 100501d675db67e43cff47fa8138374679122baefb4David Schleef 101501d675db67e43cff47fa8138374679122baefb4David Schleef s = dev->subdevices + 1; 102501d675db67e43cff47fa8138374679122baefb4David Schleef /* di */ 103501d675db67e43cff47fa8138374679122baefb4David Schleef s->type = COMEDI_SUBD_DI; 104501d675db67e43cff47fa8138374679122baefb4David Schleef s->subdev_flags = SDF_READABLE; 105501d675db67e43cff47fa8138374679122baefb4David Schleef s->maxdata = 1; 106501d675db67e43cff47fa8138374679122baefb4David Schleef s->n_chan = 8; 107501d675db67e43cff47fa8138374679122baefb4David Schleef s->insn_bits = pcl725_di_insn; 108501d675db67e43cff47fa8138374679122baefb4David Schleef s->range_table = &range_digital; 109501d675db67e43cff47fa8138374679122baefb4David Schleef 110acb60e915a68c44757e12c45a8cede11339b6172Benjamin Adolphi printk(KERN_INFO "\n"); 111501d675db67e43cff47fa8138374679122baefb4David Schleef 112501d675db67e43cff47fa8138374679122baefb4David Schleef return 0; 113501d675db67e43cff47fa8138374679122baefb4David Schleef} 114501d675db67e43cff47fa8138374679122baefb4David Schleef 115da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_detach(struct comedi_device *dev) 116501d675db67e43cff47fa8138374679122baefb4David Schleef{ 117acb60e915a68c44757e12c45a8cede11339b6172Benjamin Adolphi printk(KERN_INFO "comedi%d: pcl725: remove\n", dev->minor); 118501d675db67e43cff47fa8138374679122baefb4David Schleef 119501d675db67e43cff47fa8138374679122baefb4David Schleef if (dev->iobase) 120501d675db67e43cff47fa8138374679122baefb4David Schleef release_region(dev->iobase, PCL725_SIZE); 121501d675db67e43cff47fa8138374679122baefb4David Schleef 122501d675db67e43cff47fa8138374679122baefb4David Schleef return 0; 123501d675db67e43cff47fa8138374679122baefb4David Schleef} 12490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 12590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 12690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 12790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 128