in master/mipi-i3c-hci/cmd_v2.c [151:215]
static int hci_cmd_v2_prep_ccc(struct i3c_hci *hci, struct hci_xfer *xfer,
u8 ccc_addr, u8 ccc_cmd, bool raw)
{
unsigned int mode = XFERMODE_IDX_I3C_SDR;
unsigned int rate = get_i3c_rate_idx(hci);
u8 *data = xfer->data;
unsigned int data_len = xfer->data_len;
bool rnw = xfer->rnw;
if (raw && ccc_addr != I3C_BROADCAST_ADDR) {
hci_cmd_v2_prep_private_xfer(hci, xfer, ccc_addr, mode, rate);
return 0;
}
xfer->cmd_tid = hci_get_tid();
if (!rnw && data_len <= 4) {
xfer->cmd_desc[0] =
CMD_0_ATTR_U |
CMD_U0_TID(xfer->cmd_tid) |
CMD_U0_DEV_ADDRESS(ccc_addr) |
CMD_U0_XFER_RATE(rate) |
CMD_U0_MODE_INDEX(mode) |
CMD_U0_IDB_COUNT(data_len + (!raw ? 0 : 1));
xfer->cmd_desc[1] =
CMD_U1_DATA_LENGTH(0);
xfer->cmd_desc[2] =
CMD_U2_IDB0(ccc_cmd);
xfer->cmd_desc[3] = 0;
switch (data_len) {
case 4:
xfer->cmd_desc[3] |= CMD_U3_IDB4(data[3]);
fallthrough;
case 3:
xfer->cmd_desc[2] |= CMD_U2_IDB3(data[2]);
fallthrough;
case 2:
xfer->cmd_desc[2] |= CMD_U2_IDB2(data[1]);
fallthrough;
case 1:
xfer->cmd_desc[2] |= CMD_U2_IDB1(data[0]);
fallthrough;
case 0:
break;
}
/* we consumed all the data with the cmd descriptor */
xfer->data = NULL;
} else {
xfer->cmd_desc[0] =
CMD_0_ATTR_U |
CMD_U0_TID(xfer->cmd_tid) |
(rnw ? CMD_U0_RnW : 0) |
CMD_U0_DEV_ADDRESS(ccc_addr) |
CMD_U0_XFER_RATE(rate) |
CMD_U0_MODE_INDEX(mode) |
CMD_U0_IDB_COUNT(!raw ? 0 : 1);
xfer->cmd_desc[1] =
CMD_U1_DATA_LENGTH(data_len);
xfer->cmd_desc[2] =
CMD_U2_IDB0(ccc_cmd);
xfer->cmd_desc[3] = 0;
}
return 0;
}