blob: 5bdeb94cc0a48cf03dc292b1ec51787dc1c42e80 [file] [log] [blame]
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -08001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/init.h>
15#include <linux/ioport.h>
16#include <linux/platform_device.h>
17#include <asm/mach-types.h>
18#include <asm/mach/mmc.h>
19#include <mach/msm_bus_board.h>
20#include <mach/board.h>
21#include <mach/gpiomux.h>
22#include "devices.h"
23
Krishna Konda39f5b2c2012-03-14 12:55:22 -070024#include "board-9615.h"
Subhash Jadavanibcd435f2012-04-24 18:26:49 +053025#include "board-storage-common-a.h"
Krishna Konda39f5b2c2012-03-14 12:55:22 -070026
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -080027#if (defined(CONFIG_MMC_MSM_SDC1_SUPPORT) \
28 || defined(CONFIG_MMC_MSM_SDC2_SUPPORT))
29
30#define GPIO_SDC1_HW_DET 80
31#define GPIO_SDC2_DAT1_WAKEUP 26
32
33/* MDM9x15 has 2 SDCC controllers */
34enum sdcc_controllers {
35 SDCC1,
36 SDCC2,
37 MAX_SDCC_CONTROLLER
38};
39
40#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
41/* All SDCC controllers requires VDD/VCC voltage */
42static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
43 /* SDCC1 : External card slot connected */
44 [SDCC1] = {
45 .name = "sdc_vdd",
46 /*
47 * This is a gpio-regulator and does not support
48 * regulator_set_voltage and regulator_set_optimum_mode
49 */
50 .high_vol_level = 2950000,
51 .low_vol_level = 2950000,
52 .hpm_uA = 600000, /* 600mA */
53 }
54};
55
56/* All SDCC controllers may require voting for VDD PAD voltage */
57static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
58 /* SDCC1 : External card slot connected */
59 [SDCC1] = {
60 .name = "sdc_vddp",
61 .high_vol_level = 2950000,
62 .low_vol_level = 1850000,
63 .always_on = true,
64 .lpm_sup = true,
65 /* Max. Active current required is 16 mA */
66 .hpm_uA = 16000,
67 /*
68 * Sleep current required is ~300 uA. But min. vote can be
69 * in terms of mA (min. 1 mA). So let's vote for 2 mA
70 * during sleep.
71 */
72 .lpm_uA = 2000,
73 }
74};
75
76static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
77 /* SDCC1 : External card slot connected */
78 [SDCC1] = {
79 .vdd_data = &mmc_vdd_reg_data[SDCC1],
80 .vddp_data = &mmc_vddp_reg_data[SDCC1],
81 }
82};
83
84/* SDC1 pad data */
85static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
86 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
87 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
88 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
89};
90
91static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
92 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
93 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
94 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
95};
96
97static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
98 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
99 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
100 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
101};
102
103static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
104 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
105 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_DOWN},
106 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_DOWN}
107};
108
109static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
110 [SDCC1] = {
111 .on = sdc1_pad_pull_on_cfg,
112 .off = sdc1_pad_pull_off_cfg,
113 .size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
114 },
115};
116
117static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
118 [SDCC1] = {
119 .on = sdc1_pad_drv_on_cfg,
120 .off = sdc1_pad_drv_off_cfg,
121 .size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
122 },
123};
124
125static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
126 [SDCC1] = {
127 .pull = &mmc_pad_pull_data[SDCC1],
128 .drv = &mmc_pad_drv_data[SDCC1]
129 },
130};
131#endif
132
133#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
134
135static struct msm_mmc_gpio sdc2_gpio_cfg[] = {
136 {25, "sdc2_dat_0"},
137 {26, "sdc2_dat_1"},
138 {27, "sdc2_dat_2"},
139 {28, "sdc2_dat_3"},
140 {29, "sdc2_cmd"},
141 {30, "sdc2_clk"},
142};
143
144static struct msm_mmc_gpio_data mmc_gpio_data[MAX_SDCC_CONTROLLER] = {
145 [SDCC2] = {
146 .gpio = sdc2_gpio_cfg,
147 .size = ARRAY_SIZE(sdc2_gpio_cfg),
148 },
149};
150#endif
151
152static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
153#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
154 [SDCC1] = {
155 .is_gpio = 0,
156 .pad_data = &mmc_pad_data[SDCC1],
157 },
158#endif
159#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
160 [SDCC2] = {
161 .is_gpio = 1,
162 .gpio_data = &mmc_gpio_data[SDCC2],
163 },
164#endif
165};
166
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530167#define MSM_MPM_PIN_SDC1_DAT1 17
168
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800169#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
170static unsigned int sdc1_sup_clk_rates[] = {
171 400000, 24000000, 48000000
172};
173
174static struct mmc_platform_data sdc1_data = {
175 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
176 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
177 .sup_clk_table = sdc1_sup_clk_rates,
178 .sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
179 .pclk_src_dfab = true,
180 .vreg_data = &mmc_slot_vreg_data[SDCC1],
181 .pin_data = &mmc_slot_pin_data[SDCC1],
182#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
183 .status_gpio = GPIO_SDC1_HW_DET,
184 .status_irq = MSM_GPIO_TO_INT(GPIO_SDC1_HW_DET),
185 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
186#endif
187 .xpc_cap = 1,
188 .uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530189 MMC_CAP_MAX_CURRENT_400),
190 .mpm_sdiowakeup_int = MSM_MPM_PIN_SDC1_DAT1,
Subhash Jadavanibcd435f2012-04-24 18:26:49 +0530191 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800192};
193static struct mmc_platform_data *msm9615_sdc1_pdata = &sdc1_data;
194#else
195static struct mmc_platform_data *msm9615_sdc1_pdata;
196#endif
197
198#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
199static unsigned int sdc2_sup_clk_rates[] = {
200 400000, 24000000, 48000000
201};
202
203static struct mmc_platform_data sdc2_data = {
204 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
205 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
206 .sup_clk_table = sdc2_sup_clk_rates,
207 .sup_clk_cnt = ARRAY_SIZE(sdc2_sup_clk_rates),
208 .pclk_src_dfab = 1,
209 .pin_data = &mmc_slot_pin_data[SDCC2],
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800210 .sdiowakeup_irq = MSM_GPIO_TO_INT(GPIO_SDC2_DAT1_WAKEUP),
Subhash Jadavanibcd435f2012-04-24 18:26:49 +0530211 .msm_bus_voting_data = &sps_to_ddr_bus_voting_data,
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800212};
213static struct mmc_platform_data *msm9615_sdc2_pdata = &sdc2_data;
214#else
215static struct mmc_platform_data *msm9615_sdc2_pdata;
216#endif
217
218void __init msm9615_init_mmc(void)
219{
Oluwafemi Adeyemi784b4392012-04-10 13:49:38 -0700220 if (msm9615_sdc1_pdata)
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800221 /* SDC1: External card slot for SD/MMC cards */
222 msm_add_sdcc(1, msm9615_sdc1_pdata);
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800223
Oluwafemi Adeyemi784b4392012-04-10 13:49:38 -0700224 if (msm9615_sdc2_pdata)
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800225 /* SDC2: External card slot used for WLAN */
226 msm_add_sdcc(2, msm9615_sdc2_pdata);
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800227}
228#else
229void __init msm9615_init_mmc(void)
230{
231}
232#endif