blob: 11a0472c695eeb4c9aeae1e663a7a62e186ff411 [file] [log] [blame]
Minkyu Kang1edf0f22010-02-12 18:17:52 +09001/*
2 * (C) Copyright 2009 Samsung Electronics
3 * Minkyu Kang <mk7.kang@samsung.com>
4 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Minkyu Kang1edf0f22010-02-12 18:17:52 +09006 */
7
8#include <common.h>
9#include <asm/io.h>
Joe Hershbergerf8928f12011-11-11 15:55:36 -060010#include <asm/gpio.h>
Minkyu Kang1edf0f22010-02-12 18:17:52 +090011
Przemyslaw Marczakb18c47e2014-01-22 11:24:10 +010012#define S5P_GPIO_GET_BANK(x) ((x >> S5P_GPIO_BANK_SHIFT) \
13 & S5P_GPIO_BANK_MASK)
14
15#define S5P_GPIO_GET_PIN(x) (x & S5P_GPIO_PIN_MASK)
16
Minkyu Kang1edf0f22010-02-12 18:17:52 +090017#define CON_MASK(x) (0xf << ((x) << 2))
18#define CON_SFR(x, v) ((v) << ((x) << 2))
19
20#define DAT_MASK(x) (0x1 << (x))
21#define DAT_SET(x) (0x1 << (x))
22
23#define PULL_MASK(x) (0x3 << ((x) << 1))
24#define PULL_MODE(x, v) ((v) << ((x) << 1))
25
26#define DRV_MASK(x) (0x3 << ((x) << 1))
27#define DRV_SET(x, m) ((m) << ((x) << 1))
28#define RATE_MASK(x) (0x1 << (x + 16))
29#define RATE_SET(x) (0x1 << (x + 16))
30
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000031void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090032{
33 unsigned int value;
34
35 value = readl(&bank->con);
36 value &= ~CON_MASK(gpio);
37 value |= CON_SFR(gpio, cfg);
38 writel(value, &bank->con);
39}
40
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000041void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090042{
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000043 s5p_gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
Axel Lin7b885cf2013-06-15 22:19:45 +080044 s5p_gpio_set_value(bank, gpio, en);
Minkyu Kang1edf0f22010-02-12 18:17:52 +090045}
46
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000047void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090048{
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000049 s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT);
Minkyu Kang1edf0f22010-02-12 18:17:52 +090050}
51
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000052void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090053{
54 unsigned int value;
55
56 value = readl(&bank->dat);
57 value &= ~DAT_MASK(gpio);
58 if (en)
59 value |= DAT_SET(gpio);
60 writel(value, &bank->dat);
61}
62
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000063unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090064{
65 unsigned int value;
66
67 value = readl(&bank->dat);
68 return !!(value & DAT_MASK(gpio));
69}
70
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000071void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090072{
73 unsigned int value;
74
75 value = readl(&bank->pull);
76 value &= ~PULL_MASK(gpio);
77
78 switch (mode) {
79 case GPIO_PULL_DOWN:
80 case GPIO_PULL_UP:
81 value |= PULL_MODE(gpio, mode);
82 break;
83 default:
Minkyu Kangced528f2010-05-28 12:34:29 +090084 break;
Minkyu Kang1edf0f22010-02-12 18:17:52 +090085 }
86
87 writel(value, &bank->pull);
88}
89
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000090void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090091{
92 unsigned int value;
93
94 value = readl(&bank->drv);
95 value &= ~DRV_MASK(gpio);
96
97 switch (mode) {
98 case GPIO_DRV_1X:
99 case GPIO_DRV_2X:
100 case GPIO_DRV_3X:
101 case GPIO_DRV_4X:
102 value |= DRV_SET(gpio, mode);
103 break;
104 default:
105 return;
106 }
107
108 writel(value, &bank->drv);
109}
110
Łukasz Majewski4d954cc2011-07-15 00:16:22 +0000111void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
Minkyu Kang1edf0f22010-02-12 18:17:52 +0900112{
113 unsigned int value;
114
115 value = readl(&bank->drv);
116 value &= ~RATE_MASK(gpio);
117
118 switch (mode) {
119 case GPIO_DRV_FAST:
120 case GPIO_DRV_SLOW:
121 value |= RATE_SET(gpio);
122 break;
123 default:
124 return;
125 }
126
127 writel(value, &bank->drv);
128}
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000129
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600130struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000131{
Przemyslaw Marczakb18c47e2014-01-22 11:24:10 +0100132 unsigned bank = S5P_GPIO_GET_BANK(gpio);
133 unsigned base = s5p_gpio_base(gpio);
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000134
Przemyslaw Marczakb18c47e2014-01-22 11:24:10 +0100135 return (struct s5p_gpio_bank *)(base + bank);
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000136}
137
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600138int s5p_gpio_get_pin(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000139{
Przemyslaw Marczakb18c47e2014-01-22 11:24:10 +0100140 return S5P_GPIO_GET_PIN(gpio);
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000141}
142
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600143/* Common GPIO API */
144
145int gpio_request(unsigned gpio, const char *label)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000146{
147 return 0;
148}
149
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600150int gpio_free(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000151{
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000152 return 0;
153}
154
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600155int gpio_direction_input(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000156{
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600157 s5p_gpio_direction_input(s5p_gpio_get_bank(gpio),
158 s5p_gpio_get_pin(gpio));
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000159 return 0;
160}
161
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600162int gpio_direction_output(unsigned gpio, int value)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000163{
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600164 s5p_gpio_direction_output(s5p_gpio_get_bank(gpio),
165 s5p_gpio_get_pin(gpio), value);
166 return 0;
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000167}
168
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600169int gpio_get_value(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000170{
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600171 return (int) s5p_gpio_get_value(s5p_gpio_get_bank(gpio),
172 s5p_gpio_get_pin(gpio));
173}
174
175int gpio_set_value(unsigned gpio, int value)
176{
177 s5p_gpio_set_value(s5p_gpio_get_bank(gpio),
178 s5p_gpio_get_pin(gpio), value);
179
180 return 0;
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000181}