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