Merge branch 'integration' into for-linus
[pandora-kernel.git] / arch / arm / mach-exynos4 / mach-nuri.c
1 /*
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>
15 #include <linux/i2c/atmel_mxt_ts.h>
16 #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>
21 #include <linux/fb.h>
22 #include <linux/pwm_backlight.h>
23
24 #include <video/platform_lcd.h>
25
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>
34 #include <plat/ehci.h>
35 #include <plat/clock.h>
36 #include <plat/gpio-cfg.h>
37 #include <plat/iic.h>
38
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
55 enum fixed_regulator_id {
56         FIXED_REG_ID_MMC = 0,
57 };
58
59 static 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 */
87 static 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
96 static struct regulator_consumer_supply emmc_supplies[] = {
97         REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
98         REGULATOR_SUPPLY("vmmc", "dw_mmc"),
99 };
100
101 static 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
110 static 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
118 static 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 */
127 static 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 */
139 static 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
147 static 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 */
155 static 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
181 static 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
186 static struct platform_device nuri_gpio_keys = {
187         .name                   = "gpio-keys",
188         .dev                    = {
189                 .platform_data  = &nuri_gpio_keys_data,
190         },
191 };
192
193 static 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
202 static 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
213 static 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
223 static void nuri_bl_exit(struct device *dev)
224 {
225         gpio_free(EXYNOS4_GPE2(3));
226 }
227
228 /* nuri pwm backlight */
229 static 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
239 static 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
248 static struct plat_lcd_data nuri_lcd_platform_data = {
249         .set_power              = nuri_lcd_power_on,
250 };
251
252 static 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
260 /* I2C1 */
261 static struct i2c_board_info i2c1_devs[] __initdata = {
262         /* Gyro, To be updated */
263 };
264
265 /* TSP */
266 static 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
305 static 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
320 static 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
328 static 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
336 static 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
347 /* GPIO I2C 5 (PMIC) */
348 static struct i2c_board_info i2c5_devs[] __initdata = {
349         /* max8997, To be updated */
350 };
351
352 /* USB EHCI */
353 static struct s5p_ehci_platdata nuri_ehci_pdata;
354
355 static 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
362 static 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,
369         &s3c_device_timer[0],
370         &s5p_device_ehci,
371         &s3c_device_i2c3,
372
373         /* NURI Devices */
374         &nuri_gpio_keys,
375         &nuri_lcd_device,
376         &nuri_backlight_device,
377 };
378
379 static 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
386 static void __init nuri_machine_init(void)
387 {
388         nuri_sdhci_init();
389         nuri_tsp_init();
390
391         i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
392         s3c_i2c3_set_platdata(&i2c3_data);
393         i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
394         i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
395
396         nuri_ehci_init();
397         clk_xusbxti.rate = 24000000;
398
399         /* Last */
400         platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
401 }
402
403 MACHINE_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,
410 MACHINE_END