Lines Matching +full:spi +full:- +full:samsung
1 // SPDX-License-Identifier: GPL-2.0+
3 // Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 // Jaswinder Singh <jassi.brar@samsung.com>
11 #include <linux/dma-mapping.h>
15 #include <linux/spi/spi.h>
20 #include <linux/platform_data/spi-s3c64xx.h>
27 /* Registers and bit-fields */
105 #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
107 (1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
109 #define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
118 #define is_polling(x) (x->port_conf->quirks & S3C64XX_SPI_QUIRK_POLL)
130 * struct s3c64xx_spi_info - SPI Controller hardware info
131 * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
138 * The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
139 * differ in some aspects such as the size of the fifo and spi bus clock
154 * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
155 * @clk: Pointer to the spi clock.
156 * @src_clk: Pointer to the clock used to generate SPI signals.
158 * @master: Pointer to the SPI Protocol master.
164 * @sfr_start: BUS address of SPI controller regs.
194 void __iomem *regs = sdd->regs; in s3c64xx_flush_fifo()
213 } while (TX_FIFO_LVL(val, sdd) && loops--); in s3c64xx_flush_fifo()
216 dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); in s3c64xx_flush_fifo()
226 } while (loops--); in s3c64xx_flush_fifo()
229 dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); in s3c64xx_flush_fifo()
246 if (dma->direction == DMA_DEV_TO_MEM) in s3c64xx_spi_dmacb()
253 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_dmacb()
255 if (dma->direction == DMA_DEV_TO_MEM) { in s3c64xx_spi_dmacb()
256 sdd->state &= ~RXBUSY; in s3c64xx_spi_dmacb()
257 if (!(sdd->state & TXBUSY)) in s3c64xx_spi_dmacb()
258 complete(&sdd->xfer_completion); in s3c64xx_spi_dmacb()
260 sdd->state &= ~TXBUSY; in s3c64xx_spi_dmacb()
261 if (!(sdd->state & RXBUSY)) in s3c64xx_spi_dmacb()
262 complete(&sdd->xfer_completion); in s3c64xx_spi_dmacb()
265 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_dmacb()
278 if (dma->direction == DMA_DEV_TO_MEM) { in prepare_dma()
281 config.direction = dma->direction; in prepare_dma()
282 config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA; in prepare_dma()
283 config.src_addr_width = sdd->cur_bpw / 8; in prepare_dma()
285 dmaengine_slave_config(dma->ch, &config); in prepare_dma()
289 config.direction = dma->direction; in prepare_dma()
290 config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA; in prepare_dma()
291 config.dst_addr_width = sdd->cur_bpw / 8; in prepare_dma()
293 dmaengine_slave_config(dma->ch, &config); in prepare_dma()
296 desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents, in prepare_dma()
297 dma->direction, DMA_PREP_INTERRUPT); in prepare_dma()
299 dev_err(&sdd->pdev->dev, "unable to prepare %s scatterlist", in prepare_dma()
300 dma->direction == DMA_DEV_TO_MEM ? "rx" : "tx"); in prepare_dma()
301 return -ENOMEM; in prepare_dma()
304 desc->callback = s3c64xx_spi_dmacb; in prepare_dma()
305 desc->callback_param = dma; in prepare_dma()
307 dma->cookie = dmaengine_submit(desc); in prepare_dma()
308 ret = dma_submit_error(dma->cookie); in prepare_dma()
310 dev_err(&sdd->pdev->dev, "DMA submission failed"); in prepare_dma()
311 return -EIO; in prepare_dma()
314 dma_async_issue_pending(dma->ch); in prepare_dma()
318 static void s3c64xx_spi_set_cs(struct spi_device *spi, bool enable) in s3c64xx_spi_set_cs() argument
321 spi_master_get_devdata(spi->master); in s3c64xx_spi_set_cs()
323 if (sdd->cntrlr_info->no_cs) in s3c64xx_spi_set_cs()
327 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) { in s3c64xx_spi_set_cs()
328 writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); in s3c64xx_spi_set_cs()
330 u32 ssel = readl(sdd->regs + S3C64XX_SPI_SLAVE_SEL); in s3c64xx_spi_set_cs()
334 writel(ssel, sdd->regs + S3C64XX_SPI_SLAVE_SEL); in s3c64xx_spi_set_cs()
337 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) in s3c64xx_spi_set_cs()
339 sdd->regs + S3C64XX_SPI_SLAVE_SEL); in s3c64xx_spi_set_cs()
343 static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) in s3c64xx_spi_prepare_transfer() argument
345 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); in s3c64xx_spi_prepare_transfer()
350 spi->dma_rx = sdd->rx_dma.ch; in s3c64xx_spi_prepare_transfer()
351 spi->dma_tx = sdd->tx_dma.ch; in s3c64xx_spi_prepare_transfer()
357 struct spi_device *spi, in s3c64xx_spi_can_dma() argument
362 return xfer->len > (FIFO_LVL_MASK(sdd) >> 1) + 1; in s3c64xx_spi_can_dma()
368 void __iomem *regs = sdd->regs; in s3c64xx_enable_datapath()
386 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) in s3c64xx_enable_datapath()
391 if (xfer->tx_buf != NULL) { in s3c64xx_enable_datapath()
392 sdd->state |= TXBUSY; in s3c64xx_enable_datapath()
396 ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg); in s3c64xx_enable_datapath()
398 switch (sdd->cur_bpw) { in s3c64xx_enable_datapath()
401 xfer->tx_buf, xfer->len / 4); in s3c64xx_enable_datapath()
405 xfer->tx_buf, xfer->len / 2); in s3c64xx_enable_datapath()
409 xfer->tx_buf, xfer->len); in s3c64xx_enable_datapath()
415 if (xfer->rx_buf != NULL) { in s3c64xx_enable_datapath()
416 sdd->state |= RXBUSY; in s3c64xx_enable_datapath()
418 if (sdd->port_conf->high_speed && sdd->cur_speed >= 30000000UL in s3c64xx_enable_datapath()
419 && !(sdd->cur_mode & SPI_CPHA)) in s3c64xx_enable_datapath()
425 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) in s3c64xx_enable_datapath()
428 ret = prepare_dma(&sdd->rx_dma, &xfer->rx_sg); in s3c64xx_enable_datapath()
444 void __iomem *regs = sdd->regs; in s3c64xx_spi_wait_for_timeout()
456 } while (RX_FIFO_LVL(status, sdd) < max_fifo && --val); in s3c64xx_spi_wait_for_timeout()
465 void __iomem *regs = sdd->regs; in s3c64xx_wait_for_dma()
471 ms = xfer->len * 8 * 1000 / sdd->cur_speed; in s3c64xx_wait_for_dma()
475 val = wait_for_completion_timeout(&sdd->xfer_completion, val); in s3c64xx_wait_for_dma()
479 * proceed further else return -EIO. in s3c64xx_wait_for_dma()
486 if (val && !xfer->rx_buf) { in s3c64xx_wait_for_dma()
491 && --val) { in s3c64xx_wait_for_dma()
500 return -EIO; in s3c64xx_wait_for_dma()
508 void __iomem *regs = sdd->regs; in s3c64xx_wait_for_pio()
517 ms = xfer->len * 8 * 1000 / sdd->cur_speed; in s3c64xx_wait_for_pio()
523 } while (RX_FIFO_LVL(status, sdd) < xfer->len && --val); in s3c64xx_wait_for_pio()
526 return -EIO; in s3c64xx_wait_for_pio()
529 if (!xfer->rx_buf) { in s3c64xx_wait_for_pio()
530 sdd->state &= ~TXBUSY; in s3c64xx_wait_for_pio()
542 loops = xfer->len / ((FIFO_LVL_MASK(sdd) >> 1) + 1); in s3c64xx_wait_for_pio()
543 buf = xfer->rx_buf; in s3c64xx_wait_for_pio()
549 switch (sdd->cur_bpw) { in s3c64xx_wait_for_pio()
565 } while (loops--); in s3c64xx_wait_for_pio()
566 sdd->state &= ~RXBUSY; in s3c64xx_wait_for_pio()
573 void __iomem *regs = sdd->regs; in s3c64xx_spi_config()
578 if (!sdd->port_conf->clk_from_cmu) { in s3c64xx_spi_config()
590 if (sdd->cur_mode & SPI_CPOL) in s3c64xx_spi_config()
593 if (sdd->cur_mode & SPI_CPHA) in s3c64xx_spi_config()
603 switch (sdd->cur_bpw) { in s3c64xx_spi_config()
620 if (sdd->port_conf->clk_from_cmu) { in s3c64xx_spi_config()
622 ret = clk_set_rate(sdd->src_clk, sdd->cur_speed * 2); in s3c64xx_spi_config()
629 val |= ((clk_get_rate(sdd->src_clk) / sdd->cur_speed / 2 - 1) in s3c64xx_spi_config()
648 struct spi_device *spi = msg->spi; in s3c64xx_spi_prepare_message() local
649 struct s3c64xx_spi_csinfo *cs = spi->controller_data; in s3c64xx_spi_prepare_message()
652 writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); in s3c64xx_spi_prepare_message()
658 struct spi_device *spi, in s3c64xx_spi_transfer_one() argument
672 reinit_completion(&sdd->xfer_completion); in s3c64xx_spi_transfer_one()
675 bpw = xfer->bits_per_word; in s3c64xx_spi_transfer_one()
676 speed = xfer->speed_hz; in s3c64xx_spi_transfer_one()
678 if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { in s3c64xx_spi_transfer_one()
679 sdd->cur_bpw = bpw; in s3c64xx_spi_transfer_one()
680 sdd->cur_speed = speed; in s3c64xx_spi_transfer_one()
681 sdd->cur_mode = spi->mode; in s3c64xx_spi_transfer_one()
687 if (!is_polling(sdd) && (xfer->len > fifo_len) && in s3c64xx_spi_transfer_one()
688 sdd->rx_dma.ch && sdd->tx_dma.ch) { in s3c64xx_spi_transfer_one()
691 } else if (is_polling(sdd) && xfer->len > fifo_len) { in s3c64xx_spi_transfer_one()
692 tx_buf = xfer->tx_buf; in s3c64xx_spi_transfer_one()
693 rx_buf = xfer->rx_buf; in s3c64xx_spi_transfer_one()
694 origin_len = xfer->len; in s3c64xx_spi_transfer_one()
696 target_len = xfer->len; in s3c64xx_spi_transfer_one()
697 if (xfer->len > fifo_len) in s3c64xx_spi_transfer_one()
698 xfer->len = fifo_len; in s3c64xx_spi_transfer_one()
702 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_transfer_one()
705 sdd->state &= ~RXBUSY; in s3c64xx_spi_transfer_one()
706 sdd->state &= ~TXBUSY; in s3c64xx_spi_transfer_one()
709 s3c64xx_spi_set_cs(spi, true); in s3c64xx_spi_transfer_one()
713 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_transfer_one()
716 dev_err(&spi->dev, "failed to enable data path for transfer: %d\n", status); in s3c64xx_spi_transfer_one()
726 dev_err(&spi->dev, in s3c64xx_spi_transfer_one()
727 "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n", in s3c64xx_spi_transfer_one()
728 xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, in s3c64xx_spi_transfer_one()
729 (sdd->state & RXBUSY) ? 'f' : 'p', in s3c64xx_spi_transfer_one()
730 (sdd->state & TXBUSY) ? 'f' : 'p', in s3c64xx_spi_transfer_one()
731 xfer->len); in s3c64xx_spi_transfer_one()
734 if (xfer->tx_buf && (sdd->state & TXBUSY)) in s3c64xx_spi_transfer_one()
735 dmaengine_terminate_all(sdd->tx_dma.ch); in s3c64xx_spi_transfer_one()
736 if (xfer->rx_buf && (sdd->state & RXBUSY)) in s3c64xx_spi_transfer_one()
737 dmaengine_terminate_all(sdd->rx_dma.ch); in s3c64xx_spi_transfer_one()
743 target_len -= xfer->len; in s3c64xx_spi_transfer_one()
745 if (xfer->tx_buf) in s3c64xx_spi_transfer_one()
746 xfer->tx_buf += xfer->len; in s3c64xx_spi_transfer_one()
748 if (xfer->rx_buf) in s3c64xx_spi_transfer_one()
749 xfer->rx_buf += xfer->len; in s3c64xx_spi_transfer_one()
752 xfer->len = fifo_len; in s3c64xx_spi_transfer_one()
754 xfer->len = target_len; in s3c64xx_spi_transfer_one()
760 xfer->tx_buf = tx_buf; in s3c64xx_spi_transfer_one()
761 xfer->rx_buf = rx_buf; in s3c64xx_spi_transfer_one()
762 xfer->len = origin_len; in s3c64xx_spi_transfer_one()
769 struct spi_device *spi) in s3c64xx_get_slave_ctrldata() argument
775 slave_np = spi->dev.of_node; in s3c64xx_get_slave_ctrldata()
777 dev_err(&spi->dev, "device node not found\n"); in s3c64xx_get_slave_ctrldata()
778 return ERR_PTR(-EINVAL); in s3c64xx_get_slave_ctrldata()
781 data_np = of_get_child_by_name(slave_np, "controller-data"); in s3c64xx_get_slave_ctrldata()
783 dev_err(&spi->dev, "child node 'controller-data' not found\n"); in s3c64xx_get_slave_ctrldata()
784 return ERR_PTR(-EINVAL); in s3c64xx_get_slave_ctrldata()
790 return ERR_PTR(-ENOMEM); in s3c64xx_get_slave_ctrldata()
793 of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay); in s3c64xx_get_slave_ctrldata()
794 cs->fb_delay = fb_delay; in s3c64xx_get_slave_ctrldata()
801 * and save the configuration in a local data-structure.
805 static int s3c64xx_spi_setup(struct spi_device *spi) in s3c64xx_spi_setup() argument
807 struct s3c64xx_spi_csinfo *cs = spi->controller_data; in s3c64xx_spi_setup()
811 sdd = spi_master_get_devdata(spi->master); in s3c64xx_spi_setup()
812 if (spi->dev.of_node) { in s3c64xx_spi_setup()
813 cs = s3c64xx_get_slave_ctrldata(spi); in s3c64xx_spi_setup()
814 spi->controller_data = cs; in s3c64xx_spi_setup()
816 /* On non-DT platforms the SPI core will set spi->cs_gpio in s3c64xx_spi_setup()
817 * to -ENOENT. The GPIO pin used to drive the chip select in s3c64xx_spi_setup()
818 * is defined by using platform data so spi->cs_gpio value in s3c64xx_spi_setup()
821 spi->cs_gpio = cs->line; in s3c64xx_spi_setup()
825 dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select); in s3c64xx_spi_setup()
826 return -ENODEV; in s3c64xx_spi_setup()
829 if (!spi_get_ctldata(spi)) { in s3c64xx_spi_setup()
830 if (gpio_is_valid(spi->cs_gpio)) { in s3c64xx_spi_setup()
831 err = gpio_request_one(spi->cs_gpio, GPIOF_OUT_INIT_HIGH, in s3c64xx_spi_setup()
832 dev_name(&spi->dev)); in s3c64xx_spi_setup()
834 dev_err(&spi->dev, in s3c64xx_spi_setup()
836 spi->cs_gpio, err); in s3c64xx_spi_setup()
841 spi_set_ctldata(spi, cs); in s3c64xx_spi_setup()
844 pm_runtime_get_sync(&sdd->pdev->dev); in s3c64xx_spi_setup()
847 if (!sdd->port_conf->clk_from_cmu) { in s3c64xx_spi_setup()
851 speed = clk_get_rate(sdd->src_clk) / 2 / (0 + 1); in s3c64xx_spi_setup()
853 if (spi->max_speed_hz > speed) in s3c64xx_spi_setup()
854 spi->max_speed_hz = speed; in s3c64xx_spi_setup()
856 psr = clk_get_rate(sdd->src_clk) / 2 / spi->max_speed_hz - 1; in s3c64xx_spi_setup()
859 psr--; in s3c64xx_spi_setup()
861 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1); in s3c64xx_spi_setup()
862 if (spi->max_speed_hz < speed) { in s3c64xx_spi_setup()
866 err = -EINVAL; in s3c64xx_spi_setup()
871 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1); in s3c64xx_spi_setup()
872 if (spi->max_speed_hz >= speed) { in s3c64xx_spi_setup()
873 spi->max_speed_hz = speed; in s3c64xx_spi_setup()
875 dev_err(&spi->dev, "Can't set %dHz transfer speed\n", in s3c64xx_spi_setup()
876 spi->max_speed_hz); in s3c64xx_spi_setup()
877 err = -EINVAL; in s3c64xx_spi_setup()
882 pm_runtime_mark_last_busy(&sdd->pdev->dev); in s3c64xx_spi_setup()
883 pm_runtime_put_autosuspend(&sdd->pdev->dev); in s3c64xx_spi_setup()
884 s3c64xx_spi_set_cs(spi, false); in s3c64xx_spi_setup()
889 pm_runtime_mark_last_busy(&sdd->pdev->dev); in s3c64xx_spi_setup()
890 pm_runtime_put_autosuspend(&sdd->pdev->dev); in s3c64xx_spi_setup()
891 /* setup() returns with device de-selected */ in s3c64xx_spi_setup()
892 s3c64xx_spi_set_cs(spi, false); in s3c64xx_spi_setup()
894 if (gpio_is_valid(spi->cs_gpio)) in s3c64xx_spi_setup()
895 gpio_free(spi->cs_gpio); in s3c64xx_spi_setup()
896 spi_set_ctldata(spi, NULL); in s3c64xx_spi_setup()
899 if (spi->dev.of_node) in s3c64xx_spi_setup()
905 static void s3c64xx_spi_cleanup(struct spi_device *spi) in s3c64xx_spi_cleanup() argument
907 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi); in s3c64xx_spi_cleanup()
909 if (gpio_is_valid(spi->cs_gpio)) { in s3c64xx_spi_cleanup()
910 gpio_free(spi->cs_gpio); in s3c64xx_spi_cleanup()
911 if (spi->dev.of_node) in s3c64xx_spi_cleanup()
914 /* On non-DT platforms, the SPI core sets in s3c64xx_spi_cleanup()
915 * spi->cs_gpio to -ENOENT and .setup() in s3c64xx_spi_cleanup()
919 spi->cs_gpio = -ENOENT; in s3c64xx_spi_cleanup()
923 spi_set_ctldata(spi, NULL); in s3c64xx_spi_cleanup()
929 struct spi_master *spi = sdd->master; in s3c64xx_spi_irq() local
932 val = readl(sdd->regs + S3C64XX_SPI_STATUS); in s3c64xx_spi_irq()
936 dev_err(&spi->dev, "RX overrun\n"); in s3c64xx_spi_irq()
940 dev_err(&spi->dev, "RX underrun\n"); in s3c64xx_spi_irq()
944 dev_err(&spi->dev, "TX overrun\n"); in s3c64xx_spi_irq()
948 dev_err(&spi->dev, "TX underrun\n"); in s3c64xx_spi_irq()
952 writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); in s3c64xx_spi_irq()
953 writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR); in s3c64xx_spi_irq()
960 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_hwinit()
961 void __iomem *regs = sdd->regs; in s3c64xx_spi_hwinit()
964 sdd->cur_speed = 0; in s3c64xx_spi_hwinit()
966 if (sci->no_cs) in s3c64xx_spi_hwinit()
967 writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); in s3c64xx_spi_hwinit()
968 else if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) in s3c64xx_spi_hwinit()
969 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); in s3c64xx_spi_hwinit()
971 /* Disable Interrupts - we use Polling if not DMA mode */ in s3c64xx_spi_hwinit()
974 if (!sdd->port_conf->clk_from_cmu) in s3c64xx_spi_hwinit()
975 writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT, in s3c64xx_spi_hwinit()
1007 return ERR_PTR(-ENOMEM); in s3c64xx_spi_parse_dt()
1009 if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) { in s3c64xx_spi_parse_dt()
1010 dev_warn(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n"); in s3c64xx_spi_parse_dt()
1011 sci->src_clk_nr = 0; in s3c64xx_spi_parse_dt()
1013 sci->src_clk_nr = temp; in s3c64xx_spi_parse_dt()
1016 if (of_property_read_u32(dev->of_node, "num-cs", &temp)) { in s3c64xx_spi_parse_dt()
1018 sci->num_cs = 1; in s3c64xx_spi_parse_dt()
1020 sci->num_cs = temp; in s3c64xx_spi_parse_dt()
1023 sci->no_cs = of_property_read_bool(dev->of_node, "no-cs-readback"); in s3c64xx_spi_parse_dt()
1040 if (pdev->dev.of_node) { in s3c64xx_spi_get_port_config()
1042 match = of_match_node(s3c64xx_spi_dt_match, pdev->dev.of_node); in s3c64xx_spi_get_port_config()
1043 return (struct s3c64xx_spi_port_config *)match->data; in s3c64xx_spi_get_port_config()
1047 platform_get_device_id(pdev)->driver_data; in s3c64xx_spi_get_port_config()
1054 struct s3c64xx_spi_info *sci = dev_get_platdata(&pdev->dev); in s3c64xx_spi_probe()
1059 if (!sci && pdev->dev.of_node) { in s3c64xx_spi_probe()
1060 sci = s3c64xx_spi_parse_dt(&pdev->dev); in s3c64xx_spi_probe()
1066 dev_err(&pdev->dev, "platform_data missing!\n"); in s3c64xx_spi_probe()
1067 return -ENODEV; in s3c64xx_spi_probe()
1072 dev_err(&pdev->dev, "Unable to get SPI MEM resource\n"); in s3c64xx_spi_probe()
1073 return -ENXIO; in s3c64xx_spi_probe()
1078 dev_warn(&pdev->dev, "Failed to get IRQ: %d\n", irq); in s3c64xx_spi_probe()
1082 master = spi_alloc_master(&pdev->dev, in s3c64xx_spi_probe()
1085 dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); in s3c64xx_spi_probe()
1086 return -ENOMEM; in s3c64xx_spi_probe()
1092 sdd->port_conf = s3c64xx_spi_get_port_config(pdev); in s3c64xx_spi_probe()
1093 sdd->master = master; in s3c64xx_spi_probe()
1094 sdd->cntrlr_info = sci; in s3c64xx_spi_probe()
1095 sdd->pdev = pdev; in s3c64xx_spi_probe()
1096 sdd->sfr_start = mem_res->start; in s3c64xx_spi_probe()
1097 if (pdev->dev.of_node) { in s3c64xx_spi_probe()
1098 ret = of_alias_get_id(pdev->dev.of_node, "spi"); in s3c64xx_spi_probe()
1100 dev_err(&pdev->dev, "failed to get alias id, errno %d\n", in s3c64xx_spi_probe()
1104 sdd->port_id = ret; in s3c64xx_spi_probe()
1106 sdd->port_id = pdev->id; in s3c64xx_spi_probe()
1109 sdd->cur_bpw = 8; in s3c64xx_spi_probe()
1111 sdd->tx_dma.direction = DMA_MEM_TO_DEV; in s3c64xx_spi_probe()
1112 sdd->rx_dma.direction = DMA_DEV_TO_MEM; in s3c64xx_spi_probe()
1114 master->dev.of_node = pdev->dev.of_node; in s3c64xx_spi_probe()
1115 master->bus_num = sdd->port_id; in s3c64xx_spi_probe()
1116 master->setup = s3c64xx_spi_setup; in s3c64xx_spi_probe()
1117 master->cleanup = s3c64xx_spi_cleanup; in s3c64xx_spi_probe()
1118 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; in s3c64xx_spi_probe()
1119 master->prepare_message = s3c64xx_spi_prepare_message; in s3c64xx_spi_probe()
1120 master->transfer_one = s3c64xx_spi_transfer_one; in s3c64xx_spi_probe()
1121 master->num_chipselect = sci->num_cs; in s3c64xx_spi_probe()
1122 master->dma_alignment = 8; in s3c64xx_spi_probe()
1123 master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | in s3c64xx_spi_probe()
1125 /* the spi->mode bits understood by this driver: */ in s3c64xx_spi_probe()
1126 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; in s3c64xx_spi_probe()
1127 master->auto_runtime_pm = true; in s3c64xx_spi_probe()
1129 master->can_dma = s3c64xx_spi_can_dma; in s3c64xx_spi_probe()
1131 sdd->regs = devm_ioremap_resource(&pdev->dev, mem_res); in s3c64xx_spi_probe()
1132 if (IS_ERR(sdd->regs)) { in s3c64xx_spi_probe()
1133 ret = PTR_ERR(sdd->regs); in s3c64xx_spi_probe()
1137 if (sci->cfg_gpio && sci->cfg_gpio()) { in s3c64xx_spi_probe()
1138 dev_err(&pdev->dev, "Unable to config gpio\n"); in s3c64xx_spi_probe()
1139 ret = -EBUSY; in s3c64xx_spi_probe()
1144 sdd->clk = devm_clk_get(&pdev->dev, "spi"); in s3c64xx_spi_probe()
1145 if (IS_ERR(sdd->clk)) { in s3c64xx_spi_probe()
1146 dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n"); in s3c64xx_spi_probe()
1147 ret = PTR_ERR(sdd->clk); in s3c64xx_spi_probe()
1151 ret = clk_prepare_enable(sdd->clk); in s3c64xx_spi_probe()
1153 dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n"); in s3c64xx_spi_probe()
1157 sprintf(clk_name, "spi_busclk%d", sci->src_clk_nr); in s3c64xx_spi_probe()
1158 sdd->src_clk = devm_clk_get(&pdev->dev, clk_name); in s3c64xx_spi_probe()
1159 if (IS_ERR(sdd->src_clk)) { in s3c64xx_spi_probe()
1160 dev_err(&pdev->dev, in s3c64xx_spi_probe()
1162 ret = PTR_ERR(sdd->src_clk); in s3c64xx_spi_probe()
1166 ret = clk_prepare_enable(sdd->src_clk); in s3c64xx_spi_probe()
1168 dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", clk_name); in s3c64xx_spi_probe()
1172 if (sdd->port_conf->clk_ioclk) { in s3c64xx_spi_probe()
1173 sdd->ioclk = devm_clk_get(&pdev->dev, "spi_ioclk"); in s3c64xx_spi_probe()
1174 if (IS_ERR(sdd->ioclk)) { in s3c64xx_spi_probe()
1175 dev_err(&pdev->dev, "Unable to acquire 'ioclk'\n"); in s3c64xx_spi_probe()
1176 ret = PTR_ERR(sdd->ioclk); in s3c64xx_spi_probe()
1180 ret = clk_prepare_enable(sdd->ioclk); in s3c64xx_spi_probe()
1182 dev_err(&pdev->dev, "Couldn't enable clock 'ioclk'\n"); in s3c64xx_spi_probe()
1189 sdd->rx_dma.ch = dma_request_slave_channel_reason(&pdev->dev, in s3c64xx_spi_probe()
1191 if (IS_ERR(sdd->rx_dma.ch)) { in s3c64xx_spi_probe()
1192 dev_err(&pdev->dev, "Failed to get RX DMA channel\n"); in s3c64xx_spi_probe()
1193 ret = PTR_ERR(sdd->rx_dma.ch); in s3c64xx_spi_probe()
1196 sdd->tx_dma.ch = dma_request_slave_channel_reason(&pdev->dev, in s3c64xx_spi_probe()
1198 if (IS_ERR(sdd->tx_dma.ch)) { in s3c64xx_spi_probe()
1199 dev_err(&pdev->dev, "Failed to get TX DMA channel\n"); in s3c64xx_spi_probe()
1200 ret = PTR_ERR(sdd->tx_dma.ch); in s3c64xx_spi_probe()
1205 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT); in s3c64xx_spi_probe()
1206 pm_runtime_use_autosuspend(&pdev->dev); in s3c64xx_spi_probe()
1207 pm_runtime_set_active(&pdev->dev); in s3c64xx_spi_probe()
1208 pm_runtime_enable(&pdev->dev); in s3c64xx_spi_probe()
1209 pm_runtime_get_sync(&pdev->dev); in s3c64xx_spi_probe()
1214 spin_lock_init(&sdd->lock); in s3c64xx_spi_probe()
1215 init_completion(&sdd->xfer_completion); in s3c64xx_spi_probe()
1217 ret = devm_request_irq(&pdev->dev, irq, s3c64xx_spi_irq, 0, in s3c64xx_spi_probe()
1218 "spi-s3c64xx", sdd); in s3c64xx_spi_probe()
1220 dev_err(&pdev->dev, "Failed to request IRQ %d: %d\n", in s3c64xx_spi_probe()
1227 sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_probe()
1229 ret = devm_spi_register_master(&pdev->dev, master); in s3c64xx_spi_probe()
1231 dev_err(&pdev->dev, "cannot register SPI master: %d\n", ret); in s3c64xx_spi_probe()
1235 dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached\n", in s3c64xx_spi_probe()
1236 sdd->port_id, master->num_chipselect); in s3c64xx_spi_probe()
1237 dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n", in s3c64xx_spi_probe()
1240 pm_runtime_mark_last_busy(&pdev->dev); in s3c64xx_spi_probe()
1241 pm_runtime_put_autosuspend(&pdev->dev); in s3c64xx_spi_probe()
1246 pm_runtime_put_noidle(&pdev->dev); in s3c64xx_spi_probe()
1247 pm_runtime_disable(&pdev->dev); in s3c64xx_spi_probe()
1248 pm_runtime_set_suspended(&pdev->dev); in s3c64xx_spi_probe()
1251 dma_release_channel(sdd->tx_dma.ch); in s3c64xx_spi_probe()
1254 dma_release_channel(sdd->rx_dma.ch); in s3c64xx_spi_probe()
1256 clk_disable_unprepare(sdd->ioclk); in s3c64xx_spi_probe()
1258 clk_disable_unprepare(sdd->src_clk); in s3c64xx_spi_probe()
1260 clk_disable_unprepare(sdd->clk); in s3c64xx_spi_probe()
1272 pm_runtime_get_sync(&pdev->dev); in s3c64xx_spi_remove()
1274 writel(0, sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_remove()
1277 dma_release_channel(sdd->rx_dma.ch); in s3c64xx_spi_remove()
1278 dma_release_channel(sdd->tx_dma.ch); in s3c64xx_spi_remove()
1281 clk_disable_unprepare(sdd->ioclk); in s3c64xx_spi_remove()
1283 clk_disable_unprepare(sdd->src_clk); in s3c64xx_spi_remove()
1285 clk_disable_unprepare(sdd->clk); in s3c64xx_spi_remove()
1287 pm_runtime_put_noidle(&pdev->dev); in s3c64xx_spi_remove()
1288 pm_runtime_disable(&pdev->dev); in s3c64xx_spi_remove()
1289 pm_runtime_set_suspended(&pdev->dev); in s3c64xx_spi_remove()
1308 sdd->cur_speed = 0; /* Output Clock is stopped */ in s3c64xx_spi_suspend()
1317 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_resume()
1320 if (sci->cfg_gpio) in s3c64xx_spi_resume()
1321 sci->cfg_gpio(); in s3c64xx_spi_resume()
1337 clk_disable_unprepare(sdd->clk); in s3c64xx_spi_runtime_suspend()
1338 clk_disable_unprepare(sdd->src_clk); in s3c64xx_spi_runtime_suspend()
1339 clk_disable_unprepare(sdd->ioclk); in s3c64xx_spi_runtime_suspend()
1350 if (sdd->port_conf->clk_ioclk) { in s3c64xx_spi_runtime_resume()
1351 ret = clk_prepare_enable(sdd->ioclk); in s3c64xx_spi_runtime_resume()
1356 ret = clk_prepare_enable(sdd->src_clk); in s3c64xx_spi_runtime_resume()
1360 ret = clk_prepare_enable(sdd->clk); in s3c64xx_spi_runtime_resume()
1369 clk_disable_unprepare(sdd->src_clk); in s3c64xx_spi_runtime_resume()
1371 clk_disable_unprepare(sdd->ioclk); in s3c64xx_spi_runtime_resume()
1432 .name = "s3c2443-spi",
1435 .name = "s3c6410-spi",
1442 { .compatible = "samsung,s3c2443-spi",
1445 { .compatible = "samsung,s3c6410-spi",
1448 { .compatible = "samsung,s5pv210-spi",
1451 { .compatible = "samsung,exynos4210-spi",
1454 { .compatible = "samsung,exynos7-spi",
1457 { .compatible = "samsung,exynos5433-spi",
1466 .name = "s3c64xx-spi",
1474 MODULE_ALIAS("platform:s3c64xx-spi");
1478 MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
1479 MODULE_DESCRIPTION("S3C64XX SPI Controller Driver");