linux/drivers/comedi/drivers/adl_pci9118.c

// SPDX-License-Identifier: GPL-2.0
/*
 *  comedi/drivers/adl_pci9118.c
 *
 *  hardware driver for ADLink cards:
 *   card:   PCI-9118DG, PCI-9118HG, PCI-9118HR
 *   driver: pci9118dg,  pci9118hg,  pci9118hr
 *
 * Author: Michal Dobes <[email protected]>
 *
 */

/*
 * Driver: adl_pci9118
 * Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
 * Author: Michal Dobes <[email protected]>
 * Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
 * PCI-9118HR (pci9118hr)
 * Status: works
 *
 * This driver supports AI, AO, DI and DO subdevices.
 * AI subdevice supports cmd and insn interface,
 * other subdevices support only insn interface.
 * For AI:
 * - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
 * - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
 * - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
 * - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
 * cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
 * - If return value of cmdtest is 5 then you've bad channel list
 * (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
 * ranges).
 *
 * There are some hardware limitations:
 * a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
 *  ended inputs.
 * b) DMA transfers must have the length aligned to two samples (32 bit),
 *  so there is some problems if cmd->chanlist_len is odd. This driver tries
 *  bypass this with adding one sample to the end of the every scan and discard
 *  it on output but this can't be used if cmd->scan_begin_src=TRIG_FOLLOW
 *  and is used flag CMDF_WAKE_EOS, then driver switch to interrupt driven mode
 *  with interrupt after every sample.
 * c) If isn't used DMA then you can use only mode where
 *  cmd->scan_begin_src=TRIG_FOLLOW.
 *
 * Configuration options:
 * [0] - PCI bus of device (optional)
 * [1] - PCI slot of device (optional)
 *	 If bus/slot is not specified, then first available PCI
 *	 card will be used.
 * [2] - 0= standard 8 DIFF/16 SE channels configuration
 *	 n = external multiplexer connected, 1 <= n <= 256
 * [3] - ignored
 * [4] - sample&hold signal - card can generate signal for external S&H board
 *	 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
 *	 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
 *		long delay is requested in ns and sign polarity of the hold
 *		(in this case external multiplexor can serve only 128 channels)
 * [5] - ignored
 */

/*
 * FIXME
 *
 * All the supported boards have the same PCI vendor and device IDs, so
 * auto-attachment of PCI devices will always find the first board type.
 *
 * Perhaps the boards have different subdevice IDs that we could use to
 * distinguish them?
 *
 * Need some device attributes so the board type can be corrected after
 * attachment if necessary, and possibly to set other options supported by
 * manual attachment.
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/gfp.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/comedi/comedi_pci.h>
#include <linux/comedi/comedi_8254.h>

#include "amcc_s5933.h"

/*
 * PCI BAR2 Register map (dev->iobase)
 */
#define PCI9118_TIMER_BASE
#define PCI9118_AI_FIFO_REG
#define PCI9118_AO_REG(x)
#define PCI9118_AI_STATUS_REG
#define PCI9118_AI_STATUS_NFULL
#define PCI9118_AI_STATUS_NHFULL
#define PCI9118_AI_STATUS_NEPTY
#define PCI9118_AI_STATUS_ACMP
#define PCI9118_AI_STATUS_DTH
#define PCI9118_AI_STATUS_BOVER
#define PCI9118_AI_STATUS_ADOS
#define PCI9118_AI_STATUS_ADOR
#define PCI9118_AI_STATUS_ADRDY
#define PCI9118_AI_CTRL_REG
#define PCI9118_AI_CTRL_UNIP
#define PCI9118_AI_CTRL_DIFF
#define PCI9118_AI_CTRL_SOFTG
#define PCI9118_AI_CTRL_EXTG
#define PCI9118_AI_CTRL_EXTM
#define PCI9118_AI_CTRL_TMRTR
#define PCI9118_AI_CTRL_INT
#define PCI9118_AI_CTRL_DMA
#define PCI9118_DIO_REG
#define PCI9118_SOFTTRG_REG
#define PCI9118_AI_CHANLIST_REG
#define PCI9118_AI_CHANLIST_RANGE(x)
#define PCI9118_AI_CHANLIST_CHAN(x)
#define PCI9118_AI_BURST_NUM_REG
#define PCI9118_AI_AUTOSCAN_MODE_REG
#define PCI9118_AI_CFG_REG
#define PCI9118_AI_CFG_PDTRG
#define PCI9118_AI_CFG_PETRG
#define PCI9118_AI_CFG_BSSH
#define PCI9118_AI_CFG_BM
#define PCI9118_AI_CFG_BS
#define PCI9118_AI_CFG_PM
#define PCI9118_AI_CFG_AM
#define PCI9118_AI_CFG_START
#define PCI9118_FIFO_RESET_REG
#define PCI9118_INT_CTRL_REG
#define PCI9118_INT_CTRL_TIMER
#define PCI9118_INT_CTRL_ABOUT
#define PCI9118_INT_CTRL_HFULL
#define PCI9118_INT_CTRL_DTRG

#define START_AI_EXT
#define STOP_AI_EXT
#define STOP_AI_INT

static const struct comedi_lrange pci9118_ai_range =;

static const struct comedi_lrange pci9118hg_ai_range =;

enum pci9118_boardid {};

struct pci9118_boardinfo {};

static const struct pci9118_boardinfo pci9118_boards[] =;

struct pci9118_dmabuf {};

struct pci9118_private {};

static void pci9118_amcc_setup_dma(struct comedi_device *dev, unsigned int buf)
{}

static void pci9118_amcc_dma_ena(struct comedi_device *dev, bool enable)
{}

static void pci9118_amcc_int_ena(struct comedi_device *dev, bool enable)
{}

static void pci9118_ai_reset_fifo(struct comedi_device *dev)
{}

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

static void pci9118_set_chanlist(struct comedi_device *dev,
				 struct comedi_subdevice *s,
				 int n_chan, unsigned int *chanlist,
				 int frontadd, int backadd)
{}

static void pci9118_ai_mode4_switch(struct comedi_device *dev,
				    unsigned int next_buf)
{}

static unsigned int pci9118_ai_samples_ready(struct comedi_device *dev,
					     struct comedi_subdevice *s,
					     unsigned int n_raw_samples)
{}

static void pci9118_ai_dma_xfer(struct comedi_device *dev,
				struct comedi_subdevice *s,
				unsigned short *dma_buffer,
				unsigned int n_raw_samples)
{}

static void pci9118_exttrg_enable(struct comedi_device *dev, bool enable)
{}

static void pci9118_calc_divisors(struct comedi_device *dev,
				  struct comedi_subdevice *s,
				  unsigned int *tim1, unsigned int *tim2,
				  unsigned int flags, int chans,
				  unsigned int *div1, unsigned int *div2,
				  unsigned int chnsshfront)
{}

static void pci9118_start_pacer(struct comedi_device *dev, int mode)
{}

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

static void pci9118_ai_munge(struct comedi_device *dev,
			     struct comedi_subdevice *s, void *data,
			     unsigned int num_bytes,
			     unsigned int start_chan_index)
{}

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

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

static irqreturn_t pci9118_interrupt(int irq, void *d)
{}

static void pci9118_ai_cmd_start(struct comedi_device *dev)
{}

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

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

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

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

static int pci9118_ai_eoc(struct comedi_device *dev,
			  struct comedi_subdevice *s,
			  struct comedi_insn *insn,
			  unsigned long context)
{}

static void pci9118_ai_start_conv(struct comedi_device *dev)
{}

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

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

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

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

static void pci9118_reset(struct comedi_device *dev)
{}

static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
					struct comedi_devconfig *it)
{}

static void pci9118_alloc_dma(struct comedi_device *dev)
{}

static void pci9118_free_dma(struct comedi_device *dev)
{}

static int pci9118_common_attach(struct comedi_device *dev,
				 int ext_mux, int softsshdelay)
{}

static int pci9118_attach(struct comedi_device *dev,
			  struct comedi_devconfig *it)
{}

static int pci9118_auto_attach(struct comedi_device *dev,
			       unsigned long context)
{}

static void pci9118_detach(struct comedi_device *dev)
{}

static struct comedi_driver adl_pci9118_driver =;

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

/* FIXME: All the supported board types have the same device ID! */
static const struct pci_device_id adl_pci9118_pci_table[] =;
MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table);

static struct pci_driver adl_pci9118_pci_driver =;
module_comedi_pci_driver();

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