xref: /rk3399_rockchip-uboot/drivers/gpio/mpc83xx_gpio.c (revision 8121d3c5ccc2cb552ddcf7eba7be5e1196232e1c)
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