/*
  comedi/drivers/ni_tiocmd.c
  Command 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.
*/

/*
Driver: ni_tiocmd
Description: National Instruments general purpose counters command support
Devices:
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: Fri, 11 Apr 2008 12:32:35 +0100
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 command support for NI's general purpose counters.
It was originally split out of ni_tio.c to stop the 'ni_tio'
module depending on the 'mite' module.

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 "comedi_fc.h"
#include "ni_tio_internal.h"
#include "mite.h"

static void ni_tio_configure_dma(struct ni_gpct *counter, short enable,
				 short read_not_write)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned cidx = counter->counter_index;
	unsigned input_select_bits = 0;

	if (enable) {
		if (read_not_write)
			input_select_bits |= Gi_Read_Acknowledges_Irq;
		else
			input_select_bits |= Gi_Write_Acknowledges_Irq;
	}
	ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
			Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq,
			input_select_bits);
	switch (counter_dev->variant) {
	case ni_gpct_variant_e_series:
		break;
	case ni_gpct_variant_m_series:
	case ni_gpct_variant_660x:
		{
			unsigned gi_dma_config_bits = 0;

			if (enable) {
				gi_dma_config_bits |= Gi_DMA_Enable_Bit;
				gi_dma_config_bits |= Gi_DMA_Int_Bit;
			}
			if (read_not_write == 0)
				gi_dma_config_bits |= Gi_DMA_Write_Bit;
			ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx),
					Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit |
					Gi_DMA_Write_Bit, gi_dma_config_bits);
		}
		break;
	}
}

static int ni_tio_input_inttrig(struct comedi_device *dev,
				struct comedi_subdevice *s,
				unsigned int trignum)
{
	unsigned long flags;
	int retval = 0;
	struct ni_gpct *counter = s->private;

	BUG_ON(counter == NULL);
	if (trignum != 0)
		return -EINVAL;

	spin_lock_irqsave(&counter->lock, flags);
	if (counter->mite_chan)
		mite_dma_arm(counter->mite_chan);
	else
		retval = -EIO;
	spin_unlock_irqrestore(&counter->lock, flags);
	if (retval < 0)
		return retval;
	retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
	s->async->inttrig = NULL;

	return retval;
}

static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async)
{
	struct ni_gpct_device *counter_dev = counter->counter_dev;
	unsigned cidx = counter->counter_index;
	struct comedi_cmd *cmd = &async->cmd;
	int retval = 0;

	/* write alloc the entire buffer */
	comedi_buf_write_alloc(async, async->prealloc_bufsz);
	counter->mite_chan->dir = COMEDI_INPUT;
	switch (counter_dev->variant) {
	case ni_gpct_variant_m_series:
	case ni_gpct_variant_660x:
		mite_prep_dma(counter->mite_chan, 32, 32);
		break;
	case ni_gpct_variant_e_series:
		mite_prep_dma(counter->mite_chan, 16, 32);
		break;
	default:
		BUG();
		break;
	}
	ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), Gi_Save_Trace_Bit, 0);
	ni_tio_configure_dma(counter, 1, 1);
	switch (cmd->start_src) {
	case TRIG_NOW:
		async->inttrig = NULL;
		mite_dma_arm(counter->mite_chan);
		retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
		break;
	case TRIG_INT:
		async->inttrig = &ni_tio_input_inttrig;
		break;
	case TRIG_EXT:
		async->inttrig = NULL;
		mite_dma_arm(counter->mite_chan);
		retval = ni_tio_arm(counter, 1, cmd->start_arg);
		break;
	case TRIG_OTHER:
		async->inttrig = NULL;
		mite_dma_arm(counter->mite_chan);
		break;
	default:
		BUG();
		break;
	}
	return retval;
}

static int ni_tio_output_cmd(struct ni_gpct *counter,
			     struct comedi_async *async)
{
	dev_err(counter->counter_dev->dev->class_dev,
		"output commands not yet implemented.\n");
	return -ENOTSUPP;

	counter->mite_chan->dir = COMEDI_OUTPUT;
	mite_prep_dma(counter->mite_chan, 32, 32);
	ni_tio_configure_dma(counter, 1, 0);
	mite_dma_arm(counter->mite_chan);
	return ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
}

static int ni_tio_cmd_setup(struct ni_gpct *counter, struct comedi_async *async)
{
	struct comedi_cmd *cmd = &async->cmd;
	unsigned cidx = counter->counter_index;
	int set_gate_source = 0;
	unsigned gate_source;
	int retval = 0;

	if (cmd->scan_begin_src == TRIG_EXT) {
		set_gate_source = 1;
		gate_source = cmd->scan_begin_arg;
	} else if (cmd->convert_src == TRIG_EXT) {
		set_gate_source = 1;
		gate_source = cmd->convert_arg;
	}
	if (set_gate_source)
		retval = ni_tio_set_gate_src(counter, 0, gate_source);
	if (cmd->flags & TRIG_WAKE_EOS) {
		ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx),
				Gi_Gate_Interrupt_Enable_Bit(cidx),
				Gi_Gate_Interrupt_Enable_Bit(cidx));
	}
	return retval;
}

int ni_tio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
	struct ni_gpct *counter = s->private;
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;
	int retval = 0;
	unsigned long flags;

	spin_lock_irqsave(&counter->lock, flags);
	if (counter->mite_chan == NULL) {
		dev_err(counter->counter_dev->dev->class_dev,
			"commands only supported with DMA.  ");
		dev_err(counter->counter_dev->dev->class_dev,
			"Interrupt-driven commands not yet implemented.\n");
		retval = -EIO;
	} else {
		retval = ni_tio_cmd_setup(counter, async);
		if (retval == 0) {
			if (cmd->flags & CMDF_WRITE)
				retval = ni_tio_output_cmd(counter, async);
			else
				retval = ni_tio_input_cmd(counter, async);
		}
	}
	spin_unlock_irqrestore(&counter->lock, flags);
	return retval;
}
EXPORT_SYMBOL_GPL(ni_tio_cmd);

int ni_tio_cmdtest(struct comedi_device *dev,
		   struct comedi_subdevice *s,
		   struct comedi_cmd *cmd)
{
	struct ni_gpct *counter = s->private;
	int err = 0;
	unsigned int sources;

	/* Step 1 : check if triggers are trivially valid */

	sources = TRIG_NOW | TRIG_INT | TRIG_OTHER;
	if (ni_tio_counting_mode_registers_present(counter->counter_dev))
		sources |= TRIG_EXT;
	err |= cfc_check_trigger_src(&cmd->start_src, sources);

	err |= cfc_check_trigger_src(&cmd->scan_begin_src,
					TRIG_FOLLOW | TRIG_EXT | TRIG_OTHER);
	err |= cfc_check_trigger_src(&cmd->convert_src,
					TRIG_NOW | TRIG_EXT | TRIG_OTHER);
	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);

	if (err)
		return 1;

	/* Step 2a : make sure trigger sources are unique */

	err |= cfc_check_trigger_is_unique(cmd->start_src);
	err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
	err |= cfc_check_trigger_is_unique(cmd->convert_src);

	/* Step 2b : and mutually compatible */

	if (cmd->convert_src != TRIG_NOW && cmd->scan_begin_src != TRIG_FOLLOW)
		err |= -EINVAL;

	if (err)
		return 2;

	/* Step 3: check if arguments are trivially valid */

	if (cmd->start_src != TRIG_EXT)
		err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);

	if (cmd->scan_begin_src != TRIG_EXT)
		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);

	if (cmd->convert_src != TRIG_EXT)
		err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);

	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
	err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);

	if (err)
		return 3;

	/* step 4: fix up any arguments */

	if (err)
		return 4;

	return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_cmdtest);

int ni_tio_cancel(struct ni_gpct *counter)
{
	unsigned cidx = counter->counter_index;
	unsigned long flags;

	ni_tio_arm(counter, 0, 0);
	spin_lock_irqsave(&counter->lock, flags);
	if (counter->mite_chan)
		mite_dma_disarm(counter->mite_chan);
	spin_unlock_irqrestore(&counter->lock, flags);
	ni_tio_configure_dma(counter, 0, 0);

	ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx),
			Gi_Gate_Interrupt_Enable_Bit(cidx), 0x0);
	return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_cancel);

	/* During buffered input counter operation for e-series, the gate
	   interrupt is acked automatically by the dma controller, due to the
	   Gi_Read/Write_Acknowledges_IRQ bits in the input select register.  */
static int should_ack_gate(struct ni_gpct *counter)
{
	unsigned long flags;
	int retval = 0;

	switch (counter->counter_dev->variant) {
	case ni_gpct_variant_m_series:
	/*  not sure if 660x really supports gate
	    interrupts (the bits are not listed
	    in register-level manual) */
	case ni_gpct_variant_660x:
		return 1;
		break;
	case ni_gpct_variant_e_series:
		spin_lock_irqsave(&counter->lock, flags);
		{
			if (counter->mite_chan == NULL ||
			    counter->mite_chan->dir != COMEDI_INPUT ||
			    (mite_done(counter->mite_chan))) {
				retval = 1;
			}
		}
		spin_unlock_irqrestore(&counter->lock, flags);
		break;
	}
	return retval;
}

void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
				    int *tc_error, int *perm_stale_data,
				    int *stale_data)
{
	unsigned cidx = counter->counter_index;
	const unsigned short gxx_status = read_register(counter,
						NITIO_SHARED_STATUS_REG(cidx));
	const unsigned short gi_status = read_register(counter,
						NITIO_STATUS_REG(cidx));
	unsigned ack = 0;

	if (gate_error)
		*gate_error = 0;
	if (tc_error)
		*tc_error = 0;
	if (perm_stale_data)
		*perm_stale_data = 0;
	if (stale_data)
		*stale_data = 0;

	if (gxx_status & Gi_Gate_Error_Bit(cidx)) {
		ack |= Gi_Gate_Error_Confirm_Bit(cidx);
		if (gate_error) {
			/*660x don't support automatic acknowledgement
			  of gate interrupt via dma read/write
			   and report bogus gate errors */
			if (counter->counter_dev->variant !=
			    ni_gpct_variant_660x) {
				*gate_error = 1;
			}
		}
	}
	if (gxx_status & Gi_TC_Error_Bit(cidx)) {
		ack |= Gi_TC_Error_Confirm_Bit(cidx);
		if (tc_error)
			*tc_error = 1;
	}
	if (gi_status & Gi_TC_Bit)
		ack |= Gi_TC_Interrupt_Ack_Bit;
	if (gi_status & Gi_Gate_Interrupt_Bit) {
		if (should_ack_gate(counter))
			ack |= Gi_Gate_Interrupt_Ack_Bit;
	}
	if (ack)
		write_register(counter, ack, NITIO_INT_ACK_REG(cidx));
	if (ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)) &
	    Gi_Loading_On_Gate_Bit) {
		if (gxx_status & Gi_Stale_Data_Bit(cidx)) {
			if (stale_data)
				*stale_data = 1;
		}
		if (read_register(counter, NITIO_STATUS2_REG(cidx)) &
		    Gi_Permanent_Stale_Bit(cidx)) {
			dev_info(counter->counter_dev->dev->class_dev,
				 "%s: Gi_Permanent_Stale_Data detected.\n",
				 __func__);
			if (perm_stale_data)
				*perm_stale_data = 1;
		}
	}
}
EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm);

void ni_tio_handle_interrupt(struct ni_gpct *counter,
			     struct comedi_subdevice *s)
{
	unsigned cidx = counter->counter_index;
	unsigned gpct_mite_status;
	unsigned long flags;
	int gate_error;
	int tc_error;
	int perm_stale_data;

	ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error,
				       &perm_stale_data, NULL);
	if (gate_error) {
		dev_notice(counter->counter_dev->dev->class_dev,
			   "%s: Gi_Gate_Error detected.\n", __func__);
		s->async->events |= COMEDI_CB_OVERFLOW;
	}
	if (perm_stale_data)
		s->async->events |= COMEDI_CB_ERROR;
	switch (counter->counter_dev->variant) {
	case ni_gpct_variant_m_series:
	case ni_gpct_variant_660x:
		if (read_register(counter, NITIO_DMA_STATUS_REG(cidx)) &
		    Gi_DRQ_Error_Bit) {
			dev_notice(counter->counter_dev->dev->class_dev,
				   "%s: Gi_DRQ_Error detected.\n", __func__);
			s->async->events |= COMEDI_CB_OVERFLOW;
		}
		break;
	case ni_gpct_variant_e_series:
		break;
	}
	spin_lock_irqsave(&counter->lock, flags);
	if (counter->mite_chan == NULL) {
		spin_unlock_irqrestore(&counter->lock, flags);
		return;
	}
	gpct_mite_status = mite_get_status(counter->mite_chan);
	if (gpct_mite_status & CHSR_LINKC) {
		writel(CHOR_CLRLC,
		       counter->mite_chan->mite->mite_io_addr +
		       MITE_CHOR(counter->mite_chan->channel));
	}
	mite_sync_input_dma(counter->mite_chan, s->async);
	spin_unlock_irqrestore(&counter->lock, flags);
}
EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt);

void ni_tio_set_mite_channel(struct ni_gpct *counter,
			     struct mite_channel *mite_chan)
{
	unsigned long flags;

	spin_lock_irqsave(&counter->lock, flags);
	counter->mite_chan = mite_chan;
	spin_unlock_irqrestore(&counter->lock, flags);
}
EXPORT_SYMBOL_GPL(ni_tio_set_mite_channel);

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

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

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