📄 poc.c
字号:
/* comedi/drivers/poc.c Mini-drivers for POC (Piece of Crap) boards Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net> Copyright (C) 2001 David A. Schleef <ds@schleef.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*//*Driver: poc.oDescription: Generic driver for very simple devicesDevice names: dac02Author: dsDevices: [Keithley Metrabyte] DAC-02 (dac02), [Advantech] PCL-733 (pcl733), PCL-734 (pcl734)Updated: Sat, 16 Mar 2002 17:34:48 -0800Status: unknownThis driver is indended to support very simple ISA-based devices,including: dac02 - Keithley DAC-02 analog output board pcl733 - Advantech PCL-733 pcl734 - Advantech PCL-734Configuration options: [0] - I/O port base*/#include <linux/comedidev.h>#include <linux/ioport.h>static int poc_attach(comedi_device *dev,comedi_devconfig *it);static int poc_detach(comedi_device *dev);static int readback_insn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static int dac02_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);static int pcl733_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data);static int pcl734_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data);struct boarddef_struct{ char *name; int iosize; int (*setup)(comedi_device *); int type; int n_chan; int n_bits; int (*winsn)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *); int (*rinsn)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *); int (*insnbits)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *); comedi_lrange* range;};static struct boarddef_struct boards[]={ { name: "dac02", iosize: 8, //setup: dac02_setup, type: COMEDI_SUBD_AO, n_chan: 2, n_bits: 12, winsn: dac02_ao_winsn, rinsn: readback_insn, range: &range_unknown, }, { name: "pcl733", iosize: 4, type: COMEDI_SUBD_DI, n_chan: 32, n_bits: 1, insnbits: pcl733_insn_bits, range: &range_digital, }, { name: "pcl734", iosize: 4, type: COMEDI_SUBD_DO, n_chan: 32, n_bits: 1, insnbits: pcl734_insn_bits, range: &range_digital, },};#define n_boards (sizeof(boards)/sizeof(boards[0]))#define this_board ((struct boarddef_struct *)dev->board_ptr)static comedi_driver driver_poc={ driver_name: "poc", module: THIS_MODULE, attach: poc_attach, detach: poc_detach, board_name: boards, num_names: n_boards, offset: sizeof(boards[0]),};static int poc_attach(comedi_device *dev, comedi_devconfig *it){ comedi_subdevice *s; int iosize, iobase; iobase = it->options[0]; printk("comedi%d: poc: using %s iobase 0x%x\n", dev->minor, this_board->name, iobase); dev->board_name = this_board->name; if(iobase == 0) { printk("io base address required\n"); return -EINVAL; } iosize = this_board->iosize; /* check if io addresses are available */ if(check_region(iobase, iosize) < 0) { printk("I/O port conflict: failed to allocate ports 0x%x to 0x%x\n", iobase, iobase + iosize - 1); return -EIO; } request_region(iobase, iosize, "dac02"); dev->iobase = iobase; if(alloc_subdevices(dev, 1) < 0) return -ENOMEM; if(alloc_private(dev,sizeof(lsampl_t)*this_board->n_chan) < 0) return -ENOMEM; /* analog output subdevice */ s=dev->subdevices + 0; s->type = this_board->type; s->n_chan = this_board->n_chan; s->maxdata = (1<<this_board->n_bits)-1; s->range_table = this_board->range; s->insn_write = this_board->winsn; s->insn_read = this_board->rinsn; s->insn_bits = this_board->insnbits; if(s->type==COMEDI_SUBD_AO || s->type==COMEDI_SUBD_DO){ s->subdev_flags = SDF_WRITABLE; } return 0;}static int poc_detach(comedi_device *dev){ /* only free stuff if it has been allocated by _attach */ if(dev->iobase) release_region(dev->iobase, this_board->iosize); printk("comedi%d: dac02: remove\n", dev->minor); return 0;}static int readback_insn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){ int chan; chan = CR_CHAN(insn->chanspec); data[0]=((lsampl_t *)dev->private)[chan]; return 1;}/* DAC-02 registers */#define DAC02_LSB(a) (2 * a)#define DAC02_MSB(a) (2 * a + 1)static int dac02_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){ int temp; int chan; int output; chan = CR_CHAN(insn->chanspec); ((lsampl_t *)dev->private)[chan] = data[0]; output = data[0];#if wrong // convert to complementary binary if range is bipolar if((CR_RANGE(insn->chanspec) & 0x2) == 0) output = ~output;#endif temp = (output << 4) & 0xf0; outb(temp, dev->iobase + DAC02_LSB(chan)); temp = (output >> 4) & 0xff; outb(temp, dev->iobase + DAC02_MSB(chan)); return 1;}static int pcl733_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data){ if(insn->n!=2)return -EINVAL; data[1] = inb(dev->iobase + 0); data[1] |= (inb(dev->iobase + 1) << 8); data[1] |= (inb(dev->iobase + 2) << 16); data[1] |= (inb(dev->iobase + 3) << 24); return 2;}static int pcl734_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data){ if(insn->n!=2)return -EINVAL; if(data[0]){ s->state &= ~data[0]; s->state |= (data[0]&data[1]); if((data[0]>>0)&0xff) outb((s->state>>0)&0xff, dev->iobase + 0); if((data[0]>>8)&0xff) outb((s->state>>8)&0xff, dev->iobase + 1); if((data[0]>>16)&0xff) outb((s->state>>16)&0xff, dev->iobase + 2); if((data[0]>>24)&0xff) outb((s->state>>24)&0xff, dev->iobase + 3); } data[1] = s->state; return 2;}COMEDI_INITCLEANUP(driver_poc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -