static int hci_cmd_v2_prep_ccc()

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;
}