[4] - divisor
-ID=INSN_CONFIG_PWM_OUTPUT: Configure a pulse-width-modulation output. Returns
+ID=INSN_CONFIG_PWM_OUTPUT: Configure a pulse-width-modulated output. Returns
EAGAIN error with modified values if exact timing is not achievable.
[0] - ID
}
if(!dev->attached){
- DPRINTK("no driver configured on /dev/comedi%i\n", dev->minor);
+ DPRINTK("no driver configured on /dev/comedi%i\n", minor);
return -ENODEV;
}
}
DPRINTK("comedi%i subd %d buffer resized to %i bytes\n",
- dev->minor, bc.subdevice, async->prealloc_bufsz);
+ MINOR(dev->devt), bc.subdevice, async->prealloc_bufsz);
}
bc.size = async->prealloc_bufsz;
us->len_chanlist = s->len_chanlist;
us->maxdata = s->maxdata;
if(s->range_table){
- us->range_type = (dev->minor<<28)|(i<<24)|(0<<16)|
- (s->range_table->length);
+ us->range_type = (MINOR(dev->devt) << 28) | (i << 24) | (0 << 16) |
+ (s->range_table->length);
}else{
us->range_type = 0; /* XXX */
}
for(i=0;i<s->n_chan;i++){
int x;
- x=(dev->minor<<28)|(it.subdev<<24)|(i<<16)|
+ x=(MINOR(dev->devt) << 28) | (it.subdev << 24) | (i << 16) |
(s->range_table_list[i]->length);
put_user(x,it.rangelist+i);
}
static int comedi_mmap(struct file * file, struct vm_area_struct *vma)
{
- unsigned int minor=MINOR(RDEV_OF_FILE(file));
- comedi_device *dev=comedi_get_device_by_minor(minor);
+ unsigned int minor = MINOR(RDEV_OF_FILE(file));
+ comedi_device *dev = comedi_get_device_by_minor(minor);
comedi_async *async = NULL;
unsigned long start = vma->vm_start;
unsigned long size;
if(!dev->attached)
{
- DPRINTK("no driver configured on comedi%i\n", dev->minor);
+ DPRINTK("no driver configured on comedi%i\n", minor);
return -ENODEV;
}
if(!dev->attached)
{
- DPRINTK("no driver configured on comedi%i\n", dev->minor);
+ DPRINTK("no driver configured on comedi%i\n", MINOR(dev->devt));
return -ENODEV;
}
if(!dev->attached)
{
- DPRINTK("no driver configured on comedi%i\n", dev->minor);
+ DPRINTK("no driver configured on comedi%i\n", MINOR(dev->devt));
return -ENODEV;
}
if(!dev->attached)
{
- DPRINTK("no driver configured on comedi%i\n", dev->minor);
+ DPRINTK("no driver configured on comedi%i\n", MINOR(dev->devt));
return -ENODEV;
}
return -ENOMEM;
}
memset(comedi_devices,0,sizeof(comedi_device)*COMEDI_NDEVICES);
- for(i=0;i<COMEDI_NDEVICES;i++){
- comedi_devices[i].minor=i;
- spin_lock_init(&(comedi_devices[i].spinlock));
- }
/* XXX requires /proc interface */
comedi_proc_init();
sprintf(name, "comedi%d", i);
devfs_register(NULL, name, DEVFS_FL_DEFAULT,
COMEDI_MAJOR, i, 0666 | S_IFCHR, &comedi_fops, NULL);
- COMEDI_CLASS_DEVICE_CREATE(comedi_class, 0,
- MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i);
+ struct class_device *class_dev = COMEDI_CLASS_DEVICE_CREATE(comedi_class, 0,
+ MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i);
+ comedi_devices[i].devt = class_dev->devt;
+ comedi_devices[i].minor = MINOR(class_dev->devt);
+ spin_lock_init(&comedi_devices[i].spinlock);
}
comedi_rt_init();
if(MOD_IN_USE)
printk("comedi: module in use -- remove delayed\n");
- for(i=0;i<COMEDI_NDEVICES;i++){
+ for(i = 0; i < COMEDI_NDEVICES; i++){
+ comedi_device *dev;
+
+ dev=comedi_get_device_by_minor(i);
+ if(dev->attached)
+ comedi_device_detach(dev);
+ }
+
+ for(i = 0; i < COMEDI_NDEVICES; i++){
char name[20];
- class_device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, i));
+ class_device_destroy(comedi_class, comedi_devices[i].devt);
sprintf(name, "comedi%d", i);
devfs_unregister(devfs_find_handle(NULL, name,
COMEDI_MAJOR, i, DEVFS_SPECIAL_CHR, 0));
comedi_proc_cleanup();
- for(i=0;i<COMEDI_NDEVICES;i++){
- comedi_device *dev;
-
- dev=comedi_get_device_by_minor(i);
- if(dev->attached)
- comedi_device_detach(dev);
- }
kfree(comedi_devices);
comedi_rt_cleanup();
void comedi_error(const comedi_device *dev,const char *s)
{
- rt_printk("comedi%d: %s: %s\n",dev->minor,dev->driver->driver_name,s);
+ rt_printk("comedi%d: %s: %s\n", MINOR(dev->devt), dev->driver->driver_name, s);
}
void comedi_event(comedi_device *dev,comedi_subdevice *s, unsigned int mask)
}
kfree(dev->subdevices);
dev->subdevices = NULL;
+ dev->n_subdevices = 0;
}
if(dev->private)
{
}
cleanup_device_allocations(dev);
+ dev->driver = 0;
+ dev->board_name = 0;
+ dev->board_ptr = 0;
+ dev->iobase = 0;
+ dev->irq = 0;
+ dev->read_subdev = NULL;
+ dev->write_subdev = NULL;
+ dev->open = NULL;
+ dev->close = NULL;
return 0;
}
{
comedi_driver *driv;
int ret;
- int minor;
- int use_count;
if(dev->attached)
return -EBUSY;
- minor = dev->minor;
- use_count = dev->use_count;
- memset(dev,0,sizeof(comedi_device));
- spin_lock_init(&dev->spinlock);
- dev->minor=minor;
- dev->use_count = use_count;
for(driv=comedi_drivers;driv;driv=driv->next){
if(!try_module_get( driv->module ))
{
dev->driver=driv;
ret=driv->attach(dev,it);
if(ret<0){
- driv->detach(dev);
- cleanup_device_allocations(dev);
- module_put( driv->module );
+ comedi_device_detach(dev);
return ret;
}
goto attached;
comedi/drivers/cb_pcimdda.c
Computer Boards PCIM-DDA06-16 Comedi driver
Author: Calin Culianu <calin@ajvar.org>
-
+
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 2000 David A. Schleef <ds@schleef.org>
Status: works
All features of the PCIM-DDA06-16 board are supported. This board
-has 6 16-bit AO channels, and the usual 8255 DIO setup. (24 channels,
+has 6 16-bit AO channels, and the usual 8255 DIO setup. (24 channels,
configurable in banks of 8 and 4, etc.). This board does not support commands.
The board has a peculiar way of specifying AO gain/range settings -- You have
1 jumper bank on the card, which either makes all 6 AO channels either
-5 Volt unipolar, 5V bipolar, 10 Volt unipolar or 10V bipolar.
-
+5 Volt unipolar, 5V bipolar, 10 Volt unipolar or 10V bipolar.
+
Since there is absolutely _no_ way to tell in software how this jumper is set
(well, at least according to the rather thin spec. from Measurement Computing
- that comes with the board), the driver assumes the jumper is at its factory
+ that comes with the board), the driver assumes the jumper is at its factory
default setting of +/-5V.
Also of note is the fact that this board features another jumper, whose
signal output by the DAC on the board (this is the factory default).
- Simultaneous XFER Mode: Writing to an AO channel has no effect until
you read from any one of the AO channels. This is useful for loading
- all 6 AO values, and then reading from any one of the AO channels on the
+ all 6 AO values, and then reading from any one of the AO channels on the
device to instantly update all 6 AO values in unison. Useful for some
- control apps, I would assume? If your jumper is in this setting, then you
+ control apps, I would assume? If your jumper is in this setting, then you
need to issue your comedi_data_write()s to load all the values you want,
then issue one comedi_data_read() on any channel on the AO subdevice
to initiate the simultaneous XFER.
-
+
Configuration Options:
[0] PCI bus (optional) (unimplemented)
/*
This is a driver for the Computer Boards PCIM-DDA06-16 Analog Output
- card. This board has a unique register layout and as such probably
- deserves its own driver file.
+ card. This board has a unique register layout and as such probably
+ deserves its own driver file.
It is theoretically possible to integrate this board into the cb_pcidda
file, but since that isn't my code, I didn't want to significantly
int dio_chans;
int dio_method;
int dio_offset; /* how many bytes into the BADR are the DIO ports */
- int regs_badrindex; /* IO Region for the control, analog output,
+ int regs_badrindex; /* IO Region for the control, analog output,
and DIO registers */
int reg_sz; /* number of bytes of registers in io region */
} board;
ao_bits: 16,
dio_chans: 24,
dio_method: DIO_8255,
- dio_offset: 12,
+ dio_offset: 12,
regs_badrindex: 3,
reg_sz: 16,
}
#define MAX_AO_READBACK_CHANNELS 6
/* Used for AO readback */
lsampl_t ao_readback[MAX_AO_READBACK_CHANNELS];
-
+
} private;
/*
attach: attach,
detach: detach,
};
-MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>");
+MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>");
MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA "
"series. Currently only supports PCIM-DDA06-16 (which "
- "also happens to be the only board in this series. :) ) ");
+ "also happens to be the only board in this series. :) ) ");
MODULE_LICENSE("GPL");
COMEDI_INITCLEANUP_NOMODULE(cb_pcimdda_driver);
-static int ao_winsn(comedi_device *dev, comedi_subdevice *s,
+static int ao_winsn(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn,lsampl_t *data);
-static int ao_rinsn(comedi_device *dev, comedi_subdevice *s,
+static int ao_rinsn(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn,lsampl_t *data);
/*---------------------------------------------------------------------------
- HELPER FUNCTION DECLARATIONS
+ HELPER FUNCTION DECLARATIONS
-----------------------------------------------------------------------------*/
/* returns a maxdata value for a given n_bits */
return (((lsampl_t)1 << bits) - 1);
}
-/*
+/*
* Probes for a supported device.
*
* Prerequisite: private be allocated already inside dev
- *
+ *
* If the device is found, it returns 0 and has the following side effects:
*
- * o assigns a struct pci_dev * to dev->private->pci_dev
+ * o assigns a struct pci_dev * to dev->private->pci_dev
* o assigns a struct board * to dev->board_ptr
* o sets dev->private->registers
* o sets dev->private->dio_registers
{
comedi_subdevice *s;
int err;
-
+
/*
* Allocate the private structure area. alloc_private() is a
* convenient macro defined in comedidev.h.
*/
if (alloc_private(dev,sizeof(private))<0)
return -ENOMEM;
-
+
/*
* If you can probe the device to determine what device in a series
* it is, this is the place to do it. Otherwise, dev->board_ptr
* should already be initialized.
- */
+ */
if ( (err = probe(dev, it)) ) return err;
-
+
/* Output some info */
printk("comedi%d: %s: ",dev->minor, thisboard->name);
/*
* Initialize dev->board_name. Note that we can use the "thisboard"
* macro now, since we just initialized it in the last line.
- */
+ */
dev->board_name = thisboard->name;
/*
s->n_chan = thisboard->ao_chans;
s->maxdata = figure_out_maxdata(thisboard->ao_bits);
/* this is hard-coded here */
- if(dev->options[2]){
+ if(it->options[2]){
s->range_table = &range_bipolar10;
}else{
s->range_table = &range_bipolar5;
} else {
s->type = COMEDI_SUBD_UNUSED;
}
-
+
devpriv->attached_successfully = 1;
printk("attached\n");
-
+
return 1;
}
/*
* _detach is called to deconfigure a device. It should deallocate
- * resources.
+ * resources.
* This function is also called when _attach() fails, so it should be
* careful not to release resources that were not necessarily
* allocated by _attach(). dev->private and dev->subdevices are
/* Writing a list of values to an AO channel is probably not
* very useful, but that's how the interface is defined. */
for(i=0;i<insn->n;i++) {
- /* first, load the low byte */
+ /* first, load the low byte */
outb((char)(data[i] & 0x00ff), offset);
/* next, write the high byte -- only after this is written is
the channel voltage updated in the DAC, unless
/* AO subdevices should have a read insn as well as a write insn.
- Usually this means copying a value stored in devpriv->ao_readback.
+ Usually this means copying a value stored in devpriv->ao_readback.
However, since this board has this jumper setting called "Simultaneous
Xfer mode" (off by default), we will support it. Simultaneaous xfer
- mode is accomplished by loading ALL the values you want for AO in all the
- channels, then READing off one of the AO registers to initiate the
+ mode is accomplished by loading ALL the values you want for AO in all the
+ channels, then READing off one of the AO registers to initiate the
instantaneous simultaneous update of all DAC outputs, which makes
all AO channels update simultaneously. This is useful for some control
applications, I would imagine.
-----------------------------------------------------------------------------*/
-/*
+/*
* Probes for a supported device.
*
* Prerequisite: private be allocated already inside dev
- *
+ *
* If the device is found, it returns 0 and has the following side effects:
*
- * o assigns a struct pci_dev * to dev->private->pci_dev
+ * o assigns a struct pci_dev * to dev->private->pci_dev
* o assigns a struct board * to dev->board_ptr
* o sets dev->private->registers
* o sets dev->private->dio_registers
*
* Otherwise, returns a -errno on error
*/
-static int probe(comedi_device *dev, const comedi_devconfig *it)
+static int probe(comedi_device *dev, const comedi_devconfig *it)
{
struct pci_dev *pcidev;
int index;
unsigned long registers;
- for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ;
+ for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ;
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev))
{
// is it not a computer boards card?
return -EIO;
}
registers = pci_resource_start(devpriv->pci_dev, REGS_BADRINDEX);
- devpriv->registers = registers;
- devpriv->dio_registers
+ devpriv->registers = registers;
+ devpriv->dio_registers
= devpriv->registers + thisboard->dio_offset;
return 0;
}
References for specifications:
-
+
321747b.pdf Register Level Programmer Manual (obsolete)
321747c.pdf Register Level Programmer Manual (new)
DAQ-STC reference manual
Other possibly relevant info:
-
+
320517c.pdf User manual (obsolete)
320517f.pdf User manual (new)
320889a.pdf delete
struct pci_dev *pcidev;
struct mite_struct *mite;
- for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ;
+ for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ;
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
if(pcidev->vendor==PCI_VENDOR_ID_NATINST){
mite=kmalloc(sizeof(*mite),GFP_KERNEL);
printk("mite: version = %i, type = %i, mite mode = %i, interface mode = %i\n",
mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits),
mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits));
- printk("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n",
+ printk("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n",
mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits),
mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
}
resource_size_t addr;
int i;
u32 csigr_bits;
-
+
if(pci_enable_device(mite->pcidev)){
printk("error enabling mite\n");
return -EIO;
writel(mcr, mite->mite_io_addr + MITE_MCR(channel));
/* from/to device */
- dcr = CR_RL(64) | CR_ASEQUP;
+ dcr = CR_RL(64) | CR_ASEQUP;
dcr |= CR_PORTIO | CR_AMDEVICE | CR_REQSDRQ(channel);
switch( num_device_bits ){
case 8:
comedi_insn *insn,lsampl_t *data);
static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,
comedi_insn *insn,lsampl_t *data);
+static int ni_gpct_cmd(comedi_device *dev,comedi_subdevice *s);
+static int ni_gpct_cmdtest(comedi_device *dev, comedi_subdevice *s, comedi_cmd *cmd);
+static int ni_gpct_cancel(comedi_device *dev,comedi_subdevice *s);
static int init_cs5529(comedi_device *dev);
static int cs5529_do_conversion(comedi_device *dev, unsigned short *data);
comedi_subdevice *s = dev->subdevices + 1;
devpriv->last_buf_write_count = s->async->buf_write_count;
-
mite_chan->current_link = 0;
mite_chan->dir = COMEDI_OUTPUT;
if(boardtype.reg_type & (ni_reg_611x | ni_reg_6713))
/* general purpose counter/timer device */
s=dev->subdevices+4;
- s->type=COMEDI_SUBD_COUNTER;
- s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
- s->insn_read= ni_gpct_insn_read;
- s->insn_write= ni_gpct_insn_write;
- s->insn_config=ni_gpct_insn_config;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->insn_read = ni_gpct_insn_read;
+ s->insn_write = ni_gpct_insn_write;
+ s->insn_config = ni_gpct_insn_config;
s->n_chan=2;
s->maxdata=1;
+ s->do_cmdtest = ni_gpct_cmdtest;
+ s->do_cmd = ni_gpct_cmd;
+ s->cancel = ni_gpct_cancel;
+// s->poll=ni_gpct_poll;
+// s->munge=ni_gpct_munge;
devpriv->an_trig_etc_reg = 0;
GPCT_Reset(dev,0);
GPCT_Reset(dev,1);
return 1;
}
+static int ni_gpct_cmd(comedi_device *dev, comedi_subdevice *s)
+{
+ return 0;
+}
+
+static int ni_gpct_cmdtest(comedi_device *dev, comedi_subdevice *s, comedi_cmd *cmd)
+{
+ return 0;
+}
+
+static int ni_gpct_cancel(comedi_device *dev, comedi_subdevice *s)
+{
+ return 0;
+}
/*
*
unsigned int num_bytes, unsigned int start_chan_index );
unsigned int state;
+
+ dev_t devt;
};
struct comedi_async_struct{
int use_count;
comedi_driver *driver;
void *private;
- unsigned int minor;
+ unsigned minor;
+ dev_t devt;
const char *board_name;
const void * board_ptr;
int attached;
int n_subdevices;
comedi_subdevice *subdevices;
- int options[COMEDI_NDEVCONFOPTS];
/* dumb */
unsigned long iobase;