aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-s5p6440/Makefile1
-rw-r--r--arch/arm/mach-s5p6440/dev-spi.c176
-rw-r--r--arch/arm/mach-s5p6440/include/mach/map.h3
-rw-r--r--arch/arm/mach-s5p6440/include/mach/spi-clocks.h17
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h1
6 files changed, 200 insertions, 0 deletions
diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile
index 44facf43d59f..be3c53aab23f 100644
--- a/arch/arm/mach-s5p6440/Makefile
+++ b/arch/arm/mach-s5p6440/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o
21 21
22# device support 22# device support
23obj-y += dev-audio.o 23obj-y += dev-audio.o
24obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
diff --git a/arch/arm/mach-s5p6440/dev-spi.c b/arch/arm/mach-s5p6440/dev-spi.c
new file mode 100644
index 000000000000..0a30280019c0
--- /dev/null
+++ b/arch/arm/mach-s5p6440/dev-spi.c
@@ -0,0 +1,176 @@
1/* linux/arch/arm/mach-s5p6440/dev-spi.c
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
13
14#include <mach/dma.h>
15#include <mach/map.h>
16#include <mach/irqs.h>
17#include <mach/gpio.h>
18#include <mach/spi-clocks.h>
19
20#include <plat/s3c64xx-spi.h>
21#include <plat/gpio-cfg.h>
22
23static char *spi_src_clks[] = {
24 [S5P6440_SPI_SRCCLK_PCLK] = "pclk",
25 [S5P6440_SPI_SRCCLK_SCLK] = "spi_epll",
26};
27
28/* SPI Controller platform_devices */
29
30/* Since we emulate multi-cs capability, we do not touch the CS.
31 * The emulated CS is toggled by board specific mechanism, as it can
32 * be either some immediate GPIO or some signal out of some other
33 * chip in between ... or some yet another way.
34 * We simply do not assume anything about CS.
35 */
36static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
37{
38 switch (pdev->id) {
39 case 0:
40 s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2));
41 s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2));
42 s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2));
43 s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP);
44 s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP);
45 s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP);
46 break;
47
48 case 1:
49 s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2));
50 s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2));
51 s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2));
52 s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP);
53 s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP);
54 s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP);
55 break;
56
57 default:
58 dev_err(&pdev->dev, "Invalid SPI Controller number!");
59 return -EINVAL;
60 }
61
62 return 0;
63}
64
65static struct resource s5p6440_spi0_resource[] = {
66 [0] = {
67 .start = S5P6440_PA_SPI0,
68 .end = S5P6440_PA_SPI0 + 0x100 - 1,
69 .flags = IORESOURCE_MEM,
70 },
71 [1] = {
72 .start = DMACH_SPI0_TX,
73 .end = DMACH_SPI0_TX,
74 .flags = IORESOURCE_DMA,
75 },
76 [2] = {
77 .start = DMACH_SPI0_RX,
78 .end = DMACH_SPI0_RX,
79 .flags = IORESOURCE_DMA,
80 },
81 [3] = {
82 .start = IRQ_SPI0,
83 .end = IRQ_SPI0,
84 .flags = IORESOURCE_IRQ,
85 },
86};
87
88static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
89 .cfg_gpio = s5p6440_spi_cfg_gpio,
90 .fifo_lvl_mask = 0x1ff,
91 .rx_lvl_offset = 15,
92};
93
94static u64 spi_dmamask = DMA_BIT_MASK(32);
95
96struct platform_device s5p6440_device_spi0 = {
97 .name = "s3c64xx-spi",
98 .id = 0,
99 .num_resources = ARRAY_SIZE(s5p6440_spi0_resource),
100 .resource = s5p6440_spi0_resource,
101 .dev = {
102 .dma_mask = &spi_dmamask,
103 .coherent_dma_mask = DMA_BIT_MASK(32),
104 .platform_data = &s5p6440_spi0_pdata,
105 },
106};
107
108static struct resource s5p6440_spi1_resource[] = {
109 [0] = {
110 .start = S5P6440_PA_SPI1,
111 .end = S5P6440_PA_SPI1 + 0x100 - 1,
112 .flags = IORESOURCE_MEM,
113 },
114 [1] = {
115 .start = DMACH_SPI1_TX,
116 .end = DMACH_SPI1_TX,
117 .flags = IORESOURCE_DMA,
118 },
119 [2] = {
120 .start = DMACH_SPI1_RX,
121 .end = DMACH_SPI1_RX,
122 .flags = IORESOURCE_DMA,
123 },
124 [3] = {
125 .start = IRQ_SPI1,
126 .end = IRQ_SPI1,
127 .flags = IORESOURCE_IRQ,
128 },
129};
130
131static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
132 .cfg_gpio = s5p6440_spi_cfg_gpio,
133 .fifo_lvl_mask = 0x7f,
134 .rx_lvl_offset = 15,
135};
136
137struct platform_device s5p6440_device_spi1 = {
138 .name = "s3c64xx-spi",
139 .id = 1,
140 .num_resources = ARRAY_SIZE(s5p6440_spi1_resource),
141 .resource = s5p6440_spi1_resource,
142 .dev = {
143 .dma_mask = &spi_dmamask,
144 .coherent_dma_mask = DMA_BIT_MASK(32),
145 .platform_data = &s5p6440_spi1_pdata,
146 },
147};
148
149void __init s5p6440_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
150{
151 struct s3c64xx_spi_info *pd;
152
153 /* Reject invalid configuration */
154 if (!num_cs || src_clk_nr < 0
155 || src_clk_nr > S5P6440_SPI_SRCCLK_SCLK) {
156 printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
157 return;
158 }
159
160 switch (cntrlr) {
161 case 0:
162 pd = &s5p6440_spi0_pdata;
163 break;
164 case 1:
165 pd = &s5p6440_spi1_pdata;
166 break;
167 default:
168 printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
169 __func__, cntrlr);
170 return;
171 }
172
173 pd->num_cs = num_cs;
174 pd->src_clk_nr = src_clk_nr;
175 pd->src_clk_name = spi_src_clks[src_clk_nr];
176}
diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h
index 72aedadd412c..8246895d3977 100644
--- a/arch/arm/mach-s5p6440/include/mach/map.h
+++ b/arch/arm/mach-s5p6440/include/mach/map.h
@@ -54,6 +54,9 @@
54 54
55#define S5P6440_PA_IIC0 (0xEC104000) 55#define S5P6440_PA_IIC0 (0xEC104000)
56 56
57#define S5P6440_PA_SPI0 0xEC400000
58#define S5P6440_PA_SPI1 0xEC500000
59
57#define S5P6440_PA_HSOTG (0xED100000) 60#define S5P6440_PA_HSOTG (0xED100000)
58 61
59#define S5P6440_PA_HSMMC0 (0xED800000) 62#define S5P6440_PA_HSMMC0 (0xED800000)
diff --git a/arch/arm/mach-s5p6440/include/mach/spi-clocks.h b/arch/arm/mach-s5p6440/include/mach/spi-clocks.h
new file mode 100644
index 000000000000..5fbca50d1cfb
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/spi-clocks.h
@@ -0,0 +1,17 @@
1/* linux/arch/arm/mach-s5p6440/include/mach/spi-clocks.h
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __S5P6440_PLAT_SPI_CLKS_H
12#define __S5P6440_PLAT_SPI_CLKS_H __FILE__
13
14#define S5P6440_SPI_SRCCLK_PCLK 0
15#define S5P6440_SPI_SRCCLK_SCLK 1
16
17#endif /* __S5P6440_PLAT_SPI_CLKS_H */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 62660b1058da..cd74a0700fc7 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -62,6 +62,8 @@ extern struct platform_device s5pc100_device_spi1;
62extern struct platform_device s5pc100_device_spi2; 62extern struct platform_device s5pc100_device_spi2;
63extern struct platform_device s5pv210_device_spi0; 63extern struct platform_device s5pv210_device_spi0;
64extern struct platform_device s5pv210_device_spi1; 64extern struct platform_device s5pv210_device_spi1;
65extern struct platform_device s5p6440_device_spi0;
66extern struct platform_device s5p6440_device_spi1;
65 67
66extern struct platform_device s3c_device_hwmon; 68extern struct platform_device s3c_device_hwmon;
67 69
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
index 7759f57b240a..e5aba8f95b79 100644
--- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -65,6 +65,7 @@ struct s3c64xx_spi_info {
65extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); 65extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
66extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); 66extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
67extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); 67extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
68extern void s5p6440_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
68extern void s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); 69extern void s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
69 70
70#endif /* __S3C64XX_PLAT_SPI_H */ 71#endif /* __S3C64XX_PLAT_SPI_H */