wilc1000: add reset/terminate/repeat command support for SPI bus
Add reset/terminate/repeat command for SPI module. In case of SPI commands failure, the host should issue a RESET command to WILC chip to recover from any temporary bus error. For now, the new command support is added and later the SPI read/write API's would be modified to make use of these commands for retry mechanism Signed-off-by: Ajay Singh <ajay.kathat@microchip.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/20210916164902.74629-6-ajay.kathat@microchip.com
This commit is contained in:
Родитель
5bb9de8bcb
Коммит
1bcc0879c9
|
@ -144,6 +144,12 @@ struct wilc_spi_rsp_data {
|
|||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct wilc_spi_special_cmd_rsp {
|
||||
u8 skip_byte;
|
||||
u8 rsp_cmd_type;
|
||||
u8 status;
|
||||
} __packed;
|
||||
|
||||
static int wilc_bus_probe(struct spi_device *spi)
|
||||
{
|
||||
int ret;
|
||||
|
@ -709,6 +715,61 @@ static int wilc_spi_dma_rw(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wilc_spi_special_cmd(struct wilc *wilc, u8 cmd)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(wilc->dev);
|
||||
struct wilc_spi *spi_priv = wilc->bus_data;
|
||||
u8 wb[32], rb[32];
|
||||
int cmd_len, resp_len = 0;
|
||||
struct wilc_spi_cmd *c;
|
||||
struct wilc_spi_special_cmd_rsp *r;
|
||||
|
||||
if (cmd != CMD_TERMINATE && cmd != CMD_REPEAT && cmd != CMD_RESET)
|
||||
return -EINVAL;
|
||||
|
||||
memset(wb, 0x0, sizeof(wb));
|
||||
memset(rb, 0x0, sizeof(rb));
|
||||
c = (struct wilc_spi_cmd *)wb;
|
||||
c->cmd_type = cmd;
|
||||
|
||||
if (cmd == CMD_RESET)
|
||||
memset(c->u.simple_cmd.addr, 0xFF, 3);
|
||||
|
||||
cmd_len = offsetof(struct wilc_spi_cmd, u.simple_cmd.crc);
|
||||
resp_len = sizeof(*r);
|
||||
|
||||
if (spi_priv->crc7_enabled) {
|
||||
c->u.simple_cmd.crc[0] = wilc_get_crc7(wb, cmd_len);
|
||||
cmd_len += 1;
|
||||
}
|
||||
if (cmd_len + resp_len > ARRAY_SIZE(wb)) {
|
||||
dev_err(&spi->dev, "spi buffer size too small (%d) (%d) (%zu)\n",
|
||||
cmd_len, resp_len, ARRAY_SIZE(wb));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wilc_spi_tx_rx(wilc, wb, rb, cmd_len + resp_len)) {
|
||||
dev_err(&spi->dev, "Failed cmd write, bus error...\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = (struct wilc_spi_special_cmd_rsp *)&rb[cmd_len];
|
||||
if (r->rsp_cmd_type != cmd) {
|
||||
if (!spi_priv->probing_crc)
|
||||
dev_err(&spi->dev,
|
||||
"Failed cmd response, cmd (%02x), resp (%02x)\n",
|
||||
cmd, r->rsp_cmd_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (r->status != WILC_SPI_COMMAND_STAT_SUCCESS) {
|
||||
dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
|
||||
r->status);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(wilc->dev);
|
||||
|
|
Загрузка…
Ссылка в новой задаче