io.c 3.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * 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>
15
#include <mach/pinmux.h>
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
#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
	},
};

S
Stoyan Gaydarov 已提交
39
#define NBR_OF_PORTS ARRAY_SIZE(crisv32_ioports)
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

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;
}

117
int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name)
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
{
	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