1 /*
2  * Copyright (c) 2022 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 
9 #include <zephyr/toolchain.h>
10 #include <zephyr/sys/byteorder.h>
11 #include <zephyr/sys/__assert.h>
12 
13 #include <zephyr/drivers/i3c.h>
14 
15 #include <zephyr/logging/log.h>
16 LOG_MODULE_DECLARE(i3c, CONFIG_I3C_LOG_LEVEL);
17 
i3c_ccc_do_getbcr(struct i3c_device_desc * target,struct i3c_ccc_getbcr * bcr)18 int i3c_ccc_do_getbcr(struct i3c_device_desc *target,
19 		      struct i3c_ccc_getbcr *bcr)
20 {
21 	struct i3c_ccc_payload ccc_payload;
22 	struct i3c_ccc_target_payload ccc_tgt_payload;
23 
24 	__ASSERT_NO_MSG(target != NULL);
25 	__ASSERT_NO_MSG(target->bus != NULL);
26 	__ASSERT_NO_MSG(bcr != NULL);
27 
28 	ccc_tgt_payload.addr = target->dynamic_addr;
29 	ccc_tgt_payload.rnw = 1;
30 	ccc_tgt_payload.data = &bcr->bcr;
31 	ccc_tgt_payload.data_len = sizeof(bcr->bcr);
32 
33 	memset(&ccc_payload, 0, sizeof(ccc_payload));
34 	ccc_payload.ccc.id = I3C_CCC_GETBCR;
35 	ccc_payload.targets.payloads = &ccc_tgt_payload;
36 	ccc_payload.targets.num_targets = 1;
37 
38 	return i3c_do_ccc(target->bus, &ccc_payload);
39 }
40 
i3c_ccc_do_getdcr(struct i3c_device_desc * target,struct i3c_ccc_getdcr * dcr)41 int i3c_ccc_do_getdcr(struct i3c_device_desc *target,
42 		      struct i3c_ccc_getdcr *dcr)
43 {
44 	struct i3c_ccc_payload ccc_payload;
45 	struct i3c_ccc_target_payload ccc_tgt_payload;
46 
47 	__ASSERT_NO_MSG(target != NULL);
48 	__ASSERT_NO_MSG(target->bus != NULL);
49 	__ASSERT_NO_MSG(dcr != NULL);
50 
51 	ccc_tgt_payload.addr = target->dynamic_addr;
52 	ccc_tgt_payload.rnw = 1;
53 	ccc_tgt_payload.data = &dcr->dcr;
54 	ccc_tgt_payload.data_len = sizeof(dcr->dcr);
55 
56 	memset(&ccc_payload, 0, sizeof(ccc_payload));
57 	ccc_payload.ccc.id = I3C_CCC_GETDCR;
58 	ccc_payload.targets.payloads = &ccc_tgt_payload;
59 	ccc_payload.targets.num_targets = 1;
60 
61 	return i3c_do_ccc(target->bus, &ccc_payload);
62 }
63 
i3c_ccc_do_getpid(struct i3c_device_desc * target,struct i3c_ccc_getpid * pid)64 int i3c_ccc_do_getpid(struct i3c_device_desc *target,
65 		      struct i3c_ccc_getpid *pid)
66 {
67 	struct i3c_ccc_payload ccc_payload;
68 	struct i3c_ccc_target_payload ccc_tgt_payload;
69 
70 	__ASSERT_NO_MSG(target != NULL);
71 	__ASSERT_NO_MSG(target->bus != NULL);
72 	__ASSERT_NO_MSG(pid != NULL);
73 
74 	ccc_tgt_payload.addr = target->dynamic_addr;
75 	ccc_tgt_payload.rnw = 1;
76 	ccc_tgt_payload.data = &pid->pid[0];
77 	ccc_tgt_payload.data_len = sizeof(pid->pid);
78 
79 	memset(&ccc_payload, 0, sizeof(ccc_payload));
80 	ccc_payload.ccc.id = I3C_CCC_GETPID;
81 	ccc_payload.targets.payloads = &ccc_tgt_payload;
82 	ccc_payload.targets.num_targets = 1;
83 
84 	return i3c_do_ccc(target->bus, &ccc_payload);
85 }
86 
i3c_ccc_do_rstact_all(const struct device * controller,enum i3c_ccc_rstact_defining_byte action)87 int i3c_ccc_do_rstact_all(const struct device *controller,
88 			  enum i3c_ccc_rstact_defining_byte action)
89 {
90 	struct i3c_ccc_payload ccc_payload;
91 	uint8_t def_byte;
92 
93 	__ASSERT_NO_MSG(controller != NULL);
94 
95 	memset(&ccc_payload, 0, sizeof(ccc_payload));
96 	ccc_payload.ccc.id = I3C_CCC_RSTACT(true);
97 
98 	def_byte = (uint8_t)action;
99 	ccc_payload.ccc.data = &def_byte;
100 	ccc_payload.ccc.data_len = 1U;
101 
102 	return i3c_do_ccc(controller, &ccc_payload);
103 }
104 
i3c_ccc_do_rstact(const struct i3c_device_desc * target,enum i3c_ccc_rstact_defining_byte action,bool get,uint8_t * data)105 int i3c_ccc_do_rstact(const struct i3c_device_desc *target,
106 			  enum i3c_ccc_rstact_defining_byte action,
107 			  bool get,
108 			  uint8_t *data)
109 {
110 	struct i3c_ccc_payload ccc_payload;
111 	struct i3c_ccc_target_payload ccc_tgt_payload;
112 	uint8_t def_byte;
113 
114 	__ASSERT_NO_MSG(target != NULL);
115 	__ASSERT_NO_MSG(target->bus != NULL);
116 
117 	memset(&ccc_payload, 0, sizeof(ccc_payload));
118 
119 	ccc_tgt_payload.addr = target->dynamic_addr;
120 	if (get) {
121 		__ASSERT_NO_MSG(data != NULL);
122 
123 		ccc_tgt_payload.rnw = 1;
124 		ccc_tgt_payload.data = data;
125 		ccc_tgt_payload.data_len = sizeof(*data);
126 	} else {
127 		ccc_tgt_payload.rnw = 0;
128 	}
129 
130 	ccc_payload.ccc.id = I3C_CCC_RSTACT(false);
131 	def_byte = (uint8_t)action;
132 	ccc_payload.ccc.data = &def_byte;
133 	ccc_payload.ccc.data_len = 1U;
134 	ccc_payload.targets.payloads = &ccc_tgt_payload;
135 	ccc_payload.targets.num_targets = 1;
136 
137 	return i3c_do_ccc(target->bus, &ccc_payload);
138 }
139 
i3c_ccc_do_rstdaa_all(const struct device * controller)140 int i3c_ccc_do_rstdaa_all(const struct device *controller)
141 {
142 	struct i3c_ccc_payload ccc_payload;
143 
144 	__ASSERT_NO_MSG(controller != NULL);
145 
146 	memset(&ccc_payload, 0, sizeof(ccc_payload));
147 	ccc_payload.ccc.id = I3C_CCC_RSTDAA;
148 
149 	return i3c_do_ccc(controller, &ccc_payload);
150 }
151 
i3c_ccc_do_setdasa(const struct i3c_device_desc * target,struct i3c_ccc_address da)152 int i3c_ccc_do_setdasa(const struct i3c_device_desc *target, struct i3c_ccc_address da)
153 {
154 	struct i3c_ccc_payload ccc_payload;
155 	struct i3c_ccc_target_payload ccc_tgt_payload;
156 
157 	__ASSERT_NO_MSG(target != NULL);
158 	__ASSERT_NO_MSG(target->bus != NULL);
159 
160 	if ((target->static_addr == 0U) || (target->dynamic_addr != 0U)) {
161 		return -EINVAL;
162 	}
163 
164 	ccc_tgt_payload.addr = target->static_addr;
165 	ccc_tgt_payload.rnw = 0;
166 	ccc_tgt_payload.data = (uint8_t *)&da.addr;
167 	ccc_tgt_payload.data_len = 1;
168 
169 	memset(&ccc_payload, 0, sizeof(ccc_payload));
170 	ccc_payload.ccc.id = I3C_CCC_SETDASA;
171 	ccc_payload.targets.payloads = &ccc_tgt_payload;
172 	ccc_payload.targets.num_targets = 1;
173 
174 	return i3c_do_ccc(target->bus, &ccc_payload);
175 }
176 
i3c_ccc_do_setnewda(const struct i3c_device_desc * target,struct i3c_ccc_address new_da)177 int i3c_ccc_do_setnewda(const struct i3c_device_desc *target, struct i3c_ccc_address new_da)
178 {
179 	struct i3c_ccc_payload ccc_payload;
180 	struct i3c_ccc_target_payload ccc_tgt_payload;
181 
182 	__ASSERT_NO_MSG(target != NULL);
183 	__ASSERT_NO_MSG(target->bus != NULL);
184 
185 	if (target->dynamic_addr == 0U) {
186 		return -EINVAL;
187 	}
188 
189 	ccc_tgt_payload.addr = target->dynamic_addr;
190 	ccc_tgt_payload.rnw = 0;
191 	ccc_tgt_payload.data = (uint8_t *)&new_da.addr;
192 	ccc_tgt_payload.data_len = 1;
193 
194 	memset(&ccc_payload, 0, sizeof(ccc_payload));
195 	ccc_payload.ccc.id = I3C_CCC_SETNEWDA;
196 	ccc_payload.targets.payloads = &ccc_tgt_payload;
197 	ccc_payload.targets.num_targets = 1;
198 
199 	return i3c_do_ccc(target->bus, &ccc_payload);
200 }
201 
i3c_ccc_do_events_all_set(const struct device * controller,bool enable,struct i3c_ccc_events * events)202 int i3c_ccc_do_events_all_set(const struct device *controller,
203 			      bool enable, struct i3c_ccc_events *events)
204 {
205 	struct i3c_ccc_payload ccc_payload;
206 
207 	__ASSERT_NO_MSG(controller != NULL);
208 
209 	memset(&ccc_payload, 0, sizeof(ccc_payload));
210 
211 	ccc_payload.ccc.id = enable ? I3C_CCC_ENEC(true) : I3C_CCC_DISEC(true);
212 
213 	ccc_payload.ccc.data = &events->events;
214 	ccc_payload.ccc.data_len = sizeof(events->events);
215 
216 	return i3c_do_ccc(controller, &ccc_payload);
217 }
218 
i3c_ccc_do_events_set(struct i3c_device_desc * target,bool enable,struct i3c_ccc_events * events)219 int i3c_ccc_do_events_set(struct i3c_device_desc *target,
220 			  bool enable, struct i3c_ccc_events *events)
221 {
222 	struct i3c_ccc_payload ccc_payload;
223 	struct i3c_ccc_target_payload ccc_tgt_payload;
224 
225 	__ASSERT_NO_MSG(target != NULL);
226 	__ASSERT_NO_MSG(target->bus != NULL);
227 
228 	if (target->dynamic_addr == 0U) {
229 		return -EINVAL;
230 	}
231 
232 	ccc_tgt_payload.addr = target->dynamic_addr;
233 	ccc_tgt_payload.rnw = 0;
234 	ccc_tgt_payload.data = &events->events;
235 	ccc_tgt_payload.data_len = sizeof(events->events);
236 
237 	memset(&ccc_payload, 0, sizeof(ccc_payload));
238 	ccc_payload.ccc.id = enable ? I3C_CCC_ENEC(false) : I3C_CCC_DISEC(false);
239 	ccc_payload.targets.payloads = &ccc_tgt_payload;
240 	ccc_payload.targets.num_targets = 1;
241 
242 	return i3c_do_ccc(target->bus, &ccc_payload);
243 }
244 
i3c_ccc_do_entas(const struct i3c_device_desc * target,uint8_t as)245 int i3c_ccc_do_entas(const struct i3c_device_desc *target, uint8_t as)
246 {
247 	struct i3c_ccc_payload ccc_payload;
248 	struct i3c_ccc_target_payload ccc_tgt_payload;
249 
250 	__ASSERT_NO_MSG(target != NULL);
251 	__ASSERT_NO_MSG(target->bus != NULL);
252 	__ASSERT_NO_MSG(as <= 3);
253 
254 	memset(&ccc_payload, 0, sizeof(ccc_payload));
255 
256 	ccc_tgt_payload.addr = target->dynamic_addr;
257 	ccc_tgt_payload.rnw = 0;
258 	ccc_tgt_payload.data_len = 0;
259 
260 	ccc_payload.ccc.id = I3C_CCC_ENTAS(as, false);
261 	ccc_payload.targets.payloads = &ccc_tgt_payload;
262 	ccc_payload.targets.num_targets = 1;
263 
264 	return i3c_do_ccc(target->bus, &ccc_payload);
265 }
266 
i3c_ccc_do_entas_all(const struct device * controller,uint8_t as)267 int i3c_ccc_do_entas_all(const struct device *controller, uint8_t as)
268 {
269 	struct i3c_ccc_payload ccc_payload;
270 
271 	__ASSERT_NO_MSG(controller != NULL);
272 	__ASSERT_NO_MSG(as <= 3);
273 
274 	memset(&ccc_payload, 0, sizeof(ccc_payload));
275 	ccc_payload.ccc.id = I3C_CCC_ENTAS(as, true);
276 
277 	return i3c_do_ccc(controller, &ccc_payload);
278 }
279 
i3c_ccc_do_setmwl_all(const struct device * controller,const struct i3c_ccc_mwl * mwl)280 int i3c_ccc_do_setmwl_all(const struct device *controller,
281 			  const struct i3c_ccc_mwl *mwl)
282 {
283 	struct i3c_ccc_payload ccc_payload;
284 	uint8_t data[2];
285 
286 	__ASSERT_NO_MSG(controller != NULL);
287 
288 	memset(&ccc_payload, 0, sizeof(ccc_payload));
289 
290 	ccc_payload.ccc.id = I3C_CCC_SETMWL(true);
291 
292 	ccc_payload.ccc.data = &data[0];
293 	ccc_payload.ccc.data_len = sizeof(data);
294 
295 	/* The actual data is MSB first. So order the data. */
296 	sys_put_be16(mwl->len, data);
297 
298 	return i3c_do_ccc(controller, &ccc_payload);
299 }
300 
i3c_ccc_do_setmwl(const struct i3c_device_desc * target,const struct i3c_ccc_mwl * mwl)301 int i3c_ccc_do_setmwl(const struct i3c_device_desc *target,
302 		      const struct i3c_ccc_mwl *mwl)
303 {
304 	struct i3c_ccc_payload ccc_payload;
305 	struct i3c_ccc_target_payload ccc_tgt_payload;
306 	uint8_t data[2];
307 
308 	__ASSERT_NO_MSG(target != NULL);
309 	__ASSERT_NO_MSG(target->bus != NULL);
310 
311 	memset(&ccc_payload, 0, sizeof(ccc_payload));
312 
313 	ccc_tgt_payload.addr = target->dynamic_addr;
314 	ccc_tgt_payload.rnw = 0;
315 	ccc_tgt_payload.data = &data[0];
316 	ccc_tgt_payload.data_len = sizeof(data);
317 
318 	ccc_payload.ccc.id = I3C_CCC_SETMWL(false);
319 	ccc_payload.targets.payloads = &ccc_tgt_payload;
320 	ccc_payload.targets.num_targets = 1;
321 
322 	/* The actual length is MSB first. So order the data. */
323 	sys_put_be16(mwl->len, data);
324 
325 	return i3c_do_ccc(target->bus, &ccc_payload);
326 }
327 
i3c_ccc_do_getmwl(const struct i3c_device_desc * target,struct i3c_ccc_mwl * mwl)328 int i3c_ccc_do_getmwl(const struct i3c_device_desc *target,
329 		      struct i3c_ccc_mwl *mwl)
330 {
331 	struct i3c_ccc_payload ccc_payload;
332 	struct i3c_ccc_target_payload ccc_tgt_payload;
333 	uint8_t data[2];
334 	int ret;
335 
336 	__ASSERT_NO_MSG(target != NULL);
337 	__ASSERT_NO_MSG(target->bus != NULL);
338 	__ASSERT_NO_MSG(mwl != NULL);
339 
340 	ccc_tgt_payload.addr = target->dynamic_addr;
341 	ccc_tgt_payload.rnw = 1;
342 	ccc_tgt_payload.data = &data[0];
343 	ccc_tgt_payload.data_len = sizeof(data);
344 
345 	memset(&ccc_payload, 0, sizeof(ccc_payload));
346 	ccc_payload.ccc.id = I3C_CCC_GETMWL;
347 	ccc_payload.targets.payloads = &ccc_tgt_payload;
348 	ccc_payload.targets.num_targets = 1;
349 
350 	ret = i3c_do_ccc(target->bus, &ccc_payload);
351 
352 	if (ret == 0) {
353 		/* The actual length is MSB first. So order the data. */
354 		mwl->len = sys_get_be16(data);
355 	}
356 
357 	return ret;
358 }
359 
i3c_ccc_do_setmrl_all(const struct device * controller,const struct i3c_ccc_mrl * mrl,bool has_ibi_size)360 int i3c_ccc_do_setmrl_all(const struct device *controller,
361 			  const struct i3c_ccc_mrl *mrl,
362 			  bool has_ibi_size)
363 {
364 	struct i3c_ccc_payload ccc_payload;
365 	uint8_t data[3];
366 
367 	__ASSERT_NO_MSG(controller != NULL);
368 
369 	memset(&ccc_payload, 0, sizeof(ccc_payload));
370 
371 	ccc_payload.ccc.id = I3C_CCC_SETMRL(true);
372 
373 	ccc_payload.ccc.data = &data[0];
374 	ccc_payload.ccc.data_len = has_ibi_size ? 3 : 2;
375 
376 	/* The actual length is MSB first. So order the data. */
377 	sys_put_be16(mrl->len, data);
378 
379 	if (has_ibi_size) {
380 		data[2] = mrl->ibi_len;
381 	}
382 
383 	return i3c_do_ccc(controller, &ccc_payload);
384 }
385 
i3c_ccc_do_setmrl(const struct i3c_device_desc * target,const struct i3c_ccc_mrl * mrl)386 int i3c_ccc_do_setmrl(const struct i3c_device_desc *target,
387 		      const struct i3c_ccc_mrl *mrl)
388 {
389 	struct i3c_ccc_payload ccc_payload;
390 	struct i3c_ccc_target_payload ccc_tgt_payload;
391 	uint8_t data[3];
392 
393 	__ASSERT_NO_MSG(target != NULL);
394 	__ASSERT_NO_MSG(target->bus != NULL);
395 
396 	memset(&ccc_payload, 0, sizeof(ccc_payload));
397 
398 	ccc_tgt_payload.addr = target->dynamic_addr;
399 	ccc_tgt_payload.rnw = 0;
400 	ccc_tgt_payload.data = &data[0];
401 
402 	ccc_payload.ccc.id = I3C_CCC_SETMRL(false);
403 	ccc_payload.targets.payloads = &ccc_tgt_payload;
404 	ccc_payload.targets.num_targets = 1;
405 
406 	/* The actual length is MSB first. So order the data. */
407 	sys_put_be16(mrl->len, data);
408 
409 	if ((target->bcr & I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE)
410 	    == I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE) {
411 		ccc_tgt_payload.data_len = 3;
412 
413 		data[2] = mrl->ibi_len;
414 	} else {
415 		ccc_tgt_payload.data_len = 2;
416 	}
417 
418 	return i3c_do_ccc(target->bus, &ccc_payload);
419 }
420 
i3c_ccc_do_getmrl(const struct i3c_device_desc * target,struct i3c_ccc_mrl * mrl)421 int i3c_ccc_do_getmrl(const struct i3c_device_desc *target,
422 		      struct i3c_ccc_mrl *mrl)
423 {
424 	struct i3c_ccc_payload ccc_payload;
425 	struct i3c_ccc_target_payload ccc_tgt_payload;
426 	uint8_t data[3];
427 	bool has_ibi_sz;
428 	int ret;
429 
430 	__ASSERT_NO_MSG(target != NULL);
431 	__ASSERT_NO_MSG(target->bus != NULL);
432 	__ASSERT_NO_MSG(mrl != NULL);
433 
434 	has_ibi_sz = (target->bcr & I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE)
435 		     == I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE;
436 
437 	ccc_tgt_payload.addr = target->dynamic_addr;
438 	ccc_tgt_payload.rnw = 1;
439 	ccc_tgt_payload.data = &data[0];
440 	ccc_tgt_payload.data_len = has_ibi_sz ? 3 : 2;
441 
442 	memset(&ccc_payload, 0, sizeof(ccc_payload));
443 	ccc_payload.ccc.id = I3C_CCC_GETMRL;
444 	ccc_payload.targets.payloads = &ccc_tgt_payload;
445 	ccc_payload.targets.num_targets = 1;
446 
447 	ret = i3c_do_ccc(target->bus, &ccc_payload);
448 
449 	if (ret == 0) {
450 		/* The actual length is MSB first. So order the data. */
451 		mrl->len = sys_get_be16(data);
452 
453 		if (has_ibi_sz) {
454 			mrl->ibi_len = data[2];
455 		}
456 	}
457 
458 	return ret;
459 }
460 
i3c_ccc_do_enttm(const struct device * controller,enum i3c_ccc_enttm_defbyte defbyte)461 int i3c_ccc_do_enttm(const struct device *controller,
462 			  enum i3c_ccc_enttm_defbyte defbyte)
463 {
464 	struct i3c_ccc_payload ccc_payload;
465 	uint8_t def_byte;
466 
467 	__ASSERT_NO_MSG(controller != NULL);
468 
469 	memset(&ccc_payload, 0, sizeof(ccc_payload));
470 	ccc_payload.ccc.id = I3C_CCC_ENTTM;
471 
472 	def_byte = (uint8_t)defbyte;
473 	ccc_payload.ccc.data = &def_byte;
474 	ccc_payload.ccc.data_len = 1U;
475 
476 	return i3c_do_ccc(controller, &ccc_payload);
477 }
478 
i3c_ccc_do_deftgts_all(const struct device * controller,struct i3c_ccc_deftgts * deftgts)479 int i3c_ccc_do_deftgts_all(const struct device *controller,
480 			   struct i3c_ccc_deftgts *deftgts)
481 {
482 	struct i3c_ccc_payload ccc_payload;
483 
484 	__ASSERT_NO_MSG(controller != NULL);
485 	__ASSERT_NO_MSG(deftgts != NULL);
486 
487 	memset(&ccc_payload, 0, sizeof(ccc_payload));
488 	ccc_payload.ccc.id = I3C_CCC_DEFTGTS;
489 
490 	ccc_payload.ccc.data = (uint8_t *)deftgts;
491 	ccc_payload.ccc.data_len = sizeof(uint8_t) +
492 				   sizeof(struct i3c_ccc_deftgts_active_controller) +
493 				   (deftgts->count * sizeof(struct i3c_ccc_deftgts_target));
494 
495 	return i3c_do_ccc(controller, &ccc_payload);
496 }
497 
i3c_ccc_do_getstatus(const struct i3c_device_desc * target,union i3c_ccc_getstatus * status,enum i3c_ccc_getstatus_fmt fmt,enum i3c_ccc_getstatus_defbyte defbyte)498 int i3c_ccc_do_getstatus(const struct i3c_device_desc *target,
499 			 union i3c_ccc_getstatus *status,
500 			 enum i3c_ccc_getstatus_fmt fmt,
501 			 enum i3c_ccc_getstatus_defbyte defbyte)
502 {
503 	struct i3c_ccc_payload ccc_payload;
504 	struct i3c_ccc_target_payload ccc_tgt_payload;
505 	uint8_t defining_byte;
506 	uint8_t data[2];
507 	int ret;
508 
509 	__ASSERT_NO_MSG(target != NULL);
510 	__ASSERT_NO_MSG(target->bus != NULL);
511 	__ASSERT_NO_MSG(status != NULL);
512 
513 	ccc_tgt_payload.addr = target->dynamic_addr;
514 	ccc_tgt_payload.rnw = 1;
515 	ccc_tgt_payload.data = &data[0];
516 
517 	if (fmt == GETSTATUS_FORMAT_1) {
518 		ccc_tgt_payload.data_len = 2;
519 	} else if (fmt == GETSTATUS_FORMAT_2) {
520 		switch (defbyte) {
521 		case GETSTATUS_FORMAT_2_TGTSTAT:
522 			__fallthrough;
523 		case GETSTATUS_FORMAT_2_PRECR:
524 			ccc_tgt_payload.data_len = 2;
525 			break;
526 		default:
527 			ret = -EINVAL;
528 			goto out;
529 		}
530 	} else {
531 		ret = -EINVAL;
532 		goto out;
533 	}
534 
535 	memset(&ccc_payload, 0, sizeof(ccc_payload));
536 	ccc_payload.ccc.id = I3C_CCC_GETSTATUS;
537 	ccc_payload.targets.payloads = &ccc_tgt_payload;
538 	ccc_payload.targets.num_targets = 1;
539 
540 	if (fmt == GETSTATUS_FORMAT_2) {
541 		defining_byte = (uint8_t)defbyte;
542 
543 		ccc_payload.ccc.data = &defining_byte;
544 		ccc_payload.ccc.data_len = 1;
545 	}
546 
547 	ret = i3c_do_ccc(target->bus, &ccc_payload);
548 
549 	if (ret == 0) {
550 		/* Received data is MSB first. So order the data. */
551 		if (fmt == GETSTATUS_FORMAT_1) {
552 			status->fmt1.status = sys_get_be16(data);
553 		} else if (fmt == GETSTATUS_FORMAT_2) {
554 			switch (defbyte) {
555 			case GETSTATUS_FORMAT_2_TGTSTAT:
556 				__fallthrough;
557 			case GETSTATUS_FORMAT_2_PRECR:
558 				status->fmt2.raw_u16 = sys_get_be16(data);
559 				break;
560 			default:
561 				break;
562 			}
563 		}
564 	}
565 
566 out:
567 	return ret;
568 }
569 
i3c_ccc_do_getcaps(const struct i3c_device_desc * target,union i3c_ccc_getcaps * caps,enum i3c_ccc_getcaps_fmt fmt,enum i3c_ccc_getcaps_defbyte defbyte)570 int i3c_ccc_do_getcaps(const struct i3c_device_desc *target,
571 			 union i3c_ccc_getcaps *caps,
572 			 enum i3c_ccc_getcaps_fmt fmt,
573 			 enum i3c_ccc_getcaps_defbyte defbyte)
574 {
575 	struct i3c_ccc_payload ccc_payload;
576 	struct i3c_ccc_target_payload ccc_tgt_payload;
577 	uint8_t defining_byte;
578 	uint8_t data[4];
579 	uint8_t len;
580 	int ret;
581 
582 	__ASSERT_NO_MSG(target != NULL);
583 	__ASSERT_NO_MSG(target->bus != NULL);
584 	__ASSERT_NO_MSG(caps != NULL);
585 
586 	ccc_tgt_payload.addr = target->dynamic_addr;
587 	ccc_tgt_payload.rnw = 1;
588 	ccc_tgt_payload.data = &data[0];
589 
590 	if (fmt == GETCAPS_FORMAT_1) {
591 		/* Could be 1-4 Data Bytes Returned */
592 		ccc_tgt_payload.data_len = 4;
593 	} else if (fmt == GETCAPS_FORMAT_2) {
594 		switch (defbyte) {
595 		case GETCAPS_FORMAT_2_CRCAPS:
596 			__fallthrough;
597 		case GETCAPS_FORMAT_2_VTCAPS:
598 			/* Could be 1-2 Data Bytes Returned*/
599 			ccc_tgt_payload.data_len = 2;
600 			break;
601 		case GETCAPS_FORMAT_2_TGTCAPS:
602 			__fallthrough;
603 		case GETCAPS_FORMAT_2_TESTPAT:
604 			/* Could be 1-4 Data Bytes Returned */
605 			ccc_tgt_payload.data_len = 4;
606 			break;
607 		default:
608 			ret = -EINVAL;
609 			goto out;
610 		}
611 	} else {
612 		ret = -EINVAL;
613 		goto out;
614 	}
615 
616 	memset(&ccc_payload, 0, sizeof(ccc_payload));
617 	ccc_payload.ccc.id = I3C_CCC_GETCAPS;
618 	ccc_payload.targets.payloads = &ccc_tgt_payload;
619 	ccc_payload.targets.num_targets = 1;
620 
621 	if (fmt == GETCAPS_FORMAT_2) {
622 		defining_byte = (uint8_t)defbyte;
623 
624 		ccc_payload.ccc.data = &defining_byte;
625 		ccc_payload.ccc.data_len = 1;
626 	}
627 
628 	ret = i3c_do_ccc(target->bus, &ccc_payload);
629 
630 	if (ret == 0) {
631 		/* GETCAPS will return a variable length */
632 		len = ccc_tgt_payload.num_xfer;
633 
634 		if (fmt == GETCAPS_FORMAT_1) {
635 			memcpy(caps->fmt1.getcaps, data, len);
636 			/* for values not received, assume default (1'b0) */
637 			memset(&caps->fmt1.getcaps[len], 0, sizeof(caps->fmt1.getcaps) - len);
638 		} else if (fmt == GETCAPS_FORMAT_2) {
639 			switch (defbyte) {
640 			case GETCAPS_FORMAT_2_CRCAPS:
641 				memcpy(caps->fmt2.crcaps, data, len);
642 				/* for values not received, assume default (1'b0) */
643 				memset(&caps->fmt2.crcaps[len], 0, sizeof(caps->fmt2.crcaps) - len);
644 				break;
645 			case GETCAPS_FORMAT_2_VTCAPS:
646 				memcpy(caps->fmt2.vtcaps, data, len);
647 				/* for values not received, assume default (1'b0) */
648 				memset(&caps->fmt2.vtcaps[len], 0, sizeof(caps->fmt2.vtcaps) - len);
649 				break;
650 			case GETCAPS_FORMAT_2_TGTCAPS:
651 				memcpy(caps->fmt2.tgtcaps, data, len);
652 				/* for values not received, assume default (1'b0) */
653 				memset(&caps->fmt2.tgtcaps[len], 0,
654 				       sizeof(caps->fmt2.tgtcaps) - len);
655 				break;
656 			case GETCAPS_FORMAT_2_TESTPAT:
657 				/* should always be 4 data bytes */
658 				caps->fmt2.testpat = sys_get_be32(data);
659 				break;
660 			default:
661 				break;
662 			}
663 		}
664 	}
665 
666 out:
667 	return ret;
668 }
669 
i3c_ccc_do_setvendor(const struct i3c_device_desc * target,uint8_t id,uint8_t * payload,size_t len)670 int i3c_ccc_do_setvendor(const struct i3c_device_desc *target,
671 			 uint8_t id,
672 			 uint8_t *payload,
673 			 size_t len)
674 {
675 	struct i3c_ccc_payload ccc_payload;
676 
677 	__ASSERT_NO_MSG(target != NULL);
678 
679 	/* CCC must be between 0xE0 and 0xFE, the total range of this is 0x1E */
680 	if (id > 0x1E) {
681 		return -EINVAL;
682 	}
683 
684 	memset(&ccc_payload, 0, sizeof(ccc_payload));
685 	ccc_payload.ccc.id = I3C_CCC_VENDOR(false, id);
686 	ccc_payload.ccc.data = payload;
687 	ccc_payload.ccc.data_len = len;
688 
689 	return i3c_do_ccc(target->bus, &ccc_payload);
690 }
691 
i3c_ccc_do_getvendor(const struct i3c_device_desc * target,uint8_t id,uint8_t * payload,size_t len,size_t * num_xfer)692 int i3c_ccc_do_getvendor(const struct i3c_device_desc *target,
693 			 uint8_t id,
694 			 uint8_t *payload,
695 			 size_t len,
696 			 size_t *num_xfer)
697 {
698 	struct i3c_ccc_payload ccc_payload;
699 	struct i3c_ccc_target_payload ccc_tgt_payload;
700 	int ret;
701 
702 	__ASSERT_NO_MSG(target != NULL);
703 
704 	/* CCC must be between 0xE0 and 0xFE, the total range of this is 0x1E */
705 	if (id > 0x1E) {
706 		return -EINVAL;
707 	}
708 
709 	ccc_tgt_payload.addr = target->dynamic_addr;
710 	ccc_tgt_payload.rnw = 1;
711 	ccc_tgt_payload.data = payload;
712 	ccc_tgt_payload.data_len = len;
713 
714 	memset(&ccc_payload, 0, sizeof(ccc_payload));
715 	ccc_payload.ccc.id = I3C_CCC_VENDOR(false, id);
716 	ccc_payload.targets.payloads = &ccc_tgt_payload;
717 	ccc_payload.targets.num_targets = 1;
718 
719 	ret = i3c_do_ccc(target->bus, &ccc_payload);
720 
721 	if (ret == 0) {
722 		*num_xfer = ccc_tgt_payload.num_xfer;
723 	}
724 
725 	return ret;
726 }
727 
i3c_ccc_do_getvendor_defbyte(const struct i3c_device_desc * target,uint8_t id,uint8_t defbyte,uint8_t * payload,size_t len,size_t * num_xfer)728 int i3c_ccc_do_getvendor_defbyte(const struct i3c_device_desc *target,
729 				 uint8_t id,
730 				 uint8_t defbyte,
731 				 uint8_t *payload,
732 				 size_t len,
733 				 size_t *num_xfer)
734 {
735 	struct i3c_ccc_payload ccc_payload;
736 	struct i3c_ccc_target_payload ccc_tgt_payload;
737 	int ret;
738 
739 	__ASSERT_NO_MSG(target != NULL);
740 
741 	/* CCC must be between 0xE0 and 0xFE, the total range of this is 0x1E */
742 	if (id > 0x1E) {
743 		return -EINVAL;
744 	}
745 
746 	ccc_tgt_payload.addr = target->dynamic_addr;
747 	ccc_tgt_payload.rnw = 1;
748 	ccc_tgt_payload.data = payload;
749 	ccc_tgt_payload.data_len = len;
750 
751 	memset(&ccc_payload, 0, sizeof(ccc_payload));
752 	ccc_payload.ccc.id = I3C_CCC_VENDOR(false, id);
753 	ccc_payload.ccc.data = &defbyte;
754 	ccc_payload.ccc.data_len = 1;
755 	ccc_payload.targets.payloads = &ccc_tgt_payload;
756 	ccc_payload.targets.num_targets = 1;
757 
758 	ret = i3c_do_ccc(target->bus, &ccc_payload);
759 
760 	if (ret == 0) {
761 		*num_xfer = ccc_tgt_payload.num_xfer;
762 	}
763 
764 	return ret;
765 }
766 
i3c_ccc_do_setvendor_all(const struct device * controller,uint8_t id,uint8_t * payload,size_t len)767 int i3c_ccc_do_setvendor_all(const struct device *controller,
768 				 uint8_t id,
769 				 uint8_t *payload,
770 				 size_t len)
771 {
772 	struct i3c_ccc_payload ccc_payload;
773 
774 	__ASSERT_NO_MSG(controller != NULL);
775 
776 	/* CCC must be between 0x61 and 0x7F, the total range of this is 0x1E */
777 	if (id > 0x1E) {
778 		return -EINVAL;
779 	}
780 
781 	memset(&ccc_payload, 0, sizeof(ccc_payload));
782 	ccc_payload.ccc.id = I3C_CCC_VENDOR(true, id);
783 	ccc_payload.ccc.data = payload;
784 	ccc_payload.ccc.data_len = len;
785 
786 	return i3c_do_ccc(controller, &ccc_payload);
787 }
788 
i3c_ccc_do_setaasa_all(const struct device * controller)789 int i3c_ccc_do_setaasa_all(const struct device *controller)
790 {
791 	struct i3c_ccc_payload ccc_payload;
792 
793 	__ASSERT_NO_MSG(controller != NULL);
794 
795 	memset(&ccc_payload, 0, sizeof(ccc_payload));
796 	ccc_payload.ccc.id = I3C_CCC_SETAASA;
797 
798 	return i3c_do_ccc(controller, &ccc_payload);
799 }
800 
i3c_ccc_do_getmxds(const struct i3c_device_desc * target,union i3c_ccc_getmxds * mxds,enum i3c_ccc_getmxds_fmt fmt,enum i3c_ccc_getmxds_defbyte defbyte)801 int i3c_ccc_do_getmxds(const struct i3c_device_desc *target,
802 			 union i3c_ccc_getmxds *mxds,
803 			 enum i3c_ccc_getmxds_fmt fmt,
804 			 enum i3c_ccc_getmxds_defbyte defbyte)
805 {
806 	struct i3c_ccc_payload ccc_payload;
807 	struct i3c_ccc_target_payload ccc_tgt_payload;
808 	uint8_t defining_byte;
809 	uint8_t data[5];
810 	uint8_t len;
811 	int ret;
812 
813 	__ASSERT_NO_MSG(target != NULL);
814 	__ASSERT_NO_MSG(target->bus != NULL);
815 	__ASSERT_NO_MSG(mxds != NULL);
816 
817 	ccc_tgt_payload.addr = target->dynamic_addr;
818 	ccc_tgt_payload.rnw = 1;
819 	ccc_tgt_payload.data = &data[0];
820 
821 	if ((fmt == GETMXDS_FORMAT_1) || (fmt == GETMXDS_FORMAT_2)) {
822 		/* Could be 2 or 5 Data Bytes Returned */
823 		ccc_tgt_payload.data_len = sizeof(((union i3c_ccc_getmxds *)0)->fmt2);
824 	} else if (fmt == GETMXDS_FORMAT_3) {
825 		switch (defbyte) {
826 		case GETMXDS_FORMAT_3_WRRDTURN:
827 			/* Could be 2 or 5 Data Bytes Returned */
828 			ccc_tgt_payload.data_len =
829 				sizeof(((union i3c_ccc_getmxds *)0)->fmt3.wrrdturn);
830 			break;
831 		case GETMXDS_FORMAT_3_CRHDLY:
832 			/* Only 1 Byte returned */
833 			ccc_tgt_payload.data_len =
834 				sizeof(((union i3c_ccc_getmxds *)0)->fmt3.crhdly1);
835 			break;
836 		default:
837 			ret = -EINVAL;
838 			goto out;
839 		}
840 	} else {
841 		ret = -EINVAL;
842 		goto out;
843 	}
844 
845 	memset(&ccc_payload, 0, sizeof(ccc_payload));
846 	ccc_payload.ccc.id = I3C_CCC_GETMXDS;
847 	ccc_payload.targets.payloads = &ccc_tgt_payload;
848 	ccc_payload.targets.num_targets = 1;
849 
850 	if (fmt == GETMXDS_FORMAT_3) {
851 		defining_byte = (uint8_t)defbyte;
852 
853 		ccc_payload.ccc.data = &defining_byte;
854 		ccc_payload.ccc.data_len = 1;
855 	}
856 
857 	ret = i3c_do_ccc(target->bus, &ccc_payload);
858 
859 	if (ret == 0) {
860 		/* GETMXDS will return a variable length */
861 		len = ccc_tgt_payload.num_xfer;
862 
863 		if ((fmt == GETMXDS_FORMAT_1) || (fmt == GETMXDS_FORMAT_2)) {
864 			if (len == SIZEOF_FIELD(union i3c_ccc_getmxds, fmt1)) {
865 				mxds->fmt1.maxwr = data[0];
866 				mxds->fmt1.maxrd = data[1];
867 				/* It is unknown wither format 1 or format 2 is returned ahead of
868 				 * time
869 				 */
870 				memset(&mxds->fmt2.maxrdturn, 0, sizeof(mxds->fmt2.maxrdturn));
871 			} else if (len == SIZEOF_FIELD(union i3c_ccc_getmxds, fmt2)) {
872 				mxds->fmt2.maxwr = data[0];
873 				mxds->fmt2.maxrd = data[1];
874 				memcpy(&mxds->fmt2.maxrdturn, &data[2],
875 				       sizeof(mxds->fmt2.maxrdturn));
876 			}
877 		} else if (fmt == GETMXDS_FORMAT_3) {
878 			switch (defbyte) {
879 			case GETMXDS_FORMAT_3_WRRDTURN:
880 				memcpy(mxds->fmt3.wrrdturn, data, len);
881 				/* for values not received, assume default (1'b0) */
882 				memset(&mxds->fmt3.wrrdturn[len], 0,
883 				       sizeof(mxds->fmt3.wrrdturn) - len);
884 				break;
885 			case GETMXDS_FORMAT_3_CRHDLY:
886 				mxds->fmt3.crhdly1 = data[0];
887 				break;
888 			default:
889 				break;
890 			}
891 		}
892 	}
893 
894 out:
895 	return ret;
896 }
897 
i3c_ccc_do_setbuscon(const struct device * controller,uint8_t * context,uint16_t length)898 int i3c_ccc_do_setbuscon(const struct device *controller,
899 				uint8_t *context, uint16_t length)
900 {
901 	struct i3c_ccc_payload ccc_payload;
902 
903 	__ASSERT_NO_MSG(controller != NULL);
904 	__ASSERT_NO_MSG(context != NULL);
905 
906 	memset(&ccc_payload, 0, sizeof(ccc_payload));
907 	ccc_payload.ccc.id = I3C_CCC_SETBUSCON;
908 
909 	ccc_payload.ccc.data = context;
910 	ccc_payload.ccc.data_len = length;
911 
912 	return i3c_do_ccc(controller, &ccc_payload);
913 }
914 
i3c_ccc_do_getacccr(const struct i3c_device_desc * target,struct i3c_ccc_address * handoff_address)915 int i3c_ccc_do_getacccr(const struct i3c_device_desc *target,
916 			 struct i3c_ccc_address *handoff_address)
917 {
918 	struct i3c_ccc_payload ccc_payload;
919 	struct i3c_ccc_target_payload ccc_tgt_payload;
920 	int ret;
921 
922 	__ASSERT_NO_MSG(target != NULL);
923 	__ASSERT_NO_MSG(handoff_address != NULL);
924 
925 	ccc_tgt_payload.addr = target->dynamic_addr;
926 	ccc_tgt_payload.rnw = 1;
927 	ccc_tgt_payload.data = &handoff_address->addr;
928 	ccc_tgt_payload.data_len = 1;
929 
930 	memset(&ccc_payload, 0, sizeof(ccc_payload));
931 	ccc_payload.ccc.id = I3C_CCC_GETACCCR;
932 	ccc_payload.targets.payloads = &ccc_tgt_payload;
933 	ccc_payload.targets.num_targets = 1;
934 
935 	ret = i3c_do_ccc(target->bus, &ccc_payload);
936 
937 	return ret;
938 }
939