1 /*
2  * Copyright (c) 2016 Freescale Semiconductor, Inc.
3  * Copyright (c) 2019, 2022 NXP
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT nxp_lpc_i2c
9 
10 #include <errno.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/drivers/clock_control.h>
13 #include <fsl_i2c.h>
14 #include <zephyr/drivers/pinctrl.h>
15 #include <zephyr/drivers/reset.h>
16 
17 #ifdef CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY
18 #include "i2c_bitbang.h"
19 #include <zephyr/drivers/gpio.h>
20 #endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */
21 
22 #include <zephyr/logging/log.h>
23 #include <zephyr/irq.h>
24 LOG_MODULE_REGISTER(mcux_flexcomm);
25 
26 #include "i2c-priv.h"
27 
28 #define I2C_TRANSFER_TIMEOUT_MSEC                                                                  \
29 	COND_CODE_0(CONFIG_I2C_NXP_TRANSFER_TIMEOUT, (K_FOREVER),                                  \
30 		    (K_MSEC(CONFIG_I2C_NXP_TRANSFER_TIMEOUT)))
31 
32 #define MCUX_FLEXCOMM_MAX_TARGETS 4
33 
34 struct mcux_flexcomm_config {
35 	I2C_Type *base;
36 	const struct device *clock_dev;
37 	clock_control_subsys_t clock_subsys;
38 	void (*irq_config_func)(const struct device *dev);
39 	uint32_t bitrate;
40 	const struct pinctrl_dev_config *pincfg;
41 	const struct reset_dt_spec reset;
42 #ifdef CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY
43 	struct gpio_dt_spec scl;
44 	struct gpio_dt_spec sda;
45 #endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */
46 };
47 
48 #ifdef CONFIG_I2C_TARGET
49 struct mcux_flexcomm_target_data {
50 	struct i2c_target_config *target_cfg;
51 	bool target_attached;
52 	bool first_read;
53 	bool first_write;
54 	bool is_write;
55 };
56 #endif
57 
58 struct mcux_flexcomm_data {
59 	i2c_master_handle_t handle;
60 	struct k_sem device_sync_sem;
61 	struct k_sem lock;
62 	status_t callback_status;
63 #ifdef CONFIG_I2C_TARGET
64 	uint8_t nr_targets_attached;
65 	i2c_slave_config_t i2c_cfg;
66 	i2c_slave_handle_t target_handle;
67 	struct mcux_flexcomm_target_data target_data[MCUX_FLEXCOMM_MAX_TARGETS];
68 #endif
69 };
70 
mcux_flexcomm_configure(const struct device * dev,uint32_t dev_config_raw)71 static int mcux_flexcomm_configure(const struct device *dev,
72 				   uint32_t dev_config_raw)
73 {
74 	const struct mcux_flexcomm_config *config = dev->config;
75 	struct mcux_flexcomm_data *data = dev->data;
76 	I2C_Type *base = config->base;
77 	uint32_t clock_freq;
78 	uint32_t baudrate;
79 
80 	if (!(I2C_MODE_CONTROLLER & dev_config_raw)) {
81 		return -EINVAL;
82 	}
83 
84 	if (I2C_ADDR_10_BITS & dev_config_raw) {
85 		return -EINVAL;
86 	}
87 
88 	switch (I2C_SPEED_GET(dev_config_raw)) {
89 	case I2C_SPEED_STANDARD:
90 		baudrate = KHZ(100);
91 		break;
92 	case I2C_SPEED_FAST:
93 		baudrate = KHZ(400);
94 		break;
95 	case I2C_SPEED_FAST_PLUS:
96 		baudrate = MHZ(1);
97 		break;
98 	default:
99 		return -EINVAL;
100 	}
101 
102 	/* Get the clock frequency */
103 	if (clock_control_get_rate(config->clock_dev, config->clock_subsys,
104 				   &clock_freq)) {
105 		return -EINVAL;
106 	}
107 
108 	k_sem_take(&data->lock, K_FOREVER);
109 	I2C_MasterSetBaudRate(base, baudrate, clock_freq);
110 	k_sem_give(&data->lock);
111 
112 	return 0;
113 }
114 
mcux_flexcomm_master_transfer_callback(I2C_Type * base,i2c_master_handle_t * handle,status_t status,void * userData)115 static void mcux_flexcomm_master_transfer_callback(I2C_Type *base,
116 						   i2c_master_handle_t *handle,
117 						   status_t status,
118 						   void *userData)
119 {
120 	struct mcux_flexcomm_data *data = userData;
121 
122 	ARG_UNUSED(handle);
123 	ARG_UNUSED(base);
124 
125 	data->callback_status = status;
126 	k_sem_give(&data->device_sync_sem);
127 }
128 
mcux_flexcomm_convert_flags(int msg_flags)129 static uint32_t mcux_flexcomm_convert_flags(int msg_flags)
130 {
131 	uint32_t flags = 0U;
132 
133 	if (!(msg_flags & I2C_MSG_STOP)) {
134 		flags |= kI2C_TransferNoStopFlag;
135 	}
136 
137 	if (msg_flags & I2C_MSG_RESTART) {
138 		flags |= kI2C_TransferRepeatedStartFlag;
139 	}
140 
141 	return flags;
142 }
143 
mcux_flexcomm_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)144 static int mcux_flexcomm_transfer(const struct device *dev,
145 				  struct i2c_msg *msgs,
146 				  uint8_t num_msgs, uint16_t addr)
147 {
148 	const struct mcux_flexcomm_config *config = dev->config;
149 	struct mcux_flexcomm_data *data = dev->data;
150 	I2C_Type *base = config->base;
151 	i2c_master_transfer_t transfer;
152 	status_t status;
153 	int ret = 0;
154 
155 	k_sem_take(&data->lock, K_FOREVER);
156 
157 	/* Iterate over all the messages */
158 	for (int i = 0; i < num_msgs; i++) {
159 		if (I2C_MSG_ADDR_10_BITS & msgs->flags) {
160 			ret = -ENOTSUP;
161 			break;
162 		}
163 
164 		/* Initialize the transfer descriptor */
165 		transfer.flags = mcux_flexcomm_convert_flags(msgs->flags);
166 
167 		/* Prevent the controller to send a start condition between
168 		 * messages, except if explicitly requested.
169 		 */
170 		if (i != 0 && !(msgs->flags & I2C_MSG_RESTART)) {
171 			transfer.flags |= kI2C_TransferNoStartFlag;
172 		}
173 
174 		transfer.slaveAddress = addr;
175 		transfer.direction = (msgs->flags & I2C_MSG_READ)
176 			? kI2C_Read : kI2C_Write;
177 		transfer.subaddress = 0;
178 		transfer.subaddressSize = 0;
179 		transfer.data = msgs->buf;
180 		transfer.dataSize = msgs->len;
181 
182 		/* Start the transfer */
183 		status = I2C_MasterTransferNonBlocking(base,
184 				&data->handle, &transfer);
185 
186 		/* Return an error if the transfer didn't start successfully
187 		 * e.g., if the bus was busy
188 		 */
189 		if (status != kStatus_Success) {
190 			I2C_MasterTransferAbort(base, &data->handle);
191 			ret = -EIO;
192 			break;
193 		}
194 
195 		/* Wait for the transfer to complete */
196 		k_sem_take(&data->device_sync_sem, I2C_TRANSFER_TIMEOUT_MSEC);
197 
198 		/* Return an error if the transfer didn't complete
199 		 * successfully. e.g., nak, timeout, lost arbitration
200 		 */
201 		if (data->callback_status != kStatus_Success) {
202 			I2C_MasterTransferAbort(base, &data->handle);
203 			ret = -EIO;
204 			break;
205 		}
206 
207 		/* Move to the next message */
208 		msgs++;
209 	}
210 
211 	k_sem_give(&data->lock);
212 
213 	return ret;
214 }
215 
216 #if CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY
mcux_flexcomm_bitbang_set_scl(void * io_context,int state)217 static void mcux_flexcomm_bitbang_set_scl(void *io_context, int state)
218 {
219 	const struct mcux_flexcomm_config *config = io_context;
220 
221 	gpio_pin_set_dt(&config->scl, state);
222 }
223 
mcux_flexcomm_bitbang_set_sda(void * io_context,int state)224 static void mcux_flexcomm_bitbang_set_sda(void *io_context, int state)
225 {
226 	const struct mcux_flexcomm_config *config = io_context;
227 
228 	gpio_pin_set_dt(&config->sda, state);
229 }
230 
mcux_flexcomm_bitbang_get_sda(void * io_context)231 static int mcux_flexcomm_bitbang_get_sda(void *io_context)
232 {
233 	const struct mcux_flexcomm_config *config = io_context;
234 
235 	return gpio_pin_get_dt(&config->sda) == 0 ? 0 : 1;
236 }
237 
mcux_flexcomm_recover_bus(const struct device * dev)238 static int mcux_flexcomm_recover_bus(const struct device *dev)
239 {
240 	const struct mcux_flexcomm_config *config = dev->config;
241 	struct mcux_flexcomm_data *data = dev->data;
242 	struct i2c_bitbang bitbang_ctx;
243 	struct i2c_bitbang_io bitbang_io = {
244 		.set_scl = mcux_flexcomm_bitbang_set_scl,
245 		.set_sda = mcux_flexcomm_bitbang_set_sda,
246 		.get_sda = mcux_flexcomm_bitbang_get_sda,
247 	};
248 	uint32_t bitrate_cfg;
249 	int error = 0;
250 
251 	if (!gpio_is_ready_dt(&config->scl)) {
252 		LOG_ERR("SCL GPIO device not ready");
253 		return -EIO;
254 	}
255 
256 	if (!gpio_is_ready_dt(&config->sda)) {
257 		LOG_ERR("SDA GPIO device not ready");
258 		return -EIO;
259 	}
260 
261 	k_sem_take(&data->lock, K_FOREVER);
262 
263 	error = gpio_pin_configure_dt(&config->scl, GPIO_OUTPUT_HIGH);
264 	if (error != 0) {
265 		LOG_ERR("failed to configure SCL GPIO (err %d)", error);
266 		goto restore;
267 	}
268 
269 	error = gpio_pin_configure_dt(&config->sda, GPIO_OUTPUT_HIGH);
270 	if (error != 0) {
271 		LOG_ERR("failed to configure SDA GPIO (err %d)", error);
272 		goto restore;
273 	}
274 
275 	i2c_bitbang_init(&bitbang_ctx, &bitbang_io, (void *)config);
276 
277 	bitrate_cfg = i2c_map_dt_bitrate(config->bitrate) | I2C_MODE_CONTROLLER;
278 	error = i2c_bitbang_configure(&bitbang_ctx, bitrate_cfg);
279 	if (error != 0) {
280 		LOG_ERR("failed to configure I2C bitbang (err %d)", error);
281 		goto restore;
282 	}
283 
284 	error = i2c_bitbang_recover_bus(&bitbang_ctx);
285 	if (error != 0) {
286 		LOG_ERR("failed to recover bus (err %d)", error);
287 		goto restore;
288 	}
289 
290 restore:
291 	(void)pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
292 
293 	k_sem_give(&data->lock);
294 
295 	return error;
296 }
297 #endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */
298 
299 #if defined(CONFIG_I2C_TARGET)
300 
mcux_flexcomm_find_free_target(struct mcux_flexcomm_data * data)301 static struct mcux_flexcomm_target_data *mcux_flexcomm_find_free_target(
302 		struct mcux_flexcomm_data *data)
303 {
304 	struct mcux_flexcomm_target_data *target;
305 	int i;
306 
307 	for (i = 0; i < ARRAY_SIZE(data->target_data); i++) {
308 		target = &data->target_data[i];
309 		if (!target->target_attached) {
310 			return target;
311 		}
312 	}
313 	return NULL;
314 }
315 
mcux_flexcomm_find_target_by_address(struct mcux_flexcomm_data * data,uint16_t address)316 static struct mcux_flexcomm_target_data *mcux_flexcomm_find_target_by_address(
317 		struct mcux_flexcomm_data *data, uint16_t address)
318 {
319 	struct mcux_flexcomm_target_data *target;
320 	int i;
321 
322 	for (i = 0; i < ARRAY_SIZE(data->target_data); i++) {
323 		target = &data->target_data[i];
324 		if (target->target_attached && target->target_cfg->address == address) {
325 			return target;
326 		}
327 	}
328 	return NULL;
329 }
330 
mcux_flexcomm_setup_i2c_config_address(struct mcux_flexcomm_data * data,struct mcux_flexcomm_target_data * target,bool disabled)331 static int mcux_flexcomm_setup_i2c_config_address(struct mcux_flexcomm_data *data,
332 		struct mcux_flexcomm_target_data *target, bool disabled)
333 {
334 	i2c_slave_address_t *addr;
335 	int idx = -1;
336 	int i;
337 
338 	for (i = 0; i < ARRAY_SIZE(data->target_data); i++) {
339 		if (data->target_data[i].target_attached && &data->target_data[i] == target) {
340 			idx = i;
341 			break;
342 		}
343 	}
344 
345 	if (idx < 0) {
346 		return -ENODEV;
347 	}
348 
349 	/* This could be just shifting a pointer in the i2c_cfg struct */
350 	/* However would be less readable and error prone if the struct changes */
351 	switch (idx) {
352 	case 0:
353 		addr = &data->i2c_cfg.address0;
354 		break;
355 	case 1:
356 		addr = &data->i2c_cfg.address1;
357 		break;
358 	case 2:
359 		addr = &data->i2c_cfg.address2;
360 		break;
361 	case 3:
362 		addr = &data->i2c_cfg.address3;
363 		break;
364 	default:
365 		return -1;
366 	}
367 
368 	addr->address = target->target_cfg->address;
369 	addr->addressDisable = disabled;
370 
371 	return 0;
372 }
373 
i2c_target_transfer_callback(I2C_Type * base,volatile i2c_slave_transfer_t * transfer,void * userData)374 static void i2c_target_transfer_callback(I2C_Type *base,
375 		volatile i2c_slave_transfer_t *transfer, void *userData)
376 {
377 	/* Convert 8-bit received address to 7-bit address */
378 	uint8_t address = transfer->receivedAddress >> 1;
379 	struct mcux_flexcomm_data *data = userData;
380 	struct mcux_flexcomm_target_data *target;
381 	const struct i2c_target_callbacks *target_cb;
382 	static uint8_t rxVal, txVal;
383 
384 	ARG_UNUSED(base);
385 
386 	target = mcux_flexcomm_find_target_by_address(data, address);
387 	if (!target) {
388 		LOG_ERR("No target found for address: 0x%x", address);
389 		return;
390 	}
391 
392 	target_cb = target->target_cfg->callbacks;
393 
394 	switch (transfer->event) {
395 	case kI2C_SlaveTransmitEvent:
396 		/* request to provide data to transmit */
397 		if (target->first_read && target_cb->read_requested) {
398 			target->first_read = false;
399 			target_cb->read_requested(target->target_cfg, &txVal);
400 		} else if (target_cb->read_processed) {
401 			target_cb->read_processed(target->target_cfg, &txVal);
402 		}
403 
404 		transfer->txData = &txVal;
405 		transfer->txSize = 1;
406 		break;
407 
408 	case kI2C_SlaveReceiveEvent:
409 		/* request to provide a buffer in which to place received data */
410 		if (target->first_write && target_cb->write_requested) {
411 			target_cb->write_requested(target->target_cfg);
412 			target->first_write = false;
413 		}
414 
415 		transfer->rxData = &rxVal;
416 		transfer->rxSize = 1;
417 		target->is_write = true;
418 		break;
419 
420 	case kI2C_SlaveCompletionEvent:
421 		/* called after every transferred byte */
422 		if (target->is_write && target_cb->write_received) {
423 			target_cb->write_received(target->target_cfg, rxVal);
424 			target->is_write = false;
425 		}
426 		break;
427 
428 	case kI2C_SlaveDeselectedEvent:
429 		if (target_cb->stop) {
430 			target_cb->stop(target->target_cfg);
431 		}
432 
433 		target->first_read = true;
434 		target->first_write = true;
435 		break;
436 
437 	default:
438 		LOG_INF("Unhandled event: %d", transfer->event);
439 		break;
440 	}
441 }
442 
mcux_flexcomm_setup_slave_config(const struct device * dev)443 static int mcux_flexcomm_setup_slave_config(const struct device *dev)
444 {
445 	const struct mcux_flexcomm_config *config = dev->config;
446 	struct mcux_flexcomm_data *data = dev->data;
447 	I2C_Type *base = config->base;
448 	uint32_t clock_freq;
449 
450 	/* Get the clock frequency */
451 	if (clock_control_get_rate(config->clock_dev, config->clock_subsys,
452 				   &clock_freq)) {
453 		return -EINVAL;
454 	}
455 
456 	I2C_SlaveInit(base, &data->i2c_cfg, clock_freq);
457 	I2C_SlaveTransferCreateHandle(base, &data->target_handle,
458 			i2c_target_transfer_callback, data);
459 	I2C_SlaveTransferNonBlocking(base, &data->target_handle,
460 			kI2C_SlaveCompletionEvent | kI2C_SlaveTransmitEvent |
461 			kI2C_SlaveReceiveEvent | kI2C_SlaveDeselectedEvent);
462 
463 	return 0;
464 }
465 
mcux_flexcomm_target_register(const struct device * dev,struct i2c_target_config * target_config)466 int mcux_flexcomm_target_register(const struct device *dev,
467 			     struct i2c_target_config *target_config)
468 {
469 	const struct mcux_flexcomm_config *config = dev->config;
470 	struct mcux_flexcomm_data *data = dev->data;
471 	struct mcux_flexcomm_target_data *target;
472 	I2C_Type *base = config->base;
473 
474 	I2C_MasterDeinit(base);
475 
476 	if (!target_config) {
477 		return -EINVAL;
478 	}
479 
480 	target = mcux_flexcomm_find_free_target(data);
481 	if (!target) {
482 		return -EBUSY;
483 	}
484 
485 	target->target_cfg = target_config;
486 	target->target_attached = true;
487 	target->first_read = true;
488 	target->first_write = true;
489 
490 	if (data->nr_targets_attached == 0) {
491 		I2C_SlaveGetDefaultConfig(&data->i2c_cfg);
492 	}
493 
494 	if (mcux_flexcomm_setup_i2c_config_address(data, target, false) < 0) {
495 		return -EINVAL;
496 	}
497 
498 	if (mcux_flexcomm_setup_slave_config(dev) < 0) {
499 		return -EINVAL;
500 	}
501 
502 	data->nr_targets_attached++;
503 	return 0;
504 }
505 
mcux_flexcomm_target_unregister(const struct device * dev,struct i2c_target_config * target_config)506 int mcux_flexcomm_target_unregister(const struct device *dev,
507 			       struct i2c_target_config *target_config)
508 {
509 	const struct mcux_flexcomm_config *config = dev->config;
510 	struct mcux_flexcomm_data *data = dev->data;
511 	struct mcux_flexcomm_target_data *target;
512 	I2C_Type *base = config->base;
513 
514 	target = mcux_flexcomm_find_target_by_address(data, target_config->address);
515 	if (!target || !target->target_attached) {
516 		return -EINVAL;
517 	}
518 
519 	if (mcux_flexcomm_setup_i2c_config_address(data, target, true) < 0) {
520 		return -EINVAL;
521 	}
522 
523 	target->target_cfg = NULL;
524 	target->target_attached = false;
525 
526 	data->nr_targets_attached--;
527 
528 	if (data->nr_targets_attached > 0) {
529 		/* still slaves attached, reconfigure the I2C peripheral after address removal */
530 		if (mcux_flexcomm_setup_slave_config(dev) < 0) {
531 			return -EINVAL;
532 		}
533 
534 	} else {
535 		I2C_SlaveDeinit(base);
536 	}
537 
538 	return 0;
539 }
540 #endif
541 
mcux_flexcomm_isr(const struct device * dev)542 static void mcux_flexcomm_isr(const struct device *dev)
543 {
544 	const struct mcux_flexcomm_config *config = dev->config;
545 	struct mcux_flexcomm_data *data = dev->data;
546 	I2C_Type *base = config->base;
547 
548 #if defined(CONFIG_I2C_TARGET)
549 	if (data->nr_targets_attached > 0) {
550 		I2C_SlaveTransferHandleIRQ(base, &data->target_handle);
551 		return;
552 	}
553 #endif
554 
555 	I2C_MasterTransferHandleIRQ(base, &data->handle);
556 }
557 
mcux_flexcomm_init(const struct device * dev)558 static int mcux_flexcomm_init(const struct device *dev)
559 {
560 	const struct mcux_flexcomm_config *config = dev->config;
561 	struct mcux_flexcomm_data *data = dev->data;
562 	I2C_Type *base = config->base;
563 	uint32_t clock_freq, bitrate_cfg;
564 	i2c_master_config_t master_config;
565 	int error;
566 
567 	if (!device_is_ready(config->reset.dev)) {
568 		LOG_ERR("Reset device not ready");
569 		return -ENODEV;
570 	}
571 
572 	error = reset_line_toggle(config->reset.dev, config->reset.id);
573 	if (error) {
574 		return error;
575 	}
576 
577 	error = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
578 	if (error) {
579 		return error;
580 	}
581 
582 	k_sem_init(&data->lock, 1, 1);
583 	k_sem_init(&data->device_sync_sem, 0, K_SEM_MAX_LIMIT);
584 
585 	if (!device_is_ready(config->clock_dev)) {
586 		LOG_ERR("clock control device not ready");
587 		return -ENODEV;
588 	}
589 
590 	/* Get the clock frequency */
591 	if (clock_control_get_rate(config->clock_dev, config->clock_subsys,
592 				   &clock_freq)) {
593 		return -EINVAL;
594 	}
595 
596 	I2C_MasterGetDefaultConfig(&master_config);
597 	I2C_MasterInit(base, &master_config, clock_freq);
598 	I2C_MasterTransferCreateHandle(base, &data->handle,
599 				       mcux_flexcomm_master_transfer_callback,
600 				       data);
601 
602 	bitrate_cfg = i2c_map_dt_bitrate(config->bitrate);
603 
604 	error = mcux_flexcomm_configure(dev, I2C_MODE_CONTROLLER | bitrate_cfg);
605 	if (error) {
606 		return error;
607 	}
608 
609 	config->irq_config_func(dev);
610 
611 	return 0;
612 }
613 
614 static DEVICE_API(i2c, mcux_flexcomm_driver_api) = {
615 	.configure = mcux_flexcomm_configure,
616 	.transfer = mcux_flexcomm_transfer,
617 #if CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY
618 	.recover_bus = mcux_flexcomm_recover_bus,
619 #endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */
620 #if defined(CONFIG_I2C_TARGET)
621 	.target_register = mcux_flexcomm_target_register,
622 	.target_unregister = mcux_flexcomm_target_unregister,
623 #endif
624 #ifdef CONFIG_I2C_RTIO
625 	.iodev_submit = i2c_iodev_submit_fallback,
626 #endif
627 };
628 
629 #if CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY
630 #define I2C_MCUX_FLEXCOMM_SCL_INIT(n) .scl = GPIO_DT_SPEC_INST_GET_OR(n, scl_gpios, {0}),
631 #define I2C_MCUX_FLEXCOMM_SDA_INIT(n) .sda = GPIO_DT_SPEC_INST_GET_OR(n, sda_gpios, {0}),
632 #else
633 #define I2C_MCUX_FLEXCOMM_SCL_INIT(n)
634 #define I2C_MCUX_FLEXCOMM_SDA_INIT(n)
635 #endif /* CONFIG_I2C_MCUX_FLEXCOMM_BUS_RECOVERY */
636 
637 #define I2C_MCUX_FLEXCOMM_DEVICE(id)					\
638 	PINCTRL_DT_INST_DEFINE(id);					\
639 	static void mcux_flexcomm_config_func_##id(const struct device *dev); \
640 	static const struct mcux_flexcomm_config mcux_flexcomm_config_##id = {	\
641 		.base = (I2C_Type *) DT_INST_REG_ADDR(id),		\
642 		.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)),	\
643 		.clock_subsys =				\
644 		(clock_control_subsys_t)DT_INST_CLOCKS_CELL(id, name),\
645 		.irq_config_func = mcux_flexcomm_config_func_##id,	\
646 		.bitrate = DT_INST_PROP(id, clock_frequency),		\
647 		.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id),		\
648 		I2C_MCUX_FLEXCOMM_SCL_INIT(id)				\
649 		I2C_MCUX_FLEXCOMM_SDA_INIT(id)				\
650 		.reset = RESET_DT_SPEC_INST_GET(id),			\
651 	};								\
652 	static struct mcux_flexcomm_data mcux_flexcomm_data_##id;	\
653 	I2C_DEVICE_DT_INST_DEFINE(id,					\
654 			    mcux_flexcomm_init,				\
655 			    NULL,					\
656 			    &mcux_flexcomm_data_##id,			\
657 			    &mcux_flexcomm_config_##id,			\
658 			    POST_KERNEL,				\
659 			    CONFIG_I2C_INIT_PRIORITY,			\
660 			    &mcux_flexcomm_driver_api);			\
661 	static void mcux_flexcomm_config_func_##id(const struct device *dev) \
662 	{								\
663 		IRQ_CONNECT(DT_INST_IRQN(id),				\
664 			    DT_INST_IRQ(id, priority),			\
665 			    mcux_flexcomm_isr,				\
666 			    DEVICE_DT_INST_GET(id),			\
667 			    0);						\
668 		irq_enable(DT_INST_IRQN(id));				\
669 	}								\
670 
671 DT_INST_FOREACH_STATUS_OKAY(I2C_MCUX_FLEXCOMM_DEVICE)
672