Merge branch 'dev/removing-s5p6442' into for-next
[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/gpio-cfg.h>
35 #include <plat/iic.h>
36
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
53 enum fixed_regulator_id {
54         FIXED_REG_ID_MMC = 0,
55 };
56
57 static 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 */
85 static 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
94 static struct regulator_consumer_supply emmc_supplies[] = {
95         REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
96         REGULATOR_SUPPLY("vmmc", "dw_mmc"),
97 };
98
99 static 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
108 static 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
116 static 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 */
125 static 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 */
137 static 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
145 static 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 */
153 static 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
179 static 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
184 static struct platform_device nuri_gpio_keys = {
185         .name                   = "gpio-keys",
186         .dev                    = {
187                 .platform_data  = &nuri_gpio_keys_data,
188         },
189 };
190
191 static 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
200 static 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
211 static 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
221 static void nuri_bl_exit(struct device *dev)
222 {
223         gpio_free(EXYNOS4_GPE2(3));
224 }
225
226 /* nuri pwm backlight */
227 static 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
237 static 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
246 static struct plat_lcd_data nuri_lcd_platform_data = {
247         .set_power              = nuri_lcd_power_on,
248 };
249
250 static 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
258 /* I2C1 */
259 static struct i2c_board_info i2c1_devs[] __initdata = {
260         /* Gyro, To be updated */
261 };
262
263 /* TSP */
264 static 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
303 static 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
318 static 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
326 static 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
334 static 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
345 /* GPIO I2C 5 (PMIC) */
346 static struct i2c_board_info i2c5_devs[] __initdata = {
347         /* max8997, To be updated */
348 };
349
350 static 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,
357         &s3c_device_timer[0],
358         &s3c_device_i2c3,
359
360         /* NURI Devices */
361         &nuri_gpio_keys,
362         &nuri_lcd_device,
363         &nuri_backlight_device,
364 };
365
366 static 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
373 static void __init nuri_machine_init(void)
374 {
375         nuri_sdhci_init();
376         nuri_tsp_init();
377
378         i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
379         s3c_i2c3_set_platdata(&i2c3_data);
380         i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
381         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
387 MACHINE_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,
394 MACHINE_END