/* I2C data */ struct i2c_client *client; enum chips id;
u8 buffer[SC18IS602_BUFSIZ + 1]; int tlen; /* Data queued for tx in buffer */ int rindex; /* Receive data index in buffer */
struct gpio_desc *reset;
};
staticint sc18is602_wait_ready(struct sc18is602 *hw, int len)
{ int i, err; int usecs = 1000000 * len / hw->speed + 1;
u8 dummy[1];
for (i = 0; i < 10; i++) {
err = i2c_master_recv(hw->client, dummy, 1); if (err >= 0) return 0;
usleep_range(usecs, usecs * 2);
} return -ETIMEDOUT;
}
staticint sc18is602_txrx(struct sc18is602 *hw, struct spi_message *msg, struct spi_transfer *t, bool do_transfer)
{ unsignedint len = t->len; int ret;
if (hw->tlen == 0) { /* First byte (I2C command) is chip select */
hw->buffer[0] = 1 << spi_get_chipselect(msg->spi, 0);
hw->tlen = 1;
hw->rindex = 0;
} /* * We can not immediately send data to the chip, since each I2C message * resembles a full SPI message (from CS active to CS inactive). * Enqueue messages up to the first read or until do_transfer is true.
*/ if (t->tx_buf) {
memcpy(&hw->buffer[hw->tlen], t->tx_buf, len);
hw->tlen += len; if (t->rx_buf)
do_transfer = true; else
hw->rindex = hw->tlen - 1;
} elseif (t->rx_buf) { /* * For receive-only transfers we still need to perform a dummy * write to receive data from the SPI chip. * Read data starts at the end of transmit data (minus 1 to * account for CS).
*/
hw->rindex = hw->tlen - 1;
memset(&hw->buffer[hw->tlen], 0, len);
hw->tlen += len;
do_transfer = true;
}
if (do_transfer && hw->tlen > 1) {
ret = sc18is602_wait_ready(hw, SC18IS602_BUFSIZ); if (ret < 0) return ret;
ret = i2c_master_send(hw->client, hw->buffer, hw->tlen); if (ret < 0) return ret; if (ret != hw->tlen) return -EIO;
if (t->rx_buf) { int rlen = hw->rindex + len;
ret = sc18is602_wait_ready(hw, hw->tlen); if (ret < 0) return ret;
ret = i2c_master_recv(hw->client, hw->buffer, rlen); if (ret < 0) return ret; if (ret != rlen) return -EIO;
memcpy(t->rx_buf, &hw->buffer[hw->rindex], len);
}
hw->tlen = 0;
} return len;
}
/* * Don't do anything if the control value did not change. The initial * value of 0xff for hw->ctrl ensures that the correct mode will be set * with the first call to this function.
*/ if (ctrl == hw->ctrl) return 0;
ret = i2c_smbus_write_byte_data(hw->client, 0xf0, ctrl); if (ret < 0) return ret;
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.