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