aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2008-12-10 20:37:17 -0500
committerTony Lindgren <tony@atomide.com>2008-12-10 20:37:17 -0500
commit90c62bf08f5823faa097271f3346a9142769b9ac (patch)
treeaa3bf442380815268b03092fd4b9c47924f9c3ee
parentd88746652b4d133284d1fdd05b5e999e8f44c998 (diff)
omap mmc: Add low-level initialization for hsmmc controller
Add low-level initialization for hsmmc controller. Merged into this patch patch are various improvments and board support by Grazvydas Ignotas and David Brownell. Also change wire4 to be wires, as some newer controllers support 8 data lines. Cc: Pierre Ossman <drzeus-mmc@drzeus.cx> Signed-off-by: Grazvydas Ignotas <notasas@gmail.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--arch/arm/mach-omap1/board-innovator.c2
-rw-r--r--arch/arm/mach-omap1/devices.c4
-rw-r--r--arch/arm/mach-omap2/Makefile15
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c48
-rw-r--r--arch/arm/mach-omap2/board-ldp.c40
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c90
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c32
-rw-r--r--arch/arm/mach-omap2/board-overo.c43
-rw-r--r--arch/arm/mach-omap2/devices.c3
-rw-r--r--arch/arm/mach-omap2/mmc-twl4030.c408
-rw-r--r--arch/arm/mach-omap2/mmc-twl4030.h29
-rw-r--r--arch/arm/plat-omap/include/mach/control.h17
-rw-r--r--arch/arm/plat-omap/include/mach/mmc.h16
-rw-r--r--drivers/mmc/host/omap.c2
14 files changed, 730 insertions, 19 deletions
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 8ffb06fc0f0..af2fb907008 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -385,7 +385,7 @@ static struct omap_mmc_platform_data mmc1_data = {
385 .nr_slots = 1, 385 .nr_slots = 1,
386 .slots[0] = { 386 .slots[0] = {
387 .set_power = mmc_set_power, 387 .set_power = mmc_set_power,
388 .wire4 = 1, 388 .wires = 4,
389 .name = "mmcblk", 389 .name = "mmcblk",
390 }, 390 },
391}; 391};
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 024dab13d4b..77382d8b6b2 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -116,7 +116,7 @@ static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
116 omap_cfg_reg(P19_1710_MMC_CMDDIR); 116 omap_cfg_reg(P19_1710_MMC_CMDDIR);
117 omap_cfg_reg(P20_1710_MMC_DATDIR0); 117 omap_cfg_reg(P20_1710_MMC_DATDIR0);
118 } 118 }
119 if (mmc_controller->slots[0].wire4) { 119 if (mmc_controller->slots[0].wires == 4) {
120 omap_cfg_reg(MMC_DAT1); 120 omap_cfg_reg(MMC_DAT1);
121 /* NOTE: DAT2 can be on W10 (here) or M15 */ 121 /* NOTE: DAT2 can be on W10 (here) or M15 */
122 if (!mmc_controller->slots[0].nomux) 122 if (!mmc_controller->slots[0].nomux)
@@ -132,7 +132,7 @@ static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
132 omap_cfg_reg(Y10_1610_MMC2_CLK); 132 omap_cfg_reg(Y10_1610_MMC2_CLK);
133 omap_cfg_reg(R18_1610_MMC2_CLKIN); 133 omap_cfg_reg(R18_1610_MMC2_CLKIN);
134 omap_cfg_reg(W8_1610_MMC2_DAT0); 134 omap_cfg_reg(W8_1610_MMC2_DAT0);
135 if (mmc_controller->slots[1].wire4) { 135 if (mmc_controller->slots[1].wires == 4) {
136 omap_cfg_reg(V8_1610_MMC2_DAT1); 136 omap_cfg_reg(V8_1610_MMC2_DAT1);
137 omap_cfg_reg(W15_1610_MMC2_DAT2); 137 omap_cfg_reg(W15_1610_MMC2_DAT2);
138 omap_cfg_reg(R10_1610_MMC2_DAT3); 138 omap_cfg_reg(R10_1610_MMC2_DAT3);
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index f12c43e4932..bbd12bc10fd 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -27,10 +27,15 @@ obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o
27# Specific board support 27# Specific board support
28obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o 28obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
29obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o 29obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
30obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o 30obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \
31 mmc-twl4030.o
31obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o 32obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
32obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o 33obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \
33obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o 34 mmc-twl4030.o
34obj-$(CONFIG_MACH_OVERO) += board-overo.o 35obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \
35obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o 36 mmc-twl4030.o
37obj-$(CONFIG_MACH_OVERO) += board-overo.o \
38 mmc-twl4030.o
39obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \
40 mmc-twl4030.o
36 41
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 6748de6e19a..83fa37211d7 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -19,6 +19,7 @@
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/i2c/twl4030.h>
22#include <linux/err.h> 23#include <linux/err.h>
23#include <linux/clk.h> 24#include <linux/clk.h>
24#include <linux/io.h> 25#include <linux/io.h>
@@ -35,6 +36,7 @@
35#include <mach/common.h> 36#include <mach/common.h>
36#include <mach/gpmc.h> 37#include <mach/gpmc.h>
37 38
39#include "mmc-twl4030.h"
38 40
39#define SDP2430_FLASH_CS 0 41#define SDP2430_FLASH_CS 0
40#define SDP2430_SMC91X_CS 5 42#define SDP2430_SMC91X_CS 5
@@ -197,12 +199,58 @@ static struct omap_board_config_kernel sdp2430_config[] = {
197 {OMAP_TAG_UART, &sdp2430_uart_config}, 199 {OMAP_TAG_UART, &sdp2430_uart_config},
198}; 200};
199 201
202
203static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
204 .gpio_base = OMAP_MAX_GPIO_LINES,
205 .irq_base = TWL4030_GPIO_IRQ_BASE,
206 .irq_end = TWL4030_GPIO_IRQ_END,
207};
208
209static struct twl4030_platform_data sdp2430_twldata = {
210 .irq_base = TWL4030_IRQ_BASE,
211 .irq_end = TWL4030_IRQ_END,
212
213 /* platform_data for children goes here */
214 .gpio = &sdp2430_gpio_data,
215};
216
217static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = {
218 {
219 I2C_BOARD_INFO("twl4030", 0x48),
220 .flags = I2C_CLIENT_WAKE,
221 .irq = INT_24XX_SYS_NIRQ,
222 .platform_data = &sdp2430_twldata,
223 },
224};
225
226static int __init omap2430_i2c_init(void)
227{
228 omap_register_i2c_bus(1, 400, NULL, 0);
229 omap_register_i2c_bus(2, 2600, sdp2430_i2c_boardinfo,
230 ARRAY_SIZE(sdp2430_i2c_boardinfo));
231 return 0;
232}
233
234static struct twl4030_hsmmc_info mmc[] __initdata = {
235 {
236 .mmc = 1,
237 .wires = 4,
238 .gpio_cd = -EINVAL,
239 .gpio_wp = -EINVAL,
240 .ext_clock = 1,
241 },
242 {} /* Terminator */
243};
244
200static void __init omap_2430sdp_init(void) 245static void __init omap_2430sdp_init(void)
201{ 246{
247 omap2430_i2c_init();
248
202 platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); 249 platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
203 omap_board_config = sdp2430_config; 250 omap_board_config = sdp2430_config;
204 omap_board_config_size = ARRAY_SIZE(sdp2430_config); 251 omap_board_config_size = ARRAY_SIZE(sdp2430_config);
205 omap_serial_init(); 252 omap_serial_init();
253 twl4030_mmc_init(mmc);
206} 254}
207 255
208static void __init omap_2430sdp_map_io(void) 256static void __init omap_2430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 43c7ac4b7f8..aa6972781e4 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -21,6 +21,7 @@
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/spi/ads7846.h> 23#include <linux/spi/ads7846.h>
24#include <linux/i2c/twl4030.h>
24 25
25#include <mach/hardware.h> 26#include <mach/hardware.h>
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
@@ -38,6 +39,8 @@
38#include <asm/delay.h> 39#include <asm/delay.h>
39#include <mach/control.h> 40#include <mach/control.h>
40 41
42#include "mmc-twl4030.h"
43
41#define SDP3430_SMC91X_CS 3 44#define SDP3430_SMC91X_CS 3
42 45
43static struct resource ldp_smc911x_resources[] = { 46static struct resource ldp_smc911x_resources[] = {
@@ -109,14 +112,48 @@ static struct omap_board_config_kernel ldp_config[] __initdata = {
109 { OMAP_TAG_UART, &ldp_uart_config }, 112 { OMAP_TAG_UART, &ldp_uart_config },
110}; 113};
111 114
115static struct twl4030_gpio_platform_data ldp_gpio_data = {
116 .gpio_base = OMAP_MAX_GPIO_LINES,
117 .irq_base = TWL4030_GPIO_IRQ_BASE,
118 .irq_end = TWL4030_GPIO_IRQ_END,
119};
120
121static struct twl4030_platform_data ldp_twldata = {
122 .irq_base = TWL4030_IRQ_BASE,
123 .irq_end = TWL4030_IRQ_END,
124
125 /* platform_data for children goes here */
126 .gpio = &ldp_gpio_data,
127};
128
129static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = {
130 {
131 I2C_BOARD_INFO("twl4030", 0x48),
132 .flags = I2C_CLIENT_WAKE,
133 .irq = INT_34XX_SYS_NIRQ,
134 .platform_data = &ldp_twldata,
135 },
136};
137
112static int __init omap_i2c_init(void) 138static int __init omap_i2c_init(void)
113{ 139{
114 omap_register_i2c_bus(1, 2600, NULL, 0); 140 omap_register_i2c_bus(1, 2600, ldp_i2c_boardinfo,
141 ARRAY_SIZE(ldp_i2c_boardinfo));
115 omap_register_i2c_bus(2, 400, NULL, 0); 142 omap_register_i2c_bus(2, 400, NULL, 0);
116 omap_register_i2c_bus(3, 400, NULL, 0); 143 omap_register_i2c_bus(3, 400, NULL, 0);
117 return 0; 144 return 0;
118} 145}
119 146
147static struct twl4030_hsmmc_info mmc[] __initdata = {
148 {
149 .mmc = 1,
150 .wires = 4,
151 .gpio_cd = -EINVAL,
152 .gpio_wp = -EINVAL,
153 },
154 {} /* Terminator */
155};
156
120static void __init omap_ldp_init(void) 157static void __init omap_ldp_init(void)
121{ 158{
122 omap_i2c_init(); 159 omap_i2c_init();
@@ -124,6 +161,7 @@ static void __init omap_ldp_init(void)
124 omap_board_config = ldp_config; 161 omap_board_config = ldp_config;
125 omap_board_config_size = ARRAY_SIZE(ldp_config); 162 omap_board_config_size = ARRAY_SIZE(ldp_config);
126 omap_serial_init(); 163 omap_serial_init();
164 twl4030_mmc_init(mmc);
127} 165}
128 166
129static void __init omap_ldp_map_io(void) 167static void __init omap_ldp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index baa79674e9d..9e5ada01b5f 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -38,7 +38,9 @@
38#include <mach/common.h> 38#include <mach/common.h>
39#include <mach/gpmc.h> 39#include <mach/gpmc.h>
40#include <mach/nand.h> 40#include <mach/nand.h>
41#include <mach/mux.h>
41 42
43#include "mmc-twl4030.h"
42 44
43#define GPMC_CS0_BASE 0x60 45#define GPMC_CS0_BASE 0x60
44#define GPMC_CS_SIZE 0x30 46#define GPMC_CS_SIZE 0x30
@@ -103,6 +105,78 @@ static struct omap_uart_config omap3_beagle_uart_config __initdata = {
103 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), 105 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
104}; 106};
105 107
108static struct twl4030_hsmmc_info mmc[] = {
109 {
110 .mmc = 1,
111 .wires = 8,
112 .gpio_wp = 29,
113 },
114 {} /* Terminator */
115};
116
117static struct gpio_led gpio_leds[];
118
119static int beagle_twl_gpio_setup(struct device *dev,
120 unsigned gpio, unsigned ngpio)
121{
122 /* gpio + 0 is "mmc0_cd" (input/IRQ) */
123
124 /* REVISIT: need ehci-omap hooks for external VBUS
125 * power switch and overcurrent detect
126 */
127
128 gpio_request(gpio + 1, "EHCI_nOC");
129 gpio_direction_input(gpio + 1);
130
131 /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
132 gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
133 gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
134
135 /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
136 gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
137
138 return 0;
139}
140
141static struct twl4030_gpio_platform_data beagle_gpio_data = {
142 .gpio_base = OMAP_MAX_GPIO_LINES,
143 .irq_base = TWL4030_GPIO_IRQ_BASE,
144 .irq_end = TWL4030_GPIO_IRQ_END,
145 .use_leds = true,
146 .pullups = BIT(1),
147 .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
148 | BIT(15) | BIT(16) | BIT(17),
149 .setup = beagle_twl_gpio_setup,
150};
151
152static struct twl4030_platform_data beagle_twldata = {
153 .irq_base = TWL4030_IRQ_BASE,
154 .irq_end = TWL4030_IRQ_END,
155
156 /* platform_data for children goes here */
157 .gpio = &beagle_gpio_data,
158};
159
160static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
161 {
162 I2C_BOARD_INFO("twl4030", 0x48),
163 .flags = I2C_CLIENT_WAKE,
164 .irq = INT_34XX_SYS_NIRQ,
165 .platform_data = &beagle_twldata,
166 },
167};
168
169static int __init omap3_beagle_i2c_init(void)
170{
171 omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
172 ARRAY_SIZE(beagle_i2c_boardinfo));
173#ifdef CONFIG_I2C2_OMAP_BEAGLE
174 omap_register_i2c_bus(2, 400, NULL, 0);
175#endif
176 omap_register_i2c_bus(3, 400, NULL, 0);
177 return 0;
178}
179
106static void __init omap3_beagle_init_irq(void) 180static void __init omap3_beagle_init_irq(void)
107{ 181{
108 omap2_init_common_hw(); 182 omap2_init_common_hw();
@@ -130,6 +204,11 @@ static struct gpio_led gpio_leds[] = {
130 .default_trigger = "mmc0", 204 .default_trigger = "mmc0",
131 .gpio = 149, 205 .gpio = 149,
132 }, 206 },
207 {
208 .name = "beagleboard::pmu_stat",
209 .gpio = -EINVAL, /* gets replaced */
210 .active_low = true,
211 },
133}; 212};
134 213
135static struct gpio_led_platform_data gpio_led_info = { 214static struct gpio_led_platform_data gpio_led_info = {
@@ -218,11 +297,22 @@ static void __init omap3beagle_flash_init(void)
218 297
219static void __init omap3_beagle_init(void) 298static void __init omap3_beagle_init(void)
220{ 299{
300 omap3_beagle_i2c_init();
221 platform_add_devices(omap3_beagle_devices, 301 platform_add_devices(omap3_beagle_devices,
222 ARRAY_SIZE(omap3_beagle_devices)); 302 ARRAY_SIZE(omap3_beagle_devices));
223 omap_board_config = omap3_beagle_config; 303 omap_board_config = omap3_beagle_config;
224 omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); 304 omap_board_config_size = ARRAY_SIZE(omap3_beagle_config);
225 omap_serial_init(); 305 omap_serial_init();
306
307 omap_cfg_reg(AH8_34XX_GPIO29);
308 mmc[0].gpio_cd = gpio + 0;
309 twl4030_mmc_init(mmc);
310
311 omap_cfg_reg(J25_34XX_GPIO170);
312 gpio_request(170, "DVI_nPD");
313 /* REVISIT leave DVI powered down until it's needed ... */
314 gpio_direction_output(170, true);
315
226 omap3beagle_flash_init(); 316 omap3beagle_flash_init();
227} 317}
228 318
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 7236c7be05b..b3196107afd 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -35,16 +35,48 @@
35#include <mach/hardware.h> 35#include <mach/hardware.h>
36#include <mach/mcspi.h> 36#include <mach/mcspi.h>
37 37
38#include "mmc-twl4030.h"
39
38#define OMAP3_PANDORA_TS_GPIO 94 40#define OMAP3_PANDORA_TS_GPIO 94
39 41
42static struct twl4030_hsmmc_info omap3pandora_mmc[] = {
43 {
44 .mmc = 1,
45 .wires = 4,
46 .gpio_cd = -EINVAL,
47 .gpio_wp = 126,
48 .ext_clock = 0,
49 },
50 {
51 .mmc = 2,
52 .wires = 4,
53 .gpio_cd = -EINVAL,
54 .gpio_wp = 127,
55 .ext_clock = 1,
56 },
57 {} /* Terminator */
58};
59
40static struct omap_uart_config omap3pandora_uart_config __initdata = { 60static struct omap_uart_config omap3pandora_uart_config __initdata = {
41 .enabled_uarts = (1 << 2), /* UART3 */ 61 .enabled_uarts = (1 << 2), /* UART3 */
42}; 62};
43 63
64static int omap3pandora_twl_gpio_setup(struct device *dev,
65 unsigned gpio, unsigned ngpio)
66{
67 /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
68 omap3pandora_mmc[0].gpio_cd = gpio + 0;
69 omap3pandora_mmc[1].gpio_cd = gpio + 1;
70 twl4030_mmc_init(omap3pandora_mmc);
71
72 return 0;
73}
74
44static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { 75static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
45 .gpio_base = OMAP_MAX_GPIO_LINES, 76 .gpio_base = OMAP_MAX_GPIO_LINES,
46 .irq_base = TWL4030_GPIO_IRQ_BASE, 77 .irq_base = TWL4030_GPIO_IRQ_BASE,
47 .irq_end = TWL4030_GPIO_IRQ_END, 78 .irq_end = TWL4030_GPIO_IRQ_END,
79 .setup = omap3pandora_twl_gpio_setup,
48}; 80};
49 81
50static struct twl4030_usb_data omap3pandora_usb_data = { 82static struct twl4030_usb_data omap3pandora_usb_data = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index e09aa59a399..82b3dc557c9 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -26,6 +26,7 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/i2c/twl4030.h>
29 30
30#include <linux/mtd/mtd.h> 31#include <linux/mtd/mtd.h>
31#include <linux/mtd/nand.h> 32#include <linux/mtd/nand.h>
@@ -44,6 +45,8 @@
44#include <mach/hardware.h> 45#include <mach/hardware.h>
45#include <mach/nand.h> 46#include <mach/nand.h>
46 47
48#include "mmc-twl4030.h"
49
47#define NAND_BLOCK_SIZE SZ_128K 50#define NAND_BLOCK_SIZE SZ_128K
48#define GPMC_CS0_BASE 0x60 51#define GPMC_CS0_BASE 0x60
49#define GPMC_CS_SIZE 0x30 52#define GPMC_CS_SIZE 0x30
@@ -139,8 +142,31 @@ static struct omap_uart_config overo_uart_config __initdata = {
139 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), 142 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
140}; 143};
141 144
145static struct twl4030_gpio_platform_data overo_gpio_data = {
146 .gpio_base = OMAP_MAX_GPIO_LINES,
147 .irq_base = TWL4030_GPIO_IRQ_BASE,
148 .irq_end = TWL4030_GPIO_IRQ_END,
149};
150
151static struct twl4030_platform_data overo_twldata = {
152 .irq_base = TWL4030_IRQ_BASE,
153 .irq_end = TWL4030_IRQ_END,
154 .gpio = &overo_gpio_data,
155};
156
157static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
158 {
159 I2C_BOARD_INFO("twl4030", 0x48),
160 .flags = I2C_CLIENT_WAKE,
161 .irq = INT_34XX_SYS_NIRQ,
162 .platform_data = &overo_twldata,
163 },
164};
165
142static int __init overo_i2c_init(void) 166static int __init overo_i2c_init(void)
143{ 167{
168 omap_register_i2c_bus(1, 2600, overo_i2c_boardinfo,
169 ARRAY_SIZE(overo_i2c_boardinfo));
144 /* i2c2 pins are used for gpio */ 170 /* i2c2 pins are used for gpio */
145 omap_register_i2c_bus(3, 400, NULL, 0); 171 omap_register_i2c_bus(3, 400, NULL, 0);
146 return 0; 172 return 0;
@@ -171,6 +197,22 @@ static struct platform_device *overo_devices[] __initdata = {
171 &overo_lcd_device, 197 &overo_lcd_device,
172}; 198};
173 199
200static struct twl4030_hsmmc_info mmc[] __initdata = {
201 {
202 .mmc = 1,
203 .wires = 4,
204 .gpio_cd = -EINVAL,
205 .gpio_wp = -EINVAL,
206 },
207 {
208 .mmc = 2,
209 .wires = 4,
210 .gpio_cd = -EINVAL,
211 .gpio_wp = -EINVAL,
212 },
213 {} /* Terminator */
214};
215
174static void __init overo_init(void) 216static void __init overo_init(void)
175{ 217{
176 overo_i2c_init(); 218 overo_i2c_init();
@@ -178,6 +220,7 @@ static void __init overo_init(void)
178 omap_board_config = overo_config; 220 omap_board_config = overo_config;
179 omap_board_config_size = ARRAY_SIZE(overo_config); 221 omap_board_config_size = ARRAY_SIZE(overo_config);
180 omap_serial_init(); 222 omap_serial_init();
223 twl4030_mmc_init(mmc);
181 overo_flash_init(); 224 overo_flash_init();
182 225
183 if ((gpio_request(OVERO_GPIO_W2W_NRESET, 226 if ((gpio_request(OVERO_GPIO_W2W_NRESET,
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 8ccdfcf2942..6e03272b052 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -19,6 +19,7 @@
19#include <asm/mach-types.h> 19#include <asm/mach-types.h>
20#include <asm/mach/map.h> 20#include <asm/mach/map.h>
21 21
22#include <mach/control.h>
22#include <mach/tc.h> 23#include <mach/tc.h>
23#include <mach/board.h> 24#include <mach/board.h>
24#include <mach/mux.h> 25#include <mach/mux.h>
@@ -311,7 +312,7 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
311 omap_cfg_reg(F20_24XX_MMC_DAT0); 312 omap_cfg_reg(F20_24XX_MMC_DAT0);
312 omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); 313 omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
313 omap_cfg_reg(G18_24XX_MMC_CMD_DIR); 314 omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
314 if (mmc_controller->slots[0].wire4) { 315 if (mmc_controller->slots[0].wires == 4) {
315 omap_cfg_reg(H14_24XX_MMC_DAT1); 316 omap_cfg_reg(H14_24XX_MMC_DAT1);
316 omap_cfg_reg(E19_24XX_MMC_DAT2); 317 omap_cfg_reg(E19_24XX_MMC_DAT2);
317 omap_cfg_reg(D19_24XX_MMC_DAT3); 318 omap_cfg_reg(D19_24XX_MMC_DAT3);
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c
new file mode 100644
index 00000000000..437f52073f6
--- /dev/null
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -0,0 +1,408 @@
1/*
2 * linux/arch/arm/mach-omap2/mmc-twl4030.c
3 *
4 * Copyright (C) 2007-2008 Texas Instruments
5 * Copyright (C) 2008 Nokia Corporation
6 * Author: Texas Instruments
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/err.h>
13#include <linux/io.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/interrupt.h>
17#include <linux/delay.h>
18#include <linux/gpio.h>
19#include <linux/i2c/twl4030.h>
20
21#include <mach/hardware.h>
22#include <mach/control.h>
23#include <mach/mmc.h>
24#include <mach/board.h>
25
26#include "mmc-twl4030.h"
27
28#if defined(CONFIG_TWL4030_CORE) && \
29 (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
30
31#define LDO_CLR 0x00
32#define VSEL_S2_CLR 0x40
33
34#define VMMC1_DEV_GRP 0x27
35#define VMMC1_CLR 0x00
36#define VMMC1_315V 0x03
37#define VMMC1_300V 0x02
38#define VMMC1_285V 0x01
39#define VMMC1_185V 0x00
40#define VMMC1_DEDICATED 0x2A
41
42#define VMMC2_DEV_GRP 0x2B
43#define VMMC2_CLR 0x40
44#define VMMC2_315V 0x0c
45#define VMMC2_300V 0x0b
46#define VMMC2_285V 0x0a
47#define VMMC2_260V 0x08
48#define VMMC2_185V 0x06
49#define VMMC2_DEDICATED 0x2E
50
51#define VMMC_DEV_GRP_P1 0x20
52
53static u16 control_pbias_offset;
54static u16 control_devconf1_offset;
55
56#define HSMMC_NAME_LEN 9
57
58static struct twl_mmc_controller {
59 struct omap_mmc_platform_data *mmc;
60 u8 twl_vmmc_dev_grp;
61 u8 twl_mmc_dedicated;
62 char name[HSMMC_NAME_LEN];
63} hsmmc[] = {
64 {
65 .twl_vmmc_dev_grp = VMMC1_DEV_GRP,
66 .twl_mmc_dedicated = VMMC1_DEDICATED,
67 },
68 {
69 .twl_vmmc_dev_grp = VMMC2_DEV_GRP,
70 .twl_mmc_dedicated = VMMC2_DEDICATED,
71 },
72};
73
74static int twl_mmc_card_detect(int irq)
75{
76 unsigned i;
77
78 for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
79 struct omap_mmc_platform_data *mmc;
80
81 mmc = hsmmc[i].mmc;
82 if (!mmc)
83 continue;
84 if (irq != mmc->slots[0].card_detect_irq)
85 continue;
86
87 /* NOTE: assumes card detect signal is active-low */
88 return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
89 }
90 return -ENOSYS;
91}
92
93static int twl_mmc_get_ro(struct device *dev, int slot)
94{
95 struct omap_mmc_platform_data *mmc = dev->platform_data;
96
97 /* NOTE: assumes write protect signal is active-high */
98 return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
99}
100
101/*
102 * MMC Slot Initialization.
103 */
104static int twl_mmc_late_init(struct device *dev)
105{
106 struct omap_mmc_platform_data *mmc = dev->platform_data;
107 int ret = 0;
108 int i;
109
110 ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd");
111 if (ret)
112 goto done;
113 ret = gpio_direction_input(mmc->slots[0].switch_pin);
114 if (ret)
115 goto err;
116
117 for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
118 if (hsmmc[i].name == mmc->slots[0].name) {
119 hsmmc[i].mmc = mmc;
120 break;
121 }
122 }
123
124 return 0;
125
126err:
127 gpio_free(mmc->slots[0].switch_pin);
128done:
129 mmc->slots[0].card_detect_irq = 0;
130 mmc->slots[0].card_detect = NULL;
131
132 dev_err(dev, "err %d configuring card detect\n", ret);
133 return ret;
134}
135
136static void twl_mmc_cleanup(struct device *dev)
137{
138 struct omap_mmc_platform_data *mmc = dev->platform_data;
139
140 gpio_free(mmc->slots[0].switch_pin);
141}
142
143#ifdef CONFIG_PM
144
145static int twl_mmc_suspend(struct device *dev, int slot)
146{
147 struct omap_mmc_platform_data *mmc = dev->platform_data;
148
149 disable_irq(mmc->slots[0].card_detect_irq);
150 return 0;
151}
152
153static int twl_mmc_resume(struct device *dev, int slot)
154{
155 struct omap_mmc_platform_data *mmc = dev->platform_data;
156
157 enable_irq(mmc->slots[0].card_detect_irq);
158 return 0;
159}
160
161#else
162#define twl_mmc_suspend NULL
163#define twl_mmc_resume NULL
164#endif
165
166/*
167 * Sets the MMC voltage in twl4030
168 */
169static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
170{
171 int ret;
172 u8 vmmc, dev_grp_val;
173
174 switch (1 << vdd) {
175 case MMC_VDD_35_36:
176 case MMC_VDD_34_35:
177 case MMC_VDD_33_34:
178 case MMC_VDD_32_33:
179 case MMC_VDD_31_32:
180 case MMC_VDD_30_31:
181 if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
182 vmmc = VMMC1_315V;
183 else
184 vmmc = VMMC2_315V;
185 break;
186 case MMC_VDD_29_30:
187 if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
188 vmmc = VMMC1_315V;
189 else
190 vmmc = VMMC2_300V;
191 break;
192 case MMC_VDD_27_28:
193 case MMC_VDD_26_27:
194 if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
195 vmmc = VMMC1_285V;
196 else
197 vmmc = VMMC2_285V;
198 break;
199 case MMC_VDD_25_26:
200 case MMC_VDD_24_25:
201 case MMC_VDD_23_24:
202 case MMC_VDD_22_23:
203 case MMC_VDD_21_22:
204 case MMC_VDD_20_21:
205 if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
206 vmmc = VMMC1_285V;
207 else
208 vmmc = VMMC2_260V;
209 break;
210 case MMC_VDD_165_195:
211 if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
212 vmmc = VMMC1_185V;
213 else
214 vmmc = VMMC2_185V;
215 break;
216 default:
217 vmmc = 0;
218 break;
219 }
220
221 if (vmmc)
222 dev_grp_val = VMMC_DEV_GRP_P1; /* Power up */
223 else
224 dev_grp_val = LDO_CLR; /* Power down */
225
226 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
227 dev_grp_val, c->twl_vmmc_dev_grp);
228 if (ret)
229 return ret;
230
231 ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
232 vmmc, c->twl_mmc_dedicated);
233
234 return ret;
235}
236
237static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
238 int vdd)
239{
240 u32 reg;
241 int ret = 0;
242 struct twl_mmc_controller *c = &hsmmc[0];
243 struct omap_mmc_platform_data *mmc = dev->platform_data;
244
245 if (power_on) {
246 if (cpu_is_omap2430()) {
247 reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
248 if ((1 << vdd) >= MMC_VDD_30_31)
249 reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
250 else
251 reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
252 omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
253 }
254
255 if (mmc->slots[0].internal_clock) {
256 reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
257 reg |= OMAP2_MMCSDIO1ADPCLKISEL;
258 omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
259 }
260
261 reg = omap_ctrl_readl(control_pbias_offset);
262 reg |= OMAP2_PBIASSPEEDCTRL0;
263 reg &= ~OMAP2_PBIASLITEPWRDNZ0;
264 omap_ctrl_writel(reg, control_pbias_offset);
265
266 ret = twl_mmc_set_voltage(c, vdd);
267
268 /* 100ms delay required for PBIAS configuration */
269 msleep(100);
270 reg = omap_ctrl_readl(control_pbias_offset);
271 reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
272 if ((1 << vdd) <= MMC_VDD_165_195)
273 reg &= ~OMAP2_PBIASLITEVMODE0;
274 else
275 reg |= OMAP2_PBIASLITEVMODE0;
276 omap_ctrl_writel(reg, control_pbias_offset);
277 } else {
278 reg = omap_ctrl_readl(control_pbias_offset);
279 reg &= ~OMAP2_PBIASLITEPWRDNZ0;
280 omap_ctrl_writel(reg, control_pbias_offset);
281
282 ret = twl_mmc_set_voltage(c, 0);
283
284 /* 100ms delay required for PBIAS configuration */
285 msleep(100);
286 reg = omap_ctrl_readl(control_pbias_offset);
287 reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
288 OMAP2_PBIASLITEVMODE0);
289 omap_ctrl_writel(reg, control_pbias_offset);
290 }
291
292 return ret;
293}
294
295static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vdd)
296{
297 int ret;
298 struct twl_mmc_controller *c = &hsmmc[1];
299 struct omap_mmc_platform_data *mmc = dev->platform_data;
300
301 if (power_on) {
302 if (mmc->slots[0].internal_clock) {
303 u32 reg;
304
305 reg = omap_ctrl_readl(control_devconf1_offset);
306 reg |= OMAP2_MMCSDIO2ADPCLKISEL;
307 omap_ctrl_writel(reg, control_devconf1_offset);
308 }
309 ret = twl_mmc_set_voltage(c, vdd);
310 } else {
311 ret = twl_mmc_set_voltage(c, 0);
312 }
313
314 return ret;
315}
316
317static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
318
319void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
320{
321 struct twl4030_hsmmc_info *c;
322 int nr_hsmmc = ARRAY_SIZE(hsmmc_data);
323
324 if (cpu_is_omap2430()) {
325 control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
326 control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
327 nr_hsmmc = 2;
328 } else {
329 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
330 control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
331 }
332
333 for (c = controllers; c->mmc; c++) {
334 struct twl_mmc_controller *twl = hsmmc + c->mmc - 1;
335 struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
336
337 if (!c->mmc || c->mmc > nr_hsmmc) {
338 pr_debug("MMC%d: no such controller\n", c->mmc);
339 continue;
340 }
341 if (mmc) {
342 pr_debug("MMC%d: already configured\n", c->mmc);
343 continue;
344 }
345
346 mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
347 if (!mmc) {
348 pr_err("Cannot allocate memory for mmc device!\n");
349 return;
350 }
351
352 sprintf(twl->name, "mmc%islot%i", c->mmc, 1);
353 mmc->slots[0].name = twl->name;
354 mmc->nr_slots = 1;
355 mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
356 MMC_VDD_26_27 | MMC_VDD_27_28 |
357 MMC_VDD_29_30 |
358 MMC_VDD_30_31 | MMC_VDD_31_32;
359 mmc->slots[0].wires = c->wires;
360 mmc->slots[0].internal_clock = !c->ext_clock;
361 mmc->dma_mask = 0xffffffff;
362
363 /* note: twl4030 card detect GPIOs normally switch VMMCx ... */
364 if (gpio_is_valid(c->gpio_cd)) {
365 mmc->init = twl_mmc_late_init;
366 mmc->cleanup = twl_mmc_cleanup;
367 mmc->suspend = twl_mmc_suspend;
368 mmc->resume = twl_mmc_resume;
369
370 mmc->slots[0].switch_pin = c->gpio_cd;
371 mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd);
372 mmc->slots[0].card_detect = twl_mmc_card_detect;
373 } else
374 mmc->slots[0].switch_pin = -EINVAL;
375
376 /* write protect normally uses an OMAP gpio */
377 if (gpio_is_valid(c->gpio_wp)) {
378 gpio_request(c->gpio_wp, "mmc_wp");
379 gpio_direction_input(c->gpio_wp);
380
381 mmc->slots[0].gpio_wp = c->gpio_wp;
382 mmc->slots[0].get_ro = twl_mmc_get_ro;
383 } else
384 mmc->slots[0].gpio_wp = -EINVAL;
385
386 /* NOTE: we assume OMAP's MMC1 and MMC2 use
387 * the TWL4030's VMMC1 and VMMC2, respectively;
388 * and that OMAP's MMC3 isn't used.
389 */
390
391 switch (c->mmc) {
392 case 1:
393 mmc->slots[0].set_power = twl_mmc1_set_power;
394 break;
395 case 2:
396 mmc->slots[0].set_power = twl_mmc2_set_power;
397 break;
398 default:
399 pr_err("MMC%d configuration not supported!\n", c->mmc);
400 continue;
401 }
402 hsmmc_data[c->mmc - 1] = mmc;
403 }
404
405 omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
406}
407
408#endif
diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h
new file mode 100644
index 00000000000..e1c8076400c
--- /dev/null
+++ b/arch/arm/mach-omap2/mmc-twl4030.h
@@ -0,0 +1,29 @@
1/*
2 * MMC definitions for OMAP2
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9struct twl4030_hsmmc_info {
10 u8 mmc; /* controller 1/2/3 */
11 u8 wires; /* 1/4/8 wires */
12 int gpio_cd; /* or -EINVAL */
13 int gpio_wp; /* or -EINVAL */
14 int ext_clock:1; /* use external pin for input clock */
15};
16
17#if defined(CONFIG_TWL4030_CORE) && \
18 (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
19 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
20
21void twl4030_mmc_init(struct twl4030_hsmmc_info *);
22
23#else
24
25static inline void twl4030_mmc_init(struct twl4030_hsmmc_info *info)
26{
27}
28
29#endif
diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h
index dc988676057..269147f3836 100644
--- a/arch/arm/plat-omap/include/mach/control.h
+++ b/arch/arm/plat-omap/include/mach/control.h
@@ -74,6 +74,7 @@
74#define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) 74#define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
75#define OMAP243X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) 75#define OMAP243X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
76#define OMAP243X_CONTROL_IVA2_GEMCFG (OMAP2_CONTROL_GENERAL + 0x0198) 76#define OMAP243X_CONTROL_IVA2_GEMCFG (OMAP2_CONTROL_GENERAL + 0x0198)
77#define OMAP243X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x0230)
77 78
78/* 24xx-only CONTROL_GENERAL register offsets */ 79/* 24xx-only CONTROL_GENERAL register offsets */
79#define OMAP24XX_CONTROL_DEBOBS (OMAP2_CONTROL_GENERAL + 0x0000) 80#define OMAP24XX_CONTROL_DEBOBS (OMAP2_CONTROL_GENERAL + 0x0000)
@@ -140,6 +141,7 @@
140#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc) 141#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc)
141#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) 142#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
142#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) 143#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
144#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02b0)
143#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4) 145#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4)
144 146
145/* 147/*
@@ -154,11 +156,14 @@
154 * and the security mode (secure, non-secure, don't care) 156 * and the security mode (secure, non-secure, don't care)
155 */ 157 */
156/* CONTROL_DEVCONF0 bits */ 158/* CONTROL_DEVCONF0 bits */
159#define OMAP2_MMCSDIO1ADPCLKISEL (1 << 24) /* MMC1 loop back clock */
157#define OMAP24XX_USBSTANDBYCTRL (1 << 15) 160#define OMAP24XX_USBSTANDBYCTRL (1 << 15)
158#define OMAP2_MCBSP2_CLKS_MASK (1 << 6) 161#define OMAP2_MCBSP2_CLKS_MASK (1 << 6)
159#define OMAP2_MCBSP1_CLKS_MASK (1 << 2) 162#define OMAP2_MCBSP1_CLKS_MASK (1 << 2)
160 163
161/* CONTROL_DEVCONF1 bits */ 164/* CONTROL_DEVCONF1 bits */
165#define OMAP243X_MMC1_ACTIVE_OVERWRITE (1 << 31)
166#define OMAP2_MMCSDIO2ADPCLKISEL (1 << 6) /* MMC2 loop back clock */
162#define OMAP2_MCBSP5_CLKS_MASK (1 << 4) /* > 242x */ 167#define OMAP2_MCBSP5_CLKS_MASK (1 << 4) /* > 242x */
163#define OMAP2_MCBSP4_CLKS_MASK (1 << 2) /* > 242x */ 168#define OMAP2_MCBSP4_CLKS_MASK (1 << 2) /* > 242x */
164#define OMAP2_MCBSP3_CLKS_MASK (1 << 0) /* > 242x */ 169#define OMAP2_MCBSP3_CLKS_MASK (1 << 0) /* > 242x */
@@ -172,6 +177,18 @@
172#define OMAP2_SYSBOOT_1_MASK (1 << 1) 177#define OMAP2_SYSBOOT_1_MASK (1 << 1)
173#define OMAP2_SYSBOOT_0_MASK (1 << 0) 178#define OMAP2_SYSBOOT_0_MASK (1 << 0)
174 179
180/* CONTROL_PBIAS_LITE bits */
181#define OMAP343X_PBIASLITESUPPLY_HIGH1 (1 << 15)
182#define OMAP343X_PBIASLITEVMODEERROR1 (1 << 11)
183#define OMAP343X_PBIASSPEEDCTRL1 (1 << 10)
184#define OMAP343X_PBIASLITEPWRDNZ1 (1 << 9)
185#define OMAP343X_PBIASLITEVMODE1 (1 << 8)
186#define OMAP343X_PBIASLITESUPPLY_HIGH0 (1 << 7)
187#define OMAP343X_PBIASLITEVMODEERROR0 (1 << 3)
188#define OMAP2_PBIASSPEEDCTRL0 (1 << 2)
189#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1)
190#define OMAP2_PBIASLITEVMODE0 (1 << 0)
191
175#ifndef __ASSEMBLY__ 192#ifndef __ASSEMBLY__
176#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 193#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
177extern void __iomem *omap_ctrl_base_get(void); 194extern void __iomem *omap_ctrl_base_get(void);
diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index 0c2ef3b8956..031250f0280 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -61,6 +61,11 @@ struct omap_mmc_platform_data {
61 61
62 struct omap_mmc_slot_data { 62 struct omap_mmc_slot_data {
63 63
64 /* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC;
65 * 8 wire signaling is also optional, and is used with HSMMC
66 */
67 u8 wires;
68
64 /* 69 /*
65 * nomux means "standard" muxing is wrong on this board, and 70 * nomux means "standard" muxing is wrong on this board, and
66 * that board-specific code handled it before common init logic. 71 * that board-specific code handled it before common init logic.
@@ -70,13 +75,12 @@ struct omap_mmc_platform_data {
70 /* switch pin can be for card detect (default) or card cover */ 75 /* switch pin can be for card detect (default) or card cover */
71 unsigned cover:1; 76 unsigned cover:1;
72 77
73 /* 4 wire signaling is optional, and is only used for SD/SDIO */
74 unsigned wire4:1;
75
76 /* use the internal clock */ 78 /* use the internal clock */
77 unsigned internal_clock:1; 79 unsigned internal_clock:1;
78 s16 power_pin; 80 s16 power_pin;
79 s16 switch_pin; 81
82 int switch_pin; /* gpio (card detect) */
83 int gpio_wp; /* gpio (write protect) */
80 84
81 int (* set_bus_mode)(struct device *dev, int slot, int bus_mode); 85 int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
82 int (* set_power)(struct device *dev, int slot, int power_on, int vdd); 86 int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
@@ -111,7 +115,6 @@ void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
111 int nr_controllers); 115 int nr_controllers);
112void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, 116void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
113 int nr_controllers); 117 int nr_controllers);
114void hsmmc_init(int controller_mask);
115int omap_mmc_add(int id, unsigned long base, unsigned long size, 118int omap_mmc_add(int id, unsigned long base, unsigned long size,
116 unsigned int irq, struct omap_mmc_platform_data *data); 119 unsigned int irq, struct omap_mmc_platform_data *data);
117#else 120#else
@@ -123,9 +126,6 @@ static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
123 int nr_controllers) 126 int nr_controllers)
124{ 127{
125} 128}
126static inline void hsmmc_init(int controller_mask)
127{
128}
129static inline int omap_mmc_add(int id, unsigned long base, unsigned long size, 129static inline int omap_mmc_add(int id, unsigned long base, unsigned long size,
130 unsigned int irq, struct omap_mmc_platform_data *data) 130 unsigned int irq, struct omap_mmc_platform_data *data)
131{ 131{
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index c6544d2d072..67d7b7fef08 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
1317 host->slots[id] = slot; 1317 host->slots[id] = slot;
1318 1318
1319 mmc->caps = 0; 1319 mmc->caps = 0;
1320 if (host->pdata->slots[id].wire4) 1320 if (host->pdata->slots[id].wires >= 4)
1321 mmc->caps |= MMC_CAP_4_BIT_DATA; 1321 mmc->caps |= MMC_CAP_4_BIT_DATA;
1322 1322
1323 mmc->ops = &mmc_omap_ops; 1323 mmc->ops = &mmc_omap_ops;