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) >> 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_set);
746b6440deSMarek Vasut else
75365d6070SJoe Hershberger writel(1 << PAD_PIN(gpio), ®->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_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_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