1 /*
2 * Xilinx Processor System MIO / EMIO GPIO controller driver
3 * GPIO bank module
4 *
5 * Copyright (c) 2022, Weidmueller Interface GmbH & Co. KG
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr/arch/cpu.h>
10 #include <zephyr/device.h>
11 #include <zephyr/devicetree.h>
12
13 #include <zephyr/drivers/gpio.h>
14 #include <zephyr/drivers/gpio/gpio_utils.h>
15 #include "gpio_xlnx_ps_bank.h"
16
17 #define LOG_MODULE_NAME gpio_xlnx_ps_bank
18 #define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
19 #include <zephyr/logging/log.h>
20 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
21
22 #define DT_DRV_COMPAT xlnx_ps_gpio_bank
23
24 #define DEV_CFG(_dev) ((const struct gpio_xlnx_ps_bank_dev_cfg *)(_dev)->config)
25 #define DEV_DATA(_dev) ((struct gpio_xlnx_ps_bank_dev_data *const)(_dev)->data)
26
27 /**
28 * @brief GPIO bank pin configuration function
29 *
30 * Configures an individual pin within a MIO / EMIO GPIO pin bank.
31 * The following flags specified by the GPIO subsystem are NOT
32 * supported by the PS GPIO controller:
33 *
34 * - Pull up
35 * - Pull down
36 * - Open drain
37 * - Open source.
38 *
39 * @param dev Pointer to the GPIO bank's device.
40 * @param pin Index of the pin within the bank to be configured
41 * (decimal index of the pin).
42 * @param flags Flags specifying the pin's configuration.
43 *
44 * @retval 0 if the device initialization completed successfully,
45 * -EINVAL if the specified pin index is out of range,
46 * -ENOTSUP if the pin configuration data contains a flag
47 * that is not supported by the controller.
48 */
gpio_xlnx_ps_pin_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)49 static int gpio_xlnx_ps_pin_configure(const struct device *dev,
50 gpio_pin_t pin,
51 gpio_flags_t flags)
52 {
53 const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
54 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
55 uint32_t pin_mask = BIT(pin);
56 uint32_t bank_data;
57 uint32_t dirm_data;
58 uint32_t oen_data;
59
60 /* Validity of the specified pin index is checked in drivers/gpio.h */
61
62 /* Check for config flags not supported by the controller */
63 if (flags & (GPIO_PULL_UP | GPIO_PULL_DOWN | GPIO_SINGLE_ENDED)) {
64 return -ENOTSUP;
65 }
66
67 /* Read the data direction & output enable registers */
68 dirm_data = sys_read32(GPIO_XLNX_PS_BANK_DIRM_REG);
69 oen_data = sys_read32(GPIO_XLNX_PS_BANK_OEN_REG);
70
71 if (flags & GPIO_OUTPUT) {
72 dirm_data |= pin_mask;
73 oen_data |= pin_mask;
74
75 /*
76 * Setting of an initial value (see below) requires the
77 * direction register to be written *BEFORE* the data
78 * register, otherwise, the value will not be applied!
79 * The output enable bit can be set after the initial
80 * value has been written.
81 */
82 sys_write32(dirm_data, GPIO_XLNX_PS_BANK_DIRM_REG);
83
84 /*
85 * If the current pin is to be configured as an output
86 * pin, it is up to the caller to specify whether the
87 * output's initial value shall be high or low.
88 * -> Write the initial output value into the data register.
89 */
90 bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
91 if (flags & GPIO_OUTPUT_INIT_HIGH) {
92 bank_data |= pin_mask;
93 } else if (flags & GPIO_OUTPUT_INIT_LOW) {
94 bank_data &= ~pin_mask;
95 }
96 sys_write32(bank_data, GPIO_XLNX_PS_BANK_DATA_REG);
97
98 /* Set the pin's output enable bit */
99 sys_write32(oen_data, GPIO_XLNX_PS_BANK_OEN_REG);
100 } else {
101 dirm_data &= ~pin_mask;
102 oen_data &= ~pin_mask;
103
104 /*
105 * Disable the output first in case of an O -> I
106 * transition, then change the pin's direction.
107 */
108 sys_write32(oen_data, GPIO_XLNX_PS_BANK_OEN_REG);
109 sys_write32(dirm_data, GPIO_XLNX_PS_BANK_DIRM_REG);
110 }
111
112 return 0;
113 }
114
115 /**
116 * @brief Reads the current bit mask of the entire GPIO pin bank.
117 *
118 * Reads the current bit mask of the entire bank from the
119 * read-only data register. This includes the current values
120 * of not just all input pins, but both the input and output
121 * pins within the bank.
122 *
123 * @param dev Pointer to the GPIO bank's device.
124 * @param value Pointer to a variable of type gpio_port_value_t
125 * to which the current bit mask read from the bank's
126 * RO data register will be written to.
127 *
128 * @retval 0 if the read operation completed successfully,
129 * -EINVAL if the pointer to the output variable is NULL.
130 */
gpio_xlnx_ps_bank_get(const struct device * dev,gpio_port_value_t * value)131 static int gpio_xlnx_ps_bank_get(const struct device *dev,
132 gpio_port_value_t *value)
133 {
134 const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
135 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
136
137 *value = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
138 return 0;
139 }
140
141 /**
142 * @brief Masked write of a bit mask for the entire GPIO pin bank.
143 *
144 * Performs a masked write operation on the data register of
145 * the current GPIO pin bank. The mask is applied twice:
146 * first, it is applied to the current contents of the bank's
147 * RO data register, clearing any bits that are zeroes in the
148 * mask (will not have any effect on input pins). Second, it
149 * is applied to the data word to be written into the current
150 * bank's data register. The masked data word read from the
151 * RO data register and the masked data word provided by the
152 * caller ar then OR'ed and written to the bank's data register.
153 *
154 * @param dev Pointer to the GPIO bank's device.
155 * @param mask Mask to be applied to both the current contents
156 * of the data register and the data word provided
157 * by the caller.
158 * @param value Value to be written to the current bank's data
159 * register.
160 *
161 * @retval Always 0.
162 */
gpio_xlnx_ps_bank_set_masked(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)163 static int gpio_xlnx_ps_bank_set_masked(const struct device *dev,
164 gpio_port_pins_t mask,
165 gpio_port_value_t value)
166 {
167 const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
168 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
169 uint32_t bank_data;
170
171 bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
172 bank_data = (bank_data & ~mask) | (value & mask);
173 sys_write32(bank_data, GPIO_XLNX_PS_BANK_DATA_REG);
174
175 return 0;
176 }
177
178 /**
179 * @brief Sets bits in the data register of the GPIO pin bank.
180 *
181 * Sets bits in the data register of the current GPIO pin bank
182 * as a read-modify-write operation. All bits set in the bit
183 * mask provided by the caller are OR'ed into the current data
184 * word of the bank. This operation has no effect on the values
185 * associated with pins configured as inputs.
186 *
187 * @param dev Pointer to the GPIO bank's device.
188 * @param pins Bit mask specifying which bits shall be set in
189 * the data word of the current GPIO pin bank.
190 *
191 * @retval Always 0.
192 */
gpio_xlnx_ps_bank_set_bits(const struct device * dev,gpio_port_pins_t pins)193 static int gpio_xlnx_ps_bank_set_bits(const struct device *dev,
194 gpio_port_pins_t pins)
195 {
196 const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
197 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
198 uint32_t bank_data;
199
200 bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
201 bank_data |= pins;
202 sys_write32(bank_data, GPIO_XLNX_PS_BANK_DATA_REG);
203
204 return 0;
205 }
206
207 /**
208 * @brief Clears bits in the data register of the GPIO pin bank.
209 *
210 * Clears bits in the data register of the current GPIO pin bank
211 * as a read-modify-write operation. All bits set in the bit
212 * mask provided by the caller are NAND'ed into the current data
213 * word of the bank. This operation has no effect on the values
214 * associated with pins configured as inputs.
215 *
216 * @param dev Pointer to the GPIO bank's device.
217 * @param pins Bit mask specifying which bits shall be cleared
218 * in the data word of the current GPIO pin bank.
219 *
220 * @retval Always 0.
221 */
gpio_xlnx_ps_bank_clear_bits(const struct device * dev,gpio_port_pins_t pins)222 static int gpio_xlnx_ps_bank_clear_bits(const struct device *dev,
223 gpio_port_pins_t pins)
224 {
225 const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
226 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
227 uint32_t bank_data;
228
229 bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
230 bank_data &= ~pins;
231 sys_write32(bank_data, GPIO_XLNX_PS_BANK_DATA_REG);
232
233 return 0;
234 }
235
236 /**
237 * @brief Toggles bits in the data register of the GPIO pin bank.
238 *
239 * Toggles bits in the data register of the current GPIO pin bank
240 * as a read-modify-write operation. All bits set in the bit
241 * mask provided by the caller are XOR'ed into the current data
242 * word of the bank. This operation has no effect on the values
243 * associated with pins configured as inputs.
244 *
245 * @param dev Pointer to the GPIO bank's device.
246 * @param pins Bit mask specifying which bits shall be toggled
247 * in the data word of the current GPIO pin bank.
248 *
249 * @retval Always 0.
250 */
gpio_xlnx_ps_bank_toggle_bits(const struct device * dev,gpio_port_pins_t pins)251 static int gpio_xlnx_ps_bank_toggle_bits(const struct device *dev,
252 gpio_port_pins_t pins)
253 {
254 const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
255 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
256 uint32_t bank_data;
257
258 bank_data = sys_read32(GPIO_XLNX_PS_BANK_DATA_REG);
259 bank_data ^= pins;
260 sys_write32(bank_data, GPIO_XLNX_PS_BANK_DATA_REG);
261
262 return 0;
263 }
264
265 /**
266 * @brief Configures the interrupt behaviour of a pin within the
267 * current GPIO bank.
268 *
269 * Configures the interrupt behaviour of a pin within the current
270 * GPIO bank. If a pin is to be configured to trigger an interrupt,
271 * the following modes are supported:
272 *
273 * - edge or level triggered,
274 * - rising edge / high level or falling edge / low level,
275 * - in edge mode only: trigger on both rising and falling edge.
276 *
277 * @param dev Pointer to the GPIO bank's device.
278 * @param pin Index of the pin within the bank to be configured
279 * (decimal index of the pin).
280 * @param mode Mode configuration: edge, level or interrupt disabled.
281 * @param trig Trigger condition configuration: high/low level or
282 * rising/falling/both edge(s).
283 *
284 * @retval 0 if the interrupt configuration completed successfully,
285 * -EINVAL if the specified pin index is out of range,
286 * -ENOTSUP if the interrupt configuration data contains an
287 * invalid combination of configuration flags.
288 */
gpio_xlnx_ps_bank_pin_irq_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)289 static int gpio_xlnx_ps_bank_pin_irq_configure(const struct device *dev,
290 gpio_pin_t pin,
291 enum gpio_int_mode mode,
292 enum gpio_int_trig trig)
293 {
294 const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
295 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
296 uint32_t pin_mask = BIT(pin);
297 uint32_t int_type_data;
298 uint32_t int_polarity_data;
299 uint32_t int_any_data;
300
301 /* Validity of the specified pin index is checked in drivers/gpio.h */
302
303 /* Disable the specified pin's interrupt before (re-)configuring it */
304 sys_write32(pin_mask, GPIO_XLNX_PS_BANK_INT_DIS_REG);
305
306 int_type_data = sys_read32(GPIO_XLNX_PS_BANK_INT_TYPE_REG);
307 int_polarity_data = sys_read32(GPIO_XLNX_PS_BANK_INT_POLARITY_REG);
308 int_any_data = sys_read32(GPIO_XLNX_PS_BANK_INT_ANY_REG);
309
310 if (mode != GPIO_INT_MODE_DISABLED) {
311
312 if (mode == GPIO_INT_MODE_LEVEL) {
313 int_type_data &= ~pin_mask;
314 } else if (mode == GPIO_INT_MODE_EDGE) {
315 int_type_data |= pin_mask;
316 } else {
317 return -EINVAL;
318 }
319
320 if (trig == GPIO_INT_TRIG_LOW) {
321 int_any_data &= ~pin_mask;
322 int_polarity_data &= ~pin_mask;
323 } else if (trig == GPIO_INT_TRIG_HIGH) {
324 int_any_data &= ~pin_mask;
325 int_polarity_data |= pin_mask;
326 } else if (trig == GPIO_INT_TRIG_BOTH) {
327 if (mode == GPIO_INT_MODE_LEVEL) {
328 return -EINVAL;
329 }
330 int_any_data |= pin_mask;
331 }
332
333 } else { /* mode == GPIO_INT_MODE_DISABLED */
334 int_any_data &= ~pin_mask;
335 int_polarity_data &= ~pin_mask;
336 int_type_data &= ~pin_mask;
337 }
338
339 sys_write32(int_any_data, GPIO_XLNX_PS_BANK_INT_ANY_REG);
340 sys_write32(int_polarity_data, GPIO_XLNX_PS_BANK_INT_POLARITY_REG);
341 sys_write32(int_type_data, GPIO_XLNX_PS_BANK_INT_TYPE_REG);
342
343 if (mode != GPIO_INT_MODE_DISABLED) {
344 /* Clear potential stale pending bit before enabling interrupt */
345 sys_write32(pin_mask, GPIO_XLNX_PS_BANK_INT_STAT_REG);
346 sys_write32(pin_mask, GPIO_XLNX_PS_BANK_INT_EN_REG);
347 }
348
349 return 0;
350 }
351
352 /**
353 * @brief Returns the interrupt status of the current GPIO bank.
354 *
355 * Returns the interrupt status of the current GPIO bank, in the
356 * form of a bit mask where each pin with a pending interrupt is
357 * indicated. This information can either be used by the PM sub-
358 * system or the parent controller device driver, which manages
359 * the interrupt line of the entire PS GPIO controller, regardless
360 * of how many bank sub-devices exist. As the current status is
361 * read, it is automatically cleared. Callback triggering is handled
362 * by the parent controller device.
363 *
364 * @param dev Pointer to the GPIO bank's device.
365 *
366 * @retval A bit mask indicating for which pins within the bank
367 * an interrupt is pending.
368 */
gpio_xlnx_ps_bank_get_int_status(const struct device * dev)369 static uint32_t gpio_xlnx_ps_bank_get_int_status(const struct device *dev)
370 {
371 const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
372 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
373 uint32_t int_status;
374
375 int_status = sys_read32(GPIO_XLNX_PS_BANK_INT_STAT_REG);
376 if (int_status != 0) {
377 sys_write32(int_status, GPIO_XLNX_PS_BANK_INT_STAT_REG);
378 }
379
380 return int_status;
381 }
382
383 /**
384 * @brief Callback management re-direction function.
385 *
386 * Re-directs any callback management calls relating to the current
387 * GPIO bank to the GPIO sub-system. Comp. documentation of the
388 * underlying sub-system's #gpio_manage_callback function.
389 *
390 * @param dev Pointer to the GPIO bank's device.
391 * @param callback Pointer to a GPIO callback struct.
392 * @param set Callback set flag.
393 *
394 * @retval A bit mask indicating for which pins within the bank
395 * an interrupt is pending.
396 */
gpio_xlnx_ps_bank_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)397 static int gpio_xlnx_ps_bank_manage_callback(const struct device *dev,
398 struct gpio_callback *callback,
399 bool set)
400 {
401 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
402
403 return gpio_manage_callback(&dev_data->callbacks, callback, set);
404 }
405
406 /* GPIO bank device driver API */
407 static DEVICE_API(gpio, gpio_xlnx_ps_bank_apis) = {
408 .pin_configure = gpio_xlnx_ps_pin_configure,
409 .port_get_raw = gpio_xlnx_ps_bank_get,
410 .port_set_masked_raw = gpio_xlnx_ps_bank_set_masked,
411 .port_set_bits_raw = gpio_xlnx_ps_bank_set_bits,
412 .port_clear_bits_raw = gpio_xlnx_ps_bank_clear_bits,
413 .port_toggle_bits = gpio_xlnx_ps_bank_toggle_bits,
414 .pin_interrupt_configure = gpio_xlnx_ps_bank_pin_irq_configure,
415 .manage_callback = gpio_xlnx_ps_bank_manage_callback,
416 .get_pending_int = gpio_xlnx_ps_bank_get_int_status
417 };
418
419 /**
420 * @brief Initialize a MIO / EMIO GPIO bank sub-device
421 *
422 * Initialize a MIO / EMIO GPIO bank sub-device, which is a child
423 * of the parent Xilinx PS GPIO controller device driver. This ini-
424 * tialization function sets up a defined initial state for each
425 * GPIO bank.
426 *
427 * @param dev Pointer to the GPIO bank's device.
428 *
429 * @retval Always 0.
430 */
gpio_xlnx_ps_bank_init(const struct device * dev)431 static int gpio_xlnx_ps_bank_init(const struct device *dev)
432 {
433 const struct gpio_xlnx_ps_bank_dev_cfg *dev_conf = DEV_CFG(dev);
434 struct gpio_xlnx_ps_bank_dev_data *dev_data = DEV_DATA(dev);
435
436 __ASSERT(dev_data->base != 0, "%s mapped base address missing", dev->name);
437 if (dev_data->base == 0) {
438 LOG_ERR("%s mapped base address missing", dev->name);
439 return -EIO;
440 }
441
442 sys_write32(~0x0, GPIO_XLNX_PS_BANK_INT_DIS_REG); /* Disable all interrupts */
443 sys_write32(~0x0, GPIO_XLNX_PS_BANK_INT_STAT_REG); /* Clear all interrupts */
444 sys_write32(0x0, GPIO_XLNX_PS_BANK_OEN_REG); /* All outputs disabled */
445 sys_write32(0x0, GPIO_XLNX_PS_BANK_DIRM_REG); /* All pins input */
446 sys_write32(0x0, GPIO_XLNX_PS_BANK_DATA_REG); /* Zero data register */
447
448 return 0;
449 }
450
451 /* MIO / EMIO bank device definition macros */
452 #define GPIO_XLNX_PS_BANK_INIT(idx)\
453 static const struct gpio_xlnx_ps_bank_dev_cfg gpio_xlnx_ps_bank##idx##_cfg = {\
454 .common = {\
455 .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(idx),\
456 },\
457 .bank_index = idx,\
458 };\
459 static struct gpio_xlnx_ps_bank_dev_data gpio_xlnx_ps_bank##idx##_data = {\
460 .base = 0,\
461 };\
462 DEVICE_DT_INST_DEFINE(idx, gpio_xlnx_ps_bank_init, NULL,\
463 &gpio_xlnx_ps_bank##idx##_data, &gpio_xlnx_ps_bank##idx##_cfg,\
464 PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_xlnx_ps_bank_apis);
465
466 /* Register & initialize all MIO / EMIO GPIO banks specified in the device tree. */
467 DT_INST_FOREACH_STATUS_OKAY(GPIO_XLNX_PS_BANK_INIT);
468