Lines Matching +full:bcm6358 +full:- +full:spi

1 // SPDX-License-Identifier: GPL-2.0+
5 * Derived from linux/drivers/spi/spi-bcm63xx.c:
6 * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
13 #include <spi.h>
18 /* BCM6348 SPI core */
31 /* BCM6358 SPI core */
44 /* SPI Clock register */
61 /* SPI Command register */
71 /* SPI Control register */
76 /* SPI Interrupt registers */
131 if (cs >= priv->num_cs) { in bcm63xx_spi_cs_info()
133 return -ENODEV; in bcm63xx_spi_cs_info()
142 const unsigned long *regs = priv->regs; in bcm63xx_spi_set_mode()
145 setbits_8(priv->base + regs[SPI_CLK], SPI_CLK_BSWAP_MASK); in bcm63xx_spi_set_mode()
147 clrbits_8(priv->base + regs[SPI_CLK], SPI_CLK_BSWAP_MASK); in bcm63xx_spi_set_mode()
155 const unsigned long *regs = priv->regs; in bcm63xx_spi_set_speed()
171 clrsetbits_8(priv->base + regs[SPI_CLK], in bcm63xx_spi_set_speed()
179 * BCM63xx SPI driver doesn't allow keeping CS active between transfers since
183 * SPI-connected flashes since reading requires prepending a write transfer of
197 struct bcm63xx_spi_priv *priv = dev_get_priv(dev->parent); in bcm63xx_spi_xfer()
198 const unsigned long *regs = priv->regs; in bcm63xx_spi_xfer()
203 priv->tx_bytes = 0; in bcm63xx_spi_xfer()
206 writeb_be(0, priv->base + regs[SPI_IR_MASK]); in bcm63xx_spi_xfer()
213 return -EINVAL; in bcm63xx_spi_xfer()
219 return -EMSGSIZE; in bcm63xx_spi_xfer()
225 if (priv->tx_bytes + data_bytes > regs[SPI_TX_SIZE]) { in bcm63xx_spi_xfer()
227 return -EMSGSIZE; in bcm63xx_spi_xfer()
231 memcpy_toio(priv->base + regs[SPI_TX] + priv->tx_bytes, in bcm63xx_spi_xfer()
233 priv->tx_bytes += data_bytes; in bcm63xx_spi_xfer()
245 val = priv->tx_bytes; in bcm63xx_spi_xfer()
247 priv->tx_bytes = 0; in bcm63xx_spi_xfer()
254 priv->tx_bytes = 0; in bcm63xx_spi_xfer()
260 if (priv->tx_bytes > SPI_CMD_PREPEND_BYTES) { in bcm63xx_spi_xfer()
262 return -EMSGSIZE; in bcm63xx_spi_xfer()
268 writew_be(val, priv->base + regs[SPI_CTL]); in bcm63xx_spi_xfer()
270 writeb_be(val, priv->base + regs[SPI_CTL]); in bcm63xx_spi_xfer()
273 writeb_be(SPI_IR_CLEAR_MASK, priv->base + regs[SPI_IR_STAT]); in bcm63xx_spi_xfer()
277 cmd |= (plat->cs << SPI_CMD_SLAVE_SHIFT) & SPI_CMD_SLAVE_MASK; in bcm63xx_spi_xfer()
278 cmd |= (priv->tx_bytes << SPI_CMD_PREPEND_SHIFT); in bcm63xx_spi_xfer()
279 if (plat->mode & SPI_3WIRE) in bcm63xx_spi_xfer()
281 writew_be(cmd, priv->base + regs[SPI_CMD]); in bcm63xx_spi_xfer()
284 writeb_be(SPI_IR_DONE_MASK, priv->base + regs[SPI_IR_MASK]); in bcm63xx_spi_xfer()
286 ret = wait_for_bit_8(priv->base + regs[SPI_IR_STAT], in bcm63xx_spi_xfer()
295 memcpy_fromio(din, priv->base + regs[SPI_RX], in bcm63xx_spi_xfer()
339 .compatible = "brcm,bcm6348-spi",
342 .compatible = "brcm,bcm6358-spi",
349 struct bcm63xx_spi_priv *priv = dev_get_priv(dev->parent); in bcm63xx_spi_child_pre_probe()
350 const unsigned long *regs = priv->regs; in bcm63xx_spi_child_pre_probe()
355 if (plat->cs >= priv->num_cs) { in bcm63xx_spi_child_pre_probe()
356 printf("no cs %u\n", plat->cs); in bcm63xx_spi_child_pre_probe()
357 return -ENODEV; in bcm63xx_spi_child_pre_probe()
361 slave->max_read_size = regs[SPI_RX_SIZE]; in bcm63xx_spi_child_pre_probe()
362 slave->max_write_size = regs[SPI_TX_SIZE]; in bcm63xx_spi_child_pre_probe()
376 priv->base = dev_remap_addr(dev); in bcm63xx_spi_probe()
377 if (!priv->base) in bcm63xx_spi_probe()
378 return -EINVAL; in bcm63xx_spi_probe()
380 priv->regs = regs; in bcm63xx_spi_probe()
381 priv->num_cs = dev_read_u32_default(dev, "num-cs", 8); in bcm63xx_spi_probe()
410 writeb_be(0, priv->base + regs[SPI_IR_MASK]); in bcm63xx_spi_probe()
413 writeb_be(0xff, priv->base + regs[SPI_FILL]); in bcm63xx_spi_probe()