/*
 * Helper functions for I/O pins.
 *
 * Copyright (c) 2005-2007 Axis Communications AB.
 */

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/io.h>
#include <mach/pinmux.h>
#include <hwregs/gio_defs.h>

struct crisv32_ioport crisv32_ioports[] = {
	{
		(unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_oe),
		(unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_dout),
		(unsigned long *)REG_ADDR(gio, regi_gio, r_pa_din),
		32
	},
	{
		(unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_oe),
		(unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_dout),
		(unsigned long *)REG_ADDR(gio, regi_gio, r_pb_din),
		32
	},
	{
		(unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_oe),
		(unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_dout),
		(unsigned long *)REG_ADDR(gio, regi_gio, r_pc_din),
		16
	},
};

#define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)

struct crisv32_iopin crisv32_led_net0_green;
struct crisv32_iopin crisv32_led_net0_red;
struct crisv32_iopin crisv32_led2_green;
struct crisv32_iopin crisv32_led2_red;
struct crisv32_iopin crisv32_led3_green;
struct crisv32_iopin crisv32_led3_red;

/* Dummy port used when green LED and red LED is on the same bit */
static unsigned long io_dummy;
static struct crisv32_ioport dummy_port = {
	&io_dummy,
	&io_dummy,
	&io_dummy,
	32
};
static struct crisv32_iopin dummy_led = {
	&dummy_port,
	0
};

static int __init crisv32_io_init(void)
{
	int ret = 0;

	u32 i;

	/* Locks *should* be dynamically initialized. */
	for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++)
		spin_lock_init(&crisv32_ioports[i].lock);
	spin_lock_init(&dummy_port.lock);

	/* Initialize LEDs */
#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO))
	ret += crisv32_io_get_name(&crisv32_led_net0_green,
		CONFIG_ETRAX_LED_G_NET0);
	crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out);
	if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) {
		ret += crisv32_io_get_name(&crisv32_led_net0_red,
			CONFIG_ETRAX_LED_R_NET0);
		crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out);
	} else
		crisv32_led_net0_red = dummy_led;
#endif

	ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_V32_LED2G);
	ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_V32_LED2R);
	ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_V32_LED3G);
	ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_V32_LED3R);

	crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
	crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
	crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
	crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);

	return ret;
}

__initcall(crisv32_io_init);

int crisv32_io_get(struct crisv32_iopin *iopin,
	unsigned int port, unsigned int pin)
{
	if (port > NBR_OF_PORTS)
		return -EINVAL;
	if (port > crisv32_ioports[port].pin_count)
		return -EINVAL;

	iopin->bit = 1 << pin;
	iopin->port = &crisv32_ioports[port];

	if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
		return -EIO;

	return 0;
}

int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name)
{
	int port;
	int pin;

	if (toupper(*name) == 'P')
		name++;

	if (toupper(*name) < 'A' || toupper(*name) > 'E')
		return -EINVAL;

	port = toupper(*name) - 'A';
	name++;
	pin = simple_strtoul(name, NULL, 10);

	if (pin < 0 || pin > crisv32_ioports[port].pin_count)
		return -EINVAL;

	iopin->bit = 1 << pin;
	iopin->port = &crisv32_ioports[port];

	if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
		return -EIO;

	return 0;
}

#ifdef CONFIG_PCI
/* PCI I/O access stuff */
struct cris_io_operations *cris_iops = NULL;
EXPORT_SYMBOL(cris_iops);
#endif

