14b565793SJoe Hershberger /* 24b565793SJoe Hershberger * Freescale MPC83xx GPIO handling. 34b565793SJoe Hershberger * 44b565793SJoe Hershberger * See file CREDITS for list of people who contributed to this 54b565793SJoe Hershberger * project. 64b565793SJoe Hershberger * 74b565793SJoe Hershberger * This program is free software; you can redistribute it and/or 84b565793SJoe Hershberger * modify it under the terms of the GNU General Public License as 94b565793SJoe Hershberger * published by the Free Software Foundation; either version 2 of 104b565793SJoe Hershberger * the License, or (at your option) any later version. 114b565793SJoe Hershberger * 124b565793SJoe Hershberger * This program is distributed in the hope that it will be useful, 134b565793SJoe Hershberger * but WITHOUT ANY WARRANTY; without even the implied warranty of 144b565793SJoe Hershberger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 154b565793SJoe Hershberger * GNU General Public License for more details. 164b565793SJoe Hershberger * 174b565793SJoe Hershberger * You should have received a copy of the GNU General Public License 184b565793SJoe Hershberger * along with this program; if not, write to the Free Software 194b565793SJoe Hershberger * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 204b565793SJoe Hershberger * MA 02111-1307 USA 214b565793SJoe Hershberger */ 224b565793SJoe Hershberger 234b565793SJoe Hershberger #include <common.h> 244b565793SJoe Hershberger #include <mpc83xx.h> 254b565793SJoe Hershberger #include <asm/gpio.h> 264b565793SJoe Hershberger #include <asm/io.h> 274b565793SJoe Hershberger 284b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 294b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 0 304b565793SJoe Hershberger #endif 314b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 324b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 0 334b565793SJoe Hershberger #endif 344b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 354b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0 364b565793SJoe Hershberger #endif 374b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 384b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0 394b565793SJoe Hershberger #endif 404b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_0_INIT_VALUE 414b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_0_INIT_VALUE 0 424b565793SJoe Hershberger #endif 434b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_1_INIT_VALUE 444b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_1_INIT_VALUE 0 454b565793SJoe Hershberger #endif 464b565793SJoe Hershberger 474b565793SJoe Hershberger static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS]; 484b565793SJoe Hershberger 494b565793SJoe Hershberger /* 504b565793SJoe Hershberger * Generic_GPIO primitives. 514b565793SJoe Hershberger */ 524b565793SJoe Hershberger 534b565793SJoe Hershberger int gpio_request(unsigned gpio, const char *label) 544b565793SJoe Hershberger { 554b565793SJoe Hershberger if (gpio >= MAX_NUM_GPIOS) 564b565793SJoe Hershberger return -1; 574b565793SJoe Hershberger 584b565793SJoe Hershberger return 0; 594b565793SJoe Hershberger } 604b565793SJoe Hershberger 614b565793SJoe Hershberger int gpio_free(unsigned gpio) 624b565793SJoe Hershberger { 634b565793SJoe Hershberger /* Do not set to input */ 644b565793SJoe Hershberger return 0; 654b565793SJoe Hershberger } 664b565793SJoe Hershberger 674b565793SJoe Hershberger /* set GPIO pin 'gpio' as an input */ 684b565793SJoe Hershberger int gpio_direction_input(unsigned gpio) 694b565793SJoe Hershberger { 704b565793SJoe Hershberger immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 714b565793SJoe Hershberger unsigned int ctrlr; 724b565793SJoe Hershberger unsigned int line; 734b565793SJoe Hershberger unsigned int line_mask; 744b565793SJoe Hershberger 754b565793SJoe Hershberger /* 32-bits per controller */ 764b565793SJoe Hershberger ctrlr = gpio >> 5; 774b565793SJoe Hershberger line = gpio & (0x1F); 784b565793SJoe Hershberger 794b565793SJoe Hershberger /* Big endian */ 804b565793SJoe Hershberger line_mask = 1 << (31 - line); 814b565793SJoe Hershberger 824b565793SJoe Hershberger clrbits_be32(&im->gpio[ctrlr].dir, line_mask); 834b565793SJoe Hershberger 844b565793SJoe Hershberger return 0; 854b565793SJoe Hershberger } 864b565793SJoe Hershberger 874b565793SJoe Hershberger /* set GPIO pin 'gpio' as an output, with polarity 'value' */ 884b565793SJoe Hershberger int gpio_direction_output(unsigned gpio, int value) 894b565793SJoe Hershberger { 904b565793SJoe Hershberger immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 914b565793SJoe Hershberger unsigned int ctrlr; 924b565793SJoe Hershberger unsigned int line; 934b565793SJoe Hershberger unsigned int line_mask; 944b565793SJoe Hershberger 954b565793SJoe Hershberger if (value != 0 && value != 1) { 964b565793SJoe Hershberger printf("Error: Value parameter must be 0 or 1.\n"); 974b565793SJoe Hershberger return -1; 984b565793SJoe Hershberger } 994b565793SJoe Hershberger 1004b565793SJoe Hershberger gpio_set_value(gpio, value); 1014b565793SJoe Hershberger 1024b565793SJoe Hershberger /* 32-bits per controller */ 1034b565793SJoe Hershberger ctrlr = gpio >> 5; 1044b565793SJoe Hershberger line = gpio & (0x1F); 1054b565793SJoe Hershberger 1064b565793SJoe Hershberger /* Big endian */ 1074b565793SJoe Hershberger line_mask = 1 << (31 - line); 1084b565793SJoe Hershberger 1094b565793SJoe Hershberger /* Make the line output */ 1104b565793SJoe Hershberger setbits_be32(&im->gpio[ctrlr].dir, line_mask); 1114b565793SJoe Hershberger 1124b565793SJoe Hershberger return 0; 1134b565793SJoe Hershberger } 1144b565793SJoe Hershberger 1154b565793SJoe Hershberger /* read GPIO IN value of pin 'gpio' */ 1164b565793SJoe Hershberger int gpio_get_value(unsigned gpio) 1174b565793SJoe Hershberger { 1184b565793SJoe Hershberger immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 1194b565793SJoe Hershberger unsigned int ctrlr; 1204b565793SJoe Hershberger unsigned int line; 1214b565793SJoe Hershberger unsigned int line_mask; 1224b565793SJoe Hershberger 1234b565793SJoe Hershberger /* 32-bits per controller */ 1244b565793SJoe Hershberger ctrlr = gpio >> 5; 1254b565793SJoe Hershberger line = gpio & (0x1F); 1264b565793SJoe Hershberger 1274b565793SJoe Hershberger /* Big endian */ 1284b565793SJoe Hershberger line_mask = 1 << (31 - line); 1294b565793SJoe Hershberger 1304b565793SJoe Hershberger /* Read the value and mask off the bit */ 1314b565793SJoe Hershberger return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0; 1324b565793SJoe Hershberger } 1334b565793SJoe Hershberger 1344b565793SJoe Hershberger /* write GPIO OUT value to pin 'gpio' */ 1354b565793SJoe Hershberger int gpio_set_value(unsigned gpio, int value) 1364b565793SJoe Hershberger { 1374b565793SJoe Hershberger immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 1384b565793SJoe Hershberger unsigned int ctrlr; 1394b565793SJoe Hershberger unsigned int line; 1404b565793SJoe Hershberger unsigned int line_mask; 1414b565793SJoe Hershberger 1424b565793SJoe Hershberger if (value != 0 && value != 1) { 1434b565793SJoe Hershberger printf("Error: Value parameter must be 0 or 1.\n"); 1444b565793SJoe Hershberger return -1; 1454b565793SJoe Hershberger } 1464b565793SJoe Hershberger 1474b565793SJoe Hershberger /* 32-bits per controller */ 1484b565793SJoe Hershberger ctrlr = gpio >> 5; 1494b565793SJoe Hershberger line = gpio & (0x1F); 1504b565793SJoe Hershberger 1514b565793SJoe Hershberger /* Big endian */ 1524b565793SJoe Hershberger line_mask = 1 << (31 - line); 1534b565793SJoe Hershberger 1544b565793SJoe Hershberger /* Update the local output buffer soft copy */ 1554b565793SJoe Hershberger gpio_output_value[ctrlr] = 1564b565793SJoe Hershberger (gpio_output_value[ctrlr] & ~line_mask) | \ 1574b565793SJoe Hershberger (value ? line_mask : 0); 1584b565793SJoe Hershberger 1594b565793SJoe Hershberger /* Write the output */ 1604b565793SJoe Hershberger out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]); 1614b565793SJoe Hershberger 1624b565793SJoe Hershberger return 0; 1634b565793SJoe Hershberger } 1644b565793SJoe Hershberger 1654b565793SJoe Hershberger /* Configure GPIO registers early */ 166*8121d3c5SKim Phillips void mpc83xx_gpio_init_f(void) 1674b565793SJoe Hershberger { 1684b565793SJoe Hershberger immap_t *im = (immap_t *)CONFIG_SYS_IMMR; 1694b565793SJoe Hershberger 1704b565793SJoe Hershberger #if MPC83XX_GPIO_CTRLRS >= 1 1714b565793SJoe Hershberger out_be32(&im->gpio[0].dir, CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION); 1724b565793SJoe Hershberger out_be32(&im->gpio[0].odr, CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN); 1734b565793SJoe Hershberger out_be32(&im->gpio[0].dat, CONFIG_MPC83XX_GPIO_0_INIT_VALUE); 1744b565793SJoe Hershberger out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */ 1754b565793SJoe Hershberger out_be32(&im->gpio[0].imr, 0); 1764b565793SJoe Hershberger out_be32(&im->gpio[0].icr, 0); 1774b565793SJoe Hershberger #endif 1784b565793SJoe Hershberger 1794b565793SJoe Hershberger #if MPC83XX_GPIO_CTRLRS >= 2 1804b565793SJoe Hershberger out_be32(&im->gpio[1].dir, CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION); 1814b565793SJoe Hershberger out_be32(&im->gpio[1].odr, CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN); 1824b565793SJoe Hershberger out_be32(&im->gpio[1].dat, CONFIG_MPC83XX_GPIO_1_INIT_VALUE); 1834b565793SJoe Hershberger out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */ 1844b565793SJoe Hershberger out_be32(&im->gpio[1].imr, 0); 1854b565793SJoe Hershberger out_be32(&im->gpio[1].icr, 0); 1864b565793SJoe Hershberger #endif 1874b565793SJoe Hershberger } 1884b565793SJoe Hershberger 1894b565793SJoe Hershberger /* Initialize GPIO soft-copies */ 190*8121d3c5SKim Phillips void mpc83xx_gpio_init_r(void) 1914b565793SJoe Hershberger { 1924b565793SJoe Hershberger #if MPC83XX_GPIO_CTRLRS >= 1 1934b565793SJoe Hershberger gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE; 1944b565793SJoe Hershberger #endif 1954b565793SJoe Hershberger 1964b565793SJoe Hershberger #if MPC83XX_GPIO_CTRLRS >= 2 1974b565793SJoe Hershberger gpio_output_value[1] = CONFIG_MPC83XX_GPIO_1_INIT_VALUE; 1984b565793SJoe Hershberger #endif 1994b565793SJoe Hershberger } 200