blob: d13c5e81c6a443689a3d3b0d64987fcfcf49aa12 [file] [log] [blame]
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +09001/*
2 * linux/arch/arm/mach-exynos4/mach-nuri.c
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/serial_core.h>
13#include <linux/input.h>
14#include <linux/i2c.h>
Joonyoung Shim3260ecd2011-03-23 15:25:14 +090015#include <linux/i2c/atmel_mxt_ts.h>
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +090016#include <linux/gpio_keys.h>
17#include <linux/gpio.h>
18#include <linux/regulator/machine.h>
19#include <linux/regulator/fixed.h>
20#include <linux/mmc/host.h>
Donghwa Leecc7df872011-03-08 07:17:09 +090021#include <linux/fb.h>
22#include <linux/pwm_backlight.h>
23
24#include <video/platform_lcd.h>
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +090025
26#include <asm/mach/arch.h>
27#include <asm/mach-types.h>
28
29#include <plat/regs-serial.h>
30#include <plat/exynos4.h>
31#include <plat/cpu.h>
32#include <plat/devs.h>
33#include <plat/sdhci.h>
Joonyoung Shim3260ecd2011-03-23 15:25:14 +090034#include <plat/gpio-cfg.h>
35#include <plat/iic.h>
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +090036
37#include <mach/map.h>
38
39/* Following are default values for UCON, ULCON and UFCON UART registers */
40#define NURI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
41 S3C2410_UCON_RXILEVEL | \
42 S3C2410_UCON_TXIRQMODE | \
43 S3C2410_UCON_RXIRQMODE | \
44 S3C2410_UCON_RXFIFO_TOI | \
45 S3C2443_UCON_RXERR_IRQEN)
46
47#define NURI_ULCON_DEFAULT S3C2410_LCON_CS8
48
49#define NURI_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
50 S5PV210_UFCON_TXTRIG256 | \
51 S5PV210_UFCON_RXTRIG256)
52
53enum fixed_regulator_id {
54 FIXED_REG_ID_MMC = 0,
55};
56
57static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
58 {
59 .hwport = 0,
60 .ucon = NURI_UCON_DEFAULT,
61 .ulcon = NURI_ULCON_DEFAULT,
62 .ufcon = NURI_UFCON_DEFAULT,
63 },
64 {
65 .hwport = 1,
66 .ucon = NURI_UCON_DEFAULT,
67 .ulcon = NURI_ULCON_DEFAULT,
68 .ufcon = NURI_UFCON_DEFAULT,
69 },
70 {
71 .hwport = 2,
72 .ucon = NURI_UCON_DEFAULT,
73 .ulcon = NURI_ULCON_DEFAULT,
74 .ufcon = NURI_UFCON_DEFAULT,
75 },
76 {
77 .hwport = 3,
78 .ucon = NURI_UCON_DEFAULT,
79 .ulcon = NURI_ULCON_DEFAULT,
80 .ufcon = NURI_UFCON_DEFAULT,
81 },
82};
83
84/* eMMC */
85static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = {
86 .max_width = 8,
87 .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
88 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
89 MMC_CAP_DISABLE | MMC_CAP_ERASE),
90 .cd_type = S3C_SDHCI_CD_PERMANENT,
91 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
92};
93
94static struct regulator_consumer_supply emmc_supplies[] = {
95 REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
96 REGULATOR_SUPPLY("vmmc", "dw_mmc"),
97};
98
99static struct regulator_init_data emmc_fixed_voltage_init_data = {
100 .constraints = {
101 .name = "VMEM_VDD_2.8V",
102 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
103 },
104 .num_consumer_supplies = ARRAY_SIZE(emmc_supplies),
105 .consumer_supplies = emmc_supplies,
106};
107
108static struct fixed_voltage_config emmc_fixed_voltage_config = {
109 .supply_name = "MASSMEMORY_EN (inverted)",
110 .microvolts = 2800000,
111 .gpio = EXYNOS4_GPL1(1),
112 .enable_high = false,
113 .init_data = &emmc_fixed_voltage_init_data,
114};
115
116static struct platform_device emmc_fixed_voltage = {
117 .name = "reg-fixed-voltage",
118 .id = FIXED_REG_ID_MMC,
119 .dev = {
120 .platform_data = &emmc_fixed_voltage_config,
121 },
122};
123
124/* SD */
125static struct s3c_sdhci_platdata nuri_hsmmc2_data __initdata = {
126 .max_width = 4,
127 .host_caps = MMC_CAP_4_BIT_DATA |
128 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
129 MMC_CAP_DISABLE,
130 .ext_cd_gpio = EXYNOS4_GPX3(3), /* XEINT_27 */
131 .ext_cd_gpio_invert = 1,
132 .cd_type = S3C_SDHCI_CD_GPIO,
133 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
134};
135
136/* WLAN */
137static struct s3c_sdhci_platdata nuri_hsmmc3_data __initdata = {
138 .max_width = 4,
139 .host_caps = MMC_CAP_4_BIT_DATA |
140 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
141 .cd_type = S3C_SDHCI_CD_EXTERNAL,
142 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
143};
144
145static void __init nuri_sdhci_init(void)
146{
147 s3c_sdhci0_set_platdata(&nuri_hsmmc0_data);
148 s3c_sdhci2_set_platdata(&nuri_hsmmc2_data);
149 s3c_sdhci3_set_platdata(&nuri_hsmmc3_data);
150}
151
152/* GPIO KEYS */
153static struct gpio_keys_button nuri_gpio_keys_tables[] = {
154 {
155 .code = KEY_VOLUMEUP,
156 .gpio = EXYNOS4_GPX2(0), /* XEINT16 */
157 .desc = "gpio-keys: KEY_VOLUMEUP",
158 .type = EV_KEY,
159 .active_low = 1,
160 .debounce_interval = 1,
161 }, {
162 .code = KEY_VOLUMEDOWN,
163 .gpio = EXYNOS4_GPX2(1), /* XEINT17 */
164 .desc = "gpio-keys: KEY_VOLUMEDOWN",
165 .type = EV_KEY,
166 .active_low = 1,
167 .debounce_interval = 1,
168 }, {
169 .code = KEY_POWER,
170 .gpio = EXYNOS4_GPX2(7), /* XEINT23 */
171 .desc = "gpio-keys: KEY_POWER",
172 .type = EV_KEY,
173 .active_low = 1,
174 .wakeup = 1,
175 .debounce_interval = 1,
176 },
177};
178
179static struct gpio_keys_platform_data nuri_gpio_keys_data = {
180 .buttons = nuri_gpio_keys_tables,
181 .nbuttons = ARRAY_SIZE(nuri_gpio_keys_tables),
182};
183
184static struct platform_device nuri_gpio_keys = {
185 .name = "gpio-keys",
186 .dev = {
187 .platform_data = &nuri_gpio_keys_data,
188 },
189};
190
Donghwa Leecc7df872011-03-08 07:17:09 +0900191static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power)
192{
193 int gpio = EXYNOS4_GPE1(5);
194
195 gpio_request(gpio, "LVDS_nSHDN");
196 gpio_direction_output(gpio, power);
197 gpio_free(gpio);
198}
199
200static int nuri_bl_init(struct device *dev)
201{
202 int ret, gpio = EXYNOS4_GPE2(3);
203
204 ret = gpio_request(gpio, "LCD_LDO_EN");
205 if (!ret)
206 gpio_direction_output(gpio, 0);
207
208 return ret;
209}
210
211static int nuri_bl_notify(struct device *dev, int brightness)
212{
213 if (brightness < 1)
214 brightness = 0;
215
216 gpio_set_value(EXYNOS4_GPE2(3), 1);
217
218 return brightness;
219}
220
221static void nuri_bl_exit(struct device *dev)
222{
223 gpio_free(EXYNOS4_GPE2(3));
224}
225
226/* nuri pwm backlight */
227static struct platform_pwm_backlight_data nuri_backlight_data = {
228 .pwm_id = 0,
229 .pwm_period_ns = 30000,
230 .max_brightness = 100,
231 .dft_brightness = 50,
232 .init = nuri_bl_init,
233 .notify = nuri_bl_notify,
234 .exit = nuri_bl_exit,
235};
236
237static struct platform_device nuri_backlight_device = {
238 .name = "pwm-backlight",
239 .id = -1,
240 .dev = {
241 .parent = &s3c_device_timer[0].dev,
242 .platform_data = &nuri_backlight_data,
243 },
244};
245
246static struct plat_lcd_data nuri_lcd_platform_data = {
247 .set_power = nuri_lcd_power_on,
248};
249
250static struct platform_device nuri_lcd_device = {
251 .name = "platform-lcd",
252 .id = -1,
253 .dev = {
254 .platform_data = &nuri_lcd_platform_data,
255 },
256};
257
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +0900258/* I2C1 */
259static struct i2c_board_info i2c1_devs[] __initdata = {
260 /* Gyro, To be updated */
261};
262
Joonyoung Shim3260ecd2011-03-23 15:25:14 +0900263/* TSP */
264static u8 mxt_init_vals[] = {
265 /* MXT_GEN_COMMAND(6) */
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 /* MXT_GEN_POWER(7) */
268 0x20, 0xff, 0x32,
269 /* MXT_GEN_ACQUIRE(8) */
270 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23,
271 /* MXT_TOUCH_MULTI(9) */
272 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00,
273 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00,
276 /* MXT_TOUCH_KEYARRAY(15) */
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
278 0x00,
279 /* MXT_SPT_GPIOPWM(19) */
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 /* MXT_PROCI_GRIPFACE(20) */
283 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04,
284 0x0f, 0x0a,
285 /* MXT_PROCG_NOISE(22) */
286 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00,
287 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03,
288 /* MXT_TOUCH_PROXIMITY(23) */
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00,
291 /* MXT_PROCI_ONETOUCH(24) */
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 /* MXT_SPT_SELFTEST(25) */
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00,
297 /* MXT_PROCI_TWOTOUCH(27) */
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 /* MXT_SPT_CTECONFIG(28) */
300 0x00, 0x00, 0x02, 0x08, 0x10, 0x00,
301};
302
303static struct mxt_platform_data mxt_platform_data = {
304 .config = mxt_init_vals,
305 .config_length = ARRAY_SIZE(mxt_init_vals),
306
307 .x_line = 18,
308 .y_line = 11,
309 .x_size = 1024,
310 .y_size = 600,
311 .blen = 0x1,
312 .threshold = 0x28,
313 .voltage = 2800000, /* 2.8V */
314 .orient = MXT_DIAGONAL_COUNTER,
315 .irqflags = IRQF_TRIGGER_FALLING,
316};
317
318static struct s3c2410_platform_i2c i2c3_data __initdata = {
319 .flags = 0,
320 .bus_num = 3,
321 .slave_addr = 0x10,
322 .frequency = 400 * 1000,
323 .sda_delay = 100,
324};
325
326static struct i2c_board_info i2c3_devs[] __initdata = {
327 {
328 I2C_BOARD_INFO("atmel_mxt_ts", 0x4a),
329 .platform_data = &mxt_platform_data,
330 .irq = IRQ_EINT(4),
331 },
332};
333
334static void __init nuri_tsp_init(void)
335{
336 int gpio;
337
338 /* TOUCH_INT: XEINT_4 */
339 gpio = EXYNOS4_GPX0(4);
340 gpio_request(gpio, "TOUCH_INT");
341 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
342 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
343}
344
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +0900345/* GPIO I2C 5 (PMIC) */
346static struct i2c_board_info i2c5_devs[] __initdata = {
347 /* max8997, To be updated */
348};
349
350static struct platform_device *nuri_devices[] __initdata = {
351 /* Samsung Platform Devices */
352 &emmc_fixed_voltage,
353 &s3c_device_hsmmc0,
354 &s3c_device_hsmmc2,
355 &s3c_device_hsmmc3,
356 &s3c_device_wdt,
Donghwa Leecc7df872011-03-08 07:17:09 +0900357 &s3c_device_timer[0],
Joonyoung Shim3260ecd2011-03-23 15:25:14 +0900358 &s3c_device_i2c3,
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +0900359
360 /* NURI Devices */
361 &nuri_gpio_keys,
Donghwa Leecc7df872011-03-08 07:17:09 +0900362 &nuri_lcd_device,
363 &nuri_backlight_device,
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +0900364};
365
366static void __init nuri_map_io(void)
367{
368 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
369 s3c24xx_init_clocks(24000000);
370 s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
371}
372
373static void __init nuri_machine_init(void)
374{
375 nuri_sdhci_init();
Joonyoung Shim3260ecd2011-03-23 15:25:14 +0900376 nuri_tsp_init();
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +0900377
378 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
Joonyoung Shim3260ecd2011-03-23 15:25:14 +0900379 s3c_i2c3_set_platdata(&i2c3_data);
380 i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
Minkyu Kangcaf8b1f22011-02-28 20:39:43 +0900381 i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
382
383 /* Last */
384 platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
385}
386
387MACHINE_START(NURI, "NURI")
388 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
389 .boot_params = S5P_PA_SDRAM + 0x100,
390 .init_irq = exynos4_init_irq,
391 .map_io = nuri_map_io,
392 .init_machine = nuri_machine_init,
393 .timer = &exynos4_timer,
394MACHINE_END