1 /*
2 * Copyright (c) 2024, Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/drivers/i2c.h>
8 #include <zephyr/drivers/pinctrl.h>
9 #include <zephyr/irq.h>
10 #include <zephyr/linker/devicetree_regions.h>
11 #include <zephyr/logging/log.h>
12 #include <zephyr/pm/device.h>
13
14 #include <nrfx_twis.h>
15 #include <string.h>
16
17 #define DT_DRV_COMPAT nordic_nrf_twis
18
19 #define SHIM_NRF_TWIS_NODE(id) \
20 DT_NODELABEL(_CONCAT(i2c, id))
21
22 #define SHIM_NRF_TWIS_DEVICE_GET(id) \
23 DEVICE_DT_GET(SHIM_NRF_TWIS_NODE(id))
24
25 #define SHIM_NRF_TWIS_IRQ_HANDLER(id) \
26 _CONCAT_3(nrfx_twis_, id, _irq_handler)
27
28 #define SHIM_NRF_TWIS_IRQN(id) \
29 DT_IRQN(SHIM_NRF_TWIS_NODE(id))
30
31 #define SHIM_NRF_TWIS_IRQ_PRIO(id) \
32 DT_IRQ(SHIM_NRF_TWIS_NODE(id), priority)
33
34 #define SHIM_NRF_TWIS_HAS_MEMORY_REGIONS(id) \
35 DT_NODE_HAS_PROP(id, memory_regions)
36
37 #define SHIM_NRF_TWIS_LINKER_REGION_NAME(id) \
38 LINKER_DT_NODE_REGION_NAME(DT_PHANDLE(SHIM_NRF_TWIS_NODE(id), memory_regions))
39
40 #define SHIM_NRF_TWIS_BUF_ATTR_SECTION(id) \
41 __attribute__((__section__(SHIM_NRF_TWIS_LINKER_REGION_NAME, ())))
42
43 #define SHIM_NRF_TWIS_BUF_ATTR(id) \
44 COND_CODE_1( \
45 SHIM_NRF_TWIS_HAS_MEMORY_REGIONS(id), \
46 (SHIM_NRF_TWIS_BUF_ATTR_SECTION(id)), \
47 () \
48 )
49
50 #define SHIM_NRF_TWIS_BUF_SIZE \
51 CONFIG_I2C_NRFX_TWIS_BUF_SIZE
52
53 LOG_MODULE_REGISTER(i2c_nrfx_twis, CONFIG_I2C_LOG_LEVEL);
54
55 struct shim_nrf_twis_config {
56 nrfx_twis_t twis;
57 void (*irq_connect)(void);
58 void (*event_handler)(nrfx_twis_evt_t const *event);
59 const struct pinctrl_dev_config *pcfg;
60 uint8_t *buf;
61 };
62
63 struct shim_nrf_twis_data {
64 struct i2c_target_config *target_config;
65 bool enabled;
66 };
67
68 #if CONFIG_PM_DEVICE
shim_nrf_twis_is_resumed(const struct device * dev)69 static bool shim_nrf_twis_is_resumed(const struct device *dev)
70 {
71 enum pm_device_state state;
72
73 (void)pm_device_state_get(dev, &state);
74 return state == PM_DEVICE_STATE_ACTIVE;
75 }
76 #else
shim_nrf_twis_is_resumed(const struct device * dev)77 static bool shim_nrf_twis_is_resumed(const struct device *dev)
78 {
79 ARG_UNUSED(dev);
80
81 return true;
82 }
83 #endif
84
shim_nrf_twis_enable(const struct device * dev)85 static void shim_nrf_twis_enable(const struct device *dev)
86 {
87 struct shim_nrf_twis_data *dev_data = dev->data;
88 const struct shim_nrf_twis_config *dev_config = dev->config;
89
90 if (dev_data->enabled) {
91 return;
92 }
93
94 if (dev_data->target_config == NULL) {
95 return;
96 }
97
98 (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT);
99 nrfx_twis_enable(&dev_config->twis);
100 dev_data->enabled = true;
101 }
102
shim_nrf_twis_disable(const struct device * dev)103 static void shim_nrf_twis_disable(const struct device *dev)
104 {
105 struct shim_nrf_twis_data *dev_data = dev->data;
106 const struct shim_nrf_twis_config *dev_config = dev->config;
107
108 if (!dev_data->enabled) {
109 return;
110 }
111
112 dev_data->enabled = false;
113 nrfx_twis_disable(&dev_config->twis);
114 (void)pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP);
115 }
116
shim_nrf_twis_handle_read_req(const struct device * dev)117 static void shim_nrf_twis_handle_read_req(const struct device *dev)
118 {
119 struct shim_nrf_twis_data *dev_data = dev->data;
120 const struct shim_nrf_twis_config *dev_config = dev->config;
121 struct i2c_target_config *target_config = dev_data->target_config;
122 const struct i2c_target_callbacks *callbacks = target_config->callbacks;
123 const nrfx_twis_t *twis = &dev_config->twis;
124 uint8_t *buf;
125 uint32_t buf_size;
126 nrfx_err_t err;
127
128 if (callbacks->buf_read_requested(target_config, &buf, &buf_size)) {
129 LOG_ERR("no buffer provided");
130 return;
131 }
132
133 if (SHIM_NRF_TWIS_BUF_SIZE < buf_size) {
134 LOG_ERR("provided buffer too large");
135 return;
136 }
137
138 memcpy(dev_config->buf, buf, buf_size);
139
140 err = nrfx_twis_tx_prepare(twis, dev_config->buf, buf_size);
141 if (err != NRFX_SUCCESS) {
142 LOG_ERR("tx prepare failed");
143 return;
144 }
145 }
146
shim_nrf_twis_handle_write_req(const struct device * dev)147 static void shim_nrf_twis_handle_write_req(const struct device *dev)
148 {
149 const struct shim_nrf_twis_config *dev_config = dev->config;
150 const nrfx_twis_t *twis = &dev_config->twis;
151 nrfx_err_t err;
152
153 err = nrfx_twis_rx_prepare(twis, dev_config->buf, SHIM_NRF_TWIS_BUF_SIZE);
154 if (err != NRFX_SUCCESS) {
155 LOG_ERR("rx prepare failed");
156 return;
157 }
158 }
159
shim_nrf_twis_handle_write_done(const struct device * dev)160 static void shim_nrf_twis_handle_write_done(const struct device *dev)
161 {
162 struct shim_nrf_twis_data *dev_data = dev->data;
163 const struct shim_nrf_twis_config *dev_config = dev->config;
164 struct i2c_target_config *target_config = dev_data->target_config;
165 const struct i2c_target_callbacks *callbacks = target_config->callbacks;
166 const nrfx_twis_t *twis = &dev_config->twis;
167
168 callbacks->buf_write_received(target_config, dev_config->buf, nrfx_twis_rx_amount(twis));
169 }
170
shim_nrf_twis_event_handler(const struct device * dev,nrfx_twis_evt_t const * event)171 static void shim_nrf_twis_event_handler(const struct device *dev,
172 nrfx_twis_evt_t const *event)
173 {
174 switch (event->type) {
175 case NRFX_TWIS_EVT_READ_REQ:
176 shim_nrf_twis_handle_read_req(dev);
177 break;
178
179 case NRFX_TWIS_EVT_WRITE_REQ:
180 shim_nrf_twis_handle_write_req(dev);
181 break;
182
183 case NRFX_TWIS_EVT_WRITE_DONE:
184 shim_nrf_twis_handle_write_done(dev);
185 break;
186
187 default:
188 break;
189 }
190 }
191
shim_nrf_twis_pm_action_cb(const struct device * dev,enum pm_device_action action)192 static int shim_nrf_twis_pm_action_cb(const struct device *dev,
193 enum pm_device_action action)
194 {
195 switch (action) {
196 case PM_DEVICE_ACTION_RESUME:
197 shim_nrf_twis_enable(dev);
198 break;
199
200 #if CONFIG_PM_DEVICE
201 case PM_DEVICE_ACTION_SUSPEND:
202 shim_nrf_twis_disable();
203 break;
204 #endif
205
206 default:
207 return -ENOTSUP;
208 }
209
210 return 0;
211 }
212
shim_nrf_twis_target_register(const struct device * dev,struct i2c_target_config * target_config)213 static int shim_nrf_twis_target_register(const struct device *dev,
214 struct i2c_target_config *target_config)
215 {
216 struct shim_nrf_twis_data *dev_data = dev->data;
217 const struct shim_nrf_twis_config *dev_config = dev->config;
218 const nrfx_twis_t *twis = &dev_config->twis;
219 nrfx_err_t err;
220 const nrfx_twis_config_t config = {
221 .addr = {
222 target_config->address,
223 },
224 .skip_gpio_cfg = true,
225 .skip_psel_cfg = true,
226 };
227
228 if (target_config->flags) {
229 LOG_ERR("16-bit address unsupported");
230 return -EINVAL;
231 }
232
233 shim_nrf_twis_disable(dev);
234
235 err = nrfx_twis_reconfigure(twis, &config);
236 if (err != NRFX_SUCCESS) {
237 return -ENODEV;
238 }
239
240 dev_data->target_config = target_config;
241
242 if (shim_nrf_twis_is_resumed(dev)) {
243 shim_nrf_twis_enable(dev);
244 }
245
246 return 0;
247 }
248
shim_nrf_twis_target_unregister(const struct device * dev,struct i2c_target_config * target_config)249 static int shim_nrf_twis_target_unregister(const struct device *dev,
250 struct i2c_target_config *target_config)
251 {
252 struct shim_nrf_twis_data *dev_data = dev->data;
253
254 if (dev_data->target_config != target_config) {
255 return -EINVAL;
256 }
257
258 shim_nrf_twis_disable(dev);
259 dev_data->target_config = NULL;
260 return 0;
261 }
262
263 const struct i2c_driver_api shim_nrf_twis_api = {
264 .target_register = shim_nrf_twis_target_register,
265 .target_unregister = shim_nrf_twis_target_unregister,
266 };
267
shim_nrf_twis_init(const struct device * dev)268 static int shim_nrf_twis_init(const struct device *dev)
269 {
270 const struct shim_nrf_twis_config *dev_config = dev->config;
271 nrfx_err_t err;
272 const nrfx_twis_config_t config = {
273 .skip_gpio_cfg = true,
274 .skip_psel_cfg = true,
275 };
276
277 err = nrfx_twis_init(&dev_config->twis, &config, dev_config->event_handler);
278 if (err != NRFX_SUCCESS) {
279 return -ENODEV;
280 }
281
282 dev_config->irq_connect();
283 return pm_device_driver_init(dev, shim_nrf_twis_pm_action_cb);
284 }
285
286 #define SHIM_NRF_TWIS_NAME(id, name) \
287 _CONCAT_4(shim_nrf_twis_, name, _, id)
288
289 #define SHIM_NRF_TWIS_DEVICE_DEFINE(id) \
290 static void SHIM_NRF_TWIS_NAME(id, irq_connect)(void) \
291 { \
292 IRQ_CONNECT( \
293 SHIM_NRF_TWIS_IRQN(id), \
294 SHIM_NRF_TWIS_IRQ_PRIO(id), \
295 nrfx_isr, \
296 SHIM_NRF_TWIS_IRQ_HANDLER(id), \
297 0 \
298 ); \
299 } \
300 \
301 static void SHIM_NRF_TWIS_NAME(id, event_handler)(nrfx_twis_evt_t const *event) \
302 { \
303 shim_nrf_twis_event_handler(SHIM_NRF_TWIS_DEVICE_GET(id), event); \
304 } \
305 \
306 static struct shim_nrf_twis_data SHIM_NRF_TWIS_NAME(id, data); \
307 \
308 PINCTRL_DT_DEFINE(SHIM_NRF_TWIS_NODE(id)); \
309 \
310 static uint8_t SHIM_NRF_TWIS_NAME(id, buf) \
311 [SHIM_NRF_TWIS_BUF_SIZE] SHIM_NRF_TWIS_BUF_ATTR(id); \
312 \
313 static const struct shim_nrf_twis_config SHIM_NRF_TWIS_NAME(id, config) = { \
314 .twis = NRFX_TWIS_INSTANCE(id), \
315 .irq_connect = SHIM_NRF_TWIS_NAME(id, irq_connect), \
316 .event_handler = SHIM_NRF_TWIS_NAME(id, event_handler), \
317 .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SHIM_NRF_TWIS_NODE(id)), \
318 .buf = SHIM_NRF_TWIS_NAME(id, buf), \
319 }; \
320 \
321 PM_DEVICE_DT_DEFINE( \
322 SHIM_NRF_TWIS_NODE(id), \
323 shim_nrf_twis_pm_action_cb, \
324 ); \
325 \
326 DEVICE_DT_DEFINE( \
327 SHIM_NRF_TWIS_NODE(id), \
328 shim_nrf_twis_init, \
329 PM_DEVICE_DT_GET(SHIM_NRF_TWIS_NODE(id)), \
330 &SHIM_NRF_TWIS_NAME(id, data), \
331 &SHIM_NRF_TWIS_NAME(id, config), \
332 POST_KERNEL, \
333 CONFIG_I2C_INIT_PRIORITY, \
334 &shim_nrf_twis_api \
335 );
336
337 #ifdef CONFIG_HAS_HW_NRF_TWIS0
338 SHIM_NRF_TWIS_DEVICE_DEFINE(0);
339 #endif
340
341 #ifdef CONFIG_HAS_HW_NRF_TWIS1
342 SHIM_NRF_TWIS_DEVICE_DEFINE(1);
343 #endif
344
345 #ifdef CONFIG_HAS_HW_NRF_TWIS2
346 SHIM_NRF_TWIS_DEVICE_DEFINE(2);
347 #endif
348
349 #ifdef CONFIG_HAS_HW_NRF_TWIS3
350 SHIM_NRF_TWIS_DEVICE_DEFINE(3);
351 #endif
352
353 #ifdef CONFIG_HAS_HW_NRF_TWIS20
354 SHIM_NRF_TWIS_DEVICE_DEFINE(20);
355 #endif
356
357 #ifdef CONFIG_HAS_HW_NRF_TWIS21
358 SHIM_NRF_TWIS_DEVICE_DEFINE(21);
359 #endif
360
361 #ifdef CONFIG_HAS_HW_NRF_TWIS22
362 SHIM_NRF_TWIS_DEVICE_DEFINE(22);
363 #endif
364
365 #ifdef CONFIG_HAS_HW_NRF_TWIS30
366 SHIM_NRF_TWIS_DEVICE_DEFINE(30);
367 #endif
368
369 #ifdef CONFIG_HAS_HW_NRF_TWIS130
370 SHIM_NRF_TWIS_DEVICE_DEFINE(130);
371 #endif
372
373 #ifdef CONFIG_HAS_HW_NRF_TWIS131
374 SHIM_NRF_TWIS_DEVICE_DEFINE(131);
375 #endif
376
377 #ifdef CONFIG_HAS_HW_NRF_TWIS133
378 SHIM_NRF_TWIS_DEVICE_DEFINE(133);
379 #endif
380
381 #ifdef CONFIG_HAS_HW_NRF_TWIS134
382 SHIM_NRF_TWIS_DEVICE_DEFINE(134);
383 #endif
384
385 #ifdef CONFIG_HAS_HW_NRF_TWIS135
386 SHIM_NRF_TWIS_DEVICE_DEFINE(135);
387 #endif
388
389 #ifdef CONFIG_HAS_HW_NRF_TWIS136
390 SHIM_NRF_TWIS_DEVICE_DEFINE(136);
391 #endif
392
393 #ifdef CONFIG_HAS_HW_NRF_TWIS137
394 SHIM_NRF_TWIS_DEVICE_DEFINE(137);
395 #endif
396