/**
 * @file me0600_optoi.c
 *
 * @brief ME-630 Optoisolated input subdevice instance.
 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
 * @author Guenter Gebhardt
 * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
 */

/*
 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
 *
 * This file 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef __KERNEL__
#  define __KERNEL__
#endif

/*
 * Includes
 */
#include <linux/module.h>

#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/types.h>

#include "medefines.h"
#include "meinternal.h"
#include "meerror.h"

#include "medebug.h"
#include "me0600_optoi_reg.h"
#include "me0600_optoi.h"

/*
 * Defines
 */

/*
 * Functions
 */

static int me0600_optoi_io_reset_subdevice(struct me_subdevice *subdevice,
					   struct file *filep, int flags)
{

	if (flags) {
		PERROR("Invalid flag specified.\n");
		return ME_ERRNO_INVALID_FLAGS;
	}

	PDEBUG("executed.\n");
	return ME_ERRNO_SUCCESS;
}

static int me0600_optoi_io_single_config(me_subdevice_t *subdevice,
					 struct file *filep,
					 int channel,
					 int single_config,
					 int ref,
					 int trig_chan,
					 int trig_type,
					 int trig_edge, int flags)
{
	me0600_optoi_subdevice_t *instance;
	int err = ME_ERRNO_SUCCESS;

	PDEBUG("executed.\n");

	instance = (me0600_optoi_subdevice_t *) subdevice;

	ME_SUBDEVICE_ENTER;

	spin_lock(&instance->subdevice_lock);

	switch (flags) {
	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
		if (channel == 0) {
			if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) {
				PERROR("Invalid port direction specified.\n");
				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
			}
		} else {
			PERROR("Invalid channel specified.\n");
			err = ME_ERRNO_INVALID_CHANNEL;
		}

		break;

	default:
		PERROR("Invalid flags specified.\n");

		err = ME_ERRNO_INVALID_FLAGS;

		break;
	}

	spin_unlock(&instance->subdevice_lock);

	ME_SUBDEVICE_EXIT;

	return err;
}

static int me0600_optoi_io_single_read(me_subdevice_t *subdevice,
				       struct file *filep,
				       int channel,
				       int *value, int time_out, int flags)
{
	me0600_optoi_subdevice_t *instance;
	int err = ME_ERRNO_SUCCESS;

	PDEBUG("executed.\n");

	instance = (me0600_optoi_subdevice_t *) subdevice;

	ME_SUBDEVICE_ENTER;

	spin_lock(&instance->subdevice_lock);

	switch (flags) {
	case ME_IO_SINGLE_TYPE_DIO_BIT:
		if ((channel >= 0) && (channel < 8)) {
			*value = inb(instance->port_reg) & (0x1 << channel);
		} else {
			PERROR("Invalid bit number specified.\n");
			err = ME_ERRNO_INVALID_CHANNEL;
		}

		break;

	case ME_IO_SINGLE_NO_FLAGS:
	case ME_IO_SINGLE_TYPE_DIO_BYTE:
		if (channel == 0) {
			*value = inb(instance->port_reg);
		} else {
			PERROR("Invalid byte number specified.\n");
			err = ME_ERRNO_INVALID_CHANNEL;
		}

		break;

	default:
		PERROR("Invalid flags specified.\n");

		err = ME_ERRNO_INVALID_FLAGS;
	}

	spin_unlock(&instance->subdevice_lock);

	ME_SUBDEVICE_EXIT;

	return err;
}

static int me0600_optoi_query_number_channels(me_subdevice_t *subdevice,
					      int *number)
{
	PDEBUG("executed.\n");
	*number = 8;
	return ME_ERRNO_SUCCESS;
}

static int me0600_optoi_query_subdevice_type(me_subdevice_t *subdevice,
					     int *type, int *subtype)
{
	PDEBUG("executed.\n");
	*type = ME_TYPE_DI;
	*subtype = ME_SUBTYPE_SINGLE;
	return ME_ERRNO_SUCCESS;
}

static int me0600_optoi_query_subdevice_caps(me_subdevice_t *subdevice,
					     int *caps)
{
	PDEBUG("executed.\n");
	*caps = 0;
	return ME_ERRNO_SUCCESS;
}

me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base)
{
	me0600_optoi_subdevice_t *subdevice;
	int err;

	PDEBUG("executed.\n");

	/* Allocate memory for subdevice instance */
	subdevice = kmalloc(sizeof(me0600_optoi_subdevice_t), GFP_KERNEL);

	if (!subdevice) {
		PERROR("Cannot get memory for subdevice instance.\n");
		return NULL;
	}

	memset(subdevice, 0, sizeof(me0600_optoi_subdevice_t));

	/* Initialize subdevice base class */
	err = me_subdevice_init(&subdevice->base);

	if (err) {
		PERROR("Cannot initialize subdevice base class instance.\n");
		kfree(subdevice);
		return NULL;
	}
	/* Initialize spin locks. */
	spin_lock_init(&subdevice->subdevice_lock);

	/* Save the subdevice index */
	subdevice->port_reg = reg_base + ME0600_OPTO_INPUT_REG;

	/* Overload base class methods. */
	subdevice->base.me_subdevice_io_reset_subdevice =
	    me0600_optoi_io_reset_subdevice;
	subdevice->base.me_subdevice_io_single_config =
	    me0600_optoi_io_single_config;
	subdevice->base.me_subdevice_io_single_read =
	    me0600_optoi_io_single_read;
	subdevice->base.me_subdevice_query_number_channels =
	    me0600_optoi_query_number_channels;
	subdevice->base.me_subdevice_query_subdevice_type =
	    me0600_optoi_query_subdevice_type;
	subdevice->base.me_subdevice_query_subdevice_caps =
	    me0600_optoi_query_subdevice_caps;

	return subdevice;
}
