1/* 2 * Helper functions for I/O pins. 3 * 4 * Copyright (c) 2004 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 <asm/arch/pinmux.h> 16#include <asm/arch/hwregs/gio_defs.h> 17 18struct crisv32_ioport crisv32_ioports[] = 19{ 20 { 21 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_oe), 22 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_dout), 23 (unsigned long*)REG_ADDR(gio, regi_gio, r_pa_din), 24 8 25 }, 26 { 27 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_oe), 28 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_dout), 29 (unsigned long*)REG_ADDR(gio, regi_gio, r_pb_din), 30 18 31 }, 32 { 33 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_oe), 34 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_dout), 35 (unsigned long*)REG_ADDR(gio, regi_gio, r_pc_din), 36 18 37 }, 38 { 39 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_oe), 40 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_dout), 41 (unsigned long*)REG_ADDR(gio, regi_gio, r_pd_din), 42 18 43 }, 44 { 45 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_oe), 46 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_dout), 47 (unsigned long*)REG_ADDR(gio, regi_gio, r_pe_din), 48 18 49 } 50}; 51 52#define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport) 53 54struct crisv32_iopin crisv32_led1_green; 55struct crisv32_iopin crisv32_led1_red; 56struct crisv32_iopin crisv32_led2_green; 57struct crisv32_iopin crisv32_led2_red; 58struct crisv32_iopin crisv32_led3_green; 59struct crisv32_iopin crisv32_led3_red; 60 61/* Dummy port used when green LED and red LED is on the same bit */ 62static unsigned long io_dummy; 63static struct crisv32_ioport dummy_port = 64{ 65 &io_dummy, 66 &io_dummy, 67 &io_dummy, 68 18 69}; 70static struct crisv32_iopin dummy_led = 71{ 72 &dummy_port, 73 0 74}; 75 76static int __init crisv32_io_init(void) 77{ 78 int ret = 0; 79 /* Initialize LEDs */ 80 ret += crisv32_io_get_name(&crisv32_led1_green, CONFIG_ETRAX_LED1G); 81 ret += crisv32_io_get_name(&crisv32_led1_red, CONFIG_ETRAX_LED1R); 82 ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_LED2G); 83 ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_LED2R); 84 ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_LED3G); 85 ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_LED3R); 86 crisv32_io_set_dir(&crisv32_led1_green, crisv32_io_dir_out); 87 crisv32_io_set_dir(&crisv32_led1_red, crisv32_io_dir_out); 88 crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out); 89 crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out); 90 crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out); 91 crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out); 92 93 if (!strcmp(CONFIG_ETRAX_LED1G, CONFIG_ETRAX_LED1R)) 94 crisv32_led1_red = dummy_led; 95 if (!strcmp(CONFIG_ETRAX_LED2G, CONFIG_ETRAX_LED2R)) 96 crisv32_led2_red = dummy_led; 97 98 return ret; 99} 100 101__initcall(crisv32_io_init); 102 103int crisv32_io_get(struct crisv32_iopin* iopin, 104 unsigned int port, unsigned int pin) 105{ 106 if (port > NBR_OF_PORTS) 107 return -EINVAL; 108 if (port > crisv32_ioports[port].pin_count) 109 return -EINVAL; 110 111 iopin->bit = 1 << pin; 112 iopin->port = &crisv32_ioports[port]; 113 114 if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio)) 115 return -EIO; 116 117 return 0; 118} 119 120int crisv32_io_get_name(struct crisv32_iopin* iopin, 121 char* name) 122{ 123 int port; 124 int pin; 125 126 if (toupper(*name) == 'P') 127 name++; 128 129 if (toupper(*name) < 'A' || toupper(*name) > 'E') 130 return -EINVAL; 131 132 port = toupper(*name) - 'A'; 133 name++; 134 pin = simple_strtoul(name, NULL, 10); 135 136 if (pin < 0 || pin > crisv32_ioports[port].pin_count) 137 return -EINVAL; 138 139 iopin->bit = 1 << pin; 140 iopin->port = &crisv32_ioports[port]; 141 142 if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio)) 143 return -EIO; 144 145 return 0; 146} 147 148#ifdef CONFIG_PCI 149/* PCI I/O access stuff */ 150struct cris_io_operations* cris_iops = NULL; 151EXPORT_SYMBOL(cris_iops); 152#endif 153