Lines Matching +full:mode +full:- +full:flag
2 * Copyright (C) 2011-2015 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
3 * Copyright (C) 2016 Hauke Mehrtens <hauke@hauke-m.de>
59 #define LTQ_SPI_CLC_SMC_S 16 /* Clock divider for sleep mode */
61 #define LTQ_SPI_CLC_RMC_S 8 /* Clock divider for normal run mode */
78 #define LTQ_SPI_CON_EM BIT(24) /* Echo mode */
95 #define LTQ_SPI_STAT_BSY BIT(13) /* Busy flag */
96 #define LTQ_SPI_STAT_RUE BIT(12) /* Receive underflow error flag */
97 #define LTQ_SPI_STAT_TUE BIT(11) /* Transmit underflow error flag */
98 #define LTQ_SPI_STAT_AE BIT(10) /* Abort error flag */
99 #define LTQ_SPI_STAT_RE BIT(9) /* Receive error flag */
100 #define LTQ_SPI_STAT_TE BIT(8) /* Transmit error flag */
101 #define LTQ_SPI_STAT_ME BIT(7) /* Mode error flag */
108 #define LTQ_SPI_WHBSTATE_SETTUE BIT(15) /* Set transmit underflow error flag */
109 #define LTQ_SPI_WHBSTATE_SETAE BIT(14) /* Set abort error flag */
110 #define LTQ_SPI_WHBSTATE_SETRE BIT(13) /* Set receive error flag */
111 #define LTQ_SPI_WHBSTATE_SETTE BIT(12) /* Set transmit error flag */
112 #define LTQ_SPI_WHBSTATE_CLRTUE BIT(11) /* Clear transmit underflow error flag */
113 #define LTQ_SPI_WHBSTATE_CLRAE BIT(10) /* Clear abort error flag */
114 #define LTQ_SPI_WHBSTATE_CLRRE BIT(9) /* Clear receive error flag */
115 #define LTQ_SPI_WHBSTATE_CLRTE BIT(8) /* Clear transmit error flag */
116 #define LTQ_SPI_WHBSTATE_SETME BIT(7) /* Set mode error flag */
117 #define LTQ_SPI_WHBSTATE_CLRME BIT(6) /* Clear mode error flag */
118 #define LTQ_SPI_WHBSTATE_SETRUE BIT(5) /* Set receive underflow error flag */
119 #define LTQ_SPI_WHBSTATE_CLRRUE BIT(4) /* Clear receive underflow error flag */
122 #define LTQ_SPI_WHBSTATE_SETEN BIT(1) /* Set enable bit (operational mode) */
123 #define LTQ_SPI_WHBSTATE_CLREN BIT(0) /* Clear enable bit (config mode */
153 #define LTQ_SPI_RXCNT_TODO_M 0xFFFF /* Recevie to-do value */
195 return __raw_readl(spi->regbase + reg); in lantiq_ssc_readl()
201 __raw_writel(val, spi->regbase + reg); in lantiq_ssc_writel()
207 u32 val = __raw_readl(spi->regbase + reg); in lantiq_ssc_maskl()
211 __raw_writel(val, spi->regbase + reg); in lantiq_ssc_maskl()
230 return spi->tx_fifo_size - tx_fifo_level(spi); in tx_fifo_free()
235 u32 val = spi->rx_fifo_size << LTQ_SPI_RXFCON_RXFITL_S; in rx_fifo_reset()
279 * baudrate = -------------- in hw_setup_speed_hz()
282 spi_clk = clk_get_rate(spi->fpi_clk) / 2; in hw_setup_speed_hz()
287 brt = spi_clk / max_speed_hz - 1; in hw_setup_speed_hz()
292 dev_dbg(spi->dev, "spi_clk %u, max_speed_hz %u, brt %u\n", in hw_setup_speed_hz()
303 /* CON.BM value = bits_per_word - 1 */ in hw_setup_bits_per_word()
304 bm = (bits_per_word - 1) << LTQ_SPI_CON_BM_S; in hw_setup_bits_per_word()
310 unsigned int mode) in hw_setup_clock_mode() argument
315 * SPI mode mapping in CON register: in hw_setup_clock_mode()
316 * Mode CPOL CPHA CON.PO CON.PH in hw_setup_clock_mode()
322 if (mode & SPI_CPHA) in hw_setup_clock_mode()
327 if (mode & SPI_CPOL) in hw_setup_clock_mode()
333 if (mode & SPI_LSB_FIRST) in hw_setup_clock_mode()
338 /* Set loopback mode */ in hw_setup_clock_mode()
339 if (mode & SPI_LOOP) in hw_setup_clock_mode()
349 const struct lantiq_ssc_hwcfg *hwcfg = spi->hwcfg; in lantiq_ssc_hw_init()
352 * Set clock divider for run mode to 1 to in lantiq_ssc_hw_init()
357 /* Put controller into config mode */ in lantiq_ssc_hw_init()
368 /* Setup default SPI mode */ in lantiq_ssc_hw_init()
369 hw_setup_bits_per_word(spi, spi->bits_per_word); in lantiq_ssc_hw_init()
372 /* Enable master mode and clear error flags */ in lantiq_ssc_hw_init()
386 lantiq_ssc_writel(spi, hwcfg->irnen_t | hwcfg->irnen_r | in lantiq_ssc_hw_init()
392 struct spi_master *master = spidev->master; in lantiq_ssc_setup()
394 unsigned int cs = spidev->chip_select; in lantiq_ssc_setup()
398 if (gpio_is_valid(spidev->cs_gpio)) in lantiq_ssc_setup()
401 dev_dbg(spi->dev, "using internal chipselect %u\n", cs); in lantiq_ssc_setup()
403 if (cs < spi->base_cs) { in lantiq_ssc_setup()
404 dev_err(spi->dev, in lantiq_ssc_setup()
405 "chipselect %i too small (min %i)\n", cs, spi->base_cs); in lantiq_ssc_setup()
406 return -EINVAL; in lantiq_ssc_setup()
409 /* set GPO pin to CS mode */ in lantiq_ssc_setup()
410 gpocon = 1 << ((cs - spi->base_cs) + LTQ_SPI_GPOCON_ISCSBN_S); in lantiq_ssc_setup()
413 if (spidev->mode & SPI_CS_HIGH) in lantiq_ssc_setup()
414 gpocon |= 1 << (cs - spi->base_cs); in lantiq_ssc_setup()
427 hw_setup_clock_mode(spi, message->spi->mode); in lantiq_ssc_prepare_message()
436 unsigned int speed_hz = t->speed_hz; in hw_setup_transfer()
437 unsigned int bits_per_word = t->bits_per_word; in hw_setup_transfer()
440 if (bits_per_word != spi->bits_per_word || in hw_setup_transfer()
441 speed_hz != spi->speed_hz) { in hw_setup_transfer()
447 spi->speed_hz = speed_hz; in hw_setup_transfer()
448 spi->bits_per_word = bits_per_word; in hw_setup_transfer()
453 if (t->tx_buf) in hw_setup_transfer()
458 if (t->rx_buf) in hw_setup_transfer()
471 flush_workqueue(spi->wq); in lantiq_ssc_unprepare_message()
488 spi->fdx_tx_level = 0; in tx_fifo_write()
489 while (spi->tx_todo && tx_free) { in tx_fifo_write()
490 switch (spi->bits_per_word) { in tx_fifo_write()
492 tx8 = spi->tx; in tx_fifo_write()
494 spi->tx_todo--; in tx_fifo_write()
495 spi->tx++; in tx_fifo_write()
498 tx16 = (u16 *) spi->tx; in tx_fifo_write()
500 spi->tx_todo -= 2; in tx_fifo_write()
501 spi->tx += 2; in tx_fifo_write()
504 tx32 = (u32 *) spi->tx; in tx_fifo_write()
506 spi->tx_todo -= 4; in tx_fifo_write()
507 spi->tx += 4; in tx_fifo_write()
516 tx_free--; in tx_fifo_write()
517 spi->fdx_tx_level++; in tx_fifo_write()
533 while (rx_fill != spi->fdx_tx_level) in rx_fifo_read_full_duplex()
539 switch (spi->bits_per_word) { in rx_fifo_read_full_duplex()
541 rx8 = spi->rx; in rx_fifo_read_full_duplex()
543 spi->rx_todo--; in rx_fifo_read_full_duplex()
544 spi->rx++; in rx_fifo_read_full_duplex()
547 rx16 = (u16 *) spi->rx; in rx_fifo_read_full_duplex()
549 spi->rx_todo -= 2; in rx_fifo_read_full_duplex()
550 spi->rx += 2; in rx_fifo_read_full_duplex()
553 rx32 = (u32 *) spi->rx; in rx_fifo_read_full_duplex()
555 spi->rx_todo -= 4; in rx_fifo_read_full_duplex()
556 spi->rx += 4; in rx_fifo_read_full_duplex()
563 rx_fill--; in rx_fifo_read_full_duplex()
575 * In RX-only mode the bits per word value is ignored by HW. A value in rx_fifo_read_half_duplex()
582 if (spi->rx_todo < 4) { in rx_fifo_read_half_duplex()
587 shift = (rxbv - 1) * 8; in rx_fifo_read_half_duplex()
588 rx8 = spi->rx; in rx_fifo_read_half_duplex()
592 rxbv--; in rx_fifo_read_half_duplex()
593 shift -= 8; in rx_fifo_read_half_duplex()
594 spi->rx_todo--; in rx_fifo_read_half_duplex()
595 spi->rx++; in rx_fifo_read_half_duplex()
599 rx32 = (u32 *) spi->rx; in rx_fifo_read_half_duplex()
602 spi->rx_todo -= 4; in rx_fifo_read_half_duplex()
603 spi->rx += 4; in rx_fifo_read_half_duplex()
605 rx_fill--; in rx_fifo_read_half_duplex()
618 rxreq = spi->rx_todo; in rx_request()
619 rxreq_max = spi->rx_fifo_size * 4; in rx_request()
630 if (spi->tx) { in lantiq_ssc_xmit_interrupt()
631 if (spi->rx && spi->rx_todo) in lantiq_ssc_xmit_interrupt()
634 if (spi->tx_todo) in lantiq_ssc_xmit_interrupt()
638 } else if (spi->rx) { in lantiq_ssc_xmit_interrupt()
639 if (spi->rx_todo) { in lantiq_ssc_xmit_interrupt()
642 if (spi->rx_todo) in lantiq_ssc_xmit_interrupt()
654 queue_work(spi->wq, &spi->work); in lantiq_ssc_xmit_interrupt()
668 dev_err(spi->dev, "receive underflow error\n"); in lantiq_ssc_err_interrupt()
670 dev_err(spi->dev, "transmit underflow error\n"); in lantiq_ssc_err_interrupt()
672 dev_err(spi->dev, "abort error\n"); in lantiq_ssc_err_interrupt()
674 dev_err(spi->dev, "receive overflow error\n"); in lantiq_ssc_err_interrupt()
676 dev_err(spi->dev, "transmit overflow error\n"); in lantiq_ssc_err_interrupt()
678 dev_err(spi->dev, "mode error\n"); in lantiq_ssc_err_interrupt()
684 if (spi->master->cur_msg) in lantiq_ssc_err_interrupt()
685 spi->master->cur_msg->status = -EIO; in lantiq_ssc_err_interrupt()
686 queue_work(spi->wq, &spi->work); in lantiq_ssc_err_interrupt()
696 spin_lock_irqsave(&spi->lock, flags); in transfer_start()
698 spi->tx = t->tx_buf; in transfer_start()
699 spi->rx = t->rx_buf; in transfer_start()
701 if (t->tx_buf) { in transfer_start()
702 spi->tx_todo = t->len; in transfer_start()
708 if (spi->rx) { in transfer_start()
709 spi->rx_todo = t->len; in transfer_start()
711 /* start shift clock in RX-only mode */ in transfer_start()
712 if (!spi->tx) in transfer_start()
716 spin_unlock_irqrestore(&spi->lock, flags); in transfer_start()
718 return t->len; in transfer_start()
736 do_div(timeout, spi->speed_hz); in lantiq_ssc_bussy_work()
744 spi_finalize_current_transfer(spi->master); in lantiq_ssc_bussy_work()
751 if (spi->master->cur_msg) in lantiq_ssc_bussy_work()
752 spi->master->cur_msg->status = -EIO; in lantiq_ssc_bussy_work()
753 spi_finalize_current_transfer(spi->master); in lantiq_ssc_bussy_work()
768 struct lantiq_ssc_spi *spi = spi_master_get_devdata(spidev->master); in lantiq_ssc_set_cs()
769 unsigned int cs = spidev->chip_select; in lantiq_ssc_set_cs()
772 if (!!(spidev->mode & SPI_CS_HIGH) == enable) in lantiq_ssc_set_cs()
773 fgpo = (1 << (cs - spi->base_cs)); in lantiq_ssc_set_cs()
775 fgpo = (1 << (cs - spi->base_cs + LTQ_SPI_FGPO_SETOUTN_S)); in lantiq_ssc_set_cs()
802 { .compatible = "lantiq,ase-spi", .data = &lantiq_ssc_xway, },
803 { .compatible = "lantiq,falcon-spi", .data = &lantiq_ssc_xrx, },
804 { .compatible = "lantiq,xrx100-spi", .data = &lantiq_ssc_xrx, },
811 struct device *dev = &pdev->dev; in lantiq_ssc_probe()
824 return -EINVAL; in lantiq_ssc_probe()
826 hwcfg = match->data; in lantiq_ssc_probe()
831 return -ENXIO; in lantiq_ssc_probe()
837 return -ENXIO; in lantiq_ssc_probe()
843 return -ENXIO; in lantiq_ssc_probe()
849 return -ENXIO; in lantiq_ssc_probe()
854 return -ENOMEM; in lantiq_ssc_probe()
857 spi->master = master; in lantiq_ssc_probe()
858 spi->dev = dev; in lantiq_ssc_probe()
859 spi->hwcfg = hwcfg; in lantiq_ssc_probe()
862 spi->regbase = devm_ioremap_resource(dev, res); in lantiq_ssc_probe()
863 if (IS_ERR(spi->regbase)) { in lantiq_ssc_probe()
864 err = PTR_ERR(spi->regbase); in lantiq_ssc_probe()
883 spi->spi_clk = devm_clk_get(dev, "gate"); in lantiq_ssc_probe()
884 if (IS_ERR(spi->spi_clk)) { in lantiq_ssc_probe()
885 err = PTR_ERR(spi->spi_clk); in lantiq_ssc_probe()
888 err = clk_prepare_enable(spi->spi_clk); in lantiq_ssc_probe()
897 spi->fpi_clk = clk_get_fpi(); in lantiq_ssc_probe()
899 spi->fpi_clk = clk_get(dev, "freq"); in lantiq_ssc_probe()
901 if (IS_ERR(spi->fpi_clk)) { in lantiq_ssc_probe()
902 err = PTR_ERR(spi->fpi_clk); in lantiq_ssc_probe()
907 of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); in lantiq_ssc_probe()
909 spi->base_cs = 1; in lantiq_ssc_probe()
910 of_property_read_u32(pdev->dev.of_node, "base-cs", &spi->base_cs); in lantiq_ssc_probe()
912 spin_lock_init(&spi->lock); in lantiq_ssc_probe()
913 spi->bits_per_word = 8; in lantiq_ssc_probe()
914 spi->speed_hz = 0; in lantiq_ssc_probe()
916 master->dev.of_node = pdev->dev.of_node; in lantiq_ssc_probe()
917 master->num_chipselect = num_cs; in lantiq_ssc_probe()
918 master->setup = lantiq_ssc_setup; in lantiq_ssc_probe()
919 master->set_cs = lantiq_ssc_set_cs; in lantiq_ssc_probe()
920 master->handle_err = lantiq_ssc_handle_err; in lantiq_ssc_probe()
921 master->prepare_message = lantiq_ssc_prepare_message; in lantiq_ssc_probe()
922 master->unprepare_message = lantiq_ssc_unprepare_message; in lantiq_ssc_probe()
923 master->transfer_one = lantiq_ssc_transfer_one; in lantiq_ssc_probe()
924 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH | in lantiq_ssc_probe()
926 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 8) | in lantiq_ssc_probe()
929 spi->wq = alloc_ordered_workqueue(dev_name(dev), 0); in lantiq_ssc_probe()
930 if (!spi->wq) { in lantiq_ssc_probe()
931 err = -ENOMEM; in lantiq_ssc_probe()
934 INIT_WORK(&spi->work, lantiq_ssc_bussy_work); in lantiq_ssc_probe()
937 spi->tx_fifo_size = (id & LTQ_SPI_ID_TXFS_M) >> LTQ_SPI_ID_TXFS_S; in lantiq_ssc_probe()
938 spi->rx_fifo_size = (id & LTQ_SPI_ID_RXFS_M) >> LTQ_SPI_ID_RXFS_S; in lantiq_ssc_probe()
946 revision, spi->tx_fifo_size, spi->rx_fifo_size, supports_dma); in lantiq_ssc_probe()
957 destroy_workqueue(spi->wq); in lantiq_ssc_probe()
959 clk_put(spi->fpi_clk); in lantiq_ssc_probe()
961 clk_disable_unprepare(spi->spi_clk); in lantiq_ssc_probe()
978 destroy_workqueue(spi->wq); in lantiq_ssc_remove()
979 clk_disable_unprepare(spi->spi_clk); in lantiq_ssc_remove()
980 clk_put(spi->fpi_clk); in lantiq_ssc_remove()
989 .name = "spi-lantiq-ssc",
997 MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
999 MODULE_ALIAS("platform:spi-lantiq-ssc");