📄 ii_pci20kc.c
字号:
/* * ii_pci20kc.c * driver for Intelligent Instruments PCI-20001C carrier board * and modules * * Copyright (C) 2000 Markus Kempf <kempf@matsci.uni-sb.de> * with suggestions from David Schleef * 16.06.2000 * * Linux device driver for COMEDI * Intelligent Instrumentation * PCI-20001 C-2A Carrier Board * PCI-20341 M-1A 16-Bit analog input module * - differential * - range (-5V - +5V) * - 16 bit * PCI-20006 M-2 16-Bit analog output module * - ranges (-10V - +10V) (0V - +10V) (-5V - +5V) * - 16 bit * * only ONE PCI-20341 module possible * only ONE PCI-20006 module possible * no extern trigger implemented * * NOT WORKING (but soon) only 4 on-board differential channels supported * NOT WORKING (but soon) only ONE di-port and ONE do-port supported instead of 4 digital ports * di-port == Port 0 * do-port == Port 1 * * The state of this driver is only a starting point for a complete * COMEDI-driver. The final driver should support all features of the * carrier board and modules. * * The test configuration: * * kernel 2.2.14 with RTAI v1.2 and patch-2.2.14rthal2 * COMEDI 0.7.45 * COMEDILIB 0.7.9 * *//*Driver: ii_pci20kc.oDescription: Intelligent Instruments PCI-20001C carrier boardAuthor: Markus Kempf <kempf@matsci.uni-sb.de>Devices: [Intelligent Instrumentation] PCI-20001C (ii_pci20kc)Status: worksSupports the PCI-20001 C-2a Carrier board, and could probably supportthe other carrier boards with small modifications. Modules supportedare: PCI-20006 M-2 16-bit analog output module PCI-20341 M-1A 16-bit analog input moduleOptions: 0 Board base address 1 IRQ 2 first option for module 1 3 second option for module 1 4 first option for module 2 5 second option for module 2 6 first option for module 3 7 second option for module 3options for PCI-20006M: first: Analog output channel 0 range configuration 0 bipolar 10 (-10V -- +10V) 1 unipolar 10 (0V -- +10V) 2 bipolar 5 (-5V -- 5V) second: Analog output channel 1 range configurationoptions for PCI-20341M: first: Analog input gain configuration 0 1 1 10 2 100 3 200*//* XXX needs to use ioremap() for compatibility with 2.4 kernels. Should also * check_mem_region() etc. - fmhess */#include <linux/comedidev.h>#define PCI20000_ID 0x1d#define PCI20341_ID 0x77#define PCI20006_ID 0xe3#define PCI20xxx_EMPTY_ID 0xff#define PCI20000_OFFSET 0x100#define PCI20000_MODULES 3#define PCI20000_DIO_0 0x80#define PCI20000_DIO_1 0x81#define PCI20000_DIO_2 0xc0#define PCI20000_DIO_3 0xc1#define PCI20000_DIO_CONTROL_01 0x83 /* port 0, 1 control */#define PCI20000_DIO_CONTROL_23 0xc3 /* port 2, 3 control */#define PCI20000_DIO_BUFFER 0x82 /* buffer direction and enable */#define PCI20000_DIO_EOC 0xef /* even port, control output */#define PCI20000_DIO_OOC 0xfd /* odd port, control output */#define PCI20000_DIO_EIC 0x90 /* even port, control input */#define PCI20000_DIO_OIC 0x82 /* odd port, control input */#define DIO_CAND 0x12 /* and bit 1, bit 4 of control */#define DIO_BE 0x01 /* buffer: port enable */#define DIO_BO 0x04 /* buffer: output */#define DIO_BI 0x05 /* buffer: input */#define DIO_PS_0 0x00 /* buffer: port shift 0 */#define DIO_PS_1 0x01 /* buffer: port shift 1 */#define DIO_PS_2 0x04 /* buffer: port shift 2 */#define DIO_PS_3 0x05 /* buffer: port shift 3 */#define PCI20006_LCHAN0 0x0d#define PCI20006_STROBE0 0x0b#define PCI20006_LCHAN1 0x15#define PCI20006_STROBE1 0x13#define PCI20341_INIT 0x04 #define PCI20341_REPMODE 0x00 /* single shot mode */#define PCI20341_PACER 0x00 /* Hardware Pacer disabled */#define PCI20341_CHAN_NR 0x04 /* number of input channels */#define PCI20341_CONFIG_REG 0x10#define PCI20341_MOD_STATUS 0x01#define PCI20341_OPT_REG 0x11#define PCI20341_SET_TIME_REG 0x15#define PCI20341_LCHAN_ADDR_REG 0x13#define PCI20341_CHAN_LIST 0x80#define PCI20341_CC_RESET 0x1b#define PCI20341_CHAN_RESET 0x19#define PCI20341_SOFT_PACER 0x04#define PCI20341_STATUS_REG 0x12#define PCI20341_LDATA 0x02#define PCI20341_DAISY_CHAIN 0x20 /* On-board inputs only */#define PCI20341_MUX 0x04 /* Enable on-board MUX */#define PCI20341_SCANLIST 0x80 /* Channel/Gain Scan List */typedef union { int iobase; struct { int iobase; comedi_lrange *ao_range_list[2]; /* range of channels of ao module */ lsampl_t last_data[2]; }pci20006; struct { int iobase; int timebase; int settling_time; int ai_gain; }pci20341;} pci20xxx_subdev_private;typedef struct { pci20xxx_subdev_private subdev_private[PCI20000_MODULES];} pci20xxx_private;#define devpriv ((pci20xxx_private *)dev->private)#define CHAN (CR_CHAN(it->chanlist[0]))static int pci20xxx_attach(comedi_device * dev, comedi_devconfig * it);static int pci20xxx_detach(comedi_device * dev);static comedi_driver driver_pci20xxx = { driver_name: "ii_pci20kc", module: THIS_MODULE, attach: pci20xxx_attach, detach: pci20xxx_detach,};static int pci20006_init(comedi_device * dev,comedi_subdevice *s, int opt0,int opt1);static int pci20341_init(comedi_device * dev,comedi_subdevice *s, int opt0,int opt1);static int pci20xxx_dio_init(comedi_device * dev,comedi_subdevice *s);/* options[0] Board base address options[1] IRQ options[2] first option for module 1 options[3] second option for module 1 options[4] first option for module 2 options[5] second option for module 2 options[6] first option for module 3 options[7] second option for module 3 options for PCI-20341M: first Analog input gain configuration 0 == 1 1 == 10 2 == 100 3 == 200 options for PCI-20006M: first Analog output channel 0 range configuration 0 == bipolar 10 (-10V -- +10V) 1 == unipolar 10V (0V -- +10V) 2 == bipolar 5V (-5V -- +5V) second Analog output channel 1 range configuration 0 == bipolar 10 (-10V -- +10V) 1 == unipolar 10V (0V -- +10V) 2 == bipolar 5V (-5V -- +5V)*/static int pci20xxx_attach(comedi_device * dev, comedi_devconfig * it){ unsigned char i; int ret; int id; comedi_subdevice *s; pci20xxx_subdev_private *sdp; if ((ret = alloc_subdevices(dev, 1 + PCI20000_MODULES)) < 0) return ret; if ((ret = alloc_private(dev, sizeof(pci20xxx_private))) < 0) return ret; dev->iobase = it->options[0]; dev->board_name = "pci20kc"; /* Check PCI-20001 C-2A Carrier Board ID */ if ((readb(dev->iobase) & PCI20000_ID) != PCI20000_ID) { printk("comedi%d: ii_pci20kc", dev->minor); printk(" PCI-20001 C-2A Carrier Board at base=0x%05x not found !\n", dev->iobase); return -EINVAL; } printk("comedi%d:\n", dev->minor); printk("ii_pci20kc: PCI-20001 C-2A at base=0x%05x\n", dev->iobase); for (i = 0; i < PCI20000_MODULES; i++) { s = dev->subdevices + i; id = readb(dev->iobase + (i+1) * PCI20000_OFFSET); s->private = devpriv->subdev_private +i; sdp = s->private; switch(id){ case PCI20006_ID: sdp->pci20006.iobase = dev->iobase + (i+1) * PCI20000_OFFSET; pci20006_init(dev,s,it->options[2*i+2],it->options[2*i+3]); printk("comedi%d: ii_pci20kc", dev->minor); printk(" PCI-20006 module in slot %d \n", i+1); break; case PCI20341_ID: sdp->pci20341.iobase = dev->iobase + (i+1) * PCI20000_OFFSET; pci20341_init(dev,s,it->options[2*i+2],it->options[2*i+3]); printk("comedi%d: ii_pci20kc", dev->minor); printk(" PCI-20341 module in slot %d \n", i+1); break; default: printk("ii_pci20kc: unknown module code 0x%02x in slot %d: module disabled\n", id,i); /* fall through */ case PCI20xxx_EMPTY_ID: s->type = COMEDI_SUBD_UNUSED; break; } } /* initialize pci20xxx_private */ pci20xxx_dio_init(dev,dev->subdevices + PCI20000_MODULES); return 1;}static int pci20xxx_detach(comedi_device * dev){ printk("comedi%d: pci20xxx: remove\n", dev->minor); return 0;}/* pci20006m */static int pci20006_insn_read(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data);static int pci20006_insn_write(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data);static comedi_lrange *pci20006_range_list[] = { &range_bipolar10, &range_unipolar10, &range_bipolar5,};static int pci20006_init(comedi_device * dev,comedi_subdevice *s, int opt0,int opt1){ pci20xxx_subdev_private *sdp = s->private; if(opt0<0 || opt0>2) opt0=0; if(opt1<0 || opt1>2) opt1=0; sdp->pci20006.ao_range_list[0] = pci20006_range_list[opt0]; sdp->pci20006.ao_range_list[1] = pci20006_range_list[opt1]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->len_chanlist = 2; s->insn_read = pci20006_insn_read; s->insn_write = pci20006_insn_write; s->maxdata = 0xffff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -