Lines Matching +full:spi +full:- +full:base
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2003-2015 Broadcom Corporation
11 #include <linux/spi/spi.h>
14 /* SPI Configuration Register */
25 /* SPI Frequency Divider Register */
28 /* SPI Command Register */
37 /* SPI Status Register */
47 /* SPI Interrupt Enable Register */
55 /* SPI FIFO Threshold Register */
58 /* SPI FIFO Word Count Register */
64 /* SPI Transmit Data FIFO Register */
67 /* SPI Receive Data FIFO Register */
70 /* SPI System Control Register */
84 * SPI can transfer only 28 bytes properly at a time. So split the
91 void __iomem *base; /* spi registers base address */ member
99 u32 spi_clk; /* spi clock frequency */
107 return readl(priv->base + regoff + cs * SPI_CS_OFFSET); in xlp_spi_reg_read()
113 writel(val, priv->base + regoff + cs * SPI_CS_OFFSET); in xlp_spi_reg_write()
119 writel(val, priv->base + regoff); in xlp_spi_sysctl_write()
123 * Setup global SPI_SYSCTRL register for all SPI channels.
135 static int xlp_spi_setup(struct spi_device *spi) in xlp_spi_setup() argument
141 xspi = spi_controller_get_devdata(spi->controller); in xlp_spi_setup()
142 cs = spi_get_chipselect(spi, 0); in xlp_spi_setup()
146 fdiv = DIV_ROUND_UP(xspi->spi_clk, spi->max_speed_hz); in xlp_spi_setup()
155 if (spi->mode & SPI_CPHA) in xlp_spi_setup()
159 if (spi->mode & SPI_CPOL) in xlp_spi_setup()
163 if (!(spi->mode & SPI_CS_HIGH)) in xlp_spi_setup()
167 if (spi->mode & SPI_LSB_FIRST) in xlp_spi_setup()
185 rxfifo_cnt = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_FIFO_WCNT); in xlp_spi_read_rxfifo()
188 rx_data = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_RXDATA_FIFO); in xlp_spi_read_rxfifo()
190 nbytes = min(xspi->rx_len, 4); in xlp_spi_read_rxfifo()
191 for (i = nbytes - 1; i >= 0; i--, j++) in xlp_spi_read_rxfifo()
192 xspi->rx_buf[i] = (rx_data >> (j * 8)) & 0xff; in xlp_spi_read_rxfifo()
194 xspi->rx_len -= nbytes; in xlp_spi_read_rxfifo()
195 xspi->rx_buf += nbytes; in xlp_spi_read_rxfifo()
196 rxfifo_cnt--; in xlp_spi_read_rxfifo()
205 txfifo_cnt = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_FIFO_WCNT); in xlp_spi_fill_txfifo()
208 while (xspi->tx_len && (txfifo_cnt < XLP_SPI_FIFO_SIZE)) { in xlp_spi_fill_txfifo()
211 nbytes = min(xspi->tx_len, 4); in xlp_spi_fill_txfifo()
212 for (i = nbytes - 1; i >= 0; i--, j++) in xlp_spi_fill_txfifo()
213 tx_data |= xspi->tx_buf[i] << (j * 8); in xlp_spi_fill_txfifo()
215 xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_TXDATA_FIFO, tx_data); in xlp_spi_fill_txfifo()
216 xspi->tx_len -= nbytes; in xlp_spi_fill_txfifo()
217 xspi->tx_buf += nbytes; in xlp_spi_fill_txfifo()
227 stat = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_STATUS) & in xlp_spi_interrupt()
233 if (xspi->tx_len) in xlp_spi_interrupt()
236 xspi->txerrors++; in xlp_spi_interrupt()
240 if (xspi->rx_len) in xlp_spi_interrupt()
243 xspi->rxerrors++; in xlp_spi_interrupt()
247 xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_STATUS, stat); in xlp_spi_interrupt()
249 complete(&xspi->done); in xlp_spi_interrupt()
259 if (xspi->tx_buf) in xlp_spi_send_cmd()
261 if (xspi->rx_buf) in xlp_spi_send_cmd()
265 cmd |= ((xfer_len * 8 - 1) << XLP_SPI_XFR_BITCNT_SHIFT); in xlp_spi_send_cmd()
266 xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_CMD, cmd); in xlp_spi_send_cmd()
276 xs->tx_buf = tx_buf; in xlp_spi_xfer_block()
277 xs->rx_buf = rx_buf; in xlp_spi_xfer_block()
278 xs->tx_len = (xs->tx_buf == NULL) ? 0 : xfer_len; in xlp_spi_xfer_block()
279 xs->rx_len = (xs->rx_buf == NULL) ? 0 : xfer_len; in xlp_spi_xfer_block()
280 xs->txerrors = xs->rxerrors = 0; in xlp_spi_xfer_block()
283 if (xs->tx_len) in xlp_spi_xfer_block()
293 if (xs->tx_len) in xlp_spi_xfer_block()
300 xlp_spi_reg_write(xs, xs->cs, XLP_SPI_INTR_EN, intr_mask); in xlp_spi_xfer_block()
302 time_left = wait_for_completion_timeout(&xs->done, in xlp_spi_xfer_block()
305 xlp_spi_reg_write(xs, xs->cs, XLP_SPI_INTR_EN, 0x0); in xlp_spi_xfer_block()
307 dev_err(&xs->dev, "xfer timedout!\n"); in xlp_spi_xfer_block()
310 if (xs->txerrors || xs->rxerrors) in xlp_spi_xfer_block()
311 dev_err(&xs->dev, "Over/Underflow rx %d tx %d xfer %d!\n", in xlp_spi_xfer_block()
312 xs->rxerrors, xs->txerrors, xfer_len); in xlp_spi_xfer_block()
316 return -ETIMEDOUT; in xlp_spi_xfer_block()
325 tx_buf = t->tx_buf; in xlp_spi_txrx_bufs()
326 rx_buf = t->rx_buf; in xlp_spi_txrx_bufs()
327 bytesleft = t->len; in xlp_spi_txrx_bufs()
334 bytesleft, xs->cmd_cont); in xlp_spi_txrx_bufs()
337 bytesleft -= sz; in xlp_spi_txrx_bufs()
347 struct spi_device *spi, in xlp_spi_transfer_one() argument
353 xspi->cs = spi_get_chipselect(spi, 0); in xlp_spi_transfer_one()
354 xspi->dev = spi->dev; in xlp_spi_transfer_one()
357 xspi->cmd_cont = 0; in xlp_spi_transfer_one()
359 xspi->cmd_cont = 1; in xlp_spi_transfer_one()
362 ret = -EIO; in xlp_spi_transfer_one()
375 xspi = devm_kzalloc(&pdev->dev, sizeof(*xspi), GFP_KERNEL); in xlp_spi_probe()
377 return -ENOMEM; in xlp_spi_probe()
379 xspi->base = devm_platform_ioremap_resource(pdev, 0); in xlp_spi_probe()
380 if (IS_ERR(xspi->base)) in xlp_spi_probe()
381 return PTR_ERR(xspi->base); in xlp_spi_probe()
386 err = devm_request_irq(&pdev->dev, irq, xlp_spi_interrupt, 0, in xlp_spi_probe()
387 pdev->name, xspi); in xlp_spi_probe()
389 dev_err(&pdev->dev, "unable to request irq %d\n", irq); in xlp_spi_probe()
393 clk = devm_clk_get(&pdev->dev, NULL); in xlp_spi_probe()
395 dev_err(&pdev->dev, "could not get spi clock\n"); in xlp_spi_probe()
399 xspi->spi_clk = clk_get_rate(clk); in xlp_spi_probe()
401 host = spi_alloc_host(&pdev->dev, 0); in xlp_spi_probe()
403 dev_err(&pdev->dev, "could not alloc host\n"); in xlp_spi_probe()
404 return -ENOMEM; in xlp_spi_probe()
407 host->bus_num = 0; in xlp_spi_probe()
408 host->num_chipselect = XLP_SPI_MAX_CS; in xlp_spi_probe()
409 host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; in xlp_spi_probe()
410 host->setup = xlp_spi_setup; in xlp_spi_probe()
411 host->transfer_one = xlp_spi_transfer_one; in xlp_spi_probe()
412 host->dev.of_node = pdev->dev.of_node; in xlp_spi_probe()
414 init_completion(&xspi->done); in xlp_spi_probe()
418 /* register spi controller */ in xlp_spi_probe()
419 err = devm_spi_register_controller(&pdev->dev, host); in xlp_spi_probe()
421 dev_err(&pdev->dev, "spi register host failed!\n"); in xlp_spi_probe()
441 .name = "xlp-spi",
448 MODULE_DESCRIPTION("Netlogic XLP SPI controller driver");