]> Pileus Git - ~andy/linux/blob - arch/arm/mach-ux500/board-mop500-sdi.c
Merge branch 'amba' of git://git.linaro.org/people/rmk/linux-arm
[~andy/linux] / arch / arm / mach-ux500 / board-mop500-sdi.c
1 /*
2  * Copyright (C) ST-Ericsson SA 2010
3  *
4  * Author: Hanumath Prasad <hanumath.prasad@stericsson.com>
5  * License terms: GNU General Public License (GPL) version 2
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/gpio.h>
10 #include <linux/amba/bus.h>
11 #include <linux/amba/mmci.h>
12 #include <linux/mmc/host.h>
13 #include <linux/platform_device.h>
14
15 #include <asm/mach-types.h>
16 #include <plat/ste_dma40.h>
17 #include <mach/devices.h>
18 #include <mach/hardware.h>
19
20 #include "devices-db8500.h"
21 #include "board-mop500.h"
22 #include "ste-dma40-db8500.h"
23
24 /*
25  * v2 has a new version of this block that need to be forced, the number found
26  * in hardware is incorrect
27  */
28 #define U8500_SDI_V2_PERIPHID 0x10480180
29
30 /*
31  * SDI 0 (MicroSD slot)
32  */
33
34 /* GPIO pins used by the sdi0 level shifter */
35 static int sdi0_en = -1;
36 static int sdi0_vsel = -1;
37
38 static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios)
39 {
40         switch (ios->power_mode) {
41         case MMC_POWER_UP:
42         case MMC_POWER_ON:
43                 /*
44                  * Level shifter voltage should depend on vdd to when deciding
45                  * on either 1.8V or 2.9V. Once the decision has been made the
46                  * level shifter must be disabled and re-enabled with a changed
47                  * select signal in order to switch the voltage. Since there is
48                  * no framework support yet for indicating 1.8V in vdd, use the
49                  * default 2.9V.
50                  */
51                 gpio_direction_output(sdi0_vsel, 0);
52                 gpio_direction_output(sdi0_en, 1);
53                 break;
54         case MMC_POWER_OFF:
55                 gpio_direction_output(sdi0_vsel, 0);
56                 gpio_direction_output(sdi0_en, 0);
57                 break;
58         }
59
60         return 0;
61 }
62
63 #ifdef CONFIG_STE_DMA40
64 struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
65         .mode = STEDMA40_MODE_LOGICAL,
66         .dir = STEDMA40_PERIPH_TO_MEM,
67         .src_dev_type = DB8500_DMA_DEV29_SD_MM0_RX,
68         .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
69         .src_info.data_width = STEDMA40_WORD_WIDTH,
70         .dst_info.data_width = STEDMA40_WORD_WIDTH,
71 };
72
73 static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
74         .mode = STEDMA40_MODE_LOGICAL,
75         .dir = STEDMA40_MEM_TO_PERIPH,
76         .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
77         .dst_dev_type = DB8500_DMA_DEV29_SD_MM0_TX,
78         .src_info.data_width = STEDMA40_WORD_WIDTH,
79         .dst_info.data_width = STEDMA40_WORD_WIDTH,
80 };
81 #endif
82
83 static struct mmci_platform_data mop500_sdi0_data = {
84         .ios_handler    = mop500_sdi0_ios_handler,
85         .ocr_mask       = MMC_VDD_29_30,
86         .f_max          = 50000000,
87         .capabilities   = MMC_CAP_4_BIT_DATA |
88                                 MMC_CAP_SD_HIGHSPEED |
89                                 MMC_CAP_MMC_HIGHSPEED,
90         .gpio_wp        = -1,
91         .sigdir         = MCI_ST_FBCLKEN |
92                                 MCI_ST_CMDDIREN |
93                                 MCI_ST_DATA0DIREN |
94                                 MCI_ST_DATA2DIREN,
95 #ifdef CONFIG_STE_DMA40
96         .dma_filter     = stedma40_filter,
97         .dma_rx_param   = &mop500_sdi0_dma_cfg_rx,
98         .dma_tx_param   = &mop500_sdi0_dma_cfg_tx,
99 #endif
100 };
101
102 static void sdi0_configure(void)
103 {
104         int ret;
105
106         ret = gpio_request(sdi0_en, "level shifter enable");
107         if (!ret)
108                 ret = gpio_request(sdi0_vsel,
109                                    "level shifter 1v8-3v select");
110
111         if (ret) {
112                 pr_warning("unable to config sdi0 gpios for level shifter.\n");
113                 return;
114         }
115
116         /* Select the default 2.9V and enable level shifter */
117         gpio_direction_output(sdi0_vsel, 0);
118         gpio_direction_output(sdi0_en, 1);
119
120         /* Add the device, force v2 to subrevision 1 */
121         db8500_add_sdi0(&mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
122 }
123
124 void mop500_sdi_tc35892_init(void)
125 {
126         mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
127         sdi0_en = GPIO_SDMMC_EN;
128         sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL;
129         sdi0_configure();
130 }
131
132 /*
133  * SDI1 (SDIO WLAN)
134  */
135 #ifdef CONFIG_STE_DMA40
136 static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
137         .mode = STEDMA40_MODE_LOGICAL,
138         .dir = STEDMA40_PERIPH_TO_MEM,
139         .src_dev_type = DB8500_DMA_DEV32_SD_MM1_RX,
140         .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
141         .src_info.data_width = STEDMA40_WORD_WIDTH,
142         .dst_info.data_width = STEDMA40_WORD_WIDTH,
143 };
144
145 static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
146         .mode = STEDMA40_MODE_LOGICAL,
147         .dir = STEDMA40_MEM_TO_PERIPH,
148         .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
149         .dst_dev_type = DB8500_DMA_DEV32_SD_MM1_TX,
150         .src_info.data_width = STEDMA40_WORD_WIDTH,
151         .dst_info.data_width = STEDMA40_WORD_WIDTH,
152 };
153 #endif
154
155 static struct mmci_platform_data mop500_sdi1_data = {
156         .ocr_mask       = MMC_VDD_29_30,
157         .f_max          = 50000000,
158         .capabilities   = MMC_CAP_4_BIT_DATA,
159         .gpio_cd        = -1,
160         .gpio_wp        = -1,
161 #ifdef CONFIG_STE_DMA40
162         .dma_filter     = stedma40_filter,
163         .dma_rx_param   = &sdi1_dma_cfg_rx,
164         .dma_tx_param   = &sdi1_dma_cfg_tx,
165 #endif
166 };
167
168 /*
169  * SDI 2 (POP eMMC, not on DB8500ed)
170  */
171
172 #ifdef CONFIG_STE_DMA40
173 struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
174         .mode = STEDMA40_MODE_LOGICAL,
175         .dir = STEDMA40_PERIPH_TO_MEM,
176         .src_dev_type =  DB8500_DMA_DEV28_SD_MM2_RX,
177         .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
178         .src_info.data_width = STEDMA40_WORD_WIDTH,
179         .dst_info.data_width = STEDMA40_WORD_WIDTH,
180 };
181
182 static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
183         .mode = STEDMA40_MODE_LOGICAL,
184         .dir = STEDMA40_MEM_TO_PERIPH,
185         .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
186         .dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX,
187         .src_info.data_width = STEDMA40_WORD_WIDTH,
188         .dst_info.data_width = STEDMA40_WORD_WIDTH,
189 };
190 #endif
191
192 static struct mmci_platform_data mop500_sdi2_data = {
193         .ocr_mask       = MMC_VDD_165_195,
194         .f_max          = 50000000,
195         .capabilities   = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
196                           MMC_CAP_MMC_HIGHSPEED,
197         .gpio_cd        = -1,
198         .gpio_wp        = -1,
199 #ifdef CONFIG_STE_DMA40
200         .dma_filter     = stedma40_filter,
201         .dma_rx_param   = &mop500_sdi2_dma_cfg_rx,
202         .dma_tx_param   = &mop500_sdi2_dma_cfg_tx,
203 #endif
204 };
205
206 /*
207  * SDI 4 (on-board eMMC)
208  */
209
210 #ifdef CONFIG_STE_DMA40
211 struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
212         .mode = STEDMA40_MODE_LOGICAL,
213         .dir = STEDMA40_PERIPH_TO_MEM,
214         .src_dev_type =  DB8500_DMA_DEV42_SD_MM4_RX,
215         .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
216         .src_info.data_width = STEDMA40_WORD_WIDTH,
217         .dst_info.data_width = STEDMA40_WORD_WIDTH,
218 };
219
220 static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = {
221         .mode = STEDMA40_MODE_LOGICAL,
222         .dir = STEDMA40_MEM_TO_PERIPH,
223         .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
224         .dst_dev_type = DB8500_DMA_DEV42_SD_MM4_TX,
225         .src_info.data_width = STEDMA40_WORD_WIDTH,
226         .dst_info.data_width = STEDMA40_WORD_WIDTH,
227 };
228 #endif
229
230 static struct mmci_platform_data mop500_sdi4_data = {
231         .ocr_mask       = MMC_VDD_29_30,
232         .f_max          = 50000000,
233         .capabilities   = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
234                           MMC_CAP_MMC_HIGHSPEED,
235         .gpio_cd        = -1,
236         .gpio_wp        = -1,
237 #ifdef CONFIG_STE_DMA40
238         .dma_filter     = stedma40_filter,
239         .dma_rx_param   = &mop500_sdi4_dma_cfg_rx,
240         .dma_tx_param   = &mop500_sdi4_dma_cfg_tx,
241 #endif
242 };
243
244 void __init mop500_sdi_init(void)
245 {
246         /* PoP:ed eMMC */
247         db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
248         /* On-board eMMC */
249         db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
250         /*
251          * On boards with the TC35892 GPIO expander, sdi0 will finally
252          * be added when the TC35892 initializes and calls
253          * mop500_sdi_tc35892_init() above.
254          */
255 }
256
257 void __init snowball_sdi_init(void)
258 {
259         /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */
260         mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED;
261         /* On-board eMMC */
262         db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
263         /* External Micro SD slot */
264         mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO;
265         mop500_sdi0_data.cd_invert = true;
266         sdi0_en = SNOWBALL_SDMMC_EN_GPIO;
267         sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO;
268         sdi0_configure();
269 }
270
271 void __init hrefv60_sdi_init(void)
272 {
273         /* PoP:ed eMMC */
274         db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
275         /* On-board eMMC */
276         db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
277         /* External Micro SD slot */
278         mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO;
279         sdi0_en = HREFV60_SDMMC_EN_GPIO;
280         sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO;
281         sdi0_configure();
282         /* WLAN SDIO channel */
283         db8500_add_sdi1(&mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
284 }