|  | /* | 
|  | * Freescale MPC83xx GPIO handling. | 
|  | * | 
|  | * SPDX-License-Identifier:	GPL-2.0+ | 
|  | */ | 
|  |  | 
|  | #include <common.h> | 
|  | #include <mpc83xx.h> | 
|  | #include <asm/gpio.h> | 
|  | #include <asm/io.h> | 
|  |  | 
|  | #ifndef CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION | 
|  | #define CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 0 | 
|  | #endif | 
|  | #ifndef CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION | 
|  | #define CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 0 | 
|  | #endif | 
|  | #ifndef CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN | 
|  | #define CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0 | 
|  | #endif | 
|  | #ifndef CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN | 
|  | #define CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0 | 
|  | #endif | 
|  | #ifndef CONFIG_MPC83XX_GPIO_0_INIT_VALUE | 
|  | #define CONFIG_MPC83XX_GPIO_0_INIT_VALUE 0 | 
|  | #endif | 
|  | #ifndef CONFIG_MPC83XX_GPIO_1_INIT_VALUE | 
|  | #define CONFIG_MPC83XX_GPIO_1_INIT_VALUE 0 | 
|  | #endif | 
|  |  | 
|  | static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS]; | 
|  |  | 
|  | /* | 
|  | * Generic_GPIO primitives. | 
|  | */ | 
|  |  | 
|  | int gpio_request(unsigned gpio, const char *label) | 
|  | { | 
|  | if (gpio >= MAX_NUM_GPIOS) | 
|  | return -1; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int gpio_free(unsigned gpio) | 
|  | { | 
|  | /* Do not set to input */ | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* set GPIO pin 'gpio' as an input */ | 
|  | int gpio_direction_input(unsigned gpio) | 
|  | { | 
|  | immap_t *im = (immap_t *)CONFIG_SYS_IMMR; | 
|  | unsigned int ctrlr; | 
|  | unsigned int line; | 
|  | unsigned int line_mask; | 
|  |  | 
|  | /* 32-bits per controller */ | 
|  | ctrlr = gpio >> 5; | 
|  | line = gpio & (0x1F); | 
|  |  | 
|  | /* Big endian */ | 
|  | line_mask = 1 << (31 - line); | 
|  |  | 
|  | clrbits_be32(&im->gpio[ctrlr].dir, line_mask); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* set GPIO pin 'gpio' as an output, with polarity 'value' */ | 
|  | int gpio_direction_output(unsigned gpio, int value) | 
|  | { | 
|  | immap_t *im = (immap_t *)CONFIG_SYS_IMMR; | 
|  | unsigned int ctrlr; | 
|  | unsigned int line; | 
|  | unsigned int line_mask; | 
|  |  | 
|  | if (value != 0 && value != 1) { | 
|  | printf("Error: Value parameter must be 0 or 1.\n"); | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | gpio_set_value(gpio, value); | 
|  |  | 
|  | /* 32-bits per controller */ | 
|  | ctrlr = gpio >> 5; | 
|  | line = gpio & (0x1F); | 
|  |  | 
|  | /* Big endian */ | 
|  | line_mask = 1 << (31 - line); | 
|  |  | 
|  | /* Make the line output */ | 
|  | setbits_be32(&im->gpio[ctrlr].dir, line_mask); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* read GPIO IN value of pin 'gpio' */ | 
|  | int gpio_get_value(unsigned gpio) | 
|  | { | 
|  | immap_t *im = (immap_t *)CONFIG_SYS_IMMR; | 
|  | unsigned int ctrlr; | 
|  | unsigned int line; | 
|  | unsigned int line_mask; | 
|  |  | 
|  | /* 32-bits per controller */ | 
|  | ctrlr = gpio >> 5; | 
|  | line = gpio & (0x1F); | 
|  |  | 
|  | /* Big endian */ | 
|  | line_mask = 1 << (31 - line); | 
|  |  | 
|  | /* Read the value and mask off the bit */ | 
|  | return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0; | 
|  | } | 
|  |  | 
|  | /* write GPIO OUT value to pin 'gpio' */ | 
|  | int gpio_set_value(unsigned gpio, int value) | 
|  | { | 
|  | immap_t *im = (immap_t *)CONFIG_SYS_IMMR; | 
|  | unsigned int ctrlr; | 
|  | unsigned int line; | 
|  | unsigned int line_mask; | 
|  |  | 
|  | if (value != 0 && value != 1) { | 
|  | printf("Error: Value parameter must be 0 or 1.\n"); | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | /* 32-bits per controller */ | 
|  | ctrlr = gpio >> 5; | 
|  | line = gpio & (0x1F); | 
|  |  | 
|  | /* Big endian */ | 
|  | line_mask = 1 << (31 - line); | 
|  |  | 
|  | /* Update the local output buffer soft copy */ | 
|  | gpio_output_value[ctrlr] = | 
|  | (gpio_output_value[ctrlr] & ~line_mask) | \ | 
|  | (value ? line_mask : 0); | 
|  |  | 
|  | /* Write the output */ | 
|  | out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]); | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Configure GPIO registers early */ | 
|  | void mpc83xx_gpio_init_f(void) | 
|  | { | 
|  | immap_t *im = (immap_t *)CONFIG_SYS_IMMR; | 
|  |  | 
|  | #if MPC83XX_GPIO_CTRLRS >= 1 | 
|  | out_be32(&im->gpio[0].dir, CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION); | 
|  | out_be32(&im->gpio[0].odr, CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN); | 
|  | out_be32(&im->gpio[0].dat, CONFIG_MPC83XX_GPIO_0_INIT_VALUE); | 
|  | out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */ | 
|  | out_be32(&im->gpio[0].imr, 0); | 
|  | out_be32(&im->gpio[0].icr, 0); | 
|  | #endif | 
|  |  | 
|  | #if MPC83XX_GPIO_CTRLRS >= 2 | 
|  | out_be32(&im->gpio[1].dir, CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION); | 
|  | out_be32(&im->gpio[1].odr, CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN); | 
|  | out_be32(&im->gpio[1].dat, CONFIG_MPC83XX_GPIO_1_INIT_VALUE); | 
|  | out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */ | 
|  | out_be32(&im->gpio[1].imr, 0); | 
|  | out_be32(&im->gpio[1].icr, 0); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /* Initialize GPIO soft-copies */ | 
|  | void mpc83xx_gpio_init_r(void) | 
|  | { | 
|  | #if MPC83XX_GPIO_CTRLRS >= 1 | 
|  | gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE; | 
|  | #endif | 
|  |  | 
|  | #if MPC83XX_GPIO_CTRLRS >= 2 | 
|  | gpio_output_value[1] = CONFIG_MPC83XX_GPIO_1_INIT_VALUE; | 
|  | #endif | 
|  | } |