Lines Matching +full:cs +full:- +full:to +full:- +full:clk

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2003-2015 Broadcom Corporation
7 #include <linux/clk.h>
98 int cs; /* slave device chip select */ member
100 bool cmd_cont; /* cs active */
105 int cs, int regoff) in xlp_spi_reg_read() argument
107 return readl(priv->base + regoff + cs * SPI_CS_OFFSET); in xlp_spi_reg_read()
110 static inline void xlp_spi_reg_write(struct xlp_spi_priv *priv, int cs, in xlp_spi_reg_write() argument
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()
127 int cs; in xlp_spi_sysctl_setup() local
129 for (cs = 0; cs < XLP_SPI_MAX_CS; cs++) in xlp_spi_sysctl_setup()
131 XLP_SPI_SYS_RESET << cs); in xlp_spi_sysctl_setup()
139 int cs; in xlp_spi_setup() local
141 xspi = spi_master_get_devdata(spi->master); 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()
152 xlp_spi_reg_write(xspi, cs, XLP_SPI_FDIV, fdiv); in xlp_spi_setup()
153 xlp_spi_reg_write(xspi, cs, XLP_SPI_FIFO_THRESH, XLP_SPI_TXRXTH); in xlp_spi_setup()
154 cfg = xlp_spi_reg_read(xspi, cs, XLP_SPI_CONFIG); 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()
175 xlp_spi_reg_write(xspi, cs, XLP_SPI_CONFIG, cfg); 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()
246 /* write status back to clear interrupts */ 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 timeout = 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()
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()
372 struct clk *clk; in xlp_spi_probe() local
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()
394 if (IS_ERR(clk)) { in xlp_spi_probe()
395 dev_err(&pdev->dev, "could not get spi clock\n"); in xlp_spi_probe()
396 return PTR_ERR(clk); in xlp_spi_probe()
399 xspi->spi_clk = clk_get_rate(clk); in xlp_spi_probe()
401 master = spi_alloc_master(&pdev->dev, 0); in xlp_spi_probe()
403 dev_err(&pdev->dev, "could not alloc master\n"); in xlp_spi_probe()
404 return -ENOMEM; in xlp_spi_probe()
407 master->bus_num = 0; in xlp_spi_probe()
408 master->num_chipselect = XLP_SPI_MAX_CS; in xlp_spi_probe()
409 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; in xlp_spi_probe()
410 master->setup = xlp_spi_setup; in xlp_spi_probe()
411 master->transfer_one = xlp_spi_transfer_one; in xlp_spi_probe()
412 master->dev.of_node = pdev->dev.of_node; in xlp_spi_probe()
414 init_completion(&xspi->done); in xlp_spi_probe()
419 err = devm_spi_register_master(&pdev->dev, master); in xlp_spi_probe()
421 dev_err(&pdev->dev, "spi register master failed!\n"); in xlp_spi_probe()
441 .name = "xlp-spi",