pcl725.c revision 790c55415aa31f4c732729f94d2c3a54f7d3bfc2
1/* 2 * comedi/drivers/pcl725.c 3 * Driver for PCL725 and clones 4 * David A. Schleef 5 */ 6/* 7Driver: pcl725 8Description: Advantech PCL-725 (& compatibles) 9Author: ds 10Status: unknown 11Devices: [Advantech] PCL-725 (pcl725) 12*/ 13 14#include "../comedidev.h" 15 16#include <linux/ioport.h> 17 18#define PCL725_SIZE 2 19 20#define PCL725_DO 0 21#define PCL725_DI 1 22 23static int pcl725_attach(comedi_device * dev, comedi_devconfig * it); 24static int pcl725_detach(comedi_device * dev); 25static comedi_driver driver_pcl725 = { 26 driver_name:"pcl725", 27 module:THIS_MODULE, 28 attach:pcl725_attach, 29 detach:pcl725_detach, 30}; 31 32COMEDI_INITCLEANUP(driver_pcl725); 33 34static int pcl725_do_insn(comedi_device * dev, comedi_subdevice * s, 35 comedi_insn * insn, unsigned int * data) 36{ 37 if (insn->n != 2) 38 return -EINVAL; 39 40 if (data[0]) { 41 s->state &= ~data[0]; 42 s->state |= (data[0] & data[1]); 43 outb(s->state, dev->iobase + PCL725_DO); 44 } 45 46 data[1] = s->state; 47 48 return 2; 49} 50 51static int pcl725_di_insn(comedi_device * dev, comedi_subdevice * s, 52 comedi_insn * insn, unsigned int * data) 53{ 54 if (insn->n != 2) 55 return -EINVAL; 56 57 data[1] = inb(dev->iobase + PCL725_DI); 58 59 return 2; 60} 61 62static int pcl725_attach(comedi_device * dev, comedi_devconfig * it) 63{ 64 comedi_subdevice *s; 65 unsigned long iobase; 66 67 iobase = it->options[0]; 68 printk("comedi%d: pcl725: 0x%04lx ", dev->minor, iobase); 69 if (!request_region(iobase, PCL725_SIZE, "pcl725")) { 70 printk("I/O port conflict\n"); 71 return -EIO; 72 } 73 dev->board_name = "pcl725"; 74 dev->iobase = iobase; 75 dev->irq = 0; 76 77 if (alloc_subdevices(dev, 2) < 0) 78 return -ENOMEM; 79 80 s = dev->subdevices + 0; 81 /* do */ 82 s->type = COMEDI_SUBD_DO; 83 s->subdev_flags = SDF_WRITABLE; 84 s->maxdata = 1; 85 s->n_chan = 8; 86 s->insn_bits = pcl725_do_insn; 87 s->range_table = &range_digital; 88 89 s = dev->subdevices + 1; 90 /* di */ 91 s->type = COMEDI_SUBD_DI; 92 s->subdev_flags = SDF_READABLE; 93 s->maxdata = 1; 94 s->n_chan = 8; 95 s->insn_bits = pcl725_di_insn; 96 s->range_table = &range_digital; 97 98 printk("\n"); 99 100 return 0; 101} 102 103static int pcl725_detach(comedi_device * dev) 104{ 105 printk("comedi%d: pcl725: remove\n", dev->minor); 106 107 if (dev->iobase) 108 release_region(dev->iobase, PCL725_SIZE); 109 110 return 0; 111} 112