/*
 * Support for NI general purpose counters
 *
 * Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
 *
 * 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
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * Module: ni_tio
 * Description: National Instruments general purpose counters
 * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
 *         Herman.Bruyninckx@mech.kuleuven.ac.be,
 *         Wim.Meeussen@mech.kuleuven.ac.be,
 *         Klaas.Gadeyne@mech.kuleuven.ac.be,
 *         Frank Mori Hess <fmhess@users.sourceforge.net>
 * 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		0x0	/* 20MHz */
#define NI_M_PFI_CLK(x)			(((x) < 10) ? (1 + (x)) : (0xb + (x)))
#define NI_M_RTSI_CLK(x)		(((x) == 7) ? 0x1b : (0xb + (x)))
#define NI_M_TIMEBASE_2_CLK		0x12	/* 100KHz */
#define NI_M_NEXT_TC_CLK		0x13
#define NI_M_NEXT_GATE_CLK		0x14	/* Gi_Src_SubSelect=0 */
#define NI_M_PXI_STAR_TRIGGER_CLK	0x14	/* Gi_Src_SubSelect=1 */
#define NI_M_PXI10_CLK			0x1d
#define NI_M_TIMEBASE_3_CLK		0x1e	/* 80MHz, Gi_Src_SubSelect=0 */
#define NI_M_ANALOG_TRIGGER_OUT_CLK	0x1e	/* Gi_Src_SubSelect=1 */
#define NI_M_LOGIC_LOW_CLK		0x1f
#define NI_M_MAX_PFI_CHAN		15
#define NI_M_MAX_RTSI_CHAN		7

/*
 * clock sources for ni_660x boards,
 * get bits with GI_SRC_SEL()
 */
#define NI_660X_TIMEBASE_1_CLK		0x0	/* 20MHz */
#define NI_660X_SRC_PIN_I_CLK		0x1
#define NI_660X_SRC_PIN_CLK(x)		(0x2 + (x))
#define NI_660X_NEXT_GATE_CLK		0xa
#define NI_660X_RTSI_CLK(x)		(0xb + (x))
#define NI_660X_TIMEBASE_2_CLK		0x12	/* 100KHz */
#define NI_660X_NEXT_TC_CLK		0x13
#define NI_660X_TIMEBASE_3_CLK		0x1e	/* 80MHz */
#define NI_660X_LOGIC_LOW_CLK		0x1f
#define NI_660X_MAX_SRC_PIN		7
#define NI_660X_MAX_RTSI_CHAN		6

/* ni m series gate_select */
#define NI_M_TIMESTAMP_MUX_GATE_SEL	0x0
#define NI_M_PFI_GATE_SEL(x)		(((x) < 10) ? (1 + (x)) : (0xb + (x)))
#define NI_M_RTSI_GATE_SEL(x)		(((x) == 7) ? 0x1b : (0xb + (x)))
#define NI_M_AI_START2_GATE_SEL		0x12
#define NI_M_PXI_STAR_TRIGGER_GATE_SEL	0x13
#define NI_M_NEXT_OUT_GATE_SEL		0x14
#define NI_M_AI_START1_GATE_SEL		0x1c
#define NI_M_NEXT_SRC_GATE_SEL		0x1d
#define NI_M_ANALOG_TRIG_OUT_GATE_SEL	0x1e
#define NI_M_LOGIC_LOW_GATE_SEL		0x1f

/* ni_660x gate select */
#define NI_660X_SRC_PIN_I_GATE_SEL	0x0
#define NI_660X_GATE_PIN_I_GATE_SEL	0x1
#define NI_660X_PIN_GATE_SEL(x)		(0x2 + (x))
#define NI_660X_NEXT_SRC_GATE_SEL	0xa
#define NI_660X_RTSI_GATE_SEL(x)	(0xb + (x))
#define NI_660X_NEXT_OUT_GATE_SEL	0x14
#define NI_660X_LOGIC_LOW_GATE_SEL	0x1f
#define NI_660X_MAX_GATE_PIN		7

/* ni_660x second gate select */
#define NI_660X_SRC_PIN_I_GATE2_SEL	0x0
#define NI_660X_UD_PIN_I_GATE2_SEL	0x1
#define NI_660X_UD_PIN_GATE2_SEL(x)	(0x2 + (x))
#define NI_660X_NEXT_SRC_GATE2_SEL	0xa
#define NI_660X_RTSI_GATE2_SEL(x)	(0xb + (x))
#define NI_660X_NEXT_OUT_GATE2_SEL	0x14
#define NI_660X_SELECTED_GATE2_SEL	0x1e
#define NI_660X_LOGIC_LOW_GATE2_SEL	0x1f
#define NI_660X_MAX_UP_DOWN_PIN		7

static inline unsigned int GI_PRESCALE_X2(enum ni_gpct_variant variant)
{
	switch (variant) {
	case ni_gpct_variant_e_series:
	default:
		return 0;
	case ni_gpct_variant_m_series:
		return GI_M_PRESCALE_X2;
	case ni_gpct_variant_660x:
		return GI_660X_PRESCALE_X2;
	}
}

static inline unsigned int GI_PRESCALE_X8(enum ni_gpct_variant variant)
{
	switch (variant) {
	case ni_gpct_variant_e_series:
	default:
		return 0;
	case ni_gpct_variant_m_series:
		return GI_M_PRESCALE_X8;
	case ni_gpct_variant_660x:
		return GI_660X_PRESCALE_X8;
	}
}

static bool ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev)
{
	switch (counter_dev->variant) {
	case ni_gpct_variant_e_series:
	default:
		return false;
	case ni_gpct_variant_m_series:
	case ni_gpct_variant_660x:
		return true;
	}
}

/**
 * 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)
{
	if (reg < NITIO_NUM_REGS)
		counter->counter_dev->write(counter, value, reg);
}
EXPORT_SYMBOL_GPL(ni_tio_write);

/**
 * 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)
{
	if (reg < NITIO_NUM_REGS)
		return counter->counter_dev->read(counter, reg);
	return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_read);

static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
{
	unsigned int cidx = counter->counter_index;

	ni_tio_write(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx));
}

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

	switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
	case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
		clock_period_ps = 50000;
		break;
	case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
		clock_period_ps = 10000000;
		break;
	case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
		clock_period_ps = 12500;
		break;
	case NI_GPCT_PXI10_CLOCK_SRC_BITS:
		clock_period_ps = 100000;
		break;
	default:
		/*
		 * clock period is specified by user with prescaling
		 * already taken into account.
		 */
		*period_ps = counter->clock_period_ps;
		return 0;
	}

	switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
	case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
		break;
	case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
		clock_period_ps *= 2;
		break;
	case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
		clock_period_ps *= 8;
		break;
	default:
		return -EINVAL;
	}
	*period_ps = clock_period_ps;
	return 0;
}

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)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned long flags;

	if (reg < NITIO_NUM_REGS) {
		spin_lock_irqsave(&counter_dev->regs_lock, flags);
		counter_dev->regs[reg] &= ~mask;
		counter_dev->regs[reg] |= (value & mask);
		ni_tio_write(counter, counter_dev->regs[reg] | transient, reg);
		mmiowb();
		spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
	}
}

/**
 * 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)
{
	ni_tio_set_bits_transient(counter, reg, mask, value, 0x0);
}
EXPORT_SYMBOL_GPL(ni_tio_set_bits);

/**
 * 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)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int value = 0;
	unsigned long flags;

	if (reg < NITIO_NUM_REGS) {
		spin_lock_irqsave(&counter_dev->regs_lock, flags);
		value = counter_dev->regs[reg];
		spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
	}
	return value;
}
EXPORT_SYMBOL_GPL(ni_tio_get_soft_copy);

static unsigned int ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int counting_mode_bits =
		ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx));
	unsigned int bits = 0;

	if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
	    GI_SRC_POL_INVERT)
		bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
	if (counting_mode_bits & GI_PRESCALE_X2(counter_dev->variant))
		bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
	if (counting_mode_bits & GI_PRESCALE_X8(counter_dev->variant))
		bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
	return bits;
}

static int ni_m_series_clock_src_select(const struct ni_gpct *counter,
					unsigned int *clk_src)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int second_gate_reg = NITIO_GATE2_REG(cidx);
	unsigned int clock_source = 0;
	unsigned int src;
	unsigned int i;

	src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
						  NITIO_INPUT_SEL_REG(cidx)));

	switch (src) {
	case NI_M_TIMEBASE_1_CLK:
		clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
		break;
	case NI_M_TIMEBASE_2_CLK:
		clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
		break;
	case NI_M_TIMEBASE_3_CLK:
		if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL)
			clock_source =
			    NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
		else
			clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
		break;
	case NI_M_LOGIC_LOW_CLK:
		clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
		break;
	case NI_M_NEXT_GATE_CLK:
		if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL)
			clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
		else
			clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
		break;
	case NI_M_PXI10_CLK:
		clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
		break;
	case NI_M_NEXT_TC_CLK:
		clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
		break;
	default:
		for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
			if (src == NI_M_RTSI_CLK(i)) {
				clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
				break;
			}
		}
		if (i <= NI_M_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
			if (src == NI_M_PFI_CLK(i)) {
				clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
				break;
			}
		}
		if (i <= NI_M_MAX_PFI_CHAN)
			break;
		return -EINVAL;
	}
	clock_source |= ni_tio_clock_src_modifiers(counter);
	*clk_src = clock_source;
	return 0;
}

static int ni_660x_clock_src_select(const struct ni_gpct *counter,
				    unsigned int *clk_src)
{
	unsigned int clock_source = 0;
	unsigned int cidx = counter->counter_index;
	unsigned int src;
	unsigned int i;

	src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
						  NITIO_INPUT_SEL_REG(cidx)));

	switch (src) {
	case NI_660X_TIMEBASE_1_CLK:
		clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
		break;
	case NI_660X_TIMEBASE_2_CLK:
		clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
		break;
	case NI_660X_TIMEBASE_3_CLK:
		clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
		break;
	case NI_660X_LOGIC_LOW_CLK:
		clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
		break;
	case NI_660X_SRC_PIN_I_CLK:
		clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
		break;
	case NI_660X_NEXT_GATE_CLK:
		clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
		break;
	case NI_660X_NEXT_TC_CLK:
		clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
		break;
	default:
		for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
			if (src == NI_660X_RTSI_CLK(i)) {
				clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
				break;
			}
		}
		if (i <= NI_660X_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
			if (src == NI_660X_SRC_PIN_CLK(i)) {
				clock_source =
				    NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
				break;
			}
		}
		if (i <= NI_660X_MAX_SRC_PIN)
			break;
		return -EINVAL;
	}
	clock_source |= ni_tio_clock_src_modifiers(counter);
	*clk_src = clock_source;
	return 0;
}

static int ni_tio_generic_clock_src_select(const struct ni_gpct *counter,
					   unsigned int *clk_src)
{
	switch (counter->counter_dev->variant) {
	case ni_gpct_variant_e_series:
	case ni_gpct_variant_m_series:
	default:
		return ni_m_series_clock_src_select(counter, clk_src);
	case ni_gpct_variant_660x:
		return ni_660x_clock_src_select(counter, clk_src);
	}
}

static void ni_tio_set_sync_mode(struct ni_gpct *counter)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	static const u64 min_normal_sync_period_ps = 25000;
	unsigned int mask = 0;
	unsigned int bits = 0;
	unsigned int reg;
	unsigned int mode;
	unsigned int clk_src;
	u64 ps;
	bool force_alt_sync;

	/* only m series and 660x variants have counting mode registers */
	switch (counter_dev->variant) {
	case ni_gpct_variant_e_series:
	default:
		return;
	case ni_gpct_variant_m_series:
		mask = GI_M_ALT_SYNC;
		break;
	case ni_gpct_variant_660x:
		mask = GI_660X_ALT_SYNC;
		break;
	}

	reg = NITIO_CNT_MODE_REG(cidx);
	mode = ni_tio_get_soft_copy(counter, reg);
	switch (mode & GI_CNT_MODE_MASK) {
	case GI_CNT_MODE_QUADX1:
	case GI_CNT_MODE_QUADX2:
	case GI_CNT_MODE_QUADX4:
	case GI_CNT_MODE_SYNC_SRC:
		force_alt_sync = true;
		break;
	default:
		force_alt_sync = false;
		break;
	}

	ni_tio_generic_clock_src_select(counter, &clk_src);
	ni_tio_clock_period_ps(counter, clk_src, &ps);

	/*
	 * It's not clear what we should do if clock_period is unknown, so we
	 * are not using the alt sync bit in that case.
	 */
	if (force_alt_sync || (ps && ps < min_normal_sync_period_ps))
		bits = mask;

	ni_tio_set_bits(counter, reg, mask, bits);
}

static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned int mode)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int mode_reg_mask;
	unsigned int mode_reg_values;
	unsigned int input_select_bits = 0;
	/* these bits map directly on to the mode register */
	static const unsigned int mode_reg_direct_mask =
	    NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK |
	    NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK |
	    NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT |
	    NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT;

	mode_reg_mask = mode_reg_direct_mask | GI_RELOAD_SRC_SWITCHING;
	mode_reg_values = mode & mode_reg_direct_mask;
	switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) {
	case NI_GPCT_RELOAD_SOURCE_FIXED_BITS:
		break;
	case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS:
		mode_reg_values |= GI_RELOAD_SRC_SWITCHING;
		break;
	case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS:
		input_select_bits |= GI_GATE_SEL_LOAD_SRC;
		mode_reg_mask |= GI_GATING_MODE_MASK;
		mode_reg_values |= GI_LEVEL_GATING;
		break;
	default:
		break;
	}
	ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
			mode_reg_mask, mode_reg_values);

	if (ni_tio_counting_mode_registers_present(counter_dev)) {
		unsigned int bits = 0;

		bits |= GI_CNT_MODE(mode >> NI_GPCT_COUNTING_MODE_SHIFT);
		bits |= GI_INDEX_PHASE((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT));
		if (mode & NI_GPCT_INDEX_ENABLE_BIT)
			bits |= GI_INDEX_MODE;
		ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
				GI_CNT_MODE_MASK | GI_INDEX_PHASE_MASK |
				GI_INDEX_MODE, bits);
		ni_tio_set_sync_mode(counter);
	}

	ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_CNT_DIR_MASK,
			GI_CNT_DIR(mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT));

	if (mode & NI_GPCT_OR_GATE_BIT)
		input_select_bits |= GI_OR_GATE;
	if (mode & NI_GPCT_INVERT_OUTPUT_BIT)
		input_select_bits |= GI_OUTPUT_POL_INVERT;
	ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
			GI_GATE_SEL_LOAD_SRC | GI_OR_GATE |
			GI_OUTPUT_POL_INVERT, input_select_bits);

	return 0;
}

int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int transient_bits = 0;

	if (arm) {
		unsigned int mask = 0;
		unsigned int bits = 0;

		/* only m series and 660x have counting mode registers */
		switch (counter_dev->variant) {
		case ni_gpct_variant_e_series:
		default:
			break;
		case ni_gpct_variant_m_series:
			mask = GI_M_HW_ARM_SEL_MASK;
			break;
		case ni_gpct_variant_660x:
			mask = GI_660X_HW_ARM_SEL_MASK;
			break;
		}

		switch (start_trigger) {
		case NI_GPCT_ARM_IMMEDIATE:
			transient_bits |= GI_ARM;
			break;
		case NI_GPCT_ARM_PAIRED_IMMEDIATE:
			transient_bits |= GI_ARM | GI_ARM_COPY;
			break;
		default:
			/*
			 * for m series and 660x, pass-through the least
			 * significant bits so we can figure out what select
			 * later
			 */
			if (mask && (start_trigger & NI_GPCT_ARM_UNKNOWN)) {
				bits |= GI_HW_ARM_ENA |
					(GI_HW_ARM_SEL(start_trigger) & mask);
			} else {
				return -EINVAL;
			}
			break;
		}

		if (mask)
			ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
					GI_HW_ARM_ENA | mask, bits);
	} else {
		transient_bits |= GI_DISARM;
	}
	ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
				  0, 0, transient_bits);
	return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_arm);

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

	switch (clk_src) {
	case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
		ni_660x_clock = NI_660X_TIMEBASE_1_CLK;
		break;
	case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
		ni_660x_clock = NI_660X_TIMEBASE_2_CLK;
		break;
	case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
		ni_660x_clock = NI_660X_TIMEBASE_3_CLK;
		break;
	case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
		ni_660x_clock = NI_660X_LOGIC_LOW_CLK;
		break;
	case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS:
		ni_660x_clock = NI_660X_SRC_PIN_I_CLK;
		break;
	case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
		ni_660x_clock = NI_660X_NEXT_GATE_CLK;
		break;
	case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
		ni_660x_clock = NI_660X_NEXT_TC_CLK;
		break;
	default:
		for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
			if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
				ni_660x_clock = NI_660X_RTSI_CLK(i);
				break;
			}
		}
		if (i <= NI_660X_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
			if (clk_src == NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
				ni_660x_clock = NI_660X_SRC_PIN_CLK(i);
				break;
			}
		}
		if (i <= NI_660X_MAX_SRC_PIN)
			break;
		return -EINVAL;
	}
	*bits = GI_SRC_SEL(ni_660x_clock);
	return 0;
}

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)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int second_gate_reg = NITIO_GATE2_REG(cidx);

	if (counter_dev->variant != ni_gpct_variant_m_series)
		return;
	switch (clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
		/* Gi_Source_Subselect is zero */
	case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
	case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
		counter_dev->regs[second_gate_reg] &= ~GI_SRC_SUBSEL;
		break;
		/* Gi_Source_Subselect is one */
	case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
	case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
		counter_dev->regs[second_gate_reg] |= GI_SRC_SUBSEL;
		break;
		/* Gi_Source_Subselect doesn't matter */
	default:
		return;
	}
	ni_tio_write(counter, counter_dev->regs[second_gate_reg],
		     second_gate_reg);
}

static int ni_tio_set_clock_src(struct ni_gpct *counter,
				unsigned int clock_source,
				unsigned int period_ns)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int bits = 0;
	int ret;

	switch (counter_dev->variant) {
	case ni_gpct_variant_660x:
		ret = ni_660x_clk_src(clock_source, &bits);
		break;
	case ni_gpct_variant_e_series:
	case ni_gpct_variant_m_series:
	default:
		ret = ni_m_clk_src(clock_source, &bits);
		break;
	}
	if (ret) {
		struct comedi_device *dev = counter_dev->dev;

		dev_err(dev->class_dev, "invalid clock source 0x%x\n",
			clock_source);
		return ret;
	}

	if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT)
		bits |= GI_SRC_POL_INVERT;
	ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
			GI_SRC_SEL_MASK | GI_SRC_POL_INVERT, bits);
	ni_tio_set_source_subselect(counter, clock_source);

	if (ni_tio_counting_mode_registers_present(counter_dev)) {
		bits = 0;
		switch (clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
		case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
			break;
		case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
			bits |= GI_PRESCALE_X2(counter_dev->variant);
			break;
		case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
			bits |= GI_PRESCALE_X8(counter_dev->variant);
			break;
		default:
			return -EINVAL;
		}
		ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
				GI_PRESCALE_X2(counter_dev->variant) |
				GI_PRESCALE_X8(counter_dev->variant), bits);
	}
	counter->clock_period_ps = period_ns * 1000;
	ni_tio_set_sync_mode(counter);
	return 0;
}

static int ni_tio_get_clock_src(struct ni_gpct *counter,
				unsigned int *clock_source,
				unsigned int *period_ns)
{
	u64 temp64;
	int ret;

	ret = ni_tio_generic_clock_src_select(counter, clock_source);
	if (ret)
		return ret;
	ret = ni_tio_clock_period_ps(counter, *clock_source, &temp64);
	if (ret)
		return ret;
	do_div(temp64, 1000);	/* ps to ns */
	*period_ns = temp64;
	return 0;
}

static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source)
{
	unsigned int chan = CR_CHAN(gate_source);
	unsigned int cidx = counter->counter_index;
	unsigned int gate_sel;
	unsigned int i;

	switch (chan) {
	case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
		gate_sel = NI_660X_NEXT_SRC_GATE_SEL;
		break;
	case NI_GPCT_NEXT_OUT_GATE_SELECT:
	case NI_GPCT_LOGIC_LOW_GATE_SELECT:
	case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
	case NI_GPCT_GATE_PIN_i_GATE_SELECT:
		gate_sel = chan & 0x1f;
		break;
	default:
		for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
			if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
				gate_sel = chan & 0x1f;
				break;
			}
		}
		if (i <= NI_660X_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
			if (chan == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
				gate_sel = chan & 0x1f;
				break;
			}
		}
		if (i <= NI_660X_MAX_GATE_PIN)
			break;
		return -EINVAL;
	}
	ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
			GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
	return 0;
}

static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source)
{
	unsigned int chan = CR_CHAN(gate_source);
	unsigned int cidx = counter->counter_index;
	unsigned int gate_sel;
	unsigned int i;

	switch (chan) {
	case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT:
	case NI_GPCT_AI_START2_GATE_SELECT:
	case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT:
	case NI_GPCT_NEXT_OUT_GATE_SELECT:
	case NI_GPCT_AI_START1_GATE_SELECT:
	case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
	case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT:
	case NI_GPCT_LOGIC_LOW_GATE_SELECT:
		gate_sel = chan & 0x1f;
		break;
	default:
		for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
			if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
				gate_sel = chan & 0x1f;
				break;
			}
		}
		if (i <= NI_M_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
			if (chan == NI_GPCT_PFI_GATE_SELECT(i)) {
				gate_sel = chan & 0x1f;
				break;
			}
		}
		if (i <= NI_M_MAX_PFI_CHAN)
			break;
		return -EINVAL;
	}
	ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
			GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
	return 0;
}

static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int chan = CR_CHAN(gate_source);
	unsigned int gate2_reg = NITIO_GATE2_REG(cidx);
	unsigned int gate2_sel;
	unsigned int i;

	switch (chan) {
	case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
	case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT:
	case NI_GPCT_SELECTED_GATE_GATE_SELECT:
	case NI_GPCT_NEXT_OUT_GATE_SELECT:
	case NI_GPCT_LOGIC_LOW_GATE_SELECT:
		gate2_sel = chan & 0x1f;
		break;
	case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
		gate2_sel = NI_660X_NEXT_SRC_GATE2_SEL;
		break;
	default:
		for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
			if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
				gate2_sel = chan & 0x1f;
				break;
			}
		}
		if (i <= NI_660X_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
			if (chan == NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
				gate2_sel = chan & 0x1f;
				break;
			}
		}
		if (i <= NI_660X_MAX_UP_DOWN_PIN)
			break;
		return -EINVAL;
	}
	counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
	counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
	counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
	ni_tio_write(counter, counter_dev->regs[gate2_reg], gate2_reg);
	return 0;
}

static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int chan = CR_CHAN(gate_source);
	unsigned int gate2_reg = NITIO_GATE2_REG(cidx);
	unsigned int gate2_sel;

	/*
	 * FIXME: We don't know what the m-series second gate codes are,
	 * so we'll just pass the bits through for now.
	 */
	switch (chan) {
	default:
		gate2_sel = chan & 0x1f;
		break;
	}
	counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
	counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
	counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
	ni_tio_write(counter, counter_dev->regs[gate2_reg], gate2_reg);
	return 0;
}

int ni_tio_set_gate_src(struct ni_gpct *counter,
			unsigned int gate, unsigned int src)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int chan = CR_CHAN(src);
	unsigned int gate2_reg = NITIO_GATE2_REG(cidx);
	unsigned int mode = 0;

	switch (gate) {
	case 0:
		if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
			ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
					GI_GATING_MODE_MASK,
					GI_GATING_DISABLED);
			return 0;
		}
		if (src & CR_INVERT)
			mode |= GI_GATE_POL_INVERT;
		if (src & CR_EDGE)
			mode |= GI_RISING_EDGE_GATING;
		else
			mode |= GI_LEVEL_GATING;
		ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
				GI_GATE_POL_INVERT | GI_GATING_MODE_MASK,
				mode);
		switch (counter_dev->variant) {
		case ni_gpct_variant_e_series:
		case ni_gpct_variant_m_series:
		default:
			return ni_m_set_gate(counter, src);
		case ni_gpct_variant_660x:
			return ni_660x_set_gate(counter, src);
		}
		break;
	case 1:
		if (!ni_tio_has_gate2_registers(counter_dev))
			return -EINVAL;

		if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
			counter_dev->regs[gate2_reg] &= ~GI_GATE2_MODE;
			ni_tio_write(counter, counter_dev->regs[gate2_reg],
				     gate2_reg);
			return 0;
		}
		if (src & CR_INVERT)
			counter_dev->regs[gate2_reg] |= GI_GATE2_POL_INVERT;
		else
			counter_dev->regs[gate2_reg] &= ~GI_GATE2_POL_INVERT;
		switch (counter_dev->variant) {
		case ni_gpct_variant_m_series:
			return ni_m_set_gate2(counter, src);
		case ni_gpct_variant_660x:
			return ni_660x_set_gate2(counter, src);
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_set_gate_src);

static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index,
				unsigned int source)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int abz_reg, shift, mask;

	if (counter_dev->variant != ni_gpct_variant_m_series)
		return -EINVAL;

	abz_reg = NITIO_ABZ_REG(cidx);
	switch (index) {
	case NI_GPCT_SOURCE_ENCODER_A:
		shift = 10;
		break;
	case NI_GPCT_SOURCE_ENCODER_B:
		shift = 5;
		break;
	case NI_GPCT_SOURCE_ENCODER_Z:
		shift = 0;
		break;
	default:
		return -EINVAL;
	}
	mask = 0x1f << shift;
	if (source > 0x1f)
		source = 0x1f;	/* Disable gate */

	counter_dev->regs[abz_reg] &= ~mask;
	counter_dev->regs[abz_reg] |= (source << shift) & mask;
	ni_tio_write(counter, counter_dev->regs[abz_reg], abz_reg);
	return 0;
}

static int ni_660x_gate_to_generic_gate(unsigned int gate, unsigned int *src)
{
	unsigned int source;
	unsigned int i;

	switch (gate) {
	case NI_660X_SRC_PIN_I_GATE_SEL:
		source = NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
		break;
	case NI_660X_GATE_PIN_I_GATE_SEL:
		source = NI_GPCT_GATE_PIN_i_GATE_SELECT;
		break;
	case NI_660X_NEXT_SRC_GATE_SEL:
		source = NI_GPCT_NEXT_SOURCE_GATE_SELECT;
		break;
	case NI_660X_NEXT_OUT_GATE_SEL:
		source = NI_GPCT_NEXT_OUT_GATE_SELECT;
		break;
	case NI_660X_LOGIC_LOW_GATE_SEL:
		source = NI_GPCT_LOGIC_LOW_GATE_SELECT;
		break;
	default:
		for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
			if (gate == NI_660X_RTSI_GATE_SEL(i)) {
				source = NI_GPCT_RTSI_GATE_SELECT(i);
				break;
			}
		}
		if (i <= NI_660X_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
			if (gate == NI_660X_PIN_GATE_SEL(i)) {
				source = NI_GPCT_GATE_PIN_GATE_SELECT(i);
				break;
			}
		}
		if (i <= NI_660X_MAX_GATE_PIN)
			break;
		return -EINVAL;
	}
	*src = source;
	return 0;
};

static int ni_m_gate_to_generic_gate(unsigned int gate, unsigned int *src)
{
	unsigned int source;
	unsigned int i;

	switch (gate) {
	case NI_M_TIMESTAMP_MUX_GATE_SEL:
		source = NI_GPCT_TIMESTAMP_MUX_GATE_SELECT;
		break;
	case NI_M_AI_START2_GATE_SEL:
		source = NI_GPCT_AI_START2_GATE_SELECT;
		break;
	case NI_M_PXI_STAR_TRIGGER_GATE_SEL:
		source = NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT;
		break;
	case NI_M_NEXT_OUT_GATE_SEL:
		source = NI_GPCT_NEXT_OUT_GATE_SELECT;
		break;
	case NI_M_AI_START1_GATE_SEL:
		source = NI_GPCT_AI_START1_GATE_SELECT;
		break;
	case NI_M_NEXT_SRC_GATE_SEL:
		source = NI_GPCT_NEXT_SOURCE_GATE_SELECT;
		break;
	case NI_M_ANALOG_TRIG_OUT_GATE_SEL:
		source = NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT;
		break;
	case NI_M_LOGIC_LOW_GATE_SEL:
		source = NI_GPCT_LOGIC_LOW_GATE_SELECT;
		break;
	default:
		for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
			if (gate == NI_M_RTSI_GATE_SEL(i)) {
				source = NI_GPCT_RTSI_GATE_SELECT(i);
				break;
			}
		}
		if (i <= NI_M_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
			if (gate == NI_M_PFI_GATE_SEL(i)) {
				source = NI_GPCT_PFI_GATE_SELECT(i);
				break;
			}
		}
		if (i <= NI_M_MAX_PFI_CHAN)
			break;
		return -EINVAL;
	}
	*src = source;
	return 0;
};

static int ni_660x_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
{
	unsigned int source;
	unsigned int i;

	switch (gate) {
	case NI_660X_SRC_PIN_I_GATE2_SEL:
		source = NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
		break;
	case NI_660X_UD_PIN_I_GATE2_SEL:
		source = NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT;
		break;
	case NI_660X_NEXT_SRC_GATE2_SEL:
		source = NI_GPCT_NEXT_SOURCE_GATE_SELECT;
		break;
	case NI_660X_NEXT_OUT_GATE2_SEL:
		source = NI_GPCT_NEXT_OUT_GATE_SELECT;
		break;
	case NI_660X_SELECTED_GATE2_SEL:
		source = NI_GPCT_SELECTED_GATE_GATE_SELECT;
		break;
	case NI_660X_LOGIC_LOW_GATE2_SEL:
		source = NI_GPCT_LOGIC_LOW_GATE_SELECT;
		break;
	default:
		for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
			if (gate == NI_660X_RTSI_GATE2_SEL(i)) {
				source = NI_GPCT_RTSI_GATE_SELECT(i);
				break;
			}
		}
		if (i <= NI_660X_MAX_RTSI_CHAN)
			break;
		for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
			if (gate == NI_660X_UD_PIN_GATE2_SEL(i)) {
				source = NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i);
				break;
			}
		}
		if (i <= NI_660X_MAX_UP_DOWN_PIN)
			break;
		return -EINVAL;
	}
	*src = source;
	return 0;
};

static int ni_m_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
{
	/*
	 * FIXME: the second gate sources for the m series are undocumented,
	 * so we just return the raw bits for now.
	 */
	*src = gate;
	return 0;
};

static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index,
			       unsigned int *gate_source)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;
	unsigned int mode;
	unsigned int reg;
	unsigned int gate;
	int ret;

	mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx));
	if (((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) ||
	    (gate_index == 1 &&
	     !(counter_dev->regs[NITIO_GATE2_REG(cidx)] & GI_GATE2_MODE))) {
		*gate_source = NI_GPCT_DISABLED_GATE_SELECT;
		return 0;
	}

	switch (gate_index) {
	case 0:
		reg = NITIO_INPUT_SEL_REG(cidx);
		gate = GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter, reg));

		switch (counter_dev->variant) {
		case ni_gpct_variant_e_series:
		case ni_gpct_variant_m_series:
		default:
			ret = ni_m_gate_to_generic_gate(gate, gate_source);
			break;
		case ni_gpct_variant_660x:
			ret = ni_660x_gate_to_generic_gate(gate, gate_source);
			break;
		}
		if (ret)
			return ret;
		if (mode & GI_GATE_POL_INVERT)
			*gate_source |= CR_INVERT;
		if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
			*gate_source |= CR_EDGE;
		break;
	case 1:
		reg = NITIO_GATE2_REG(cidx);
		gate = GI_BITS_TO_GATE2(counter_dev->regs[reg]);

		switch (counter_dev->variant) {
		case ni_gpct_variant_e_series:
		case ni_gpct_variant_m_series:
		default:
			ret = ni_m_gate2_to_generic_gate(gate, gate_source);
			break;
		case ni_gpct_variant_660x:
			ret = ni_660x_gate2_to_generic_gate(gate, gate_source);
			break;
		}
		if (ret)
			return ret;
		if (counter_dev->regs[reg] & GI_GATE2_POL_INVERT)
			*gate_source |= CR_INVERT;
		/* second gate can't have edge/level mode set independently */
		if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
			*gate_source |= CR_EDGE;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

int ni_tio_insn_config(struct comedi_device *dev,
		       struct comedi_subdevice *s,
		       struct comedi_insn *insn,
		       unsigned int *data)
{
	struct ni_gpct *counter = s->private;
	unsigned int cidx = counter->counter_index;
	unsigned int status;
	int ret = 0;

	switch (data[0]) {
	case INSN_CONFIG_SET_COUNTER_MODE:
		ret = ni_tio_set_counter_mode(counter, data[1]);
		break;
	case INSN_CONFIG_ARM:
		ret = ni_tio_arm(counter, true, data[1]);
		break;
	case INSN_CONFIG_DISARM:
		ret = ni_tio_arm(counter, false, 0);
		break;
	case INSN_CONFIG_GET_COUNTER_STATUS:
		data[1] = 0;
		status = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx));
		if (status & GI_ARMED(cidx)) {
			data[1] |= COMEDI_COUNTER_ARMED;
			if (status & GI_COUNTING(cidx))
				data[1] |= COMEDI_COUNTER_COUNTING;
		}
		data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
		break;
	case INSN_CONFIG_SET_CLOCK_SRC:
		ret = ni_tio_set_clock_src(counter, data[1], data[2]);
		break;
	case INSN_CONFIG_GET_CLOCK_SRC:
		ret = ni_tio_get_clock_src(counter, &data[1], &data[2]);
		break;
	case INSN_CONFIG_SET_GATE_SRC:
		ret = ni_tio_set_gate_src(counter, data[1], data[2]);
		break;
	case INSN_CONFIG_GET_GATE_SRC:
		ret = ni_tio_get_gate_src(counter, data[1], &data[2]);
		break;
	case INSN_CONFIG_SET_OTHER_SRC:
		ret = ni_tio_set_other_src(counter, data[1], data[2]);
		break;
	case INSN_CONFIG_RESET:
		ni_tio_reset_count_and_disarm(counter);
		break;
	default:
		return -EINVAL;
	}
	return ret ? ret : insn->n;
}
EXPORT_SYMBOL_GPL(ni_tio_insn_config);

static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev,
					    struct comedi_subdevice *s)
{
	struct ni_gpct *counter = s->private;
	unsigned int cidx = counter->counter_index;
	unsigned int val;

	ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0);
	ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
			GI_SAVE_TRACE, GI_SAVE_TRACE);

	/*
	 * The count doesn't get latched until the next clock edge, so it is
	 * possible the count may change (once) while we are reading. Since
	 * the read of the SW_Save_Reg isn't atomic (apparently even when it's
	 * a 32 bit register according to 660x docs), we need to read twice
	 * and make sure the reading hasn't changed. If it has, a third read
	 * will be correct since the count value will definitely have latched
	 * by then.
	 */
	val = ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx));
	if (val != ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx)))
		val = ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx));

	return val;
}

int ni_tio_insn_read(struct comedi_device *dev,
		     struct comedi_subdevice *s,
		     struct comedi_insn *insn,
		     unsigned int *data)
{
	struct ni_gpct *counter = s->private;
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int channel = CR_CHAN(insn->chanspec);
	unsigned int cidx = counter->counter_index;
	int i;

	for (i = 0; i < insn->n; i++) {
		switch (channel) {
		case 0:
			data[i] = ni_tio_read_sw_save_reg(dev, s);
			break;
		case 1:
			data[i] = counter_dev->regs[NITIO_LOADA_REG(cidx)];
			break;
		case 2:
			data[i] = counter_dev->regs[NITIO_LOADB_REG(cidx)];
			break;
		}
	}
	return insn->n;
}
EXPORT_SYMBOL_GPL(ni_tio_insn_read);

static unsigned int ni_tio_next_load_register(struct ni_gpct *counter)
{
	unsigned int cidx = counter->counter_index;
	unsigned int bits = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx));

	return (bits & GI_NEXT_LOAD_SRC(cidx))
			? NITIO_LOADB_REG(cidx)
			: NITIO_LOADA_REG(cidx);
}

int ni_tio_insn_write(struct comedi_device *dev,
		      struct comedi_subdevice *s,
		      struct comedi_insn *insn,
		      unsigned int *data)
{
	struct ni_gpct *counter = s->private;
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int channel = CR_CHAN(insn->chanspec);
	unsigned int cidx = counter->counter_index;
	unsigned int load_reg;

	if (insn->n < 1)
		return 0;
	switch (channel) {
	case 0:
		/*
		 * Unsafe if counter is armed.
		 * Should probably check status and return -EBUSY if armed.
		 */

		/*
		 * Don't disturb load source select, just use whichever
		 * load register is already selected.
		 */
		load_reg = ni_tio_next_load_register(counter);
		ni_tio_write(counter, data[0], load_reg);
		ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
					  0, 0, GI_LOAD);
		/* restore load reg */
		ni_tio_write(counter, counter_dev->regs[load_reg], load_reg);
		break;
	case 1:
		counter_dev->regs[NITIO_LOADA_REG(cidx)] = data[0];
		ni_tio_write(counter, data[0], NITIO_LOADA_REG(cidx));
		break;
	case 2:
		counter_dev->regs[NITIO_LOADB_REG(cidx)] = data[0];
		ni_tio_write(counter, data[0], NITIO_LOADB_REG(cidx));
		break;
	default:
		return -EINVAL;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_insn_write);

void ni_tio_init_counter(struct ni_gpct *counter)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned int cidx = counter->counter_index;

	ni_tio_reset_count_and_disarm(counter);

	/* initialize counter registers */
	counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0;
	ni_tio_write(counter, 0x0, NITIO_AUTO_INC_REG(cidx));

	ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
			~0, GI_SYNC_GATE);

	ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0);

	counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0;
	ni_tio_write(counter, 0x0, NITIO_LOADA_REG(cidx));

	counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0;
	ni_tio_write(counter, 0x0, NITIO_LOADB_REG(cidx));

	ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0);

	if (ni_tio_counting_mode_registers_present(counter_dev))
		ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0);

	if (ni_tio_has_gate2_registers(counter_dev)) {
		counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0;
		ni_tio_write(counter, 0x0, NITIO_GATE2_REG(cidx));
	}

	ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0);

	ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0);
}
EXPORT_SYMBOL_GPL(ni_tio_init_counter);

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)
{
	struct ni_gpct_device *counter_dev;
	struct ni_gpct *counter;
	unsigned int i;

	if (num_counters == 0)
		return NULL;

	counter_dev = kzalloc(sizeof(*counter_dev), GFP_KERNEL);
	if (!counter_dev)
		return NULL;

	counter_dev->dev = dev;
	counter_dev->write = write;
	counter_dev->read = read;
	counter_dev->variant = variant;

	spin_lock_init(&counter_dev->regs_lock);

	counter_dev->counters = kcalloc(num_counters, sizeof(*counter),
					GFP_KERNEL);
	if (!counter_dev->counters) {
		kfree(counter_dev);
		return NULL;
	}

	for (i = 0; i < num_counters; ++i) {
		counter = &counter_dev->counters[i];
		counter->counter_dev = counter_dev;
		spin_lock_init(&counter->lock);
	}
	counter_dev->num_counters = num_counters;

	return counter_dev;
}
EXPORT_SYMBOL_GPL(ni_gpct_device_construct);

void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
{
	if (!counter_dev)
		return;
	kfree(counter_dev->counters);
	kfree(counter_dev);
}
EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);

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

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

MODULE_AUTHOR("Comedi <comedi@comedi.org>");
MODULE_DESCRIPTION("Comedi support for NI general-purpose counters");
MODULE_LICENSE("GPL");
