Lines Matching +full:sp7021 +full:- +full:spi
1 // SPDX-License-Identifier: GPL-2.0-only
3 // Author: Li-hao Kuo <lhjeff911@gmail.com>
8 #include <linux/dma-mapping.h>
15 #include <linux/spi/spi.h>
104 data_status = readl(pspim->s_base + SP7021_DATA_RDY_REG); in sp7021_spi_slave_irq()
106 writel(data_status , pspim->s_base + SP7021_DATA_RDY_REG); in sp7021_spi_slave_irq()
107 complete(&pspim->slave_isr); in sp7021_spi_slave_irq()
115 complete(&pspim->slave_isr); in sp7021_spi_slave_abort()
116 complete(&pspim->isr_done); in sp7021_spi_slave_abort()
120 static int sp7021_spi_slave_tx(struct spi_device *spi, struct spi_transfer *xfer) in sp7021_spi_slave_tx() argument
122 struct sp7021_spi_ctlr *pspim = spi_controller_get_devdata(spi->controller); in sp7021_spi_slave_tx()
125 reinit_completion(&pspim->slave_isr); in sp7021_spi_slave_tx()
127 writel(value, pspim->s_base + SP7021_SLAVE_DMA_CTRL_REG); in sp7021_spi_slave_tx()
128 writel(xfer->len, pspim->s_base + SP7021_SLAVE_DMA_LENGTH_REG); in sp7021_spi_slave_tx()
129 writel(xfer->tx_dma, pspim->s_base + SP7021_SLAVE_DMA_ADDR_REG); in sp7021_spi_slave_tx()
130 value = readl(pspim->s_base + SP7021_DATA_RDY_REG); in sp7021_spi_slave_tx()
132 writel(value, pspim->s_base + SP7021_DATA_RDY_REG); in sp7021_spi_slave_tx()
133 if (wait_for_completion_interruptible(&pspim->isr_done)) { in sp7021_spi_slave_tx()
134 dev_err(&spi->dev, "%s() wait_for_completion err\n", __func__); in sp7021_spi_slave_tx()
135 return -EINTR; in sp7021_spi_slave_tx()
140 static int sp7021_spi_slave_rx(struct spi_device *spi, struct spi_transfer *xfer) in sp7021_spi_slave_rx() argument
142 struct sp7021_spi_ctlr *pspim = spi_controller_get_devdata(spi->controller); in sp7021_spi_slave_rx()
145 reinit_completion(&pspim->isr_done); in sp7021_spi_slave_rx()
147 writel(value, pspim->s_base + SP7021_SLAVE_DMA_CTRL_REG); in sp7021_spi_slave_rx()
148 writel(xfer->len, pspim->s_base + SP7021_SLAVE_DMA_LENGTH_REG); in sp7021_spi_slave_rx()
149 writel(xfer->rx_dma, pspim->s_base + SP7021_SLAVE_DMA_ADDR_REG); in sp7021_spi_slave_rx()
150 if (wait_for_completion_interruptible(&pspim->isr_done)) { in sp7021_spi_slave_rx()
151 dev_err(&spi->dev, "%s() wait_for_completion err\n", __func__); in sp7021_spi_slave_rx()
152 return -EINTR; in sp7021_spi_slave_rx()
154 writel(SP7021_SLAVE_SW_RST, pspim->s_base + SP7021_SLAVE_DMA_CTRL_REG); in sp7021_spi_slave_rx()
163 pspim->rx_buf[pspim->rx_cur_len] = in sp7021_spi_master_rb()
164 readl(pspim->m_base + SP7021_FIFO_REG); in sp7021_spi_master_rb()
165 pspim->rx_cur_len++; in sp7021_spi_master_rb()
174 writel(pspim->tx_buf[pspim->tx_cur_len], in sp7021_spi_master_wb()
175 pspim->m_base + SP7021_FIFO_REG); in sp7021_spi_master_wb()
176 pspim->tx_cur_len++; in sp7021_spi_master_wb()
189 fd_status = readl(pspim->m_base + SP7021_SPI_STATUS_REG); in sp7021_spi_master_irq()
202 rx_cnt = pspim->data_unit; in sp7021_spi_master_irq()
204 tx_cnt = min(tx_len - pspim->tx_cur_len, pspim->data_unit - tx_cnt); in sp7021_spi_master_irq()
205 dev_dbg(pspim->dev, "fd_st=0x%x rx_c:%d tx_c:%d tx_l:%d", in sp7021_spi_master_irq()
213 fd_status = readl(pspim->m_base + SP7021_SPI_STATUS_REG); in sp7021_spi_master_irq()
217 if (fd_status & SP7021_FINISH_FLAG || tx_len == pspim->tx_cur_len) { in sp7021_spi_master_irq()
218 while (total_len != pspim->rx_cur_len) { in sp7021_spi_master_irq()
219 fd_status = readl(pspim->m_base + SP7021_SPI_STATUS_REG); in sp7021_spi_master_irq()
222 rx_cnt = pspim->data_unit; in sp7021_spi_master_irq()
229 value = readl(pspim->m_base + SP7021_INT_BUSY_REG); in sp7021_spi_master_irq()
231 writel(value, pspim->m_base + SP7021_INT_BUSY_REG); in sp7021_spi_master_irq()
232 writel(SP7021_FINISH_FLAG, pspim->m_base + SP7021_SPI_STATUS_REG); in sp7021_spi_master_irq()
237 complete(&pspim->isr_done); in sp7021_spi_master_irq()
241 static void sp7021_prep_transfer(struct spi_controller *ctlr, struct spi_device *spi) in sp7021_prep_transfer() argument
245 pspim->tx_cur_len = 0; in sp7021_prep_transfer()
246 pspim->rx_cur_len = 0; in sp7021_prep_transfer()
247 pspim->data_unit = SP7021_FIFO_DATA_LEN; in sp7021_prep_transfer()
255 struct spi_device *s = msg->spi; in sp7021_spi_controller_prepare_message()
258 valus = readl(pspim->m_base + SP7021_SPI_STATUS_REG); in sp7021_spi_controller_prepare_message()
260 writel(valus, pspim->m_base + SP7021_SPI_STATUS_REG); in sp7021_spi_controller_prepare_message()
262 if (s->mode & SPI_CPOL) in sp7021_spi_controller_prepare_message()
265 if (s->mode & SPI_LSB_FIRST) in sp7021_spi_controller_prepare_message()
268 if (s->mode & SPI_CS_HIGH) in sp7021_spi_controller_prepare_message()
271 if (s->mode & SPI_CPHA) in sp7021_spi_controller_prepare_message()
277 pspim->xfer_conf = rs; in sp7021_spi_controller_prepare_message()
278 if (pspim->xfer_conf & SP7021_CPOL_FD) in sp7021_spi_controller_prepare_message()
279 writel(pspim->xfer_conf, pspim->m_base + SP7021_SPI_CONFIG_REG); in sp7021_spi_controller_prepare_message()
289 clk_rate = clk_get_rate(pspim->spi_clk); in sp7021_spi_setup_clk()
290 div = max(2U, clk_rate / xfer->speed_hz); in sp7021_spi_setup_clk()
292 clk_sel = (div / 2) - 1; in sp7021_spi_setup_clk()
293 pspim->xfer_conf &= ~SP7021_CLK_MASK; in sp7021_spi_setup_clk()
294 pspim->xfer_conf |= FIELD_PREP(SP7021_CLK_MASK, clk_sel); in sp7021_spi_setup_clk()
295 writel(pspim->xfer_conf, pspim->m_base + SP7021_SPI_CONFIG_REG); in sp7021_spi_setup_clk()
298 static int sp7021_spi_master_transfer_one(struct spi_controller *ctlr, struct spi_device *spi, in sp7021_spi_master_transfer_one() argument
307 xfer_cnt = xfer->len / SP7021_SPI_DATA_SIZE; in sp7021_spi_master_transfer_one()
308 last_len = xfer->len % SP7021_SPI_DATA_SIZE; in sp7021_spi_master_transfer_one()
311 mutex_lock(&pspim->buf_lock); in sp7021_spi_master_transfer_one()
312 sp7021_prep_transfer(ctlr, spi); in sp7021_spi_master_transfer_one()
314 reinit_completion(&pspim->isr_done); in sp7021_spi_master_transfer_one()
321 pspim->tx_buf = xfer->tx_buf + i * SP7021_SPI_DATA_SIZE; in sp7021_spi_master_transfer_one()
322 pspim->rx_buf = xfer->rx_buf + i * SP7021_SPI_DATA_SIZE; in sp7021_spi_master_transfer_one()
324 if (pspim->tx_cur_len < xfer_len) { in sp7021_spi_master_transfer_one()
325 len_temp = min(pspim->data_unit, xfer_len); in sp7021_spi_master_transfer_one()
328 reg_temp = readl(pspim->m_base + SP7021_SPI_CONFIG_REG); in sp7021_spi_master_transfer_one()
334 writel(reg_temp, pspim->m_base + SP7021_SPI_CONFIG_REG); in sp7021_spi_master_transfer_one()
339 writel(reg_temp, pspim->m_base + SP7021_SPI_STATUS_REG); in sp7021_spi_master_transfer_one()
341 if (!wait_for_completion_interruptible_timeout(&pspim->isr_done, timeout)) { in sp7021_spi_master_transfer_one()
342 dev_err(&spi->dev, "wait_for_completion err\n"); in sp7021_spi_master_transfer_one()
343 mutex_unlock(&pspim->buf_lock); in sp7021_spi_master_transfer_one()
344 return -ETIMEDOUT; in sp7021_spi_master_transfer_one()
347 reg_temp = readl(pspim->m_base + SP7021_SPI_STATUS_REG); in sp7021_spi_master_transfer_one()
349 writel(SP7021_FINISH_FLAG, pspim->m_base + SP7021_SPI_STATUS_REG); in sp7021_spi_master_transfer_one()
350 writel(readl(pspim->m_base + SP7021_SPI_CONFIG_REG) & in sp7021_spi_master_transfer_one()
351 SP7021_CLEAN_FLUG_MASK, pspim->m_base + SP7021_SPI_CONFIG_REG); in sp7021_spi_master_transfer_one()
354 if (pspim->xfer_conf & SP7021_CPOL_FD) in sp7021_spi_master_transfer_one()
355 writel(pspim->xfer_conf, pspim->m_base + SP7021_SPI_CONFIG_REG); in sp7021_spi_master_transfer_one()
357 mutex_unlock(&pspim->buf_lock); in sp7021_spi_master_transfer_one()
362 static int sp7021_spi_slave_transfer_one(struct spi_controller *ctlr, struct spi_device *spi, in sp7021_spi_slave_transfer_one() argument
366 struct device *dev = pspim->dev; in sp7021_spi_slave_transfer_one()
369 if (xfer->tx_buf && !xfer->rx_buf) { in sp7021_spi_slave_transfer_one()
370 xfer->tx_dma = dma_map_single(dev, (void *)xfer->tx_buf, in sp7021_spi_slave_transfer_one()
371 xfer->len, DMA_TO_DEVICE); in sp7021_spi_slave_transfer_one()
372 if (dma_mapping_error(dev, xfer->tx_dma)) in sp7021_spi_slave_transfer_one()
373 return -ENOMEM; in sp7021_spi_slave_transfer_one()
374 ret = sp7021_spi_slave_tx(spi, xfer); in sp7021_spi_slave_transfer_one()
375 dma_unmap_single(dev, xfer->tx_dma, xfer->len, DMA_TO_DEVICE); in sp7021_spi_slave_transfer_one()
376 } else if (xfer->rx_buf && !xfer->tx_buf) { in sp7021_spi_slave_transfer_one()
377 xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, xfer->len, in sp7021_spi_slave_transfer_one()
379 if (dma_mapping_error(dev, xfer->rx_dma)) in sp7021_spi_slave_transfer_one()
380 return -ENOMEM; in sp7021_spi_slave_transfer_one()
381 ret = sp7021_spi_slave_rx(spi, xfer); in sp7021_spi_slave_transfer_one()
382 dma_unmap_single(dev, xfer->rx_dma, xfer->len, DMA_FROM_DEVICE); in sp7021_spi_slave_transfer_one()
384 dev_dbg(&ctlr->dev, "%s() wrong command\n", __func__); in sp7021_spi_slave_transfer_one()
385 return -EINVAL; in sp7021_spi_slave_transfer_one()
404 struct device *dev = &pdev->dev; in sp7021_spi_controller_probe()
409 pdev->id = of_alias_get_id(pdev->dev.of_node, "sp_spi"); in sp7021_spi_controller_probe()
411 if (device_property_read_bool(dev, "spi-slave")) in sp7021_spi_controller_probe()
421 return -ENOMEM; in sp7021_spi_controller_probe()
422 device_set_node(&ctlr->dev, dev_fwnode(dev)); in sp7021_spi_controller_probe()
423 ctlr->bus_num = pdev->id; in sp7021_spi_controller_probe()
424 ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; in sp7021_spi_controller_probe()
425 ctlr->auto_runtime_pm = true; in sp7021_spi_controller_probe()
426 ctlr->prepare_message = sp7021_spi_controller_prepare_message; in sp7021_spi_controller_probe()
428 ctlr->transfer_one = sp7021_spi_slave_transfer_one; in sp7021_spi_controller_probe()
429 ctlr->slave_abort = sp7021_spi_slave_abort; in sp7021_spi_controller_probe()
430 ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX; in sp7021_spi_controller_probe()
432 ctlr->bits_per_word_mask = SPI_BPW_MASK(8); in sp7021_spi_controller_probe()
433 ctlr->min_speed_hz = 40000; in sp7021_spi_controller_probe()
434 ctlr->max_speed_hz = 25000000; in sp7021_spi_controller_probe()
435 ctlr->use_gpio_descriptors = true; in sp7021_spi_controller_probe()
436 ctlr->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX; in sp7021_spi_controller_probe()
437 ctlr->transfer_one = sp7021_spi_master_transfer_one; in sp7021_spi_controller_probe()
441 pspim->mode = mode; in sp7021_spi_controller_probe()
442 pspim->ctlr = ctlr; in sp7021_spi_controller_probe()
443 pspim->dev = dev; in sp7021_spi_controller_probe()
444 mutex_init(&pspim->buf_lock); in sp7021_spi_controller_probe()
445 init_completion(&pspim->isr_done); in sp7021_spi_controller_probe()
446 init_completion(&pspim->slave_isr); in sp7021_spi_controller_probe()
448 pspim->m_base = devm_platform_ioremap_resource_byname(pdev, "master"); in sp7021_spi_controller_probe()
449 if (IS_ERR(pspim->m_base)) in sp7021_spi_controller_probe()
450 return dev_err_probe(dev, PTR_ERR(pspim->m_base), "m_base get fail\n"); in sp7021_spi_controller_probe()
452 pspim->s_base = devm_platform_ioremap_resource_byname(pdev, "slave"); in sp7021_spi_controller_probe()
453 if (IS_ERR(pspim->s_base)) in sp7021_spi_controller_probe()
454 return dev_err_probe(dev, PTR_ERR(pspim->s_base), "s_base get fail\n"); in sp7021_spi_controller_probe()
456 pspim->m_irq = platform_get_irq_byname(pdev, "master_risc"); in sp7021_spi_controller_probe()
457 if (pspim->m_irq < 0) in sp7021_spi_controller_probe()
458 return pspim->m_irq; in sp7021_spi_controller_probe()
460 pspim->s_irq = platform_get_irq_byname(pdev, "slave_risc"); in sp7021_spi_controller_probe()
461 if (pspim->s_irq < 0) in sp7021_spi_controller_probe()
462 return pspim->s_irq; in sp7021_spi_controller_probe()
464 pspim->spi_clk = devm_clk_get(dev, NULL); in sp7021_spi_controller_probe()
465 if (IS_ERR(pspim->spi_clk)) in sp7021_spi_controller_probe()
466 return dev_err_probe(dev, PTR_ERR(pspim->spi_clk), "clk get fail\n"); in sp7021_spi_controller_probe()
468 pspim->rstc = devm_reset_control_get_exclusive(dev, NULL); in sp7021_spi_controller_probe()
469 if (IS_ERR(pspim->rstc)) in sp7021_spi_controller_probe()
470 return dev_err_probe(dev, PTR_ERR(pspim->rstc), "rst get fail\n"); in sp7021_spi_controller_probe()
472 ret = clk_prepare_enable(pspim->spi_clk); in sp7021_spi_controller_probe()
476 ret = devm_add_action_or_reset(dev, sp7021_spi_disable_unprepare, pspim->spi_clk); in sp7021_spi_controller_probe()
480 ret = reset_control_deassert(pspim->rstc); in sp7021_spi_controller_probe()
484 ret = devm_add_action_or_reset(dev, sp7021_spi_reset_control_assert, pspim->rstc); in sp7021_spi_controller_probe()
488 ret = devm_request_irq(dev, pspim->m_irq, sp7021_spi_master_irq, in sp7021_spi_controller_probe()
489 IRQF_TRIGGER_RISING, pdev->name, pspim); in sp7021_spi_controller_probe()
493 ret = devm_request_irq(dev, pspim->s_irq, sp7021_spi_slave_irq, in sp7021_spi_controller_probe()
494 IRQF_TRIGGER_RISING, pdev->name, pspim); in sp7021_spi_controller_probe()
509 struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev); in sp7021_spi_controller_remove()
512 pm_runtime_disable(&pdev->dev); in sp7021_spi_controller_remove()
513 pm_runtime_set_suspended(&pdev->dev); in sp7021_spi_controller_remove()
521 return reset_control_assert(pspim->rstc); in sp7021_spi_controller_suspend()
529 reset_control_deassert(pspim->rstc); in sp7021_spi_controller_resume()
530 return clk_prepare_enable(pspim->spi_clk); in sp7021_spi_controller_resume()
539 return reset_control_assert(pspim->rstc); in sp7021_spi_runtime_suspend()
547 return reset_control_deassert(pspim->rstc); in sp7021_spi_runtime_resume()
559 { .compatible = "sunplus,sp7021-spi" },
568 .name = "sunplus,sp7021-spi-controller",
575 MODULE_AUTHOR("Li-hao Kuo <lhjeff911@gmail.com>");
576 MODULE_DESCRIPTION("Sunplus SPI controller driver");