From: Frank Mori Hess Date: Mon, 16 Oct 2006 21:01:20 +0000 (+0000) Subject: Added support for 6509, and other boards in family. Will test X-Git-Tag: r0_7_74~197 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=32547e529dca8a4e93007673dde66f5cd9486c01;p=comedi.git Added support for 6509, and other boards in family. Will test tommorrow. --- diff --git a/comedi/drivers/ni_65xx.c b/comedi/drivers/ni_65xx.c index 7c0d3e88..58a5d7ac 100644 --- a/comedi/drivers/ni_65xx.c +++ b/comedi/drivers/ni_65xx.c @@ -2,6 +2,9 @@ comedi/drivers/ni_6514.c driver for National Instruments PCI-6514 + Copyright (C) 2006 Jon Grierson + Copyright (C) 2006 Frank Mori Hess + COMEDI - Linux Control and Measurement Device Interface Copyright (C) 1999,2002,2003 David A. Schleef @@ -23,13 +26,14 @@ /* Driver: ni_65xx.o Description: National Instruments 65xx static dio boards -Author: Jon Grierson +Author: Jon Grierson , Frank Mori Hess Status: testing Devices: [National Instruments] PCI-6514 (ni_65xx), PXI-6514, PXI-6509 Updated: Mon, 17 Jul 2006 16:40:10 +0100 Based on the PCI-6527 driver by ds. -Should be easily modified for 6509, 651x, 6520, 6521 and 6528 +Should be easily modified for 6509, 651x, 6520, 6521 and 6528 if you +send in the pci device id of your board. */ @@ -40,9 +44,9 @@ Should be easily modified for 6509, 651x, 6520, 6521 and 6528 */ +#define _GNU_SOURCE #define DEBUG 1 #define DEBUG_FLAGS - #include #include "mite.h" @@ -51,8 +55,30 @@ Should be easily modified for 6509, 651x, 6520, 6521 and 6528 #define NI6514_DIO_SIZE 4096 #define NI6514_MITE_SIZE 4096 +#define NI_65XX_MAX_NUM_PORTS 12 +static const unsigned ni_65xx_channels_per_port = 8; +static const unsigned ni_65xx_port_offset = 0x10; -#define Port_Register(x) (0x40+(x)) +static inline unsigned Port_Data(unsigned port) +{ + return 0x40 + port * ni_65xx_port_offset; +} +static inline unsigned Port_Select(unsigned port) +{ + return 0x41 + port * ni_65xx_port_offset; +} +static inline unsigned Rising_Edge_Detection_Enable(unsigned port) +{ + return 0x42 + port * ni_65xx_port_offset; +} +static inline unsigned Falling_Edge_Detection_Enable(unsigned port) +{ + return 0x43 + port * ni_65xx_port_offset; +} +static inline unsigned Filter_Enable(unsigned port) +{ + return 0x44 + port * ni_65xx_port_offset; +} #define ID_Register 0x00 #define Clear_Register 0x01 @@ -60,7 +86,6 @@ Should be easily modified for 6509, 651x, 6520, 6521 and 6528 #define ClrOverflow 0x04 #define Filter_Interval 0x08 -#define Filter_Enable(x) (0x44+(x)) #define Change_Status 0x02 #define MasterInterruptStatus 0x04 @@ -74,146 +99,310 @@ Should be easily modified for 6509, 651x, 6520, 6521 and 6528 #define OverflowIntEnable 0x02 #define EdgeIntEnable 0x01 -#define Rising_Edge_Detection_Enable(x) (0x42+(x)) -#define Falling_Edge_Detection_Enable(x) (0x43+(x)) - - - -static int ni6514_attach(comedi_device *dev,comedi_devconfig *it); -static int ni6514_detach(comedi_device *dev); -static comedi_driver driver_ni6514={ +static int ni_65xx_attach(comedi_device *dev,comedi_devconfig *it); +static int ni_65xx_detach(comedi_device *dev); +static comedi_driver driver_ni_65xx={ driver_name: "ni_65xx", module: THIS_MODULE, - attach: ni6514_attach, - detach: ni6514_detach, + attach: ni_65xx_attach, + detach: ni_65xx_detach, }; -COMEDI_INITCLEANUP(driver_ni6514); +COMEDI_INITCLEANUP(driver_ni_65xx); typedef struct{ int dev_id; - char *name; -}ni6514_board; -static ni6514_board ni6514_boards[] = { + const char *name; + unsigned num_dio_ports; + unsigned num_di_ports; + unsigned num_do_ports; + unsigned invert_outputs : 1; +}ni_65xx_board; +static ni_65xx_board ni_65xx_boards[] = { + { + dev_id: 0x0, //XXX + name: "pci-6509", + num_dio_ports: 12 + }, { dev_id: 0x1710, name: "pxi-6509", + num_dio_ports: 12 + }, + { + dev_id: 0x0, //XXX + name: "pci-6510", + num_di_ports: 4 + }, + { + dev_id: 0x0, //XXX + name: "pci-6511", + num_di_ports: 8 + }, + { + dev_id: 0x0, //XXX + name: "pxi-6511", + num_di_ports: 8 + }, + { + dev_id: 0x0, //XXX + name: "pci-6512", + num_do_ports: 8 + }, + { + dev_id: 0x0, //XXX + name: "pxi-6512", + num_do_ports: 8 + }, + { + dev_id: 0x0, //XXX + name: "pci-6513", + num_do_ports: 8 + }, + { + dev_id: 0x0, //XXX + name: "pxi-6513", + num_do_ports: 8 }, { dev_id: 0x7088, name: "pci-6514", + num_di_ports: 4, + num_do_ports: 4, + invert_outputs: 1 }, { dev_id: 0x70CD, name: "pxi-6514", + num_di_ports: 4, + num_do_ports: 4, + invert_outputs: 1 + }, + { + dev_id: 0x0, //XXX + name: "pci-6515", + num_di_ports: 4, + num_do_ports: 4, + }, + { + dev_id: 0x0, //XXX + name: "pxi-6515", + num_di_ports: 4, + num_do_ports: 4, + }, + { + dev_id: 0x0, //XXX + name: "pci-6516", + num_do_ports: 4, + }, + { + dev_id: 0x0, //XXX + name: "pci-6517", + num_do_ports: 4, + }, + { + dev_id: 0x0, //XXX + name: "pci-6518", + num_di_ports: 2, + num_do_ports: 2, + }, + { + dev_id: 0x0, //XXX + name: "pci-6519", + num_di_ports: 2, + num_do_ports: 2, + }, + { + dev_id: 0x0, //XXX + name: "pci-6520", + num_di_ports: 1, + num_do_ports: 1, + }, + { + dev_id: 0x0, //XXX + name: "pci-6521", + num_di_ports: 1, + num_do_ports: 1, + }, + { + dev_id: 0x0, //XXX + name: "pxi-6521", + num_di_ports: 1, + num_do_ports: 1, + }, + { + dev_id: 0x0, //XXX + name: "pci-6528", + num_di_ports: 3, + num_do_ports: 3, + }, + { + dev_id: 0x0, //XXX + name: "pxi-6528", + num_di_ports: 3, + num_do_ports: 3, }, }; -#define n_ni6514_boards (sizeof(ni6514_boards)/sizeof(ni6514_boards[0])) -#define this_board ((ni6514_board *)dev->board_ptr) +#define n_ni_65xx_boards (sizeof(ni_65xx_boards)/sizeof(ni_65xx_boards[0])) +static inline const ni_65xx_board* board(comedi_device *dev) +{ + return dev->board_ptr; +} +static inline unsigned ni_65xx_port_by_channel(unsigned channel) +{ + return channel / ni_65xx_channels_per_port; +} +static inline unsigned ni_65xx_total_num_ports(const ni_65xx_board *board) +{ + return board->num_dio_ports + board->num_di_ports + board->num_do_ports; +} -static struct pci_device_id ni6514_pci_table[] __devinitdata = { +static struct pci_device_id ni_65xx_pci_table[] __devinitdata = { { PCI_VENDOR_ID_NATINST, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NATINST, 0x7088, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NATINST, 0x70CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0 } }; -MODULE_DEVICE_TABLE(pci, ni6514_pci_table); +MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table); typedef struct{ struct mite_struct *mite; unsigned int filter_interval; - unsigned int filter_enable; -}ni6514_private; -#define devpriv ((ni6514_private *)dev->private) - -static int ni6514_find_device(comedi_device *dev,int bus,int slot); - - -static int ni6514_di_insn_config(comedi_device *dev,comedi_subdevice *s, - comedi_insn *insn,lsampl_t *data) + unsigned short filter_enable[NI_65XX_MAX_NUM_PORTS]; + unsigned short output_bits[NI_65XX_MAX_NUM_PORTS]; + unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS]; +}ni_65xx_private; +static inline ni_65xx_private* private(comedi_device *dev) { - int chan = CR_CHAN(insn->chanspec); - unsigned int interval; - - if(insn->n!=2)return -EINVAL; + return dev->private; +} - if(data[0] != INSN_CONFIG_FILTER)return -EINVAL; +typedef struct +{ + unsigned base_port; +}ni_65xx_subdevice_private; +static inline ni_65xx_subdevice_private* sprivate(comedi_subdevice *subdev) +{ + return subdev->private; +} +static ni_65xx_subdevice_private* ni_65xx_alloc_subdevice_private(void) +{ + ni_65xx_subdevice_private *subdev_private = kmalloc(sizeof(ni_65xx_subdevice_private), GFP_KERNEL); + if(subdev_private == NULL) return NULL; + memset(subdev_private, 0, sizeof(ni_65xx_subdevice_private)); + return subdev_private; +} - if(data[1]){ - interval = (data[1]+100)/200; - data[1] = interval*200; +static int ni_65xx_find_device(comedi_device *dev,int bus,int slot); - if(interval!=devpriv->filter_interval){ - writeb(interval&0x000fffff, devpriv->mite->daq_io_addr + Filter_Interval); /* FIXME 32 bit reg - mask possibly wrong??? */ +static int ni_65xx_config_filter(comedi_device *dev, comedi_subdevice *s, + comedi_insn *insn, lsampl_t *data) +{ + const unsigned chan = CR_CHAN(insn->chanspec); + const unsigned port = sprivate(s)->base_port + ni_65xx_port_by_channel(chan); - devpriv->filter_interval = interval; + if(insn->n != 2)return -EINVAL; + if(data[0] != INSN_CONFIG_FILTER) return -EINVAL; + if(data[1]) + { + static const unsigned filter_resolution_ns = 200; + static const unsigned max_filter_interval = 0xfffff; + unsigned interval = (data[1] + (filter_resolution_ns / 2)) / filter_resolution_ns; + if(interval > max_filter_interval) interval = max_filter_interval; + data[1] = interval * filter_resolution_ns; + + if(interval != private(dev)->filter_interval) + { + writeb(interval, private(dev)->mite->daq_io_addr + Filter_Interval); + private(dev)->filter_interval = interval; } - devpriv->filter_enable |= 1<filter_enable[port] |= 1 << (chan % ni_65xx_channels_per_port); }else{ - devpriv->filter_enable &= ~(1<filter_enable[port] &= ~(1 << (chan % ni_65xx_channels_per_port)); } - writeb(devpriv->filter_enable, devpriv->mite->daq_io_addr + Filter_Enable(0)); - writeb(devpriv->filter_enable>>8, devpriv->mite->daq_io_addr + Filter_Enable(0x10)); - writeb(devpriv->filter_enable>>16, devpriv->mite->daq_io_addr + Filter_Enable(0x20)); - writeb(devpriv->filter_enable>>24, devpriv->mite->daq_io_addr + Filter_Enable(0x30)); + writeb(private(dev)->filter_enable[port], private(dev)->mite->daq_io_addr + Filter_Enable(port)); return 2; } -static int ni6514_di_insn_bits(comedi_device *dev,comedi_subdevice *s, +static int ni_65xx_dio_insn_config(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) { - if(insn->n!=2)return -EINVAL; - - data[1] = readb(devpriv->mite->daq_io_addr+Port_Register(0)); - data[1] |= readb(devpriv->mite->daq_io_addr+Port_Register(0x10))<<8; - data[1] |= readb(devpriv->mite->daq_io_addr+Port_Register(0x20))<<16; - data[1] |= readb(devpriv->mite->daq_io_addr+Port_Register(0x30))<<24; - - return 2; + if(insn->n < 1) return -EINVAL; + unsigned port = sprivate(s)->base_port + ni_65xx_port_by_channel(CR_CHAN(insn->chanspec)); + switch(data[0]) + { + case INSN_CONFIG_FILTER: + return ni_65xx_config_filter(dev, s, insn, data); + break; + case INSN_CONFIG_DIO_OUTPUT: + if(s->type != COMEDI_SUBD_DIO) return -EINVAL; + private(dev)->dio_direction[port] = COMEDI_OUTPUT; + writeb(1, private(dev)->mite->daq_io_addr + Port_Select(port)); + return 1; + break; + case INSN_CONFIG_DIO_INPUT: + if(s->type != COMEDI_SUBD_DIO) return -EINVAL; + private(dev)->dio_direction[port] = COMEDI_INPUT; + writeb(0, private(dev)->mite->daq_io_addr + Port_Select(port)); + return 1; + break; + case INSN_CONFIG_DIO_QUERY: + if(s->type != COMEDI_SUBD_DIO) return -EINVAL; + data[1] = private(dev)->dio_direction[port]; + return insn->n; + break; + default: + break; + } + return -EINVAL; } -static int ni6514_do_insn_bits(comedi_device *dev,comedi_subdevice *s, +static int ni_65xx_dio_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]); - - /* The open relay state on the board cooresponds to 1, - * but in Comedi, it is represented by 0. */ - if(data[0]&0x000000ff){ - writeb((s->state^0xff),devpriv->mite->daq_io_addr+Port_Register(0x40)); - } - if(data[0]&0x0000ff00){ - writeb((s->state>>8)^0xff,devpriv->mite->daq_io_addr+Port_Register(0x50)); - } - if(data[0]&0x00ff0000){ - writeb((s->state>>16)^0xff,devpriv->mite->daq_io_addr+Port_Register(0x60)); - } - if(data[0]&0xff000000){ - writeb((s->state>>24)^0xff,devpriv->mite->daq_io_addr+Port_Register(0x70)); + const unsigned elements_per_bitfield = 2; + if(insn->n % elements_per_bitfield) return -EINVAL; + const unsigned num_bitfields = insn->n / elements_per_bitfield; + unsigned i; + for(i = 0; i < num_bitfields; ++i) + { + const unsigned ports_per_bitfield = 4; + const unsigned array_offset = i * elements_per_bitfield; + data[array_offset + 1] = 0; + unsigned j; + for(j = 0; j < ports_per_bitfield; ++j) + { + const unsigned port = sprivate(s)->base_port + i * ports_per_bitfield + j; + if(port >= ni_65xx_total_num_ports(board(dev))) break; + const unsigned port_mask = (data[array_offset] >> (j * 8)) & 0xff; + if(port_mask) + { + private(dev)->output_bits[port] &= ~port_mask; + private(dev)->output_bits[port] |= (data[array_offset + 1] >> (j * 8)) & port_mask; + unsigned bits = private(dev)->output_bits[port]; + if(board(dev)->invert_outputs) bits = ~bits; + writeb(bits, private(dev)->mite->daq_io_addr + Port_Data(port)); + } + data[array_offset + 1] |= readb(private(dev)->mite->daq_io_addr + Port_Data(port)); } } - data[1] = s->state; - - return 2; + return insn->n; } -static irqreturn_t ni6514_interrupt(int irq, void *d, struct pt_regs *regs) +static irqreturn_t ni_65xx_interrupt(int irq, void *d, struct pt_regs *regs) { comedi_device *dev = d; comedi_subdevice *s = dev->subdevices + 2; unsigned int status; - status = readb(devpriv->mite->daq_io_addr + Change_Status); + status = readb(private(dev)->mite->daq_io_addr + Change_Status); if((status & MasterInterruptStatus) == 0) return IRQ_NONE; if((status & EdgeStatus) == 0) return IRQ_NONE; - writeb(ClrEdge | ClrOverflow, devpriv->mite->daq_io_addr + Clear_Register); + writeb(ClrEdge | ClrOverflow, private(dev)->mite->daq_io_addr + Clear_Register); comedi_buf_put(s->async, 0); s->async->events |= COMEDI_CB_EOS; @@ -221,7 +410,7 @@ static irqreturn_t ni6514_interrupt(int irq, void *d, struct pt_regs *regs) return IRQ_HANDLED; } -static int ni6514_intr_cmdtest(comedi_device *dev,comedi_subdevice *s, +static int ni_65xx_intr_cmdtest(comedi_device *dev,comedi_subdevice *s, comedi_cmd *cmd) { int err=0; @@ -288,26 +477,26 @@ static int ni6514_intr_cmdtest(comedi_device *dev,comedi_subdevice *s, return 0; } -static int ni6514_intr_cmd(comedi_device *dev,comedi_subdevice *s) +static int ni_65xx_intr_cmd(comedi_device *dev,comedi_subdevice *s) { //comedi_cmd *cmd = &s->async->cmd; - writeb(ClrEdge|ClrOverflow, devpriv->mite->daq_io_addr + Clear_Register); + writeb(ClrEdge|ClrOverflow, private(dev)->mite->daq_io_addr + Clear_Register); writeb(FallingEdgeIntEnable|RisingEdgeIntEnable| MasterInterruptEnable|EdgeIntEnable, - devpriv->mite->daq_io_addr + Master_Interrupt_Control); + private(dev)->mite->daq_io_addr + Master_Interrupt_Control); return 0; } -static int ni6514_intr_cancel(comedi_device *dev,comedi_subdevice *s) +static int ni_65xx_intr_cancel(comedi_device *dev,comedi_subdevice *s) { - writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); + writeb(0x00, private(dev)->mite->daq_io_addr + Master_Interrupt_Control); return 0; } -static int ni6514_intr_insn_bits(comedi_device *dev, comedi_subdevice *s, +static int ni_65xx_intr_insn_bits(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data) { if(insn->n < 1)return -EINVAL; @@ -316,103 +505,135 @@ static int ni6514_intr_insn_bits(comedi_device *dev, comedi_subdevice *s, return 2; } -static int ni6514_intr_insn_config(comedi_device *dev, comedi_subdevice *s, +static int ni_65xx_intr_insn_config(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data) { if(insn->n < 1)return -EINVAL; if(data[0] != INSN_CONFIG_CHANGE_NOTIFY)return -EINVAL; - writeb(data[1], devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0)); - writeb(data[1]>>8, devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x10)); - writeb(data[1]>>16, devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x20)); - writeb(data[1]>>24, devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x30)); + writeb(data[1], private(dev)->mite->daq_io_addr + Rising_Edge_Detection_Enable(0)); + writeb(data[1]>>8, private(dev)->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x10)); + writeb(data[1]>>16, private(dev)->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x20)); + writeb(data[1]>>24, private(dev)->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x30)); - writeb(data[2], devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0)); - writeb(data[2]>>8, devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x10)); - writeb(data[2]>>16, devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x20)); - writeb(data[2]>>24, devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x30)); + writeb(data[2], private(dev)->mite->daq_io_addr + Falling_Edge_Detection_Enable(0)); + writeb(data[2]>>8, private(dev)->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x10)); + writeb(data[2]>>16, private(dev)->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x20)); + writeb(data[2]>>24, private(dev)->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x30)); return 2; } -static int ni6514_attach(comedi_device *dev,comedi_devconfig *it) +static int ni_65xx_attach(comedi_device *dev,comedi_devconfig *it) { comedi_subdevice *s; int ret; - printk("comedi%d: ni6514:",dev->minor); + printk("comedi%d: ni_65xx:",dev->minor); - if((ret=alloc_private(dev,sizeof(ni6514_private)))<0) + if((ret=alloc_private(dev,sizeof(ni_65xx_private)))<0) return ret; - ret=ni6514_find_device(dev,it->options[0],it->options[1]); + ret=ni_65xx_find_device(dev,it->options[0],it->options[1]); if(ret<0)return ret; - ret = mite_setup(devpriv->mite); + ret = mite_setup(private(dev)->mite); if(ret < 0) { printk("error setting up mite\n"); return ret; } - dev->board_name=this_board->name; - dev->irq=mite_irq(devpriv->mite); + dev->board_name = board(dev)->name; + dev->irq = mite_irq(private(dev)->mite); printk(" %s",dev->board_name); - printk(" ID=0x%02x", readb(devpriv->mite->daq_io_addr + ID_Register)); + printk(" ID=0x%02x", readb(private(dev)->mite->daq_io_addr + ID_Register)); - if((ret=alloc_subdevices(dev,3))<0) + if((ret=alloc_subdevices(dev, 4)) < 0) return ret; - s=dev->subdevices+0; - s->type=COMEDI_SUBD_DI; - s->subdev_flags=SDF_READABLE; - s->n_chan=32; - s->range_table=&range_digital; - s->maxdata=1; - s->insn_config = ni6514_di_insn_config; - s->insn_bits = ni6514_di_insn_bits; - - s=dev->subdevices+1; - s->type=COMEDI_SUBD_DO; - s->subdev_flags=SDF_READABLE|SDF_WRITABLE; - s->n_chan=32; - s->range_table=&range_digital; - s->maxdata=1; - s->insn_bits = ni6514_do_insn_bits; + s = dev->subdevices + 0; + if(board(dev)->num_di_ports) + { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = board(dev)->num_di_ports * ni_65xx_channels_per_port; + s->range_table = &range_digital; + s->maxdata = 1; + s->insn_config = ni_65xx_dio_insn_config; + s->insn_bits = ni_65xx_dio_insn_bits; + s->private = ni_65xx_alloc_subdevice_private(); + if(s->private == NULL) return -ENOMEM; + sprivate(s)->base_port = 0; + }else + { + s->type = COMEDI_SUBD_UNUSED; + } + + s=dev->subdevices + 1; + if(board(dev)->num_do_ports) + { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = board(dev)->num_di_ports * ni_65xx_channels_per_port; + s->range_table = &range_digital; + s->maxdata = 1; + s->insn_bits = ni_65xx_dio_insn_bits; + s->private = ni_65xx_alloc_subdevice_private(); + if(s->private == NULL) return -ENOMEM; + sprivate(s)->base_port = board(dev)->num_di_ports; + }else + { + s->type = COMEDI_SUBD_UNUSED; + } s=dev->subdevices + 2; + if(board(dev)->num_dio_ports) + { + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = board(dev)->num_dio_ports * ni_65xx_channels_per_port; + s->range_table=&range_digital; + s->maxdata=1; + s->insn_config = ni_65xx_dio_insn_config; + s->insn_bits = ni_65xx_dio_insn_bits; + s->private = ni_65xx_alloc_subdevice_private(); + if(s->private == NULL) return -ENOMEM; + sprivate(s)->base_port = 0; + }else + { + s->type = COMEDI_SUBD_UNUSED; + } + + s=dev->subdevices + 3; dev->read_subdev = s; s->type=COMEDI_SUBD_DI; s->subdev_flags=SDF_READABLE; s->n_chan=1; s->range_table=&range_unknown; s->maxdata=1; - s->do_cmdtest = ni6514_intr_cmdtest; - s->do_cmd = ni6514_intr_cmd; - s->cancel = ni6514_intr_cancel; - s->insn_bits = ni6514_intr_insn_bits; - s->insn_config = ni6514_intr_insn_config; - - writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0)); - writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0x10)); - writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0x20)); - writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0x30)); - - writeb(0x00,devpriv->mite->daq_io_addr+Port_Register(0x40)); - writeb(0x00,devpriv->mite->daq_io_addr+Port_Register(0x50)); - writeb(0x00,devpriv->mite->daq_io_addr+Port_Register(0x60)); - writeb(0x00,devpriv->mite->daq_io_addr+Port_Register(0x70)); - + s->do_cmdtest = ni_65xx_intr_cmdtest; + s->do_cmd = ni_65xx_intr_cmd; + s->cancel = ni_65xx_intr_cancel; + s->insn_bits = ni_65xx_intr_insn_bits; + s->insn_config = ni_65xx_intr_insn_config; + + unsigned i; + for(i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) + { + writeb(0x00, private(dev)->mite->daq_io_addr + Filter_Enable(i)); + writeb(0x00,private(dev)->mite->daq_io_addr + Port_Data(i)); + } writeb(ClrEdge|ClrOverflow, - devpriv->mite->daq_io_addr + Clear_Register); - writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); + private(dev)->mite->daq_io_addr + Clear_Register); + writeb(0x00, private(dev)->mite->daq_io_addr + Master_Interrupt_Control); /* Set filter interval to 0 (32bit reg) */ - writeb(0x00000000, devpriv->mite->daq_io_addr + Filter_Interval); + writeb(0x00000000, private(dev)->mite->daq_io_addr + Filter_Interval); - ret=comedi_request_irq(dev->irq,ni6514_interrupt,SA_SHIRQ,"ni6514",dev); + ret=comedi_request_irq(dev->irq,ni_65xx_interrupt,SA_SHIRQ,"ni_65xx",dev); if(ret<0){ dev->irq=0; printk(" irq not available"); @@ -423,24 +644,35 @@ static int ni6514_attach(comedi_device *dev,comedi_devconfig *it) return 0; } -static int ni6514_detach(comedi_device *dev) +static int ni_65xx_detach(comedi_device *dev) { - if(devpriv && devpriv->mite && devpriv->mite->daq_io_addr){ - writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); + if(private(dev) && private(dev)->mite && private(dev)->mite->daq_io_addr){ + writeb(0x00, private(dev)->mite->daq_io_addr + Master_Interrupt_Control); } if(dev->irq){ comedi_free_irq(dev->irq,dev); } - if(devpriv && devpriv->mite){ - mite_unsetup(devpriv->mite); + if(private(dev)) + { + unsigned i; + for(i = 0; i < dev->n_subdevices; ++i) + { + if(dev->subdevices[i].private) + { + kfree(dev->subdevices[i].private); + dev->subdevices[i].private = NULL; + } + } + if(private(dev)->mite){ + mite_unsetup(private(dev)->mite); + } } - return 0; } -static int ni6514_find_device(comedi_device *dev,int bus,int slot) +static int ni_65xx_find_device(comedi_device *dev,int bus,int slot) { struct mite_struct *mite; int i; @@ -452,10 +684,10 @@ static int ni6514_find_device(comedi_device *dev,int bus,int slot) slot!=PCI_SLOT(mite->pcidev->devfn)) continue; } - for(i=0;iboard_ptr = ni6514_boards + i; - devpriv->mite=mite; + for(i=0;iboard_ptr = ni_65xx_boards + i; + private(dev)->mite=mite; return 0; } }