diff options
Diffstat (limited to 'arch/arm/mach-s5pv210/mach-smdkc110.c')
-rw-r--r-- | arch/arm/mach-s5pv210/mach-smdkc110.c | 589 |
1 files changed, 582 insertions, 7 deletions
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index 6c412c8..85d1b73 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c @@ -10,27 +10,51 @@ #include <linux/kernel.h> #include <linux/types.h> +#include <linux/i2c.h> +#include <linux/regulator/consumer.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> +#include <linux/mfd/max8698.h> #include <linux/init.h> #include <linux/serial_core.h> -#include <linux/i2c.h> #include <linux/sysdev.h> +#include <linux/dm9000.h> +#include <linux/fb.h> +#include <linux/gpio.h> +#include <linux/gpio_event.h> +#include <linux/delay.h> +#include <linux/pwm_backlight.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/setup.h> #include <asm/mach-types.h> +#include <video/platform_lcd.h> + #include <mach/map.h> +#include <mach/gpio.h> #include <mach/regs-clock.h> +#include <mach/cpu-freq-v210.h> +#include <mach/media.h> #include <plat/regs-serial.h> +#include <plat/regs-srom.h> +#include <plat/gpio-cfg.h> #include <plat/s5pv210.h> #include <plat/devs.h> #include <plat/cpu.h> +#include <plat/adc.h> +#include <plat/ts.h> #include <plat/ata.h> #include <plat/iic.h> +#include <plat/keypad.h> #include <plat/pm.h> +#include <plat/fb.h> #include <plat/s5p-time.h> +#include <plat/media.h> +#include <plat/backlight.h> +#include <plat/regs-fb-v4.h> /* Following are default values for UCON, ULCON and UFCON UART registers */ #define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ @@ -77,23 +101,511 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = { }, }; +#ifdef CONFIG_CPU_FREQ +static struct s5pv210_cpufreq_voltage smdkc110_cpufreq_volt[] = { + { + .freq = 1000000, + .varm = 1275000, + .vint = 1100000, + }, { + .freq = 800000, + .varm = 1200000, + .vint = 1100000, + }, { + .freq = 400000, + .varm = 1050000, + .vint = 1100000, + }, { + .freq = 200000, + .varm = 950000, + .vint = 1100000, + }, { + .freq = 100000, + .varm = 950000, + .vint = 1000000, + }, +}; + +static struct s5pv210_cpufreq_data smdkc110_cpufreq_plat = { + .volt = smdkc110_cpufreq_volt, + .size = ARRAY_SIZE(smdkc110_cpufreq_volt), +}; +#endif + +#if defined(CONFIG_REGULATOR_MAX8698) +/* LDO */ +static struct regulator_consumer_supply smdkc110_ldo3_consumer[] = { + REGULATOR_SUPPLY("pd_io", "s3c-usbgadget") +}; + +static struct regulator_consumer_supply smdkc110_ldo5_consumer[] = { + REGULATOR_SUPPLY("AVDD", "0-001b"), + REGULATOR_SUPPLY("DVDD", "0-001b"), +}; + +static struct regulator_consumer_supply smdkc110_ldo8_consumer[] = { + REGULATOR_SUPPLY("pd_core", "s3c-usbgadget") +}; + +static struct regulator_init_data smdkc110_ldo2_data = { + .constraints = { + .name = "VALIVE_1.1V", + .min_uV = 1100000, + .max_uV = 1100000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, +}; + +static struct regulator_init_data smdkc110_ldo3_data = { + .constraints = { + .name = "VUOTG_D+VUHOST_D_1.1V", + .min_uV = 1100000, + .max_uV = 1100000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(smdkc110_ldo3_consumer), + .consumer_supplies = smdkc110_ldo3_consumer, +}; + +static struct regulator_init_data smdkc110_ldo4_data = { + .constraints = { + .name = "V_MIPI_1.8V", + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = 1, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, +}; + +static struct regulator_init_data smdkc110_ldo5_data = { + .constraints = { + .name = "VMMC+VEXT_2.8V", + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = 1, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .enabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(smdkc110_ldo5_consumer), + .consumer_supplies = smdkc110_ldo5_consumer, +}; + +static struct regulator_init_data smdkc110_ldo6_data = { + .constraints = { + .name = "VCC_2.6V", + .min_uV = 2600000, + .max_uV = 2600000, + .apply_uV = 1, + .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, +}; + +static struct regulator_init_data smdkc110_ldo7_data = { + .constraints = { + .name = "VDAC_2.8V", + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .enabled = 1, + }, + }, +}; + +static struct regulator_init_data smdkc110_ldo8_data = { + .constraints = { + .name = "VUOTG_A+VUHOST_A_3.3V", + .min_uV = 3300000, + .max_uV = 3300000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .state_mem = { + .disabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(smdkc110_ldo8_consumer), + .consumer_supplies = smdkc110_ldo8_consumer, +}; + +static struct regulator_init_data smdkc110_ldo9_data = { + .constraints = { + .name = "VADC+VSYS+VKEY_2.8V", + .min_uV = 2800000, + .max_uV = 2800000, + .apply_uV = 1, + .always_on = 1, + .state_mem = { + .enabled = 1, + }, + }, +}; + +/* BUCK */ +static struct regulator_consumer_supply smdkc110_buck1_consumer = + REGULATOR_SUPPLY("vddarm", NULL); + +static struct regulator_consumer_supply smdkc110_buck2_consumer = + REGULATOR_SUPPLY("vddint", NULL); + +static struct regulator_init_data smdkc110_buck1_data = { + .constraints = { + .name = "VCC_ARM", + .min_uV = 750000, + .max_uV = 1500000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .state_mem = { + .uV = 1250000, + .mode = REGULATOR_MODE_NORMAL, + .disabled = 1, + }, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &smdkc110_buck1_consumer, +}; + +static struct regulator_init_data smdkc110_buck2_data = { + .constraints = { + .name = "VCC_INTERNAL", + .min_uV = 950000, + .max_uV = 1200000, + .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 = &smdkc110_buck2_consumer, +}; + +static struct regulator_init_data smdkc110_buck3_data = { + .constraints = { + .name = "VCC_MEM", + .min_uV = 1800000, + .max_uV = 1800000, + .always_on = 1, + .apply_uV = 1, + .state_mem = { + .uV = 1800000, + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + }, +}; + +static struct max8698_regulator_data smdkc110_regulators[] = { + { MAX8698_LDO2, &smdkc110_ldo2_data }, + { MAX8698_LDO3, &smdkc110_ldo3_data }, + { MAX8698_LDO4, &smdkc110_ldo4_data }, + { MAX8698_LDO5, &smdkc110_ldo5_data }, + { MAX8698_LDO6, &smdkc110_ldo6_data }, + { MAX8698_LDO7, &smdkc110_ldo7_data }, + { MAX8698_LDO8, &smdkc110_ldo8_data }, + { MAX8698_LDO9, &smdkc110_ldo9_data }, + { MAX8698_BUCK1, &smdkc110_buck1_data }, + { MAX8698_BUCK2, &smdkc110_buck2_data }, + { MAX8698_BUCK3, &smdkc110_buck3_data }, +}; + +static struct max8698_platform_data smdkc110_max8698_pdata = { + .num_regulators = ARRAY_SIZE(smdkc110_regulators), + .regulators = smdkc110_regulators, + + /* 1GHz default voltage */ + .dvsarm1 = 0xa, /* 1.25v */ + .dvsarm2 = 0x9, /* 1.20V */ + .dvsarm3 = 0x6, /* 1.05V */ + .dvsarm4 = 0x4, /* 0.95V */ + .dvsint1 = 0x7, /* 1.10v */ + .dvsint2 = 0x5, /* 1.00V */ + + .set1 = S5PV210_GPH1(6), + .set2 = S5PV210_GPH1(7), + .set3 = S5PV210_GPH0(4), +}; +#endif + static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = { .setup_gpio = s5pv210_ide_setup_gpio, }; +static uint32_t smdkc110_keymap[] __initdata = { + /* KEY(row, col, keycode) */ + KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3), + KEY(0, 6, KEY_4), KEY(0, 7, KEY_5), + KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C), + KEY(1, 6, KEY_D), KEY(1, 7, KEY_E) +}; + +static struct matrix_keymap_data smdkc110_keymap_data __initdata = { + .keymap = smdkc110_keymap, + .keymap_size = ARRAY_SIZE(smdkc110_keymap), +}; + +static struct samsung_keypad_platdata smdkc110_keypad_data __initdata = { + .keymap_data = &smdkc110_keymap_data, + .rows = 2, + .cols = 8, +}; + +static struct resource smdkc110_dm9000_resources[] = { + [0] = { + .start = S5PV210_PA_SROM_BANK5, + .end = S5PV210_PA_SROM_BANK5, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = S5PV210_PA_SROM_BANK5 + 2, + .end = S5PV210_PA_SROM_BANK5 + 2, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_EINT(9), + .end = IRQ_EINT(9), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + }, +}; + +static struct dm9000_plat_data smdkc110_dm9000_platdata = { + .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM, + .dev_addr = { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 }, +}; + +struct platform_device smdkc110_dm9000 = { + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(smdkc110_dm9000_resources), + .resource = smdkc110_dm9000_resources, + .dev = { + .platform_data = &smdkc110_dm9000_platdata, + }, +}; + +#ifdef CONFIG_REGULATOR +static struct regulator_consumer_supply smdkc110_b_pwr_5v_consumers[] = { + { + /* WM8580 */ + .supply = "PVDD", + .dev_name = "0-001b", + }, +}; + +static struct regulator_init_data smdkc110_b_pwr_5v_data = { + .constraints = { + .always_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(smdkc110_b_pwr_5v_consumers), + .consumer_supplies = smdkc110_b_pwr_5v_consumers, +}; + +static struct fixed_voltage_config smdkc110_b_pwr_5v_pdata = { + .supply_name = "B_PWR_5V", + .microvolts = 5000000, + .init_data = &smdkc110_b_pwr_5v_data, +}; + +static struct platform_device smdkc110_b_pwr_5v = { + .name = "reg-fixed-voltage", + .id = -1, + .dev = { + .platform_data = &smdkc110_b_pwr_5v_pdata, + }, +}; +#endif + +static void smdkc110_lte480wv_set_power(struct plat_lcd_data *pd, + unsigned int power) +{ + if (power) { +#if !defined(CONFIG_BACKLIGHT_PWM) + gpio_request(S5PV210_GPD0(3), "GPD0"); + gpio_direction_output(S5PV210_GPD0(3), 1); + gpio_free(S5PV210_GPD0(3)); +#endif + + /* fire nRESET on power up */ + gpio_request(S5PV210_GPH0(6), "GPH0"); + + gpio_direction_output(S5PV210_GPH0(6), 1); + + gpio_set_value(S5PV210_GPH0(6), 0); + mdelay(10); + + gpio_set_value(S5PV210_GPH0(6), 1); + mdelay(10); + + gpio_free(S5PV210_GPH0(6)); + } else { +#if !defined(CONFIG_BACKLIGHT_PWM) + gpio_request(S5PV210_GPD0(3), "GPD0"); + gpio_direction_output(S5PV210_GPD0(3), 0); + gpio_free(S5PV210_GPD0(3)); +#endif + } +} + +static struct plat_lcd_data smdkc110_lcd_lte480wv_data = { + .set_power = smdkc110_lte480wv_set_power, +}; + +static struct platform_device smdkc110_lcd_lte480wv = { + .name = "platform-lcd", + .dev.parent = &s3c_device_fb.dev, + .dev.platform_data = &smdkc110_lcd_lte480wv_data, +}; + +static struct s3c_fb_pd_win smdkc110_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, + }, + .max_bpp = 32, + .default_bpp = 24, +}; + +static struct s3c_fb_platdata smdkc110_lcd0_pdata __initdata = { + .win[0] = &smdkc110_fb_win0, + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, + .setup_gpio = s5pv210_fb_gpio_setup_24bpp, +}; + +static struct gpio_event_direct_entry smdkc110_keypad_key_map[] = { + { + .gpio = S5PV210_GPH3(7), + .code = KEY_POWER, + } +}; + +static struct gpio_event_input_info smdkc110_keypad_key_info = { + .info.func = gpio_event_input_func, + .info.no_suspend = true, + .debounce_time.tv64 = 5 * NSEC_PER_MSEC, + .type = EV_KEY, + .keymap = smdkc110_keypad_key_map, + .keymap_size = ARRAY_SIZE(smdkc110_keypad_key_map) +}; + +static struct gpio_event_info *smdkc110_input_info[] = { + &smdkc110_keypad_key_info.info, +}; + +static struct gpio_event_platform_data smdkc110_input_data = { + .names = { + "smdkc110-keypad", + NULL, + }, + .info = smdkc110_input_info, + .info_count = ARRAY_SIZE(smdkc110_input_info), +}; + +static struct platform_device smdkc110_input_device = { + .name = GPIO_EVENT_DEV_NAME, + .id = 0, + .dev = { + .platform_data = &smdkc110_input_data, + }, +}; + +#ifdef CONFIG_BATTERY_SAMSUNG +static struct platform_device samsung_device_battery = { + .name = "samsung-fake-battery", + .id = -1, +}; +#endif + static struct platform_device *smdkc110_devices[] __initdata = { - &samsung_asoc_dma, - &s5pv210_device_iis0, - &s5pv210_device_ac97, - &s5pv210_device_spdif, + &s3c_device_adc, &s3c_device_cfcon, + &s3c_device_fb, + &s3c_device_hsmmc0, + &s3c_device_hsmmc1, + &s3c_device_hsmmc2, + &s3c_device_hsmmc3, &s3c_device_i2c0, &s3c_device_i2c1, &s3c_device_i2c2, &s3c_device_rtc, + &s3c_device_ts, &s3c_device_wdt, + &s5pv210_device_ac97, + &s5pv210_device_iis0, + &s5pv210_device_spdif, +#ifdef CONFIG_CPU_FREQ + &s5pv210_device_cpufreq, +#endif + &samsung_asoc_dma, + &samsung_device_keypad, +#ifdef CONFIG_BATTERY_SAMSUNG + &samsung_device_battery, +#endif + &smdkc110_dm9000, + &smdkc110_lcd_lte480wv, + &smdkc110_input_device, +#ifdef CONFIG_REGULATOR + &smdkc110_b_pwr_5v, +#endif +#ifdef CONFIG_CRYPTO_S5P_DEV_ACE + &s5p_device_ace, +#endif }; +static void __init smdkc110_button_init(void) +{ + s3c_gpio_cfgpin(S5PV210_GPH3(7), (0xf << 28)); + s3c_gpio_setpull(S5PV210_GPH3(7), S3C_GPIO_PULL_NONE); + + s3c_gpio_cfgpin(S5PV210_GPH0(4), (0xf << 16)); + s3c_gpio_setpull(S5PV210_GPH0(4), S3C_GPIO_PULL_NONE); +} + +static void __init smdkc110_dm9000_init(void) +{ + unsigned int tmp; + + gpio_request(S5PV210_MP01(5), "nCS5"); + s3c_gpio_cfgpin(S5PV210_MP01(5), S3C_GPIO_SFN(2)); + gpio_free(S5PV210_MP01(5)); + + tmp = (5 << S5P_SROM_BCX__TACC__SHIFT); + __raw_writel(tmp, S5P_SROM_BC5); + + tmp = __raw_readl(S5P_SROM_BW); + tmp &= (S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS5__SHIFT); + tmp |= (1 << S5P_SROM_BW__NCS5__SHIFT); + __raw_writel(tmp, S5P_SROM_BW); +} + static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = { { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */ { I2C_BOARD_INFO("wm8580", 0x1b), }, @@ -104,7 +616,51 @@ static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = { }; static struct i2c_board_info smdkc110_i2c_devs2[] __initdata = { - /* To Be Updated */ +#if defined(CONFIG_REGULATOR_MAX8698) + { + I2C_BOARD_INFO("max8698", 0xCC >> 1), + .platform_data = &smdkc110_max8698_pdata, + }, +#endif +}; + +static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { + .delay = 10000, + .presc = 49, + .oversampling_shift = 2, + .cal_x_max = 800, + .cal_y_max = 480, + .cal_param = { + -13357, -85, 53858048, -95, -8493, 32809514, 65536 + }, +}; + +static void smdkc110_sound_init(void) +{ + u32 reg; + + reg = __raw_readl(S5P_CLK_OUT); + reg &= ~S5P_CLKOUT_CLKSEL_MASK; + reg &= ~S5P_CLKOUT_DIVVAL_MASK; + reg |= S5P_CLKOUT_CLKSEL_XUSBXTI; + reg |= 0x1 << S5P_CLKOUT_DIVVAL_SHIFT; + __raw_writel(reg, S5P_CLK_OUT); + + reg = __raw_readl(S5P_OTHERS); + reg &= ~S5P_OTHERS_CLKOUT_MASK; + reg |= S5P_OTHERS_CLKOUT_SYSCON; + __raw_writel(reg, S5P_OTHERS); +} + +/* LCD Backlight data */ +static struct samsung_bl_gpio_info smdkc110_bl_gpio_info = { + .no = S5PV210_GPD0(3), + .func = S3C_GPIO_SFN(2), +}; + +static struct platform_pwm_backlight_data smdkc110_bl_data = { + .pwm_id = 3, + .pwm_period_ns = 1000, }; static void __init smdkc110_map_io(void) @@ -112,13 +668,21 @@ static void __init smdkc110_map_io(void) s5p_init_io(NULL, 0, S5P_VA_CHIPID); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs)); - s5p_set_timer_source(S5P_PWM3, S5P_PWM4); + s5p_set_timer_source(S5P_PWM2, S5P_PWM4); + + s5p_reserve_mem(S5P_RANGE_MFC); } static void __init smdkc110_machine_init(void) { s3c_pm_init(); + smdkc110_button_init(); + smdkc110_dm9000_init(); + + samsung_keypad_set_platdata(&smdkc110_keypad_data); + s3c24xx_ts_set_platdata(&s3c_ts_platform); + s3c_i2c0_set_platdata(NULL); s3c_i2c1_set_platdata(NULL); s3c_i2c2_set_platdata(NULL); @@ -131,6 +695,17 @@ static void __init smdkc110_machine_init(void) s3c_ide_set_platdata(&smdkc110_ide_pdata); + s3c_fb_set_platdata(&smdkc110_lcd0_pdata); + +#ifdef CONFIG_CPU_FREQ + s5pv210_cpufreq_set_platdata(&smdkc110_cpufreq_plat); +#endif + + /* SOUND */ + smdkc110_sound_init(); + + samsung_bl_set(&smdkc110_bl_gpio_info, &smdkc110_bl_data); + platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices)); } |