linux/drivers/comedi/drivers/pcl818.c

// SPDX-License-Identifier: GPL-2.0
/*
 * comedi/drivers/pcl818.c
 *
 * Driver: pcl818
 * Description: Advantech PCL-818 cards, PCL-718
 * Author: Michal Dobes <[email protected]>
 * Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
 *   PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
 *   PCL-718 (pcl718)
 * Status: works
 *
 * All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
 * Differences are only at maximal sample speed, range list and FIFO
 * support.
 * The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
 * only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
 * PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
 * but this code is untested.
 * A word or two about DMA. Driver support DMA operations at two ways:
 * 1) DMA uses two buffers and after one is filled then is generated
 *    INT and DMA restart with second buffer. With this mode I'm unable run
 *    more that 80Ksamples/secs without data dropouts on K6/233.
 * 2) DMA uses one buffer and run in autoinit mode and the data are
 *    from DMA buffer moved on the fly with 2kHz interrupts from RTC.
 *    This mode is used if the interrupt 8 is available for allocation.
 *    If not, then first DMA mode is used. With this I can run at
 *    full speed one card (100ksamples/secs) or two cards with
 *    60ksamples/secs each (more is problem on account of ISA limitations).
 *    To use this mode you must have compiled  kernel with disabled
 *    "Enhanced Real Time Clock Support".
 *    Maybe you can have problems if you use xntpd or similar.
 *    If you've data dropouts with DMA mode 2 then:
 *     a) disable IDE DMA
 *     b) switch text mode console to fb.
 *
 *  Options for PCL-818L:
 *  [0] - IO Base
 *  [1] - IRQ        (0=disable, 2, 3, 4, 5, 6, 7)
 *  [2] - DMA        (0=disable, 1, 3)
 *  [3] - 0, 10=10MHz clock for 8254
 *            1= 1MHz clock for 8254
 *  [4] - 0,  5=A/D input  -5V.. +5V
 *        1, 10=A/D input -10V..+10V
 *  [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 unknown (external reference)
 *
 *  Options for PCL-818, PCL-818H:
 *  [0] - IO Base
 *  [1] - IRQ        (0=disable, 2, 3, 4, 5, 6, 7)
 *  [2] - DMA        (0=disable, 1, 3)
 *  [3] - 0, 10=10MHz clock for 8254
 *            1= 1MHz clock for 8254
 *  [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
 *        1, 10=D/A output 0-10V (internal reference -10V)
 *        2    =D/A output unknown (external reference)
 *
 *  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,
 *                    1=use DMA ch 1, 3=use DMA ch 3)
 *  [3] - 0, 10=10MHz clock for 8254
 *            1= 1MHz clock for 8254
 *  [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
 *        1, 10=D/A output 0-10V (internal reference -10V)
 *        2    =D/A output unknown (external reference)
 *
 *  Options for PCL-718:
 *  [0] - IO Base
 *  [1] - IRQ        (0=disable, 2, 3, 4, 5, 6, 7)
 *  [2] - DMA        (0=disable, 1, 3)
 *  [3] - 0, 10=10MHz clock for 8254
 *            1= 1MHz clock for 8254
 *  [4] -     0=A/D Range is +/-10V
 *            1=             +/-5V
 *            2=             +/-2.5V
 *            3=             +/-1V
 *            4=             +/-0.5V
 *            5=             user defined bipolar
 *            6=             0-10V
 *            7=             0-5V
 *            8=             0-2V
 *            9=             0-1V
 *           10=             user defined unipolar
 *  [5] - 0,  5=D/A outputs 0-5V  (internal reference -5V)
 *        1, 10=D/A outputs 0-10V (internal reference -10V)
 *            2=D/A outputs unknown (external reference)
 *  [6] - 0, 60=max  60kHz A/D sampling
 *        1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
 *
 */

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

/*
 * Register I/O map
 */
#define PCL818_AI_LSB_REG
#define PCL818_AI_MSB_REG
#define PCL818_RANGE_REG
#define PCL818_MUX_REG
#define PCL818_MUX_SCAN(_first, _last)
#define PCL818_DO_DI_LSB_REG
#define PCL818_AO_LSB_REG(x)
#define PCL818_AO_MSB_REG(x)
#define PCL818_STATUS_REG
#define PCL818_STATUS_NEXT_CHAN_MASK
#define PCL818_STATUS_INT
#define PCL818_STATUS_MUX
#define PCL818_STATUS_UNI
#define PCL818_STATUS_EOC
#define PCL818_CTRL_REG
#define PCL818_CTRL_TRIG(x)
#define PCL818_CTRL_DISABLE_TRIG
#define PCL818_CTRL_SOFT_TRIG
#define PCL818_CTRL_EXT_TRIG
#define PCL818_CTRL_PACER_TRIG
#define PCL818_CTRL_DMAE
#define PCL818_CTRL_IRQ(x)
#define PCL818_CTRL_INTE
#define PCL818_CNTENABLE_REG
#define PCL818_CNTENABLE_PACER_TRIG0
#define PCL818_CNTENABLE_CNT0_INT_CLK
#define PCL818_DO_DI_MSB_REG
#define PCL818_TIMER_BASE

/* W: fifo enable/disable */
#define PCL818_FI_ENABLE
/* W: fifo interrupt clear */
#define PCL818_FI_INTCLR
/* W: fifo interrupt clear */
#define PCL818_FI_FLUSH
/* R: fifo status */
#define PCL818_FI_STATUS
/* R: one record from FIFO */
#define PCL818_FI_DATALO
#define PCL818_FI_DATAHI

#define MAGIC_DMA_WORD

static const struct comedi_lrange range_pcl818h_ai =;

static const struct comedi_lrange range_pcl818hg_ai =;

static const struct comedi_lrange range_pcl818l_l_ai =;

static const struct comedi_lrange range_pcl818l_h_ai =;

static const struct comedi_lrange range718_bipolar1 =;

static const struct comedi_lrange range718_bipolar0_5 =;

static const struct comedi_lrange range718_unipolar2 =;

static const struct comedi_lrange range718_unipolar1 =;

struct pcl818_board {};

static const struct pcl818_board boardtypes[] =;

struct pcl818_private {};

static void pcl818_ai_setup_dma(struct comedi_device *dev,
				struct comedi_subdevice *s,
				unsigned int unread_samples)
{}

static void pcl818_ai_set_chan_range(struct comedi_device *dev,
				     unsigned int chan,
				     unsigned int range)
{}

static void pcl818_ai_set_chan_scan(struct comedi_device *dev,
				    unsigned int first_chan,
				    unsigned int last_chan)
{}

static void pcl818_ai_setup_chanlist(struct comedi_device *dev,
				     unsigned int *chanlist,
				     unsigned int seglen)
{}

static void pcl818_ai_clear_eoc(struct comedi_device *dev)
{}

static void pcl818_ai_soft_trig(struct comedi_device *dev)
{}

static unsigned int pcl818_ai_get_fifo_sample(struct comedi_device *dev,
					      struct comedi_subdevice *s,
					      unsigned int *chan)
{}

static unsigned int pcl818_ai_get_sample(struct comedi_device *dev,
					 struct comedi_subdevice *s,
					 unsigned int *chan)
{}

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

static bool pcl818_ai_write_sample(struct comedi_device *dev,
				   struct comedi_subdevice *s,
				   unsigned int chan, unsigned short val)
{}

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

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

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

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

static int check_channel_list(struct comedi_device *dev,
			      struct comedi_subdevice *s,
			      unsigned int *chanlist, unsigned int n_chan)
{}

static int check_single_ended(unsigned int port)
{}

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

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

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

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

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

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

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

static void pcl818_reset(struct comedi_device *dev)
{}

static void pcl818_set_ai_range_table(struct comedi_device *dev,
				      struct comedi_subdevice *s,
				      struct comedi_devconfig *it)
{}

static void pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
{}

static void pcl818_free_dma(struct comedi_device *dev)
{}

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

static void pcl818_detach(struct comedi_device *dev)
{}

static struct comedi_driver pcl818_driver =;
module_comedi_driver();

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