mirror of https://gitee.com/openkylin/linux.git
i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
The code related to packet header setting up is a bit messy and makes tegra_i2c_xfer_msg() more difficult to read than it could be. Let's factor the packet header setup from tegra_i2c_xfer_msg() into separate function in order to make code easier to read and follow. Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Acked-by: Thierry Reding <treding@nvidia.com> Tested-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Wolfram Sang <wsa@kernel.org>
This commit is contained in:
parent
4a8e0f8797
commit
4be62340f3
|
@ -281,7 +281,7 @@ struct tegra_i2c_dev {
|
|||
struct dma_chan *tx_dma_chan;
|
||||
struct dma_chan *rx_dma_chan;
|
||||
dma_addr_t dma_phys;
|
||||
u32 *dma_buf;
|
||||
void *dma_buf;
|
||||
unsigned int dma_buf_size;
|
||||
bool is_curr_dma_xfer;
|
||||
struct completion dma_complete;
|
||||
|
@ -1105,6 +1105,57 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
|
|||
return -EAGAIN;
|
||||
}
|
||||
|
||||
static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
|
||||
struct i2c_msg *msg,
|
||||
enum msg_end_type end_state)
|
||||
{
|
||||
u32 *dma_buf = i2c_dev->dma_buf;
|
||||
u32 packet_header;
|
||||
|
||||
packet_header = FIELD_PREP(PACKET_HEADER0_HEADER_SIZE, 0) |
|
||||
FIELD_PREP(PACKET_HEADER0_PROTOCOL,
|
||||
PACKET_HEADER0_PROTOCOL_I2C) |
|
||||
FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
|
||||
FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
|
||||
|
||||
if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
|
||||
*dma_buf++ = packet_header;
|
||||
else
|
||||
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
|
||||
|
||||
packet_header = msg->len - 1;
|
||||
|
||||
if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
|
||||
*dma_buf++ = packet_header;
|
||||
else
|
||||
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
|
||||
|
||||
packet_header = I2C_HEADER_IE_ENABLE;
|
||||
|
||||
if (end_state == MSG_END_CONTINUE)
|
||||
packet_header |= I2C_HEADER_CONTINUE_XFER;
|
||||
else if (end_state == MSG_END_REPEAT_START)
|
||||
packet_header |= I2C_HEADER_REPEAT_START;
|
||||
|
||||
if (msg->flags & I2C_M_TEN) {
|
||||
packet_header |= msg->addr;
|
||||
packet_header |= I2C_HEADER_10BIT_ADDR;
|
||||
} else {
|
||||
packet_header |= msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;
|
||||
}
|
||||
|
||||
if (msg->flags & I2C_M_IGNORE_NAK)
|
||||
packet_header |= I2C_HEADER_CONT_ON_NAK;
|
||||
|
||||
if (msg->flags & I2C_M_RD)
|
||||
packet_header |= I2C_HEADER_READ;
|
||||
|
||||
if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
|
||||
*dma_buf++ = packet_header;
|
||||
else
|
||||
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
|
||||
}
|
||||
|
||||
static int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev,
|
||||
struct i2c_msg *msg)
|
||||
{
|
||||
|
@ -1135,11 +1186,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
|
|||
struct i2c_msg *msg,
|
||||
enum msg_end_type end_state)
|
||||
{
|
||||
u32 packet_header;
|
||||
u32 int_mask;
|
||||
unsigned long time_left;
|
||||
size_t xfer_size;
|
||||
u32 *buffer = NULL;
|
||||
int err = 0;
|
||||
u16 xfer_time = 100;
|
||||
|
||||
|
@ -1192,49 +1241,15 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
|
|||
i2c_dev->dma_phys,
|
||||
xfer_size,
|
||||
DMA_TO_DEVICE);
|
||||
buffer = i2c_dev->dma_buf;
|
||||
}
|
||||
}
|
||||
|
||||
packet_header = FIELD_PREP(PACKET_HEADER0_HEADER_SIZE, 0) |
|
||||
FIELD_PREP(PACKET_HEADER0_PROTOCOL,
|
||||
PACKET_HEADER0_PROTOCOL_I2C) |
|
||||
FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
|
||||
FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
|
||||
if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
|
||||
*buffer++ = packet_header;
|
||||
else
|
||||
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
|
||||
|
||||
packet_header = msg->len - 1;
|
||||
if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
|
||||
*buffer++ = packet_header;
|
||||
else
|
||||
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
|
||||
|
||||
packet_header = I2C_HEADER_IE_ENABLE;
|
||||
if (end_state == MSG_END_CONTINUE)
|
||||
packet_header |= I2C_HEADER_CONTINUE_XFER;
|
||||
else if (end_state == MSG_END_REPEAT_START)
|
||||
packet_header |= I2C_HEADER_REPEAT_START;
|
||||
if (msg->flags & I2C_M_TEN) {
|
||||
packet_header |= msg->addr;
|
||||
packet_header |= I2C_HEADER_10BIT_ADDR;
|
||||
} else {
|
||||
packet_header |= msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;
|
||||
}
|
||||
if (msg->flags & I2C_M_IGNORE_NAK)
|
||||
packet_header |= I2C_HEADER_CONT_ON_NAK;
|
||||
if (msg->flags & I2C_M_RD)
|
||||
packet_header |= I2C_HEADER_READ;
|
||||
if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
|
||||
*buffer++ = packet_header;
|
||||
else
|
||||
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
|
||||
tegra_i2c_push_packet_header(i2c_dev, msg, end_state);
|
||||
|
||||
if (!i2c_dev->msg_read) {
|
||||
if (i2c_dev->is_curr_dma_xfer) {
|
||||
memcpy(buffer, msg->buf, msg->len);
|
||||
memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
|
||||
msg->buf, msg->len);
|
||||
dma_sync_single_for_device(i2c_dev->dev,
|
||||
i2c_dev->dma_phys,
|
||||
xfer_size,
|
||||
|
|
Loading…
Reference in New Issue