Hi Weidong,
Here is my mx53_loco.c code, and have had little modified by me. Because MC34708 not supply power for USB. My Bsp only has mx53_loco_pmic_mc34708.c. I paste it in the lastest part.
mx53_loco.c:
/*
* Copyright (C) 2010-2011 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 <linux/types.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/nodemask.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
#include <linux/spi/spi.h>
#include <linux/i2c.h>
#include <linux/ata.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/regulator/consumer.h>
#include <linux/pmic_external.h>
#include <linux/pmic_status.h>
#include <linux/ipu.h>
#include <linux/mxcfb.h>
#include <linux/pwm_backlight.h>
#include <linux/fec.h>
#include <linux/powerkey.h>
#include <linux/ahci_platform.h>
#include <linux/gpio_keys.h>
#include <linux/mfd/da9052/da9052.h>
#include <mach/common.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/mach/keypad.h>
#include <asm/mach/flash.h>
#include <mach/memory.h>
#include <mach/gpio.h>
#include <mach/mmc.h>
#include <mach/mxc_dvfs.h>
#include <mach/iomux-mx53.h>
#include <mach/i2c.h>
#include <mach/mxc_iim.h>
#include <mach/check_fuse.h>
#include "crm_regs.h"
#include "devices.h"
#include "usb.h"
#include "pmic.h"
#include "mx53_loco.h"
/*!
* @file mach-mx5/mx53_loco.c
*
* @brief This file contains MX53 loco board specific initialization routines.
*
* @ingroup MSL_MX53
*/
/* MX53 LOCO GPIO PIN configurations */
#define NVDD_FAULT (0*32 + 5) /* GPIO1_5 */
#define FEC_INT (1*32 + 4) /* GPIO_2_4 */
#define HEADPHONE_DEC_B (1*32 + 5) /* GPIO_2_5 */
#define MIC_DEC_B (1*32 + 6) /* GPIO_2_6 */
#define USER_UI1 (1*32 + 14) /* GPIO_2_14 */
#define USER_UI2 (1*32 + 15) /* GPIO_2_15 */
#define MX53_nONKEY (0*32 + 8) /* GPIO_1_8 */
#define SD3_CD (2*32 + 11) /* GPIO_3_11 */
#define SD3_WP (2*32 + 12) /* GPIO_3_12 */
#define DISP0_POWER_EN (2*32 + 24) /* GPIO_3_24 */
#define DISP0_DET_INT (2*32 + 31) /* GPIO_3_31 */
#define DISP0_RESET (4*32 + 0) /* GPIO_5_0 */
#define CSI0_RTSB (5*32 + 9) /* GPIO_6_9 */
#define CSI0_PWDN (5*32 + 10) /* GPIO_6_10 */
#define ACCL_EN (5*32 + 14) /* GPIO_6_14 */
#define ACCL_INT1_IN (5*32 + 15) /* GPIO_6_15 */
#define ACCL_INT2_IN (5*32 + 16) /* GPIO_6_16 */
#define LCD_BLT_EN (6*32 + 2) /* GPIO_7_2 */
#define FEC_RST (6*32 + 6) /* GPIO_7_6 */
#define USER_LED_EN (6*32 + 7) /* GPIO_7_7 */
#define USB_PWREN (6*32 + 8) /* GPIO_7_8 */
#define NIRQ (6*32 + 11) /* GPIO7_11 */
#define MX53_LOCO_MC34708_IRQ_REVA (4*32 + 30) /* GPIO5_30 */
#define MX53_LOCO_MC34708_IRQ_REVB (4*32 + 23) /* GPIO5_23 */
#define MX53_OFFSET (0x20000000)
#define TZIC_WAKEUP0_OFFSET (0x0E00)
#define TZIC_WAKEUP1_OFFSET (0x0E04)
#define TZIC_WAKEUP2_OFFSET (0x0E08)
#define TZIC_WAKEUP3_OFFSET (0x0E0C)
#define GPIO7_0_11_IRQ_BIT (0x1<<11)
extern void pm_i2c_init(u32 base_addr);
static u32 mx53_loco_mc34708_irq;
static iomux_v3_cfg_t mx53_loco_pads[] = {
/* FEC */
MX53_PAD_FEC_MDC__FEC_MDC,
MX53_PAD_FEC_MDIO__FEC_MDIO,
MX53_PAD_FEC_REF_CLK__FEC_TX_CLK,
MX53_PAD_FEC_RX_ER__FEC_RX_ER,
MX53_PAD_FEC_CRS_DV__FEC_RX_DV,
MX53_PAD_FEC_RXD1__FEC_RDATA_1,
MX53_PAD_FEC_RXD0__FEC_RDATA_0,
MX53_PAD_FEC_TX_EN__FEC_TX_EN,
MX53_PAD_FEC_TXD1__FEC_TDATA_1,
MX53_PAD_FEC_TXD0__FEC_TDATA_0,
/* FEC_nRST */
MX53_PAD_PATA_DA_0__GPIO7_6,
/* FEC_nINT */
MX53_PAD_PATA_DATA4__GPIO2_4,
/* AUDMUX5 */
MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC,
MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD,
MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS,
MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD,
/* I2C2 */
MX53_PAD_KEY_COL3__I2C2_SCL,
MX53_PAD_KEY_ROW3__I2C2_SDA,
/* I2C3 */
MX53_PAD_GPIO_3__I2C3_SCL,
MX53_PAD_GPIO_6__I2C3_SDA,
/* SD1 */
MX53_PAD_SD1_CMD__ESDHC1_CMD,
MX53_PAD_SD1_CLK__ESDHC1_CLK,
MX53_PAD_SD1_DATA0__ESDHC1_DAT0,
MX53_PAD_SD1_DATA1__ESDHC1_DAT1,
MX53_PAD_SD1_DATA2__ESDHC1_DAT2,
MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
/* SD3 */
MX53_PAD_PATA_DATA8__ESDHC3_DAT0,
MX53_PAD_PATA_DATA9__ESDHC3_DAT1,
MX53_PAD_PATA_DATA10__ESDHC3_DAT2,
MX53_PAD_PATA_DATA11__ESDHC3_DAT3,
MX53_PAD_PATA_DATA0__ESDHC3_DAT4,
MX53_PAD_PATA_DATA1__ESDHC3_DAT5,
MX53_PAD_PATA_DATA2__ESDHC3_DAT6,
MX53_PAD_PATA_DATA3__ESDHC3_DAT7,
MX53_PAD_PATA_IORDY__ESDHC3_CLK,
MX53_PAD_PATA_RESET_B__ESDHC3_CMD,
/* SD3_CD */
MX53_PAD_EIM_DA11__GPIO3_11,
/* SD3_WP */
MX53_PAD_EIM_DA12__GPIO3_12,
/* VGA */
MX53_PAD_EIM_OE__IPU_DI1_PIN7,
MX53_PAD_EIM_RW__IPU_DI1_PIN8,
/* DISPLB */
MX53_PAD_EIM_D20__IPU_SER_DISP0_CS,
MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK,
MX53_PAD_EIM_D22__IPU_DISPB0_SER_DIN,
MX53_PAD_EIM_D23__IPU_DI0_D0_CS,
/* DISP0_POWER_EN */
MX53_PAD_EIM_D24__GPIO3_24,
/* DISP0 DET INT */
MX53_PAD_EIM_D31__GPIO3_31,
/* LVDS */
MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3,
MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK,
MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2,
MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1,
MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0,
MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3,
MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2,
MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK,
MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1,
MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0,
/* I2C1 */
MX53_PAD_CSI0_DAT8__I2C1_SDA,
MX53_PAD_CSI0_DAT9__I2C1_SCL,
/* UART1 */
MX53_PAD_CSI0_DAT10__UART1_TXD_MUX,
MX53_PAD_CSI0_DAT11__UART1_RXD_MUX,
/* CSI0 */
MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13,
MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14,
MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15,
MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16,
MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17,
MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18,
MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19,
MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC,
MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC,
MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK,
/* DISPLAY */
MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK,
MX53_PAD_DI0_PIN15__IPU_DI0_PIN15,
MX53_PAD_DI0_PIN2__IPU_DI0_PIN2,
MX53_PAD_DI0_PIN3__IPU_DI0_PIN3,
MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0,
MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1,
MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2,
MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3,
MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4,
MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5,
MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6,
MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7,
MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8,
MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9,
MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10,
MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11,
MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12,
MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13,
MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14,
MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15,
MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16,
MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17,
MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18,
MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19,
MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20,
MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21,
MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22,
MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23,
/* Audio CLK*/
MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK,
/* PWM */
MX53_PAD_GPIO_1__PWM2_PWMO,
/* SPDIF */
MX53_PAD_GPIO_7__SPDIF_PLOCK,
MX53_PAD_GPIO_17__SPDIF_OUT1,
/* GPIO */
MX53_PAD_PATA_DA_1__GPIO7_7,
MX53_PAD_PATA_DA_2__GPIO7_8,
MX53_PAD_PATA_DATA5__GPIO2_5,
MX53_PAD_PATA_DATA6__GPIO2_6,
MX53_PAD_PATA_DATA14__GPIO2_14,
MX53_PAD_PATA_DATA15__GPIO2_15,
MX53_PAD_PATA_INTRQ__GPIO7_2,
MX53_PAD_EIM_WAIT__GPIO5_0,
MX53_PAD_NANDF_WP_B__GPIO6_9,
MX53_PAD_NANDF_RB0__GPIO6_10,
MX53_PAD_NANDF_CS1__GPIO6_14,
MX53_PAD_NANDF_CS2__GPIO6_15,
MX53_PAD_NANDF_CS3__GPIO6_16,
MX53_PAD_GPIO_5__GPIO1_5,
MX53_PAD_GPIO_16__GPIO7_11,
MX53_PAD_GPIO_8__GPIO1_8,
};
static void loco_da9053_irq_wakeup_only_fixup(void)
{
void __iomem *tzic_base;
tzic_base = ioremap(MX53_TZIC_BASE_ADDR, SZ_4K);
if (NULL == tzic_base) {
pr_err("fail to map MX53_TZIC_BASE_ADDR\n");
return;
}
__raw_writel(0, tzic_base + TZIC_WAKEUP0_OFFSET);
__raw_writel(0, tzic_base + TZIC_WAKEUP1_OFFSET);
__raw_writel(0, tzic_base + TZIC_WAKEUP2_OFFSET);
/* only enable irq wakeup for da9053 */
__raw_writel(GPIO7_0_11_IRQ_BIT, tzic_base + TZIC_WAKEUP3_OFFSET);
iounmap(tzic_base);
pr_info("only da9053 irq is wakeup-enabled\n");
}
static void loco_suspend_enter(void)
{
if (!board_is_mx53_loco_mc34708()) {
loco_da9053_irq_wakeup_only_fixup();
da9053_suspend_cmd_sw();
}
}
static void loco_suspend_exit(void)
{
if (!board_is_mx53_loco_mc34708()) {
if (da9053_get_chip_version())
da9053_restore_volt_settings();
}
}
static struct mxc_pm_platform_data loco_pm_data = {
.suspend_enter = loco_suspend_enter,
.suspend_exit = loco_suspend_exit,
};
static struct fb_videomode video_modes[] = {
{
/* 800x480 @ 57 Hz , pixel clk @ 27MHz */
"CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10,
FB_SYNC_CLK_LAT_FALL,
FB_VMODE_NONINTERLACED,
0,},
{
/* 800x480 @ 60 Hz , pixel clk @ 32MHz */
"SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
FB_SYNC_CLK_LAT_FALL,
FB_VMODE_NONINTERLACED,
0,},
{
/* 1600x1200 @ 60 Hz 162M pixel clk*/
"UXGA", 60, 1600, 1200, 6172,
304, 64,
1, 46,
192, 3,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
FB_VMODE_NONINTERLACED,
0,},
};
static struct platform_pwm_backlight_data mxc_pwm_backlight_data = {
.pwm_id = 1,
.max_brightness = 255,
.dft_brightness = 128,
.pwm_period_ns = 50000,
};
extern void mx5_ipu_reset(void);
static struct mxc_ipu_config mxc_ipu_data = {
.rev = 3,
.reset = mx5_ipu_reset,
};
extern void mx5_vpu_reset(void);
static struct mxc_vpu_platform_data mxc_vpu_data = {
.iram_enable = true,
.iram_size = 0x14000,
.reset = mx5_vpu_reset,
};
static struct fec_platform_data fec_data = {
.phy = PHY_INTERFACE_MODE_RMII,
};
static struct mxc_dvfs_platform_data dvfs_core_data = {
.clk1_id = "cpu_clk",
.clk2_id = "gpc_dvfs_clk",
.gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
.gpc_vcr_offset = MXC_GPC_VCR_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 = 30,
};
static struct mxc_bus_freq_platform_data bus_freq_data;
static struct tve_platform_data tve_data = {
.boot_enable = MXC_TVE_VGA,
};
static struct ldb_platform_data ldb_data = {
.ext_ref = 1,
};
static void mxc_iim_enable_fuse(void)
{
u32 reg;
if (!ccm_base)
return;
/* enable fuse blown */
reg = readl(ccm_base + 0x64);
reg |= 0x10;
writel(reg, ccm_base + 0x64);
}
static void mxc_iim_disable_fuse(void)
{
u32 reg;
if (!ccm_base)
return;
/* enable fuse blown */
reg = readl(ccm_base + 0x64);
reg &= ~0x10;
writel(reg, ccm_base + 0x64);
}
static struct mxc_iim_data iim_data = {
.bank_start = MXC_IIM_MX53_BANK_START_ADDR,
.bank_end = MXC_IIM_MX53_BANK_END_ADDR,
.enable_fuse = mxc_iim_enable_fuse,
.disable_fuse = mxc_iim_disable_fuse,
};
static struct resource mxcfb_resources[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
};
static struct mxc_fb_platform_data fb_data[] = {
{
.interface_pix_fmt = IPU_PIX_FMT_RGB565,
.mode_str = "CLAA-WVGA",
.mode = video_modes,
.num_modes = ARRAY_SIZE(video_modes),
},
{
.interface_pix_fmt = IPU_PIX_FMT_GBR24,
.mode_str = "VGA-XGA",
.mode = video_modes,
.num_modes = ARRAY_SIZE(video_modes),
},
};
extern int primary_di;
static int __init mxc_init_fb(void)
{
if (!machine_is_mx53_loco())
return 0;
/*for loco board, set default display as VGA*/
if (primary_di < 0)
primary_di = 1;
if (primary_di) {
printk(KERN_INFO "DI1 is primary\n");
/* DI1 -> DP-BG channel: */
mxc_fb_devices[1].num_resources = ARRAY_SIZE(mxcfb_resources);
mxc_fb_devices[1].resource = mxcfb_resources;
mxc_register_device(&mxc_fb_devices[1], &fb_data[1]);
/* DI0 -> DC channel: */
mxc_register_device(&mxc_fb_devices[0], &fb_data[0]);
} else {
printk(KERN_INFO "DI0 is primary\n");
/* DI0 -> DP-BG channel: */
mxc_fb_devices[0].num_resources = ARRAY_SIZE(mxcfb_resources);
mxc_fb_devices[0].resource = mxcfb_resources;
mxc_register_device(&mxc_fb_devices[0], &fb_data[0]);
/* DI1 -> DC channel: */
mxc_register_device(&mxc_fb_devices[1], &fb_data[1]);
}
/*
* DI0/1 DP-FG channel:
*/
mxc_register_device(&mxc_fb_devices[2], NULL);
return 0;
}
device_initcall(mxc_init_fb);
static void sii902x_hdmi_reset(void)
{
gpio_set_value(DISP0_RESET, 0);
msleep(10);
gpio_set_value(DISP0_RESET, 1);
msleep(10);
}
static int sii902x_get_pins(void)
{
/* Sii902x HDMI controller */
gpio_request(DISP0_RESET, "disp0-reset");
gpio_direction_output(DISP0_RESET, 0);
gpio_request(DISP0_DET_INT, "disp0-detect");
gpio_direction_input(DISP0_DET_INT);
return 1;
}
static void sii902x_put_pins(void)
{
gpio_free(DISP0_RESET);
gpio_free(DISP0_DET_INT);
}
static struct mxc_lcd_platform_data sii902x_hdmi_data = {
.reset = sii902x_hdmi_reset,
.fb_id = "DISP3 BG",
.get_pins = sii902x_get_pins,
.put_pins = sii902x_put_pins,
};
static struct imxi2c_platform_data mxci2c_data = {
.bitrate = 100000,
};
static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
{
.type = "mma8450",
.addr = 0x1C,
},
};
static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
{
.type = "sgtl5000-i2c",
.addr = 0x0a,
},
{
.type = "sii902x",
.addr = 0x39,
.irq = gpio_to_irq(DISP0_DET_INT),
.platform_data = &sii902x_hdmi_data,
},
};
static int p1003_ts_hw_status(void)
{
return gpio_get_value(DISP0_DET_INT);
}
static struct p1003_ts_platform_data p1003_ts_data = {
.hw_status = p1003_ts_hw_status,
};
static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
{
.type = "p1003_fwv33",
.addr = 0x41,
.irq = gpio_to_irq(DISP0_DET_INT),
.platform_data = &p1003_ts_data,
},
{
.type = "egalax_ts",
.addr = 0x4,
.irq = gpio_to_irq(DISP0_DET_INT),
},
};
static int sdhc_write_protect(struct device *dev)
{
int ret = 0;
if (to_platform_device(dev)->id == 2)
ret = gpio_get_value(SD3_WP);
return ret;
}
static unsigned int sdhc_get_card_det_status(struct device *dev)
{
int ret = 0;
if (to_platform_device(dev)->id == 2)
ret = gpio_get_value(SD3_CD);
return ret;
}
static struct mxc_mmc_platform_data mmc1_data = {
.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30
| MMC_VDD_31_32,
.caps = MMC_CAP_4_BIT_DATA,
.min_clk = 400000,
.max_clk = 50000000,
.card_inserted_state = 1,
.clock_mmc = "esdhc_clk",
.power_mmc = NULL,
};
static struct mxc_mmc_platform_data mmc3_data = {
.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30
| MMC_VDD_31_32,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA
| MMC_CAP_DATA_DDR,
.min_clk = 400000,
.max_clk = 50000000,
.card_inserted_state = 0,
.status = sdhc_get_card_det_status,
.wp_status = sdhc_write_protect,
.clock_mmc = "esdhc_clk",
};
static int headphone_det_status(void)
{
return (gpio_get_value(HEADPHONE_DEC_B) == 0);
}
static int mxc_sgtl5000_init(void);
static struct mxc_audio_platform_data sgtl5000_data = {
.ssi_num = 1,
.src_port = 2,
.ext_port = 5,
.hp_irq = gpio_to_irq(HEADPHONE_DEC_B),
.hp_status = headphone_det_status,
.init = mxc_sgtl5000_init,
.ext_ram_rx = 1,
};
static int mxc_sgtl5000_init(void)
{
struct clk *ssi_ext1;
int rate;
ssi_ext1 = clk_get(NULL, "ssi_ext1_clk");
if (IS_ERR(ssi_ext1))
return -1;
rate = clk_round_rate(ssi_ext1, 24000000);
if (rate < 8000000 || rate > 27000000) {
printk(KERN_ERR "Error: SGTL5000 mclk freq %d out of range!\n",
rate);
clk_put(ssi_ext1);
return -1;
}
clk_set_rate(ssi_ext1, rate);
clk_enable(ssi_ext1);
sgtl5000_data.sysclk = rate;
return 0;
}
static struct platform_device mxc_sgtl5000_device = {
.name = "imx-3stack-sgtl5000",
};
static struct mxc_asrc_platform_data mxc_asrc_data = {
.channel_bits = 4,
.clk_map_ver = 2,
};
static struct mxc_spdif_platform_data mxc_spdif_data = {
.spdif_tx = 1,
.spdif_rx = 0,
.spdif_clk_44100 = -1, /* Souce from CKIH1 for 44.1K */
/* Source from CCM spdif_clk (24M) for 48k and 32k
* It's not accurate
*/
.spdif_clk_48000 = 1,
.spdif_clkid = 0,
.spdif_clk = NULL, /* spdif bus clk */
};
static struct mxc_audio_platform_data spdif_audio_data = {
.ext_ram_tx = 1,
};
static struct platform_device mxc_spdif_audio_device = {
.name = "imx-spdif-audio-device",
};
static void mx53_loco_usbh1_vbus(bool on)
{
if (on)
gpio_set_value(USB_PWREN, 1);
else
gpio_set_value(USB_PWREN, 0);
}
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake) \
{ \
.gpio = gpio_num, \
.type = EV_KEY, \
.code = ev_code, \
.active_low = act_low, \
.desc = "btn " descr, \
.wakeup = wake, \
}
static struct gpio_keys_button loco_buttons[] = {
GPIO_BUTTON(MX53_nONKEY, KEY_POWER, 1, "power", 0),
GPIO_BUTTON(USER_UI1, KEY_VOLUMEUP, 1, "volume-up", 0),
GPIO_BUTTON(USER_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0),
};
static struct gpio_keys_platform_data loco_button_data = {
.buttons = loco_buttons,
.nbuttons = ARRAY_SIZE(loco_buttons),
};
static struct platform_device loco_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
.dev = {
.platform_data = &loco_button_data,
}
};
static void __init loco_add_device_buttons(void)
{
platform_device_register(&loco_button_device);
}
#else
static void __init loco_add_device_buttons(void) {}
#endif
static void mxc_register_powerkey(pwrkey_callback pk_cb)
{
pmic_event_callback_t power_key_event;
power_key_event.param = (void *)1;
power_key_event.func = (void *)pk_cb;
pmic_event_subscribe(EVENT_PWRONI, power_key_event);
}
static int mxc_pwrkey_getstatus(int id)
{
int sense;
pmic_read_reg(REG_INT_SENSE1, &sense, 0xffffffff);
if (sense & (1 << 3))
return 0;
return 1;
}
static struct power_key_platform_data pwrkey_data = {
.key_value = KEY_F4,
.register_pwrkey = mxc_register_powerkey,
.get_key_status = mxc_pwrkey_getstatus,
};
/*!
* Board specific fixup function. It is called by \b setup_arch() in
* setup.c file very early on during kernel starts. It allows the user to
* statically fill in the proper values for the passed-in parameters. None of
* the parameters is used currently.
*
* @param desc pointer to \b struct \b machine_desc
* @param tags pointer to \b struct \b tag
* @param cmdline pointer to the command line
* @param mi pointer to \b struct \b meminfo
*/
static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
struct tag *t;
struct tag *mem_tag = 0;
int total_mem = SZ_1G;
int left_mem = 0;
int gpu_mem = SZ_128M;
int fb_mem = SZ_32M;
char *str;
mxc_set_cpu_type(MXC_CPU_MX53);
for_each_tag(mem_tag, tags) {
if (mem_tag->hdr.tag == ATAG_MEM) {
total_mem = mem_tag->u.mem.size;
break;
}
}
for_each_tag(t, tags) {
if (t->hdr.tag == ATAG_CMDLINE) {
str = t->u.cmdline.cmdline;
str = strstr(str, "mem=");
if (str != NULL) {
str += 4;
left_mem = memparse(str, &str);
}
str = t->u.cmdline.cmdline;
str = strstr(str, "gpu_nommu");
if (str != NULL)
gpu_data.enable_mmu = 0;
str = t->u.cmdline.cmdline;
str = strstr(str, "gpu_memory=");
if (str != NULL) {
str += 11;
gpu_mem = memparse(str, &str);
}
break;
}
}
if (gpu_data.enable_mmu)
gpu_mem = 0;
if (left_mem == 0 || left_mem > total_mem)
left_mem = total_mem - gpu_mem - fb_mem;
if (mem_tag) {
fb_mem = total_mem - left_mem - gpu_mem;
if (fb_mem < 0) {
gpu_mem = total_mem - left_mem;
fb_mem = 0;
}
mem_tag->u.mem.size = left_mem;
/*reserve memory for gpu*/
if (!gpu_data.enable_mmu) {
gpu_device.resource[5].start =
mem_tag->u.mem.start + left_mem;
gpu_device.resource[5].end =
gpu_device.resource[5].start + gpu_mem - 1;
}
#if defined(CONFIG_FB_MXC_SYNC_PANEL) || \
defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
if (fb_mem) {
mxcfb_resources[0].start =
gpu_data.enable_mmu ?
mem_tag->u.mem.start + left_mem :
gpu_device.resource[5].end + 1;
mxcfb_resources[0].end =
mxcfb_resources[0].start + fb_mem - 1;
} else {
mxcfb_resources[0].start = 0;
mxcfb_resources[0].end = 0;
}
#endif
}
}
static void __init mx53_loco_io_init(void)
{
mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads,
ARRAY_SIZE(mx53_loco_pads));
/* SD3 */
gpio_request(SD3_CD, "sd3-cd");
gpio_direction_input(SD3_CD);
gpio_request(SD3_WP, "sd3-wp");
gpio_direction_input(SD3_WP);
/* reset FEC PHY */
gpio_request(FEC_RST, "fec-rst");
gpio_direction_output(FEC_RST, 0);
gpio_set_value(FEC_RST, 0);
msleep(1);
gpio_set_value(FEC_RST, 1);
/* headphone_det_b */
gpio_request(HEADPHONE_DEC_B, "headphone-dec");
gpio_direction_input(HEADPHONE_DEC_B);
/* USB PWR enable */
gpio_request(USB_PWREN, "usb-pwr");
gpio_direction_output(USB_PWREN, 0);
/* LCD panel power enable */
gpio_request(DISP0_POWER_EN, "disp0-power-en");
gpio_direction_output(DISP0_POWER_EN, 1);
}
/*!
* Board specific initialization.
*/
static void __init mxc_board_init(void)
{
iomux_v3_cfg_t mc34708_int = MX53_PAD_CSI0_DAT12__GPIO5_30;
iomux_v3_cfg_t da9052_csi0_d12;
mxc_ipu_data.di_clk[0] = clk_get(NULL, "ipu_di0_clk");
mxc_ipu_data.di_clk[1] = clk_get(NULL, "ipu_di1_clk");
mxc_ipu_data.csi_clk[0] = clk_get(NULL, "ssi_ext1_clk");
mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk");
clk_put(mxc_spdif_data.spdif_core_clk);
mxcsdhc3_device.resource[2].start = gpio_to_irq(SD3_CD);
mxcsdhc3_device.resource[2].end = gpio_to_irq(SD3_CD);
mxc_cpu_common_init();
mx53_loco_io_init();
mxc_register_device(&mxc_dma_device, NULL);
mxc_register_device(&mxc_wdt_device, NULL);
mxc_register_device(&mxci2c_devices[0], &mxci2c_data);
mxc_register_device(&mxci2c_devices[1], &mxci2c_data);
mxc_register_device(&mxci2c_devices[2], &mxci2c_data);
//if (board_is_mx53_loco_mc34708()) {
if(1){
/* set pmic INT gpio pin */
//if (board_is_rev(BOARD_REV_2)) {/*Board rev A*/
// mc34708_int = MX53_PAD_CSI0_DAT12__GPIO5_30;
// mx53_loco_mc34708_irq = MX53_LOCO_MC34708_IRQ_REVA;
//} else if (board_is_rev(BOARD_REV_4)) {/*Board rev B*/
mc34708_int = MX53_PAD_CSI0_DAT5__GPIO5_23;
mx53_loco_mc34708_irq = MX53_LOCO_MC34708_IRQ_REVB;
// }
mxc_iomux_v3_setup_pad(mc34708_int);
gpio_request(mx53_loco_mc34708_irq, "pmic-int");
gpio_direction_input(mx53_loco_mc34708_irq);
mx53_loco_init_mc34708(mx53_loco_mc34708_irq);
dvfs_core_data.reg_id = "SW1A";
tve_data.dac_reg = "VDAC";
bus_freq_data.gp_reg_id = "SW1A";
bus_freq_data.lp_reg_id = "SW2";
mxc_register_device(&mxc_powerkey_device, &pwrkey_data);
}
/*
else {
da9052_csi0_d12 = MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12;
mxc_iomux_v3_setup_pad(da9052_csi0_d12);
mx53_loco_init_da9052();
dvfs_core_data.reg_id = "DA9052_BUCK_CORE";
tve_data.dac_reg = "DA9052_LDO7";
bus_freq_data.gp_reg_id = "DA9052_BUCK_CORE";
bus_freq_data.lp_reg_id = "DA9052_BUCK_PRO";
}
*/
mxc_register_device(&mxc_rtc_device, NULL);
mxc_register_device(&mxc_ipu_device, &mxc_ipu_data);
mxc_register_device(&mxc_ldb_device, &ldb_data);
mxc_register_device(&mxc_tve_device, &tve_data);
if (!mxc_fuse_get_vpu_status())
mxc_register_device(&mxcvpu_device, &mxc_vpu_data);
if (!mxc_fuse_get_gpu_status())
mxc_register_device(&gpu_device, &gpu_data);
mxc_register_device(&mxcscc_device, NULL);
mxc_register_device(&pm_device, &loco_pm_data);
mxc_register_device(&mxc_dvfs_core_device, &dvfs_core_data);
mxc_register_device(&busfreq_device, &bus_freq_data);
mxc_register_device(&mxc_iim_device, &iim_data);
mxc_register_device(&mxc_pwm2_device, NULL);
mxc_register_device(&mxc_pwm1_backlight_device, &mxc_pwm_backlight_data);
mxc_register_device(&mxcsdhc1_device, &mmc1_data);
mxc_register_device(&mxcsdhc3_device, &mmc3_data);
mxc_register_device(&mxc_ssi1_device, NULL);
mxc_register_device(&mxc_ssi2_device, NULL);
mxc_register_device(&mxc_alsa_spdif_device, &mxc_spdif_data);
mxc_register_device(&ahci_fsl_device, &sata_data);
mxc_register_device(&imx_ahci_device_hwmon, NULL);
mxc_register_device(&mxc_fec_device, &fec_data);
mxc_register_device(&mxc_ptp_device, NULL);
/* ASRC is only available for MX53 TO2.0 */
if (mx53_revision() >= IMX_CHIP_REVISION_2_0) {
mxc_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
clk_put(mxc_asrc_data.asrc_core_clk);
mxc_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
clk_put(mxc_asrc_data.asrc_audio_clk);
mxc_register_device(&mxc_asrc_device, &mxc_asrc_data);
}
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));
sgtl5000_data.ext_ram_clk = clk_get(NULL, "emi_fast_clk");
clk_put(sgtl5000_data.ext_ram_clk);
mxc_register_device(&mxc_sgtl5000_device, &sgtl5000_data);
spdif_audio_data.ext_ram_clk = clk_get(NULL, "emi_fast_clk");
clk_put(spdif_audio_data.ext_ram_clk);
mxc_register_device(&mxc_spdif_audio_device, &spdif_audio_data);
mx5_usb_dr_init();
mx5_set_host1_vbus_func(mx53_loco_usbh1_vbus);
mx5_usbh1_init();
mxc_register_device(&mxc_v4l2_device, NULL);
mxc_register_device(&mxc_v4l2out_device, NULL);
loco_add_device_buttons();
//pm_power_off = da9053_power_off;
pm_power_off = mc34708_power_off;
pm_i2c_init(I2C1_BASE_ADDR - MX53_OFFSET);
}
static void __init mx53_loco_timer_init(void)
{
struct clk *uart_clk;
mx53_clocks_init(32768, 24000000, 0, 0);
uart_clk = clk_get_sys("mxcintuart.0", NULL);
early_console_setup(MX53_BASE_ADDR(UART1_BASE_ADDR), uart_clk);
}
static struct sys_timer mxc_timer = {
.init = mx53_loco_timer_init,
};
/*
* The following uses standard kernel macros define in arch.h in order to
* initialize __mach_desc_MX53_LOCO data structure.
*/
MACHINE_START(MX53_LOCO, "Freescale MX53 LOCO Board")
/* Maintainer: Freescale Semiconductor, Inc. */
.fixup = fixup_mxc_board,
.map_io = mx5_map_io,
.init_irq = mx5_init_irq,
.init_machine = mxc_board_init,
.timer = &mxc_timer,
MACHINE_END
mx53_loco_pmic_mc34708.c:
/*
* Copyright (C) 2011 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/pmic_external.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/mc34708/core.h>
#include <mach/irqs.h>
#include <mach/iomux-mx53.h>
#include <mach/gpio.h>
#include "pmic.h"
/*
* Convenience conversion.
* Here atm, maybe there is somewhere better for this.
*/
#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)
/* regulator standby mask */
#define GEN1_STBY_MASK (1 << 1)
#define GEN2_STBY_MASK (1 << 13)
#define PLL_STBY_MASK (1 << 16)
#define USB2_STBY_MASK (1 << 19)
#define USB_EN_MASK (1 << 3)
#define REG_MODE_0_ALL_MASK (GEN1_STBY_MASK)
#define SW1A_MODE_MASK (0xf << 0)
#define SW2_MODE_MASK (0xf << 14)
#define SW1A_MODE_VALUE (0xc << 0)
#define SW2_MODE_VALUE (0xc << 14)
#define REG_SW_1_2_MASK (SW1A_MODE_MASK | SW2_MODE_MASK)
#define REG_SW_1_2_VALUE (SW1A_MODE_VALUE | SW2_MODE_VALUE)
#define SW3_MODE_MASK (0xf << 0)
#define SW4A_MODE_MASK (0xf << 6)
#define SW4B_MODE_MASK (0xf << 12)
#define SW5_MODE_MASK (0xf << 18)
#define SW3_MODE_VALUE (0x0 << 0)
#define SW4A_MODE_VALUE (0xc << 6)
#define SW4B_MODE_VALUE (0xc << 12)
#define SW5_MODE_VALUE (0xc << 18)
#define REG_SW_3_4_5_MASK (SW3_MODE_MASK | SW4A_MODE_MASK\
| SW4B_MODE_MASK | SW5_MODE_MASK)
#define REG_SW_3_4_5_VALUE (SW3_MODE_VALUE | SW4A_MODE_VALUE\
| SW4B_MODE_VALUE | SW5_MODE_VALUE)
#define SWBST_MODE_MASK (0x3 << 5)
#define SWBST_MODE_VALUE (0x2 << 5) /*Auto mode*/
#define REG_SWBST_MODE_MASK (SWBST_MODE_MASK)
#define REG_SWBST_MODE_VALUE (SWBST_MODE_VALUE)
#define SWHOLD_MASK (0x1 << 12)
#define MC34708_I2C_DEVICE_NAME "mc34708"
/* 7-bit I2C bus slave address */
#define MC34708_I2C_ADDR (0x08)
#define MX53_LOCO_MC34708_IRQ (4*32 + 30) /* GPIO5_30 */
struct mc34708;
static struct regulator_init_data sw1a_init = {
.constraints = {
.name = "SW1",
.min_uV = 650000,
.max_uV = 1437500,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.valid_modes_mask = 0,
.always_on = 1,
.boot_on = 1,
.initial_state = PM_SUSPEND_MEM,
.state_mem = {
.uV = 850000,
.mode = REGULATOR_MODE_NORMAL,
.enabled = 1,
},
},
};
static struct regulator_init_data sw1b_init = {
.constraints = {
.name = "SW1B",
.min_uV = 650000,
.max_uV = 1437500,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.valid_modes_mask = 0,
.always_on = 1,
.boot_on = 1,
},
};
static struct regulator_init_data sw2_init = {
.constraints = {
.name = "SW2",
.min_uV = 650000,
.max_uV = 1437500,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
.boot_on = 1,
.initial_state = PM_SUSPEND_MEM,
.state_mem = {
.uV = 950000,
.mode = REGULATOR_MODE_NORMAL,
.enabled = 1,
},
}
};
static struct regulator_init_data sw3_init = {
.constraints = {
.name = "SW3",
.min_uV = 650000,
.max_uV = 1425000,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.boot_on = 1,
}
};
static struct regulator_init_data sw4a_init = {
.constraints = {
.name = "SW4A",
.min_uV = mV_to_uV(1200),
.max_uV = mV_to_uV(3300),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
.boot_on = 1,
}
};
static struct regulator_init_data sw4b_init = {
.constraints = {
.name = "SW4B",
.min_uV = mV_to_uV(1200),
.max_uV = mV_to_uV(3300),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
.boot_on = 1,
}
};
static struct regulator_init_data sw5_init = {
.constraints = {
.name = "SW5",
.min_uV = mV_to_uV(1200),
.max_uV = mV_to_uV(1975),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
.boot_on = 1,
}
};
static struct regulator_init_data vrefddr_init = {
.constraints = {
.name = "VREFDDR",
.always_on = 1,
.boot_on = 1,
}
};
static struct regulator_init_data vusb_init = {
.constraints = {
.name = "VUSB",
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
.boot_on = 1,
.always_on = 1,
}
};
static struct regulator_init_data swbst_init = {
.constraints = {
.name = "SWBST",
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
.boot_on = 1,
.always_on = 1,
}
};
static struct regulator_init_data vpll_init = {
.constraints = {
.name = "VPLL",
.min_uV = mV_to_uV(1200),
.max_uV = mV_to_uV(1800),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.boot_on = 1,
},
};
static struct regulator_init_data vdac_init = {
.constraints = {
.name = "VDAC",
.min_uV = mV_to_uV(2500),
.max_uV = mV_to_uV(2775),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.boot_on = 1,
.always_on = 1,
}
};
static struct regulator_init_data vusb2_init = {
.constraints = {
.name = "VUSB2",
.min_uV = mV_to_uV(2500),
.max_uV = mV_to_uV(3000),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.boot_on = 1,
.always_on = 1,
}
};
static struct regulator_init_data vgen1_init = {
.constraints = {
.name = "VGEN1",
.min_uV = mV_to_uV(1200),
.max_uV = mV_to_uV(1550),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
}
};
static struct regulator_init_data vgen2_init = {
.constraints = {
.name = "VGEN2",
.min_uV = mV_to_uV(2500),
.max_uV = mV_to_uV(3300),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
}
};
static int mc34708_regulator_init(struct mc34708 *mc34708)
{
unsigned int value;
pmic_read_reg(REG_MC34708_IDENTIFICATION, &value, 0xffffff);
pr_info("PMIC MC34708 ID:0x%x\n", value);
printk("PMIC_34708");
/* setting switch operating mode for SW1/2 regulators */
pmic_read_reg(REG_MC34708_SW_1_2_OP, &value, 0xffffff);
value &= ~REG_SW_1_2_MASK;
value |= REG_SW_1_2_VALUE;
pmic_write_reg(REG_MC34708_SW_1_2_OP, value, 0xffffff);
/* setting switch operating mode for SW3/4/5 regulators */
pmic_read_reg(REG_MC34708_SW_3_4_5_OP, &value, 0xffffff);
value &= ~REG_SW_3_4_5_MASK;
value |= REG_SW_3_4_5_VALUE;
pmic_write_reg(REG_MC34708_SW_3_4_5_OP, value, 0xffffff);
/* setting switch operating mode for SWBST regulators */
pmic_read_reg(REG_MC34708_SWBST, &value, 0xffffff);
value &= ~REG_SWBST_MODE_MASK;
value |= REG_SWBST_MODE_VALUE;
pmic_write_reg(REG_MC34708_SWBST, value, 0xffffff);
/* clear SWHOLD bit to enable USB MUX */
pmic_read_reg(REG_MC34708_USB_CONTROL, &value, 0xffffff);
value &= ~SWHOLD_MASK;
pmic_write_reg(REG_MC34708_USB_CONTROL, value, 0xffffff);
/* enable WDI reset*/
pmic_read_reg(REG_MC34708_POWER_CTL2, &value, 0xffffff);
value |= 0x1000;
pmic_write_reg(REG_MC34708_POWER_CTL2, value, 0xffffff);
mc34708_register_regulator(mc34708, MC34708_SW1A, &sw1a_init);
mc34708_register_regulator(mc34708, MC34708_SW1B, &sw1b_init);
mc34708_register_regulator(mc34708, MC34708_SW2, &sw2_init);
mc34708_register_regulator(mc34708, MC34708_SW3, &sw3_init);
mc34708_register_regulator(mc34708, MC34708_SW4A, &sw4a_init);
mc34708_register_regulator(mc34708, MC34708_SW4B, &sw4b_init);
mc34708_register_regulator(mc34708, MC34708_SW5, &sw5_init);
mc34708_register_regulator(mc34708, MC34708_SWBST, &swbst_init);
mc34708_register_regulator(mc34708, MC34708_VPLL, &vpll_init);
mc34708_register_regulator(mc34708, MC34708_VREFDDR, &vrefddr_init);
mc34708_register_regulator(mc34708, MC34708_VDAC, &vdac_init);
mc34708_register_regulator(mc34708, MC34708_VUSB, &vusb_init);
mc34708_register_regulator(mc34708, MC34708_VUSB2, &vusb2_init);
mc34708_register_regulator(mc34708, MC34708_VGEN1, &vgen1_init);
mc34708_register_regulator(mc34708, MC34708_VGEN2, &vgen2_init);
regulator_has_full_constraints();
return 0;
}
static struct mc34708_platform_data mc34708_plat = {
.init = mc34708_regulator_init,
};
static struct i2c_board_info __initdata mc34708_i2c_device = {
I2C_BOARD_INFO(MC34708_I2C_DEVICE_NAME, MC34708_I2C_ADDR),
.platform_data = &mc34708_plat,
};
int __init mx53_loco_init_mc34708(u32 int_gpio)
{
mc34708_i2c_device.irq = gpio_to_irq(int_gpio);/*update INT gpio*/
return i2c_register_board_info(0, &mc34708_i2c_device, 1);
}