Original t20 slink could work with commands only fully divisible by 8. This patch removes such restriction, so commands of any bitlength now can be passed and processed.
Tested-by: Andreas Westman Dorcsak <hed...@yahoo.com> # ASUS TF600T T30 Tested-by: Svyatoslav Ryhel <clamo...@gmail.com> # LG P895 T30 Signed-off-by: Svyatoslav Ryhel <clamo...@gmail.com> --- drivers/spi/tegra20_slink.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c index 209ba8b0cc..d0e788539e 100644 --- a/drivers/spi/tegra20_slink.c +++ b/drivers/spi/tegra20_slink.c @@ -208,16 +208,14 @@ static int tegra30_spi_xfer(struct udevice *dev, unsigned int bitlen, u32 reg, tmpdout, tmpdin = 0; const u8 *dout = data_out; u8 *din = data_in; - int num_bytes; - int ret; + int num_bytes, overflow; + int ret = 0; debug("%s: slave %u:%u dout %p din %p bitlen %u\n", __func__, dev_seq(bus), spi_chip_select(dev), dout, din, bitlen); - if (bitlen % 8) - return -1; - num_bytes = bitlen / 8; - ret = 0; + num_bytes = DIV_ROUND_UP(bitlen, 8); + overflow = bitlen % 8; reg = readl(®s->status); writel(reg, ®s->status); /* Clear all SPI events via R/W */ @@ -254,8 +252,13 @@ static int tegra30_spi_xfer(struct udevice *dev, unsigned int bitlen, num_bytes -= bytes; - clrsetbits_le32(®s->command, SLINK_CMD_BIT_LENGTH_MASK, - bytes * 8 - 1); + if (overflow && !num_bytes) + clrsetbits_le32(®s->command, SLINK_CMD_BIT_LENGTH_MASK, + (bytes - 1) * 8 + overflow - 1); + else + clrsetbits_le32(®s->command, SLINK_CMD_BIT_LENGTH_MASK, + bytes * 8 - 1); + writel(tmpdout, ®s->tx_fifo); setbits_le32(®s->command, SLINK_CMD_GO); -- 2.37.2