blob: c2c8a25886ab18233d2416cbe5d0c32e1bbe9fc4 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Marek Vasut53fdab22011-11-08 23:18:13 +00002/*
3 * Freescale i.MX28 GPIO control code
4 *
5 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
6 * on behalf of DENX Software Engineering GmbH
Marek Vasut53fdab22011-11-08 23:18:13 +00007 */
8
9#include <common.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090010#include <linux/errno.h>
Marek Vasut53fdab22011-11-08 23:18:13 +000011#include <asm/io.h>
12#include <asm/arch/iomux.h>
13#include <asm/arch/imx-regs.h>
14
15#if defined(CONFIG_MX23)
16#define PINCTRL_BANKS 3
17#define PINCTRL_DOUT(n) (0x0500 + ((n) * 0x10))
18#define PINCTRL_DIN(n) (0x0600 + ((n) * 0x10))
19#define PINCTRL_DOE(n) (0x0700 + ((n) * 0x10))
20#define PINCTRL_PIN2IRQ(n) (0x0800 + ((n) * 0x10))
21#define PINCTRL_IRQEN(n) (0x0900 + ((n) * 0x10))
22#define PINCTRL_IRQSTAT(n) (0x0c00 + ((n) * 0x10))
23#elif defined(CONFIG_MX28)
24#define PINCTRL_BANKS 5
25#define PINCTRL_DOUT(n) (0x0700 + ((n) * 0x10))
26#define PINCTRL_DIN(n) (0x0900 + ((n) * 0x10))
27#define PINCTRL_DOE(n) (0x0b00 + ((n) * 0x10))
28#define PINCTRL_PIN2IRQ(n) (0x1000 + ((n) * 0x10))
29#define PINCTRL_IRQEN(n) (0x1100 + ((n) * 0x10))
30#define PINCTRL_IRQSTAT(n) (0x1400 + ((n) * 0x10))
31#else
32#error "Please select CONFIG_MX23 or CONFIG_MX28"
33#endif
34
35#define GPIO_INT_FALL_EDGE 0x0
36#define GPIO_INT_LOW_LEV 0x1
37#define GPIO_INT_RISE_EDGE 0x2
38#define GPIO_INT_HIGH_LEV 0x3
39#define GPIO_INT_LEV_MASK (1 << 0)
40#define GPIO_INT_POL_MASK (1 << 1)
41
42void mxs_gpio_init(void)
43{
44 int i;
45
46 for (i = 0; i < PINCTRL_BANKS; i++) {
47 writel(0, MXS_PINCTRL_BASE + PINCTRL_PIN2IRQ(i));
48 writel(0, MXS_PINCTRL_BASE + PINCTRL_IRQEN(i));
49 /* Use SCT address here to clear the IRQSTAT bits */
50 writel(0xffffffff, MXS_PINCTRL_BASE + PINCTRL_IRQSTAT(i) + 8);
51 }
52}
53
Joe Hershbergerf8928f12011-11-11 15:55:36 -060054int gpio_get_value(unsigned gpio)
Marek Vasut53fdab22011-11-08 23:18:13 +000055{
Joe Hershbergerf8928f12011-11-11 15:55:36 -060056 uint32_t bank = PAD_BANK(gpio);
Marek Vasut53fdab22011-11-08 23:18:13 +000057 uint32_t offset = PINCTRL_DIN(bank);
Otavio Salvador5309b002012-08-05 09:05:30 +000058 struct mxs_register_32 *reg =
59 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
Marek Vasut53fdab22011-11-08 23:18:13 +000060
Joe Hershbergerf8928f12011-11-11 15:55:36 -060061 return (readl(&reg->reg) >> PAD_PIN(gpio)) & 1;
Marek Vasut53fdab22011-11-08 23:18:13 +000062}
63
Joe Hershbergerf8928f12011-11-11 15:55:36 -060064void gpio_set_value(unsigned gpio, int value)
Marek Vasut53fdab22011-11-08 23:18:13 +000065{
Joe Hershbergerf8928f12011-11-11 15:55:36 -060066 uint32_t bank = PAD_BANK(gpio);
Marek Vasut53fdab22011-11-08 23:18:13 +000067 uint32_t offset = PINCTRL_DOUT(bank);
Otavio Salvador5309b002012-08-05 09:05:30 +000068 struct mxs_register_32 *reg =
69 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
Marek Vasut53fdab22011-11-08 23:18:13 +000070
71 if (value)
Joe Hershbergerf8928f12011-11-11 15:55:36 -060072 writel(1 << PAD_PIN(gpio), &reg->reg_set);
Marek Vasut53fdab22011-11-08 23:18:13 +000073 else
Joe Hershbergerf8928f12011-11-11 15:55:36 -060074 writel(1 << PAD_PIN(gpio), &reg->reg_clr);
Marek Vasut53fdab22011-11-08 23:18:13 +000075}
76
Joe Hershbergerf8928f12011-11-11 15:55:36 -060077int gpio_direction_input(unsigned gpio)
Marek Vasut53fdab22011-11-08 23:18:13 +000078{
Joe Hershbergerf8928f12011-11-11 15:55:36 -060079 uint32_t bank = PAD_BANK(gpio);
Marek Vasut53fdab22011-11-08 23:18:13 +000080 uint32_t offset = PINCTRL_DOE(bank);
Otavio Salvador5309b002012-08-05 09:05:30 +000081 struct mxs_register_32 *reg =
82 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
Marek Vasut53fdab22011-11-08 23:18:13 +000083
Joe Hershbergerf8928f12011-11-11 15:55:36 -060084 writel(1 << PAD_PIN(gpio), &reg->reg_clr);
Marek Vasut53fdab22011-11-08 23:18:13 +000085
86 return 0;
87}
88
Joe Hershbergerf8928f12011-11-11 15:55:36 -060089int gpio_direction_output(unsigned gpio, int value)
Marek Vasut53fdab22011-11-08 23:18:13 +000090{
Joe Hershbergerf8928f12011-11-11 15:55:36 -060091 uint32_t bank = PAD_BANK(gpio);
Marek Vasut53fdab22011-11-08 23:18:13 +000092 uint32_t offset = PINCTRL_DOE(bank);
Otavio Salvador5309b002012-08-05 09:05:30 +000093 struct mxs_register_32 *reg =
94 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
Marek Vasut53fdab22011-11-08 23:18:13 +000095
Joe Hershbergerf8928f12011-11-11 15:55:36 -060096 gpio_set_value(gpio, value);
Marek Vasut53fdab22011-11-08 23:18:13 +000097
Michael Heimpold041487c2013-11-03 22:59:26 +010098 writel(1 << PAD_PIN(gpio), &reg->reg_set);
99
Marek Vasut53fdab22011-11-08 23:18:13 +0000100 return 0;
101}
102
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600103int gpio_request(unsigned gpio, const char *label)
Marek Vasut53fdab22011-11-08 23:18:13 +0000104{
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600105 if (PAD_BANK(gpio) >= PINCTRL_BANKS)
106 return -1;
Marek Vasut53fdab22011-11-08 23:18:13 +0000107
108 return 0;
109}
110
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600111int gpio_free(unsigned gpio)
Marek Vasut53fdab22011-11-08 23:18:13 +0000112{
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600113 return 0;
Marek Vasut53fdab22011-11-08 23:18:13 +0000114}
Måns Rullgårda7ec6862015-12-15 22:27:57 +0000115
116int name_to_gpio(const char *name)
117{
118 unsigned bank, pin;
119 char *end;
120
121 bank = simple_strtoul(name, &end, 10);
122
123 if (!*end || *end != ':')
124 return bank;
125
126 pin = simple_strtoul(end + 1, NULL, 10);
127
128 return (bank << MXS_PAD_BANK_SHIFT) | (pin << MXS_PAD_PIN_SHIFT);
129}