Lines Matching +full:spi +full:- +full:slave

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Xilinx SPI controller driver (master mode only)
10 * 2002-2007 (c) MontaVista Software, Inc.
18 #include <linux/spi/spi.h>
19 #include <linux/spi/spi_bitbang.h>
20 #include <linux/spi/xilinx_spi.h>
27 /* Register definitions as per "OPB Serial Peripheral Interface (SPI) (v1.00e)
56 #define XSPI_SSR_OFFSET 0x70 /* 32-bit Slave Select Register */
68 #define XSPI_INTR_SLAVE_MODE_FAULT 0x02 /* Selected as slave while
120 if (!xspi->tx_ptr) { in xilinx_spi_tx()
121 xspi->write_fn(0, xspi->regs + XSPI_TXD_OFFSET); in xilinx_spi_tx()
125 switch (xspi->bytes_per_word) { in xilinx_spi_tx()
127 data = *(u8 *)(xspi->tx_ptr); in xilinx_spi_tx()
130 data = *(u16 *)(xspi->tx_ptr); in xilinx_spi_tx()
133 data = *(u32 *)(xspi->tx_ptr); in xilinx_spi_tx()
137 xspi->write_fn(data, xspi->regs + XSPI_TXD_OFFSET); in xilinx_spi_tx()
138 xspi->tx_ptr += xspi->bytes_per_word; in xilinx_spi_tx()
143 u32 data = xspi->read_fn(xspi->regs + XSPI_RXD_OFFSET); in xilinx_spi_rx()
145 if (!xspi->rx_ptr) in xilinx_spi_rx()
148 switch (xspi->bytes_per_word) { in xilinx_spi_rx()
150 *(u8 *)(xspi->rx_ptr) = data; in xilinx_spi_rx()
153 *(u16 *)(xspi->rx_ptr) = data; in xilinx_spi_rx()
156 *(u32 *)(xspi->rx_ptr) = data; in xilinx_spi_rx()
160 xspi->rx_ptr += xspi->bytes_per_word; in xilinx_spi_rx()
165 void __iomem *regs_base = xspi->regs; in xspi_init_hw()
167 /* Reset the SPI device */ in xspi_init_hw()
168 xspi->write_fn(XIPIF_V123B_RESET_MASK, in xspi_init_hw()
173 xspi->write_fn(XSPI_INTR_TX_EMPTY, in xspi_init_hw()
176 xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); in xspi_init_hw()
177 /* Deselect the slave on the SPI bus */ in xspi_init_hw()
178 xspi->write_fn(0xffff, regs_base + XSPI_SSR_OFFSET); in xspi_init_hw()
179 /* Disable the transmitter, enable Manual Slave Select Assertion, in xspi_init_hw()
180 * put SPI controller into master mode, and enable it */ in xspi_init_hw()
181 xspi->write_fn(XSPI_CR_MANUAL_SSELECT | XSPI_CR_MASTER_MODE | in xspi_init_hw()
186 static void xilinx_spi_chipselect(struct spi_device *spi, int is_on) in xilinx_spi_chipselect() argument
188 struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); in xilinx_spi_chipselect()
193 /* Deselect the slave on the SPI bus */ in xilinx_spi_chipselect()
194 xspi->write_fn(xspi->cs_inactive, xspi->regs + XSPI_SSR_OFFSET); in xilinx_spi_chipselect()
198 /* Set the SPI clock phase and polarity */ in xilinx_spi_chipselect()
199 cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) & ~XSPI_CR_MODE_MASK; in xilinx_spi_chipselect()
200 if (spi->mode & SPI_CPHA) in xilinx_spi_chipselect()
202 if (spi->mode & SPI_CPOL) in xilinx_spi_chipselect()
204 if (spi->mode & SPI_LSB_FIRST) in xilinx_spi_chipselect()
206 if (spi->mode & SPI_LOOP) in xilinx_spi_chipselect()
208 xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); in xilinx_spi_chipselect()
210 /* We do not check spi->max_speed_hz here as the SPI clock in xilinx_spi_chipselect()
215 cs = xspi->cs_inactive; in xilinx_spi_chipselect()
216 cs ^= BIT(spi->chip_select); in xilinx_spi_chipselect()
219 xspi->write_fn(cs, xspi->regs + XSPI_SSR_OFFSET); in xilinx_spi_chipselect()
225 static int xilinx_spi_setup_transfer(struct spi_device *spi, in xilinx_spi_setup_transfer() argument
228 struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); in xilinx_spi_setup_transfer()
230 if (spi->mode & SPI_CS_HIGH) in xilinx_spi_setup_transfer()
231 xspi->cs_inactive &= ~BIT(spi->chip_select); in xilinx_spi_setup_transfer()
233 xspi->cs_inactive |= BIT(spi->chip_select); in xilinx_spi_setup_transfer()
238 static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) in xilinx_spi_txrx_bufs() argument
240 struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); in xilinx_spi_txrx_bufs()
247 xspi->tx_ptr = t->tx_buf; in xilinx_spi_txrx_bufs()
248 xspi->rx_ptr = t->rx_buf; in xilinx_spi_txrx_bufs()
249 remaining_words = t->len / xspi->bytes_per_word; in xilinx_spi_txrx_bufs()
251 if (xspi->irq >= 0 && remaining_words > xspi->buffer_size) { in xilinx_spi_txrx_bufs()
255 cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); in xilinx_spi_txrx_bufs()
256 xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, in xilinx_spi_txrx_bufs()
257 xspi->regs + XSPI_CR_OFFSET); in xilinx_spi_txrx_bufs()
259 isr = xspi->read_fn(xspi->regs + XIPIF_V123B_IISR_OFFSET); in xilinx_spi_txrx_bufs()
261 xspi->write_fn(isr, in xilinx_spi_txrx_bufs()
262 xspi->regs + XIPIF_V123B_IISR_OFFSET); in xilinx_spi_txrx_bufs()
264 xspi->write_fn(XIPIF_V123B_GINTR_ENABLE, in xilinx_spi_txrx_bufs()
265 xspi->regs + XIPIF_V123B_DGIER_OFFSET); in xilinx_spi_txrx_bufs()
266 reinit_completion(&xspi->done); in xilinx_spi_txrx_bufs()
274 n_words = min(remaining_words, xspi->buffer_size); in xilinx_spi_txrx_bufs()
277 while (tx_words--) in xilinx_spi_txrx_bufs()
285 xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); in xilinx_spi_txrx_bufs()
286 wait_for_completion(&xspi->done); in xilinx_spi_txrx_bufs()
293 xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, in xilinx_spi_txrx_bufs()
294 xspi->regs + XSPI_CR_OFFSET); in xilinx_spi_txrx_bufs()
297 sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); in xilinx_spi_txrx_bufs()
303 if (rx_words == n_words && !(stalled--) && in xilinx_spi_txrx_bufs()
306 dev_err(&spi->dev, in xilinx_spi_txrx_bufs()
309 return -EIO; in xilinx_spi_txrx_bufs()
314 rx_words--; in xilinx_spi_txrx_bufs()
318 sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); in xilinx_spi_txrx_bufs()
321 rx_words--; in xilinx_spi_txrx_bufs()
325 remaining_words -= n_words; in xilinx_spi_txrx_bufs()
329 xspi->write_fn(0, xspi->regs + XIPIF_V123B_DGIER_OFFSET); in xilinx_spi_txrx_bufs()
330 xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); in xilinx_spi_txrx_bufs()
333 return t->len; in xilinx_spi_txrx_bufs()
339 * Receive FIFO Overrun, Transmit FIFO Underrun, Mode Fault, and Slave Mode
348 ipif_isr = xspi->read_fn(xspi->regs + XIPIF_V123B_IISR_OFFSET); in xilinx_spi_irq()
349 xspi->write_fn(ipif_isr, xspi->regs + XIPIF_V123B_IISR_OFFSET); in xilinx_spi_irq()
352 complete(&xspi->done); in xilinx_spi_irq()
368 xspi->write_fn(XIPIF_V123B_RESET_MASK, in xilinx_spi_find_buffer_size()
369 xspi->regs + XIPIF_V123B_RESETR_OFFSET); in xilinx_spi_find_buffer_size()
373 xspi->write_fn(0, xspi->regs + XSPI_TXD_OFFSET); in xilinx_spi_find_buffer_size()
374 sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); in xilinx_spi_find_buffer_size()
382 { .compatible = "xlnx,axi-quad-spi-1.00.a", },
383 { .compatible = "xlnx,xps-spi-2.00.a", },
384 { .compatible = "xlnx,xps-spi-2.00.b", },
399 pdata = dev_get_platdata(&pdev->dev); in xilinx_spi_probe()
401 num_cs = pdata->num_chipselect; in xilinx_spi_probe()
402 bits_per_word = pdata->bits_per_word; in xilinx_spi_probe()
404 of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits", in xilinx_spi_probe()
406 ret = of_property_read_u32(pdev->dev.of_node, in xilinx_spi_probe()
407 "xlnx,num-transfer-bits", in xilinx_spi_probe()
414 dev_err(&pdev->dev, in xilinx_spi_probe()
415 "Missing slave select configuration data\n"); in xilinx_spi_probe()
416 return -EINVAL; in xilinx_spi_probe()
420 dev_err(&pdev->dev, "Invalid number of spi slaves\n"); in xilinx_spi_probe()
421 return -EINVAL; in xilinx_spi_probe()
424 master = spi_alloc_master(&pdev->dev, sizeof(struct xilinx_spi)); in xilinx_spi_probe()
426 return -ENODEV; in xilinx_spi_probe()
428 /* the spi->mode bits understood by this driver: */ in xilinx_spi_probe()
429 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | in xilinx_spi_probe()
433 xspi->cs_inactive = 0xffffffff; in xilinx_spi_probe()
434 xspi->bitbang.master = master; in xilinx_spi_probe()
435 xspi->bitbang.chipselect = xilinx_spi_chipselect; in xilinx_spi_probe()
436 xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer; in xilinx_spi_probe()
437 xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; in xilinx_spi_probe()
438 init_completion(&xspi->done); in xilinx_spi_probe()
441 xspi->regs = devm_ioremap_resource(&pdev->dev, res); in xilinx_spi_probe()
442 if (IS_ERR(xspi->regs)) { in xilinx_spi_probe()
443 ret = PTR_ERR(xspi->regs); in xilinx_spi_probe()
447 master->bus_num = pdev->id; in xilinx_spi_probe()
448 master->num_chipselect = num_cs; in xilinx_spi_probe()
449 master->dev.of_node = pdev->dev.of_node; in xilinx_spi_probe()
458 xspi->read_fn = xspi_read32; in xilinx_spi_probe()
459 xspi->write_fn = xspi_write32; in xilinx_spi_probe()
461 xspi->write_fn(XSPI_CR_LOOP, xspi->regs + XSPI_CR_OFFSET); in xilinx_spi_probe()
462 tmp = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); in xilinx_spi_probe()
465 xspi->read_fn = xspi_read32_be; in xilinx_spi_probe()
466 xspi->write_fn = xspi_write32_be; in xilinx_spi_probe()
469 master->bits_per_word_mask = SPI_BPW_MASK(bits_per_word); in xilinx_spi_probe()
470 xspi->bytes_per_word = bits_per_word / 8; in xilinx_spi_probe()
471 xspi->buffer_size = xilinx_spi_find_buffer_size(xspi); in xilinx_spi_probe()
473 xspi->irq = platform_get_irq(pdev, 0); in xilinx_spi_probe()
474 if (xspi->irq < 0 && xspi->irq != -ENXIO) { in xilinx_spi_probe()
475 ret = xspi->irq; in xilinx_spi_probe()
477 } else if (xspi->irq >= 0) { in xilinx_spi_probe()
478 /* Register for SPI Interrupt */ in xilinx_spi_probe()
479 ret = devm_request_irq(&pdev->dev, xspi->irq, xilinx_spi_irq, 0, in xilinx_spi_probe()
480 dev_name(&pdev->dev), xspi); in xilinx_spi_probe()
485 /* SPI controller initializations */ in xilinx_spi_probe()
488 ret = spi_bitbang_start(&xspi->bitbang); in xilinx_spi_probe()
490 dev_err(&pdev->dev, "spi_bitbang_start FAILED\n"); in xilinx_spi_probe()
494 dev_info(&pdev->dev, "at %pR, irq=%d\n", res, xspi->irq); in xilinx_spi_probe()
497 for (i = 0; i < pdata->num_devices; i++) in xilinx_spi_probe()
498 spi_new_device(master, pdata->devices + i); in xilinx_spi_probe()
514 void __iomem *regs_base = xspi->regs; in xilinx_spi_remove()
516 spi_bitbang_stop(&xspi->bitbang); in xilinx_spi_remove()
519 xspi->write_fn(0, regs_base + XIPIF_V123B_IIER_OFFSET); in xilinx_spi_remove()
521 xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); in xilinx_spi_remove()
523 spi_master_put(xspi->bitbang.master); in xilinx_spi_remove()
542 MODULE_DESCRIPTION("Xilinx SPI driver");