xref: /rk3399_rockchip-uboot/drivers/gpio/mxs_gpio.c (revision 1221ce459d04a428f8880f58581f671b736c3c27)
16b6440deSMarek Vasut /*
26b6440deSMarek Vasut  * Freescale i.MX28 GPIO control code
36b6440deSMarek Vasut  *
46b6440deSMarek Vasut  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
56b6440deSMarek Vasut  * on behalf of DENX Software Engineering GmbH
66b6440deSMarek Vasut  *
71a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
86b6440deSMarek Vasut  */
96b6440deSMarek Vasut 
106b6440deSMarek Vasut #include <common.h>
11*1221ce45SMasahiro Yamada #include <linux/errno.h>
126b6440deSMarek Vasut #include <asm/io.h>
136b6440deSMarek Vasut #include <asm/arch/iomux.h>
146b6440deSMarek Vasut #include <asm/arch/imx-regs.h>
156b6440deSMarek Vasut 
166b6440deSMarek Vasut #if	defined(CONFIG_MX23)
176b6440deSMarek Vasut #define	PINCTRL_BANKS		3
186b6440deSMarek Vasut #define	PINCTRL_DOUT(n)		(0x0500 + ((n) * 0x10))
196b6440deSMarek Vasut #define	PINCTRL_DIN(n)		(0x0600 + ((n) * 0x10))
206b6440deSMarek Vasut #define	PINCTRL_DOE(n)		(0x0700 + ((n) * 0x10))
216b6440deSMarek Vasut #define	PINCTRL_PIN2IRQ(n)	(0x0800 + ((n) * 0x10))
226b6440deSMarek Vasut #define	PINCTRL_IRQEN(n)	(0x0900 + ((n) * 0x10))
236b6440deSMarek Vasut #define	PINCTRL_IRQSTAT(n)	(0x0c00 + ((n) * 0x10))
246b6440deSMarek Vasut #elif	defined(CONFIG_MX28)
256b6440deSMarek Vasut #define	PINCTRL_BANKS		5
266b6440deSMarek Vasut #define	PINCTRL_DOUT(n)		(0x0700 + ((n) * 0x10))
276b6440deSMarek Vasut #define	PINCTRL_DIN(n)		(0x0900 + ((n) * 0x10))
286b6440deSMarek Vasut #define	PINCTRL_DOE(n)		(0x0b00 + ((n) * 0x10))
296b6440deSMarek Vasut #define	PINCTRL_PIN2IRQ(n)	(0x1000 + ((n) * 0x10))
306b6440deSMarek Vasut #define	PINCTRL_IRQEN(n)	(0x1100 + ((n) * 0x10))
316b6440deSMarek Vasut #define	PINCTRL_IRQSTAT(n)	(0x1400 + ((n) * 0x10))
326b6440deSMarek Vasut #else
336b6440deSMarek Vasut #error "Please select CONFIG_MX23 or CONFIG_MX28"
346b6440deSMarek Vasut #endif
356b6440deSMarek Vasut 
366b6440deSMarek Vasut #define GPIO_INT_FALL_EDGE	0x0
376b6440deSMarek Vasut #define GPIO_INT_LOW_LEV	0x1
386b6440deSMarek Vasut #define GPIO_INT_RISE_EDGE	0x2
396b6440deSMarek Vasut #define GPIO_INT_HIGH_LEV	0x3
406b6440deSMarek Vasut #define GPIO_INT_LEV_MASK	(1 << 0)
416b6440deSMarek Vasut #define GPIO_INT_POL_MASK	(1 << 1)
426b6440deSMarek Vasut 
mxs_gpio_init(void)436b6440deSMarek Vasut void mxs_gpio_init(void)
446b6440deSMarek Vasut {
456b6440deSMarek Vasut 	int i;
466b6440deSMarek Vasut 
476b6440deSMarek Vasut 	for (i = 0; i < PINCTRL_BANKS; i++) {
486b6440deSMarek Vasut 		writel(0, MXS_PINCTRL_BASE + PINCTRL_PIN2IRQ(i));
496b6440deSMarek Vasut 		writel(0, MXS_PINCTRL_BASE + PINCTRL_IRQEN(i));
506b6440deSMarek Vasut 		/* Use SCT address here to clear the IRQSTAT bits */
516b6440deSMarek Vasut 		writel(0xffffffff, MXS_PINCTRL_BASE + PINCTRL_IRQSTAT(i) + 8);
526b6440deSMarek Vasut 	}
536b6440deSMarek Vasut }
546b6440deSMarek Vasut 
gpio_get_value(unsigned gpio)55365d6070SJoe Hershberger int gpio_get_value(unsigned gpio)
566b6440deSMarek Vasut {
57365d6070SJoe Hershberger 	uint32_t bank = PAD_BANK(gpio);
586b6440deSMarek Vasut 	uint32_t offset = PINCTRL_DIN(bank);
59ddcf13b1SOtavio Salvador 	struct mxs_register_32 *reg =
60ddcf13b1SOtavio Salvador 		(struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
616b6440deSMarek Vasut 
62365d6070SJoe Hershberger 	return (readl(&reg->reg) >> PAD_PIN(gpio)) & 1;
636b6440deSMarek Vasut }
646b6440deSMarek Vasut 
gpio_set_value(unsigned gpio,int value)65365d6070SJoe Hershberger void gpio_set_value(unsigned gpio, int value)
666b6440deSMarek Vasut {
67365d6070SJoe Hershberger 	uint32_t bank = PAD_BANK(gpio);
686b6440deSMarek Vasut 	uint32_t offset = PINCTRL_DOUT(bank);
69ddcf13b1SOtavio Salvador 	struct mxs_register_32 *reg =
70ddcf13b1SOtavio Salvador 		(struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
716b6440deSMarek Vasut 
726b6440deSMarek Vasut 	if (value)
73365d6070SJoe Hershberger 		writel(1 << PAD_PIN(gpio), &reg->reg_set);
746b6440deSMarek Vasut 	else
75365d6070SJoe Hershberger 		writel(1 << PAD_PIN(gpio), &reg->reg_clr);
766b6440deSMarek Vasut }
776b6440deSMarek Vasut 
gpio_direction_input(unsigned gpio)78365d6070SJoe Hershberger int gpio_direction_input(unsigned gpio)
796b6440deSMarek Vasut {
80365d6070SJoe Hershberger 	uint32_t bank = PAD_BANK(gpio);
816b6440deSMarek Vasut 	uint32_t offset = PINCTRL_DOE(bank);
82ddcf13b1SOtavio Salvador 	struct mxs_register_32 *reg =
83ddcf13b1SOtavio Salvador 		(struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
846b6440deSMarek Vasut 
85365d6070SJoe Hershberger 	writel(1 << PAD_PIN(gpio), &reg->reg_clr);
866b6440deSMarek Vasut 
876b6440deSMarek Vasut 	return 0;
886b6440deSMarek Vasut }
896b6440deSMarek Vasut 
gpio_direction_output(unsigned gpio,int value)90365d6070SJoe Hershberger int gpio_direction_output(unsigned gpio, int value)
916b6440deSMarek Vasut {
92365d6070SJoe Hershberger 	uint32_t bank = PAD_BANK(gpio);
936b6440deSMarek Vasut 	uint32_t offset = PINCTRL_DOE(bank);
94ddcf13b1SOtavio Salvador 	struct mxs_register_32 *reg =
95ddcf13b1SOtavio Salvador 		(struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
966b6440deSMarek Vasut 
97365d6070SJoe Hershberger 	gpio_set_value(gpio, value);
986b6440deSMarek Vasut 
99ac135f66SMichael Heimpold 	writel(1 << PAD_PIN(gpio), &reg->reg_set);
100ac135f66SMichael Heimpold 
1016b6440deSMarek Vasut 	return 0;
1026b6440deSMarek Vasut }
1036b6440deSMarek Vasut 
gpio_request(unsigned gpio,const char * label)104365d6070SJoe Hershberger int gpio_request(unsigned gpio, const char *label)
1056b6440deSMarek Vasut {
106365d6070SJoe Hershberger 	if (PAD_BANK(gpio) >= PINCTRL_BANKS)
107365d6070SJoe Hershberger 		return -1;
1086b6440deSMarek Vasut 
1096b6440deSMarek Vasut 	return 0;
1106b6440deSMarek Vasut }
1116b6440deSMarek Vasut 
gpio_free(unsigned gpio)112365d6070SJoe Hershberger int gpio_free(unsigned gpio)
1136b6440deSMarek Vasut {
114365d6070SJoe Hershberger 	return 0;
1156b6440deSMarek Vasut }
11688f91d13SMåns Rullgård 
name_to_gpio(const char * name)11788f91d13SMåns Rullgård int name_to_gpio(const char *name)
11888f91d13SMåns Rullgård {
11988f91d13SMåns Rullgård 	unsigned bank, pin;
12088f91d13SMåns Rullgård 	char *end;
12188f91d13SMåns Rullgård 
12288f91d13SMåns Rullgård 	bank = simple_strtoul(name, &end, 10);
12388f91d13SMåns Rullgård 
12488f91d13SMåns Rullgård 	if (!*end || *end != ':')
12588f91d13SMåns Rullgård 		return bank;
12688f91d13SMåns Rullgård 
12788f91d13SMåns Rullgård 	pin = simple_strtoul(end + 1, NULL, 10);
12888f91d13SMåns Rullgård 
12988f91d13SMåns Rullgård 	return (bank << MXS_PAD_BANK_SHIFT) | (pin << MXS_PAD_PIN_SHIFT);
13088f91d13SMåns Rullgård }
131