linux/drivers/comedi/drivers/ni_tio.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * Support for NI general purpose counters
 *
 * Copyright (C) 2006 Frank Mori Hess <[email protected]>
 */

/*
 * Module: ni_tio
 * Description: National Instruments general purpose counters
 * Author: J.P. Mellor <[email protected]>,
 *         [email protected],
 *         [email protected],
 *         [email protected],
 *         Frank Mori Hess <[email protected]>
 * Updated: Thu Nov 16 09:50:32 EST 2006
 * Status: works
 *
 * This module is not used directly by end-users.  Rather, it
 * is used by other drivers (for example ni_660x and ni_pcimio)
 * to provide support for NI's general purpose counters.  It was
 * originally based on the counter code from ni_660x.c and
 * ni_mio_common.c.
 *
 * References:
 * DAQ 660x Register-Level Programmer Manual  (NI 370505A-01)
 * DAQ 6601/6602 User Manual (NI 322137B-01)
 * 340934b.pdf  DAQ-STC reference manual
 *
 * TODO: Support use of both banks X and Y
 */

#include <linux/module.h>
#include <linux/slab.h>

#include "ni_tio_internal.h"

/*
 * clock sources for ni e and m series boards,
 * get bits with GI_SRC_SEL()
 */
#define NI_M_TIMEBASE_1_CLK
#define NI_M_PFI_CLK(x)
#define NI_M_RTSI_CLK(x)
#define NI_M_TIMEBASE_2_CLK
#define NI_M_NEXT_TC_CLK
#define NI_M_NEXT_GATE_CLK
#define NI_M_PXI_STAR_TRIGGER_CLK
#define NI_M_PXI10_CLK
#define NI_M_TIMEBASE_3_CLK
#define NI_M_ANALOG_TRIGGER_OUT_CLK
#define NI_M_LOGIC_LOW_CLK
#define NI_M_MAX_PFI_CHAN
#define NI_M_MAX_RTSI_CHAN

/*
 * clock sources for ni_660x boards,
 * get bits with GI_SRC_SEL()
 */
#define NI_660X_TIMEBASE_1_CLK
#define NI_660X_SRC_PIN_I_CLK
#define NI_660X_SRC_PIN_CLK(x)
#define NI_660X_NEXT_GATE_CLK
#define NI_660X_RTSI_CLK(x)
#define NI_660X_TIMEBASE_2_CLK
#define NI_660X_NEXT_TC_CLK
#define NI_660X_TIMEBASE_3_CLK
#define NI_660X_LOGIC_LOW_CLK
#define NI_660X_MAX_SRC_PIN
#define NI_660X_MAX_RTSI_CHAN

/* ni m series gate_select */
#define NI_M_TIMESTAMP_MUX_GATE_SEL
#define NI_M_PFI_GATE_SEL(x)
#define NI_M_RTSI_GATE_SEL(x)
#define NI_M_AI_START2_GATE_SEL
#define NI_M_PXI_STAR_TRIGGER_GATE_SEL
#define NI_M_NEXT_OUT_GATE_SEL
#define NI_M_AI_START1_GATE_SEL
#define NI_M_NEXT_SRC_GATE_SEL
#define NI_M_ANALOG_TRIG_OUT_GATE_SEL
#define NI_M_LOGIC_LOW_GATE_SEL

/* ni_660x gate select */
#define NI_660X_SRC_PIN_I_GATE_SEL
#define NI_660X_GATE_PIN_I_GATE_SEL
#define NI_660X_PIN_GATE_SEL(x)
#define NI_660X_NEXT_SRC_GATE_SEL
#define NI_660X_RTSI_GATE_SEL(x)
#define NI_660X_NEXT_OUT_GATE_SEL
#define NI_660X_LOGIC_LOW_GATE_SEL
#define NI_660X_MAX_GATE_PIN

/* ni_660x second gate select */
#define NI_660X_SRC_PIN_I_GATE2_SEL
#define NI_660X_UD_PIN_I_GATE2_SEL
#define NI_660X_UD_PIN_GATE2_SEL(x)
#define NI_660X_NEXT_SRC_GATE2_SEL
#define NI_660X_RTSI_GATE2_SEL(x)
#define NI_660X_NEXT_OUT_GATE2_SEL
#define NI_660X_SELECTED_GATE2_SEL
#define NI_660X_LOGIC_LOW_GATE2_SEL
#define NI_660X_MAX_UP_DOWN_PIN

static inline unsigned int GI_PRESCALE_X2(enum ni_gpct_variant variant)
{}

static inline unsigned int GI_PRESCALE_X8(enum ni_gpct_variant variant)
{}

static bool ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev)
{}

/**
 * ni_tio_write() - Write a TIO register using the driver provided callback.
 * @counter: struct ni_gpct counter.
 * @value: the value to write
 * @reg: the register to write.
 */
void ni_tio_write(struct ni_gpct *counter, unsigned int value,
		  enum ni_gpct_register reg)
{}
EXPORT_SYMBOL_GPL();

/**
 * ni_tio_read() - Read a TIO register using the driver provided callback.
 * @counter: struct ni_gpct counter.
 * @reg: the register to read.
 */
unsigned int ni_tio_read(struct ni_gpct *counter, enum ni_gpct_register reg)
{}
EXPORT_SYMBOL_GPL();

static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
{}

static int ni_tio_clock_period_ps(const struct ni_gpct *counter,
				  unsigned int generic_clock_source,
				  u64 *period_ps)
{}

static void ni_tio_set_bits_transient(struct ni_gpct *counter,
				      enum ni_gpct_register reg,
				      unsigned int mask, unsigned int value,
				      unsigned int transient)
{}

/**
 * ni_tio_set_bits() - Safely write a counter register.
 * @counter: struct ni_gpct counter.
 * @reg: the register to write.
 * @mask: the bits to change.
 * @value: the new bits value.
 *
 * Used to write to, and update the software copy, a register whose bits may
 * be twiddled in interrupt context, or whose software copy may be read in
 * interrupt context.
 */
void ni_tio_set_bits(struct ni_gpct *counter, enum ni_gpct_register reg,
		     unsigned int mask, unsigned int value)
{}
EXPORT_SYMBOL_GPL();

/**
 * ni_tio_get_soft_copy() - Safely read the software copy of a counter register.
 * @counter: struct ni_gpct counter.
 * @reg: the register to read.
 *
 * Used to get the software copy of a register whose bits might be modified
 * in interrupt context, or whose software copy might need to be read in
 * interrupt context.
 */
unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter,
				  enum ni_gpct_register reg)
{}
EXPORT_SYMBOL_GPL();

static unsigned int ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
{}

static int ni_m_series_clock_src_select(const struct ni_gpct *counter,
					unsigned int *clk_src)
{}

static int ni_660x_clock_src_select(const struct ni_gpct *counter,
				    unsigned int *clk_src)
{}

static int ni_tio_generic_clock_src_select(const struct ni_gpct *counter,
					   unsigned int *clk_src)
{}

static void ni_tio_set_sync_mode(struct ni_gpct *counter)
{}

static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned int mode)
{}

int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger)
{}
EXPORT_SYMBOL_GPL();

static int ni_660x_clk_src(unsigned int clock_source, unsigned int *bits)
{}

static int ni_m_clk_src(unsigned int clock_source, unsigned int *bits)
{
	unsigned int clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
	unsigned int ni_m_series_clock;
	unsigned int i;

	switch (clk_src) {
	case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
		ni_m_series_clock = NI_M_TIMEBASE_1_CLK;
		break;
	case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
		ni_m_series_clock = NI_M_TIMEBASE_2_CLK;
		break;
	case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
		ni_m_series_clock = NI_M_TIMEBASE_3_CLK;
		break;
	case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
		ni_m_series_clock = NI_M_LOGIC_LOW_CLK;
		break;
	case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
		ni_m_series_clock = NI_M_NEXT_GATE_CLK;
		break;
	case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
		ni_m_series_clock = NI_M_NEXT_TC_CLK;
		break;
	case NI_GPCT_PXI10_CLOCK_SRC_BITS:
		ni_m_series_clock = NI_M_PXI10_CLK;
		break;
	case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
		ni_m_series_clock = NI_M_PXI_STAR_TRIGGER_CLK;
		break;
	case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
		ni_m_series_clock = NI_M_ANALOG_TRIGGER_OUT_CLK;
		break;
	default:
		for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
			if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
				ni_m_series_clock = NI_M_RTSI_CLK(i);
				break;
			}
		}
		if (i <= NI_M_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
			if (clk_src == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
				ni_m_series_clock = NI_M_PFI_CLK(i);
				break;
			}
		}
		if (i <= NI_M_MAX_PFI_CHAN)
			break;
		return -EINVAL;
	}
	*bits = GI_SRC_SEL(ni_m_series_clock);
	return 0;
};

static void ni_tio_set_source_subselect(struct ni_gpct *counter,
					unsigned int clock_source)
{}

static int ni_tio_set_clock_src(struct ni_gpct *counter,
				unsigned int clock_source,
				unsigned int period_ns)
{}

static int ni_tio_get_clock_src(struct ni_gpct *counter,
				unsigned int *clock_source,
				unsigned int *period_ns)
{}

static inline void ni_tio_set_gate_raw(struct ni_gpct *counter,
				       unsigned int gate_source)
{}

static inline void ni_tio_set_gate2_raw(struct ni_gpct *counter,
					unsigned int gate_source)
{}

/* Set the mode bits for gate. */
static inline void ni_tio_set_gate_mode(struct ni_gpct *counter,
					unsigned int src)
{}

/*
 * Set the mode bits for gate2.
 *
 * Previously, the code this function represents did not actually write anything
 * to the register.  Rather, writing to this register was reserved for the code
 * ni ni_tio_set_gate2_raw.
 */
static inline void ni_tio_set_gate2_mode(struct ni_gpct *counter,
					 unsigned int src)
{}

static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source)
{}

static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source)
{}

static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
{}

static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
{}

int ni_tio_set_gate_src_raw(struct ni_gpct *counter,
			    unsigned int gate, unsigned int src)
{}
EXPORT_SYMBOL_GPL();

int ni_tio_set_gate_src(struct ni_gpct *counter,
			unsigned int gate, unsigned int src)
{}
EXPORT_SYMBOL_GPL();

static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index,
				unsigned int source)
{}

static int ni_tio_get_other_src(struct ni_gpct *counter, unsigned int index,
				unsigned int *source)
{}

static int ni_660x_gate_to_generic_gate(unsigned int gate, unsigned int *src)
{}

static int ni_m_gate_to_generic_gate(unsigned int gate, unsigned int *src)
{}

static int ni_660x_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
{}

static int ni_m_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
{}

static inline unsigned int ni_tio_get_gate_mode(struct ni_gpct *counter)
{}

static inline unsigned int ni_tio_get_gate2_mode(struct ni_gpct *counter)
{}

static inline unsigned int ni_tio_get_gate_val(struct ni_gpct *counter)
{}

static inline unsigned int ni_tio_get_gate2_val(struct ni_gpct *counter)
{}

static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index,
			       unsigned int *gate_source)
{}

static int ni_tio_get_gate_src_raw(struct ni_gpct *counter,
				   unsigned int gate_index,
				   unsigned int *gate_source)
{}

int ni_tio_insn_config(struct comedi_device *dev,
		       struct comedi_subdevice *s,
		       struct comedi_insn *insn,
		       unsigned int *data)
{}
EXPORT_SYMBOL_GPL();

/*
 * Retrieves the register value of the current source of the output selector for
 * the given destination.
 *
 * If the terminal for the destination is not already configured as an output,
 * this function returns -EINVAL as error.
 *
 * Return: the register value of the destination output selector;
 *         -EINVAL if terminal is not configured for output.
 */
int ni_tio_get_routing(struct ni_gpct_device *counter_dev, unsigned int dest)
{}
EXPORT_SYMBOL_GPL();

/**
 * ni_tio_set_routing() - Sets the register value of the selector MUX for the given destination.
 * @counter_dev: Pointer to general counter device.
 * @dest:        Device-global identifier of route destination.
 * @reg:
 *		The first several bits of this value should store the desired
 *		value to write to the register.  All other bits are for
 *		transmitting information that modify the mode of the particular
 *		destination/gate.  These mode bits might include a bitwise or of
 *		CR_INVERT and CR_EDGE.  Note that the calling function should
 *		have already validated the correctness of this value.
 */
int ni_tio_set_routing(struct ni_gpct_device *counter_dev, unsigned int dest,
		       unsigned int reg)
{}
EXPORT_SYMBOL_GPL();

/*
 * Sets the given destination MUX to its default value or disable it.
 *
 * Return: 0 if successful; -EINVAL if terminal is unknown.
 */
int ni_tio_unset_routing(struct ni_gpct_device *counter_dev, unsigned int dest)
{}
EXPORT_SYMBOL_GPL();

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

int ni_tio_insn_read(struct comedi_device *dev,
		     struct comedi_subdevice *s,
		     struct comedi_insn *insn,
		     unsigned int *data)
{}
EXPORT_SYMBOL_GPL();

static unsigned int ni_tio_next_load_register(struct ni_gpct *counter)
{}

int ni_tio_insn_write(struct comedi_device *dev,
		      struct comedi_subdevice *s,
		      struct comedi_insn *insn,
		      unsigned int *data)
{}
EXPORT_SYMBOL_GPL();

void ni_tio_init_counter(struct ni_gpct *counter)
{}
EXPORT_SYMBOL_GPL();

struct ni_gpct_device *
ni_gpct_device_construct(struct comedi_device *dev,
			 void (*write)(struct ni_gpct *counter,
				       unsigned int value,
				       enum ni_gpct_register reg),
			 unsigned int (*read)(struct ni_gpct *counter,
					      enum ni_gpct_register reg),
			 enum ni_gpct_variant variant,
			 unsigned int num_counters,
			 unsigned int counters_per_chip,
			 const struct ni_route_tables *routing_tables)
{}
EXPORT_SYMBOL_GPL();

void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
{}
EXPORT_SYMBOL_GPL();

static int __init ni_tio_init_module(void)
{}
module_init();

static void __exit ni_tio_cleanup_module(void)
{}
module_exit(ni_tio_cleanup_module);

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