Skip to content

Commit 0366df3

Browse files
henrikbrixandersenkartben
authored andcommitted
drivers: gpio: neorv32: add interrupt support
Add interrupt support to the NEORV32 GPIO controller driver. Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
1 parent de2f9ee commit 0366df3

File tree

1 file changed

+114
-36
lines changed

1 file changed

+114
-36
lines changed

drivers/gpio/gpio_neorv32.c

Lines changed: 114 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,19 @@ LOG_MODULE_REGISTER(gpio_neorv32, CONFIG_GPIO_LOG_LEVEL);
2222
#include <zephyr/drivers/gpio/gpio_utils.h>
2323

2424
/* Register offsets */
25-
#define NEORV32_GPIO_PORT_IN 0x00
26-
#define NEORV32_GPIO_PORT_OUT 0x04
27-
28-
/* Maximum number of GPIOs supported */
29-
#define MAX_GPIOS 32
25+
#define NEORV32_GPIO_PORT_IN 0x00
26+
#define NEORV32_GPIO_PORT_OUT 0x04
27+
#define NEORV32_GPIO_IRQ_TYPE 0x10
28+
#define NEORV32_GPIO_IRQ_POLARITY 0x14
29+
#define NEORV32_GPIO_IRQ_ENABLE 0x18
30+
#define NEORV32_GPIO_IRQ_PENDING 0x1c
3031

3132
struct neorv32_gpio_config {
3233
/* gpio_driver_config needs to be first */
3334
struct gpio_driver_config common;
3435
const struct device *syscon;
3536
mm_reg_t base;
37+
void (*irq_config_func)(void);
3638
};
3739

3840
struct neorv32_gpio_data {
@@ -41,24 +43,24 @@ struct neorv32_gpio_data {
4143
/* Shadow register for output */
4244
uint32_t output;
4345
struct k_spinlock lock;
46+
sys_slist_t callbacks;
4447
};
4548

46-
static inline uint32_t neorv32_gpio_read(const struct device *dev)
49+
static inline uint32_t neorv32_gpio_read(const struct device *dev, uint16_t reg)
4750
{
4851
const struct neorv32_gpio_config *config = dev->config;
4952

50-
return sys_read32(config->base + NEORV32_GPIO_PORT_IN);
53+
return sys_read32(config->base + reg);
5154
}
5255

53-
static inline void neorv32_gpio_write(const struct device *dev, uint32_t val)
56+
static inline void neorv32_gpio_write(const struct device *dev, uint16_t reg, uint32_t val)
5457
{
5558
const struct neorv32_gpio_config *config = dev->config;
5659

57-
sys_write32(val, config->base + NEORV32_GPIO_PORT_OUT);
60+
sys_write32(val, config->base + reg);
5861
}
5962

60-
static int neorv32_gpio_pin_configure(const struct device *dev, gpio_pin_t pin,
61-
gpio_flags_t flags)
63+
static int neorv32_gpio_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
6264
{
6365
const struct neorv32_gpio_config *config = dev->config;
6466
struct neorv32_gpio_data *data = dev->data;
@@ -85,91 +87,156 @@ static int neorv32_gpio_pin_configure(const struct device *dev, gpio_pin_t pin,
8587
data->output &= ~BIT(pin);
8688
}
8789

88-
neorv32_gpio_write(dev, data->output);
90+
neorv32_gpio_write(dev, NEORV32_GPIO_PORT_OUT, data->output);
8991
k_spin_unlock(&data->lock, key);
9092
}
9193

9294
return 0;
9395
}
9496

95-
static int neorv32_gpio_port_get_raw(const struct device *dev,
96-
gpio_port_value_t *value)
97+
static int neorv32_gpio_port_get_raw(const struct device *dev, gpio_port_value_t *value)
9798
{
98-
*value = neorv32_gpio_read(dev);
99+
*value = neorv32_gpio_read(dev, NEORV32_GPIO_PORT_IN);
99100
return 0;
100101
}
101102

102-
static int neorv32_gpio_port_set_masked_raw(const struct device *dev,
103-
gpio_port_pins_t mask,
104-
gpio_port_value_t value)
103+
static int neorv32_gpio_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
104+
gpio_port_value_t value)
105105
{
106106
struct neorv32_gpio_data *data = dev->data;
107107
k_spinlock_key_t key;
108108

109109
key = k_spin_lock(&data->lock);
110110
data->output = (data->output & ~mask) | (mask & value);
111-
neorv32_gpio_write(dev, data->output);
111+
neorv32_gpio_write(dev, NEORV32_GPIO_PORT_OUT, data->output);
112112
k_spin_unlock(&data->lock, key);
113113

114114
return 0;
115115
}
116116

117-
static int neorv32_gpio_port_set_bits_raw(const struct device *dev,
118-
gpio_port_pins_t pins)
117+
static int neorv32_gpio_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
119118
{
120119
struct neorv32_gpio_data *data = dev->data;
121120
k_spinlock_key_t key;
122121

123122
key = k_spin_lock(&data->lock);
124123
data->output |= pins;
125-
neorv32_gpio_write(dev, data->output);
124+
neorv32_gpio_write(dev, NEORV32_GPIO_PORT_OUT, data->output);
126125
k_spin_unlock(&data->lock, key);
127126

128127
return 0;
129128
}
130129

131-
static int neorv32_gpio_port_clear_bits_raw(const struct device *dev,
132-
gpio_port_pins_t pins)
130+
static int neorv32_gpio_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
133131
{
134132
struct neorv32_gpio_data *data = dev->data;
135133
k_spinlock_key_t key;
136134

137135
key = k_spin_lock(&data->lock);
138136
data->output &= ~pins;
139-
neorv32_gpio_write(dev, data->output);
137+
neorv32_gpio_write(dev, NEORV32_GPIO_PORT_OUT, data->output);
140138
k_spin_unlock(&data->lock, key);
141139

142140
return 0;
143141
}
144142

145-
static int neorv32_gpio_port_toggle_bits(const struct device *dev,
146-
gpio_port_pins_t pins)
143+
static int neorv32_gpio_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
147144
{
148145
struct neorv32_gpio_data *data = dev->data;
149146
k_spinlock_key_t key;
150147

151148
key = k_spin_lock(&data->lock);
152149
data->output ^= pins;
153-
neorv32_gpio_write(dev, data->output);
150+
neorv32_gpio_write(dev, NEORV32_GPIO_PORT_OUT, data->output);
154151
k_spin_unlock(&data->lock, key);
155152

156153
return 0;
157154
}
158155

159-
static int neorv32_gpio_manage_callback(const struct device *dev,
160-
struct gpio_callback *cb,
156+
static int neorv32_gpio_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin,
157+
enum gpio_int_mode mode, enum gpio_int_trig trig)
158+
{
159+
const struct neorv32_gpio_config *config = dev->config;
160+
struct neorv32_gpio_data *data = dev->data;
161+
const uint32_t mask = BIT(pin);
162+
k_spinlock_key_t key;
163+
uint32_t polarity;
164+
uint32_t enable;
165+
uint32_t type;
166+
int err = 0;
167+
168+
if (!(mask & config->common.port_pin_mask)) {
169+
return -EINVAL;
170+
}
171+
172+
key = k_spin_lock(&data->lock);
173+
174+
type = neorv32_gpio_read(dev, NEORV32_GPIO_IRQ_TYPE);
175+
polarity = neorv32_gpio_read(dev, NEORV32_GPIO_IRQ_POLARITY);
176+
enable = neorv32_gpio_read(dev, NEORV32_GPIO_IRQ_ENABLE);
177+
178+
if (mode == GPIO_INT_MODE_DISABLED) {
179+
enable &= ~mask;
180+
neorv32_gpio_write(dev, NEORV32_GPIO_IRQ_ENABLE, enable);
181+
neorv32_gpio_write(dev, NEORV32_GPIO_IRQ_PENDING, ~mask);
182+
} else {
183+
enable |= mask;
184+
185+
if (mode == GPIO_INT_MODE_LEVEL) {
186+
type &= ~mask;
187+
} else if (mode == GPIO_INT_MODE_EDGE) {
188+
type |= mask;
189+
} else {
190+
LOG_ERR("unsupported interrupt mode 0x%02x", mode);
191+
err = -ENOTSUP;
192+
goto unlock;
193+
}
194+
195+
if (trig == GPIO_INT_TRIG_LOW) {
196+
polarity &= ~mask;
197+
} else if (trig == GPIO_INT_TRIG_HIGH) {
198+
polarity |= mask;
199+
} else {
200+
LOG_ERR("unsupported interrupt trig 0x%02x", trig);
201+
err = -ENOTSUP;
202+
goto unlock;
203+
}
204+
205+
neorv32_gpio_write(dev, NEORV32_GPIO_IRQ_TYPE, type);
206+
neorv32_gpio_write(dev, NEORV32_GPIO_IRQ_POLARITY, polarity);
207+
208+
neorv32_gpio_write(dev, NEORV32_GPIO_IRQ_PENDING, ~mask);
209+
neorv32_gpio_write(dev, NEORV32_GPIO_IRQ_ENABLE, enable);
210+
}
211+
212+
unlock:
213+
k_spin_unlock(&data->lock, key);
214+
215+
return err;
216+
}
217+
218+
static int neorv32_gpio_manage_callback(const struct device *dev, struct gpio_callback *cb,
161219
bool set)
162220
{
163-
ARG_UNUSED(dev);
164-
ARG_UNUSED(cb);
165-
ARG_UNUSED(set);
221+
struct neorv32_gpio_data *data = dev->data;
166222

167-
return -ENOTSUP;
223+
return gpio_manage_callback(&data->callbacks, cb, set);
168224
}
169225

170226
static uint32_t neorv32_gpio_get_pending_int(const struct device *dev)
171227
{
172-
return 0;
228+
return neorv32_gpio_read(dev, NEORV32_GPIO_IRQ_PENDING);
229+
}
230+
231+
static void neorv32_gpio_isr(const struct device *dev)
232+
{
233+
struct neorv32_gpio_data *data = dev->data;
234+
uint32_t pending;
235+
236+
pending = neorv32_gpio_read(dev, NEORV32_GPIO_IRQ_PENDING);
237+
neorv32_gpio_write(dev, NEORV32_GPIO_IRQ_PENDING, ~(pending));
238+
239+
gpio_fire_callbacks(&data->callbacks, dev, pending);
173240
}
174241

175242
static int neorv32_gpio_init(const struct device *dev)
@@ -195,7 +262,9 @@ static int neorv32_gpio_init(const struct device *dev)
195262
return -ENODEV;
196263
}
197264

198-
neorv32_gpio_write(dev, data->output);
265+
neorv32_gpio_write(dev, NEORV32_GPIO_PORT_OUT, data->output);
266+
267+
config->irq_config_func();
199268

200269
return 0;
201270
}
@@ -207,11 +276,19 @@ static DEVICE_API(gpio, neorv32_gpio_driver_api) = {
207276
.port_set_bits_raw = neorv32_gpio_port_set_bits_raw,
208277
.port_clear_bits_raw = neorv32_gpio_port_clear_bits_raw,
209278
.port_toggle_bits = neorv32_gpio_port_toggle_bits,
279+
.pin_interrupt_configure = neorv32_gpio_pin_interrupt_configure,
210280
.manage_callback = neorv32_gpio_manage_callback,
211281
.get_pending_int = neorv32_gpio_get_pending_int,
212282
};
213283

214284
#define NEORV32_GPIO_INIT(n) \
285+
static void neorv32_gpio_config_func_##n(void) \
286+
{ \
287+
IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \
288+
neorv32_gpio_isr, DEVICE_DT_INST_GET(n), 0);\
289+
irq_enable(DT_INST_IRQN(n)); \
290+
} \
291+
\
215292
static struct neorv32_gpio_data neorv32_gpio_##n##_data = { \
216293
.output = 0, \
217294
}; \
@@ -222,6 +299,7 @@ static DEVICE_API(gpio, neorv32_gpio_driver_api) = {
222299
}, \
223300
.syscon = DEVICE_DT_GET(DT_INST_PHANDLE(n, syscon)), \
224301
.base = DT_INST_REG_ADDR(n), \
302+
.irq_config_func = neorv32_gpio_config_func_##n, \
225303
}; \
226304
\
227305
DEVICE_DT_INST_DEFINE(n, \

0 commit comments

Comments
 (0)