/* * Freescale MPC83xx GPIO handling. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #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() { 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() { #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 }