blob: 7580cc3b3bfbcb36e852fd4d4e480910587754ea [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"
25
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -080026#if (defined(CONFIG_MMC_MSM_SDC1_SUPPORT) \
27 || defined(CONFIG_MMC_MSM_SDC2_SUPPORT))
28
29#define GPIO_SDC1_HW_DET 80
30#define GPIO_SDC2_DAT1_WAKEUP 26
31
32/* MDM9x15 has 2 SDCC controllers */
33enum sdcc_controllers {
34 SDCC1,
35 SDCC2,
36 MAX_SDCC_CONTROLLER
37};
38
39#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
40/* All SDCC controllers requires VDD/VCC voltage */
41static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
42 /* SDCC1 : External card slot connected */
43 [SDCC1] = {
44 .name = "sdc_vdd",
45 /*
46 * This is a gpio-regulator and does not support
47 * regulator_set_voltage and regulator_set_optimum_mode
48 */
49 .high_vol_level = 2950000,
50 .low_vol_level = 2950000,
51 .hpm_uA = 600000, /* 600mA */
52 }
53};
54
55/* All SDCC controllers may require voting for VDD PAD voltage */
56static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
57 /* SDCC1 : External card slot connected */
58 [SDCC1] = {
59 .name = "sdc_vddp",
60 .high_vol_level = 2950000,
61 .low_vol_level = 1850000,
62 .always_on = true,
63 .lpm_sup = true,
64 /* Max. Active current required is 16 mA */
65 .hpm_uA = 16000,
66 /*
67 * Sleep current required is ~300 uA. But min. vote can be
68 * in terms of mA (min. 1 mA). So let's vote for 2 mA
69 * during sleep.
70 */
71 .lpm_uA = 2000,
72 }
73};
74
75static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
76 /* SDCC1 : External card slot connected */
77 [SDCC1] = {
78 .vdd_data = &mmc_vdd_reg_data[SDCC1],
79 .vddp_data = &mmc_vddp_reg_data[SDCC1],
80 }
81};
82
83/* SDC1 pad data */
84static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
85 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
86 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
87 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
88};
89
90static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
91 {TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
92 {TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
93 {TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
94};
95
96static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
97 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
98 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
99 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
100};
101
102static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
103 {TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
104 {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_DOWN},
105 {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_DOWN}
106};
107
108static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
109 [SDCC1] = {
110 .on = sdc1_pad_pull_on_cfg,
111 .off = sdc1_pad_pull_off_cfg,
112 .size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
113 },
114};
115
116static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
117 [SDCC1] = {
118 .on = sdc1_pad_drv_on_cfg,
119 .off = sdc1_pad_drv_off_cfg,
120 .size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
121 },
122};
123
124static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
125 [SDCC1] = {
126 .pull = &mmc_pad_pull_data[SDCC1],
127 .drv = &mmc_pad_drv_data[SDCC1]
128 },
129};
130#endif
131
132#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
133
134static struct msm_mmc_gpio sdc2_gpio_cfg[] = {
135 {25, "sdc2_dat_0"},
136 {26, "sdc2_dat_1"},
137 {27, "sdc2_dat_2"},
138 {28, "sdc2_dat_3"},
139 {29, "sdc2_cmd"},
140 {30, "sdc2_clk"},
141};
142
143static struct msm_mmc_gpio_data mmc_gpio_data[MAX_SDCC_CONTROLLER] = {
144 [SDCC2] = {
145 .gpio = sdc2_gpio_cfg,
146 .size = ARRAY_SIZE(sdc2_gpio_cfg),
147 },
148};
149#endif
150
151static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
152#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
153 [SDCC1] = {
154 .is_gpio = 0,
155 .pad_data = &mmc_pad_data[SDCC1],
156 },
157#endif
158#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
159 [SDCC2] = {
160 .is_gpio = 1,
161 .gpio_data = &mmc_gpio_data[SDCC2],
162 },
163#endif
164};
165
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530166#define MSM_MPM_PIN_SDC1_DAT1 17
167
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800168#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
169static unsigned int sdc1_sup_clk_rates[] = {
170 400000, 24000000, 48000000
171};
172
173static struct mmc_platform_data sdc1_data = {
174 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
175 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
176 .sup_clk_table = sdc1_sup_clk_rates,
177 .sup_clk_cnt = ARRAY_SIZE(sdc1_sup_clk_rates),
178 .pclk_src_dfab = true,
179 .vreg_data = &mmc_slot_vreg_data[SDCC1],
180 .pin_data = &mmc_slot_pin_data[SDCC1],
181#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
182 .status_gpio = GPIO_SDC1_HW_DET,
183 .status_irq = MSM_GPIO_TO_INT(GPIO_SDC1_HW_DET),
184 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
185#endif
186 .xpc_cap = 1,
187 .uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
Subhash Jadavani55e188e2012-04-13 11:31:08 +0530188 MMC_CAP_MAX_CURRENT_400),
189 .mpm_sdiowakeup_int = MSM_MPM_PIN_SDC1_DAT1,
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800190};
191static struct mmc_platform_data *msm9615_sdc1_pdata = &sdc1_data;
192#else
193static struct mmc_platform_data *msm9615_sdc1_pdata;
194#endif
195
196#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
197static unsigned int sdc2_sup_clk_rates[] = {
198 400000, 24000000, 48000000
199};
200
201static struct mmc_platform_data sdc2_data = {
202 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
203 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
204 .sup_clk_table = sdc2_sup_clk_rates,
205 .sup_clk_cnt = ARRAY_SIZE(sdc2_sup_clk_rates),
206 .pclk_src_dfab = 1,
207 .pin_data = &mmc_slot_pin_data[SDCC2],
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800208 .sdiowakeup_irq = MSM_GPIO_TO_INT(GPIO_SDC2_DAT1_WAKEUP),
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800209};
210static struct mmc_platform_data *msm9615_sdc2_pdata = &sdc2_data;
211#else
212static struct mmc_platform_data *msm9615_sdc2_pdata;
213#endif
214
215void __init msm9615_init_mmc(void)
216{
Oluwafemi Adeyemi784b4392012-04-10 13:49:38 -0700217 if (msm9615_sdc1_pdata)
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800218 /* SDC1: External card slot for SD/MMC cards */
219 msm_add_sdcc(1, msm9615_sdc1_pdata);
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800220
Oluwafemi Adeyemi784b4392012-04-10 13:49:38 -0700221 if (msm9615_sdc2_pdata)
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800222 /* SDC2: External card slot used for WLAN */
223 msm_add_sdcc(2, msm9615_sdc2_pdata);
Rohit Vaswanie9a1ae32011-12-15 20:26:47 -0800224}
225#else
226void __init msm9615_init_mmc(void)
227{
228}
229#endif