Added const qualifier to some char*.
continue;
}
if(driv->num_names){
- dev->board_ptr=comedi_recognize(driv, it->board_name);
+ dev->board_ptr = comedi_recognize(driv, it->board_name);
if(dev->board_ptr==NULL){
module_put( driv->module );
continue;
comedi_device *dev;
// XXX we need to do actual allocation here.
-
+
dev=comedi_get_device_by_minor(0);
dev->driver=driver;
// generic recognize function for drivers that register their supported board names
void *comedi_recognize(comedi_driver *driv, const char *name)
{
- unsigned int i = 0;
- void *name_ptr;
-
- name_ptr=driv->board_name;
+ unsigned i;
+ const char **name_ptr = driv->board_name;
for(i = 0; i < driv->num_names; i++)
{
- if(strcmp(*(char **)name_ptr, name) == 0)
+ if(strcmp(*name_ptr, name) == 0)
return name_ptr;
name_ptr += driv->offset;
}
void comedi_report_boards(comedi_driver *driv)
{
unsigned int i;
- void *name_ptr;
+ const char **name_ptr;
printk("comedi: valid board names for %s driver are:\n", driv->driver_name);
- name_ptr=driv->board_name;
+ name_ptr = driv->board_name;
for(i = 0; i < driv->num_names; i++)
{
- printk(" %s\n", *(char **)name_ptr);
+ printk(" %s\n", *name_ptr);
name_ptr += driv->offset;
}
pmd_t *pmd;
pte_t *ptep, pte;
pud_t *pud;
-
+
if(!pgd_none(*pgd)){
pud = pud_offset(pgd, adr);
pmd = pmd_offset(pud, adr);
module: THIS_MODULE,
attach: acl7225b_attach,
detach: acl7225b_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
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;
if(dev->iobase)
release_region(dev->iobase, this_board->io_range);
-
+
return 0;
}
attach: adl_pci7296_attach,
detach: adl_pci7296_detach,
- board_name: adl_pci7296_boards,
+ board_name: (const char**)adl_pci7296_boards,
offset: sizeof(adl_pci7296_board),
num_names: sizeof(adl_pci7296_boards) / sizeof(adl_pci7296_board),
};
}
pci_dev_put(devpriv->pci_dev);
}
-
+
// detach four 8255 digital io subdevices
if(dev->subdevices)
{
attach: adl_pci7432_attach,
detach: adl_pci7432_detach,
num_names: 1,
- board_name: adl_pci7432_boards,
+ board_name: (const char**)adl_pci7432_boards,
offset: sizeof(adl_pci7432_board),
};
attach: adl_pci8164_attach,
detach: adl_pci8164_detach,
num_names: 1,
- board_name: adl_pci8164_boards,
+ board_name: (const char**)adl_pci8164_boards,
offset: sizeof(adl_pci8164_board),
};
/*
comedi/drivers/adl_pci9111.c
-
+
Hardware driver for PCI9111 ADLink cards:
-
+
PCI-9111HR
-
+
Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
-
+
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
- di_insn read
- do_insn read/write
- ai_do_cmd mode with the following sources:
-
+
- start_src TRIG_NOW
- scan_begin_src TRIG_FOLLOW TRIG_TIMER TRIG_EXT
- convert_src TRIG_TIMER TRIG_EXT
- scan_end_src TRIG_COUNT
- stop_src TRIG_COUNT TRIG_NONE
-
+
The scanned channels must be consecutive and start from 0. They must
all have the same range and aref.
-
+
Configuration options:
-
+
[0] - PCI bus number (optional)
[1] - PCI slot number (optional)
-
+
If bus/slot is not specified, the first available PCI
device will be used.
-
+
*/
/*
2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data.
2002/02/18 Added external trigger support for analog input.
-TODO:
+TODO:
- Really test implemented functionality.
- - Add support for the PCI-9111DG with a probe routine to identify the card type
- (perhaps with the help of the channel number readback of the A/D Data register).
+ - Add support for the PCI-9111DG with a probe routine to identify the card type
+ (perhaps with the help of the channel number readback of the A/D Data register).
- Add external multiplexer support.
*/
#define PCI9111_DO_MASK 0xFFFF
#define PCI9111_RANGE_SETTING_DELAY 10
-#define PCI9111_AI_INSTANT_READ_UDELAY_US 2
+#define PCI9111_AI_INSTANT_READ_UDELAY_US 2
#define PCI9111_AI_INSTANT_READ_TIMEOUT 100
#define PCI9111_8254_CLOCK_PERIOD_NS 500
/* IO address map */
-#define PCI9111_REGISTER_AD_FIFO_VALUE 0x00 // AD Data stored in FIFO
+#define PCI9111_REGISTER_AD_FIFO_VALUE 0x00 // AD Data stored in FIFO
#define PCI9111_REGISTER_DA_OUTPUT 0x00
#define PCI9111_REGISTER_DIGITAL_IO 0x02
#define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04
-#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 // Channel selection
+#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 // Channel selection
#define PCI9111_REGISTER_AD_CHANNEL_READBACK 0x06
#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE 0x08
#define PCI9111_REGISTER_RANGE_STATUS_READBACK 0x08
#define PCI9111_IO_BASE dev->iobase
-/*
+/*
* Define inlined function
*/
#define pci9111_interrupt_clear() \
outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR)
-
+
#define pci9111_software_trigger() \
outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER)
#define pci9111_hr_ai_get_data() \
(inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) & PCI9111_HR_AI_RESOLUTION_MASK) \
^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT
-
+
#define pci9111_ao_set_data(data) \
outw(data&PCI9111_AO_RESOLUTION_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
#define pci9111_do_set_bits(bits) \
outw(bits,PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
-
+
#define pci9111_8254_control_set(flags) \
outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL)
static pci9111_board_struct pci9111_boards[] =
{
{
- name: "pci9111_hr",
+ name: "pci9111_hr",
device_id: PCI9111_HR_DEVICE_ID,
- ai_channel_nbr: PCI9111_AI_CHANNEL_NBR,
+ ai_channel_nbr: PCI9111_AI_CHANNEL_NBR,
ao_channel_nbr: PCI9111_AO_CHANNEL_NBR,
ai_resolution: PCI9111_HR_AI_RESOLUTION,
- ai_resolution_mask: PCI9111_HR_AI_RESOLUTION_MASK,
+ ai_resolution_mask: PCI9111_HR_AI_RESOLUTION_MASK,
ao_resolution: PCI9111_AO_RESOLUTION,
- ao_resolution_mask: PCI9111_AO_RESOLUTION_MASK,
- ai_range_list: &pci9111_hr_ai_range,
+ ao_resolution_mask: PCI9111_AO_RESOLUTION_MASK,
+ ai_range_list: &pci9111_hr_ai_range,
ao_range_list: &range_bipolar10,
ai_acquisition_period_min_ns: PCI9111_AI_ACQUISITION_PERIOD_MIN_NS
}
attach: pci9111_attach,
detach: pci9111_detach,
num_names: pci9111_board_nbr,
- board_name: pci9111_boards,
+ board_name: (const char**)pci9111_boards,
offset: sizeof(pci9111_board_struct),
};
COMEDI_INITCLEANUP(pci9111_driver);
bool interrupt_enable)
{
int flags = 0;
-
+
if (LINTi1_enable) flags |= PLX9050_LINTI1_ENABLE;
if (LINTi1_active_high) flags |= PLX9050_LINTI1_ACTIVE_HIGH;
if (LINTi2_enable) flags |= PLX9050_LINTI2_ENABLE;
if (LINTi2_active_high) flags |= PLX9050_LINTI2_ACTIVE_HIGH;
if (interrupt_enable) flags |= PLX9050_PCI_INTERRUPT_ENABLE;
-
+
outb (flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL);
}
-
+
// ------------------------------------------------------------------
-//
+//
// MISCELLANEOUS SECTION
-//
+//
// ------------------------------------------------------------------
//
-// 8254 timer
+// 8254 timer
//
-static void pci9111_timer_set ( comedi_device * dev)
+static void pci9111_timer_set ( comedi_device * dev)
{
pci9111_8254_control_set ( PCI9111_8254_COUNTER_0|
PCI9111_8254_READ_LOAD_LSB_MSB|
software,
timer_pacer,
external
-}
+}
pci9111_trigger_sources;
-
+
static void pci9111_trigger_source_set (comedi_device *dev,
pci9111_trigger_sources source)
{
int flags;
-
+
flags = pci9111_trigger_and_autoscan_get() & 0x09;
switch (source)
flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER;
break;
- case external :
+ case external :
flags |= PCI9111_EITS_EXTERNAL;
break;
}
pci9111_trigger_and_autoscan_set (flags);
}
-typedef enum
+typedef enum
{
irq_on_eoc,
irq_on_fifo_half_full
{
irq_on_timer_tick,
irq_on_external_trigger
-}
+}
pci9111_ISC1_sources;
static void pci9111_interrupt_source_set (comedi_device *dev,
pci9111_ISC1_sources irq_1_source)
{
int flags;
-
+
flags = pci9111_interrupt_and_fifo_get() & 0x04;
- if (irq_0_source == irq_on_fifo_half_full)
+ if (irq_0_source == irq_on_fifo_half_full)
flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL;
-
+
if (irq_1_source == irq_on_external_trigger)
flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG;
-
+
pci9111_interrupt_and_fifo_set (flags);
}
// ------------------------------------------------------------------
-//
+//
// HARDWARE TRIGGERED ANALOG INPUT SECTION
-//
+//
// ------------------------------------------------------------------
//
comedi_subdevice *s)
{
// Disable interrupts
-
+
plx9050_interrupt_control (dev_private->lcr_io_base, true, true, true, true, false);
pci9111_trigger_source_set (dev, software);
-
+
pci9111_autoscan_set (dev, false);
pci9111_fifo_reset();
-
+
#ifdef AI_DO_CMD_DEBUG
printk (PCI9111_DRIVER_NAME ": ai_cancel\n");
#endif
-
+
return 0;
}
//
// Test analog input command
-//
-
+//
+
#define pci9111_check_trigger_src(src,flags) \
tmp = src; \
src &= flags; \
if (!src || tmp != src) error++
-static int
+static int
pci9111_ai_do_cmd_test ( comedi_device *dev,
comedi_subdevice *s,
comedi_cmd *cmd)
// be a multiple of chanlist_len*convert_arg
if (cmd->scan_begin_src == TRIG_TIMER) {
-
+
unsigned int scan_begin_min;
unsigned int scan_begin_arg;
unsigned int scan_factor;
-
+
scan_begin_min = cmd->chanlist_len * cmd->convert_arg;
-
+
if (cmd->scan_begin_arg != scan_begin_min) {
if (scan_begin_min < cmd->scan_begin_arg) {
scan_factor = cmd->scan_begin_arg / scan_begin_min;
cmd->scan_begin_arg = scan_begin_arg;
error++;
}
- } else {
+ } else {
cmd->scan_begin_arg = scan_begin_min;
error++;
}
if ((CR_CHAN (cmd->chanlist[0]) > (board->ai_channel_nbr -1)) ||
(CR_CHAN (cmd->chanlist[0]) < 0))
{
- comedi_error (dev,
+ comedi_error (dev,
"channel number is out of limits\n");
error++;
}
- }
+ }
}
if (error) return 5;
return 0;
-
+
}
//
static int pci9111_ai_do_cmd ( comedi_device *dev,
- comedi_subdevice *subdevice)
+ comedi_subdevice *subdevice)
{
comedi_cmd *async_cmd=&subdevice->async->cmd;
-
+
if (!dev->irq)
{
comedi_error (dev, "no irq assigned for PCI9111, cannot do hardware conversion");
// PCI9111 allows only scanning from channel 0 to channel n
//
// TODO: handle the case of an external multiplexer
- //
+ //
if (async_cmd->chanlist_len > 1)
{
// Set gain
//
// This is the same gain on every channel
- //
-
+ //
+
pci9111_ai_range_set (CR_RANGE(async_cmd->chanlist[0]));
/* Set counter */
pci9111_trigger_source_set (dev,timer_pacer);
plx9050_interrupt_control (dev_private->lcr_io_base, true, true, false, true, true);
- dev_private->scan_delay =
+ dev_private->scan_delay =
(async_cmd->scan_begin_arg / (async_cmd->convert_arg * async_cmd->chanlist_len)) - 1;
break;
dev_private->chanlist_len = async_cmd->chanlist_len;
dev_private->chunk_counter = 0;
dev_private->chunk_num_samples = dev_private->chanlist_len * (1 + dev_private->scan_delay);
-
+
#ifdef AI_DO_CMD_DEBUG
printk (PCI9111_DRIVER_NAME ": start interruptions!\n");
printk (PCI9111_DRIVER_NAME ": trigger source = %2x\n",
#undef INTERRUPT_DEBUG
-static irqreturn_t
+static irqreturn_t
pci9111_interrupt (int irq, void *p_device, struct pt_regs *regs)
{
comedi_device *dev=p_device;
comedi_spin_lock_irqsave (&dev->spinlock, irq_flags);
if ((inb (dev_private->lcr_io_base + PLX9050_REGISTER_INTERRUPT_CONTROL) &
- PLX9050_LINTI1_STATUS) != 0)
+ PLX9050_LINTI1_STATUS) != 0)
{
// Interrupt comes from fifo_half-full signal
{
unsigned int num_samples;
unsigned int bytes_written = 0;
-
+
#ifdef INTERRUPT_DEBUG
printk (PCI9111_DRIVER_NAME ": fifo is half full\n");
#endif
- num_samples = PCI9111_FIFO_HALF_SIZE > dev_private->stop_counter &&
+ num_samples = PCI9111_FIFO_HALF_SIZE > dev_private->stop_counter &&
!dev_private->stop_is_none ?
dev_private->stop_counter :
PCI9111_FIFO_HALF_SIZE;
- insw (PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE,
+ insw (PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE,
dev_private->ai_bounce_buffer,
num_samples);
if (dev_private->scan_delay < 1) {
- bytes_written = cfc_write_array_to_buffer (subdevice,
+ bytes_written = cfc_write_array_to_buffer (subdevice,
dev_private->ai_bounce_buffer,
num_samples * sizeof(sampl_t));
} else {
int position = 0;
int to_read;
-
+
while (position < num_samples) {
if (dev_private->chunk_counter < dev_private->chanlist_len) {
to_read = dev_private->chanlist_len - dev_private->chunk_counter;
if (to_read > num_samples - position)
to_read = num_samples - position;
- bytes_written += cfc_write_array_to_buffer (subdevice,
+ bytes_written += cfc_write_array_to_buffer (subdevice,
dev_private->ai_bounce_buffer + position,
to_read * sizeof(sampl_t));
} else {
bytes_written += sizeof(sampl_t) * to_read;
}
-
+
position += to_read;
dev_private->chunk_counter += to_read;
- if (dev_private->chunk_counter >= dev_private->chunk_num_samples)
+ if (dev_private->chunk_counter >= dev_private->chunk_num_samples)
dev_private->chunk_counter = 0;
}
}
pci9111_ai_cancel (dev, subdevice);
}
- /* Very important, otherwise another interrupt request will be inserted
+ /* Very important, otherwise another interrupt request will be inserted
* and will cause driver hangs on processing interrupt event. */
pci9111_interrupt_clear();
for (i=0;i<insn->n;i++)
{
pci9111_software_trigger();
-
+
timeout=PCI9111_AI_INSTANT_READ_TIMEOUT;
-
+
while (timeout--) {
if (!pci9111_is_fifo_empty()) goto conversion_done;
}
return -ETIME;
conversion_done:
-
+
if (resolution==PCI9111_HR_AI_RESOLUTION)
{
data[i] = pci9111_hr_ai_get_data();
- }
+ }
else
{
data[i] = pci9111_ai_get_data();
}
}
-
+
#ifdef AI_INSN_DEBUG
printk (PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n",
pci9111_ai_channel_get(),
// Analog instant output
//
-static int
+static int
pci9111_ao_insn_write ( comedi_device *dev,
- comedi_subdevice *s,
+ comedi_subdevice *s,
comedi_insn *insn,
lsampl_t *data )
{
return i;
}
-//
+//
// Analog output readback
//
-static int pci9111_ao_insn_read ( comedi_device * dev,
- comedi_subdevice * s,
- comedi_insn *insn,
- lsampl_t *data)
+static int pci9111_ao_insn_read ( comedi_device * dev,
+ comedi_subdevice * s,
+ comedi_insn *insn,
+ lsampl_t *data)
{
int i;
- for (i=0; i<insn->n; i++) {
+ for (i=0; i<insn->n; i++) {
data[i]=dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK;
}
}
// ------------------------------------------------------------------
-//
+//
// DIGITAL INPUT OUTPUT SECTION
-//
+//
// ------------------------------------------------------------------
//
// Digital inputs
//
-static int pci9111_di_insn_bits ( comedi_device *dev,
+static int pci9111_di_insn_bits ( comedi_device *dev,
comedi_subdevice *subdevice,
comedi_insn *insn,
lsampl_t *data)
bits = pci9111_di_get_bits();
data[1] = bits;
-
+
return 2;
}
// Digital outputs
//
-static int pci9111_do_insn_bits ( comedi_device *dev,
+static int pci9111_do_insn_bits ( comedi_device *dev,
comedi_subdevice *subdevice,
comedi_insn *insn,
lsampl_t *data)
// Only set bits that have been masked
// data[0] = mask
// data[1] = bit state
-
+
data[0] &= PCI9111_DO_MASK;
-
+
bits = subdevice->state;
bits &= ~data[0];
bits |= data[0] & data[1];
subdevice->state = bits;
-
+
pci9111_do_set_bits(bits);
data[1] = bits;
-
+
return 2;
}
// ------------------------------------------------------------------
-//
+//
// INITIALISATION SECTION
-//
+//
// ------------------------------------------------------------------
//
// Reset device
-//
+//
static int pci9111_reset (comedi_device *dev)
-{
+{
// Set trigger source to software
-
+
plx9050_interrupt_control (dev_private->lcr_io_base, true, true, true, true, false);
pci9111_trigger_source_set (dev, software);
pci9111_autoscan_set (dev,false);
// Reset 8254 chip
-
+
dev_private->timer_divisor_1=0;
dev_private->timer_divisor_2=0;
-
+
pci9111_timer_set (dev);
return 0;
}
//
-// Attach
-//
+// Attach
+//
// - Register PCI device
// - Declare device driver capability
-//
+//
static int pci9111_attach(comedi_device *dev,comedi_devconfig *it)
{
struct pci_dev* pci_device;
int error,i;
pci9111_board_struct* board;
-
+
if(alloc_private(dev, sizeof(pci9111_private_data_struct)) < 0)
{
return -ENOMEM;
//
// Probe the device to determine what device in the series it is.
//
-
+
printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n",dev->minor);
- for(pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_device != NULL ;
- pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device))
+ for(pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_device != NULL ;
+ pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device))
{
if (pci_device->vendor == PCI_VENDOR_ID_ADLINK)
{
continue;
}
}
-
+
dev->board_ptr = pci9111_boards + i;
board = (pci9111_board_struct *) dev->board_ptr;
dev_private->pci_device = pci_device;
}
}
}
-
+
printk ("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
dev->minor,it->options[0], it->options[1]);
return -EIO;
-
+
found:
-
- printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
+
+ printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
dev->minor,
pci9111_boards[i].name,
pci_device->bus->number,
PCI_SLOT(pci_device->devfn),
PCI_FUNC(pci_device->devfn),
pci_device->irq);
-
+
// TODO: Warn about non-tested boards.
-
+
switch(board->device_id)
{
};
-
+
// Read local configuration register base address [PCI_BASE_ADDRESS #1].
-
+
lcr_io_base = pci_resource_start (pci_device, 1);
lcr_io_range = pci_resource_len (pci_device, 1);
-
+
printk ("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n",
dev->minor,
lcr_io_base,
lcr_io_range);
-
+
// Enable PCI device
if(pci_enable_device (pci_device) < 0)
{
printk("comedi%d: Failed to enable PCI device\n", dev->minor);
return -EIO;
}
-
+
// Read PCI6308 register base address [PCI_BASE_ADDRESS #2].
-
+
io_base = pci_resource_start (pci_device, 2);
io_range = pci_resource_len (pci_device, 2);
-
+
printk ("comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n",
dev->minor,
io_base,
io_range);
-
+
// Allocate IO ressources
if(pci_request_regions(pci_device, PCI9111_DRIVER_NAME))
{
printk("comedi%d: I/O port conflict\n",dev->minor);
return -EIO;
}
-
+
dev->iobase=io_base;
dev->board_name = board->name;
dev_private->io_range = io_range;
dev_private->is_valid=0;
dev_private->lcr_io_base=lcr_io_base;
dev_private->lcr_io_range=lcr_io_range;
-
+
pci9111_reset(dev);
// Irq setup
-
+
dev->irq=0;
- if (pci_device->irq>0)
+ if (pci_device->irq>0)
{
if (comedi_request_irq (pci_device->irq,
- pci9111_interrupt,
- SA_SHIRQ,
- PCI9111_DRIVER_NAME,
+ pci9111_interrupt,
+ SA_SHIRQ,
+ PCI9111_DRIVER_NAME,
dev)!=0)
{
printk ("comedi%d: unable to allocate irq %u\n", dev->minor, pci_device->irq);
}
}
dev->irq = pci_device->irq;
-
+
//
// TODO: Add external multiplexer setup (according to option[2]).
//
-
+
if((error=alloc_subdevices(dev, 4))<0)
return error;
-
+
subdevice = dev->subdevices + 0;
dev->read_subdev = subdevice;
-
+
subdevice->type = COMEDI_SUBD_AI;
subdevice->subdev_flags = SDF_READABLE|SDF_COMMON;
-
+
//
// TODO: Add external multiplexer data
//
static int pci9111_detach(comedi_device *dev)
{
// Reset device
-
+
if (dev->private!=0)
{
if (dev_private->is_valid) pci9111_reset(dev);
-
+
}
-
+
// Release previously allocated irq
-
+
if (dev->irq!=0)
{
comedi_free_irq(dev->irq,dev);
}
-
+
if (dev_private!=0 && dev_private->pci_device!=0)
{
if(dev->iobase)
}
pci_dev_put(dev_private->pci_device);
}
-
+
return 0;
}
unsigned int ai_ns_min; // max sample speed of card v ns
unsigned int ai_pacer_min; // minimal pacer value (c1*c2 or c1 in burst)
int half_fifo_size; // size of FIFO/2
-
+
} boardtype;
static struct pci_device_id pci9118_pci_table[] __devinitdata = {
3000, 12, 512 },
{"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9,
AMCC_OP_REG_SIZE, IORANGE_9118,
- 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
+ 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
&range_pci9118hg, &range_bipolar10,
3000, 12, 512 },
{"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9,
AMCC_OP_REG_SIZE, IORANGE_9118,
- 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
+ 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
&range_pci9118dg_hr, &range_bipolar10,
10000, 40, 512 },
};
attach: pci9118_attach,
detach: pci9118_detach,
num_names: n_boardtypes,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
offset: sizeof(boardtype),
};
COMEDI_INITCLEANUP(driver_pci9118);
unsigned int ai_add_front; // how many channels we must add before scan to satisfy S&H?
unsigned int ai_add_back; // how many channels we must add before scan to satisfy DMA?
unsigned int *ai_chanlist;// actaul chanlist
- unsigned int ai_timer1;
+ unsigned int ai_timer1;
unsigned int ai_timer2;
unsigned int ai_flags;
char ai12_startstop; // measure can start/stop on external trigger
unsigned int dmabuf_size[2]; // size of dma buffer in bytes
unsigned int dmabuf_use_size[2]; // which size we may now used for transfer
unsigned int dmabuf_used_size[2]; // which size was trully used
- unsigned int dmabuf_panic_size[2];
+ unsigned int dmabuf_panic_size[2];
unsigned int dmabuf_samples[2]; // size in samples
int dmabuf_pages[2]; // number of pages in buffer
unsigned char cnt0_users; // bit field of 8254 CNT0 users (0-unused, 1-AO, 2-DI, 3-DO)
static int pci9118_exttrg_add(comedi_device * dev, unsigned char source);
static int pci9118_exttrg_del(comedi_device * dev, unsigned char source);
static int pci9118_ai_cancel(comedi_device * dev, comedi_subdevice * s);
-static void pci9118_calc_divisors(char mode, comedi_device * dev, comedi_subdevice * s,
- unsigned int *tim1, unsigned int *tim2, unsigned int flags,
+static void pci9118_calc_divisors(char mode, comedi_device * dev, comedi_subdevice * s,
+ unsigned int *tim1, unsigned int *tim2, unsigned int flags,
int chans, unsigned int *div1, unsigned int *div2,
char usessh, unsigned int chnsshfront);
if (devpriv->ai16bits) {
data[n] = (inl(dev->iobase+PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
} else {
- data[n] = (inw(dev->iobase+PCI9118_AD_DATA)>>4) & 0xfff;
+ data[n] = (inw(dev->iobase+PCI9118_AD_DATA)>>4) & 0xfff;
}
}
ch=CR_CHAN(insn->chanspec);
if (ch) { chanreg=PCI9118_DA2;}
- else { chanreg=PCI9118_DA1; }
+ else { chanreg=PCI9118_DA1; }
for (n=0; n<insn->n; n++) {
outl(data[n], dev->iobase + chanreg);
return n;
}
-/*
+/*
==============================================================================
*/
-static int pci9118_insn_read_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
+static int pci9118_insn_read_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
{
int n,chan;
-
+
chan=CR_CHAN(insn->chanspec);
- for (n=0; n<insn->n; n++)
+ for (n=0; n<insn->n; n++)
data[n]=devpriv->ao_data[chan];
return n;
comedi_event(dev,s,s->async->events);
}
-/*
+/*
==============================================================================
*/
static irqreturn_t interrupt_pci9118(int irq, void *d, struct pt_regs *regs)
if (cmd->scan_begin_src!=TRIG_TIMER &&
cmd->scan_begin_src!=TRIG_EXT &&
cmd->scan_begin_src!=TRIG_INT &&
- cmd->scan_begin_src!=TRIG_FOLLOW) {
+ cmd->scan_begin_src!=TRIG_FOLLOW) {
cmd->scan_begin_src=TRIG_FOLLOW;
err++;
}
cmd->convert_src=TRIG_TIMER;
err++;
}
-
+
if ((cmd->scan_begin_src==TRIG_FOLLOW) &&
(!(cmd->convert_src&(TRIG_TIMER|TRIG_EXT)))) {
cmd->convert_src=TRIG_TIMER;
err++;
}
-
+
if (cmd->stop_src==TRIG_EXT &&
cmd->scan_begin_src==TRIG_EXT) {
cmd->stop_src=TRIG_COUNT;
/* step 3: make sure arguments are trivially compatible */
- if (cmd->start_src&(TRIG_NOW|TRIG_EXT))
+ if (cmd->start_src&(TRIG_NOW|TRIG_EXT))
if (cmd->start_arg!=0) {
cmd->start_arg=0;
err++;
cmd->convert_arg=cmd->scan_begin_arg;
cmd->scan_begin_arg=0;
}
-
+
if (cmd->scan_begin_src==TRIG_TIMER)
if (cmd->scan_begin_arg<this_board->ai_ns_min) {
cmd->scan_begin_arg=this_board->ai_ns_min;
if(cmd->scan_begin_arg<this_board->ai_ns_min)
cmd->scan_begin_arg=this_board->ai_ns_min;
if(tmp!=cmd->scan_begin_arg)err++;
- }
+ }
if (cmd->convert_src&(TRIG_TIMER|TRIG_NOW)) {
tmp=cmd->convert_arg;
dmalen1=devpriv->ai_data_len&~3L; // allign to 32bit down
}
DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
-
+
// we want wake up every scan?
if (devpriv->ai_flags & TRIG_WAKE_EOS) {
if (dmalen0<(devpriv->ai_n_realscanlen<<1)) {
{
DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",dev->minor,devpriv->ai_do);
switch (devpriv->ai_do) {
- case 1:
+ case 1:
devpriv->AdControlReg|=AdControl_TmrTr;
break;
- case 2:
+ case 2:
comedi_error(dev,"pci9118_ai_docmd_sampl() mode 2 bug!\n");
return -EIO;
- case 3:
+ case 3:
devpriv->AdControlReg|=AdControl_ExtM;
break;
- case 4:
+ case 4:
comedi_error(dev,"pci9118_ai_docmd_sampl() mode 4 bug!\n");
return -EIO;
- default:
+ default:
comedi_error(dev,"pci9118_ai_docmd_sampl() mode number bug!\n");
return -EIO;
- };
+ };
devpriv->int_ai_func=interrupt_pci9118_ai_onesample; //transfer function
if (devpriv->ai12_startstop)
pci9118_exttrg_add(dev,EXTTRG_AI); // activate EXT trigger
-
- if ((devpriv->ai_do==1)||(devpriv->ai_do==2))
+
+ if ((devpriv->ai_do==1)||(devpriv->ai_do==2))
devpriv->IntControlReg|=Int_Timer;
devpriv->AdControlReg|=AdControl_Int;
-
+
outl(inl(devpriv->iobase_a+AMCC_OP_REG_INTCSR)|0x1f00, devpriv->iobase_a+AMCC_OP_REG_INTCSR); // allow INT in AMCC
if (!(devpriv->ai12_startstop&(START_AI_EXT|START_AI_INT))) {
return 0;
}
-/*
+/*
==============================================================================
*/
-static int pci9118_ai_docmd_dma(comedi_device * dev, comedi_subdevice * s)
+static int pci9118_ai_docmd_dma(comedi_device * dev, comedi_subdevice * s)
{
DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",dev->minor,devpriv->ai_do,devpriv->usedma);
Compute_and_setup_dma(dev);
comedi_cmd *cmd=&s->async->cmd;
unsigned int addchans=0;
int ret=0;
-
+
DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n",dev->minor);
devpriv->ai12_startstop=0;
devpriv->ai_flags=cmd->flags;
if (cmd->stop_src==TRIG_NONE) devpriv->ai_neverending=1;
if (cmd->stop_src==TRIG_COUNT) { devpriv->ai_scans=cmd->stop_arg; devpriv->ai_neverending=0; }
else { devpriv->ai_scans=0; }
-
+
// use sample&hold signal?
- if (cmd->convert_src==TRIG_NOW) { devpriv->usessh=1; } // yes
+ if (cmd->convert_src==TRIG_NOW) { devpriv->usessh=1; } // yes
else { devpriv->usessh=0; } // no
- DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
+ DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh, devpriv->ai12_startstop);
// use additional sample at end of every scan to satisty DMA 32 bit transfer?
}
// we need software S&H signal? It add two samples before every scan as minimum
- if (devpriv->usessh&&devpriv->softsshdelay) {
+ if (devpriv->usessh&&devpriv->softsshdelay) {
devpriv->ai_add_front=2;
if ((devpriv->usedma==1)&&(devpriv->ai_add_back==1)) {// move it to front
devpriv->ai_add_front++;
if ((devpriv->ai_add_front+devpriv->ai_n_chan+devpriv->ai_add_back)&1) devpriv->ai_add_front++; // round up to 32 bit
}
} // well, we now know what must be all added
-
+
devpriv->ai_n_realscanlen= // what we must take from card in real to have ai_n_scanlen on output?
(devpriv->ai_add_front+devpriv->ai_n_chan+devpriv->ai_add_back)*
(devpriv->ai_n_scanlen / devpriv->ai_n_chan);
DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
devpriv->usedma,
- devpriv->ai_n_realscanlen, devpriv->ai_add_front, devpriv->ai_n_chan,
+ devpriv->ai_n_realscanlen, devpriv->ai_add_front, devpriv->ai_n_chan,
devpriv->ai_add_back, devpriv->ai_n_scanlen);
-
+
// check and setup channel list
if (!check_channel_list(dev, s, devpriv->ai_n_chan, devpriv->ai_chanlist,
devpriv->ai_add_front, devpriv->ai_add_back)) return -EINVAL;
- if (!setup_channel_list(dev, s, devpriv->ai_n_chan, devpriv->ai_chanlist,
- 0, devpriv->ai_add_front, devpriv->ai_add_back, devpriv->usedma,
+ if (!setup_channel_list(dev, s, devpriv->ai_n_chan, devpriv->ai_chanlist,
+ 0, devpriv->ai_add_front, devpriv->ai_add_back, devpriv->usedma,
devpriv->useeoshandle)) return -EINVAL;
} else {
devpriv->ai_do=1;
}
- pci9118_calc_divisors(devpriv->ai_do, dev, s,
- &cmd->scan_begin_arg, &cmd->convert_arg, devpriv->ai_flags,
- devpriv->ai_n_realscanlen, &devpriv->ai_divisor1, &devpriv->ai_divisor2,
+ pci9118_calc_divisors(devpriv->ai_do, dev, s,
+ &cmd->scan_begin_arg, &cmd->convert_arg, devpriv->ai_flags,
+ devpriv->ai_n_realscanlen, &devpriv->ai_divisor1, &devpriv->ai_divisor2,
devpriv->usessh, devpriv->ai_add_front);
devpriv->ai_timer2=cmd->convert_arg;
}
comedi_error(dev,"cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!");
return -EIO;
}
-
+
devpriv->ai_do=2;
- pci9118_calc_divisors(devpriv->ai_do, dev, s,
- &cmd->scan_begin_arg, &cmd->convert_arg, devpriv->ai_flags,
- devpriv->ai_n_realscanlen, &devpriv->ai_divisor1, &devpriv->ai_divisor2,
+ pci9118_calc_divisors(devpriv->ai_do, dev, s,
+ &cmd->scan_begin_arg, &cmd->convert_arg, devpriv->ai_flags,
+ devpriv->ai_n_realscanlen, &devpriv->ai_divisor1, &devpriv->ai_divisor2,
devpriv->usessh, devpriv->ai_add_front);
devpriv->ai_timer1=cmd->scan_begin_arg;
devpriv->ai_timer2=cmd->convert_arg;
}
- if ((cmd->scan_begin_src==TRIG_FOLLOW)&&(cmd->convert_src==TRIG_EXT)) {
+ if ((cmd->scan_begin_src==TRIG_FOLLOW)&&(cmd->convert_src==TRIG_EXT)) {
devpriv->ai_do=3;
}
int n_chan, unsigned int *chanlist, int frontadd, int backadd)
{
unsigned int i, differencial=0, bipolar=0;
-
+
/* correct channel and range number check itself comedi/range.c */
if (n_chan<1) {
comedi_error(dev,"range/channel list is empty!");
- return 0;
+ return 0;
}
if ((frontadd+n_chan+backadd)>s->len_chanlist) {
rt_printk("comedi%d: range/channel list is too long for actual configuration (%d>%d)!",dev->minor,n_chan,s->len_chanlist-frontadd-backadd);
- return 0;
+ return 0;
}
-
+
if (CR_AREF(chanlist[0])==AREF_DIFF)
differencial=1; // all input must be diff
if (CR_RANGE(chanlist[0])<PCI9118_BIPOLAR_RANGES)
}
DPRINTK("\n ");
}
-
+
#ifdef PCI9118_PARANOIDCHECK
devpriv->chanlist[n_chan^usedma]=devpriv->chanlist[0^usedma]; // for 32bit oerations
if (useeos) {
==============================================================================
calculate 8254 divisors if they are used for dual timing
*/
-static void pci9118_calc_divisors(char mode, comedi_device * dev, comedi_subdevice * s,
- unsigned int *tim1, unsigned int *tim2, unsigned int flags,
- int chans, unsigned int *div1, unsigned int *div2,
+static void pci9118_calc_divisors(char mode, comedi_device * dev, comedi_subdevice * s,
+ unsigned int *tim1, unsigned int *tim2, unsigned int flags,
+ int chans, unsigned int *div1, unsigned int *div2,
char usessh, unsigned int chnsshfront)
{
DPRINTK("adl_pci9118 EDBG: BGN: pci9118_calc_divisors(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n",
if (usessh & (chnsshfront==0)) // use BSSH signal
if (*div2<(chans+2))
*div2=chans+2;
-
+
DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n",*div1,*div2,*tim1,*tim2);
*tim1= *div1 * *div2 * devpriv->i8254_osc_base;
DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",devpriv->i8254_osc_base,*div1,*div2,*tim1,*tim2);
}
DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
*div1, *div2);
-}
+}
/*
==============================================================================
*/
-static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2)
+static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2)
{
outl(0x74, dev->iobase + PCI9118_CNTCTRL);
outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
// outl(0x30, dev->iobase + PCI9118_CNTCTRL);
comedi_udelay(1);
-
+
if ((mode==1)||(mode==2)||(mode==4)) {
outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci9118_exttrg_del(comedi_device * dev, unsigned char source)
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci9118_ai_cancel(comedi_device * dev, comedi_subdevice * s)
devpriv->ai_do=0;
devpriv->usedma=0;
-
+
devpriv->ai_act_scan=0;
devpriv->ai_act_dmapos=0;
s->async->cur_chan=0;
if (!devpriv->IntControlReg)
outl(inl(devpriv->iobase_a+AMCC_OP_REG_INTCSR)|0x1f00, devpriv->iobase_a+AMCC_OP_REG_INTCSR); // allow INT in AMCC
-
+
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci9118_reset(comedi_device *dev)
outl(0,dev->iobase+PCI9118_INTSRC); // remove INT requests
inl(dev->iobase+PCI9118_ADSTAT); // flush A/D status register
inl(dev->iobase+PCI9118_INTSRC); // flush INT requests
- devpriv->AdControlReg=0;
+ devpriv->AdControlReg=0;
outl(devpriv->AdControlReg,dev->iobase+PCI9118_ADCNTRL);// bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
devpriv->cnt0_users=0;
devpriv->exttrg_users=0;
-
+
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci9118_attach(comedi_device *dev,comedi_devconfig *it)
const char *errstr;
unsigned char pci_bus,pci_slot,pci_func;
u16 u16w;
-
+
rt_printk("comedi%d: adl_pci9118: board=%s",dev->minor,this_board->name);
opt_bus = it->options[0];
iobase_9 = pci_resource_start(pcidev, 2);
rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx",pci_bus,pci_slot,pci_func,iobase_9,iobase_a);
-
+
dev->iobase=iobase_9;
dev->board_name = this_board->name;
devpriv->pcidev=pcidev;
devpriv->iobase_a=iobase_a;
-
+
if (it->options[3]&2) irq=0; // user don't want use IRQ
if (irq>0) {
if (comedi_request_irq(irq, interrupt_pci9118, SA_SHIRQ, "ADLink PCI-9118", dev)) {
irq=0; /* Can't use IRQ */
} else {
rt_printk(", irq=%u", irq);
- }
+ }
} else {
rt_printk(", IRQ disabled");
}
devpriv->dma_doublebuf=1;
}
-
+
if ((devpriv->master=master)) {
rt_printk(", bus master");
} else {
devpriv->softsshsample=0x00;
devpriv->softsshhold=0x80;
}
-
+
rt_printk(".\n");
pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
}
-/*
+/*
==============================================================================
*/
static int pci9118_detach(comedi_device *dev)
* driver: pci1710, pci1710hg, pci1711, pci1713, pci1720, pci1731
*
* Options:
- * [0] - PCI bus number - if bus number and slot number are 0,
+ * [0] - PCI bus number - if bus number and slot number are 0,
* then driver search for first unused card
- * [1] - PCI slot number
- *
+ * [1] - PCI slot number
+ *
*/
/*
Driver: adv_pci1710.o
#define TYPE_PCI1713 2
#define TYPE_PCI1720 3
-#define IORANGE_171x 32
-#define IORANGE_1720 16
+#define IORANGE_171x 32
+#define IORANGE_1720 16
#define PCI171x_AD_DATA 0 /* R: A/D data */
#define PCI171x_SOFTTRG 0 /* W: soft trigger for A/D */
#define Counter_BCD 0x0001 /* 0 = binary counter, 1 = BCD counter */
#define Counter_M0 0x0002 /* M0-M2 select modes 0-5 */
#define Counter_M1 0x0004 /* 000 = mode 0, 010 = mode 2 ... */
-#define Counter_M2 0x0008
+#define Counter_M2 0x0008
#define Counter_RW0 0x0010 /* RW0/RW1 select read/write mode */
#define Counter_RW1 0x0020
#define Counter_SC0 0x0040 /* Select Counter. Only 00 or 11 may */
attach: pci1710_attach,
detach: pci1710_detach,
num_names: n_boardtypes,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
offset: sizeof(boardtype),
};
unsigned char act_chanlist_pos;// actual position in MUX list
unsigned char da_ranges; // copy of D/A outpit range register
unsigned int ai_scans; // len of scanlist
- unsigned int ai_n_chan; // how many channels is measured
+ unsigned int ai_n_chan; // how many channels is measured
unsigned int *ai_chanlist; // actaul chanlist
unsigned int ai_flags; // flaglist
unsigned int ai_data_len; // len of data buffer
#define devpriv ((pci1710_private *)dev->private)
#define this_board ((boardtype *)dev->board_ptr)
-/*
+/*
==============================================================================
*/
0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f};
-/*
+/*
==============================================================================
*/
-static int pci171x_insn_read_ai(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
+static int pci171x_insn_read_ai(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
{
int n,timeout;
#ifdef PCI171x_PARANOIDCHECK
outw(devpriv->CntrlReg, dev->iobase+PCI171x_CONTROL);
outb(0,dev->iobase + PCI171x_CLRFIFO);
outb(0,dev->iobase + PCI171x_CLRINT);
-
+
setup_channel_list(dev,s,&insn->chanspec, 1, 1);
DPRINTK("adv_pci1710 A ST=%4x IO=%x\n",inw(dev->iobase+PCI171x_STATUS), dev->iobase+PCI171x_STATUS);
comedi_error(dev,"A/D insn data droput!");
return -ETIME;
}
- data[n] = idata & 0x0fff;
+ data[n] = idata & 0x0fff;
#else
- data[n] = inw(dev->iobase+PCI171x_AD_DATA) & 0x0fff;
+ data[n] = inw(dev->iobase+PCI171x_AD_DATA) & 0x0fff;
#endif
}
-
+
outb(0,dev->iobase + PCI171x_CLRFIFO);
outb(0,dev->iobase + PCI171x_CLRINT);
return n;
}
-/*
+/*
==============================================================================
*/
-static int pci171x_insn_write_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
+static int pci171x_insn_write_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
{
int n,chan,range,ofs;
chan=CR_CHAN(insn->chanspec);
range=CR_RANGE(insn->chanspec);
- if (chan) {
+ if (chan) {
devpriv->da_ranges&=0xfb;
devpriv->da_ranges|=(range<<2);
outw(devpriv->da_ranges, dev->iobase+PCI171x_DAREF);
ofs=PCI171x_DA1;
}
- for (n=0; n<insn->n; n++)
+ for (n=0; n<insn->n; n++)
outw(data[n], dev->iobase + ofs);
devpriv->ao_data[chan]=data[n];
}
-/*
+/*
==============================================================================
*/
-static int pci171x_insn_read_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
+static int pci171x_insn_read_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
{
int n,chan;
-
+
chan=CR_CHAN(insn->chanspec);
- for (n=0; n<insn->n; n++)
+ for (n=0; n<insn->n; n++)
data[n]=devpriv->ao_data[chan];
return n;
if ( /* count and status */ )
ccntrl = 0xC2;
/* status, if latched, first */
- data[1] = inw(dev->iobase+PCI171x_CNT0);
+ data[1] = inw(dev->iobase+PCI171x_CNT0);
}
#endif
#ifdef unused
/* This doesn't work like a normal Comedi counter config */
uint ccntrl = 0;
-
+
devpriv->cnt0_write_wait = data[0] & 0x20;
/* internal or external clock? */
ccntrl |= Counter_RW1;
outw(ccntrl, dev->iobase+PCI171x_CNTCTRL);
#endif
-
+
return 1;
}
-/*
+/*
==============================================================================
*/
-static int pci1720_insn_write_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
+static int pci1720_insn_write_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data)
{
int n,rangereg,chan;
comedi_event(dev,s,s->async->events);
}
-/*
+/*
==============================================================================
*/
static int move_block_from_fifo(comedi_device *dev,comedi_subdevice *s, int n, int turn)
return 0;
}
-/*
+/*
==============================================================================
*/
-static void interrupt_pci1710_half_fifo(void *d)
+static void interrupt_pci1710_half_fifo(void *d)
{
comedi_device *dev = d;
comedi_subdevice *s = dev->subdevices + 0;
int m,samplesinbuf;
-
+
DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_half_fifo(...)\n");
m=inw(dev->iobase+PCI171x_STATUS);
if (!(m & Status_FH)) {
rt_printk("comedi%d: A/D FIFO not half full! (%4x)\n", dev->minor, m);
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev,s,s->async->events);
return;
}
if (m & Status_FF) {
rt_printk("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n", dev->minor, m);
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev,s,s->async->events);
return;
}
if ( devpriv->ai_act_scan>=devpriv->ai_scans ) { /* all data sampled */
pci171x_ai_cancel(dev,s);
s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev,s,s->async->events);
+ comedi_event(dev,s,s->async->events);
return;
}
outb(0, dev->iobase + PCI171x_CLRINT); // clear our INT request
outb(0, dev->iobase + PCI171x_CLRFIFO);
outb(0, dev->iobase + PCI171x_CLRINT);
-
+
devpriv->ai_do=mode;
devpriv->ai_act_scan=0;
outw(devpriv->CntrlReg, dev->iobase+PCI171x_CONTROL);
break;
}
-
-
+
+
DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_docmd_and_mode(...)\n");
return 0;
}
#ifdef PCI171X_EXTDEBUG
-/*
+/*
==============================================================================
*/
static void pci171x_cmdtest_out(int e,comedi_cmd *cmd) {
}
#endif
-/*
+/*
==============================================================================
*/
static int pci171x_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci171x_ai_cmd(comedi_device *dev,comedi_subdevice *s)
return pci171x_ai_docmd_and_mode(3,dev,s);
}
}
-
+
return -1;
}
/*
==============================================================================
- Check if channel list from user is builded correctly
+ Check if channel list from user is builded correctly
If it's ok, then program scan/gain logic.
This works for all cards.
*/
static int check_channel_list(comedi_device * dev, comedi_subdevice * s, unsigned int *chanlist, unsigned int n_chan)
{
- unsigned int chansegment[32];
+ unsigned int chansegment[32];
unsigned int i, nowmustbechan, seglen, segpos;
-
+
DPRINTK("adv_pci1710 EDBG: check_channel_list(...,%d)\n",n_chan);
/* correct channel and range number check itself comedi/range.c */
if (n_chan<1) {
return 0;
}
nowmustbechan=(CR_CHAN(chansegment[i-1])+1) % s->n_chan;
- if (CR_AREF(chansegment[i-1])==AREF_DIFF)
+ if (CR_AREF(chansegment[i-1])==AREF_DIFF)
nowmustbechan=(nowmustbechan+1) % s->n_chan;
if (nowmustbechan!=CR_CHAN(chanlist[i])) { // channel list isn't continous :-(
rt_printk("channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
}
return seglen;
}
-
+
static void setup_channel_list(comedi_device * dev, comedi_subdevice * s, unsigned int *chanlist,
unsigned int n_chan, unsigned int seglen)
{
unsigned int i, range, chanprog;
-
+
DPRINTK("adv_pci1710 EDBG: setup_channel_list(...,%d,%d)\n",n_chan,seglen);
devpriv->act_chanlist_len=seglen;
devpriv->act_chanlist_pos=0;
/*
==============================================================================
*/
-static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2)
+static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2)
{
DPRINTK("adv_pci1710 EDBG: BGN: start_pacer(%d,%u,%u)\n",mode,divisor1,divisor2);
outw(0xb4, dev->iobase + PCI171x_CNTCTRL);
outw(0x74, dev->iobase + PCI171x_CNTCTRL);
-
+
if (mode==1) {
outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2);
outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2);
DPRINTK("adv_pci1710 EDBG: END: start_pacer(...)\n");
}
-/*
+/*
==============================================================================
*/
static int pci171x_ai_cancel(comedi_device * dev, comedi_subdevice * s)
default:
devpriv->CntrlReg&=Control_CNT0;
devpriv->CntrlReg|=Control_SW;
-
+
outw(devpriv->CntrlReg, dev->iobase+PCI171x_CONTROL); // reset any operations
start_pacer(dev,-1,0,0);
outb(0,dev->iobase + PCI171x_CLRFIFO);
outb(0,dev->iobase + PCI171x_CLRINT);
break;
- }
-
+ }
+
devpriv->ai_do=0;
devpriv->ai_act_scan=0;
s->async->cur_chan=0;
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci171x_reset(comedi_device *dev)
if (this_board->n_aochan) {
outb(devpriv->da_ranges, dev->iobase+PCI171x_DAREF); // set DACs to 0..5V
outw(0, dev->iobase+PCI171x_DA1); // set DA outputs to 0V
- devpriv->ao_data[0]=0x0000;
+ devpriv->ao_data[0]=0x0000;
if (this_board->n_aochan>1) {
outw(0, dev->iobase+PCI171x_DA2);
devpriv->ao_data[1]=0x0000;
outw(0, dev->iobase + PCI171x_DO); // digital outputs to 0
outb(0, dev->iobase + PCI171x_CLRFIFO); // clear FIFO
outb(0, dev->iobase + PCI171x_CLRINT); // clear INT request
-
+
DPRINTK("adv_pci1710 EDBG: END: pci171x_reset(...)\n");
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci1720_reset(comedi_device *dev)
DPRINTK("adv_pci1710 EDBG: BGN: pci1720_reset(...)\n");
outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT); // set synchronous output mode
devpriv->da_ranges=0xAA;
- outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE); // set all ranges to +/-5V
+ outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE); // set all ranges to +/-5V
outw(0x0800, dev->iobase + PCI1720_DA0); // set outputs to 0V
outw(0x0800, dev->iobase + PCI1720_DA1);
outw(0x0800, dev->iobase + PCI1720_DA2);
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci1710_reset(comedi_device *dev)
DPRINTK("adv_pci1710 EDBG: END: pci1710_reset(...)\n");
}
-/*
+/*
==============================================================================
*/
static int pci1710_attach(comedi_device *dev,comedi_devconfig *it)
irq=0; /* Can't use IRQ */
} else {
rt_printk(", irq=%u", irq);
- }
+ }
} else {
rt_printk(", IRQ disabled");
}
} else {
irq=0;
}
-
+
dev->irq = irq;
printk(".\n");
subdev=0;
-
+
if (this_board->n_aichan) {
s = dev->subdevices + subdev;
dev->read_subdev = s;
if (irq) {
s->do_cmdtest=pci171x_ai_cmdtest;
s->do_cmd=pci171x_ai_cmd;
- }
+ }
devpriv->i8254_osc_base=100; // 100ns=10MHz
subdev++;
}
-
+
if (this_board->n_aochan) {
s = dev->subdevices + subdev;
s->type = COMEDI_SUBD_AO;
s->insn_bits=pci171x_insn_bits_do;
subdev++;
}
-
+
if (this_board->n_counter) {
s = dev->subdevices + subdev;
s->type = COMEDI_SUBD_COUNTER;
s->insn_config = pci171x_insn_counter_config;
subdev++;
}
-
+
devpriv->valid=1;
pci1710_reset(dev);
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci1710_detach(comedi_device *dev)
{
-
+
if (dev->private) {
if (devpriv->valid) pci1710_reset(dev);
if (dev->irq) comedi_free_irq(dev->irq,dev);
return 0;
}
-/*
+/*
==============================================================================
*/
COMEDI_INITCLEANUP(driver_pci1710);
-/*
+/*
==============================================================================
*/
Devices: [Advantech] PCI-1730 (pci1730), PCI-1733 (pci1733),
PCI-1734 (pci1734), PCI-1750 (pci1750), PCI-1751 (pci1751),
PCI-1752 (pci1752), PCI-1753 (pci1753), PCI-1753+PCI-1753E (pci1753e),
- PCI-1754 (pci1754), PCI-1756 (pci1756), PCI-1760(pci1760),
+ PCI-1754 (pci1754), PCI-1756 (pci1756), PCI-1760(pci1760),
PCI-1762 (pci1762)
Status: untested
Updated: 2003-04-06
// hardware types of the cards
typedef enum {
TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734,
- TYPE_PCI1750,
+ TYPE_PCI1750,
TYPE_PCI1751,
- TYPE_PCI1752,
+ TYPE_PCI1752,
TYPE_PCI1753, TYPE_PCI1753E,
TYPE_PCI1754, TYPE_PCI1756,
TYPE_PCI1760,
{{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
{{ 0, 0, 0, 0}, { 0, 0, 0, 0}},
{ 4, PCI173x_BOARDID, 1, SDF_INTERNAL},
- IO_8b,
+ IO_8b,
},
{"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG,
TYPE_PCI1733,
attach: pci_dio_attach,
detach: pci_dio_detach,
num_names: n_boardtypes,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
offset: sizeof(boardtype),
};
typedef struct pci_dio_private_st pci_dio_private;
/*
==============================================================================
*/
-static int pci_dio_insn_bits_di_b(comedi_device *dev, comedi_subdevice *s,
+static int pci_dio_insn_bits_di_b(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn, lsampl_t *data)
{
diosubd_data *d=(diosubd_data *)s->private;
int i;
-
+
data[1]=0;
for (i=0; i<d->regs;i++) {
data[1]|=inb(dev->iobase+d->addr+i)<<(8*i);
/*
==============================================================================
*/
-static int pci_dio_insn_bits_di_w(comedi_device *dev, comedi_subdevice *s,
+static int pci_dio_insn_bits_di_w(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn, lsampl_t *data)
{
diosubd_data *d=(diosubd_data *)s->private;
int i;
-
+
data[1]=0;
for (i=0; i<d->regs; i++)
data[1]|=inw(dev->iobase+d->addr+2*i)<<(16*i);
/*
==============================================================================
*/
-static int pci_dio_insn_bits_do_b(comedi_device *dev, comedi_subdevice *s,
+static int pci_dio_insn_bits_do_b(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn, lsampl_t *data)
{
diosubd_data *d=(diosubd_data *)s->private;
/*
==============================================================================
*/
-static int pci_dio_insn_bits_do_w(comedi_device *dev, comedi_subdevice *s,
+static int pci_dio_insn_bits_do_w(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn,lsampl_t *data)
{
diosubd_data *d=(diosubd_data *)s->private;
==============================================================================
*/
static int pci1760_unchecked_mbxrequest(comedi_device *dev,
- unsigned char *omb, unsigned char *imb,
+ unsigned char *omb, unsigned char *imb,
int repeats)
{
int cnt, tout, ok=0;
-
+
for (cnt=0; cnt<repeats; cnt++) {
outb(omb[0], dev->iobase+OMB0);
outb(omb[1], dev->iobase+OMB1);
}
if (ok) return 0;
}
-
+
comedi_error(dev, "PCI-1760 mailbox request timeout!");
return -ETIME;
}
/*
==============================================================================
*/
-static int pci1760_insn_bits_di(comedi_device *dev, comedi_subdevice *s,
+static int pci1760_insn_bits_di(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn, lsampl_t *data)
{
data[1]=inb(dev->iobase + IMB3);
/*
==============================================================================
*/
-static int pci1760_insn_bits_do(comedi_device *dev, comedi_subdevice *s,
+static int pci1760_insn_bits_do(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn, lsampl_t *data)
{
int ret;
unsigned char omb[4]={
- 0x00,
- 0x00,
- CMD_SetRelaysOutput,
+ 0x00,
+ 0x00,
+ CMD_SetRelaysOutput,
0x00};
unsigned char imb[4];
/*
==============================================================================
*/
-static int pci1760_insn_cnt_read(comedi_device *dev, comedi_subdevice *s,
+static int pci1760_insn_cnt_read(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn, lsampl_t *data)
{
int ret, n;
unsigned char omb[4]={
- CR_CHAN(insn->chanspec)&0x07,
- 0x00,
- CMD_GetIDICntCurValue,
+ CR_CHAN(insn->chanspec)&0x07,
+ 0x00,
+ CMD_GetIDICntCurValue,
0x00};
unsigned char imb[4];
/*
==============================================================================
*/
-static int pci1760_insn_cnt_write(comedi_device *dev, comedi_subdevice *s,
+static int pci1760_insn_cnt_write(comedi_device *dev, comedi_subdevice *s,
comedi_insn *insn, lsampl_t *data)
{
int ret;
unsigned char chan=CR_CHAN(insn->chanspec)&0x07;
unsigned char bitmask=1<<chan;
unsigned char omb[4]={
- data[0]&0xff,
- (data[0]>>8)&0xff,
- CMD_SetIDI0CntResetValue+chan,
+ data[0]&0xff,
+ (data[0]>>8)&0xff,
+ CMD_SetIDI0CntResetValue+chan,
0x00};
unsigned char imb[4];
omb[0] = 0x00;
omb[2] = CMD_SetRelaysOutput; // reset relay outputs
pci1760_mbxrequest(dev, omb, imb);
-
+
omb[0] = 0x00;
omb[2] = CMD_EnableIDICounters; // disable IDI up counters
pci1760_mbxrequest(dev, omb, imb);
pci1760_mbxrequest(dev, omb, imb);
devpriv->CntResValue[i] = 0x0000;
}
-
+
omb[0] = 0xff;
omb[2] = CMD_ResetIDICounters; // reset IDI up counters to reset values
pci1760_mbxrequest(dev, omb, imb);
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci_dio_reset(comedi_device *dev)
{
DPRINTK("adv_pci_dio EDBG: BGN: pci171x_reset(...)\n");
-
+
switch (this_board->cardtype) {
case TYPE_PCI1730:
outb(0, dev->iobase+PCI1730_DO); // clear outputs
outb(0x80, dev->iobase+PCI1753_ICR3);
break;
case TYPE_PCI1754:
- outw(0x08, dev->iobase+PCI1754_6_ICR0); // disable and clear interrupts
+ outw(0x08, dev->iobase+PCI1754_6_ICR0); // disable and clear interrupts
outw(0x08, dev->iobase+PCI1754_6_ICR1);
outw(0x08, dev->iobase+PCI1754_ICR2);
outw(0x08, dev->iobase+PCI1754_ICR3);
break;
case TYPE_PCI1756:
outw(0, dev->iobase+PCI1752_6_CFC); // disable channel freeze function
- outw(0x08, dev->iobase+PCI1754_6_ICR0); // disable and clear interrupts
+ outw(0x08, dev->iobase+PCI1754_6_ICR0); // disable and clear interrupts
outw(0x08, dev->iobase+PCI1754_6_ICR1);
outw(0, dev->iobase+PCI1756_IDO); // clear outputs
outw(0, dev->iobase+PCI1756_IDO+2);
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci1760_attach(comedi_device *dev, comedi_devconfig *it)
s->len_chanlist = 8;
s->range_table = &range_digital;
s->insn_bits=pci1760_insn_bits_di;
- subdev++;
+ subdev++;
s = dev->subdevices + subdev;
s->type = COMEDI_SUBD_DO;
s->range_table = &range_digital;
s->state=0;
s->insn_bits=pci1760_insn_bits_do;
- subdev++;
+ subdev++;
s = dev->subdevices + subdev;
s->type = COMEDI_SUBD_TIMER;
s->maxdata = 0xffffffff;
s->len_chanlist = 2;
// s->insn_config=pci1760_insn_pwm_cfg;
- subdev++;
+ subdev++;
s = dev->subdevices + subdev;
s->type = COMEDI_SUBD_COUNTER;
s->insn_read=pci1760_insn_cnt_read;
s->insn_write=pci1760_insn_cnt_write;
// s->insn_config=pci1760_insn_cnt_cfg;
- subdev++;
+ subdev++;
return 0;
}
-/*
+/*
==============================================================================
*/
-static int pci_dio_add_di(comedi_device *dev, comedi_subdevice *s,
+static int pci_dio_add_di(comedi_device *dev, comedi_subdevice *s,
diosubd_data *d, int subdev)
{
s->type = COMEDI_SUBD_DI;
return 0;
}
-/*
+/*
==============================================================================
*/
-static int pci_dio_add_do(comedi_device *dev, comedi_subdevice *s,
+static int pci_dio_add_do(comedi_device *dev, comedi_subdevice *s,
diosubd_data *d, int subdev)
{
s->type = COMEDI_SUBD_DO;
return 0;
}
-/*
+/*
==============================================================================
*/
static int CheckAndAllocCard(comedi_device *dev, comedi_devconfig *it,
struct pci_dev* pcidev)
{
pci_dio_private *pr, *prev;
-
+
for (pr=pci_priv, prev=NULL; pr!=NULL; prev=pr, pr=pr->next) {
if (pr->pcidev==pcidev) {
if (it->options[0]||it->options[1]) {
}
devpriv->pcidev = pcidev;
-
+
return 1;
}
-/*
+/*
==============================================================================
*/
static int pci_dio_attach(comedi_device *dev, comedi_devconfig *it)
return -ENOMEM;
}
- 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!=this_board->vendor_id)||
(pcidev->device!=this_board->device_id))
continue;
}
}
- ret=CheckAndAllocCard(dev, it, pcidev);
+ ret=CheckAndAllocCard(dev, it, pcidev);
if (ret==1) { found=1; break; }
- if (ret>1) {
+ if (ret>1) {
return -EIO;
}
}
rt_printk(", Error: Requested type of the card was not found!\n");
return -EIO;
}
-
+
if (pci_enable_device(pcidev)) {
rt_printk(", Error: Can't enable PCI device!\n");
return -EIO;
if (pci_request_regions(pcidev, driver_pci_dio.driver_name)) {
rt_printk(", Error: Can't allocate PCI device!\n");
return -EIO;
- }
+ }
iobase=pci_resource_start(pcidev, this_board->main_pci_region);
rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx",
pcidev->bus->number, PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn),
iobase);
-
+
dev->iobase=iobase;
dev->board_name=this_board->name;
-
+
if (this_board->cardtype==TYPE_PCI1760) {
- n_subdevices=4; // 8 IDI, 8 IDO, 2 PWM, 8 CNT
+ n_subdevices=4; // 8 IDI, 8 IDO, 2 PWM, 8 CNT
} else {
n_subdevices=0;
for (i=0; i<MAX_DI_SUBDEVS; i++)
}
rt_printk(".\n");
-
+
subdev=0;
-
+
for (i=0; i<MAX_DI_SUBDEVS; i++)
if (this_board->sdi[i].chans) {
s = dev->subdevices + subdev;
for (i=0; i<MAX_DIO_SUBDEVG; i++)
for (j=0; j<this_board->sdio[i].regs; j++) {
s = dev->subdevices + subdev;
- subdev_8255_init(dev, s, NULL,
+ subdev_8255_init(dev, s, NULL,
dev->iobase+this_board->sdio[i].addr+SIZE_8255*j);
subdev++;
}
pci_dio_add_di(dev, s, &this_board->boardid, subdev);
subdev++;
}
-
- if (this_board->cardtype==TYPE_PCI1760)
+
+ if (this_board->cardtype==TYPE_PCI1760)
pci1760_attach(dev, it);
-
+
devpriv->valid=1;
pci_dio_reset(dev);
return 0;
}
-/*
+/*
==============================================================================
*/
static int pci_dio_detach(comedi_device *dev)
int i, j;
comedi_subdevice *s;
int subdev;
-
+
if (dev->private) {
if (devpriv->valid) {
pci_dio_reset(dev);
}
pci_dev_put(devpriv->pcidev);
}
-
+
if (devpriv->prev) {
devpriv->prev->next=devpriv->next;
} else {
return 0;
}
-/*
+/*
==============================================================================
*/
COMEDI_INITCLEANUP(driver_pci_dio);
-/*
+/*
==============================================================================
*/
module: THIS_MODULE,
attach: aio_aio12_8_attach,
detach: aio_aio12_8_detach,
- board_name: board_types,
+ board_name: (const char**)board_types,
num_names: 1,
offset: sizeof (board_type),
};
module: THIS_MODULE,
attach: aio_iiro_16_attach,
detach: aio_iiro_16_detach,
- board_name: aio_iiro_16_boards,
+ board_name: (const char**)aio_iiro_16_boards,
offset: sizeof (aio_iiro_16_board),
num_names: sizeof (aio_iiro_16_boards) /
sizeof (aio_iiro_16_board),
PC214E PC272E/PCI272
------------- -------------
- Subdevices 4 4
+ Subdevices 4 4
0 PPI-X PPI-X
1 PPI-Y PPI-Y
2 CTR-Z1* PPI-Z
2. Gate source /OUT n-2 is the inverted output of channel 0 on the
same counter subdevice if n = 2, or the inverted output of channel n+1
on the preceding counter subdevice (see note 3) if n < 2.
-
+
3. The counter subdevices are connected in a ring, so the highest
counter subdevice precedes the lowest.
module: THIS_MODULE,
attach: dio200_attach,
detach: dio200_detach,
- board_name: dio200_boards,
+ board_name: (const char**)dio200_boards,
offset: sizeof(dio200_board),
num_names: sizeof(dio200_boards) / sizeof(dio200_board),
};
/* Look for matching PCI device. */
for(pci_dev = pci_get_device(pci_id->vendor, pci_id->device, NULL);
- pci_dev != NULL ;
+ pci_dev != NULL ;
pci_dev = pci_get_device(pci_id->vendor,
pci_id->device, pci_dev)) {
/* If bus/slot specified, check them. */
*/
triggered = subpriv->enabled_isns;
}
-
+
if (triggered) {
/*
* Some interrupt sources have triggered and have been
if (subpriv->has_int_sce) {
outb(cur_enabled, subpriv->iobase);
}
-
+
if (subpriv->active) {
/*
* The command is still active.
if (!cmd->convert_src || tmp != cmd->convert_src) err++;
tmp = cmd->scan_end_src;
- cmd->scan_end_src &= TRIG_COUNT;
+ cmd->scan_end_src &= TRIG_COUNT;
if (!cmd->scan_end_src || tmp != cmd->scan_end_src) err++;
tmp = cmd->stop_src;
} else {
printk("(no irq) ");
}
-
+
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
printk(KERN_INFO "comedi%d: %s removed\n",
dev->minor, dev->board_name);
}
-
+
return 0;
}
module: THIS_MODULE,
attach: pc236_attach,
detach: pc236_detach,
- board_name: pc236_boards,
+ board_name: (const char**)pc236_boards,
offset: sizeof(pc236_board),
num_names: sizeof(pc236_boards) / sizeof(pc236_board),
};
/* Look for matching PCI device. */
for(pci_dev = pci_get_device(pci_id->vendor, pci_id->device,
- NULL); pci_dev != NULL;
+ NULL); pci_dev != NULL;
pci_dev = pci_get_device(pci_id->vendor,
pci_id->device, pci_dev)) {
/* If bus/slot specified, check them. */
} else {
printk("(no irq) ");
}
-
+
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
module: THIS_MODULE,
attach: pc263_attach,
detach: pc263_detach,
- board_name: pc263_boards,
+ board_name: (const char**)pc263_boards,
offset: sizeof(pc263_board),
num_names: sizeof(pc263_boards) / sizeof(pc263_board),
};
/* Look for matching PCI device. */
for(pci_dev = pci_get_device(pci_id->vendor, pci_id->device,
- NULL); pci_dev != NULL;
+ NULL); pci_dev != NULL;
pci_dev = pci_get_device(pci_id->vendor,
pci_id->device, pci_dev)) {
/* If bus/slot specified, check them. */
} else {
printk("(pci %s) ", pci_name(pci_dev));
}
-
+
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
module: THIS_MODULE,
attach: pci224_attach,
detach: pci224_detach,
- board_name: pci224_boards,
+ board_name: (const char**)pci224_boards,
offset: sizeof(pci224_board),
num_names: sizeof(pci224_boards) / sizeof(pci224_board),
};
/* Look for matching PCI device. */
for(pci_dev = pci_get_device(pci_id->vendor, pci_id->device, NULL);
- pci_dev != NULL ;
+ pci_dev != NULL ;
pci_dev = pci_get_device(pci_id->vendor,
pci_id->device, pci_dev)) {
/* If bus/slot specified, check them. */
PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY);
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
dev->iobase + PCI224_DACCON);
-
+
/* Allocate subdevices. There is only one! */
if ((ret=alloc_subdevices(dev, 1)) < 0) {
printk(KERN_ERR "comedi%d: error! out of memory!\n",
dev->minor);
return ret;
}
-
+
s = dev->subdevices + 0;
/* Analog output subdevice. */
s->type = COMEDI_SUBD_AO;
} else {
printk("(no irq) ");
}
-
+
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
printk(KERN_INFO "comedi%d: %s removed\n",
dev->minor, dev->board_name);
}
-
+
return 0;
}
This driver allows you to 'bond' (merge) multiple comedi subdevices
(coming from possibly difference boards and/or drivers) together. For
example, if you had a board with 2 different DIO subdevices, and
-another with 1 DIO subdevice, you could 'bond' them with this driver
-so that they look like one big fat DIO subdevice. This makes writing
+another with 1 DIO subdevice, you could 'bond' them with this driver
+so that they look like one big fat DIO subdevice. This makes writing
applications slightly easier as you don't have to worry about managing
different subdevices in the application -- you just worry about
indexing one linear array of channel id's.
#include <linux/string.h>
/* The maxiumum number of channels per subdevice. */
-#define MAX_CHANS 256
+#define MAX_CHANS 256
#define MODULE_NAME "comedi_bond"
#ifdef MODULE_LICENSE
* boards in this way is optional, and completely driver-dependent.
* Some drivers use arrays such as this, other do not.
*/
-struct BondingBoard
+struct BondingBoard
{
char *name;
};
*/
#define thisboard ((BondingBoard *)dev->board_ptr)
-struct BondedDevice
+struct BondedDevice
{
comedi_t *dev;
unsigned minor;
unsigned subdev;
unsigned subdev_type;
unsigned nchans;
- unsigned chanid_offset; /* The offset into our unified linear channel-id's
+ unsigned chanid_offset; /* The offset into our unified linear channel-id's
of chanid 0 on this subdevice. */
};
typedef struct BondedDevice BondedDevice;
* the type of board in software. ISA PnP, PCI, and PCMCIA
* devices are such boards.
*/
- board_name: bondingBoards,
+ board_name: (const char**)bondingBoards,
offset: sizeof(BondingBoard),
num_names: sizeof(bondingBoards) / sizeof(BondingBoard),
};
*/
if ( alloc_private(dev, sizeof(Private)) < 0 )
return -ENOMEM;
-
+
/*
* Setup our bonding from config params.. sets up our Private struct..
*/
- if ( !doDevConfig(dev, it) )
+ if ( !doDevConfig(dev, it) )
return -EINVAL;
-
+
/*
* Initialize dev->board_name. Note that we can use the "thisboard"
s->range_table = &range_digital;
s->insn_bits = bonding_dio_insn_bits;
s->insn_config = bonding_dio_insn_config;
-
+
LOG_MSG("attached with %u DIO channels coming from %u different subdevices all bonded together. John Lennon would be proud!\n", devpriv->nchans, devpriv->ndevs);
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
if(insn->n != 2) return -EINVAL;
if (devpriv->nchans < nchans) nchans = devpriv->nchans;
-
+
/* The insn data is a mask in data[0] and the new data
* in data[1], each channel cooresponding to a bit. */
for (i = 0; num_done < nchans && i < devpriv->ndevs; ++i) {
BondedDevice *bdev = devpriv->devs[i];
- /* Grab the channel mask and data of only the bits corresponding
- to this subdevice.. need to shift them to zero position of
+ /* Grab the channel mask and data of only the bits corresponding
+ to this subdevice.. need to shift them to zero position of
course. */
- lsampl_t subdevMask = ((1<<bdev->nchans)-1); /* Bits corresponding
+ lsampl_t subdevMask = ((1<<bdev->nchans)-1); /* Bits corresponding
to this subdev. */
lsampl_t writeMask, dataBits;
/* Read/Write the new digital lines */
if ( comedi_dio_bitfield(bdev->dev, bdev->subdev, writeMask, &dataBits) != 2 )
- return -EINVAL;
+ return -EINVAL;
/* Make room for the new bits in data[1], the return value */
data[1] &= ~(subdevMask << num_done);
{
int i;
comedi_t *devs_opened[COMEDI_NDEVICES];
-
+
memset(devs_opened, 0, sizeof(devs_opened));
devpriv->name[0] = 0;;
- /* Loop through all comedi devices specified on the command-line,
+ /* Loop through all comedi devices specified on the command-line,
building our device list */
for (i = 0; i < COMEDI_NDEVCONFOPTS && (!i || it->options[i]); ++i) {
- char file[] = "/dev/comediXXXXXX";
+ char file[] = "/dev/comediXXXXXX";
int minor = it->options[i];
comedi_t *d;
int sdev = -1, nchans, tmp;
ERROR("Minor %u could not be opened\n", minor);
return 0;
}
-
+
/* Do DIO, as that's all we support now.. */
while ( (sdev = comedi_find_subdevice_by_type(d, COMEDI_SUBD_DIO, sdev+1)) > -1 ) {
- if ( (nchans = comedi_get_n_channels(d, sdev)) <= 0) {
+ if ( (nchans = comedi_get_n_channels(d, sdev)) <= 0) {
ERROR("comedi_get_n_channels() returned %d on minor %u subdev %d!\n", nchans, minor, sdev);
return 0;
}
if (!devpriv->devs) {
ERROR("Could not allocate memory. Out of memory?");
return 0;
- }
+ }
devpriv->devs[devpriv->ndevs-1] = bdev;
{ /** Append dev:subdev to devpriv->name */
unsigned long devs_closed = 0;
if (devpriv) {
- while(devpriv->ndevs-- && devpriv->devs) {
+ while(devpriv->ndevs-- && devpriv->devs) {
BondedDevice *bdev = devpriv->devs[devpriv->ndevs];
if (!bdev) continue;
if (! (devs_closed & (0x1<<bdev->minor)) ) {
module: THIS_MODULE,
attach: waveform_attach,
detach: waveform_detach,
- board_name: waveform_boards,
+ board_name: (const char**)waveform_boards,
offset: sizeof(waveform_board),
num_names: sizeof(waveform_boards) / sizeof(waveform_board),
};
s->maxdata = (1 << thisboard->ai_bits) - 1;
s->range_table = &waveform_ai_ranges;
s->len_chanlist = s->n_chan * 2;
- s->insn_read = waveform_ai_insn_read;
+ s->insn_read = waveform_ai_insn_read;
s->do_cmd = waveform_ai_cmd;
s->do_cmdtest = waveform_ai_cmdtest;
s->cancel = waveform_ai_cancel;
s->maxdata = (1 << thisboard->ai_bits) - 1;
s->range_table = &waveform_ai_ranges;
s->len_chanlist = s->n_chan * 2;
- s->insn_write = waveform_ao_insn_write;
+ s->insn_write = waveform_ao_insn_write;
s->do_cmd = 0;
s->do_cmdtest = 0;
s->cancel = 0;
{
/* Our default loopback value is just a 0V flatline */
int i;
- for (i = 0; i < s->n_chan; i++)
+ for (i = 0; i < s->n_chan; i++)
devpriv->ao_loopbacks[i] = s->maxdata / 2;
}
static int waveform_ao_insn_write(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data)
{
int i, chan = CR_CHAN(insn->chanspec);
-
+
for(i = 0; i < insn->n; i++)
devpriv->ao_loopbacks[chan] = data[i];
/* The following instructions must be in order.
We must avoid other process reading the counter's value in the
middle.
- The spin_lock isn't needed since ioctl calls grab the big kernel
+ The spin_lock isn't needed since ioctl calls grab the big kernel
lock automatically */
/*spin_lock(sp);*/
outb(chan<<6,base+I8254_CTRL);
static unsigned int i8254_read_status(struct i8254_struct *st, int channel)
{
int chan=st->logic2phys[channel];
-
+
return i8254_read_status_low(st->iobase,chan);
}
//printk("Reading counter channel %d ",chan);
data[0]=i8254_read_channel(&devpriv->i8254,chan);
//printk("=> 0x%08X\n",data[0]);
-
+
return 1;
}
//printk("Writing counter channel %d with 0x%04X\n",chan,data[0]);
i8254_write_channel(&devpriv->i8254,chan,data[0]);
-
+
return 1;
}
module: THIS_MODULE,
attach: das08_attach,
detach: das08_common_detach,
- board_name: das08_boards,
+ board_name: (const char**)(das08_boards),
num_names: sizeof(das08_boards)/sizeof(struct das08_board_struct),
offset: sizeof(struct das08_board_struct),
};
}
printk("\n");
// find card
- for(pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pdev != NULL ;
+ for(pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pdev != NULL ;
pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) {
if(pdev->vendor == PCI_VENDOR_ID_COMPUTERBOARDS &&
pdev->device == PCI_DEVICE_ID_PCIDAS08){
enum das08_lrange {das08_pg_none, das08_bipolar5, das08_pgh, das08_pgl, das08_pgm};
typedef struct das08_board_struct{
- char *name;
+ const char * name;
unsigned int id; // id for pci/pcmcia boards
enum das08_bustype bustype;
void *ai;
module: THIS_MODULE,
attach: das16_attach,
detach: das16_detach,
- board_name: das16_boards,
+ board_name: (const char**)das16_boards,
num_names: n_das16_boards,
offset: sizeof(das16_boards[0]),
};
module: THIS_MODULE,
attach: das16m1_attach,
detach: das16m1_detach,
- board_name: das16m1_boards,
+ board_name: (const char**)das16m1_boards,
num_names: das16m1_num_boards,
offset: sizeof(das16m1_boards[0]),
};
attach: das1800_attach,
detach: das1800_detach,
num_names: sizeof(das1800_boards) / sizeof(das1800_board),
- board_name: das1800_boards,
+ board_name: (const char**)das1800_boards,
offset: sizeof(das1800_board),
};
static int das1800_init_dma( comedi_device *dev, unsigned int dma0, unsigned int dma1 )
{
unsigned long flags;
-
+
// need an irq to do dma
if( dev->irq && dma0 )
{
attach: das800_attach,
detach: das800_detach,
num_names: sizeof(das800_boards) / sizeof(das800_board),
- board_name: (char **)das800_boards,
+ board_name: (const char **)das800_boards,
offset: sizeof(das800_board),
};
/* DMM32AT_DIOCONF 0x0f */
#define DMM32AT_DIENABLE 0x80
-#define DMM32AT_DIRA 0x10
+#define DMM32AT_DIRA 0x10
#define DMM32AT_DIRB 0x02
#define DMM32AT_DIRCL 0x01
#define DMM32AT_DIRCH 0x08
ai_ranges: &dmm32at_airanges,
ao_chans: 4,
ao_bits: 12,
- ao_ranges: &dmm32at_aoranges,
+ ao_ranges: &dmm32at_aoranges,
have_dio: 1,
dio_chans: 24,
},
/* this structure is for data unique to this hardware driver. If
* several hardware drivers keep similar information in this structure,
- * feel free to suggest moving the variable to the comedi_device struct.
+ * feel free to suggest moving the variable to the comedi_device struct.
*/
typedef struct {
-
+
int data;
int ai_inuse;
unsigned int ai_scans_left;
-
+
/* Used for AO readback */
lsampl_t ao_readback[4];
unsigned char dio_config;
* the type of board in software. ISA PnP, PCI, and PCMCIA
* devices are such boards.
*/
- board_name: dmm32at_boards,
+ board_name: (const char**)dmm32at_boards,
offset: sizeof(dmm32at_board),
num_names: sizeof(dmm32at_boards) / sizeof(dmm32at_board),
};
irq = it->options[1];
printk("comedi%d: dmm32at: attaching\n",dev->minor);
- printk("dmm32at: probing at address 0x%04lx, irq %u\n",
+ printk("dmm32at: probing at address 0x%04lx, irq %u\n",
iobase, irq);
-
+
/* register address space */
if (!request_region(iobase,DMM32AT_MEMSIZE,thisboard->name)) {
printk("I/O port conflict\n");
/* reset the board */
dmm_outb(dev,DMM32AT_CNTRL,DMM32AT_RESET);
-
+
/* allow a millisecond to reset */
udelay(1000);
/* zero scan and fifo control */
dmm_outb(dev,DMM32AT_FIFOCNTRL,0x0);
-
+
/* zero interrupt and clock control */
dmm_outb(dev,DMM32AT_INTCLOCK,0x0);
aistat = dmm_inb(dev,DMM32AT_AISTAT);
intstat = dmm_inb(dev,DMM32AT_INTCLOCK);
airback = dmm_inb(dev,DMM32AT_AIRBACK);
-
+
printk("dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n",
ailo,aihi,fifostat);
printk("dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n",
aistat,intstat,airback);
-
+
if( (ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) ||
(aistat != 0x60 || (intstat != 0x00) || airback != 0x0c) ){
printk("dmmat32: board detection failed\n");
}
-
+
/*
* 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
s=dev->subdevices+2;
/* digital i/o subdevice */
if(thisboard->have_dio){
-
+
/* get access to the DIO regs */
dmm_outb(dev,DMM32AT_CNTRL,DMM32AT_DIOACC);
/* set the DIO's to the defualt input setting */
devpriv->dio_config = DMM32AT_DIRA|DMM32AT_DIRB|
DMM32AT_DIRCL|DMM32AT_DIRCH|DMM32AT_DIENABLE;
dmm_outb(dev,DMM32AT_DIOCONF,devpriv->dio_config);
-
+
/* set up the subdevice */
s->type=COMEDI_SUBD_DIO;
s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
}else{
s->type = COMEDI_SUBD_UNUSED;
}
-
+
/* success */
printk("comedi%d: dmm32at: attached\n",dev->minor);
/*
* _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
printk("comedi%d: dmm32at: remove\n",dev->minor);
if(dev->irq)comedi_free_irq(dev->irq,dev);
if(dev->iobase)release_region(dev->iobase,DMM32AT_MEMSIZE);
-
+
return 0;
}
int range;
/* get the channel and range number */
-
+
chan = CR_CHAN(insn->chanspec)&(s->n_chan-1);
range = CR_RANGE(insn->chanspec);
-
+
//printk("channel=0x%02x, range=%d\n",chan,range);
-
+
/* zero scan and fifo control and reset fifo*/
dmm_outb(dev,DMM32AT_FIFOCNTRL,DMM32AT_FIFORESET);
-
+
/* write the ai channel range regs */
dmm_outb(dev,DMM32AT_AILOW,chan);
dmm_outb(dev,DMM32AT_AIHIGH,chan);
/* set the range bits */
dmm_outb(dev,DMM32AT_AICONF,dmm32at_rangebits[range]);
-
+
/* wait for circuit to settle */
for(i=0;i<40000;i++){
status = dmm_inb(dev,DMM32AT_AIRBACK);
printk("timeout\n");
return -ETIMEDOUT;
}
-
+
/* convert n samples */
for(n=0;n<insn->n;n++){
used by comedi */
d = ((msb^0x0080)<<8) + lsb;
-
+
data[n] = d;
}
if(err)return 1;
-
+
/* step 2: make sure trigger sources are unique and mutually compatible */
/* note that mutual compatiblity is not an issue here */
if(err)return 2;
-
-
+
+
/* step 3: make sure arguments are trivially compatible */
if(cmd->start_arg!=0){
cmd->convert_arg=10000;
else
cmd->convert_arg=5000;
-
+
}else{
/* external trigger */
/* see above */
if(err)return 3;
-
+
/* step 4: fix up any arguments */
if(cmd->scan_begin_src==TRIG_TIMER){
if(err)return 4;
-
+
/* step 5 check the channel list, the channel list for this
board must be consecutive and gains must be the same */
-
+
if(cmd->chanlist){
gain = CR_RANGE(cmd->chanlist[0]);
start_chan = CR_CHAN(cmd->chanlist[0]);
}
}
}
-
-
+
+
if(err)return 5;
-
+
return 0;
}
dmm_outb(dev,DMM32AT_CNTRL,DMM32AT_INTRESET);
if(cmd->stop_src==TRIG_COUNT)
- devpriv->ai_scans_left = cmd->stop_arg;
+ devpriv->ai_scans_left = cmd->stop_arg;
else { /* TRIG_NONE */
devpriv->ai_scans_left = 0xffffffff; /* indicates TRIG_NONE to isr */
}
-
+
/* wait for circuit to settle */
for(i=0;i<40000;i++){
status = dmm_inb(dev,DMM32AT_AIRBACK);
printk("timeout\n");
return -ETIMEDOUT;
}
-
-
-
+
+
+
if(devpriv->ai_scans_left > 1){
/* start the clock and enable the interrupts */
dmm32at_setaitimer(dev,cmd->scan_begin_arg);
dmm_outb(dev,DMM32AT_INTCLOCK,DMM32AT_ADINT);
dmm_outb(dev,DMM32AT_CONV,0xff);
}
-
+
/* printk("dmmat32 in command\n"); */
-
+
/* for(i=0;i<cmd->chanlist_len;i++) */
/* comedi_buf_put(s->async,i*100); */
/* s->async->events |= COMEDI_CB_EOA; */
/* comedi_event(dev,s,s->async->events); */
-
+
return 0;
}
comedi_device *dev=d;
comedi_subdevice *s=dev->read_subdev;
comedi_cmd *cmd = &s->async->cmd;
-
+
intstat = dmm_inb(dev,DMM32AT_INTCLOCK);
if(intstat & DMM32AT_ADINT){
/* read data */
lsb = dmm_inb(dev,DMM32AT_AILSB);
msb = dmm_inb(dev,DMM32AT_AIMSB);
-
+
/* invert sign bit to make range unsigned */
samp = ((msb^0x0080)<<8) + lsb;
comedi_buf_put(s->async,samp);
}
-
+
if(devpriv->ai_scans_left != 0xffffffff){ /* TRIG_COUNT */
devpriv->ai_scans_left--;
if(devpriv->ai_scans_left == 0){
/* set the buffer to be flushed with an EOF */
s->async->events |= COMEDI_CB_EOA;
}
-
+
}
/* flush the buffer */
comedi_event(dev,s,s->async->events);
}
-
+
/* reset the interrupt */
dmm_outb(dev,DMM32AT_CNTRL,DMM32AT_INTRESET);
return IRQ_HANDLED;
/* write the low and high values to the board */
dmm_outb(dev,DMM32AT_DACLSB,lo);
dmm_outb(dev,DMM32AT_DACMSB,hi);
-
+
/* wait for circuit to settle */
for(i=0;i<40000;i++){
status = dmm_inb(dev,DMM32AT_DACSTAT);
}
/* dummy read to update trigger the output */
status = dmm_inb(dev,DMM32AT_DACMSB);
-
+
}
/* return the number of samples read/written */
comedi_insn *insn,lsampl_t *data)
{
unsigned char diobits;
-
+
if(insn->n!=2)return -EINVAL;
/* The insn data is a mask in data[0] and the new data
/* get access to the DIO regs */
dmm_outb(dev,DMM32AT_CNTRL,DMM32AT_DIOACC);
-
-
+
+
/* if either part of dio is set for output */
if( ((devpriv->dio_config&DMM32AT_DIRCL) == 0) ||
((devpriv->dio_config&DMM32AT_DIRCH) == 0) ){
diobits = (s->state&0x000000ff);
dmm_outb(dev,DMM32AT_DIOA,diobits);
}
-
+
/* now read the state back in */
- s->state = dmm_inb(dev,DMM32AT_DIOC);
+ s->state = dmm_inb(dev,DMM32AT_DIOC);
s->state <<= 8;
- s->state |= dmm_inb(dev,DMM32AT_DIOB);
+ s->state |= dmm_inb(dev,DMM32AT_DIOB);
s->state <<= 8;
- s->state |= dmm_inb(dev,DMM32AT_DIOA);
+ s->state |= dmm_inb(dev,DMM32AT_DIOA);
data[1]=s->state;
-
-
+
+
/* on return, data[1] contains the value of the digital
* input and output lines. */
chanbit = DMM32AT_DIRCL;
else
chanbit = DMM32AT_DIRCH;
-
+
/* The input or output configuration of each digital line is
* configured by a special insn_config instruction. chanspec
* contains the channel to be changed, and data[0] contains the
* value COMEDI_INPUT or COMEDI_OUTPUT. */
-
+
/* if output clear the bit, otherwise set it */
if(data[0]==COMEDI_OUTPUT){
devpriv->dio_config &= ~chanbit;
dmm_outb(dev,DMM32AT_CNTRL,DMM32AT_DIOACC);
/* set the DIO's to the new configuration setting */
dmm_outb(dev,DMM32AT_DIOCONF,devpriv->dio_config);
-
+
return 1;
}
void dmm32at_setaitimer(comedi_device *dev,unsigned int nansec){
unsigned char lo1, lo2, hi2;
unsigned short both2;
-
+
/* based on 10mhz clock */
lo1=200;
both2 = nansec/20000;
/* set the counter frequency to 10mhz*/
dmm_outb(dev,DMM32AT_CNTRDIO,0);
-
+
/* get access to the clock regs */
dmm_outb(dev,DMM32AT_CNTRL,DMM32AT_CLKACC);
}
-
+
/*
* A convenient macro that defines init_module() and cleanup_module(),
module: THIS_MODULE,
attach: dt2811_attach,
detach: dt2811_detach,
- board_name: boardtypes,
+ board_name: (const char **)boardtypes,
num_names: sizeof(boardtypes)/sizeof(boardtype),
offset: sizeof(boardtype),
};
module: THIS_MODULE,
attach: dt282x_attach,
detach: dt282x_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype_t),
};
if (irq < 0) {
unsigned long flags;
int irqs;
-
+
save_flags(flags);
sti();
irqs = probe_irq_on();
4 x 16-bit counters
Options:
- [0] - PCI bus number - if bus number and slot number are 0,
+ [0] - PCI bus number - if bus number and slot number are 0,
then driver search for first unused card
- [1] - PCI slot number
+ [1] - PCI slot number
*/
#include <linux/comedidev.h>
// Hardware types of the cards
#define TYPE_ICP_MULTI 0
-#define IORANGE_ICP_MULTI 32
+#define IORANGE_ICP_MULTI 32
#define ICP_MULTI_ADC_CSR 0 /* R/W: ADC command/status register */
#define ICP_MULTI_AI 2 /* R: Analogue input data */
attach: icp_multi_attach,
detach: icp_multi_detach,
num_names: n_boardtypes,
- board_name: boardtypes,
- offset: sizeof(boardtype),
+ board_name: (const char**)boardtypes,
+ offset: sizeof(boardtype),
};
COMEDI_INITCLEANUP(driver_icp_multi);
#define devpriv ((icp_multi_private *)dev->private)
#define this_board ((boardtype *)dev->board_ptr)
-/*
+/*
==============================================================================
More forward declarations
==============================================================================
static int icp_multi_reset(comedi_device *dev);
-/*
+/*
==============================================================================
Functions
==============================================================================
// Disable A/D conversion ready interrupt
devpriv->IntEnable &= ~ADC_READY;
writew(devpriv->IntEnable,devpriv->io_addr + ICP_MULTI_INT_EN);
-
+
// Clear interrupt status
devpriv->IntStatus |= ADC_READY;
writew(devpriv->IntStatus,devpriv->io_addr + ICP_MULTI_INT_STAT);
conv_finish:
data[n] = (readw(devpriv->io_addr+ICP_MULTI_AI) >> 4 ) & 0x0fff;
}
-
+
// Disable interrupt
devpriv->IntEnable &= ~ADC_READY;
writew(devpriv->IntEnable,devpriv->io_addr + ICP_MULTI_INT_EN);
/*
==============================================================================
-
+
Name: icp_multi_insn_write_ao
Description:
// Disable D/A conversion ready interrupt
devpriv->IntEnable &= ~DAC_READY;
writew(devpriv->IntEnable,devpriv->io_addr + ICP_MULTI_INT_EN);
-
+
// Clear interrupt status
devpriv->IntStatus |= DAC_READY;
writew(devpriv->IntStatus,devpriv->io_addr + ICP_MULTI_INT_STAT);
devpriv->DacCmdStatus &= 0xfccf;
devpriv->DacCmdStatus |= this_board->rangecode[range];
devpriv->DacCmdStatus |= (chan << 8);
-
+
writew(devpriv->DacCmdStatus, devpriv->io_addr+ICP_MULTI_DAC_CSR);
for (n=0; n<insn->n; n++) {
/*
==============================================================================
-
+
Name: icp_multi_insn_read_ao
Description:
{
int n,chan;
- // Get channel number
+ // Get channel number
chan = CR_CHAN(insn->chanspec);
// Read analogue outputs
- for (n=0; n<insn->n; n++)
+ for (n=0; n<insn->n; n++)
data[n]=devpriv->ao_data[chan];
return n;
/*
==============================================================================
-
+
Name: icp_multi_insn_bits_di
Description:
/*
==============================================================================
-
+
Name: icp_multi_insn_bits_do
Description:
static int check_channel_list(comedi_device * dev, comedi_subdevice * s, unsigned int *chanlist, unsigned int n_chan)
{
unsigned int i;
-
+
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: check_channel_list(...,%d)\n",n_chan);
#endif
Description:
This function resets the icp multi device to a 'safe' state
-
+
Parameters:
comedi_device *dev Pointer to current sevice structure
// Output to command / status register
writew(devpriv->DacCmdStatus, devpriv->io_addr+ICP_MULTI_DAC_CSR);
-
+
// Delay to allow DAC time to recover
comedi_udelay(1);
}
-
+
// Digital outputs to 0
writew(0, devpriv->io_addr + ICP_MULTI_DO);
==============================================================================
Name: icp_multi_attach
-
+
Description:
This function sets up all the appropriate data for the current
device.
}
else
irq=0;
-
+
dev->irq = irq;
printk(".\n");
subdev=0;
-
+
if (this_board->n_aichan) {
s = dev->subdevices + subdev;
dev->read_subdev = s;
s->insn_read=icp_multi_insn_read_ai;
subdev++;
}
-
+
if (this_board->n_aochan) {
s = dev->subdevices + subdev;
s->type = COMEDI_SUBD_AO;
s->insn_write=icp_multi_insn_write_ctr;
subdev++;
}
-
+
devpriv->valid = 1;
icp_multi_reset(dev);
==============================================================================
Name: icp_multi_detach
-
+
Description:
This function releases all the resources used by the current
device.
-
+
Parameters:
comedi_device *dev Pointer to current device structure
static int icp_multi_detach(comedi_device *dev)
{
- if (dev->private)
+ if (dev->private)
if (devpriv->valid)
icp_multi_reset(dev);
-
+
if (dev->irq)
comedi_free_irq(dev->irq,dev);
static int cnt_reset(comedi_device *dev, unsigned int channel);
static int cnt_config(
- comedi_device *dev,
+ comedi_device *dev,
unsigned int channel,
unsigned int mode);
lsampl_t *data);
static int me4000_ao_insn_read(
- comedi_device * dev,
- comedi_subdevice * s,
- comedi_insn *insn,
+ comedi_device * dev,
+ comedi_subdevice * s,
+ comedi_insn *insn,
lsampl_t *data);
/*-----------------------------------------------------------------------------
- Meilhaus inline functions
+ Meilhaus inline functions
---------------------------------------------------------------------------*/
static void inline me4000_outb(comedi_device *dev, unsigned char value, unsigned long port);
static void inline me4000_outl(comedi_device *dev, unsigned long value, unsigned long port);
result = me4000_probe(dev, it);
if(result) return result;
- dev->board_name = thisboard->name;
-
/*
* Allocate the subdevice structures. alloc_subdevice() is a
* convenient macro defined in comedidev.h. It relies on
s->cancel = me4000_ai_cancel;
s->do_cmdtest = me4000_ai_do_cmd_test;
s->do_cmd = me4000_ai_do_cmd;
- }
+ }
}
else{
printk(KERN_WARNING"comedi%d: me4000: me4000_attach(): No interrupt available\n", dev->minor);
s->io_bits |= 0xFF;
me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0, info->dio_context.dir_reg);
}
-
+
/*=========================================================================
Counter subdevice
========================================================================*/
/*
* Probe the device to determine what device in the series it is.
*/
- for(pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_device != NULL ;
+ for(pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_device != NULL ;
pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
if(pci_device->vendor == PCI_VENDOR_ID_MEILHAUS){
for(i = 0; i < ME4000_BOARD_VERSIONS; i++){
init_waitqueue_head(&queue);
- /*
+ /*
* Set PLX local interrupt 2 polarity to high.
* Interrupt is thrown by init pin of xilinx.
*/
outl(0x10, info->plx_regbase + PLX_INTCSR);
/* Set /CS and /WRITE of the Xilinx */
- value = inl(info->plx_regbase + PLX_ICR);
+ value = inl(info->plx_regbase + PLX_ICR);
value |= 0x100;
outl(value, info->plx_regbase + PLX_ICR);
CALL_PDEBUG("In reset_board()\n");
/* Make a hardware reset */
- icr = me4000_inl(dev, info->plx_regbase + PLX_ICR);
+ icr = me4000_inl(dev, info->plx_regbase + PLX_ICR);
icr |= 0x40000000;
me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
icr &= ~0x40000000;
/* Set both stop bits in the analog input control register */
me4000_outl(
- dev,
- ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
+ dev,
+ ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
info->me4000_regbase + ME4000_AI_CTRL_REG);
/* Set both stop bits in the analog output control register */
/* Clear channel list, data fifo and both stop bits */
tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
- ME4000_AI_CTRL_BIT_DATA_FIFO |
+ ME4000_AI_CTRL_BIT_DATA_FIFO |
ME4000_AI_CTRL_BIT_STOP |
ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
static int ai_check_chanlist(
- comedi_device *dev,
- comedi_subdevice *s,
+ comedi_device *dev,
+ comedi_subdevice *s,
comedi_cmd *cmd){
int aref;
int i;
/* Check if bipolar is set for all entries when in differential mode */
if(aref == SDF_DIFF){
for(i = 0; i < cmd->chanlist_len; i++){
- if(CR_RANGE(cmd->chanlist[i]) != 1 &&
+ if(CR_RANGE(cmd->chanlist[i]) != 1 &&
CR_RANGE(cmd->chanlist[i]) != 2){
printk(KERN_ERR"comedi%d: me4000: ai_check_chanlist(): Bipolar is not selected in differential mode\n",
dev->minor);
(cmd->start_src == TRIG_EXT &&
cmd->scan_begin_src == TRIG_FOLLOW &&
cmd->convert_src == TRIG_TIMER)){
- tmp =
+ tmp =
ME4000_AI_CTRL_BIT_MODE_1 |
ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
ME4000_AI_CTRL_BIT_DATA_FIFO;
else if(cmd->start_src == TRIG_EXT &&
cmd->scan_begin_src == TRIG_EXT &&
cmd->convert_src == TRIG_TIMER){
- tmp =
+ tmp =
ME4000_AI_CTRL_BIT_MODE_2 |
ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
ME4000_AI_CTRL_BIT_DATA_FIFO;
else if(cmd->start_src == TRIG_EXT &&
cmd->scan_begin_src == TRIG_EXT &&
cmd->convert_src == TRIG_EXT){
- tmp =
+ tmp =
ME4000_AI_CTRL_BIT_MODE_0 |
ME4000_AI_CTRL_BIT_MODE_1 |
ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
ME4000_AI_CTRL_BIT_DATA_FIFO;
}
else{
- tmp =
+ tmp =
ME4000_AI_CTRL_BIT_MODE_0 |
ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
ME4000_AI_CTRL_BIT_DATA_FIFO;
comedi_device *dev,
comedi_subdevice *s,
comedi_cmd *cmd){
-
+
unsigned int init_ticks;
unsigned int chan_ticks;
unsigned int scan_ticks;
}
if(scan_ticks <= cmd->chanlist_len * chan_ticks){
printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n", dev->minor);
- cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
+ cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
err++;
}
}
}
if(scan_ticks <= cmd->chanlist_len * chan_ticks){
printk(KERN_ERR"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n", dev->minor);
- cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
+ cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
err++;
}
}
tmp = me4000_inl(dev, ai_context->ctrl_reg);
if(!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
- !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
+ !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
(tmp & ME4000_AI_STATUS_BIT_EF_DATA)){
ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
c = ME4000_AI_FIFO_COUNT;
printk(KERN_ERR"comedi%d: me4000: me4000_ai_isr(): FIFO overflow\n", dev->minor);
}
else if((tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
- !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
+ !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
(tmp & ME4000_AI_STATUS_BIT_EF_DATA)){
ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n");
}
/* Work is done, so reset the interrupt */
- ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n");
+ ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n");
tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
me4000_outl(dev, tmp, ai_context->ctrl_reg);
tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
me4000_outl(dev, tmp, ai_context->ctrl_reg);
- }
+ }
if(me4000_inl(dev, ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC){
ISR_PDEBUG("me4000_ai_isr(): Sample counter interrupt occured\n");
}
/* Work is done, so reset the interrupt */
- ISR_PDEBUG("me4000_ai_isr(): Reset interrupt from sample counter\n");
+ ISR_PDEBUG("me4000_ai_isr(): Reset interrupt from sample counter\n");
tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
me4000_outl(dev, tmp, ai_context->ctrl_reg);
tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
comedi_event(dev, s, s->async->events);
return IRQ_HANDLED;
-}
+}
static int me4000_ao_insn_read(
- comedi_device * dev,
- comedi_subdevice * s,
- comedi_insn *insn,
+ comedi_device * dev,
+ comedi_subdevice * s,
+ comedi_insn *insn,
lsampl_t *data){
int chan = CR_CHAN(insn->chanspec);
return -EINVAL;
}
- /*
+ /*
* The insn data consists of a mask in data[0] and the new data
- * in data[1]. The mask defines which bits we are concerning about.
- * The new data must be anded with the mask.
+ * in data[1]. The mask defines which bits we are concerning about.
+ * The new data must be anded with the mask.
* Each channel corresponds to a bit.
*/
if(data[0]){
/* Check if requested ports are configured for output */
if((s->io_bits & data[0]) != data[0])
return -EIO;
-
+
s->state &= ~data[0];
s->state |= data[0] & data[1];
me4000_outl(dev, (s->state >> 24) & 0xFF, info->dio_context.port_3_reg);
}
- /* On return, data[1] contains the value of
+ /* On return, data[1] contains the value of
the digital input and output lines. */
data[1] =
((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) |
return insn->n;
}
- /*
+ /*
* The input or output configuration of each digital line is
* configured by a special insn_config instruction. chanspec
* contains the channel to be changed, and data[0] contains the
#ifdef ME4000_CALL_DEBUG
#undef CALL_PDEBUG
#define CALL_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
-#else
+#else
# define CALL_PDEBUG(fmt, args...) // no debugging, do nothing
#endif
#ifdef ME4000_PORT_DEBUG
#undef PORT_PDEBUG
#define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
-#else
+#else
#define PORT_PDEBUG(fmt, args...) // no debugging, do nothing
#endif
#ifdef ME4000_ISR_DEBUG
#undef ISR_PDEBUG
#define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
-#else
+#else
#define ISR_PDEBUG(fmt, args...) // no debugging, do nothing
#endif
#ifdef ME4000_DEBUG
#undef PDEBUG
#define PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
-#else
+#else
#define PDEBUG(fmt, args...) // no debugging, do nothing
#endif
ME-4000 base register offsets
===========================================================================*/
-#define ME4000_AO_00_CTRL_REG 0x00 // R/W
+#define ME4000_AO_00_CTRL_REG 0x00 // R/W
#define ME4000_AO_00_STATUS_REG 0x04 // R/_
#define ME4000_AO_00_FIFO_REG 0x08 // _/W
#define ME4000_AO_00_SINGLE_REG 0x0C // R/W
#define ME4000_AO_00_TIMER_REG 0x10 // _/W
-#define ME4000_AO_01_CTRL_REG 0x18 // R/W
+#define ME4000_AO_01_CTRL_REG 0x18 // R/W
#define ME4000_AO_01_STATUS_REG 0x1C // R/_
#define ME4000_AO_01_FIFO_REG 0x20 // _/W
#define ME4000_AO_01_SINGLE_REG 0x24 // R/W
#define ME4000_AO_01_TIMER_REG 0x28 // _/W
-#define ME4000_AO_02_CTRL_REG 0x30 // R/W
+#define ME4000_AO_02_CTRL_REG 0x30 // R/W
#define ME4000_AO_02_STATUS_REG 0x34 // R/_
#define ME4000_AO_02_FIFO_REG 0x38 // _/W
#define ME4000_AO_02_SINGLE_REG 0x3C // R/W
#define ME4000_AO_02_TIMER_REG 0x40 // _/W
-#define ME4000_AO_03_CTRL_REG 0x48 // R/W
+#define ME4000_AO_03_CTRL_REG 0x48 // R/W
#define ME4000_AO_03_STATUS_REG 0x4C // R/_
#define ME4000_AO_03_FIFO_REG 0x50 // _/W
#define ME4000_AO_03_SINGLE_REG 0x54 // R/W
Value to adjust Demux
===========================================================================*/
-#define ME4000_AO_DEMUX_ADJUST_VALUE 0x4C
+#define ME4000_AO_DEMUX_ADJUST_VALUE 0x4C
/*=============================================================================
typedef struct me4000_board {
- char *name;
+ const char *name;
unsigned short device_id;
me4000_ao_info_t ao;
me4000_ai_info_t ai;
unsigned long plx_regbase_size; // PLX register set space
unsigned long me4000_regbase_size; // ME4000 register set space
unsigned long timer_regbase_size; // Timer circuit register set space
- unsigned long program_regbase_size; // Size of program base address of the ME4000
+ unsigned long program_regbase_size; // Size of program base address of the ME4000
unsigned int serial_no; // Serial number of the board
unsigned char hw_revision; // Hardware revision of the board
/*-----------------------------------------------------------------------------
- Defines for analog input
+ Defines for analog input
----------------------------------------------------------------------------*/
/* General stuff */
device will be used.
The 2600 requires a firmware upload, which can be accomplished
-using the -i or --init-data option of comedi_config.
+using the -i or --init-data option of comedi_config.
The firmware can be
found in the comedi_nonfree_firmware tarball available
-from http://www.comedi.org
+from http://www.comedi.org
*/
attach: me_attach,
detach: me_detach,
num_names: me_board_nbr,
- board_name: me_boards,
+ board_name: (const char**)me_boards,
offset: sizeof(me_board_struct),
};
COMEDI_INITCLEANUP(me_driver);
//
// Probe the device to determine what device in the series it is.
//
- for(pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_device != NULL ;
+ for(pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_device != NULL ;
pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device))
{
if(pci_device->vendor == PCI_VENDOR_ID_MEILHAUS)
module: THIS_MODULE,
attach: atao_attach,
detach: atao_detach,
- board_name: atao_boards,
+ board_name: (const char**)atao_boards,
offset: sizeof(atao_board),
num_names: sizeof(atao_boards) / sizeof(atao_board),
};
comedi_subdevice *s;
unsigned long iobase;
int ao_unipolar;
-
+
iobase = it->options[0];
if(iobase==0)iobase = 0x1c0;
ao_unipolar = it->options[3];
-
+
printk("comedi%d: ni_at_ao: 0x%04lx",dev->minor,iobase);
-
+
if(!request_region(iobase, ATAO_SIZE, "ni_at_ao")){
printk(" I/O port conflict\n");
return -EIO;
s->range_table=&range_digital;
s->insn_bits = atao_dio_insn_bits;
s->insn_config = atao_dio_insn_config;
-
+
s=dev->subdevices+2;
/* caldac subdevice */
s->type=COMEDI_SUBD_CALIB;
/* eeprom subdevice */
//s->type=COMEDI_SUBD_EEPROM;
s->type=COMEDI_SUBD_UNUSED;
-
+
atao_reset(dev);
printk("\n");
if(dev->iobase)
release_region(dev->iobase, ATAO_SIZE);
-
+
return 0;
}
devpriv->cfg2 = 0;
outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
-
+
devpriv->cfg3 = 0;
outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
-
+
inw(dev->iobase + ATAO_FIFO_CLEAR);
devpriv->cfg1 |= GRP2WR;
int i;
int chan = CR_CHAN(insn->chanspec);
short bits;
-
+
for(i=0;i<insn->n;i++){
bits = data[i] - 0x800;
if(chan == 0)
*/
/*
* I must give credit here to Michal Dobes <dobes@tesnet.cz> who
- * wrote the driver for Advantec's pcl812 boards. I used the interrupt
+ * wrote the driver for Advantec's pcl812 boards. I used the interrupt
* handling code from his driver as an example for this one.
- *
+ *
* Chris Baugher
* 5/1/2000
- *
+ *
*/
#include <linux/comedidev.h>
module: THIS_MODULE,
attach: atmio16d_attach,
detach: atmio16d_detach,
- board_name: atmio16_boards,
+ board_name: (const char**)atmio16_boards,
num_names: n_atmio16_boards,
offset: sizeof(atmio16_board_t),
};
static void reset_atmio16d(comedi_device *dev)
{
int i;
-
+
/* now we need to initialize the board */
outw(0, dev->iobase+COM_REG_1);
outw(0, dev->iobase+COM_REG_2);
- outw(0, dev->iobase+MUX_GAIN_REG);
+ outw(0, dev->iobase+MUX_GAIN_REG);
/* init AM9513A timer */
outw(0xFFFF, dev->iobase+AM9513A_COM_REG);
outw(0xFFEF, dev->iobase+AM9513A_COM_REG);
reset_counters(dev);
s->async->cur_chan = 0;
-
+
/* check if scanning multiple channels */
if(cmd->chanlist_len < 2) {
devpriv->com_reg_1_state &= ~COMREG1_SCANEN;
if( i == cmd->scan_end_arg-1 ) tmp |= 0x0010; /* set LASTONE bit */
outw(tmp, dev->iobase+MUX_GAIN_REG);
}
-
+
/* Now program the sample interval timer */
/* Figure out which clock to use then get an
* appropriate timer value */
outw(0xFFF3, dev->iobase+AM9513A_COM_REG);
outw(timer, dev->iobase+AM9513A_DATA_REG);
outw(0xFF24, dev->iobase+AM9513A_COM_REG);
-
-
-
+
+
+
/* Now figure out how many samples to get */
/* and program the sample counter */
sample_count = cmd->stop_arg*cmd->scan_end_arg;
outw(timer, dev->iobase+AM9513A_DATA_REG);
outw(0xFF22, dev->iobase+AM9513A_COM_REG);
}
-
+
/* Clear the A/D FIFO and reset the MUX counter */
outw(0, dev->iobase+AD_CLEAR_REG);
outw(0, dev->iobase+MUX_CNTR_REG);
static int atmio16d_ai_cancel(comedi_device *dev, comedi_subdevice *s)
{
reset_atmio16d(dev);
-
+
return 0;
}
int chan;
int gain;
int status;
-
+
#ifdef DEBUG1
printk("atmio16d_ai_insn_read\n");
#endif
return -ETIME;
}
}
-
+
return i;
}
0=internal, 1=external
options[9] - dac0 coding
0=2's comp, 1=straight binary
-
+
options[10] - dac1 range
options[11] - dac1 reference
options[12] - dac1 coding
unsigned int irq;
unsigned long iobase;
int ret;
-
+
comedi_subdevice *s;
/* make sure the address range is free and allocate it */
}
dev->iobase = iobase;
-
+
/* board name */
dev->board_name = boardtype->name;
/* reset the atmio16d hardware */
reset_atmio16d(dev);
-
+
/* check if our interrupt is available and get it */
irq=it->options[1];
if(irq){
if((ret=comedi_request_irq(irq,atmio16d_interrupt,
0, "atmio16d", dev))<0)
{
- printk("failed to allocate irq %u\n", irq);
+ printk("failed to allocate irq %u\n", irq);
return ret;
}
dev->irq=irq;
/* set device options */
devpriv->adc_mux = it->options[5];
devpriv->adc_range = it->options[6];
-
+
devpriv->dac0_range = it->options[7];
devpriv->dac0_reference = it->options[8];
devpriv->dac0_coding = it->options[9];
devpriv->dac1_reference = it->options[11];
devpriv->dac1_coding = it->options[12];
-
+
/* setup sub-devices */
s=dev->subdevices+0;
dev->read_subdev = s;
s->maxdata=1;
s->range_table=&range_digital;
-
+
/* 8255 subdevice */
s++;
if(boardtype->has_8255){
comedi_free_irq(dev->irq,dev);
reset_atmio16d(dev);
-
+
if(dev->iobase)
release_region(dev->iobase, ATMIO16D_SIZE);
attach: labpc_attach,
detach: labpc_common_detach,
num_names: sizeof(labpc_boards) / sizeof(labpc_board),
- board_name: (char **)labpc_boards,
+ board_name: (const char **)labpc_boards,
offset: sizeof(labpc_board),
};
module: THIS_MODULE,
attach: pcl711_attach,
detach: pcl711_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
int chan_register;
outb(CR_RANGE(chan), dev->iobase + PCL711_GAIN);
-
+
chan_register=CR_CHAN(chan);
if (this_board->is_8112) {
}
rt_printk("comedi%d: pcl711: A/D timeout\n", dev->minor);
return -ETIME;
-
+
ok:
lo = inb(dev->iobase + PCL711_AD_LO);
/*
module/pcl724.c
- Michal Dobes <dobes@tesnet.cz>
+ Michal Dobes <dobes@tesnet.cz>
hardware driver for Advantech cards:
card: PCL-724, PCL-722, PCL-731
and ADLink cards:
card: ACL-7122, ACL-7124, PET-48DIO
driver: acl7122, acl7124, pet48dio
-
+
Options for PCL-724, PCL-731, ACL-7124 and PET-48DIO:
[0] - IO Base
int numofports; // num of 8255 subdevices
unsigned int IRQbits; // allowed interrupts
unsigned int io_range; // len of IO space
- char can_have96;
+ char can_have96;
char is_pet48;
} boardtype;
{
{"pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, },
{"pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0, },
- {"pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0, },
+ {"pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0, },
{"acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0, },
{"acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, },
{"pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1, },
module: THIS_MODULE,
attach: pcl724_attach,
detach: pcl724_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
int i;
// printk("comedi%d: pcl724: remove\n",dev->minor);
-
+
for(i=0;i<dev->n_subdevices;i++){
subdev_8255_cleanup(dev,dev->subdevices+i);
}
and for ADLink cards:
card: ACL-6126, ACL-6128
driver: acl6126, acl6128
-
+
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 1998 David A. Schleef <ds@schleef.org>
-
+
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
Options for PCL-726:
[0] - IO Base
- [2]...[7] - D/A output range for channel 1-6:
- 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+ [2]...[7] - D/A output range for channel 1-6:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
4: 4-20mA, 5: unknown (external reference)
-
+
Options for PCL-727:
[0] - IO Base
- [2]...[13] - D/A output range for channel 1-12:
- 0: 0-5V, 1: 0-10V, 2: +/-5V,
+ [2]...[13] - D/A output range for channel 1-12:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V,
3: 4-20mA
-
+
Options for PCL-728 and ACL-6128:
[0] - IO Base
- [2], [3] - D/A output range for channel 1 and 2:
- 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+ [2], [3] - D/A output range for channel 1 and 2:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
4: 4-20mA, 5: 0-20mA
-
+
Options for ACL-6126:
[0] - IO Base
[1] - IRQ (0=disable, 3, 5, 6, 7, 9, 10, 11, 12, 15) (currently ignored)
- [2]...[7] - D/A output range for channel 1-6:
- 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+ [2]...[7] - D/A output range for channel 1-6:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
4: 4-20mA
*/
static comedi_lrange range_0_20mA={ 1, {RANGE_mA(0,20)}};
static comedi_lrange *rangelist_726[]={
- &range_unipolar5, &range_unipolar10,
+ &range_unipolar5, &range_unipolar10,
&range_bipolar5, &range_bipolar10,
&range_4_20mA, &range_unknown
};
static comedi_lrange *rangelist_727[]={
- &range_unipolar5, &range_unipolar10,
- &range_bipolar5,
+ &range_unipolar5, &range_unipolar10,
+ &range_bipolar5,
&range_4_20mA
};
static comedi_lrange *rangelist_728[]={
- &range_unipolar5, &range_unipolar10,
+ &range_unipolar5, &range_unipolar10,
&range_bipolar5, &range_bipolar10,
&range_4_20mA, &range_0_20mA
};
static boardtype boardtypes[] =
{
- {"pcl726", 6, 6, 0x0000, PCL726_SIZE, 1,
- PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
+ {"pcl726", 6, 6, 0x0000, PCL726_SIZE, 1,
+ PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
&rangelist_726[0], },
- {"pcl727", 12, 4, 0x0000, PCL727_SIZE, 1,
- PCL727_DI_HI, PCL727_DI_LO, PCL727_DO_HI, PCL727_DO_LO,
+ {"pcl727", 12, 4, 0x0000, PCL727_SIZE, 1,
+ PCL727_DI_HI, PCL727_DI_LO, PCL727_DO_HI, PCL727_DO_LO,
&rangelist_727[0], },
- {"pcl728", 2, 6, 0x0000, PCL728_SIZE, 0,
- 0, 0, 0, 0,
+ {"pcl728", 2, 6, 0x0000, PCL728_SIZE, 0,
+ 0, 0, 0, 0,
&rangelist_728[0], },
{"acl6126", 6, 5, 0x96e8, PCL726_SIZE, 1,
- PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
+ PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
&rangelist_726[0], },
{"acl6128", 2, 6, 0x0000, PCL728_SIZE, 0,
0, 0, 0, 0,
module: THIS_MODULE,
attach: pcl726_attach,
detach: pcl726_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
outb(lo,dev->iobase+PCL726_DAC0_LO + 2*chan);
devpriv->ao_readback[chan]=data[n];
}
-
+
return n;
}
comedi_insn *insn,lsampl_t *data)
{
if(insn->n!=2)return -EINVAL;
-
+
data[1]=inb(dev->iobase+this_board->di_lo)|
(inb(dev->iobase+this_board->di_hi)<<8);
-
+
return 2;
}
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];
outb((s->state>>8),dev->iobase+this_board->do_hi);
data[1] = s->state;
-
+
return 2;
}
#ifdef ACL6126_IRQ
unsigned int irq;
#endif
-
+
iobase=it->options[0];
iorange=this_board->io_range;
printk("comedi%d: pcl726: board=%s, 0x%03lx ",dev->minor,this_board->name,iobase);
printk("I/O port conflict\n");
return -EIO;
}
-
+
dev->iobase=iobase;
-
+
dev->board_name = this_board->name;
if((ret=alloc_private(dev,sizeof(pcl726_private)))<0)
if (((1<<irq)&boardtypes[board].IRQbits)==0) {
rt_printk(", IRQ %d is out of allowed range, DISABLING IT",irq);
irq=0; /* Bad IRQ */
- } else {
+ } else {
if (comedi_request_irq(irq, interrupt_pcl818, 0, "pcl726", dev)) {
rt_printk(", unable to allocate IRQ %d, DISABLING IT", irq);
irq=0; /* Can't use IRQ */
} else {
rt_printk(", irq=%d", irq);
- }
- }
+ }
+ }
}
}
dev->irq = irq;
#endif
-
+
printk("\n");
if((ret=alloc_subdevices(dev, 3))<0)
static int pcl726_detach(comedi_device *dev)
{
// printk("comedi%d: pcl726: remove\n",dev->minor);
-
+
#ifdef ACL6126_IRQ
if(dev->irq){
comedi_free_irq(dev->irq,dev);
module: THIS_MODULE,
attach: pcl730_attach,
detach: pcl730_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
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;
if( insn->n != 2 )
return -EINVAL;
- data[1]=inb(dev->iobase+((unsigned long)s->private)) |
+ data[1]=inb(dev->iobase+((unsigned long)s->private)) |
(inb(dev->iobase+((unsigned long)s->private)+1)<<8);
return 2;
s->n_chan=16;
s->insn_bits = pcl730_do_insn;
s->range_table=&range_digital;
- s->private = (void *)PCL730_IDIO_LO;
+ s->private = (void *)PCL730_IDIO_LO;
s=dev->subdevices+1;
/* Isolated di */
s->n_chan=16;
s->insn_bits = pcl730_di_insn;
s->range_table=&range_digital;
- s->private = (void *)PCL730_IDIO_LO;
+ s->private = (void *)PCL730_IDIO_LO;
s=dev->subdevices+2;
/* TTL do */
s->n_chan=16;
s->insn_bits = pcl730_do_insn;
s->range_table=&range_digital;
- s->private = (void *)PCL730_DIO_LO;
+ s->private = (void *)PCL730_DIO_LO;
s=dev->subdevices+3;
/* TTL di */
s->n_chan=16;
s->insn_bits = pcl730_di_insn;
s->range_table=&range_digital;
- s->private = (void *)PCL730_DIO_LO;
+ s->private = (void *)PCL730_DIO_LO;
printk("\n");
if(dev->iobase)
release_region(dev->iobase, this_board->io_range);
-
+
return 0;
}
* card: ACL-8112DG, ACL-8112HG, ACL-8112PG, ACL-8113, ACL-8216
* driver: acl8112dg, acl8112hg, acl8112pg, acl8113, acl8216
* and for ICP DAS cards
- * card: ISO-813, A-821PGH, A-821PGL, A-821PGL-NDA, A-822PGH, A-822PGL,
+ * card: ISO-813, A-821PGH, A-821PGL, A-821PGL-NDA, A-822PGH, A-822PGL,
* driver: iso813, a821pgh, a-821pgl, a-821pglnda, a822pgh, a822pgl,
- * card: A-823PGH, A-823PGL, A-826PG
+ * card: A-823PGH, A-823PGL, A-826PG
* driver: a823pgh, a823pgl, a826pg
*/
/*
* [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
* [2] - DMA (0=disable, 1, 3)
* [3] - 0=trigger source is internal 8253 with 2MHz clock
- * 1=trigger source is external
+ * 1=trigger source is external
* [4] - 0=A/D input range is +/-10V
* 1=A/D input range is +/-5V
* 2=A/D input range is +/-2.5V
* [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
* [2] - DMA (0=disable, 1, 3)
* [3] - 0=trigger source is internal 8253 with 2MHz clock
- * 1=trigger source is external
+ * 1=trigger source is external
* [4] - 0=A/D have max +/-5V input
* 1=A/D have max +/-10V input
* [5] - 0=D/A outputs 0-5V (internal reference -5V)
* [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
* [2] - DMA (0=disable, 1, 3)
* [3] - 0=trigger source is internal 8253 with 2MHz clock
- * 1=trigger source is external
+ * 1=trigger source is external
* [4] - 0=A/D channels are S.E.
* 1=A/D channels are DIFF
* [5] - 0=D/A outputs 0-5V (internal reference -5V)
* [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
* [2] - 0=A/D channels are S.E.
* 1=A/D channels are DIFF
- * [3] - 0=D/A output 0-5V (internal reference -5V)
+ * [3] - 0=D/A output 0-5V (internal reference -5V)
* 1=D/A output 0-10V (internal reference -10V)
*
* Options for A-821PGL-NDA:
* [0] - IO Base
* [1] - 0= bipolar inputs
* 1= unipolar inputs
- *
+ *
* Options for ACL-8113, ISO-813:
* [0] - IO Base
* [1] - 0= 10V bipolar inputs
* 1= 10V unipolar inputs
* 2= 20V bipolar inputs
* 3= 20V unipolar inputs
- *
+ *
*/
#include <linux/comedidev.h>
module: THIS_MODULE,
attach: pcl812_attach,
detach: pcl812_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
unsigned int ai_scans; // len of scanlist
unsigned int ai_act_scan; // how many scans we finished
unsigned int ai_chanlist[MAX_CHANLIST_LEN];// our copy of channel/range list
- unsigned int ai_n_chan; // how many channels is measured
+ unsigned int ai_n_chan; // how many channels is measured
unsigned int ai_flags; // flaglist
unsigned int ai_data_len; // len of data buffer
sampl_t *ai_data; // data buffer
#define devpriv ((pcl812_private *)dev->private)
-/*
+/*
==============================================================================
*/
static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2);
-static void setup_range_channel(comedi_device * dev, comedi_subdevice * s,
+static void setup_range_channel(comedi_device * dev, comedi_subdevice * s,
unsigned int rangechan, char wait);
static int pcl812_ai_cancel(comedi_device * dev, comedi_subdevice * s);
-/*
+/*
==============================================================================
*/
static int pcl812_ai_insn_read(comedi_device *dev,comedi_subdevice *s,
return n;
}
-/*
+/*
==============================================================================
*/
static int acl8216_ai_insn_read(comedi_device *dev,comedi_subdevice *s,
return n;
}
-/*
+/*
==============================================================================
*/
static int pcl812_ao_insn_write(comedi_device *dev,comedi_subdevice *s,
return i;
}
-/*
+/*
==============================================================================
*/
static int pcl812_ao_insn_read(comedi_device *dev,comedi_subdevice *s,
return i;
}
-/*
+/*
==============================================================================
*/
static int pcl812_di_insn_bits(comedi_device *dev,comedi_subdevice *s,
return 2;
}
-/*
+/*
==============================================================================
*/
static int pcl812_do_insn_bits(comedi_device *dev,comedi_subdevice *s,
}
#ifdef PCL812_EXTDEBUG
-/*
+/*
==============================================================================
*/
static void pcl812_cmdtest_out(int e,comedi_cmd *cmd) {
}
#endif
-/*
+/*
==============================================================================
*/
static int pcl812_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
return 0;
}
-/*
+/*
==============================================================================
*/
static int pcl812_ai_cmd(comedi_device *dev,comedi_subdevice *s)
{
unsigned int divisor1=0, divisor2=0, i, dma_flags, bytes;
comedi_cmd *cmd=&s->async->cmd;
-
+
#ifdef PCL812_EXTDEBUG
rt_printk("pcl812 EDBG: BGN: pcl812_ai_cmd(...)\n");
#endif
if (cmd->convert_src==TRIG_TIMER) {
if(cmd->convert_arg<this_board->ai_ns_min) cmd->convert_arg=this_board->ai_ns_min;
- i8253_cascade_ns_to_timer(this_board->i8254_osc_base,
- &divisor1, &divisor2, &cmd->convert_arg,
+ i8253_cascade_ns_to_timer(this_board->i8254_osc_base,
+ &divisor1, &divisor2, &cmd->convert_arg,
cmd->flags&TRIG_ROUND_MASK);
}
if (devpriv->dma) { // check if we can use DMA transfer
devpriv->ai_dma=1;
- for (i=1; i<devpriv->ai_n_chan; i++)
+ for (i=1; i<devpriv->ai_n_chan; i++)
if (devpriv->ai_chanlist[0]!=devpriv->ai_chanlist[i]) {
devpriv->ai_dma=0; // we cann't use DMA :-(
break;
}
} else devpriv->ai_dma=0;
-
+
devpriv->ai_flags=cmd->flags;
devpriv->ai_data_len=s->async->prealloc_bufsz;
devpriv->ai_data=s->async->prealloc_buf;
devpriv->ai_poll_ptr=0;
s->async->cur_chan=0;
- if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan?
+ if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan?
devpriv->ai_eos=1;
if (devpriv->ai_n_chan==1)
devpriv->ai_dma=0; // DMA is useless for this situation
}
- if (devpriv->ai_dma) {
+ if (devpriv->ai_dma) {
if (devpriv->ai_eos) { // we use EOS, so adapt DMA buffer to one scan
devpriv->dmabytestomove[0]=devpriv->ai_n_chan*sizeof(sampl_t);
devpriv->dmabytestomove[1]=devpriv->ai_n_chan*sizeof(sampl_t);
- devpriv->dma_runs_to_end=1;
+ devpriv->dma_runs_to_end=1;
} else {
- devpriv->dmabytestomove[0]=devpriv->hwdmasize[0];
+ devpriv->dmabytestomove[0]=devpriv->hwdmasize[0];
devpriv->dmabytestomove[1]=devpriv->hwdmasize[1];
if (devpriv->ai_data_len<devpriv->hwdmasize[0])
devpriv->dmabytestomove[0]=devpriv->ai_data_len;
if (devpriv->ai_data_len<devpriv->hwdmasize[1])
devpriv->dmabytestomove[1]=devpriv->ai_data_len;
if (devpriv->ai_neverending) {
- devpriv->dma_runs_to_end=1;
+ devpriv->dma_runs_to_end=1;
} else {
bytes=devpriv->ai_n_chan*devpriv->ai_scans*sizeof(sampl_t); // how many samples we must transfer?
devpriv->dma_runs_to_end=bytes / devpriv->dmabytestomove[0]; // how many DMA pages we must fill
devpriv->last_dma_run=bytes % devpriv->dmabytestomove[0]; //on last dma transfer must be moved
- if (devpriv->dma_runs_to_end==0)
+ if (devpriv->dma_runs_to_end==0)
devpriv->dmabytestomove[0]=devpriv->last_dma_run;
devpriv->dma_runs_to_end--;
}
devpriv->ai_eos);
#endif
}
-
+
switch (cmd->convert_src) {
case TRIG_TIMER:
start_pacer(dev, 1, divisor1, divisor2);
break;
}
-
- if (devpriv->ai_dma) {
+
+ if (devpriv->ai_dma) {
outb(devpriv->mode_reg_int|2, dev->iobase + PCL812_MODE); // let's go!
} else {
outb(devpriv->mode_reg_int|6, dev->iobase + PCL812_MODE); // let's go!
return 0;
}
-/*
+/*
==============================================================================
*/
static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d, struct pt_regs *regs)
sampl_t *ptr, unsigned int bufptr, unsigned int len)
{
unsigned int i;
-
+
s->async->events = 0;
for (i=len; i; i--) {
comedi_buf_put( s->async, ptr[bufptr++] ); // get one sample
comedi_event(dev,s,s->async->events);
}
-/*
+/*
==============================================================================
*/
static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d, struct pt_regs *regs)
/*
==============================================================================
*/
-static void setup_range_channel(comedi_device * dev, comedi_subdevice * s,
+static void setup_range_channel(comedi_device * dev, comedi_subdevice * s,
unsigned int rangechan, char wait)
{
unsigned char chan_reg=CR_CHAN(rangechan); // normal board
unsigned char gain_reg=CR_RANGE(rangechan)+devpriv->range_correction; // gain index
-
- if ((chan_reg==devpriv->old_chan_reg)&&(gain_reg==devpriv->old_gain_reg))
+
+ if ((chan_reg==devpriv->old_chan_reg)&&(gain_reg==devpriv->old_gain_reg))
return; // we can return, no change
-
+
devpriv->old_chan_reg=chan_reg;
devpriv->old_gain_reg=gain_reg;
-
+
if (devpriv->use_MPC) {
if (devpriv->use_diff) {
- chan_reg=chan_reg | 0x30; // DIFF inputs
+ chan_reg=chan_reg | 0x30; // DIFF inputs
} else {
if (chan_reg&0x80) {
chan_reg=chan_reg | 0x20; // SE inputs 8-15
}
}
}
-
+
outb(chan_reg, dev->iobase + PCL812_MUX); /* select channel */
outb(gain_reg, dev->iobase + PCL812_GAIN); /* select gain */
/*
==============================================================================
*/
-static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2)
+static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2)
{
#ifdef PCL812_EXTDEBUG
rt_printk("pcl812 EDBG: BGN: start_pacer(%d,%u,%u)\n",mode,divisor1,divisor2);
outb(0xb4, dev->iobase + PCL812_CTRCTL);
outb(0x74, dev->iobase + PCL812_CTRCTL);
comedi_udelay(1);
-
+
if (mode==1) {
outb(divisor2 & 0xff, dev->iobase + PCL812_CTR2);
outb((divisor2 >> 8) & 0xff, dev->iobase + PCL812_CTR2);
#endif
}
-/*
+/*
==============================================================================
*/
static void free_resources(comedi_device * dev)
release_region(dev->iobase, this_board->io_range);
}
-/*
+/*
==============================================================================
*/
static int pcl812_ai_cancel(comedi_device * dev, comedi_subdevice * s)
return 0;
}
-/*
+/*
==============================================================================
*/
static void pcl812_reset(comedi_device * dev)
s->n_chan = this_board->n_aichan;
s->subdev_flags |= SDF_GROUND;
}
- break;
+ break;
case boardACL8112:
case boardACL8216:
if (it->options[4] == 1) {
s->n_chan = this_board->n_aichan;
s->subdev_flags |= SDF_GROUND;
}
- break;
+ break;
default:
s->n_chan = this_board->n_aichan;
s->subdev_flags |= SDF_GROUND;
- break;
+ break;
}
s->maxdata = this_board->ai_maxdata;
s->len_chanlist = MAX_CHANLIST_LEN;
devpriv->max_812_ai_mode0_rangewait = 5; /* maybe there must by greatest timeout */
break;
}
-
+
printk("\n");
devpriv->valid=1;
unsigned int IRQbits; // allowed interrupts
unsigned int DMAbits; // allowed DMA chans
int ai_maxdata; // maxdata for A/D
- int ao_maxdata; // maxdata for D/A
+ int ao_maxdata; // maxdata for D/A
int ai_chanlist; // allowed len of channel list A/D
int ao_chanlist; // allowed len of channel list D/A
int i8254_osc_base; // 1/frequency of on board oscilator in ns
static boardtype boardtypes[] = {
{"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816,
- &range_pcl816, PCLx1x_RANGE,
- 0x00fc, // IRQ mask
+ &range_pcl816, PCLx1x_RANGE,
+ 0x00fc, // IRQ mask
0x0a, // DMA mask
- 0xffff, // 16-bit card
+ 0xffff, // 16-bit card
0xffff, // D/A maxdata
- 1024,
- 1, // ao chan list
+ 1024,
+ 1, // ao chan list
100 },
{"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816,
- &range_pcl816, PCLx1x_RANGE,
+ &range_pcl816, PCLx1x_RANGE,
0x00fc,
- 0x0a,
+ 0x0a,
0x3fff, /* 14 bit card */
- 0x3fff,
+ 0x3fff,
1024,
1,
100},
module: THIS_MODULE,
attach: pcl816_attach,
detach: pcl816_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
int rtc_irq_blocked; // 1=we now do AI with DMA&RTC
#endif
int irq_was_now_closed; // when IRQ finish, there's stored int816_mode for last interrupt
- int int816_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
+ int int816_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
comedi_subdevice *last_int_sub; // ptr to subdevice which now finish
int ai_act_scan; // how many scans we finished
unsigned int ai_act_chanlist[16]; // MUX setting for actual AI operations
-/*
+/*
==============================================================================
*/
static int check_and_setup_channel_list (comedi_device * dev, comedi_subdevice * s, unsigned int *chanlist, int chanlen);
static int pcl816_ai_cmd(comedi_device *dev, comedi_subdevice *s);
-/*
+/*
==============================================================================
ANALOG INPUT MODE0, 816 cards, slow version
*/
int timeout;
DPRINTK("mode 0 analog input\n");
- // software trigger, DMA and INT off
- outb (0, dev->iobase + PCL816_CONTROL);
- // clear INT (conversion end) flag
- outb (0, dev->iobase + PCL816_CLRINT);
-
+ // software trigger, DMA and INT off
+ outb (0, dev->iobase + PCL816_CONTROL);
+ // clear INT (conversion end) flag
+ outb (0, dev->iobase + PCL816_CLRINT);
+
// Set the input channel
- outb (CR_CHAN(insn->chanspec) & 0xf, dev->iobase + PCL816_MUX);
+ outb (CR_CHAN(insn->chanspec) & 0xf, dev->iobase + PCL816_MUX);
outb (CR_RANGE(insn->chanspec), dev->iobase + PCL816_RANGE); /* select gain */
for(n=0;n<insn->n;n++){
timeout=100;
while (timeout--) {
if (!(inb (dev->iobase + PCL816_STATUS) & PCL816_STATUS_DRDY_MASK)) {
- // return read value
+ // return read value
data[n] =
((inb (dev->iobase + PCL816_AD_HI) << 8 ) |
(inb (dev->iobase + PCL816_AD_LO)));
outb (0, dev->iobase + PCL816_CLRINT); /* clear INT (conversion end) flag */
return -EIO;
}
-
+
}
return n;
}
/*
==============================================================================
analog input interrupt mode 1 & 3, 818 cards
- one sample per interrupt version
+ one sample per interrupt version
*/
static irqreturn_t
interrupt_pcl816_ai_mode13_int (int irq, void *d, struct pt_regs *regs)
sampl_t *ptr, unsigned int bufptr, unsigned int len)
{
int i;
-
+
s->async->events = 0;
for (i = 0; i < len; i++) {
rt_printk("pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",e,cmd->stop_arg,cmd->scan_end_arg,cmd->chanlist_len);
}
-/*
+/*
==============================================================================
*/
static int pcl816_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
cmd->convert_src=TRIG_TIMER;
err++;
}
-
+
if(cmd->scan_end_src!=TRIG_COUNT) {
cmd->scan_end_src=TRIG_COUNT;
{
unsigned int divisor1=0, divisor2=0, dma_flags, bytes, dmairq;
comedi_cmd *cmd=&s->async->cmd;
-
+
if(cmd->start_src!=TRIG_NOW) return -EINVAL;
if(cmd->scan_begin_src!=TRIG_FOLLOW) return -EINVAL;
return -EBUSY;
if (cmd->convert_src==TRIG_TIMER) {
- if(cmd->convert_arg < this_board->ai_ns_min)
+ if(cmd->convert_arg < this_board->ai_ns_min)
cmd->convert_arg=this_board->ai_ns_min;
i8253_cascade_ns_to_timer (this_board->i8254_osc_base, &divisor1,
&divisor2, &cmd->convert_arg, cmd->flags&TRIG_ROUND_MASK);
- if (divisor1 == 1) { // PCL816 crash if any divisor is set to 1
+ if (divisor1 == 1) { // PCL816 crash if any divisor is set to 1
divisor1 = 2;
divisor2 /= 2;
}
return -EINVAL;
comedi_udelay (1);
-
+
devpriv->ai_act_scan=0;
s->async->cur_chan=0;
devpriv->irq_blocked = 1;
devpriv->ai_poll_ptr=0;
devpriv->irq_was_now_closed = 0;
-
- if (cmd->stop_src==TRIG_COUNT) {
- devpriv->ai_scans = cmd->stop_arg;
- devpriv->ai_neverending = 0;
- } else {
- devpriv->ai_scans = 0;
- devpriv->ai_neverending = 1;
+
+ if (cmd->stop_src==TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ devpriv->ai_neverending = 0;
+ } else {
+ devpriv->ai_scans = 0;
+ devpriv->ai_neverending = 1;
}
- if ((cmd->flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan?
+ if ((cmd->flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan?
printk("pl816: You wankt WAKE_EOS but I dont want handle it");
// devpriv->ai_eos=1;
//if (devpriv->ai_n_chan==1)
// devpriv->dma=0; // DMA is useless for this situation
}
- if (devpriv->dma) {
+ if (devpriv->dma) {
bytes = devpriv->hwdmasize[0];
if (!devpriv->ai_neverending) {
- bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof (sampl_t); // how many
+ bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof (sampl_t); // how many
devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fill
devpriv->last_dma_run = bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved
devpriv->dma_runs_to_end--;
release_dma_lock (dma_flags);
enable_dma (devpriv->dma);
}
-
+
start_pacer(dev, 1, divisor1, divisor2);
dmairq = ((devpriv->dma & 0x3)<<4) | (dev->irq & 0x7);
switch (cmd->convert_src) {
case TRIG_TIMER:
devpriv->int816_mode = INT_TYPE_AI1_DMA;
- outb (0x32, dev->iobase + PCL816_CONTROL); // Pacer+IRQ+DMA
+ outb (0x32, dev->iobase + PCL816_CONTROL); // Pacer+IRQ+DMA
outb(dmairq, dev->iobase + PCL816_STATUS); // write irq and DMA to card
break;
}
-/*
+/*
==============================================================================
cancel any mode 1-4 AI
*/
pcl816_ai_cancel (comedi_device * dev, comedi_subdevice * s)
{
// DEBUG(rt_printk("pcl816_ai_cancel()\n");)
-
+
if (devpriv->irq_blocked > 0) {
switch (devpriv->int816_mode) {
#ifdef unused
break;
}
}
-
+
DEBUG(rt_printk("comedi: pcl816_ai_cancel() successful\n");)
return 0;
}
-/*
+/*
==============================================================================
chech for PCL816
*/
return 0; // ok, card exist
}
-/*
+/*
==============================================================================
reset whole PCL-816 cards
*/
outb(divisor1 & 0xff, dev->iobase + PCL816_CTR1);
outb((divisor1 >> 8) & 0xff, dev->iobase + PCL816_CTR1);
}
-
+
/* clear pending interrupts (just in case) */
// outb(0, dev->iobase + PCL816_CLRINT);
}
/*
==============================================================================
- Check if channel list from user is builded correctly
+ Check if channel list from user is builded correctly
If it's ok, then program scan/gain logic
*/
static int
unsigned int chansegment[16];
unsigned int i, nowmustbechan, seglen, segpos;
- // correct channel and range number check itself comedi/range.c
+ // correct channel and range number check itself comedi/range.c
if (chanlen < 1) {
comedi_error (dev, "range/channel list is empty!");
return 0;
if (chanlen > 1)
{
chansegment[0] = chanlist[0]; // first channel is everytime ok
- for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
+ for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
// build part of chanlist
DEBUG(rt_printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i]));)
if (chanlist[0] == chanlist[i])
for (i = 0; i < seglen; i++) { // store range list to card
devpriv->ai_act_chanlist[i] = CR_CHAN (chanlist[i]);
- outb (CR_CHAN(chanlist[0]) & 0xf, dev->iobase + PCL816_MUX);
+ outb (CR_CHAN(chanlist[0]) & 0xf, dev->iobase + PCL816_MUX);
outb (CR_RANGE(chanlist[0]), dev->iobase + PCL816_RANGE); /* select gain */
}
}
#ifdef unused
-/*
+/*
==============================================================================
Enable(1)/disable(0) periodic interrupts from RTC
*/
{
unsigned char val;
unsigned long flags;
-
+
if (bit==1) {
RTC_timer_lock++;
if (RTC_timer_lock>1) return 0;
if (RTC_timer_lock<0) RTC_timer_lock=0;
if (RTC_timer_lock>0) return 0;
}
-
+
save_flags(flags);
cli();
val = CMOS_READ(RTC_CONTROL);
#endif
-/*
+/*
==============================================================================
- Free any resources that we have claimed
+ Free any resources that we have claimed
*/
static void
free_resources (comedi_device * dev)
}
-/*
+/*
==============================================================================
- Initialization
+ Initialization
*/
static int
iobase = it->options[0];
printk("comedi%d: pcl816: board=%s, ioport=0x%03lx", dev->minor,
this_board->name, iobase);
-
+
if (!request_region (iobase, this_board->io_range, "pcl816")) {
rt_printk ("I/O port conflict\n");
return -EIO;
#else
printk("pcl816: RTC code missing");
#endif
-
+
}
no_rtc:
devpriv->dma = dma;
if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
goto no_dma; /* if we haven't IRQ, we can't use DMA */
-
+
if (this_board->DMAbits != 0) { /* board support DMA */
dma = it->options[2];
if (dma < 1)
goto no_dma; /* DMA disabled */
-
+
if (((1 << dma) & this_board->DMAbits) == 0) {
rt_printk (", DMA is out of allowed range, FAIL!\n");
return -EINVAL; /* Bad DMA */
rt_printk (", unable to allocate DMA %u, FAIL!\n", dma);
return -EBUSY; /* DMA isn't free */
}
-
+
devpriv->dma = dma;
rt_printk (", dma=%u", dma);
pages = 2; /* we need 16KB */
devpriv->dmabuf[0] = __get_dma_pages (GFP_KERNEL, pages);
-
+
if (!devpriv->dmabuf[0]) {
rt_printk (", unable to allocate DMA buffer, FAIL!\n");
/* maybe experiment with try_to_free_pages() will help .... */
/*
module/pcl818.c
- Author: Michal Dobes <dobes@tesnet.cz>
+ Author: Michal Dobes <dobes@tesnet.cz>
hardware driver for Advantech cards:
card: PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818, PCL-718
[5] - 0, 5=D/A output 0-5V (internal reference -5V)
1, 10=D/A output 0-10V (internal reference -10V)
2 =D/A output unknow (external reference)
-
+
Options for PCL-818, PCL-818H:
[0] - IO Base
[1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
Options for PCL-818HD, PCL-818HG:
[0] - IO Base
[1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
- [2] - DMA/FIFO (-1=use FIFO, 0=disable both FIFO and DMA,
+ [2] - DMA/FIFO (-1=use FIFO, 0=disable both FIFO and DMA,
1=use DMA ch 1, 3=use DMA ch 3)
[3] - 0, 10=10MHz clock for 8254
1= 1MHz clock for 8254
1= +/-5V
2= +/-2.5V
3= +/-1V
- 4= +/-0.5V
+ 4= +/-0.5V
5= user defined bipolar
6= 0-10V
7= 0-5V
// W: D/A low&high byte
#define PCL818_DA_LO 4
#define PCL818_DA_HI 5
-// R: low&high byte of DI
+// R: low&high byte of DI
#define PCL818_DI_LO 3
#define PCL818_DI_HI 11
// W: low&high byte of DO
// type of interrupt handler
#define INT_TYPE_AI1_INT 1
-#define INT_TYPE_AI1_DMA 2
+#define INT_TYPE_AI1_DMA 2
#define INT_TYPE_AI1_FIFO 3
#define INT_TYPE_AI3_INT 4
#define INT_TYPE_AI3_DMA 5
unsigned int IRQbits; // allowed interrupts
unsigned int DMAbits; // allowed DMA chans
int ai_maxdata; // maxdata for A/D
- int ao_maxdata; // maxdata for D/A
+ int ao_maxdata; // maxdata for D/A
unsigned char fifo; // 1=board has FIFO
int is_818;
} boardtype;
static boardtype boardtypes[] =
{
- {"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ {"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
0x0a, 0xfff, 0xfff, 0, 1 },
- {"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ {"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
0x0a, 0xfff, 0xfff, 0, 1 },
- {"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ {"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
0x0a, 0xfff, 0xfff, 1, 1 },
{"pcl818hg", 12, 16, 8, 10000, 1, 16, 16, &range_pcl818hg_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
0x0a, 0xfff, 0xfff, 1, 1 },
- {"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ {"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
0x0a, 0xfff, 0xfff, 0, 1 },
- {"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ {"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
0x0a, 0xfff, 0xfff, 0, 0 },
/* pcm3718 */
- {"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ {"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai, &range_unipolar5, PCLx1x_RANGE, 0x00fc,
0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ },
};
module: THIS_MODULE,
attach: pcl818_attach,
detach: pcl818_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
int irq_free; // 1=have allocated IRQ
int irq_blocked; // 1=IRQ now uses any subdev
int irq_was_now_closed;// when IRQ finish, there's stored int818_mode for last interrupt
- int ai_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
+ int ai_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
comedi_subdevice *last_int_sub; // ptr to subdevice which now finish
int ai_act_scan; // how many scans we finished
int ai_act_chan; // actual position in actual scan
unsigned int act_chanlist_len;// how long is actual MUX list
unsigned int act_chanlist_pos;// actual position in MUX list
unsigned int ai_scans; // len of scanlist
- unsigned int ai_n_chan; // how many channels is measured
+ unsigned int ai_n_chan; // how many channels is measured
unsigned int *ai_chanlist; // actaul chanlist
unsigned int ai_flags; // flaglist
unsigned int ai_data_len; // len of data buffer
#define devpriv ((pcl818_private *)dev->private)
#define this_board ((boardtype *)dev->board_ptr)
-/*
+/*
==============================================================================
*/
static void setup_channel_list(comedi_device * dev, comedi_subdevice * s, unsigned int *chanlist,
static int rtc_setfreq_irq(int freq);
#endif
-/*
+/*
==============================================================================
ANALOG INPUT MODE0, 818 cards, slow version
*/
comedi_insn *insn, lsampl_t *data)
{
int n;
- int timeout;
+ int timeout;
/* software trigger, DMA and INT off */
outb(0, dev->iobase+PCL818_CONTROL);
return n;
}
-/*
+/*
==============================================================================
ANALOG OUTPUT MODE0, 818 cards
only one sample per call is supported
return n;
}
-/*
+/*
==============================================================================
DIGITAL INPUT MODE0, 818 cards
-
+
only one sample per call is supported
*/
static int pcl818_di_insn_bits(comedi_device *dev, comedi_subdevice *s,
return 2;
}
-/*
+/*
==============================================================================
DIGITAL OUTPUT MODE0, 818 cards
-
+
only one sample per call is supported
*/
static int pcl818_do_insn_bits(comedi_device *dev, comedi_subdevice *s,
outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
data[1] = s->state;
-
+
return 2;
}
if ((!dev->irq)||(!devpriv->irq_free)||(!devpriv->irq_blocked)||(!devpriv->ai_mode)) {
if (devpriv->irq_was_now_closed) {
- if ( devpriv->neverending_ai &&
+ if ( devpriv->neverending_ai &&
(devpriv->ai_mode == INT_TYPE_AI1_DMA || devpriv->ai_mode == INT_TYPE_AI3_DMA) ) {
/* we had neverending ai but ai_cancel() has been called
the cleanup from ai_cancel() has been delayed until know
==============================================================================
ANALOG INPUT MODE 1 or 3 DMA , 818 cards
*/
-static void pcl818_ai_mode13dma_int(int mode, comedi_device * dev, comedi_subdevice * s)
+static void pcl818_ai_mode13dma_int(int mode, comedi_device * dev, comedi_subdevice * s)
{
unsigned int flags;
unsigned int bytes;
disable_dma(devpriv->dma); // disable dma
bytes=devpriv->hwdmasize[0];
if (!devpriv->neverending_ai) {
- bytes=devpriv->ai_n_chan*devpriv->ai_scans*sizeof(sampl_t); // how many
+ bytes=devpriv->ai_n_chan*devpriv->ai_scans*sizeof(sampl_t); // how many
devpriv->dma_runs_to_end=bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fiil
devpriv->last_dma_run=bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved
devpriv->dma_runs_to_end--;
if (devpriv->dma_runs_to_end>=0) bytes=devpriv->hwdmasize[0];
- }
+ }
devpriv->next_dma_buf=0;
set_dma_mode(devpriv->dma, DMA_MODE_READ);
release_dma_lock(flags);
enable_dma(devpriv->dma);
- if (mode==1) {
+ if (mode==1) {
devpriv->ai_mode=INT_TYPE_AI1_DMA;
- outb(0x87 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ+DMA */
- } else {
+ outb(0x87 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ+DMA */
+ } else {
devpriv->ai_mode=INT_TYPE_AI3_DMA;
- outb(0x86 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ+DMA */
+ outb(0x86 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ+DMA */
};
}
#ifdef unused
-/*
+/*
==============================================================================
ANALOG INPUT MODE 1 or 3 DMA rtc, 818 cards
*/
-static void pcl818_ai_mode13dma_rtc(int mode, comedi_device * dev, comedi_subdevice * s)
+static void pcl818_ai_mode13dma_rtc(int mode, comedi_device * dev, comedi_subdevice * s)
{
unsigned int flags;
sampl_t *pole;
-
+
set_dma_mode(devpriv->dma, DMA_MODE_READ|DMA_AUTOINIT);
flags=claim_dma_lock();
clear_dma_ff(devpriv->dma);
devpriv->rtc_irq_timer.expires=jiffies + HZ/devpriv->rtc_freq + 2*HZ/100;
devpriv->rtc_irq_timer.data=(unsigned long)dev;
devpriv->rtc_irq_timer.function=rtc_dropped_irq;
-
+
add_timer(&devpriv->rtc_irq_timer);
#endif
-
- if (mode==1) {
+
+ if (mode==1) {
devpriv->int818_mode=INT_TYPE_AI1_DMA_RTC;
- outb(0x07 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+DMA */
- } else {
+ outb(0x07 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+DMA */
+ } else {
devpriv->int818_mode=INT_TYPE_AI3_DMA_RTC;
- outb(0x06 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+DMA */
+ outb(0x06 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+DMA */
};
}
#endif
-/*
+/*
==============================================================================
ANALOG INPUT MODE 1 or 3, 818 cards
*/
-static int pcl818_ai_cmd_mode(int mode, comedi_device * dev, comedi_subdevice * s)
+static int pcl818_ai_cmd_mode(int mode, comedi_device * dev, comedi_subdevice * s)
{
comedi_cmd *cmd=&s->async->cmd;
int divisor1, divisor2;
devpriv->neverending_ai=0;
devpriv->act_chanlist_pos=0;
devpriv->dma_runs_to_end=0;
-
+
if ((devpriv->ai_scans==0)||(devpriv->ai_scans==-1)) devpriv->neverending_ai=1; //well, user want neverending
-
+
if (mode==1) {
i8253_cascade_ns_to_timer(devpriv->i8253_osc_base,&divisor1,&divisor2,&cmd->convert_arg,TRIG_ROUND_NEAREST);
if (divisor1==1) { /* PCL718/818 crash if any divisor is set to 1 */
divisor1/=2;
}
}
-
+
outb(0 , dev->iobase + PCL818_CNTENABLE); /* enable pacer */
switch (devpriv->dma) {
case 1: // DMA
case 3:
if (devpriv->dma_rtc==0) { pcl818_ai_mode13dma_int(mode, dev, s); }
-#ifdef unused
- else { pcl818_ai_mode13dma_rtc(mode, dev, s); }
+#ifdef unused
+ else { pcl818_ai_mode13dma_rtc(mode, dev, s); }
#else
else { return -EINVAL; }
#endif
break;
case 0: // IRQ
// rt_printk("IRQ\n");
- if (mode==1) {
+ if (mode==1) {
devpriv->ai_mode=INT_TYPE_AI1_INT;
outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ */
} else {
devpriv->ai_mode=INT_TYPE_AI3_INT;
- outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ */
+ outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ */
};
break;
case -1: // FIFO
outb(1, dev->iobase + PCL818_FI_ENABLE); // enable FIFO
- if (mode==1) {
+ if (mode==1) {
devpriv->ai_mode=INT_TYPE_AI1_FIFO;
- outb(0x03, dev->iobase + PCL818_CONTROL); /* Pacer */
- } else {
+ outb(0x03, dev->iobase + PCL818_CONTROL); /* Pacer */
+ } else {
devpriv->ai_mode=INT_TYPE_AI3_FIFO;
- outb(0x02, dev->iobase + PCL818_CONTROL);
- }; /* Ext trig */
+ outb(0x02, dev->iobase + PCL818_CONTROL);
+ }; /* Ext trig */
break;
}
start_pacer(dev, mode, divisor1, divisor2);
-
+
#ifdef unused
switch(devpriv->ai_mode) {
case INT_TYPE_AI1_DMA_RTC:
ANALOG OUTPUT MODE 1 or 3, 818 cards
*/
#ifdef PCL818_MODE13_AO
-static int pcl818_ao_mode13(int mode, comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+static int pcl818_ao_mode13(int mode, comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
{
int divisor1, divisor2;
-
+
if (!dev->irq) {
comedi_error(dev,"IRQ not defined!");
devpriv->irq_was_now_closed=0;
devpriv->neverending_ai=0;
devpriv->act_chanlist_pos=0;
-
+
if (mode==1) {
i8253_cascade_ns_to_timer(devpriv->i8253_osc_base,&divisor1,&divisor2,&it->trigvar,TRIG_ROUND_NEAREST);
if (divisor1==1) { /* PCL818 crash if any divisor is set to 1 */
}
outb(0 , dev->iobase + PCL818_CNTENABLE); /* enable pacer */
- if (mode==1) {
+ if (mode==1) {
devpriv->int818_mode=INT_TYPE_AO1_INT;
- outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ */
- } else {
+ outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ */
+ } else {
devpriv->int818_mode=INT_TYPE_AO3_INT;
outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ */
};
return 0;
}
-/*
+/*
==============================================================================
ANALOG OUTPUT MODE 1, 818 cards
*/
-static int pcl818_ao_mode1(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+static int pcl818_ao_mode1(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
{
return pcl818_ao_mode13(1, dev, s, it);
}
-/*
+/*
==============================================================================
ANALOG OUTPUT MODE 3, 818 cards
*/
-static int pcl818_ao_mode3(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+static int pcl818_ao_mode3(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
{
return pcl818_ao_mode13(3, dev, s, it);
}
==============================================================================
Start/stop pacer onboard pacer
*/
-static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2)
+static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2)
{
outb(0xb4, dev->iobase + PCL818_CTRCTL);
outb(0x74, dev->iobase + PCL818_CTRCTL);
comedi_udelay(1);
-
+
if (mode==1) {
outb(divisor2 & 0xff, dev->iobase + PCL818_CTR2);
outb((divisor2 >> 8) & 0xff, dev->iobase + PCL818_CTR2);
static int check_channel_list(comedi_device * dev, comedi_subdevice * s, unsigned int *chanlist,
unsigned int n_chan)
{
- unsigned int chansegment[16];
+ unsigned int chansegment[16];
unsigned int i, nowmustbechan, seglen, segpos;
-
+
/* correct channel and range number check itself comedi/range.c */
if (n_chan<1) {
comedi_error(dev,"range/channel list is empty!");
- return 0;
+ return 0;
}
if (n_chan > 1) {
rt_printk("comedi%d: pcl818: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
dev->minor,i,CR_CHAN(chanlist[i]),
nowmustbechan,CR_CHAN(chanlist[0]) );
- return 0;
+ return 0;
}
// well, this is next correct channel in list
chansegment[i]=chanlist[i];
unsigned int n_chan, unsigned int seglen)
{
int i;
-
+
devpriv->act_chanlist_len=seglen;
devpriv->act_chanlist_pos=0;
dev->iobase+PCL818_MUX);
}
-/*
+/*
==============================================================================
Check if board is switched to SE (1) or DIFF(0) mode
*/
else { return 0; }
}
-/*
+/*
==============================================================================
*/
static int ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd) {
return 0;
}
-/*
+/*
==============================================================================
*/
static int ai_cmd(comedi_device *dev,comedi_subdevice *s) {
return pcl818_ai_cmd_mode(3,dev,s);
}
}
-
+
return -1;
}
-/*
+/*
==============================================================================
cancel any mode 1-4 AI
*/
-static int pcl818_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int pcl818_ai_cancel(comedi_device * dev, comedi_subdevice * s)
{
if (devpriv->irq_blocked>0) {
rt_printk("pcl818_ai_cancel()\n");
devpriv->irq_was_now_closed=devpriv->ai_mode;
devpriv->ai_mode=0;
-
+
switch (devpriv->irq_was_now_closed) {
#ifdef unused
case INT_TYPE_AI1_DMA_RTC:
return 0;
}
-/*
+/*
==============================================================================
chech for PCL818
*/
-static int pcl818_check(unsigned long iobase)
+static int pcl818_check(unsigned long iobase)
{
outb(0x00, iobase + PCL818_MUX);
- comedi_udelay(1);
+ comedi_udelay(1);
if (inb(iobase + PCL818_MUX)!=0x00) return 1; //there isn't card
outb(0x55, iobase + PCL818_MUX);
- comedi_udelay(1);
+ comedi_udelay(1);
if (inb(iobase + PCL818_MUX)!=0x55) return 1; //there isn't card
outb(0x00, iobase + PCL818_MUX);
- comedi_udelay(1);
- outb(0x18, iobase + PCL818_CONTROL);
- comedi_udelay(1);
+ comedi_udelay(1);
+ outb(0x18, iobase + PCL818_CONTROL);
+ comedi_udelay(1);
if (inb(iobase + PCL818_CONTROL)!=0x18) return 1; //there isn't card
return 0; // ok, card exist
}
-/*
+/*
==============================================================================
reset whole PCL-818 cards
*/
-static void pcl818_reset(comedi_device * dev)
+static void pcl818_reset(comedi_device * dev)
{
if (devpriv->usefifo) { // FIFO shutdown
outb(0, dev->iobase + PCL818_FI_INTCLR);
}
#ifdef unused
-/*
+/*
==============================================================================
Enable(1)/disable(0) periodic interrupts from RTC
*/
{
unsigned char val;
unsigned long flags;
-
+
if (bit==1) {
RTC_timer_lock++;
if (RTC_timer_lock>1) return 0;
if (RTC_timer_lock<0) RTC_timer_lock=0;
if (RTC_timer_lock>0) return 0;
}
-
+
save_flags(flags);
cli();
val = CMOS_READ(RTC_CONTROL);
==============================================================================
Restart RTC if something stop it (xntpd every 11 mins or large IDE transfers)
*/
-static void rtc_dropped_irq(unsigned long data)
+static void rtc_dropped_irq(unsigned long data)
{
comedi_device *dev = (void *)data;
unsigned long flags,tmp;
tmp=(CMOS_READ(RTC_INTR_FLAGS) & 0xF0); /* restart */
restore_flags(flags);
break;
- };
+ };
}
==============================================================================
Set frequency of interrupts from RTC
*/
-static int rtc_setfreq_irq(int freq)
+static int rtc_setfreq_irq(int freq)
{
int tmp = 0;
int rtc_freq;
}
#endif
-/*
+/*
==============================================================================
- Free any resources that we have claimed
+ Free any resources that we have claimed
*/
static void free_resources(comedi_device * dev)
{
//rt_printk("free_resource() end\n");
}
-/*
+/*
==============================================================================
- Initialization
+ Initialization
*/
static int pcl818_attach(comedi_device * dev, comedi_devconfig * it)
if (((1<<irq)&this_board->IRQbits)==0) {
rt_printk(", IRQ %u is out of allowed range, DISABLING IT",irq);
irq=0; /* Bad IRQ */
- } else {
+ } else {
if (comedi_request_irq(irq, interrupt_pcl818, 0, "pcl818", dev)) {
rt_printk(", unable to allocate IRQ %u, DISABLING IT", irq);
irq=0; /* Can't use IRQ */
} else {
rt_printk(", irq=%u", irq);
- }
- }
+ }
+ }
}
}
dev->irq = irq;
if (irq) { devpriv->irq_free=1; } /* 1=we have allocated irq */
- else { devpriv->irq_free=0; }
+ else { devpriv->irq_free=0; }
devpriv->irq_blocked=0; /* number of subdevice which use IRQ */
devpriv->ai_mode=0; /* mode of irq */
if (RTC_lock==0) {
if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "pcl818 (RTC)"))
goto no_rtc;
- }
+ }
devpriv->rtc_iobase=RTC_PORT(0);
devpriv->rtc_iosize=RTC_IO_EXTENT;
RTC_lock++;
devpriv->rtc_iobase=0;
devpriv->rtc_iosize=0;
}
- }
+ }
no_rtc:
#endif
if (((1<<dma)&this_board->DMAbits)==0) {
rt_printk(", DMA is out of allowed range, FAIL!\n");
return -EINVAL; /* Bad DMA */
- }
+ }
ret=request_dma(dma, "pcl818");
if (ret) {
rt_printk(", unable to allocate DMA %u, FAIL!\n",dma);
return -EBUSY; /* DMA isn't free */
- }
+ }
devpriv->dma=dma;
rt_printk(", dma=%u", dma);
pages=2; /* we need 16KB */
if (irq) {
s->trig[1] = pcl818_ao_mode1;
s->trig[3] = pcl818_ao_mode3;
- }
+ }
#endif
#endif
if(this_board->is_818){
- if ((it->options[4]==1)||(it->options[4]==10))
- s->range_table=&range_unipolar10;
- if (it->options[4]==2)
- s->range_table=&range_unknown;
+ if ((it->options[4]==1)||(it->options[4]==10))
+ s->range_table=&range_unipolar10;
+ if (it->options[4]==2)
+ s->range_table=&range_unknown;
}else{
- if ((it->options[5]==1)||(it->options[5]==10))
- s->range_table=&range_unipolar10;
- if (it->options[5]==2)
- s->range_table=&range_unknown;
- }
+ if ((it->options[5]==1)||(it->options[5]==10))
+ s->range_table=&range_unipolar10;
+ if (it->options[5]==2)
+ s->range_table=&range_unknown;
+ }
}
s = dev->subdevices + 2;
}
/* select 1/10MHz oscilator */
- if ((it->options[3]==0)||(it->options[3]==10)) {
- devpriv->i8253_osc_base= 100;
- } else {
- devpriv->i8253_osc_base=1000;
- }
+ if ((it->options[3]==0)||(it->options[3]==10)) {
+ devpriv->i8253_osc_base= 100;
+ } else {
+ devpriv->i8253_osc_base=1000;
+ }
/* max sampling speed */
devpriv->ns_min=this_board->ns_min;
-
+
if(!this_board->is_818){
- if ((it->options[6]==1)||(it->options[6]==100))
+ if ((it->options[6]==1)||(it->options[6]==100))
devpriv->ns_min=10000; /* extended PCL718 to 100kHz DAC */
}
- pcl818_reset(dev);
+ pcl818_reset(dev);
rt_printk("\n");
==============================================================================
Removes device
*/
-static int pcl818_detach(comedi_device * dev)
+static int pcl818_detach(comedi_device * dev)
{
// rt_printk("comedi%d: pcl818: remove\n", dev->minor);
free_resources(dev);
hardware driver for Advantech card:
card: PCM-3724
driver: pcm3724
-
+
Options for PCM-3724
[0] - IO Base
*/
#define GATE_C1 0x8
/* from 8255.c */
-#define CR_CW 0x80
+#define CR_CW 0x80
#define _8255_CR 3
#define CR_B_IO 0x02
#define CR_B_MODE 0x04
unsigned int io_range; // len of IO space
} boardtype;
-//used to track configured dios
+//used to track configured dios
typedef struct {
int dio_1;
int dio_2;
module: THIS_MODULE,
attach: pcm3724_attach,
detach: pcm3724_detach,
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
COMEDI_INITCLEANUP(driver_pcm3724);
-// (setq c-basic-offset 8)
+// (setq c-basic-offset 8)
static int subdev_8255_cb(int dir,int port,int data,unsigned long arg)
{
return config;
}
-static void do_3724_config(comedi_device *dev,comedi_subdevice *s,
+static void do_3724_config(comedi_device *dev,comedi_subdevice *s,
int chanspec)
{
int config;
outb(config, port_8255_cfg);
}
-static void enable_chan(comedi_device *dev, comedi_subdevice *s,
+static void enable_chan(comedi_device *dev, comedi_subdevice *s,
int chanspec)
{
unsigned int mask;
priv->dio_1 |= mask;
}
else { //subdev 1
- priv->dio_2 |= mask;
+ priv->dio_2 |= mask;
}
- if (priv->dio_1 & 0xff0000){
+ if (priv->dio_1 & 0xff0000){
gatecfg |= GATE_C0;
}
- if (priv->dio_1 & 0xff00){
+ if (priv->dio_1 & 0xff00){
gatecfg |= GATE_B0;
}
if (priv->dio_1 & 0xff){
gatecfg |= GATE_A0;
}
- if (priv->dio_2 & 0xff0000){
+ if (priv->dio_2 & 0xff0000){
gatecfg |= GATE_C1;
}
- if (priv->dio_2 & 0xff00){
+ if (priv->dio_2 & 0xff00){
gatecfg |= GATE_B1;
}
- if (priv->dio_2 & 0xff){
+ if (priv->dio_2 & 0xff){
gatecfg |= GATE_A1;
}
// printk("gate control %x\n", gatecfg);
module: THIS_MODULE,
attach: pcmad_attach,
detach: pcmad_detach,
- board_name: pcmad_boards,
+ board_name: (const char**)pcmad_boards,
num_names: n_pcmad_boards,
offset: sizeof(pcmad_boards[0]),
};
data[n] ^= (1<<(this_board->n_ai_bits-1));
}
}
-
+
return n;
}
static int pcmad_detach(comedi_device *dev)
{
printk("comedi%d: pcmad: remove\n",dev->minor);
-
+
if(dev->irq){
free_irq(dev->irq,dev);
}
particular channel from 0-7.
Note that the board is not ISA-PNP capable and thus
-needs the I/O port comedi_config parameter.
+needs the I/O port comedi_config parameter.
Note that passing a nonzero value as the second config option will
enable "simultaneous xfer" mode for this board, in which AO writes
#define IOSIZE 16
#define LSB(x) ((unsigned char)((x) & 0xff))
#define MSB(x) ((unsigned char)((((unsigned short)(x))>>8) & 0xff))
-#define LSB_PORT(chan) (dev->iobase + (chan)*2)
+#define LSB_PORT(chan) (dev->iobase + (chan)*2)
#define MSB_PORT(chan) (LSB_PORT(chan)+1)
#define BITS 12
*/
typedef struct pcmda12_board_struct
{
- char * const name;
+ char * const name;
} pcmda12_board;
/* note these have no effect and are merely here for reference..
these are configured by jumpering the board! */
-static comedi_lrange pcmda12_ranges =
-{
- 3,
- {
- UNI_RANGE( 5 ), UNI_RANGE( 10 ), BIP_RANGE( 5 )
- }
+static comedi_lrange pcmda12_ranges =
+{
+ 3,
+ {
+ UNI_RANGE( 5 ), UNI_RANGE( 10 ), BIP_RANGE( 5 )
+ }
};
-static pcmda12_board pcmda12_boards[] =
+static pcmda12_board pcmda12_boards[] =
{
{
name: "pcmda12",
static void zero_chans(comedi_device *dev);
-static comedi_driver driver =
+static comedi_driver driver =
{
driver_name: "pcmda12",
module: THIS_MODULE,
* the type of board in software. ISA PnP, PCI, and PCMCIA
* devices are such boards.
*/
- board_name: pcmda12_boards,
+ board_name: (const char**)pcmda12_boards,
offset: sizeof(pcmda12_board),
num_names: sizeof(pcmda12_boards) / sizeof(pcmda12_board),
};
iobase = it->options[0];
printk("comedi%d: %s: io: %lx %s ", dev->minor, driver.driver_name, iobase, it->options[1] ? "simultaneous xfer mode enabled" : "");
- if ( !request_region(iobase,
- IOSIZE,
+ if ( !request_region(iobase,
+ IOSIZE,
driver.driver_name) ) {
printk("I/O port conflict\n");
return -EIO;
printk("cannot allocate private data structure\n");
return -ENOMEM;
}
-
+
memset(devpriv, 0, sizeof(*devpriv));
-
+
devpriv->simultaneous_xfer_mode = it->options[1];
-
+
/*
* Allocate the subdevice structures. alloc_subdevice() is a
* convenient macro defined in comedidev.h.
*
- * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
+ * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
* 96-channel version of the board.
*/
if ( alloc_subdevices(dev, 1) < 0 ) {
/*
* _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
return 0;
}
-static void zero_chans(comedi_device *dev) /* sets up an
+static void zero_chans(comedi_device *dev) /* sets up an
ASIC chip to defaults */
{
int i;
/* save shadow register */
devpriv->ao_readback[chan] = data[i];
- if (!devpriv->simultaneous_xfer_mode)
+ if (!devpriv->simultaneous_xfer_mode)
inb(LSB_PORT(chan));
}
/* 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 driver supports simultaneous xfer then sometimes
this function actually accomplishes work.
first and second comedi_config option, respectively. Note that the
48-channel version uses 16 bytes of IO memory and the 96-channel
version uses 32-bytes (in case you are worried about conflicts). The
-48-channel board is split into two 24-channel comedi subdevices.
-The 96-channel board is split into 4 24-channel DIO subdevices.
+48-channel board is split into two 24-channel comedi subdevices.
+The 96-channel board is split into 4 24-channel DIO subdevices.
Note that IRQ support has been added, but it is untested.
-To use edge-detection IRQ support, pass the IRQs of both ASICS
-(for the 96 channel version) or just 1 ASIC (for 48-channel version).
-Then, use use comedi_commands with TRIG_NOW.
+To use edge-detection IRQ support, pass the IRQs of both ASICS
+(for the 96 channel version) or just 1 ASIC (for 48-channel version).
+Then, use use comedi_commands with TRIG_NOW.
Your callback will be called each time an edge is triggered, and the data
values will be two sample_t's, which should be concatenated to form one
32-bit unsigned int. This value is the mask of channels that had
in the mask correspond to positions in your chanlist when you specified
the command and *not* channel id's!
-To set the polarity of the edge-detection interrupts pass a nonzero value for
+To set the polarity of the edge-detection interrupts pass a nonzero value for
either CR_RANGE or CR_AREF for edge-up polarity, or a zero value for both
CR_RANGE and CR_AREF if you want edge-down polarity.
--------------------------------------------------------------
REG_PORTx All R/W Read/Write/Configure IO
REG_INT_PENDING All ReadOnly Quickly see which INT_IDx has int.
- REG_PAGELOCK All WriteOnly Select a page
+ REG_PAGELOCK All WriteOnly Select a page
REG_POLx Pg. 1 only WriteOnly Select edge-detection polarity
REG_ENABx Pg. 2 only WriteOnly Enable/Disable edge-detect. int.
REG_INT_IDx Pg. 3 only R/W See which ports/bits have ints.
#define REG_PAGELOCK 0x7 /* page selector register, upper 2 bits select a page
and bits 0-5 are used to 'lock down' a particular
port above to make it readonly. */
-#define REG_POL0 0x8
+#define REG_POL0 0x8
#define REG_POL1 0x9
#define REG_POL2 0xA
-#define REG_ENAB0 0x8
+#define REG_ENAB0 0x8
#define REG_ENAB1 0x9
#define REG_ENAB2 0xA
#define REG_INT_ID0 0x8
const int num_ports;
} pcmuio_board;
-static pcmuio_board pcmuio_boards[] =
+static pcmuio_board pcmuio_boards[] =
{
{
name: "pcmuio48",
#define thisboard ((pcmuio_board *)dev->board_ptr)
/* this structure is for data unique to this subdevice. */
-typedef struct
+typedef struct
{
/* mapping of halfwords (bytes) in port/chanarray to iobase */
unsigned long iobases[PORTS_PER_SUBDEV];
-
+
/* The below is only used for intr subdevices */
struct {
int asic; /* if non-negative, this subdev has an interrupt asic */
- int first_chan; /* if nonnegative, the first channel id for
+ int first_chan; /* if nonnegative, the first channel id for
interrupts. */
int num_asic_chans; /* the number of asic channels in this subdev
that have interrutps */
several hardware drivers keep similar information in this structure,
feel free to suggest moving the variable to the comedi_device struct. */
typedef struct
-{
- struct
+{
+ struct
{
unsigned char pagelock; /* current page and lock*/
unsigned char pol [NUM_PAGED_REGS]; /* shadow of POLx registers */
unsigned long iobase;
unsigned int irq;
spinlock_t spinlock;
- } asics[MAX_ASICS];
+ } asics[MAX_ASICS];
pcmuio_subdev_private *sprivs;
} pcmuio_private;
static int pcmuio_attach(comedi_device *dev, comedi_devconfig *it);
static int pcmuio_detach(comedi_device *dev);
-static comedi_driver driver =
+static comedi_driver driver =
{
driver_name: "pcmuio",
module: THIS_MODULE,
* the type of board in software. ISA PnP, PCI, and PCMCIA
* devices are such boards.
*/
- board_name: pcmuio_boards,
+ board_name: (const char**)pcmuio_boards,
offset: sizeof(pcmuio_board),
num_names: sizeof(pcmuio_boards) / sizeof(pcmuio_board),
};
irq[1] = it->options[2];
printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name, iobase);
-
+
dev->iobase = iobase;
-
- if ( !iobase || !request_region(iobase,
- thisboard->num_asics*ASIC_IOSIZE,
+
+ if ( !iobase || !request_region(iobase,
+ thisboard->num_asics*ASIC_IOSIZE,
driver.driver_name) ) {
printk("I/O port conflict\n");
return -EIO;
}
-
+
/*
* Initialize dev->board_name. Note that we can use the "thisboard"
* macro now, since we just initialized it in the last line.
for (asic = 0; asic < MAX_ASICS; ++asic) {
devpriv->asics[asic].num = asic;
devpriv->asics[asic].iobase = dev->iobase + asic*ASIC_IOSIZE;
- devpriv->asics[asic].irq = 0; /* this gets actually set at the end of
- this function when we
+ devpriv->asics[asic].irq = 0; /* this gets actually set at the end of
+ this function when we
comedi_request_irqs */
spin_lock_init(&devpriv->asics[asic].spinlock);
}
-
- chans_left = CHANS_PER_ASIC * thisboard->num_asics;
+
+ chans_left = CHANS_PER_ASIC * thisboard->num_asics;
n_subdevs = CALC_N_SUBDEVS(chans_left);
devpriv->sprivs = (pcmuio_subdev_private *)kmalloc(sizeof(pcmuio_subdev_private) * n_subdevs, GFP_KERNEL);
if (!devpriv->sprivs) {
* Allocate the subdevice structures. alloc_subdevice() is a
* convenient macro defined in comedidev.h.
*
- * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
+ * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
* 96-channel version of the board.
*/
if ( alloc_subdevices(dev, n_subdevs ) < 0 ) {
memset(dev->subdevices, 0, sizeof(*dev->subdevices) * n_subdevs);
port = 0;
- asic = 0;
+ asic = 0;
for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no)
- {
+ {
int byte_no;
s = dev->subdevices + sdev_no;
s->private = devpriv->sprivs + sdev_no;
s->maxdata = 1;
- s->range_table = &range_digital;
+ s->range_table = &range_digital;
s->subdev_flags = SDF_READABLE|SDF_WRITABLE;
s->type = COMEDI_SUBD_DIO;
s->insn_bits = pcmuio_dio_insn_bits;
subpriv->intr.asic_chan = -1;
subpriv->intr.num_asic_chans = -1;
subpriv->intr.active = 0;
- s->len_chanlist = 1;
+ s->len_chanlist = 1;
- /* save the ioport address for each 'port' of 8 channels in the
- subdevice */
+ /* save the ioport address for each 'port' of 8 channels in the
+ subdevice */
for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) {
if (port >= PORTS_PER_ASIC) {
port = 0;
s->cancel = pcmuio_cancel;
s->do_cmd = pcmuio_cmd;
s->do_cmdtest = pcmuio_cmdtest;
- s->len_chanlist = subpriv->intr.num_asic_chans;
+ s->len_chanlist = subpriv->intr.num_asic_chans;
}
thisasic_chanct += CHANS_PER_PORT;
}
asic = 0; /* reset the asic to our first asic, to do intr subdevs */
port = 0;
}
-
+
}
init_asics(dev); /* clear out all the registers, basically */
int i;
/* unroll the allocated irqs.. */
for (i = asic-1; i >= 0; --i) {
- comedi_free_irq(irq[i], dev);
+ comedi_free_irq(irq[i], dev);
devpriv->asics[i].irq = irq[i] = 0;
}
irq[asic] = 0;
}
devpriv->asics[asic].irq = irq[asic];
}
-
- dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple
+
+ dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple
irqs.. */
if (irq[0]) {
printk("irq: %u ", irq[0]);
- if (irq[1] && thisboard->num_asics == 2)
+ if (irq[1] && thisboard->num_asics == 2)
printk("second ASIC irq: %u ", irq[1]);
} else {
printk("(IRQ mode disabled) ");
}
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
release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics);
for (i = 0; i < MAX_ASICS; ++i) {
- if (devpriv->asics[i].irq)
+ if (devpriv->asics[i].irq)
comedi_free_irq(devpriv->asics[i].irq, dev);
}
-
+
if (devpriv && devpriv->sprivs)
kfree(devpriv->sprivs);
if (insn->n != 2) return -EINVAL;
/* NOTE:
- reading a 0 means this channel was high
+ reading a 0 means this channel was high
writine a 0 sets the channel high
- reading a 1 means this channel was low
+ reading a 1 means this channel was low
writing a 1 means set this channel low
Therefore everything is always inverted. */
for (byte_no = 0; byte_no < s->n_chan/CHANS_PER_PORT; ++byte_no) {
/* address of 8-bit port */
- unsigned long ioaddr = subpriv->iobases[byte_no],
+ unsigned long ioaddr = subpriv->iobases[byte_no],
/* bit offset of port in 32-bit doubleword */
- offset = byte_no * 8;
+ offset = byte_no * 8;
/* this 8-bit port's data */
- unsigned char byte = 0,
+ unsigned char byte = 0,
/* The write mask for this port (if any) */
- write_mask_byte = (data[0] >> offset) & 0xff,
+ write_mask_byte = (data[0] >> offset) & 0xff,
/* The data byte for this port */
data_byte = (data[1] >> offset) & 0xff;
printk("byte %d wmb %02x db %02x offset %02d io %04x, data_in %02x ", byte_no, (unsigned)write_mask_byte, (unsigned)data_byte, offset, ioaddr, (unsigned)byte);
#endif
- if ( write_mask_byte ) {
+ if ( write_mask_byte ) {
/* this byte has some write_bits -- so set the output lines */
byte &= ~write_mask_byte; /* clear bits for write mask */
byte |= ~data_byte & write_mask_byte; /* set to inverted data_byte */
printk("data_out_byte %02x\n", (unsigned)byte);
#endif
/* save the digital input lines for this byte.. */
- s->state |= ((unsigned int)byte) << offset;
+ s->state |= ((unsigned int)byte) << offset;
}
/* now return the DIO lines to data[1] - note they came inverted! */
- data[1] = ~s->state;
+ data[1] = ~s->state;
#ifdef DAMMIT_ITS_BROKEN
/* DEBUG */
printk("s->state %08x data_out %08x\n", s->state, data[1]);
#endif
-
+
return 2;
}
/* Compute ioaddr for this channel */
ioaddr = subpriv->iobases[byte_no];
-
+
/* NOTE:
- writing a 0 an IO channel's bit sets the channel to INPUT
+ writing a 0 an IO channel's bit sets the channel to INPUT
and pulls the line high as well
-
+
writing a 1 to an IO channel's bit pulls the line low
- All channels are implicitly always in OUTPUT mode -- but when
+ All channels are implicitly always in OUTPUT mode -- but when
they are high they can be considered to be in INPUT mode..
- Thus, we only force channels low if the config request was INPUT,
+ Thus, we only force channels low if the config request was INPUT,
otherwise we do nothing to the hardware. */
switch(data[0])
{
case INSN_CONFIG_DIO_OUTPUT:
- /* save to io_bits -- don't actually do anything since
+ /* save to io_bits -- don't actually do anything since
all input channels are also output channels... */
s->io_bits |= 1<<chan;
break;
byte = inb(ioaddr);
byte &= ~(1<<bit_no); /**< set input channel to '0' */
- /* write out byte -- this is the only time we actually affect the
- hardware as all channels are implicitly output -- but input
+ /* write out byte -- this is the only time we actually affect the
+ hardware as all channels are implicitly output -- but input
channels are set to float-high */
outb(byte, ioaddr);
-
+
/* save to io_bits */
s->io_bits &= ~(1<<chan);
break;
default:
return -EINVAL;
break;
- }
+ }
- return insn->n;
+ return insn->n;
}
-static void init_asics(comedi_device *dev) /* sets up an
+static void init_asics(comedi_device *dev) /* sets up an
ASIC chip to defaults */
{
int asic;
-
+
for (asic = 0; asic < thisboard->num_asics; ++asic)
{
int port, page;
switch_page(dev, asic, 0); /* switch back to page 0 */
/* first, clear all the DIO port bits */
- for (port = 0; port < PORTS_PER_ASIC; ++port)
+ for (port = 0; port < PORTS_PER_ASIC; ++port)
outb(0, baseaddr + REG_PORT0 + port);
/* Next, clear all the paged registers for each page */
/* END DEBUG */
switch_page(dev, asic, 0); /* switch back to default page 0 */
-
+
}
}
devpriv->asics[asic].pagelock |= page<<REG_PAGE_BITOFFSET;
/* now write out the shadow register */
- outb(devpriv->asics[asic].pagelock,
+ outb(devpriv->asics[asic].pagelock,
dev->iobase + ASIC_IOSIZE*asic + REG_PAGELOCK);
}
if (asic < 0 || asic >= thisboard->num_asics) return; /* paranoia */
if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */
- devpriv->asics[asic].pagelock |= 0x1<<port;
+ devpriv->asics[asic].pagelock |= 0x1<<port;
/* now write out the shadow register */
outb(devpriv->asics[asic].pagelock, dev->iobase + ASIC_IOSIZE*asic + REG_PAGELOCK);
return;
{
if (asic < 0 || asic >= thisboard->num_asics) return; /* paranoia */
if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */
- devpriv->asics[asic].pagelock &= ~(0x1<<port) | REG_LOCK_MASK;
+ devpriv->asics[asic].pagelock &= ~(0x1<<port) | REG_LOCK_MASK;
/* now write out the shadow register */
outb(devpriv->asics[asic].pagelock, dev->iobase + ASIC_IOSIZE*asic + REG_PAGELOCK);
(void)unlock_port(dev, asic, port); /* not reached, suppress compiler warnings*/
{
int asic, got1 = 0;
comedi_device *dev = (comedi_device *)d;
-
+
for (asic = 0; asic < MAX_ASICS; ++asic) {
if (irq == devpriv->asics[asic].irq) {
- unsigned long flags;
+ unsigned long flags;
unsigned triggered = 0;
unsigned long iobase = devpriv->asics[asic].iobase;
/* it is an interrupt for ASIC #asic */
unsigned char io_lines_with_edges = 0;
switch_page(dev, asic, PAGE_INT_ID);
io_lines_with_edges = inb(iobase + REG_INT_ID0 + port);
-
- if (io_lines_with_edges)
+
+ if (io_lines_with_edges)
/* clear pending interrupt */
outb(0, iobase + REG_INT_ID0 + port);
comedi_spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags);
- if (triggered) {
+ if (triggered) {
comedi_subdevice *s;
/* TODO here: dispatch io lines to subdevs with commands.. */
printk("PCMUIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered);
if (subpriv->intr.asic == asic) { /* this is an interrupt subdev, and it matches this asic! */
unsigned long flags;
unsigned oldevents;
-
+
comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
-
+
oldevents = s->async->events;
if (subpriv->intr.active) {
if (mytrig & subpriv->intr.enabled_mask) {
lsampl_t val = 0;
unsigned int n, ch, len;
-
+
len = s->async->cmd.chanlist_len;
for (n = 0; n < len; n++) {
ch = CR_CHAN(s->async->cmd.chanlist[n]);
} else {
/* Overflow! Stop acquisition!! */
/* TODO: STOP_ACQUISITION_CALL_HERE!! */
- pcmuio_stop_intr(dev, s);
+ pcmuio_stop_intr(dev, s);
}
-
+
/* Check for end of acquisition. */
if (!subpriv->intr.continuous) {
/* stop_src == TRIG_COUNT */
if (subpriv->intr.stop_count == 0) {
s->async->events |= COMEDI_CB_EOA;
/* TODO: STOP_ACQUISITION_CALL_HERE!! */
- pcmuio_stop_intr(dev, s);
+ pcmuio_stop_intr(dev, s);
}
}
}
}
comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
-
+
if (oldevents != s->async->events) {
comedi_event(dev, s, s->async->events);
}
}
-
+
}
}
static void pcmuio_stop_intr(comedi_device *dev, comedi_subdevice *s)
{
int nports, firstport, asic, port;
-
+
if ( (asic = subpriv->intr.asic) < 0 ) return; /* not an interrupt subdev */
-
+
subpriv->intr.enabled_mask = 0;
subpriv->intr.active = 0;
s->async->inttrig = 0;
} else {
unsigned bits = 0, pol_bits = 0, n;
int nports, firstport, asic, port;
- comedi_cmd *cmd = &s->async->cmd;
-
- if ( (asic = subpriv->intr.asic) < 0 ) return 1; /* not an interrupt
+ comedi_cmd *cmd = &s->async->cmd;
+
+ if ( (asic = subpriv->intr.asic) < 0 ) return 1; /* not an interrupt
subdev */
subpriv->intr.enabled_mask = 0;
subpriv->intr.active = 1;
if (cmd->chanlist) {
for (n = 0; n < cmd->chanlist_len; n++) {
bits |= (1U << CR_CHAN(cmd->chanlist[n]));
- pol_bits |=
+ pol_bits |=
(CR_AREF(cmd->chanlist[n]) || CR_RANGE(cmd->chanlist[n]) ? 1U : 0U)
<< CR_CHAN(cmd->chanlist[n]);
}
switch_page(dev, asic, PAGE_ENAB);
for (port = firstport; port < firstport+nports; ++port) {
- unsigned enab = bits >> (subpriv->intr.first_chan + (port-firstport)*8) & 0xff,
+ unsigned enab = bits >> (subpriv->intr.first_chan + (port-firstport)*8) & 0xff,
pol = pol_bits >> (subpriv->intr.first_chan + (port-firstport)*8) & 0xff ;
/* set enab intrs for this subdev.. */
outb(enab, devpriv->asics[asic].iobase + REG_ENAB0 + port);
if (subpriv->intr.active) pcmuio_stop_intr(dev, s);
comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
- return 0;
+ return 0;
}
/*
if (!cmd->convert_src || tmp != cmd->convert_src) err++;
tmp = cmd->scan_end_src;
- cmd->scan_end_src &= TRIG_COUNT;
+ cmd->scan_end_src &= TRIG_COUNT;
if (!cmd->scan_end_src || tmp != cmd->scan_end_src) err++;
tmp = cmd->stop_src;
module: THIS_MODULE,
attach: poc_attach,
detach: poc_detach,
- board_name: boards,
+ board_name: (const char**)boards,
num_names: n_boards,
offset: sizeof(boards[0]),
};
comedi_insn *insn,lsampl_t *data)
{
if(insn->n!=2)return -EINVAL;
-
+
data[1] = inb(dev->iobase + 0);
data[1] |= (inb(dev->iobase + 1) << 8);
data[1] |= (inb(dev->iobase + 2) << 16);
/*
comedi/drivers/rtd520.c
Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
-
+
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 2001 David A. Schleef <ds@schleef.org>
/*
driver status:
- Analog-In supports instruction and command mode.
+ Analog-In supports instruction and command mode.
With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
(single channel, 64K read buffer). I get random system lockups when
Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
(with a 256K read buffer).
-
+
Digital-IO and Analog-Out only support instruction mode.
*/
#define DMA_TRANSFER_BITS (\
/* descriptors in PCI memory*/ PLX_DESC_IN_PCI_BIT \
/* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
-/* from board to PCI */ | PLX_XFER_LOCAL_TO_PCI)
+/* from board to PCI */ | PLX_XFER_LOCAL_TO_PCI)
/*======================================================================
Comedi specific stuff
module: THIS_MODULE,
attach: rtd_attach,
detach: rtd_detach,
- board_name: rtd520Boards,
+ board_name: (const char**)rtd520Boards,
offset: sizeof(rtdBoard),
num_names: sizeof(rtd520Boards) / sizeof(rtdBoard),
};
* Initialize base addresses
*/
/* Get the physical address from PCI config */
- physLas0 = pci_resource_start(devpriv->pci_dev, LAS0_PCIINDEX);
- physLas1 = pci_resource_start(devpriv->pci_dev, LAS1_PCIINDEX);
- physLcfg = pci_resource_start(devpriv->pci_dev, LCFG_PCIINDEX);
+ physLas0 = pci_resource_start(devpriv->pci_dev, LAS0_PCIINDEX);
+ physLas1 = pci_resource_start(devpriv->pci_dev, LAS1_PCIINDEX);
+ physLcfg = pci_resource_start(devpriv->pci_dev, LCFG_PCIINDEX);
/* Now have the kernel map this into memory */
/* ASSUME page aligned */
devpriv->las0 = ioremap_nocache(physLas0, LAS0_PCISIZE);
#else /* USE_DMA */
printk("\n"); /* end configuration line */
#endif /* USE_DMA */
-
+
/* initialize board, per RTD spec */
/* also, initialize shadow registers */
RtdResetBoard (dev);
/*
* _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
{
pci_release_regions(devpriv->pci_dev);
pci_disable_device(devpriv->pci_dev);
- }
+ }
pci_dev_put(devpriv->pci_dev);
}
}
printk("comedi%d: rtd520: removed.\n",dev->minor);
-
+
return 0;
}
/* clear any old fifo data */
RtdAdcClearFifo (dev);
- /* write channel to multiplexer and clear channel gain table */
+ /* write channel to multiplexer and clear channel gain table */
rtd_load_channelgain_list (dev, 1, &insn->chanspec);
-
+
/* set conversion source */
RtdAdcConversionSource (dev, 0); /* software */
cmdtest tests a particular command to see if it is valid.
Using the cmdtest ioctl, a user can create a valid cmd
and then have it executed by the cmd ioctl (asyncronously).
-
+
cmdtest returns 1,2,3,4 or 0, depending on which tests
the command passes.
*/
else { /* 1/2 FIFO transfers */
#ifdef USE_DMA
devpriv->flags |= DMA0_ACTIVE;
-
+
/* point to first transfer in ring */
devpriv->dma0Offset = 0;
RtdDma0Mode (dev, DMA_MODE_BITS);
/* Must be 2 steps. See PLX app note about "Starting a DMA transfer"*/
RtdDma0Control (dev, PLX_DMA_EN_BIT); /* enable DMA (clear INTR?) */
RtdDma0Control (dev, PLX_DMA_EN_BIT | PLX_DMA_START_BIT); /*start DMA*/
- DPRINTK ("rtd520: Using DMA0 transfers. plxInt %x RtdInt %x\n",
+ DPRINTK ("rtd520: Using DMA0 transfers. plxInt %x RtdInt %x\n",
RtdPlxInterruptRead (dev), devpriv->intMask);
#else /* USE_DMA */
RtdInterruptMask (dev, IRQM_ADC_ABOUT_CNT );
return i;
}
-/*
+/*
Write a masked set of bits and the read back the port.
We track what the bits should be (i.e. we don't read the port first).
-
+
DIO devices are slightly special. Although it is possible to
* implement the insn_read/insn_write interface, it is much more
* useful to applications if you implement the insn_bits interface.
if (data[0]) {
s->state &= ~data[0];
s->state |= data[0]&data[1];
-
+
/* Write out the new digital output lines */
RtdDio0Write (dev, s->state);
}
/* The input or output configuration of each digital line is
* configured by a special insn_config instruction. chanspec
- * contains the channel to be changed, and data[0] contains the
+ * contains the channel to be changed, and data[0] contains the
* value COMEDI_INPUT or COMEDI_OUTPUT. */
switch(data[0])
{
attach: rti800_attach,
detach: rti800_detach,
num_names: sizeof(boardtypes)/sizeof(boardtype),
- board_name: boardtypes,
+ board_name: (const char**)boardtypes,
offset: sizeof(boardtype),
};
COMEDI_INITCLEANUP(driver_rti800);
return ret;
if((ret=alloc_private(dev,sizeof(rti800_private)))<0)
return ret;
-
+
devpriv->adc_mux = it->options[2];
devpriv->adc_range = it->options[3];
devpriv->adc_coding = it->options[4];
* the type of board in software. ISA PnP, PCI, and PCMCIA
* devices are such boards.
*/
- board_name: s526_boards,
+ board_name: (const char**)s526_boards,
offset: sizeof(s526_board),
num_names: sizeof(s526_boards) / sizeof(s526_board),
};
* the type of board in software. ISA PnP, PCI, and PCMCIA
* devices are such boards.
*/
- board_name: skel_boards,
+ board_name: (const char**)skel_boards,
offset: sizeof(skel_board),
num_names: sizeof(skel_boards) / sizeof(skel_board),
};
comedi_subdevice *s;
printk("comedi%d: skel: ",dev->minor);
-
+
/*
* 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
}else{
s->type = COMEDI_SUBD_UNUSED;
}
-
+
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
static int skel_detach(comedi_device *dev)
{
printk("comedi%d: skel: remove\n",dev->minor);
-
+
return 0;
}
/*
comedi/drivers/ssv_dnp.c
generic comedi driver for SSV Embedded Systems' DIL/Net-PCs
- Copyright (C) 2001 Robert Schwebel <robert@schwebel.de>
+ Copyright (C) 2001 Robert Schwebel <robert@schwebel.de>
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 2000 David A. Schleef <ds@schleef.org>
module: THIS_MODULE,
attach: dnp_attach,
detach: dnp_detach,
- board_name: dnp_boards, /* only necessary for non-PnP devs */
+ board_name: (const char**)dnp_boards, /* only necessary for non-PnP devs */
offset: sizeof(dnp_board), /* like ISA-PnP, PCI or PCMCIA. */
num_names: sizeof(dnp_boards) / sizeof(dnp_board),
};
comedi_subdevice *s;
printk("comedi%d: dnp: ",dev->minor);
-
+
/* Autoprobing: this should find out which board we have. Currently only */
/* the 1486 board is supported and autoprobing is not implemented :-) */
- //dev->board_ptr = dnp_probe(dev);
+ //dev->board_ptr = dnp_probe(dev);
/* Initialize the name of the board. We can use the "thisboard" macro now. */
dev->board_name = thisboard->name;
s->range_table =& range_digital;
s->insn_bits = dnp_dio_insn_bits;
s->insn_config = dnp_dio_insn_config;
-
+
printk("attached\n");
/* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always
/* configure all ports as input (default) */
outb(PAMR,CSCIR); outb(0x00,CSCDR);
outb(PBMR,CSCIR); outb(0x00,CSCDR);
- outb(PCMR,CSCIR); outb((inb(CSCDR) & 0xAA),CSCDR);
+ outb(PCMR,CSCIR); outb((inb(CSCDR) & 0xAA),CSCDR);
/* announce that we are finished */
printk("comedi%d: dnp: remove\n",dev->minor);
-
+
return 0;
}
outb(PADR,CSCIR);
outb(
- (inb(CSCDR)
+ (inb(CSCDR)
& ~(u8)(data[0] & 0x0000FF))
| (u8)(data[1] & 0x0000FF),
CSCDR
outb(PBDR,CSCIR);
outb(
- (inb(CSCDR)
+ (inb(CSCDR)
& ~(u8)((data[0] & 0x00FF00) >> 8))
| (u8)((data[1] & 0x00FF00) >> 8),
CSCDR
outb(PCDR,CSCIR);
outb(
(inb(CSCDR)
- & ~(u8)((data[0] & 0x0F0000) >> 12))
+ & ~(u8)((data[0] & 0x0F0000) >> 12))
| (u8)((data[1] & 0x0F0000) >> 12),
CSCDR
);
data[0] += inb(CSCDR) << 8;
outb(PCDR,CSCIR);
data[0] += ((inb(CSCDR) & 0xF0) << 12);
-
+
return 2;
}
comedi_subdevice *s,
comedi_insn *insn,
lsampl_t *data
-)
+)
{
u8 register_buffer;
break;
}
/* Test: which port does the channel belong to? */
-
+
/* We have to pay attention with port C: this is the meaning of PCMR: */
/* Bit in PCMR: 7 6 5 4 3 2 1 0 */
/* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch */
-
- if ((chan >= 0) && (chan <= 7)) {
+
+ if ((chan >= 0) && (chan <= 7)) {
/* this is port A */
outb(PAMR,CSCIR);
}
- else if ((chan >= 8) && (chan <= 15)) {
+ else if ((chan >= 8) && (chan <= 15)) {
/* this is port B */
- chan -= 8;
+ chan -= 8;
outb(PBMR,CSCIR);
}
- else if ((chan >= 16) && (chan <= 19)) {
+ else if ((chan >= 16) && (chan <= 19)) {
/* this is port C; multiplication with 2 brings bits into correct */
/* position for PCMR! */
chan -= 16;
else { return -EINVAL; }
/* read 'old' direction of the port and set bits (out=1, in=0) */
- register_buffer = inb(CSCDR);
+ register_buffer = inb(CSCDR);
if (data[0] == COMEDI_OUTPUT) { register_buffer |= (1<<chan); }
else { register_buffer &= ~(1<<chan); }
- outb(register_buffer,CSCDR);
+ outb(register_buffer,CSCDR);
return 1;
int comedi_get_n_subdevices(comedi_t *d)
{
comedi_device *dev = (comedi_device *)d;
-
+
return dev->n_subdevices;
}
return COMEDI_VERSION_CODE;
}
-char *comedi_get_driver_name(comedi_t *d)
+const char *comedi_get_driver_name(comedi_t *d)
{
comedi_device *dev = (comedi_device *)d;
return dev->driver->driver_name;
}
-char *comedi_get_board_name(comedi_t *d)
+const char *comedi_get_board_name(comedi_t *d)
{
comedi_device *dev = (comedi_device *)d;
comedi_subdevice *s = dev->subdevices + subdevice;
comedi_async *async;
int bytes_written;
-
+
if( subdevice >= dev->n_subdevices ) return -1;
async = s->async;
if( async == NULL ) return -1;
struct comedi_driver_struct{
struct comedi_driver_struct *next;
- char *driver_name;
+ const char *driver_name;
struct module *module;
int (*attach)(comedi_device *,comedi_devconfig *);
int (*detach)(comedi_device *);
/* number of elements in board_name and board_id arrays */
unsigned int num_names;
- void *board_name;
+ const char **board_name;
/* offset in bytes from one board name pointer to the next */
int offset;
};
comedi_driver *driver;
void *private;
unsigned int minor;
- char *board_name;
+ const char *board_name;
const void * board_ptr;
int attached;
int rt;
unsigned int *bits);
int comedi_get_n_subdevices(comedi_t *dev);
int comedi_get_version_code(comedi_t *dev);
-char *comedi_get_driver_name(comedi_t *dev);
-char *comedi_get_board_name(comedi_t *dev);
+const char *comedi_get_driver_name(comedi_t *dev);
+const char *comedi_get_board_name(comedi_t *dev);
int comedi_get_subdevice_type(comedi_t *dev,unsigned int subdevice);
int comedi_find_subdevice_by_type(comedi_t *dev,int type,unsigned int subd);
int comedi_get_n_channels(comedi_t *dev,unsigned int subdevice);