1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <soc/aml-s905x/s905x-gpio.h>
6
7static aml_gpio_block_t s905x_gpio_blocks[] = {
8    // GPIOX Block
9    {
10        .pin_count = S905X_GPIOX_PINS,
11        .oen_offset = S905X_GPIOX_0EN,
12        .input_offset = S905X_GPIOX_IN,
13        .output_offset = S905X_GPIOX_OUT,
14        .output_shift = 0,
15        .mmio_index = 0,
16        .pull_offset = S905X_PULL_UP_REG4,
17        .pull_en_offset = S905X_PULL_UP_EN_REG4,
18        .pin_start = S905X_GPIOX_PIN_START,
19        .lock = MTX_INIT,
20    },
21    // GPIODV Block
22    {
23        .pin_count = S905X_GPIODV_PINS,
24        .oen_offset = S905X_GPIODV_0EN,
25        .input_offset = S905X_GPIODV_IN,
26        .output_offset = S905X_GPIODV_OUT,
27        .output_shift = 0,
28        .mmio_index = 0,
29        .pull_offset = S905X_PULL_UP_REG0,
30        .pull_en_offset = S905X_PULL_UP_EN_REG0,
31        .pin_start = S905X_GPIODV_PIN_START,
32        .lock = MTX_INIT,
33    },
34    // GPIOH Block
35    {
36        .pin_count = S905X_GPIOH_PINS,
37        .oen_offset = S905X_GPIOH_0EN,
38        .input_offset = S905X_GPIOH_IN,
39        .output_offset = S905X_GPIOH_OUT,
40        .output_shift = 20,
41        .mmio_index = 0,
42        .pull_offset = S905X_PULL_UP_REG1,
43        .pull_en_offset = S905X_PULL_UP_EN_REG1,
44        .pin_start = S905X_GPIOH_PIN_START,
45        .lock = MTX_INIT,
46    },
47    // GPIOBOOT Block
48    {
49        .pin_count = S905X_GPIOBOOT_PINS,
50        .oen_offset = S905X_GPIOBOOT_0EN,
51        .input_offset = S905X_GPIOBOOT_IN,
52        .output_offset = S905X_GPIOBOOT_OUT,
53        .output_shift = 0,
54        .mmio_index = 0,
55        .pull_offset = S905X_PULL_UP_REG2,
56        .pull_en_offset = S905X_PULL_UP_EN_REG2,
57        .pin_start = S905X_GPIOBOOT_PIN_START,
58        .lock = MTX_INIT,
59    },
60    // GPIOCARD Block
61    {
62        .pin_count = S905X_GPIOCARD_PINS,
63        .oen_offset = S905X_GPIOCARD_0EN,
64        .input_offset = S905X_GPIOCARD_IN,
65        .output_offset = S905X_GPIOCARD_OUT,
66        .output_shift = 20,
67        .mmio_index = 0,
68        .pull_offset = S905X_PULL_UP_REG2,
69        .pull_en_offset = S905X_PULL_UP_EN_REG2,
70        .pin_start = S905X_GPIOCARD_PIN_START,
71        .lock = MTX_INIT,
72    },
73    // GPIOCLK Block
74    {
75        .pin_count = S905X_GPIOCLK_PINS,
76        .oen_offset = S905X_GPIOCLK_0EN,
77        .input_offset = S905X_GPIOCLK_IN,
78        .output_offset = S905X_GPIOCLK_OUT,
79        .output_shift = 28,
80        .mmio_index = 0,
81        .pull_offset = S905X_PULL_UP_REG3,
82        .pull_en_offset = S905X_PULL_UP_EN_REG3,
83        .pin_start = S905X_GPIOCLK_PIN_START,
84        .lock = MTX_INIT,
85    },
86    // GPIOZ Block
87    {
88        .pin_count = S905X_GPIOZ_PINS,
89        .oen_offset = S905X_GPIOZ_0EN,
90        .input_offset = S905X_GPIOZ_IN,
91        .output_offset = S905X_GPIOZ_OUT,
92        .output_shift = 0,
93        .mmio_index = 0,
94        .pull_offset = S905X_PULL_UP_REG3,
95        .pull_en_offset = S905X_PULL_UP_EN_REG3,
96        .pin_start = S905X_GPIOZ_PIN_START,
97        .lock = MTX_INIT,
98    },
99    // GPIOAO Block
100    {
101        .pin_count = S905X_GPIOAO_PINS,
102        .oen_offset = S905X_AO_GPIO_OEN_OUT,
103        .input_offset = S905X_AO_GPIO_IN,
104        .output_offset = S905X_AO_GPIO_OEN_OUT,
105        .output_shift = 0, // output is shared with OEN
106        .output_write_shift = 16, //OUT/EN share reg
107        .mmio_index = 1,
108        .pull_offset = 0, // not supported
109        .pull_en_offset = 0, // not supported
110        .pin_start = S905X_GPIOA0_PIN_START,
111        .lock = MTX_INIT,
112    },
113};
114
115#define REG_0 S905X_PERIPHS_PIN_MUX_0
116#define REG_1 S905X_PERIPHS_PIN_MUX_1
117#define REG_2 S905X_PERIPHS_PIN_MUX_2
118#define REG_3 S905X_PERIPHS_PIN_MUX_3
119#define REG_4 S905X_PERIPHS_PIN_MUX_4
120#define REG_5 S905X_PERIPHS_PIN_MUX_5
121#define REG_6 S905X_PERIPHS_PIN_MUX_6
122#define REG_7 S905X_PERIPHS_PIN_MUX_7
123#define REG_8 S905X_PERIPHS_PIN_MUX_8
124#define REG_9 S905X_PERIPHS_PIN_MUX_9
125#define AO_REG S905X_AO_RTI_PIN_MUX_REG
126#define AO_REG_2 S905X_AO_RTI_PIN_MUX_REG2
127
128static aml_gpio_interrupt_t s905x_interrupt_block = {
129    .pin_0_3_select_offset =    S905X_GPIO_0_3_PIN_SELECT,
130    .pin_4_7_select_offset =    S905X_GPIO_4_7_PIN_SELECT,
131    .edge_polarity_offset =     S905X_GPIO_INT_EDGE_POLARITY,
132    .filter_select_offset =     S905X_GPIO_FILTER_SELECT,
133    .status_offset =            S905X_GPIO_INT_STATUS,
134    .mask_offset =              S905X_GPIO_INT_MASK,
135};
136
137static const aml_pinmux_block_t s905x_pinmux_blocks[] = {
138    // GPIOX Block
139    {
140        .mux = {
141            { .regs = { REG_5 }, .bits = { 31 }, },
142            { .regs = { REG_5 }, .bits = { 30 }, },
143            { .regs = { REG_5 }, .bits = { 29 }, },
144            { .regs = { REG_5 }, .bits = { 28 }, },
145            { .regs = { REG_5 }, .bits = { 27 }, },
146            { .regs = { REG_5 }, .bits = { 26 }, },
147            { .regs = { REG_5 }, .bits = { 25 }, },
148            { .regs = { REG_5, REG_5 }, .bits = { 24, 14 }, },
149            { .regs = { REG_5, REG_5, 0, REG_5 }, .bits = { 23, 13, 0, 3 }, },
150            { .regs = { REG_5, REG_5, 0, REG_5 }, .bits = { 22, 12, 0, 2 }, },
151            { .regs = { REG_5, REG_5, REG_5, REG_5 }, .bits = { 21, 11, 5, 1 }, },
152            { .regs = { REG_5, REG_5, REG_5, REG_5 }, .bits = { 20, 10, 4, 0 }, },
153            { .regs = { REG_5 }, .bits = { 19 }, },
154            { .regs = { REG_5 }, .bits = { 18 }, },
155            { .regs = { REG_5 }, .bits = { 17 }, },
156            { .regs = { REG_5 }, .bits = { 16 }, },
157            { .regs = { REG_5 }, .bits = { 15 }, },
158            // pinmux not specified for GPIOX_17 and GPIOX_18.
159        },
160    },
161    // GPIODV Block
162    {
163        .mux = {
164            {},
165            {},
166            {},
167            {},
168            {},
169            {},
170            {},
171            {},
172            {},
173            {},
174            {},
175            {},
176            {},
177            {},
178            {},
179            {},
180            {},
181            {},
182            {},
183            {},
184            {},
185            {},
186            {},
187            {},
188            { .regs = { REG_2, REG_2, REG_1 }, .bits = { 16, 7, 15 }, },
189            { .regs = { REG_2, REG_2, REG_1 }, .bits = { 15, 6, 14 }, },
190            { .regs = { REG_2, 0, REG_1 }, .bits = { 14, 0, 13 }, },
191            { .regs = { REG_2, 0, REG_1 }, .bits = { 13, 0, 12 }, },
192            { .regs = { REG_2, REG_1, REG_1 }, .bits = { 12, 9, 11 }, },
193            { .regs = { REG_2, REG_2, REG_1 }, .bits = { 11, 5, 10 }, },
194        },
195    },
196    // GPIOH Block
197    {
198        .mux = {
199            { .regs = { REG_6 }, .bits = { 31 }, },
200            { .regs = { REG_6 }, .bits = { 30 }, },
201            { .regs = { REG_6 }, .bits = { 29 }, },
202            {},
203            { .regs = { REG_6, REG_6 }, .bits = { 28, 27 }, },
204            {},
205            { .regs = { 0, 0, REG_6 }, .bits = { 0, 0, 26 }, },
206            { .regs = { 0, 0, REG_6, REG_6 }, .bits = { 0, 0, 25, 22 }, },
207            { .regs = { 0, 0, REG_6, REG_6 }, .bits = { 0, 0, 24, 21 }, },
208            { .regs = { 0, 0, REG_6 }, .bits = { 0, 0, 23 }, },
209        },
210    },
211    // GPIOBOOT Block
212    {
213        .mux = {
214            { .regs = { REG_7 }, .bits = { 31 }, },
215            { .regs = { REG_7 }, .bits = { 31 }, },
216            { .regs = { REG_7 }, .bits = { 31 }, },
217            { .regs = { REG_7 }, .bits = { 31 }, },
218            { .regs = { REG_7 }, .bits = { 31 }, },
219            { .regs = { REG_7 }, .bits = { 31 }, },
220            { .regs = { REG_7 }, .bits = { 31 }, },
221            { .regs = { REG_7 }, .bits = { 31 }, },
222            { .regs = { REG_7, REG_7 }, .bits = { 30, 7 }, },
223            { .regs = { 0, REG_7 }, .bits = { 0, 6 }, },
224            { .regs = { REG_7, REG_7 }, .bits = { 29, 5 }, },
225            { .regs = { 0, REG_7, REG_7 }, .bits = { 0, 4, 13 }, },
226            { .regs = { 0, REG_7, REG_7 }, .bits = { 0, 3, 12 }, },
227            { .regs = { 0, REG_7, REG_7 }, .bits = { 0, 2, 11 }, },
228            { .regs = { 0, REG_7 }, .bits = { 0, 1 }, },
229        },
230    },
231    // GPIOCARD Block
232    {
233        .mux = {
234            { .regs = { REG_6 }, .bits = { 5 }, },
235            { .regs = { REG_6 }, .bits = { 4 }, },
236            { .regs = { REG_6 }, .bits = { 3 }, },
237            { .regs = { REG_6 }, .bits = { 2 }, },
238            { .regs = { REG_6, REG_6, REG_6 }, .bits = { 1, 9, 11 }, },
239            { .regs = { REG_6, REG_6, REG_6 }, .bits = { 0, 8, 10 }, },
240        },
241    },
242    // GPIOCLK Block
243    {
244        .mux = {
245           {},
246           {},
247        },
248    },
249    // GPIOZ Block
250    {
251        .mux = {
252            {},
253            {},
254            {},
255            {},
256            {},
257            {},
258            {},
259            {},
260            {},
261            {},
262            {},
263            {},
264            {},
265            {},
266            { .regs = { REG_4, REG_3 }, .bits = { 25, 21 }, },
267            { .regs = { REG_4, 0, REG_3 }, .bits = { 24, 0, 20 }, },
268        },
269    },
270    // GPIOAO Block
271    {
272        .mux = {
273            { .regs = { AO_REG, AO_REG }, .bits = { 12, 26 }, },
274            { .regs = { AO_REG, AO_REG }, .bits = { 11, 25 }, },
275            { .regs = { AO_REG, AO_REG }, .bits = { 10, 8 }, },
276            { .regs = { AO_REG, AO_REG, 0, AO_REG }, .bits = { 9, 7, 0, 22 }, },
277            { .regs = { AO_REG, AO_REG, AO_REG }, .bits = { 24, 6, 2 }, },
278            { .regs = { AO_REG, AO_REG, AO_REG }, .bits = { 23, 5, 1 }, },
279            { .regs = { 0, 0, AO_REG, AO_REG }, .bits = { 0, 0, 16, 18 }, },
280            { .regs = { AO_REG, AO_REG }, .bits = { 0, 21 }, },
281            { .regs = { AO_REG, AO_REG, AO_REG_2, AO_REG }, .bits = { 15, 14, 0, 17 }, },
282            { .regs = { AO_REG, AO_REG, AO_REG_2, AO_REG }, .bits = { 31, 4, 1, 3 }, },
283        },
284    },
285};
286
287static_assert(countof(s905x_gpio_blocks) == countof(s905x_pinmux_blocks), "");
288
289#undef REG_0
290#undef REG_1
291#undef REG_2
292#undef REG_3
293#undef REG_4
294#undef REG_5
295#undef REG_6
296#undef REG_7
297#undef REG_8
298#undef REG_9
299#undef AO_REG
300#undef AO_REG_2
301