blob: ed61c1f5d5e663ae82c607ec24b3d7a0954f9819 [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
Keshava Munegowda181b2502011-03-01 20:08:16 +053086static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
87 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
88 .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
89 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
David Anders4415beb2010-10-07 19:36:30 +000090 .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
Keshava Munegowda9e64bb12011-03-01 20:08:19 +0530131 usbhs_init(&usbhs_bdata);
David Anders4415beb2010-10-07 19:36:30 +0000132
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,
Hema HK09e72002010-12-10 18:11:42 +0530147 .mode = MUSB_OTG,
David Andersb075f582010-08-02 13:18:05 +0300148 .power = 100,
149};
150
Hema HKe70357e2010-12-10 18:09:52 +0530151static struct twl4030_usb_data omap4_usbphy_data = {
152 .phy_init = omap4430_phy_init,
153 .phy_exit = omap4430_phy_exit,
154 .phy_power = omap4430_phy_power,
155 .phy_set_clock = omap4430_phy_set_clk,
Hema HKee896e32011-02-17 12:06:07 +0530156 .phy_suspend = omap4430_phy_suspend,
Hema HKe70357e2010-12-10 18:09:52 +0530157};
158
David Andersb075f582010-08-02 13:18:05 +0300159static struct omap2_hsmmc_info mmc[] = {
160 {
161 .mmc = 1,
Sukumar Ghorai3a638332010-09-15 14:49:23 +0000162 .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
David Andersb075f582010-08-02 13:18:05 +0300163 .gpio_wp = -EINVAL,
Raghuveer Murthy5b59cc22010-12-21 14:14:34 +0000164 .gpio_cd = -EINVAL,
David Andersb075f582010-08-02 13:18:05 +0300165 },
166 {} /* Terminator */
167};
168
169static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = {
170 {
171 .supply = "vmmc",
172 .dev_name = "mmci-omap-hs.0",
173 },
David Andersb075f582010-08-02 13:18:05 +0300174};
175
176static int omap4_twl6030_hsmmc_late_init(struct device *dev)
177{
178 int ret = 0;
179 struct platform_device *pdev = container_of(dev,
180 struct platform_device, dev);
181 struct omap_mmc_platform_data *pdata = dev->platform_data;
182
Menon, Nishanthbf56f0a2010-10-19 09:50:25 -0500183 if (!pdata) {
184 dev_err(dev, "%s: NULL platform data\n", __func__);
185 return -EINVAL;
186 }
David Andersb075f582010-08-02 13:18:05 +0300187 /* Setting MMC1 Card detect Irq */
Menon, Nishanthbf56f0a2010-10-19 09:50:25 -0500188 if (pdev->id == 0) {
189 ret = twl6030_mmc_card_detect_config();
190 if (ret)
191 dev_err(dev, "%s: Error card detect config(%d)\n",
192 __func__, ret);
193 else
194 pdata->slots[0].card_detect = twl6030_mmc_card_detect;
195 }
David Andersb075f582010-08-02 13:18:05 +0300196 return ret;
197}
198
199static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
200{
David Andersb9b52622010-10-07 19:36:29 +0000201 struct omap_mmc_platform_data *pdata;
202
203 /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
204 if (!dev) {
205 pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n");
206 return;
207 }
208 pdata = dev->platform_data;
David Andersb075f582010-08-02 13:18:05 +0300209
210 pdata->init = omap4_twl6030_hsmmc_late_init;
211}
212
213static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
214{
215 struct omap2_hsmmc_info *c;
216
217 omap2_hsmmc_init(controllers);
218 for (c = controllers; c->mmc; c++)
219 omap4_twl6030_hsmmc_set_late_init(c->dev);
220
221 return 0;
222}
223
224static struct regulator_init_data omap4_panda_vaux1 = {
225 .constraints = {
226 .min_uV = 1000000,
227 .max_uV = 3000000,
228 .apply_uV = true,
229 .valid_modes_mask = REGULATOR_MODE_NORMAL
230 | REGULATOR_MODE_STANDBY,
231 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
232 | REGULATOR_CHANGE_MODE
233 | REGULATOR_CHANGE_STATUS,
234 },
235};
236
237static struct regulator_init_data omap4_panda_vaux2 = {
238 .constraints = {
239 .min_uV = 1200000,
240 .max_uV = 2800000,
241 .apply_uV = true,
242 .valid_modes_mask = REGULATOR_MODE_NORMAL
243 | REGULATOR_MODE_STANDBY,
244 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
245 | REGULATOR_CHANGE_MODE
246 | REGULATOR_CHANGE_STATUS,
247 },
248};
249
250static struct regulator_init_data omap4_panda_vaux3 = {
251 .constraints = {
252 .min_uV = 1000000,
253 .max_uV = 3000000,
254 .apply_uV = true,
255 .valid_modes_mask = REGULATOR_MODE_NORMAL
256 | REGULATOR_MODE_STANDBY,
257 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
258 | REGULATOR_CHANGE_MODE
259 | REGULATOR_CHANGE_STATUS,
260 },
261};
262
263/* VMMC1 for MMC1 card */
264static struct regulator_init_data omap4_panda_vmmc = {
265 .constraints = {
266 .min_uV = 1200000,
267 .max_uV = 3000000,
268 .apply_uV = true,
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 },
David Anders191183b2010-10-07 19:36:28 +0000275 .num_consumer_supplies = 1,
David Andersb075f582010-08-02 13:18:05 +0300276 .consumer_supplies = omap4_panda_vmmc_supply,
277};
278
279static struct regulator_init_data omap4_panda_vpp = {
280 .constraints = {
281 .min_uV = 1800000,
282 .max_uV = 2500000,
283 .apply_uV = true,
284 .valid_modes_mask = REGULATOR_MODE_NORMAL
285 | REGULATOR_MODE_STANDBY,
286 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
287 | REGULATOR_CHANGE_MODE
288 | REGULATOR_CHANGE_STATUS,
289 },
290};
291
292static struct regulator_init_data omap4_panda_vusim = {
293 .constraints = {
294 .min_uV = 1200000,
295 .max_uV = 2900000,
296 .apply_uV = true,
297 .valid_modes_mask = REGULATOR_MODE_NORMAL
298 | REGULATOR_MODE_STANDBY,
299 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
300 | REGULATOR_CHANGE_MODE
301 | REGULATOR_CHANGE_STATUS,
302 },
303};
304
305static struct regulator_init_data omap4_panda_vana = {
306 .constraints = {
307 .min_uV = 2100000,
308 .max_uV = 2100000,
309 .apply_uV = true,
310 .valid_modes_mask = REGULATOR_MODE_NORMAL
311 | REGULATOR_MODE_STANDBY,
312 .valid_ops_mask = REGULATOR_CHANGE_MODE
313 | REGULATOR_CHANGE_STATUS,
314 },
315};
316
317static struct regulator_init_data omap4_panda_vcxio = {
318 .constraints = {
319 .min_uV = 1800000,
320 .max_uV = 1800000,
321 .apply_uV = true,
322 .valid_modes_mask = REGULATOR_MODE_NORMAL
323 | REGULATOR_MODE_STANDBY,
324 .valid_ops_mask = REGULATOR_CHANGE_MODE
325 | REGULATOR_CHANGE_STATUS,
326 },
327};
328
329static struct regulator_init_data omap4_panda_vdac = {
330 .constraints = {
331 .min_uV = 1800000,
332 .max_uV = 1800000,
333 .apply_uV = true,
334 .valid_modes_mask = REGULATOR_MODE_NORMAL
335 | REGULATOR_MODE_STANDBY,
336 .valid_ops_mask = REGULATOR_CHANGE_MODE
337 | REGULATOR_CHANGE_STATUS,
338 },
339};
340
341static struct regulator_init_data omap4_panda_vusb = {
342 .constraints = {
343 .min_uV = 3300000,
344 .max_uV = 3300000,
345 .apply_uV = true,
346 .valid_modes_mask = REGULATOR_MODE_NORMAL
347 | REGULATOR_MODE_STANDBY,
348 .valid_ops_mask = REGULATOR_CHANGE_MODE
349 | REGULATOR_CHANGE_STATUS,
350 },
351};
352
353static struct twl4030_platform_data omap4_panda_twldata = {
354 .irq_base = TWL6030_IRQ_BASE,
355 .irq_end = TWL6030_IRQ_END,
356
357 /* Regulators */
358 .vmmc = &omap4_panda_vmmc,
359 .vpp = &omap4_panda_vpp,
360 .vusim = &omap4_panda_vusim,
361 .vana = &omap4_panda_vana,
362 .vcxio = &omap4_panda_vcxio,
363 .vdac = &omap4_panda_vdac,
364 .vusb = &omap4_panda_vusb,
365 .vaux1 = &omap4_panda_vaux1,
366 .vaux2 = &omap4_panda_vaux2,
367 .vaux3 = &omap4_panda_vaux3,
Hema HKe70357e2010-12-10 18:09:52 +0530368 .usb = &omap4_usbphy_data,
David Andersb075f582010-08-02 13:18:05 +0300369};
370
371static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = {
372 {
373 I2C_BOARD_INFO("twl6030", 0x48),
374 .flags = I2C_CLIENT_WAKE,
375 .irq = OMAP44XX_IRQ_SYS_1N,
376 .platform_data = &omap4_panda_twldata,
377 },
378};
379static int __init omap4_panda_i2c_init(void)
380{
381 /*
382 * Phoenix Audio IC needs I2C1 to
383 * start with 400 KHz or less
384 */
385 omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo,
386 ARRAY_SIZE(omap4_panda_i2c_boardinfo));
387 omap_register_i2c_bus(2, 400, NULL, 0);
388 omap_register_i2c_bus(3, 400, NULL, 0);
389 omap_register_i2c_bus(4, 400, NULL, 0);
390 return 0;
391}
sricharanfc63de822010-11-08 19:26:11 +0530392
393#ifdef CONFIG_OMAP_MUX
394static struct omap_board_mux board_mux[] __initdata = {
395 { .reg_offset = OMAP_MUX_TERMINATOR },
396};
397#else
398#define board_mux NULL
399#endif
400
David Andersb075f582010-08-02 13:18:05 +0300401static void __init omap4_panda_init(void)
402{
sricharanfc63de822010-11-08 19:26:11 +0530403 int package = OMAP_PACKAGE_CBS;
404
405 if (omap_rev() == OMAP4430_REV_ES1_0)
406 package = OMAP_PACKAGE_CBL;
407 omap4_mux_init(board_mux, package);
408
David Andersb075f582010-08-02 13:18:05 +0300409 omap4_panda_i2c_init();
Ricardo Salveti de Araujo3da434a2010-09-23 18:22:49 -0700410 platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
David Andersb075f582010-08-02 13:18:05 +0300411 omap_serial_init();
412 omap4_twl6030_hsmmc_init(mmc);
David Anders4415beb2010-10-07 19:36:30 +0000413 omap4_ehci_init();
Felipe Balbi1ea7f352010-12-01 13:48:54 +0200414 usb_musb_init(&musb_board_data);
David Andersb075f582010-08-02 13:18:05 +0300415}
416
417static void __init omap4_panda_map_io(void)
418{
419 omap2_set_globals_443x();
420 omap44xx_map_common_io();
421}
422
423MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
424 /* Maintainer: David Anders - Texas Instruments Inc */
David Andersb075f582010-08-02 13:18:05 +0300425 .boot_params = 0x80000100,
Raghuveer Murthyd920e522010-12-17 18:15:07 -0800426 .reserve = omap_reserve,
David Andersb075f582010-08-02 13:18:05 +0300427 .map_io = omap4_panda_map_io,
428 .init_irq = omap4_panda_init_irq,
429 .init_machine = omap4_panda_init,
430 .timer = &omap_timer,
431MACHINE_END