3b972bf06c
Otherwise omap_device_build() and omap_mux related functions can't be marked as __init when twl is build as a module. If a board is using GPIO pins or regulators configured by an external chip, such as TWL PMIC on I2C bus, the board must mark those MMC controllers as deferred. Additionally both omap_hsmmc_init() and omap_hsmmc_late_init() must be called by the board. For MMC controllers using internal GPIO pins for card detect and regulators the slots don't need to be marked deferred. In this case calling omap_hsmmc_init() is sufficient. Only mark the MMC slots using gpio_cd or gpio_wd as deferred as noted by Igor Grinberg <grinberg@compulab.co.il>. Note that this patch does not change the behaviour for board-4430sdp.c board-omap4panda.c. These boards wrongly rely on the omap_hsmmc.c init function callback to configure the PMIC GPIO interrupt lines on external chip. If the PMIC interrupt lines are not configured during init, they will fail. Reported-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
157 lines
3.8 KiB
C
157 lines
3.8 KiB
C
/*
|
|
* Board support file for Nokia RM-680.
|
|
*
|
|
* Copyright (C) 2010 Nokia
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <linux/io.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/gpio.h>
|
|
#include <linux/init.h>
|
|
#include <linux/i2c/twl.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/regulator/fixed.h>
|
|
#include <linux/regulator/machine.h>
|
|
#include <linux/regulator/consumer.h>
|
|
|
|
#include <asm/mach/arch.h>
|
|
#include <asm/mach-types.h>
|
|
|
|
#include <plat/i2c.h>
|
|
#include <plat/mmc.h>
|
|
#include <plat/usb.h>
|
|
#include <plat/gpmc.h>
|
|
#include "common.h"
|
|
#include <plat/onenand.h>
|
|
|
|
#include "mux.h"
|
|
#include "hsmmc.h"
|
|
#include "sdram-nokia.h"
|
|
#include "common-board-devices.h"
|
|
|
|
static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
|
|
REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
|
|
};
|
|
|
|
/* Fixed regulator for internal eMMC */
|
|
static struct regulator_init_data rm680_vemmc = {
|
|
.constraints = {
|
|
.name = "rm680_vemmc",
|
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
|
| REGULATOR_MODE_STANDBY,
|
|
.valid_ops_mask = REGULATOR_CHANGE_STATUS
|
|
| REGULATOR_CHANGE_MODE,
|
|
},
|
|
.num_consumer_supplies = ARRAY_SIZE(rm680_vemmc_consumers),
|
|
.consumer_supplies = rm680_vemmc_consumers,
|
|
};
|
|
|
|
static struct fixed_voltage_config rm680_vemmc_config = {
|
|
.supply_name = "VEMMC",
|
|
.microvolts = 2900000,
|
|
.gpio = 157,
|
|
.startup_delay = 150,
|
|
.enable_high = 1,
|
|
.init_data = &rm680_vemmc,
|
|
};
|
|
|
|
static struct platform_device rm680_vemmc_device = {
|
|
.name = "reg-fixed-voltage",
|
|
.dev = {
|
|
.platform_data = &rm680_vemmc_config,
|
|
},
|
|
};
|
|
|
|
static struct platform_device *rm680_peripherals_devices[] __initdata = {
|
|
&rm680_vemmc_device,
|
|
};
|
|
|
|
/* TWL */
|
|
static struct twl4030_gpio_platform_data rm680_gpio_data = {
|
|
.gpio_base = OMAP_MAX_GPIO_LINES,
|
|
.irq_base = TWL4030_GPIO_IRQ_BASE,
|
|
.irq_end = TWL4030_GPIO_IRQ_END,
|
|
.pullups = BIT(0),
|
|
.pulldowns = BIT(1) | BIT(2) | BIT(8) | BIT(15),
|
|
};
|
|
|
|
static struct twl4030_platform_data rm680_twl_data = {
|
|
.gpio = &rm680_gpio_data,
|
|
/* add rest of the children here */
|
|
};
|
|
|
|
static void __init rm680_i2c_init(void)
|
|
{
|
|
omap3_pmic_get_config(&rm680_twl_data, TWL_COMMON_PDATA_USB, 0);
|
|
omap_pmic_init(1, 2900, "twl5031", INT_34XX_SYS_NIRQ, &rm680_twl_data);
|
|
omap_register_i2c_bus(2, 400, NULL, 0);
|
|
omap_register_i2c_bus(3, 400, NULL, 0);
|
|
}
|
|
|
|
#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
|
|
defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
|
|
static struct omap_onenand_platform_data board_onenand_data[] = {
|
|
{
|
|
.gpio_irq = 65,
|
|
.flags = ONENAND_SYNC_READWRITE,
|
|
}
|
|
};
|
|
#endif
|
|
|
|
/* eMMC */
|
|
static struct omap2_hsmmc_info mmc[] __initdata = {
|
|
{
|
|
.name = "internal",
|
|
.mmc = 2,
|
|
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED,
|
|
.gpio_cd = -EINVAL,
|
|
.gpio_wp = -EINVAL,
|
|
},
|
|
{ /* Terminator */ }
|
|
};
|
|
|
|
static void __init rm680_peripherals_init(void)
|
|
{
|
|
platform_add_devices(rm680_peripherals_devices,
|
|
ARRAY_SIZE(rm680_peripherals_devices));
|
|
rm680_i2c_init();
|
|
gpmc_onenand_init(board_onenand_data);
|
|
omap_hsmmc_init(mmc);
|
|
}
|
|
|
|
#ifdef CONFIG_OMAP_MUX
|
|
static struct omap_board_mux board_mux[] __initdata = {
|
|
{ .reg_offset = OMAP_MUX_TERMINATOR },
|
|
};
|
|
#endif
|
|
|
|
static void __init rm680_init(void)
|
|
{
|
|
struct omap_sdrc_params *sdrc_params;
|
|
|
|
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
|
|
omap_serial_init();
|
|
|
|
sdrc_params = nokia_get_sdram_timings();
|
|
omap_sdrc_init(sdrc_params, sdrc_params);
|
|
|
|
usb_musb_init(NULL);
|
|
rm680_peripherals_init();
|
|
}
|
|
|
|
MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
|
|
.atag_offset = 0x100,
|
|
.reserve = omap_reserve,
|
|
.map_io = omap3_map_io,
|
|
.init_early = omap3630_init_early,
|
|
.init_irq = omap3_init_irq,
|
|
.handle_irq = omap3_intc_handle_irq,
|
|
.init_machine = rm680_init,
|
|
.timer = &omap3_timer,
|
|
.restart = omap_prcm_restart,
|
|
MACHINE_END
|