From 849369d6c66d3054688672f97d31fceb8e8230fb Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Dec 2015 04:40:36 +0000 Subject: initial_commit --- arch/arm/mach-mx6/board-mx6sl_ntx.c | 3886 +++++++++++++++++++++++++++++++++++ 1 file changed, 3886 insertions(+) create mode 100755 arch/arm/mach-mx6/board-mx6sl_ntx.c (limited to 'arch/arm/mach-mx6/board-mx6sl_ntx.c') diff --git a/arch/arm/mach-mx6/board-mx6sl_ntx.c b/arch/arm/mach-mx6/board-mx6sl_ntx.c new file mode 100755 index 00000000..26c3c900 --- /dev/null +++ b/arch/arm/mach-mx6/board-mx6sl_ntx.c @@ -0,0 +1,3886 @@ +/* + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include <../drivers/misc/ntx-misc.h> + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#include "usb.h" +#include "devices-imx6q.h" +#include "crm_regs.h" +#include "cpu_op-mx6.h" +#include "board-mx6sl_common.h" +#include "board-mx6sl_ntx.h" + +#include "ntx_hwconfig.h" + +#include +#include +#include +#include + +#include "../../../drivers/input/keyboard/gpiofn.h" +#define TOUCH_HOME_LED 1 +#include "../../../drivers/misc/ntx-misc.h" + + +#define GDEBUG 0 +#include + + +#define EPD_TIMING_ED068OG1_NUMCE3 1 +#define EPD_TIMING_ED068TG1 1 + + + +extern int gSleep_Mode_Suspend; + + +volatile unsigned gMX6SL_NTX_ACIN_PG = IMX_GPIO_NR(4, 20); /* FEC_MDIO */ +volatile unsigned gMX6SL_NTX_CHG = IMX_GPIO_NR(4, 21); /* FEC_TX_CLK */ +volatile unsigned gMX6SL_MSP_INT = IMX_GPIO_NR(4, 19); /* FEC_RX_ER */ +volatile unsigned gMX6SL_PWR_SW = IMX_GPIO_NR(4, 25); /* FEC_CRS_DV */ +volatile unsigned gMX6SL_IR_TOUCH_INT = IMX_GPIO_NR(4, 24); /* FEC_TXD0 */ +volatile unsigned gMX6SL_IR_TOUCH_RST = IMX_GPIO_NR(4, 17); /* FEC_RXD0 */ +volatile unsigned gMX6SL_HALL_EN = IMX_GPIO_NR(4, 23); /* FEC_MDC */ +volatile unsigned gMX6SL_ON_LED = IMX_GPIO_NR(4, 22); /* FEC_TX_EN */ +volatile unsigned gMX6SL_CHG_LED = IMX_GPIO_NR(4, 16); /* FEC_TXD1 */ +volatile unsigned gMX6SL_ACT_LED = IMX_GPIO_NR(4, 26); /* FEC_REF_CLK */ +volatile unsigned gMX6SL_WIFI_3V3 = IMX_GPIO_NR(5, 0); /* SD2_DAT7 */ +volatile unsigned gMX6SL_WIFI_RST = IMX_GPIO_NR(4, 27); /* SD2_RST */ +volatile unsigned gMX6SL_WIFI_INT = IMX_GPIO_NR(4, 29); /* SD2_DAT6 */ +volatile unsigned gMX6SL_HOME_LED = IMX_GPIO_NR(5, 10); /* SD2_DAT6 */ + +volatile int giISD_3V3_ON_Ctrl = -1; + +static int spdc_sel; +static int max17135_regulator_init(struct max17135 *max17135); + +extern char *gp_reg_id; +extern char *soc_reg_id; +extern char *pu_reg_id; +extern int __init mx6sl_ntx_init_pfuze100(u32 int_gpio); +extern void tle4913_init(void); + +static int csi_enabled; + +#define _MYINIT_DATA +#define _MYINIT_TEXT +volatile static unsigned char _MYINIT_DATA *gpbHWCFG_paddr; +//volatile unsigned char *gpbHWCFG_vaddr; +volatile unsigned long _MYINIT_DATA gdwHWCFG_size; +volatile int _MYINIT_DATA giBootPort; + +volatile NTX_HWCONFIG *gptHWCFG; + +static void * _MemoryRequest(void *addr, u32 len, const char * name) +{ + void * mem = NULL; + do { + printk(KERN_DEBUG "***%s:%d: request memory region! addr=%p, len=%hd***\n", + __FUNCTION__, __LINE__, addr, len); + if (!request_mem_region((u32)addr, len, name)) { + printk(KERN_CRIT "%s(): request memory region failed! addr=%p, len %hd\n",__FUNCTION__, addr, len); + break; + } + mem = (void *) ioremap_nocache((u32)addr, len); + if (!mem) { + printk(KERN_CRIT "***%s:%d: could not ioremap %s***\n", __FUNCTION__, __LINE__, name); + release_mem_region((u32)addr, len); + break; + } + } while (0); + return mem; +} + +int gIsCustomerUi; +static int _MYINIT_TEXT hwcfg_p_setup(char *str) +{ + gpbHWCFG_paddr = (unsigned char *)simple_strtoul(str,NULL,0); + if(NULL==gptHWCFG) { + gptHWCFG = (NTX_HWCONFIG *)_MemoryRequest((void *)gpbHWCFG_paddr, gdwHWCFG_size, "hwcfg_p"); + if(!gptHWCFG) { + return 0; + } + } + printk("%s() hwcfg_p=%p,vaddr=%p,size=%d,pcb=0x%x\n",__FUNCTION__, + gpbHWCFG_paddr,gptHWCFG,(int)gdwHWCFG_size,gptHWCFG->m_val.bPCB); + gIsCustomerUi = (int)gptHWCFG->m_val.bUIStyle; + + return 1; +} + +static int _MYINIT_TEXT hwcfg_size_setup(char *str) +{ + gdwHWCFG_size = (unsigned long)simple_strtoul(str,NULL,0); + printk("%s() hwcfg_szie=%d\n",__FUNCTION__,(int)gdwHWCFG_size); + return 1; +} + +static int _MYINIT_TEXT boot_port_setup(char *str) +{ + giBootPort = (int)simple_strtoul(str,NULL,0); + printk("%s() boot_port=%d\n",__FUNCTION__,giBootPort); + return 1; +} + +static void _parse_cmdline(void) +{ + static int iParseCnt = 0; + char *pcPatternStart,*pcPatternVal,*pcPatternValEnd,cTempStore; + unsigned long ulPatternLen; + + char *szParsePatternA[]={"hwcfg_sz=","hwcfg_p=","boot_port="}; + int ((*pfnDispatchA[])(char *str))={hwcfg_size_setup,hwcfg_p_setup,boot_port_setup }; + + int i; + char *pszCmdLineBuf; + + + if(iParseCnt++>0) { + printk("%s : cmdline parse already done .\n",__FUNCTION__); + return ; + } + //printk("%s():cmdline(%d)=%s\n",__FUNCTION__,strlen(saved_command_line),saved_command_line); + + pszCmdLineBuf = kmalloc(strlen(saved_command_line)+1,GFP_KERNEL); + //ASSERT(pszCmdLineBuf); + strcpy(pszCmdLineBuf,saved_command_line); + printk("%s():cp cmdline=%s\n",__FUNCTION__,pszCmdLineBuf); + + for(i=0;im_val.bTouchCtrl = 8; + } +} + + + +/* uart2 pins */ +#if 0 // gallen disabled . +static iomux_v3_cfg_t mx6sl_uart2_pads[] = { + MX6SL_PAD_SD2_DAT5__UART2_TXD, + MX6SL_PAD_SD2_DAT4__UART2_RXD, + MX6SL_PAD_SD2_DAT6__UART2_RTS, + MX6SL_PAD_SD2_DAT7__UART2_CTS, +}; +#endif + +enum sd_pad_mode { + SD_PAD_MODE_LOW_SPEED, + SD_PAD_MODE_MED_SPEED, + SD_PAD_MODE_HIGH_SPEED, +}; + +static int plt_sd_pad_change(unsigned int index, int clock) +{ + /* LOW speed is the default state of SD pads */ + static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED; + + iomux_v3_cfg_t *sd_pads_200mhz = NULL; + iomux_v3_cfg_t *sd_pads_100mhz = NULL; + iomux_v3_cfg_t *sd_pads_50mhz = NULL; + + u32 sd_pads_200mhz_cnt; + u32 sd_pads_100mhz_cnt; + u32 sd_pads_50mhz_cnt; + + switch (index) { + case 0: + sd_pads_200mhz = mx6sl_sd1_200mhz; + sd_pads_100mhz = mx6sl_sd1_100mhz; + sd_pads_50mhz = mx6sl_sd1_50mhz; + + sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd1_200mhz); + sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd1_100mhz); + sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd1_50mhz); + break; + case 1: + sd_pads_200mhz = mx6sl_sd2_200mhz; + sd_pads_100mhz = mx6sl_sd2_100mhz; + sd_pads_50mhz = mx6sl_sd2_50mhz; + + sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd2_200mhz); + sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd2_100mhz); + sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd2_50mhz); + break; + case 2: + sd_pads_200mhz = mx6sl_sd3_200mhz; + sd_pads_100mhz = mx6sl_sd3_100mhz; + sd_pads_50mhz = mx6sl_sd3_50mhz; + + sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd3_200mhz); + sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd3_100mhz); + sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd3_50mhz); + break; + case 3: + sd_pads_200mhz = mx6sl_brd_ntx_sd4_pads; + sd_pads_100mhz = mx6sl_brd_ntx_sd4_pads; + sd_pads_50mhz = mx6sl_brd_ntx_sd4_pads; + + sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_brd_ntx_sd4_pads); + sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_brd_ntx_sd4_pads); + sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_brd_ntx_sd4_pads); + break; + + default: + printk(KERN_ERR "no such SD host controller index %d\n", index); + return -EINVAL; + } + + if (clock > 100000000) { + if (pad_mode == SD_PAD_MODE_HIGH_SPEED) + return 0; + BUG_ON(!sd_pads_200mhz); + pad_mode = SD_PAD_MODE_HIGH_SPEED; + return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz, + sd_pads_200mhz_cnt); + } else if (clock > 52000000) { + if (pad_mode == SD_PAD_MODE_MED_SPEED) + return 0; + BUG_ON(!sd_pads_100mhz); + pad_mode = SD_PAD_MODE_MED_SPEED; + return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz, + sd_pads_100mhz_cnt); + } else { + if (pad_mode == SD_PAD_MODE_LOW_SPEED) + return 0; + BUG_ON(!sd_pads_50mhz); + pad_mode = SD_PAD_MODE_LOW_SPEED; + return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz, + sd_pads_50mhz_cnt); + } +} + + +static const struct esdhc_platform_data mx6_ntx_isd_data __initconst = { + .always_present = 1, + .delay_line = 0, + .platform_pad_change = plt_sd_pad_change, + .cd_type = ESDHC_CD_PERMANENT, +}; +static const struct esdhc_platform_data mx6_ntx_isd8bits_data __initconst = { + .always_present = 1, + .delay_line = 0, + .support_8bit = 1, + .platform_pad_change = plt_sd_pad_change, + .cd_type = ESDHC_CD_PERMANENT, +}; + +static const struct esdhc_platform_data mx6_ntx_sd_wifi_data __initconst = { + .cd_gpio = MX6SL_WIFI_3V3, + .wp_gpio = -1, + .keep_power_at_suspend = 1, + .delay_line = 0, +// .platform_pad_change = plt_sd_pad_change, + .cd_type = ESDHC_CD_WIFI_PWR, +}; + +static const struct esdhc_platform_data mx6_ntx_q22_sd_wifi_data __initconst = { + .cd_gpio = IMX_GPIO_NR(4, 29), + .wp_gpio = -1, + .keep_power_at_suspend = 1, + .delay_line = 0, +// .platform_pad_change = plt_sd_pad_change, + .cd_type = ESDHC_CD_WIFI_PWR, +}; + +static const struct esdhc_platform_data mx6_ntx_esd_data __initconst = { + .cd_gpio = MX6SL_EXT_SD_CD, + .wp_gpio = -1, + .keep_power_at_suspend = 1, + .delay_line = 0, + .platform_pad_change = plt_sd_pad_change, + .cd_type = ESDHC_CD_GPIO, +}; +static const struct esdhc_platform_data mx6_ntx_esd_nocd_data __initconst = { + .always_present = 1, + .cd_gpio = 0, + .wp_gpio = -1, + .keep_power_at_suspend = 1, + .delay_line = 0, + .platform_pad_change = 0, + .cd_type = ESDHC_CD_PERMANENT, +}; + +#define mV_to_uV(mV) (mV * 1000) +#define uV_to_mV(uV) (uV / 1000) +#define V_to_uV(V) (mV_to_uV(V * 1000)) +#define uV_to_V(uV) (uV_to_mV(uV) / 1000) + +#if 0 +static struct regulator_consumer_supply ntx_vmmc_consumers[] = { + REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"), + REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"), + REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"), + REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"), +}; + +static struct regulator_init_data ntx_vmmc_init = { + .num_consumer_supplies = ARRAY_SIZE(ntx_vmmc_consumers), + .consumer_supplies = ntx_vmmc_consumers, +}; + +static struct fixed_voltage_config ntx_vmmc_reg_config = { + .supply_name = "vmmc", + .microvolts = 3300000, + .gpio = -1, + .init_data = &ntx_vmmc_init, +}; + +static struct platform_device ntx_vmmc_reg_devices = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &ntx_vmmc_reg_config, + }, +}; +#endif + +static struct regulator_consumer_supply display_consumers[] = { + { + /* MAX17135 */ + .supply = "DISPLAY", + }, +}; + +static struct regulator_consumer_supply vcom_consumers[] = { + { + /* MAX17135 */ + .supply = "VCOM", + }, +}; + +static struct regulator_consumer_supply v3p3_consumers[] = { + { + /* MAX17135 */ + .supply = "V3P3", + }, +}; + +static struct regulator_init_data max17135_init_data[] = { +#if 0 + { + .constraints = { + .name = "DISPLAY", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(display_consumers), + .consumer_supplies = display_consumers, + }, { + .constraints = { + .name = "GVDD", + .min_uV = V_to_uV(20), + .max_uV = V_to_uV(20), + }, + }, { + .constraints = { + .name = "GVEE", + .min_uV = V_to_uV(-22), + .max_uV = V_to_uV(-22), + }, + }, { + .constraints = { + .name = "HVINN", + .min_uV = V_to_uV(-22), + .max_uV = V_to_uV(-22), + }, + }, { + .constraints = { + .name = "HVINP", + .min_uV = V_to_uV(20), + .max_uV = V_to_uV(20), + }, + }, { + .constraints = { + .name = "VCOM", + .min_uV = mV_to_uV(-4325), + .max_uV = mV_to_uV(-500), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(vcom_consumers), + .consumer_supplies = vcom_consumers, + }, { + .constraints = { + .name = "VNEG", + .min_uV = V_to_uV(-15), + .max_uV = V_to_uV(-15), + }, + }, { + .constraints = { + .name = "VPOS", + .min_uV = V_to_uV(15), + .max_uV = V_to_uV(15), + }, + }, { + .constraints = { + .name = "V3P3", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers), + .consumer_supplies = v3p3_consumers, + }, +#endif +}; + +static const struct anatop_thermal_platform_data + mx6sl_anatop_thermal_data __initconst = { + .name = "anatop_thermal", + }; + +static struct platform_device max17135_sensor_device = { + .name = "max17135_sensor", + .id = 0, +}; + +static struct max17135_platform_data max17135_pdata __initdata = { + .vneg_pwrup = 1, + .gvee_pwrup = 1, + .vpos_pwrup = 2, + .gvdd_pwrup = 1, + .gvdd_pwrdn = 1, + .vpos_pwrdn = 2, + .gvee_pwrdn = 1, + .vneg_pwrdn = 1, + .gpio_pmic_pwrgood = MX6SL_BRD_EPDC_PWRSTAT, + .gpio_pmic_vcom_ctrl = MX6SL_BRD_EPDC_VCOM, + .gpio_pmic_wakeup = MX6SL_BRD_EPDC_PMIC_WAKE, + .gpio_pmic_v3p3 = MX6SL_BRD_EPDC_PWRCTRL0, + .gpio_pmic_intr = MX6SL_BRD_EPDC_PMIC_INT, + .regulator_init = max17135_init_data, + .init = max17135_regulator_init, +}; + +static int __init max17135_regulator_init(struct max17135 *max17135) +{ +#if 0 + struct max17135_platform_data *pdata = &max17135_pdata; + int i, ret; + + max17135->gvee_pwrup = pdata->gvee_pwrup; + max17135->vneg_pwrup = pdata->vneg_pwrup; + max17135->vpos_pwrup = pdata->vpos_pwrup; + max17135->gvdd_pwrup = pdata->gvdd_pwrup; + max17135->gvdd_pwrdn = pdata->gvdd_pwrdn; + max17135->vpos_pwrdn = pdata->vpos_pwrdn; + max17135->vneg_pwrdn = pdata->vneg_pwrdn; + max17135->gvee_pwrdn = pdata->gvee_pwrdn; + + max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup + + pdata->gvdd_pwrup + pdata->gvee_pwrup; + + max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood; + max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl; + max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup; + max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3; + max17135->gpio_pmic_intr = pdata->gpio_pmic_intr; + + gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake"); + gpio_direction_output(max17135->gpio_pmic_wakeup, 0); + + gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom"); + gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0); + + gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3"); + gpio_direction_output(max17135->gpio_pmic_v3p3, 0); + + gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int"); + gpio_direction_input(max17135->gpio_pmic_intr); + + gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat"); + gpio_direction_input(max17135->gpio_pmic_pwrgood); + + max17135->vcom_setup = false; + max17135->init_done = false; + + for (i = 0; i < MAX17135_NUM_REGULATORS; i++) { + ret = max17135_register_regulator(max17135, i, + &pdata->regulator_init[i]); + if (ret != 0) { + printk(KERN_ERR"max17135 regulator init failed: %d\n", + ret); + return ret; + } + } + + /* + * TODO: We cannot enable full constraints for now, since + * it results in the PFUZE regulators being disabled + * at the end of boot, which disables critical regulators. + */ + /*regulator_has_full_constraints();*/ +#endif + return 0; +} + +static int mx6_ntx_spi_cs[] = { + MX6_BRD_ECSPI1_CS0, +}; + +static const struct spi_imx_master mx6_ntx_spi_data __initconst = { + .chipselect = mx6_ntx_spi_cs, + .num_chipselect = ARRAY_SIZE(mx6_ntx_spi_cs), +}; + +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition m25p32_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 0x00100000, + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct flash_platform_data m25p32_spi_flash_data = { + .name = "m25p32", + .parts = m25p32_partitions, + .nr_parts = ARRAY_SIZE(m25p32_partitions), + .type = "m25p32", +}; + +static struct spi_board_info m25p32_spi0_board_info[] __initdata = { + { + /* The modalias must be the same as spi device driver name */ + .modalias = "m25p80", + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + .platform_data = &m25p32_spi_flash_data, + }, +}; +#endif + +static void spi_device_init(void) +{ +#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) + spi_register_board_info(m25p32_spi0_board_info, + ARRAY_SIZE(m25p32_spi0_board_info)); +#endif +} + +static struct imx_ssi_platform_data mx6_sabresd_ssi_pdata = { + .flags = IMX_SSI_DMA | IMX_SSI_SYN, +}; + +#if 0 +static struct mxc_audio_platform_data wm8962_data; + +static struct platform_device mx6_sabresd_audio_wm8962_device = { + .name = "imx-wm8962", +}; + +static struct wm8962_pdata wm8962_config_data = { + +}; + +static int wm8962_clk_enable(int enable) +{ + if (enable) + clk_enable(ntx_extern_audio_root); + else + clk_disable(ntx_extern_audio_root); + + return 0; +} + +static int mxc_wm8962_init(void) +{ + struct clk *pll4; + int rate; + + ntx_extern_audio_root = clk_get(NULL, "extern_audio_clk"); + if (IS_ERR(ntx_extern_audio_root)) { + pr_err("can't get ntx_extern_audio_root clock.\n"); + return PTR_ERR(ntx_extern_audio_root); + } + + pll4 = clk_get(NULL, "pll4"); + if (IS_ERR(pll4)) { + pr_err("can't get pll4 clock.\n"); + return PTR_ERR(pll4); + } + + clk_set_parent(ntx_extern_audio_root, pll4); + + rate = clk_round_rate(ntx_extern_audio_root, 26000000); + clk_set_rate(ntx_extern_audio_root, rate); + + wm8962_data.sysclk = rate; + /* set AUDMUX pads to 1.8v */ + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_MCLK, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_RXD, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXC, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXD, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); + mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXFS, + PAD_CTL_LVE, PAD_CTL_LVE_MASK); + + return 0; +} + +static struct mxc_audio_platform_data wm8962_data = { + .ssi_num = 1, + .src_port = 2, + .ext_port = 3, + .hp_gpio = MX6_BRD_HEADPHONE_DET, + .hp_active_low = 1, + .mic_gpio = -1, + .mic_active_low = 1, + .init = mxc_wm8962_init, + .clock_enable = wm8962_clk_enable, +}; + +static struct regulator_consumer_supply sabresd_vwm8962_consumers[] = { + REGULATOR_SUPPLY("SPKVDD1", "1-001a"), + REGULATOR_SUPPLY("SPKVDD2", "1-001a"), +}; + +static struct regulator_init_data sabresd_vwm8962_init = { + .constraints = { + .name = "SPKVDD", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(sabresd_vwm8962_consumers), + .consumer_supplies = sabresd_vwm8962_consumers, +}; + +static struct fixed_voltage_config sabresd_vwm8962_reg_config = { + .supply_name = "SPKVDD", + .microvolts = 4325000, + .gpio = -1, + .enabled_at_boot = 1, + .init_data = &sabresd_vwm8962_init, +}; + +static struct platform_device sabresd_vwm8962_reg_devices = { + .name = "reg-fixed-voltage", + .id = 4, + .dev = { + .platform_data = &sabresd_vwm8962_reg_config, + }, +}; + +static int __init imx6q_init_audio(void) +{ + platform_device_register(&sabresd_vwm8962_reg_devices); + mxc_register_device(&mx6_sabresd_audio_wm8962_device, + &wm8962_data); + imx6q_add_imx_ssi(1, &mx6_sabresd_ssi_pdata); + + return 0; +} + +static int spdif_clk_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long rate_actual; + rate_actual = clk_round_rate(clk, rate); + clk_set_rate(clk, rate_actual); + return 0; +} + +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 1, + .spdif_rx = 0, + .spdif_clk_44100 = 1, + .spdif_clk_48000 = -1, + .spdif_div_44100 = 23, + .spdif_clk_set_rate = spdif_clk_set_rate, + .spdif_clk = NULL, +}; +#endif + + +enum DISPLAY_PANEL_MODE { + PANEL_MODE_LCD, + PANEL_MODE_HDMI, + PANEL_MODE_EINK, +}; + +static int display_panel_mode = PANEL_MODE_EINK; + +#if 0 +static iomux_v3_cfg_t mx6sl_sii902x_hdmi_pads_enabled[] = { + MX6SL_PAD_LCD_RESET__GPIO_2_19, + MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10, +}; + +static int sii902x_get_pins(void) +{ + /* Sii902x HDMI controller */ + mxc_iomux_v3_setup_multiple_pads(mx6sl_sii902x_hdmi_pads_enabled, \ + ARRAY_SIZE(mx6sl_sii902x_hdmi_pads_enabled)); + + /* Reset Pin */ + gpio_request(MX6_BRD_LCD_RESET, "disp0-reset"); + gpio_direction_output(MX6_BRD_LCD_RESET, 1); + + /* Interrupter pin GPIO */ + gpio_request(MX6SL_BRD_EPDC_PWRCTRL3, "disp0-detect"); + gpio_direction_input(MX6SL_BRD_EPDC_PWRCTRL3); + return 1; +} + +static void sii902x_put_pins(void) +{ + gpio_free(MX6_BRD_LCD_RESET); + gpio_free(MX6SL_BRD_EPDC_PWRCTRL3); +} + +static void sii902x_hdmi_reset(void) +{ + gpio_set_value(MX6_BRD_LCD_RESET, 0); + msleep(10); + gpio_set_value(MX6_BRD_LCD_RESET, 1); + msleep(10); +} + +static struct fsl_mxc_lcd_platform_data sii902x_hdmi_data = { + .ipu_id = 0, + .disp_id = 0, + .reset = sii902x_hdmi_reset, + .get_pins = sii902x_get_pins, + .put_pins = sii902x_put_pins, +}; + +static void mx6sl_csi_io_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_csi_enable_pads, \ + ARRAY_SIZE(mx6sl_brd_csi_enable_pads)); + + /* Camera reset */ + gpio_request(MX6SL_BRD_CSI_RST, "cam-reset"); + gpio_direction_output(MX6SL_BRD_CSI_RST, 1); + + /* Camera power down */ + gpio_request(MX6SL_BRD_CSI_PWDN, "cam-pwdn"); + gpio_direction_output(MX6SL_BRD_CSI_PWDN, 1); + msleep(5); + gpio_set_value(MX6SL_BRD_CSI_PWDN, 0); + msleep(5); + gpio_set_value(MX6SL_BRD_CSI_RST, 0); + msleep(1); + gpio_set_value(MX6SL_BRD_CSI_RST, 1); + msleep(5); + gpio_set_value(MX6SL_BRD_CSI_PWDN, 1); +} + +static void mx6sl_csi_cam_powerdown(int powerdown) +{ + if (powerdown) + gpio_set_value(MX6SL_BRD_CSI_PWDN, 1); + else + gpio_set_value(MX6SL_BRD_CSI_PWDN, 0); + + msleep(2); +} + +static struct fsl_mxc_camera_platform_data camera_data = { + .mclk = 24000000, + .io_init = mx6sl_csi_io_init, + .pwdn = mx6sl_csi_cam_powerdown, + .core_regulator = "VGEN2_1V5", + .analog_regulator = "VGEN6_2V8", +}; +#endif + +static struct imxi2c_platform_data mx6_ntx_i2c0_data = { + .bitrate = 100000, +}; + +static struct imxi2c_platform_data mx6_ntx_i2c1_data = { + .bitrate = 100000, +}; + +static struct imxi2c_platform_data mx6_ntx_i2c2_data = { + .bitrate = 100000, +}; + +static struct i2c_board_info i2c_zforce_ir_touch_binfo = { + .type = "zforce-ir-touch", + .addr = 0x50, + //.platform_data = MX6SL_IR_TOUCH_INT, + //.irq = gpio_to_irq(MX6SL_IR_TOUCH_INT), +}; + +static struct i2c_board_info i2c_elan_touch_binfo = { + .type = "elan-touch", + .addr = 0x15, +}; + +int ricoh619_init_port(int irq_num) +{ + printk("[%s-%d] ...\n",__func__,__LINE__); + return 0; +} + +static struct ricoh619_rtc_platform_data ricoh_rtc_data = { + .time = { + .tm_year = 1970, + .tm_mon = 0, + .tm_mday = 1, + .tm_hour = 0, + .tm_min = 0, + .tm_sec = 0, + }, +}; + +static struct ricoh619_battery_platform_data ricoh_battery_data = { +// .irq = RICOH619_IRQ_BASE, + .alarm_vol_mv = 3400, + // .adc_channel = RICOH619_ADC_CHANNEL_VBAT, + .multiple = 100, //100% + .monitor_time = 60, + /* some parameter is depend of battery type */ + .type[0] = { + .ch_vfchg = 0xFF, /* VFCHG = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */ + .ch_vrchg = 0xFF, /* VRCHG = 0 - 4 (3.85v, 3.90v, 3.95v, 4.00v, 4.10v) */ + .ch_vbatovset = 0xFF, /* VBATOVSET = 0 or 1 (0 : 4.38v(up)/3.95v(down) 1: 4.53v(up)/4.10v(down)) */ + .ch_ichg = 0xFF, /* ICHG = 0 - 0x1D (100mA - 3000mA) */ + .ch_ilim_adp = 0xFF, /* ILIM_ADP = 0 - 0x1D (100mA - 3000mA) */ + .ch_ilim_usb = 0xFF, /* ILIM_USB = 0 - 0x1D (100mA - 3000mA) */ + .ch_icchg = 0, /* ICCHG = 0 - 3 (50mA 100mA 150mA 200mA) */ + .fg_target_vsys = 0, /* This value is the target one to DSOC=0% */ + .fg_target_ibat = 0, /* This value is the target one to DSOC=0% */ + .fg_poff_vbat = 3520, /* setting value of 0 per Vbat */ + .jt_en = 0, /* JEITA Enable = 0 or 1 (1:enable, 0:disable) */ + .jt_hw_sw = 1, /* JEITA HW or SW = 0 or 1 (1:HardWare, 0:SoftWare) */ + .jt_temp_h = 50, /* degree C */ + .jt_temp_l = 12, /* degree C */ + .jt_vfchg_h = 0x03, /* VFCHG High = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */ + .jt_vfchg_l = 0, /* VFCHG High = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */ + .jt_ichg_h = 0x0D, /* VFCHG Low = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */ + .jt_ichg_l = 0x09, /* ICHG Low = 0 - 0x1D (100mA - 3000mA) */ + }, + /* + .type[1] = { + .ch_vfchg = 0x0, + .ch_vrchg = 0x0, + .ch_vbatovset = 0x0, + .ch_ichg = 0x0, + .ch_ilim_adp = 0x0, + .ch_ilim_usb = 0x0, + .ch_icchg = 0x00, + .fg_target_vsys = 3300,//3000, + .fg_target_ibat = 1000,//1000, + .jt_en = 0, + .jt_hw_sw = 1, + .jt_temp_h = 40, + .jt_temp_l = 10, + .jt_vfchg_h = 0x0, + .jt_vfchg_l = 0, + .jt_ichg_h = 0x01, + .jt_ichg_l = 0x01, + }, + */ + +/* JEITA Parameter +* +* VCHG +* | +* jt_vfchg_h~+~~~~~~~~~~~~~~~~~~~+ +* | | +* jt_vfchg_l-| - - - - - - - - - +~~~~~~~~~~+ +* | Charge area + | +* -------0--+-------------------+----------+--- Temp +* ! + +* ICHG +* | + +* jt_ichg_h-+ - -+~~~~~~~~~~~~~~+~~~~~~~~~~+ +* + | + | +* jt_ichg_l-+~~~~+ Charge area | +* | + + | +* 0--+----+--------------+----------+--- Temp +* 0 jt_temp_l jt_temp_h 55 +*/ +}; + +#define RICOH_REG(_id, _name, _sname) \ +{ \ + .id = RICOH619_ID_##_id, \ + .name = "ricoh61x-regulator", \ + .platform_data = &pdata_##_name##_##_sname, \ +} + +static struct regulator_consumer_supply ricoh619_dc1_supply_0[] = { + REGULATOR_SUPPLY("vdd_core2_1v3_soc", NULL), +}; +static struct regulator_consumer_supply ricoh619_dc2_supply_0[] = { + REGULATOR_SUPPLY("vdd_core1_3v3", NULL), +}; +static struct regulator_consumer_supply ricoh619_dc3_supply_0[] = { + REGULATOR_SUPPLY("vdd_core2_1v3_arm", NULL), +}; +static struct regulator_consumer_supply ricoh619_dc4_supply_0[] = { + REGULATOR_SUPPLY("vdd_core4_1v2", NULL), +}; +static struct regulator_consumer_supply ricoh619_dc5_supply_0[] = { + REGULATOR_SUPPLY("vdd_core4_1v8", NULL), +}; +static struct regulator_consumer_supply ricoh619_ldo1_supply_0[] = { + REGULATOR_SUPPLY("vdd_ir_3v3", NULL), +}; +static struct regulator_consumer_supply ricoh619_ldo2_supply_0[] = { +}; +static struct regulator_consumer_supply ricoh619_ldo3_supply_0[] = { + REGULATOR_SUPPLY("vdd_core5_1v2", NULL), +}; +static struct regulator_consumer_supply ricoh619_ldo4_supply_0[] = { +}; +static struct regulator_consumer_supply ricoh619_ldo5_supply_0[] = { + REGULATOR_SUPPLY("vdd_spd_3v3", NULL), +// REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"), +}; +static struct regulator_consumer_supply ricoh619_ldo6_supply_0[] = { + REGULATOR_SUPPLY("vdd_ddr_0v6", NULL), +}; +static struct regulator_consumer_supply ricoh619_ldo7_supply_0[] = { + REGULATOR_SUPPLY("vdd_pwm", "0-0007"), + REGULATOR_SUPPLY("vdd_fl_0_pwm", "0-0043"), + REGULATOR_SUPPLY("vdd_fl_pwm", "2-0043"), +}; +static struct regulator_consumer_supply ricoh619_ldo8_supply_0[] = { + REGULATOR_SUPPLY("ldo_1v8", NULL), +}; +static struct regulator_consumer_supply ricoh619_ldo9_supply_0[] = { +}; +static struct regulator_consumer_supply ricoh619_ldo10_supply_0[] = { +}; +static struct regulator_consumer_supply ricoh619_ldortc1_supply_0[] = { + REGULATOR_SUPPLY("vdd_rtc_3v3", NULL), +}; +static struct regulator_consumer_supply ricoh619_ldortc2_supply_0[] = { +}; + +#define RICOH_PDATA_INIT(_name, _sname, _minmv, _maxmv, _supply_reg, _always_on, \ + _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply, _flags, \ + _ext_contol, _sleep_mV) \ + static struct ricoh619_regulator_platform_data pdata_##_name##_##_sname = \ + { \ + .regulator = { \ + .constraints = { \ + .min_uV = (_minmv)*1000, \ + .max_uV = (_maxmv)*1000, \ + .valid_modes_mask = (REGULATOR_MODE_NORMAL | \ + REGULATOR_MODE_STANDBY), \ + .valid_ops_mask = (REGULATOR_CHANGE_MODE | \ + REGULATOR_CHANGE_STATUS | \ + REGULATOR_CHANGE_VOLTAGE), \ + .always_on = _always_on, \ + .boot_on = _boot_on, \ + .apply_uV = _apply_uv, \ + }, \ + .num_consumer_supplies = \ + ARRAY_SIZE(ricoh619_##_name##_supply_##_sname), \ + .consumer_supplies = ricoh619_##_name##_supply_##_sname, \ + .supply_regulator = _supply_reg, \ + }, \ + .init_uV = _init_uV * 1000, \ + .init_enable = _init_enable, \ + .init_apply = _init_apply, \ + .sleep_uV = (_sleep_mV)*1000, \ + .flags = _flags, \ + .ext_pwr_req = _ext_contol, \ + } + +RICOH_PDATA_INIT(dc1, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 950); // Core2_1V3 +RICOH_PDATA_INIT(dc2, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core3_3V3 +RICOH_PDATA_INIT(dc3, 0, 950, 1425, 0, 1, 1, 0, 1425, 1, 1, 0, 0, 950); // Core2_1V3_ARM +RICOH_PDATA_INIT(dc4, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core4_1V2 +RICOH_PDATA_INIT(dc5, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core4_1V8 + +RICOH_PDATA_INIT(ldo1, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // IR_3V3 +RICOH_PDATA_INIT(ldo2, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core1_3V3* +RICOH_PDATA_INIT(ldo3, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core5_1V2 +RICOH_PDATA_INIT(ldo4, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // Reserved +RICOH_PDATA_INIT(ldo5, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // SPD_3V3 +RICOH_PDATA_INIT(ldo6, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // DDR_0V6 +RICOH_PDATA_INIT(ldo7, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // VDD_PWM +RICOH_PDATA_INIT(ldo8, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // ldo_1v8 +//RICOH_PDATA_INIT(ldo8, 0, 3300, 3300, 0, 1, 1, 0, 3300, 1, 1, 0, 0, 3300); // ldo_1v8 output 3V3 +RICOH_PDATA_INIT(ldo9, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // Reserved +RICOH_PDATA_INIT(ldo10, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // Reserved +RICOH_PDATA_INIT(ldortc1, 0,0, 0, 0, 1, 1, 0, -1, 1, 1, -1, -1, -1); +RICOH_PDATA_INIT(ldortc2, 0,0, 0, 0, 0, 0, 0, -1, 0, 1, -1, -1, -1); + +#define RICOH619_DEV_REG \ + RICOH_REG(DC1, dc1, 0), \ + RICOH_REG(DC2, dc2, 0), \ + RICOH_REG(DC3, dc3, 0), \ + RICOH_REG(DC4, dc4, 0), \ + RICOH_REG(DC5, dc5, 0), \ + RICOH_REG(LDO1, ldo1, 0), \ + RICOH_REG(LDO2, ldo2, 0), \ + RICOH_REG(LDO3, ldo3, 0), \ + RICOH_REG(LDO4, ldo4, 0), \ + RICOH_REG(LDO5, ldo5, 0), \ + RICOH_REG(LDO6, ldo6, 0), \ + RICOH_REG(LDO7, ldo7, 0), \ + RICOH_REG(LDO8, ldo8, 0), \ + RICOH_REG(LDO9, ldo9, 0), \ + RICOH_REG(LDO10, ldo10, 0), \ + RICOH_REG(LDORTC1, ldortc1, 0), \ + RICOH_REG(LDORTC2, ldortc2, 0) + +struct ricoh619_subdev_info ricoh619_sub_data[] = { + RICOH619_DEV_REG, + { + .name = "ricoh619-battery", + .id = -1, + .platform_data = &ricoh_battery_data, + }, + { + .name = "rtc_ricoh619", + .id = 0, + .platform_data = &ricoh_rtc_data, + }, +}; + + +#define RICOH_GPIO_INIT(_init_apply, _output_mode, _output_val, _led_mode, _led_func) \ + { \ + .output_mode_en = _output_mode, \ + .output_val = _output_val, \ + .init_apply = _init_apply, \ + .led_mode = _led_mode, \ + .led_func = _led_func, \ + } +struct ricoh619_gpio_init_data ricoh_gpio_data[] = { + RICOH_GPIO_INIT(false, false, 0, 0, 0), + RICOH_GPIO_INIT(false, false, 0, 0, 0), + RICOH_GPIO_INIT(false, false, 0, 0, 0), + RICOH_GPIO_INIT(false, false, 0, 0, 0), +}; + +static struct ricoh619_platform_data ntx_ricoh_data = { + .num_subdevs = ARRAY_SIZE(ricoh619_sub_data), + .subdevs = ricoh619_sub_data, + .gpio_base = 7*32, + .gpio_init_data = ricoh_gpio_data, + .num_gpioinit_data = ARRAY_SIZE(ricoh_gpio_data), + .enable_shutdown_pin = true, +}; + +static struct i2c_board_info i2c_sysmp_ricoh619_binfo = { + .type = "ricoh619", + .addr = 0x32, + .platform_data = &ntx_ricoh_data, +}; + +static struct i2c_board_info i2c_sysmp_msp430_binfo = { + .type = "msp430", + .addr = 0x43, + //.irq = gpio_to_irq(MX6SL_MSP_INT), +}; + +static struct i2c_board_info i2c_ht68f20_binfo = { + .type = "ht68f20", + .addr = 0x07, +}; + +static struct i2c_board_info i2c_kl25_binfo = { + .type = "kl25", + .addr = 0x5A, + .irq = gpio_to_irq(MX6SL_KL25_INT2), +}; + +static struct i2c_board_info i2c_mma8652_binfo = { + .type = "mma8652", + .addr = 0x1D, + .irq = gpio_to_irq(MX6SL_KL25_INT2), +}; + +static struct i2c_board_info i2c_wacom_binfo = { + .type = "wacom_i2c", + .addr = 0x09, + .irq = gpio_to_irq(MX6SL_WACOM_INT), +}; + +static struct i2c_board_info __initdata i2c_waltop_binfo = { + .type = "waltop_i2c", + .addr = 0x37, + .platform_data = MX6SL_WALTOP_RST, + .irq = gpio_to_irq(MX6SL_WALTOP_INT), +}; +#if 0 +static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { +}; +static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { +#if 0 + { + I2C_BOARD_INFO("ov5640", 0x3c), + .platform_data = (void *)&camera_data, + }, +#endif + { + .type = "msp430", + .addr = 0x43, + .irq = gpio_to_irq(MX6SL_MSP_INT), + }, +}; +#endif + +static struct ntx_misc_platform_data ntx_misc_info; + +static struct platform_device ntx_charger = { + .name = "pmic_battery", + .id = 1, + .dev = { + .platform_data = &ntx_misc_info, + } +}; + +static struct platform_device ntx_light_ldm = { + .name = "pmic_light", + .id = 1, +}; + +static struct mxc_dvfs_platform_data mx6sl_ntx_dvfscore_data = { +#ifdef CONFIG_MX6_INTER_LDO_BYPASS + .reg_id = "VDDCORE", + .soc_id = "VDDSOC", +#else + .reg_id = "cpu_vddgp", + .soc_id = "cpu_vddsoc", + .pu_id = "cpu_vddvpu", +#endif + .clk1_id = "cpu_clk", + .clk2_id = "gpc_dvfs_clk", + .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, + .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET, + .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET, + .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET, + .prediv_mask = 0x1F800, + .prediv_offset = 11, + .prediv_val = 3, + .div3ck_mask = 0xE0000000, + .div3ck_offset = 29, + .div3ck_val = 2, + .emac_val = 0x08, + .upthr_val = 25, + .dnthr_val = 9, + .pncthr_val = 33, + .upcnt_val = 10, + .dncnt_val = 10, + .delay_time = 80, +}; + +static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = { + .reserved_mem_size = SZ_32M, +}; + +void __init early_console_setup(unsigned long base, struct clk *clk); + +static const struct imxuart_platform_data mx6sl_ntx_uart1_data __initconst = { + .flags = IMXUART_HAVE_RTSCTS | IMXUART_SDMA, + .dma_req_rx = MX6Q_DMA_REQ_UART2_RX, + .dma_req_tx = MX6Q_DMA_REQ_UART2_TX, +}; + +static inline void mx6_ntx_init_uart(void) +{ + imx6q_add_imx_uart(0, NULL); /* DEBUG UART1 */ +} + +#if 0 +static int mx6sl_ntx_fec_phy_init(struct phy_device *phydev) +{ + int val; + + /* power on FEC phy and reset phy */ + gpio_request(MX6_BRD_FEC_PWR_EN, "fec-pwr"); + gpio_direction_output(MX6_BRD_FEC_PWR_EN, 0); + /* wait RC ms for hw reset */ + msleep(1); + gpio_direction_output(MX6_BRD_FEC_PWR_EN, 1); + + /* check phy power */ + val = phy_read(phydev, 0x0); + if (val & BMCR_PDOWN) + phy_write(phydev, 0x0, (val & ~BMCR_PDOWN)); + + return 0; +} + +static struct fec_platform_data fec_data __initdata = { + .init = mx6sl_ntx_fec_phy_init, + .phy = PHY_INTERFACE_MODE_RMII, +}; +#endif + +static int epdc_get_pins(void) +{ + int ret = 0; + + /* Claim GPIOs for EPDC pins - used during power up/down */ + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "epdc_d0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "epdc_d1"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "epdc_d2"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "epdc_d3"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "epdc_d4"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "epdc_d5"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "epdc_d6"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "epdc_d7"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_8 , "epdc_d8"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9 , "epdc_d9"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "epdc_d10"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_11, "epdc_d11"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_12, "epdc_d12"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_13, "epdc_d13"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_14, "epdc_d14"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_15, "epdc_d15"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "epdc_gdclk"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "epdc_gdsp"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "epdc_gdoe"); + ret |= gpio_request(MX6SL_BRD_EPDC_GDRL, "epdc_gdrl"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "epdc_sdclk"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDOE, "epdc_sdoe"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "epdc_sdle"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "epdc_sdshr"); + ret |= gpio_request(MX6SL_BRD_EPDC_BDR0, "epdc_bdr0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "epdc_sdce0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "epdc_sdce1"); +// ret |= gpio_request(MX6SL_BRD_EPDC_SDCE2, "epdc_sdce2"); + + return ret; +} + +static void epdc_put_pins(void) +{ + gpio_free(MX6SL_BRD_EPDC_SDDO_0); + gpio_free(MX6SL_BRD_EPDC_SDDO_1); + gpio_free(MX6SL_BRD_EPDC_SDDO_2); + gpio_free(MX6SL_BRD_EPDC_SDDO_3); + gpio_free(MX6SL_BRD_EPDC_SDDO_4); + gpio_free(MX6SL_BRD_EPDC_SDDO_5); + gpio_free(MX6SL_BRD_EPDC_SDDO_6); + gpio_free(MX6SL_BRD_EPDC_SDDO_7); + gpio_free(MX6SL_BRD_EPDC_SDDO_8); + gpio_free(MX6SL_BRD_EPDC_SDDO_9); + gpio_free(MX6SL_BRD_EPDC_SDDO_10); + gpio_free(MX6SL_BRD_EPDC_SDDO_11); + gpio_free(MX6SL_BRD_EPDC_SDDO_12); + gpio_free(MX6SL_BRD_EPDC_SDDO_13); + gpio_free(MX6SL_BRD_EPDC_SDDO_14); + gpio_free(MX6SL_BRD_EPDC_SDDO_15); + gpio_free(MX6SL_BRD_EPDC_GDCLK); + gpio_free(MX6SL_BRD_EPDC_GDSP); + gpio_free(MX6SL_BRD_EPDC_GDOE); + gpio_free(MX6SL_BRD_EPDC_GDRL); + gpio_free(MX6SL_BRD_EPDC_SDCLK); + gpio_free(MX6SL_BRD_EPDC_SDOE); + gpio_free(MX6SL_BRD_EPDC_SDLE); + gpio_free(MX6SL_BRD_EPDC_SDSHR); + gpio_free(MX6SL_BRD_EPDC_BDR0); + gpio_free(MX6SL_BRD_EPDC_SDCE0); + gpio_free(MX6SL_BRD_EPDC_SDCE1); +// gpio_free(MX6SL_BRD_EPDC_SDCE2); +} + +static void mxc_pads_lve_setup(iomux_v3_cfg_t *pad_list, unsigned count,int iIsLVE) +{ + iomux_v3_cfg_t tPadctrlOld; + iomux_v3_cfg_t tPadctrl; + iomux_v3_cfg_t *p = pad_list; + + int i; + + for(i=0;i0x%llx \n", + pad_list[i],tPadctrlOld,tPadctrl); + #endif + + mxc_iomux_v3_setup_pad(tPadctrl); + p++; + } +} + + + + + +static void epdc_enable_pins(void) +{ + /* Configure MUX settings to enable EPDC use */ + + if(NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bPCB_Flags,4)) { + // Panel is designed for low voltage . + mxc_pads_lve_setup(mx6sl_brd_epdc_enable_pads,\ + ARRAY_SIZE(mx6sl_brd_epdc_enable_pads),1); + } + else { +#if 0 + mxc_pads_lve_setup(mx6sl_brd_epdc_enable_pads,\ + ARRAY_SIZE(mx6sl_brd_epdc_enable_pads),0); +#else + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_enable_pads, \ + ARRAY_SIZE(mx6sl_brd_epdc_enable_pads)); +#endif + + } + + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7); + //if( 1==gptHWCFG->m_val.bDisplayBusWidth || + // 3==gptHWCFG->m_val.bDisplayBusWidth) + { + // 16 bits . + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_8); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_11); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_12); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_13); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_14); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_15); + } + gpio_direction_input(MX6SL_BRD_EPDC_GDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_GDSP); + gpio_direction_input(MX6SL_BRD_EPDC_GDOE); + gpio_direction_input(MX6SL_BRD_EPDC_GDRL); + gpio_direction_input(MX6SL_BRD_EPDC_SDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_SDOE); + gpio_direction_input(MX6SL_BRD_EPDC_SDLE); + gpio_direction_input(MX6SL_BRD_EPDC_SDSHR); + gpio_direction_input(MX6SL_BRD_EPDC_BDR0); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE0); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE1); +// gpio_direction_input(MX6SL_BRD_EPDC_SDCE2); +} + +static void epdc_disable_pins(void) +{ + /* Configure MUX settings for EPDC pins to + * GPIO and drive to 0. */ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_disable_pads, \ + ARRAY_SIZE(mx6sl_brd_epdc_disable_pads)); + + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0); + //if( 1==gptHWCFG->m_val.bDisplayBusWidth || + // 3==gptHWCFG->m_val.bDisplayBusWidth) + { + // 16 bits . + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_8, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_11, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_12, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_13, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_14, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_15, 0); + } + gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDRL, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDOE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0); + gpio_direction_output(MX6SL_BRD_EPDC_BDR0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0); +// gpio_direction_output(MX6SL_BRD_EPDC_SDCE2, 0); +} + +#if 1 //[ +static struct fb_videomode ed060scq_mode = { +.name = "E60SCQ", +.refresh = 85, +.xres = 800, +.yres = 600, +.pixclock = 25000000, +.left_margin = 8, +.right_margin = 60, +.upper_margin = 4, +.lower_margin = 10, +.hsync_len = 8, +.vsync_len = 4, +.sync = 0, +.vmode = FB_VMODE_NONINTERLACED, +.flag = 0, +}; + +static struct fb_videomode ed060sc8_mode = { +.name = "E60SC8", +.refresh = 85, +.xres = 800, +.yres = 600, +.pixclock = 30000000, +.left_margin = 8, +.right_margin = 164, +.upper_margin = 4, +.lower_margin = 18, +.hsync_len = 4, +.vsync_len = 1, +.sync = 0, +.vmode = FB_VMODE_NONINTERLACED, +.flag = 0, +}; + +// for ED060XC5 release by Freescale Grace 20120726 . + +static struct fb_videomode ed060xc1_mode = { +.name = "E60XC1", +.refresh = 85, +.xres = 1024, +.yres = 768, +.pixclock = 40000000, +.left_margin = 12, +.right_margin = 72, +.upper_margin = 4, +.lower_margin = 5, +.hsync_len = 8, +.vsync_len = 2, +.sync = 0, +.vmode = FB_VMODE_NONINTERLACED, +.flag = 0, +}; + +static struct fb_videomode ed060xc5_mode = { +.name = "E60XC5", +.refresh = 85, +.xres = 1024, +.yres = 758, +.pixclock = 40000000, +.left_margin = 12, +.right_margin = 76, +.upper_margin = 4, +.lower_margin = 5, +.hsync_len = 12, +.vsync_len = 2, +.sync = 0, +.vmode = FB_VMODE_NONINTERLACED, +.flag = 0, +}; + +static struct fb_videomode e60_v110_mode = { +.name = "E60_V110", +.refresh = 50, +.xres = 800, +.yres = 600, +.pixclock = 18604700, +.left_margin = 8, +.right_margin = 176, +.upper_margin = 4, +.lower_margin = 2, +.hsync_len = 4, +.vsync_len = 1, +.sync = 0, +.vmode = FB_VMODE_NONINTERLACED, +.flag = 0, +}; + +static struct fb_videomode ed050xxx_mode = { + .name="ED050XXXX", + .refresh=85, + .xres=800, + .yres=600, + .pixclock=26666667, + .left_margin=4, + .right_margin=98, + .upper_margin=4, + .lower_margin=9, + .hsync_len=8, + .vsync_len=2, + .sync=0, + .vmode=FB_VMODE_NONINTERLACED, + .flag=0, +}; + + +#ifdef EPD_TIMING_ED068TG1 //[ +static struct fb_videomode ed068tg1_mode = { +.name = "ED068TG1", +.refresh=85, +.xres=1440, +.yres=1080, +.pixclock=96000000, +.left_margin=24, +.right_margin=267, +.upper_margin=4, +.lower_margin=5, +.hsync_len=24, +.vsync_len=2, +.sync=0, +.vmode=FB_VMODE_NONINTERLACED, +.flag=0, +}; +#elif defined(EPD_TIMING_ED068OG1_NUMCE3) //][ +/* i.MX508 waveform data timing data structures for ed068og1_numce3 */ +/* Created on - Monday, October 15, 2012 10:36:24 + Warning: this pixel clock is derived from 480 MHz parent! */ + +static struct fb_videomode ed068og1_numce3_mode = { +.name="ED068OG1_NUMCE3", +.refresh=85, +.xres=1440, +.yres=1080, +.pixclock=96000000, +.left_margin=24, +.right_margin=267, +.upper_margin=4, +.lower_margin=5, +.hsync_len=24, +.vsync_len=2, +.sync=0, +.vmode=FB_VMODE_NONINTERLACED, +.flag=0, +}; +#else +static struct fb_videomode ed068og1_mode = { +.name = "E68OG1", +.refresh=85, +.xres=1440, +.yres=1080, +.pixclock=120000000, +.left_margin=32, +.right_margin=508, +.upper_margin=4, +.lower_margin=5, +.hsync_len=32, +.vsync_len=2, +.sync=0, +.vmode=FB_VMODE_NONINTERLACED, +.flag=0, +}; +#endif//]EPD_TIMING_ED068OG1_NUMCE3 + +static struct fb_videomode peng060d_mode = { +.name = "PENG060D", +.refresh=85, +.xres=1448, +.yres=1072, +.pixclock=80000000, +.left_margin=16, +.right_margin=102, +.upper_margin=4, +.lower_margin=4, +.hsync_len=28, +.vsync_len=2, +.sync=0, +.vmode=FB_VMODE_NONINTERLACED, +.flag=0, +}; + +static struct fb_videomode ef133ut1sce_mode = { +.name="EF133UT1SCE", +.refresh=65, +.xres=1600, +.yres=1200, +.pixclock=72222223, +.left_margin=8, +.right_margin=97, +.upper_margin=4, +.lower_margin=7, +.hsync_len=12, +.vsync_len=1, +.sync=0, +.vmode=FB_VMODE_NONINTERLACED, +.flag=0, +}; + + + +static struct imx_epdc_fb_mode panel_modes[] = { +//////////////////// +{ +& ed060sc8_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +465, /* gdclk_hp_offs */ +250, /* gdsp_offs changed delay to 8.3 uS */ +0, /* gdoe_offs */ +8, /* gdclk_offs changed delay to 4.5 SDCLK */ +1, /* num_ce */ +}, + +//////////////////// +{ +& e60_v110_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +465, /* gdclk_hp_offs */ +250, /* gdsp_offs changed delay to 8.3 uS */ +0, /* gdoe_offs */ +8, /* gdclk_offs changed delay to 4.5 SDCLK */ +1, /* num_ce */ +}, + +//////////////////// +{ +& ed060xc5_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +524, /* gdclk_hp_offs */ +25, /* gdsp_offs changed delay to 8.3 uS */ +0, /* gdoe_offs */ +19, /* gdclk_offs changed delay to 4.5 SDCLK */ +1, /* num_ce */ +}, + +//////////////////// +{ +& ed060xc1_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +492, /* gdclk_hp_offs */ +29, /* gdsp_offs changed delay to 8.3 uS */ +0, /* gdoe_offs */ +23, /* gdclk_offs changed delay to 4.5 SDCLK */ +1, /* num_ce */ +}, + +//////////////////// +{ + &ed050xxx_mode, /* struct fb_videomode *mode */ + 4, /* vscan_holdoff */ + 10, /* sdoed_width */ + 20, /* sdoed_delay */ + 10, /* sdoez_width */ + 20, /* sdoez_delay */ + 420, /* GDCLK_HP */ + 20, /* GDSP_OFF */ + 0, /* GDOE_OFF */ + 11, /* gdclk_offs */ + 3, /* num_ce */ +}, + +#ifdef EPD_TIMING_ED068TG1 //[ +{ +& ed068tg1_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +665, /* GDCLK_HP */ +718, /* GDSP_OFF */ +0, /* GDOE_OFF */ +199, /* gdclk_offs */ +1, /* num_ce */ +}, +#elif defined(EPD_TIMING_ED068OG1_NUMCE3)//][ +{ +& ed068og1_numce3_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +665, /* GDCLK_HP */ +210, /* GDSP_OFF */ +0, /* GDOE_OFF */ +199, /* gdclk_offs */ +3, /* num_ce */ +}, +#else//][ !EPD_TIMING_ED068OG1_NUMCE3 +{ +& ed068og1_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +831, /* GDCLK_HP */ +285, /* GDSP_OFF */ +0, /* GDOE_OFF */ +271, /* gdclk_offs */ +1, /* num_ce */ +}, +#endif//] EPD_TIMING_ED068OG1_NUMCE3 + +{ +&peng060d_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +562, /* GDCLK_HP */ +664, /* GDSP_OFF */ +0, /* GDOE_OFF */ +227, /* gdclk_offs */ +3, /* num_ce */ +}, +{ +&ef133ut1sce_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +743, /* GDCLK_HP */ +475, /* GDSP_OFF */ +0, /* GDOE_OFF */ +15, /* gdclk_offs */ +1, /* num_ce */ +}, +{ +&ed060scq_mode, +4, /* vscan_holdoff */ +10, /* sdoed_width */ +20, /* sdoed_delay */ +10, /* sdoez_width */ +20, /* sdoez_delay */ +438, /* GDCLK_HP */ +263, /* GDSP_OFF */ +0, /* GDOE_OFF */ +23, /* gdclk_offs */ +3, /* num_ce */ +}, +}; + + +#else //][! +static struct fb_videomode e60_v110_mode = { + .name = "E60_V110", + .refresh = 50, + .xres = 800, + .yres = 600, + .pixclock = 18604700, + .left_margin = 8, + .right_margin = 178, + .upper_margin = 4, + .lower_margin = 10, + .hsync_len = 20, + .vsync_len = 4, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, +}; +static struct fb_videomode e60_v220_mode = { + .name = "E60_V220", + .refresh = 85, + .xres = 800, + .yres = 600, + .pixclock = 30000000, + .left_margin = 8, + .right_margin = 164, + .upper_margin = 4, + .lower_margin = 8, + .hsync_len = 4, + .vsync_len = 1, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + .refresh = 85, + .xres = 800, + .yres = 600, +}; +static struct fb_videomode e060scm_mode = { + .name = "E060SCM", + .refresh = 85, + .xres = 800, + .yres = 600, + .pixclock = 26666667, + .left_margin = 8, + .right_margin = 100, + .upper_margin = 4, + .lower_margin = 8, + .hsync_len = 4, + .vsync_len = 1, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, +}; +static struct fb_videomode e97_v110_mode = { + .name = "E97_V110", + .refresh = 50, + .xres = 1200, + .yres = 825, + .pixclock = 32000000, + .left_margin = 12, + .right_margin = 128, + .upper_margin = 4, + .lower_margin = 10, + .hsync_len = 20, + .vsync_len = 4, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, +}; + +static struct imx_epdc_fb_mode panel_modes[] = { + { + &e60_v110_mode, + 4, /* vscan_holdoff */ + 10, /* sdoed_width */ + 20, /* sdoed_delay */ + 10, /* sdoez_width */ + 20, /* sdoez_delay */ + 428, /* gdclk_hp_offs */ + 20, /* gdsp_offs */ + 0, /* gdoe_offs */ + 1, /* gdclk_offs */ + 1, /* num_ce */ + }, + { + &e60_v220_mode, + 4, /* vscan_holdoff */ + 10, /* sdoed_width */ + 20, /* sdoed_delay */ + 10, /* sdoez_width */ + 20, /* sdoez_delay */ + 465, /* gdclk_hp_offs */ + 20, /* gdsp_offs */ + 0, /* gdoe_offs */ + 9, /* gdclk_offs */ + 1, /* num_ce */ + }, + { + &e060scm_mode, + 4, /* vscan_holdoff */ + 10, /* sdoed_width */ + 20, /* sdoed_delay */ + 10, /* sdoez_width */ + 20, /* sdoez_delay */ + 419, /* gdclk_hp_offs */ + 20, /* gdsp_offs */ + 0, /* gdoe_offs */ + 5, /* gdclk_offs */ + 1, /* num_ce */ + }, + { + &e97_v110_mode, + 8, /* vscan_holdoff */ + 10, /* sdoed_width */ + 20, /* sdoed_delay */ + 10, /* sdoez_width */ + 20, /* sdoez_delay */ + 632, /* gdclk_hp_offs */ + 20, /* gdsp_offs */ + 0, /* gdoe_offs */ + 1, /* gdclk_offs */ + 3, /* num_ce */ + } +}; +#endif //] + +static struct imx_epdc_fb_platform_data epdc_data = { + .epdc_mode = panel_modes, + .num_modes = ARRAY_SIZE(panel_modes), + .get_pins = epdc_get_pins, + .put_pins = epdc_put_pins, + .enable_pins = epdc_enable_pins, + .disable_pins = epdc_disable_pins, +}; + +typedef void (*usb_insert_handler) (char inserted); +usb_insert_handler mxc_misc_report_usb; + +static void mxc_register_usb_plug(void* pk_cb) +{ + pmic_event_callback_t usb_plug_event; + +// usb_plug_event.param = (void *)1; +// usb_plug_event.func = (void *)pk_cb; +// pmic_event_subscribe(EVENT_VBUSVI, usb_plug_event); + if (gIsCustomerUi) + mxc_misc_report_usb = pk_cb; + DBG_MSG("%s(),pk_cb=%p\n",__FUNCTION__,pk_cb); + +} + + +extern int mxc_usb_plug_getstatus (void); + + +#define SW_USBPLUG 0x0C +static struct usbplug_event_platform_data usbplug_data = { + .usbevent.type = EV_SW, + .usbevent.code = SW_USBPLUG, + .register_usbplugevent = mxc_register_usb_plug, + .get_key_status = mxc_usb_plug_getstatus, +}; + +struct platform_device mxc_usb_plug_device = { + .name = "usb_plug", + .id = 0, + }; + + + +static int spdc_get_pins(void) +{ + int ret = 0; + + /* Claim GPIOs for SPDC pins - used during power up/down */ + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "SPDC_D0"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "SPDC_D1"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "SPDC_D2"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "SPDC_D3"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "SPDC_D4"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "SPDC_D5"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "SPDC_D6"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "SPDC_D7"); + + ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "SIPIX_YOE"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9, "SIPIX_PWR_RDY"); + + ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "SIPIX_YDIO"); + + ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "SIPIX_YCLK"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "SIPIX_XDIO"); + + ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "SIPIX_LD"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "SIPIX_SOE"); + + ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "SIPIX_XCLK"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "SIPIX_SHD_N"); + ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "SIPIX2_CE"); + + return ret; +} + +static void spdc_put_pins(void) +{ + gpio_free(MX6SL_BRD_EPDC_SDDO_0); + gpio_free(MX6SL_BRD_EPDC_SDDO_1); + gpio_free(MX6SL_BRD_EPDC_SDDO_2); + gpio_free(MX6SL_BRD_EPDC_SDDO_3); + gpio_free(MX6SL_BRD_EPDC_SDDO_4); + gpio_free(MX6SL_BRD_EPDC_SDDO_5); + gpio_free(MX6SL_BRD_EPDC_SDDO_6); + gpio_free(MX6SL_BRD_EPDC_SDDO_7); + + gpio_free(MX6SL_BRD_EPDC_GDOE); + gpio_free(MX6SL_BRD_EPDC_SDDO_9); + gpio_free(MX6SL_BRD_EPDC_GDSP); + gpio_free(MX6SL_BRD_EPDC_GDCLK); + gpio_free(MX6SL_BRD_EPDC_SDSHR); + gpio_free(MX6SL_BRD_EPDC_SDLE); + gpio_free(MX6SL_BRD_EPDC_SDCE1); + gpio_free(MX6SL_BRD_EPDC_SDCLK); + gpio_free(MX6SL_BRD_EPDC_SDDO_10); + gpio_free(MX6SL_BRD_EPDC_SDCE0); +} + +static void spdc_enable_pins(void) +{ + /* Configure MUX settings to enable SPDC use */ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_enable_pads, \ + ARRAY_SIZE(mx6sl_brd_spdc_enable_pads)); + + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_8); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_11); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_12); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_13); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_14); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_15); + gpio_direction_input(MX6SL_BRD_EPDC_GDOE); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9); + gpio_direction_input(MX6SL_BRD_EPDC_GDSP); + gpio_direction_input(MX6SL_BRD_EPDC_GDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_SDSHR); + gpio_direction_input(MX6SL_BRD_EPDC_SDLE); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE1); + gpio_direction_input(MX6SL_BRD_EPDC_SDCLK); + gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10); + gpio_direction_input(MX6SL_BRD_EPDC_SDCE0); +} + +static void spdc_disable_pins(void) +{ + /* Configure MUX settings for SPDC pins to + * GPIO and drive to 0. */ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_disable_pads, \ + ARRAY_SIZE(mx6sl_brd_spdc_disable_pads)); + + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_8 , 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9 , 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_11, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_12, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_13, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_14, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_15, 0); + + gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0); + gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0); + gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0); +} + +static struct imx_spdc_panel_init_set spdc_init_set = { + .yoe_pol = false, + .dual_gate = false, + .resolution = 0, + .ud = false, + .rl = false, + .data_filter_n = true, + .power_ready = true, + .rgbw_mode_enable = false, + .hburst_len_en = true, +}; + +static struct fb_videomode erk_1_4_a01 = { + .name = "ERK_1_4_A01", + .refresh = 50, + .xres = 800, + .yres = 600, + .pixclock = 40000000, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static struct imx_spdc_fb_mode spdc_panel_modes[] = { + { + &erk_1_4_a01, + &spdc_init_set, + .wave_timing = "pvi" + }, +}; + +static struct imx_spdc_fb_platform_data spdc_data = { + .spdc_mode = spdc_panel_modes, + .num_modes = ARRAY_SIZE(spdc_panel_modes), + .get_pins = spdc_get_pins, + .put_pins = spdc_put_pins, + .enable_pins = spdc_enable_pins, + .disable_pins = spdc_disable_pins, +}; + +static int __init early_use_spdc_sel(char *p) +{ + spdc_sel = 1; + return 0; +} +early_param("spdc", early_use_spdc_sel); + +static void setup_spdc(void) +{ + /* GPR0[8]: 0:EPDC, 1:SPDC */ + if (spdc_sel) + mxc_iomux_set_gpr_register(0, 8, 1, 1); +} + +static void imx6_ntx_usbotg_vbus(bool on) +{ +#if 0 + if (on) + gpio_set_value(MX6_BRD_USBOTG1_PWR, 1); + else + gpio_set_value(MX6_BRD_USBOTG1_PWR, 0); +#endif +} + +static void __init mx6_ntx_init_usb(void) +{ + int ret = 0; + + imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); + +#if 0 + /* disable external charger detect, + * or it will affect signal quality at dp. + */ + + ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr"); + if (ret) { + pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret); + return; + } + gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0); + + ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr"); + if (ret) { + pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret); + return; + } + gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1); +#endif + + mx6_set_otghost_vbus_func(imx6_ntx_usbotg_vbus); +#ifdef CONFIG_USB_EHCI_ARC_HSIC + mx6_usb_h2_init(); +#endif +} + +static struct platform_device mxcbl_device = { + .name = "mxc_msp430_fl", +}; + +static struct platform_pwm_backlight_data mx6_ntx_pwm_backlight_data = { + .pwm_id = 0, + .max_brightness = 255, + .dft_brightness = 128, + .pwm_period_ns = 50000, +}; +static struct fb_videomode wvga_video_modes[] = { + { + /* 800x480 @ 57 Hz , pixel clk @ 32MHz */ + "SEIKO-WVGA", 60, 800, 480, 29850, 99, 164, 33, 10, 10, 10, + FB_SYNC_CLK_LAT_FALL, + FB_VMODE_NONINTERLACED, + 0,}, +}; + +static struct mxc_fb_platform_data wvga_fb_data[] = { + { + .interface_pix_fmt = V4L2_PIX_FMT_RGB24, + .mode_str = "SEIKO-WVGA", + .mode = wvga_video_modes, + .num_modes = ARRAY_SIZE(wvga_video_modes), + .panel_type = "lcd", + }, +}; + +static struct platform_device lcd_wvga_device = { + .name = "lcd_seiko", +}; + +#if 0 +static struct fb_videomode hdmi_video_modes[] = { + { + /* 1920x1080 @ 60 Hz , pixel clk @ 148MHz */ + "sii9022x_1080p60", 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5, + FB_SYNC_CLK_LAT_FALL, + FB_VMODE_NONINTERLACED, + 0,}, +}; + +static struct mxc_fb_platform_data hdmi_fb_data[] = { + { + .interface_pix_fmt = V4L2_PIX_FMT_RGB24, + .mode_str = "1920x1080M@60", + .mode = hdmi_video_modes, + .num_modes = ARRAY_SIZE(hdmi_video_modes), + .panel_type = "hdmi", + }, +}; +#endif + +static int mx6sl_ntx_keymap[] = { + KEY(0, 0, 90), +}; + +static struct platform_device ntx_device_rtc = { + .name = "ntx_misc_rtc", + .id = 0, + .dev = { + .platform_data = -1, + } +}; + +static const struct matrix_keymap_data mx6sl_ntx_map_data __initconst = { + .keymap = mx6sl_ntx_keymap, + .keymap_size = ARRAY_SIZE(mx6sl_ntx_keymap), +}; +#if 0 +static void __init elan_ts_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_elan_pads, + ARRAY_SIZE(mx6sl_brd_elan_pads)); + + /* ELAN Touchscreen */ + gpio_request(MX6SL_BRD_ELAN_INT, "elan-interrupt"); + gpio_direction_input(MX6SL_BRD_ELAN_INT); + + gpio_request(MX6SL_BRD_ELAN_CE, "elan-cs"); + gpio_direction_output(MX6SL_BRD_ELAN_CE, 1); + gpio_direction_output(MX6SL_BRD_ELAN_CE, 0); + + gpio_request(MX6SL_BRD_ELAN_RST, "elan-rst"); + gpio_direction_output(MX6SL_BRD_ELAN_RST, 1); + gpio_direction_output(MX6SL_BRD_ELAN_RST, 0); + mdelay(1); + gpio_direction_output(MX6SL_BRD_ELAN_RST, 1); + gpio_direction_output(MX6SL_BRD_ELAN_CE, 1); +} +#endif + +/* + *Usually UOK and DOK should have separate + *line to differentiate its behaviour (with different + * GPIO irq),because connect max8903 pin UOK to + *pin DOK from hardware design,cause software cannot + *process and distinguish two interrupt, so default + *enable dc_valid for ac charger + */ +static struct max8903_pdata charger1_data = { + .dok = MX6_BRD_CHG_DOK, + .uok = MX6_BRD_CHG_UOK, + .chg = MX6_BRD_CHG_STATUS, + .flt = MX6_BRD_CHG_FLT, + .dcm_always_high = true, + .dc_valid = true, + .usb_valid = false, + .feature_flag = 1, +}; + +static struct platform_device ntx_max8903_charger_1 = { + .name = "max8903-charger", + .dev = { + .platform_data = &charger1_data, + }, +}; + +/*! Device Definition for csi v4l2 device */ +static struct platform_device csi_v4l2_devices = { + .name = "csi_v4l2", + .id = 0, +}; + +#define SNVS_LPCR 0x38 +static void mx6_snvs_poweroff(void) +{ + u32 value; + void __iomem *mx6_snvs_base = MX6_IO_ADDRESS(MX6Q_SNVS_BASE_ADDR); + + value = readl(mx6_snvs_base + SNVS_LPCR); + /* set TOP and DP_EN bit */ + writel(value | 0x60, mx6_snvs_base + SNVS_LPCR); +} + +#if 0 +static int uart2_enabled; +static int __init uart2_setup(char * __unused) +{ + uart2_enabled = 1; + return 1; +} +__setup("bluetooth", uart2_setup); + +static void __init uart2_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx6sl_uart2_pads, + ARRAY_SIZE(mx6sl_uart2_pads)); + imx6sl_add_imx_uart(1, &mx6sl_ntx_uart1_data); +} +#endif + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) + +#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake, debounce) \ +{ \ + .gpio = gpio_num, \ + .type = EV_KEY, \ + .code = ev_code, \ + .active_low = act_low, \ + .desc = "btn " descr, \ + .wakeup = wake, \ + .debounce_interval = debounce, \ +} + +static struct gpio_keys_button gpio_key_matrix_FL[] = { + GPIO_BUTTON(GPIO_KB_ROW0, 90, 1, "front_light", 1,1), // Front light +//#ifdef CONFIG_ANDROID //[ + GPIO_BUTTON(IMX_GPIO_NR(4, 25), KEY_POWER, 1, "power", 1, 1), +//#endif //]CONFIG_ANDROID +}; + +static struct gpio_keys_button gpio_key_HOME_FL[] = { + GPIO_BUTTON(GPIO_KB_COL1, 90, 1, "front_light", 1,1), // Front light + GPIO_BUTTON(GPIO_KB_COL0, KEY_HOME, 1, "home", 1,1), // home +//#ifdef CONFIG_ANDROID //[ + GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1), +//#endif //]CONFIG_ANDROID +}; +static struct gpio_keys_button gpio_key_RETURN_HOME_MENU[] = { + GPIO_BUTTON(GPIO_KB_ROW0, KEY_HOME, 1, "home", 1,1), // home + GPIO_BUTTON(GPIO_KB_ROW1, KEY_MENU, 1, "menu", 1,1), // menu + GPIO_BUTTON(GPIO_KB_ROW2, KEY_ESC, 1, "return", 1,1), // return +//#ifdef CONFIG_ANDROID //[ + GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1), +//#endif //]CONFIG_ANDROID +}; + +static struct gpio_keys_button gpio_key_HOME[] = { + GPIO_BUTTON(GPIO_KB_COL0, 61, 1, "home", 1, 50), // home +//#ifdef CONFIG_ANDROID //[ + GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1), +//#endif //]CONFIG_ANDROID +}; + +static struct gpio_keys_button gpio_key_FL[] = { + GPIO_BUTTON(GPIO_KB_COL1, 90, 1, "front_light", 1, 10), // Front light +//#ifdef CONFIG_ANDROID //[ + GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1), +//#endif //]CONFIG_ANDROID +}; + +static struct gpio_keys_button gpio_key_None[] = { +//#ifdef CONFIG_ANDROID //[ + GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1), +//#endif //]CONFIG_ANDROID +}; + +static struct gpio_keys_button *gptGPIO_HOME_KEY; + +static struct gpio_keys_platform_data ntx_gpio_key_data = { + .buttons = gpio_key_matrix_FL, + .nbuttons = ARRAY_SIZE(gpio_key_matrix_FL), +}; + +static struct platform_device ntx_gpio_key_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &ntx_gpio_key_data, + } +}; + +#ifdef TOUCH_HOME_LED//[ + +extern int ntx_get_homepad_enabled_status(void); + +static int giHomeLED_Delay_Ticks=100; +static volatile int giCurHomeLED_state; +static struct delayed_work homeled_pwrdwn_work,homepad_check_work; +/* + * giHomePad_enable : + * 0 = disabled . + * 1 = enabled home pad/led action . + * 2 = enabled home pad/led action and send event to application layer . + */ +static int giHomePad_enable=2; + + +static void _homeled_onoff_force(int iIsON) +{ + //int iOldHomeLED_state=giCurHomeLED_state; + int iIsHOMELED_gpio=1; + + if( 0==gptHWCFG->m_val.bHOME_LED_PWM && \ + ( 36!=gptHWCFG->m_val.bPCB && 40!=gptHWCFG->m_val.bPCB) ) + { + // HOME_LED_PWM==NO && !=E60Q3X&&E60Q5X + return ; + } + + if(1==gptHWCFG->m_val.bHOME_LED_PWM) { + printk("MSP430 "); + iIsHOMELED_gpio=0; + } + else { + printk("GPIO "); + } + + if(iIsON) { + giCurHomeLED_state=1; + printk("HOME LED [ON]\n"); + if(iIsHOMELED_gpio) { + gpio_direction_output (gMX6SL_HOME_LED, 0); + } + else { + } + } + else { + giCurHomeLED_state=0; + printk("HOME LED [OFF]\n"); + if(iIsHOMELED_gpio) { + gpio_direction_output (gMX6SL_HOME_LED, 1); + } + else { + } + } +} + + +static ssize_t homepad_enable_write(struct device *dev, + struct device_attribute *attr,const char *buf,size_t count) +{ + int iParam; + extern void gpiokeys_enable_button(struct gpio_keys_button *button,int iIsEnable); + + iParam = simple_strtol(buf,NULL,0); + + if(iParam!=giHomePad_enable) { + switch (iParam) { + case 0: + if(1==gptHWCFG->m_val.bHOME_LED_PWM) { + // HOME LED is controlled by MSP430 . + //msp430_homeled_enable(0); + } + //gpiokeys_enable_button(gptGPIO_HOME_KEY,0); + _homeled_onoff_force(0); + msp430_homepad_enable(0); + giHomePad_enable = iParam; + break; + case 1: + case 2: + //gpiokeys_enable_button(gptGPIO_HOME_KEY,1); + if(1==gptHWCFG->m_val.bHOME_LED_PWM) { + // HOME LED is controlled by MSP430 . + //msp430_homeled_enable(1); + } + msp430_homepad_enable(2); + giHomePad_enable = iParam; + break; + default : + printk(KERN_ERR"invalid parameter !\n"); + return -1; + } + } + else { + + } + + return strlen(buf); +} +static ssize_t homepad_enable_read(struct device *dev, + struct device_attribute *attr,const char *buf,size_t count) +{ + ssize_t szChk=0; + sprintf(buf,"%d\n",giHomePad_enable); + szChk = strlen(buf); + return szChk; +} +static DEVICE_ATTR(homepad_enable,0666, + homepad_enable_read, + homepad_enable_write); + +static ssize_t homeled_delayms_show(struct device *dev, + struct device_attribute *attr,const char *buf,size_t count) +{ + ssize_t szChk=0; + sprintf(buf,"%d\n",giHomeLED_Delay_Ticks*(1000/HZ)); + szChk = strlen(buf); + return szChk; +} +static ssize_t homeled_delayms_store(struct device *dev, + struct device_attribute *attr,const char *buf,size_t count) +{ + int iDelayms; + ssize_t szChk; + iDelayms = simple_strtol(buf,NULL,0); + if(1==gptHWCFG->m_val.bHOME_LED_PWM) { + // HOME LED is controlled by MSP430 . + int iChk = msp430_set_homeled_delayms(iDelayms); + if(iChk>=0) { + giHomeLED_Delay_Ticks = msecs_to_jiffies(iChk); + szChk = strlen(buf); + } + else { + szChk = -1; + } + } + else if (36==gptHWCFG->m_val.bPCB || 2==gptHWCFG->m_val.bHOME_LED_PWM) + { + // HOME LED is controlled by SOC . + giHomeLED_Delay_Ticks = msecs_to_jiffies(iDelayms); + szChk = strlen(buf); + } + return szChk; +} +static DEVICE_ATTR(homeled_delayms,0666, + homeled_delayms_show, + homeled_delayms_store); + +static ssize_t homeled_delaylevel_show(struct device *dev, + struct device_attribute *attr,const char *buf,size_t count) +{ + ssize_t szChk=0; + if(1==gptHWCFG->m_val.bHOME_LED_PWM) { + // HOME LED is controlled by MSP430 . + if(MSP430_HOMELED_TYPE_PWM==msp430_homeled_type_get(0)) { + sprintf(buf,"%d\n",msp430_get_homeled_pwm_delaylevel()); + } + else { + sprintf(buf,"%d\n",msp430_get_homeled_gpio_delaylevel()); + } + szChk = strlen(buf); + } + else { + } + return szChk; +} +static ssize_t homeled_delaylevel_store(struct device *dev, + struct device_attribute *attr,const char *buf,size_t count) +{ + int iDelayLevel; + + iDelayLevel = simple_strtol(buf,NULL,0); + if(1==gptHWCFG->m_val.bHOME_LED_PWM) { + // HOME LED is controlled by MSP430 . + if(MSP430_HOMELED_TYPE_PWM==msp430_homeled_type_get(0)) { + msp430_set_homeled_pwm_delaylevel(iDelayLevel); + } + else { + msp430_set_homeled_gpio_delaylevel(iDelayLevel); + } + return strlen(buf); + } + else { + return (ssize_t)(-1); + } +} +static DEVICE_ATTR(homeled_delaylevel,0666, + homeled_delaylevel_show, + homeled_delaylevel_store); + + +static ssize_t homeled_type_show(struct device *dev, + struct device_attribute *attr,const char *buf,size_t count) +{ + if(1==gptHWCFG->m_val.bHOME_LED_PWM) { + // HOME LED is controlled by MSP430 . + char *pszHomeLedType; + + msp430_homeled_type_get(&pszHomeLedType); + sprintf(buf,"%s\n",pszHomeLedType); + + return strlen(buf); + } + else { + return 0; + } +} + +static ssize_t homeled_type_store(struct device *dev, + struct device_attribute *attr,const char *buf,size_t count) +{ + ssize_t szChk = -1; + + if(1==gptHWCFG->m_val.bHOME_LED_PWM) { + // HOME LED is controlled by MSP430 . + if( msp430_homeled_type_set_by_name(buf) >=0 ) { + szChk = strlen(buf); + } + } + else { + printk(KERN_WARNING"Home led control type cannot changed on this hardware \n"); + } + + return szChk; +} + +static DEVICE_ATTR(homeled_type,0666, + homeled_type_show, + homeled_type_store); + + +static const struct attribute *sysfs_homepad_attrs[] = { + &dev_attr_homepad_enable.attr, + NULL +}; +static const struct attribute *sysfs_homeled_msp430_attrs[] = { + &dev_attr_homeled_type.attr, + &dev_attr_homeled_delayms.attr, + &dev_attr_homeled_delaylevel.attr, + NULL +}; +static const struct attribute *sysfs_homeled_socgpio_attrs[] = { + &dev_attr_homeled_delayms.attr, + NULL +}; + + + +static void _homeled_onoff(int iIsON) +{ + if(2==gptHWCFG->m_val.bUIStyle) { + if(gSleep_Mode_Suspend) { + // skip home led control when system want to enter fake hibernation . + _homeled_onoff_force(0); + return ; + } + } + _homeled_onoff_force(iIsON); +} + +static void _homepad_work_func(struct work_struct *work) +{ + int iIsHomePressing,iHomeGPIOVal; + + iHomeGPIOVal=gpio_get_value(gptGPIO_HOME_KEY->gpio); + iIsHomePressing = (iHomeGPIOVal?1:0)^gptGPIO_HOME_KEY->active_low; + //printk("%s(),\"%s\" gpio=%d,down=%d\n",__FUNCTION__, + // gptGPIO_HOME_KEY->desc,iHomeGPIOVal,iIsHomePressing); + if(iIsHomePressing) { + msp430_homepad_enable(2); + } +} +static void _homeled_work_func(struct work_struct *work) +{ + + _homeled_onoff(0); + +} + +static int ntx_touch_home_key_hook(struct gpio_keys_button *I_gpio_btn_data,int state) +{ + int iRet = 0; + //printk("%s(%p,%d)\n",__FUNCTION__,I_gpio_btn_data,state); + /*if(0x03==gptHWCFG->m_val.bUIConfig) { + // RD/MP mode . + if(!state) { + printk("%s():current home led=%d\n",__FUNCTION__,giCurHomeLED_state); + _homeled_onoff(!giCurHomeLED_state); + } + } + else*/ + { + if(state) { + + if( 36==gptHWCFG->m_val.bPCB || 2==gptHWCFG->m_val.bHOME_LED_PWM ) { + // E60Q3X or HOME LED is GPIO controlled by SOC . + cancel_delayed_work_sync(&homeled_pwrdwn_work); + cancel_delayed_work_sync(&homepad_check_work); + schedule_delayed_work(&homepad_check_work, giHomeLED_Delay_Ticks+400); + _homeled_onoff(1); + } + } + else { + + if( 36==gptHWCFG->m_val.bPCB || 2==gptHWCFG->m_val.bHOME_LED_PWM ) { + // E60Q3X or HOME LED is GPIO controlled by SOC . + cancel_delayed_work_sync(&homeled_pwrdwn_work); + schedule_delayed_work(&homeled_pwrdwn_work, giHomeLED_Delay_Ticks); + } + } + + if(giHomePad_enable<=1) { + iRet = -1; + } + } + return iRet; +} + +void homeled_onoff(int iIsON) { + _homeled_onoff_force(iIsON); +} + +int ntx_get_homepad_enabled_status(void) +{ + return giHomePad_enable; +} + +int ntx_get_homeled_delay_ms(void) +{ + return jiffies_to_msecs(giHomeLED_Delay_Ticks); +} + +void ntx_create_homepad_sys_attrs(struct kobject *kobj) +{ + int iChk; + if(36==gptHWCFG->m_val.bPCB || 40==gptHWCFG->m_val.bPCB || 0!=gptHWCFG->m_val.bHOME_LED_PWM) { + iChk = sysfs_create_files(kobj,sysfs_homepad_attrs); + if(iChk) { + pr_err("Can't create homepad attr sysfs !\n"); + } + if(36==gptHWCFG->m_val.bPCB||2==gptHWCFG->m_val.bHOME_LED_PWM) { + // E60Q3X or HOME LED PWM controlled by SOC . + iChk = sysfs_create_files(kobj,sysfs_homeled_socgpio_attrs); + if(iChk) { + pr_err("Can't create homepad soc gpio attr sysfs !\n"); + } + } + else if(1==gptHWCFG->m_val.bHOME_LED_PWM) { + // HOME LED PWM is controlled by MSP430 . + iChk = sysfs_create_files(kobj,sysfs_homeled_msp430_attrs); + if(iChk) { + pr_err("Can't create homepad msp430 pwm attr sysfs !\n"); + } + } + } +} +#else //][!TOUCH_HOME_LED +static void _homeled_onoff(int iIsON) {} +void homeled_onoff(int iIsON) {} +#endif //]TOUCH_HOME_LED + +#endif + + + +void *g_wifi_sd_host; +irq_handler_t g_cd_irq; + +void ntx_register_wifi_cd (irq_handler_t handler, void *data) +{ + printk ("[%s-%d] register g_cd_irq \n",__func__,__LINE__); + g_wifi_sd_host = data; + g_cd_irq = handler; +} + + +static DEFINE_MUTEX(ntx_wifi_power_mutex); +static int gi_wifi_power_status = -1; + +int _ntx_get_wifi_power_status(void) +{ + int iWifiPowerStatus; + + mutex_lock(&ntx_wifi_power_mutex); + iWifiPowerStatus = gi_wifi_power_status; + mutex_unlock(&ntx_wifi_power_mutex); + + return iWifiPowerStatus; +} + +int _ntx_wifi_power_ctrl (int isWifiEnable) +{ + int iHWID; + int iOldStatus; + + mutex_lock(&ntx_wifi_power_mutex); + iOldStatus = gi_wifi_power_status; + printk("Wifi / BT power control %d\n", isWifiEnable); + if(isWifiEnable == 0){ + gpio_direction_output (gMX6SL_WIFI_RST, 0); + gpio_direction_input (gMX6SL_WIFI_3V3); // turn off Wifi_3V3_on + + msleep(10); +// DO NOT switch pin functions to GPIO +/* + // sdio port disable ... + if(33==gptHWCFG->m_val.bPCB) { + //E60Q2X . + mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd3_gpio_pads, ARRAY_SIZE(mx6sl_ntx_sd3_gpio_pads)); + gpio_request (MX6SL_SD3_CLK , "MX6SL_SD3_CLK" ); + gpio_request (MX6SL_SD3_CMD , "MX6SL_SD3_CMD" ); + gpio_request (MX6SL_SD3_DAT0, "MX6SL_SD3_DAT0"); + gpio_request (MX6SL_SD3_DAT1, "MX6SL_SD3_DAT1"); + gpio_request (MX6SL_SD3_DAT2, "MX6SL_SD3_DAT2"); + gpio_request (MX6SL_SD3_DAT3, "MX6SL_SD3_DAT3"); + gpio_direction_output (MX6SL_SD3_CLK , 0); + gpio_direction_output (MX6SL_SD3_CMD , 0); + gpio_direction_output (MX6SL_SD3_DAT0, 0); + gpio_direction_output (MX6SL_SD3_DAT1, 0); + gpio_direction_output (MX6SL_SD3_DAT2, 0); + gpio_direction_output (MX6SL_SD3_DAT3, 0); + } + else { + mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd2_gpio_pads, ARRAY_SIZE(mx6sl_ntx_sd2_gpio_pads)); + gpio_request (MX6SL_SD2_CLK , "MX6SL_SD2_CLK" ); + gpio_request (MX6SL_SD2_CMD , "MX6SL_SD2_CMD" ); + gpio_request (MX6SL_SD2_DAT0, "MX6SL_SD2_DAT0"); + gpio_request (MX6SL_SD2_DAT1, "MX6SL_SD2_DAT1"); + gpio_request (MX6SL_SD2_DAT2, "MX6SL_SD2_DAT2"); + gpio_request (MX6SL_SD2_DAT3, "MX6SL_SD2_DAT3"); + gpio_direction_input (MX6SL_SD2_CLK ); + gpio_direction_input (MX6SL_SD2_CMD ); + gpio_direction_input (MX6SL_SD2_DAT0); + gpio_direction_input (MX6SL_SD2_DAT1); + gpio_direction_input (MX6SL_SD2_DAT2); + gpio_direction_input (MX6SL_SD2_DAT3); + } +*/ + +#ifdef _WIFI_ALWAYS_ON_ + disable_irq_wake(gpio_to_irq(gMX6SL_WIFI_INT)); +#endif + gi_wifi_power_status=0; + } + else { + + + // sdio port process ... + if(31==gptHWCFG->m_val.bPCB||32==gptHWCFG->m_val.bPCB) { + // E60Q0X/E60Q1X + gpio_free (MX6SL_SD2_CLK ); + gpio_free (MX6SL_SD2_CMD ); + gpio_free (MX6SL_SD2_DAT0); + gpio_free (MX6SL_SD2_DAT1); + gpio_free (MX6SL_SD2_DAT2); + gpio_free (MX6SL_SD2_DAT3); + mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd2_wifi_pads, ARRAY_SIZE(mx6sl_ntx_sd2_wifi_pads)); + } + else { + gpio_free (MX6SL_SD3_CLK ); + gpio_free (MX6SL_SD3_CMD ); + gpio_free (MX6SL_SD3_DAT0); + gpio_free (MX6SL_SD3_DAT1); + gpio_free (MX6SL_SD3_DAT2); + gpio_free (MX6SL_SD3_DAT3); + mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd3_wifi_pads, ARRAY_SIZE(mx6sl_ntx_sd3_wifi_pads)); + } + //msleep(10); + + gpio_direction_output (gMX6SL_WIFI_3V3, 0); // turn on Wifi_3V3_on + //schedule_timeout(HZ/50); + msleep(10); + + gpio_direction_input (gMX6SL_WIFI_INT); + //msleep(10); + gpio_direction_output (gMX6SL_WIFI_RST, 1); // turn on wifi_RST + //schedule_timeout(HZ/10); + msleep(30); +#ifdef _WIFI_ALWAYS_ON_ + enable_irq_wake(gpio_to_irq(gMX6SL_WIFI_INT)); +#endif + gi_wifi_power_status=1; + } + + if (g_cd_irq) { + struct sdhci_host *host; + + host = (struct sdhci_host *) g_wifi_sd_host; + //g_cd_irq (0, g_wifi_sd_host); + //schedule_timeout (100); + //msleep(1000); + mmc_detect_change(host->mmc, msecs_to_jiffies(500)); + //msleep(600); + schedule_timeout(500); + } + else { + printk ("[%s-%d] not registered.\n",__func__,__LINE__); + } + + if(isWifiEnable == 0){ // switch PIN function to GPIO + // sdio port disable ... + if(31==gptHWCFG->m_val.bPCB||32==gptHWCFG->m_val.bPCB) { + // E60Q0X/E60Q1X. + mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd2_gpio_pads, ARRAY_SIZE(mx6sl_ntx_sd2_gpio_pads)); + gpio_request (MX6SL_SD2_CLK , "MX6SL_SD2_CLK" ); + gpio_request (MX6SL_SD2_CMD , "MX6SL_SD2_CMD" ); + gpio_request (MX6SL_SD2_DAT0, "MX6SL_SD2_DAT0"); + gpio_request (MX6SL_SD2_DAT1, "MX6SL_SD2_DAT1"); + gpio_request (MX6SL_SD2_DAT2, "MX6SL_SD2_DAT2"); + gpio_request (MX6SL_SD2_DAT3, "MX6SL_SD2_DAT3"); + gpio_direction_input (MX6SL_SD2_CLK ); + gpio_direction_input (MX6SL_SD2_CMD ); + gpio_direction_input (MX6SL_SD2_DAT0); + gpio_direction_input (MX6SL_SD2_DAT1); + gpio_direction_input (MX6SL_SD2_DAT2); + gpio_direction_input (MX6SL_SD2_DAT3); + } + else { + mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd3_gpio_pads, ARRAY_SIZE(mx6sl_ntx_sd3_gpio_pads)); + gpio_request (MX6SL_SD3_CLK , "MX6SL_SD3_CLK" ); + gpio_request (MX6SL_SD3_CMD , "MX6SL_SD3_CMD" ); + gpio_request (MX6SL_SD3_DAT0, "MX6SL_SD3_DAT0"); + gpio_request (MX6SL_SD3_DAT1, "MX6SL_SD3_DAT1"); + gpio_request (MX6SL_SD3_DAT2, "MX6SL_SD3_DAT2"); + gpio_request (MX6SL_SD3_DAT3, "MX6SL_SD3_DAT3"); + gpio_direction_output (MX6SL_SD3_CLK , 0); + gpio_direction_output (MX6SL_SD3_CMD , 0); + gpio_direction_output (MX6SL_SD3_DAT0, 0); + gpio_direction_output (MX6SL_SD3_DAT1, 0); + gpio_direction_output (MX6SL_SD3_DAT2, 0); + gpio_direction_output (MX6SL_SD3_DAT3, 0); + } + } + printk("%s() end.\n",__FUNCTION__); + mutex_unlock(&ntx_wifi_power_mutex); + return iOldStatus; +} + +void ntx_wifi_power_ctrl(int iIsWifiEnable) +{ + _ntx_wifi_power_ctrl(iIsWifiEnable); +} + +EXPORT_SYMBOL(ntx_wifi_power_ctrl); + +static iomux_v3_cfg_t mx6sl_ntx_suspend_pads[] = { + MX6SL_PAD_I2C2_SCL__GPIO_3_14, + MX6SL_PAD_I2C2_SDA__GPIO_3_15, +}; + +static iomux_v3_cfg_t mx6sl_ntx_resume_pads[] = { + MX6SL_PAD_I2C2_SCL__I2C2_SCL, + MX6SL_PAD_I2C2_SDA__I2C2_SDA, +}; + +extern void ntx_gpio_suspend (void); +extern void ntx_gpio_resume (void); + +static void ntx_suspend_enter(void) +{ +// mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_suspend_pads, ARRAY_SIZE(mx6sl_ntx_suspend_pads)); +// gpio_request(MX6SL_I2C2_SCL, "MX6SL_I2C2_SCL"); +// gpio_request(MX6SL_I2C2_SDA, "MX6SL_I2C2_SDA"); +// gpio_direction_output (MX6SL_I2C2_SCL, 0); +// gpio_direction_output (MX6SL_I2C2_SDA, 0); + +#if 0 + gpio_direction_output (MX6SL_EP_PWRALL, 1); + gpio_direction_output (MX6SL_EP_WAKEUP, 0); + gpio_direction_output (MX6SL_EP_PWRUP, 0); + gpio_direction_output (MX6SL_EP_VCOM, 0); + gpio_direction_input (MX6SL_EP_INT); + gpio_direction_input (MX6SL_EP_PWRSTAT); +#endif + + _homeled_onoff_force(0); + + ntx_gpio_suspend (); + +#if 0 + { + unsigned int *pIomux = IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR)+0x4C; + unsigned int value; + + printk ("Addr , value\n"); + while (IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR)+0x5A8 >= pIomux) { + value = *pIomux; + printk ("0x%08X, 0x%08X, %s%s%s\n",pIomux, value,((value&0x2000)?"PUE - ":""),\ + ((value&0x2000)?((value&0xC000)?"Pull Up - ":"Pull Down - "):""),((value&0x1000)?"PKE":"")); + ++pIomux; + } + } +#endif +#if 0 +{ + void __iomem *base = IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR); + unsigned int offset = 0x4C; + unsigned int addr = 0x20E0000; + unsigned int value; + + for(offset=0x4C; offset <=0x884; offset+=4) { + value = __raw_readl( base + offset); + printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value); + } + + base = IO_ADDRESS(GPIO1_BASE_ADDR); + addr = 0x209C000; + for(offset=0; offset<=0x1C; offset+=4) { + value = __raw_readl( base + offset); + printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value); + } + + base = IO_ADDRESS(GPIO2_BASE_ADDR); + addr = 0x20A0000; + for(offset=0; offset<=0x1C; offset+=4) { + value = __raw_readl( base + offset); + printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value); + } + + base = IO_ADDRESS(GPIO3_BASE_ADDR); + addr = 0x20A4000; + for(offset=0; offset<=0x1C; offset+=4) { + value = __raw_readl( base + offset); + printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value); + } + + base = IO_ADDRESS(GPIO4_BASE_ADDR); + addr = 0x20A8000; + for(offset=0; offset<=0x1C; offset+=4) { + value = __raw_readl( base + offset); + printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value); + } + + base = IO_ADDRESS(GPIO5_BASE_ADDR); + addr = 0x20AC000; + for(offset=0; offset<=0x1C; offset+=4) { + value = __raw_readl( base + offset); + printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value); + } +} +#endif +} + +static void ntx_suspend_exit(void) +{ +#if 0 + gpio_direction_output (MX6SL_EP_WAKEUP, 1); +#endif + +// gpio_free(MX6SL_I2C2_SCL); +// gpio_free(MX6SL_I2C2_SDA); +// mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_resume_pads, ARRAY_SIZE(mx6sl_ntx_resume_pads)); + ntx_gpio_resume (); + +} + +static const struct pm_platform_data mx6sl_ntx_pm_data __initconst = { + .name = "imx_pm", + .suspend_enter = ntx_suspend_enter, + .suspend_exit = ntx_suspend_exit, +}; + +void ntx_wacom_reset(bool on) { + gpio_direction_output (MX6SL_WACOM_RST, on); +} +static void ntx_gpio_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_pads, + ARRAY_SIZE(mx6sl_brd_ntx_pads)); + + + + if(31==gptHWCFG->m_val.bPCB||32==gptHWCFG->m_val.bPCB) { + // E60Q0X|E60Q1X. + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_sd4_gpio_pads, + ARRAY_SIZE(mx6sl_brd_ntx_sd4_gpio_pads)); + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_sd1_pads, + ARRAY_SIZE(mx6sl_brd_ntx_sd1_pads)); +#if 1 + mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_q12_wifictrl_pads, + ARRAY_SIZE(mx6sl_ntx_q12_wifictrl_pads)); +#endif + giISD_3V3_ON_Ctrl=-1; + } + else { + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_sd4_pads, + ARRAY_SIZE(mx6sl_brd_ntx_sd4_pads)); + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_sd1_gpio_pads, + ARRAY_SIZE(mx6sl_brd_ntx_sd1_gpio_pads)); + +#if 1 + mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_q22_wifictrl_pads, + ARRAY_SIZE(mx6sl_ntx_q22_wifictrl_pads)); +#endif + if(1==gptHWCFG->m_val.bLed) { + // RGB/G type LED . + // ON_LED# + mxc_iomux_v3_setup_pad(MX6SL_PAD_SD1_DAT2__GPIO_5_13_PULLHIGH); + } + + gMX6SL_NTX_ACIN_PG = IMX_GPIO_NR(5, 14); + gMX6SL_NTX_CHG = IMX_GPIO_NR(5, 15); + gMX6SL_MSP_INT = IMX_GPIO_NR(5, 11); + gMX6SL_PWR_SW = IMX_GPIO_NR(5, 8); + gMX6SL_IR_TOUCH_INT = IMX_GPIO_NR(5, 6); + gMX6SL_IR_TOUCH_RST = IMX_GPIO_NR(5, 9); + if(49==gptHWCFG->m_val.bPCB) { + // E60QDX + gMX6SL_IR_TOUCH_RST = IMX_GPIO_NR(5, 13); + } + + gMX6SL_HALL_EN = IMX_GPIO_NR(5, 12); + + // LED assign ... + gMX6SL_CHG_LED = IMX_GPIO_NR(5, 10); + if(37==gptHWCFG->m_val.bPCB) { + // E60QB0 . + gMX6SL_ACT_LED = IMX_GPIO_NR(5, 13); + gMX6SL_ON_LED = IMX_GPIO_NR(5, 7); + } + else if(46==gptHWCFG->m_val.bPCB||48==gptHWCFG->m_val.bPCB) { + // E60Q9X/E60QAX . + + // ON_LED# pull high . + mxc_iomux_v3_setup_pad(MX6SL_PAD_SD1_DAT2__GPIO_5_13_PULLHIGH); + + gMX6SL_ACT_LED = IMX_GPIO_NR(5, 7); + gMX6SL_ON_LED = IMX_GPIO_NR(5, 13); + } + else if(42==gptHWCFG->m_val.bPCB){ + // E60Q6X + gMX6SL_ACT_LED = IMX_GPIO_NR(5, 13); + gMX6SL_ON_LED = IMX_GPIO_NR(5, 13); + } + else { + gMX6SL_ACT_LED = IMX_GPIO_NR(5, 7); + gMX6SL_ON_LED = IMX_GPIO_NR(5, 7); + } + + gMX6SL_WIFI_3V3 = IMX_GPIO_NR(4, 29); + gMX6SL_WIFI_RST = IMX_GPIO_NR(5, 0); + gMX6SL_WIFI_INT = IMX_GPIO_NR(4, 31); + + if(37==gptHWCFG->m_val.bPCB) { + // E60QBX. + gpio_request (GPIO_ESD_3V3_ON, "ESD_3V3_ON"); + gpio_direction_input (GPIO_ESD_3V3_ON); + gpio_free (GPIO_ESD_3V3_ON); + giISD_3V3_ON_Ctrl = -1; + } + else { + if(36==gptHWCFG->m_val.bPCB || 40==gptHWCFG->m_val.bPCB) { + // E60Q3X/E60Q5X + gMX6SL_CHG_LED = IMX_GPIO_NR(5, 7); + gMX6SL_IR_TOUCH_RST = IMX_GPIO_NR(5, 13); + gpio_request (MX6SL_KL25_INT2, "MX6SL_KL25_INT2"); + gpio_direction_input (MX6SL_KL25_INT2); + } + else { + if(0==gptHWCFG->m_val.bPMIC) { + //若有RICOH PMIC則ESD_3V3_ON都會交由PMIC控制. + gpio_request (GPIO_ESD_3V3_ON, "ESD_3V3_ON"); + gpio_direction_output (GPIO_ESD_3V3_ON, 1); + } + } + + if(0==gptHWCFG->m_val.bPMIC) { + gpio_request (GPIO_ISD_3V3_ON, "ISD_3V3_ON"); + if(33==gptHWCFG->m_val.bPCB) { + // E60Q2X . + giISD_3V3_ON_Ctrl = 0; + } + else { + giISD_3V3_ON_Ctrl = 1; + } + } + } + + + gpio_request (GPIO_IR_3V3_ON, "IR_3V3_ON"); + gpio_direction_output (GPIO_IR_3V3_ON, 1); + //gpio_request (GPIO_EP_3V3_ON, "EP_3V3_ON"); + //gpio_direction_output (GPIO_EP_3V3_ON, 1); + + if(2==gptHWCFG->m_val.bTouch2Ctrl) { + // Wacom Digitizer + gpio_request (MX6SL_WACOM_PDCT, "MX6SL_WACOM_PDCT"); + gpio_direction_input (MX6SL_WACOM_PDCT); + gpio_request (MX6SL_WACOM_FWE, "MX6SL_WACOM_FWE"); + gpio_direction_output (MX6SL_WACOM_FWE, 0); + gpio_request (MX6SL_WACOM_RST, "MX6SL_WACOM_RST"); + ntx_wacom_reset(0); + + if(42==gptHWCFG->m_val.bPCB) { + // Wacom GPIOs + gpio_request (MX6SL_WACOM_INT, "MX6SL_WACOM_INT"); + gpio_direction_input (MX6SL_WACOM_INT); + i2c_register_board_info(1,&i2c_wacom_binfo,1); + } + else { + gpio_request (MX6SL_WACOM_INT_4_1, "MX6SL_WACOM_INT"); + gpio_direction_input (MX6SL_WACOM_INT_4_1); + i2c_register_board_info(0,&i2c_wacom_binfo,1); + } + } + else if(3==gptHWCFG->m_val.bTouch2Ctrl) { + if(42==gptHWCFG->m_val.bPCB) { + gpio_request (MX6SL_WALTOP_INT_4_0, "MX6SL_WALTOP_INT_4_0"); + gpio_direction_input (MX6SL_WALTOP_INT_4_0); + gpio_request (MX6SL_WALTOP_RST_3_30, "MX6SL_WALTOP_RST_3_30"); + gpio_direction_output (MX6SL_WALTOP_RST_3_30, 1); + + i2c_waltop_binfo.platform_data = MX6SL_WALTOP_RST_3_30; + i2c_waltop_binfo.irq = gpio_to_irq(MX6SL_WALTOP_INT_4_0); + i2c_register_board_info(1,&i2c_waltop_binfo,1); + } else { + gpio_request (MX6SL_WALTOP_INT, "MX6SL_WALTOP_INT"); + gpio_direction_input (MX6SL_WALTOP_INT); + gpio_request (MX6SL_WALTOP_RST, "MX6SL_WALTOP_RST"); + gpio_direction_output (MX6SL_WALTOP_RST, 1); + i2c_register_board_info(0,&i2c_waltop_binfo,1); + } + } + } + + if(-1!=giISD_3V3_ON_Ctrl) { + gpio_direction_output (GPIO_ISD_3V3_ON, giISD_3V3_ON_Ctrl?1:0); + } + + i2c_zforce_ir_touch_binfo.platform_data = gMX6SL_IR_TOUCH_INT; + i2c_zforce_ir_touch_binfo.irq = gpio_to_irq(gMX6SL_IR_TOUCH_INT); + + i2c_elan_touch_binfo.platform_data = gMX6SL_IR_TOUCH_INT; + i2c_elan_touch_binfo.irq = gpio_to_irq(gMX6SL_IR_TOUCH_INT); + if(47==gptHWCFG->m_val.bPCB) { //ED0Q02 + i2c_elan_touch_binfo.addr = 0x10; + } + + i2c_sysmp_msp430_binfo.irq = gpio_to_irq(gMX6SL_MSP_INT); + i2c_sysmp_ricoh619_binfo.irq = gpio_to_irq(gMX6SL_MSP_INT); + + ntx_misc_info.acin_gpio = gMX6SL_NTX_ACIN_PG; + ntx_misc_info.chg_gpio = gMX6SL_NTX_CHG; + + if(37!=gptHWCFG->m_val.bPCB) { + gpio_request (MX6SL_HW_ID0, "MX6SL_HW_ID0"); + gpio_request (MX6SL_HW_ID1, "MX6SL_HW_ID1"); + gpio_request (MX6SL_HW_ID2, "MX6SL_HW_ID2"); + gpio_request (MX6SL_HW_ID3, "MX6SL_HW_ID3"); + gpio_request (MX6SL_HW_ID4, "MX6SL_HW_ID4"); + gpio_direction_input (MX6SL_HW_ID0); + gpio_direction_input (MX6SL_HW_ID1); + gpio_direction_input (MX6SL_HW_ID2); + gpio_direction_input (MX6SL_HW_ID3); + gpio_direction_input (MX6SL_HW_ID4); + } + + gpio_request (gMX6SL_ON_LED, "MX6SL_ON_LED"); + gpio_request (gMX6SL_ACT_LED, "MX6SL_ACT_LED"); + gpio_direction_input (gMX6SL_ACT_LED); + gpio_direction_output (gMX6SL_ON_LED, 0); + + if(36==gptHWCFG->m_val.bPCB || 40==gptHWCFG->m_val.bPCB) { + // E60Q3X/E60Q5X + gpio_request (gMX6SL_HOME_LED, "MX6SL_HOME_LED"); + } + else { + gpio_request (gMX6SL_CHG_LED, "MX6SL_CHG_LED"); + gpio_direction_input (gMX6SL_CHG_LED); + } + + gpio_request (gMX6SL_NTX_ACIN_PG, "MX6SL_NTX_ACIN_PG"); + gpio_direction_input (gMX6SL_NTX_ACIN_PG); + + gpio_request (gMX6SL_NTX_CHG, "MX6SL_NTX_CHG"); + gpio_direction_input (gMX6SL_NTX_CHG); + + gpio_request (gMX6SL_MSP_INT, "MX6SL_MSP_INT"); + gpio_direction_input (gMX6SL_MSP_INT); + //#ifndef CONFIG_ANDROID //[ + if(0==gptHWCFG->m_val.bUIStyle) { + gpio_request (gMX6SL_PWR_SW, "MX6SL_PWR_SW"); + gpio_direction_input (gMX6SL_PWR_SW); + } + //#endif //]CONFIG_ANDROID + + gpio_request (gMX6SL_IR_TOUCH_INT, "MX6SL_IR_TOUCH_INT"); + gpio_direction_input (gMX6SL_IR_TOUCH_INT); + + gpio_request (gMX6SL_IR_TOUCH_RST, "MX6SL_IR_TOUCH_RST"); + gpio_direction_output (gMX6SL_IR_TOUCH_RST, 0); + mdelay (10); + gpio_direction_input (gMX6SL_IR_TOUCH_RST); + if(0==gptHWCFG->m_val.bHallSensor) { + gpio_request (gMX6SL_HALL_EN, "MX6SL_HALL_EN"); + gpio_direction_input (gMX6SL_HALL_EN); + } + + gpio_request (gMX6SL_WIFI_RST, "MX6SL_WIFI_RST"); + gpio_request (gMX6SL_WIFI_3V3, "MX6SL_WIFI_3V3"); + gpio_request (gMX6SL_WIFI_INT, "MX6SL_WIFI_INT"); + gpio_direction_input (gMX6SL_WIFI_INT); + ntx_wifi_power_ctrl (0); + + gpio_request (MX6SL_FL_EN, "MX6SL_FL_EN"); + gpio_direction_input (MX6SL_FL_EN); + gpio_request (MX6SL_FL_R_EN, "MX6SL_FL_R_EN"); + gpio_direction_input (MX6SL_FL_R_EN); + +#if 0 //[ + gpio_request (MX6SL_EP_PWRALL, "MX6SL_EP_PWRALL" ); + gpio_request (MX6SL_EP_WAKEUP , "MX6SL_EP_WAKEUP" ); + gpio_request (MX6SL_EP_PWRUP , "MX6SL_EP_PWRUP" ); + gpio_request (MX6SL_EP_INT , "MX6SL_EP_INT" ); + gpio_request (MX6SL_EP_PWRSTAT , "MX6SL_EP_PWRSTAT" ); + gpio_request (MX6SL_EP_VCOM , "MX6SL_EP_VCOM" ); + gpio_direction_output (MX6SL_EP_PWRALL, 1); + gpio_direction_output (MX6SL_EP_WAKEUP, 0); + gpio_direction_output (MX6SL_EP_PWRUP, 0); + gpio_direction_output (MX6SL_EP_VCOM, 0); + gpio_direction_input (MX6SL_EP_INT); + gpio_direction_input (MX6SL_EP_PWRSTAT); +#endif //] + +} + +/*! + * Board specific initialization. + */ +static void __init mx6_ntx_init(void) +{ + u32 i; + int iMSP430_I2C_Chn; + struct esdhc_platform_data *pt_esdhc_ntx_isd_data; + + _parse_cmdline(); + + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_pads, + ARRAY_SIZE(mx6sl_brd_pads)); + + ntx_gpio_init (); + + gpiofn_init(); + +#ifdef CONFIG_MX6_INTER_LDO_BYPASS + gp_reg_id = mx6sl_ntx_dvfscore_data.reg_id; + soc_reg_id = mx6sl_ntx_dvfscore_data.soc_id; +#else + gp_reg_id = mx6sl_ntx_dvfscore_data.reg_id; + soc_reg_id = mx6sl_ntx_dvfscore_data.soc_id; + pu_reg_id = mx6sl_ntx_dvfscore_data.pu_id; + mx6_cpu_regulator_init(); +#endif + + if( (46==gptHWCFG->m_val.bPCB && gptHWCFG->m_val.bPCB_REV>=0x10) || + 48==gptHWCFG->m_val.bPCB) + { + // E60Q9X rev >=A10 ... + // E60QAX ... + // MSP430 @ I2C1 + iMSP430_I2C_Chn = 0;//I2C1 + } + else { + iMSP430_I2C_Chn = 2;//I2C3 in curcuit . + if(0==gptHWCFG->m_val.bPMIC) { + // 當MSP430取代為PMIC工作時,它非常忙錄,高速的頻率有可能會使它出錯。 + mx6_ntx_i2c2_data.bitrate = 100000; + } + } +// imx6q_add_imx_snvs_rtc(); + + + imx6q_add_imx_i2c(0, &mx6_ntx_i2c0_data); + imx6q_add_imx_i2c(1, &mx6_ntx_i2c1_data); + imx6q_add_imx_i2c(2, &mx6_ntx_i2c2_data); + + if (4==gptHWCFG->m_val.bTouchType) { + // IR touch type + if ( 31==gptHWCFG->m_val.bPCB||32==gptHWCFG->m_val.bPCB|| + 33==gptHWCFG->m_val.bPCB||36==gptHWCFG->m_val.bPCB|| + 40==gptHWCFG->m_val.bPCB|| + (46==gptHWCFG->m_val.bPCB&&gptHWCFG->m_val.bPCB_REV<0x10) ) + { + // E60Q2X/E60Q3X/E60Q1X/E60Q2X/E60Q5X/m_val.bTouchType) { + // C touch type . + i2c_register_board_info(0,&i2c_elan_touch_binfo,1); + } + else { + printk("TouchType %d do not support yet ! no touch driver will be loaded \n",(int) gptHWCFG->m_val.bTouchType); + } + + if(1==gptHWCFG->m_val.bPMIC){ + // RC5T619 . + if(!NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bPCB_Flags,4)) { + // Panel is designed for low voltage . + printk("ldo8_1v8 ouput 3v3\n"); + pdata_ldo8_0.regulator.constraints.min_uV = 3300*1000; + pdata_ldo8_0.regulator.constraints.max_uV = 3300*1000; + //pdata_ldo8_0.regulator.constraints.always_on = 1; + //pdata_ldo8_0.regulator.constraints.boot_on = 1; + pdata_ldo8_0.init_uV = 3300*1000; + //pdata_ldo8_0.init_enable = 1; + pdata_ldo8_0.sleep_uV = 3300*1000; + } + + // PCB is designed for low voltage . + ntx_ricoh_data.irq_base = irq_alloc_descs (-1, 0, RICOH61x_NR_IRQS, "RICOH61x"); + if (0 < ntx_ricoh_data.irq_base) { + ricoh_battery_data.irq = ntx_ricoh_data.irq_base; + ricoh_rtc_data.irq = ntx_ricoh_data.irq_base; + printk ("[%s-%d] irq_alloc_descs return %d for %d RICOH61x\n",__func__, __LINE__, ntx_ricoh_data.irq_base, RICOH61x_NR_IRQS); + } + else { + printk ("[%s-%d] RICOH61x irq_alloc_descs failed with %d\n",__func__, __LINE__, ntx_ricoh_data.irq_base, RICOH61x_NR_IRQS); + } + i2c_register_board_info(2,&i2c_sysmp_ricoh619_binfo,1); + // platform_device_register(&ricoh_device_rtc); + pm_power_off = ricoh619_power_off; + } + + + if(38!=gptHWCFG->m_val.bPCB&&37!=gptHWCFG->m_val.bPCB) + { + i2c_register_board_info(iMSP430_I2C_Chn,&i2c_sysmp_msp430_binfo,1); + } + + if(0==gptHWCFG->m_val.bRTC) { + // RTC use MSP430 + platform_device_register(&ntx_device_rtc); + } + + if(1==gptHWCFG->m_val.bFL_PWM){ + // Front light PWM source is ht68f20 + i2c_register_board_info(0,&i2c_ht68f20_binfo,1); + } + + if(3==gptHWCFG->m_val.bRSensor) { + // g-sensor with microP KL25 + i2c_register_board_info(0,&i2c_kl25_binfo,1); + } + + + if(4==gptHWCFG->m_val.bRSensor) { + // g-sensor : MMA8652 + //if(36!=gptHWCFG->m_val.bPCB) + { + /* 20140220 temporarily remove MMA8652 from E60Q32 to save power + since not currently used but installed (MMA8652 default mode: Standby) */ + i2c_register_board_info(0,&i2c_mma8652_binfo,1); + } + } + + //i2c_register_board_info(0, mxc_i2c0_board_info, + // ARRAY_SIZE(mxc_i2c0_board_info)); + //i2c_register_board_info(1, mxc_i2c1_board_info, + // ARRAY_SIZE(mxc_i2c1_board_info)); + //i2c_register_board_info(2, mxc_i2c2_board_info, + // ARRAY_SIZE(mxc_i2c2_board_info)); + + /* only camera on I2C2, that's why we can do so */ +// if (csi_enabled == 1) { +// mxc_register_device(&csi_v4l2_devices, NULL); +// imx6q_add_imx_i2c(2, &mx6_ntx_i2c2_data); +// } +// imx6q_add_imx_snvs_rtc(); + + /* SPI */ +// imx6q_add_ecspi(0, &mx6_ntx_spi_data); +// spi_device_init(); + +// mx6sl_ntx_init_pfuze100(0); + imx6q_add_anatop_thermal_imx(1, &mx6sl_anatop_thermal_data); + imx6q_add_pm_imx(0, &mx6sl_ntx_pm_data); + + mx6_ntx_init_uart(); + /* get enet tx reference clk from FEC_REF_CLK pad. + * GPR1[14] = 0, GPR1[18:17] = 00 + */ +// mxc_iomux_set_gpr_register(1, 14, 1, 0); +// mxc_iomux_set_gpr_register(1, 17, 2, 0); + +// imx6_init_fec(fec_data); + + //platform_device_register(&ntx_vmmc_reg_devices); + + if(2==gptHWCFG->m_val.bIFlash) { + // eMMC . + pt_esdhc_ntx_isd_data = &mx6_ntx_isd8bits_data; + } + else { + pt_esdhc_ntx_isd_data = &mx6_ntx_isd_data; + } + + switch(gptHWCFG->m_val.bPCB) { + case 31: //E60Q0X . + case 32: //E60Q1X . + // SD1 = ISD + // SD2 = ESD + // SD3 = SDIO WIFI + // SD4 = GPIO + imx6q_add_sdhci_usdhc_imx(giBootPort, pt_esdhc_ntx_isd_data); + imx6q_add_sdhci_usdhc_imx(2, &mx6_ntx_esd_data); // mmcblk1 + imx6q_add_sdhci_usdhc_imx(1, &mx6_ntx_sd_wifi_data); + break; + + default: + // \C5\FD\B7s\AA\BA\B3]\ADp\BA\FB\AB\F9\A6b\B3o\ADӰ϶\F4\A1A\A5H\BAɥi\AF\E0\B9F\A8줣\ADק\EFCODE\B4N\AF\E0\A5Ψ\EC\B7s\BE\F7\BAؤW\A1C + // SD1 = GPIO + // SD2 = ESD + // SD3 = SDIO WIFI + // SD4 = EMMC + if(1==giBootPort) { + // ESD is boot device . + printk("add usdhc %d as mmcblk0\n",giBootPort+1); + if(46==gptHWCFG->m_val.bPCB|| + 48==gptHWCFG->m_val.bPCB) + { + // + imx6q_add_sdhci_usdhc_imx(giBootPort, &mx6_ntx_esd_nocd_data); + } + else { + imx6q_add_sdhci_usdhc_imx(giBootPort, &mx6_ntx_esd_data); + } + printk("add usdhc 4 as mmcblk1\n"); + imx6q_add_sdhci_usdhc_imx(3, pt_esdhc_ntx_isd_data); // mmcblk1 + printk("add usdhc 3 as sdio for wifi\n"); + imx6q_add_sdhci_usdhc_imx(2, &mx6_ntx_q22_sd_wifi_data); + } + else { + // EMMC is boot device . + imx6q_add_sdhci_usdhc_imx(giBootPort, pt_esdhc_ntx_isd_data); + imx6q_add_sdhci_usdhc_imx(1, &mx6_ntx_esd_data); // mmcblk1 + imx6q_add_sdhci_usdhc_imx(2, &mx6_ntx_q22_sd_wifi_data); + } + break; + } + + mx6_ntx_init_usb(); + imx6q_add_otp(); +// imx6q_add_mxc_pwm(0); +// imx6q_add_mxc_pwm_backlight(0, &mx6_ntx_pwm_backlight_data); + + +// gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on"); +// gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1); + //mxc_register_device(&lcd_wvga_device, NULL); + + imx6dl_add_imx_pxp(); + imx6dl_add_imx_pxp_client(); + + imx6dl_add_imx_epdc(&epdc_data); +#ifdef CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF //[ + imx6dl_add_imx_elcdif(&wvga_fb_data[0]); +#endif //]CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF + //imx6q_add_dvfs_core(&mx6sl_ntx_dvfscore_data); + + imx6q_add_viim(); + imx6q_add_imx2_wdt(0, NULL); + + +#ifdef CONFIG_MXC_GPU_VIV//[ + if(2==gptHWCFG->m_val.bUIStyle) + { + // only android models needs GPU . + imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata); + } +#endif//] CONFIG_MXC_GPU_VIV + + //imx6sl_add_device_buttons(); + if(!NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bPCB_Flags,0)) { + // key matrix : ON + + //mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_kb_pads,ARRAY_SIZE(mx6sl_brd_ntx_kb_pads)); + //mdelay(1); + + imx6sl_add_imx_keypad(&mx6sl_ntx_map_data); + } + //else + { + // gpio keys + mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_kb_gpio_pads, + ARRAY_SIZE(mx6sl_brd_ntx_kb_gpio_pads)); + udelay(1); + + switch(gptHWCFG->m_val.bPCB) { + case 32://E60Q1X + case 31://E60Q0X + // use gpio instead of keymatrix ... + gpio_request (GPIO_KB_COL0, "KB_COL0"); + gpio_direction_output (GPIO_KB_COL0, 0); + gpio_request (GPIO_KB_COL1, "KB_COL1"); + gpio_direction_output (GPIO_KB_COL1, 0); + + ntx_gpio_key_data.buttons = gpio_key_matrix_FL; + ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_matrix_FL); + break; + case 33://E60Q2X + ntx_gpio_key_data.buttons = gpio_key_HOME; + ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME); + break; + /*case 36://E60Q3X + ntx_gpio_key_data.buttons = gpio_key_HOME_FL; + ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME_FL); + break;*/ + default: + switch(gptHWCFG->m_val.bKeyPad) { //key pad define through bKeyPad in hwconfig + case 12: // NO_Key + ntx_gpio_key_data.buttons = gpio_key_None; + ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_None); + break; + case 11: // FL_Key + ntx_gpio_key_data.buttons = gpio_key_FL; + ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_FL); + break; + case 16: // FL+HOME PAD + case 13: // FL+HOME KEY + ntx_gpio_key_data.buttons = gpio_key_HOME_FL; + ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME_FL); + break; + case 14: // HOME + case 18: // HOMEPAD + ntx_gpio_key_data.buttons = gpio_key_HOME; + ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME); + break; + case 17: // RETURN+HOME+MENU + ntx_gpio_key_data.buttons = gpio_key_RETURN_HOME_MENU; + ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_RETURN_HOME_MENU); + break; + default: // FL+HOME + ntx_gpio_key_data.buttons = gpio_key_HOME_FL; + ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME_FL); + break; + } + break; + } + + for(i=0;im_val.bPCB || 40==gptHWCFG->m_val.bPCB || + 0!=gptHWCFG->m_val.bHOME_LED_PWM) + { + // E60Q32/E60Q5X/ + /* + * prepare hook functions of keys . + */ + gptGPIO_HOME_KEY = &ntx_gpio_key_data.buttons[i]; + + if( 36==gptHWCFG->m_val.bPCB || 2==gptHWCFG->m_val.bHOME_LED_PWM ) + { + // E60Q3X or HOME LED is GPIO controlled by SOC . + mxc_iomux_v3_setup_pad(MX6SL_PAD_SD1_DAT7__GPIO_5_10_OUPUT); + INIT_DELAYED_WORK(&homeled_pwrdwn_work,_homeled_work_func); + INIT_DELAYED_WORK(&homepad_check_work,_homepad_work_func); + } + + ntx_gpio_key_data.buttons[i].hook = ntx_touch_home_key_hook; + ntx_gpio_key_data.buttons[i].debounce_interval = 50; + + } + + +#endif //]TOUCH_HOME_LED + + if(2==gptHWCFG->m_val.bUIStyle) { + ntx_gpio_key_data.buttons[i].code = KEY_HOME; + } + } + else { + if(0==gptHWCFG->m_val.bUIStyle) { + if(0==strcmp(ntx_gpio_key_data.buttons[i].desc,"btn power")) { + printk("%s(),Ebrmain remote power key in gpio keys \n",__FUNCTION__); + ntx_gpio_key_data.nbuttons-=1; + } + } + } + } + + if( 1==gptHWCFG->m_val.bHOME_LED_PWM ) { + // HOME LED is controled by MSP430 . + if(MSP430_HOMELED_TYPE_PWM==msp430_homeled_type_get(0)) { + giHomeLED_Delay_Ticks = 200; + } + else { + giHomeLED_Delay_Ticks = 100; + } + } + + + platform_device_register(&ntx_gpio_key_device); + } + + imx6q_add_busfreq(); + imx6sl_add_dcp(); + imx6sl_add_rngb(); + imx6sl_add_imx_pxp_v4l2(); + + imx6q_add_perfmon(0); + imx6q_add_perfmon(1); + imx6q_add_perfmon(2); + mxc_register_device(&mxcbl_device, NULL); + + + platform_device_register(&ntx_light_ldm); +#ifndef CONFIG_ANDROID //[ + mxc_register_device(&mxc_usb_plug_device, &usbplug_data); +#endif//]CONFIG_ANDROID + if (1==gptHWCFG->m_val.bPMIC) { + // RC5T619 . + } + else { + /* Register charger chips */ + platform_device_register(&ntx_charger); + + } + + if(gptHWCFG) { + + if(1==gptHWCFG->m_val.bHallSensor) { + // hall sensor enabled . + tle4913_init(); + } + + + } + else { + printk(KERN_ERR "missing ntx hwconfig !!\n"); + } + +} + +extern void __iomem *twd_base; +static void __init mx6_timer_init(void) +{ + struct clk *uart_clk; +#ifdef CONFIG_LOCAL_TIMERS + twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256); + BUG_ON(!twd_base); +#endif + mx6sl_clocks_init(32768, 24000000, 0, 0); + + uart_clk = clk_get_sys("imx-uart.0", NULL); + early_console_setup(UART1_BASE_ADDR, uart_clk); +} + +static struct sys_timer mxc_timer = { + .init = mx6_timer_init, +}; + +static void __init mx6_ntx_reserve(void) +{ +#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE) + phys_addr_t phys; + + if (imx6q_gpu_pdata.reserved_mem_size) { + phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size, + SZ_4K, MEMBLOCK_ALLOC_ACCESSIBLE); + memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size); + imx6q_gpu_pdata.reserved_mem_base = phys; + } +#endif +} + +static int __init display_panel_setup(char *options) +{ + if (!options || !*options) { + pr_err("Error panel options\n"); + return 0; + } + + if (!strcmp(options, "lcd")) + display_panel_mode = PANEL_MODE_LCD; + else if (!strcmp(options, "hdmi")) + display_panel_mode = PANEL_MODE_HDMI; + else if (!strcmp(options, "eink")) + display_panel_mode = PANEL_MODE_EINK; + else + pr_warn("WARN: invalid display panel mode setting"); + + return 1; +} + +__setup("panel=", display_panel_setup); + +MACHINE_START(MX6SL_NTX, "Freescale i.MX 6SoloLite NTX Board") + .boot_params = MX6SL_PHYS_OFFSET + 0x100, + .map_io = mx6_map_io, + .init_irq = mx6_init_irq, + .init_machine = mx6_ntx_init, + .timer = &mxc_timer, + .reserve = mx6_ntx_reserve, +MACHINE_END -- cgit v1.2.3