Lines Matching full:spi
3 // Apple SoC SPI device driver
7 // Based on spi-sifive.c, Copyright 2018 SiFive, Inc.
18 #include <linux/spi/spi.h>
129 static inline void reg_write(struct apple_spi *spi, int offset, u32 value) in reg_write() argument
131 writel_relaxed(value, spi->regs + offset); in reg_write()
134 static inline u32 reg_read(struct apple_spi *spi, int offset) in reg_read() argument
136 return readl_relaxed(spi->regs + offset); in reg_read()
139 static inline void reg_mask(struct apple_spi *spi, int offset, u32 clear, u32 set) in reg_mask() argument
141 u32 val = reg_read(spi, offset); in reg_mask()
145 reg_write(spi, offset, val); in reg_mask()
148 static void apple_spi_init(struct apple_spi *spi) in apple_spi_init() argument
151 reg_write(spi, APPLE_SPI_PIN, APPLE_SPI_PIN_CS); in apple_spi_init()
152 reg_mask(spi, APPLE_SPI_SHIFTCFG, APPLE_SPI_SHIFTCFG_OVERRIDE_CS, 0); in apple_spi_init()
153 reg_mask(spi, APPLE_SPI_PINCFG, APPLE_SPI_PINCFG_CS_IDLE_VAL, APPLE_SPI_PINCFG_KEEP_CS); in apple_spi_init()
156 reg_write(spi, APPLE_SPI_CTRL, APPLE_SPI_CTRL_RX_RESET | APPLE_SPI_CTRL_TX_RESET); in apple_spi_init()
159 reg_write(spi, APPLE_SPI_CFG, in apple_spi_init()
165 reg_write(spi, APPLE_SPI_IE_FIFO, 0); in apple_spi_init()
166 reg_write(spi, APPLE_SPI_IE_XFER, 0); in apple_spi_init()
169 reg_write(spi, APPLE_SPI_DELAY_PRE, 0); in apple_spi_init()
170 reg_write(spi, APPLE_SPI_DELAY_POST, 0); in apple_spi_init()
175 struct apple_spi *spi = spi_controller_get_devdata(ctlr); in apple_spi_prepare_message() local
176 struct spi_device *device = msg->spi; in apple_spi_prepare_message()
183 reg_mask(spi, APPLE_SPI_CFG, in apple_spi_prepare_message()
191 struct apple_spi *spi = spi_controller_get_devdata(device->controller); in apple_spi_set_cs() local
193 reg_mask(spi, APPLE_SPI_PIN, APPLE_SPI_PIN_CS, is_high ? APPLE_SPI_PIN_CS : 0); in apple_spi_set_cs()
196 static bool apple_spi_prep_transfer(struct apple_spi *spi, struct spi_transfer *t) in apple_spi_prep_transfer() argument
201 cr = DIV_ROUND_UP(clk_get_rate(spi->clk), t->speed_hz); in apple_spi_prep_transfer()
202 reg_write(spi, APPLE_SPI_CLKDIV, min_t(u32, cr, APPLE_SPI_CLKDIV_MAX)); in apple_spi_prep_transfer()
205 reg_mask(spi, APPLE_SPI_SHIFTCFG, APPLE_SPI_SHIFTCFG_BITS, in apple_spi_prep_transfer()
220 struct apple_spi *spi = dev_id; in apple_spi_irq() local
221 u32 fifo = reg_read(spi, APPLE_SPI_IF_FIFO) & reg_read(spi, APPLE_SPI_IE_FIFO); in apple_spi_irq()
222 u32 xfer = reg_read(spi, APPLE_SPI_IF_XFER) & reg_read(spi, APPLE_SPI_IE_XFER); in apple_spi_irq()
226 reg_write(spi, APPLE_SPI_IE_XFER, 0); in apple_spi_irq()
227 reg_write(spi, APPLE_SPI_IE_FIFO, 0); in apple_spi_irq()
228 complete(&spi->done); in apple_spi_irq()
235 static int apple_spi_wait(struct apple_spi *spi, u32 fifo_bit, u32 xfer_bit, int poll) in apple_spi_wait() argument
244 fifo = reg_read(spi, APPLE_SPI_IF_FIFO); in apple_spi_wait()
245 xfer = reg_read(spi, APPLE_SPI_IF_XFER); in apple_spi_wait()
252 reinit_completion(&spi->done); in apple_spi_wait()
253 reg_write(spi, APPLE_SPI_IE_XFER, xfer_bit); in apple_spi_wait()
254 reg_write(spi, APPLE_SPI_IE_FIFO, fifo_bit); in apple_spi_wait()
256 if (!wait_for_completion_timeout(&spi->done, in apple_spi_wait()
260 reg_write(spi, APPLE_SPI_IE_XFER, 0); in apple_spi_wait()
261 reg_write(spi, APPLE_SPI_IE_FIFO, 0); in apple_spi_wait()
267 static void apple_spi_tx(struct apple_spi *spi, const void **tx_ptr, u32 *left, in apple_spi_tx() argument
275 inuse = FIELD_GET(APPLE_SPI_FIFOSTAT_LEVEL_TX, reg_read(spi, APPLE_SPI_FIFOSTAT)); in apple_spi_tx()
288 reg_write(spi, APPLE_SPI_TXDATA, *p++); in apple_spi_tx()
295 reg_write(spi, APPLE_SPI_TXDATA, *p++); in apple_spi_tx()
302 reg_write(spi, APPLE_SPI_TXDATA, *p++); in apple_spi_tx()
312 static void apple_spi_rx(struct apple_spi *spi, void **rx_ptr, u32 *left, in apple_spi_rx() argument
320 words = read = FIELD_GET(APPLE_SPI_FIFOSTAT_LEVEL_RX, reg_read(spi, APPLE_SPI_FIFOSTAT)); in apple_spi_rx()
333 *p++ = reg_read(spi, APPLE_SPI_RXDATA); in apple_spi_rx()
340 *p++ = reg_read(spi, APPLE_SPI_RXDATA); in apple_spi_rx()
347 *p++ = reg_read(spi, APPLE_SPI_RXDATA); in apple_spi_rx()
360 struct apple_spi *spi = spi_controller_get_devdata(ctlr); in apple_spi_transfer_one() local
361 bool poll = apple_spi_prep_transfer(spi, t); in apple_spi_transfer_one()
383 reg_write(spi, APPLE_SPI_CTRL, APPLE_SPI_CTRL_RX_RESET | APPLE_SPI_CTRL_TX_RESET); in apple_spi_transfer_one()
386 reg_write(spi, APPLE_SPI_IF_XFER, ~0); in apple_spi_transfer_one()
387 reg_write(spi, APPLE_SPI_IF_FIFO, ~0); in apple_spi_transfer_one()
396 reg_write(spi, APPLE_SPI_TXCNT, remaining_tx); in apple_spi_transfer_one()
397 reg_write(spi, APPLE_SPI_RXCNT, remaining_rx); in apple_spi_transfer_one()
400 apple_spi_tx(spi, &tx_ptr, &remaining_tx, bytes_per_word); in apple_spi_transfer_one()
403 reg_write(spi, APPLE_SPI_CTRL, APPLE_SPI_CTRL_RUN); in apple_spi_transfer_one()
406 apple_spi_tx(spi, &tx_ptr, &remaining_tx, bytes_per_word); in apple_spi_transfer_one()
417 ret = apple_spi_wait(spi, fifo_flags, xfer_flags, poll); in apple_spi_transfer_one()
425 xfer_flags &= ~reg_read(spi, APPLE_SPI_IF_XFER); in apple_spi_transfer_one()
428 apple_spi_tx(spi, &tx_ptr, &remaining_tx, bytes_per_word); in apple_spi_transfer_one()
429 apple_spi_rx(spi, &rx_ptr, &remaining_rx, bytes_per_word); in apple_spi_transfer_one()
437 apple_spi_rx(spi, &rx_ptr, &remaining_rx, bytes_per_word); in apple_spi_transfer_one()
447 fifo_flags = reg_read(spi, APPLE_SPI_IF_FIFO); in apple_spi_transfer_one()
452 reg_write(spi, APPLE_SPI_CTRL, 0); in apple_spi_transfer_one()
459 struct apple_spi *spi; in apple_spi_probe() local
467 spi = spi_controller_get_devdata(ctlr); in apple_spi_probe()
468 init_completion(&spi->done); in apple_spi_probe()
470 spi->regs = devm_platform_ioremap_resource(pdev, 0); in apple_spi_probe()
471 if (IS_ERR(spi->regs)) in apple_spi_probe()
472 return PTR_ERR(spi->regs); in apple_spi_probe()
474 spi->clk = devm_clk_get_enabled(&pdev->dev, NULL); in apple_spi_probe()
475 if (IS_ERR(spi->clk)) in apple_spi_probe()
476 return dev_err_probe(&pdev->dev, PTR_ERR(spi->clk), in apple_spi_probe()
484 dev_name(&pdev->dev), spi); in apple_spi_probe()
504 apple_spi_init(spi); in apple_spi_probe()
514 { .compatible = "apple,spi", },
522 .name = "apple-spi",
529 MODULE_DESCRIPTION("Apple SoC SPI driver");