aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPadmavathi Venna <padma.kvr@gmail.com>2014-11-06 04:51:49 -0500
committerMark Brown <broonie@kernel.org>2014-11-26 14:00:34 -0500
commitbf77cba95f8c06bbf76869d3bdfb03e18a33e673 (patch)
tree632b1af62cae1f17e3415968b07992d488097898
parentf114040e3ea6e07372334ade75d1ee0775c355e1 (diff)
spi: s3c64xx: add support for exynos7 SPI controller
Exynos7 SPI controller supports only the auto Selection of CS toggle mode and Exynos7 SoC includes six SPI controllers. Add support for these changes in Exynos7 SPI controller driver. Signed-off-by: Padmavathi Venna <padma.v@samsung.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/spi/spi-samsung.txt2
-rw-r--r--drivers/spi/Kconfig2
-rw-r--r--drivers/spi/spi-s3c64xx.c32
3 files changed, 29 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
index 1e8a8578148f..6dbdeb3c361a 100644
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ b/Documentation/devicetree/bindings/spi/spi-samsung.txt
@@ -9,7 +9,7 @@ Required SoC Specific Properties:
9 - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms 9 - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
10 - samsung,s3c6410-spi: for s3c6410 platforms 10 - samsung,s3c6410-spi: for s3c6410 platforms
11 - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms 11 - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
12 - samsung,exynos4210-spi: for exynos4 and exynos5 platforms 12 - samsung,exynos7-spi: for exynos7 platforms
13 13
14- reg: physical base address of the controller and length of memory mapped 14- reg: physical base address of the controller and length of memory mapped
15 region. 15 region.
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 84e7c9e6ccef..de2d33dea8b8 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -444,7 +444,7 @@ config SPI_S3C24XX_FIQ
444 444
445config SPI_S3C64XX 445config SPI_S3C64XX
446 tristate "Samsung S3C64XX series type SPI" 446 tristate "Samsung S3C64XX series type SPI"
447 depends on PLAT_SAMSUNG 447 depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
448 select S3C64XX_PL080 if ARCH_S3C64XX 448 select S3C64XX_PL080 if ARCH_S3C64XX
449 help 449 help
450 SPI driver for Samsung S3C64XX and newer SoCs. 450 SPI driver for Samsung S3C64XX and newer SoCs.
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 480133ee1eb3..59e07cf31598 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -33,8 +33,9 @@
33 33
34#include <linux/platform_data/spi-s3c64xx.h> 34#include <linux/platform_data/spi-s3c64xx.h>
35 35
36#define MAX_SPI_PORTS 3 36#define MAX_SPI_PORTS 6
37#define S3C64XX_SPI_QUIRK_POLL (1 << 0) 37#define S3C64XX_SPI_QUIRK_POLL (1 << 0)
38#define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1)
38 39
39/* Registers and bit-fields */ 40/* Registers and bit-fields */
40 41
@@ -78,6 +79,7 @@
78 79
79#define S3C64XX_SPI_SLAVE_AUTO (1<<1) 80#define S3C64XX_SPI_SLAVE_AUTO (1<<1)
80#define S3C64XX_SPI_SLAVE_SIG_INACT (1<<0) 81#define S3C64XX_SPI_SLAVE_SIG_INACT (1<<0)
82#define S3C64XX_SPI_SLAVE_NSC_CNT_2 (2<<4)
81 83
82#define S3C64XX_SPI_INT_TRAILING_EN (1<<6) 84#define S3C64XX_SPI_INT_TRAILING_EN (1<<6)
83#define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5) 85#define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5)
@@ -717,7 +719,12 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
717 enable_datapath(sdd, spi, xfer, use_dma); 719 enable_datapath(sdd, spi, xfer, use_dma);
718 720
719 /* Start the signals */ 721 /* Start the signals */
720 writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); 722 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
723 writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
724 else
725 writel(readl(sdd->regs + S3C64XX_SPI_SLAVE_SEL)
726 | S3C64XX_SPI_SLAVE_AUTO | S3C64XX_SPI_SLAVE_NSC_CNT_2,
727 sdd->regs + S3C64XX_SPI_SLAVE_SEL);
721 728
722 spin_unlock_irqrestore(&sdd->lock, flags); 729 spin_unlock_irqrestore(&sdd->lock, flags);
723 730
@@ -866,13 +873,15 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
866 } 873 }
867 874
868 pm_runtime_put(&sdd->pdev->dev); 875 pm_runtime_put(&sdd->pdev->dev);
869 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); 876 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
877 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
870 return 0; 878 return 0;
871 879
872setup_exit: 880setup_exit:
873 pm_runtime_put(&sdd->pdev->dev); 881 pm_runtime_put(&sdd->pdev->dev);
874 /* setup() returns with device de-selected */ 882 /* setup() returns with device de-selected */
875 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); 883 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
884 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
876 885
877 if (gpio_is_valid(spi->cs_gpio)) 886 if (gpio_is_valid(spi->cs_gpio))
878 gpio_free(spi->cs_gpio); 887 gpio_free(spi->cs_gpio);
@@ -946,7 +955,8 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
946 955
947 sdd->cur_speed = 0; 956 sdd->cur_speed = 0;
948 957
949 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); 958 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
959 writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
950 960
951 /* Disable Interrupts - we use Polling if not DMA mode */ 961 /* Disable Interrupts - we use Polling if not DMA mode */
952 writel(0, regs + S3C64XX_SPI_INT_EN); 962 writel(0, regs + S3C64XX_SPI_INT_EN);
@@ -1341,6 +1351,15 @@ static struct s3c64xx_spi_port_config exynos5440_spi_port_config = {
1341 .quirks = S3C64XX_SPI_QUIRK_POLL, 1351 .quirks = S3C64XX_SPI_QUIRK_POLL,
1342}; 1352};
1343 1353
1354static struct s3c64xx_spi_port_config exynos7_spi_port_config = {
1355 .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F, 0x7F, 0x7F, 0x1ff},
1356 .rx_lvl_offset = 15,
1357 .tx_st_done = 25,
1358 .high_speed = true,
1359 .clk_from_cmu = true,
1360 .quirks = S3C64XX_SPI_QUIRK_CS_AUTO,
1361};
1362
1344static struct platform_device_id s3c64xx_spi_driver_ids[] = { 1363static struct platform_device_id s3c64xx_spi_driver_ids[] = {
1345 { 1364 {
1346 .name = "s3c2443-spi", 1365 .name = "s3c2443-spi",
@@ -1374,6 +1393,9 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
1374 { .compatible = "samsung,exynos5440-spi", 1393 { .compatible = "samsung,exynos5440-spi",
1375 .data = (void *)&exynos5440_spi_port_config, 1394 .data = (void *)&exynos5440_spi_port_config,
1376 }, 1395 },
1396 { .compatible = "samsung,exynos7-spi",
1397 .data = (void *)&exynos7_spi_port_config,
1398 },
1377 { }, 1399 { },
1378}; 1400};
1379MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match); 1401MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);