/* * Linux flags are translated to BPMP defined I2C flags that are used in BPMP * firmware I2C driver to avoid any issues in future if Linux I2C flags are * changed.
*/ staticvoid tegra_bpmp_xlate_flags(u16 flags, u16 *out)
{ if (flags & I2C_M_TEN)
*out |= SERIALI2C_TEN;
if (flags & I2C_M_RD)
*out |= SERIALI2C_RD;
if (flags & I2C_M_STOP)
*out |= SERIALI2C_STOP;
if (flags & I2C_M_NOSTART)
*out |= SERIALI2C_NOSTART;
if (flags & I2C_M_REV_DIR_ADDR)
*out |= SERIALI2C_REV_DIR_ADDR;
if (flags & I2C_M_IGNORE_NAK)
*out |= SERIALI2C_IGNORE_NAK;
if (flags & I2C_M_NO_RD_ACK)
*out |= SERIALI2C_NO_RD_ACK;
if (flags & I2C_M_RECV_LEN)
*out |= SERIALI2C_RECV_LEN;
}
/* * The serialized I2C format is simply the following: * [addr little-endian][flags little-endian][len little-endian][data if write] * [addr little-endian][flags little-endian][len little-endian][data if write] * ... * * The flags are translated from Linux kernel representation to seriali2c * representation. Any undefined flag being set causes an error. * * The data is there only for writes. Reads have the data transferred in the * other direction, and thus data is not present. * * See deserialize_i2c documentation for the data format in the other direction.
*/ staticvoid tegra_bpmp_serialize_i2c_msg(struct tegra_bpmp_i2c *i2c, struct mrq_i2c_request *request, struct i2c_msg *msgs, unsignedint num)
{ char *buf = request->xfer.data_buf; unsignedint i, j, pos = 0;
for (i = 0; i < num; i++) { struct i2c_msg *msg = &msgs[i];
u16 flags = 0;
if ((flags & SERIALI2C_RD) == 0) { for (j = 0; j < msg->len; j++)
buf[pos++] = msg->buf[j];
}
}
request->xfer.data_size = pos;
}
/* * The data in the BPMP -> CPU direction is composed of sequential blocks for * those messages that have I2C_M_RD. So, for example, if you have: * * - !I2C_M_RD, len == 5, data == a0 01 02 03 04 * - !I2C_M_RD, len == 1, data == a0 * - I2C_M_RD, len == 2, data == [uninitialized buffer 1] * - !I2C_M_RD, len == 1, data == a2 * - I2C_M_RD, len == 2, data == [uninitialized buffer 2] * * ...then the data in the BPMP -> CPU direction would be 4 bytes total, and * would contain 2 bytes that will go to uninitialized buffer 1, and 2 bytes * that will go to uninitialized buffer 2.
*/ staticint tegra_bpmp_i2c_deserialize(struct tegra_bpmp_i2c *i2c, struct mrq_i2c_response *response, struct i2c_msg *msgs, unsignedint num)
{
size_t size = response->xfer.data_size, len = 0, pos = 0; char *buf = response->xfer.data_buf; unsignedint i;
for (i = 0; i < num; i++) if (msgs[i].flags & I2C_M_RD)
len += msgs[i].len;
if (len != size) return -EINVAL;
for (i = 0; i < num; i++) { if (msgs[i].flags & I2C_M_RD) {
memcpy(msgs[i].buf, buf + pos, msgs[i].len);
pos += msgs[i].len;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.