diff options
author | Tony Lindgren <tony@atomide.com> | 2009-05-28 18:45:07 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2009-05-28 18:45:07 -0400 |
commit | 4c50d22a0cf240918d53afbf9a8416a9d93aacee (patch) | |
tree | 5b76b4c167cdc80a6911fc70b168c2a2025814db /arch/arm/mach-omap2 | |
parent | 970a724d9173526512ebd8be991a4cbe18b7aace (diff) | |
parent | 7419045016e5002b3ccee72b28e41bf53dca68f2 (diff) |
Merge branch 'omap3-boards' into for-next
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-omap3beagle.c | 104 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-omap3evm.c | 329 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-omap3pandora.c | 194 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-overo.c | 76 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-rx51-peripherals.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-zoom-debugboard.c | 160 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-zoom2.c | 110 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mmc-twl4030.c | 280 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mmc-twl4030.h | 3 |
11 files changed, 1100 insertions, 200 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 64ab386a65c7..b5c9088a6a4e 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -56,6 +56,10 @@ config MACH_OVERO | |||
56 | bool "Gumstix Overo board" | 56 | bool "Gumstix Overo board" |
57 | depends on ARCH_OMAP3 && ARCH_OMAP34XX | 57 | depends on ARCH_OMAP3 && ARCH_OMAP34XX |
58 | 58 | ||
59 | config MACH_OMAP3EVM | ||
60 | bool "OMAP 3530 EVM board" | ||
61 | depends on ARCH_OMAP3 && ARCH_OMAP34XX | ||
62 | |||
59 | config MACH_OMAP3_PANDORA | 63 | config MACH_OMAP3_PANDORA |
60 | bool "OMAP3 Pandora" | 64 | bool "OMAP3 Pandora" |
61 | depends on ARCH_OMAP3 && ARCH_OMAP34XX | 65 | depends on ARCH_OMAP3 && ARCH_OMAP34XX |
@@ -67,3 +71,7 @@ config MACH_OMAP_3430SDP | |||
67 | config MACH_NOKIA_RX51 | 71 | config MACH_NOKIA_RX51 |
68 | bool "Nokia RX-51 board" | 72 | bool "Nokia RX-51 board" |
69 | depends on ARCH_OMAP3 && ARCH_OMAP34XX | 73 | depends on ARCH_OMAP3 && ARCH_OMAP34XX |
74 | |||
75 | config MACH_OMAP_ZOOM2 | ||
76 | bool "OMAP3 Zoom2 board" | ||
77 | depends on ARCH_OMAP3 && ARCH_OMAP34XX | ||
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 516477ee5690..c48b12c0fe2d 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -47,6 +47,8 @@ obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \ | |||
47 | mmc-twl4030.o | 47 | mmc-twl4030.o |
48 | obj-$(CONFIG_MACH_OVERO) += board-overo.o \ | 48 | obj-$(CONFIG_MACH_OVERO) += board-overo.o \ |
49 | mmc-twl4030.o | 49 | mmc-twl4030.o |
50 | obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o \ | ||
51 | mmc-twl4030.o | ||
50 | obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \ | 52 | obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \ |
51 | mmc-twl4030.o | 53 | mmc-twl4030.o |
52 | obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \ | 54 | obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \ |
@@ -55,7 +57,9 @@ obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \ | |||
55 | obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ | 57 | obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ |
56 | board-rx51-peripherals.o \ | 58 | board-rx51-peripherals.o \ |
57 | mmc-twl4030.o | 59 | mmc-twl4030.o |
58 | 60 | obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \ | |
61 | mmc-twl4030.o \ | ||
62 | board-zoom-debugboard.o | ||
59 | # Platform specific device init code | 63 | # Platform specific device init code |
60 | obj-y += usb-musb.o | 64 | obj-y += usb-musb.o |
61 | 65 | ||
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index f25082c53c67..991ac9c38032 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mtd/partitions.h> | 28 | #include <linux/mtd/partitions.h> |
29 | #include <linux/mtd/nand.h> | 29 | #include <linux/mtd/nand.h> |
30 | 30 | ||
31 | #include <linux/regulator/machine.h> | ||
31 | #include <linux/i2c/twl4030.h> | 32 | #include <linux/i2c/twl4030.h> |
32 | 33 | ||
33 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
@@ -120,6 +121,23 @@ static struct twl4030_hsmmc_info mmc[] = { | |||
120 | {} /* Terminator */ | 121 | {} /* Terminator */ |
121 | }; | 122 | }; |
122 | 123 | ||
124 | static struct platform_device omap3_beagle_lcd_device = { | ||
125 | .name = "omap3beagle_lcd", | ||
126 | .id = -1, | ||
127 | }; | ||
128 | |||
129 | static struct omap_lcd_config omap3_beagle_lcd_config __initdata = { | ||
130 | .ctrl_name = "internal", | ||
131 | }; | ||
132 | |||
133 | static struct regulator_consumer_supply beagle_vmmc1_supply = { | ||
134 | .supply = "vmmc", | ||
135 | }; | ||
136 | |||
137 | static struct regulator_consumer_supply beagle_vsim_supply = { | ||
138 | .supply = "vmmc_aux", | ||
139 | }; | ||
140 | |||
123 | static struct gpio_led gpio_leds[]; | 141 | static struct gpio_led gpio_leds[]; |
124 | 142 | ||
125 | static int beagle_twl_gpio_setup(struct device *dev, | 143 | static int beagle_twl_gpio_setup(struct device *dev, |
@@ -130,6 +148,10 @@ static int beagle_twl_gpio_setup(struct device *dev, | |||
130 | mmc[0].gpio_cd = gpio + 0; | 148 | mmc[0].gpio_cd = gpio + 0; |
131 | twl4030_mmc_init(mmc); | 149 | twl4030_mmc_init(mmc); |
132 | 150 | ||
151 | /* link regulators to MMC adapters */ | ||
152 | beagle_vmmc1_supply.dev = mmc[0].dev; | ||
153 | beagle_vsim_supply.dev = mmc[0].dev; | ||
154 | |||
133 | /* REVISIT: need ehci-omap hooks for external VBUS | 155 | /* REVISIT: need ehci-omap hooks for external VBUS |
134 | * power switch and overcurrent detect | 156 | * power switch and overcurrent detect |
135 | */ | 157 | */ |
@@ -158,12 +180,85 @@ static struct twl4030_gpio_platform_data beagle_gpio_data = { | |||
158 | .setup = beagle_twl_gpio_setup, | 180 | .setup = beagle_twl_gpio_setup, |
159 | }; | 181 | }; |
160 | 182 | ||
183 | static struct regulator_consumer_supply beagle_vdac_supply = { | ||
184 | .supply = "vdac", | ||
185 | .dev = &omap3_beagle_lcd_device.dev, | ||
186 | }; | ||
187 | |||
188 | static struct regulator_consumer_supply beagle_vdvi_supply = { | ||
189 | .supply = "vdvi", | ||
190 | .dev = &omap3_beagle_lcd_device.dev, | ||
191 | }; | ||
192 | |||
193 | /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ | ||
194 | static struct regulator_init_data beagle_vmmc1 = { | ||
195 | .constraints = { | ||
196 | .min_uV = 1850000, | ||
197 | .max_uV = 3150000, | ||
198 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
199 | | REGULATOR_MODE_STANDBY, | ||
200 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
201 | | REGULATOR_CHANGE_MODE | ||
202 | | REGULATOR_CHANGE_STATUS, | ||
203 | }, | ||
204 | .num_consumer_supplies = 1, | ||
205 | .consumer_supplies = &beagle_vmmc1_supply, | ||
206 | }; | ||
207 | |||
208 | /* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ | ||
209 | static struct regulator_init_data beagle_vsim = { | ||
210 | .constraints = { | ||
211 | .min_uV = 1800000, | ||
212 | .max_uV = 3000000, | ||
213 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
214 | | REGULATOR_MODE_STANDBY, | ||
215 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
216 | | REGULATOR_CHANGE_MODE | ||
217 | | REGULATOR_CHANGE_STATUS, | ||
218 | }, | ||
219 | .num_consumer_supplies = 1, | ||
220 | .consumer_supplies = &beagle_vsim_supply, | ||
221 | }; | ||
222 | |||
223 | /* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */ | ||
224 | static struct regulator_init_data beagle_vdac = { | ||
225 | .constraints = { | ||
226 | .min_uV = 1800000, | ||
227 | .max_uV = 1800000, | ||
228 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
229 | | REGULATOR_MODE_STANDBY, | ||
230 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
231 | | REGULATOR_CHANGE_STATUS, | ||
232 | }, | ||
233 | .num_consumer_supplies = 1, | ||
234 | .consumer_supplies = &beagle_vdac_supply, | ||
235 | }; | ||
236 | |||
237 | /* VPLL2 for digital video outputs */ | ||
238 | static struct regulator_init_data beagle_vpll2 = { | ||
239 | .constraints = { | ||
240 | .name = "VDVI", | ||
241 | .min_uV = 1800000, | ||
242 | .max_uV = 1800000, | ||
243 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
244 | | REGULATOR_MODE_STANDBY, | ||
245 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
246 | | REGULATOR_CHANGE_STATUS, | ||
247 | }, | ||
248 | .num_consumer_supplies = 1, | ||
249 | .consumer_supplies = &beagle_vdvi_supply, | ||
250 | }; | ||
251 | |||
161 | static struct twl4030_platform_data beagle_twldata = { | 252 | static struct twl4030_platform_data beagle_twldata = { |
162 | .irq_base = TWL4030_IRQ_BASE, | 253 | .irq_base = TWL4030_IRQ_BASE, |
163 | .irq_end = TWL4030_IRQ_END, | 254 | .irq_end = TWL4030_IRQ_END, |
164 | 255 | ||
165 | /* platform_data for children goes here */ | 256 | /* platform_data for children goes here */ |
166 | .gpio = &beagle_gpio_data, | 257 | .gpio = &beagle_gpio_data, |
258 | .vmmc1 = &beagle_vmmc1, | ||
259 | .vsim = &beagle_vsim, | ||
260 | .vdac = &beagle_vdac, | ||
261 | .vpll2 = &beagle_vpll2, | ||
167 | }; | 262 | }; |
168 | 263 | ||
169 | static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { | 264 | static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { |
@@ -195,15 +290,6 @@ static void __init omap3_beagle_init_irq(void) | |||
195 | omap_gpio_init(); | 290 | omap_gpio_init(); |
196 | } | 291 | } |
197 | 292 | ||
198 | static struct platform_device omap3_beagle_lcd_device = { | ||
199 | .name = "omap3beagle_lcd", | ||
200 | .id = -1, | ||
201 | }; | ||
202 | |||
203 | static struct omap_lcd_config omap3_beagle_lcd_config __initdata = { | ||
204 | .ctrl_name = "internal", | ||
205 | }; | ||
206 | |||
207 | static struct gpio_led gpio_leds[] = { | 293 | static struct gpio_led gpio_leds[] = { |
208 | { | 294 | { |
209 | .name = "beagleboard::usr0", | 295 | .name = "beagleboard::usr0", |
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c new file mode 100644 index 000000000000..d3cc145814d0 --- /dev/null +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
@@ -0,0 +1,329 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/board-omap3evm.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Texas Instruments | ||
5 | * | ||
6 | * Modified from mach-omap2/board-3430sdp.c | ||
7 | * | ||
8 | * Initial code: Syed Mohammed Khasim | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/leds.h> | ||
24 | |||
25 | #include <linux/spi/spi.h> | ||
26 | #include <linux/spi/ads7846.h> | ||
27 | #include <linux/i2c/twl4030.h> | ||
28 | |||
29 | #include <mach/hardware.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/mach/arch.h> | ||
32 | #include <asm/mach/map.h> | ||
33 | |||
34 | #include <mach/board.h> | ||
35 | #include <mach/mux.h> | ||
36 | #include <mach/usb.h> | ||
37 | #include <mach/common.h> | ||
38 | #include <mach/mcspi.h> | ||
39 | #include <mach/keypad.h> | ||
40 | |||
41 | #include "sdram-micron-mt46h32m32lf-6.h" | ||
42 | #include "mmc-twl4030.h" | ||
43 | |||
44 | #define OMAP3_EVM_TS_GPIO 175 | ||
45 | |||
46 | #define OMAP3EVM_ETHR_START 0x2c000000 | ||
47 | #define OMAP3EVM_ETHR_SIZE 1024 | ||
48 | #define OMAP3EVM_ETHR_GPIO_IRQ 176 | ||
49 | #define OMAP3EVM_SMC911X_CS 5 | ||
50 | |||
51 | static struct resource omap3evm_smc911x_resources[] = { | ||
52 | [0] = { | ||
53 | .start = OMAP3EVM_ETHR_START, | ||
54 | .end = (OMAP3EVM_ETHR_START + OMAP3EVM_ETHR_SIZE - 1), | ||
55 | .flags = IORESOURCE_MEM, | ||
56 | }, | ||
57 | [1] = { | ||
58 | .start = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ), | ||
59 | .end = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ), | ||
60 | .flags = IORESOURCE_IRQ, | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | static struct platform_device omap3evm_smc911x_device = { | ||
65 | .name = "smc911x", | ||
66 | .id = -1, | ||
67 | .num_resources = ARRAY_SIZE(omap3evm_smc911x_resources), | ||
68 | .resource = &omap3evm_smc911x_resources[0], | ||
69 | }; | ||
70 | |||
71 | static inline void __init omap3evm_init_smc911x(void) | ||
72 | { | ||
73 | int eth_cs; | ||
74 | struct clk *l3ck; | ||
75 | unsigned int rate; | ||
76 | |||
77 | eth_cs = OMAP3EVM_SMC911X_CS; | ||
78 | |||
79 | l3ck = clk_get(NULL, "l3_ck"); | ||
80 | if (IS_ERR(l3ck)) | ||
81 | rate = 100000000; | ||
82 | else | ||
83 | rate = clk_get_rate(l3ck); | ||
84 | |||
85 | if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMC911x irq") < 0) { | ||
86 | printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n", | ||
87 | OMAP3EVM_ETHR_GPIO_IRQ); | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ); | ||
92 | } | ||
93 | |||
94 | static struct omap_uart_config omap3_evm_uart_config __initdata = { | ||
95 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
96 | }; | ||
97 | |||
98 | static struct twl4030_hsmmc_info mmc[] = { | ||
99 | { | ||
100 | .mmc = 1, | ||
101 | .wires = 4, | ||
102 | .gpio_cd = -EINVAL, | ||
103 | .gpio_wp = 63, | ||
104 | }, | ||
105 | {} /* Terminator */ | ||
106 | }; | ||
107 | |||
108 | static struct gpio_led gpio_leds[] = { | ||
109 | { | ||
110 | .name = "omap3evm::ledb", | ||
111 | /* normally not visible (board underside) */ | ||
112 | .default_trigger = "default-on", | ||
113 | .gpio = -EINVAL, /* gets replaced */ | ||
114 | .active_low = true, | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | static struct gpio_led_platform_data gpio_led_info = { | ||
119 | .leds = gpio_leds, | ||
120 | .num_leds = ARRAY_SIZE(gpio_leds), | ||
121 | }; | ||
122 | |||
123 | static struct platform_device leds_gpio = { | ||
124 | .name = "leds-gpio", | ||
125 | .id = -1, | ||
126 | .dev = { | ||
127 | .platform_data = &gpio_led_info, | ||
128 | }, | ||
129 | }; | ||
130 | |||
131 | |||
132 | static int omap3evm_twl_gpio_setup(struct device *dev, | ||
133 | unsigned gpio, unsigned ngpio) | ||
134 | { | ||
135 | /* gpio + 0 is "mmc0_cd" (input/IRQ) */ | ||
136 | omap_cfg_reg(L8_34XX_GPIO63); | ||
137 | mmc[0].gpio_cd = gpio + 0; | ||
138 | twl4030_mmc_init(mmc); | ||
139 | |||
140 | /* | ||
141 | * Most GPIOs are for USB OTG. Some are mostly sent to | ||
142 | * the P2 connector; notably LEDA for the LCD backlight. | ||
143 | */ | ||
144 | |||
145 | /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ | ||
146 | gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; | ||
147 | |||
148 | platform_device_register(&leds_gpio); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static struct twl4030_gpio_platform_data omap3evm_gpio_data = { | ||
154 | .gpio_base = OMAP_MAX_GPIO_LINES, | ||
155 | .irq_base = TWL4030_GPIO_IRQ_BASE, | ||
156 | .irq_end = TWL4030_GPIO_IRQ_END, | ||
157 | .use_leds = true, | ||
158 | .setup = omap3evm_twl_gpio_setup, | ||
159 | }; | ||
160 | |||
161 | static struct twl4030_usb_data omap3evm_usb_data = { | ||
162 | .usb_mode = T2_USB_MODE_ULPI, | ||
163 | }; | ||
164 | |||
165 | static int omap3evm_keymap[] = { | ||
166 | KEY(0, 0, KEY_LEFT), | ||
167 | KEY(0, 1, KEY_RIGHT), | ||
168 | KEY(0, 2, KEY_A), | ||
169 | KEY(0, 3, KEY_B), | ||
170 | KEY(1, 0, KEY_DOWN), | ||
171 | KEY(1, 1, KEY_UP), | ||
172 | KEY(1, 2, KEY_E), | ||
173 | KEY(1, 3, KEY_F), | ||
174 | KEY(2, 0, KEY_ENTER), | ||
175 | KEY(2, 1, KEY_I), | ||
176 | KEY(2, 2, KEY_J), | ||
177 | KEY(2, 3, KEY_K), | ||
178 | KEY(3, 0, KEY_M), | ||
179 | KEY(3, 1, KEY_N), | ||
180 | KEY(3, 2, KEY_O), | ||
181 | KEY(3, 3, KEY_P) | ||
182 | }; | ||
183 | |||
184 | static struct twl4030_keypad_data omap3evm_kp_data = { | ||
185 | .rows = 4, | ||
186 | .cols = 4, | ||
187 | .keymap = omap3evm_keymap, | ||
188 | .keymapsize = ARRAY_SIZE(omap3evm_keymap), | ||
189 | .rep = 1, | ||
190 | }; | ||
191 | |||
192 | static struct twl4030_madc_platform_data omap3evm_madc_data = { | ||
193 | .irq_line = 1, | ||
194 | }; | ||
195 | |||
196 | static struct twl4030_platform_data omap3evm_twldata = { | ||
197 | .irq_base = TWL4030_IRQ_BASE, | ||
198 | .irq_end = TWL4030_IRQ_END, | ||
199 | |||
200 | /* platform_data for children goes here */ | ||
201 | .keypad = &omap3evm_kp_data, | ||
202 | .madc = &omap3evm_madc_data, | ||
203 | .usb = &omap3evm_usb_data, | ||
204 | .gpio = &omap3evm_gpio_data, | ||
205 | }; | ||
206 | |||
207 | static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = { | ||
208 | { | ||
209 | I2C_BOARD_INFO("twl4030", 0x48), | ||
210 | .flags = I2C_CLIENT_WAKE, | ||
211 | .irq = INT_34XX_SYS_NIRQ, | ||
212 | .platform_data = &omap3evm_twldata, | ||
213 | }, | ||
214 | }; | ||
215 | |||
216 | static int __init omap3_evm_i2c_init(void) | ||
217 | { | ||
218 | omap_register_i2c_bus(1, 2600, omap3evm_i2c_boardinfo, | ||
219 | ARRAY_SIZE(omap3evm_i2c_boardinfo)); | ||
220 | omap_register_i2c_bus(2, 400, NULL, 0); | ||
221 | omap_register_i2c_bus(3, 400, NULL, 0); | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static struct platform_device omap3_evm_lcd_device = { | ||
226 | .name = "omap3evm_lcd", | ||
227 | .id = -1, | ||
228 | }; | ||
229 | |||
230 | static struct omap_lcd_config omap3_evm_lcd_config __initdata = { | ||
231 | .ctrl_name = "internal", | ||
232 | }; | ||
233 | |||
234 | static void ads7846_dev_init(void) | ||
235 | { | ||
236 | if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0) | ||
237 | printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); | ||
238 | |||
239 | gpio_direction_input(OMAP3_EVM_TS_GPIO); | ||
240 | |||
241 | omap_set_gpio_debounce(OMAP3_EVM_TS_GPIO, 1); | ||
242 | omap_set_gpio_debounce_time(OMAP3_EVM_TS_GPIO, 0xa); | ||
243 | } | ||
244 | |||
245 | static int ads7846_get_pendown_state(void) | ||
246 | { | ||
247 | return !gpio_get_value(OMAP3_EVM_TS_GPIO); | ||
248 | } | ||
249 | |||
250 | struct ads7846_platform_data ads7846_config = { | ||
251 | .x_max = 0x0fff, | ||
252 | .y_max = 0x0fff, | ||
253 | .x_plate_ohms = 180, | ||
254 | .pressure_max = 255, | ||
255 | .debounce_max = 10, | ||
256 | .debounce_tol = 3, | ||
257 | .debounce_rep = 1, | ||
258 | .get_pendown_state = ads7846_get_pendown_state, | ||
259 | .keep_vref_on = 1, | ||
260 | .settle_delay_usecs = 150, | ||
261 | }; | ||
262 | |||
263 | static struct omap2_mcspi_device_config ads7846_mcspi_config = { | ||
264 | .turbo_mode = 0, | ||
265 | .single_channel = 1, /* 0: slave, 1: master */ | ||
266 | }; | ||
267 | |||
268 | struct spi_board_info omap3evm_spi_board_info[] = { | ||
269 | [0] = { | ||
270 | .modalias = "ads7846", | ||
271 | .bus_num = 1, | ||
272 | .chip_select = 0, | ||
273 | .max_speed_hz = 1500000, | ||
274 | .controller_data = &ads7846_mcspi_config, | ||
275 | .irq = OMAP_GPIO_IRQ(OMAP3_EVM_TS_GPIO), | ||
276 | .platform_data = &ads7846_config, | ||
277 | }, | ||
278 | }; | ||
279 | |||
280 | static void __init omap3_evm_init_irq(void) | ||
281 | { | ||
282 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params); | ||
283 | omap_init_irq(); | ||
284 | omap_gpio_init(); | ||
285 | omap3evm_init_smc911x(); | ||
286 | } | ||
287 | |||
288 | static struct omap_board_config_kernel omap3_evm_config[] __initdata = { | ||
289 | { OMAP_TAG_UART, &omap3_evm_uart_config }, | ||
290 | { OMAP_TAG_LCD, &omap3_evm_lcd_config }, | ||
291 | }; | ||
292 | |||
293 | static struct platform_device *omap3_evm_devices[] __initdata = { | ||
294 | &omap3_evm_lcd_device, | ||
295 | &omap3evm_smc911x_device, | ||
296 | }; | ||
297 | |||
298 | static void __init omap3_evm_init(void) | ||
299 | { | ||
300 | omap3_evm_i2c_init(); | ||
301 | |||
302 | platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices)); | ||
303 | omap_board_config = omap3_evm_config; | ||
304 | omap_board_config_size = ARRAY_SIZE(omap3_evm_config); | ||
305 | |||
306 | spi_register_board_info(omap3evm_spi_board_info, | ||
307 | ARRAY_SIZE(omap3evm_spi_board_info)); | ||
308 | |||
309 | omap_serial_init(); | ||
310 | usb_musb_init(); | ||
311 | ads7846_dev_init(); | ||
312 | } | ||
313 | |||
314 | static void __init omap3_evm_map_io(void) | ||
315 | { | ||
316 | omap2_set_globals_343x(); | ||
317 | omap2_map_common_io(); | ||
318 | } | ||
319 | |||
320 | MACHINE_START(OMAP3EVM, "OMAP3 EVM") | ||
321 | /* Maintainer: Syed Mohammed Khasim - Texas Instruments */ | ||
322 | .phys_io = 0x48000000, | ||
323 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | ||
324 | .boot_params = 0x80000100, | ||
325 | .map_io = omap3_evm_map_io, | ||
326 | .init_irq = omap3_evm_init_irq, | ||
327 | .init_machine = omap3_evm_init, | ||
328 | .timer = &omap_timer, | ||
329 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 3571bb47ab86..e32aa23ce962 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
@@ -23,7 +23,11 @@ | |||
23 | 23 | ||
24 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
25 | #include <linux/spi/ads7846.h> | 25 | #include <linux/spi/ads7846.h> |
26 | #include <linux/regulator/machine.h> | ||
26 | #include <linux/i2c/twl4030.h> | 27 | #include <linux/i2c/twl4030.h> |
28 | #include <linux/leds.h> | ||
29 | #include <linux/input.h> | ||
30 | #include <linux/gpio_keys.h> | ||
27 | 31 | ||
28 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
29 | #include <asm/mach/arch.h> | 33 | #include <asm/mach/arch.h> |
@@ -35,12 +39,154 @@ | |||
35 | #include <mach/hardware.h> | 39 | #include <mach/hardware.h> |
36 | #include <mach/mcspi.h> | 40 | #include <mach/mcspi.h> |
37 | #include <mach/usb.h> | 41 | #include <mach/usb.h> |
42 | #include <mach/keypad.h> | ||
38 | 43 | ||
39 | #include "sdram-micron-mt46h32m32lf-6.h" | 44 | #include "sdram-micron-mt46h32m32lf-6.h" |
40 | #include "mmc-twl4030.h" | 45 | #include "mmc-twl4030.h" |
41 | 46 | ||
42 | #define OMAP3_PANDORA_TS_GPIO 94 | 47 | #define OMAP3_PANDORA_TS_GPIO 94 |
43 | 48 | ||
49 | /* hardware debounce: (value + 1) * 31us */ | ||
50 | #define GPIO_DEBOUNCE_TIME 127 | ||
51 | |||
52 | static struct gpio_led pandora_gpio_leds[] = { | ||
53 | { | ||
54 | .name = "pandora::sd1", | ||
55 | .default_trigger = "mmc0", | ||
56 | .gpio = 128, | ||
57 | }, { | ||
58 | .name = "pandora::sd2", | ||
59 | .default_trigger = "mmc1", | ||
60 | .gpio = 129, | ||
61 | }, { | ||
62 | .name = "pandora::bluetooth", | ||
63 | .gpio = 158, | ||
64 | }, { | ||
65 | .name = "pandora::wifi", | ||
66 | .gpio = 159, | ||
67 | }, | ||
68 | }; | ||
69 | |||
70 | static struct gpio_led_platform_data pandora_gpio_led_data = { | ||
71 | .leds = pandora_gpio_leds, | ||
72 | .num_leds = ARRAY_SIZE(pandora_gpio_leds), | ||
73 | }; | ||
74 | |||
75 | static struct platform_device pandora_leds_gpio = { | ||
76 | .name = "leds-gpio", | ||
77 | .id = -1, | ||
78 | .dev = { | ||
79 | .platform_data = &pandora_gpio_led_data, | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | #define GPIO_BUTTON(gpio_num, ev_type, ev_code, act_low, descr) \ | ||
84 | { \ | ||
85 | .gpio = gpio_num, \ | ||
86 | .type = ev_type, \ | ||
87 | .code = ev_code, \ | ||
88 | .active_low = act_low, \ | ||
89 | .desc = "btn " descr, \ | ||
90 | } | ||
91 | |||
92 | #define GPIO_BUTTON_LOW(gpio_num, event_code, description) \ | ||
93 | GPIO_BUTTON(gpio_num, EV_KEY, event_code, 1, description) | ||
94 | |||
95 | static struct gpio_keys_button pandora_gpio_keys[] = { | ||
96 | GPIO_BUTTON_LOW(110, KEY_UP, "up"), | ||
97 | GPIO_BUTTON_LOW(103, KEY_DOWN, "down"), | ||
98 | GPIO_BUTTON_LOW(96, KEY_LEFT, "left"), | ||
99 | GPIO_BUTTON_LOW(98, KEY_RIGHT, "right"), | ||
100 | GPIO_BUTTON_LOW(111, BTN_A, "a"), | ||
101 | GPIO_BUTTON_LOW(106, BTN_B, "b"), | ||
102 | GPIO_BUTTON_LOW(109, BTN_X, "x"), | ||
103 | GPIO_BUTTON_LOW(101, BTN_Y, "y"), | ||
104 | GPIO_BUTTON_LOW(102, BTN_TL, "l"), | ||
105 | GPIO_BUTTON_LOW(97, BTN_TL2, "l2"), | ||
106 | GPIO_BUTTON_LOW(105, BTN_TR, "r"), | ||
107 | GPIO_BUTTON_LOW(107, BTN_TR2, "r2"), | ||
108 | GPIO_BUTTON_LOW(104, KEY_LEFTCTRL, "ctrl"), | ||
109 | GPIO_BUTTON_LOW(99, KEY_MENU, "menu"), | ||
110 | GPIO_BUTTON_LOW(176, KEY_COFFEE, "hold"), | ||
111 | GPIO_BUTTON(100, EV_KEY, KEY_LEFTALT, 0, "alt"), | ||
112 | GPIO_BUTTON(108, EV_SW, SW_LID, 1, "lid"), | ||
113 | }; | ||
114 | |||
115 | static struct gpio_keys_platform_data pandora_gpio_key_info = { | ||
116 | .buttons = pandora_gpio_keys, | ||
117 | .nbuttons = ARRAY_SIZE(pandora_gpio_keys), | ||
118 | }; | ||
119 | |||
120 | static struct platform_device pandora_keys_gpio = { | ||
121 | .name = "gpio-keys", | ||
122 | .id = -1, | ||
123 | .dev = { | ||
124 | .platform_data = &pandora_gpio_key_info, | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | static void __init pandora_keys_gpio_init(void) | ||
129 | { | ||
130 | /* set debounce time for GPIO banks 4 and 6 */ | ||
131 | omap_set_gpio_debounce_time(32 * 3, GPIO_DEBOUNCE_TIME); | ||
132 | omap_set_gpio_debounce_time(32 * 5, GPIO_DEBOUNCE_TIME); | ||
133 | } | ||
134 | |||
135 | static int pandora_keypad_map[] = { | ||
136 | /* col, row, code */ | ||
137 | KEY(0, 0, KEY_9), | ||
138 | KEY(0, 1, KEY_0), | ||
139 | KEY(0, 2, KEY_BACKSPACE), | ||
140 | KEY(0, 3, KEY_O), | ||
141 | KEY(0, 4, KEY_P), | ||
142 | KEY(0, 5, KEY_K), | ||
143 | KEY(0, 6, KEY_L), | ||
144 | KEY(0, 7, KEY_ENTER), | ||
145 | KEY(1, 0, KEY_8), | ||
146 | KEY(1, 1, KEY_7), | ||
147 | KEY(1, 2, KEY_6), | ||
148 | KEY(1, 3, KEY_5), | ||
149 | KEY(1, 4, KEY_4), | ||
150 | KEY(1, 5, KEY_3), | ||
151 | KEY(1, 6, KEY_2), | ||
152 | KEY(1, 7, KEY_1), | ||
153 | KEY(2, 0, KEY_I), | ||
154 | KEY(2, 1, KEY_U), | ||
155 | KEY(2, 2, KEY_Y), | ||
156 | KEY(2, 3, KEY_T), | ||
157 | KEY(2, 4, KEY_R), | ||
158 | KEY(2, 5, KEY_E), | ||
159 | KEY(2, 6, KEY_W), | ||
160 | KEY(2, 7, KEY_Q), | ||
161 | KEY(3, 0, KEY_J), | ||
162 | KEY(3, 1, KEY_H), | ||
163 | KEY(3, 2, KEY_G), | ||
164 | KEY(3, 3, KEY_F), | ||
165 | KEY(3, 4, KEY_D), | ||
166 | KEY(3, 5, KEY_S), | ||
167 | KEY(3, 6, KEY_A), | ||
168 | KEY(3, 7, KEY_LEFTSHIFT), | ||
169 | KEY(4, 0, KEY_N), | ||
170 | KEY(4, 1, KEY_B), | ||
171 | KEY(4, 2, KEY_V), | ||
172 | KEY(4, 3, KEY_C), | ||
173 | KEY(4, 4, KEY_X), | ||
174 | KEY(4, 5, KEY_Z), | ||
175 | KEY(4, 6, KEY_DOT), | ||
176 | KEY(4, 7, KEY_COMMA), | ||
177 | KEY(5, 0, KEY_M), | ||
178 | KEY(5, 1, KEY_SPACE), | ||
179 | KEY(5, 2, KEY_FN), | ||
180 | }; | ||
181 | |||
182 | static struct twl4030_keypad_data pandora_kp_data = { | ||
183 | .rows = 8, | ||
184 | .cols = 6, | ||
185 | .keymap = pandora_keypad_map, | ||
186 | .keymapsize = ARRAY_SIZE(pandora_keypad_map), | ||
187 | .rep = 1, | ||
188 | }; | ||
189 | |||
44 | static struct twl4030_hsmmc_info omap3pandora_mmc[] = { | 190 | static struct twl4030_hsmmc_info omap3pandora_mmc[] = { |
45 | { | 191 | { |
46 | .mmc = 1, | 192 | .mmc = 1, |
@@ -70,6 +216,14 @@ static struct omap_uart_config omap3pandora_uart_config __initdata = { | |||
70 | .enabled_uarts = (1 << 2), /* UART3 */ | 216 | .enabled_uarts = (1 << 2), /* UART3 */ |
71 | }; | 217 | }; |
72 | 218 | ||
219 | static struct regulator_consumer_supply pandora_vmmc1_supply = { | ||
220 | .supply = "vmmc", | ||
221 | }; | ||
222 | |||
223 | static struct regulator_consumer_supply pandora_vmmc2_supply = { | ||
224 | .supply = "vmmc", | ||
225 | }; | ||
226 | |||
73 | static int omap3pandora_twl_gpio_setup(struct device *dev, | 227 | static int omap3pandora_twl_gpio_setup(struct device *dev, |
74 | unsigned gpio, unsigned ngpio) | 228 | unsigned gpio, unsigned ngpio) |
75 | { | 229 | { |
@@ -78,6 +232,10 @@ static int omap3pandora_twl_gpio_setup(struct device *dev, | |||
78 | omap3pandora_mmc[1].gpio_cd = gpio + 1; | 232 | omap3pandora_mmc[1].gpio_cd = gpio + 1; |
79 | twl4030_mmc_init(omap3pandora_mmc); | 233 | twl4030_mmc_init(omap3pandora_mmc); |
80 | 234 | ||
235 | /* link regulators to MMC adapters */ | ||
236 | pandora_vmmc1_supply.dev = omap3pandora_mmc[0].dev; | ||
237 | pandora_vmmc2_supply.dev = omap3pandora_mmc[1].dev; | ||
238 | |||
81 | return 0; | 239 | return 0; |
82 | } | 240 | } |
83 | 241 | ||
@@ -88,6 +246,36 @@ static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { | |||
88 | .setup = omap3pandora_twl_gpio_setup, | 246 | .setup = omap3pandora_twl_gpio_setup, |
89 | }; | 247 | }; |
90 | 248 | ||
249 | /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ | ||
250 | static struct regulator_init_data pandora_vmmc1 = { | ||
251 | .constraints = { | ||
252 | .min_uV = 1850000, | ||
253 | .max_uV = 3150000, | ||
254 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
255 | | REGULATOR_MODE_STANDBY, | ||
256 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
257 | | REGULATOR_CHANGE_MODE | ||
258 | | REGULATOR_CHANGE_STATUS, | ||
259 | }, | ||
260 | .num_consumer_supplies = 1, | ||
261 | .consumer_supplies = &pandora_vmmc1_supply, | ||
262 | }; | ||
263 | |||
264 | /* VMMC2 for MMC2 pins CMD, CLK, DAT0..DAT3 (max 100 mA) */ | ||
265 | static struct regulator_init_data pandora_vmmc2 = { | ||
266 | .constraints = { | ||
267 | .min_uV = 1850000, | ||
268 | .max_uV = 3150000, | ||
269 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
270 | | REGULATOR_MODE_STANDBY, | ||
271 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
272 | | REGULATOR_CHANGE_MODE | ||
273 | | REGULATOR_CHANGE_STATUS, | ||
274 | }, | ||
275 | .num_consumer_supplies = 1, | ||
276 | .consumer_supplies = &pandora_vmmc2_supply, | ||
277 | }; | ||
278 | |||
91 | static struct twl4030_usb_data omap3pandora_usb_data = { | 279 | static struct twl4030_usb_data omap3pandora_usb_data = { |
92 | .usb_mode = T2_USB_MODE_ULPI, | 280 | .usb_mode = T2_USB_MODE_ULPI, |
93 | }; | 281 | }; |
@@ -97,6 +285,9 @@ static struct twl4030_platform_data omap3pandora_twldata = { | |||
97 | .irq_end = TWL4030_IRQ_END, | 285 | .irq_end = TWL4030_IRQ_END, |
98 | .gpio = &omap3pandora_gpio_data, | 286 | .gpio = &omap3pandora_gpio_data, |
99 | .usb = &omap3pandora_usb_data, | 287 | .usb = &omap3pandora_usb_data, |
288 | .vmmc1 = &pandora_vmmc1, | ||
289 | .vmmc2 = &pandora_vmmc2, | ||
290 | .keypad = &pandora_kp_data, | ||
100 | }; | 291 | }; |
101 | 292 | ||
102 | static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = { | 293 | static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = { |
@@ -189,6 +380,8 @@ static struct omap_board_config_kernel omap3pandora_config[] __initdata = { | |||
189 | 380 | ||
190 | static struct platform_device *omap3pandora_devices[] __initdata = { | 381 | static struct platform_device *omap3pandora_devices[] __initdata = { |
191 | &omap3pandora_lcd_device, | 382 | &omap3pandora_lcd_device, |
383 | &pandora_leds_gpio, | ||
384 | &pandora_keys_gpio, | ||
192 | }; | 385 | }; |
193 | 386 | ||
194 | static void __init omap3pandora_init(void) | 387 | static void __init omap3pandora_init(void) |
@@ -202,6 +395,7 @@ static void __init omap3pandora_init(void) | |||
202 | spi_register_board_info(omap3pandora_spi_board_info, | 395 | spi_register_board_info(omap3pandora_spi_board_info, |
203 | ARRAY_SIZE(omap3pandora_spi_board_info)); | 396 | ARRAY_SIZE(omap3pandora_spi_board_info)); |
204 | omap3pandora_ads7846_init(); | 397 | omap3pandora_ads7846_init(); |
398 | pandora_keys_gpio_init(); | ||
205 | usb_musb_init(); | 399 | usb_musb_init(); |
206 | } | 400 | } |
207 | 401 | ||
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index c7443ff98ee2..dff5528fbfb5 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c | |||
@@ -27,6 +27,7 @@ | |||
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 | #include <linux/i2c/twl4030.h> |
30 | #include <linux/regulator/machine.h> | ||
30 | 31 | ||
31 | #include <linux/mtd/mtd.h> | 32 | #include <linux/mtd/mtd.h> |
32 | #include <linux/mtd/nand.h> | 33 | #include <linux/mtd/nand.h> |
@@ -272,21 +273,76 @@ static struct omap_uart_config overo_uart_config __initdata = { | |||
272 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 273 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), |
273 | }; | 274 | }; |
274 | 275 | ||
276 | static struct twl4030_hsmmc_info mmc[] = { | ||
277 | { | ||
278 | .mmc = 1, | ||
279 | .wires = 4, | ||
280 | .gpio_cd = -EINVAL, | ||
281 | .gpio_wp = -EINVAL, | ||
282 | }, | ||
283 | { | ||
284 | .mmc = 2, | ||
285 | .wires = 4, | ||
286 | .gpio_cd = -EINVAL, | ||
287 | .gpio_wp = -EINVAL, | ||
288 | .transceiver = true, | ||
289 | .ocr_mask = 0x00100000, /* 3.3V */ | ||
290 | }, | ||
291 | {} /* Terminator */ | ||
292 | }; | ||
293 | |||
294 | static struct regulator_consumer_supply overo_vmmc1_supply = { | ||
295 | .supply = "vmmc", | ||
296 | }; | ||
297 | |||
298 | static int overo_twl_gpio_setup(struct device *dev, | ||
299 | unsigned gpio, unsigned ngpio) | ||
300 | { | ||
301 | twl4030_mmc_init(mmc); | ||
302 | |||
303 | overo_vmmc1_supply.dev = mmc[0].dev; | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | |||
275 | static struct twl4030_gpio_platform_data overo_gpio_data = { | 308 | static struct twl4030_gpio_platform_data overo_gpio_data = { |
276 | .gpio_base = OMAP_MAX_GPIO_LINES, | 309 | .gpio_base = OMAP_MAX_GPIO_LINES, |
277 | .irq_base = TWL4030_GPIO_IRQ_BASE, | 310 | .irq_base = TWL4030_GPIO_IRQ_BASE, |
278 | .irq_end = TWL4030_GPIO_IRQ_END, | 311 | .irq_end = TWL4030_GPIO_IRQ_END, |
312 | .setup = overo_twl_gpio_setup, | ||
313 | }; | ||
314 | |||
315 | static struct twl4030_usb_data overo_usb_data = { | ||
316 | .usb_mode = T2_USB_MODE_ULPI, | ||
317 | }; | ||
318 | |||
319 | static struct regulator_init_data overo_vmmc1 = { | ||
320 | .constraints = { | ||
321 | .min_uV = 1850000, | ||
322 | .max_uV = 3150000, | ||
323 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
324 | | REGULATOR_MODE_STANDBY, | ||
325 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
326 | | REGULATOR_CHANGE_MODE | ||
327 | | REGULATOR_CHANGE_STATUS, | ||
328 | }, | ||
329 | .num_consumer_supplies = 1, | ||
330 | .consumer_supplies = &overo_vmmc1_supply, | ||
279 | }; | 331 | }; |
280 | 332 | ||
333 | /* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */ | ||
334 | |||
281 | static struct twl4030_platform_data overo_twldata = { | 335 | static struct twl4030_platform_data overo_twldata = { |
282 | .irq_base = TWL4030_IRQ_BASE, | 336 | .irq_base = TWL4030_IRQ_BASE, |
283 | .irq_end = TWL4030_IRQ_END, | 337 | .irq_end = TWL4030_IRQ_END, |
284 | .gpio = &overo_gpio_data, | 338 | .gpio = &overo_gpio_data, |
339 | .usb = &overo_usb_data, | ||
340 | .vmmc1 = &overo_vmmc1, | ||
285 | }; | 341 | }; |
286 | 342 | ||
287 | static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { | 343 | static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { |
288 | { | 344 | { |
289 | I2C_BOARD_INFO("twl4030", 0x48), | 345 | I2C_BOARD_INFO("tps65950", 0x48), |
290 | .flags = I2C_CLIENT_WAKE, | 346 | .flags = I2C_CLIENT_WAKE, |
291 | .irq = INT_34XX_SYS_NIRQ, | 347 | .irq = INT_34XX_SYS_NIRQ, |
292 | .platform_data = &overo_twldata, | 348 | .platform_data = &overo_twldata, |
@@ -327,23 +383,6 @@ static struct platform_device *overo_devices[] __initdata = { | |||
327 | &overo_lcd_device, | 383 | &overo_lcd_device, |
328 | }; | 384 | }; |
329 | 385 | ||
330 | static struct twl4030_hsmmc_info mmc[] __initdata = { | ||
331 | { | ||
332 | .mmc = 1, | ||
333 | .wires = 4, | ||
334 | .gpio_cd = -EINVAL, | ||
335 | .gpio_wp = -EINVAL, | ||
336 | }, | ||
337 | { | ||
338 | .mmc = 2, | ||
339 | .wires = 4, | ||
340 | .gpio_cd = -EINVAL, | ||
341 | .gpio_wp = -EINVAL, | ||
342 | .transceiver = true, | ||
343 | }, | ||
344 | {} /* Terminator */ | ||
345 | }; | ||
346 | |||
347 | static void __init overo_init(void) | 386 | static void __init overo_init(void) |
348 | { | 387 | { |
349 | overo_i2c_init(); | 388 | overo_i2c_init(); |
@@ -351,7 +390,6 @@ static void __init overo_init(void) | |||
351 | omap_board_config = overo_config; | 390 | omap_board_config = overo_config; |
352 | omap_board_config_size = ARRAY_SIZE(overo_config); | 391 | omap_board_config_size = ARRAY_SIZE(overo_config); |
353 | omap_serial_init(); | 392 | omap_serial_init(); |
354 | twl4030_mmc_init(mmc); | ||
355 | overo_flash_init(); | 393 | overo_flash_init(); |
356 | usb_musb_init(); | 394 | usb_musb_init(); |
357 | overo_ads7846_init(); | 395 | overo_ads7846_init(); |
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 233c7454d84f..da93b86234ed 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
@@ -32,6 +32,9 @@ | |||
32 | 32 | ||
33 | #include "mmc-twl4030.h" | 33 | #include "mmc-twl4030.h" |
34 | 34 | ||
35 | #define SYSTEM_REV_B_USES_VAUX3 0x1699 | ||
36 | #define SYSTEM_REV_S_USES_VAUX3 0x8 | ||
37 | |||
35 | static int rx51_keymap[] = { | 38 | static int rx51_keymap[] = { |
36 | KEY(0, 0, KEY_Q), | 39 | KEY(0, 0, KEY_Q), |
37 | KEY(0, 1, KEY_W), | 40 | KEY(0, 1, KEY_W), |
@@ -147,7 +150,7 @@ static struct regulator_init_data rx51_vaux2 = { | |||
147 | }; | 150 | }; |
148 | 151 | ||
149 | /* VAUX3 - adds more power to VIO_18 rail */ | 152 | /* VAUX3 - adds more power to VIO_18 rail */ |
150 | static struct regulator_init_data rx51_vaux3 = { | 153 | static struct regulator_init_data rx51_vaux3_cam = { |
151 | .constraints = { | 154 | .constraints = { |
152 | .name = "VCAM_DIG_18", | 155 | .name = "VCAM_DIG_18", |
153 | .min_uV = 1800000, | 156 | .min_uV = 1800000, |
@@ -160,6 +163,22 @@ static struct regulator_init_data rx51_vaux3 = { | |||
160 | }, | 163 | }, |
161 | }; | 164 | }; |
162 | 165 | ||
166 | static struct regulator_init_data rx51_vaux3_mmc = { | ||
167 | .constraints = { | ||
168 | .name = "VMMC2_30", | ||
169 | .min_uV = 2800000, | ||
170 | .max_uV = 3000000, | ||
171 | .apply_uV = true, | ||
172 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
173 | | REGULATOR_MODE_STANDBY, | ||
174 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
175 | | REGULATOR_CHANGE_MODE | ||
176 | | REGULATOR_CHANGE_STATUS, | ||
177 | }, | ||
178 | .num_consumer_supplies = 1, | ||
179 | .consumer_supplies = &rx51_vmmc2_supply, | ||
180 | }; | ||
181 | |||
163 | static struct regulator_init_data rx51_vaux4 = { | 182 | static struct regulator_init_data rx51_vaux4 = { |
164 | .constraints = { | 183 | .constraints = { |
165 | .name = "VCAM_ANA_28", | 184 | .name = "VCAM_ANA_28", |
@@ -270,10 +289,8 @@ static struct twl4030_platform_data rx51_twldata = { | |||
270 | 289 | ||
271 | .vaux1 = &rx51_vaux1, | 290 | .vaux1 = &rx51_vaux1, |
272 | .vaux2 = &rx51_vaux2, | 291 | .vaux2 = &rx51_vaux2, |
273 | .vaux3 = &rx51_vaux3, | ||
274 | .vaux4 = &rx51_vaux4, | 292 | .vaux4 = &rx51_vaux4, |
275 | .vmmc1 = &rx51_vmmc1, | 293 | .vmmc1 = &rx51_vmmc1, |
276 | .vmmc2 = &rx51_vmmc2, | ||
277 | .vsim = &rx51_vsim, | 294 | .vsim = &rx51_vsim, |
278 | .vdac = &rx51_vdac, | 295 | .vdac = &rx51_vdac, |
279 | }; | 296 | }; |
@@ -289,6 +306,13 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = { | |||
289 | 306 | ||
290 | static int __init rx51_i2c_init(void) | 307 | static int __init rx51_i2c_init(void) |
291 | { | 308 | { |
309 | if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) || | ||
310 | system_rev >= SYSTEM_REV_B_USES_VAUX3) | ||
311 | rx51_twldata.vaux3 = &rx51_vaux3_mmc; | ||
312 | else { | ||
313 | rx51_twldata.vaux3 = &rx51_vaux3_cam; | ||
314 | rx51_twldata.vmmc2 = &rx51_vmmc2; | ||
315 | } | ||
292 | omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1, | 316 | omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1, |
293 | ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); | 317 | ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); |
294 | omap_register_i2c_bus(2, 100, NULL, 0); | 318 | omap_register_i2c_bus(2, 100, NULL, 0); |
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c new file mode 100644 index 000000000000..bac5c4321ff7 --- /dev/null +++ b/arch/arm/mach-omap2/board-zoom-debugboard.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Texas Instruments Inc. | ||
3 | * Mikkel Christensen <mlc@ti.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/serial_8250.h> | ||
14 | #include <linux/smsc911x.h> | ||
15 | |||
16 | #include <mach/gpmc.h> | ||
17 | |||
18 | #define ZOOM2_SMSC911X_CS 7 | ||
19 | #define ZOOM2_SMSC911X_GPIO 158 | ||
20 | #define ZOOM2_QUADUART_CS 3 | ||
21 | #define ZOOM2_QUADUART_GPIO 102 | ||
22 | #define QUART_CLK 1843200 | ||
23 | #define DEBUG_BASE 0x08000000 | ||
24 | #define ZOOM2_ETHR_START DEBUG_BASE | ||
25 | |||
26 | static struct resource zoom2_smsc911x_resources[] = { | ||
27 | [0] = { | ||
28 | .start = ZOOM2_ETHR_START, | ||
29 | .end = ZOOM2_ETHR_START + SZ_4K, | ||
30 | .flags = IORESOURCE_MEM, | ||
31 | }, | ||
32 | [1] = { | ||
33 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, | ||
34 | }, | ||
35 | }; | ||
36 | |||
37 | static struct smsc911x_platform_config zoom2_smsc911x_config = { | ||
38 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | ||
39 | .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, | ||
40 | .flags = SMSC911X_USE_32BIT, | ||
41 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
42 | }; | ||
43 | |||
44 | static struct platform_device zoom2_smsc911x_device = { | ||
45 | .name = "smsc911x", | ||
46 | .id = -1, | ||
47 | .num_resources = ARRAY_SIZE(zoom2_smsc911x_resources), | ||
48 | .resource = zoom2_smsc911x_resources, | ||
49 | .dev = { | ||
50 | .platform_data = &zoom2_smsc911x_config, | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | static inline void __init zoom2_init_smsc911x(void) | ||
55 | { | ||
56 | int eth_cs; | ||
57 | unsigned long cs_mem_base; | ||
58 | int eth_gpio = 0; | ||
59 | |||
60 | eth_cs = ZOOM2_SMSC911X_CS; | ||
61 | |||
62 | if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) { | ||
63 | printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n"); | ||
64 | return; | ||
65 | } | ||
66 | |||
67 | zoom2_smsc911x_resources[0].start = cs_mem_base + 0x0; | ||
68 | zoom2_smsc911x_resources[0].end = cs_mem_base + 0xff; | ||
69 | |||
70 | eth_gpio = ZOOM2_SMSC911X_GPIO; | ||
71 | |||
72 | zoom2_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio); | ||
73 | |||
74 | if (gpio_request(eth_gpio, "smsc911x irq") < 0) { | ||
75 | printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n", | ||
76 | eth_gpio); | ||
77 | return; | ||
78 | } | ||
79 | gpio_direction_input(eth_gpio); | ||
80 | } | ||
81 | |||
82 | static struct plat_serial8250_port serial_platform_data[] = { | ||
83 | { | ||
84 | .mapbase = 0x10000000, | ||
85 | .irq = OMAP_GPIO_IRQ(102), | ||
86 | .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ, | ||
87 | .iotype = UPIO_MEM, | ||
88 | .regshift = 1, | ||
89 | .uartclk = QUART_CLK, | ||
90 | }, { | ||
91 | .flags = 0 | ||
92 | } | ||
93 | }; | ||
94 | |||
95 | static struct platform_device zoom2_debugboard_serial_device = { | ||
96 | .name = "serial8250", | ||
97 | .id = PLAT8250_DEV_PLATFORM1, | ||
98 | .dev = { | ||
99 | .platform_data = serial_platform_data, | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | static inline void __init zoom2_init_quaduart(void) | ||
104 | { | ||
105 | int quart_cs; | ||
106 | unsigned long cs_mem_base; | ||
107 | int quart_gpio = 0; | ||
108 | |||
109 | quart_cs = ZOOM2_QUADUART_CS; | ||
110 | |||
111 | if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) { | ||
112 | printk(KERN_ERR "Failed to request GPMC mem" | ||
113 | "for Quad UART(TL16CP754C)\n"); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | quart_gpio = ZOOM2_QUADUART_GPIO; | ||
118 | |||
119 | if (gpio_request(quart_gpio, "TL16CP754C GPIO") < 0) { | ||
120 | printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n", | ||
121 | quart_gpio); | ||
122 | return; | ||
123 | } | ||
124 | gpio_direction_input(quart_gpio); | ||
125 | } | ||
126 | |||
127 | static inline int omap_zoom2_debugboard_detect(void) | ||
128 | { | ||
129 | int debug_board_detect = 0; | ||
130 | |||
131 | debug_board_detect = ZOOM2_SMSC911X_GPIO; | ||
132 | |||
133 | if (gpio_request(debug_board_detect, "Zoom2 debug board detect") < 0) { | ||
134 | printk(KERN_ERR "Failed to request GPIO%d for Zoom2 debug" | ||
135 | "board detect\n", debug_board_detect); | ||
136 | return 0; | ||
137 | } | ||
138 | gpio_direction_input(debug_board_detect); | ||
139 | |||
140 | if (!gpio_get_value(debug_board_detect)) { | ||
141 | gpio_free(debug_board_detect); | ||
142 | return 0; | ||
143 | } | ||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | static struct platform_device *zoom2_devices[] __initdata = { | ||
148 | &zoom2_smsc911x_device, | ||
149 | &zoom2_debugboard_serial_device, | ||
150 | }; | ||
151 | |||
152 | int __init omap_zoom2_debugboard_init(void) | ||
153 | { | ||
154 | if (!omap_zoom2_debugboard_detect()) | ||
155 | return 0; | ||
156 | |||
157 | zoom2_init_smsc911x(); | ||
158 | zoom2_init_quaduart(); | ||
159 | return platform_add_devices(zoom2_devices, ARRAY_SIZE(zoom2_devices)); | ||
160 | } | ||
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c new file mode 100644 index 000000000000..bcc0f7632dea --- /dev/null +++ b/arch/arm/mach-omap2/board-zoom2.c | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Texas Instruments Inc. | ||
3 | * Mikkel Christensen <mlc@ti.com> | ||
4 | * | ||
5 | * Modified from mach-omap2/board-ldp.c | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/i2c/twl4030.h> | ||
17 | |||
18 | #include <asm/mach-types.h> | ||
19 | #include <asm/mach/arch.h> | ||
20 | |||
21 | #include <mach/common.h> | ||
22 | #include <mach/usb.h> | ||
23 | |||
24 | #include "mmc-twl4030.h" | ||
25 | |||
26 | static void __init omap_zoom2_init_irq(void) | ||
27 | { | ||
28 | omap2_init_common_hw(NULL); | ||
29 | omap_init_irq(); | ||
30 | omap_gpio_init(); | ||
31 | } | ||
32 | |||
33 | static struct omap_uart_config zoom2_uart_config __initdata = { | ||
34 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
35 | }; | ||
36 | |||
37 | static struct omap_board_config_kernel zoom2_config[] __initdata = { | ||
38 | { OMAP_TAG_UART, &zoom2_uart_config }, | ||
39 | }; | ||
40 | |||
41 | static struct twl4030_gpio_platform_data zoom2_gpio_data = { | ||
42 | .gpio_base = OMAP_MAX_GPIO_LINES, | ||
43 | .irq_base = TWL4030_GPIO_IRQ_BASE, | ||
44 | .irq_end = TWL4030_GPIO_IRQ_END, | ||
45 | }; | ||
46 | |||
47 | static struct twl4030_platform_data zoom2_twldata = { | ||
48 | .irq_base = TWL4030_IRQ_BASE, | ||
49 | .irq_end = TWL4030_IRQ_END, | ||
50 | |||
51 | /* platform_data for children goes here */ | ||
52 | .gpio = &zoom2_gpio_data, | ||
53 | }; | ||
54 | |||
55 | static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = { | ||
56 | { | ||
57 | I2C_BOARD_INFO("twl4030", 0x48), | ||
58 | .flags = I2C_CLIENT_WAKE, | ||
59 | .irq = INT_34XX_SYS_NIRQ, | ||
60 | .platform_data = &zoom2_twldata, | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | static int __init omap_i2c_init(void) | ||
65 | { | ||
66 | omap_register_i2c_bus(1, 2600, zoom2_i2c_boardinfo, | ||
67 | ARRAY_SIZE(zoom2_i2c_boardinfo)); | ||
68 | omap_register_i2c_bus(2, 400, NULL, 0); | ||
69 | omap_register_i2c_bus(3, 400, NULL, 0); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static struct twl4030_hsmmc_info mmc[] __initdata = { | ||
74 | { | ||
75 | .mmc = 1, | ||
76 | .wires = 4, | ||
77 | .gpio_cd = -EINVAL, | ||
78 | .gpio_wp = -EINVAL, | ||
79 | }, | ||
80 | {} /* Terminator */ | ||
81 | }; | ||
82 | |||
83 | extern int __init omap_zoom2_debugboard_init(void); | ||
84 | |||
85 | static void __init omap_zoom2_init(void) | ||
86 | { | ||
87 | omap_i2c_init(); | ||
88 | omap_board_config = zoom2_config; | ||
89 | omap_board_config_size = ARRAY_SIZE(zoom2_config); | ||
90 | omap_serial_init(); | ||
91 | omap_zoom2_debugboard_init(); | ||
92 | twl4030_mmc_init(mmc); | ||
93 | usb_musb_init(); | ||
94 | } | ||
95 | |||
96 | static void __init omap_zoom2_map_io(void) | ||
97 | { | ||
98 | omap2_set_globals_343x(); | ||
99 | omap2_map_common_io(); | ||
100 | } | ||
101 | |||
102 | MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board") | ||
103 | .phys_io = 0x48000000, | ||
104 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | ||
105 | .boot_params = 0x80000100, | ||
106 | .map_io = omap_zoom2_map_io, | ||
107 | .init_irq = omap_zoom2_init_irq, | ||
108 | .init_machine = omap_zoom2_init, | ||
109 | .timer = &omap_timer, | ||
110 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c index dc40b3e72206..9756a878fd90 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ b/arch/arm/mach-omap2/mmc-twl4030.c | |||
@@ -16,8 +16,8 @@ | |||
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
19 | #include <linux/i2c/twl4030.h> | 19 | #include <linux/mmc/host.h> |
20 | #include <linux/regulator/machine.h> | 20 | #include <linux/regulator/consumer.h> |
21 | 21 | ||
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | #include <mach/control.h> | 23 | #include <mach/control.h> |
@@ -26,31 +26,9 @@ | |||
26 | 26 | ||
27 | #include "mmc-twl4030.h" | 27 | #include "mmc-twl4030.h" |
28 | 28 | ||
29 | #if defined(CONFIG_TWL4030_CORE) && \ | ||
30 | (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) | ||
31 | 29 | ||
32 | #define LDO_CLR 0x00 | 30 | #if defined(CONFIG_REGULATOR) && \ |
33 | #define VSEL_S2_CLR 0x40 | 31 | (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) |
34 | |||
35 | #define VMMC1_DEV_GRP 0x27 | ||
36 | #define VMMC1_CLR 0x00 | ||
37 | #define VMMC1_315V 0x03 | ||
38 | #define VMMC1_300V 0x02 | ||
39 | #define VMMC1_285V 0x01 | ||
40 | #define VMMC1_185V 0x00 | ||
41 | #define VMMC1_DEDICATED 0x2A | ||
42 | |||
43 | #define VMMC2_DEV_GRP 0x2B | ||
44 | #define VMMC2_CLR 0x40 | ||
45 | #define VMMC2_315V 0x0c | ||
46 | #define VMMC2_300V 0x0b | ||
47 | #define VMMC2_285V 0x0a | ||
48 | #define VMMC2_280V 0x09 | ||
49 | #define VMMC2_260V 0x08 | ||
50 | #define VMMC2_185V 0x06 | ||
51 | #define VMMC2_DEDICATED 0x2E | ||
52 | |||
53 | #define VMMC_DEV_GRP_P1 0x20 | ||
54 | 32 | ||
55 | static u16 control_pbias_offset; | 33 | static u16 control_pbias_offset; |
56 | static u16 control_devconf1_offset; | 34 | static u16 control_devconf1_offset; |
@@ -59,19 +37,16 @@ static u16 control_devconf1_offset; | |||
59 | 37 | ||
60 | static struct twl_mmc_controller { | 38 | static struct twl_mmc_controller { |
61 | struct omap_mmc_platform_data *mmc; | 39 | struct omap_mmc_platform_data *mmc; |
62 | u8 twl_vmmc_dev_grp; | 40 | /* Vcc == configured supply |
63 | u8 twl_mmc_dedicated; | 41 | * Vcc_alt == optional |
64 | char name[HSMMC_NAME_LEN + 1]; | 42 | * - MMC1, supply for DAT4..DAT7 |
65 | } hsmmc[OMAP34XX_NR_MMC] = { | 43 | * - MMC2/MMC2, external level shifter voltage supply, for |
66 | { | 44 | * chip (SDIO, eMMC, etc) or transceiver (MMC2 only) |
67 | .twl_vmmc_dev_grp = VMMC1_DEV_GRP, | 45 | */ |
68 | .twl_mmc_dedicated = VMMC1_DEDICATED, | 46 | struct regulator *vcc; |
69 | }, | 47 | struct regulator *vcc_aux; |
70 | { | 48 | char name[HSMMC_NAME_LEN + 1]; |
71 | .twl_vmmc_dev_grp = VMMC2_DEV_GRP, | 49 | } hsmmc[OMAP34XX_NR_MMC]; |
72 | .twl_mmc_dedicated = VMMC2_DEDICATED, | ||
73 | }, | ||
74 | }; | ||
75 | 50 | ||
76 | static int twl_mmc_card_detect(int irq) | 51 | static int twl_mmc_card_detect(int irq) |
77 | { | 52 | { |
@@ -117,16 +92,60 @@ static int twl_mmc_late_init(struct device *dev) | |||
117 | int ret = 0; | 92 | int ret = 0; |
118 | int i; | 93 | int i; |
119 | 94 | ||
120 | ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd"); | 95 | /* MMC/SD/SDIO doesn't require a card detect switch */ |
121 | if (ret) | 96 | if (gpio_is_valid(mmc->slots[0].switch_pin)) { |
122 | goto done; | 97 | ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd"); |
123 | ret = gpio_direction_input(mmc->slots[0].switch_pin); | 98 | if (ret) |
124 | if (ret) | 99 | goto done; |
125 | goto err; | 100 | ret = gpio_direction_input(mmc->slots[0].switch_pin); |
101 | if (ret) | ||
102 | goto err; | ||
103 | } | ||
126 | 104 | ||
105 | /* require at least main regulator */ | ||
127 | for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { | 106 | for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { |
128 | if (hsmmc[i].name == mmc->slots[0].name) { | 107 | if (hsmmc[i].name == mmc->slots[0].name) { |
108 | struct regulator *reg; | ||
109 | |||
129 | hsmmc[i].mmc = mmc; | 110 | hsmmc[i].mmc = mmc; |
111 | |||
112 | reg = regulator_get(dev, "vmmc"); | ||
113 | if (IS_ERR(reg)) { | ||
114 | dev_dbg(dev, "vmmc regulator missing\n"); | ||
115 | /* HACK: until fixed.c regulator is usable, | ||
116 | * we don't require a main regulator | ||
117 | * for MMC2 or MMC3 | ||
118 | */ | ||
119 | if (i != 0) | ||
120 | break; | ||
121 | ret = PTR_ERR(reg); | ||
122 | goto err; | ||
123 | } | ||
124 | hsmmc[i].vcc = reg; | ||
125 | mmc->slots[0].ocr_mask = mmc_regulator_get_ocrmask(reg); | ||
126 | |||
127 | /* allow an aux regulator */ | ||
128 | reg = regulator_get(dev, "vmmc_aux"); | ||
129 | hsmmc[i].vcc_aux = IS_ERR(reg) ? NULL : reg; | ||
130 | |||
131 | /* UGLY HACK: workaround regulator framework bugs. | ||
132 | * When the bootloader leaves a supply active, it's | ||
133 | * initialized with zero usecount ... and we can't | ||
134 | * disable it without first enabling it. Until the | ||
135 | * framework is fixed, we need a workaround like this | ||
136 | * (which is safe for MMC, but not in general). | ||
137 | */ | ||
138 | if (regulator_is_enabled(hsmmc[i].vcc) > 0) { | ||
139 | regulator_enable(hsmmc[i].vcc); | ||
140 | regulator_disable(hsmmc[i].vcc); | ||
141 | } | ||
142 | if (hsmmc[i].vcc_aux) { | ||
143 | if (regulator_is_enabled(reg) > 0) { | ||
144 | regulator_enable(reg); | ||
145 | regulator_disable(reg); | ||
146 | } | ||
147 | } | ||
148 | |||
130 | break; | 149 | break; |
131 | } | 150 | } |
132 | } | 151 | } |
@@ -173,96 +192,6 @@ static int twl_mmc_resume(struct device *dev, int slot) | |||
173 | #define twl_mmc_resume NULL | 192 | #define twl_mmc_resume NULL |
174 | #endif | 193 | #endif |
175 | 194 | ||
176 | /* | ||
177 | * Sets the MMC voltage in twl4030 | ||
178 | */ | ||
179 | |||
180 | #define MMC1_OCR (MMC_VDD_165_195 \ | ||
181 | |MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32) | ||
182 | #define MMC2_OCR (MMC_VDD_165_195 \ | ||
183 | |MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28 \ | ||
184 | |MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32) | ||
185 | |||
186 | static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd) | ||
187 | { | ||
188 | int ret; | ||
189 | u8 vmmc = 0, dev_grp_val; | ||
190 | |||
191 | if (!vdd) | ||
192 | goto doit; | ||
193 | |||
194 | if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) { | ||
195 | /* VMMC1: max 220 mA. And for 8-bit mode, | ||
196 | * VSIM: max 50 mA | ||
197 | */ | ||
198 | switch (1 << vdd) { | ||
199 | case MMC_VDD_165_195: | ||
200 | vmmc = VMMC1_185V; | ||
201 | /* and VSIM_180V */ | ||
202 | break; | ||
203 | case MMC_VDD_28_29: | ||
204 | vmmc = VMMC1_285V; | ||
205 | /* and VSIM_280V */ | ||
206 | break; | ||
207 | case MMC_VDD_29_30: | ||
208 | case MMC_VDD_30_31: | ||
209 | vmmc = VMMC1_300V; | ||
210 | /* and VSIM_300V */ | ||
211 | break; | ||
212 | case MMC_VDD_31_32: | ||
213 | vmmc = VMMC1_315V; | ||
214 | /* error if VSIM needed */ | ||
215 | break; | ||
216 | default: | ||
217 | return -EINVAL; | ||
218 | } | ||
219 | } else if (c->twl_vmmc_dev_grp == VMMC2_DEV_GRP) { | ||
220 | /* VMMC2: max 100 mA */ | ||
221 | switch (1 << vdd) { | ||
222 | case MMC_VDD_165_195: | ||
223 | vmmc = VMMC2_185V; | ||
224 | break; | ||
225 | case MMC_VDD_25_26: | ||
226 | case MMC_VDD_26_27: | ||
227 | vmmc = VMMC2_260V; | ||
228 | break; | ||
229 | case MMC_VDD_27_28: | ||
230 | vmmc = VMMC2_280V; | ||
231 | break; | ||
232 | case MMC_VDD_28_29: | ||
233 | vmmc = VMMC2_285V; | ||
234 | break; | ||
235 | case MMC_VDD_29_30: | ||
236 | case MMC_VDD_30_31: | ||
237 | vmmc = VMMC2_300V; | ||
238 | break; | ||
239 | case MMC_VDD_31_32: | ||
240 | vmmc = VMMC2_315V; | ||
241 | break; | ||
242 | default: | ||
243 | return -EINVAL; | ||
244 | } | ||
245 | } else { | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | |||
249 | doit: | ||
250 | if (vdd) | ||
251 | dev_grp_val = VMMC_DEV_GRP_P1; /* Power up */ | ||
252 | else | ||
253 | dev_grp_val = LDO_CLR; /* Power down */ | ||
254 | |||
255 | ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, | ||
256 | dev_grp_val, c->twl_vmmc_dev_grp); | ||
257 | if (ret || !vdd) | ||
258 | return ret; | ||
259 | |||
260 | ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, | ||
261 | vmmc, c->twl_mmc_dedicated); | ||
262 | |||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | 195 | static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, |
267 | int vdd) | 196 | int vdd) |
268 | { | 197 | { |
@@ -273,11 +202,13 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | |||
273 | 202 | ||
274 | /* | 203 | /* |
275 | * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the | 204 | * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the |
276 | * card using the same TWL VMMC1 supply (hsmmc[0]); OMAP has both | 205 | * card with Vcc regulator (from twl4030 or whatever). OMAP has both |
277 | * 1.8V and 3.0V modes, controlled by the PBIAS register. | 206 | * 1.8V and 3.0V modes, controlled by the PBIAS register. |
278 | * | 207 | * |
279 | * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which | 208 | * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which |
280 | * is most naturally TWL VSIM; those pins also use PBIAS. | 209 | * is most naturally TWL VSIM; those pins also use PBIAS. |
210 | * | ||
211 | * FIXME handle VMMC1A as needed ... | ||
281 | */ | 212 | */ |
282 | if (power_on) { | 213 | if (power_on) { |
283 | if (cpu_is_omap2430()) { | 214 | if (cpu_is_omap2430()) { |
@@ -300,7 +231,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | |||
300 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; | 231 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; |
301 | omap_ctrl_writel(reg, control_pbias_offset); | 232 | omap_ctrl_writel(reg, control_pbias_offset); |
302 | 233 | ||
303 | ret = twl_mmc_set_voltage(c, vdd); | 234 | ret = mmc_regulator_set_ocr(c->vcc, vdd); |
304 | 235 | ||
305 | /* 100ms delay required for PBIAS configuration */ | 236 | /* 100ms delay required for PBIAS configuration */ |
306 | msleep(100); | 237 | msleep(100); |
@@ -316,7 +247,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | |||
316 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; | 247 | reg &= ~OMAP2_PBIASLITEPWRDNZ0; |
317 | omap_ctrl_writel(reg, control_pbias_offset); | 248 | omap_ctrl_writel(reg, control_pbias_offset); |
318 | 249 | ||
319 | ret = twl_mmc_set_voltage(c, 0); | 250 | ret = mmc_regulator_set_ocr(c->vcc, 0); |
320 | 251 | ||
321 | /* 100ms delay required for PBIAS configuration */ | 252 | /* 100ms delay required for PBIAS configuration */ |
322 | msleep(100); | 253 | msleep(100); |
@@ -329,19 +260,33 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | |||
329 | return ret; | 260 | return ret; |
330 | } | 261 | } |
331 | 262 | ||
332 | static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vdd) | 263 | static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int vdd) |
333 | { | 264 | { |
334 | int ret; | 265 | int ret = 0; |
335 | struct twl_mmc_controller *c = &hsmmc[1]; | 266 | struct twl_mmc_controller *c = &hsmmc[1]; |
336 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 267 | struct omap_mmc_platform_data *mmc = dev->platform_data; |
337 | 268 | ||
269 | /* If we don't see a Vcc regulator, assume it's a fixed | ||
270 | * voltage always-on regulator. | ||
271 | */ | ||
272 | if (!c->vcc) | ||
273 | return 0; | ||
274 | |||
338 | /* | 275 | /* |
339 | * Assume TWL VMMC2 (hsmmc[1]) is used only to power the card ... OMAP | 276 | * Assume Vcc regulator is used only to power the card ... OMAP |
340 | * VDDS is used to power the pins, optionally with a transceiver to | 277 | * VDDS is used to power the pins, optionally with a transceiver to |
341 | * support cards using voltages other than VDDS (1.8V nominal). When a | 278 | * support cards using voltages other than VDDS (1.8V nominal). When a |
342 | * transceiver is used, DAT3..7 are muxed as transceiver control pins. | 279 | * transceiver is used, DAT3..7 are muxed as transceiver control pins. |
280 | * | ||
281 | * In some cases this regulator won't support enable/disable; | ||
282 | * e.g. it's a fixed rail for a WLAN chip. | ||
283 | * | ||
284 | * In other cases vcc_aux switches interface power. Example, for | ||
285 | * eMMC cards it represents VccQ. Sometimes transceivers or SDIO | ||
286 | * chips/cards need an interface voltage rail too. | ||
343 | */ | 287 | */ |
344 | if (power_on) { | 288 | if (power_on) { |
289 | /* only MMC2 supports a CLKIN */ | ||
345 | if (mmc->slots[0].internal_clock) { | 290 | if (mmc->slots[0].internal_clock) { |
346 | u32 reg; | 291 | u32 reg; |
347 | 292 | ||
@@ -349,24 +294,23 @@ static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vd | |||
349 | reg |= OMAP2_MMCSDIO2ADPCLKISEL; | 294 | reg |= OMAP2_MMCSDIO2ADPCLKISEL; |
350 | omap_ctrl_writel(reg, control_devconf1_offset); | 295 | omap_ctrl_writel(reg, control_devconf1_offset); |
351 | } | 296 | } |
352 | ret = twl_mmc_set_voltage(c, vdd); | 297 | ret = mmc_regulator_set_ocr(c->vcc, vdd); |
298 | /* enable interface voltage rail, if needed */ | ||
299 | if (ret == 0 && c->vcc_aux) { | ||
300 | ret = regulator_enable(c->vcc_aux); | ||
301 | if (ret < 0) | ||
302 | ret = mmc_regulator_set_ocr(c->vcc, 0); | ||
303 | } | ||
353 | } else { | 304 | } else { |
354 | ret = twl_mmc_set_voltage(c, 0); | 305 | if (c->vcc_aux && (ret = regulator_is_enabled(c->vcc_aux)) > 0) |
306 | ret = regulator_disable(c->vcc_aux); | ||
307 | if (ret == 0) | ||
308 | ret = mmc_regulator_set_ocr(c->vcc, 0); | ||
355 | } | 309 | } |
356 | 310 | ||
357 | return ret; | 311 | return ret; |
358 | } | 312 | } |
359 | 313 | ||
360 | static int twl_mmc3_set_power(struct device *dev, int slot, int power_on, | ||
361 | int vdd) | ||
362 | { | ||
363 | /* | ||
364 | * Assume MMC3 has self-powered device connected, for example on-board | ||
365 | * chip with external power source. | ||
366 | */ | ||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; | 314 | static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; |
371 | 315 | ||
372 | void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | 316 | void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) |
@@ -412,10 +356,10 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
412 | mmc->slots[0].wires = c->wires; | 356 | mmc->slots[0].wires = c->wires; |
413 | mmc->slots[0].internal_clock = !c->ext_clock; | 357 | mmc->slots[0].internal_clock = !c->ext_clock; |
414 | mmc->dma_mask = 0xffffffff; | 358 | mmc->dma_mask = 0xffffffff; |
359 | mmc->init = twl_mmc_late_init; | ||
415 | 360 | ||
416 | /* note: twl4030 card detect GPIOs normally switch VMMCx ... */ | 361 | /* note: twl4030 card detect GPIOs can disable VMMCx ... */ |
417 | if (gpio_is_valid(c->gpio_cd)) { | 362 | if (gpio_is_valid(c->gpio_cd)) { |
418 | mmc->init = twl_mmc_late_init; | ||
419 | mmc->cleanup = twl_mmc_cleanup; | 363 | mmc->cleanup = twl_mmc_cleanup; |
420 | mmc->suspend = twl_mmc_suspend; | 364 | mmc->suspend = twl_mmc_suspend; |
421 | mmc->resume = twl_mmc_resume; | 365 | mmc->resume = twl_mmc_resume; |
@@ -439,26 +383,28 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
439 | } else | 383 | } else |
440 | mmc->slots[0].gpio_wp = -EINVAL; | 384 | mmc->slots[0].gpio_wp = -EINVAL; |
441 | 385 | ||
442 | /* NOTE: we assume OMAP's MMC1 and MMC2 use | 386 | /* NOTE: MMC slots should have a Vcc regulator set up. |
443 | * the TWL4030's VMMC1 and VMMC2, respectively; | 387 | * This may be from a TWL4030-family chip, another |
444 | * and that MMC3 device has it's own power source. | 388 | * controllable regulator, or a fixed supply. |
389 | * | ||
390 | * temporary HACK: ocr_mask instead of fixed supply | ||
445 | */ | 391 | */ |
392 | mmc->slots[0].ocr_mask = c->ocr_mask; | ||
446 | 393 | ||
447 | switch (c->mmc) { | 394 | switch (c->mmc) { |
448 | case 1: | 395 | case 1: |
396 | /* on-chip level shifting via PBIAS0/PBIAS1 */ | ||
449 | mmc->slots[0].set_power = twl_mmc1_set_power; | 397 | mmc->slots[0].set_power = twl_mmc1_set_power; |
450 | mmc->slots[0].ocr_mask = MMC1_OCR; | ||
451 | break; | 398 | break; |
452 | case 2: | 399 | case 2: |
453 | mmc->slots[0].set_power = twl_mmc2_set_power; | 400 | if (c->ext_clock) |
454 | if (c->transceiver) | 401 | c->transceiver = 1; |
455 | mmc->slots[0].ocr_mask = MMC2_OCR; | 402 | if (c->transceiver && c->wires > 4) |
456 | else | 403 | c->wires = 4; |
457 | mmc->slots[0].ocr_mask = MMC_VDD_165_195; | 404 | /* FALLTHROUGH */ |
458 | break; | ||
459 | case 3: | 405 | case 3: |
460 | mmc->slots[0].set_power = twl_mmc3_set_power; | 406 | /* off-chip level shifting, or none */ |
461 | mmc->slots[0].ocr_mask = MMC_VDD_165_195; | 407 | mmc->slots[0].set_power = twl_mmc23_set_power; |
462 | break; | 408 | break; |
463 | default: | 409 | default: |
464 | pr_err("MMC%d configuration not supported!\n", c->mmc); | 410 | pr_err("MMC%d configuration not supported!\n", c->mmc); |
diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h index ea59e8624290..3807c45c9a6c 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.h +++ b/arch/arm/mach-omap2/mmc-twl4030.h | |||
@@ -16,9 +16,10 @@ struct twl4030_hsmmc_info { | |||
16 | int gpio_wp; /* or -EINVAL */ | 16 | int gpio_wp; /* or -EINVAL */ |
17 | char *name; /* or NULL for default */ | 17 | char *name; /* or NULL for default */ |
18 | struct device *dev; /* returned: pointer to mmc adapter */ | 18 | struct device *dev; /* returned: pointer to mmc adapter */ |
19 | int ocr_mask; /* temporary HACK */ | ||
19 | }; | 20 | }; |
20 | 21 | ||
21 | #if defined(CONFIG_TWL4030_CORE) && \ | 22 | #if defined(CONFIG_REGULATOR) && \ |
22 | (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ | 23 | (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ |
23 | defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) | 24 | defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) |
24 | 25 | ||