Lines Matching +full:spi +full:- +full:mux

2  * Driver for Amlogic Meson SPI communication controller (SPICC)
7 * SPDX-License-Identifier: GPL-2.0+
12 #include <linux/clk-provider.h>
19 #include <linux/spi/spi.h>
24 #include <linux/dma-mapping.h>
31 * DMA achieves a transfer with one or more SPI bursts, each SPI burst is made
40 * - 64 bits per word
41 * - The transfer length in word must be multiples of the dma_burst_len, and
43 * into several SPI bursts by this driver
77 #define SPICC_TH_EN BIT(1) /* TX FIFO Half-Full Interrupt */
80 #define SPICC_RH_EN BIT(4) /* RX FIFO Half-Full Interrupt */
97 #define SPICC_TH BIT(1) /* TX FIFO Half-Full Interrupt */
100 #define SPICC_RH BIT(4) /* RX FIFO Half-Full Interrupt */
112 #define SPICC_LBC_RO BIT(13) /* Loop Back Control Read-Only */
113 #define SPICC_LBC_W1 BIT(14) /* Loop Back Control Write-Only */
114 #define SPICC_SWAP_RO BIT(14) /* RX FIFO Data Swap Read-Only */
115 #define SPICC_SWAP_W1 BIT(15) /* RX FIFO Data Swap Write-Only */
116 #define SPICC_DLYCTL_RO_MASK GENMASK(20, 15) /* Delay Control Read-Only */
132 #define SPICC_FIFORST_RO_MASK GENMASK(22, 21) /* FIFO Softreset Read-Only */
133 #define SPICC_FIFORST_W1_MASK GENMASK(23, 22) /* FIFO Softreset Write-Only */
210 if (!spicc->data->has_oen) { in meson_spicc_oen_enable()
212 spicc->pins_idle_high = pinctrl_lookup_state(spicc->pinctrl, in meson_spicc_oen_enable()
213 "idle-high"); in meson_spicc_oen_enable()
214 if (IS_ERR(spicc->pins_idle_high)) { in meson_spicc_oen_enable()
215 dev_warn(&spicc->pdev->dev, "can't get idle-high pinctrl\n"); in meson_spicc_oen_enable()
216 spicc->pins_idle_high = NULL; in meson_spicc_oen_enable()
218 spicc->pins_idle_low = pinctrl_lookup_state(spicc->pinctrl, in meson_spicc_oen_enable()
219 "idle-low"); in meson_spicc_oen_enable()
220 if (IS_ERR(spicc->pins_idle_low)) { in meson_spicc_oen_enable()
221 dev_warn(&spicc->pdev->dev, "can't get idle-low pinctrl\n"); in meson_spicc_oen_enable()
222 spicc->pins_idle_low = NULL; in meson_spicc_oen_enable()
227 conf = readl_relaxed(spicc->base + SPICC_ENH_CTL0) | in meson_spicc_oen_enable()
230 writel_relaxed(conf, spicc->base + SPICC_ENH_CTL0); in meson_spicc_oen_enable()
236 struct device *dev = spicc->host->dev.parent; in meson_spicc_dma_map()
238 if (!(t->tx_buf && t->rx_buf)) in meson_spicc_dma_map()
239 return -EINVAL; in meson_spicc_dma_map()
241 t->tx_dma = dma_map_single(dev, (void *)t->tx_buf, t->len, DMA_TO_DEVICE); in meson_spicc_dma_map()
242 if (dma_mapping_error(dev, t->tx_dma)) in meson_spicc_dma_map()
243 return -ENOMEM; in meson_spicc_dma_map()
245 t->rx_dma = dma_map_single(dev, t->rx_buf, t->len, DMA_FROM_DEVICE); in meson_spicc_dma_map()
246 if (dma_mapping_error(dev, t->rx_dma)) in meson_spicc_dma_map()
247 return -ENOMEM; in meson_spicc_dma_map()
249 spicc->tx_dma = t->tx_dma; in meson_spicc_dma_map()
250 spicc->rx_dma = t->rx_dma; in meson_spicc_dma_map()
258 struct device *dev = spicc->host->dev.parent; in meson_spicc_dma_unmap()
260 if (t->tx_dma) in meson_spicc_dma_unmap()
261 dma_unmap_single(dev, t->tx_dma, t->len, DMA_TO_DEVICE); in meson_spicc_dma_unmap()
262 if (t->rx_dma) in meson_spicc_dma_unmap()
263 dma_unmap_single(dev, t->rx_dma, t->len, DMA_FROM_DEVICE); in meson_spicc_dma_unmap()
267 * According to the remain words length, calculate a suitable spi burst length
268 * and a dma burst length for current spi burst
275 if (len <= spicc->data->fifo_size) { in meson_spicc_calc_dma_len()
283 return SPI_BURST_LEN_MAX - DMA_BURST_LEN_DEFAULT; in meson_spicc_calc_dma_len()
288 for (i = DMA_BURST_LEN_DEFAULT; i > 1; i--) in meson_spicc_calc_dma_len()
295 len -= i; in meson_spicc_calc_dma_len()
298 len -= DMA_BURST_LEN_DEFAULT; in meson_spicc_calc_dma_len()
314 writel_relaxed(spicc->tx_dma, spicc->base + SPICC_DRADDR); in meson_spicc_setup_dma()
315 writel_relaxed(spicc->rx_dma, spicc->base + SPICC_DWADDR); in meson_spicc_setup_dma()
322 spicc->base + SPICC_CONREG); in meson_spicc_setup_dma()
324 len = meson_spicc_calc_dma_len(spicc, spicc->xfer_remain, in meson_spicc_setup_dma()
326 spicc->xfer_remain -= len; in meson_spicc_setup_dma()
328 dma_burst_len--; in meson_spicc_setup_dma()
330 if (spicc->tx_dma) { in meson_spicc_setup_dma()
331 spicc->tx_dma += len; in meson_spicc_setup_dma()
333 txfifo_thres = spicc->data->fifo_size - dma_burst_len; in meson_spicc_setup_dma()
338 if (spicc->rx_dma) { in meson_spicc_setup_dma()
339 spicc->rx_dma += len; in meson_spicc_setup_dma()
346 writel_relaxed(count_en, spicc->base + SPICC_LD_CNTL0); in meson_spicc_setup_dma()
347 writel_relaxed(ld_ctr1, spicc->base + SPICC_LD_CNTL1); in meson_spicc_setup_dma()
354 spicc->base + SPICC_DMAREG); in meson_spicc_setup_dma()
359 if (readl_relaxed(spicc->base + SPICC_DMAREG) & SPICC_DMA_ENABLE) in meson_spicc_dma_irq()
362 if (spicc->xfer_remain) { in meson_spicc_dma_irq()
365 writel_bits_relaxed(SPICC_SMC, 0, spicc->base + SPICC_CONREG); in meson_spicc_dma_irq()
366 writel_relaxed(0, spicc->base + SPICC_INTREG); in meson_spicc_dma_irq()
367 writel_relaxed(0, spicc->base + SPICC_DMAREG); in meson_spicc_dma_irq()
368 meson_spicc_dma_unmap(spicc, spicc->xfer); in meson_spicc_dma_irq()
369 complete(&spicc->done); in meson_spicc_dma_irq()
378 readl_relaxed(spicc->base + SPICC_STATREG)); in meson_spicc_txfull()
384 readl_relaxed(spicc->base + SPICC_STATREG)); in meson_spicc_rxready()
389 unsigned int bytes = spicc->bytes_per_word; in meson_spicc_pull_data()
394 while (bytes--) { in meson_spicc_pull_data()
395 byte = *spicc->tx_buf++; in meson_spicc_pull_data()
400 spicc->tx_remain--; in meson_spicc_pull_data()
407 unsigned int bytes = spicc->bytes_per_word; in meson_spicc_push_data()
411 while (bytes--) { in meson_spicc_push_data()
413 *spicc->rx_buf++ = byte; in meson_spicc_push_data()
417 spicc->rx_remain--; in meson_spicc_push_data()
423 while (spicc->rx_remain && in meson_spicc_rx()
426 readl_relaxed(spicc->base + SPICC_RXDATA)); in meson_spicc_rx()
432 while (spicc->tx_remain && in meson_spicc_tx()
435 spicc->base + SPICC_TXDATA); in meson_spicc_tx()
442 spicc->xfer_remain / in meson_spicc_setup_burst()
443 spicc->bytes_per_word, in meson_spicc_setup_burst()
444 spicc->data->fifo_size); in meson_spicc_setup_burst()
446 spicc->tx_remain = burst_len; in meson_spicc_setup_burst()
447 spicc->rx_remain = burst_len; in meson_spicc_setup_burst()
448 spicc->xfer_remain -= burst_len * spicc->bytes_per_word; in meson_spicc_setup_burst()
453 burst_len - 1), in meson_spicc_setup_burst()
454 spicc->base + SPICC_CONREG); in meson_spicc_setup_burst()
464 writel_bits_relaxed(SPICC_TC, SPICC_TC, spicc->base + SPICC_STATREG); in meson_spicc_irq()
466 if (spicc->using_dma) in meson_spicc_irq()
472 if (!spicc->xfer_remain) { in meson_spicc_irq()
474 writel(0, spicc->base + SPICC_INTREG); in meson_spicc_irq()
476 complete(&spicc->done); in meson_spicc_irq()
485 writel_bits_relaxed(SPICC_XCH, SPICC_XCH, spicc->base + SPICC_CONREG); in meson_spicc_irq()
496 if (spicc->data->has_enhance_clk_div) { in meson_spicc_auto_io_delay()
498 readl_relaxed(spicc->base + SPICC_ENH_CTL0)); in meson_spicc_auto_io_delay()
503 readl_relaxed(spicc->base + SPICC_CONREG)); in meson_spicc_auto_io_delay()
510 hz = clk_get_rate(spicc->clk); in meson_spicc_auto_io_delay()
525 conf = readl_relaxed(spicc->base + SPICC_TESTREG); in meson_spicc_auto_io_delay()
530 writel_relaxed(conf, spicc->base + SPICC_TESTREG); in meson_spicc_auto_io_delay()
539 conf = conf_orig = readl_relaxed(spicc->base + SPICC_CONREG); in meson_spicc_setup_xfer()
544 (spicc->bytes_per_word << 3) - 1); in meson_spicc_setup_xfer()
548 writel_relaxed(conf, spicc->base + SPICC_CONREG); in meson_spicc_setup_xfer()
550 clk_set_rate(spicc->clk, xfer->speed_hz); in meson_spicc_setup_xfer()
554 writel_relaxed(0, spicc->base + SPICC_DMAREG); in meson_spicc_setup_xfer()
559 if (spicc->data->has_oen) in meson_spicc_reset_fifo()
562 spicc->base + SPICC_ENH_CTL0); in meson_spicc_reset_fifo()
565 spicc->base + SPICC_TESTREG); in meson_spicc_reset_fifo()
568 readl_relaxed(spicc->base + SPICC_RXDATA); in meson_spicc_reset_fifo()
570 if (spicc->data->has_oen) in meson_spicc_reset_fifo()
572 spicc->base + SPICC_ENH_CTL0); in meson_spicc_reset_fifo()
576 struct spi_device *spi, in meson_spicc_transfer_one() argument
583 spicc->xfer = xfer; in meson_spicc_transfer_one()
586 spicc->tx_buf = (u8 *)xfer->tx_buf; in meson_spicc_transfer_one()
587 spicc->rx_buf = (u8 *)xfer->rx_buf; in meson_spicc_transfer_one()
588 spicc->xfer_remain = xfer->len; in meson_spicc_transfer_one()
590 /* Pre-calculate word size */ in meson_spicc_transfer_one()
591 spicc->bytes_per_word = in meson_spicc_transfer_one()
592 DIV_ROUND_UP(spicc->xfer->bits_per_word, 8); in meson_spicc_transfer_one()
594 if (xfer->len % spicc->bytes_per_word) in meson_spicc_transfer_one()
595 return -EINVAL; in meson_spicc_transfer_one()
603 reinit_completion(&spicc->done); in meson_spicc_transfer_one()
605 /* For each byte we wait for 8 cycles of the SPI clock */ in meson_spicc_transfer_one()
606 timeout = 8LL * MSEC_PER_SEC * xfer->len; in meson_spicc_transfer_one()
607 do_div(timeout, xfer->speed_hz); in meson_spicc_transfer_one()
610 timeout += ((xfer->len >> 4) * 10) / MSEC_PER_SEC; in meson_spicc_transfer_one()
615 if (xfer->bits_per_word == 64) { in meson_spicc_transfer_one()
619 if (xfer->len < 16) in meson_spicc_transfer_one()
620 return -EINVAL; in meson_spicc_transfer_one()
625 dev_err(host->dev.parent, "dma map failed\n"); in meson_spicc_transfer_one()
629 spicc->using_dma = true; in meson_spicc_transfer_one()
630 spicc->xfer_remain = DIV_ROUND_UP(xfer->len, spicc->bytes_per_word); in meson_spicc_transfer_one()
632 writel_relaxed(SPICC_TE_EN, spicc->base + SPICC_INTREG); in meson_spicc_transfer_one()
633 writel_bits_relaxed(SPICC_SMC, SPICC_SMC, spicc->base + SPICC_CONREG); in meson_spicc_transfer_one()
635 spicc->using_dma = false; in meson_spicc_transfer_one()
640 writel_bits_relaxed(SPICC_XCH, SPICC_XCH, spicc->base + SPICC_CONREG); in meson_spicc_transfer_one()
643 writel_relaxed(SPICC_TC_EN, spicc->base + SPICC_INTREG); in meson_spicc_transfer_one()
646 if (!wait_for_completion_timeout(&spicc->done, msecs_to_jiffies(timeout))) in meson_spicc_transfer_one()
647 return -ETIMEDOUT; in meson_spicc_transfer_one()
656 struct spi_device *spi = message->spi; in meson_spicc_prepare_message() local
657 u32 conf = readl_relaxed(spicc->base + SPICC_CONREG) & SPICC_DATARATE_MASK; in meson_spicc_prepare_message()
660 spicc->message = message; in meson_spicc_prepare_message()
669 if (spi->mode & SPI_CPOL) in meson_spicc_prepare_message()
674 if (!spicc->data->has_oen) { in meson_spicc_prepare_message()
675 if (spi->mode & SPI_CPOL) { in meson_spicc_prepare_message()
676 if (spicc->pins_idle_high) in meson_spicc_prepare_message()
677 pinctrl_select_state(spicc->pinctrl, spicc->pins_idle_high); in meson_spicc_prepare_message()
679 if (spicc->pins_idle_low) in meson_spicc_prepare_message()
680 pinctrl_select_state(spicc->pinctrl, spicc->pins_idle_low); in meson_spicc_prepare_message()
684 if (spi->mode & SPI_CPHA) in meson_spicc_prepare_message()
691 if (spi->mode & SPI_CS_HIGH) in meson_spicc_prepare_message()
696 if (spi->mode & SPI_READY) in meson_spicc_prepare_message()
702 conf |= FIELD_PREP(SPICC_CS_MASK, spi_get_chipselect(spi, 0)); in meson_spicc_prepare_message()
705 conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, 8 - 1); in meson_spicc_prepare_message()
707 writel_relaxed(conf, spicc->base + SPICC_CONREG); in meson_spicc_prepare_message()
710 writel_relaxed(0, spicc->base + SPICC_PERIODREG); in meson_spicc_prepare_message()
713 spi->mode & SPI_LOOP ? SPICC_LBC_W1 : 0, in meson_spicc_prepare_message()
714 spicc->base + SPICC_TESTREG); in meson_spicc_prepare_message()
722 u32 conf = readl_relaxed(spicc->base + SPICC_CONREG) & SPICC_DATARATE_MASK; in meson_spicc_unprepare_transfer()
725 writel(0, spicc->base + SPICC_INTREG); in meson_spicc_unprepare_transfer()
727 device_reset_optional(&spicc->pdev->dev); in meson_spicc_unprepare_transfer()
730 writel_relaxed(conf, spicc->base + SPICC_CONREG); in meson_spicc_unprepare_transfer()
732 if (!spicc->data->has_oen) in meson_spicc_unprepare_transfer()
733 pinctrl_select_default_state(&spicc->pdev->dev); in meson_spicc_unprepare_transfer()
738 static int meson_spicc_setup(struct spi_device *spi) in meson_spicc_setup() argument
740 if (!spi->controller_state) in meson_spicc_setup()
741 spi->controller_state = spi_controller_get_devdata(spi->controller); in meson_spicc_setup()
744 if (spi->bits_per_word != 8 && in meson_spicc_setup()
745 spi->bits_per_word != 16 && in meson_spicc_setup()
746 spi->bits_per_word != 24 && in meson_spicc_setup()
747 spi->bits_per_word != 32 && in meson_spicc_setup()
748 spi->bits_per_word != 64) in meson_spicc_setup()
749 return -EINVAL; in meson_spicc_setup()
754 static void meson_spicc_cleanup(struct spi_device *spi) in meson_spicc_cleanup() argument
756 spi->controller_state = NULL; in meson_spicc_cleanup()
760 * The Clock Mux
761 * x-----------------x x------------x x------\
762 * |---| pow2 fixed div |---| pow2 div |----| |
763 * | x-----------------x x------------x | |
764 * src ---| | mux |-- out
765 * | x-----------------x x------------x | |
766 * |---| enh fixed div |---| enh div |0---| |
767 * x-----------------x x------------x x------/
770 * src -> pow2 fixed div -> pow2 div -> out
773 * src -> pow2 fixed div -> pow2 div -> mux -> out
774 * src -> enh fixed div -> enh div -> mux -> out
777 * pclk -> pow2 fixed div -> pow2 div -> mux -> out
778 * pclk -> enh fixed div -> enh div -> mux -> out
793 if (!spicc->host->cur_msg) in meson_spicc_pow2_recalc_rate()
805 if (!spicc->host->cur_msg) in meson_spicc_pow2_determine_rate()
806 return -EINVAL; in meson_spicc_pow2_determine_rate()
817 if (!spicc->host->cur_msg) in meson_spicc_pow2_set_rate()
818 return -EINVAL; in meson_spicc_pow2_set_rate()
831 struct device *dev = &spicc->pdev->dev; in meson_spicc_pow2_clk_init()
847 return -ENOMEM; in meson_spicc_pow2_clk_init()
852 if (spicc->data->has_pclk) { in meson_spicc_pow2_clk_init()
854 parent_data[0].hw = __clk_get_hw(spicc->pclk); in meson_spicc_pow2_clk_init()
857 parent_data[0].hw = __clk_get_hw(spicc->core); in meson_spicc_pow2_clk_init()
861 pow2_fixed_div->mult = 1; in meson_spicc_pow2_clk_init()
862 pow2_fixed_div->div = 4; in meson_spicc_pow2_clk_init()
863 pow2_fixed_div->hw.init = &init; in meson_spicc_pow2_clk_init()
865 clk = devm_clk_register(dev, &pow2_fixed_div->hw); in meson_spicc_pow2_clk_init()
877 parent_data[0].hw = &pow2_fixed_div->hw; in meson_spicc_pow2_clk_init()
880 spicc->pow2_div.shift = 16; in meson_spicc_pow2_clk_init()
881 spicc->pow2_div.width = 3; in meson_spicc_pow2_clk_init()
882 spicc->pow2_div.flags = CLK_DIVIDER_POWER_OF_TWO; in meson_spicc_pow2_clk_init()
883 spicc->pow2_div.reg = spicc->base + SPICC_CONREG; in meson_spicc_pow2_clk_init()
884 spicc->pow2_div.hw.init = &init; in meson_spicc_pow2_clk_init()
886 spicc->clk = devm_clk_register(dev, &spicc->pow2_div.hw); in meson_spicc_pow2_clk_init()
887 if (WARN_ON(IS_ERR(spicc->clk))) in meson_spicc_pow2_clk_init()
888 return PTR_ERR(spicc->clk); in meson_spicc_pow2_clk_init()
895 struct device *dev = &spicc->pdev->dev; in meson_spicc_enh_clk_init()
898 struct clk_mux *mux; in meson_spicc_enh_clk_init() local
913 return -ENOMEM; in meson_spicc_enh_clk_init()
918 if (spicc->data->has_pclk) { in meson_spicc_enh_clk_init()
920 parent_data[0].hw = __clk_get_hw(spicc->pclk); in meson_spicc_enh_clk_init()
923 parent_data[0].hw = __clk_get_hw(spicc->core); in meson_spicc_enh_clk_init()
927 enh_fixed_div->mult = 1; in meson_spicc_enh_clk_init()
928 enh_fixed_div->div = 2; in meson_spicc_enh_clk_init()
929 enh_fixed_div->hw.init = &init; in meson_spicc_enh_clk_init()
931 clk = devm_clk_register(dev, &enh_fixed_div->hw); in meson_spicc_enh_clk_init()
937 return -ENOMEM; in meson_spicc_enh_clk_init()
943 parent_data[0].hw = &enh_fixed_div->hw; in meson_spicc_enh_clk_init()
946 enh_div->shift = 16; in meson_spicc_enh_clk_init()
947 enh_div->width = 8; in meson_spicc_enh_clk_init()
948 enh_div->reg = spicc->base + SPICC_ENH_CTL0; in meson_spicc_enh_clk_init()
949 enh_div->hw.init = &init; in meson_spicc_enh_clk_init()
951 clk = devm_clk_register(dev, &enh_div->hw); in meson_spicc_enh_clk_init()
955 mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); in meson_spicc_enh_clk_init()
956 if (!mux) in meson_spicc_enh_clk_init()
957 return -ENOMEM; in meson_spicc_enh_clk_init()
962 parent_data[0].hw = &spicc->pow2_div.hw; in meson_spicc_enh_clk_init()
963 parent_data[1].hw = &enh_div->hw; in meson_spicc_enh_clk_init()
967 mux->mask = 0x1; in meson_spicc_enh_clk_init()
968 mux->shift = 24; in meson_spicc_enh_clk_init()
969 mux->reg = spicc->base + SPICC_ENH_CTL0; in meson_spicc_enh_clk_init()
970 mux->hw.init = &init; in meson_spicc_enh_clk_init()
972 spicc->clk = devm_clk_register(dev, &mux->hw); in meson_spicc_enh_clk_init()
973 if (WARN_ON(IS_ERR(spicc->clk))) in meson_spicc_enh_clk_init()
974 return PTR_ERR(spicc->clk); in meson_spicc_enh_clk_init()
985 host = spi_alloc_host(&pdev->dev, sizeof(*spicc)); in meson_spicc_probe()
987 dev_err(&pdev->dev, "host allocation failed\n"); in meson_spicc_probe()
988 return -ENOMEM; in meson_spicc_probe()
991 spicc->host = host; in meson_spicc_probe()
993 spicc->data = of_device_get_match_data(&pdev->dev); in meson_spicc_probe()
994 if (!spicc->data) { in meson_spicc_probe()
995 dev_err(&pdev->dev, "failed to get match data\n"); in meson_spicc_probe()
996 ret = -EINVAL; in meson_spicc_probe()
1000 spicc->pdev = pdev; in meson_spicc_probe()
1003 init_completion(&spicc->done); in meson_spicc_probe()
1005 spicc->base = devm_platform_ioremap_resource(pdev, 0); in meson_spicc_probe()
1006 if (IS_ERR(spicc->base)) { in meson_spicc_probe()
1007 dev_err(&pdev->dev, "io resource mapping failed\n"); in meson_spicc_probe()
1008 ret = PTR_ERR(spicc->base); in meson_spicc_probe()
1014 spicc->base + SPICC_CONREG); in meson_spicc_probe()
1017 writel_relaxed(0, spicc->base + SPICC_INTREG); in meson_spicc_probe()
1025 ret = devm_request_irq(&pdev->dev, irq, meson_spicc_irq, in meson_spicc_probe()
1028 dev_err(&pdev->dev, "irq request failed\n"); in meson_spicc_probe()
1032 spicc->core = devm_clk_get_enabled(&pdev->dev, "core"); in meson_spicc_probe()
1033 if (IS_ERR(spicc->core)) { in meson_spicc_probe()
1034 dev_err(&pdev->dev, "core clock request failed\n"); in meson_spicc_probe()
1035 ret = PTR_ERR(spicc->core); in meson_spicc_probe()
1039 if (spicc->data->has_pclk) { in meson_spicc_probe()
1040 spicc->pclk = devm_clk_get_enabled(&pdev->dev, "pclk"); in meson_spicc_probe()
1041 if (IS_ERR(spicc->pclk)) { in meson_spicc_probe()
1042 dev_err(&pdev->dev, "pclk clock request failed\n"); in meson_spicc_probe()
1043 ret = PTR_ERR(spicc->pclk); in meson_spicc_probe()
1048 spicc->pinctrl = devm_pinctrl_get(&pdev->dev); in meson_spicc_probe()
1049 if (IS_ERR(spicc->pinctrl)) { in meson_spicc_probe()
1050 ret = PTR_ERR(spicc->pinctrl); in meson_spicc_probe()
1054 device_reset_optional(&pdev->dev); in meson_spicc_probe()
1056 host->num_chipselect = 4; in meson_spicc_probe()
1057 host->dev.of_node = pdev->dev.of_node; in meson_spicc_probe()
1058 host->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LOOP; in meson_spicc_probe()
1059 host->flags = (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX); in meson_spicc_probe()
1060 host->min_speed_hz = spicc->data->min_speed_hz; in meson_spicc_probe()
1061 host->max_speed_hz = spicc->data->max_speed_hz; in meson_spicc_probe()
1062 host->setup = meson_spicc_setup; in meson_spicc_probe()
1063 host->cleanup = meson_spicc_cleanup; in meson_spicc_probe()
1064 host->prepare_message = meson_spicc_prepare_message; in meson_spicc_probe()
1065 host->unprepare_transfer_hardware = meson_spicc_unprepare_transfer; in meson_spicc_probe()
1066 host->transfer_one = meson_spicc_transfer_one; in meson_spicc_probe()
1067 host->use_gpio_descriptors = true; in meson_spicc_probe()
1073 dev_err(&pdev->dev, "pow2 clock registration failed\n"); in meson_spicc_probe()
1077 if (spicc->data->has_enhance_clk_div) { in meson_spicc_probe()
1080 dev_err(&pdev->dev, "clock registration failed\n"); in meson_spicc_probe()
1085 ret = devm_spi_register_controller(&pdev->dev, host); in meson_spicc_probe()
1087 dev_err(&pdev->dev, "spi registration failed\n"); in meson_spicc_probe()
1103 /* Disable SPI */ in meson_spicc_remove()
1104 writel(0, spicc->base + SPICC_CONREG); in meson_spicc_remove()
1106 spi_controller_put(spicc->host); in meson_spicc_remove()
1134 .compatible = "amlogic,meson-gx-spicc",
1138 .compatible = "amlogic,meson-axg-spicc",
1142 .compatible = "amlogic,meson-g12a-spicc",
1153 .name = "meson-spicc",
1160 MODULE_DESCRIPTION("Meson SPI Communication Controller driver");