Commit | Line | Data |
---|---|---|
78ded168 MD |
1 | /* |
2 | * APE6EVM board support | |
3 | * | |
4 | * Copyright (C) 2013 Renesas Solutions Corp. | |
5 | * Copyright (C) 2013 Magnus Damm | |
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 as published by | |
9 | * the Free Software Foundation; version 2 of the License. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
78ded168 MD |
15 | */ |
16 | ||
15351a7a | 17 | #include <linux/gpio.h> |
5c6db1a4 SH |
18 | #include <linux/gpio_keys.h> |
19 | #include <linux/input.h> | |
78ded168 | 20 | #include <linux/interrupt.h> |
974b072f MD |
21 | #include <linux/irqchip.h> |
22 | #include <linux/irqchip/arm-gic.h> | |
78ded168 | 23 | #include <linux/kernel.h> |
f79d68da | 24 | #include <linux/mfd/tmio.h> |
87116132 GL |
25 | #include <linux/mmc/host.h> |
26 | #include <linux/mmc/sh_mmcif.h> | |
f79d68da | 27 | #include <linux/mmc/sh_mobile_sdhi.h> |
2c56055c | 28 | #include <linux/pinctrl/machine.h> |
78ded168 | 29 | #include <linux/platform_device.h> |
15351a7a MD |
30 | #include <linux/regulator/fixed.h> |
31 | #include <linux/regulator/machine.h> | |
b8568a04 | 32 | #include <linux/sh_clk.h> |
15351a7a | 33 | #include <linux/smsc911x.h> |
fac49568 | 34 | |
78ded168 MD |
35 | #include <asm/mach-types.h> |
36 | #include <asm/mach/arch.h> | |
37 | ||
fd44aa5e | 38 | #include "common.h" |
b6bab126 | 39 | #include "irqs.h" |
fac49568 | 40 | #include "r8a73a4.h" |
78ded168 | 41 | |
9adad788 SH |
42 | /* LEDS */ |
43 | static struct gpio_led ape6evm_leds[] = { | |
44 | { | |
45 | .name = "gnss-en", | |
46 | .gpio = 28, | |
47 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | |
48 | }, { | |
49 | .name = "nfc-nrst", | |
50 | .gpio = 126, | |
51 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | |
52 | }, { | |
53 | .name = "gnss-nrst", | |
54 | .gpio = 132, | |
55 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | |
56 | }, { | |
57 | .name = "bt-wakeup", | |
58 | .gpio = 232, | |
59 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | |
60 | }, { | |
61 | .name = "strobe", | |
62 | .gpio = 250, | |
63 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | |
64 | }, { | |
65 | .name = "bbresetout", | |
66 | .gpio = 288, | |
67 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | |
68 | }, | |
69 | }; | |
70 | ||
71 | static __initdata struct gpio_led_platform_data ape6evm_leds_pdata = { | |
72 | .leds = ape6evm_leds, | |
73 | .num_leds = ARRAY_SIZE(ape6evm_leds), | |
74 | }; | |
75 | ||
5c6db1a4 SH |
76 | /* GPIO KEY */ |
77 | #define GPIO_KEY(c, g, d, ...) \ | |
78 | { .code = c, .gpio = g, .desc = d, .active_low = 1 } | |
79 | ||
80 | static struct gpio_keys_button gpio_buttons[] = { | |
81 | GPIO_KEY(KEY_0, 324, "S16"), | |
82 | GPIO_KEY(KEY_MENU, 325, "S17"), | |
83 | GPIO_KEY(KEY_HOME, 326, "S18"), | |
84 | GPIO_KEY(KEY_BACK, 327, "S19"), | |
85 | GPIO_KEY(KEY_VOLUMEUP, 328, "S20"), | |
86 | GPIO_KEY(KEY_VOLUMEDOWN, 329, "S21"), | |
87 | }; | |
88 | ||
40fca03c | 89 | static struct gpio_keys_platform_data ape6evm_keys_pdata __initdata = { |
5c6db1a4 SH |
90 | .buttons = gpio_buttons, |
91 | .nbuttons = ARRAY_SIZE(gpio_buttons), | |
92 | }; | |
93 | ||
15351a7a MD |
94 | /* Dummy supplies, where voltage doesn't matter */ |
95 | static struct regulator_consumer_supply dummy_supplies[] = { | |
96 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | |
97 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | |
98 | }; | |
99 | ||
100 | /* SMSC LAN9220 */ | |
23f1751c | 101 | static const struct resource lan9220_res[] __initconst = { |
15351a7a MD |
102 | DEFINE_RES_MEM(0x08000000, 0x1000), |
103 | { | |
104 | .start = irq_pin(40), /* IRQ40 */ | |
105 | .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH, | |
106 | }, | |
107 | }; | |
108 | ||
23f1751c | 109 | static const struct smsc911x_platform_config lan9220_data __initconst = { |
15351a7a MD |
110 | .flags = SMSC911X_USE_32BIT, |
111 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, | |
112 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, | |
113 | }; | |
114 | ||
87116132 | 115 | /* |
8b98126d GL |
116 | * MMC0 power supplies: |
117 | * Both Vcc and VccQ to eMMC on APE6EVM are supplied by a tps80032 voltage | |
118 | * regulator. Until support for it is added to this file we simulate the | |
119 | * Vcc supply by a fixed always-on regulator | |
87116132 | 120 | */ |
8b98126d | 121 | static struct regulator_consumer_supply vcc_mmc0_consumers[] = |
87116132 GL |
122 | { |
123 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | |
8b98126d GL |
124 | }; |
125 | ||
126 | /* | |
127 | * SDHI0 power supplies: | |
128 | * Vcc to SDHI0 on APE6EVM is supplied by a GPIO-switchable regulator. VccQ is | |
129 | * provided by the same tps80032 regulator as both MMC0 voltages - see comment | |
130 | * above | |
131 | */ | |
132 | static struct regulator_consumer_supply vcc_sdhi0_consumers[] = | |
133 | { | |
f79d68da | 134 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), |
8b98126d GL |
135 | }; |
136 | ||
137 | static struct regulator_init_data vcc_sdhi0_init_data = { | |
138 | .constraints = { | |
139 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
140 | }, | |
141 | .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi0_consumers), | |
142 | .consumer_supplies = vcc_sdhi0_consumers, | |
143 | }; | |
144 | ||
145 | static const struct fixed_voltage_config vcc_sdhi0_info __initconst = { | |
146 | .supply_name = "SDHI0 Vcc", | |
147 | .microvolts = 3300000, | |
148 | .gpio = 76, | |
149 | .enable_high = 1, | |
150 | .init_data = &vcc_sdhi0_init_data, | |
151 | }; | |
152 | ||
153 | /* | |
154 | * SDHI1 power supplies: | |
155 | * Vcc and VccQ to SDHI1 on APE6EVM are both fixed at 3.3V | |
156 | */ | |
157 | static struct regulator_consumer_supply vcc_sdhi1_consumers[] = | |
158 | { | |
f79d68da | 159 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), |
87116132 GL |
160 | }; |
161 | ||
162 | /* MMCIF */ | |
23f1751c | 163 | static const struct sh_mmcif_plat_data mmcif0_pdata __initconst = { |
87116132 | 164 | .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, |
7a2a7a37 GL |
165 | .slave_id_tx = SHDMA_SLAVE_MMCIF0_TX, |
166 | .slave_id_rx = SHDMA_SLAVE_MMCIF0_RX, | |
a2eeabcc | 167 | .ccs_unsupported = true, |
87116132 GL |
168 | }; |
169 | ||
23f1751c | 170 | static const struct resource mmcif0_resources[] __initconst = { |
61a4fd12 | 171 | DEFINE_RES_MEM(0xee200000, 0x100), |
87116132 GL |
172 | DEFINE_RES_IRQ(gic_spi(169)), |
173 | }; | |
174 | ||
f79d68da | 175 | /* SDHI0 */ |
23f1751c | 176 | static const struct sh_mobile_sdhi_info sdhi0_pdata __initconst = { |
f79d68da GL |
177 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE, |
178 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, | |
179 | }; | |
180 | ||
23f1751c | 181 | static const struct resource sdhi0_resources[] __initconst = { |
e33e6968 | 182 | DEFINE_RES_MEM(0xee100000, 0x100), |
f79d68da GL |
183 | DEFINE_RES_IRQ(gic_spi(165)), |
184 | }; | |
185 | ||
186 | /* SDHI1 */ | |
23f1751c | 187 | static const struct sh_mobile_sdhi_info sdhi1_pdata __initconst = { |
f79d68da GL |
188 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE, |
189 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | | |
190 | MMC_CAP_NEEDS_POLL, | |
191 | }; | |
192 | ||
23f1751c | 193 | static const struct resource sdhi1_resources[] __initconst = { |
e33e6968 | 194 | DEFINE_RES_MEM(0xee120000, 0x100), |
f79d68da GL |
195 | DEFINE_RES_IRQ(gic_spi(166)), |
196 | }; | |
197 | ||
23f1751c | 198 | static const struct pinctrl_map ape6evm_pinctrl_map[] __initconst = { |
2c56055c MD |
199 | /* SCIFA0 console */ |
200 | PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a73a4", | |
201 | "scifa0_data", "scifa0"), | |
15351a7a MD |
202 | /* SMSC */ |
203 | PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a73a4", | |
204 | "irqc_irq40", "irqc"), | |
87116132 GL |
205 | /* MMCIF0 */ |
206 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a73a4", | |
207 | "mmc0_data8", "mmc0"), | |
208 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a73a4", | |
209 | "mmc0_ctrl", "mmc0"), | |
f79d68da GL |
210 | /* SDHI0: uSD: no WP */ |
211 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a73a4", | |
212 | "sdhi0_data4", "sdhi0"), | |
213 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a73a4", | |
214 | "sdhi0_ctrl", "sdhi0"), | |
215 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a73a4", | |
216 | "sdhi0_cd", "sdhi0"), | |
217 | /* SDHI1 */ | |
218 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a73a4", | |
219 | "sdhi1_data4", "sdhi1"), | |
220 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a73a4", | |
221 | "sdhi1_ctrl", "sdhi1"), | |
2c56055c MD |
222 | }; |
223 | ||
78ded168 MD |
224 | static void __init ape6evm_add_standard_devices(void) |
225 | { | |
b8568a04 KM |
226 | |
227 | struct clk *parent; | |
228 | struct clk *mp; | |
229 | ||
78ded168 | 230 | r8a73a4_clock_init(); |
b8568a04 KM |
231 | |
232 | /* MP clock parent = extal2 */ | |
233 | parent = clk_get(NULL, "extal2"); | |
234 | mp = clk_get(NULL, "mp"); | |
235 | BUG_ON(IS_ERR(parent) || IS_ERR(mp)); | |
236 | ||
237 | clk_set_parent(mp, parent); | |
238 | clk_put(parent); | |
239 | clk_put(mp); | |
240 | ||
2c56055c MD |
241 | pinctrl_register_mappings(ape6evm_pinctrl_map, |
242 | ARRAY_SIZE(ape6evm_pinctrl_map)); | |
243 | r8a73a4_pinmux_init(); | |
78ded168 | 244 | r8a73a4_add_standard_devices(); |
15351a7a MD |
245 | |
246 | /* LAN9220 ethernet */ | |
247 | gpio_request_one(270, GPIOF_OUT_INIT_HIGH, NULL); /* smsc9220 RESET */ | |
248 | ||
249 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | |
250 | ||
d2168146 | 251 | platform_device_register_resndata(NULL, "smsc911x", -1, |
15351a7a MD |
252 | lan9220_res, ARRAY_SIZE(lan9220_res), |
253 | &lan9220_data, sizeof(lan9220_data)); | |
8b98126d GL |
254 | |
255 | regulator_register_always_on(1, "MMC0 Vcc", vcc_mmc0_consumers, | |
256 | ARRAY_SIZE(vcc_mmc0_consumers), 2800000); | |
d2168146 | 257 | platform_device_register_resndata(NULL, "sh_mmcif", 0, |
87116132 GL |
258 | mmcif0_resources, ARRAY_SIZE(mmcif0_resources), |
259 | &mmcif0_pdata, sizeof(mmcif0_pdata)); | |
d2168146 | 260 | platform_device_register_data(NULL, "reg-fixed-voltage", 2, |
8b98126d | 261 | &vcc_sdhi0_info, sizeof(vcc_sdhi0_info)); |
d2168146 | 262 | platform_device_register_resndata(NULL, "sh_mobile_sdhi", 0, |
f79d68da GL |
263 | sdhi0_resources, ARRAY_SIZE(sdhi0_resources), |
264 | &sdhi0_pdata, sizeof(sdhi0_pdata)); | |
8b98126d GL |
265 | regulator_register_always_on(3, "SDHI1 Vcc", vcc_sdhi1_consumers, |
266 | ARRAY_SIZE(vcc_sdhi1_consumers), 3300000); | |
d2168146 | 267 | platform_device_register_resndata(NULL, "sh_mobile_sdhi", 1, |
f79d68da GL |
268 | sdhi1_resources, ARRAY_SIZE(sdhi1_resources), |
269 | &sdhi1_pdata, sizeof(sdhi1_pdata)); | |
d2168146 | 270 | platform_device_register_data(NULL, "gpio-keys", -1, |
5c6db1a4 SH |
271 | &ape6evm_keys_pdata, |
272 | sizeof(ape6evm_keys_pdata)); | |
d2168146 | 273 | platform_device_register_data(NULL, "leds-gpio", -1, |
9adad788 SH |
274 | &ape6evm_leds_pdata, |
275 | sizeof(ape6evm_leds_pdata)); | |
78ded168 MD |
276 | } |
277 | ||
974b072f MD |
278 | static void __init ape6evm_legacy_init_time(void) |
279 | { | |
280 | /* Do not invoke DT-based timers via clocksource_of_init() */ | |
281 | } | |
282 | ||
283 | static void __init ape6evm_legacy_init_irq(void) | |
284 | { | |
285 | void __iomem *gic_dist_base = ioremap_nocache(0xf1001000, 0x1000); | |
286 | void __iomem *gic_cpu_base = ioremap_nocache(0xf1002000, 0x1000); | |
287 | ||
288 | gic_init(0, 29, gic_dist_base, gic_cpu_base); | |
289 | ||
290 | /* Do not invoke DT-based interrupt code via irqchip_init() */ | |
291 | } | |
292 | ||
293 | ||
78ded168 MD |
294 | static const char *ape6evm_boards_compat_dt[] __initdata = { |
295 | "renesas,ape6evm", | |
296 | NULL, | |
297 | }; | |
298 | ||
299 | DT_MACHINE_START(APE6EVM_DT, "ape6evm") | |
911f7cec | 300 | .init_early = shmobile_init_delay, |
974b072f | 301 | .init_irq = ape6evm_legacy_init_irq, |
78ded168 | 302 | .init_machine = ape6evm_add_standard_devices, |
509c42a5 | 303 | .init_late = shmobile_init_late, |
78ded168 | 304 | .dt_compat = ape6evm_boards_compat_dt, |
974b072f | 305 | .init_time = ape6evm_legacy_init_time, |
78ded168 | 306 | MACHINE_END |