linux/drivers/comedi/drivers/amplc_pci224.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * comedi/drivers/amplc_pci224.c
 * Driver for Amplicon PCI224 and PCI234 AO boards.
 *
 * Copyright (C) 2005 MEV Ltd. <https://www.mev.co.uk/>
 *
 * COMEDI - Linux Control and Measurement Device Interface
 * Copyright (C) 1998,2000 David A. Schleef <[email protected]>
 */

/*
 * Driver: amplc_pci224
 * Description: Amplicon PCI224, PCI234
 * Author: Ian Abbott <[email protected]>
 * Devices: [Amplicon] PCI224 (amplc_pci224), PCI234
 * Updated: Thu, 31 Jul 2014 11:08:03 +0000
 * Status: works, but see caveats
 *
 * Supports:
 *
 *   - ao_insn read/write
 *   - ao_do_cmd mode with the following sources:
 *
 *     - start_src         TRIG_INT        TRIG_EXT
 *     - scan_begin_src    TRIG_TIMER      TRIG_EXT
 *     - convert_src       TRIG_NOW
 *     - scan_end_src      TRIG_COUNT
 *     - stop_src          TRIG_COUNT      TRIG_EXT        TRIG_NONE
 *
 *     The channel list must contain at least one channel with no repeated
 *     channels.  The scan end count must equal the number of channels in
 *     the channel list.
 *
 *     There is only one external trigger source so only one of start_src,
 *     scan_begin_src or stop_src may use TRIG_EXT.
 *
 * Configuration options:
 *   none
 *
 * Manual configuration of PCI cards is not supported; they are configured
 * automatically.
 *
 * Output range selection - PCI224:
 *
 *   Output ranges on PCI224 are partly software-selectable and partly
 *   hardware-selectable according to jumper LK1.  All channels are set
 *   to the same range:
 *
 *   - LK1 position 1-2 (factory default) corresponds to the following
 *     comedi ranges:
 *
 *       0: [-10V,+10V]; 1: [-5V,+5V]; 2: [-2.5V,+2.5V], 3: [-1.25V,+1.25V],
 *       4: [0,+10V],    5: [0,+5V],   6: [0,+2.5V],     7: [0,+1.25V]
 *
 *   - LK1 position 2-3 corresponds to the following Comedi ranges, using
 *     an external voltage reference:
 *
 *       0: [-Vext,+Vext],
 *       1: [0,+Vext]
 *
 * Output range selection - PCI234:
 *
 *   Output ranges on PCI234 are hardware-selectable according to jumper
 *   LK1 which affects all channels, and jumpers LK2, LK3, LK4 and LK5
 *   which affect channels 0, 1, 2 and 3 individually.  LK1 chooses between
 *   an internal 5V reference and an external voltage reference (Vext).
 *   LK2/3/4/5 choose (per channel) to double the reference or not according
 *   to the following table:
 *
 *     LK1 position   LK2/3/4/5 pos  Comedi range
 *     -------------  -------------  --------------
 *     2-3 (factory)  1-2 (factory)  0: [-10V,+10V]
 *     2-3 (factory)  2-3            1: [-5V,+5V]
 *     1-2            1-2 (factory)  2: [-2*Vext,+2*Vext]
 *     1-2            2-3            3: [-Vext,+Vext]
 *
 * Caveats:
 *
 *   1) All channels on the PCI224 share the same range.  Any change to the
 *      range as a result of insn_write or a streaming command will affect
 *      the output voltages of all channels, including those not specified
 *      by the instruction or command.
 *
 *   2) For the analog output command,  the first scan may be triggered
 *      falsely at the start of acquisition.  This occurs when the DAC scan
 *      trigger source is switched from 'none' to 'timer' (scan_begin_src =
 *      TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
 *      of acquisition and the trigger source is at logic level 1 at the
 *      time of the switch.  This is very likely for TRIG_TIMER.  For
 *      TRIG_EXT, it depends on the state of the external line and whether
 *      the CR_INVERT flag has been set.  The remaining scans are triggered
 *      correctly.
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/comedi/comedi_pci.h>
#include <linux/comedi/comedi_8254.h>

/*
 * PCI224/234 i/o space 1 (PCIBAR2) registers.
 */
#define PCI224_Z2_BASE
#define PCI224_ZCLK_SCE
#define PCI224_ZGAT_SCE
#define PCI224_INT_SCE
				/* /Interrupt status */

/*
 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
 */
#define PCI224_DACDATA
#define PCI224_SOFTTRIG
#define PCI224_DACCON
#define PCI224_FIFOSIZ
#define PCI224_DACCEN

/*
 * DACCON values.
 */
/* (r/w) Scan trigger. */
#define PCI224_DACCON_TRIG(x)
#define PCI224_DACCON_TRIG_MASK
#define PCI224_DACCON_TRIG_NONE
#define PCI224_DACCON_TRIG_SW
#define PCI224_DACCON_TRIG_EXTP
#define PCI224_DACCON_TRIG_EXTN
#define PCI224_DACCON_TRIG_Z2CT0
#define PCI224_DACCON_TRIG_Z2CT1
#define PCI224_DACCON_TRIG_Z2CT2
/* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
#define PCI224_DACCON_POLAR(x)
#define PCI224_DACCON_POLAR_MASK
#define PCI224_DACCON_POLAR_UNI
#define PCI224_DACCON_POLAR_BI
/* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
#define PCI224_DACCON_VREF(x)
#define PCI224_DACCON_VREF_MASK
#define PCI224_DACCON_VREF_1_25
#define PCI224_DACCON_VREF_2_5
#define PCI224_DACCON_VREF_5
#define PCI224_DACCON_VREF_10
/* (r/w) Wraparound mode enable (to play back stored waveform). */
#define PCI224_DACCON_FIFOWRAP
/* (r/w) FIFO enable.  It MUST be set! */
#define PCI224_DACCON_FIFOENAB
/* (r/w) FIFO interrupt trigger level (most values are not very useful). */
#define PCI224_DACCON_FIFOINTR(x)
#define PCI224_DACCON_FIFOINTR_MASK
#define PCI224_DACCON_FIFOINTR_EMPTY
#define PCI224_DACCON_FIFOINTR_NEMPTY
#define PCI224_DACCON_FIFOINTR_NHALF
#define PCI224_DACCON_FIFOINTR_HALF
#define PCI224_DACCON_FIFOINTR_NFULL
#define PCI224_DACCON_FIFOINTR_FULL
/* (r-o) FIFO fill level. */
#define PCI224_DACCON_FIFOFL(x)
#define PCI224_DACCON_FIFOFL_MASK
#define PCI224_DACCON_FIFOFL_EMPTY
#define PCI224_DACCON_FIFOFL_ONETOHALF
#define PCI224_DACCON_FIFOFL_HALFTOFULL
#define PCI224_DACCON_FIFOFL_FULL
/* (r-o) DAC busy flag. */
#define PCI224_DACCON_BUSY
/* (w-o) FIFO reset. */
#define PCI224_DACCON_FIFORESET
/* (w-o) Global reset (not sure what it does). */
#define PCI224_DACCON_GLOBALRESET

/*
 * DAC FIFO size.
 */
#define PCI224_FIFO_SIZE

/*
 * DAC FIFO guaranteed minimum room available, depending on reported fill level.
 * The maximum room available depends on the reported fill level and how much
 * has been written!
 */
#define PCI224_FIFO_ROOM_EMPTY
#define PCI224_FIFO_ROOM_ONETOHALF
#define PCI224_FIFO_ROOM_HALFTOFULL
#define PCI224_FIFO_ROOM_FULL

/*
 * Counter/timer clock input configuration sources.
 */
#define CLK_CLK
#define CLK_10MHZ
#define CLK_1MHZ
#define CLK_100KHZ
#define CLK_10KHZ
#define CLK_1KHZ
#define CLK_OUTNM1
#define CLK_EXT

static unsigned int pci224_clk_config(unsigned int chan, unsigned int src)
{}

/*
 * Counter/timer gate input configuration sources.
 */
#define GAT_VCC
#define GAT_GND
#define GAT_EXT
#define GAT_NOUTNM2

static unsigned int pci224_gat_config(unsigned int chan, unsigned int src)
{}

/*
 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
 *
 *              Channel's       Channel's
 *              clock input     gate input
 * Channel      CLK_OUTNM1      GAT_NOUTNM2
 * -------      ----------      -----------
 * Z2-CT0       Z2-CT2-OUT      /Z2-CT1-OUT
 * Z2-CT1       Z2-CT0-OUT      /Z2-CT2-OUT
 * Z2-CT2       Z2-CT1-OUT      /Z2-CT0-OUT
 */

/*
 * Interrupt enable/status bits
 */
#define PCI224_INTR_EXT
#define PCI224_INTR_DAC
#define PCI224_INTR_Z2CT1

#define PCI224_INTR_EDGE_BITS
#define PCI224_INTR_LEVEL_BITS

/*
 * Handy macros.
 */

/* Combine old and new bits. */
#define COMBINE(old, new, mask)

/* Current CPU.  XXX should this be hard_smp_processor_id()? */
#define THISCPU

/* State bits for use with atomic bit operations. */
#define AO_CMD_STARTED

/*
 * Range tables.
 */

/*
 * The ranges for PCI224.
 *
 * These are partly hardware-selectable by jumper LK1 and partly
 * software-selectable.
 *
 * All channels share the same hardware range.
 */
static const struct comedi_lrange range_pci224 =;

static const unsigned short hwrange_pci224[10] =;

/* Used to check all channels set to the same range on PCI224. */
static const unsigned char range_check_pci224[10] =;

/*
 * The ranges for PCI234.
 *
 * These are all hardware-selectable by jumper LK1 affecting all channels,
 * and jumpers LK2, LK3, LK4 and LK5 affecting channels 0, 1, 2 and 3
 * individually.
 */
static const struct comedi_lrange range_pci234 =;

/* N.B. PCI234 ignores the polarity bit, but software uses it. */
static const unsigned short hwrange_pci234[4] =;

/* Used to check all channels use same LK1 setting on PCI234. */
static const unsigned char range_check_pci234[4] =;

/*
 * Board descriptions.
 */

enum pci224_model {};

struct pci224_board {};

static const struct pci224_board pci224_boards[] =;

struct pci224_private {};

/*
 * Called from the 'insn_write' function to perform a single write.
 */
static void
pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
		   unsigned int data)
{}

static int pci224_ao_insn_write(struct comedi_device *dev,
				struct comedi_subdevice *s,
				struct comedi_insn *insn,
				unsigned int *data)
{}

/*
 * Kills a command running on the AO subdevice.
 */
static void pci224_ao_stop(struct comedi_device *dev,
			   struct comedi_subdevice *s)
{}

/*
 * Handles start of acquisition for the AO subdevice.
 */
static void pci224_ao_start(struct comedi_device *dev,
			    struct comedi_subdevice *s)
{}

/*
 * Handles interrupts from the DAC FIFO.
 */
static void pci224_ao_handle_fifo(struct comedi_device *dev,
				  struct comedi_subdevice *s)
{}

static int pci224_ao_inttrig_start(struct comedi_device *dev,
				   struct comedi_subdevice *s,
				   unsigned int trig_num)
{}

static int pci224_ao_check_chanlist(struct comedi_device *dev,
				    struct comedi_subdevice *s,
				    struct comedi_cmd *cmd)
{}

#define MAX_SCAN_PERIOD
#define MIN_SCAN_PERIOD
#define CONVERT_PERIOD

/*
 * 'do_cmdtest' function for AO subdevice.
 */
static int
pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
		  struct comedi_cmd *cmd)
{}

static void pci224_ao_start_pacer(struct comedi_device *dev,
				  struct comedi_subdevice *s)
{}

static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{}

/*
 * 'cancel' function for AO subdevice.
 */
static int pci224_ao_cancel(struct comedi_device *dev,
			    struct comedi_subdevice *s)
{}

/*
 * 'munge' data for AO command.
 */
static void
pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
		void *data, unsigned int num_bytes, unsigned int chan_index)
{}

/*
 * Interrupt handler.
 */
static irqreturn_t pci224_interrupt(int irq, void *d)
{}

static int
pci224_auto_attach(struct comedi_device *dev, unsigned long context_model)
{}

static void pci224_detach(struct comedi_device *dev)
{}

static struct comedi_driver amplc_pci224_driver =;

static int amplc_pci224_pci_probe(struct pci_dev *dev,
				  const struct pci_device_id *id)
{}

static const struct pci_device_id amplc_pci224_pci_table[] =;
MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);

static struct pci_driver amplc_pci224_pci_driver =;
module_comedi_pci_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();