1 /* 2 * Freescale MPC83xx GPIO handling. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <mpc83xx.h> 9 #include <asm/gpio.h> 10 #include <asm/io.h> 11 12 #ifndef CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 13 #define CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 0 14 #endif 15 #ifndef CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 16 #define CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 0 17 #endif 18 #ifndef CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 19 #define CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0 20 #endif 21 #ifndef CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 22 #define CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0 23 #endif 24 #ifndef CONFIG_MPC83XX_GPIO_0_INIT_VALUE 25 #define CONFIG_MPC83XX_GPIO_0_INIT_VALUE 0 26 #endif 27 #ifndef CONFIG_MPC83XX_GPIO_1_INIT_VALUE 28 #define CONFIG_MPC83XX_GPIO_1_INIT_VALUE 0 29 #endif 30 31 static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS]; 32 33 /* 34 * Generic_GPIO primitives. 35 */ 36 37 int gpio_request(unsigned gpio, const char *label) 38 { 39 if (gpio >= MAX_NUM_GPIOS) 40 return -1; 41 42 return 0; 43 } 44 45 int gpio_free(unsigned gpio) 46 { 47 /* Do not set to input */ 48 return 0; 49 } 50 51 /* set GPIO pin 'gpio' as an input */ 52 int gpio_direction_input(unsigned gpio) 53 { 54 immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 55 unsigned int ctrlr; 56 unsigned int line; 57 unsigned int line_mask; 58 59 /* 32-bits per controller */ 60 ctrlr = gpio >> 5; 61 line = gpio & (0x1F); 62 63 /* Big endian */ 64 line_mask = 1 << (31 - line); 65 66 clrbits_be32(&im->gpio[ctrlr].dir, line_mask); 67 68 return 0; 69 } 70 71 /* set GPIO pin 'gpio' as an output, with polarity 'value' */ 72 int gpio_direction_output(unsigned gpio, int value) 73 { 74 immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 75 unsigned int ctrlr; 76 unsigned int line; 77 unsigned int line_mask; 78 79 if (value != 0 && value != 1) { 80 printf("Error: Value parameter must be 0 or 1.\n"); 81 return -1; 82 } 83 84 gpio_set_value(gpio, value); 85 86 /* 32-bits per controller */ 87 ctrlr = gpio >> 5; 88 line = gpio & (0x1F); 89 90 /* Big endian */ 91 line_mask = 1 << (31 - line); 92 93 /* Make the line output */ 94 setbits_be32(&im->gpio[ctrlr].dir, line_mask); 95 96 return 0; 97 } 98 99 /* read GPIO IN value of pin 'gpio' */ 100 int gpio_get_value(unsigned gpio) 101 { 102 immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 103 unsigned int ctrlr; 104 unsigned int line; 105 unsigned int line_mask; 106 107 /* 32-bits per controller */ 108 ctrlr = gpio >> 5; 109 line = gpio & (0x1F); 110 111 /* Big endian */ 112 line_mask = 1 << (31 - line); 113 114 /* Read the value and mask off the bit */ 115 return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0; 116 } 117 118 /* write GPIO OUT value to pin 'gpio' */ 119 int gpio_set_value(unsigned gpio, int value) 120 { 121 immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 122 unsigned int ctrlr; 123 unsigned int line; 124 unsigned int line_mask; 125 126 if (value != 0 && value != 1) { 127 printf("Error: Value parameter must be 0 or 1.\n"); 128 return -1; 129 } 130 131 /* 32-bits per controller */ 132 ctrlr = gpio >> 5; 133 line = gpio & (0x1F); 134 135 /* Big endian */ 136 line_mask = 1 << (31 - line); 137 138 /* Update the local output buffer soft copy */ 139 gpio_output_value[ctrlr] = 140 (gpio_output_value[ctrlr] & ~line_mask) | \ 141 (value ? line_mask : 0); 142 143 /* Write the output */ 144 out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]); 145 146 return 0; 147 } 148 149 /* Configure GPIO registers early */ 150 void mpc83xx_gpio_init_f(void) 151 { 152 immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 153 154 #if MPC83XX_GPIO_CTRLRS >= 1 155 out_be32(&im->gpio[0].dir, CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION); 156 out_be32(&im->gpio[0].odr, CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN); 157 out_be32(&im->gpio[0].dat, CONFIG_MPC83XX_GPIO_0_INIT_VALUE); 158 out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */ 159 out_be32(&im->gpio[0].imr, 0); 160 out_be32(&im->gpio[0].icr, 0); 161 #endif 162 163 #if MPC83XX_GPIO_CTRLRS >= 2 164 out_be32(&im->gpio[1].dir, CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION); 165 out_be32(&im->gpio[1].odr, CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN); 166 out_be32(&im->gpio[1].dat, CONFIG_MPC83XX_GPIO_1_INIT_VALUE); 167 out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */ 168 out_be32(&im->gpio[1].imr, 0); 169 out_be32(&im->gpio[1].icr, 0); 170 #endif 171 } 172 173 /* Initialize GPIO soft-copies */ 174 void mpc83xx_gpio_init_r(void) 175 { 176 #if MPC83XX_GPIO_CTRLRS >= 1 177 gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE; 178 #endif 179 180 #if MPC83XX_GPIO_CTRLRS >= 2 181 gpio_output_value[1] = CONFIG_MPC83XX_GPIO_1_INIT_VALUE; 182 #endif 183 } 184