1 /* 2 * Copyright (C) 2009 3 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> 4 * 5 * Copyright (C) 2011 6 * Stefano Babic, DENX Software Engineering, <sbabic@denx.de> 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 #include <common.h> 11 #include <asm/arch/imx-regs.h> 12 #include <asm/gpio.h> 13 #include <asm/io.h> 14 #include <errno.h> 15 16 enum mxc_gpio_direction { 17 MXC_GPIO_DIRECTION_IN, 18 MXC_GPIO_DIRECTION_OUT, 19 }; 20 21 #define GPIO_TO_PORT(n) (n / 32) 22 23 /* GPIO port description */ 24 static unsigned long gpio_ports[] = { 25 [0] = GPIO1_BASE_ADDR, 26 [1] = GPIO2_BASE_ADDR, 27 [2] = GPIO3_BASE_ADDR, 28 #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \ 29 defined(CONFIG_MX53) || defined(CONFIG_MX6) 30 [3] = GPIO4_BASE_ADDR, 31 #endif 32 #if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6) 33 [4] = GPIO5_BASE_ADDR, 34 [5] = GPIO6_BASE_ADDR, 35 #endif 36 #if defined(CONFIG_MX53) || defined(CONFIG_MX6) 37 [6] = GPIO7_BASE_ADDR, 38 #endif 39 }; 40 41 static int mxc_gpio_direction(unsigned int gpio, 42 enum mxc_gpio_direction direction) 43 { 44 unsigned int port = GPIO_TO_PORT(gpio); 45 struct gpio_regs *regs; 46 u32 l; 47 48 if (port >= ARRAY_SIZE(gpio_ports)) 49 return -1; 50 51 gpio &= 0x1f; 52 53 regs = (struct gpio_regs *)gpio_ports[port]; 54 55 l = readl(®s->gpio_dir); 56 57 switch (direction) { 58 case MXC_GPIO_DIRECTION_OUT: 59 l |= 1 << gpio; 60 break; 61 case MXC_GPIO_DIRECTION_IN: 62 l &= ~(1 << gpio); 63 } 64 writel(l, ®s->gpio_dir); 65 66 return 0; 67 } 68 69 int gpio_set_value(unsigned gpio, int value) 70 { 71 unsigned int port = GPIO_TO_PORT(gpio); 72 struct gpio_regs *regs; 73 u32 l; 74 75 if (port >= ARRAY_SIZE(gpio_ports)) 76 return -1; 77 78 gpio &= 0x1f; 79 80 regs = (struct gpio_regs *)gpio_ports[port]; 81 82 l = readl(®s->gpio_dr); 83 if (value) 84 l |= 1 << gpio; 85 else 86 l &= ~(1 << gpio); 87 writel(l, ®s->gpio_dr); 88 89 return 0; 90 } 91 92 int gpio_get_value(unsigned gpio) 93 { 94 unsigned int port = GPIO_TO_PORT(gpio); 95 struct gpio_regs *regs; 96 u32 val; 97 98 if (port >= ARRAY_SIZE(gpio_ports)) 99 return -1; 100 101 gpio &= 0x1f; 102 103 regs = (struct gpio_regs *)gpio_ports[port]; 104 105 val = (readl(®s->gpio_psr) >> gpio) & 0x01; 106 107 return val; 108 } 109 110 int gpio_request(unsigned gpio, const char *label) 111 { 112 unsigned int port = GPIO_TO_PORT(gpio); 113 if (port >= ARRAY_SIZE(gpio_ports)) 114 return -1; 115 return 0; 116 } 117 118 int gpio_free(unsigned gpio) 119 { 120 return 0; 121 } 122 123 int gpio_direction_input(unsigned gpio) 124 { 125 return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_IN); 126 } 127 128 int gpio_direction_output(unsigned gpio, int value) 129 { 130 int ret = gpio_set_value(gpio, value); 131 132 if (ret < 0) 133 return ret; 134 135 return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_OUT); 136 } 137