blob: 613bdd89bcfaa069477fd1e7c974bfbd678bc4bb [file] [log] [blame]
David Andersb075f582010-08-02 13:18:05 +03001/*
2 * Board support file for OMAP4430 based PandaBoard.
3 *
4 * Copyright (C) 2010 Texas Instruments
5 *
6 * Author: David Anders <x0132446@ti.com>
7 *
8 * Based on mach-omap2/board-4430sdp.c
9 *
10 * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
11 *
12 * Based on mach-omap2/board-3430sdp.c
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
Anand Gadiyar1740d482011-01-10 14:42:15 +000022#include <linux/clk.h>
David Andersb075f582010-08-02 13:18:05 +030023#include <linux/io.h>
Ricardo Salveti de Araujo3da434a2010-09-23 18:22:49 -070024#include <linux/leds.h>
David Andersb075f582010-08-02 13:18:05 +030025#include <linux/gpio.h>
26#include <linux/usb/otg.h>
27#include <linux/i2c/twl.h>
28#include <linux/regulator/machine.h>
29
30#include <mach/hardware.h>
31#include <mach/omap4-common.h>
32#include <asm/mach-types.h>
33#include <asm/mach/arch.h>
34#include <asm/mach/map.h>
35
36#include <plat/board.h>
37#include <plat/common.h>
David Andersb075f582010-08-02 13:18:05 +030038#include <plat/usb.h>
39#include <plat/mmc.h>
Manjunath Kondaiah G04aeae72010-10-08 09:58:35 -070040#include "timer-gp.h"
David Andersb075f582010-08-02 13:18:05 +030041
Paul Walmsley4814ced2010-10-08 11:40:20 -060042#include "hsmmc.h"
43#include "control.h"
sricharanfc63de822010-11-08 19:26:11 +053044#include "mux.h"
David Andersb075f582010-08-02 13:18:05 +030045
David Anders4415beb2010-10-07 19:36:30 +000046#define GPIO_HUB_POWER 1
47#define GPIO_HUB_NRESET 62
48
Ricardo Salveti de Araujo3da434a2010-09-23 18:22:49 -070049static struct gpio_led gpio_leds[] = {
50 {
51 .name = "pandaboard::status1",
52 .default_trigger = "heartbeat",
53 .gpio = 7,
54 },
55 {
56 .name = "pandaboard::status2",
57 .default_trigger = "mmc0",
58 .gpio = 8,
59 },
60};
61
62static struct gpio_led_platform_data gpio_led_info = {
63 .leds = gpio_leds,
64 .num_leds = ARRAY_SIZE(gpio_leds),
65};
66
67static struct platform_device leds_gpio = {
68 .name = "leds-gpio",
69 .id = -1,
70 .dev = {
71 .platform_data = &gpio_led_info,
72 },
73};
74
75static struct platform_device *panda_devices[] __initdata = {
76 &leds_gpio,
77};
David Andersb075f582010-08-02 13:18:05 +030078
79static void __init omap4_panda_init_irq(void)
80{
Paul Walmsley48057342010-12-21 15:25:10 -070081 omap2_init_common_infrastructure();
82 omap2_init_common_devices(NULL, NULL);
David Andersb075f582010-08-02 13:18:05 +030083 gic_init_irq();
David Andersb075f582010-08-02 13:18:05 +030084}
85
David Anders4415beb2010-10-07 19:36:30 +000086static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
87 .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
88 .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
89 .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
90 .phy_reset = false,
91 .reset_gpio_port[0] = -EINVAL,
92 .reset_gpio_port[1] = -EINVAL,
93 .reset_gpio_port[2] = -EINVAL
94};
95
96static void __init omap4_ehci_init(void)
97{
98 int ret;
Anand Gadiyar1740d482011-01-10 14:42:15 +000099 struct clk *phy_ref_clk;
David Anders4415beb2010-10-07 19:36:30 +0000100
Anand Gadiyar1740d482011-01-10 14:42:15 +0000101 /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
102 phy_ref_clk = clk_get(NULL, "auxclk3_ck");
103 if (IS_ERR(phy_ref_clk)) {
104 pr_err("Cannot request auxclk3\n");
105 goto error1;
106 }
107 clk_set_rate(phy_ref_clk, 19200000);
108 clk_enable(phy_ref_clk);
David Anders4415beb2010-10-07 19:36:30 +0000109
110 /* disable the power to the usb hub prior to init */
111 ret = gpio_request(GPIO_HUB_POWER, "hub_power");
112 if (ret) {
113 pr_err("Cannot request GPIO %d\n", GPIO_HUB_POWER);
114 goto error1;
115 }
116 gpio_export(GPIO_HUB_POWER, 0);
117 gpio_direction_output(GPIO_HUB_POWER, 0);
118 gpio_set_value(GPIO_HUB_POWER, 0);
119
120 /* reset phy+hub */
121 ret = gpio_request(GPIO_HUB_NRESET, "hub_nreset");
122 if (ret) {
123 pr_err("Cannot request GPIO %d\n", GPIO_HUB_NRESET);
124 goto error2;
125 }
126 gpio_export(GPIO_HUB_NRESET, 0);
127 gpio_direction_output(GPIO_HUB_NRESET, 0);
128 gpio_set_value(GPIO_HUB_NRESET, 0);
129 gpio_set_value(GPIO_HUB_NRESET, 1);
130
131 usb_ehci_init(&ehci_pdata);
132
133 /* enable power to hub */
134 gpio_set_value(GPIO_HUB_POWER, 1);
135 return;
136
137error2:
138 gpio_free(GPIO_HUB_POWER);
139error1:
140 pr_err("Unable to initialize EHCI power/reset\n");
141 return;
142
143}
144
David Andersb075f582010-08-02 13:18:05 +0300145static struct omap_musb_board_data musb_board_data = {
146 .interface_type = MUSB_INTERFACE_UTMI,
147 .mode = MUSB_PERIPHERAL,
148 .power = 100,
149};
150
151static struct omap2_hsmmc_info mmc[] = {
152 {
153 .mmc = 1,
Sukumar Ghorai3a638332010-09-15 14:49:23 +0000154 .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
David Andersb075f582010-08-02 13:18:05 +0300155 .gpio_wp = -EINVAL,
Raghuveer Murthy5b59cc22010-12-21 14:14:34 +0000156 .gpio_cd = -EINVAL,
David Andersb075f582010-08-02 13:18:05 +0300157 },
158 {} /* Terminator */
159};
160
161static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = {
162 {
163 .supply = "vmmc",
164 .dev_name = "mmci-omap-hs.0",
165 },
David Andersb075f582010-08-02 13:18:05 +0300166};
167
168static int omap4_twl6030_hsmmc_late_init(struct device *dev)
169{
170 int ret = 0;
171 struct platform_device *pdev = container_of(dev,
172 struct platform_device, dev);
173 struct omap_mmc_platform_data *pdata = dev->platform_data;
174
Menon, Nishanthbf56f0a2010-10-19 09:50:25 -0500175 if (!pdata) {
176 dev_err(dev, "%s: NULL platform data\n", __func__);
177 return -EINVAL;
178 }
David Andersb075f582010-08-02 13:18:05 +0300179 /* Setting MMC1 Card detect Irq */
Menon, Nishanthbf56f0a2010-10-19 09:50:25 -0500180 if (pdev->id == 0) {
181 ret = twl6030_mmc_card_detect_config();
182 if (ret)
183 dev_err(dev, "%s: Error card detect config(%d)\n",
184 __func__, ret);
185 else
186 pdata->slots[0].card_detect = twl6030_mmc_card_detect;
187 }
David Andersb075f582010-08-02 13:18:05 +0300188 return ret;
189}
190
191static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
192{
David Andersb9b52622010-10-07 19:36:29 +0000193 struct omap_mmc_platform_data *pdata;
194
195 /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
196 if (!dev) {
197 pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n");
198 return;
199 }
200 pdata = dev->platform_data;
David Andersb075f582010-08-02 13:18:05 +0300201
202 pdata->init = omap4_twl6030_hsmmc_late_init;
203}
204
205static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
206{
207 struct omap2_hsmmc_info *c;
208
209 omap2_hsmmc_init(controllers);
210 for (c = controllers; c->mmc; c++)
211 omap4_twl6030_hsmmc_set_late_init(c->dev);
212
213 return 0;
214}
215
216static struct regulator_init_data omap4_panda_vaux1 = {
217 .constraints = {
218 .min_uV = 1000000,
219 .max_uV = 3000000,
220 .apply_uV = true,
221 .valid_modes_mask = REGULATOR_MODE_NORMAL
222 | REGULATOR_MODE_STANDBY,
223 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
224 | REGULATOR_CHANGE_MODE
225 | REGULATOR_CHANGE_STATUS,
226 },
227};
228
229static struct regulator_init_data omap4_panda_vaux2 = {
230 .constraints = {
231 .min_uV = 1200000,
232 .max_uV = 2800000,
233 .apply_uV = true,
234 .valid_modes_mask = REGULATOR_MODE_NORMAL
235 | REGULATOR_MODE_STANDBY,
236 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
237 | REGULATOR_CHANGE_MODE
238 | REGULATOR_CHANGE_STATUS,
239 },
240};
241
242static struct regulator_init_data omap4_panda_vaux3 = {
243 .constraints = {
244 .min_uV = 1000000,
245 .max_uV = 3000000,
246 .apply_uV = true,
247 .valid_modes_mask = REGULATOR_MODE_NORMAL
248 | REGULATOR_MODE_STANDBY,
249 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
250 | REGULATOR_CHANGE_MODE
251 | REGULATOR_CHANGE_STATUS,
252 },
253};
254
255/* VMMC1 for MMC1 card */
256static struct regulator_init_data omap4_panda_vmmc = {
257 .constraints = {
258 .min_uV = 1200000,
259 .max_uV = 3000000,
260 .apply_uV = true,
261 .valid_modes_mask = REGULATOR_MODE_NORMAL
262 | REGULATOR_MODE_STANDBY,
263 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
264 | REGULATOR_CHANGE_MODE
265 | REGULATOR_CHANGE_STATUS,
266 },
David Anders191183b2010-10-07 19:36:28 +0000267 .num_consumer_supplies = 1,
David Andersb075f582010-08-02 13:18:05 +0300268 .consumer_supplies = omap4_panda_vmmc_supply,
269};
270
271static struct regulator_init_data omap4_panda_vpp = {
272 .constraints = {
273 .min_uV = 1800000,
274 .max_uV = 2500000,
275 .apply_uV = true,
276 .valid_modes_mask = REGULATOR_MODE_NORMAL
277 | REGULATOR_MODE_STANDBY,
278 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
279 | REGULATOR_CHANGE_MODE
280 | REGULATOR_CHANGE_STATUS,
281 },
282};
283
284static struct regulator_init_data omap4_panda_vusim = {
285 .constraints = {
286 .min_uV = 1200000,
287 .max_uV = 2900000,
288 .apply_uV = true,
289 .valid_modes_mask = REGULATOR_MODE_NORMAL
290 | REGULATOR_MODE_STANDBY,
291 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
292 | REGULATOR_CHANGE_MODE
293 | REGULATOR_CHANGE_STATUS,
294 },
295};
296
297static struct regulator_init_data omap4_panda_vana = {
298 .constraints = {
299 .min_uV = 2100000,
300 .max_uV = 2100000,
301 .apply_uV = true,
302 .valid_modes_mask = REGULATOR_MODE_NORMAL
303 | REGULATOR_MODE_STANDBY,
304 .valid_ops_mask = REGULATOR_CHANGE_MODE
305 | REGULATOR_CHANGE_STATUS,
306 },
307};
308
309static struct regulator_init_data omap4_panda_vcxio = {
310 .constraints = {
311 .min_uV = 1800000,
312 .max_uV = 1800000,
313 .apply_uV = true,
314 .valid_modes_mask = REGULATOR_MODE_NORMAL
315 | REGULATOR_MODE_STANDBY,
316 .valid_ops_mask = REGULATOR_CHANGE_MODE
317 | REGULATOR_CHANGE_STATUS,
318 },
319};
320
321static struct regulator_init_data omap4_panda_vdac = {
322 .constraints = {
323 .min_uV = 1800000,
324 .max_uV = 1800000,
325 .apply_uV = true,
326 .valid_modes_mask = REGULATOR_MODE_NORMAL
327 | REGULATOR_MODE_STANDBY,
328 .valid_ops_mask = REGULATOR_CHANGE_MODE
329 | REGULATOR_CHANGE_STATUS,
330 },
331};
332
333static struct regulator_init_data omap4_panda_vusb = {
334 .constraints = {
335 .min_uV = 3300000,
336 .max_uV = 3300000,
337 .apply_uV = true,
338 .valid_modes_mask = REGULATOR_MODE_NORMAL
339 | REGULATOR_MODE_STANDBY,
340 .valid_ops_mask = REGULATOR_CHANGE_MODE
341 | REGULATOR_CHANGE_STATUS,
342 },
343};
344
345static struct twl4030_platform_data omap4_panda_twldata = {
346 .irq_base = TWL6030_IRQ_BASE,
347 .irq_end = TWL6030_IRQ_END,
348
349 /* Regulators */
350 .vmmc = &omap4_panda_vmmc,
351 .vpp = &omap4_panda_vpp,
352 .vusim = &omap4_panda_vusim,
353 .vana = &omap4_panda_vana,
354 .vcxio = &omap4_panda_vcxio,
355 .vdac = &omap4_panda_vdac,
356 .vusb = &omap4_panda_vusb,
357 .vaux1 = &omap4_panda_vaux1,
358 .vaux2 = &omap4_panda_vaux2,
359 .vaux3 = &omap4_panda_vaux3,
360};
361
362static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = {
363 {
364 I2C_BOARD_INFO("twl6030", 0x48),
365 .flags = I2C_CLIENT_WAKE,
366 .irq = OMAP44XX_IRQ_SYS_1N,
367 .platform_data = &omap4_panda_twldata,
368 },
369};
370static int __init omap4_panda_i2c_init(void)
371{
372 /*
373 * Phoenix Audio IC needs I2C1 to
374 * start with 400 KHz or less
375 */
376 omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo,
377 ARRAY_SIZE(omap4_panda_i2c_boardinfo));
378 omap_register_i2c_bus(2, 400, NULL, 0);
379 omap_register_i2c_bus(3, 400, NULL, 0);
380 omap_register_i2c_bus(4, 400, NULL, 0);
381 return 0;
382}
sricharanfc63de822010-11-08 19:26:11 +0530383
384#ifdef CONFIG_OMAP_MUX
385static struct omap_board_mux board_mux[] __initdata = {
386 { .reg_offset = OMAP_MUX_TERMINATOR },
387};
388#else
389#define board_mux NULL
390#endif
391
David Andersb075f582010-08-02 13:18:05 +0300392static void __init omap4_panda_init(void)
393{
sricharanfc63de822010-11-08 19:26:11 +0530394 int package = OMAP_PACKAGE_CBS;
395
396 if (omap_rev() == OMAP4430_REV_ES1_0)
397 package = OMAP_PACKAGE_CBL;
398 omap4_mux_init(board_mux, package);
399
David Andersb075f582010-08-02 13:18:05 +0300400 omap4_panda_i2c_init();
Ricardo Salveti de Araujo3da434a2010-09-23 18:22:49 -0700401 platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
David Andersb075f582010-08-02 13:18:05 +0300402 omap_serial_init();
403 omap4_twl6030_hsmmc_init(mmc);
404 /* OMAP4 Panda uses internal transceiver so register nop transceiver */
405 usb_nop_xceiv_register();
David Anders4415beb2010-10-07 19:36:30 +0000406 omap4_ehci_init();
David Andersb075f582010-08-02 13:18:05 +0300407 /* FIXME: allow multi-omap to boot until musb is updated for omap4 */
408 if (!cpu_is_omap44xx())
409 usb_musb_init(&musb_board_data);
410}
411
412static void __init omap4_panda_map_io(void)
413{
414 omap2_set_globals_443x();
415 omap44xx_map_common_io();
416}
417
418MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
419 /* Maintainer: David Anders - Texas Instruments Inc */
David Andersb075f582010-08-02 13:18:05 +0300420 .boot_params = 0x80000100,
Raghuveer Murthyd920e522010-12-17 18:15:07 -0800421 .reserve = omap_reserve,
David Andersb075f582010-08-02 13:18:05 +0300422 .map_io = omap4_panda_map_io,
423 .init_irq = omap4_panda_init_irq,
424 .init_machine = omap4_panda_init,
425 .timer = &omap_timer,
426MACHINE_END