]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/arm/mach-ux500/board-mop500-sdi.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jesse/openvswitch
[karo-tx-linux.git] / 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 #include <linux/platform_data/dma-ste-dma40.h>
15
16 #include <asm/mach-types.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 struct mmci_platform_data mop500_sdi0_data = {
84         .ocr_mask       = MMC_VDD_29_30,
85         .f_max          = 50000000,
86         .capabilities   = MMC_CAP_4_BIT_DATA |
87                                 MMC_CAP_SD_HIGHSPEED |
88                                 MMC_CAP_MMC_HIGHSPEED,
89         .gpio_wp        = -1,
90         .sigdir         = MCI_ST_FBCLKEN |
91                                 MCI_ST_CMDDIREN |
92                                 MCI_ST_DATA0DIREN |
93                                 MCI_ST_DATA2DIREN,
94 #ifdef CONFIG_STE_DMA40
95         .dma_filter     = stedma40_filter,
96         .dma_rx_param   = &mop500_sdi0_dma_cfg_rx,
97         .dma_tx_param   = &mop500_sdi0_dma_cfg_tx,
98 #endif
99 };
100
101 static void sdi0_configure(struct device *parent)
102 {
103         int ret;
104
105         ret = gpio_request(sdi0_en, "level shifter enable");
106         if (!ret)
107                 ret = gpio_request(sdi0_vsel,
108                                    "level shifter 1v8-3v select");
109
110         if (ret) {
111                 pr_warning("unable to config sdi0 gpios for level shifter.\n");
112                 return;
113         }
114
115         /* Select the default 2.9V and enable level shifter */
116         gpio_direction_output(sdi0_vsel, 0);
117         gpio_direction_output(sdi0_en, 1);
118
119         /* Add the device, force v2 to subrevision 1 */
120         db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
121 }
122
123 void mop500_sdi_tc35892_init(struct device *parent)
124 {
125         mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
126         sdi0_en = GPIO_SDMMC_EN;
127         sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL;
128         sdi0_configure(parent);
129 }
130
131 /*
132  * SDI1 (SDIO WLAN)
133  */
134 #ifdef CONFIG_STE_DMA40
135 static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
136         .mode = STEDMA40_MODE_LOGICAL,
137         .dir = STEDMA40_PERIPH_TO_MEM,
138         .src_dev_type = DB8500_DMA_DEV32_SD_MM1_RX,
139         .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
140         .src_info.data_width = STEDMA40_WORD_WIDTH,
141         .dst_info.data_width = STEDMA40_WORD_WIDTH,
142 };
143
144 static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
145         .mode = STEDMA40_MODE_LOGICAL,
146         .dir = STEDMA40_MEM_TO_PERIPH,
147         .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
148         .dst_dev_type = DB8500_DMA_DEV32_SD_MM1_TX,
149         .src_info.data_width = STEDMA40_WORD_WIDTH,
150         .dst_info.data_width = STEDMA40_WORD_WIDTH,
151 };
152 #endif
153
154 struct mmci_platform_data mop500_sdi1_data = {
155         .ocr_mask       = MMC_VDD_29_30,
156         .f_max          = 50000000,
157         .capabilities   = MMC_CAP_4_BIT_DATA,
158         .gpio_cd        = -1,
159         .gpio_wp        = -1,
160 #ifdef CONFIG_STE_DMA40
161         .dma_filter     = stedma40_filter,
162         .dma_rx_param   = &sdi1_dma_cfg_rx,
163         .dma_tx_param   = &sdi1_dma_cfg_tx,
164 #endif
165 };
166
167 /*
168  * SDI 2 (POP eMMC, not on DB8500ed)
169  */
170
171 #ifdef CONFIG_STE_DMA40
172 struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
173         .mode = STEDMA40_MODE_LOGICAL,
174         .dir = STEDMA40_PERIPH_TO_MEM,
175         .src_dev_type =  DB8500_DMA_DEV28_SD_MM2_RX,
176         .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
177         .src_info.data_width = STEDMA40_WORD_WIDTH,
178         .dst_info.data_width = STEDMA40_WORD_WIDTH,
179 };
180
181 static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
182         .mode = STEDMA40_MODE_LOGICAL,
183         .dir = STEDMA40_MEM_TO_PERIPH,
184         .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
185         .dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX,
186         .src_info.data_width = STEDMA40_WORD_WIDTH,
187         .dst_info.data_width = STEDMA40_WORD_WIDTH,
188 };
189 #endif
190
191 struct mmci_platform_data mop500_sdi2_data = {
192         .ocr_mask       = MMC_VDD_165_195,
193         .f_max          = 50000000,
194         .capabilities   = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
195                           MMC_CAP_MMC_HIGHSPEED,
196         .gpio_cd        = -1,
197         .gpio_wp        = -1,
198 #ifdef CONFIG_STE_DMA40
199         .dma_filter     = stedma40_filter,
200         .dma_rx_param   = &mop500_sdi2_dma_cfg_rx,
201         .dma_tx_param   = &mop500_sdi2_dma_cfg_tx,
202 #endif
203 };
204
205 /*
206  * SDI 4 (on-board eMMC)
207  */
208
209 #ifdef CONFIG_STE_DMA40
210 struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
211         .mode = STEDMA40_MODE_LOGICAL,
212         .dir = STEDMA40_PERIPH_TO_MEM,
213         .src_dev_type =  DB8500_DMA_DEV42_SD_MM4_RX,
214         .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
215         .src_info.data_width = STEDMA40_WORD_WIDTH,
216         .dst_info.data_width = STEDMA40_WORD_WIDTH,
217 };
218
219 static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = {
220         .mode = STEDMA40_MODE_LOGICAL,
221         .dir = STEDMA40_MEM_TO_PERIPH,
222         .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
223         .dst_dev_type = DB8500_DMA_DEV42_SD_MM4_TX,
224         .src_info.data_width = STEDMA40_WORD_WIDTH,
225         .dst_info.data_width = STEDMA40_WORD_WIDTH,
226 };
227 #endif
228
229 struct mmci_platform_data mop500_sdi4_data = {
230         .ocr_mask       = MMC_VDD_29_30,
231         .f_max          = 50000000,
232         .capabilities   = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
233                           MMC_CAP_MMC_HIGHSPEED,
234         .gpio_cd        = -1,
235         .gpio_wp        = -1,
236 #ifdef CONFIG_STE_DMA40
237         .dma_filter     = stedma40_filter,
238         .dma_rx_param   = &mop500_sdi4_dma_cfg_rx,
239         .dma_tx_param   = &mop500_sdi4_dma_cfg_tx,
240 #endif
241 };
242
243 void __init mop500_sdi_init(struct device *parent)
244 {
245         /* PoP:ed eMMC */
246         db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
247         /* On-board eMMC */
248         db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
249
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(struct device *parent)
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(parent, &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(parent);
269 }
270
271 void __init hrefv60_sdi_init(struct device *parent)
272 {
273         /* PoP:ed eMMC */
274         db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
275         /* On-board eMMC */
276         db8500_add_sdi4(parent, &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(parent);
282         /* WLAN SDIO channel */
283         db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
284 }