summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSvyatoslav Ryhel <[email protected]>2023-02-14 19:35:29 +0200
committerTom <[email protected]>2023-02-23 12:55:36 -0700
commit09ca4d802887defff2ba8ae6639703d6046136cf (patch)
tree809a1e9b21e112d1cf6cc448995a447514d3d936 /drivers
parent23d24df34cdd8157d10d302dbba798cd0b518451 (diff)
spi: tegra20_slink: accept any word length
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 <[email protected]> # ASUS TF600T T30 Tested-by: Svyatoslav Ryhel <[email protected]> # LG P895 T30 Tested-by: Thierry Reding <[email protected]> # T30 and T124 Signed-off-by: Svyatoslav Ryhel <[email protected]> Signed-off-by: Tom <[email protected]>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/tegra20_slink.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c
index 209ba8b0ccf..d0e788539e0 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(&regs->status);
writel(reg, &regs->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(&regs->command, SLINK_CMD_BIT_LENGTH_MASK,
- bytes * 8 - 1);
+ if (overflow && !num_bytes)
+ clrsetbits_le32(&regs->command, SLINK_CMD_BIT_LENGTH_MASK,
+ (bytes - 1) * 8 + overflow - 1);
+ else
+ clrsetbits_le32(&regs->command, SLINK_CMD_BIT_LENGTH_MASK,
+ bytes * 8 - 1);
+
writel(tmpdout, &regs->tx_fifo);
setbits_le32(&regs->command, SLINK_CMD_GO);