/* * Freescale MPC83xx GPIO handling. * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #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 }