2010-08-02 14:18:05 +04:00
/*
* Board support file for OMAP4430 based PandaBoard .
*
* Copyright ( C ) 2010 Texas Instruments
*
* Author : David Anders < x0132446 @ ti . com >
*
* Based on mach - omap2 / board - 4430 sdp . c
*
* Author : Santosh Shilimkar < santosh . shilimkar @ ti . com >
*
* Based on mach - omap2 / board - 3430 sdp . c
*
* 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/kernel.h>
# include <linux/init.h>
# include <linux/platform_device.h>
# include <linux/io.h>
2010-09-24 05:22:49 +04:00
# include <linux/leds.h>
2010-08-02 14:18:05 +04:00
# include <linux/gpio.h>
# include <linux/usb/otg.h>
# include <linux/i2c/twl.h>
# include <linux/regulator/machine.h>
# include <mach/hardware.h>
# include <mach/omap4-common.h>
# include <asm/mach-types.h>
# include <asm/mach/arch.h>
# include <asm/mach/map.h>
# include <plat/board.h>
# include <plat/common.h>
# include <plat/usb.h>
# include <plat/mmc.h>
2010-10-08 20:58:35 +04:00
# include "timer-gp.h"
2010-08-02 14:18:05 +04:00
# include "hsmmc.h"
2010-10-08 21:40:20 +04:00
# include "control.h"
2010-11-08 16:56:11 +03:00
# include "mux.h"
2010-08-02 14:18:05 +04:00
2010-10-07 23:36:30 +04:00
# define GPIO_HUB_POWER 1
# define GPIO_HUB_NRESET 62
2010-09-24 05:22:49 +04:00
static struct gpio_led gpio_leds [ ] = {
{
. name = " pandaboard::status1 " ,
. default_trigger = " heartbeat " ,
. gpio = 7 ,
} ,
{
. name = " pandaboard::status2 " ,
. default_trigger = " mmc0 " ,
. gpio = 8 ,
} ,
} ;
2010-08-02 14:18:05 +04:00
2010-09-24 05:22:49 +04:00
static struct gpio_led_platform_data gpio_led_info = {
. leds = gpio_leds ,
. num_leds = ARRAY_SIZE ( gpio_leds ) ,
} ;
static struct platform_device leds_gpio = {
. name = " leds-gpio " ,
. id = - 1 ,
. dev = {
. platform_data = & gpio_led_info ,
} ,
} ;
static struct platform_device * panda_devices [ ] __initdata = {
& leds_gpio ,
} ;
2010-08-02 14:18:05 +04:00
static void __init omap4_panda_init_irq ( void )
{
omap2_init_common_hw ( NULL , NULL ) ;
gic_init_irq ( ) ;
}
2010-10-07 23:36:30 +04:00
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
. port_mode [ 0 ] = EHCI_HCD_OMAP_MODE_PHY ,
. port_mode [ 1 ] = EHCI_HCD_OMAP_MODE_UNKNOWN ,
. port_mode [ 2 ] = EHCI_HCD_OMAP_MODE_UNKNOWN ,
. phy_reset = false ,
. reset_gpio_port [ 0 ] = - EINVAL ,
. reset_gpio_port [ 1 ] = - EINVAL ,
. reset_gpio_port [ 2 ] = - EINVAL
} ;
static void __init omap4_ehci_init ( void )
{
int ret ;
/* disable the power to the usb hub prior to init */
ret = gpio_request ( GPIO_HUB_POWER , " hub_power " ) ;
if ( ret ) {
pr_err ( " Cannot request GPIO %d \n " , GPIO_HUB_POWER ) ;
goto error1 ;
}
gpio_export ( GPIO_HUB_POWER , 0 ) ;
gpio_direction_output ( GPIO_HUB_POWER , 0 ) ;
gpio_set_value ( GPIO_HUB_POWER , 0 ) ;
/* reset phy+hub */
ret = gpio_request ( GPIO_HUB_NRESET , " hub_nreset " ) ;
if ( ret ) {
pr_err ( " Cannot request GPIO %d \n " , GPIO_HUB_NRESET ) ;
goto error2 ;
}
gpio_export ( GPIO_HUB_NRESET , 0 ) ;
gpio_direction_output ( GPIO_HUB_NRESET , 0 ) ;
gpio_set_value ( GPIO_HUB_NRESET , 0 ) ;
gpio_set_value ( GPIO_HUB_NRESET , 1 ) ;
usb_ehci_init ( & ehci_pdata ) ;
/* enable power to hub */
gpio_set_value ( GPIO_HUB_POWER , 1 ) ;
return ;
error2 :
gpio_free ( GPIO_HUB_POWER ) ;
error1 :
pr_err ( " Unable to initialize EHCI power/reset \n " ) ;
return ;
}
2010-08-02 14:18:05 +04:00
static struct omap_musb_board_data musb_board_data = {
. interface_type = MUSB_INTERFACE_UTMI ,
. mode = MUSB_PERIPHERAL ,
. power = 100 ,
} ;
static struct omap2_hsmmc_info mmc [ ] = {
{
. mmc = 1 ,
2010-09-15 18:49:23 +04:00
. caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA ,
2010-08-02 14:18:05 +04:00
. gpio_wp = - EINVAL ,
} ,
{ } /* Terminator */
} ;
static struct regulator_consumer_supply omap4_panda_vmmc_supply [ ] = {
{
. supply = " vmmc " ,
. dev_name = " mmci-omap-hs.0 " ,
} ,
} ;
static int omap4_twl6030_hsmmc_late_init ( struct device * dev )
{
int ret = 0 ;
struct platform_device * pdev = container_of ( dev ,
struct platform_device , dev ) ;
struct omap_mmc_platform_data * pdata = dev - > platform_data ;
2010-10-19 18:50:25 +04:00
if ( ! pdata ) {
dev_err ( dev , " %s: NULL platform data \n " , __func__ ) ;
return - EINVAL ;
}
2010-08-02 14:18:05 +04:00
/* Setting MMC1 Card detect Irq */
2010-10-19 18:50:25 +04:00
if ( pdev - > id = = 0 ) {
ret = twl6030_mmc_card_detect_config ( ) ;
if ( ret )
dev_err ( dev , " %s: Error card detect config(%d) \n " ,
__func__ , ret ) ;
else
pdata - > slots [ 0 ] . card_detect = twl6030_mmc_card_detect ;
}
2010-08-02 14:18:05 +04:00
return ret ;
}
static __init void omap4_twl6030_hsmmc_set_late_init ( struct device * dev )
{
2010-10-07 23:36:29 +04:00
struct omap_mmc_platform_data * pdata ;
/* dev can be null if CONFIG_MMC_OMAP_HS is not set */
if ( ! dev ) {
pr_err ( " Failed omap4_twl6030_hsmmc_set_late_init \n " ) ;
return ;
}
pdata = dev - > platform_data ;
2010-08-02 14:18:05 +04:00
pdata - > init = omap4_twl6030_hsmmc_late_init ;
}
static int __init omap4_twl6030_hsmmc_init ( struct omap2_hsmmc_info * controllers )
{
struct omap2_hsmmc_info * c ;
omap2_hsmmc_init ( controllers ) ;
for ( c = controllers ; c - > mmc ; c + + )
omap4_twl6030_hsmmc_set_late_init ( c - > dev ) ;
return 0 ;
}
static struct regulator_init_data omap4_panda_vaux1 = {
. constraints = {
. min_uV = 1000000 ,
. max_uV = 3000000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
} ;
static struct regulator_init_data omap4_panda_vaux2 = {
. constraints = {
. min_uV = 1200000 ,
. max_uV = 2800000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
} ;
static struct regulator_init_data omap4_panda_vaux3 = {
. constraints = {
. min_uV = 1000000 ,
. max_uV = 3000000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
} ;
/* VMMC1 for MMC1 card */
static struct regulator_init_data omap4_panda_vmmc = {
. constraints = {
. min_uV = 1200000 ,
. max_uV = 3000000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
2010-10-07 23:36:28 +04:00
. num_consumer_supplies = 1 ,
2010-08-02 14:18:05 +04:00
. consumer_supplies = omap4_panda_vmmc_supply ,
} ;
static struct regulator_init_data omap4_panda_vpp = {
. constraints = {
. min_uV = 1800000 ,
. max_uV = 2500000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
} ;
static struct regulator_init_data omap4_panda_vusim = {
. constraints = {
. min_uV = 1200000 ,
. max_uV = 2900000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
} ;
static struct regulator_init_data omap4_panda_vana = {
. constraints = {
. min_uV = 2100000 ,
. max_uV = 2100000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
} ;
static struct regulator_init_data omap4_panda_vcxio = {
. constraints = {
. min_uV = 1800000 ,
. max_uV = 1800000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
} ;
static struct regulator_init_data omap4_panda_vdac = {
. constraints = {
. min_uV = 1800000 ,
. max_uV = 1800000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
} ;
static struct regulator_init_data omap4_panda_vusb = {
. constraints = {
. min_uV = 3300000 ,
. max_uV = 3300000 ,
. apply_uV = true ,
. valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY ,
. valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS ,
} ,
} ;
static struct twl4030_platform_data omap4_panda_twldata = {
. irq_base = TWL6030_IRQ_BASE ,
. irq_end = TWL6030_IRQ_END ,
/* Regulators */
. vmmc = & omap4_panda_vmmc ,
. vpp = & omap4_panda_vpp ,
. vusim = & omap4_panda_vusim ,
. vana = & omap4_panda_vana ,
. vcxio = & omap4_panda_vcxio ,
. vdac = & omap4_panda_vdac ,
. vusb = & omap4_panda_vusb ,
. vaux1 = & omap4_panda_vaux1 ,
. vaux2 = & omap4_panda_vaux2 ,
. vaux3 = & omap4_panda_vaux3 ,
} ;
static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo [ ] = {
{
I2C_BOARD_INFO ( " twl6030 " , 0x48 ) ,
. flags = I2C_CLIENT_WAKE ,
. irq = OMAP44XX_IRQ_SYS_1N ,
. platform_data = & omap4_panda_twldata ,
} ,
} ;
static int __init omap4_panda_i2c_init ( void )
{
/*
* Phoenix Audio IC needs I2C1 to
* start with 400 KHz or less
*/
omap_register_i2c_bus ( 1 , 400 , omap4_panda_i2c_boardinfo ,
ARRAY_SIZE ( omap4_panda_i2c_boardinfo ) ) ;
omap_register_i2c_bus ( 2 , 400 , NULL , 0 ) ;
omap_register_i2c_bus ( 3 , 400 , NULL , 0 ) ;
omap_register_i2c_bus ( 4 , 400 , NULL , 0 ) ;
return 0 ;
}
2010-11-08 16:56:11 +03:00
# ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux [ ] __initdata = {
{ . reg_offset = OMAP_MUX_TERMINATOR } ,
} ;
# else
# define board_mux NULL
# endif
2010-08-02 14:18:05 +04:00
static void __init omap4_panda_init ( void )
{
2010-11-08 16:56:11 +03:00
int package = OMAP_PACKAGE_CBS ;
if ( omap_rev ( ) = = OMAP4430_REV_ES1_0 )
package = OMAP_PACKAGE_CBL ;
omap4_mux_init ( board_mux , package ) ;
2010-08-02 14:18:05 +04:00
omap4_panda_i2c_init ( ) ;
2010-09-24 05:22:49 +04:00
platform_add_devices ( panda_devices , ARRAY_SIZE ( panda_devices ) ) ;
2010-08-02 14:18:05 +04:00
omap_serial_init ( ) ;
omap4_twl6030_hsmmc_init ( mmc ) ;
/* OMAP4 Panda uses internal transceiver so register nop transceiver */
usb_nop_xceiv_register ( ) ;
2010-10-07 23:36:30 +04:00
omap4_ehci_init ( ) ;
2010-08-02 14:18:05 +04:00
/* FIXME: allow multi-omap to boot until musb is updated for omap4 */
if ( ! cpu_is_omap44xx ( ) )
usb_musb_init ( & musb_board_data ) ;
}
static void __init omap4_panda_map_io ( void )
{
omap2_set_globals_443x ( ) ;
omap44xx_map_common_io ( ) ;
}
MACHINE_START ( OMAP4_PANDA , " OMAP4 Panda board " )
/* Maintainer: David Anders - Texas Instruments Inc */
. boot_params = 0x80000100 ,
2010-12-18 05:15:07 +03:00
. reserve = omap_reserve ,
2010-08-02 14:18:05 +04:00
. map_io = omap4_panda_map_io ,
. init_irq = omap4_panda_init_irq ,
. init_machine = omap4_panda_init ,
. timer = & omap_timer ,
MACHINE_END