blob: 7eeb96d19ff0daad96bfd4ff546bd090048ff73a [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
12#define CON_MASK(x) (0xf << ((x) << 2))
13#define CON_SFR(x, v) ((v) << ((x) << 2))
14
15#define DAT_MASK(x) (0x1 << (x))
16#define DAT_SET(x) (0x1 << (x))
17
18#define PULL_MASK(x) (0x3 << ((x) << 1))
19#define PULL_MODE(x, v) ((v) << ((x) << 1))
20
21#define DRV_MASK(x) (0x3 << ((x) << 1))
22#define DRV_SET(x, m) ((m) << ((x) << 1))
23#define RATE_MASK(x) (0x1 << (x + 16))
24#define RATE_SET(x) (0x1 << (x + 16))
25
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000026void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090027{
28 unsigned int value;
29
30 value = readl(&bank->con);
31 value &= ~CON_MASK(gpio);
32 value |= CON_SFR(gpio, cfg);
33 writel(value, &bank->con);
34}
35
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000036void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090037{
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000038 s5p_gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
Axel Lin7b885cf2013-06-15 22:19:45 +080039 s5p_gpio_set_value(bank, gpio, en);
Minkyu Kang1edf0f22010-02-12 18:17:52 +090040}
41
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000042void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090043{
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000044 s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT);
Minkyu Kang1edf0f22010-02-12 18:17:52 +090045}
46
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000047void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090048{
49 unsigned int value;
50
51 value = readl(&bank->dat);
52 value &= ~DAT_MASK(gpio);
53 if (en)
54 value |= DAT_SET(gpio);
55 writel(value, &bank->dat);
56}
57
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000058unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090059{
60 unsigned int value;
61
62 value = readl(&bank->dat);
63 return !!(value & DAT_MASK(gpio));
64}
65
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000066void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090067{
68 unsigned int value;
69
70 value = readl(&bank->pull);
71 value &= ~PULL_MASK(gpio);
72
73 switch (mode) {
74 case GPIO_PULL_DOWN:
75 case GPIO_PULL_UP:
76 value |= PULL_MODE(gpio, mode);
77 break;
78 default:
Minkyu Kangced528f2010-05-28 12:34:29 +090079 break;
Minkyu Kang1edf0f22010-02-12 18:17:52 +090080 }
81
82 writel(value, &bank->pull);
83}
84
Łukasz Majewski4d954cc2011-07-15 00:16:22 +000085void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
Minkyu Kang1edf0f22010-02-12 18:17:52 +090086{
87 unsigned int value;
88
89 value = readl(&bank->drv);
90 value &= ~DRV_MASK(gpio);
91
92 switch (mode) {
93 case GPIO_DRV_1X:
94 case GPIO_DRV_2X:
95 case GPIO_DRV_3X:
96 case GPIO_DRV_4X:
97 value |= DRV_SET(gpio, mode);
98 break;
99 default:
100 return;
101 }
102
103 writel(value, &bank->drv);
104}
105
Łukasz Majewski4d954cc2011-07-15 00:16:22 +0000106void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
Minkyu Kang1edf0f22010-02-12 18:17:52 +0900107{
108 unsigned int value;
109
110 value = readl(&bank->drv);
111 value &= ~RATE_MASK(gpio);
112
113 switch (mode) {
114 case GPIO_DRV_FAST:
115 case GPIO_DRV_SLOW:
116 value |= RATE_SET(gpio);
117 break;
118 default:
119 return;
120 }
121
122 writel(value, &bank->drv);
123}
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000124
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600125struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000126{
Łukasz Majewskid6614b72012-09-04 21:47:46 +0000127 int bank;
128 unsigned g = gpio - s5p_gpio_part_max(gpio);
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000129
Łukasz Majewskid6614b72012-09-04 21:47:46 +0000130 bank = g / GPIO_PER_BANK;
131 bank *= sizeof(struct s5p_gpio_bank);
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600132 return (struct s5p_gpio_bank *) (s5p_gpio_base(gpio) + bank);
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000133}
134
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600135int s5p_gpio_get_pin(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000136{
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600137 return gpio % GPIO_PER_BANK;
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000138}
139
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600140/* Common GPIO API */
141
142int gpio_request(unsigned gpio, const char *label)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000143{
144 return 0;
145}
146
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600147int gpio_free(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000148{
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000149 return 0;
150}
151
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600152int gpio_direction_input(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000153{
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600154 s5p_gpio_direction_input(s5p_gpio_get_bank(gpio),
155 s5p_gpio_get_pin(gpio));
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000156 return 0;
157}
158
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600159int gpio_direction_output(unsigned gpio, int value)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000160{
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600161 s5p_gpio_direction_output(s5p_gpio_get_bank(gpio),
162 s5p_gpio_get_pin(gpio), value);
163 return 0;
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000164}
165
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600166int gpio_get_value(unsigned gpio)
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000167{
Joe Hershbergerf8928f12011-11-11 15:55:36 -0600168 return (int) s5p_gpio_get_value(s5p_gpio_get_bank(gpio),
169 s5p_gpio_get_pin(gpio));
170}
171
172int gpio_set_value(unsigned gpio, int value)
173{
174 s5p_gpio_set_value(s5p_gpio_get_bank(gpio),
175 s5p_gpio_get_pin(gpio), value);
176
177 return 0;
Łukasz Majewski1e04cae2011-08-22 22:34:58 +0000178}