diff options
Diffstat (limited to 'arch/arm/mach-exynos/mach-smdk4x12.c')
-rw-r--r-- | arch/arm/mach-exynos/mach-smdk4x12.c | 4388 |
1 files changed, 4388 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c new file mode 100644 index 0000000..97daba2 --- /dev/null +++ b/arch/arm/mach-exynos/mach-smdk4x12.c @@ -0,0 +1,4388 @@ +/* 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/usb-switch.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/s5p-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/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_EXYNOS_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 +#ifdef CONFIG_FB_S5P_EXTDSP +struct s3cfb_extdsp_lcd { + int width; + int height; + int bpp; +}; +#endif +#include <plat/fimg2d.h> +#include <mach/dev-sysmmu.h> + +#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 + +#ifdef CONFIG_REGULATOR_S5M8767 +#include <linux/mfd/s5m87xx/s5m-core.h> +#include <linux/mfd/s5m87xx/s5m-pmic.h> +#endif + +#if defined(CONFIG_EXYNOS_SETUP_THERMAL) +#include <plat/s5p-tmu.h> +#endif + +#define REG_INFORM4 (S5P_INFORM4) + +/* 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_S5K4BA +static struct s5k4ba_platform_data s5k4ba_plat = { + .default_width = 800, + .default_height = 600, + .pixelformat = V4L2_PIX_FMT_YUYV, + .freq = 24000000, + .is_mipi = 0, +}; + +static struct i2c_board_info s5k4ba_i2c_info = { + I2C_BOARD_INFO("S5K4BA", 0x2d), + .platform_data = &s5k4ba_plat, +}; + +static struct s3c_platform_camera s5k4ba = { +#ifdef CONFIG_ITU_A + .id = CAMERA_PAR_A, + .clk_name = "sclk_cam0", + .i2c_busnum = 4, + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_ITU_B + .id = CAMERA_PAR_B, + .clk_name = "sclk_cam1", + .i2c_busnum = 5, + .cam_power = smdk4x12_cam1_reset, +#endif + .type = CAM_TYPE_ITU, + .fmt = ITU_601_YCBCR422_8BIT, + .order422 = CAM_ORDER422_8BIT_CBYCRY, + .info = &s5k4ba_i2c_info, + .pixelformat = V4L2_PIX_FMT_YUYV, + .srclk_name = "xusbxti", + .clk_rate = 24000000, + .line_length = 1920, + .width = 1600, + .height = 1200, + .window = { + .left = 0, + .top = 0, + .width = 1600, + .height = 1200, + }, + + /* Polarity */ + .inv_pclk = 0, + .inv_vsync = 1, + .inv_href = 0, + .inv_hsync = 0, + .reset_camera = 1, + .initialized = 0, +}; +#endif + +/* 2 MIPI Cameras */ +#ifdef CONFIG_VIDEO_S5K4EA +static struct s5k4ea_platform_data s5k4ea_plat = { + .default_width = 1920, + .default_height = 1080, + .pixelformat = V4L2_PIX_FMT_UYVY, + .freq = 24000000, + .is_mipi = 1, +}; + +static struct i2c_board_info s5k4ea_i2c_info = { + I2C_BOARD_INFO("S5K4EA", 0x2d), + .platform_data = &s5k4ea_plat, +}; + +static struct s3c_platform_camera s5k4ea = { +#ifdef CONFIG_CSI_C + .id = CAMERA_CSI_C, + .clk_name = "sclk_cam0", + .i2c_busnum = 4, + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_CSI_D + .id = CAMERA_CSI_D, + .clk_name = "sclk_cam1", + .i2c_busnum = 5, + .cam_power = smdk4x12_cam1_reset, +#endif + .type = CAM_TYPE_MIPI, + .fmt = MIPI_CSI_YCBCR422_8BIT, + .order422 = CAM_ORDER422_8BIT_YCBYCR, + .info = &s5k4ea_i2c_info, + .pixelformat = V4L2_PIX_FMT_UYVY, + .srclk_name = "xusbxti", + .clk_rate = 24000000, + .line_length = 1920, + .width = 1920, + .height = 1080, + .window = { + .left = 0, + .top = 0, + .width = 1920, + .height = 1080, + }, + + .mipi_lanes = 2, + .mipi_settle = 12, + .mipi_align = 32, + + /* Polarity */ + .inv_pclk = 0, + .inv_vsync = 1, + .inv_href = 0, + .inv_hsync = 0, + + .initialized = 0, +}; +#endif + +#ifdef WRITEBACK_ENABLED +static struct i2c_board_info writeback_i2c_info = { + I2C_BOARD_INFO("WriteBack", 0x0), +}; + +static struct s3c_platform_camera writeback = { + .id = CAMERA_WB, + .fmt = ITU_601_YCBCR422_8BIT, + .order422 = CAM_ORDER422_8BIT_CBYCRY, + .i2c_busnum = 0, + .info = &writeback_i2c_info, + .pixelformat = V4L2_PIX_FMT_YUV444, + .line_length = 800, + .width = 480, + .height = 800, + .window = { + .left = 0, + .top = 0, + .width = 480, + .height = 800, + }, + + .initialized = 0, +}; +#endif + +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS +#ifdef CONFIG_VIDEO_S5K3H2 +static struct i2c_board_info s5k3h2_sensor_info = { + .type = "S5K3H2", +}; + +static struct s3c_platform_camera s5k3h2 = { +#ifdef CONFIG_S5K3H2_CSI_C + .id = CAMERA_CSI_C, + .clk_name = "sclk_cam0", + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_S5K3H2_CSI_D + .id = CAMERA_CSI_D, + .clk_name = "sclk_cam1", + .cam_power = smdk4x12_cam1_reset, +#endif + .type = CAM_TYPE_MIPI, + .fmt = MIPI_CSI_RAW10, + .info = &s5k3h2_sensor_info, + .order422 = CAM_ORDER422_8BIT_YCBYCR, + .pixelformat = V4L2_PIX_FMT_UYVY, + .line_length = 1920, + .width = 1920, + .height = 1080, + .window = { + .left = 0, + .top = 0, + .width = 1920, + .height = 1080, + }, + .srclk_name = "xusbxti", + .clk_rate = 24000000, + .mipi_lanes = 2, + .mipi_settle = 12, + .mipi_align = 24, + + .initialized = 0, +#ifdef CONFIG_S5K3H2_CSI_C + .flite_id = FLITE_IDX_A, +#endif +#ifdef CONFIG_S5K3H2_CSI_D + .flite_id = FLITE_IDX_B, +#endif + .use_isp = true, +#ifdef CONFIG_S5K3H2_CSI_C + .sensor_index = 1, +#endif +#ifdef CONFIG_S5K3H2_CSI_D + .sensor_index = 101, +#endif +}; +#endif + +#ifdef CONFIG_VIDEO_S5K3H7 +static struct i2c_board_info s5k3h7_sensor_info = { + .type = "S5K3H7", +}; + +static struct s3c_platform_camera s5k3h7 = { +#ifdef CONFIG_S5K3H7_CSI_C + .id = CAMERA_CSI_C, + .clk_name = "sclk_cam0", + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_S5K3H7_CSI_D + .id = CAMERA_CSI_D, + .clk_name = "sclk_cam1", + .cam_power = smdk4x12_cam1_reset, +#endif + .type = CAM_TYPE_MIPI, + .fmt = MIPI_CSI_RAW10, + .info = &s5k3h7_sensor_info, + .order422 = CAM_ORDER422_8BIT_YCBYCR, + .pixelformat = V4L2_PIX_FMT_UYVY, + .line_length = 1920, + .width = 1920, + .height = 1080, + .window = { + .left = 0, + .top = 0, + .width = 1920, + .height = 1080, + }, + .srclk_name = "xusbxti", + .clk_rate = 24000000, + .mipi_lanes = 2, + .mipi_settle = 12, + .mipi_align = 24, + + .initialized = 0, +#ifdef CONFIG_S5K3H7_CSI_C + .flite_id = FLITE_IDX_A, +#endif +#ifdef CONFIG_S5K3H7_CSI_D + .flite_id = FLITE_IDX_B, +#endif + .use_isp = true, +#ifdef CONFIG_S5K3H7_CSI_C + .sensor_index = 4, +#endif +#ifdef CONFIG_S5K3H7_CSI_D + .sensor_index = 104, +#endif +}; +#endif + +#ifdef CONFIG_VIDEO_S5K4E5 +static struct i2c_board_info s5k4e5_sensor_info = { + .type = "S5K4E5", +}; + +static struct s3c_platform_camera s5k4e5 = { +#ifdef CONFIG_S5K4E5_CSI_C + .id = CAMERA_CSI_C, + .clk_name = "sclk_cam0", + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_S5K4E5_CSI_D + .id = CAMERA_CSI_D, + .clk_name = "sclk_cam1", + .cam_power = smdk4x12_cam1_reset, +#endif + .type = CAM_TYPE_MIPI, + .fmt = MIPI_CSI_RAW10, + .info = &s5k4e5_sensor_info, + .order422 = CAM_ORDER422_8BIT_YCBYCR, + .pixelformat = V4L2_PIX_FMT_UYVY, + .line_length = 1920, + .width = 1920, + .height = 1080, + .window = { + .left = 0, + .top = 0, + .width = 1920, + .height = 1080, + }, + .srclk_name = "xusbxti", + .clk_rate = 24000000, + .mipi_lanes = 2, + .mipi_settle = 12, + .mipi_align = 24, + + .initialized = 0, +#ifdef CONFIG_S5K4E5_CSI_C + .flite_id = FLITE_IDX_A, +#endif +#ifdef CONFIG_S5K4E5_CSI_D + .flite_id = FLITE_IDX_B, +#endif + .use_isp = true, +#ifdef CONFIG_S5K4E5_CSI_C + .sensor_index = 3, +#endif +#ifdef CONFIG_S5K4E5_CSI_D + .sensor_index = 103, +#endif +}; +#endif + + +#ifdef CONFIG_VIDEO_S5K6A3 +static struct i2c_board_info s5k6a3_sensor_info = { + .type = "S5K6A3", +}; + +static struct s3c_platform_camera s5k6a3 = { +#ifdef CONFIG_S5K6A3_CSI_C + .id = CAMERA_CSI_C, + .clk_name = "sclk_cam0", + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_S5K6A3_CSI_D + .id = CAMERA_CSI_D, + .clk_name = "sclk_cam1", + .cam_power = smdk4x12_cam1_reset, +#endif + .type = CAM_TYPE_MIPI, + .fmt = MIPI_CSI_RAW10, + .info = &s5k6a3_sensor_info, + .order422 = CAM_ORDER422_8BIT_YCBYCR, + .pixelformat = V4L2_PIX_FMT_UYVY, + .line_length = 1920, + .width = 1920, + .height = 1080, + .window = { + .left = 0, + .top = 0, + .width = 1920, + .height = 1080, + }, + .srclk_name = "xusbxti", + .clk_rate = 24000000, + .mipi_lanes = 1, + .mipi_settle = 18, + .mipi_align = 24, + + .initialized = 0, +#ifdef CONFIG_S5K6A3_CSI_C + .flite_id = FLITE_IDX_A, +#endif +#ifdef CONFIG_S5K6A3_CSI_D + .flite_id = FLITE_IDX_B, +#endif + .use_isp = true, +#ifdef CONFIG_S5K6A3_CSI_C + .sensor_index = 2, +#endif +#ifdef CONFIG_S5K6A3_CSI_D + .sensor_index = 102, +#endif +}; +#endif + +#if defined(CONFIG_VIDEO_S5K6A3) && defined(CONFIG_S5K6A3_CSI_D) +static struct i2c_board_info s5k6a3_fd_sensor_info = { + .type = "S5K6A3_FD", +}; + +static struct s3c_platform_camera s5k6a3_fd = { + .id = CAMERA_CSI_D, + .clk_name = "sclk_cam1", + .cam_power = smdk4x12_cam1_reset, + + .type = CAM_TYPE_MIPI, + .fmt = MIPI_CSI_RAW10, + .info = &s5k6a3_fd_sensor_info, + .order422 = CAM_ORDER422_8BIT_YCBYCR, + .pixelformat = V4L2_PIX_FMT_UYVY, + .line_length = 1920, + .width = 1920, + .height = 1080, + .window = { + .left = 0, + .top = 0, + .width = 1920, + .height = 1080, + }, + .srclk_name = "xusbxti", + .clk_rate = 24000000, + .mipi_lanes = 1, + .mipi_settle = 18, + .mipi_align = 24, + + .initialized = 0, + .flite_id = FLITE_IDX_B, + .use_isp = true, + .sensor_index = 200 +}; +#endif + +#endif + +/* legacy M5MOLS Camera driver configuration */ +#ifdef CONFIG_VIDEO_M5MO +#define CAM_CHECK_ERR_RET(x, msg) \ + if (unlikely((x) < 0)) { \ + printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \ + return x; \ + } +#define CAM_CHECK_ERR(x, msg) \ + if (unlikely((x) < 0)) { \ + printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \ + } + +static int m5mo_config_isp_irq(void) +{ + s3c_gpio_cfgpin(EXYNOS4_GPX3(3), S3C_GPIO_SFN(0xF)); + s3c_gpio_setpull(EXYNOS4_GPX3(3), S3C_GPIO_PULL_NONE); + return 0; +} + +static struct m5mo_platform_data m5mo_plat = { + .default_width = 640, /* 1920 */ + .default_height = 480, /* 1080 */ + .pixelformat = V4L2_PIX_FMT_UYVY, + .freq = 24000000, + .is_mipi = 1, + .config_isp_irq = m5mo_config_isp_irq, + .irq = IRQ_EINT(27), +}; + +static struct i2c_board_info m5mo_i2c_info = { + I2C_BOARD_INFO("M5MO", 0x1F), + .platform_data = &m5mo_plat, + .irq = IRQ_EINT(27), +}; + +static struct s3c_platform_camera m5mo = { +#ifdef CONFIG_CSI_C + .id = CAMERA_CSI_C, + .clk_name = "sclk_cam0", + .i2c_busnum = 4, + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_CSI_D + .id = CAMERA_CSI_D, + .clk_name = "sclk_cam1", + .i2c_busnum = 5, + .cam_power = smdk4x12_cam1_reset, +#endif + .type = CAM_TYPE_MIPI, + .fmt = MIPI_CSI_YCBCR422_8BIT, + .order422 = CAM_ORDER422_8BIT_YCBYCR, + .info = &m5mo_i2c_info, + .pixelformat = V4L2_PIX_FMT_UYVY, + .srclk_name = "xusbxti", /* "mout_mpll" */ + .clk_rate = 24000000, /* 48000000 */ + .line_length = 1920, + .width = 640, + .height = 480, + .window = { + .left = 0, + .top = 0, + .width = 640, + .height = 480, + }, + + .mipi_lanes = 2, + .mipi_settle = 12, + .mipi_align = 32, + + /* Polarity */ + .inv_pclk = 1, + .inv_vsync = 1, + .inv_href = 0, + .inv_hsync = 0, + .reset_camera = 0, + .initialized = 0, +}; +#endif + +/* Interface setting */ +static struct s3c_platform_fimc fimc_plat = { +#ifdef CONFIG_ITU_A + .default_cam = CAMERA_PAR_A, +#endif +#ifdef CONFIG_ITU_B + .default_cam = CAMERA_PAR_B, +#endif +#ifdef CONFIG_CSI_C + .default_cam = CAMERA_CSI_C, +#endif +#ifdef CONFIG_CSI_D + .default_cam = CAMERA_CSI_D, +#endif +#ifdef WRITEBACK_ENABLED + .default_cam = CAMERA_WB, +#endif + .camera = { +#ifdef CONFIG_VIDEO_S5K4BA + &s5k4ba, +#endif +#ifdef CONFIG_VIDEO_S5K4EA + &s5k4ea, +#endif +#ifdef CONFIG_VIDEO_M5MO + &m5mo, +#endif +#ifdef CONFIG_VIDEO_S5K3H2 + &s5k3h2, +#endif +#ifdef CONFIG_VIDEO_S5K3H7 + &s5k3h7, +#endif +#ifdef CONFIG_VIDEO_S5K4E5 + &s5k4e5, +#endif +#ifdef CONFIG_VIDEO_S5K6A3 + &s5k6a3, +#endif +#ifdef WRITEBACK_ENABLED + &writeback, +#endif +#if defined(CONFIG_VIDEO_S5K6A3) && defined(CONFIG_S5K6A3_CSI_D) + &s5k6a3_fd, +#endif + }, + .hw_ver = 0x51, +}; +#endif /* CONFIG_VIDEO_FIMC */ + +/* for mainline fimc interface */ +#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC +#ifdef WRITEBACK_ENABLED +struct writeback_mbus_platform_data { + int id; + struct v4l2_mbus_framefmt fmt; +}; + +static struct i2c_board_info __initdata writeback_info = { + I2C_BOARD_INFO("writeback", 0x0), +}; +#endif + +#ifdef CONFIG_VIDEO_S5K4BA +static struct s5k4ba_mbus_platform_data s5k4ba_mbus_plat = { + .id = 0, + .fmt = { + .width = 1600, + .height = 1200, + /*.code = V4L2_MBUS_FMT_UYVY8_2X8, */ + .code = V4L2_MBUS_FMT_VYUY8_2X8, + }, + .clk_rate = 24000000UL, +#ifdef CONFIG_ITU_A + .set_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_ITU_B + .set_power = smdk4x12_cam1_reset, +#endif +}; + +static struct i2c_board_info s5k4ba_info = { + I2C_BOARD_INFO("S5K4BA", 0x2d), + .platform_data = &s5k4ba_mbus_plat, +}; +#endif + +/* 2 MIPI Cameras */ +#ifdef CONFIG_VIDEO_S5K4EA +static struct s5k4ea_mbus_platform_data s5k4ea_mbus_plat = { +#ifdef CONFIG_CSI_C + .id = 0, + .set_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_CSI_D + .id = 1, + .set_power = smdk4x12_cam1_reset, +#endif + .fmt = { + .width = 1920, + .height = 1080, + .code = V4L2_MBUS_FMT_VYUY8_2X8, + }, + .clk_rate = 24000000UL, +}; + +static struct i2c_board_info s5k4ea_info = { + I2C_BOARD_INFO("S5K4EA", 0x2d), + .platform_data = &s5k4ea_mbus_plat, +}; +#endif + +#ifdef CONFIG_VIDEO_M5MOLS +static struct m5mols_platform_data m5mols_platdata = { +#ifdef CONFIG_CSI_C + .gpio_rst = EXYNOS4_GPX1(2), /* ISP_RESET */ +#endif +#ifdef CONFIG_CSI_D + .gpio_rst = EXYNOS4_GPX1(0), /* ISP_RESET */ +#endif + .enable_rst = true, /* positive reset */ + .irq = IRQ_EINT(27), +}; + +static struct i2c_board_info m5mols_board_info = { + I2C_BOARD_INFO("M5MOLS", 0x1F), + .platform_data = &m5mols_platdata, +}; + +#endif + +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS +#ifdef CONFIG_VIDEO_S5K3H2 +static struct i2c_board_info s5k3h2_sensor_info = { + .type = "S5K3H2", +}; +#endif +#ifdef CONFIG_VIDEO_S5K3H7 +static struct i2c_board_info s5k3h7_sensor_info = { + .type = "S5K3H7", +}; +#endif +#ifdef CONFIG_VIDEO_S5K4E5 +static struct i2c_board_info s5k4e5_sensor_info = { + .type = "S5K4E5", +}; +#endif +#ifdef CONFIG_VIDEO_S5K6A3 +static struct i2c_board_info s5k6a3_sensor_info = { + .type = "S5K6A3", +}; +#endif +#endif +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE +/* This is for platdata of fimc-lite */ +#ifdef CONFIG_VIDEO_S5K3H2 +static struct s3c_platform_camera s5k3h2 = { + .type = CAM_TYPE_MIPI, + .use_isp = true, + .inv_pclk = 0, + .inv_vsync = 0, + .inv_href = 0, + .inv_hsync = 0, +}; +#endif + +#ifdef CONFIG_VIDEO_S5K3H7 +static struct s3c_platform_camera s5k3h7 = { + .type = CAM_TYPE_MIPI, + .use_isp = true, + .inv_pclk = 0, + .inv_vsync = 0, + .inv_href = 0, + .inv_hsync = 0, +}; +#endif + +#ifdef CONFIG_VIDEO_S5K4E5 +static struct s3c_platform_camera s5k4e5 = { + .type = CAM_TYPE_MIPI, + .use_isp = true, + .inv_pclk = 0, + .inv_vsync = 0, + .inv_href = 0, + .inv_hsync = 0, +}; +#endif + + +#ifdef CONFIG_VIDEO_S5K6A3 +static struct s3c_platform_camera s5k6a3 = { + .type = CAM_TYPE_MIPI, + .use_isp = true, + .inv_pclk = 0, + .inv_vsync = 0, + .inv_href = 0, + .inv_hsync = 0, +}; +#endif +#endif +#endif /* CONFIG_VIDEO_SAMSUNG_S5P_FIMC */ + +#ifdef CONFIG_S3C64XX_DEV_SPI +static struct s3c64xx_spi_csinfo spi0_csi[] = { + [0] = { + .line = EXYNOS4_GPB(1), + .set_level = gpio_set_value, + .fb_delay = 0x2, + }, +}; + +static struct spi_board_info spi0_board_info[] __initdata = { + { + .modalias = "spidev", + .platform_data = NULL, + .max_speed_hz = 10*1000*1000, + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_0, + .controller_data = &spi0_csi[0], + } +}; + +#ifndef CONFIG_FB_S5P_LMS501KF03 +static struct s3c64xx_spi_csinfo spi1_csi[] = { + [0] = { + .line = EXYNOS4_GPB(5), + .set_level = gpio_set_value, + .fb_delay = 0x2, + }, +}; + +static struct spi_board_info spi1_board_info[] __initdata = { + { + .modalias = "spidev", + .platform_data = NULL, + .max_speed_hz = 10*1000*1000, + .bus_num = 1, + .chip_select = 0, + .mode = SPI_MODE_3, + .controller_data = &spi1_csi[0], + } +}; +#endif + +static struct s3c64xx_spi_csinfo spi2_csi[] = { + [0] = { + .line = EXYNOS4_GPC1(2), + .set_level = gpio_set_value, + .fb_delay = 0x2, + }, +}; + +static struct spi_board_info spi2_board_info[] __initdata = { + { + .modalias = "spidev", + .platform_data = NULL, + .max_speed_hz = 10*1000*1000, + .bus_num = 2, + .chip_select = 0, + .mode = SPI_MODE_0, + .controller_data = &spi2_csi[0], + } +}; +#endif + +#ifdef CONFIG_FB_S3C +#if defined(CONFIG_LCD_AMS369FG06) +static int lcd_power_on(struct lcd_device *ld, int enable) +{ + return 1; +} + +static int reset_lcd(struct lcd_device *ld) +{ + int err = 0; + + err = gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0"); + if (err) { + printk(KERN_ERR "failed to request GPX0 for " + "lcd reset control\n"); + return err; + } + gpio_set_value(EXYNOS4_GPX0(6), 0); + mdelay(1); + + gpio_set_value(EXYNOS4_GPX0(6), 1); + + gpio_free(EXYNOS4_GPX0(6)); + + return 1; +} + +static struct lcd_platform_data ams369fg06_platform_data = { + .reset = reset_lcd, + .power_on = lcd_power_on, + .lcd_enabled = 0, + .reset_delay = 100, /* 100ms */ +}; + +#define LCD_BUS_NUM 3 +#define DISPLAY_CS EXYNOS4_GPB(5) +#define DISPLAY_CLK EXYNOS4_GPB(4) +#define DISPLAY_SI EXYNOS4_GPB(7) + +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "ams369fg06", + .platform_data = (void *)&ams369fg06_platform_data, + .max_speed_hz = 1200000, + .bus_num = LCD_BUS_NUM, + .chip_select = 0, + .mode = SPI_MODE_3, + .controller_data = (void *)DISPLAY_CS, + } +}; + +static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = { + .sck = DISPLAY_CLK, + .mosi = DISPLAY_SI, + .miso = -1, + .num_chipselect = 1, +}; + +static struct platform_device s3c_device_spi_gpio = { + .name = "spi_gpio", + .id = LCD_BUS_NUM, + .dev = { + .parent = &s5p_device_fimd0.dev, + .platform_data = &ams369fg06_spi_gpio_data, + }, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win0 = { + .win_mode = { + .left_margin = 9, + .right_margin = 9, + .upper_margin = 5, + .lower_margin = 5, + .hsync_len = 2, + .vsync_len = 2, + .xres = 480, + .yres = 800, + }, + .virtual_x = 480, + .virtual_y = 1600, + .width = 48, + .height = 80, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win1 = { + .win_mode = { + .left_margin = 9, + .right_margin = 9, + .upper_margin = 5, + .lower_margin = 5, + .hsync_len = 2, + .vsync_len = 2, + .xres = 480, + .yres = 800, + }, + .virtual_x = 480, + .virtual_y = 1600, + .width = 48, + .height = 80, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win2 = { + .win_mode = { + .left_margin = 9, + .right_margin = 9, + .upper_margin = 5, + .lower_margin = 5, + .hsync_len = 2, + .vsync_len = 2, + .xres = 480, + .yres = 800, + }, + .virtual_x = 480, + .virtual_y = 1600, + .width = 48, + .height = 80, + .max_bpp = 32, + .default_bpp = 24, +}; +#elif defined(CONFIG_LCD_LMS501KF03) +static int lcd_power_on(struct lcd_device *ld, int enable) +{ + return 1; +} + +static int reset_lcd(struct lcd_device *ld) +{ + int err = 0; + + if (samsung_board_rev_is_0_1()) { + err = gpio_request_one(EXYNOS4212_GPM3(6), + GPIOF_OUT_INIT_HIGH, "GPM3"); + if (err) { + printk(KERN_ERR "failed to request GPM3 for " + "lcd reset control\n"); + return err; + } + gpio_set_value(EXYNOS4212_GPM3(6), 0); + mdelay(1); + + gpio_set_value(EXYNOS4212_GPM3(6), 1); + + gpio_free(EXYNOS4212_GPM3(6)); + } else { + err = gpio_request_one(EXYNOS4_GPX1(5), + GPIOF_OUT_INIT_HIGH, "GPX1"); + if (err) { + printk(KERN_ERR "failed to request GPX1 for " + "lcd reset control\n"); + return err; + } + gpio_set_value(EXYNOS4_GPX1(5), 0); + mdelay(1); + + gpio_set_value(EXYNOS4_GPX1(5), 1); + + gpio_free(EXYNOS4_GPX1(5)); + } + + return 1; +} + +static struct lcd_platform_data lms501kf03_platform_data = { + .reset = reset_lcd, + .power_on = lcd_power_on, + .lcd_enabled = 0, + .reset_delay = 100, /* 100ms */ +}; + +#define LCD_BUS_NUM 3 +#define DISPLAY_CS EXYNOS4_GPB(5) +#define DISPLAY_CLK EXYNOS4_GPB(4) +#define DISPLAY_SI EXYNOS4_GPB(7) + +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "lms501kf03", + .platform_data = (void *)&lms501kf03_platform_data, + .max_speed_hz = 1200000, + .bus_num = LCD_BUS_NUM, + .chip_select = 0, + .mode = SPI_MODE_3, + .controller_data = (void *)DISPLAY_CS, + } +}; + +static struct spi_gpio_platform_data lms501kf03_spi_gpio_data = { + .sck = DISPLAY_CLK, + .mosi = DISPLAY_SI, + .miso = -1, + .num_chipselect = 1, +}; + +static struct platform_device s3c_device_spi_gpio = { + .name = "spi_gpio", + .id = LCD_BUS_NUM, + .dev = { + .parent = &s5p_device_fimd0.dev, + .platform_data = &lms501kf03_spi_gpio_data, + }, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win0 = { + .win_mode = { + .left_margin = 8, /* HBPD */ + .right_margin = 8, /* HFPD */ + .upper_margin = 6, /* VBPD */ + .lower_margin = 6, /* VFPD */ + .hsync_len = 6, /* HSPW */ + .vsync_len = 4, /* VSPW */ + .xres = 480, + .yres = 800, + }, + .virtual_x = 480, + .virtual_y = 1600, + .width = 48, + .height = 80, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win1 = { + .win_mode = { + .left_margin = 8, /* HBPD */ + .right_margin = 8, /* HFPD */ + .upper_margin = 6, /* VBPD */ + .lower_margin = 6, /* VFPD */ + .hsync_len = 6, /* HSPW */ + .vsync_len = 4, /* VSPW */ + .xres = 480, + .yres = 800, + }, + .virtual_x = 480, + .virtual_y = 1600, + .width = 48, + .height = 80, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win2 = { + .win_mode = { + .left_margin = 8, /* HBPD */ + .right_margin = 8, /* HFPD */ + .upper_margin = 6, /* VBPD */ + .lower_margin = 6, /* VFPD */ + .hsync_len = 6, /* HSPW */ + .vsync_len = 4, /* VSPW */ + .xres = 480, + .yres = 800, + }, + .virtual_x = 480, + .virtual_y = 1600, + .width = 48, + .height = 80, + .max_bpp = 32, + .default_bpp = 24, +}; +#elif defined(CONFIG_LCD_WA101S) +static void lcd_wa101s_set_power(struct plat_lcd_data *pd, + unsigned int power) +{ + if (power) { +#if !defined(CONFIG_BACKLIGHT_PWM) + gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0"); + gpio_free(EXYNOS4_GPD0(1)); +#endif + } else { +#if !defined(CONFIG_BACKLIGHT_PWM) + gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0"); + gpio_free(EXYNOS4_GPD0(1)); +#endif + } +} + +static struct plat_lcd_data smdk4x12_lcd_wa101s_data = { + .set_power = lcd_wa101s_set_power, +}; + +static struct platform_device smdk4x12_lcd_wa101s = { + .name = "platform-lcd", + .dev.parent = &s5p_device_fimd0.dev, + .dev.platform_data = &smdk4x12_lcd_wa101s_data, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win0 = { + .win_mode = { + .left_margin = 80, + .right_margin = 48, + .upper_margin = 14, + .lower_margin = 3, + .hsync_len = 32, + .vsync_len = 5, + .xres = 1360, /* real size : 1366 */ + .yres = 768, + }, + .virtual_x = 1360, /* real size : 1366 */ + .virtual_y = 768 * 2, + .width = 223, + .height = 125, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win1 = { + .win_mode = { + .left_margin = 80, + .right_margin = 48, + .upper_margin = 14, + .lower_margin = 3, + .hsync_len = 32, + .vsync_len = 5, + .xres = 1360, /* real size : 1366 */ + .yres = 768, + }, + .virtual_x = 1360, /* real size : 1366 */ + .virtual_y = 768 * 2, + .width = 223, + .height = 125, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win2 = { + .win_mode = { + .left_margin = 80, + .right_margin = 48, + .upper_margin = 14, + .lower_margin = 3, + .hsync_len = 32, + .vsync_len = 5, + .xres = 1360, /* real size : 1366 */ + .yres = 768, + }, + .virtual_x = 1360, /* real size : 1366 */ + .virtual_y = 768 * 2, + .width = 223, + .height = 125, + .max_bpp = 32, + .default_bpp = 24, +}; + +#elif defined(CONFIG_LCD_LTE480WV) +static void lcd_lte480wv_set_power(struct plat_lcd_data *pd, + unsigned int power) +{ + if (power) { +#if !defined(CONFIG_BACKLIGHT_PWM) + gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0"); + gpio_free(EXYNOS4_GPD0(1)); +#endif + /* fire nRESET on power up */ + gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0"); + mdelay(100); + + gpio_set_value(EXYNOS4_GPX0(6), 0); + mdelay(10); + + gpio_set_value(EXYNOS4_GPX0(6), 1); + mdelay(10); + + gpio_free(EXYNOS4_GPX0(6)); + } else { +#if !defined(CONFIG_BACKLIGHT_PWM) + gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0"); + gpio_free(EXYNOS4_GPD0(1)); +#endif + } +} + +static struct plat_lcd_data smdk4x12_lcd_lte480wv_data = { + .set_power = lcd_lte480wv_set_power, +}; + +static struct platform_device smdk4x12_lcd_lte480wv = { + .name = "platform-lcd", + .dev.parent = &s5p_device_fimd0.dev, + .dev.platform_data = &smdk4x12_lcd_lte480wv_data, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win0 = { + .win_mode = { + .left_margin = 13, + .right_margin = 8, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, + }, + .virtual_x = 800, + .virtual_y = 960, + .width = 104, + .height = 62, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win1 = { + .win_mode = { + .left_margin = 13, + .right_margin = 8, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, + }, + .virtual_x = 800, + .virtual_y = 960, + .width = 104, + .height = 62, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win2 = { + .win_mode = { + .left_margin = 13, + .right_margin = 8, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, + }, + .virtual_x = 800, + .virtual_y = 960, + .width = 104, + .height = 62, + .max_bpp = 32, + .default_bpp = 24, +}; +#elif defined(CONFIG_LCD_MIPI_S6E63M0) +static void mipi_lcd_set_power(struct plat_lcd_data *pd, + unsigned int power) +{ + gpio_request_one(EXYNOS4_GPX2(7), GPIOF_OUT_INIT_HIGH, "GPX2"); + + mdelay(100); + if (power) { + /* fire nRESET on power up */ + gpio_set_value(EXYNOS4_GPX2(7), 0); + mdelay(100); + gpio_set_value(EXYNOS4_GPX2(7), 1); + mdelay(100); + gpio_free(EXYNOS4_GPX2(7)); + } else { + /* fire nRESET on power off */ + gpio_set_value(EXYNOS4_GPX2(7), 0); + mdelay(100); + gpio_set_value(EXYNOS4_GPX2(7), 1); + mdelay(100); + gpio_free(EXYNOS4_GPX2(7)); + } +} + +static struct plat_lcd_data smdk4x12_mipi_lcd_data = { + .set_power = mipi_lcd_set_power, +}; + +static struct platform_device smdk4x12_mipi_lcd = { + .name = "platform-lcd", + .dev.parent = &s5p_device_fimd0.dev, + .dev.platform_data = &smdk4x12_mipi_lcd_data, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win0 = { + .win_mode = { + .left_margin = 0x16, + .right_margin = 0x16, + .upper_margin = 0x1, + .lower_margin = 0x28, + .hsync_len = 0x2, + .vsync_len = 0x3, + .xres = 480, + .yres = 800, + }, + .virtual_x = 480, + .virtual_y = 1600, + .width = 48, + .height = 80, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win1 = { + .win_mode = { + .left_margin = 0x16, + .right_margin = 0x16, + .upper_margin = 0x1, + .lower_margin = 0x28, + .hsync_len = 0x2, + .vsync_len = 0x3, + .xres = 480, + .yres = 800, + }, + .virtual_x = 480, + .virtual_y = 1600, + .width = 48, + .height = 80, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_pd_win smdk4x12_fb_win2 = { + .win_mode = { + .left_margin = 0x16, + .right_margin = 0x16, + .upper_margin = 0x1, + .lower_margin = 0x28, + .hsync_len = 0x2, + .vsync_len = 0x3, + .xres = 480, + .yres = 800, + }, + .virtual_x = 480, + .virtual_y = 1600, + .width = 48, + .height = 80, + .max_bpp = 32, + .default_bpp = 24, +}; +#endif + +static struct s3c_fb_platdata smdk4x12_lcd0_pdata __initdata = { +#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_WA101S) || \ + defined(CONFIG_LCD_LTE480WV) || defined(CONFIG_LCD_LMS501KF03) || \ + defined(CONFIG_LCD_MIPI_S6E63M0) + .win[0] = &smdk4x12_fb_win0, + .win[1] = &smdk4x12_fb_win1, + .win[2] = &smdk4x12_fb_win2, +#endif + .default_win = 2, + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, +#if defined(CONFIG_LCD_AMS369FG06) + .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN | + VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, +#elif defined(CONFIG_LCD_LMS501KF03) + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, +#elif defined(CONFIG_LCD_WA101S) + .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_HSYNC | + VIDCON1_INV_VSYNC, +#elif defined(CONFIG_LCD_LTE480WV) + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, +#endif + .setup_gpio = exynos4_fimd0_gpio_setup_24bpp, +}; +#endif + +#ifdef CONFIG_FB_S5P +#ifdef CONFIG_FB_S5P_LMS501KF03 +static struct s3c_platform_fb lms501kf03_data __initdata = { + .hw_ver = 0x70, + .clk_name = "sclk_lcd", + .nr_wins = 5, + .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW, + .swap = FB_SWAP_HWORD | FB_SWAP_WORD, +}; + +#define LCD_BUS_NUM 3 +#define DISPLAY_CS EXYNOS4_GPB(5) +#define DISPLAY_CLK EXYNOS4_GPB(4) +#define DISPLAY_SI EXYNOS4_GPB(7) + +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "lms501kf03", + .platform_data = NULL, + .max_speed_hz = 1200000, + .bus_num = LCD_BUS_NUM, + .chip_select = 0, + .mode = SPI_MODE_3, + .controller_data = (void *)DISPLAY_CS, + } +}; +static struct spi_gpio_platform_data lms501kf03_spi_gpio_data = { + .sck = DISPLAY_CLK, + .mosi = DISPLAY_SI, + .miso = -1, + .num_chipselect = 1, +}; + +static struct platform_device s3c_device_spi_gpio = { + .name = "spi_gpio", + .id = LCD_BUS_NUM, + .dev = { + .parent = &s3c_device_fb.dev, + .platform_data = &lms501kf03_spi_gpio_data, + }, +}; +#elif defined(CONFIG_FB_S5P_DUMMY_MIPI_LCD) +#define LCD_BUS_NUM 3 +#define DISPLAY_CS EXYNOS4_GPB(5) +#define DISPLAY_CLK EXYNOS4_GPB(4) +#define DISPLAY_SI EXYNOS4_GPB(7) + +static struct s3cfb_lcd dummy_mipi_lcd = { + .width = 480, + .height = 800, + .bpp = 24, + + .freq = 60, + + .timing = { + .h_fp = 0x16, + .h_bp = 0x16, + .h_sw = 0x2, + .v_fp = 0x28, + .v_fpe = 2, + .v_bp = 0x1, + .v_bpe = 1, + .v_sw = 3, + .cmd_allow_len = 0x4, + }, + + .polarity = { + .rise_vclk = 0, + .inv_hsync = 0, + .inv_vsync = 0, + .inv_vden = 0, + }, +}; + +static struct s3c_platform_fb fb_platform_data __initdata = { + .hw_ver = 0x70, + .clk_name = "sclk_lcd", + .nr_wins = 5, + .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW, + .swap = FB_SWAP_HWORD | FB_SWAP_WORD, +}; + +static void lcd_cfg_gpio(void) +{ + return; +} + +static int reset_lcd(void) +{ + int err = 0; + + /* fire nRESET on power off */ + err = gpio_request(EXYNOS4_GPX3(1), "GPX3"); + if (err) { + printk(KERN_ERR "failed to request GPX0 for lcd reset control\n"); + return err; + } + +#ifdef CONFIG_CPU_EXYNOS4212 + gpio_direction_output(EXYNOS4_GPX2(7), 1); + mdelay(100); + + gpio_set_value(EXYNOS4_GPX2(7), 0); + mdelay(100); + gpio_set_value(EXYNOS4_GPX2(7), 1); + mdelay(100); + gpio_free(EXYNOS4_GPX2(7)); +#else + gpio_direction_output(EXYNOS4_GPX3(1), 1); + mdelay(100); + + gpio_set_value(EXYNOS4_GPX3(1), 0); + mdelay(100); + gpio_set_value(EXYNOS4_GPX3(1), 1); + mdelay(100); + gpio_free(EXYNOS4_GPX3(1)); +#endif + return 0; +} + +static int lcd_power_on(void *pdev, int enable) +{ + return 1; +} + +static void __init mipi_fb_init(void) +{ + struct s5p_platform_dsim *dsim_pd = NULL; + struct mipi_ddi_platform_data *mipi_ddi_pd = NULL; + struct dsim_lcd_config *dsim_lcd_info = NULL; + + /* gpio pad configuration for rgb and spi interface. */ + lcd_cfg_gpio(); + + /* + * register lcd panel data. + */ + dsim_pd = (struct s5p_platform_dsim *) + s5p_device_dsim.dev.platform_data; + + strcpy(dsim_pd->lcd_panel_name, "dummy_mipi_lcd"); + + dsim_lcd_info = dsim_pd->dsim_lcd_info; + dsim_lcd_info->lcd_panel_info = (void *)&dummy_mipi_lcd; + + mipi_ddi_pd = (struct mipi_ddi_platform_data *) + dsim_lcd_info->mipi_ddi_pd; + mipi_ddi_pd->lcd_reset = reset_lcd; + mipi_ddi_pd->lcd_power_on = lcd_power_on; + + platform_device_register(&s5p_device_dsim); + + s3cfb_set_platdata(&fb_platform_data); + + printk(KERN_INFO "platform data of %s lcd panel has been registered.\n", + dsim_pd->lcd_panel_name); +} +#endif +#endif + +static int exynos4_notifier_call(struct notifier_block *this, + unsigned long code, void *_cmd) +{ + int mode = 0; + + if ((code == SYS_RESTART) && _cmd) + if (!strcmp((char *)_cmd, "recovery")) + mode = 0xf; + + __raw_writel(mode, REG_INFORM4); + + return NOTIFY_DONE; +} + +static struct notifier_block exynos4_reboot_notifier = { + .notifier_call = exynos4_notifier_call, +}; + +#ifdef CONFIG_EXYNOS4_DEV_DWMCI +static void exynos_dwmci_cfg_gpio(int width) +{ + unsigned int gpio; + + for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2); + } + + switch (width) { + case MMC_BUS_WIDTH_8: + for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); + s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2); + } + case MMC_BUS_WIDTH_4: + for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); + s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2); + } + break; + case MMC_BUS_WIDTH_1: + gpio = EXYNOS4_GPK0(3); + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); + s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2); + default: + break; + } +} + +static struct dw_mci_board exynos_dwmci_pdata __initdata = { + .num_slots = 1, + .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION | DW_MCI_QUIRK_HIGHSPEED, + .bus_hz = 100 * 1000 * 1000, + .caps = MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR | + MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23, + .fifo_depth = 0x80, + .detect_delay_ms = 200, + .hclk_name = "dwmci", + .cclk_name = "sclk_dwmci", + .cfg_gpio = exynos_dwmci_cfg_gpio, +}; +#endif + +#ifdef CONFIG_S3C_DEV_HSMMC +static struct s3c_sdhci_platdata smdk4x12_hsmmc0_pdata __initdata = { + .cd_type = S3C_SDHCI_CD_INTERNAL, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT + .max_width = 8, + .host_caps = MMC_CAP_8_BIT_DATA, +#endif +}; +#endif + +#ifdef CONFIG_S3C_DEV_HSMMC1 +static struct s3c_sdhci_platdata smdk4x12_hsmmc1_pdata __initdata = { + .cd_type = S3C_SDHCI_CD_INTERNAL, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +}; +#endif + +#ifdef CONFIG_S3C_DEV_HSMMC2 +static struct s3c_sdhci_platdata smdk4x12_hsmmc2_pdata __initdata = { + .cd_type = S3C_SDHCI_CD_INTERNAL, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT + .max_width = 8, + .host_caps = MMC_CAP_8_BIT_DATA, +#endif +}; +#endif + +#ifdef CONFIG_S3C_DEV_HSMMC3 +static struct s3c_sdhci_platdata smdk4x12_hsmmc3_pdata __initdata = { + .cd_type = S3C_SDHCI_CD_INTERNAL, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +}; +#endif + +#ifdef CONFIG_S5P_DEV_MSHC +static struct s3c_mshci_platdata exynos4_mshc_pdata __initdata = { + .cd_type = S3C_MSHCI_CD_PERMANENT, + .has_wp_gpio = true, + .wp_gpio = 0xffffffff, +#if defined(CONFIG_EXYNOS4_MSHC_8BIT) && \ + defined(CONFIG_EXYNOS4_MSHC_DDR) + .max_width = 8, + .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR | + MMC_CAP_UHS_DDR50, +#elif defined(CONFIG_EXYNOS4_MSHC_8BIT) + .max_width = 8, + .host_caps = MMC_CAP_8_BIT_DATA, +#elif defined(CONFIG_EXYNOS4_MSHC_DDR) + .host_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50, +#endif +}; +#endif + +#ifdef CONFIG_USB_EHCI_S5P +static struct s5p_ehci_platdata smdk4x12_ehci_pdata; + +static void __init smdk4x12_ehci_init(void) +{ + struct s5p_ehci_platdata *pdata = &smdk4x12_ehci_pdata; + + s5p_ehci_set_platdata(pdata); +} +#endif + +#ifdef CONFIG_USB_OHCI_S5P +static struct s5p_ohci_platdata smdk4x12_ohci_pdata; + +static void __init smdk4x12_ohci_init(void) +{ + struct s5p_ohci_platdata *pdata = &smdk4x12_ohci_pdata; + + s5p_ohci_set_platdata(pdata); +} +#endif + +/* USB GADGET */ +#ifdef CONFIG_USB_GADGET +static struct s5p_usbgadget_platdata smdk4x12_usbgadget_pdata; + +static void __init smdk4x12_usbgadget_init(void) +{ + struct s5p_usbgadget_platdata *pdata = &smdk4x12_usbgadget_pdata; + + s5p_usbgadget_set_platdata(pdata); +} +#endif + +static struct regulator_consumer_supply max8952_supply = + REGULATOR_SUPPLY("vdd_mif", NULL); + +static struct regulator_init_data max8952_init_data = { + .constraints = { + .name = "vdd_mif range", + .min_uV = 800000, + .max_uV = 1100000, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .state_mem = { + .uV = 1100000, + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max8952_supply, +}; + +static struct max8649_platform_data exynos4_max8952_info = { + .mode = 1, /* VID1 = 0, VID0 = 1 */ + .extclk = 0, + .ramp_timing = MAX8649_RAMP_32MV, + .regulator = &max8952_init_data, +}; + +/* max8997 */ +static struct regulator_consumer_supply max8997_buck1 = + REGULATOR_SUPPLY("vdd_arm", NULL); + +static struct regulator_consumer_supply max8997_buck2 = + REGULATOR_SUPPLY("vdd_int", NULL); + +static struct regulator_consumer_supply max8997_buck3 = + REGULATOR_SUPPLY("vdd_g3d", NULL); + +static struct regulator_consumer_supply __initdata ldo2_consumer = + REGULATOR_SUPPLY("vdd_ldo2", NULL); + +static struct regulator_consumer_supply __initdata ldo3_consumer = + REGULATOR_SUPPLY("vdd_ldo3", NULL); + +static struct regulator_consumer_supply __initdata ldo4_consumer = + REGULATOR_SUPPLY("vdd_ldo4", NULL); + +static struct regulator_consumer_supply __initdata ldo5_consumer = + REGULATOR_SUPPLY("vdd_ldo5", NULL); + +static struct regulator_consumer_supply __initdata ldo6_consumer = + REGULATOR_SUPPLY("vdd_ldo6", NULL); + +static struct regulator_consumer_supply __initdata ldo7_consumer = + REGULATOR_SUPPLY("vdd_ldo7", NULL); + +static struct regulator_consumer_supply __initdata ldo8_consumer = + REGULATOR_SUPPLY("vdd_ldo8", NULL); + +static struct regulator_consumer_supply __initdata ldo9_consumer = + REGULATOR_SUPPLY("vdd_ldo9", NULL); + +static struct regulator_consumer_supply __initdata ldo10_consumer = + REGULATOR_SUPPLY("vdd_ldo10", NULL); + +static struct regulator_consumer_supply __initdata ldo11_consumer = + REGULATOR_SUPPLY("vdd_ldo11", NULL); + +static struct regulator_consumer_supply __initdata ldo12_consumer = + REGULATOR_SUPPLY("vdd_adc", NULL); + +static struct regulator_consumer_supply __initdata ldo14_consumer = + REGULATOR_SUPPLY("vdd_ldo14", NULL); + +static struct regulator_consumer_supply __initdata ldo21_consumer = + REGULATOR_SUPPLY("vdd_ldo21", NULL); + +static struct regulator_init_data __initdata max8997_ldo2_data = { + .constraints = { + .name = "vdd_ldo2 range", + .min_uV = 1000000, + .max_uV = 1000000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo2_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo3_data = { + .constraints = { + .name = "vdd_ldo3 range", + .min_uV = 1000000, + .max_uV = 1000000, + .apply_uV = 1, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo3_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo4_data = { + .constraints = { + .name = "vdd_ldo4 range", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = 1, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo4_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo5_data = { + .constraints = { + .name = "vdd_ldo5 range", + .min_uV = 1000000, + .max_uV = 1000000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo5_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo6_data = { + .constraints = { + .name = "vdd_ldo6 range", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo6_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo7_data = { + .constraints = { + .name = "vdd_ldo7 range", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo7_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo8_data = { + .constraints = { + .name = "vdd_ldo8 range", + .min_uV = 3300000, + .max_uV = 3300000, + .apply_uV = 1, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo8_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo9_data = { + .constraints = { + .name = "vdd_ldo9 range", + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo9_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo10_data = { + .constraints = { + .name = "vdd_ldo10 range", + .min_uV = 1000000, + .max_uV = 1000000, + .apply_uV = 1, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo10_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo11_data = { + .constraints = { + .name = "vdd_ldo11 range", + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo11_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo12_data = { + .constraints = { + .name = "vdd_adc range", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo12_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo14_data = { + .constraints = { + .name = "vdd_ldo14 range", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo14_consumer, +}; + +static struct regulator_init_data __initdata max8997_ldo21_data = { + .constraints = { + .name = "vdd_ldo21 range", + .min_uV = 1200000, + .max_uV = 1200000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ldo21_consumer, +}; + +static struct regulator_init_data __initdata max8997_buck1_data = { + .constraints = { + .name = "vdd_arm range", + .min_uV = 800000, + .max_uV = 1500000, + .always_on = 1, + .boot_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max8997_buck1, +}; + +static struct regulator_init_data __initdata max8997_buck2_data = { + .constraints = { + .name = "vdd_int range", + .min_uV = 800000, + .max_uV = 1150000, + .always_on = 1, + .boot_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max8997_buck2, +}; + +static struct regulator_init_data __initdata max8997_buck3_data = { + .constraints = { + .name = "vdd_g3d range", + .min_uV = 800000, + .max_uV = 1200000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max8997_buck3, +}; + +static struct max8997_regulator_data __initdata max8997_regulators[] = { + { MAX8997_LDO2, &max8997_ldo2_data, }, + { MAX8997_LDO3, &max8997_ldo3_data, }, + { MAX8997_LDO4, &max8997_ldo4_data, }, + { MAX8997_LDO5, &max8997_ldo5_data, }, + { MAX8997_LDO6, &max8997_ldo6_data, }, + { MAX8997_LDO7, &max8997_ldo7_data, }, + { MAX8997_LDO8, &max8997_ldo8_data, }, + { MAX8997_LDO9, &max8997_ldo9_data, }, + { MAX8997_LDO10, &max8997_ldo10_data, }, + { MAX8997_LDO11, &max8997_ldo11_data, }, + { MAX8997_LDO12, &max8997_ldo12_data, }, + { MAX8997_LDO14, &max8997_ldo14_data, }, + { MAX8997_LDO21, &max8997_ldo21_data, }, + { MAX8997_BUCK1, &max8997_buck1_data, }, + { MAX8997_BUCK2, &max8997_buck2_data, }, + { MAX8997_BUCK3, &max8997_buck3_data, }, +}; + +static struct max8997_platform_data __initdata exynos4_max8997_info = { + .num_regulators = ARRAY_SIZE(max8997_regulators), + .regulators = max8997_regulators, + + .buck1_voltage[0] = 1300000, /* 1.25V */ + .buck1_voltage[1] = 1100000, /* 1.1V */ + .buck1_voltage[2] = 1100000, /* 1.1V */ + .buck1_voltage[3] = 1100000, /* 1.1V */ + .buck1_voltage[4] = 1100000, /* 1.1V */ + .buck1_voltage[5] = 1100000, /* 1.1V */ + .buck1_voltage[6] = 1000000, /* 1.0V */ + .buck1_voltage[7] = 950000, /* 0.95V */ + + .buck2_voltage[0] = 1037500, /* 1.0375V */ + .buck2_voltage[1] = 1000000, /* 1.0V */ + .buck2_voltage[2] = 950000, /* 0.95V */ + .buck2_voltage[3] = 900000, /* 0.9V */ + .buck2_voltage[4] = 1000000, /* 1.0V */ + .buck2_voltage[5] = 1000000, /* 1.0V */ + .buck2_voltage[6] = 950000, /* 0.95V */ + .buck2_voltage[7] = 900000, /* 0.9V */ + + .buck5_voltage[0] = 1100000, /* 1.1V */ + .buck5_voltage[1] = 1100000, /* 1.1V */ + .buck5_voltage[2] = 1100000, /* 1.1V */ + .buck5_voltage[3] = 1100000, /* 1.1V */ + .buck5_voltage[4] = 1100000, /* 1.1V */ + .buck5_voltage[5] = 1100000, /* 1.1V */ + .buck5_voltage[6] = 1100000, /* 1.1V */ + .buck5_voltage[7] = 1100000, /* 1.1V */ +}; + +/* max77686 */ +static struct regulator_consumer_supply max77686_buck1 = +REGULATOR_SUPPLY("vdd_mif", NULL); + +static struct regulator_consumer_supply max77686_buck2 = +REGULATOR_SUPPLY("vdd_arm", NULL); + +static struct regulator_consumer_supply max77686_buck3 = +REGULATOR_SUPPLY("vdd_int", NULL); + +static struct regulator_consumer_supply max77686_buck4 = +REGULATOR_SUPPLY("vdd_g3d", NULL); + +static struct regulator_consumer_supply max77686_ldo11_consumer = +REGULATOR_SUPPLY("vdd_ldo11", NULL); + +static struct regulator_consumer_supply max77686_ldo14_consumer = +REGULATOR_SUPPLY("vdd_ldo14", NULL); + +static struct regulator_init_data max77686_buck1_data = { + .constraints = { + .name = "vdd_mif range", + .min_uV = 800000, + .max_uV = 1050000, + .always_on = 1, + .boot_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max77686_buck1, +}; + +static struct regulator_init_data max77686_buck2_data = { + .constraints = { + .name = "vdd_arm range", + .min_uV = 800000, + .max_uV = 1350000, + .always_on = 1, + .boot_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max77686_buck2, +}; + +static struct regulator_init_data max77686_buck3_data = { + .constraints = { + .name = "vdd_int range", + .min_uV = 800000, + .max_uV = 1150000, + .always_on = 1, + .boot_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max77686_buck3, +}; + +static struct regulator_init_data max77686_buck4_data = { + .constraints = { + .name = "vdd_g3d range", + .min_uV = 850000, + .max_uV = 1200000, + .boot_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max77686_buck4, +}; + +static struct regulator_init_data max77686_ldo11_data = { + .constraints = { + .name = "vdd_ldo11 range", + .min_uV = 1900000, + .max_uV = 1900000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max77686_ldo11_consumer, +}; + +static struct regulator_init_data max77686_ldo14_data = { + .constraints = { + .name = "vdd_ldo14 range", + .min_uV = 1900000, + .max_uV = 1900000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &max77686_ldo14_consumer, +}; + +static struct max77686_regulator_data max77686_regulators[] = { + {MAX77686_BUCK1, &max77686_buck1_data,}, + {MAX77686_BUCK2, &max77686_buck2_data,}, + {MAX77686_BUCK3, &max77686_buck3_data,}, + {MAX77686_BUCK4, &max77686_buck4_data,}, + {MAX77686_LDO11, &max77686_ldo11_data,}, + {MAX77686_LDO14, &max77686_ldo14_data,}, +}; + +struct max77686_opmode_data max77686_opmode_data[MAX77686_REG_MAX] = { + [MAX77686_LDO11] = {MAX77686_LDO11, MAX77686_OPMODE_STANDBY}, + [MAX77686_LDO14] = {MAX77686_LDO14, MAX77686_OPMODE_STANDBY}, + [MAX77686_BUCK1] = {MAX77686_BUCK1, MAX77686_OPMODE_STANDBY}, + [MAX77686_BUCK2] = {MAX77686_BUCK2, MAX77686_OPMODE_STANDBY}, + [MAX77686_BUCK3] = {MAX77686_BUCK3, MAX77686_OPMODE_STANDBY}, + [MAX77686_BUCK4] = {MAX77686_BUCK4, MAX77686_OPMODE_STANDBY}, +}; + +static struct max77686_platform_data exynos4_max77686_info = { + .num_regulators = ARRAY_SIZE(max77686_regulators), + .regulators = max77686_regulators, + .irq_gpio = 0, + .irq_base = 0, + .wakeup = 0, + + .opmode_data = max77686_opmode_data, + .ramp_rate = MAX77686_RAMP_RATE_27MV, + + .buck2_voltage[0] = 1300000, /* 1.3V */ + .buck2_voltage[1] = 1000000, /* 1.0V */ + .buck2_voltage[2] = 950000, /* 0.95V */ + .buck2_voltage[3] = 900000, /* 0.9V */ + .buck2_voltage[4] = 1000000, /* 1.0V */ + .buck2_voltage[5] = 1000000, /* 1.0V */ + .buck2_voltage[6] = 950000, /* 0.95V */ + .buck2_voltage[7] = 900000, /* 0.9V */ + + .buck3_voltage[0] = 1037500, /* 1.0375V */ + .buck3_voltage[1] = 1000000, /* 1.0V */ + .buck3_voltage[2] = 950000, /* 0.95V */ + .buck3_voltage[3] = 900000, /* 0.9V */ + .buck3_voltage[4] = 1000000, /* 1.0V */ + .buck3_voltage[5] = 1000000, /* 1.0V */ + .buck3_voltage[6] = 950000, /* 0.95V */ + .buck3_voltage[7] = 900000, /* 0.9V */ + + .buck4_voltage[0] = 1100000, /* 1.1V */ + .buck4_voltage[1] = 1000000, /* 1.0V */ + .buck4_voltage[2] = 950000, /* 0.95V */ + .buck4_voltage[3] = 900000, /* 0.9V */ + .buck4_voltage[4] = 1000000, /* 1.0V */ + .buck4_voltage[5] = 1000000, /* 1.0V */ + .buck4_voltage[6] = 950000, /* 0.95V */ + .buck4_voltage[7] = 900000, /* 0.9V */ +}; +#ifdef CONFIG_REGULATOR_S5M8767 +/* S5M8767 Regulator */ +static int s5m_cfg_irq(void) +{ + /* AP_PMIC_IRQ: EINT26 */ + s3c_gpio_cfgpin(EXYNOS4_GPX3(2), S3C_GPIO_SFN(0xF)); + s3c_gpio_setpull(EXYNOS4_GPX3(2), S3C_GPIO_PULL_UP); + return 0; +} +static struct regulator_consumer_supply s5m8767_buck1_consumer = + REGULATOR_SUPPLY("vdd_mif", NULL); + +static struct regulator_consumer_supply s5m8767_buck2_consumer = + REGULATOR_SUPPLY("vdd_arm", NULL); + +static struct regulator_consumer_supply s5m8767_buck3_consumer = + REGULATOR_SUPPLY("vdd_int", NULL); + +static struct regulator_consumer_supply s5m8767_buck4_consumer = + REGULATOR_SUPPLY("vdd_g3d", NULL); + +static struct regulator_init_data s5m8767_buck1_data = { + .constraints = { + .name = "vdd_mif range", + .min_uV = 800000, + .max_uV = 1100000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &s5m8767_buck1_consumer, +}; + +static struct regulator_init_data s5m8767_buck2_data = { + .constraints = { + .name = "vdd_arm range", + .min_uV = 800000, + .max_uV = 1350000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &s5m8767_buck2_consumer, +}; + +static struct regulator_init_data s5m8767_buck3_data = { + .constraints = { + .name = "vdd_int range", + .min_uV = 800000, + .max_uV = 1150000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .state_mem = { + .uV = 1100000, + .mode = REGULATOR_MODE_NORMAL, + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &s5m8767_buck3_consumer, +}; + +static struct regulator_init_data s5m8767_buck4_data = { + .constraints = { + .name = "vdd_g3d range", + .min_uV = 850000, + .max_uV = 1200000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &s5m8767_buck4_consumer, +}; + +static struct s5m_regulator_data pegasus_regulators[] = { + { S5M8767_BUCK1, &s5m8767_buck1_data }, + { S5M8767_BUCK2, &s5m8767_buck2_data }, + { S5M8767_BUCK3, &s5m8767_buck3_data }, + { S5M8767_BUCK4, &s5m8767_buck4_data }, +}; + +static struct s5m_platform_data exynos4_s5m8767_pdata = { + .device_type = S5M8767X, + .irq_base = IRQ_BOARD_START, + .num_regulators = ARRAY_SIZE(pegasus_regulators), + .regulators = pegasus_regulators, + .cfg_pmic_irq = s5m_cfg_irq, + .wakeup = 1, + .opmode_data = s5m8767_opmode_data, + .wtsr_smpl = 1, + + .buck2_voltage[0] = 1250000, + .buck2_voltage[1] = 1200000, + .buck2_voltage[2] = 1150000, + .buck2_voltage[3] = 1100000, + .buck2_voltage[4] = 1050000, + .buck2_voltage[5] = 1000000, + .buck2_voltage[6] = 950000, + .buck2_voltage[7] = 900000, + + .buck3_voltage[0] = 1100000, + .buck3_voltage[1] = 1000000, + .buck3_voltage[2] = 950000, + .buck3_voltage[3] = 900000, + .buck3_voltage[4] = 1100000, + .buck3_voltage[5] = 1000000, + .buck3_voltage[6] = 950000, + .buck3_voltage[7] = 900000, + + .buck4_voltage[0] = 1200000, + .buck4_voltage[1] = 1150000, + .buck4_voltage[2] = 1200000, + .buck4_voltage[3] = 1100000, + .buck4_voltage[4] = 1100000, + .buck4_voltage[5] = 1100000, + .buck4_voltage[6] = 1100000, + .buck4_voltage[7] = 1100000, + + .buck_default_idx = 3, + .buck_gpios[0] = EXYNOS4_GPX2(3), + .buck_gpios[1] = EXYNOS4_GPX2(4), + .buck_gpios[2] = EXYNOS4_GPX2(5), + + .buck_ramp_delay = 25, + .buck2_ramp_enable = true, + .buck3_ramp_enable = true, + .buck4_ramp_enable = true, +}; +/* End of S5M8767 */ +#endif + +#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS +static struct regulator_consumer_supply mipi_csi_fixed_voltage_supplies[] = { + REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.0"), + REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.1"), +}; + +static struct regulator_init_data mipi_csi_fixed_voltage_init_data = { + .constraints = { + .always_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(mipi_csi_fixed_voltage_supplies), + .consumer_supplies = mipi_csi_fixed_voltage_supplies, +}; + +static struct fixed_voltage_config mipi_csi_fixed_voltage_config = { + .supply_name = "DC_5V", + .microvolts = 5000000, + .gpio = -EINVAL, + .init_data = &mipi_csi_fixed_voltage_init_data, +}; + +static struct platform_device mipi_csi_fixed_voltage = { + .name = "reg-fixed-voltage", + .id = 3, + .dev = { + .platform_data = &mipi_csi_fixed_voltage_config, + }, +}; +#endif + +#ifdef CONFIG_VIDEO_M5MOLS +static struct regulator_consumer_supply m5mols_fixed_voltage_supplies[] = { + REGULATOR_SUPPLY("core", NULL), + REGULATOR_SUPPLY("dig_18", NULL), + REGULATOR_SUPPLY("d_sensor", NULL), + REGULATOR_SUPPLY("dig_28", NULL), + REGULATOR_SUPPLY("a_sensor", NULL), + REGULATOR_SUPPLY("dig_12", NULL), +}; + +static struct regulator_init_data m5mols_fixed_voltage_init_data = { + .constraints = { + .always_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(m5mols_fixed_voltage_supplies), + .consumer_supplies = m5mols_fixed_voltage_supplies, +}; + +static struct fixed_voltage_config m5mols_fixed_voltage_config = { + .supply_name = "CAM_SENSOR", + .microvolts = 1800000, + .gpio = -EINVAL, + .init_data = &m5mols_fixed_voltage_init_data, +}; + +static struct platform_device m5mols_fixed_voltage = { + .name = "reg-fixed-voltage", + .id = 4, + .dev = { + .platform_data = &m5mols_fixed_voltage_config, + }, +}; +#endif + +static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = { + REGULATOR_SUPPLY("AVDD2", "1-001a"), + REGULATOR_SUPPLY("CPVDD", "1-001a"), +}; + +static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = { + REGULATOR_SUPPLY("SPKVDD1", "1-001a"), + REGULATOR_SUPPLY("SPKVDD2", "1-001a"), +}; + +static struct regulator_consumer_supply wm8994_fixed_voltage2_supplies = + REGULATOR_SUPPLY("DBVDD", "1-001a"); + +static struct regulator_init_data wm8994_fixed_voltage0_init_data = { + .constraints = { + .always_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies), + .consumer_supplies = wm8994_fixed_voltage0_supplies, +}; + +static struct regulator_init_data wm8994_fixed_voltage1_init_data = { + .constraints = { + .always_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies), + .consumer_supplies = wm8994_fixed_voltage1_supplies, +}; + +static struct regulator_init_data wm8994_fixed_voltage2_init_data = { + .constraints = { + .always_on = 1, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &wm8994_fixed_voltage2_supplies, +}; + +static struct fixed_voltage_config wm8994_fixed_voltage0_config = { + .supply_name = "VDD_1.8V", + .microvolts = 1800000, + .gpio = -EINVAL, + .init_data = &wm8994_fixed_voltage0_init_data, +}; + +static struct fixed_voltage_config wm8994_fixed_voltage1_config = { + .supply_name = "DC_5V", + .microvolts = 5000000, + .gpio = -EINVAL, + .init_data = &wm8994_fixed_voltage1_init_data, +}; + +static struct fixed_voltage_config wm8994_fixed_voltage2_config = { + .supply_name = "VDD_3.3V", + .microvolts = 3300000, + .gpio = -EINVAL, + .init_data = &wm8994_fixed_voltage2_init_data, +}; + +static struct platform_device wm8994_fixed_voltage0 = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &wm8994_fixed_voltage0_config, + }, +}; + +static struct platform_device wm8994_fixed_voltage1 = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &wm8994_fixed_voltage1_config, + }, +}; + +static struct platform_device wm8994_fixed_voltage2 = { + .name = "reg-fixed-voltage", + .id = 2, + .dev = { + .platform_data = &wm8994_fixed_voltage2_config, + }, +}; + +static struct regulator_consumer_supply wm8994_avdd1_supply = + REGULATOR_SUPPLY("AVDD1", "1-001a"); + +static struct regulator_consumer_supply wm8994_dcvdd_supply = + REGULATOR_SUPPLY("DCVDD", "1-001a"); + +static struct regulator_init_data wm8994_ldo1_data = { + .constraints = { + .name = "AVDD1", + }, + .num_consumer_supplies = 1, + .consumer_supplies = &wm8994_avdd1_supply, +}; + +static struct regulator_init_data wm8994_ldo2_data = { + .constraints = { + .name = "DCVDD", + }, + .num_consumer_supplies = 1, + .consumer_supplies = &wm8994_dcvdd_supply, +}; + +static struct wm8994_pdata wm8994_platform_data = { + /* configure gpio1 function: 0x0001(Logic level input/output) */ + .gpio_defaults[0] = 0x0001, + /* If the i2s0 and i2s2 is enabled simultaneously */ + .gpio_defaults[7] = 0x8100, /* GPIO8 DACDAT3 in */ + .gpio_defaults[8] = 0x0100, /* GPIO9 ADCDAT3 out */ + .gpio_defaults[9] = 0x0100, /* GPIO10 LRCLK3 out */ + .gpio_defaults[10] = 0x0100,/* GPIO11 BCLK3 out */ + .ldo[0] = { 0, NULL, &wm8994_ldo1_data }, + .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, +}; + +static struct i2c_board_info i2c_devs0[] __initdata = { +#ifdef CONFIG_REGULATOR_S5M8767 + { + I2C_BOARD_INFO("s5m87xx", 0xCC >> 1), + .platform_data = &exynos4_s5m8767_pdata, + .irq = IRQ_EINT(26), + }, +#else + { + I2C_BOARD_INFO("max8997", 0x66), + .platform_data = &exynos4_max8997_info, + }, { + I2C_BOARD_INFO("max77686", (0x12 >> 1)), + .platform_data = &exynos4_max77686_info, + }, +#endif +}; + +static struct i2c_board_info i2c_devs1[] __initdata = { + { + I2C_BOARD_INFO("wm8994", 0x1a), + .platform_data = &wm8994_platform_data, + }, +}; + +static struct i2c_board_info i2c_devs2[] __initdata = { +#ifdef CONFIG_VIDEO_TVOUT + { + I2C_BOARD_INFO("s5p_ddc", (0x74 >> 1)), + }, +#endif +}; + +static struct i2c_board_info i2c_devs3[] __initdata = { + { + I2C_BOARD_INFO("max8952", 0x60), + .platform_data = &exynos4_max8952_info, + }, +}; + +static struct i2c_board_info i2c_devs7[] __initdata = { + { + I2C_BOARD_INFO("pixcir-ts", 0x5C), + }, +}; + +#ifdef CONFIG_BATTERY_SAMSUNG +static struct platform_device samsung_device_battery = { + .name = "samsung-fake-battery", + .id = -1, +}; +#endif + +static struct gpio_event_direct_entry smdk4x12_keypad_key_map[] = { + { + .gpio = EXYNOS4_GPX0(0), + .code = KEY_POWER, + } +}; + +static struct gpio_event_input_info smdk4x12_keypad_key_info = { + .info.func = gpio_event_input_func, + .info.no_suspend = true, + .debounce_time.tv64 = 5 * NSEC_PER_MSEC, + .type = EV_KEY, + .keymap = smdk4x12_keypad_key_map, + .keymap_size = ARRAY_SIZE(smdk4x12_keypad_key_map) +}; + +static struct gpio_event_info *smdk4x12_input_info[] = { + &smdk4x12_keypad_key_info.info, +}; + +static struct gpio_event_platform_data smdk4x12_input_data = { + .names = { + "smdk4x12-keypad", + NULL, + }, + .info = smdk4x12_input_info, + .info_count = ARRAY_SIZE(smdk4x12_input_info), +}; + +static struct platform_device smdk4x12_input_device = { + .name = GPIO_EVENT_DEV_NAME, + .id = 0, + .dev = { + .platform_data = &smdk4x12_input_data, + }, +}; + +static void __init smdk4x12_gpio_power_init(void) +{ + int err = 0; + + err = gpio_request_one(EXYNOS4_GPX0(0), 0, "GPX0"); + if (err) { + printk(KERN_ERR "failed to request GPX0 for " + "suspend/resume control\n"); + return; + } + s3c_gpio_setpull(EXYNOS4_GPX0(0), S3C_GPIO_PULL_NONE); + + gpio_free(EXYNOS4_GPX0(0)); +} + +static uint32_t smdk4x12_keymap0[] __initdata = { + /* KEY(row, col, keycode) */ + KEY(1, 0, KEY_D), KEY(1, 1, KEY_A), KEY(1, 2, KEY_B), + KEY(1, 3, KEY_E), KEY(1, 4, KEY_C) +}; + +static struct matrix_keymap_data smdk4x12_keymap_data0 __initdata = { + .keymap = smdk4x12_keymap0, + .keymap_size = ARRAY_SIZE(smdk4x12_keymap0), +}; + +static struct samsung_keypad_platdata smdk4x12_keypad_data0 __initdata = { + .keymap_data = &smdk4x12_keymap_data0, + .rows = 2, + .cols = 5, +}; + +static uint32_t smdk4x12_keymap1[] __initdata = { + /* KEY(row, col, keycode) */ + KEY(1, 3, KEY_1), KEY(1, 4, KEY_2), KEY(1, 5, KEY_3), + KEY(1, 6, KEY_4), KEY(1, 7, KEY_5), + KEY(2, 5, KEY_D), KEY(2, 6, KEY_A), KEY(2, 7, KEY_B), + KEY(0, 7, KEY_E), KEY(0, 5, KEY_C) +}; + +static struct matrix_keymap_data smdk4x12_keymap_data1 __initdata = { + .keymap = smdk4x12_keymap1, + .keymap_size = ARRAY_SIZE(smdk4x12_keymap1), +}; + +static struct samsung_keypad_platdata smdk4x12_keypad_data1 __initdata = { + .keymap_data = &smdk4x12_keymap_data1, + .rows = 3, + .cols = 8, +}; + +#ifdef CONFIG_WAKEUP_ASSIST +static struct platform_device wakeup_assist_device = { + .name = "wakeup_assist", +}; +#endif + +#ifdef CONFIG_VIDEO_FIMG2D +static struct fimg2d_platdata fimg2d_data __initdata = { + .hw_ver = 0x41, + .parent_clkname = "mout_g2d0", + .clkname = "sclk_fimg2d", + .gate_clkname = "fimg2d", + .clkrate = 201 * 1000000, /* 200 Mhz */ +}; +#endif + +#ifdef CONFIG_EXYNOS_C2C +struct exynos_c2c_platdata smdk4x12_c2c_pdata = { + .setup_gpio = NULL, + .shdmem_addr = C2C_SHAREDMEM_BASE, + .shdmem_size = C2C_MEMSIZE_64, + .ap_sscm_addr = NULL, + .cp_sscm_addr = NULL, + .rx_width = C2C_BUSWIDTH_16, + .tx_width = C2C_BUSWIDTH_16, + .clk_opp100 = 400, + .clk_opp50 = 266, + .clk_opp25 = 0, + .default_opp_mode = C2C_OPP50, + .get_c2c_state = NULL, + .c2c_sysreg = S5P_VA_CMU + 0x12000, +}; +#endif + +#ifdef CONFIG_USB_EXYNOS_SWITCH +static struct s5p_usbswitch_platdata smdk4x12_usbswitch_pdata; + +static void __init smdk4x12_usbswitch_init(void) +{ + struct s5p_usbswitch_platdata *pdata = &smdk4x12_usbswitch_pdata; + int err; + + pdata->gpio_host_detect = EXYNOS4_GPX3(5); /* low active */ + err = gpio_request_one(pdata->gpio_host_detect, GPIOF_IN, "HOST_DETECT"); + if (err) { + printk(KERN_ERR "failed to request gpio_host_detect\n"); + return; + } + + s3c_gpio_cfgpin(pdata->gpio_host_detect, S3C_GPIO_SFN(0xF)); + s3c_gpio_setpull(pdata->gpio_host_detect, S3C_GPIO_PULL_NONE); + gpio_free(pdata->gpio_host_detect); + + pdata->gpio_device_detect = EXYNOS4_GPX3(4); /* high active */ + err = gpio_request_one(pdata->gpio_device_detect, GPIOF_IN, "DEVICE_DETECT"); + if (err) { + printk(KERN_ERR "failed to request gpio_host_detect for\n"); + return; + } + + s3c_gpio_cfgpin(pdata->gpio_device_detect, S3C_GPIO_SFN(0xF)); + s3c_gpio_setpull(pdata->gpio_device_detect, S3C_GPIO_PULL_NONE); + gpio_free(pdata->gpio_device_detect); + + if (samsung_board_rev_is_0_0()) + pdata->gpio_host_vbus = 0; + else { + pdata->gpio_host_vbus = EXYNOS4_GPL2(0); + err = gpio_request_one(pdata->gpio_host_vbus, GPIOF_OUT_INIT_LOW, "HOST_VBUS_CONTROL"); + if (err) { + printk(KERN_ERR "failed to request gpio_host_vbus\n"); + return; + } + + s3c_gpio_setpull(pdata->gpio_host_vbus, S3C_GPIO_PULL_NONE); + gpio_free(pdata->gpio_host_vbus); + } + + s5p_usbswitch_set_platdata(pdata); +} +#endif + +#ifdef CONFIG_BUSFREQ_OPP +/* BUSFREQ to control memory/bus*/ +static struct device_domain busfreq; +#endif + +static struct platform_device exynos4_busfreq = { + .id = -1, + .name = "exynos-busfreq", +}; + +static struct platform_device *smdk4412_devices[] __initdata = { + &s3c_device_adc, +}; + +static struct platform_device *smdk4x12_devices[] __initdata = { + /* Samsung Power Domain */ + &exynos4_device_pd[PD_MFC], + &exynos4_device_pd[PD_G3D], + &exynos4_device_pd[PD_LCD0], + &exynos4_device_pd[PD_CAM], + &exynos4_device_pd[PD_TV], + &exynos4_device_pd[PD_GPS], + &exynos4_device_pd[PD_GPS_ALIVE], +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS + &exynos4_device_pd[PD_ISP], +#endif +#ifdef CONFIG_FB_MIPI_DSIM + &s5p_device_mipi_dsim, +#endif +/* mainline fimd */ +#ifdef CONFIG_FB_S3C + &s5p_device_fimd0, +#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_LMS501KF03) + &s3c_device_spi_gpio, +#elif defined(CONFIG_LCD_WA101S) + &smdk4x12_lcd_wa101s, +#elif defined(CONFIG_LCD_LTE480WV) + &smdk4x12_lcd_lte480wv, +#elif defined(CONFIG_LCD_MIPI_S6E63M0) + &smdk4x12_mipi_lcd, +#endif +#endif + /* legacy fimd */ +#ifdef CONFIG_FB_S5P + &s3c_device_fb, +#ifdef CONFIG_FB_S5P_LMS501KF03 + &s3c_device_spi_gpio, +#endif +#endif + &s3c_device_wdt, + &s3c_device_rtc, + &s3c_device_i2c0, + &s3c_device_i2c1, + &s3c_device_i2c2, + &s3c_device_i2c3, + &s3c_device_i2c4, + &s3c_device_i2c5, + &s3c_device_i2c7, +#ifdef CONFIG_USB_EHCI_S5P + &s5p_device_ehci, +#endif +#ifdef CONFIG_USB_OHCI_S5P + &s5p_device_ohci, +#endif +#ifdef CONFIG_USB_GADGET + &s3c_device_usbgadget, +#endif +#ifdef CONFIG_USB_ANDROID_RNDIS + &s3c_device_rndis, +#endif +#ifdef CONFIG_USB_ANDROID + &s3c_device_android_usb, + &s3c_device_usb_mass_storage, +#endif +#ifdef CONFIG_S3C_DEV_HSMMC + &s3c_device_hsmmc0, +#endif +#ifdef CONFIG_S3C_DEV_HSMMC1 + &s3c_device_hsmmc1, +#endif +#ifdef CONFIG_S3C_DEV_HSMMC2 + &s3c_device_hsmmc2, +#endif +#ifdef CONFIG_S3C_DEV_HSMMC3 + &s3c_device_hsmmc3, +#endif +#ifdef CONFIG_S5P_DEV_MSHC + &s3c_device_mshci, +#endif +#ifdef CONFIG_EXYNOS4_DEV_DWMCI + &exynos_device_dwmci, +#endif +#ifdef CONFIG_SND_SAMSUNG_AC97 + &exynos_device_ac97, +#endif +#ifdef CONFIG_SND_SAMSUNG_I2S + &exynos_device_i2s0, +#endif +#ifdef CONFIG_SND_SAMSUNG_PCM + &exynos_device_pcm0, +#endif +#ifdef CONFIG_SND_SAMSUNG_SPDIF + &exynos_device_spdif, +#endif +#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP) + &exynos_device_srp, +#endif +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS + &exynos4_device_fimc_is, +#endif +#ifdef CONFIG_VIDEO_TVOUT + &s5p_device_tvout, + &s5p_device_cec, + &s5p_device_hpd, +#endif +#ifdef CONFIG_FB_S5P_EXTDSP + &s3c_device_extdsp, +#endif +#ifdef CONFIG_VIDEO_EXYNOS_TV + &s5p_device_i2c_hdmiphy, + &s5p_device_hdmi, + &s5p_device_sdo, + &s5p_device_mixer, + &s5p_device_cec, +#endif +#if defined(CONFIG_VIDEO_FIMC) + &s3c_device_fimc0, + &s3c_device_fimc1, + &s3c_device_fimc2, + &s3c_device_fimc3, +/* CONFIG_VIDEO_SAMSUNG_S5P_FIMC is the feature for mainline */ +#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) + &s5p_device_fimc0, + &s5p_device_fimc1, + &s5p_device_fimc2, + &s5p_device_fimc3, +#endif +#if defined(CONFIG_VIDEO_FIMC_MIPI) + &s3c_device_csis0, + &s3c_device_csis1, +#elif defined(CONFIG_VIDEO_S5P_MIPI_CSIS) + &s5p_device_mipi_csis0, + &s5p_device_mipi_csis1, +#endif +#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS + &mipi_csi_fixed_voltage, +#endif +#ifdef CONFIG_VIDEO_M5MOLS + &m5mols_fixed_voltage, +#endif + +#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) + &s5p_device_mfc, +#endif +#ifdef CONFIG_S5P_SYSTEM_MMU + &SYSMMU_PLATDEV(g2d_acp), + &SYSMMU_PLATDEV(fimc0), + &SYSMMU_PLATDEV(fimc1), + &SYSMMU_PLATDEV(fimc2), + &SYSMMU_PLATDEV(fimc3), + &SYSMMU_PLATDEV(jpeg), + &SYSMMU_PLATDEV(mfc_l), + &SYSMMU_PLATDEV(mfc_r), + &SYSMMU_PLATDEV(tv), +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS + &SYSMMU_PLATDEV(is_isp), + &SYSMMU_PLATDEV(is_drc), + &SYSMMU_PLATDEV(is_fd), + &SYSMMU_PLATDEV(is_cpu), +#endif +#endif /* CONFIG_S5P_SYSTEM_MMU */ +#ifdef CONFIG_ION_EXYNOS + &exynos_device_ion, +#endif +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE + &exynos_device_flite0, + &exynos_device_flite1, +#endif +#ifdef CONFIG_VIDEO_FIMG2D + &s5p_device_fimg2d, +#endif +#ifdef CONFIG_EXYNOS_MEDIA_DEVICE + &exynos_device_md0, +#endif +#ifdef CONFIG_VIDEO_JPEG_V2X + &s5p_device_jpeg, +#endif + &wm8994_fixed_voltage0, + &wm8994_fixed_voltage1, + &wm8994_fixed_voltage2, + &samsung_asoc_dma, + &samsung_asoc_idma, +#ifdef CONFIG_BATTERY_SAMSUNG + &samsung_device_battery, +#endif + &samsung_device_keypad, +#ifdef CONFIG_WAKEUP_ASSIST + &wakeup_assist_device, +#endif +#ifdef CONFIG_EXYNOS_C2C + &exynos_device_c2c, +#endif + &smdk4x12_input_device, + &smdk4x12_smsc911x, +#ifdef CONFIG_S3C64XX_DEV_SPI + &exynos_device_spi0, +#ifndef CONFIG_FB_S5P_LMS501KF03 + &exynos_device_spi1, +#endif + &exynos_device_spi2, +#endif +#ifdef CONFIG_EXYNOS_SETUP_THERMAL + &exynos_device_tmu, +#endif +#ifdef CONFIG_S5P_DEV_ACE + &s5p_device_ace, +#endif + &exynos4_busfreq, +}; + +#ifdef CONFIG_EXYNOS_SETUP_THERMAL +/* below temperature base on the celcius degree */ +struct tmu_data exynos_tmu_data __initdata = { + .ts = { + .stop_throttle = 82, + .start_throttle = 85, + .stop_warning = 95, + .start_warning = 103, + .start_tripping = 110, /* temp to do tripping */ + }, + .efuse_value = 55, + .slope = 0x10008802, + .mode = 0, +}; +#endif + +#if defined(CONFIG_VIDEO_TVOUT) +static struct s5p_platform_hpd hdmi_hpd_data __initdata = { + +}; +static struct s5p_platform_cec hdmi_cec_data __initdata = { + +}; +#endif + +#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC +static struct s5p_platform_cec hdmi_cec_data __initdata = { + +}; +#endif + +#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC +static struct s5p_fimc_isp_info isp_info[] = { +#if defined(CONFIG_VIDEO_S5K4BA) + { + .board_info = &s5k4ba_info, + .clk_frequency = 24000000UL, + .bus_type = FIMC_ITU_601, +#ifdef CONFIG_ITU_A + .i2c_bus_num = 0, + .mux_id = 0, /* A-Port : 0, B-Port : 1 */ +#endif +#ifdef CONFIG_ITU_B + .i2c_bus_num = 1, + .mux_id = 1, /* A-Port : 0, B-Port : 1 */ +#endif + .flags = FIMC_CLK_INV_VSYNC, + }, +#endif +#if defined(CONFIG_VIDEO_S5K4EA) + { + .board_info = &s5k4ea_info, + .clk_frequency = 24000000UL, + .bus_type = FIMC_MIPI_CSI2, +#ifdef CONFIG_CSI_C + .i2c_bus_num = 0, + .mux_id = 0, /* A-Port : 0, B-Port : 1 */ +#endif +#ifdef CONFIG_CSI_D + .i2c_bus_num = 1, + .mux_id = 1, /* A-Port : 0, B-Port : 1 */ +#endif + .flags = FIMC_CLK_INV_VSYNC, + .csi_data_align = 32, + }, +#endif +#if defined(CONFIG_VIDEO_M5MOLS) + { + .board_info = &m5mols_board_info, + .clk_frequency = 24000000UL, + .bus_type = FIMC_MIPI_CSI2, +#ifdef CONFIG_CSI_C + .i2c_bus_num = 4, + .mux_id = 0, /* A-Port : 0, B-Port : 1 */ +#endif +#ifdef CONFIG_CSI_D + .i2c_bus_num = 5, + .mux_id = 1, /* A-Port : 0, B-Port : 1 */ +#endif + .flags = FIMC_CLK_INV_PCLK | FIMC_CLK_INV_VSYNC, + .csi_data_align = 32, + }, +#endif +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS +#if defined(CONFIG_VIDEO_S5K3H2) + { + .board_info = &s5k3h2_sensor_info, + .clk_frequency = 24000000UL, + .bus_type = FIMC_MIPI_CSI2, +#ifdef CONFIG_S5K3H2_CSI_C + .i2c_bus_num = 0, + .mux_id = 0, /* A-Port : 0, B-Port : 1 */ + .flite_id = FLITE_IDX_A, + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_S5K3H2_CSI_D + .i2c_bus_num = 1, + .mux_id = 1, /* A-Port : 0, B-Port : 1 */ + .flite_id = FLITE_IDX_B, + .cam_power = smdk4x12_cam1_reset, +#endif + .flags = 0, + .csi_data_align = 24, + .use_isp = true, + }, +#endif +#if defined(CONFIG_VIDEO_S5K3H7) + { + .board_info = &s5k3h7_sensor_info, + .clk_frequency = 24000000UL, + .bus_type = FIMC_MIPI_CSI2, +#ifdef CONFIG_S5K3H7_CSI_C + .i2c_bus_num = 0, + .mux_id = 0, /* A-Port : 0, B-Port : 1 */ + .flite_id = FLITE_IDX_A, + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_S5K3H7_CSI_D + .i2c_bus_num = 1, + .mux_id = 1, /* A-Port : 0, B-Port : 1 */ + .flite_id = FLITE_IDX_B, + .cam_power = smdk4x12_cam1_reset, +#endif + .csi_data_align = 24, + .use_isp = true, + }, +#endif +#if defined(CONFIG_VIDEO_S5K4E5) + { + .board_info = &s5k4e5_sensor_info, + .clk_frequency = 24000000UL, + .bus_type = FIMC_MIPI_CSI2, +#ifdef CONFIG_S5K4E5_CSI_C + .i2c_bus_num = 0, + .mux_id = 0, /* A-Port : 0, B-Port : 1 */ + .flite_id = FLITE_IDX_A, + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_S5K4E5_CSI_D + .i2c_bus_num = 1, + .mux_id = 1, /* A-Port : 0, B-Port : 1 */ + .flite_id = FLITE_IDX_B, + .cam_power = smdk4x12_cam1_reset, +#endif + .csi_data_align = 24, + .use_isp = true, + }, +#endif +#if defined(CONFIG_VIDEO_S5K6A3) + { + .board_info = &s5k6a3_sensor_info, + .clk_frequency = 12000000UL, + .bus_type = FIMC_MIPI_CSI2, +#ifdef CONFIG_S5K6A3_CSI_C + .i2c_bus_num = 0, + .mux_id = 0, /* A-Port : 0, B-Port : 1 */ + .flite_id = FLITE_IDX_A, + .cam_power = smdk4x12_cam0_reset, +#endif +#ifdef CONFIG_S5K6A3_CSI_D + .i2c_bus_num = 1, + .mux_id = 1, /* A-Port : 0, B-Port : 1 */ + .flite_id = FLITE_IDX_B, + .cam_power = smdk4x12_cam1_reset, +#endif + .flags = 0, + .csi_data_align = 12, + .use_isp = true, + }, +#endif +#endif +#if defined(WRITEBACK_ENABLED) + { + .board_info = &writeback_info, + .bus_type = FIMC_LCD_WB, + .i2c_bus_num = 0, + .mux_id = 0, /* A-Port : 0, B-Port : 1 */ + .flags = FIMC_CLK_INV_VSYNC, + }, +#endif +}; + +static void __init smdk4x12_subdev_config(void) +{ + s3c_fimc0_default_data.isp_info[0] = &isp_info[0]; + s3c_fimc0_default_data.isp_info[0]->use_cam = true; + s3c_fimc0_default_data.isp_info[1] = &isp_info[1]; + s3c_fimc0_default_data.isp_info[1]->use_cam = true; + /* support using two fimc as one sensore */ + { + static struct s5p_fimc_isp_info camcording1; + static struct s5p_fimc_isp_info camcording2; + memcpy(&camcording1, &isp_info[0], sizeof(struct s5p_fimc_isp_info)); + memcpy(&camcording2, &isp_info[1], sizeof(struct s5p_fimc_isp_info)); + s3c_fimc1_default_data.isp_info[0] = &camcording1; + s3c_fimc1_default_data.isp_info[0]->use_cam = false; + s3c_fimc1_default_data.isp_info[1] = &camcording2; + s3c_fimc1_default_data.isp_info[1]->use_cam = false; + } +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS +#ifdef CONFIG_VIDEO_S5K3H2 +#ifdef CONFIG_S5K3H2_CSI_C + s5p_mipi_csis0_default_data.clk_rate = 160000000; + s5p_mipi_csis0_default_data.lanes = 2; + s5p_mipi_csis0_default_data.alignment = 24; + s5p_mipi_csis0_default_data.hs_settle = 12; +#endif +#ifdef CONFIG_S5K3H2_CSI_D + s5p_mipi_csis1_default_data.clk_rate = 160000000; + s5p_mipi_csis1_default_data.lanes = 2; + s5p_mipi_csis1_default_data.alignment = 24; + s5p_mipi_csis1_default_data.hs_settle = 12; +#endif +#endif +#ifdef CONFIG_VIDEO_S5K3H7 +#ifdef CONFIG_S5K3H7_CSI_C + s5p_mipi_csis0_default_data.clk_rate = 160000000; + s5p_mipi_csis0_default_data.lanes = 2; + s5p_mipi_csis0_default_data.alignment = 24; + s5p_mipi_csis0_default_data.hs_settle = 12; +#endif +#ifdef CONFIG_S5K3H7_CSI_D + s5p_mipi_csis1_default_data.clk_rate = 160000000; + s5p_mipi_csis1_default_data.lanes = 2; + s5p_mipi_csis1_default_data.alignment = 24; + s5p_mipi_csis1_default_data.hs_settle = 12; +#endif +#endif +#ifdef CONFIG_VIDEO_S5K4E5 +#ifdef CONFIG_S5K4E5_CSI_C + s5p_mipi_csis0_default_data.clk_rate = 160000000; + s5p_mipi_csis0_default_data.lanes = 2; + s5p_mipi_csis0_default_data.alignment = 24; + s5p_mipi_csis0_default_data.hs_settle = 12; +#endif +#ifdef CONFIG_S5K4E5_CSI_D + s5p_mipi_csis1_default_data.clk_rate = 160000000; + s5p_mipi_csis1_default_data.lanes = 2; + s5p_mipi_csis1_default_data.alignment = 24; + s5p_mipi_csis1_default_data.hs_settle = 12; +#endif +#endif +#ifdef CONFIG_VIDEO_S5K6A3 +#ifdef CONFIG_S5K6A3_CSI_C + s5p_mipi_csis0_default_data.clk_rate = 160000000; + s5p_mipi_csis0_default_data.lanes = 1; + s5p_mipi_csis0_default_data.alignment = 24; + s5p_mipi_csis0_default_data.hs_settle = 12; +#endif +#ifdef CONFIG_S5K6A3_CSI_D + s5p_mipi_csis1_default_data.clk_rate = 160000000; + s5p_mipi_csis1_default_data.lanes = 1; + s5p_mipi_csis1_default_data.alignment = 24; + s5p_mipi_csis1_default_data.hs_settle = 12; +#endif +#endif +#endif +} +static void __init smdk4x12_camera_config(void) +{ + /* CAM A port(b0010) : PCLK, VSYNC, HREF, DATA[0-4] */ + s3c_gpio_cfgrange_nopull(EXYNOS4212_GPJ0(0), 8, S3C_GPIO_SFN(2)); + /* CAM A port(b0010) : DATA[5-7], CLKOUT(MIPI CAM also), FIELD */ + s3c_gpio_cfgrange_nopull(EXYNOS4212_GPJ1(0), 5, S3C_GPIO_SFN(2)); + /* CAM B port(b0011) : PCLK, DATA[0-6] */ + s3c_gpio_cfgrange_nopull(EXYNOS4212_GPM0(0), 8, S3C_GPIO_SFN(3)); + /* CAM B port(b0011) : FIELD, DATA[7]*/ + s3c_gpio_cfgrange_nopull(EXYNOS4212_GPM1(0), 2, S3C_GPIO_SFN(3)); + /* CAM B port(b0011) : VSYNC, HREF, CLKOUT*/ + s3c_gpio_cfgrange_nopull(EXYNOS4212_GPM2(0), 3, S3C_GPIO_SFN(3)); + + /* note : driver strength to max is unnecessary */ +#ifdef CONFIG_VIDEO_M5MOLS + s3c_gpio_cfgpin(EXYNOS4_GPX2(6), S3C_GPIO_SFN(0xF)); + s3c_gpio_setpull(EXYNOS4_GPX2(6), S3C_GPIO_PULL_NONE); +#endif +} +#endif /* CONFIG_VIDEO_SAMSUNG_S5P_FIMC */ + +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE +static void __set_flite_camera_config(struct exynos_platform_flite *data, + u32 active_index, u32 max_cam) +{ + data->active_cam_index = active_index; + data->num_clients = max_cam; +} + +static void __init smdk4x12_set_camera_flite_platdata(void) +{ + int flite0_cam_index = 0; + int flite1_cam_index = 0; +#ifdef CONFIG_VIDEO_S5K3H2 +#ifdef CONFIG_S5K3H2_CSI_C + exynos_flite0_default_data.cam[flite0_cam_index++] = &s5k3h2; +#endif +#ifdef CONFIG_S5K3H2_CSI_D + exynos_flite1_default_data.cam[flite1_cam_index++] = &s5k3h2; +#endif +#endif +#ifdef CONFIG_VIDEO_S5K3H7 +#ifdef CONFIG_S5K3H7_CSI_C + exynos_flite0_default_data.cam[flite0_cam_index++] = &s5k3h7; +#endif +#ifdef CONFIG_S5K3H7_CSI_D + exynos_flite1_default_data.cam[flite1_cam_index++] = &s5k3h7; +#endif +#endif +#ifdef CONFIG_VIDEO_S5K4E5 +#ifdef CONFIG_S5K4E5_CSI_C + exynos_flite0_default_data.cam[flite0_cam_index++] = &s5k4e5; +#endif +#ifdef CONFIG_S5K4E5_CSI_D + exynos_flite1_default_data.cam[flite1_cam_index++] = &s5k4e5; +#endif +#endif + +#ifdef CONFIG_VIDEO_S5K6A3 +#ifdef CONFIG_S5K6A3_CSI_C + exynos_flite0_default_data.cam[flite0_cam_index++] = &s5k6a3; +#endif +#ifdef CONFIG_S5K6A3_CSI_D + exynos_flite1_default_data.cam[flite1_cam_index++] = &s5k6a3; +#endif +#endif + __set_flite_camera_config(&exynos_flite0_default_data, 0, flite0_cam_index); + __set_flite_camera_config(&exynos_flite1_default_data, 0, flite1_cam_index); +} +#endif + +#if defined(CONFIG_CMA) +static void __init exynos4_reserve_mem(void) +{ + static struct cma_region regions[] = { +#ifndef CONFIG_VIDEOBUF2_ION +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV + { + .name = "tv", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV * SZ_1K, + .start = 0 + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG + { + .name = "jpeg", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * SZ_1K, + .start = 0 + }, +#endif +#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP + { + .name = "srp", + .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K, + .start = 0, + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D + { + .name = "fimg2d", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K, + .start = 0 + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD + { + .name = "fimd", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K, + .start = 0 + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 + { + .name = "fimc0", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K, + .start = 0 + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2 + { + .name = "fimc2", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2 * SZ_1K, + .start = 0 + }, +#endif +#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \ + defined(CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3) + { + .name = "fimc3", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 * SZ_1K, + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 + { + .name = "fimc1", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K, + .start = 0 + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL + { + .name = "mfc-normal", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL * SZ_1K, + { .alignment = 1 << 17 }, + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 + { + .name = "mfc1", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K, + { + .alignment = 1 << 17, + }, + .start = 0, + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 + { + .name = "mfc0", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K, + { + .alignment = 1 << 17, + } + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC + { + .name = "mfc", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC * SZ_1K, + { + .alignment = 1 << 17, + }, + .start = 0 + }, +#endif +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS + { + .name = "fimc_is", + .size = CONFIG_VIDEO_EXYNOS_MEMSIZE_FIMC_IS * SZ_1K, + { + .alignment = 1 << 26, + }, + .start = 0 + }, +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS_BAYER + { + .name = "fimc_is_isp", + .size = CONFIG_VIDEO_EXYNOS_MEMSIZE_FIMC_IS_ISP * SZ_1K, + .start = 0 + }, +#endif +#endif +#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \ + defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) + { + .name = "b2", + .size = 32 << 20, + { .alignment = 128 << 10 }, + }, + { + .name = "b1", + .size = 32 << 20, + { .alignment = 128 << 10 }, + }, + { + .name = "fw", + .size = 1 << 20, + { .alignment = 128 << 10 }, + }, +#endif +#else /* !CONFIG_VIDEOBUF2_ION */ +#ifdef CONFIG_FB_S5P +#error CONFIG_FB_S5P is defined. Select CONFIG_FB_S3C, instead +#endif + { + .name = "ion", + .size = CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE * SZ_1K, + }, +#endif /* !CONFIG_VIDEOBUF2_ION */ + { + .size = 0 + }, + }; +#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION + static struct cma_region regions_secure[] = { +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 + { + .name = "fimc3", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 * SZ_1K, + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD_VIDEO + { + .name = "video", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD_VIDEO * SZ_1K, + }, +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE + { + .name = "mfc-secure", + .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE * SZ_1K, + }, +#endif + { + .name = "sectbl", + .size = SZ_1M, + }, + { + .size = 0 + }, + }; +#else /* !CONFIG_EXYNOS_CONTENT_PATH_PROTECTION */ + struct cma_region *regions_secure = NULL; +#endif + static const char map[] __initconst = +#ifdef CONFIG_EXYNOS_C2C + "samsung-c2c=c2c_shdmem;" +#endif + "s3cfb.0/fimd=fimd;exynos4-fb.0/fimd=fimd;" +#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION + "s3cfb.0/video=video;exynos4-fb.0/video=video;" +#endif + "s3c-fimc.0=fimc0;s3c-fimc.1=fimc1;s3c-fimc.2=fimc2;s3c-fimc.3=fimc3;" + "exynos4210-fimc.0=fimc0;exynos4210-fimc.1=fimc1;exynos4210-fimc.2=fimc2;exynos4210-fimc.3=fimc3;" +#ifdef CONFIG_VIDEO_MFC5X + "s3c-mfc=mfc,mfc0,mfc1;" +#endif +#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC + "s5p-mfc/f=fw;" + "s5p-mfc/a=b1;" + "s5p-mfc/b=b2;" +#endif + "samsung-rp=srp;" + "s5p-jpeg=jpeg;" + "exynos4-fimc-is/f=fimc_is;" +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS_BAYER + "exynos4-fimc-is/i=fimc_is_isp;" +#endif + "s5p-mixer=tv;" + "s5p-fimg2d=fimg2d;" + "ion-exynos=ion,fimd,fimc0,fimc1,fimc2,fimc3,mfc,mfc0,mfc1,fw,b1,b2;" +#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION + "s5p-smem/video=video;" + "s5p-smem/sectbl=sectbl;" +#endif + "s5p-smem/mfc=mfc0;" + "s5p-smem/fimc=fimc3;" + "s5p-smem/mfc-shm=mfc1,mfc-normal;" + "s5p-smem/fimd=fimd;"; + + s5p_cma_region_reserve(regions, regions_secure, 0, map); +} +#else +static inline void exynos4_reserve_mem(void) +{ +} +#endif /* CONFIG_CMA */ + +/* LCD Backlight data */ +static struct samsung_bl_gpio_info smdk4x12_bl_gpio_info = { + .no = EXYNOS4_GPD0(1), + .func = S3C_GPIO_SFN(2), +}; + +static struct platform_pwm_backlight_data smdk4x12_bl_data = { + .pwm_id = 1, +#ifdef CONFIG_FB_S5P_LMS501KF03 + .pwm_period_ns = 1000, +#endif +}; + +static void __init smdk4x12_map_io(void) +{ + clk_xusbxti.rate = 24000000; + s5p_init_io(NULL, 0, S5P_VA_CHIPID); + s3c24xx_init_clocks(24000000); + s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs)); + + exynos4_reserve_mem(); +} + +static void __init smdk4x12_smsc911x_init(void) +{ + u32 cs1; + + /* configure nCS1 width to 16 bits */ + cs1 = __raw_readl(S5P_SROM_BW) & + ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT); + cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) | + (1 << S5P_SROM_BW__WAITENABLE__SHIFT) | + (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) << + S5P_SROM_BW__NCS1__SHIFT; + __raw_writel(cs1, S5P_SROM_BW); + + /* set timing for nCS1 suitable for ethernet chip */ + __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) | + (0x9 << S5P_SROM_BCX__TACP__SHIFT) | + (0xc << S5P_SROM_BCX__TCAH__SHIFT) | + (0x1 << S5P_SROM_BCX__TCOH__SHIFT) | + (0x6 << S5P_SROM_BCX__TACC__SHIFT) | + (0x1 << S5P_SROM_BCX__TCOS__SHIFT) | + (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1); +} + +static void __init exynos_sysmmu_init(void) +{ + ASSIGN_SYSMMU_POWERDOMAIN(fimc0, &exynos4_device_pd[PD_CAM].dev); + ASSIGN_SYSMMU_POWERDOMAIN(fimc1, &exynos4_device_pd[PD_CAM].dev); + ASSIGN_SYSMMU_POWERDOMAIN(fimc2, &exynos4_device_pd[PD_CAM].dev); + ASSIGN_SYSMMU_POWERDOMAIN(fimc3, &exynos4_device_pd[PD_CAM].dev); + ASSIGN_SYSMMU_POWERDOMAIN(jpeg, &exynos4_device_pd[PD_CAM].dev); + ASSIGN_SYSMMU_POWERDOMAIN(mfc_l, &exynos4_device_pd[PD_MFC].dev); + ASSIGN_SYSMMU_POWERDOMAIN(mfc_r, &exynos4_device_pd[PD_MFC].dev); + ASSIGN_SYSMMU_POWERDOMAIN(tv, &exynos4_device_pd[PD_TV].dev); +#ifdef CONFIG_VIDEO_FIMG2D + sysmmu_set_owner(&SYSMMU_PLATDEV(g2d_acp).dev, &s5p_device_fimg2d.dev); +#endif +#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X) + sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc.dev); +#endif +#if defined(CONFIG_VIDEO_FIMC) + sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s3c_device_fimc0.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s3c_device_fimc1.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s3c_device_fimc2.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s3c_device_fimc3.dev); +#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) + sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev); +#endif +#ifdef CONFIG_VIDEO_EXYNOS_TV + sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_mixer.dev); +#endif +#ifdef CONFIG_VIDEO_TVOUT + sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_tvout.dev); +#endif +#ifdef CONFIG_VIDEO_JPEG_V2X + sysmmu_set_owner(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev); +#endif +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS + ASSIGN_SYSMMU_POWERDOMAIN(is_isp, &exynos4_device_pd[PD_ISP].dev); + ASSIGN_SYSMMU_POWERDOMAIN(is_drc, &exynos4_device_pd[PD_ISP].dev); + ASSIGN_SYSMMU_POWERDOMAIN(is_fd, &exynos4_device_pd[PD_ISP].dev); + ASSIGN_SYSMMU_POWERDOMAIN(is_cpu, &exynos4_device_pd[PD_ISP].dev); + + sysmmu_set_owner(&SYSMMU_PLATDEV(is_isp).dev, + &exynos4_device_fimc_is.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(is_drc).dev, + &exynos4_device_fimc_is.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(is_fd).dev, + &exynos4_device_fimc_is.dev); + sysmmu_set_owner(&SYSMMU_PLATDEV(is_cpu).dev, + &exynos4_device_fimc_is.dev); +#endif +} + +#ifdef CONFIG_FB_S5P_EXTDSP +struct platform_device s3c_device_extdsp = { + .name = "s3cfb_extdsp", + .id = 0, +}; + +static struct s3cfb_extdsp_lcd dummy_buffer = { + .width = 1280, + .height = 720, + .bpp = 16, +}; + +static struct s3c_platform_fb default_extdsp_data __initdata = { + .hw_ver = 0x70, + .nr_wins = 1, + .default_win = 0, + .swap = FB_SWAP_WORD | FB_SWAP_HWORD, + .lcd = &dummy_buffer +}; + +void __init s3cfb_extdsp_set_platdata(struct s3c_platform_fb *pd) +{ + struct s3c_platform_fb *npd; + int i; + + if (!pd) + pd = &default_extdsp_data; + + npd = kmemdup(pd, sizeof(struct s3c_platform_fb), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else { + for (i = 0; i < npd->nr_wins; i++) + npd->nr_buffers[i] = 1; + s3c_device_extdsp.dev.platform_data = npd; + } +} +#endif + +#define SMDK4412_REV_0_0_ADC_VALUE 0 +#define SMDK4412_REV_0_1_ADC_VALUE 443 +int samsung_board_rev; + +static int get_samsung_board_rev(void) +{ + int adc_val = 0; + struct clk *adc_clk; + struct resource *res; + void __iomem *adc_regs; + unsigned int con; + int ret; + + if ((soc_is_exynos4412() && samsung_rev() < EXYNOS4412_REV_1_0) || + (soc_is_exynos4212() && samsung_rev() < EXYNOS4212_REV_1_0)) + return SAMSUNG_BOARD_REV_0_0; + + adc_clk = clk_get(NULL, "adc"); + if (unlikely(IS_ERR(adc_clk))) + return SAMSUNG_BOARD_REV_0_0; + + clk_enable(adc_clk); + + res = platform_get_resource(&s3c_device_adc, IORESOURCE_MEM, 0); + if (unlikely(!res)) + goto err_clk; + + adc_regs = ioremap(res->start, resource_size(res)); + if (unlikely(!adc_regs)) + goto err_clk; + + writel(S5PV210_ADCCON_SELMUX(3), adc_regs + S5P_ADCMUX); + + con = readl(adc_regs + S3C2410_ADCCON); + con &= ~S3C2410_ADCCON_MUXMASK; + con &= ~S3C2410_ADCCON_STDBM; + con &= ~S3C2410_ADCCON_STARTMASK; + con |= S3C2410_ADCCON_PRSCEN; + + con |= S3C2410_ADCCON_ENABLE_START; + writel(con, adc_regs + S3C2410_ADCCON); + + udelay (50); + + adc_val = readl(adc_regs + S3C2410_ADCDAT0) & 0xFFF; + writel(0, adc_regs + S3C64XX_ADCCLRINT); + + iounmap(adc_regs); +err_clk: + clk_disable(adc_clk); + clk_put(adc_clk); + + ret = (adc_val < SMDK4412_REV_0_1_ADC_VALUE/2) ? + SAMSUNG_BOARD_REV_0_0 : SAMSUNG_BOARD_REV_0_1; + + pr_info ("SMDK MAIN Board Rev 0.%d (ADC value:%d)\n", ret, adc_val); + return ret; +} + +static void __init smdk4x12_machine_init(void) +{ +#ifdef CONFIG_S3C64XX_DEV_SPI + struct clk *sclk = NULL; + struct clk *prnt = NULL; + struct device *spi0_dev = &exynos_device_spi0.dev; +#ifndef CONFIG_FB_S5P_LMS501KF03 + struct device *spi1_dev = &exynos_device_spi1.dev; +#endif + struct device *spi2_dev = &exynos_device_spi2.dev; +#endif + samsung_board_rev = get_samsung_board_rev(); +#if defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME) + exynos_pd_disable(&exynos4_device_pd[PD_MFC].dev); + exynos_pd_disable(&exynos4_device_pd[PD_G3D].dev); + exynos_pd_disable(&exynos4_device_pd[PD_LCD0].dev); + exynos_pd_disable(&exynos4_device_pd[PD_CAM].dev); + exynos_pd_disable(&exynos4_device_pd[PD_TV].dev); + exynos_pd_disable(&exynos4_device_pd[PD_GPS].dev); + exynos_pd_disable(&exynos4_device_pd[PD_GPS_ALIVE].dev); + exynos_pd_disable(&exynos4_device_pd[PD_ISP].dev); +#elif defined(CONFIG_EXYNOS_DEV_PD) + /* + * These power domains should be always on + * without runtime pm support. + */ + exynos_pd_enable(&exynos4_device_pd[PD_MFC].dev); + exynos_pd_enable(&exynos4_device_pd[PD_G3D].dev); + exynos_pd_enable(&exynos4_device_pd[PD_LCD0].dev); + exynos_pd_enable(&exynos4_device_pd[PD_CAM].dev); + exynos_pd_enable(&exynos4_device_pd[PD_TV].dev); + exynos_pd_enable(&exynos4_device_pd[PD_GPS].dev); + exynos_pd_enable(&exynos4_device_pd[PD_GPS_ALIVE].dev); + exynos_pd_enable(&exynos4_device_pd[PD_ISP].dev); +#endif + s3c_i2c0_set_platdata(NULL); + i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); + + s3c_i2c1_set_platdata(NULL); + i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); + + s3c_i2c2_set_platdata(NULL); + i2c_register_board_info(2, i2c_devs2, ARRAY_SIZE(i2c_devs2)); + + s3c_i2c3_set_platdata(NULL); + i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3)); + + s3c_i2c4_set_platdata(NULL); + s3c_i2c5_set_platdata(NULL); + + s3c_i2c7_set_platdata(NULL); + i2c_devs7[0].irq = samsung_board_rev_is_0_0() ? IRQ_EINT(15) : IRQ_EINT(22); + i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7)); + +#if defined(CONFIG_FB_S5P_MIPI_DSIM) + mipi_fb_init(); +#endif +#ifdef CONFIG_FB_S3C + dev_set_name(&s5p_device_fimd0.dev, "s3cfb.0"); + clk_add_alias("lcd", "exynos4-fb.0", "lcd", &s5p_device_fimd0.dev); + clk_add_alias("sclk_fimd", "exynos4-fb.0", "sclk_fimd", &s5p_device_fimd0.dev); + s5p_fb_setname(0, "exynos4-fb"); +#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_LMS501KF03) + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); +#endif + s5p_fimd0_set_platdata(&smdk4x12_lcd0_pdata); +#ifdef CONFIG_FB_MIPI_DSIM + s5p_device_mipi_dsim.dev.parent = &exynos4_device_pd[PD_LCD0].dev; +#endif +#ifdef CONFIG_EXYNOS_DEV_PD + s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev; +#endif +#endif +#ifdef CONFIG_FB_S5P +#ifdef CONFIG_FB_S5P_LMS501KF03 + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); + s3cfb_set_platdata(&lms501kf03_data); +#else + s3cfb_set_platdata(NULL); +#endif +#ifdef CONFIG_FB_S5P_MIPI_DSIM + s5p_device_dsim.dev.parent = &exynos4_device_pd[PD_LCD0].dev; +#endif +#ifdef CONFIG_EXYNOS_DEV_PD + s3c_device_fb.dev.parent = &exynos4_device_pd[PD_LCD0].dev; +#endif +#endif +#ifdef CONFIG_USB_EHCI_S5P + smdk4x12_ehci_init(); +#endif +#ifdef CONFIG_USB_OHCI_S5P + smdk4x12_ohci_init(); +#endif +#ifdef CONFIG_USB_GADGET + smdk4x12_usbgadget_init(); +#endif +#ifdef CONFIG_USB_EXYNOS_SWITCH + smdk4x12_usbswitch_init(); +#endif + + samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data); + +#ifdef CONFIG_EXYNOS4_DEV_DWMCI + exynos_dwmci_set_platdata(&exynos_dwmci_pdata, 0); +#endif + +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS + exynos4_fimc_is_set_platdata(NULL); +#ifdef CONFIG_EXYNOS_DEV_PD + exynos4_device_fimc_is.dev.parent = &exynos4_device_pd[PD_ISP].dev; +#endif +#endif +#ifdef CONFIG_S3C_DEV_HSMMC + s3c_sdhci0_set_platdata(&smdk4x12_hsmmc0_pdata); +#endif +#ifdef CONFIG_S3C_DEV_HSMMC1 + s3c_sdhci1_set_platdata(&smdk4x12_hsmmc1_pdata); +#endif +#ifdef CONFIG_S3C_DEV_HSMMC2 + s3c_sdhci2_set_platdata(&smdk4x12_hsmmc2_pdata); +#endif +#ifdef CONFIG_S3C_DEV_HSMMC3 + s3c_sdhci3_set_platdata(&smdk4x12_hsmmc3_pdata); +#endif +#ifdef CONFIG_S5P_DEV_MSHC + s3c_mshci_set_platdata(&exynos4_mshc_pdata); +#endif +#if defined(CONFIG_VIDEO_EXYNOS_TV) && defined(CONFIG_VIDEO_EXYNOS_HDMI) + dev_set_name(&s5p_device_hdmi.dev, "exynos4-hdmi"); + clk_add_alias("hdmi", "s5p-hdmi", "hdmi", &s5p_device_hdmi.dev); + clk_add_alias("hdmiphy", "s5p-hdmi", "hdmiphy", &s5p_device_hdmi.dev); + + s5p_tv_setup(); + + /* setup dependencies between TV devices */ + s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev; + s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev; + + s5p_i2c_hdmiphy_set_platdata(NULL); + +#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC + s5p_hdmi_cec_set_platdata(&hdmi_cec_data); +#endif +#endif +#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE + smdk4x12_set_camera_flite_platdata(); + s3c_set_platdata(&exynos_flite0_default_data, + sizeof(exynos_flite0_default_data), &exynos_device_flite0); + s3c_set_platdata(&exynos_flite1_default_data, + sizeof(exynos_flite1_default_data), &exynos_device_flite1); +#ifdef CONFIG_EXYNOS_DEV_PD + exynos_device_flite0.dev.parent = &exynos4_device_pd[PD_ISP].dev; + exynos_device_flite1.dev.parent = &exynos4_device_pd[PD_ISP].dev; +#endif +#endif +#ifdef CONFIG_EXYNOS_SETUP_THERMAL + s5p_tmu_set_platdata(&exynos_tmu_data); +#endif +#ifdef CONFIG_VIDEO_FIMC + s3c_fimc0_set_platdata(&fimc_plat); + s3c_fimc1_set_platdata(&fimc_plat); + s3c_fimc2_set_platdata(&fimc_plat); + s3c_fimc3_set_platdata(NULL); +#ifdef CONFIG_EXYNOS_DEV_PD + s3c_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev; + s3c_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev; + s3c_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev; + s3c_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev; +#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION + secmem.parent = &exynos4_device_pd[PD_CAM].dev; +#endif +#endif +#ifdef CONFIG_VIDEO_FIMC_MIPI + s3c_csis0_set_platdata(NULL); + s3c_csis1_set_platdata(NULL); +#ifdef CONFIG_EXYNOS_DEV_PD + s3c_device_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev; + s3c_device_csis1.dev.parent = &exynos4_device_pd[PD_CAM].dev; +#endif +#endif + +#if defined(CONFIG_ITU_A) || defined(CONFIG_CSI_C) \ + || defined(CONFIG_S5K3H1_CSI_C) || defined(CONFIG_S5K3H2_CSI_C) \ + || defined(CONFIG_S5K6A3_CSI_C) + smdk4x12_cam0_reset(1); +#endif +#if defined(CONFIG_ITU_B) || defined(CONFIG_CSI_D) \ + || defined(CONFIG_S5K3H1_CSI_D) || defined(CONFIG_S5K3H2_CSI_D) \ + || defined(CONFIG_S5K6A3_CSI_D) + smdk4x12_cam1_reset(1); +#endif +#endif /* CONFIG_VIDEO_FIMC */ +#ifdef CONFIG_FB_S5P_EXTDSP + s3cfb_extdsp_set_platdata(&default_extdsp_data); +#endif + + +#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC + smdk4x12_camera_config(); + smdk4x12_subdev_config(); + + dev_set_name(&s5p_device_fimc0.dev, "s3c-fimc.0"); + dev_set_name(&s5p_device_fimc1.dev, "s3c-fimc.1"); + dev_set_name(&s5p_device_fimc2.dev, "s3c-fimc.2"); + dev_set_name(&s5p_device_fimc3.dev, "s3c-fimc.3"); + + clk_add_alias("fimc", "exynos4210-fimc.0", "fimc", &s5p_device_fimc0.dev); + clk_add_alias("sclk_fimc", "exynos4210-fimc.0", "sclk_fimc", + &s5p_device_fimc0.dev); + clk_add_alias("fimc", "exynos4210-fimc.1", "fimc", &s5p_device_fimc1.dev); + clk_add_alias("sclk_fimc", "exynos4210-fimc.1", "sclk_fimc", + &s5p_device_fimc1.dev); + clk_add_alias("fimc", "exynos4210-fimc.2", "fimc", &s5p_device_fimc2.dev); + clk_add_alias("sclk_fimc", "exynos4210-fimc.2", "sclk_fimc", + &s5p_device_fimc2.dev); + clk_add_alias("fimc", "exynos4210-fimc.3", "fimc", &s5p_device_fimc3.dev); + clk_add_alias("sclk_fimc", "exynos4210-fimc.3", "sclk_fimc", + &s5p_device_fimc3.dev); + + s3c_fimc_setname(0, "exynos4210-fimc"); + s3c_fimc_setname(1, "exynos4210-fimc"); + s3c_fimc_setname(2, "exynos4210-fimc"); + s3c_fimc_setname(3, "exynos4210-fimc"); + /* FIMC */ + s3c_set_platdata(&s3c_fimc0_default_data, + sizeof(s3c_fimc0_default_data), &s5p_device_fimc0); + s3c_set_platdata(&s3c_fimc1_default_data, + sizeof(s3c_fimc1_default_data), &s5p_device_fimc1); + s3c_set_platdata(&s3c_fimc2_default_data, + sizeof(s3c_fimc2_default_data), &s5p_device_fimc2); + s3c_set_platdata(&s3c_fimc3_default_data, + sizeof(s3c_fimc3_default_data), &s5p_device_fimc3); +#ifdef CONFIG_EXYNOS_DEV_PD + s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev; + s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev; + s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev; + s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev; +#endif +#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS + dev_set_name(&s5p_device_mipi_csis0.dev, "s3c-csis.0"); + dev_set_name(&s5p_device_mipi_csis1.dev, "s3c-csis.1"); + clk_add_alias("csis", "s5p-mipi-csis.0", "csis", + &s5p_device_mipi_csis0.dev); + clk_add_alias("sclk_csis", "s5p-mipi-csis.0", "sclk_csis", + &s5p_device_mipi_csis0.dev); + clk_add_alias("csis", "s5p-mipi-csis.1", "csis", + &s5p_device_mipi_csis1.dev); + clk_add_alias("sclk_csis", "s5p-mipi-csis.1", "sclk_csis", + &s5p_device_mipi_csis1.dev); + dev_set_name(&s5p_device_mipi_csis0.dev, "s5p-mipi-csis.0"); + dev_set_name(&s5p_device_mipi_csis1.dev, "s5p-mipi-csis.1"); + + s3c_set_platdata(&s5p_mipi_csis0_default_data, + sizeof(s5p_mipi_csis0_default_data), &s5p_device_mipi_csis0); + s3c_set_platdata(&s5p_mipi_csis1_default_data, + sizeof(s5p_mipi_csis1_default_data), &s5p_device_mipi_csis1); +#ifdef CONFIG_EXYNOS_DEV_PD + s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev; + s5p_device_mipi_csis1.dev.parent = &exynos4_device_pd[PD_CAM].dev; +#endif +#endif +#if defined(CONFIG_ITU_A) || defined(CONFIG_CSI_C) \ + || defined(CONFIG_S5K3H1_CSI_C) || defined(CONFIG_S5K3H2_CSI_C) \ + || defined(CONFIG_S5K6A3_CSI_C) + smdk4x12_cam0_reset(1); +#endif +#if defined(CONFIG_ITU_B) || defined(CONFIG_CSI_D) \ + || defined(CONFIG_S5K3H1_CSI_D) || defined(CONFIG_S5K3H2_CSI_D) \ + || defined(CONFIG_S5K6A3_CSI_D) + smdk4x12_cam1_reset(1); +#endif +#endif + +#if defined(CONFIG_VIDEO_TVOUT) + s5p_hdmi_hpd_set_platdata(&hdmi_hpd_data); + s5p_hdmi_cec_set_platdata(&hdmi_cec_data); +#ifdef CONFIG_EXYNOS_DEV_PD + s5p_device_tvout.dev.parent = &exynos4_device_pd[PD_TV].dev; + exynos4_device_pd[PD_TV].dev.parent = &exynos4_device_pd[PD_LCD0].dev; +#endif +#endif + +#ifdef CONFIG_VIDEO_JPEG_V2X +#ifdef CONFIG_EXYNOS_DEV_PD + s5p_device_jpeg.dev.parent = &exynos4_device_pd[PD_CAM].dev; + exynos4_jpeg_setup_clock(&s5p_device_jpeg.dev, 160000000); +#endif +#endif + +#ifdef CONFIG_ION_EXYNOS + exynos_ion_set_platdata(); +#endif + +#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) +#ifdef CONFIG_EXYNOS_DEV_PD + s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev; +#endif + if (soc_is_exynos4412() && samsung_rev() >= EXYNOS4412_REV_1_0) + exynos4_mfc_setup_clock(&s5p_device_mfc.dev, 200 * MHZ); + else + exynos4_mfc_setup_clock(&s5p_device_mfc.dev, 267 * MHZ); +#endif + +#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) + dev_set_name(&s5p_device_mfc.dev, "s3c-mfc"); + clk_add_alias("mfc", "s5p-mfc", "mfc", &s5p_device_mfc.dev); + s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc"); +#endif +#ifdef CONFIG_VIDEO_FIMG2D + s5p_fimg2d_set_platdata(&fimg2d_data); +#endif + if (samsung_board_rev_is_0_0()) + samsung_keypad_set_platdata(&smdk4x12_keypad_data0); + else + samsung_keypad_set_platdata(&smdk4x12_keypad_data1); + smdk4x12_smsc911x_init(); +#ifdef CONFIG_EXYNOS_C2C + exynos_c2c_set_platdata(&smdk4x12_c2c_pdata); +#endif + + exynos_sysmmu_init(); + + smdk4x12_gpio_power_init(); + + platform_add_devices(smdk4x12_devices, ARRAY_SIZE(smdk4x12_devices)); + if (soc_is_exynos4412()) + platform_add_devices(smdk4412_devices, ARRAY_SIZE(smdk4412_devices)); + +#ifdef CONFIG_FB_S3C + exynos4_fimd0_setup_clock(&s5p_device_fimd0.dev, "mout_mpll_user", + 800 * MHZ); +#endif +#ifdef CONFIG_S3C64XX_DEV_SPI + sclk = clk_get(spi0_dev, "dout_spi0"); + if (IS_ERR(sclk)) + dev_err(spi0_dev, "failed to get sclk for SPI-0\n"); + prnt = clk_get(spi0_dev, "mout_mpll_user"); + if (IS_ERR(prnt)) + dev_err(spi0_dev, "failed to get prnt\n"); + if (clk_set_parent(sclk, prnt)) + printk(KERN_ERR "Unable to set parent %s of clock %s.\n", + prnt->name, sclk->name); + + clk_set_rate(sclk, 800 * 1000 * 1000); + clk_put(sclk); + clk_put(prnt); + + if (!gpio_request(EXYNOS4_GPB(1), "SPI_CS0")) { + gpio_direction_output(EXYNOS4_GPB(1), 1); + s3c_gpio_cfgpin(EXYNOS4_GPB(1), S3C_GPIO_SFN(1)); + s3c_gpio_setpull(EXYNOS4_GPB(1), S3C_GPIO_PULL_UP); + exynos_spi_set_info(0, EXYNOS_SPI_SRCCLK_SCLK, + ARRAY_SIZE(spi0_csi)); + } + + spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info)); + +#ifndef CONFIG_FB_S5P_LMS501KF03 + sclk = clk_get(spi1_dev, "dout_spi1"); + if (IS_ERR(sclk)) + dev_err(spi1_dev, "failed to get sclk for SPI-1\n"); + prnt = clk_get(spi1_dev, "mout_mpll_user"); + if (IS_ERR(prnt)) + dev_err(spi1_dev, "failed to get prnt\n"); + if (clk_set_parent(sclk, prnt)) + printk(KERN_ERR "Unable to set parent %s of clock %s.\n", + prnt->name, sclk->name); + + clk_set_rate(sclk, 800 * 1000 * 1000); + clk_put(sclk); + clk_put(prnt); + + if (!gpio_request(EXYNOS4_GPB(5), "SPI_CS1")) { + gpio_direction_output(EXYNOS4_GPB(5), 1); + s3c_gpio_cfgpin(EXYNOS4_GPB(5), S3C_GPIO_SFN(1)); + s3c_gpio_setpull(EXYNOS4_GPB(5), S3C_GPIO_PULL_UP); + exynos_spi_set_info(1, EXYNOS_SPI_SRCCLK_SCLK, + ARRAY_SIZE(spi1_csi)); + } + + spi_register_board_info(spi1_board_info, ARRAY_SIZE(spi1_board_info)); +#endif + + sclk = clk_get(spi2_dev, "dout_spi2"); + if (IS_ERR(sclk)) + dev_err(spi2_dev, "failed to get sclk for SPI-2\n"); + prnt = clk_get(spi2_dev, "mout_mpll_user"); + if (IS_ERR(prnt)) + dev_err(spi2_dev, "failed to get prnt\n"); + if (clk_set_parent(sclk, prnt)) + printk(KERN_ERR "Unable to set parent %s of clock %s.\n", + prnt->name, sclk->name); + + clk_set_rate(sclk, 800 * 1000 * 1000); + clk_put(sclk); + clk_put(prnt); + + if (!gpio_request(EXYNOS4_GPC1(2), "SPI_CS2")) { + gpio_direction_output(EXYNOS4_GPC1(2), 1); + s3c_gpio_cfgpin(EXYNOS4_GPC1(2), S3C_GPIO_SFN(1)); + s3c_gpio_setpull(EXYNOS4_GPC1(2), S3C_GPIO_PULL_UP); + exynos_spi_set_info(2, EXYNOS_SPI_SRCCLK_SCLK, + ARRAY_SIZE(spi2_csi)); + } + + spi_register_board_info(spi2_board_info, ARRAY_SIZE(spi2_board_info)); +#endif +#ifdef CONFIG_BUSFREQ_OPP + dev_add(&busfreq, &exynos4_busfreq.dev); + ppmu_init(&exynos_ppmu[PPMU_DMC0], &exynos4_busfreq.dev); + ppmu_init(&exynos_ppmu[PPMU_DMC1], &exynos4_busfreq.dev); + ppmu_init(&exynos_ppmu[PPMU_CPU], &exynos4_busfreq.dev); +#endif + register_reboot_notifier(&exynos4_reboot_notifier); +} + +#ifdef CONFIG_EXYNOS_C2C +static void __init exynos_c2c_reserve(void) +{ + static struct cma_region region[] = { + { + .name = "c2c_shdmem", + .size = 64 * SZ_1M, + { .alignment = 64 * SZ_1M }, + .start = C2C_SHAREDMEM_BASE + }, { + .size = 0, + } + }; + + s5p_cma_region_reserve(region, NULL, 0, NULL); +} +#endif + +MACHINE_START(SMDK4212, "SMDK4X12") + .boot_params = S5P_PA_SDRAM + 0x100, + .init_irq = exynos4_init_irq, + .map_io = smdk4x12_map_io, + .init_machine = smdk4x12_machine_init, + .timer = &exynos4_timer, +#ifdef CONFIG_EXYNOS_C2C + .reserve = &exynos_c2c_reserve, +#endif +MACHINE_END + +MACHINE_START(SMDK4412, "SMDK4X12") + .boot_params = S5P_PA_SDRAM + 0x100, + .init_irq = exynos4_init_irq, + .map_io = smdk4x12_map_io, + .init_machine = smdk4x12_machine_init, + .timer = &exynos4_timer, +#ifdef CONFIG_EXYNOS_C2C + .reserve = &exynos_c2c_reserve, +#endif +MACHINE_END |