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