1 /*
2 * Copyright (c) 2016 Freescale Semiconductor, Inc.
3 * Copyright (c) 2019 NXP
4 * Copyright (c) 2022 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #define DT_DRV_COMPAT nxp_mcux_i3c
10
11 #include <string.h>
12
13 #include <zephyr/device.h>
14 #include <zephyr/irq.h>
15 #include <zephyr/sys/__assert.h>
16 #include <zephyr/sys/sys_io.h>
17
18 #include <zephyr/drivers/clock_control.h>
19 #include <zephyr/drivers/i3c.h>
20
21 #include <zephyr/drivers/pinctrl.h>
22
23 /*
24 * This is from NXP HAL which contains register bits macros
25 * which are used in this driver.
26 */
27 #include <fsl_i3c.h>
28
29 #include <zephyr/logging/log.h>
30 LOG_MODULE_REGISTER(i3c_mcux, CONFIG_I3C_MCUX_LOG_LEVEL);
31
32 #define I3C_MCTRL_REQUEST_NONE I3C_MCTRL_REQUEST(0)
33 #define I3C_MCTRL_REQUEST_EMIT_START_ADDR I3C_MCTRL_REQUEST(1)
34 #define I3C_MCTRL_REQUEST_EMIT_STOP I3C_MCTRL_REQUEST(2)
35 #define I3C_MCTRL_REQUEST_IBI_ACK_NACK I3C_MCTRL_REQUEST(3)
36 #define I3C_MCTRL_REQUEST_PROCESS_DAA I3C_MCTRL_REQUEST(4)
37 #define I3C_MCTRL_REQUEST_FORCE_EXIT I3C_MCTRL_REQUEST(6)
38 #define I3C_MCTRL_REQUEST_AUTO_IBI I3C_MCTRL_REQUEST(7)
39
40 #define I3C_MCTRL_IBIRESP_ACK I3C_MCTRL_IBIRESP(0)
41 #define I3C_MCTRL_IBIRESP_ACK_AUTO I3C_MCTRL_IBIRESP(0)
42 #define I3C_MCTRL_IBIRESP_NACK I3C_MCTRL_IBIRESP(1)
43 #define I3C_MCTRL_IBIRESP_ACK_WITH_BYTE I3C_MCTRL_IBIRESP(2)
44 #define I3C_MCTRL_IBIRESP_MANUAL I3C_MCTRL_IBIRESP(3)
45
46 #define I3C_MCTRL_TYPE_I3C I3C_MCTRL_TYPE(0)
47 #define I3C_MCTRL_TYPE_I2C I3C_MCTRL_TYPE(1)
48
49 #define I3C_MCTRL_DIR_WRITE I3C_MCTRL_DIR(0)
50 #define I3C_MCTRL_DIR_READ I3C_MCTRL_DIR(1)
51
52 #define I3C_MSTATUS_STATE_IDLE I3C_MSTATUS_STATE(0)
53 #define I3C_MSTATUS_STATE_SLVREQ I3C_MSTATUS_STATE(1)
54 #define I3C_MSTATUS_STATE_MSGSDR I3C_MSTATUS_STATE(2)
55 #define I3C_MSTATUS_STATE_NORMACT I3C_MSTATUS_STATE(3)
56 #define I3C_MSTATUS_STATE_MSGDDR I3C_MSTATUS_STATE(4)
57 #define I3C_MSTATUS_STATE_DAA I3C_MSTATUS_STATE(5)
58 #define I3C_MSTATUS_STATE_IBIACK I3C_MSTATUS_STATE(6)
59 #define I3C_MSTATUS_STATE_IBIRCV I3C_MSTATUS_STATE(7)
60
61 #define I3C_MSTATUS_IBITYPE_NONE I3C_MSTATUS_IBITYPE(0)
62 #define I3C_MSTATUS_IBITYPE_IBI I3C_MSTATUS_IBITYPE(1)
63 #define I3C_MSTATUS_IBITYPE_MR I3C_MSTATUS_IBITYPE(2)
64 #define I3C_MSTATUS_IBITYPE_HJ I3C_MSTATUS_IBITYPE(3)
65
66 #define I3C_MAX_STOP_RETRIES 5
67
68 struct mcux_i3c_config {
69 /** Common I3C Driver Config */
70 struct i3c_driver_config common;
71
72 /** Pointer to controller registers. */
73 I3C_Type *base;
74
75 /** Pointer to the clock device. */
76 const struct device *clock_dev;
77
78 /** Clock control subsys related struct. */
79 clock_control_subsys_t clock_subsys;
80
81 /** Pointer to pin control device. */
82 const struct pinctrl_dev_config *pincfg;
83
84 /** Interrupt configuration function. */
85 void (*irq_config_func)(const struct device *dev);
86
87 /** Disable open drain high push pull */
88 bool disable_open_drain_high_pp;
89 };
90
91 struct mcux_i3c_data {
92 /** Common I3C Driver Data */
93 struct i3c_driver_data common;
94
95 /** Mutex to serialize access */
96 struct k_mutex lock;
97
98 /** Condvar for waiting for bus to be in IDLE state */
99 struct k_condvar condvar;
100
101 /** I3C open drain clock frequency in Hz. */
102 uint32_t i3c_od_scl_hz;
103
104 #ifdef CONFIG_I3C_USE_IBI
105 struct {
106 /** List of addresses used in the MIBIRULES register. */
107 uint8_t addr[5];
108
109 /** Number of valid addresses in MIBIRULES. */
110 uint8_t num_addr;
111
112 /** True if all addresses have MSB set. */
113 bool msb;
114
115 /**
116 * True if all target devices require mandatory byte
117 * for IBI.
118 */
119 bool has_mandatory_byte;
120 } ibi;
121 #endif
122 };
123
124 /**
125 * @brief Read a register and test for bit matches with timeout.
126 *
127 * Please be aware that this uses @see k_busy_wait.
128 *
129 * @param reg Pointer to 32-bit Register.
130 * @param mask Mask to the register value.
131 * @param match Value to match for masked register value.
132 * @param timeout_us Timeout in microsecond before bailing out.
133 *
134 * @retval 0 If masked register value matches before time out.
135 * @retval -ETIMEDOUT Timedout without matching.
136 */
reg32_poll_timeout(volatile uint32_t * reg,uint32_t mask,uint32_t match,uint32_t timeout_us)137 static int reg32_poll_timeout(volatile uint32_t *reg,
138 uint32_t mask, uint32_t match,
139 uint32_t timeout_us)
140 {
141 /*
142 * These polling checks are typically satisfied
143 * quickly (some sub-microseconds) so no extra
144 * delay between checks.
145 */
146 if (!WAIT_FOR((sys_read32((mm_reg_t)reg) & mask) == match, timeout_us, /*nop*/)) {
147 return -ETIMEDOUT;
148 }
149 return 0;
150 }
151
152 /**
153 * @brief Update register value.
154 *
155 * @param reg Pointer to 32-bit Register.
156 * @param mask Mask to the register value.
157 * @param update Value to be updated in register.
158 */
reg32_update(volatile uint32_t * reg,uint32_t mask,uint32_t update)159 static inline void reg32_update(volatile uint32_t *reg,
160 uint32_t mask, uint32_t update)
161 {
162 uint32_t val = sys_read32((mem_addr_t)reg);
163
164 val &= ~mask;
165 val |= (update & mask);
166
167 sys_write32(val, (mem_addr_t)reg);
168 }
169
170 /**
171 * @brief Test if masked register value has certain value.
172 *
173 * @param reg Pointer to 32-bit register.
174 * @param mask Mask to test.
175 * @param match Value to match.
176 *
177 * @return True if bits in @p mask mask matches @p match, false otherwise.
178 */
reg32_test_match(volatile uint32_t * reg,uint32_t mask,uint32_t match)179 static inline bool reg32_test_match(volatile uint32_t *reg,
180 uint32_t mask, uint32_t match)
181 {
182 uint32_t val = sys_read32((mem_addr_t)reg);
183
184 return (val & mask) == match;
185 }
186
187 /**
188 * @brief Test if masked register value is the same as the mask.
189 *
190 * @param reg Pointer to 32-bit register.
191 * @param mask Mask to test.
192 *
193 * @return True if bits in @p mask are all set, false otherwise.
194 */
reg32_test(volatile uint32_t * reg,uint32_t mask)195 static inline bool reg32_test(volatile uint32_t *reg, uint32_t mask)
196 {
197 return reg32_test_match(reg, mask, mask);
198 }
199
200 /**
201 * @breif Disable all interrupts.
202 *
203 * @param base Pointer to controller registers.
204 *
205 * @return Previous enabled interrupts.
206 */
mcux_i3c_interrupt_disable(I3C_Type * base)207 static uint32_t mcux_i3c_interrupt_disable(I3C_Type *base)
208 {
209 uint32_t intmask = base->MINTSET;
210
211 base->MINTCLR = intmask;
212
213 return intmask;
214 }
215
216 /**
217 * @brief Enable interrupts according to mask.
218 *
219 * @param base Pointer to controller registers.
220 * @param mask Interrupts to be enabled.
221 *
222 */
mcux_i3c_interrupt_enable(I3C_Type * base,uint32_t mask)223 static void mcux_i3c_interrupt_enable(I3C_Type *base, uint32_t mask)
224 {
225 base->MINTSET = mask;
226 }
227
228 /**
229 * @brief Check if there are any errors.
230 *
231 * This checks if MSTATUS has ERRWARN bit set.
232 *
233 * @retval True if there are any errors.
234 * @retval False if no errors.
235 */
mcux_i3c_has_error(I3C_Type * base)236 static bool mcux_i3c_has_error(I3C_Type *base)
237 {
238 uint32_t mstatus, merrwarn;
239
240 mstatus = base->MSTATUS;
241 if ((mstatus & I3C_MSTATUS_ERRWARN_MASK) == I3C_MSTATUS_ERRWARN_MASK) {
242 merrwarn = base->MERRWARN;
243
244 /*
245 * Note that this uses LOG_DBG() for displaying
246 * register values for debugging. In production builds,
247 * printing any error messages should be handled in
248 * callers of this function.
249 */
250 LOG_DBG("ERROR: MSTATUS 0x%08x MERRWARN 0x%08x",
251 mstatus, merrwarn);
252
253 return true;
254 }
255
256 return false;
257 }
258
259 /**
260 * @brief Check if there are any errors, and if one of them is time out error.
261 *
262 * @retval True if controller times out on operation.
263 * @retval False if no time out error.
264 */
mcux_i3c_error_is_timeout(I3C_Type * base)265 static inline bool mcux_i3c_error_is_timeout(I3C_Type *base)
266 {
267 if (mcux_i3c_has_error(base)) {
268 if (reg32_test(&base->MERRWARN, I3C_MERRWARN_TIMEOUT_MASK)) {
269 return true;
270 }
271 }
272
273 return false;
274 }
275
276 /**
277 * @brief Check if there are any errors, and if one of them is NACK.
278 *
279 * NACK is generated when:
280 * 1. Target does not ACK the last used address.
281 * 2. All targets do not ACK on 0x7E.
282 *
283 * @retval True if NACK is received.
284 * @retval False if no NACK error.
285 */
mcux_i3c_error_is_nack(I3C_Type * base)286 static inline bool mcux_i3c_error_is_nack(I3C_Type *base)
287 {
288 if (mcux_i3c_has_error(base)) {
289 if (reg32_test(&base->MERRWARN, I3C_MERRWARN_NACK_MASK)) {
290 return true;
291 }
292 }
293
294 return false;
295 }
296
297 /**
298 * @brief Test if certain bits are set in MSTATUS.
299 *
300 * @param base Pointer to controller registers.
301 * @param mask Bits to be tested.
302 *
303 * @retval True if @p mask bits are set.
304 * @retval False if @p mask bits are not set.
305 */
mcux_i3c_status_is_set(I3C_Type * base,uint32_t mask)306 static inline bool mcux_i3c_status_is_set(I3C_Type *base, uint32_t mask)
307 {
308 return reg32_test(&base->MSTATUS, mask);
309 }
310
311 /**
312 * @brief Spin wait for MSTATUS bit to be set.
313 *
314 * This spins forever for the bits to be set.
315 *
316 * @param base Pointer to controller registers.
317 * @param mask Bits to be tested.
318 */
mcux_i3c_status_wait(I3C_Type * base,uint32_t mask)319 static inline void mcux_i3c_status_wait(I3C_Type *base, uint32_t mask)
320 {
321 /* Wait for bits to be set */
322 while (!mcux_i3c_status_is_set(base, mask)) {
323 k_busy_wait(1);
324 };
325 }
326
327 /**
328 * @brief Wait for MSTATUS bits to be set with time out.
329 *
330 * @param base Pointer to controller registers.
331 * @param mask Bits to be tested.
332 * @param timeout_us Timeout in microsecond before bailing out.
333 *
334 * @retval 0 If bits are set before time out.
335 * @retval -ETIMEDOUT
336 */
mcux_i3c_status_wait_timeout(I3C_Type * base,uint32_t mask,uint32_t timeout_us)337 static inline int mcux_i3c_status_wait_timeout(I3C_Type *base, uint32_t mask,
338 uint32_t timeout_us)
339 {
340 return reg32_poll_timeout(&base->MSTATUS, mask, mask, timeout_us);
341 }
342
343 /**
344 * @brief Clear the MSTATUS bits and wait for them to be cleared.
345 *
346 * This spins forever for the bits to be cleared;
347 *
348 * @param base Pointer to controller registers.
349 * @param mask Bits to be cleared.
350 */
mcux_i3c_status_clear(I3C_Type * base,uint32_t mask)351 static inline void mcux_i3c_status_clear(I3C_Type *base, uint32_t mask)
352 {
353 /* Try to clear bit until it is cleared */
354 while (1) {
355 base->MSTATUS = mask;
356
357 if (!mcux_i3c_status_is_set(base, mask)) {
358 break;
359 }
360
361 k_busy_wait(1);
362 }
363 }
364
365 /**
366 * @brief Clear transfer and IBI related bits in MSTATUS.
367 *
368 * This spins forever for those bits to be cleared;
369 *
370 * @see I3C_MSTATUS_MCTRLDONE_MASK
371 * @see I3C_MSTATUS_COMPLETE_MASK
372 * @see I3C_MSTATUS_IBIWON_MASK
373 * @see I3C_MSTATUS_ERRWARN_MASK
374 *
375 * @param base Pointer to controller registers.
376 */
mcux_i3c_status_clear_all(I3C_Type * base)377 static inline void mcux_i3c_status_clear_all(I3C_Type *base)
378 {
379 uint32_t mask = I3C_MSTATUS_MCTRLDONE_MASK |
380 I3C_MSTATUS_COMPLETE_MASK |
381 I3C_MSTATUS_IBIWON_MASK |
382 I3C_MSTATUS_ERRWARN_MASK;
383
384 mcux_i3c_status_clear(base, mask);
385 }
386
387 /**
388 * @brief Clear the MSTATUS bits and wait for them to be cleared with time out.
389 *
390 * @param base Pointer to controller registers.
391 * @param mask Bits to be cleared.
392 * @param timeout_us Timeout in microsecond before bailing out.
393 *
394 * @retval 0 If bits are cleared before time out.
395 * @retval -ETIMEDOUT
396 */
mcux_i3c_status_clear_timeout(I3C_Type * base,uint32_t mask,uint32_t timeout_us)397 static inline int mcux_i3c_status_clear_timeout(I3C_Type *base, uint32_t mask,
398 uint32_t timeout_us)
399 {
400 bool result;
401
402 base->MSTATUS = mask;
403 /*
404 * Status should clear quickly so no extra delays between
405 * checks. Use the delay_stmt to retry clearing the
406 * status by writing to the MSTATUS register.
407 */
408 result = WAIT_FOR(!mcux_i3c_status_is_set(base, mask), timeout_us, base->MSTATUS = mask);
409 if (!result) {
410 return -ETIMEDOUT;
411 }
412 return 0;
413 }
414
415 /**
416 * @brief Spin wait for MSTATUS bit to be set, and clear it afterwards.
417 *
418 * Note that this spins forever waiting for bits to be set, and
419 * to be cleared.
420 *
421 * @see mcux_i3c_status_wait
422 * @see mcux_i3c_status_clear
423 *
424 * @param base Pointer to controller registers.
425 * @param mask Bits to be set and to be cleared;
426 */
mcux_i3c_status_wait_clear(I3C_Type * base,uint32_t mask)427 static inline void mcux_i3c_status_wait_clear(I3C_Type *base, uint32_t mask)
428 {
429 mcux_i3c_status_wait(base, mask);
430 mcux_i3c_status_clear(base, mask);
431 }
432
433 /**
434 * @brief Wait for MSTATUS bit to be set, and clear it afterwards, with time out.
435 *
436 * @see mcux_i3c_status_wait_timeout
437 * @see mcux_i3c_status_clear_timeout
438 *
439 * @param base Pointer to controller registers.
440 * @param mask Bits to be set and to be cleared.
441 * @param timeout_us Timeout in microsecond before bailing out.
442 *
443 * @retval 0 If masked register value matches before time out.
444 * @retval -ETIMEDOUT Timedout without matching.
445 */
mcux_i3c_status_wait_clear_timeout(I3C_Type * base,uint32_t mask,uint32_t timeout_us)446 static inline int mcux_i3c_status_wait_clear_timeout(I3C_Type *base, uint32_t mask,
447 uint32_t timeout_us)
448 {
449 int ret;
450
451 ret = mcux_i3c_status_wait_timeout(base, mask, timeout_us);
452 if (ret != 0) {
453 goto out;
454 }
455
456 ret = mcux_i3c_status_clear_timeout(base, mask, timeout_us);
457
458 out:
459 return ret;
460 }
461
462 /**
463 * @brief Clear the MERRWARN register.
464 *
465 * @param base Pointer to controller registers.
466 */
mcux_i3c_errwarn_clear_all_nowait(I3C_Type * base)467 static inline void mcux_i3c_errwarn_clear_all_nowait(I3C_Type *base)
468 {
469 base->MERRWARN = base->MERRWARN;
470 }
471
472 /**
473 * @brief Tell controller to start DAA process.
474 *
475 * @param base Pointer to controller registers.
476 */
mcux_i3c_request_daa(I3C_Type * base)477 static inline void mcux_i3c_request_daa(I3C_Type *base)
478 {
479 reg32_update(&base->MCTRL,
480 I3C_MCTRL_REQUEST_MASK | I3C_MCTRL_IBIRESP_MASK | I3C_MCTRL_RDTERM_MASK,
481 I3C_MCTRL_REQUEST_PROCESS_DAA | I3C_MCTRL_IBIRESP_NACK);
482 }
483
484 /**
485 * @brief Tell controller to start auto IBI.
486 *
487 * @param base Pointer to controller registers.
488 */
mcux_i3c_request_auto_ibi(I3C_Type * base)489 static inline void mcux_i3c_request_auto_ibi(I3C_Type *base)
490 {
491 reg32_update(&base->MCTRL,
492 I3C_MCTRL_REQUEST_MASK | I3C_MCTRL_IBIRESP_MASK | I3C_MCTRL_RDTERM_MASK,
493 I3C_MCTRL_REQUEST_AUTO_IBI | I3C_MCTRL_IBIRESP_ACK_AUTO);
494
495 /* AUTO_IBI should result in IBIWON bit being set in status */
496 mcux_i3c_status_wait_clear(base, I3C_MSTATUS_IBIWON_MASK);
497 }
498
499 /**
500 * @brief Get the controller state.
501 *
502 * @param base Pointer to controller registers.
503 *
504 * @retval I3C_MSTATUS_STATE_IDLE
505 * @retval I3C_MSTATUS_STATE_SLVREQ
506 * @retval I3C_MSTATUS_STATE_MSGSDR
507 * @retval I3C_MSTATUS_STATE_NORMACT
508 * @retval I3C_MSTATUS_STATE_MSGDDR
509 * @retval I3C_MSTATUS_STATE_DAA
510 * @retval I3C_MSTATUS_STATE_IBIACK
511 * @retval I3C_MSTATUS_STATE_IBIRCV
512 */
mcux_i3c_state_get(I3C_Type * base)513 static inline uint32_t mcux_i3c_state_get(I3C_Type *base)
514 {
515 uint32_t mstatus = base->MSTATUS;
516 uint32_t state;
517
518 /* Make sure we are in a state where we can emit STOP */
519 state = (mstatus & I3C_MSTATUS_STATE_MASK) >> I3C_MSTATUS_STATE_SHIFT;
520
521 return state;
522 }
523
524 /**
525 * @brief Wait for MSTATUS state
526 *
527 * @param base Pointer to controller registers.
528 * @param state MSTATUS state to wait for.
529 * @param step_delay_us Delay in microsecond between each read of register
530 * (cannot be 0).
531 * @param total_delay_us Total delay in microsecond before bailing out.
532 *
533 * @retval 0 If masked register value matches before time out.
534 * @retval -ETIMEDOUT Exhausted all delays without matching.
535 */
mcux_i3c_state_wait_timeout(I3C_Type * base,uint32_t state,uint32_t step_delay_us,uint32_t total_delay_us)536 static inline int mcux_i3c_state_wait_timeout(I3C_Type *base, uint32_t state,
537 uint32_t step_delay_us,
538 uint32_t total_delay_us)
539 {
540 uint32_t delayed = 0;
541 int ret = -ETIMEDOUT;
542
543 while (delayed <= total_delay_us) {
544 if (mcux_i3c_state_get(base) == state) {
545 ret = 0;
546 break;
547 }
548
549 k_busy_wait(step_delay_us);
550 delayed += step_delay_us;
551 }
552
553 return ret;
554 }
555
556 /**
557 * @brief Wait for MSTATUS to be IDLE
558 *
559 * @param base Pointer to controller registers.
560 */
mcux_i3c_wait_idle(struct mcux_i3c_data * dev_data,I3C_Type * base)561 static inline void mcux_i3c_wait_idle(struct mcux_i3c_data *dev_data, I3C_Type *base)
562 {
563 while (mcux_i3c_state_get(base) != I3C_MSTATUS_STATE_IDLE) {
564 k_condvar_wait(&dev_data->condvar,
565 &dev_data->lock,
566 K_FOREVER);
567 }
568 }
569
570 /**
571 * @brief Tell controller to emit START.
572 *
573 * @param base Pointer to controller registers.
574 * @param addr Target address.
575 * @param is_i2c True if this is I2C transactions, false if I3C.
576 * @param is_read True if this is a read transaction, false if write.
577 * @param read_sz Number of bytes to read if @p is_read is true.
578 *
579 * @return 0 if successful, or negative if error.
580 */
mcux_i3c_request_emit_start(I3C_Type * base,uint8_t addr,bool is_i2c,bool is_read,size_t read_sz)581 static int mcux_i3c_request_emit_start(I3C_Type *base, uint8_t addr, bool is_i2c,
582 bool is_read, size_t read_sz)
583 {
584 uint32_t mctrl;
585 int ret = 0;
586
587 mctrl = is_i2c ? I3C_MCTRL_TYPE_I2C : I3C_MCTRL_TYPE_I3C;
588 mctrl |= I3C_MCTRL_IBIRESP_NACK;
589
590 if (is_read) {
591 mctrl |= I3C_MCTRL_DIR_READ;
592
593 /* How many bytes to read */
594 mctrl |= I3C_MCTRL_RDTERM(read_sz);
595 } else {
596 mctrl |= I3C_MCTRL_DIR_WRITE;
597 }
598
599 mctrl |= I3C_MCTRL_REQUEST_EMIT_START_ADDR | I3C_MCTRL_ADDR(addr);
600
601 base->MCTRL = mctrl;
602
603 /* Wait for controller to say the operation is done */
604 ret = mcux_i3c_status_wait_clear_timeout(base, I3C_MSTATUS_MCTRLDONE_MASK,
605 1000);
606 if (ret == 0) {
607 /* Check for NACK */
608 if (mcux_i3c_error_is_nack(base)) {
609 ret = -ENODEV;
610 }
611 }
612
613 return ret;
614 }
615
616 /**
617 * @brief Tell controller to emit STOP.
618 *
619 * This emits STOP and waits for controller to get out of NORMACT,
620 * checking for errors.
621 *
622 * @param base Pointer to controller registers.
623 * @param wait_stop True if need to wait for controller to be
624 * no longer in NORMACT.
625 */
mcux_i3c_do_request_emit_stop(I3C_Type * base,bool wait_stop)626 static inline int mcux_i3c_do_request_emit_stop(I3C_Type *base, bool wait_stop)
627 {
628 reg32_update(&base->MCTRL,
629 I3C_MCTRL_REQUEST_MASK | I3C_MCTRL_DIR_MASK | I3C_MCTRL_RDTERM_MASK,
630 I3C_MCTRL_REQUEST_EMIT_STOP);
631
632 /*
633 * EMIT_STOP request doesn't result in MCTRLDONE being cleared
634 * so don't wait for it.
635 */
636
637 if (wait_stop) {
638 /*
639 * Note that we don't exactly wait for I3C_MSTATUS_STATE_IDLE.
640 * If there is an incoming IBI, it will get stuck forever
641 * as state would be I3C_MSTATUS_STATE_SLVREQ.
642 */
643 while (reg32_test_match(&base->MSTATUS, I3C_MSTATUS_STATE_MASK,
644 I3C_MSTATUS_STATE_NORMACT)) {
645 if (mcux_i3c_has_error(base)) {
646 /*
647 * A timeout error has been observed on
648 * an EMIT_STOP request. Refman doesn't say
649 * how that could occur but clear it
650 * and return the error.
651 */
652 if (reg32_test(&base->MERRWARN,
653 I3C_MERRWARN_TIMEOUT_MASK)) {
654 mcux_i3c_errwarn_clear_all_nowait(base);
655 return -ETIMEDOUT;
656 }
657 return -EIO;
658 }
659 k_busy_wait(10);
660 }
661 }
662 return 0;
663 }
664
665 /**
666 * @brief Tell controller to emit STOP.
667 *
668 * This emits STOP when controller is in NORMACT state as this is
669 * the only valid state where STOP can be emitted. This also waits
670 * for the controller to get out of NORMACT before returning and
671 * retries if any timeout errors occur during the emit STOP.
672 *
673 * @param dev_data Pointer to device driver data
674 * @param base Pointer to controller registers.
675 * @param wait_stop True if need to wait for controller to be
676 * no longer in NORMACT.
677 */
mcux_i3c_request_emit_stop(struct mcux_i3c_data * dev_data,I3C_Type * base,bool wait_stop)678 static inline void mcux_i3c_request_emit_stop(struct mcux_i3c_data *dev_data,
679 I3C_Type *base, bool wait_stop)
680 {
681 size_t retries;
682
683 /*
684 * Stop is usually the last part of a transfer.
685 * Sometimes, an error occurred before. We want to clear
686 * it so any error as a result of emitting the stop
687 * itself doesn't get incorrectly mixed together.
688 */
689 if (mcux_i3c_has_error(base)) {
690 mcux_i3c_errwarn_clear_all_nowait(base);
691 }
692
693 /* Make sure we are in a state where we can emit STOP */
694 if (!reg32_test_match(&base->MSTATUS, I3C_MSTATUS_STATE_MASK,
695 I3C_MSTATUS_STATE_NORMACT)) {
696 return;
697 }
698
699 retries = 0;
700 while (1) {
701 int err = mcux_i3c_do_request_emit_stop(base, wait_stop);
702
703 if (err) {
704 if ((err == -ETIMEDOUT) && (++retries <= I3C_MAX_STOP_RETRIES)) {
705 LOG_WRN("Timeout on emit stop, retrying");
706 continue;
707 }
708 LOG_ERR("Error waiting for stop");
709 return;
710 }
711 /*
712 * Success. If wait_stop was true, state should now
713 * be IDLE or possibly SLVREQ.
714 */
715 if (retries) {
716 LOG_WRN("EMIT_STOP succeeded on %u retries", retries);
717 }
718 break;
719 }
720
721 /* Release any threads that might have been blocked waiting for IDLE */
722 k_condvar_broadcast(&dev_data->condvar);
723 }
724
725 /**
726 * @brief Tell controller to NACK the incoming IBI.
727 *
728 * @param base Pointer to controller registers.
729 */
mcux_i3c_ibi_respond_nack(I3C_Type * base)730 static inline void mcux_i3c_ibi_respond_nack(I3C_Type *base)
731 {
732 reg32_update(&base->MCTRL,
733 I3C_MCTRL_REQUEST_MASK | I3C_MCTRL_IBIRESP_MASK,
734 I3C_MCTRL_REQUEST_IBI_ACK_NACK | I3C_MCTRL_IBIRESP_NACK);
735
736 mcux_i3c_status_wait_clear(base, I3C_MSTATUS_MCTRLDONE_MASK);
737 }
738
739 /**
740 * @brief Tell controller to ACK the incoming IBI.
741 *
742 * @param base Pointer to controller registers.
743 */
mcux_i3c_ibi_respond_ack(I3C_Type * base)744 static inline void mcux_i3c_ibi_respond_ack(I3C_Type *base)
745 {
746 reg32_update(&base->MCTRL,
747 I3C_MCTRL_REQUEST_MASK | I3C_MCTRL_IBIRESP_MASK,
748 I3C_MCTRL_REQUEST_IBI_ACK_NACK | I3C_MCTRL_IBIRESP_ACK);
749
750 mcux_i3c_status_wait_clear(base, I3C_MSTATUS_MCTRLDONE_MASK);
751 }
752
753 /**
754 * @brief Get the number of bytes in RX FIFO.
755 *
756 * This returns the number of bytes in RX FIFO which
757 * can be read.
758 *
759 * @param base Pointer to controller registers.
760 *
761 * @return Number of bytes in RX FIFO.
762 */
mcux_i3c_fifo_rx_count_get(I3C_Type * base)763 static inline int mcux_i3c_fifo_rx_count_get(I3C_Type *base)
764 {
765 uint32_t mdatactrl = base->MDATACTRL;
766
767 return (int)((mdatactrl & I3C_MDATACTRL_RXCOUNT_MASK) >> I3C_MDATACTRL_RXCOUNT_SHIFT);
768 }
769
770 /**
771 * @brief Tell controller to flush both TX and RX FIFOs.
772 *
773 * @param base Pointer to controller registers.
774 */
mcux_i3c_fifo_flush(I3C_Type * base)775 static inline void mcux_i3c_fifo_flush(I3C_Type *base)
776 {
777 base->MDATACTRL = I3C_MDATACTRL_FLUSHFB_MASK | I3C_MDATACTRL_FLUSHTB_MASK;
778 }
779
780 /**
781 * @brief Prepare the controller for transfers.
782 *
783 * This is simply a wrapper to clear out status bits,
784 * and error bits. Also this tells the controller to
785 * flush both TX and RX FIFOs.
786 *
787 * @param base Pointer to controller registers.
788 */
mcux_i3c_xfer_reset(I3C_Type * base)789 static inline void mcux_i3c_xfer_reset(I3C_Type *base)
790 {
791 mcux_i3c_status_clear_all(base);
792 mcux_i3c_errwarn_clear_all_nowait(base);
793 mcux_i3c_fifo_flush(base);
794 }
795
796 /**
797 * @brief Drain RX FIFO.
798 *
799 * @param dev Pointer to controller device driver instance.
800 */
mcux_i3c_fifo_rx_drain(const struct device * dev)801 static void mcux_i3c_fifo_rx_drain(const struct device *dev)
802 {
803 const struct mcux_i3c_config *config = dev->config;
804 I3C_Type *base = config->base;
805 uint8_t buf;
806
807 /* Read from FIFO as long as RXPEND is set. */
808 while (mcux_i3c_status_is_set(base, I3C_MSTATUS_RXPEND_MASK)) {
809 buf = base->MRDATAB;
810 }
811 }
812
813 /**
814 * @brief Find a registered I3C target device.
815 *
816 * This returns the I3C device descriptor of the I3C device
817 * matching the incoming @p id.
818 *
819 * @param dev Pointer to controller device driver instance.
820 * @param id Pointer to I3C device ID.
821 *
822 * @return @see i3c_device_find.
823 */
824 static
mcux_i3c_device_find(const struct device * dev,const struct i3c_device_id * id)825 struct i3c_device_desc *mcux_i3c_device_find(const struct device *dev,
826 const struct i3c_device_id *id)
827 {
828 const struct mcux_i3c_config *config = dev->config;
829
830 return i3c_dev_list_find(&config->common.dev_list, id);
831 }
832
833 /**
834 * @brief Perform bus recovery.
835 *
836 * @param dev Pointer to controller device driver instance.
837 */
mcux_i3c_recover_bus(const struct device * dev)838 static int mcux_i3c_recover_bus(const struct device *dev)
839 {
840 const struct mcux_i3c_config *config = dev->config;
841 I3C_Type *base = config->base;
842 int ret = 0;
843
844 /*
845 * If the controller is in NORMACT state, tells it to emit STOP
846 * so it can return to IDLE, or is ready to clear any pending
847 * target initiated IBIs.
848 */
849 if (mcux_i3c_state_get(base) == I3C_MSTATUS_STATE_NORMACT) {
850 mcux_i3c_request_emit_stop(dev->data, base, true);
851 };
852
853 /* Exhaust all target initiated IBI */
854 while (mcux_i3c_status_is_set(base, I3C_MSTATUS_SLVSTART_MASK)) {
855 /* Tell the controller to perform auto IBI. */
856 mcux_i3c_request_auto_ibi(base);
857
858 if (mcux_i3c_status_wait_clear_timeout(base, I3C_MSTATUS_COMPLETE_MASK,
859 1000) == -ETIMEDOUT) {
860 break;
861 }
862
863 /* Once auto IBI is done, discard bytes in FIFO. */
864 mcux_i3c_fifo_rx_drain(dev);
865
866 /*
867 * There might be other IBIs waiting.
868 * So pause a bit to let other targets initiates
869 * their IBIs.
870 */
871 k_busy_wait(100);
872 }
873
874 if (reg32_poll_timeout(&base->MSTATUS, I3C_MSTATUS_STATE_MASK,
875 I3C_MSTATUS_STATE_IDLE, 1000) == -ETIMEDOUT) {
876 ret = -EBUSY;
877 }
878
879 return ret;
880 }
881
882 /**
883 * @brief Perform one read transaction.
884 *
885 * This reads from RX FIFO until COMPLETE bit is set in MSTATUS
886 * or time out.
887 *
888 * @param base Pointer to controller registers.
889 * @param buf Buffer to store data.
890 * @param buf_sz Buffer size in bytes.
891 *
892 * @return Number of bytes read, or negative if error.
893 */
mcux_i3c_do_one_xfer_read(I3C_Type * base,uint8_t * buf,uint8_t buf_sz,bool ibi)894 static int mcux_i3c_do_one_xfer_read(I3C_Type *base, uint8_t *buf, uint8_t buf_sz, bool ibi)
895 {
896 int ret = 0;
897 int offset = 0;
898
899 while (offset < buf_sz) {
900 /*
901 * Transfer data from FIFO into buffer. Read
902 * in a tight loop to reduce chance of losing
903 * FIFO data when the i3c speed is high.
904 */
905 while (offset < buf_sz) {
906 if (mcux_i3c_fifo_rx_count_get(base) == 0) {
907 break;
908 }
909 buf[offset++] = (uint8_t)base->MRDATAB;
910 }
911
912 /*
913 * If controller says timed out, we abort the transaction.
914 */
915 if (mcux_i3c_has_error(base)) {
916 if (mcux_i3c_error_is_timeout(base)) {
917 ret = -ETIMEDOUT;
918 }
919 /* clear error */
920 base->MERRWARN = base->MERRWARN;
921
922 /* for ibi, ignore timeout err if any bytes were
923 * read, since the code doesn't know how many
924 * bytes will be sent by device. for regular
925 * application read request, return err always.
926 */
927 if ((ret == -ETIMEDOUT) && ibi && offset) {
928 break;
929 } else {
930 if (ret == -ETIMEDOUT) {
931 LOG_ERR("Timeout error");
932 }
933 goto one_xfer_read_out;
934 }
935 }
936 }
937
938 ret = offset;
939
940 one_xfer_read_out:
941 return ret;
942 }
943
944 /**
945 * @brief Perform one write transaction.
946 *
947 * This writes all data in @p buf to TX FIFO or time out
948 * waiting for FIFO spaces.
949 *
950 * @param base Pointer to controller registers.
951 * @param buf Buffer containing data to be sent.
952 * @param buf_sz Number of bytes in @p buf to send.
953 * @param no_ending True if not to signal end of write message.
954 *
955 * @return Number of bytes written, or negative if error.
956 */
mcux_i3c_do_one_xfer_write(I3C_Type * base,uint8_t * buf,uint8_t buf_sz,bool no_ending)957 static int mcux_i3c_do_one_xfer_write(I3C_Type *base, uint8_t *buf, uint8_t buf_sz, bool no_ending)
958 {
959 int offset = 0;
960 int remaining = buf_sz;
961 int ret = 0;
962
963 while (remaining > 0) {
964 ret = reg32_poll_timeout(&base->MDATACTRL, I3C_MDATACTRL_TXFULL_MASK, 0, 1000);
965 if (ret == -ETIMEDOUT) {
966 goto one_xfer_write_out;
967 }
968
969 if ((remaining > 1) || no_ending) {
970 base->MWDATAB = (uint32_t)buf[offset];
971 } else {
972 base->MWDATABE = (uint32_t)buf[offset];
973 }
974
975 offset += 1;
976 remaining -= 1;
977 }
978
979 ret = offset;
980
981 one_xfer_write_out:
982 return ret;
983 }
984
985 /**
986 * @brief Perform one transfer transaction.
987 *
988 * @param base Pointer to controller registers.
989 * @param data Pointer to controller device instance data.
990 * @param addr Target address.
991 * @param is_i2c True if this is I2C transactions, false if I3C.
992 * @param buf Buffer for data to be sent or received.
993 * @param buf_sz Buffer size in bytes.
994 * @param is_read True if this is a read transaction, false if write.
995 * @param emit_start True if START is needed before read/write.
996 * @param emit_stop True if STOP is needed after read/write.
997 * @param no_ending True if not to signal end of write message.
998 *
999 * @return Number of bytes read/written, or negative if error.
1000 */
mcux_i3c_do_one_xfer(I3C_Type * base,struct mcux_i3c_data * data,uint8_t addr,bool is_i2c,uint8_t * buf,size_t buf_sz,bool is_read,bool emit_start,bool emit_stop,bool no_ending)1001 static int mcux_i3c_do_one_xfer(I3C_Type *base, struct mcux_i3c_data *data,
1002 uint8_t addr, bool is_i2c,
1003 uint8_t *buf, size_t buf_sz,
1004 bool is_read, bool emit_start, bool emit_stop,
1005 bool no_ending)
1006 {
1007 int ret = 0;
1008
1009 mcux_i3c_status_clear_all(base);
1010 mcux_i3c_errwarn_clear_all_nowait(base);
1011
1012 /* Emit START if so desired */
1013 if (emit_start) {
1014 ret = mcux_i3c_request_emit_start(base, addr, is_i2c, is_read, buf_sz);
1015 if (ret != 0) {
1016 emit_stop = true;
1017
1018 goto out_one_xfer;
1019 }
1020 }
1021
1022 if ((buf == NULL) || (buf_sz == 0)) {
1023 goto out_one_xfer;
1024 }
1025
1026 if (is_read) {
1027 ret = mcux_i3c_do_one_xfer_read(base, buf, buf_sz, false);
1028 } else {
1029 ret = mcux_i3c_do_one_xfer_write(base, buf, buf_sz, no_ending);
1030 }
1031
1032 if (ret < 0) {
1033 goto out_one_xfer;
1034 }
1035
1036 if (is_read || !no_ending) {
1037 /*
1038 * Wait for controller to say the operation is done.
1039 * Save time by not clearing the bit.
1040 */
1041 ret = mcux_i3c_status_wait_timeout(base, I3C_MSTATUS_COMPLETE_MASK, 1000);
1042 if (ret != 0) {
1043 LOG_DBG("%s: timed out addr 0x%02x, buf_sz %u",
1044 __func__, addr, buf_sz);
1045 emit_stop = true;
1046
1047 goto out_one_xfer;
1048 }
1049 }
1050
1051 if (mcux_i3c_has_error(base)) {
1052 ret = -EIO;
1053 }
1054
1055 out_one_xfer:
1056 if (emit_stop) {
1057 mcux_i3c_request_emit_stop(data, base, true);
1058 }
1059
1060 return ret;
1061 }
1062
1063 /**
1064 * @brief Transfer messages in I3C mode.
1065 *
1066 * @see i3c_transfer
1067 *
1068 * @param dev Pointer to device driver instance.
1069 * @param target Pointer to target device descriptor.
1070 * @param msgs Pointer to I3C messages.
1071 * @param num_msgs Number of messages to transfers.
1072 *
1073 * @return @see i3c_transfer
1074 */
mcux_i3c_transfer(const struct device * dev,struct i3c_device_desc * target,struct i3c_msg * msgs,uint8_t num_msgs)1075 static int mcux_i3c_transfer(const struct device *dev,
1076 struct i3c_device_desc *target,
1077 struct i3c_msg *msgs,
1078 uint8_t num_msgs)
1079 {
1080 const struct mcux_i3c_config *config = dev->config;
1081 struct mcux_i3c_data *dev_data = dev->data;
1082 I3C_Type *base = config->base;
1083 int ret;
1084 bool send_broadcast = true;
1085
1086 if (target->dynamic_addr == 0U) {
1087 ret = -EINVAL;
1088 goto out_xfer_i3c;
1089 }
1090
1091 k_mutex_lock(&dev_data->lock, K_FOREVER);
1092
1093 mcux_i3c_wait_idle(dev_data, base);
1094
1095 mcux_i3c_xfer_reset(base);
1096
1097 /* Iterate over all the messages */
1098 for (int i = 0; i < num_msgs; i++) {
1099 bool is_read = (msgs[i].flags & I3C_MSG_RW_MASK) == I3C_MSG_READ;
1100 bool no_ending = false;
1101
1102 /*
1103 * Emit start if this is the first message or that
1104 * the RESTART flag is set in message.
1105 */
1106 bool emit_start = (i == 0) ||
1107 ((msgs[i].flags & I3C_MSG_RESTART) == I3C_MSG_RESTART);
1108
1109 bool emit_stop = (msgs[i].flags & I3C_MSG_STOP) == I3C_MSG_STOP;
1110
1111 /*
1112 * The controller requires special treatment of last byte of
1113 * a write message. Since the API permits having a bunch of
1114 * write messages without RESTART in between, this is just some
1115 * logic to determine whether to treat the last byte of this
1116 * message to be the last byte of a series of write mssages.
1117 * If not, tell the write function not to treat it that way.
1118 */
1119 if (!is_read && !emit_stop && ((i + 1) != num_msgs)) {
1120 bool next_is_write =
1121 (msgs[i + 1].flags & I3C_MSG_RW_MASK) == I3C_MSG_WRITE;
1122 bool next_is_restart =
1123 ((msgs[i + 1].flags & I3C_MSG_RESTART) == I3C_MSG_RESTART);
1124
1125 if (next_is_write && !next_is_restart) {
1126 no_ending = true;
1127 }
1128 }
1129
1130 /*
1131 * Send broadcast header on first transfer or after a STOP,
1132 * unless flag is set not to.
1133 */
1134 if (!(msgs[i].flags & I3C_MSG_NBCH) && (send_broadcast)) {
1135 while (1) {
1136 ret = mcux_i3c_request_emit_start(base, I3C_BROADCAST_ADDR,
1137 false, false, 0);
1138 if (ret == -ENODEV) {
1139 LOG_WRN("emit start of broadcast addr got NACK, maybe IBI");
1140 /* wait for idle then try again */
1141 mcux_i3c_wait_idle(dev_data, base);
1142 continue;
1143 }
1144 if (ret < 0) {
1145 LOG_ERR("emit start of broadcast addr failed, error (%d)",
1146 ret);
1147 goto out_xfer_i3c_stop_unlock;
1148 }
1149 break;
1150 }
1151 send_broadcast = false;
1152 }
1153
1154 ret = mcux_i3c_do_one_xfer(base, dev_data, target->dynamic_addr, false,
1155 msgs[i].buf, msgs[i].len,
1156 is_read, emit_start, emit_stop, no_ending);
1157 if (ret < 0) {
1158 goto out_xfer_i3c_stop_unlock;
1159 }
1160
1161 /* write back the total number of bytes transferred */
1162 msgs[i].num_xfer = ret;
1163
1164 if (emit_stop) {
1165 /* After a STOP, send broadcast header before next msg */
1166 send_broadcast = true;
1167 }
1168 }
1169
1170 ret = 0;
1171
1172 out_xfer_i3c_stop_unlock:
1173 mcux_i3c_request_emit_stop(dev_data, base, true);
1174 mcux_i3c_errwarn_clear_all_nowait(base);
1175 mcux_i3c_status_clear_all(base);
1176 k_mutex_unlock(&dev_data->lock);
1177
1178 out_xfer_i3c:
1179
1180 return ret;
1181 }
1182
1183 /**
1184 * @brief Perform Dynamic Address Assignment.
1185 *
1186 * @see i3c_do_daa
1187 *
1188 * @param dev Pointer to controller device driver instance.
1189 *
1190 * @return @see i3c_do_daa
1191 */
mcux_i3c_do_daa(const struct device * dev)1192 static int mcux_i3c_do_daa(const struct device *dev)
1193 {
1194 const struct mcux_i3c_config *config = dev->config;
1195 struct mcux_i3c_data *data = dev->data;
1196 I3C_Type *base = config->base;
1197 int ret = 0;
1198 uint8_t rx_buf[8] = {0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
1199 size_t rx_count;
1200 uint8_t rx_size = 0;
1201 uint32_t intmask;
1202
1203 k_mutex_lock(&data->lock, K_FOREVER);
1204
1205 ret = mcux_i3c_state_wait_timeout(base, I3C_MSTATUS_STATE_IDLE, 100, 100000);
1206 if (ret == -ETIMEDOUT) {
1207 goto out_daa_unlock;
1208 }
1209
1210 LOG_DBG("DAA: ENTDAA");
1211
1212 /* Disable I3C IRQ sources while we configure stuff. */
1213 intmask = mcux_i3c_interrupt_disable(base);
1214
1215 mcux_i3c_xfer_reset(base);
1216
1217 /* Emit process DAA */
1218 mcux_i3c_request_daa(base);
1219
1220 /* Loop until no more responses from devices */
1221 do {
1222 /* Loop to grab data from devices (Provisioned ID, BCR and DCR) */
1223 do {
1224 if (mcux_i3c_has_error(base)) {
1225 LOG_ERR("DAA recv error");
1226
1227 ret = -EIO;
1228
1229 goto out_daa;
1230 }
1231
1232 rx_count = mcux_i3c_fifo_rx_count_get(base);
1233 while (mcux_i3c_status_is_set(base, I3C_MSTATUS_RXPEND_MASK) &&
1234 (rx_count != 0U)) {
1235 rx_buf[rx_size] = (uint8_t)(base->MRDATAB &
1236 I3C_MRDATAB_VALUE_MASK);
1237 rx_size++;
1238 rx_count--;
1239 }
1240 } while (!mcux_i3c_status_is_set(base, I3C_MSTATUS_MCTRLDONE_MASK));
1241
1242 mcux_i3c_status_clear(base, I3C_MSTATUS_MCTRLDONE_MASK);
1243
1244 /* Figure out what address to assign to device */
1245 if ((mcux_i3c_state_get(base) == I3C_MSTATUS_STATE_DAA) &&
1246 (mcux_i3c_status_is_set(base, I3C_MSTATUS_BETWEEN_MASK))) {
1247 struct i3c_device_desc *target;
1248 uint16_t vendor_id;
1249 uint32_t part_no;
1250 uint64_t pid;
1251 uint8_t dyn_addr;
1252
1253 rx_size = 0;
1254
1255 /* Vendor ID portion of Provisioned ID */
1256 vendor_id = (((uint16_t)rx_buf[0] << 8U) | (uint16_t)rx_buf[1]) &
1257 0xFFFEU;
1258
1259 /* Part Number portion of Provisioned ID */
1260 part_no = (uint32_t)rx_buf[2] << 24U | (uint32_t)rx_buf[3] << 16U |
1261 (uint32_t)rx_buf[4] << 8U | (uint32_t)rx_buf[5];
1262
1263 /* ... and combine into one Provisioned ID */
1264 pid = (uint64_t)vendor_id << 32U | (uint64_t)part_no;
1265
1266 LOG_DBG("DAA: Rcvd PID 0x%04x%08x", vendor_id, part_no);
1267
1268 ret = i3c_dev_list_daa_addr_helper(&data->common.attached_dev.addr_slots,
1269 &config->common.dev_list, pid,
1270 false, false,
1271 &target, &dyn_addr);
1272 if (ret != 0) {
1273 goto out_daa;
1274 }
1275
1276 /* Update target descriptor */
1277 target->dynamic_addr = dyn_addr;
1278 target->bcr = rx_buf[6];
1279 target->dcr = rx_buf[7];
1280
1281 /* Mark the address as I3C device */
1282 i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, dyn_addr);
1283
1284 /*
1285 * If the device has static address, after address assignment,
1286 * the device will not respond to the static address anymore.
1287 * So free the static one from address slots if different from
1288 * newly assigned one.
1289 */
1290 if ((target->static_addr != 0U) && (dyn_addr != target->static_addr)) {
1291 i3c_addr_slots_mark_free(&data->common.attached_dev.addr_slots,
1292 dyn_addr);
1293 }
1294
1295 /* Emit process DAA again to send the address to the device */
1296 base->MWDATAB = dyn_addr;
1297 mcux_i3c_request_daa(base);
1298
1299 LOG_DBG("PID 0x%04x%08x assigned dynamic address 0x%02x",
1300 vendor_id, part_no, dyn_addr);
1301 }
1302
1303 } while (!mcux_i3c_status_is_set(base, I3C_MSTATUS_COMPLETE_MASK));
1304
1305 out_daa:
1306 /* Clear all flags. */
1307 mcux_i3c_errwarn_clear_all_nowait(base);
1308 mcux_i3c_status_clear_all(base);
1309
1310 /* Re-Enable I3C IRQ sources. */
1311 mcux_i3c_interrupt_enable(base, intmask);
1312
1313 out_daa_unlock:
1314 k_mutex_unlock(&data->lock);
1315
1316 return ret;
1317 }
1318
1319 /**
1320 * @brief Send Common Command Code (CCC).
1321 *
1322 * @see i3c_do_ccc
1323 *
1324 * @param dev Pointer to controller device driver instance.
1325 * @param payload Pointer to CCC payload.
1326 *
1327 * @return @see i3c_do_ccc
1328 */
mcux_i3c_do_ccc(const struct device * dev,struct i3c_ccc_payload * payload)1329 static int mcux_i3c_do_ccc(const struct device *dev,
1330 struct i3c_ccc_payload *payload)
1331 {
1332 const struct mcux_i3c_config *config = dev->config;
1333 struct mcux_i3c_data *data = dev->data;
1334 I3C_Type *base = config->base;
1335 int ret = 0;
1336
1337 if (payload == NULL) {
1338 return -EINVAL;
1339 }
1340
1341 if (config->common.dev_list.num_i3c == 0) {
1342 /*
1343 * No i3c devices in dev tree. Just return so
1344 * we don't get errors doing cmds when there
1345 * are no devices listening/responding.
1346 */
1347 return 0;
1348 }
1349
1350 k_mutex_lock(&data->lock, K_FOREVER);
1351
1352 mcux_i3c_xfer_reset(base);
1353
1354 LOG_DBG("CCC[0x%02x]", payload->ccc.id);
1355
1356 /* Emit START */
1357 ret = mcux_i3c_request_emit_start(base, I3C_BROADCAST_ADDR, false, false, 0);
1358 if (ret < 0) {
1359 LOG_ERR("CCC[0x%02x] %s START error (%d)",
1360 payload->ccc.id,
1361 i3c_ccc_is_payload_broadcast(payload) ? "broadcast" : "direct",
1362 ret);
1363
1364 goto out_ccc_stop;
1365 }
1366
1367 /* Write the CCC code */
1368 mcux_i3c_status_clear_all(base);
1369 mcux_i3c_errwarn_clear_all_nowait(base);
1370 ret = mcux_i3c_do_one_xfer_write(base, &payload->ccc.id, 1,
1371 payload->ccc.data_len > 0);
1372 if (ret < 0) {
1373 LOG_ERR("CCC[0x%02x] %s command error (%d)",
1374 payload->ccc.id,
1375 i3c_ccc_is_payload_broadcast(payload) ? "broadcast" : "direct",
1376 ret);
1377
1378 goto out_ccc_stop;
1379 }
1380
1381 /* Write additional data for CCC if needed */
1382 if (payload->ccc.data_len > 0) {
1383 mcux_i3c_status_clear_all(base);
1384 mcux_i3c_errwarn_clear_all_nowait(base);
1385 ret = mcux_i3c_do_one_xfer_write(base, payload->ccc.data,
1386 payload->ccc.data_len, false);
1387 if (ret < 0) {
1388 LOG_ERR("CCC[0x%02x] %s command payload error (%d)",
1389 payload->ccc.id,
1390 i3c_ccc_is_payload_broadcast(payload) ? "broadcast" : "direct",
1391 ret);
1392
1393 goto out_ccc_stop;
1394 }
1395
1396 /* write back the total number of bytes transferred */
1397 payload->ccc.num_xfer = ret;
1398 }
1399
1400 /* Wait for controller to say the operation is done */
1401 ret = mcux_i3c_status_wait_clear_timeout(base, I3C_MSTATUS_COMPLETE_MASK, 1000);
1402 if (ret != 0) {
1403 goto out_ccc_stop;
1404 }
1405
1406 if (!i3c_ccc_is_payload_broadcast(payload)) {
1407 /*
1408 * If there are payload(s) for each target,
1409 * RESTART and then send payload for each target.
1410 */
1411 for (int idx = 0; idx < payload->targets.num_targets; idx++) {
1412 struct i3c_ccc_target_payload *tgt_payload =
1413 &payload->targets.payloads[idx];
1414
1415 bool is_read = tgt_payload->rnw == 1U;
1416 bool emit_start = idx == 0;
1417
1418 ret = mcux_i3c_do_one_xfer(base, data,
1419 tgt_payload->addr, false,
1420 tgt_payload->data,
1421 tgt_payload->data_len,
1422 is_read, emit_start, false, false);
1423 if (ret < 0) {
1424 LOG_ERR("CCC[0x%02x] target payload error (%d)",
1425 payload->ccc.id, ret);
1426
1427 goto out_ccc_stop;
1428 }
1429
1430 /* write back the total number of bytes transferred */
1431 tgt_payload->num_xfer = ret;
1432 }
1433 }
1434
1435 out_ccc_stop:
1436 mcux_i3c_request_emit_stop(data, base, true);
1437
1438 if (ret > 0) {
1439 ret = 0;
1440 }
1441
1442 k_mutex_unlock(&data->lock);
1443
1444 return ret;
1445 }
1446
1447 #ifdef CONFIG_I3C_USE_IBI
1448 /**
1449 * @brief Callback to service target initiated IBIs.
1450 *
1451 * @param work Pointer to k_work item.
1452 */
mcux_i3c_ibi_work(struct k_work * work)1453 static void mcux_i3c_ibi_work(struct k_work *work)
1454 {
1455 uint8_t payload[CONFIG_I3C_IBI_MAX_PAYLOAD_SIZE];
1456 size_t payload_sz = 0;
1457
1458 struct i3c_ibi_work *i3c_ibi_work = CONTAINER_OF(work, struct i3c_ibi_work, work);
1459 const struct device *dev = i3c_ibi_work->controller;
1460 const struct mcux_i3c_config *config = dev->config;
1461 struct mcux_i3c_data *data = dev->data;
1462 I3C_Type *base = config->base;
1463 struct i3c_device_desc *target = NULL;
1464 uint32_t mstatus, ibitype, ibiaddr;
1465 int ret;
1466
1467 k_mutex_lock(&data->lock, K_FOREVER);
1468
1469 if (mcux_i3c_state_get(base) != I3C_MSTATUS_STATE_SLVREQ) {
1470 LOG_DBG("IBI work %p running not because of IBI", work);
1471 LOG_DBG("MSTATUS 0x%08x MERRWARN 0x%08x",
1472 base->MSTATUS, base->MERRWARN);
1473 mcux_i3c_request_emit_stop(data, base, true);
1474
1475 goto out_ibi_work;
1476 };
1477
1478 /* Use auto IBI to service the IBI */
1479 mcux_i3c_request_auto_ibi(base);
1480
1481 mstatus = sys_read32((mem_addr_t)&base->MSTATUS);
1482 ibiaddr = (mstatus & I3C_MSTATUS_IBIADDR_MASK) >> I3C_MSTATUS_IBIADDR_SHIFT;
1483
1484 /*
1485 * Note that the I3C_MSTATUS_IBI_TYPE_* are not shifted right.
1486 * So no need to shift here.
1487 */
1488 ibitype = (mstatus & I3C_MSTATUS_IBITYPE_MASK);
1489
1490 /*
1491 * Wait for COMPLETE bit to be set to indicate auto IBI
1492 * has finished for hot-join and controller role request.
1493 * For target interrupts, the IBI payload may be longer
1494 * than the RX FIFO so we won't get the COMPLETE bit set
1495 * at the first round of data read. So checking of
1496 * COMPLETE bit is deferred to the reading.
1497 */
1498 switch (ibitype) {
1499 case I3C_MSTATUS_IBITYPE_HJ:
1500 __fallthrough;
1501
1502 case I3C_MSTATUS_IBITYPE_MR:
1503 if (mcux_i3c_status_wait_timeout(base, I3C_MSTATUS_COMPLETE_MASK,
1504 1000) == -ETIMEDOUT) {
1505 LOG_ERR("Timeout waiting for COMPLETE");
1506
1507 mcux_i3c_request_emit_stop(data, base, true);
1508
1509 goto out_ibi_work;
1510 }
1511 break;
1512
1513 default:
1514 break;
1515 };
1516
1517 switch (ibitype) {
1518 case I3C_MSTATUS_IBITYPE_IBI:
1519 target = i3c_dev_list_i3c_addr_find(dev, (uint8_t)ibiaddr);
1520 if (target != NULL) {
1521 ret = mcux_i3c_do_one_xfer_read(base, &payload[0],
1522 sizeof(payload), true);
1523 if (ret >= 0) {
1524 payload_sz = (size_t)ret;
1525 } else {
1526 LOG_ERR("Error reading IBI payload");
1527
1528 mcux_i3c_request_emit_stop(data, base, true);
1529
1530 goto out_ibi_work;
1531 }
1532 } else {
1533 LOG_ERR("IBI from unknown device addr 0x%x", ibiaddr);
1534 /* NACK IBI coming from unknown device */
1535 mcux_i3c_ibi_respond_nack(base);
1536 }
1537 break;
1538 case I3C_MSTATUS_IBITYPE_HJ:
1539 mcux_i3c_ibi_respond_ack(base);
1540 break;
1541 case I3C_MSTATUS_IBITYPE_MR:
1542 LOG_DBG("Controller role handoff not supported");
1543 mcux_i3c_ibi_respond_nack(base);
1544 break;
1545 default:
1546 break;
1547 }
1548
1549 if (mcux_i3c_has_error(base)) {
1550 /*
1551 * If the controller detects any errors, simply
1552 * emit a STOP to abort the IBI. The target will
1553 * raise IBI again if so desired.
1554 */
1555 mcux_i3c_request_emit_stop(data, base, true);
1556
1557 goto out_ibi_work;
1558 }
1559
1560 switch (ibitype) {
1561 case I3C_MSTATUS_IBITYPE_IBI:
1562 if (target != NULL) {
1563 if (i3c_ibi_work_enqueue_target_irq(target,
1564 &payload[0], payload_sz) != 0) {
1565 LOG_ERR("Error enqueue IBI IRQ work");
1566 }
1567 }
1568
1569 /* Finishing the IBI transaction */
1570 mcux_i3c_request_emit_stop(data, base, true);
1571 break;
1572 case I3C_MSTATUS_IBITYPE_HJ:
1573 if (i3c_ibi_work_enqueue_hotjoin(dev) != 0) {
1574 LOG_ERR("Error enqueue IBI HJ work");
1575 }
1576 break;
1577 case I3C_MSTATUS_IBITYPE_MR:
1578 break;
1579 default:
1580 break;
1581 }
1582
1583 out_ibi_work:
1584 k_mutex_unlock(&data->lock);
1585
1586 /* Re-enable target initiated IBI interrupt. */
1587 base->MINTSET = I3C_MINTSET_SLVSTART_MASK;
1588 }
1589
mcux_i3c_ibi_rules_setup(struct mcux_i3c_data * data,I3C_Type * base)1590 static void mcux_i3c_ibi_rules_setup(struct mcux_i3c_data *data,
1591 I3C_Type *base)
1592 {
1593 uint32_t ibi_rules;
1594 int idx;
1595
1596 ibi_rules = 0;
1597
1598 for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) {
1599 uint32_t addr_6bit;
1600
1601 /* Extract the lower 6-bit of target address */
1602 addr_6bit = (uint32_t)data->ibi.addr[idx] & I3C_MIBIRULES_ADDR0_MASK;
1603
1604 /* Shift into correct place */
1605 addr_6bit <<= idx * I3C_MIBIRULES_ADDR1_SHIFT;
1606
1607 /* Put into the temporary IBI Rules register */
1608 ibi_rules |= addr_6bit;
1609 }
1610
1611 if (!data->ibi.msb) {
1612 /* The MSB0 field is 1 if MSB is 0 */
1613 ibi_rules |= I3C_MIBIRULES_MSB0_MASK;
1614 }
1615
1616 if (!data->ibi.has_mandatory_byte) {
1617 /* The NOBYTE field is 1 if there is no mandatory byte */
1618 ibi_rules |= I3C_MIBIRULES_NOBYTE_MASK;
1619 }
1620
1621 /* Update the register */
1622 base->MIBIRULES = ibi_rules;
1623
1624 LOG_DBG("MIBIRULES 0x%08x", ibi_rules);
1625 }
1626
mcux_i3c_ibi_enable(const struct device * dev,struct i3c_device_desc * target)1627 int mcux_i3c_ibi_enable(const struct device *dev,
1628 struct i3c_device_desc *target)
1629 {
1630 const struct mcux_i3c_config *config = dev->config;
1631 struct mcux_i3c_data *data = dev->data;
1632 I3C_Type *base = config->base;
1633 struct i3c_ccc_events i3c_events;
1634 uint8_t idx;
1635 bool msb, has_mandatory_byte;
1636 int ret = 0;
1637
1638 if (!i3c_device_is_ibi_capable(target)) {
1639 ret = -EINVAL;
1640 goto out1;
1641 }
1642
1643 if (data->ibi.num_addr >= ARRAY_SIZE(data->ibi.addr)) {
1644 /* No more free entries in the IBI Rules table */
1645 ret = -ENOMEM;
1646 goto out1;
1647 }
1648
1649 /* Check for duplicate */
1650 for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) {
1651 if (data->ibi.addr[idx] == target->dynamic_addr) {
1652 ret = -EINVAL;
1653 goto out1;
1654 }
1655 }
1656
1657 /* Disable controller interrupt while we configure IBI rules. */
1658 base->MINTCLR = I3C_MINTCLR_SLVSTART_MASK;
1659
1660 LOG_DBG("IBI enabling for 0x%02x (BCR 0x%02x)",
1661 target->dynamic_addr, target->bcr);
1662
1663 msb = (target->dynamic_addr & BIT(6)) == BIT(6);
1664 has_mandatory_byte = i3c_ibi_has_payload(target);
1665
1666 /*
1667 * If there are already addresses in the table, we must
1668 * check if the incoming entry is compatible with
1669 * the existing ones.
1670 */
1671 if (data->ibi.num_addr > 0) {
1672 /*
1673 * 1. All devices in the table must all use mandatory
1674 * bytes, or do not.
1675 *
1676 * 2. Each address in entry only captures the lowest 6-bit.
1677 * The MSB (7th bit) is captured separated in another bit
1678 * in the register. So all addresses must have the same MSB.
1679 */
1680 if (has_mandatory_byte != data->ibi.has_mandatory_byte) {
1681 LOG_ERR("New IBI does not have same mandatory byte requirement"
1682 " as previous IBI");
1683 ret = -EINVAL;
1684 goto out;
1685 }
1686 if (msb != data->ibi.msb) {
1687 LOG_ERR("New IBI does not have same msb as previous IBI");
1688 ret = -EINVAL;
1689 goto out;
1690 }
1691
1692 /* Find an empty address slot */
1693 for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) {
1694 if (data->ibi.addr[idx] == 0U) {
1695 break;
1696 }
1697 }
1698 if (idx >= ARRAY_SIZE(data->ibi.addr)) {
1699 LOG_ERR("Cannot support more IBIs");
1700 ret = -ENOTSUP;
1701 goto out;
1702 }
1703 } else {
1704 /*
1705 * If the incoming address is the first in the table,
1706 * it dictates future compatibilities.
1707 */
1708 data->ibi.has_mandatory_byte = has_mandatory_byte;
1709 data->ibi.msb = msb;
1710
1711 idx = 0;
1712 }
1713
1714 data->ibi.addr[idx] = target->dynamic_addr;
1715 data->ibi.num_addr += 1U;
1716
1717 mcux_i3c_ibi_rules_setup(data, base);
1718
1719 /* Tell target to enable IBI */
1720 i3c_events.events = I3C_CCC_EVT_INTR;
1721 ret = i3c_ccc_do_events_set(target, true, &i3c_events);
1722 if (ret != 0) {
1723 LOG_ERR("Error sending IBI ENEC for 0x%02x (%d)",
1724 target->dynamic_addr, ret);
1725 }
1726
1727 out:
1728 if (data->ibi.num_addr > 0U) {
1729 /*
1730 * Enable controller to raise interrupt when a target
1731 * initiates IBI.
1732 */
1733 base->MINTSET = I3C_MINTSET_SLVSTART_MASK;
1734 }
1735 out1:
1736 return ret;
1737 }
1738
mcux_i3c_ibi_disable(const struct device * dev,struct i3c_device_desc * target)1739 int mcux_i3c_ibi_disable(const struct device *dev,
1740 struct i3c_device_desc *target)
1741 {
1742 const struct mcux_i3c_config *config = dev->config;
1743 struct mcux_i3c_data *data = dev->data;
1744 I3C_Type *base = config->base;
1745 struct i3c_ccc_events i3c_events;
1746 int ret = 0;
1747 int idx;
1748
1749 if (!i3c_device_is_ibi_capable(target)) {
1750 ret = -EINVAL;
1751 goto out;
1752 }
1753
1754 for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) {
1755 if (target->dynamic_addr == data->ibi.addr[idx]) {
1756 break;
1757 }
1758 }
1759
1760 if (idx == ARRAY_SIZE(data->ibi.addr)) {
1761 /* Target is not in list of registered addresses. */
1762 ret = -ENODEV;
1763 goto out;
1764 }
1765
1766 /* Disable controller interrupt while we configure IBI rules. */
1767 base->MINTCLR = I3C_MINTCLR_SLVSTART_MASK;
1768
1769 data->ibi.addr[idx] = 0U;
1770 data->ibi.num_addr -= 1U;
1771
1772 /* Tell target to disable IBI */
1773 i3c_events.events = I3C_CCC_EVT_INTR;
1774 ret = i3c_ccc_do_events_set(target, false, &i3c_events);
1775 if (ret != 0) {
1776 LOG_ERR("Error sending IBI DISEC for 0x%02x (%d)",
1777 target->dynamic_addr, ret);
1778 }
1779
1780 mcux_i3c_ibi_rules_setup(data, base);
1781
1782 if (data->ibi.num_addr > 0U) {
1783 /*
1784 * Enable controller to raise interrupt when a target
1785 * initiates IBI.
1786 */
1787 base->MINTSET = I3C_MINTSET_SLVSTART_MASK;
1788 }
1789 out:
1790
1791 return ret;
1792 }
1793 #endif /* CONFIG_I3C_USE_IBI */
1794
1795 /**
1796 * @brief Interrupt Service Routine
1797 *
1798 * Currently only services interrupts when any target initiates IBIs.
1799 *
1800 * @param dev Pointer to controller device driver instance.
1801 */
mcux_i3c_isr(const struct device * dev)1802 static void mcux_i3c_isr(const struct device *dev)
1803 {
1804 #ifdef CONFIG_I3C_USE_IBI
1805 const struct mcux_i3c_config *config = dev->config;
1806 I3C_Type *base = config->base;
1807
1808 /* Target initiated IBIs */
1809 if (mcux_i3c_status_is_set(base, I3C_MSTATUS_SLVSTART_MASK)) {
1810 int err;
1811
1812 /* Clear SLVSTART interrupt */
1813 base->MSTATUS = I3C_MSTATUS_SLVSTART_MASK;
1814
1815 /*
1816 * Disable further target initiated IBI interrupt
1817 * while we try to service the current one.
1818 */
1819 base->MINTCLR = I3C_MINTCLR_SLVSTART_MASK;
1820
1821 /*
1822 * Handle IBI in workqueue.
1823 */
1824 err = i3c_ibi_work_enqueue_cb(dev, mcux_i3c_ibi_work);
1825 if (err) {
1826 LOG_ERR("Error enqueuing ibi work, err %d", err);
1827 base->MINTSET = I3C_MINTCLR_SLVSTART_MASK;
1828 }
1829 }
1830 #else
1831 ARG_UNUSED(dev);
1832 #endif
1833 }
1834
1835 /**
1836 * @brief Configure I3C hardware.
1837 *
1838 * @param dev Pointer to controller device driver instance.
1839 * @param type Type of configuration parameters being passed
1840 * in @p config.
1841 * @param config Pointer to the configuration parameters.
1842 *
1843 * @retval 0 If successful.
1844 * @retval -EINVAL If invalid configure parameters.
1845 * @retval -EIO General Input/Output errors.
1846 * @retval -ENOSYS If not implemented.
1847 */
mcux_i3c_configure(const struct device * dev,enum i3c_config_type type,void * config)1848 static int mcux_i3c_configure(const struct device *dev,
1849 enum i3c_config_type type, void *config)
1850 {
1851 const struct mcux_i3c_config *dev_cfg = dev->config;
1852 struct mcux_i3c_data *dev_data = dev->data;
1853 I3C_Type *base = dev_cfg->base;
1854 i3c_master_config_t master_config;
1855 struct i3c_config_controller *ctrl_cfg = config;
1856 uint32_t clock_freq;
1857 int ret = 0;
1858
1859 if (type != I3C_CONFIG_CONTROLLER) {
1860 ret = -EINVAL;
1861 goto out_configure;
1862 }
1863
1864 /*
1865 * Check for valid configuration parameters.
1866 *
1867 * Currently, must be the primary controller.
1868 */
1869 if ((ctrl_cfg->is_secondary) ||
1870 (ctrl_cfg->scl.i2c == 0U) ||
1871 (ctrl_cfg->scl.i3c == 0U)) {
1872 ret = -EINVAL;
1873 goto out_configure;
1874 }
1875
1876 /* Get the clock frequency */
1877 if (clock_control_get_rate(dev_cfg->clock_dev, dev_cfg->clock_subsys,
1878 &clock_freq)) {
1879 ret = -EINVAL;
1880 goto out_configure;
1881 }
1882
1883 /*
1884 * Save requested config so next config_get() call returns the
1885 * correct values.
1886 */
1887 (void)memcpy(&dev_data->common.ctrl_config, ctrl_cfg, sizeof(*ctrl_cfg));
1888
1889 I3C_MasterGetDefaultConfig(&master_config);
1890
1891 master_config.baudRate_Hz.i2cBaud = ctrl_cfg->scl.i2c;
1892 master_config.baudRate_Hz.i3cPushPullBaud = ctrl_cfg->scl.i3c;
1893 master_config.enableOpenDrainHigh = dev_cfg->disable_open_drain_high_pp ? false : true;
1894
1895 if (dev_data->i3c_od_scl_hz) {
1896 master_config.baudRate_Hz.i3cOpenDrainBaud = dev_data->i3c_od_scl_hz;
1897 }
1898
1899 /* Initialize hardware */
1900 I3C_MasterInit(base, &master_config, clock_freq);
1901
1902 out_configure:
1903 return ret;
1904 }
1905
1906 /**
1907 * @brief Get configuration of the I3C hardware.
1908 *
1909 * This provides a way to get the current configuration of the I3C hardware.
1910 *
1911 * This can return cached config or probed hardware parameters, but it has to
1912 * be up to date with current configuration.
1913 *
1914 * @param[in] dev Pointer to controller device driver instance.
1915 * @param[in] type Type of configuration parameters being passed
1916 * in @p config.
1917 * @param[in,out] config Pointer to the configuration parameters.
1918 *
1919 * Note that if @p type is @c I3C_CONFIG_CUSTOM, @p config must contain
1920 * the ID of the parameter to be retrieved.
1921 *
1922 * @retval 0 If successful.
1923 * @retval -EIO General Input/Output errors.
1924 * @retval -ENOSYS If not implemented.
1925 */
mcux_i3c_config_get(const struct device * dev,enum i3c_config_type type,void * config)1926 static int mcux_i3c_config_get(const struct device *dev,
1927 enum i3c_config_type type, void *config)
1928 {
1929 struct mcux_i3c_data *data = dev->data;
1930 int ret = 0;
1931
1932 if ((type != I3C_CONFIG_CONTROLLER) || (config == NULL)) {
1933 ret = -EINVAL;
1934 goto out_configure;
1935 }
1936
1937 (void)memcpy(config, &data->common.ctrl_config, sizeof(data->common.ctrl_config));
1938
1939 out_configure:
1940 return ret;
1941 }
1942
1943 /**
1944 * @brief Initialize the hardware.
1945 *
1946 * @param dev Pointer to controller device driver instance.
1947 */
mcux_i3c_init(const struct device * dev)1948 static int mcux_i3c_init(const struct device *dev)
1949 {
1950 const struct mcux_i3c_config *config = dev->config;
1951 struct mcux_i3c_data *data = dev->data;
1952 I3C_Type *base = config->base;
1953 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config;
1954 i3c_master_config_t ctrl_config_hal;
1955 int ret = 0;
1956
1957 ret = i3c_addr_slots_init(dev);
1958 if (ret != 0) {
1959 goto err_out;
1960 }
1961
1962 ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
1963 if (ret != 0) {
1964 goto err_out;
1965 }
1966
1967 k_mutex_init(&data->lock);
1968 k_condvar_init(&data->condvar);
1969
1970 I3C_MasterGetDefaultConfig(&ctrl_config_hal);
1971
1972 /* Set default SCL clock rate (in Hz) */
1973 if (ctrl_config->scl.i2c == 0U) {
1974 ctrl_config->scl.i2c = ctrl_config_hal.baudRate_Hz.i2cBaud;
1975 }
1976
1977 if (ctrl_config->scl.i3c == 0U) {
1978 ctrl_config->scl.i3c = ctrl_config_hal.baudRate_Hz.i3cPushPullBaud;
1979 }
1980
1981 /* Currently can only act as primary controller. */
1982 ctrl_config->is_secondary = false;
1983
1984 /* HDR mode not supported at the moment. */
1985 ctrl_config->supported_hdr = 0U;
1986
1987 ret = mcux_i3c_configure(dev, I3C_CONFIG_CONTROLLER, ctrl_config);
1988 if (ret != 0) {
1989 ret = -EINVAL;
1990 goto err_out;
1991 }
1992
1993 /* Disable all interrupts */
1994 base->MINTCLR = I3C_MINTCLR_SLVSTART_MASK |
1995 I3C_MINTCLR_MCTRLDONE_MASK |
1996 I3C_MINTCLR_COMPLETE_MASK |
1997 I3C_MINTCLR_RXPEND_MASK |
1998 I3C_MINTCLR_TXNOTFULL_MASK |
1999 I3C_MINTCLR_IBIWON_MASK |
2000 I3C_MINTCLR_ERRWARN_MASK |
2001 I3C_MINTCLR_NOWMASTER_MASK;
2002
2003 /* Just in case the bus is not in idle. */
2004 ret = mcux_i3c_recover_bus(dev);
2005 if (ret != 0) {
2006 ret = -EIO;
2007 goto err_out;
2008 }
2009
2010 /* Configure interrupt */
2011 config->irq_config_func(dev);
2012
2013 /* Perform bus initialization */
2014 ret = i3c_bus_init(dev, &config->common.dev_list);
2015
2016 err_out:
2017 return ret;
2018 }
2019
mcux_i3c_i2c_api_configure(const struct device * dev,uint32_t dev_config)2020 static int mcux_i3c_i2c_api_configure(const struct device *dev, uint32_t dev_config)
2021 {
2022 return -ENOSYS;
2023 }
2024
mcux_i3c_i2c_api_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)2025 static int mcux_i3c_i2c_api_transfer(const struct device *dev,
2026 struct i2c_msg *msgs,
2027 uint8_t num_msgs,
2028 uint16_t addr)
2029 {
2030 const struct mcux_i3c_config *config = dev->config;
2031 struct mcux_i3c_data *dev_data = dev->data;
2032 I3C_Type *base = config->base;
2033 int ret;
2034
2035 k_mutex_lock(&dev_data->lock, K_FOREVER);
2036
2037 mcux_i3c_wait_idle(dev_data, base);
2038
2039 mcux_i3c_xfer_reset(base);
2040
2041 /* Iterate over all the messages */
2042 for (int i = 0; i < num_msgs; i++) {
2043 bool is_read = (msgs[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_READ;
2044 bool no_ending = false;
2045
2046 /*
2047 * Emit start if this is the first message or that
2048 * the RESTART flag is set in message.
2049 */
2050 bool emit_start = (i == 0) ||
2051 ((msgs[i].flags & I2C_MSG_RESTART) == I2C_MSG_RESTART);
2052
2053 bool emit_stop = (msgs[i].flags & I2C_MSG_STOP) == I2C_MSG_STOP;
2054
2055 /*
2056 * The controller requires special treatment of last byte of
2057 * a write message. Since the API permits having a bunch of
2058 * write messages without RESTART in between, this is just some
2059 * logic to determine whether to treat the last byte of this
2060 * message to be the last byte of a series of write mssages.
2061 * If not, tell the write function not to treat it that way.
2062 */
2063 if (!is_read && !emit_stop && ((i + 1) != num_msgs)) {
2064 bool next_is_write =
2065 (msgs[i + 1].flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE;
2066 bool next_is_restart =
2067 ((msgs[i + 1].flags & I2C_MSG_RESTART) == I2C_MSG_RESTART);
2068
2069 if (next_is_write && !next_is_restart) {
2070 no_ending = true;
2071 }
2072 }
2073
2074 ret = mcux_i3c_do_one_xfer(base, dev_data, addr, true,
2075 msgs[i].buf, msgs[i].len,
2076 is_read, emit_start, emit_stop, no_ending);
2077 if (ret < 0) {
2078 goto out_xfer_i2c_stop_unlock;
2079 }
2080 }
2081
2082 ret = 0;
2083
2084 out_xfer_i2c_stop_unlock:
2085 mcux_i3c_request_emit_stop(dev_data, base, true);
2086 mcux_i3c_errwarn_clear_all_nowait(base);
2087 mcux_i3c_status_clear_all(base);
2088 k_mutex_unlock(&dev_data->lock);
2089
2090 return ret;
2091 }
2092
2093 static DEVICE_API(i3c, mcux_i3c_driver_api) = {
2094 .i2c_api.configure = mcux_i3c_i2c_api_configure,
2095 .i2c_api.transfer = mcux_i3c_i2c_api_transfer,
2096 .i2c_api.recover_bus = mcux_i3c_recover_bus,
2097 #ifdef CONFIG_I2C_RTIO
2098 .i2c_api.iodev_submit = i2c_iodev_submit_fallback,
2099 #endif
2100
2101 .configure = mcux_i3c_configure,
2102 .config_get = mcux_i3c_config_get,
2103
2104 .recover_bus = mcux_i3c_recover_bus,
2105
2106 .do_daa = mcux_i3c_do_daa,
2107 .do_ccc = mcux_i3c_do_ccc,
2108
2109 .i3c_device_find = mcux_i3c_device_find,
2110
2111 .i3c_xfers = mcux_i3c_transfer,
2112
2113 #ifdef CONFIG_I3C_USE_IBI
2114 .ibi_enable = mcux_i3c_ibi_enable,
2115 .ibi_disable = mcux_i3c_ibi_disable,
2116 #endif
2117
2118 #ifdef CONFIG_I3C_RTIO
2119 .iodev_submit = i3c_iodev_submit_fallback,
2120 #endif
2121 };
2122
2123 #define I3C_MCUX_DEVICE(id) \
2124 PINCTRL_DT_INST_DEFINE(id); \
2125 static void mcux_i3c_config_func_##id(const struct device *dev); \
2126 static struct i3c_device_desc mcux_i3c_device_array_##id[] = \
2127 I3C_DEVICE_ARRAY_DT_INST(id); \
2128 static struct i3c_i2c_device_desc mcux_i3c_i2c_device_array_##id[] = \
2129 I3C_I2C_DEVICE_ARRAY_DT_INST(id); \
2130 static const struct mcux_i3c_config mcux_i3c_config_##id = { \
2131 .base = (I3C_Type *) DT_INST_REG_ADDR(id), \
2132 .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)), \
2133 .clock_subsys = \
2134 (clock_control_subsys_t)DT_INST_CLOCKS_CELL(id, name), \
2135 .irq_config_func = mcux_i3c_config_func_##id, \
2136 .common.dev_list.i3c = mcux_i3c_device_array_##id, \
2137 .common.dev_list.num_i3c = ARRAY_SIZE(mcux_i3c_device_array_##id), \
2138 .common.dev_list.i2c = mcux_i3c_i2c_device_array_##id, \
2139 .common.dev_list.num_i2c = ARRAY_SIZE(mcux_i3c_i2c_device_array_##id), \
2140 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \
2141 .disable_open_drain_high_pp = \
2142 DT_INST_PROP(id, disable_open_drain_high_pp), \
2143 }; \
2144 static struct mcux_i3c_data mcux_i3c_data_##id = { \
2145 .i3c_od_scl_hz = DT_INST_PROP_OR(id, i3c_od_scl_hz, 0), \
2146 .common.ctrl_config.scl.i3c = DT_INST_PROP_OR(id, i3c_scl_hz, 0), \
2147 .common.ctrl_config.scl.i2c = DT_INST_PROP_OR(id, i2c_scl_hz, 0), \
2148 }; \
2149 DEVICE_DT_INST_DEFINE(id, \
2150 mcux_i3c_init, \
2151 NULL, \
2152 &mcux_i3c_data_##id, \
2153 &mcux_i3c_config_##id, \
2154 POST_KERNEL, \
2155 CONFIG_I3C_CONTROLLER_INIT_PRIORITY, \
2156 &mcux_i3c_driver_api); \
2157 static void mcux_i3c_config_func_##id(const struct device *dev) \
2158 { \
2159 IRQ_CONNECT(DT_INST_IRQN(id), \
2160 DT_INST_IRQ(id, priority), \
2161 mcux_i3c_isr, \
2162 DEVICE_DT_INST_GET(id), \
2163 0); \
2164 irq_enable(DT_INST_IRQN(id)); \
2165 }; \
2166
2167 DT_INST_FOREACH_STATUS_OKAY(I3C_MCUX_DEVICE)
2168