/*
 * Coldfire generic GPIO support.
 *
 * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
 *
 * 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; version 2 of the License.
 *
 * 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/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>

#include <linux/io.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>

int __mcfgpio_get_value(unsigned gpio)
{
	return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio);
}
EXPORT_SYMBOL(__mcfgpio_get_value);

void __mcfgpio_set_value(unsigned gpio, int value)
{
	if (gpio < MCFGPIO_SCR_START) {
		unsigned long flags;
		MCFGPIO_PORTTYPE data;

		local_irq_save(flags);
		data = mcfgpio_read(__mcfgpio_podr(gpio));
		if (value)
			data |= mcfgpio_bit(gpio);
		else
			data &= ~mcfgpio_bit(gpio);
		mcfgpio_write(data, __mcfgpio_podr(gpio));
		local_irq_restore(flags);
	} else {
		if (value)
			mcfgpio_write(mcfgpio_bit(gpio),
					MCFGPIO_SETR_PORT(gpio));
		else
			mcfgpio_write(~mcfgpio_bit(gpio),
					MCFGPIO_CLRR_PORT(gpio));
	}
}
EXPORT_SYMBOL(__mcfgpio_set_value);

int __mcfgpio_direction_input(unsigned gpio)
{
	unsigned long flags;
	MCFGPIO_PORTTYPE dir;

	local_irq_save(flags);
	dir = mcfgpio_read(__mcfgpio_pddr(gpio));
	dir &= ~mcfgpio_bit(gpio);
	mcfgpio_write(dir, __mcfgpio_pddr(gpio));
	local_irq_restore(flags);

	return 0;
}
EXPORT_SYMBOL(__mcfgpio_direction_input);

int __mcfgpio_direction_output(unsigned gpio, int value)
{
	unsigned long flags;
	MCFGPIO_PORTTYPE data;

	local_irq_save(flags);
	data = mcfgpio_read(__mcfgpio_pddr(gpio));
	data |= mcfgpio_bit(gpio);
	mcfgpio_write(data, __mcfgpio_pddr(gpio));

	/* now set the data to output */
	if (gpio < MCFGPIO_SCR_START) {
		data = mcfgpio_read(__mcfgpio_podr(gpio));
		if (value)
			data |= mcfgpio_bit(gpio);
		else
			data &= ~mcfgpio_bit(gpio);
		mcfgpio_write(data, __mcfgpio_podr(gpio));
	} else {
		 if (value)
			mcfgpio_write(mcfgpio_bit(gpio),
					MCFGPIO_SETR_PORT(gpio));
		 else
			 mcfgpio_write(~mcfgpio_bit(gpio),
					 MCFGPIO_CLRR_PORT(gpio));
	}
	local_irq_restore(flags);
	return 0;
}
EXPORT_SYMBOL(__mcfgpio_direction_output);

int __mcfgpio_request(unsigned gpio)
{
	return 0;
}
EXPORT_SYMBOL(__mcfgpio_request);

void __mcfgpio_free(unsigned gpio)
{
	__mcfgpio_direction_input(gpio);
}
EXPORT_SYMBOL(__mcfgpio_free);

#ifdef CONFIG_GPIOLIB

static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
	return __mcfgpio_direction_input(offset);
}

static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset)
{
	return __mcfgpio_get_value(offset);
}

static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset,
				    int value)
{
	return __mcfgpio_direction_output(offset, value);
}

static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset,
			      int value)
{
	__mcfgpio_set_value(offset, value);
}

static int mcfgpio_request(struct gpio_chip *chip, unsigned offset)
{
	return __mcfgpio_request(offset);
}

static void mcfgpio_free(struct gpio_chip *chip, unsigned offset)
{
	__mcfgpio_free(offset);
}

static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
#if defined(MCFGPIO_IRQ_MIN)
	if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX))
#else
	if (offset < MCFGPIO_IRQ_MAX)
#endif
		return MCFGPIO_IRQ_VECBASE + offset;
	else
		return -EINVAL;
}

static struct bus_type mcfgpio_subsys = {
	.name		= "gpio",
	.dev_name	= "gpio",
};

static struct gpio_chip mcfgpio_chip = {
	.label			= "mcfgpio",
	.request		= mcfgpio_request,
	.free			= mcfgpio_free,
	.direction_input	= mcfgpio_direction_input,
	.direction_output	= mcfgpio_direction_output,
	.get			= mcfgpio_get_value,
	.set			= mcfgpio_set_value,
	.to_irq			= mcfgpio_to_irq,
	.base			= 0,
	.ngpio			= MCFGPIO_PIN_MAX,
};

static int __init mcfgpio_sysinit(void)
{
	gpiochip_add(&mcfgpio_chip);
	return subsys_system_register(&mcfgpio_subsys, NULL);
}

core_initcall(mcfgpio_sysinit);
#endif
