1/* 2 * Helper functions for I/O pins. 3 * 4 * Copyright (c) 2005-2007 Axis Communications AB. 5 */ 6 7#include <linux/types.h> 8#include <linux/errno.h> 9#include <linux/init.h> 10#include <linux/string.h> 11#include <linux/ctype.h> 12#include <linux/kernel.h> 13#include <linux/module.h> 14#include <asm/io.h> 15#include <mach/pinmux.h> 16#include <hwregs/gio_defs.h> 17 18struct crisv32_ioport crisv32_ioports[] = { 19 { 20 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_oe), 21 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pa_dout), 22 (unsigned long *)REG_ADDR(gio, regi_gio, r_pa_din), 23 32 24 }, 25 { 26 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_oe), 27 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pb_dout), 28 (unsigned long *)REG_ADDR(gio, regi_gio, r_pb_din), 29 32 30 }, 31 { 32 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_oe), 33 (unsigned long *)REG_ADDR(gio, regi_gio, rw_pc_dout), 34 (unsigned long *)REG_ADDR(gio, regi_gio, r_pc_din), 35 16 36 }, 37}; 38 39#define NBR_OF_PORTS ARRAY_SIZE(crisv32_ioports) 40 41struct crisv32_iopin crisv32_led_net0_green; 42struct crisv32_iopin crisv32_led_net0_red; 43struct crisv32_iopin crisv32_led2_green; 44struct crisv32_iopin crisv32_led2_red; 45struct crisv32_iopin crisv32_led3_green; 46struct crisv32_iopin crisv32_led3_red; 47 48/* Dummy port used when green LED and red LED is on the same bit */ 49static unsigned long io_dummy; 50static struct crisv32_ioport dummy_port = { 51 &io_dummy, 52 &io_dummy, 53 &io_dummy, 54 32 55}; 56static struct crisv32_iopin dummy_led = { 57 &dummy_port, 58 0 59}; 60 61static int __init crisv32_io_init(void) 62{ 63 int ret = 0; 64 65 u32 i; 66 67 /* Locks *should* be dynamically initialized. */ 68 for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++) 69 spin_lock_init(&crisv32_ioports[i].lock); 70 spin_lock_init(&dummy_port.lock); 71 72 /* Initialize LEDs */ 73#if (defined(CONFIG_ETRAX_NBR_LED_GRP_ONE) || defined(CONFIG_ETRAX_NBR_LED_GRP_TWO)) 74 ret += crisv32_io_get_name(&crisv32_led_net0_green, 75 CONFIG_ETRAX_LED_G_NET0); 76 crisv32_io_set_dir(&crisv32_led_net0_green, crisv32_io_dir_out); 77 if (strcmp(CONFIG_ETRAX_LED_G_NET0, CONFIG_ETRAX_LED_R_NET0)) { 78 ret += crisv32_io_get_name(&crisv32_led_net0_red, 79 CONFIG_ETRAX_LED_R_NET0); 80 crisv32_io_set_dir(&crisv32_led_net0_red, crisv32_io_dir_out); 81 } else 82 crisv32_led_net0_red = dummy_led; 83#endif 84 85 ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_V32_LED2G); 86 ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_V32_LED2R); 87 ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_V32_LED3G); 88 ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_V32_LED3R); 89 90 crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out); 91 crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out); 92 crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out); 93 crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out); 94 95 return ret; 96} 97 98__initcall(crisv32_io_init); 99 100int crisv32_io_get(struct crisv32_iopin *iopin, 101 unsigned int port, unsigned int pin) 102{ 103 if (port > NBR_OF_PORTS) 104 return -EINVAL; 105 if (port > crisv32_ioports[port].pin_count) 106 return -EINVAL; 107 108 iopin->bit = 1 << pin; 109 iopin->port = &crisv32_ioports[port]; 110 111 if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio)) 112 return -EIO; 113 114 return 0; 115} 116 117int crisv32_io_get_name(struct crisv32_iopin *iopin, const char *name) 118{ 119 int port; 120 int pin; 121 122 if (toupper(*name) == 'P') 123 name++; 124 125 if (toupper(*name) < 'A' || toupper(*name) > 'E') 126 return -EINVAL; 127 128 port = toupper(*name) - 'A'; 129 name++; 130 pin = simple_strtoul(name, NULL, 10); 131 132 if (pin < 0 || pin > crisv32_ioports[port].pin_count) 133 return -EINVAL; 134 135 iopin->bit = 1 << pin; 136 iopin->port = &crisv32_ioports[port]; 137 138 if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio)) 139 return -EIO; 140 141 return 0; 142} 143 144#ifdef CONFIG_PCI 145/* PCI I/O access stuff */ 146struct cris_io_operations *cris_iops = NULL; 147EXPORT_SYMBOL(cris_iops); 148#endif 149 150