/*
 * comedi_fc.c
 * This is a place for code driver writers wish to share between
 * two or more drivers.  fc is short for frank-common.
 *
 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
 * Copyright (C) 2002 Frank Mori Hess
 *
 * 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.
 */

#include <linux/module.h>
#include "../comedidev.h"

#include "comedi_fc.h"

unsigned int cfc_bytes_per_scan(struct comedi_subdevice *s)
{
	struct comedi_cmd *cmd = &s->async->cmd;
	unsigned int num_samples;
	unsigned int bits_per_sample;

	switch (s->type) {
	case COMEDI_SUBD_DI:
	case COMEDI_SUBD_DO:
	case COMEDI_SUBD_DIO:
		bits_per_sample = 8 * bytes_per_sample(s);
		num_samples = (cmd->chanlist_len + bits_per_sample - 1) /
				bits_per_sample;
		break;
	default:
		num_samples = cmd->chanlist_len;
		break;
	}
	return num_samples * bytes_per_sample(s);
}
EXPORT_SYMBOL_GPL(cfc_bytes_per_scan);

void cfc_inc_scan_progress(struct comedi_subdevice *s, unsigned int num_bytes)
{
	struct comedi_async *async = s->async;
	unsigned int scan_length = cfc_bytes_per_scan(s);

	async->scan_progress += num_bytes;
	if (async->scan_progress >= scan_length) {
		async->scan_progress %= scan_length;
		async->events |= COMEDI_CB_EOS;
	}
}
EXPORT_SYMBOL_GPL(cfc_inc_scan_progress);

/* Writes an array of data points to comedi's buffer */
unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *s,
				       void *data, unsigned int num_bytes)
{
	struct comedi_async *async = s->async;
	unsigned int retval;

	if (num_bytes == 0)
		return 0;

	retval = comedi_buf_write_alloc(s, num_bytes);
	if (retval != num_bytes) {
		dev_warn(s->device->class_dev, "buffer overrun\n");
		async->events |= COMEDI_CB_OVERFLOW;
		return 0;
	}

	comedi_buf_memcpy_to(s, 0, data, num_bytes);
	comedi_buf_write_free(s, num_bytes);
	cfc_inc_scan_progress(s, num_bytes);
	async->events |= COMEDI_CB_BLOCK;

	return num_bytes;
}
EXPORT_SYMBOL_GPL(cfc_write_array_to_buffer);

unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *s,
					void *data, unsigned int num_bytes)
{
	if (num_bytes == 0)
		return 0;

	num_bytes = comedi_buf_read_alloc(s, num_bytes);
	comedi_buf_memcpy_from(s, 0, data, num_bytes);
	comedi_buf_read_free(s, num_bytes);
	cfc_inc_scan_progress(s, num_bytes);
	s->async->events |= COMEDI_CB_BLOCK;

	return num_bytes;
}
EXPORT_SYMBOL_GPL(cfc_read_array_from_buffer);

unsigned int cfc_handle_events(struct comedi_device *dev,
			       struct comedi_subdevice *s)
{
	unsigned int events = s->async->events;

	if (events == 0)
		return events;

	if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
		s->cancel(dev, s);

	comedi_event(dev, s);

	return events;
}
EXPORT_SYMBOL_GPL(cfc_handle_events);

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

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

MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
MODULE_DESCRIPTION("Shared functions for Comedi low-level drivers");
MODULE_LICENSE("GPL");
