From b996a9451da6c512dce8b90ee6fd93293aa287c6 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Tue, 2 May 2006 01:46:54 +0000 Subject: [PATCH] New drivers from mike@mikelachaine.ca (mikelachaine) --- comedi/drivers/adl_pci7432.c | 179 ++++++++++++++ comedi/drivers/adl_pci8164.c | 441 +++++++++++++++++++++++++++++++++++ 2 files changed, 620 insertions(+) create mode 100644 comedi/drivers/adl_pci7432.c create mode 100644 comedi/drivers/adl_pci8164.c diff --git a/comedi/drivers/adl_pci7432.c b/comedi/drivers/adl_pci7432.c new file mode 100644 index 00000000..609d1bae --- /dev/null +++ b/comedi/drivers/adl_pci7432.c @@ -0,0 +1,179 @@ +/* + comedi/drivers/adl_pci7432.c + + Hardware comedi driver fot PCI7432 Adlink card + Copyright (C) 2004 Michel Lachine + + 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: adl_pci7432.o +Description: Driver for the Adlink PCI-7432 64 ch. isolated digital io board +Devices: [ADLink] PCI-7432 (pci7432) +Author: Michel Lachaine +Status: experimental + +Configuration Options: + none +*/ + +#include +#include + +#define PCI7432_DI 0x00 +#define PCI7432_DO 0x00 + +#define PCI_DEVICE_ID_PCI7432 0x7432 + +typedef struct { + char *name; + int vendor_id; + int device_id; +} adl_pci7432_board; + +static adl_pci7432_board adl_pci7432_boards[] = { + { "pci7432", PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432 }, +}; + +static struct pci_device_id adl_pci7432_pci_table[] __devinitdata = { + { PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table); + +#define thisboard ((adl_pci7432_board *)dev->board_ptr) + +typedef struct{ + int data; + struct pci_dev *pci_dev; +} adl_pci7432_private; + +#define devpriv ((pci7432_private *)dev->private) + +static int adl_pci7432_attach(comedi_device *dev,comedi_devconfig *it); +static int adl_pci7432_detach(comedi_device *dev); +static comedi_driver driver_adl_pci7432={ + driver_name: "adl_pci7432", + module: THIS_MODULE, + attach: adl_pci7432_attach, + detach: adl_pci7432_detach, + num_names: 1, + board_name: adl_pci7432_boards, + offset: sizeof(adl_pci7432_board), +}; + +/* Digital IO */ + +static int adl_pci7432_di_insn_bits(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data); + +static int adl_pci7432_do_insn_bits(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data); + +/* */ + +static int adl_pci7432_attach(comedi_device *dev,comedi_devconfig *it) +{ + struct pci_dev *pcidev; + comedi_subdevice *s; + + printk("comedi: attempt to attach...\n"); + printk("comedi%d: adl_pci7432: board=%s\n",dev->minor, thisboard->name); + + dev->board_name = thisboard->name; + + if(alloc_private(dev,sizeof(adl_pci7432_private))<0) + return -ENOMEM; + + if(alloc_subdevices(dev, 2)<0) + return -ENOMEM; + + pci_for_each_dev ( pcidev ) { + + if ( pcidev->vendor == PCI_VENDOR_ID_ADLINK && + pcidev->device == PCI_DEVICE_ID_PCI7432 ) { + dev->iobase = pci_resource_start ( pcidev, 2 ); + printk ( "comedi: base addr %4x\n", dev->iobase ); + + dev->board_ptr = adl_pci7432_boards + 0; + + s=dev->subdevices+0; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE|SDF_GROUND|SDF_COMMON; + s->n_chan = 32; + s->maxdata = 1; + s->len_chanlist = 32; + s->io_bits = 0x00000000; + s->range_table = &range_digital; + s->insn_bits = adl_pci7432_di_insn_bits; + + s=dev->subdevices+1; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE|SDF_GROUND|SDF_COMMON; + s->n_chan = 32; + s->maxdata = 1 ; + s->len_chanlist = 32; + s->io_bits = 0xffffffff; + s->range_table = &range_digital; + s->insn_bits = adl_pci7432_do_insn_bits; + } + } + + printk("comedi: attached\n"); + + return 1; +} + + +static int adl_pci7432_detach(comedi_device *dev) +{ + printk("comedi%d: pci7432: remove\n",dev->minor); + + return 0; +} + + +static int adl_pci7432_do_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) +{ + printk ( "comedi: pci7432_do_insn_bits called\n" ); + printk ( "comedi: data0: %8x data1: %8x\n", data[0], data[1] ); + + if(insn->n!=2)return -EINVAL; + + if(data[0]){ + s->state &= ~data[0]; + s->state |= (data[0]&data[1]); + + printk ( "comedi: out: %8x on iobase %4x\n", s->state, dev->iobase + PCI7432_DO); + outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO); + } + return 2; +} + +static int adl_pci7432_di_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) +{ + printk ( "comedi: pci7432_di_insn_bits called\n" ); + printk ( "comedi: data0: %8x data1: %8x\n", data[0], data[1] ); + + if(insn->n!=2)return -EINVAL; + + data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff; + printk ( "comedi: data1 %8x\n", data[1] ); + + return 2; +} + +COMEDI_INITCLEANUP(driver_adl_pci7432); diff --git a/comedi/drivers/adl_pci8164.c b/comedi/drivers/adl_pci8164.c new file mode 100644 index 00000000..b310d461 --- /dev/null +++ b/comedi/drivers/adl_pci8164.c @@ -0,0 +1,441 @@ +/* + comedi/drivers/adl_pci8164.c + + Hardware comedi driver fot PCI-8164 Adlink card + Copyright (C) 2004 Michel Lachine + + 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: adl_pci8164.o +Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board +Devices: [ADLink] PCI-8164 (pci8164) +Author: Michel Lachaine +Status: experimental + +Configuration Options: + none +*/ + +#include +#include +#include +#include +#include <8253.h> + +#define PCI8164_AXIS_X 0x00 +#define PCI8164_AXIS_Y 0x08 +#define PCI8164_AXIS_Z 0x10 +#define PCI8164_AXIS_U 0x18 + +#define PCI8164_MSTS 0x00 +#define PCI8164_SSTS 0x02 +#define PCI8164_BUF0 0x04 +#define PCI8164_BUF1 0x06 + +#define PCI8164_CMD 0x00 +#define PCI8164_OTP 0x02 + +#define PCI_DEVICE_ID_PCI8164 0x8164 + +typedef struct { + char *name; + int vendor_id; + int device_id; +} adl_pci8164_board; + +static adl_pci8164_board adl_pci8164_boards[] = { + { "pci8164", PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164 }, +}; + +static struct pci_device_id adl_pci8164_pci_table[] __devinitdata = { + { PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table); + +#define thisboard ((adl_pci8164_board *)dev->board_ptr) + +typedef struct{ + int data; + struct pci_dev *pci_dev; +} adl_pci8164_private; + +#define devpriv ((pci8164_private *)dev->private) + +static int adl_pci8164_attach(comedi_device *dev,comedi_devconfig *it); +static int adl_pci8164_detach(comedi_device *dev); +static comedi_driver driver_adl_pci8164={ + driver_name: "adl_pci8164", + module: THIS_MODULE, + attach: adl_pci8164_attach, + detach: adl_pci8164_detach, + num_names: 1, + board_name: adl_pci8164_boards, + offset: sizeof(adl_pci8164_board), +}; + +static int adl_pci8164_insn_read_msts(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data); + +static int adl_pci8164_insn_read_ssts(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data); + +static int adl_pci8164_insn_read_buf0(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data); + +static int adl_pci8164_insn_read_buf1(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data); + +static int adl_pci8164_insn_write_cmd(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data); + +static int adl_pci8164_insn_write_otp(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data); + +static int adl_pci8164_insn_write_buf0(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data); + +static int adl_pci8164_insn_write_buf1(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data); + +static int adl_pci8164_attach(comedi_device *dev,comedi_devconfig *it) +{ + struct pci_dev *pcidev; + comedi_subdevice *s; + + printk("comedi: attempt to attach...\n"); + printk("comedi%d: adl_pci8164: board=%s\n",dev->minor, thisboard->name); + + dev->board_name = thisboard->name; + + if(alloc_private(dev,sizeof(adl_pci8164_private))<0) + return -ENOMEM; + + if(alloc_subdevices(dev, 4)<0) + return -ENOMEM; + + pci_for_each_dev ( pcidev ) { + + if ( pcidev->vendor == PCI_VENDOR_ID_ADLINK && + pcidev->device == PCI_DEVICE_ID_PCI8164 ) { + dev->iobase = pci_resource_start ( pcidev, 2 ); + printk ( "comedi: base addr %4x\n", dev->iobase ); + + dev->board_ptr = adl_pci8164_boards + 0; + + s=dev->subdevices+0; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE|SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + //s->range_table = &range_axis; + s->insn_read = adl_pci8164_insn_read_msts; + s->insn_write = adl_pci8164_insn_write_cmd; + + s=dev->subdevices+1; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE|SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + //s->range_table = &range_axis; + s->insn_read = adl_pci8164_insn_read_ssts; + s->insn_write = adl_pci8164_insn_write_otp; + + s=dev->subdevices+2; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE|SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + //s->range_table = &range_axis; + s->insn_read = adl_pci8164_insn_read_buf0; + s->insn_write = adl_pci8164_insn_write_buf0; + + s=dev->subdevices+3; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE|SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + //s->range_table = &range_axis; + s->insn_read = adl_pci8164_insn_read_buf1; + s->insn_write = adl_pci8164_insn_write_buf1; + + } + } + + printk("comedi: attached\n"); + + return 1; +} + + +static int adl_pci8164_detach(comedi_device *dev) +{ + printk("comedi%d: pci8164: remove\n",dev->minor); + + return 0; +} + +static int adl_pci8164_insn_read_msts(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) +{ + int axis, axis_reg; + char *axisname; + + axis = CR_CHAN(insn->chanspec); + + switch (axis) + { + case 0: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + break; + case 1: axis_reg = PCI8164_AXIS_Y; + axisname = "Y"; + break; + case 2: axis_reg = PCI8164_AXIS_Z; + axisname = "Z"; + break; + case 3: axis_reg = PCI8164_AXIS_U; + axisname = "U"; + break; + default: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + } + + data[0] = inw(dev->iobase + axis_reg + PCI8164_MSTS); + printk("comedi: pci8164 MSTS read -> %04X:%04X on axis %s\n", data[0], data[1], axisname); + + return 2; +} + +static int adl_pci8164_insn_read_ssts(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) +{ + int axis, axis_reg; + char *axisname; + + axis = CR_CHAN(insn->chanspec); + + switch (axis) + { + case 0: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + break; + case 1: axis_reg = PCI8164_AXIS_Y; + axisname = "Y"; + break; + case 2: axis_reg = PCI8164_AXIS_Z; + axisname = "Z"; + break; + case 3: axis_reg = PCI8164_AXIS_U; + axisname = "U"; + break; + default: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + } + + data[0] = inw(dev->iobase + axis_reg + PCI8164_SSTS); + printk("comedi: pci8164 SSTS read -> %04X:%04X on axis %s\n", data[0], data[1], axisname); + + return 2; +} + +static int adl_pci8164_insn_read_buf0(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) +{ + int axis, axis_reg; + char *axisname; + + axis = CR_CHAN(insn->chanspec); + + switch (axis) + { + case 0: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + break; + case 1: axis_reg = PCI8164_AXIS_Y; + axisname = "Y"; + break; + case 2: axis_reg = PCI8164_AXIS_Z; + axisname = "Z"; + break; + case 3: axis_reg = PCI8164_AXIS_U; + axisname = "U"; + break; + default: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + } + + data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF0); + printk("comedi: pci8164 BUF0 read -> %04X:%04X on axis %s\n", data[0], data[1], axisname); + + return 2; +} + +static int adl_pci8164_insn_read_buf1(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) +{ + int axis, axis_reg; + + char *axisname; + + axis = CR_CHAN(insn->chanspec); + + switch (axis) + { + case 0: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + break; + case 1: axis_reg = PCI8164_AXIS_Y; + axisname = "Y"; + break; + case 2: axis_reg = PCI8164_AXIS_Z; + axisname = "Z"; + break; + case 3: axis_reg = PCI8164_AXIS_U; + axisname = "U"; + break; + default: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + } + + data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF1); + printk("comedi: pci8164 BUF1 read -> %04X:%04X on axis %s\n", data[0], data[1], axisname); + + return 2; +} + +static int adl_pci8164_insn_write_cmd(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) +{ + unsigned int axis, axis_reg; + + char *axisname; + + axis = CR_CHAN(insn->chanspec); + + switch (axis) + { + case 0: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + break; + case 1: axis_reg = PCI8164_AXIS_Y; + axisname = "Y"; + break; + case 2: axis_reg = PCI8164_AXIS_Z; + axisname = "Z"; + break; + case 3: axis_reg = PCI8164_AXIS_U; + axisname = "U"; + break; + default: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + } + + outw(data[0], dev->iobase + axis_reg + PCI8164_CMD); + printk("comedi: pci8164 CMD write -> %04X:%04X on axis %s\n", data[0], data[1], axisname); + + return 2; +} + +static int adl_pci8164_insn_write_otp(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) +{ + int axis, axis_reg; + + char *axisname; + + axis = CR_CHAN(insn->chanspec); + + switch (axis) + { + case 0: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + break; + case 1: axis_reg = PCI8164_AXIS_Y; + axisname = "Y"; + break; + case 2: axis_reg = PCI8164_AXIS_Z; + axisname = "Z"; + break; + case 3: axis_reg = PCI8164_AXIS_U; + axisname = "U"; + break; + default: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + } + + outw(data[0], dev->iobase + axis_reg + PCI8164_OTP); + printk("comedi: pci8164 OTP write -> %04X:%04X on axis %s\n", data[0], data[1], axisname); + + return 2; +} + +static int adl_pci8164_insn_write_buf0(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) +{ + int axis, axis_reg; + + char *axisname; + + axis = CR_CHAN(insn->chanspec); + + switch (axis) + { + case 0: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + break; + case 1: axis_reg = PCI8164_AXIS_Y; + axisname = "Y"; + break; + case 2: axis_reg = PCI8164_AXIS_Z; + axisname = "Z"; + break; + case 3: axis_reg = PCI8164_AXIS_U; + axisname = "U"; + break; + default: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + } + + outw(data[0], dev->iobase + axis_reg + PCI8164_BUF0); + printk("comedi: pci8164 BUF0 write -> %04X:%04X on axis %s\n", data[0], data[1], axisname); + + return 2; +} + +static int adl_pci8164_insn_write_buf1(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) +{ + int axis, axis_reg; + + char *axisname; + + axis = CR_CHAN(insn->chanspec); + + switch (axis) + { + case 0: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + break; + case 1: axis_reg = PCI8164_AXIS_Y; + axisname = "Y"; + break; + case 2: axis_reg = PCI8164_AXIS_Z; + axisname = "Z"; + break; + case 3: axis_reg = PCI8164_AXIS_U; + axisname = "U"; + break; + default: axis_reg = PCI8164_AXIS_X; + axisname = "X"; + } + + outw(data[0], dev->iobase + axis_reg + PCI8164_BUF1); + printk("comedi: pci8164 BUF1 write -> %04X:%04X on axis %s\n", data[0], data[1], axisname); + + return 2; +} + +COMEDI_INITCLEANUP(driver_adl_pci8164); -- 2.26.2