2007-07-18 14:31:46 +04:00
/*
2008-06-16 11:16:46 +04:00
* Support for CompuLab EM - X270 platform
2007-07-18 14:31:46 +04:00
*
2008-06-16 11:16:46 +04:00
* Copyright ( C ) 2007 , 2008 CompuLab , Ltd .
2007-07-18 14:31:46 +04:00
* Author : Mike Rapoport < mike @ compulab . co . il >
*
* 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/irq.h>
# include <linux/platform_device.h>
2009-02-02 09:57:55 +03:00
# include <linux/delay.h>
2007-07-18 14:31:46 +04:00
# include <linux/dm9000.h>
# include <linux/rtc-v3020.h>
# include <linux/mtd/nand.h>
# include <linux/mtd/partitions.h>
2008-12-03 10:38:10 +03:00
# include <linux/mtd/physmap.h>
2008-06-16 11:16:46 +04:00
# include <linux/input.h>
# include <linux/gpio_keys.h>
# include <linux/gpio.h>
2008-12-03 10:38:10 +03:00
# include <linux/mfd/da903x.h>
# include <linux/regulator/machine.h>
# include <linux/spi/spi.h>
# include <linux/spi/tdo24m.h>
2009-02-03 10:15:30 +03:00
# include <linux/spi/libertas_spi.h>
2010-11-23 04:12:15 +03:00
# include <linux/spi/pxa2xx_spi.h>
2009-02-02 09:57:53 +03:00
# include <linux/power_supply.h>
# include <linux/apm-emulation.h>
2009-05-12 17:31:13 +04:00
# include <linux/i2c.h>
# include <linux/i2c/pca953x.h>
2011-02-23 14:38:16 +03:00
# include <linux/i2c/pxa-i2c.h>
2009-05-18 09:53:56 +04:00
# include <linux/regulator/userspace-consumer.h>
2008-12-03 10:38:10 +03:00
# include <media/soc_camera.h>
2007-07-18 14:31:46 +04:00
# include <asm/mach-types.h>
# include <asm/mach/arch.h>
2009-01-02 18:17:22 +03:00
# include <mach/pxa27x.h>
2008-08-05 19:14:15 +04:00
# include <mach/pxa27x-udc.h>
# include <mach/audio.h>
2012-08-24 17:16:48 +04:00
# include <linux/platform_data/video-pxafb.h>
# include <linux/platform_data/usb-ohci-pxa27x.h>
# include <linux/platform_data/mmc-pxamci.h>
# include <linux/platform_data/keypad-pxa27x.h>
# include <linux/platform_data/camera-pxa.h>
2007-07-18 14:31:46 +04:00
# include "generic.h"
2009-02-02 09:57:51 +03:00
# include "devices.h"
2007-07-18 14:31:46 +04:00
2009-02-02 09:57:55 +03:00
/* EM-X270 specific GPIOs */
2008-06-16 11:16:46 +04:00
# define GPIO13_MMC_CD (13)
2009-02-02 09:57:55 +03:00
# define GPIO95_MMC_WP (95)
# define GPIO56_NAND_RB (56)
2009-05-12 17:31:13 +04:00
# define GPIO93_CAM_RESET (93)
2009-05-12 17:31:16 +04:00
# define GPIO16_USB_HUB_RESET (16)
2008-06-16 11:16:46 +04:00
2009-02-02 09:57:55 +03:00
/* eXeda specific GPIOs */
# define GPIO114_MMC_CD (114)
# define GPIO20_NAND_RB (20)
# define GPIO38_SD_PWEN (38)
2009-05-12 17:31:13 +04:00
# define GPIO37_WLAN_RST (37)
# define GPIO95_TOUCHPAD_INT (95)
# define GPIO130_CAM_RESET (130)
2009-05-12 17:31:16 +04:00
# define GPIO10_USB_HUB_RESET (10)
2008-06-16 11:16:46 +04:00
2009-02-02 09:57:55 +03:00
/* common GPIOs */
# define GPIO11_NAND_CS (11)
# define GPIO41_ETHIRQ (41)
2011-10-10 10:21:08 +04:00
# define EM_X270_ETHIRQ PXA_GPIO_TO_IRQ(GPIO41_ETHIRQ)
2009-02-03 10:15:30 +03:00
# define GPIO115_WLAN_PWEN (115)
# define GPIO19_WLAN_STRAP (19)
2009-05-12 17:31:16 +04:00
# define GPIO9_USB_VBUS_EN (9)
2008-12-03 10:38:10 +03:00
2009-02-02 09:57:54 +03:00
static int mmc_cd ;
static int nand_rb ;
static int dm9000_flags ;
2009-05-12 17:31:13 +04:00
static int cam_reset ;
2009-05-12 17:31:16 +04:00
static int usb_hub_reset ;
2009-02-02 09:57:54 +03:00
static unsigned long common_pin_config [ ] = {
2008-06-16 11:16:46 +04:00
/* AC'97 */
GPIO28_AC97_BITCLK ,
GPIO29_AC97_SDATA_IN_0 ,
GPIO30_AC97_SDATA_OUT ,
GPIO31_AC97_SYNC ,
GPIO98_AC97_SYSCLK ,
GPIO113_AC97_nRESET ,
/* BTUART */
GPIO42_BTUART_RXD ,
GPIO43_BTUART_TXD ,
GPIO44_BTUART_CTS ,
GPIO45_BTUART_RTS ,
/* STUART */
GPIO46_STUART_RXD ,
GPIO47_STUART_TXD ,
/* MCI controller */
GPIO32_MMC_CLK ,
GPIO112_MMC_CMD ,
GPIO92_MMC_DAT_0 ,
GPIO109_MMC_DAT_1 ,
GPIO110_MMC_DAT_2 ,
GPIO111_MMC_DAT_3 ,
/* LCD */
2010-01-04 06:37:14 +03:00
GPIOxx_LCD_TFT_16BPP ,
2008-06-16 11:16:46 +04:00
/* QCI */
GPIO84_CIF_FV ,
GPIO25_CIF_LV ,
GPIO53_CIF_MCLK ,
GPIO54_CIF_PCLK ,
GPIO81_CIF_DD_0 ,
GPIO55_CIF_DD_1 ,
GPIO51_CIF_DD_2 ,
GPIO50_CIF_DD_3 ,
GPIO52_CIF_DD_4 ,
GPIO48_CIF_DD_5 ,
GPIO17_CIF_DD_6 ,
GPIO12_CIF_DD_7 ,
/* I2C */
GPIO117_I2C_SCL ,
GPIO118_I2C_SDA ,
/* Keypad */
GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH ,
GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH ,
GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH ,
GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH ,
GPIO39_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH ,
GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH ,
GPIO91_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH ,
GPIO36_KP_MKIN_7 | WAKEUP_ON_LEVEL_HIGH ,
GPIO103_KP_MKOUT_0 ,
GPIO104_KP_MKOUT_1 ,
GPIO105_KP_MKOUT_2 ,
GPIO106_KP_MKOUT_3 ,
GPIO107_KP_MKOUT_4 ,
GPIO108_KP_MKOUT_5 ,
GPIO96_KP_MKOUT_6 ,
GPIO22_KP_MKOUT_7 ,
/* SSP1 */
GPIO26_SSP1_RXD ,
GPIO23_SSP1_SCLK ,
GPIO24_SSP1_SFRM ,
GPIO57_SSP1_TXD ,
/* SSP2 */
2009-02-03 10:15:30 +03:00
GPIO19_GPIO , /* SSP2 clock is used as GPIO for Libertas pin-strap */
GPIO14_GPIO ,
2008-06-16 11:16:46 +04:00
GPIO89_SSP2_TXD ,
GPIO88_SSP2_RXD ,
/* SDRAM and local bus */
GPIO15_nCS_1 ,
GPIO78_nCS_2 ,
GPIO79_nCS_3 ,
GPIO80_nCS_4 ,
GPIO49_nPWE ,
GPIO18_RDY ,
/* GPIO */
2009-02-02 09:57:51 +03:00
GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH , /* sleep/resume button */
2008-06-16 11:16:46 +04:00
/* power controls */
GPIO20_GPIO | MFP_LPM_DRIVE_LOW , /* GPRS_PWEN */
GPIO115_GPIO | MFP_LPM_DRIVE_LOW , /* WLAN_PWEN */
/* NAND controls */
GPIO11_GPIO | MFP_LPM_DRIVE_HIGH , /* NAND CE# */
/* interrupts */
GPIO41_GPIO , /* DM9000 interrupt */
} ;
2007-07-18 14:31:46 +04:00
2009-02-02 09:57:54 +03:00
static unsigned long em_x270_pin_config [ ] = {
2009-05-12 17:31:13 +04:00
GPIO13_GPIO , /* MMC card detect */
2009-05-12 17:31:16 +04:00
GPIO16_GPIO , /* USB hub reset */
2009-05-12 17:31:13 +04:00
GPIO56_GPIO , /* NAND Ready/Busy */
GPIO93_GPIO | MFP_LPM_DRIVE_LOW , /* Camera reset */
GPIO95_GPIO , /* MMC Write protect */
2009-02-02 09:57:54 +03:00
} ;
2009-02-02 09:57:55 +03:00
static unsigned long exeda_pin_config [ ] = {
2009-05-12 17:31:16 +04:00
GPIO10_GPIO , /* USB hub reset */
2009-02-02 09:57:55 +03:00
GPIO20_GPIO , /* NAND Ready/Busy */
GPIO38_GPIO | MFP_LPM_DRIVE_LOW , /* SD slot power */
2009-05-12 17:31:13 +04:00
GPIO95_GPIO , /* touchpad IRQ */
2009-02-02 09:57:55 +03:00
GPIO114_GPIO , /* MMC card detect */
} ;
2008-06-16 11:16:46 +04:00
# if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
static struct resource em_x270_dm9000_resource [ ] = {
2007-07-18 14:31:46 +04:00
[ 0 ] = {
. start = PXA_CS2_PHYS ,
. end = PXA_CS2_PHYS + 3 ,
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
. start = PXA_CS2_PHYS + 8 ,
. end = PXA_CS2_PHYS + 8 + 0x3f ,
. flags = IORESOURCE_MEM ,
} ,
[ 2 ] = {
. start = EM_X270_ETHIRQ ,
. end = EM_X270_ETHIRQ ,
2008-06-16 11:16:46 +04:00
. flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE ,
2007-07-18 14:31:46 +04:00
}
} ;
2008-06-16 11:16:46 +04:00
static struct dm9000_plat_data em_x270_dm9000_platdata = {
2009-02-02 09:57:54 +03:00
. flags = DM9000_PLATF_NO_EEPROM ,
2007-07-18 14:31:46 +04:00
} ;
2008-06-16 11:16:46 +04:00
static struct platform_device em_x270_dm9000 = {
2007-07-18 14:31:46 +04:00
. name = " dm9000 " ,
. id = 0 ,
2008-06-16 11:16:46 +04:00
. num_resources = ARRAY_SIZE ( em_x270_dm9000_resource ) ,
. resource = em_x270_dm9000_resource ,
2007-07-18 14:31:46 +04:00
. dev = {
2008-06-16 11:16:46 +04:00
. platform_data = & em_x270_dm9000_platdata ,
2007-07-18 14:31:46 +04:00
}
} ;
2008-06-16 11:16:46 +04:00
static void __init em_x270_init_dm9000 ( void )
{
2009-02-02 09:57:54 +03:00
em_x270_dm9000_platdata . flags | = dm9000_flags ;
2008-06-16 11:16:46 +04:00
platform_device_register ( & em_x270_dm9000 ) ;
}
# else
static inline void em_x270_init_dm9000 ( void ) { }
# endif
2007-07-18 14:31:46 +04:00
2008-06-16 11:16:46 +04:00
/* V3020 RTC */
# if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
2007-07-18 14:31:46 +04:00
static struct resource em_x270_v3020_resource [ ] = {
[ 0 ] = {
. start = PXA_CS4_PHYS ,
. end = PXA_CS4_PHYS + 3 ,
. flags = IORESOURCE_MEM ,
} ,
} ;
static struct v3020_platform_data em_x270_v3020_platdata = {
. leftshift = 0 ,
} ;
static struct platform_device em_x270_rtc = {
. name = " v3020 " ,
. num_resources = ARRAY_SIZE ( em_x270_v3020_resource ) ,
. resource = em_x270_v3020_resource ,
. id = - 1 ,
. dev = {
. platform_data = & em_x270_v3020_platdata ,
}
} ;
2008-06-16 11:16:46 +04:00
static void __init em_x270_init_rtc ( void )
{
platform_device_register ( & em_x270_rtc ) ;
}
# else
static inline void em_x270_init_rtc ( void ) { }
# endif
2007-07-18 14:31:46 +04:00
2008-06-16 11:16:46 +04:00
/* NAND flash */
# if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
2007-07-18 14:31:46 +04:00
static inline void nand_cs_on ( void )
{
2008-06-16 11:16:46 +04:00
gpio_set_value ( GPIO11_NAND_CS , 0 ) ;
2007-07-18 14:31:46 +04:00
}
static void nand_cs_off ( void )
{
dsb ( ) ;
2008-06-16 11:16:46 +04:00
gpio_set_value ( GPIO11_NAND_CS , 1 ) ;
2007-07-18 14:31:46 +04:00
}
/* hardware specific access to control-lines */
static void em_x270_nand_cmd_ctl ( struct mtd_info * mtd , int dat ,
unsigned int ctrl )
{
struct nand_chip * this = mtd - > priv ;
unsigned long nandaddr = ( unsigned long ) this - > IO_ADDR_W ;
dsb ( ) ;
if ( ctrl & NAND_CTRL_CHANGE ) {
if ( ctrl & NAND_ALE )
nandaddr | = ( 1 < < 3 ) ;
else
nandaddr & = ~ ( 1 < < 3 ) ;
if ( ctrl & NAND_CLE )
nandaddr | = ( 1 < < 2 ) ;
else
nandaddr & = ~ ( 1 < < 2 ) ;
if ( ctrl & NAND_NCE )
nand_cs_on ( ) ;
else
nand_cs_off ( ) ;
}
dsb ( ) ;
this - > IO_ADDR_W = ( void __iomem * ) nandaddr ;
if ( dat ! = NAND_CMD_NONE )
writel ( dat , this - > IO_ADDR_W ) ;
dsb ( ) ;
}
/* read device ready pin */
static int em_x270_nand_device_ready ( struct mtd_info * mtd )
{
dsb ( ) ;
2009-02-02 09:57:54 +03:00
return gpio_get_value ( nand_rb ) ;
2007-07-18 14:31:46 +04:00
}
static struct mtd_partition em_x270_partition_info [ ] = {
[ 0 ] = {
. name = " em_x270-0 " ,
. offset = 0 ,
. size = SZ_4M ,
} ,
[ 1 ] = {
. name = " em_x270-1 " ,
. offset = MTDPART_OFS_APPEND ,
. size = MTDPART_SIZ_FULL
} ,
} ;
struct platform_nand_data em_x270_nand_platdata = {
. chip = {
. nr_chips = 1 ,
. chip_offset = 0 ,
. nr_partitions = ARRAY_SIZE ( em_x270_partition_info ) ,
. partitions = em_x270_partition_info ,
. chip_delay = 20 ,
} ,
. ctrl = {
. hwcontrol = 0 ,
. dev_ready = em_x270_nand_device_ready ,
. select_chip = 0 ,
. cmd_ctrl = em_x270_nand_cmd_ctl ,
} ,
} ;
static struct resource em_x270_nand_resource [ ] = {
[ 0 ] = {
. start = PXA_CS1_PHYS ,
. end = PXA_CS1_PHYS + 12 ,
. flags = IORESOURCE_MEM ,
} ,
} ;
static struct platform_device em_x270_nand = {
. name = " gen_nand " ,
. num_resources = ARRAY_SIZE ( em_x270_nand_resource ) ,
. resource = em_x270_nand_resource ,
. id = - 1 ,
. dev = {
. platform_data = & em_x270_nand_platdata ,
}
} ;
2008-06-16 11:16:46 +04:00
static void __init em_x270_init_nand ( void )
{
int err ;
2007-07-18 14:31:46 +04:00
2008-06-16 11:16:46 +04:00
err = gpio_request ( GPIO11_NAND_CS , " NAND CS " ) ;
if ( err ) {
pr_warning ( " EM-X270: failed to request NAND CS gpio \n " ) ;
return ;
}
gpio_direction_output ( GPIO11_NAND_CS , 1 ) ;
2009-02-02 09:57:54 +03:00
err = gpio_request ( nand_rb , " NAND R/B " ) ;
2008-06-16 11:16:46 +04:00
if ( err ) {
pr_warning ( " EM-X270: failed to request NAND R/B gpio \n " ) ;
gpio_free ( GPIO11_NAND_CS ) ;
return ;
}
2009-02-02 09:57:54 +03:00
gpio_direction_input ( nand_rb ) ;
2008-06-16 11:16:46 +04:00
platform_device_register ( & em_x270_nand ) ;
}
# else
static inline void em_x270_init_nand ( void ) { }
# endif
2007-07-18 14:31:46 +04:00
2008-12-03 10:38:10 +03:00
# if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
static struct mtd_partition em_x270_nor_parts [ ] = {
{
. name = " Bootloader " ,
. offset = 0x00000000 ,
. size = 0x00050000 ,
. mask_flags = MTD_WRITEABLE /* force read-only */
} , {
. name = " Environment " ,
. offset = 0x00050000 ,
. size = 0x00010000 ,
} , {
. name = " Reserved " ,
. offset = 0x00060000 ,
. size = 0x00050000 ,
. mask_flags = MTD_WRITEABLE /* force read-only */
} , {
. name = " Splashscreen " ,
. offset = 0x000b0000 ,
. size = 0x00050000 ,
}
} ;
static struct physmap_flash_data em_x270_nor_data [ ] = {
[ 0 ] = {
. width = 2 ,
. parts = em_x270_nor_parts ,
. nr_parts = ARRAY_SIZE ( em_x270_nor_parts ) ,
} ,
} ;
static struct resource em_x270_nor_flash_resource = {
. start = PXA_CS0_PHYS ,
. end = PXA_CS0_PHYS + SZ_1M - 1 ,
. flags = IORESOURCE_MEM ,
} ;
static struct platform_device em_x270_physmap_flash = {
. name = " physmap-flash " ,
. id = 0 ,
. num_resources = 1 ,
. resource = & em_x270_nor_flash_resource ,
. dev = {
. platform_data = & em_x270_nor_data ,
} ,
} ;
static void __init em_x270_init_nor ( void )
{
platform_device_register ( & em_x270_physmap_flash ) ;
}
# else
static inline void em_x270_init_nor ( void ) { }
# endif
2007-07-18 14:31:46 +04:00
/* PXA27x OHCI controller setup */
2008-06-16 11:16:46 +04:00
# if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
2009-05-12 17:31:16 +04:00
static struct regulator * em_x270_usb_ldo ;
static int em_x270_usb_hub_init ( void )
{
int err ;
em_x270_usb_ldo = regulator_get ( NULL , " vcc usb " ) ;
if ( IS_ERR ( em_x270_usb_ldo ) )
return PTR_ERR ( em_x270_usb_ldo ) ;
err = gpio_request ( GPIO9_USB_VBUS_EN , " vbus en " ) ;
if ( err )
goto err_free_usb_ldo ;
err = gpio_request ( usb_hub_reset , " hub rst " ) ;
if ( err )
goto err_free_vbus_gpio ;
/* USB Hub power-on and reset */
2009-12-06 16:45:43 +03:00
gpio_direction_output ( usb_hub_reset , 1 ) ;
gpio_direction_output ( GPIO9_USB_VBUS_EN , 0 ) ;
2009-05-12 17:31:16 +04:00
regulator_enable ( em_x270_usb_ldo ) ;
gpio_set_value ( usb_hub_reset , 0 ) ;
2009-12-06 16:45:43 +03:00
gpio_set_value ( usb_hub_reset , 1 ) ;
2009-05-12 17:31:16 +04:00
regulator_disable ( em_x270_usb_ldo ) ;
regulator_enable ( em_x270_usb_ldo ) ;
2009-12-06 16:45:43 +03:00
gpio_set_value ( usb_hub_reset , 0 ) ;
gpio_set_value ( GPIO9_USB_VBUS_EN , 1 ) ;
2009-05-12 17:31:16 +04:00
return 0 ;
err_free_vbus_gpio :
gpio_free ( GPIO9_USB_VBUS_EN ) ;
err_free_usb_ldo :
regulator_put ( em_x270_usb_ldo ) ;
return err ;
}
2007-07-18 14:31:46 +04:00
static int em_x270_ohci_init ( struct device * dev )
{
2009-05-12 17:31:16 +04:00
int err ;
/* we don't want to entirely disable USB if the HUB init failed */
err = em_x270_usb_hub_init ( ) ;
if ( err )
pr_err ( " USB Hub initialization failed: %d \n " , err ) ;
2007-07-18 14:31:46 +04:00
/* enable port 2 transiever */
UP2OCR = UP2OCR_HXS | UP2OCR_HXOE ;
return 0 ;
}
2009-05-12 17:31:16 +04:00
static void em_x270_ohci_exit ( struct device * dev )
{
gpio_free ( usb_hub_reset ) ;
gpio_free ( GPIO9_USB_VBUS_EN ) ;
if ( ! IS_ERR ( em_x270_usb_ldo ) ) {
if ( regulator_is_enabled ( em_x270_usb_ldo ) )
regulator_disable ( em_x270_usb_ldo ) ;
regulator_put ( em_x270_usb_ldo ) ;
}
}
2007-07-18 14:31:46 +04:00
static struct pxaohci_platform_data em_x270_ohci_platform_data = {
. port_mode = PMM_PERPORT_MODE ,
2008-09-27 11:49:57 +04:00
. flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW ,
2007-07-18 14:31:46 +04:00
. init = em_x270_ohci_init ,
2009-05-12 17:31:16 +04:00
. exit = em_x270_ohci_exit ,
2007-07-18 14:31:46 +04:00
} ;
2008-06-16 11:16:46 +04:00
static void __init em_x270_init_ohci ( void )
{
pxa_set_ohci_info ( & em_x270_ohci_platform_data ) ;
}
# else
static inline void em_x270_init_ohci ( void ) { }
# endif
2007-07-18 14:31:46 +04:00
2008-06-16 11:16:46 +04:00
/* MCI controller setup */
# if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
2009-02-02 09:57:51 +03:00
static struct regulator * em_x270_sdio_ldo ;
2007-07-18 14:31:46 +04:00
static int em_x270_mci_init ( struct device * dev ,
irq_handler_t em_x270_detect_int ,
void * data )
{
2009-02-02 09:57:51 +03:00
int err ;
em_x270_sdio_ldo = regulator_get ( dev , " vcc sdio " ) ;
if ( IS_ERR ( em_x270_sdio_ldo ) ) {
dev_err ( dev , " can't request SDIO power supply: %ld \n " ,
PTR_ERR ( em_x270_sdio_ldo ) ) ;
return PTR_ERR ( em_x270_sdio_ldo ) ;
}
2009-02-02 09:57:54 +03:00
err = request_irq ( gpio_to_irq ( mmc_cd ) , em_x270_detect_int ,
2009-02-02 09:57:51 +03:00
IRQF_DISABLED | IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING ,
2008-06-16 11:16:46 +04:00
" MMC card detect " , data ) ;
2007-07-18 14:31:46 +04:00
if ( err ) {
2009-02-02 09:57:51 +03:00
dev_err ( dev , " can't request MMC card detect IRQ: %d \n " , err ) ;
goto err_irq ;
}
2009-02-02 09:57:55 +03:00
if ( machine_is_em_x270 ( ) ) {
err = gpio_request ( GPIO95_MMC_WP , " MMC WP " ) ;
if ( err ) {
dev_err ( dev , " can't request MMC write protect: %d \n " ,
err ) ;
goto err_gpio_wp ;
}
gpio_direction_input ( GPIO95_MMC_WP ) ;
} else {
err = gpio_request ( GPIO38_SD_PWEN , " sdio power " ) ;
if ( err ) {
dev_err ( dev , " can't request MMC power control : %d \n " ,
err ) ;
goto err_gpio_wp ;
}
gpio_direction_output ( GPIO38_SD_PWEN , 1 ) ;
2007-07-18 14:31:46 +04:00
}
return 0 ;
2009-02-02 09:57:51 +03:00
err_gpio_wp :
2009-02-02 09:57:54 +03:00
free_irq ( gpio_to_irq ( mmc_cd ) , data ) ;
2009-02-02 09:57:51 +03:00
err_irq :
regulator_put ( em_x270_sdio_ldo ) ;
return err ;
2007-07-18 14:31:46 +04:00
}
static void em_x270_mci_setpower ( struct device * dev , unsigned int vdd )
{
2009-02-02 09:57:51 +03:00
struct pxamci_platform_data * p_d = dev - > platform_data ;
if ( ( 1 < < vdd ) & p_d - > ocr_mask ) {
int vdd_uV = ( 2000 + ( vdd - __ffs ( MMC_VDD_20_21 ) ) * 100 ) * 1000 ;
regulator_set_voltage ( em_x270_sdio_ldo , vdd_uV , vdd_uV ) ;
regulator_enable ( em_x270_sdio_ldo ) ;
} else {
regulator_disable ( em_x270_sdio_ldo ) ;
}
2007-07-18 14:31:46 +04:00
}
static void em_x270_mci_exit ( struct device * dev , void * data )
{
2009-02-02 09:57:54 +03:00
free_irq ( gpio_to_irq ( mmc_cd ) , data ) ;
2009-02-02 09:57:55 +03:00
regulator_put ( em_x270_sdio_ldo ) ;
if ( machine_is_em_x270 ( ) )
gpio_free ( GPIO95_MMC_WP ) ;
else
gpio_free ( GPIO38_SD_PWEN ) ;
2009-02-02 09:57:51 +03:00
}
static int em_x270_mci_get_ro ( struct device * dev )
{
return gpio_get_value ( GPIO95_MMC_WP ) ;
2007-07-18 14:31:46 +04:00
}
static struct pxamci_platform_data em_x270_mci_platform_data = {
2010-04-14 03:00:42 +04:00
. detect_delay_ms = 250 ,
2009-07-07 00:16:42 +04:00
. ocr_mask = MMC_VDD_20_21 | MMC_VDD_21_22 | MMC_VDD_22_23 |
MMC_VDD_24_25 | MMC_VDD_25_26 | MMC_VDD_26_27 |
MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
MMC_VDD_30_31 | MMC_VDD_31_32 ,
. init = em_x270_mci_init ,
. setpower = em_x270_mci_setpower ,
. exit = em_x270_mci_exit ,
. gpio_card_detect = - 1 ,
. gpio_card_ro = - 1 ,
. gpio_power = - 1 ,
2007-07-18 14:31:46 +04:00
} ;
2008-06-16 11:16:46 +04:00
static void __init em_x270_init_mmc ( void )
{
2009-02-02 09:57:55 +03:00
if ( machine_is_em_x270 ( ) )
em_x270_mci_platform_data . get_ro = em_x270_mci_get_ro ;
2008-06-16 11:16:46 +04:00
pxa_set_mci_info ( & em_x270_mci_platform_data ) ;
}
# else
static inline void em_x270_init_mmc ( void ) { }
# endif
2008-12-03 10:38:10 +03:00
/* LCD */
2008-06-16 11:16:46 +04:00
# if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
2008-12-03 10:38:10 +03:00
static struct pxafb_mode_info em_x270_lcd_modes [ ] = {
[ 0 ] = {
. pixclock = 38250 ,
. bpp = 16 ,
. xres = 480 ,
. yres = 640 ,
. hsync_len = 8 ,
. vsync_len = 2 ,
. left_margin = 8 ,
. upper_margin = 2 ,
. right_margin = 24 ,
. lower_margin = 4 ,
. sync = 0 ,
} ,
[ 1 ] = {
. pixclock = 153800 ,
. bpp = 16 ,
. xres = 240 ,
. yres = 320 ,
. hsync_len = 8 ,
. vsync_len = 2 ,
. left_margin = 8 ,
. upper_margin = 2 ,
. right_margin = 88 ,
. lower_margin = 2 ,
. sync = 0 ,
} ,
2007-07-18 14:31:46 +04:00
} ;
static struct pxafb_mach_info em_x270_lcd = {
2008-12-03 10:38:10 +03:00
. modes = em_x270_lcd_modes ,
. num_modes = 2 ,
2008-06-16 11:16:46 +04:00
. lcd_conn = LCD_COLOR_TFT_16BPP ,
2007-07-18 14:31:46 +04:00
} ;
2008-12-03 10:38:10 +03:00
2008-06-16 11:16:46 +04:00
static void __init em_x270_init_lcd ( void )
2007-07-18 14:31:46 +04:00
{
2011-02-15 10:37:30 +03:00
pxa_set_fb_info ( NULL , & em_x270_lcd ) ;
2008-06-16 11:16:46 +04:00
}
# else
static inline void em_x270_init_lcd ( void ) { }
# endif
2007-07-18 14:31:46 +04:00
2008-12-03 10:38:10 +03:00
# if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
static struct pxa2xx_spi_master em_x270_spi_info = {
. num_chipselect = 1 ,
} ;
static struct pxa2xx_spi_chip em_x270_tdo24m_chip = {
2009-04-14 09:32:55 +04:00
. rx_threshold = 1 ,
. tx_threshold = 1 ,
. gpio_cs = - 1 ,
2008-12-03 10:38:10 +03:00
} ;
static struct tdo24m_platform_data em_x270_tdo24m_pdata = {
. model = TDO35S ,
} ;
2009-02-03 10:15:30 +03:00
static struct pxa2xx_spi_master em_x270_spi_2_info = {
. num_chipselect = 1 ,
. enable_dma = 1 ,
} ;
static struct pxa2xx_spi_chip em_x270_libertas_chip = {
. rx_threshold = 1 ,
. tx_threshold = 1 ,
. timeout = 1000 ,
2009-06-16 16:19:24 +04:00
. gpio_cs = 14 ,
2009-02-03 10:15:30 +03:00
} ;
static unsigned long em_x270_libertas_pin_config [ ] = {
/* SSP2 */
GPIO19_SSP2_SCLK ,
GPIO14_GPIO ,
GPIO89_SSP2_TXD ,
GPIO88_SSP2_RXD ,
} ;
static int em_x270_libertas_setup ( struct spi_device * spi )
{
int err = gpio_request ( GPIO115_WLAN_PWEN , " WLAN PWEN " ) ;
if ( err )
return err ;
2009-05-12 17:31:14 +04:00
err = gpio_request ( GPIO19_WLAN_STRAP , " WLAN STRAP " ) ;
if ( err )
goto err_free_pwen ;
if ( machine_is_exeda ( ) ) {
err = gpio_request ( GPIO37_WLAN_RST , " WLAN RST " ) ;
if ( err )
goto err_free_strap ;
gpio_direction_output ( GPIO37_WLAN_RST , 1 ) ;
msleep ( 100 ) ;
}
2009-02-03 10:15:30 +03:00
gpio_direction_output ( GPIO19_WLAN_STRAP , 1 ) ;
2009-05-12 17:31:14 +04:00
msleep ( 100 ) ;
2009-02-03 10:15:30 +03:00
pxa2xx_mfp_config ( ARRAY_AND_SIZE ( em_x270_libertas_pin_config ) ) ;
gpio_direction_output ( GPIO115_WLAN_PWEN , 0 ) ;
2009-05-12 17:31:14 +04:00
msleep ( 100 ) ;
2009-02-03 10:15:30 +03:00
gpio_set_value ( GPIO115_WLAN_PWEN , 1 ) ;
2009-05-12 17:31:14 +04:00
msleep ( 100 ) ;
2009-02-03 10:15:30 +03:00
spi - > bits_per_word = 16 ;
spi_setup ( spi ) ;
return 0 ;
2009-05-12 17:31:14 +04:00
err_free_strap :
gpio_free ( GPIO19_WLAN_STRAP ) ;
err_free_pwen :
gpio_free ( GPIO115_WLAN_PWEN ) ;
return err ;
2009-02-03 10:15:30 +03:00
}
static int em_x270_libertas_teardown ( struct spi_device * spi )
{
gpio_set_value ( GPIO115_WLAN_PWEN , 0 ) ;
gpio_free ( GPIO115_WLAN_PWEN ) ;
2009-05-12 17:31:14 +04:00
gpio_free ( GPIO19_WLAN_STRAP ) ;
if ( machine_is_exeda ( ) ) {
gpio_set_value ( GPIO37_WLAN_RST , 0 ) ;
gpio_free ( GPIO37_WLAN_RST ) ;
}
2009-02-03 10:15:30 +03:00
return 0 ;
}
struct libertas_spi_platform_data em_x270_libertas_pdata = {
. use_dummy_writes = 1 ,
. setup = em_x270_libertas_setup ,
. teardown = em_x270_libertas_teardown ,
} ;
2008-12-03 10:38:10 +03:00
static struct spi_board_info em_x270_spi_devices [ ] __initdata = {
{
2009-02-03 10:15:30 +03:00
. modalias = " tdo24m " ,
. max_speed_hz = 1000000 ,
. bus_num = 1 ,
. chip_select = 0 ,
. controller_data = & em_x270_tdo24m_chip ,
. platform_data = & em_x270_tdo24m_pdata ,
} ,
{
. modalias = " libertas_spi " ,
. max_speed_hz = 13000000 ,
. bus_num = 2 ,
2011-10-10 10:21:08 +04:00
. irq = PXA_GPIO_TO_IRQ ( 116 ) ,
2009-02-03 10:15:30 +03:00
. chip_select = 0 ,
. controller_data = & em_x270_libertas_chip ,
. platform_data = & em_x270_libertas_pdata ,
2008-12-03 10:38:10 +03:00
} ,
} ;
static void __init em_x270_init_spi ( void )
{
pxa2xx_set_spi_info ( 1 , & em_x270_spi_info ) ;
2009-02-03 10:15:30 +03:00
pxa2xx_set_spi_info ( 2 , & em_x270_spi_2_info ) ;
2008-12-03 10:38:10 +03:00
spi_register_board_info ( ARRAY_AND_SIZE ( em_x270_spi_devices ) ) ;
}
# else
static inline void em_x270_init_spi ( void ) { }
# endif
2009-06-14 13:04:19 +04:00
# if defined(CONFIG_SND_PXA2XX_LIB_AC97)
2009-05-11 16:06:16 +04:00
static pxa2xx_audio_ops_t em_x270_ac97_info = {
. reset_gpio = 113 ,
} ;
2008-06-16 11:16:46 +04:00
static void __init em_x270_init_ac97 ( void )
{
2009-05-11 16:06:16 +04:00
pxa_set_ac97_info ( & em_x270_ac97_info ) ;
2008-06-16 11:16:46 +04:00
}
# else
static inline void em_x270_init_ac97 ( void ) { }
# endif
# if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
2009-02-02 09:57:55 +03:00
static unsigned int em_x270_module_matrix_keys [ ] = {
2008-06-16 11:16:46 +04:00
KEY ( 0 , 0 , KEY_A ) , KEY ( 1 , 0 , KEY_UP ) , KEY ( 2 , 1 , KEY_B ) ,
KEY ( 0 , 2 , KEY_LEFT ) , KEY ( 1 , 1 , KEY_ENTER ) , KEY ( 2 , 0 , KEY_RIGHT ) ,
KEY ( 0 , 1 , KEY_C ) , KEY ( 1 , 2 , KEY_DOWN ) , KEY ( 2 , 2 , KEY_D ) ,
} ;
2007-07-18 14:31:46 +04:00
2009-02-02 09:57:55 +03:00
struct pxa27x_keypad_platform_data em_x270_module_keypad_info = {
2008-06-16 11:16:46 +04:00
/* code map for the matrix keys */
. matrix_key_rows = 3 ,
. matrix_key_cols = 3 ,
2009-02-02 09:57:55 +03:00
. matrix_key_map = em_x270_module_matrix_keys ,
. matrix_key_map_size = ARRAY_SIZE ( em_x270_module_matrix_keys ) ,
} ;
static unsigned int em_x270_exeda_matrix_keys [ ] = {
KEY ( 0 , 0 , KEY_RIGHTSHIFT ) , KEY ( 0 , 1 , KEY_RIGHTCTRL ) ,
KEY ( 0 , 2 , KEY_RIGHTALT ) , KEY ( 0 , 3 , KEY_SPACE ) ,
KEY ( 0 , 4 , KEY_LEFTALT ) , KEY ( 0 , 5 , KEY_LEFTCTRL ) ,
KEY ( 0 , 6 , KEY_ENTER ) , KEY ( 0 , 7 , KEY_SLASH ) ,
KEY ( 1 , 0 , KEY_DOT ) , KEY ( 1 , 1 , KEY_M ) ,
KEY ( 1 , 2 , KEY_N ) , KEY ( 1 , 3 , KEY_B ) ,
KEY ( 1 , 4 , KEY_V ) , KEY ( 1 , 5 , KEY_C ) ,
KEY ( 1 , 6 , KEY_X ) , KEY ( 1 , 7 , KEY_Z ) ,
KEY ( 2 , 0 , KEY_LEFTSHIFT ) , KEY ( 2 , 1 , KEY_SEMICOLON ) ,
KEY ( 2 , 2 , KEY_L ) , KEY ( 2 , 3 , KEY_K ) ,
KEY ( 2 , 4 , KEY_J ) , KEY ( 2 , 5 , KEY_H ) ,
KEY ( 2 , 6 , KEY_G ) , KEY ( 2 , 7 , KEY_F ) ,
KEY ( 3 , 0 , KEY_D ) , KEY ( 3 , 1 , KEY_S ) ,
KEY ( 3 , 2 , KEY_A ) , KEY ( 3 , 3 , KEY_TAB ) ,
KEY ( 3 , 4 , KEY_BACKSPACE ) , KEY ( 3 , 5 , KEY_P ) ,
KEY ( 3 , 6 , KEY_O ) , KEY ( 3 , 7 , KEY_I ) ,
KEY ( 4 , 0 , KEY_U ) , KEY ( 4 , 1 , KEY_Y ) ,
KEY ( 4 , 2 , KEY_T ) , KEY ( 4 , 3 , KEY_R ) ,
KEY ( 4 , 4 , KEY_E ) , KEY ( 4 , 5 , KEY_W ) ,
KEY ( 4 , 6 , KEY_Q ) , KEY ( 4 , 7 , KEY_MINUS ) ,
KEY ( 5 , 0 , KEY_0 ) , KEY ( 5 , 1 , KEY_9 ) ,
KEY ( 5 , 2 , KEY_8 ) , KEY ( 5 , 3 , KEY_7 ) ,
KEY ( 5 , 4 , KEY_6 ) , KEY ( 5 , 5 , KEY_5 ) ,
KEY ( 5 , 6 , KEY_4 ) , KEY ( 5 , 7 , KEY_3 ) ,
KEY ( 6 , 0 , KEY_2 ) , KEY ( 6 , 1 , KEY_1 ) ,
KEY ( 6 , 2 , KEY_ENTER ) , KEY ( 6 , 3 , KEY_END ) ,
KEY ( 6 , 4 , KEY_DOWN ) , KEY ( 6 , 5 , KEY_UP ) ,
KEY ( 6 , 6 , KEY_MENU ) , KEY ( 6 , 7 , KEY_F1 ) ,
KEY ( 7 , 0 , KEY_LEFT ) , KEY ( 7 , 1 , KEY_RIGHT ) ,
KEY ( 7 , 2 , KEY_BACK ) , KEY ( 7 , 3 , KEY_HOME ) ,
KEY ( 7 , 4 , 0 ) , KEY ( 7 , 5 , 0 ) ,
KEY ( 7 , 6 , 0 ) , KEY ( 7 , 7 , 0 ) ,
} ;
struct pxa27x_keypad_platform_data em_x270_exeda_keypad_info = {
/* code map for the matrix keys */
. matrix_key_rows = 8 ,
. matrix_key_cols = 8 ,
. matrix_key_map = em_x270_exeda_matrix_keys ,
. matrix_key_map_size = ARRAY_SIZE ( em_x270_exeda_matrix_keys ) ,
2008-06-16 11:16:46 +04:00
} ;
static void __init em_x270_init_keypad ( void )
{
2009-02-02 09:57:55 +03:00
if ( machine_is_em_x270 ( ) )
pxa_set_keypad_info ( & em_x270_module_keypad_info ) ;
else
pxa_set_keypad_info ( & em_x270_exeda_keypad_info ) ;
2008-06-16 11:16:46 +04:00
}
# else
static inline void em_x270_init_keypad ( void ) { }
# endif
2007-07-18 14:31:46 +04:00
2008-06-16 11:16:46 +04:00
# if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
static struct gpio_keys_button gpio_keys_button [ ] = {
[ 0 ] = {
. desc = " sleep/wakeup " ,
. code = KEY_SUSPEND ,
. type = EV_PWR ,
. gpio = 1 ,
. wakeup = 1 ,
} ,
} ;
2007-07-18 14:31:46 +04:00
2008-06-16 11:16:46 +04:00
static struct gpio_keys_platform_data em_x270_gpio_keys_data = {
. buttons = gpio_keys_button ,
. nbuttons = 1 ,
} ;
2007-07-18 14:31:46 +04:00
2008-06-16 11:16:46 +04:00
static struct platform_device em_x270_gpio_keys = {
. name = " gpio-keys " ,
. id = - 1 ,
. dev = {
. platform_data = & em_x270_gpio_keys_data ,
} ,
} ;
static void __init em_x270_init_gpio_keys ( void )
{
platform_device_register ( & em_x270_gpio_keys ) ;
}
# else
static inline void em_x270_init_gpio_keys ( void ) { }
# endif
2008-12-03 10:38:10 +03:00
/* Quick Capture Interface and sensor setup */
# if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
static struct regulator * em_x270_camera_ldo ;
2009-11-27 23:30:23 +03:00
static int em_x270_sensor_init ( void )
2008-12-03 10:38:10 +03:00
{
int ret ;
2009-05-12 17:31:13 +04:00
ret = gpio_request ( cam_reset , " camera reset " ) ;
2008-12-03 10:38:10 +03:00
if ( ret )
return ret ;
2009-05-12 17:31:13 +04:00
gpio_direction_output ( cam_reset , 0 ) ;
2008-12-03 10:38:10 +03:00
em_x270_camera_ldo = regulator_get ( NULL , " vcc cam " ) ;
if ( em_x270_camera_ldo = = NULL ) {
2009-05-12 17:31:13 +04:00
gpio_free ( cam_reset ) ;
2008-12-03 10:38:10 +03:00
return - ENODEV ;
}
ret = regulator_enable ( em_x270_camera_ldo ) ;
if ( ret ) {
regulator_put ( em_x270_camera_ldo ) ;
2009-05-12 17:31:13 +04:00
gpio_free ( cam_reset ) ;
2008-12-03 10:38:10 +03:00
return ret ;
}
2009-05-12 17:31:13 +04:00
gpio_set_value ( cam_reset , 1 ) ;
2008-12-03 10:38:10 +03:00
return 0 ;
}
struct pxacamera_platform_data em_x270_camera_platform_data = {
. flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN ,
. mclk_10khz = 2600 ,
} ;
static int em_x270_sensor_power ( struct device * dev , int on )
{
int ret ;
int is_on = regulator_is_enabled ( em_x270_camera_ldo ) ;
if ( on = = is_on )
return 0 ;
2009-05-12 17:31:13 +04:00
gpio_set_value ( cam_reset , ! on ) ;
2008-12-03 10:38:10 +03:00
if ( on )
ret = regulator_enable ( em_x270_camera_ldo ) ;
else
ret = regulator_disable ( em_x270_camera_ldo ) ;
if ( ret )
return ret ;
2009-05-12 17:31:13 +04:00
gpio_set_value ( cam_reset , on ) ;
2008-12-03 10:38:10 +03:00
return 0 ;
}
static struct i2c_board_info em_x270_i2c_cam_info [ ] = {
{
I2C_BOARD_INFO ( " mt9m111 " , 0x48 ) ,
2009-05-12 20:12:29 +04:00
} ,
} ;
static struct soc_camera_link iclink = {
. bus_id = 0 ,
. power = em_x270_sensor_power ,
. board_info = & em_x270_i2c_cam_info [ 0 ] ,
. i2c_adapter_id = 0 ,
} ;
static struct platform_device em_x270_camera = {
. name = " soc-camera-pdrv " ,
. id = - 1 ,
. dev = {
2008-12-03 10:38:10 +03:00
. platform_data = & iclink ,
} ,
} ;
static void __init em_x270_init_camera ( void )
{
2009-11-27 23:30:23 +03:00
if ( em_x270_sensor_init ( ) = = 0 ) {
pxa_set_camera_info ( & em_x270_camera_platform_data ) ;
platform_device_register ( & em_x270_camera ) ;
}
2008-12-03 10:38:10 +03:00
}
# else
static inline void em_x270_init_camera ( void ) { }
# endif
2009-05-18 09:53:56 +04:00
static struct regulator_bulk_data em_x270_gps_consumer_supply = {
. supply = " vcc gps " ,
} ;
static struct regulator_userspace_consumer_data em_x270_gps_consumer_data = {
. name = " vcc gps " ,
. num_supplies = 1 ,
. supplies = & em_x270_gps_consumer_supply ,
} ;
static struct platform_device em_x270_gps_userspace_consumer = {
. name = " reg-userspace-consumer " ,
. id = 0 ,
. dev = {
. platform_data = & em_x270_gps_consumer_data ,
} ,
} ;
static struct regulator_bulk_data em_x270_gprs_consumer_supply = {
. supply = " vcc gprs " ,
} ;
static struct regulator_userspace_consumer_data em_x270_gprs_consumer_data = {
. name = " vcc gprs " ,
. num_supplies = 1 ,
. supplies = & em_x270_gprs_consumer_supply
} ;
static struct platform_device em_x270_gprs_userspace_consumer = {
. name = " reg-userspace-consumer " ,
. id = 1 ,
. dev = {
. platform_data = & em_x270_gprs_consumer_data ,
}
} ;
static struct platform_device * em_x270_userspace_consumers [ ] = {
& em_x270_gps_userspace_consumer ,
& em_x270_gprs_userspace_consumer ,
} ;
static void __init em_x270_userspace_consumers_init ( void )
{
platform_add_devices ( ARRAY_AND_SIZE ( em_x270_userspace_consumers ) ) ;
}
2008-12-03 10:38:10 +03:00
/* DA9030 related initializations */
2012-03-30 04:41:02 +04:00
# define REGULATOR_CONSUMER(_name, _dev_name, _supply) \
2009-02-02 09:57:52 +03:00
static struct regulator_consumer_supply _name # # _consumers [ ] = { \
2012-05-08 12:25:10 +04:00
REGULATOR_SUPPLY ( _supply , _dev_name ) , \
2009-02-02 09:57:52 +03:00
}
2008-12-03 10:38:10 +03:00
2012-03-30 04:41:02 +04:00
REGULATOR_CONSUMER ( ldo3 , " reg-userspace-consumer.0 " , " vcc gps " ) ;
2009-02-02 09:57:52 +03:00
REGULATOR_CONSUMER ( ldo5 , NULL , " vcc cam " ) ;
2012-03-30 04:41:02 +04:00
REGULATOR_CONSUMER ( ldo10 , " pxa2xx-mci " , " vcc sdio " ) ;
2009-02-02 09:57:52 +03:00
REGULATOR_CONSUMER ( ldo12 , NULL , " vcc usb " ) ;
2012-03-30 04:41:02 +04:00
REGULATOR_CONSUMER ( ldo19 , " reg-userspace-consumer.1 " , " vcc gprs " ) ;
2009-07-26 14:48:40 +04:00
REGULATOR_CONSUMER ( buck2 , NULL , " vcc_core " ) ;
2009-02-02 09:57:52 +03:00
# define REGULATOR_INIT(_ldo, _min_uV, _max_uV, _ops_mask) \
static struct regulator_init_data _ldo # # _data = { \
. constraints = { \
. min_uV = _min_uV , \
. max_uV = _max_uV , \
. state_mem = { \
. enabled = 0 , \
} , \
. valid_ops_mask = _ops_mask , \
2009-05-18 09:53:56 +04:00
. apply_uV = 1 , \
2009-02-02 09:57:52 +03:00
} , \
. num_consumer_supplies = ARRAY_SIZE ( _ldo # # _consumers ) , \
. consumer_supplies = _ldo # # _consumers , \
} ;
REGULATOR_INIT ( ldo3 , 3200000 , 3200000 , REGULATOR_CHANGE_STATUS ) ;
REGULATOR_INIT ( ldo5 , 3000000 , 3000000 , REGULATOR_CHANGE_STATUS ) ;
REGULATOR_INIT ( ldo10 , 2000000 , 3200000 ,
REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE ) ;
REGULATOR_INIT ( ldo12 , 3000000 , 3000000 , REGULATOR_CHANGE_STATUS ) ;
REGULATOR_INIT ( ldo19 , 3200000 , 3200000 , REGULATOR_CHANGE_STATUS ) ;
2009-07-26 14:48:40 +04:00
REGULATOR_INIT ( buck2 , 1000000 , 1650000 , REGULATOR_CHANGE_VOLTAGE ) ;
2008-12-03 10:38:10 +03:00
struct led_info em_x270_led_info = {
. name = " em-x270:orange " ,
. default_trigger = " battery-charging-or-full " ,
} ;
2009-02-02 09:57:53 +03:00
struct power_supply_info em_x270_psy_info = {
2009-05-12 17:31:15 +04:00
. name = " battery " ,
2009-02-02 09:57:53 +03:00
. technology = POWER_SUPPLY_TECHNOLOGY_LIPO ,
. voltage_max_design = 4200000 ,
. voltage_min_design = 3000000 ,
. use_for_apm = 1 ,
} ;
static void em_x270_battery_low ( void )
{
2009-07-21 18:09:52 +04:00
# if defined(CONFIG_APM_EMULATION)
2009-02-02 09:57:53 +03:00
apm_queue_event ( APM_LOW_BATTERY ) ;
2009-07-21 18:09:52 +04:00
# endif
2009-02-02 09:57:53 +03:00
}
static void em_x270_battery_critical ( void )
{
2009-07-21 18:09:52 +04:00
# if defined(CONFIG_APM_EMULATION)
2009-02-02 09:57:53 +03:00
apm_queue_event ( APM_CRITICAL_SUSPEND ) ;
2009-07-21 18:09:52 +04:00
# endif
2009-02-02 09:57:53 +03:00
}
struct da9030_battery_info em_x270_batterty_info = {
. battery_info = & em_x270_psy_info ,
. charge_milliamp = 1000 ,
. charge_millivolt = 4200 ,
. vbat_low = 3600 ,
. vbat_crit = 3400 ,
. vbat_charge_start = 4100 ,
. vbat_charge_stop = 4200 ,
. vbat_charge_restart = 4000 ,
. vcharge_min = 3200 ,
. vcharge_max = 5500 ,
. tbat_low = 197 ,
. tbat_high = 78 ,
. tbat_restart = 100 ,
. batmon_interval = 0 ,
. battery_low = em_x270_battery_low ,
. battery_critical = em_x270_battery_critical ,
} ;
2009-02-02 09:57:52 +03:00
# define DA9030_SUBDEV(_name, _id, _pdata) \
{ \
. name = " da903x- " # _name , \
. id = DA9030_ID_ # # _id , \
. platform_data = _pdata , \
2008-12-03 10:38:10 +03:00
}
2009-02-02 09:57:52 +03:00
# define DA9030_LDO(num) DA9030_SUBDEV(regulator, LDO##num, &ldo##num##_data)
struct da903x_subdev_info em_x270_da9030_subdevs [ ] = {
DA9030_LDO ( 3 ) ,
DA9030_LDO ( 5 ) ,
DA9030_LDO ( 10 ) ,
DA9030_LDO ( 12 ) ,
DA9030_LDO ( 19 ) ,
2009-07-26 14:48:40 +04:00
DA9030_SUBDEV ( regulator , BUCK2 , & buck2_data ) ,
2009-02-02 09:57:52 +03:00
DA9030_SUBDEV ( led , LED_PC , & em_x270_led_info ) ,
DA9030_SUBDEV ( backlight , WLED , & em_x270_led_info ) ,
2009-02-02 09:57:53 +03:00
DA9030_SUBDEV ( battery , BAT , & em_x270_batterty_info ) ,
2008-12-03 10:38:10 +03:00
} ;
static struct da903x_platform_data em_x270_da9030_info = {
. num_subdevs = ARRAY_SIZE ( em_x270_da9030_subdevs ) ,
. subdevs = em_x270_da9030_subdevs ,
} ;
static struct i2c_board_info em_x270_i2c_pmic_info = {
I2C_BOARD_INFO ( " da9030 " , 0x49 ) ,
2011-10-10 10:21:08 +04:00
. irq = PXA_GPIO_TO_IRQ ( 0 ) ,
2008-12-03 10:38:10 +03:00
. platform_data = & em_x270_da9030_info ,
} ;
static struct i2c_pxa_platform_data em_x270_pwr_i2c_info = {
. use_pio = 1 ,
} ;
static void __init em_x270_init_da9030 ( void )
{
pxa27x_set_i2c_power_info ( & em_x270_pwr_i2c_info ) ;
i2c_register_board_info ( 1 , & em_x270_i2c_pmic_info , 1 ) ;
}
2009-05-12 17:31:13 +04:00
static struct pca953x_platform_data exeda_gpio_ext_pdata = {
. gpio_base = 128 ,
} ;
static struct i2c_board_info exeda_i2c_info [ ] = {
{
I2C_BOARD_INFO ( " pca9555 " , 0x21 ) ,
. platform_data = & exeda_gpio_ext_pdata ,
} ,
} ;
static struct i2c_pxa_platform_data em_x270_i2c_info = {
. fast_mode = 1 ,
} ;
static void __init em_x270_init_i2c ( void )
{
pxa_set_i2c_info ( & em_x270_i2c_info ) ;
if ( machine_is_exeda ( ) )
i2c_register_board_info ( 0 , ARRAY_AND_SIZE ( exeda_i2c_info ) ) ;
}
2009-02-02 09:57:54 +03:00
static void __init em_x270_module_init ( void )
2008-06-16 11:16:46 +04:00
{
pxa2xx_mfp_config ( ARRAY_AND_SIZE ( em_x270_pin_config ) ) ;
2009-02-02 09:57:54 +03:00
mmc_cd = GPIO13_MMC_CD ;
nand_rb = GPIO56_NAND_RB ;
dm9000_flags = DM9000_PLATF_32BITONLY ;
2009-05-12 17:31:13 +04:00
cam_reset = GPIO93_CAM_RESET ;
2009-05-12 17:31:16 +04:00
usb_hub_reset = GPIO16_USB_HUB_RESET ;
2009-02-02 09:57:54 +03:00
}
2009-02-02 09:57:55 +03:00
static void __init em_x270_exeda_init ( void )
{
pxa2xx_mfp_config ( ARRAY_AND_SIZE ( exeda_pin_config ) ) ;
mmc_cd = GPIO114_MMC_CD ;
nand_rb = GPIO20_NAND_RB ;
dm9000_flags = DM9000_PLATF_16BITONLY ;
2009-05-12 17:31:13 +04:00
cam_reset = GPIO130_CAM_RESET ;
2009-05-12 17:31:16 +04:00
usb_hub_reset = GPIO10_USB_HUB_RESET ;
2009-02-02 09:57:55 +03:00
}
2009-02-02 09:57:54 +03:00
static void __init em_x270_init ( void )
{
pxa2xx_mfp_config ( ARRAY_AND_SIZE ( common_pin_config ) ) ;
2009-11-09 08:34:08 +03:00
pxa_set_ffuart_info ( NULL ) ;
pxa_set_btuart_info ( NULL ) ;
pxa_set_stuart_info ( NULL ) ;
2009-05-26 10:41:46 +04:00
# ifdef CONFIG_PM
pxa27x_set_pwrmode ( PWRMODE_DEEPSLEEP ) ;
# endif
2009-02-02 09:57:55 +03:00
if ( machine_is_em_x270 ( ) )
em_x270_module_init ( ) ;
else if ( machine_is_exeda ( ) )
em_x270_exeda_init ( ) ;
else
panic ( " Unsupported machine: %d \n " , machine_arch_type ) ;
2009-02-02 09:57:54 +03:00
2008-12-03 10:38:10 +03:00
em_x270_init_da9030 ( ) ;
2008-06-16 11:16:46 +04:00
em_x270_init_dm9000 ( ) ;
em_x270_init_rtc ( ) ;
em_x270_init_nand ( ) ;
2008-12-03 10:38:10 +03:00
em_x270_init_nor ( ) ;
2008-06-16 11:16:46 +04:00
em_x270_init_lcd ( ) ;
em_x270_init_mmc ( ) ;
em_x270_init_ohci ( ) ;
em_x270_init_keypad ( ) ;
em_x270_init_gpio_keys ( ) ;
em_x270_init_ac97 ( ) ;
2008-12-03 10:38:10 +03:00
em_x270_init_spi ( ) ;
2009-05-12 17:31:13 +04:00
em_x270_init_i2c ( ) ;
em_x270_init_camera ( ) ;
2009-05-18 09:53:56 +04:00
em_x270_userspace_consumers_init ( ) ;
2007-07-18 14:31:46 +04:00
}
2008-06-16 11:16:46 +04:00
MACHINE_START ( EM_X270 , " Compulab EM-X270 " )
2011-07-06 06:38:15 +04:00
. atag_offset = 0x100 ,
2010-10-11 04:20:19 +04:00
. map_io = pxa27x_map_io ,
2012-01-04 02:53:48 +04:00
. nr_irqs = PXA_NR_IRQS ,
2007-07-18 14:31:46 +04:00
. init_irq = pxa27x_init_irq ,
2011-05-18 17:30:04 +04:00
. handle_irq = pxa27x_handle_irq ,
2012-11-08 23:40:59 +04:00
. init_time = pxa_timer_init ,
2007-07-18 14:31:46 +04:00
. init_machine = em_x270_init ,
2011-11-04 18:15:53 +04:00
. restart = pxa_restart ,
2007-07-18 14:31:46 +04:00
MACHINE_END
2009-02-02 09:57:55 +03:00
MACHINE_START ( EXEDA , " Compulab eXeda " )
2011-07-06 06:38:15 +04:00
. atag_offset = 0x100 ,
2010-10-11 04:20:19 +04:00
. map_io = pxa27x_map_io ,
2012-01-04 02:53:48 +04:00
. nr_irqs = PXA_NR_IRQS ,
2009-02-02 09:57:55 +03:00
. init_irq = pxa27x_init_irq ,
2011-05-18 17:30:04 +04:00
. handle_irq = pxa27x_handle_irq ,
2012-11-08 23:40:59 +04:00
. init_time = pxa_timer_init ,
2009-02-02 09:57:55 +03:00
. init_machine = em_x270_init ,
2011-11-04 18:15:53 +04:00
. restart = pxa_restart ,
2009-02-02 09:57:55 +03:00
MACHINE_END