2010-10-07 03:58:12 +03:00
/*
* Copyright ( C ) 2010 Linaro Limited
*
* based on code from the following
* Copyright 2009 - 2010 Freescale Semiconductor , Inc . All Rights Reserved .
* Copyright 2009 - 2010 Pegatron Corporation . All Rights Reserved .
* Copyright 2009 - 2010 Genesi USA , Inc . All Rights Reserved .
*
* The code contained herein is licensed under the GNU General Public
* License . You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations :
*
* http : //www.opensource.org/licenses/gpl-license.html
* http : //www.gnu.org/copyleft/gpl.html
*/
# include <linux/init.h>
# include <linux/platform_device.h>
# include <linux/i2c.h>
# include <linux/gpio.h>
2010-10-27 14:40:51 +02:00
# include <linux/leds.h>
2010-10-27 14:40:52 +02:00
# include <linux/input.h>
2010-10-07 03:58:12 +03:00
# include <linux/delay.h>
# include <linux/io.h>
2010-10-27 14:40:54 +02:00
# include <linux/spi/flash.h>
# include <linux/spi/spi.h>
2011-02-17 15:31:30 +01:00
# include <linux/mfd/mc13892.h>
# include <linux/regulator/machine.h>
# include <linux/regulator/consumer.h>
2010-10-07 03:58:12 +03:00
# include <mach/common.h>
# include <mach/hardware.h>
# include <mach/iomux-mx51.h>
# include <asm/setup.h>
# include <asm/mach-types.h>
# include <asm/mach/arch.h>
# include <asm/mach/time.h>
# include "devices-imx51.h"
2011-02-17 15:31:28 +01:00
# include "efika.h"
2010-10-07 03:58:25 +03:00
2010-11-26 15:20:52 +01:00
# define EFIKAMX_PCBID0 IMX_GPIO_NR(3, 16)
# define EFIKAMX_PCBID1 IMX_GPIO_NR(3, 17)
# define EFIKAMX_PCBID2 IMX_GPIO_NR(3, 11)
2010-10-27 14:40:46 +02:00
2010-11-26 15:20:52 +01:00
# define EFIKAMX_BLUE_LED IMX_GPIO_NR(3, 13)
# define EFIKAMX_GREEN_LED IMX_GPIO_NR(3, 14)
# define EFIKAMX_RED_LED IMX_GPIO_NR(3, 15)
2010-10-27 14:40:51 +02:00
2010-11-26 15:20:52 +01:00
# define EFIKAMX_POWER_KEY IMX_GPIO_NR(2, 31)
2010-10-27 14:40:52 +02:00
2010-10-27 14:40:55 +02:00
/* board 1.1 doesn't have same reset gpio */
2010-11-26 15:20:52 +01:00
# define EFIKAMX_RESET1_1 IMX_GPIO_NR(3, 2)
# define EFIKAMX_RESET IMX_GPIO_NR(1, 4)
2010-10-27 14:40:55 +02:00
2011-02-17 15:31:30 +01:00
# define EFIKAMX_POWEROFF IMX_GPIO_NR(4, 13)
# define EFIKAMX_PMIC IMX_GPIO_NR(1, 6)
2010-10-27 14:40:46 +02:00
/* the pci ids pin have pull up. they're driven low according to board id */
# define MX51_PAD_PCBID0 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, PAD_CTL_PUS_100K_UP)
# define MX51_PAD_PCBID1 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, PAD_CTL_PUS_100K_UP)
# define MX51_PAD_PCBID2 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, PAD_CTL_PUS_100K_UP)
2010-10-27 14:40:52 +02:00
# define MX51_PAD_PWRKEY IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, PAD_CTL_PUS_100K_UP | PAD_CTL_PKE)
2010-10-27 14:40:46 +02:00
2010-10-26 14:28:31 +02:00
static iomux_v3_cfg_t mx51efikamx_pads [ ] = {
2010-10-27 14:40:46 +02:00
/* board id */
MX51_PAD_PCBID0 ,
MX51_PAD_PCBID1 ,
MX51_PAD_PCBID2 ,
2010-10-27 14:40:49 +02:00
2010-10-27 14:40:51 +02:00
/* leds */
2010-12-15 09:56:35 +01:00
MX51_PAD_CSI1_D9__GPIO3_13 ,
MX51_PAD_CSI1_VSYNC__GPIO3_14 ,
MX51_PAD_CSI1_HSYNC__GPIO3_15 ,
2010-10-27 14:40:52 +02:00
/* power key */
MX51_PAD_PWRKEY ,
2010-10-27 14:40:54 +02:00
2010-10-27 14:40:55 +02:00
/* reset */
2010-12-15 09:56:35 +01:00
MX51_PAD_DI1_PIN13__GPIO3_2 ,
MX51_PAD_GPIO1_4__GPIO1_4 ,
2011-02-17 15:31:30 +01:00
/* power off */
MX51_PAD_CSI2_VSYNC__GPIO4_13 ,
2010-10-07 03:58:12 +03:00
} ;
2010-10-27 14:40:46 +02:00
/* PCBID2 PCBID1 PCBID0 STATE
1 1 1 ER1 : rev1 .1
1 1 0 ER2 : rev1 .2
1 0 1 ER3 : rev1 .3
1 0 0 ER4 : rev1 .4
*/
static void __init mx51_efikamx_board_id ( void )
{
int id ;
/* things are taking time to settle */
msleep ( 150 ) ;
gpio_request ( EFIKAMX_PCBID0 , " pcbid0 " ) ;
gpio_direction_input ( EFIKAMX_PCBID0 ) ;
gpio_request ( EFIKAMX_PCBID1 , " pcbid1 " ) ;
gpio_direction_input ( EFIKAMX_PCBID1 ) ;
gpio_request ( EFIKAMX_PCBID2 , " pcbid2 " ) ;
gpio_direction_input ( EFIKAMX_PCBID2 ) ;
2011-06-27 22:41:06 +02:00
id = gpio_get_value ( EFIKAMX_PCBID0 ) ? 1 : 0 ;
id | = ( gpio_get_value ( EFIKAMX_PCBID1 ) ? 1 : 0 ) < < 1 ;
id | = ( gpio_get_value ( EFIKAMX_PCBID2 ) ? 1 : 0 ) < < 2 ;
2010-10-27 14:40:46 +02:00
switch ( id ) {
case 7 :
system_rev = 0x11 ;
break ;
case 6 :
system_rev = 0x12 ;
break ;
case 5 :
system_rev = 0x13 ;
break ;
case 4 :
system_rev = 0x14 ;
break ;
default :
system_rev = 0x10 ;
break ;
}
if ( ( system_rev = = 0x10 )
| | ( system_rev = = 0x12 )
| | ( system_rev = = 0x14 ) ) {
printk ( KERN_WARNING
" EfikaMX: Unsupported board revision 1.%u! \n " ,
system_rev & 0xf ) ;
}
}
2011-05-28 21:05:02 +02:00
static struct gpio_led mx51_efikamx_leds [ ] __initdata = {
2010-10-27 14:40:51 +02:00
{
. name = " efikamx:green " ,
. default_trigger = " default-on " ,
. gpio = EFIKAMX_GREEN_LED ,
} ,
{
. name = " efikamx:red " ,
. default_trigger = " ide-disk " ,
. gpio = EFIKAMX_RED_LED ,
} ,
{
. name = " efikamx:blue " ,
. default_trigger = " mmc0 " ,
. gpio = EFIKAMX_BLUE_LED ,
} ,
} ;
2011-05-28 21:05:02 +02:00
static const struct gpio_led_platform_data
mx51_efikamx_leds_data __initconst = {
2010-10-27 14:40:51 +02:00
. leds = mx51_efikamx_leds ,
. num_leds = ARRAY_SIZE ( mx51_efikamx_leds ) ,
} ;
2011-08-27 15:15:58 +02:00
static struct esdhc_platform_data sd_pdata = {
. cd_type = ESDHC_CD_CONTROLLER ,
. wp_type = ESDHC_WP_CONTROLLER ,
} ;
2010-10-27 14:40:52 +02:00
static struct gpio_keys_button mx51_efikamx_powerkey [ ] = {
{
. code = KEY_POWER ,
. gpio = EFIKAMX_POWER_KEY ,
. type = EV_PWR ,
. desc = " Power Button (CM) " ,
. wakeup = 1 ,
. debounce_interval = 10 , /* ms */
} ,
} ;
static const struct gpio_keys_platform_data mx51_efikamx_powerkey_data __initconst = {
. buttons = mx51_efikamx_powerkey ,
. nbuttons = ARRAY_SIZE ( mx51_efikamx_powerkey ) ,
} ;
2011-11-06 17:12:08 +00:00
static void mx51_efikamx_restart ( char mode , const char * cmd )
2010-10-27 14:40:55 +02:00
{
if ( system_rev = = 0x11 )
gpio_direction_output ( EFIKAMX_RESET1_1 , 0 ) ;
else
gpio_direction_output ( EFIKAMX_RESET , 0 ) ;
}
2011-02-17 15:31:30 +01:00
static struct regulator * pwgt1 , * pwgt2 , * coincell ;
static void mx51_efikamx_power_off ( void )
{
if ( ! IS_ERR ( coincell ) )
regulator_disable ( coincell ) ;
if ( ! IS_ERR ( pwgt1 ) & & ! IS_ERR ( pwgt2 ) ) {
regulator_disable ( pwgt2 ) ;
regulator_disable ( pwgt1 ) ;
}
gpio_direction_output ( EFIKAMX_POWEROFF , 1 ) ;
}
static int __init mx51_efikamx_power_init ( void )
{
if ( machine_is_mx51_efikamx ( ) ) {
pwgt1 = regulator_get ( NULL , " pwgt1 " ) ;
pwgt2 = regulator_get ( NULL , " pwgt2 " ) ;
if ( ! IS_ERR ( pwgt1 ) & & ! IS_ERR ( pwgt2 ) ) {
regulator_enable ( pwgt1 ) ;
regulator_enable ( pwgt2 ) ;
}
gpio_request ( EFIKAMX_POWEROFF , " poweroff " ) ;
pm_power_off = mx51_efikamx_power_off ;
/* enable coincell charger. maybe need a small power driver ? */
coincell = regulator_get ( NULL , " coincell " ) ;
if ( ! IS_ERR ( coincell ) ) {
regulator_set_voltage ( coincell , 3000000 , 3000000 ) ;
regulator_enable ( coincell ) ;
}
regulator_has_full_constraints ( ) ;
}
return 0 ;
}
late_initcall ( mx51_efikamx_power_init ) ;
2011-02-11 10:23:19 +01:00
static void __init mx51_efikamx_init ( void )
2010-10-07 03:58:12 +03:00
{
2011-06-06 00:07:55 +08:00
imx51_soc_init ( ) ;
2010-10-07 03:58:12 +03:00
mxc_iomux_v3_setup_multiple_pads ( mx51efikamx_pads ,
ARRAY_SIZE ( mx51efikamx_pads ) ) ;
2011-02-17 15:31:28 +01:00
efika_board_common_init ( ) ;
2010-10-27 14:40:46 +02:00
mx51_efikamx_board_id ( ) ;
2010-10-27 14:40:49 +02:00
/* on < 1.2 boards both SD controllers are used */
2010-10-27 14:40:51 +02:00
if ( system_rev < 0x12 ) {
2011-08-27 15:15:58 +02:00
imx51_add_sdhci_esdhc_imx ( 0 , NULL ) ;
imx51_add_sdhci_esdhc_imx ( 1 , & sd_pdata ) ;
2010-10-27 14:40:51 +02:00
mx51_efikamx_leds [ 2 ] . default_trigger = " mmc1 " ;
2011-08-27 15:15:58 +02:00
} else
imx51_add_sdhci_esdhc_imx ( 0 , & sd_pdata ) ;
2010-10-27 14:40:51 +02:00
2011-05-28 21:05:02 +02:00
gpio_led_register_device ( - 1 , & mx51_efikamx_leds_data ) ;
2011-04-06 13:05:26 -03:00
imx_add_gpio_keys ( & mx51_efikamx_powerkey_data ) ;
2010-10-27 14:40:54 +02:00
2010-10-27 14:40:55 +02:00
if ( system_rev = = 0x11 ) {
gpio_request ( EFIKAMX_RESET1_1 , " reset " ) ;
gpio_direction_output ( EFIKAMX_RESET1_1 , 1 ) ;
} else {
gpio_request ( EFIKAMX_RESET , " reset " ) ;
gpio_direction_output ( EFIKAMX_RESET , 1 ) ;
}
2011-02-17 15:31:29 +01:00
/*
* enable wifi by default only on mx
* sb and mx have same wlan pin but the value to enable it are
* different : /
*/
gpio_request ( EFIKA_WLAN_EN , " wlan_en " ) ;
gpio_direction_output ( EFIKA_WLAN_EN , 0 ) ;
msleep ( 10 ) ;
gpio_request ( EFIKA_WLAN_RESET , " wlan_rst " ) ;
gpio_direction_output ( EFIKA_WLAN_RESET , 0 ) ;
msleep ( 10 ) ;
gpio_set_value ( EFIKA_WLAN_RESET , 1 ) ;
2010-10-07 03:58:12 +03:00
}
static void __init mx51_efikamx_timer_init ( void )
{
mx51_clocks_init ( 32768 , 24000000 , 22579200 , 24576000 ) ;
}
2011-02-11 10:23:19 +01:00
static struct sys_timer mx51_efikamx_timer = {
. init = mx51_efikamx_timer_init ,
2010-10-07 03:58:12 +03:00
} ;
MACHINE_START ( MX51_EFIKAMX , " Genesi EfikaMX nettop " )
/* Maintainer: Amit Kucheria <amit.kucheria@linaro.org> */
2011-07-05 22:38:14 -04:00
. atag_offset = 0x100 ,
2010-10-07 03:58:12 +03:00
. map_io = mx51_map_io ,
2011-02-07 16:35:21 +01:00
. init_early = imx51_init_early ,
2010-10-07 03:58:12 +03:00
. init_irq = mx51_init_irq ,
2011-09-20 14:31:24 +02:00
. handle_irq = imx51_handle_irq ,
2011-02-11 10:23:19 +01:00
. timer = & mx51_efikamx_timer ,
. init_machine = mx51_efikamx_init ,
2011-11-06 17:12:08 +00:00
. restart = mx51_efikamx_restart ,
2010-10-07 03:58:12 +03:00
MACHINE_END