Lines Matching +full:spi +full:- +full:tx +full:- +full:bus +full:- +full:width
25 #include <linux/dma-mapping.h>
27 #include <linux/spi/spi.h>
30 #include <plat/s3c64xx-spi.h>
32 /* Registers and bit-fields */
75 #define S3C64XX_SPI_ACT(c) writel(0, (c)->regs + S3C64XX_SPI_SLAVE_SEL)
78 (c)->regs + S3C64XX_SPI_SLAVE_SEL)
114 #define S3C64XX_SPI_ST_TRLCNTZ(v, i) ((((v) >> (i)->rx_lvl_offset) & \
115 (((i)->fifo_lvl_mask + 1))) \
118 #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & (1 << (i)->tx_st_done)) ? 1 : 0)
119 #define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask)
120 #define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask)
141 * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
142 * @clk: Pointer to the spi clock.
143 * @src_clk: Pointer to the clock used to generate SPI signals.
144 * @master: Pointer to the SPI Protocol master.
145 * @workqueue: Work queue for the SPI xfer requests.
149 * @queue: To log SPI xfer requests.
153 * @tx_dmach: Controller's DMA channel for Tx.
154 * @sfr_start: BUS address of SPI controller regs.
184 .name = "samsung-spi-dma",
189 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in flush_fifo()
190 void __iomem *regs = sdd->regs; in flush_fifo()
205 } while (TX_FIFO_LVL(val, sci) && loops--); in flush_fifo()
208 dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); in flush_fifo()
218 } while (loops--); in flush_fifo()
221 dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); in flush_fifo()
242 if (dma->direction == DMA_FROM_DEVICE) in s3c64xx_spi_dmacb()
249 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_dmacb()
251 if (dma->direction == DMA_FROM_DEVICE) { in s3c64xx_spi_dmacb()
252 sdd->state &= ~RXBUSY; in s3c64xx_spi_dmacb()
253 if (!(sdd->state & TXBUSY)) in s3c64xx_spi_dmacb()
254 complete(&sdd->xfer_completion); in s3c64xx_spi_dmacb()
256 sdd->state &= ~TXBUSY; in s3c64xx_spi_dmacb()
257 if (!(sdd->state & RXBUSY)) in s3c64xx_spi_dmacb()
258 complete(&sdd->xfer_completion); in s3c64xx_spi_dmacb()
261 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_dmacb()
270 if (dma->direction == DMA_FROM_DEVICE) in prepare_dma()
281 info.direction = dma->direction; in prepare_dma()
284 sdd->ops->prepare(dma->ch, &info); in prepare_dma()
285 sdd->ops->trigger(dma->ch); in prepare_dma()
292 sdd->ops = samsung_dma_get_ops(); in acquire_dma()
296 info.width = sdd->cur_bpw / 8; in acquire_dma()
298 info.direction = sdd->rx_dma.direction; in acquire_dma()
299 info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; in acquire_dma()
300 sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &info); in acquire_dma()
301 info.direction = sdd->tx_dma.direction; in acquire_dma()
302 info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; in acquire_dma()
303 sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &info); in acquire_dma()
309 struct spi_device *spi, in enable_datapath() argument
312 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in enable_datapath()
313 void __iomem *regs = sdd->regs; in enable_datapath()
325 /* Always shift in data in FIFO, even if xfer is Tx only, in enable_datapath()
330 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) in enable_datapath()
335 if (xfer->tx_buf != NULL) { in enable_datapath()
336 sdd->state |= TXBUSY; in enable_datapath()
340 prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma); in enable_datapath()
342 switch (sdd->cur_bpw) { in enable_datapath()
345 xfer->tx_buf, xfer->len / 4); in enable_datapath()
349 xfer->tx_buf, xfer->len / 2); in enable_datapath()
353 xfer->tx_buf, xfer->len); in enable_datapath()
359 if (xfer->rx_buf != NULL) { in enable_datapath()
360 sdd->state |= RXBUSY; in enable_datapath()
362 if (sci->high_speed && sdd->cur_speed >= 30000000UL in enable_datapath()
363 && !(sdd->cur_mode & SPI_CPHA)) in enable_datapath()
369 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) in enable_datapath()
372 prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma); in enable_datapath()
381 struct spi_device *spi) in enable_cs() argument
385 if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */ in enable_cs()
386 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ in enable_cs()
388 cs = sdd->tgl_spi->controller_data; in enable_cs()
389 cs->set_level(cs->line, in enable_cs()
390 spi->mode & SPI_CS_HIGH ? 0 : 1); in enable_cs()
392 sdd->tgl_spi = NULL; in enable_cs()
395 cs = spi->controller_data; in enable_cs()
396 cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); in enable_cs()
402 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in wait_for_xfer()
403 void __iomem *regs = sdd->regs; in wait_for_xfer()
408 ms = xfer->len * 8 * 1000 / sdd->cur_speed; in wait_for_xfer()
413 val = wait_for_completion_timeout(&sdd->xfer_completion, val); in wait_for_xfer()
419 } while (RX_FIFO_LVL(status, sci) < xfer->len && --val); in wait_for_xfer()
423 return -EIO; in wait_for_xfer()
430 * w/o waiting for real transmission on the bus to finish. in wait_for_xfer()
432 * needs bus transmission to finish, so we don't worry if in wait_for_xfer()
433 * Xfer involved Rx(with or without Tx). in wait_for_xfer()
435 if (xfer->rx_buf == NULL) { in wait_for_xfer()
440 && --val) { in wait_for_xfer()
446 return -EIO; in wait_for_xfer()
449 /* If it was only Tx */ in wait_for_xfer()
450 if (xfer->rx_buf == NULL) { in wait_for_xfer()
451 sdd->state &= ~TXBUSY; in wait_for_xfer()
455 switch (sdd->cur_bpw) { in wait_for_xfer()
458 xfer->rx_buf, xfer->len / 4); in wait_for_xfer()
462 xfer->rx_buf, xfer->len / 2); in wait_for_xfer()
466 xfer->rx_buf, xfer->len); in wait_for_xfer()
469 sdd->state &= ~RXBUSY; in wait_for_xfer()
476 struct spi_device *spi) in disable_cs() argument
478 struct s3c64xx_spi_csinfo *cs = spi->controller_data; in disable_cs()
480 if (sdd->tgl_spi == spi) in disable_cs()
481 sdd->tgl_spi = NULL; in disable_cs()
483 cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); in disable_cs()
488 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_config()
489 void __iomem *regs = sdd->regs; in s3c64xx_spi_config()
493 if (sci->clk_from_cmu) { in s3c64xx_spi_config()
494 clk_disable(sdd->src_clk); in s3c64xx_spi_config()
507 if (sdd->cur_mode & SPI_CPOL) in s3c64xx_spi_config()
510 if (sdd->cur_mode & SPI_CPHA) in s3c64xx_spi_config()
520 switch (sdd->cur_bpw) { in s3c64xx_spi_config()
537 if (sci->clk_from_cmu) { in s3c64xx_spi_config()
539 /* There is half-multiplier before the SPI */ in s3c64xx_spi_config()
540 clk_set_rate(sdd->src_clk, sdd->cur_speed * 2); in s3c64xx_spi_config()
542 clk_enable(sdd->src_clk); in s3c64xx_spi_config()
547 val |= ((clk_get_rate(sdd->src_clk) / sdd->cur_speed / 2 - 1) in s3c64xx_spi_config()
563 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_map_mssg()
564 struct device *dev = &sdd->pdev->dev; in s3c64xx_spi_map_mssg()
567 if (msg->is_dma_mapped) in s3c64xx_spi_map_mssg()
571 list_for_each_entry(xfer, &msg->transfers, transfer_list) { in s3c64xx_spi_map_mssg()
572 xfer->rx_dma = XFER_DMAADDR_INVALID; in s3c64xx_spi_map_mssg()
573 xfer->tx_dma = XFER_DMAADDR_INVALID; in s3c64xx_spi_map_mssg()
577 list_for_each_entry(xfer, &msg->transfers, transfer_list) { in s3c64xx_spi_map_mssg()
579 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) in s3c64xx_spi_map_mssg()
582 if (xfer->tx_buf != NULL) { in s3c64xx_spi_map_mssg()
583 xfer->tx_dma = dma_map_single(dev, in s3c64xx_spi_map_mssg()
584 (void *)xfer->tx_buf, xfer->len, in s3c64xx_spi_map_mssg()
586 if (dma_mapping_error(dev, xfer->tx_dma)) { in s3c64xx_spi_map_mssg()
587 dev_err(dev, "dma_map_single Tx failed\n"); in s3c64xx_spi_map_mssg()
588 xfer->tx_dma = XFER_DMAADDR_INVALID; in s3c64xx_spi_map_mssg()
589 return -ENOMEM; in s3c64xx_spi_map_mssg()
593 if (xfer->rx_buf != NULL) { in s3c64xx_spi_map_mssg()
594 xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, in s3c64xx_spi_map_mssg()
595 xfer->len, DMA_FROM_DEVICE); in s3c64xx_spi_map_mssg()
596 if (dma_mapping_error(dev, xfer->rx_dma)) { in s3c64xx_spi_map_mssg()
598 dma_unmap_single(dev, xfer->tx_dma, in s3c64xx_spi_map_mssg()
599 xfer->len, DMA_TO_DEVICE); in s3c64xx_spi_map_mssg()
600 xfer->tx_dma = XFER_DMAADDR_INVALID; in s3c64xx_spi_map_mssg()
601 xfer->rx_dma = XFER_DMAADDR_INVALID; in s3c64xx_spi_map_mssg()
602 return -ENOMEM; in s3c64xx_spi_map_mssg()
613 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_unmap_mssg()
614 struct device *dev = &sdd->pdev->dev; in s3c64xx_spi_unmap_mssg()
617 if (msg->is_dma_mapped) in s3c64xx_spi_unmap_mssg()
620 list_for_each_entry(xfer, &msg->transfers, transfer_list) { in s3c64xx_spi_unmap_mssg()
622 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) in s3c64xx_spi_unmap_mssg()
625 if (xfer->rx_buf != NULL in s3c64xx_spi_unmap_mssg()
626 && xfer->rx_dma != XFER_DMAADDR_INVALID) in s3c64xx_spi_unmap_mssg()
627 dma_unmap_single(dev, xfer->rx_dma, in s3c64xx_spi_unmap_mssg()
628 xfer->len, DMA_FROM_DEVICE); in s3c64xx_spi_unmap_mssg()
630 if (xfer->tx_buf != NULL in s3c64xx_spi_unmap_mssg()
631 && xfer->tx_dma != XFER_DMAADDR_INVALID) in s3c64xx_spi_unmap_mssg()
632 dma_unmap_single(dev, xfer->tx_dma, in s3c64xx_spi_unmap_mssg()
633 xfer->len, DMA_TO_DEVICE); in s3c64xx_spi_unmap_mssg()
640 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in handle_msg()
641 struct spi_device *spi = msg->spi; in handle_msg() local
642 struct s3c64xx_spi_csinfo *cs = spi->controller_data; in handle_msg()
649 if (sdd->cur_speed != spi->max_speed_hz in handle_msg()
650 || sdd->cur_mode != spi->mode in handle_msg()
651 || sdd->cur_bpw != spi->bits_per_word) { in handle_msg()
652 sdd->cur_bpw = spi->bits_per_word; in handle_msg()
653 sdd->cur_speed = spi->max_speed_hz; in handle_msg()
654 sdd->cur_mode = spi->mode; in handle_msg()
660 dev_err(&spi->dev, in handle_msg()
662 status = -ENOMEM; in handle_msg()
667 writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); in handle_msg()
669 list_for_each_entry(xfer, &msg->transfers, transfer_list) { in handle_msg()
674 INIT_COMPLETION(sdd->xfer_completion); in handle_msg()
677 bpw = xfer->bits_per_word ? : spi->bits_per_word; in handle_msg()
678 speed = xfer->speed_hz ? : spi->max_speed_hz; in handle_msg()
680 if (xfer->len % (bpw / 8)) { in handle_msg()
681 dev_err(&spi->dev, in handle_msg()
683 xfer->len, bpw / 8); in handle_msg()
684 status = -EIO; in handle_msg()
688 if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { in handle_msg()
689 sdd->cur_bpw = bpw; in handle_msg()
690 sdd->cur_speed = speed; in handle_msg()
695 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) in handle_msg()
700 spin_lock_irqsave(&sdd->lock, flags); in handle_msg()
703 sdd->state &= ~RXBUSY; in handle_msg()
704 sdd->state &= ~TXBUSY; in handle_msg()
706 enable_datapath(sdd, spi, xfer, use_dma); in handle_msg()
709 enable_cs(sdd, spi); in handle_msg()
714 spin_unlock_irqrestore(&sdd->lock, flags); in handle_msg()
722 dev_err(&spi->dev, "I/O Error: " in handle_msg()
723 "rx-%d tx-%d res:rx-%c tx-%c len-%d\n", in handle_msg()
724 xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, in handle_msg()
725 (sdd->state & RXBUSY) ? 'f' : 'p', in handle_msg()
726 (sdd->state & TXBUSY) ? 'f' : 'p', in handle_msg()
727 xfer->len); in handle_msg()
730 if (xfer->tx_buf != NULL in handle_msg()
731 && (sdd->state & TXBUSY)) in handle_msg()
732 sdd->ops->stop(sdd->tx_dma.ch); in handle_msg()
733 if (xfer->rx_buf != NULL in handle_msg()
734 && (sdd->state & RXBUSY)) in handle_msg()
735 sdd->ops->stop(sdd->rx_dma.ch); in handle_msg()
741 if (xfer->delay_usecs) in handle_msg()
742 udelay(xfer->delay_usecs); in handle_msg()
744 if (xfer->cs_change) { in handle_msg()
747 if (list_is_last(&xfer->transfer_list, in handle_msg()
748 &msg->transfers)) in handle_msg()
751 disable_cs(sdd, spi); in handle_msg()
754 msg->actual_length += xfer->len; in handle_msg()
761 disable_cs(sdd, spi); in handle_msg()
763 sdd->tgl_spi = spi; in handle_msg()
767 msg->status = status; in handle_msg()
769 if (msg->complete) in handle_msg()
770 msg->complete(msg->context); in handle_msg()
783 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_work()
785 while (!list_empty(&sdd->queue) in s3c64xx_spi_work()
786 && !(sdd->state & SUSPND)) { in s3c64xx_spi_work()
790 msg = container_of(sdd->queue.next, struct spi_message, queue); in s3c64xx_spi_work()
792 list_del_init(&msg->queue); in s3c64xx_spi_work()
795 sdd->state |= SPIBUSY; in s3c64xx_spi_work()
797 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_work()
801 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_work()
803 sdd->state &= ~SPIBUSY; in s3c64xx_spi_work()
806 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_work()
809 sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client); in s3c64xx_spi_work()
810 sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client); in s3c64xx_spi_work()
813 static int s3c64xx_spi_transfer(struct spi_device *spi, in s3c64xx_spi_transfer() argument
819 sdd = spi_master_get_devdata(spi->master); in s3c64xx_spi_transfer()
821 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_transfer()
823 if (sdd->state & SUSPND) { in s3c64xx_spi_transfer()
824 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_transfer()
825 return -ESHUTDOWN; in s3c64xx_spi_transfer()
828 msg->status = -EINPROGRESS; in s3c64xx_spi_transfer()
829 msg->actual_length = 0; in s3c64xx_spi_transfer()
831 list_add_tail(&msg->queue, &sdd->queue); in s3c64xx_spi_transfer()
833 queue_work(sdd->workqueue, &sdd->work); in s3c64xx_spi_transfer()
835 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_transfer()
842 * and save the configuration in a local data-structure.
846 static int s3c64xx_spi_setup(struct spi_device *spi) in s3c64xx_spi_setup() argument
848 struct s3c64xx_spi_csinfo *cs = spi->controller_data; in s3c64xx_spi_setup()
855 if (cs == NULL || cs->set_level == NULL) { in s3c64xx_spi_setup()
856 dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select); in s3c64xx_spi_setup()
857 return -ENODEV; in s3c64xx_spi_setup()
860 sdd = spi_master_get_devdata(spi->master); in s3c64xx_spi_setup()
861 sci = sdd->cntrlr_info; in s3c64xx_spi_setup()
863 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_setup()
865 list_for_each_entry(msg, &sdd->queue, queue) { in s3c64xx_spi_setup()
867 if (msg->spi == spi) { in s3c64xx_spi_setup()
868 dev_err(&spi->dev, in s3c64xx_spi_setup()
870 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_setup()
871 return -EBUSY; in s3c64xx_spi_setup()
875 if (sdd->state & SUSPND) { in s3c64xx_spi_setup()
876 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_setup()
877 dev_err(&spi->dev, in s3c64xx_spi_setup()
878 "setup: SPI-%d not active!\n", spi->master->bus_num); in s3c64xx_spi_setup()
879 return -ESHUTDOWN; in s3c64xx_spi_setup()
882 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_setup()
884 if (spi->bits_per_word != 8 in s3c64xx_spi_setup()
885 && spi->bits_per_word != 16 in s3c64xx_spi_setup()
886 && spi->bits_per_word != 32) { in s3c64xx_spi_setup()
887 dev_err(&spi->dev, "setup: %dbits/wrd not supported!\n", in s3c64xx_spi_setup()
888 spi->bits_per_word); in s3c64xx_spi_setup()
889 err = -EINVAL; in s3c64xx_spi_setup()
894 if (!sci->clk_from_cmu) { in s3c64xx_spi_setup()
898 speed = clk_get_rate(sdd->src_clk) / 2 / (0 + 1); in s3c64xx_spi_setup()
900 if (spi->max_speed_hz > speed) in s3c64xx_spi_setup()
901 spi->max_speed_hz = speed; in s3c64xx_spi_setup()
903 psr = clk_get_rate(sdd->src_clk) / 2 / spi->max_speed_hz - 1; in s3c64xx_spi_setup()
906 psr--; in s3c64xx_spi_setup()
908 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1); in s3c64xx_spi_setup()
909 if (spi->max_speed_hz < speed) { in s3c64xx_spi_setup()
913 err = -EINVAL; in s3c64xx_spi_setup()
918 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1); in s3c64xx_spi_setup()
919 if (spi->max_speed_hz >= speed) in s3c64xx_spi_setup()
920 spi->max_speed_hz = speed; in s3c64xx_spi_setup()
922 err = -EINVAL; in s3c64xx_spi_setup()
927 /* setup() returns with device de-selected */ in s3c64xx_spi_setup()
928 disable_cs(sdd, spi); in s3c64xx_spi_setup()
935 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_hwinit()
936 void __iomem *regs = sdd->regs; in s3c64xx_spi_hwinit()
939 sdd->cur_speed = 0; in s3c64xx_spi_hwinit()
943 /* Disable Interrupts - we use Polling if not DMA mode */ in s3c64xx_spi_hwinit()
946 if (!sci->clk_from_cmu) in s3c64xx_spi_hwinit()
947 writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT, in s3c64xx_spi_hwinit()
976 if (pdev->id < 0) { in s3c64xx_spi_probe()
977 dev_err(&pdev->dev, in s3c64xx_spi_probe()
978 "Invalid platform device id-%d\n", pdev->id); in s3c64xx_spi_probe()
979 return -ENODEV; in s3c64xx_spi_probe()
982 if (pdev->dev.platform_data == NULL) { in s3c64xx_spi_probe()
983 dev_err(&pdev->dev, "platform_data missing!\n"); in s3c64xx_spi_probe()
984 return -ENODEV; in s3c64xx_spi_probe()
987 sci = pdev->dev.platform_data; in s3c64xx_spi_probe()
993 dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n"); in s3c64xx_spi_probe()
994 return -ENXIO; in s3c64xx_spi_probe()
999 dev_err(&pdev->dev, "Unable to get SPI-Rx dma resource\n"); in s3c64xx_spi_probe()
1000 return -ENXIO; in s3c64xx_spi_probe()
1005 dev_err(&pdev->dev, "Unable to get SPI MEM resource\n"); in s3c64xx_spi_probe()
1006 return -ENXIO; in s3c64xx_spi_probe()
1009 master = spi_alloc_master(&pdev->dev, in s3c64xx_spi_probe()
1012 dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); in s3c64xx_spi_probe()
1013 return -ENOMEM; in s3c64xx_spi_probe()
1019 sdd->master = master; in s3c64xx_spi_probe()
1020 sdd->cntrlr_info = sci; in s3c64xx_spi_probe()
1021 sdd->pdev = pdev; in s3c64xx_spi_probe()
1022 sdd->sfr_start = mem_res->start; in s3c64xx_spi_probe()
1023 sdd->tx_dma.dmach = dmatx_res->start; in s3c64xx_spi_probe()
1024 sdd->tx_dma.direction = DMA_TO_DEVICE; in s3c64xx_spi_probe()
1025 sdd->rx_dma.dmach = dmarx_res->start; in s3c64xx_spi_probe()
1026 sdd->rx_dma.direction = DMA_FROM_DEVICE; in s3c64xx_spi_probe()
1028 sdd->cur_bpw = 8; in s3c64xx_spi_probe()
1030 master->bus_num = pdev->id; in s3c64xx_spi_probe()
1031 master->setup = s3c64xx_spi_setup; in s3c64xx_spi_probe()
1032 master->transfer = s3c64xx_spi_transfer; in s3c64xx_spi_probe()
1033 master->num_chipselect = sci->num_cs; in s3c64xx_spi_probe()
1034 master->dma_alignment = 8; in s3c64xx_spi_probe()
1035 /* the spi->mode bits understood by this driver: */ in s3c64xx_spi_probe()
1036 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; in s3c64xx_spi_probe()
1038 if (request_mem_region(mem_res->start, in s3c64xx_spi_probe()
1039 resource_size(mem_res), pdev->name) == NULL) { in s3c64xx_spi_probe()
1040 dev_err(&pdev->dev, "Req mem region failed\n"); in s3c64xx_spi_probe()
1041 ret = -ENXIO; in s3c64xx_spi_probe()
1045 sdd->regs = ioremap(mem_res->start, resource_size(mem_res)); in s3c64xx_spi_probe()
1046 if (sdd->regs == NULL) { in s3c64xx_spi_probe()
1047 dev_err(&pdev->dev, "Unable to remap IO\n"); in s3c64xx_spi_probe()
1048 ret = -ENXIO; in s3c64xx_spi_probe()
1052 if (sci->cfg_gpio == NULL || sci->cfg_gpio(pdev)) { in s3c64xx_spi_probe()
1053 dev_err(&pdev->dev, "Unable to config gpio\n"); in s3c64xx_spi_probe()
1054 ret = -EBUSY; in s3c64xx_spi_probe()
1059 sdd->clk = clk_get(&pdev->dev, "spi"); in s3c64xx_spi_probe()
1060 if (IS_ERR(sdd->clk)) { in s3c64xx_spi_probe()
1061 dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n"); in s3c64xx_spi_probe()
1062 ret = PTR_ERR(sdd->clk); in s3c64xx_spi_probe()
1066 if (clk_enable(sdd->clk)) { in s3c64xx_spi_probe()
1067 dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n"); in s3c64xx_spi_probe()
1068 ret = -EBUSY; in s3c64xx_spi_probe()
1072 sprintf(clk_name, "spi_busclk%d", sci->src_clk_nr); in s3c64xx_spi_probe()
1073 sdd->src_clk = clk_get(&pdev->dev, clk_name); in s3c64xx_spi_probe()
1074 if (IS_ERR(sdd->src_clk)) { in s3c64xx_spi_probe()
1075 dev_err(&pdev->dev, in s3c64xx_spi_probe()
1077 ret = PTR_ERR(sdd->src_clk); in s3c64xx_spi_probe()
1081 if (clk_enable(sdd->src_clk)) { in s3c64xx_spi_probe()
1082 dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", clk_name); in s3c64xx_spi_probe()
1083 ret = -EBUSY; in s3c64xx_spi_probe()
1087 sdd->workqueue = create_singlethread_workqueue( in s3c64xx_spi_probe()
1088 dev_name(master->dev.parent)); in s3c64xx_spi_probe()
1089 if (sdd->workqueue == NULL) { in s3c64xx_spi_probe()
1090 dev_err(&pdev->dev, "Unable to create workqueue\n"); in s3c64xx_spi_probe()
1091 ret = -ENOMEM; in s3c64xx_spi_probe()
1096 s3c64xx_spi_hwinit(sdd, pdev->id); in s3c64xx_spi_probe()
1098 spin_lock_init(&sdd->lock); in s3c64xx_spi_probe()
1099 init_completion(&sdd->xfer_completion); in s3c64xx_spi_probe()
1100 INIT_WORK(&sdd->work, s3c64xx_spi_work); in s3c64xx_spi_probe()
1101 INIT_LIST_HEAD(&sdd->queue); in s3c64xx_spi_probe()
1104 dev_err(&pdev->dev, "cannot register SPI master\n"); in s3c64xx_spi_probe()
1105 ret = -EBUSY; in s3c64xx_spi_probe()
1109 dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d " in s3c64xx_spi_probe()
1111 pdev->id, master->num_chipselect); in s3c64xx_spi_probe()
1112 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", in s3c64xx_spi_probe()
1113 mem_res->end, mem_res->start, in s3c64xx_spi_probe()
1114 sdd->rx_dma.dmach, sdd->tx_dma.dmach); in s3c64xx_spi_probe()
1119 destroy_workqueue(sdd->workqueue); in s3c64xx_spi_probe()
1121 clk_disable(sdd->src_clk); in s3c64xx_spi_probe()
1123 clk_put(sdd->src_clk); in s3c64xx_spi_probe()
1125 clk_disable(sdd->clk); in s3c64xx_spi_probe()
1127 clk_put(sdd->clk); in s3c64xx_spi_probe()
1130 iounmap((void *) sdd->regs); in s3c64xx_spi_probe()
1132 release_mem_region(mem_res->start, resource_size(mem_res)); in s3c64xx_spi_probe()
1147 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_remove()
1148 sdd->state |= SUSPND; in s3c64xx_spi_remove()
1149 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_remove()
1151 while (sdd->state & SPIBUSY) in s3c64xx_spi_remove()
1156 destroy_workqueue(sdd->workqueue); in s3c64xx_spi_remove()
1158 clk_disable(sdd->src_clk); in s3c64xx_spi_remove()
1159 clk_put(sdd->src_clk); in s3c64xx_spi_remove()
1161 clk_disable(sdd->clk); in s3c64xx_spi_remove()
1162 clk_put(sdd->clk); in s3c64xx_spi_remove()
1164 iounmap((void *) sdd->regs); in s3c64xx_spi_remove()
1168 release_mem_region(mem_res->start, resource_size(mem_res)); in s3c64xx_spi_remove()
1183 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_suspend()
1184 sdd->state |= SUSPND; in s3c64xx_spi_suspend()
1185 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_suspend()
1187 while (sdd->state & SPIBUSY) in s3c64xx_spi_suspend()
1191 clk_disable(sdd->src_clk); in s3c64xx_spi_suspend()
1192 clk_disable(sdd->clk); in s3c64xx_spi_suspend()
1194 sdd->cur_speed = 0; /* Output Clock is stopped */ in s3c64xx_spi_suspend()
1203 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_resume()
1206 sci->cfg_gpio(pdev); in s3c64xx_spi_resume()
1209 clk_enable(sdd->src_clk); in s3c64xx_spi_resume()
1210 clk_enable(sdd->clk); in s3c64xx_spi_resume()
1212 s3c64xx_spi_hwinit(sdd, pdev->id); in s3c64xx_spi_resume()
1214 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_resume()
1215 sdd->state &= ~SUSPND; in s3c64xx_spi_resume()
1216 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_resume()
1227 .name = "s3c64xx-spi",
1234 MODULE_ALIAS("platform:s3c64xx-spi");
1249 MODULE_DESCRIPTION("S3C64XX SPI Controller Driver");