]> git.sur5r.net Git - u-boot/blob - drivers/gpio/mxs_gpio.c
video: arm: rpi: Add brcm,bcm2708-fb compatible
[u-boot] / drivers / gpio / mxs_gpio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
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
7  */
8
9 #include <common.h>
10 #include <linux/errno.h>
11 #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
42 void 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
54 int gpio_get_value(unsigned gpio)
55 {
56         uint32_t bank = PAD_BANK(gpio);
57         uint32_t offset = PINCTRL_DIN(bank);
58         struct mxs_register_32 *reg =
59                 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
60
61         return (readl(&reg->reg) >> PAD_PIN(gpio)) & 1;
62 }
63
64 void gpio_set_value(unsigned gpio, int value)
65 {
66         uint32_t bank = PAD_BANK(gpio);
67         uint32_t offset = PINCTRL_DOUT(bank);
68         struct mxs_register_32 *reg =
69                 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
70
71         if (value)
72                 writel(1 << PAD_PIN(gpio), &reg->reg_set);
73         else
74                 writel(1 << PAD_PIN(gpio), &reg->reg_clr);
75 }
76
77 int gpio_direction_input(unsigned gpio)
78 {
79         uint32_t bank = PAD_BANK(gpio);
80         uint32_t offset = PINCTRL_DOE(bank);
81         struct mxs_register_32 *reg =
82                 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
83
84         writel(1 << PAD_PIN(gpio), &reg->reg_clr);
85
86         return 0;
87 }
88
89 int gpio_direction_output(unsigned gpio, int value)
90 {
91         uint32_t bank = PAD_BANK(gpio);
92         uint32_t offset = PINCTRL_DOE(bank);
93         struct mxs_register_32 *reg =
94                 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
95
96         gpio_set_value(gpio, value);
97
98         writel(1 << PAD_PIN(gpio), &reg->reg_set);
99
100         return 0;
101 }
102
103 int gpio_request(unsigned gpio, const char *label)
104 {
105         if (PAD_BANK(gpio) >= PINCTRL_BANKS)
106                 return -1;
107
108         return 0;
109 }
110
111 int gpio_free(unsigned gpio)
112 {
113         return 0;
114 }
115
116 int 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 }