aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);