/* linux/arch/arm/mach-exynos/mach-smdk4x12.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
#include <linux/clk.h>
#include <linux/lcd.h>
#include <linux/gpio.h>
#include <linux/gpio_event.h>
#include <linux/i2c.h>
#include <linux/pwm_backlight.h>
#include <linux/input.h>
#include <linux/mmc/host.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/max8649.h>
#include <linux/regulator/fixed.h>
#include <linux/mfd/wm8994/pdata.h>
#include <linux/mfd/max8997.h>
#include <linux/mfd/max77686.h>
#include <linux/v4l2-mediabus.h>
#include <linux/memblock.h>
#include <linux/delay.h>
#include <linux/smsc911x.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
#include <plat/regs-serial.h>
#include <plat/exynos4.h>
#include <plat/cpu.h>
#include <plat/clock.h>
#include <plat/keypad.h>
#include <plat/devs.h>
#include <plat/fb.h>
#include <plat/fb-s5p.h>
#include <plat/fb-core.h>
#include <plat/regs-fb-v4.h>
#include <plat/backlight.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-adc.h>
#include <plat/adc.h>
#include <plat/iic.h>
#include <plat/pd.h>
#include <plat/sdhci.h>
#include <plat/mshci.h>
#include <plat/ehci.h>
#include <plat/usbgadget.h>
#include <plat/s3c64xx-spi.h>
#if defined(CONFIG_VIDEO_FIMC)
#include <plat/fimc.h>
#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)
#include <plat/fimc-core.h>
#include <media/s5p_fimc.h>
#endif
#if defined(CONFIG_VIDEO_FIMC_MIPI)
#include <plat/csis.h>
#elif defined(CONFIG_VIDEO_S5P_MIPI_CSIS)
#include <plat/mipi_csis.h>
#endif
#include <plat/tvout.h>
#include <plat/media.h>
#include <plat/regs-srom.h>
#include <plat/sysmmu.h>
#include <plat/tv-core.h>
#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
#include <plat/s5p-mfc.h>
#endif
#include <media/gc0308_platform.h>
#include <media/GT2005_platform.h>
#include <media/sp2518_platform.h>
#include <media/hi253_platform.h>
#include <media/s5k4ba_platform.h>
#include <media/s5k4ea_platform.h>
#include <media/exynos_flite.h>
#include <media/exynos_fimc_is.h>
#include <video/platform_lcd.h>
#include <media/m5mo_platform.h>
#include <media/m5mols.h>
#include <mach/board_rev.h>
#include <mach/map.h>
#include <mach/spi-clocks.h>
#include <mach/exynos-ion.h>
#include <mach/regs-pmu.h>
#ifdef CONFIG_EXYNOS4_DEV_DWMCI
#include <mach/dwmci.h>
#endif
#ifdef CONFIG_EXYNOS4_CONTENT_PATH_PROTECTION
#include <mach/secmem.h>
#endif
#include <mach/dev.h>
#include <mach/ppmu.h>
#ifdef CONFIG_EXYNOS_C2C
#include <mach/c2c.h>
#endif
#ifdef CONFIG_FB_S5P_MIPI_DSIM
#include <mach/mipi_ddi.h>
#include <mach/dsim.h>
#include <../../../drivers/video/samsung/s3cfb.h>
#endif
#include <plat/fimg2d.h>
#include <mach/dev-sysmmu.h>
#ifdef CONFIG_MPU_SENSORS_MPU6050B1
#include <linux/mpu.h>
#endif
/* For Audio */
#define GPIO_SPK5V_EN EXYNOS4_GPA1(4)
#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
#include <plat/fimc-core.h>
#include <media/s5p_fimc.h>
#endif
#ifdef CONFIG_VIDEO_JPEG_V2X
#include <plat/jpeg.h>
#endif
#include <linux/mfd/s5m87xx/s5m-core.h>
#include <linux/mfd/s5m87xx/s5m-pmic.h>
#if defined(CONFIG_EXYNOS_THERMAL)
#include <mach/tmu.h>
#endif
#if defined(CONFIG_BATTERY_MAX17040)
#include <linux/max17040_battery.h>
#endif
#if defined(CONFIG_CHARGER_PM2301)
#include <linux/pm2301_charger.h>
#endif
#ifdef CONFIG_I2C_GPIO
#include <linux/i2c-gpio.h>
#endif
#define REG_INFORM4 (S5P_INFORM4)
#define REG_INFORM2 (S5P_INFORM2)
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDK4X12_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
S3C2410_UCON_TXIRQMODE | \
S3C2410_UCON_RXIRQMODE | \
S3C2410_UCON_RXFIFO_TOI | \
S3C2443_UCON_RXERR_IRQEN)
#define SMDK4X12_ULCON_DEFAULT S3C2410_LCON_CS8
#define SMDK4X12_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
S5PV210_UFCON_TXTRIG4 | \
S5PV210_UFCON_RXTRIG4)
static struct s3c2410_uartcfg smdk4x12_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = SMDK4X12_UCON_DEFAULT,
.ulcon = SMDK4X12_ULCON_DEFAULT,
.ufcon = SMDK4X12_UFCON_DEFAULT,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = SMDK4X12_UCON_DEFAULT,
.ulcon = SMDK4X12_ULCON_DEFAULT,
.ufcon = SMDK4X12_UFCON_DEFAULT,
},
[2] = {
.hwport = 2,
.flags = 0,
.ucon = SMDK4X12_UCON_DEFAULT,
.ulcon = SMDK4X12_ULCON_DEFAULT,
.ufcon = SMDK4X12_UFCON_DEFAULT,
},
[3] = {
.hwport = 3,
.flags = 0,
.ucon = SMDK4X12_UCON_DEFAULT,
.ulcon = SMDK4X12_ULCON_DEFAULT,
.ufcon = SMDK4X12_UFCON_DEFAULT,
},
};
static struct resource smdk4x12_smsc911x_resources[] = {
[0] = {
.start = EXYNOS4_PA_SROM_BANK(1),
.end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_EINT(5),
.end = IRQ_EINT(5),
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
},
};
static struct smsc911x_platform_config smsc9215_config = {
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
.irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
.flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
.phy_interface = PHY_INTERFACE_MODE_MII,
.mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
};
static struct platform_device smdk4x12_smsc911x = {
.name = "smsc911x",
.id = -1,
.num_resources = ARRAY_SIZE(smdk4x12_smsc911x_resources),
.resource = smdk4x12_smsc911x_resources,
.dev = {
.platform_data = &smsc9215_config,
},
};
#ifdef CONFIG_EXYNOS_MEDIA_DEVICE
struct platform_device exynos_device_md0 = {
.name = "exynos-mdev",
.id = -1,
};
#endif
#define WRITEBACK_ENABLED
#if defined(CONFIG_VIDEO_FIMC) || defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)
/*
* External camera reset
* Because the most of cameras take i2c bus signal, so that
* you have to reset at the boot time for other i2c slave devices.
* This function also called at fimc_init_camera()
* Do optimization for cameras on your platform.
*/
#if defined(CONFIG_ITU_A) || defined(CONFIG_CSI_C) \
|| defined(CONFIG_S5K3H2_CSI_C) || defined(CONFIG_S5K3H7_CSI_C) \
|| defined(CONFIG_S5K4E5_CSI_C) || defined(CONFIG_S5K6A3_CSI_C)
static int smdk4x12_cam0_reset(int dummy)
{
int err;
/* Camera A */
err = gpio_request(EXYNOS4_GPX1(2), "GPX1");
if (err)
printk(KERN_ERR "#### failed to request GPX1_2 ####\n");
s3c_gpio_setpull(EXYNOS4_GPX1(2), S3C_GPIO_PULL_NONE);
gpio_direction_output(EXYNOS4_GPX1(2), 0);
gpio_direction_output(EXYNOS4_GPX1(2), 1);
gpio_free(EXYNOS4_GPX1(2));
return 0;
}
#endif
#if defined(CONFIG_ITU_B) || defined(CONFIG_CSI_D) \
|| defined(CONFIG_S5K3H2_CSI_D) || defined(CONFIG_S5K3H7_CSI_D) \
|| defined(CONFIG_S5K4E5_CSI_D) || defined(CONFIG_S5K6A3_CSI_D)
static int smdk4x12_cam1_reset(int dummy)
{
int err;
/* Camera B */
err = gpio_request(EXYNOS4_GPX1(0), "GPX1");
if (err)
printk(KERN_ERR "#### failed to request GPX1_0 ####\n");
s3c_gpio_setpull(EXYNOS4_GPX1(0), S3C_GPIO_PULL_NONE);
gpio_direction_output(EXYNOS4_GPX1(0), 0);
gpio_direction_output(EXYNOS4_GPX1(0), 1);
gpio_free(EXYNOS4_GPX1(0));
return 0;
}
#endif
#endif
#ifdef CONFIG_VIDEO_FIMC
#ifdef CONFIG_VIDEO_GC0308
static int gc0308_power(int on_off)
{
int err;
printk("###%s____%d\n",__func__,on_off);
//CAM_B_EN0 GPM1_1
//CAM_B_EN1 GPM1_3
//CAM_B_RESET GPM1_2
if(on_off)
{
err = gpio_request(EXYNOS4212_GPM1(1), "GPM1");
if (err)
printk(KERN_ERR "#### failed to request GPM1_1 ####\n");
err = gpio_request(EXYNOS4212_GPM1(2), "GPM1");
if (err)
printk(KERN_ERR "#### failed to request GPM1_2 ####\n");
err = gpio_request(EXYNOS4212_GPM1(3), "GPM1");
if (err)
printk(KERN_ERR "#### failed to request GPM1_3 ####\n");
s3c_gpio_setpu