xref: /rk3399_rockchip-uboot/drivers/gpio/mpc83xx_gpio.c (revision 326ea986ac150acdc7656d57fca647db80b50158)
14b565793SJoe Hershberger /*
24b565793SJoe Hershberger  * Freescale MPC83xx GPIO handling.
34b565793SJoe Hershberger  *
4*1a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
54b565793SJoe Hershberger  */
64b565793SJoe Hershberger 
74b565793SJoe Hershberger #include <common.h>
84b565793SJoe Hershberger #include <mpc83xx.h>
94b565793SJoe Hershberger #include <asm/gpio.h>
104b565793SJoe Hershberger #include <asm/io.h>
114b565793SJoe Hershberger 
124b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION
134b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION 0
144b565793SJoe Hershberger #endif
154b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION
164b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION 0
174b565793SJoe Hershberger #endif
184b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN
194b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0
204b565793SJoe Hershberger #endif
214b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN
224b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0
234b565793SJoe Hershberger #endif
244b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_0_INIT_VALUE
254b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_0_INIT_VALUE 0
264b565793SJoe Hershberger #endif
274b565793SJoe Hershberger #ifndef CONFIG_MPC83XX_GPIO_1_INIT_VALUE
284b565793SJoe Hershberger #define CONFIG_MPC83XX_GPIO_1_INIT_VALUE 0
294b565793SJoe Hershberger #endif
304b565793SJoe Hershberger 
314b565793SJoe Hershberger static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS];
324b565793SJoe Hershberger 
334b565793SJoe Hershberger /*
344b565793SJoe Hershberger  * Generic_GPIO primitives.
354b565793SJoe Hershberger  */
364b565793SJoe Hershberger 
gpio_request(unsigned gpio,const char * label)374b565793SJoe Hershberger int gpio_request(unsigned gpio, const char *label)
384b565793SJoe Hershberger {
394b565793SJoe Hershberger 	if (gpio >= MAX_NUM_GPIOS)
404b565793SJoe Hershberger 		return -1;
414b565793SJoe Hershberger 
424b565793SJoe Hershberger 	return 0;
434b565793SJoe Hershberger }
444b565793SJoe Hershberger 
gpio_free(unsigned gpio)454b565793SJoe Hershberger int gpio_free(unsigned gpio)
464b565793SJoe Hershberger {
474b565793SJoe Hershberger 	/* Do not set to input */
484b565793SJoe Hershberger 	return 0;
494b565793SJoe Hershberger }
504b565793SJoe Hershberger 
514b565793SJoe Hershberger /* set GPIO pin 'gpio' as an input */
gpio_direction_input(unsigned gpio)524b565793SJoe Hershberger int gpio_direction_input(unsigned gpio)
534b565793SJoe Hershberger {
544b565793SJoe Hershberger 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
554b565793SJoe Hershberger 	unsigned int ctrlr;
564b565793SJoe Hershberger 	unsigned int line;
574b565793SJoe Hershberger 	unsigned int line_mask;
584b565793SJoe Hershberger 
594b565793SJoe Hershberger 	/* 32-bits per controller */
604b565793SJoe Hershberger 	ctrlr = gpio >> 5;
614b565793SJoe Hershberger 	line = gpio & (0x1F);
624b565793SJoe Hershberger 
634b565793SJoe Hershberger 	/* Big endian */
644b565793SJoe Hershberger 	line_mask = 1 << (31 - line);
654b565793SJoe Hershberger 
664b565793SJoe Hershberger 	clrbits_be32(&im->gpio[ctrlr].dir, line_mask);
674b565793SJoe Hershberger 
684b565793SJoe Hershberger 	return 0;
694b565793SJoe Hershberger }
704b565793SJoe Hershberger 
714b565793SJoe Hershberger /* set GPIO pin 'gpio' as an output, with polarity 'value' */
gpio_direction_output(unsigned gpio,int value)724b565793SJoe Hershberger int gpio_direction_output(unsigned gpio, int value)
734b565793SJoe Hershberger {
744b565793SJoe Hershberger 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
754b565793SJoe Hershberger 	unsigned int ctrlr;
764b565793SJoe Hershberger 	unsigned int line;
774b565793SJoe Hershberger 	unsigned int line_mask;
784b565793SJoe Hershberger 
794b565793SJoe Hershberger 	if (value != 0 && value != 1) {
804b565793SJoe Hershberger 		printf("Error: Value parameter must be 0 or 1.\n");
814b565793SJoe Hershberger 		return -1;
824b565793SJoe Hershberger 	}
834b565793SJoe Hershberger 
844b565793SJoe Hershberger 	gpio_set_value(gpio, value);
854b565793SJoe Hershberger 
864b565793SJoe Hershberger 	/* 32-bits per controller */
874b565793SJoe Hershberger 	ctrlr = gpio >> 5;
884b565793SJoe Hershberger 	line = gpio & (0x1F);
894b565793SJoe Hershberger 
904b565793SJoe Hershberger 	/* Big endian */
914b565793SJoe Hershberger 	line_mask = 1 << (31 - line);
924b565793SJoe Hershberger 
934b565793SJoe Hershberger 	/* Make the line output */
944b565793SJoe Hershberger 	setbits_be32(&im->gpio[ctrlr].dir, line_mask);
954b565793SJoe Hershberger 
964b565793SJoe Hershberger 	return 0;
974b565793SJoe Hershberger }
984b565793SJoe Hershberger 
994b565793SJoe Hershberger /* read GPIO IN value of pin 'gpio' */
gpio_get_value(unsigned gpio)1004b565793SJoe Hershberger int gpio_get_value(unsigned gpio)
1014b565793SJoe Hershberger {
1024b565793SJoe Hershberger 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
1034b565793SJoe Hershberger 	unsigned int ctrlr;
1044b565793SJoe Hershberger 	unsigned int line;
1054b565793SJoe Hershberger 	unsigned int line_mask;
1064b565793SJoe Hershberger 
1074b565793SJoe Hershberger 	/* 32-bits per controller */
1084b565793SJoe Hershberger 	ctrlr = gpio >> 5;
1094b565793SJoe Hershberger 	line = gpio & (0x1F);
1104b565793SJoe Hershberger 
1114b565793SJoe Hershberger 	/* Big endian */
1124b565793SJoe Hershberger 	line_mask = 1 << (31 - line);
1134b565793SJoe Hershberger 
1144b565793SJoe Hershberger 	/* Read the value and mask off the bit */
1154b565793SJoe Hershberger 	return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0;
1164b565793SJoe Hershberger }
1174b565793SJoe Hershberger 
1184b565793SJoe Hershberger /* write GPIO OUT value to pin 'gpio' */
gpio_set_value(unsigned gpio,int value)1194b565793SJoe Hershberger int gpio_set_value(unsigned gpio, int value)
1204b565793SJoe Hershberger {
1214b565793SJoe Hershberger 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
1224b565793SJoe Hershberger 	unsigned int ctrlr;
1234b565793SJoe Hershberger 	unsigned int line;
1244b565793SJoe Hershberger 	unsigned int line_mask;
1254b565793SJoe Hershberger 
1264b565793SJoe Hershberger 	if (value != 0 && value != 1) {
1274b565793SJoe Hershberger 		printf("Error: Value parameter must be 0 or 1.\n");
1284b565793SJoe Hershberger 		return -1;
1294b565793SJoe Hershberger 	}
1304b565793SJoe Hershberger 
1314b565793SJoe Hershberger 	/* 32-bits per controller */
1324b565793SJoe Hershberger 	ctrlr = gpio >> 5;
1334b565793SJoe Hershberger 	line = gpio & (0x1F);
1344b565793SJoe Hershberger 
1354b565793SJoe Hershberger 	/* Big endian */
1364b565793SJoe Hershberger 	line_mask = 1 << (31 - line);
1374b565793SJoe Hershberger 
1384b565793SJoe Hershberger 	/* Update the local output buffer soft copy */
1394b565793SJoe Hershberger 	gpio_output_value[ctrlr] =
1404b565793SJoe Hershberger 		(gpio_output_value[ctrlr] & ~line_mask) | \
1414b565793SJoe Hershberger 			(value ? line_mask : 0);
1424b565793SJoe Hershberger 
1434b565793SJoe Hershberger 	/* Write the output */
1444b565793SJoe Hershberger 	out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]);
1454b565793SJoe Hershberger 
1464b565793SJoe Hershberger 	return 0;
1474b565793SJoe Hershberger }
1484b565793SJoe Hershberger 
1494b565793SJoe Hershberger /* Configure GPIO registers early */
mpc83xx_gpio_init_f(void)1508121d3c5SKim Phillips void mpc83xx_gpio_init_f(void)
1514b565793SJoe Hershberger {
1524b565793SJoe Hershberger 	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
1534b565793SJoe Hershberger 
1544b565793SJoe Hershberger #if MPC83XX_GPIO_CTRLRS >= 1
1554b565793SJoe Hershberger 	out_be32(&im->gpio[0].dir, CONFIG_MPC83XX_GPIO_0_INIT_DIRECTION);
1564b565793SJoe Hershberger 	out_be32(&im->gpio[0].odr, CONFIG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN);
1574b565793SJoe Hershberger 	out_be32(&im->gpio[0].dat, CONFIG_MPC83XX_GPIO_0_INIT_VALUE);
1584b565793SJoe Hershberger 	out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */
1594b565793SJoe Hershberger 	out_be32(&im->gpio[0].imr, 0);
1604b565793SJoe Hershberger 	out_be32(&im->gpio[0].icr, 0);
1614b565793SJoe Hershberger #endif
1624b565793SJoe Hershberger 
1634b565793SJoe Hershberger #if MPC83XX_GPIO_CTRLRS >= 2
1644b565793SJoe Hershberger 	out_be32(&im->gpio[1].dir, CONFIG_MPC83XX_GPIO_1_INIT_DIRECTION);
1654b565793SJoe Hershberger 	out_be32(&im->gpio[1].odr, CONFIG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN);
1664b565793SJoe Hershberger 	out_be32(&im->gpio[1].dat, CONFIG_MPC83XX_GPIO_1_INIT_VALUE);
1674b565793SJoe Hershberger 	out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */
1684b565793SJoe Hershberger 	out_be32(&im->gpio[1].imr, 0);
1694b565793SJoe Hershberger 	out_be32(&im->gpio[1].icr, 0);
1704b565793SJoe Hershberger #endif
1714b565793SJoe Hershberger }
1724b565793SJoe Hershberger 
1734b565793SJoe Hershberger /* Initialize GPIO soft-copies */
mpc83xx_gpio_init_r(void)1748121d3c5SKim Phillips void mpc83xx_gpio_init_r(void)
1754b565793SJoe Hershberger {
1764b565793SJoe Hershberger #if MPC83XX_GPIO_CTRLRS >= 1
1774b565793SJoe Hershberger 	gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE;
1784b565793SJoe Hershberger #endif
1794b565793SJoe Hershberger 
1804b565793SJoe Hershberger #if MPC83XX_GPIO_CTRLRS >= 2
1814b565793SJoe Hershberger 	gpio_output_value[1] = CONFIG_MPC83XX_GPIO_1_INIT_VALUE;
1824b565793SJoe Hershberger #endif
1834b565793SJoe Hershberger }
184