1 /*
2  * Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT neorv32_gpio
8 
9 #include <zephyr/arch/cpu.h>
10 #include <zephyr/device.h>
11 #include <zephyr/drivers/gpio.h>
12 #include <zephyr/drivers/syscon.h>
13 #include <zephyr/irq.h>
14 #include <zephyr/sys/sys_io.h>
15 #include <zephyr/logging/log.h>
16 
17 #include <soc.h>
18 
19 LOG_MODULE_REGISTER(gpio_neorv32, CONFIG_GPIO_LOG_LEVEL);
20 
21 #include <zephyr/drivers/gpio/gpio_utils.h>
22 
23 /* Maximum number of GPIOs supported */
24 #define MAX_GPIOS 32
25 
26 struct neorv32_gpio_config {
27 	/* gpio_driver_config needs to be first */
28 	struct gpio_driver_config common;
29 	const struct device *syscon;
30 	mm_reg_t input;
31 	mm_reg_t output;
32 };
33 
34 struct neorv32_gpio_data {
35 	/* gpio_driver_data needs to be first */
36 	struct gpio_driver_data common;
37 	/* Shadow register for output */
38 	uint32_t output;
39 };
40 
neorv32_gpio_read(const struct device * dev)41 static inline uint32_t neorv32_gpio_read(const struct device *dev)
42 {
43 	const struct neorv32_gpio_config *config = dev->config;
44 
45 	return sys_read32(config->input);
46 }
47 
neorv32_gpio_write(const struct device * dev,uint32_t val)48 static inline void neorv32_gpio_write(const struct device *dev, uint32_t val)
49 {
50 	const struct neorv32_gpio_config *config = dev->config;
51 
52 	sys_write32(val, config->output);
53 }
54 
neorv32_gpio_pin_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)55 static int neorv32_gpio_pin_configure(const struct device *dev, gpio_pin_t pin,
56 				      gpio_flags_t flags)
57 {
58 	const struct neorv32_gpio_config *config = dev->config;
59 	struct neorv32_gpio_data *data = dev->data;
60 	unsigned int key;
61 
62 	if (!(BIT(pin) & config->common.port_pin_mask)) {
63 		return -EINVAL;
64 	}
65 
66 	if ((flags & GPIO_SINGLE_ENDED) != 0) {
67 		return -ENOTSUP;
68 	}
69 
70 	if ((flags & (GPIO_PULL_UP | GPIO_PULL_DOWN)) != 0) {
71 		return -ENOTSUP;
72 	}
73 
74 	if ((flags & GPIO_OUTPUT) != 0) {
75 		key = irq_lock();
76 
77 		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
78 			data->output |= BIT(pin);
79 		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
80 			data->output &= ~BIT(pin);
81 		}
82 
83 		neorv32_gpio_write(dev, data->output);
84 		irq_unlock(key);
85 	}
86 
87 	return 0;
88 }
89 
neorv32_gpio_port_get_raw(const struct device * dev,gpio_port_value_t * value)90 static int neorv32_gpio_port_get_raw(const struct device *dev,
91 				      gpio_port_value_t *value)
92 {
93 	*value = neorv32_gpio_read(dev);
94 	return 0;
95 }
96 
neorv32_gpio_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)97 static int neorv32_gpio_port_set_masked_raw(const struct device *dev,
98 					     gpio_port_pins_t mask,
99 					     gpio_port_value_t value)
100 {
101 	struct neorv32_gpio_data *data = dev->data;
102 	unsigned int key;
103 
104 	key = irq_lock();
105 	data->output = (data->output & ~mask) | (mask & value);
106 	neorv32_gpio_write(dev, data->output);
107 	irq_unlock(key);
108 
109 	return 0;
110 }
111 
neorv32_gpio_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)112 static int neorv32_gpio_port_set_bits_raw(const struct device *dev,
113 					   gpio_port_pins_t pins)
114 {
115 	struct neorv32_gpio_data *data = dev->data;
116 	unsigned int key;
117 
118 	key = irq_lock();
119 	data->output |= pins;
120 	neorv32_gpio_write(dev, data->output);
121 	irq_unlock(key);
122 
123 	return 0;
124 }
125 
neorv32_gpio_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)126 static int neorv32_gpio_port_clear_bits_raw(const struct device *dev,
127 					     gpio_port_pins_t pins)
128 {
129 	struct neorv32_gpio_data *data = dev->data;
130 	unsigned int key;
131 
132 	key = irq_lock();
133 	data->output &= ~pins;
134 	neorv32_gpio_write(dev, data->output);
135 	irq_unlock(key);
136 
137 	return 0;
138 }
139 
neorv32_gpio_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)140 static int neorv32_gpio_port_toggle_bits(const struct device *dev,
141 					  gpio_port_pins_t pins)
142 {
143 	struct neorv32_gpio_data *data = dev->data;
144 	unsigned int key;
145 
146 	key = irq_lock();
147 	data->output ^= pins;
148 	neorv32_gpio_write(dev, data->output);
149 	irq_unlock(key);
150 
151 	return 0;
152 }
153 
neorv32_gpio_manage_callback(const struct device * dev,struct gpio_callback * cb,bool set)154 static int neorv32_gpio_manage_callback(const struct device *dev,
155 					struct gpio_callback *cb,
156 					bool set)
157 {
158 	ARG_UNUSED(dev);
159 	ARG_UNUSED(cb);
160 	ARG_UNUSED(set);
161 
162 	return -ENOTSUP;
163 }
164 
neorv32_gpio_get_pending_int(const struct device * dev)165 static uint32_t neorv32_gpio_get_pending_int(const struct device *dev)
166 {
167 	return 0;
168 }
169 
neorv32_gpio_init(const struct device * dev)170 static int neorv32_gpio_init(const struct device *dev)
171 {
172 	const struct neorv32_gpio_config *config = dev->config;
173 	struct neorv32_gpio_data *data = dev->data;
174 	uint32_t features;
175 	int err;
176 
177 	if (!device_is_ready(config->syscon)) {
178 		LOG_ERR("syscon device not ready");
179 		return -EINVAL;
180 	}
181 
182 	err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_FEATURES, &features);
183 	if (err < 0) {
184 		LOG_ERR("failed to determine implemented features (err %d)", err);
185 		return -EIO;
186 	}
187 
188 	if ((features & NEORV32_SYSINFO_FEATURES_IO_GPIO) == 0) {
189 		LOG_ERR("neorv32 gpio not supported");
190 		return -ENODEV;
191 	}
192 
193 	neorv32_gpio_write(dev, data->output);
194 
195 	return 0;
196 }
197 
198 static const struct gpio_driver_api neorv32_gpio_driver_api = {
199 	.pin_configure = neorv32_gpio_pin_configure,
200 	.port_get_raw = neorv32_gpio_port_get_raw,
201 	.port_set_masked_raw = neorv32_gpio_port_set_masked_raw,
202 	.port_set_bits_raw = neorv32_gpio_port_set_bits_raw,
203 	.port_clear_bits_raw = neorv32_gpio_port_clear_bits_raw,
204 	.port_toggle_bits = neorv32_gpio_port_toggle_bits,
205 	.manage_callback = neorv32_gpio_manage_callback,
206 	.get_pending_int = neorv32_gpio_get_pending_int,
207 };
208 
209 #define NEORV32_GPIO_INIT(n)						\
210 	static struct neorv32_gpio_data neorv32_gpio_##n##_data = {	\
211 		.output = 0,						\
212 	};								\
213 									\
214 	static const struct neorv32_gpio_config neorv32_gpio_##n##_config = { \
215 		.common = {						\
216 			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n) \
217 		},							\
218 		.syscon = DEVICE_DT_GET(DT_INST_PHANDLE(n, syscon)),	\
219 		.input = DT_INST_REG_ADDR_BY_NAME(n, input),		\
220 		.output = DT_INST_REG_ADDR_BY_NAME(n, output),		\
221 	};								\
222 									\
223 	DEVICE_DT_INST_DEFINE(n,					\
224 			&neorv32_gpio_init,				\
225 			NULL,						\
226 			&neorv32_gpio_##n##_data,			\
227 			&neorv32_gpio_##n##_config,			\
228 			PRE_KERNEL_2,					\
229 			CONFIG_GPIO_INIT_PRIORITY,			\
230 			&neorv32_gpio_driver_api);
231 
232 DT_INST_FOREACH_STATUS_OKAY(NEORV32_GPIO_INIT)
233