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 >= 12500000) in get_i3c_mode()
128 if (bus->scl_rate.i3c > 8000000) in get_i3c_mode()
130 if (bus->scl_rate.i3c > 6000000) in get_i3c_mode()
132 if (bus->scl_rate.i3c > 4000000) in get_i3c_mode()
134 if (bus->scl_rate.i3c > 2000000) in get_i3c_mode()
139 static enum hci_cmd_mode get_i2c_mode(struct i3c_hci *hci) in get_i2c_mode() argument
141 struct i3c_bus *bus = i3c_master_get_bus(&hci->master); in get_i2c_mode()
143 if (bus->scl_rate.i2c >= 1000000) in get_i2c_mode()
151 xfer->cmd_desc[1] = 0; in fill_data_bytes()
154 xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_4(data[3]); in fill_data_bytes()
157 xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_3(data[2]); in fill_data_bytes()
160 xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_2(data[1]); in fill_data_bytes()
163 xfer->cmd_desc[1] |= CMD_I1_DATA_BYTE_1(data[0]); in fill_data_bytes()
169 xfer->data = NULL; in fill_data_bytes()
172 static int hci_cmd_v1_prep_ccc(struct i3c_hci *hci, in hci_cmd_v1_prep_ccc() argument
177 enum hci_cmd_mode mode = get_i3c_mode(hci); in hci_cmd_v1_prep_ccc()
178 u8 *data = xfer->data; in hci_cmd_v1_prep_ccc()
179 unsigned int data_len = xfer->data_len; in hci_cmd_v1_prep_ccc()
180 bool rnw = xfer->rnw; in hci_cmd_v1_prep_ccc()
185 return -EINVAL; in hci_cmd_v1_prep_ccc()
188 ret = mipi_i3c_hci_dat_v1.get_index(hci, ccc_addr); in hci_cmd_v1_prep_ccc()
194 xfer->cmd_tid = hci_get_tid(); in hci_cmd_v1_prep_ccc()
198 xfer->cmd_desc[0] = in hci_cmd_v1_prep_ccc()
200 CMD_I0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_ccc()
208 xfer->cmd_desc[0] = in hci_cmd_v1_prep_ccc()
210 CMD_R0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_ccc()
215 xfer->cmd_desc[1] = in hci_cmd_v1_prep_ccc()
222 static void hci_cmd_v1_prep_i3c_xfer(struct i3c_hci *hci, in hci_cmd_v1_prep_i3c_xfer() argument
227 unsigned int dat_idx = dev_data->dat_idx; in hci_cmd_v1_prep_i3c_xfer()
228 enum hci_cmd_mode mode = get_i3c_mode(hci); in hci_cmd_v1_prep_i3c_xfer()
229 u8 *data = xfer->data; in hci_cmd_v1_prep_i3c_xfer()
230 unsigned int data_len = xfer->data_len; in hci_cmd_v1_prep_i3c_xfer()
231 bool rnw = xfer->rnw; in hci_cmd_v1_prep_i3c_xfer()
233 xfer->cmd_tid = hci_get_tid(); in hci_cmd_v1_prep_i3c_xfer()
237 xfer->cmd_desc[0] = in hci_cmd_v1_prep_i3c_xfer()
239 CMD_I0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_i3c_xfer()
246 xfer->cmd_desc[0] = in hci_cmd_v1_prep_i3c_xfer()
248 CMD_R0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_i3c_xfer()
252 xfer->cmd_desc[1] = in hci_cmd_v1_prep_i3c_xfer()
257 static void hci_cmd_v1_prep_i2c_xfer(struct i3c_hci *hci, in hci_cmd_v1_prep_i2c_xfer() argument
262 unsigned int dat_idx = dev_data->dat_idx; in hci_cmd_v1_prep_i2c_xfer()
263 enum hci_cmd_mode mode = get_i2c_mode(hci); in hci_cmd_v1_prep_i2c_xfer()
264 u8 *data = xfer->data; in hci_cmd_v1_prep_i2c_xfer()
265 unsigned int data_len = xfer->data_len; in hci_cmd_v1_prep_i2c_xfer()
266 bool rnw = xfer->rnw; in hci_cmd_v1_prep_i2c_xfer()
268 xfer->cmd_tid = hci_get_tid(); in hci_cmd_v1_prep_i2c_xfer()
272 xfer->cmd_desc[0] = in hci_cmd_v1_prep_i2c_xfer()
274 CMD_I0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_i2c_xfer()
281 xfer->cmd_desc[0] = in hci_cmd_v1_prep_i2c_xfer()
283 CMD_R0_TID(xfer->cmd_tid) | in hci_cmd_v1_prep_i2c_xfer()
287 xfer->cmd_desc[1] = in hci_cmd_v1_prep_i2c_xfer()
292 static int hci_cmd_v1_daa(struct i3c_hci *hci) in hci_cmd_v1_daa() argument
295 int ret, dat_idx = -1; in hci_cmd_v1_daa()
303 return -ENOMEM; in hci_cmd_v1_daa()
313 ret = mipi_i3c_hci_dat_v1.alloc_entry(hci); in hci_cmd_v1_daa()
317 ret = i3c_master_get_free_addr(&hci->master, next_addr); in hci_cmd_v1_daa()
323 mipi_i3c_hci_dat_v1.set_dynamic_addr(hci, dat_idx, next_addr); in hci_cmd_v1_daa()
324 mipi_i3c_hci_dct_index_reset(hci); in hci_cmd_v1_daa()
326 xfer->cmd_tid = hci_get_tid(); in hci_cmd_v1_daa()
327 xfer->cmd_desc[0] = in hci_cmd_v1_daa()
329 CMD_A0_TID(xfer->cmd_tid) | in hci_cmd_v1_daa()
334 xfer->cmd_desc[1] = 0; in hci_cmd_v1_daa()
335 hci->io->queue_xfer(hci, xfer, 1); in hci_cmd_v1_daa()
337 hci->io->dequeue_xfer(hci, xfer, 1)) { in hci_cmd_v1_daa()
338 ret = -ETIME; 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()