1 /*
2 * Copyright (c) 2022 Henrik Brix Andersen <henrik@brixandersen.dk>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/syscon.h>
9 #include <zephyr/drivers/pinctrl.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/logging/log.h>
12
13 LOG_MODULE_REGISTER(pinctrl_xlnx_zynq, CONFIG_PINCTRL_LOG_LEVEL);
14
15 #define DT_DRV_COMPAT xlnx_pinctrl_zynq
16
17 BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1,
18 "Unsupported number of instances");
19
20 /* Relative SLCR register offsets for use in asserts */
21 #define MIO_PIN_53_OFFSET 0x00d4
22 #define SD0_WP_CD_SEL_OFFSET 0x0130
23 #define SD1_WP_CD_SEL_OFFSET 0x0134
24
25 static const struct device *const slcr = DEVICE_DT_GET(DT_INST_PHANDLE(0, syscon));
26 static mm_reg_t base = DT_INST_REG_ADDR(0);
27 K_SEM_DEFINE(pinctrl_lock, 1, 1);
28
pinctrl_configure_pins(const pinctrl_soc_pin_t * pins,uint8_t pin_cnt,uintptr_t reg)29 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
30 {
31 uint16_t addr;
32 uint32_t val;
33 uint8_t i;
34 int err = 0;
35
36 ARG_UNUSED(reg);
37
38 if (!device_is_ready(slcr)) {
39 LOG_ERR("SLCR device not ready");
40 return -ENODEV;
41 }
42
43 /* Guard the read-modify-write operations */
44 k_sem_take(&pinctrl_lock, K_FOREVER);
45
46 for (i = 0; i < pin_cnt; i++) {
47 __ASSERT_NO_MSG(pins[i].offset <= MIO_PIN_53_OFFSET ||
48 pins[i].offset == SD0_WP_CD_SEL_OFFSET ||
49 pins[i].offset == SD1_WP_CD_SEL_OFFSET);
50
51 addr = base + pins[i].offset;
52
53 err = syscon_read_reg(slcr, addr, &val);
54 if (err != 0) {
55 LOG_ERR("failed to read SLCR addr 0x%04x (err %d)", addr, err);
56 break;
57 }
58
59 LOG_DBG("0x%04x: mask 0x%08x, val 0x%08x", addr, pins[i].mask, pins[i].val);
60 LOG_DBG("0x%04x r: 0x%08x", addr, val);
61
62 val &= ~(pins[i].mask);
63 val |= pins[i].val;
64
65 LOG_DBG("0x%04x w: 0x%08x", addr, val);
66
67 err = syscon_write_reg(slcr, addr, val);
68 if (err != 0) {
69 LOG_ERR("failed to write SLCR addr 0x%04x (err %d)", addr, err);
70 break;
71 }
72 }
73
74 k_sem_give(&pinctrl_lock);
75
76 return err;
77 }
78