-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 141424 b: refs/heads/master c: 96a2d5f h: refs/heads/master v: v3
- Loading branch information
José Luis Sánchez
authored and
Greg Kroah-Hartman
committed
Apr 3, 2009
1 parent
fba4219
commit fb7bb90
Showing
2 changed files
with
167 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 00a224316fdc0e95c779534acde02579c16e327e | ||
refs/heads/master: 96a2d5f0a1e8ef2748088d18ea5ba97bf829dd94 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
/* | ||
* comedi/drivers/pcl730.c | ||
* Driver for Advantech PCL-730 and clones | ||
* José Luis Sánchez | ||
*/ | ||
/* | ||
Driver: pcl730 | ||
Description: Advantech PCL-730 (& compatibles) | ||
Author: José Luis Sánchez (jsanchezv@teleline.es) | ||
Status: untested | ||
Devices: [Advantech] PCL-730 (pcl730), [ICP] ISO-730 (iso730), | ||
[Adlink] ACL-7130 (acl7130) | ||
Interrupts are not supported. | ||
The ACL-7130 card have an 8254 timer/counter not supported by this driver. | ||
*/ | ||
|
||
#include "../comedidev.h" | ||
|
||
#include <linux/ioport.h> | ||
|
||
#define PCL730_SIZE 4 | ||
#define ACL7130_SIZE 8 | ||
#define PCL730_IDIO_LO 0 /* Isolated Digital I/O low byte (ID0-ID7) */ | ||
#define PCL730_IDIO_HI 1 /* Isolated Digital I/O high byte (ID8-ID15) */ | ||
#define PCL730_DIO_LO 2 /* TTL Digital I/O low byte (D0-D7) */ | ||
#define PCL730_DIO_HI 3 /* TTL Digital I/O high byte (D8-D15) */ | ||
|
||
static int pcl730_attach(comedi_device * dev, comedi_devconfig * it); | ||
static int pcl730_detach(comedi_device * dev); | ||
|
||
typedef struct { | ||
const char *name; // board name | ||
unsigned int io_range; // len of I/O space | ||
} boardtype; | ||
|
||
static const boardtype boardtypes[] = { | ||
{"pcl730", PCL730_SIZE,}, | ||
{"iso730", PCL730_SIZE,}, | ||
{"acl7130", ACL7130_SIZE,}, | ||
}; | ||
|
||
#define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype)) | ||
#define this_board ((const boardtype *)dev->board_ptr) | ||
|
||
static comedi_driver driver_pcl730 = { | ||
driver_name:"pcl730", | ||
module:THIS_MODULE, | ||
attach:pcl730_attach, | ||
detach:pcl730_detach, | ||
board_name:&boardtypes[0].name, | ||
num_names:n_boardtypes, | ||
offset:sizeof(boardtype), | ||
}; | ||
|
||
COMEDI_INITCLEANUP(driver_pcl730); | ||
|
||
static int pcl730_do_insn(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] & 0x00ff) | ||
outb(s->state & 0xff, | ||
dev->iobase + ((unsigned long)s->private)); | ||
if (data[0] & 0xff00) | ||
outb((s->state >> 8), | ||
dev->iobase + ((unsigned long)s->private) + 1); | ||
|
||
data[1] = s->state; | ||
|
||
return 2; | ||
} | ||
|
||
static int pcl730_di_insn(comedi_device * dev, comedi_subdevice * s, | ||
comedi_insn * insn, lsampl_t * data) | ||
{ | ||
if (insn->n != 2) | ||
return -EINVAL; | ||
|
||
data[1] = inb(dev->iobase + ((unsigned long)s->private)) | | ||
(inb(dev->iobase + ((unsigned long)s->private) + 1) << 8); | ||
|
||
return 2; | ||
} | ||
|
||
static int pcl730_attach(comedi_device * dev, comedi_devconfig * it) | ||
{ | ||
comedi_subdevice *s; | ||
unsigned long iobase; | ||
unsigned int iorange; | ||
|
||
iobase = it->options[0]; | ||
iorange = this_board->io_range; | ||
printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor, | ||
this_board->name, iobase); | ||
if (!request_region(iobase, iorange, "pcl730")) { | ||
printk("I/O port conflict\n"); | ||
return -EIO; | ||
} | ||
dev->board_name = this_board->name; | ||
dev->iobase = iobase; | ||
dev->irq = 0; | ||
|
||
if (alloc_subdevices(dev, 4) < 0) | ||
return -ENOMEM; | ||
|
||
s = dev->subdevices + 0; | ||
/* Isolated do */ | ||
s->type = COMEDI_SUBD_DO; | ||
s->subdev_flags = SDF_WRITABLE; | ||
s->maxdata = 1; | ||
s->n_chan = 16; | ||
s->insn_bits = pcl730_do_insn; | ||
s->range_table = &range_digital; | ||
s->private = (void *)PCL730_IDIO_LO; | ||
|
||
s = dev->subdevices + 1; | ||
/* Isolated di */ | ||
s->type = COMEDI_SUBD_DI; | ||
s->subdev_flags = SDF_READABLE; | ||
s->maxdata = 1; | ||
s->n_chan = 16; | ||
s->insn_bits = pcl730_di_insn; | ||
s->range_table = &range_digital; | ||
s->private = (void *)PCL730_IDIO_LO; | ||
|
||
s = dev->subdevices + 2; | ||
/* TTL do */ | ||
s->type = COMEDI_SUBD_DO; | ||
s->subdev_flags = SDF_WRITABLE; | ||
s->maxdata = 1; | ||
s->n_chan = 16; | ||
s->insn_bits = pcl730_do_insn; | ||
s->range_table = &range_digital; | ||
s->private = (void *)PCL730_DIO_LO; | ||
|
||
s = dev->subdevices + 3; | ||
/* TTL di */ | ||
s->type = COMEDI_SUBD_DI; | ||
s->subdev_flags = SDF_READABLE; | ||
s->maxdata = 1; | ||
s->n_chan = 16; | ||
s->insn_bits = pcl730_di_insn; | ||
s->range_table = &range_digital; | ||
s->private = (void *)PCL730_DIO_LO; | ||
|
||
printk("\n"); | ||
|
||
return 0; | ||
} | ||
|
||
static int pcl730_detach(comedi_device * dev) | ||
{ | ||
printk("comedi%d: pcl730: remove\n", dev->minor); | ||
|
||
if (dev->iobase) | ||
release_region(dev->iobase, this_board->io_range); | ||
|
||
return 0; | ||
} |