Lines Matching +full:mipi +full:- +full:i3c +full:- +full:hci

1 // SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2020, MIPI Alliance, Inc.
7 * I3C HCI v1.0/v1.1 Command Descriptor Handling
11 #include <linux/i3c/master.h>
13 #include "hci.h"
122 static enum hci_cmd_mode get_i3c_mode(struct i3c_hci *hci) in get_i3c_mode() argument
124 struct i3c_bus *bus = i3c_master_get_bus(&hci->master); in get_i3c_mode()
126 if (bus->scl_rate.i3c > 8000000) in get_i3c_mode()
128 if (bus->scl_rate.i3c > 6000000) in get_i3c_mode()
130 if (bus->scl_rate.i3c > 4000000) in get_i3c_mode()
132 if (bus->scl_rate.i3c > 2000000) in get_i3c_mode()
137 static enum hci_cmd_mode get_i2c_mode(struct i3c_hci *hci) in get_i2c_mode() argument
139 struct i3c_bus *bus = i3c_master_get_bus(&hci->master); in get_i2c_mode()
141 if (bus->scl_rate.i2c >= 1000000) in get_i2c_mode()
149 xfer->cmd_desc[1] = 0; in fill_data_bytes()
152 xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_4(data[3]); in fill_data_bytes()
155 xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_3(data[2]); in fill_data_bytes()
158 xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_2(data[1]); in fill_data_bytes()
161 xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_1(data[0]); in fill_data_bytes()
167 xfer->data = NULL; in fill_data_bytes()
170 static int hci_cmd_v1_prep_ccc(struct i3c_hci *hci, in hci_cmd_v1_prep_ccc() argument
175 enum hci_cmd_mode mode = get_i3c_mode(hci); in hci_cmd_v1_prep_ccc()
176 u8 *data = xfer->data; in hci_cmd_v1_prep_ccc()
177 unsigned int data_len = xfer->data_len; in hci_cmd_v1_prep_ccc()
178 bool rnw = xfer->rnw; in hci_cmd_v1_prep_ccc()
183 return -EINVAL; in hci_cmd_v1_prep_ccc()
186 ret = mipi_i3c_hci_dat_v1.get_index(hci, ccc_addr); in hci_cmd_v1_prep_ccc()
192 xfer->cmd_tid = hci_get_tid(); in hci_cmd_v1_prep_ccc()
196 xfer->cmd_desc[0] = in hci_cmd_v1_prep_ccc()
198 CMD_I0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_ccc()
206 xfer->cmd_desc[0] = in hci_cmd_v1_prep_ccc()
208 CMD_R0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_ccc()
213 xfer->cmd_desc[1] = in hci_cmd_v1_prep_ccc()
220 static void hci_cmd_v1_prep_i3c_xfer(struct i3c_hci *hci, in hci_cmd_v1_prep_i3c_xfer() argument
225 unsigned int dat_idx = dev_data->dat_idx; in hci_cmd_v1_prep_i3c_xfer()
226 enum hci_cmd_mode mode = get_i3c_mode(hci); in hci_cmd_v1_prep_i3c_xfer()
227 u8 *data = xfer->data; in hci_cmd_v1_prep_i3c_xfer()
228 unsigned int data_len = xfer->data_len; in hci_cmd_v1_prep_i3c_xfer()
229 bool rnw = xfer->rnw; in hci_cmd_v1_prep_i3c_xfer()
231 xfer->cmd_tid = hci_get_tid(); in hci_cmd_v1_prep_i3c_xfer()
235 xfer->cmd_desc[0] = in hci_cmd_v1_prep_i3c_xfer()
237 CMD_I0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_i3c_xfer()
244 xfer->cmd_desc[0] = in hci_cmd_v1_prep_i3c_xfer()
246 CMD_R0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_i3c_xfer()
250 xfer->cmd_desc[1] = in hci_cmd_v1_prep_i3c_xfer()
255 static void hci_cmd_v1_prep_i2c_xfer(struct i3c_hci *hci, in hci_cmd_v1_prep_i2c_xfer() argument
260 unsigned int dat_idx = dev_data->dat_idx; in hci_cmd_v1_prep_i2c_xfer()
261 enum hci_cmd_mode mode = get_i2c_mode(hci); in hci_cmd_v1_prep_i2c_xfer()
262 u8 *data = xfer->data; in hci_cmd_v1_prep_i2c_xfer()
263 unsigned int data_len = xfer->data_len; in hci_cmd_v1_prep_i2c_xfer()
264 bool rnw = xfer->rnw; in hci_cmd_v1_prep_i2c_xfer()
266 xfer->cmd_tid = hci_get_tid(); in hci_cmd_v1_prep_i2c_xfer()
270 xfer->cmd_desc[0] = in hci_cmd_v1_prep_i2c_xfer()
272 CMD_I0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_i2c_xfer()
279 xfer->cmd_desc[0] = in hci_cmd_v1_prep_i2c_xfer()
281 CMD_R0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_i2c_xfer()
285 xfer->cmd_desc[1] = in hci_cmd_v1_prep_i2c_xfer()
290 static int hci_cmd_v1_daa(struct i3c_hci *hci) in hci_cmd_v1_daa() argument
293 int ret, dat_idx = -1; in hci_cmd_v1_daa()
301 return -ENOMEM; in hci_cmd_v1_daa()
311 ret = mipi_i3c_hci_dat_v1.alloc_entry(hci); in hci_cmd_v1_daa()
315 ret = i3c_master_get_free_addr(&hci->master, next_addr); in hci_cmd_v1_daa()
321 mipi_i3c_hci_dat_v1.set_dynamic_addr(hci, dat_idx, next_addr); in hci_cmd_v1_daa()
322 mipi_i3c_hci_dct_index_reset(hci); in hci_cmd_v1_daa()
324 xfer->cmd_tid = hci_get_tid(); in hci_cmd_v1_daa()
325 xfer->cmd_desc[0] = in hci_cmd_v1_daa()
327 CMD_A0_TID(xfer->cmd_tid) | in hci_cmd_v1_daa()
332 xfer->cmd_desc[1] = 0; in hci_cmd_v1_daa()
333 xfer->completion = &done; in hci_cmd_v1_daa()
334 hci->io->queue_xfer(hci, xfer, 1); in hci_cmd_v1_daa()
336 hci->io->dequeue_xfer(hci, xfer, 1)) { in hci_cmd_v1_daa()
337 ret = -ETIME; in hci_cmd_v1_daa()
340 if ((RESP_STATUS(xfer->response) == RESP_ERR_ADDR_HEADER || in hci_cmd_v1_daa()
341 RESP_STATUS(xfer->response) == RESP_ERR_NACK) && in hci_cmd_v1_daa()
342 RESP_DATA_LENGTH(xfer->response) == 1) { in hci_cmd_v1_daa()
346 if (RESP_STATUS(xfer->response) != RESP_SUCCESS) { in hci_cmd_v1_daa()
347 ret = -EIO; in hci_cmd_v1_daa()
351 i3c_hci_dct_get_val(hci, 0, &pid, &dcr, &bcr); in hci_cmd_v1_daa()
355 mipi_i3c_hci_dat_v1.free_entry(hci, dat_idx); in hci_cmd_v1_daa()
356 dat_idx = -1; in hci_cmd_v1_daa()
362 ret = i3c_master_add_i3c_dev_locked(&hci->master, next_addr); in hci_cmd_v1_daa()
368 mipi_i3c_hci_dat_v1.free_entry(hci, dat_idx); in hci_cmd_v1_daa()