aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-whistler.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/board-whistler.c')
-rw-r--r--arch/arm/mach-tegra/board-whistler.c560
1 files changed, 560 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-whistler.c b/arch/arm/mach-tegra/board-whistler.c
new file mode 100644
index 00000000000..2ff6e55e162
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler.c
@@ -0,0 +1,560 @@
1/*
2 * arch/arm/mach-tegra/board-whistler.c
3 *
4 * Copyright (c) 2010 - 2011, NVIDIA Corporation.
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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/ctype.h>
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/serial_8250.h>
28#include <linux/i2c.h>
29#include <linux/synaptics_i2c_rmi.h>
30#include <linux/dma-mapping.h>
31#include <linux/delay.h>
32#include <linux/i2c-tegra.h>
33#include <linux/gpio.h>
34#include <linux/gpio_scrollwheel.h>
35#include <linux/input.h>
36#include <linux/platform_data/tegra_usb.h>
37#include <linux/mfd/max8907c.h>
38#include <linux/memblock.h>
39#include <linux/tegra_uart.h>
40
41#include <mach/clk.h>
42#include <mach/iomap.h>
43#include <mach/irqs.h>
44#include <mach/pinmux.h>
45#include <mach/iomap.h>
46#include <mach/io.h>
47#include <mach/i2s.h>
48#include <mach/tegra_wm8753_pdata.h>
49#include <sound/tlv320aic326x.h>
50
51#include <asm/mach-types.h>
52#include <asm/mach/arch.h>
53#include <mach/usb_phy.h>
54
55#include "board.h"
56#include "clock.h"
57#include "board-whistler.h"
58#include "devices.h"
59#include "gpio-names.h"
60#include "fuse.h"
61#include "pm.h"
62#include "board-whistler-baseband.h"
63
64#define SZ_3M (SZ_1M + SZ_2M)
65#define SZ_152M (SZ_128M + SZ_16M + SZ_8M)
66#define USB1_VBUS_GPIO TCA6416_GPIO_BASE
67
68static struct platform_device *whistler_uart_devices[] __initdata = {
69 &tegra_uarta_device,
70 &tegra_uartb_device,
71 &tegra_uartc_device,
72};
73
74struct uart_clk_parent uart_parent_clk[] = {
75 [0] = {.name = "pll_p"},
76 [1] = {.name = "pll_m"},
77 [2] = {.name = "clk_m"},
78};
79
80static struct tegra_uart_platform_data whistler_uart_pdata;
81
82static void __init uart_debug_init(void)
83{
84 unsigned long rate;
85 struct clk *debug_uart_clk;
86 struct clk *c;
87 int modem_id = tegra_get_modem_id();
88
89 if (modem_id == 0x1) {
90 /* UARTB is the debug port. */
91 pr_info("Selecting UARTB as the debug console\n");
92 whistler_uart_devices[1] = &debug_uartb_device;
93 debug_uart_port_base = ((struct plat_serial8250_port *)(
94 debug_uartb_device.dev.platform_data))->mapbase;
95 debug_uart_clk = clk_get_sys("serial8250.0", "uartb");
96
97 /* Clock enable for the debug channel */
98 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
99 rate = ((struct plat_serial8250_port *)(
100 debug_uartb_device.dev.platform_data))->uartclk;
101 pr_info("The debug console clock name is %s\n",
102 debug_uart_clk->name);
103 c = tegra_get_clock_by_name("pll_p");
104 if (IS_ERR_OR_NULL(c))
105 pr_err("Not getting the parent clock pll_p\n");
106 else
107 clk_set_parent(debug_uart_clk, c);
108
109 clk_enable(debug_uart_clk);
110 clk_set_rate(debug_uart_clk, rate);
111 } else {
112 pr_err("Not getting the clock %s for debug console\n",
113 debug_uart_clk->name);
114 }
115 } else {
116 /* UARTA is the debug port. */
117 pr_info("Selecting UARTA as the debug console\n");
118 whistler_uart_devices[0] = &debug_uarta_device;
119 debug_uart_port_base = ((struct plat_serial8250_port *)(
120 debug_uarta_device.dev.platform_data))->mapbase;
121 debug_uart_clk = clk_get_sys("serial8250.0", "uarta");
122
123 /* Clock enable for the debug channel */
124 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
125 rate = ((struct plat_serial8250_port *)(
126 debug_uarta_device.dev.platform_data))->uartclk;
127 pr_info("The debug console clock name is %s\n",
128 debug_uart_clk->name);
129 c = tegra_get_clock_by_name("pll_p");
130 if (IS_ERR_OR_NULL(c))
131 pr_err("Not getting the parent clock pll_p\n");
132 else
133 clk_set_parent(debug_uart_clk, c);
134
135 clk_enable(debug_uart_clk);
136 clk_set_rate(debug_uart_clk, rate);
137 } else {
138 pr_err("Not getting the clock %s for debug console\n",
139 debug_uart_clk->name);
140 }
141 }
142}
143
144static void __init whistler_uart_init(void)
145{
146 int i;
147 struct clk *c;
148
149 for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) {
150 c = tegra_get_clock_by_name(uart_parent_clk[i].name);
151 if (IS_ERR_OR_NULL(c)) {
152 pr_err("Not able to get the clock for %s\n",
153 uart_parent_clk[i].name);
154 continue;
155 }
156 uart_parent_clk[i].parent_clk = c;
157 uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c);
158 }
159 whistler_uart_pdata.parent_clk_list = uart_parent_clk;
160 whistler_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk);
161
162 tegra_uarta_device.dev.platform_data = &whistler_uart_pdata;
163 tegra_uartb_device.dev.platform_data = &whistler_uart_pdata;
164 tegra_uartc_device.dev.platform_data = &whistler_uart_pdata;
165
166 if (!is_tegra_debug_uartport_hs())
167 uart_debug_init();
168
169 platform_add_devices(whistler_uart_devices,
170 ARRAY_SIZE(whistler_uart_devices));
171}
172
173static struct resource whistler_bcm4329_rfkill_resources[] = {
174 {
175 .name = "bcm4329_nshutdown_gpio",
176 .start = TEGRA_GPIO_PU0,
177 .end = TEGRA_GPIO_PU0,
178 .flags = IORESOURCE_IO,
179 },
180};
181
182static struct platform_device whistler_bcm4329_rfkill_device = {
183 .name = "bcm4329_rfkill",
184 .id = -1,
185 .num_resources = ARRAY_SIZE(whistler_bcm4329_rfkill_resources),
186 .resource = whistler_bcm4329_rfkill_resources,
187};
188
189static struct resource whistler_bluesleep_resources[] = {
190 [0] = {
191 .name = "gpio_host_wake",
192 .start = TEGRA_GPIO_PU6,
193 .end = TEGRA_GPIO_PU6,
194 .flags = IORESOURCE_IO,
195 },
196 [1] = {
197 .name = "gpio_ext_wake",
198 .start = TEGRA_GPIO_PU1,
199 .end = TEGRA_GPIO_PU1,
200 .flags = IORESOURCE_IO,
201 },
202 [2] = {
203 .name = "host_wake",
204 .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
205 .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6),
206 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
207 },
208};
209
210static struct platform_device whistler_bluesleep_device = {
211 .name = "bluesleep",
212 .id = -1,
213 .num_resources = ARRAY_SIZE(whistler_bluesleep_resources),
214 .resource = whistler_bluesleep_resources,
215};
216
217static void __init whistler_setup_bluesleep(void)
218{
219 platform_device_register(&whistler_bluesleep_device);
220 tegra_gpio_enable(TEGRA_GPIO_PU6);
221 tegra_gpio_enable(TEGRA_GPIO_PU1);
222 return;
223}
224
225static struct tegra_utmip_config utmi_phy_config[] = {
226 [0] = {
227 .hssync_start_delay = 9,
228 .idle_wait_delay = 17,
229 .elastic_limit = 16,
230 .term_range_adj = 6,
231 .xcvr_setup = 15,
232 .xcvr_lsfslew = 2,
233 .xcvr_lsrslew = 2,
234 },
235 [1] = {
236 .hssync_start_delay = 9,
237 .idle_wait_delay = 17,
238 .elastic_limit = 16,
239 .term_range_adj = 6,
240 .xcvr_setup = 8,
241 .xcvr_lsfslew = 2,
242 .xcvr_lsrslew = 2,
243 },
244};
245
246static struct tegra_ulpi_config ulpi_phy_config = {
247 .reset_gpio = TEGRA_GPIO_PG2,
248 .clk = "cdev2",
249};
250
251static __initdata struct tegra_clk_init_table whistler_clk_init_table[] = {
252 /* name parent rate enabled */
253 { "pwm", "clk_32k", 32768, false},
254 { "kbc", "clk_32k", 32768, true},
255 { "sdmmc2", "pll_p", 25000000, false},
256 { "i2s1", "pll_a_out0", 0, false},
257 { "i2s2", "pll_a_out0", 0, false},
258 { "spdif_out", "pll_a_out0", 0, false},
259 { NULL, NULL, 0, 0},
260};
261
262static struct tegra_i2c_platform_data whistler_i2c1_platform_data = {
263 .adapter_nr = 0,
264 .bus_count = 1,
265 .bus_clk_rate = { 400000, 0 },
266 .scl_gpio = {TEGRA_GPIO_PC4, 0},
267 .sda_gpio = {TEGRA_GPIO_PC5, 0},
268 .arb_recovery = arb_lost_recovery,
269};
270
271static const struct tegra_pingroup_config i2c2_ddc = {
272 .pingroup = TEGRA_PINGROUP_DDC,
273 .func = TEGRA_MUX_I2C2,
274};
275
276static const struct tegra_pingroup_config i2c2_gen2 = {
277 .pingroup = TEGRA_PINGROUP_PTA,
278 .func = TEGRA_MUX_I2C2,
279};
280
281static struct tegra_i2c_platform_data whistler_i2c2_platform_data = {
282 .adapter_nr = 1,
283 .bus_count = 2,
284 .bus_clk_rate = { 100000, 100000 },
285 .bus_mux = { &i2c2_ddc, &i2c2_gen2 },
286 .bus_mux_len = { 1, 1 },
287 .scl_gpio = {0, TEGRA_GPIO_PT5},
288 .sda_gpio = {0, TEGRA_GPIO_PT6},
289 .arb_recovery = arb_lost_recovery,
290};
291
292static struct tegra_i2c_platform_data whistler_i2c3_platform_data = {
293 .adapter_nr = 3,
294 .bus_count = 1,
295 .bus_clk_rate = { 400000, 0 },
296 .scl_gpio = {TEGRA_GPIO_PBB2, 0},
297 .sda_gpio = {TEGRA_GPIO_PBB3, 0},
298 .arb_recovery = arb_lost_recovery,
299};
300
301static struct tegra_i2c_platform_data whistler_dvc_platform_data = {
302 .adapter_nr = 4,
303 .bus_count = 1,
304 .bus_clk_rate = { 400000, 0 },
305 .is_dvc = true,
306 .scl_gpio = {TEGRA_GPIO_PZ6, 0},
307 .sda_gpio = {TEGRA_GPIO_PZ7, 0},
308 .arb_recovery = arb_lost_recovery,
309};
310
311static struct aic326x_pdata whistler_aic3262_pdata = {
312 /* debounce time */
313 .debounce_time_ms = 512,
314};
315
316static struct i2c_board_info __initdata wm8753_board_info[] = {
317 {
318 I2C_BOARD_INFO("wm8753", 0x1a),
319 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_HP_DET),
320 },
321 {
322 I2C_BOARD_INFO("aic3262-codec", 0x18),
323 .platform_data = &whistler_aic3262_pdata,
324 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_HP_DET),
325 },
326};
327
328static void whistler_i2c_init(void)
329{
330 tegra_i2c_device1.dev.platform_data = &whistler_i2c1_platform_data;
331 tegra_i2c_device2.dev.platform_data = &whistler_i2c2_platform_data;
332 tegra_i2c_device3.dev.platform_data = &whistler_i2c3_platform_data;
333 tegra_i2c_device4.dev.platform_data = &whistler_dvc_platform_data;
334
335 platform_device_register(&tegra_i2c_device4);
336 platform_device_register(&tegra_i2c_device3);
337 platform_device_register(&tegra_i2c_device2);
338 platform_device_register(&tegra_i2c_device1);
339
340 i2c_register_board_info(4, wm8753_board_info,
341 ARRAY_SIZE(wm8753_board_info));
342}
343
344#define GPIO_SCROLL(_pinaction, _gpio, _desc) \
345{ \
346 .pinaction = GPIO_SCROLLWHEEL_PIN_##_pinaction, \
347 .gpio = TEGRA_GPIO_##_gpio, \
348 .desc = _desc, \
349 .active_low = 1, \
350 .debounce_interval = 2, \
351}
352
353static struct gpio_scrollwheel_button scroll_keys[] = {
354 [0] = GPIO_SCROLL(ONOFF, PR3, "sw_onoff"),
355 [1] = GPIO_SCROLL(PRESS, PQ5, "sw_press"),
356 [2] = GPIO_SCROLL(ROT1, PQ3, "sw_rot1"),
357 [3] = GPIO_SCROLL(ROT2, PQ4, "sw_rot2"),
358};
359
360static struct gpio_scrollwheel_platform_data whistler_scroll_platform_data = {
361 .buttons = scroll_keys,
362 .nbuttons = ARRAY_SIZE(scroll_keys),
363};
364
365static struct platform_device whistler_scroll_device = {
366 .name = "alps-gpio-scrollwheel",
367 .id = 0,
368 .dev = {
369 .platform_data = &whistler_scroll_platform_data,
370 },
371};
372
373static struct platform_device tegra_camera = {
374 .name = "tegra_camera",
375 .id = -1,
376};
377
378static struct tegra_wm8753_platform_data whistler_audio_pdata = {
379 .gpio_spkr_en = -1,
380 .gpio_hp_det = TEGRA_GPIO_HP_DET,
381 .gpio_hp_mute = -1,
382 .gpio_int_mic_en = -1,
383 .gpio_ext_mic_en = -1,
384 .debounce_time_hp = 200,
385};
386
387static struct platform_device whistler_audio_device1 = {
388 .name = "tegra-snd-aic326x",
389 .id = 0,
390 .dev = {
391 .platform_data = &whistler_audio_pdata,
392 },
393};
394
395static struct platform_device whistler_audio_device2 = {
396 .name = "tegra-snd-wm8753",
397 .id = 0,
398 .dev = {
399 .platform_data = &whistler_audio_pdata,
400 },
401};
402
403static struct platform_device *whistler_devices[] __initdata = {
404 &tegra_pmu_device,
405 &tegra_udc_device,
406 &tegra_gart_device,
407 &tegra_aes_device,
408 &tegra_wdt_device,
409 &tegra_avp_device,
410 &whistler_scroll_device,
411 &tegra_camera,
412 &tegra_i2s_device1,
413 &tegra_i2s_device2,
414 &tegra_spdif_device,
415 &tegra_das_device,
416 &spdif_dit_device,
417 &bluetooth_dit_device,
418 &baseband_dit_device,
419 &whistler_bcm4329_rfkill_device,
420 &tegra_pcm_device,
421 &whistler_audio_device1,
422 &whistler_audio_device2,
423};
424
425static struct synaptics_i2c_rmi_platform_data synaptics_pdata = {
426 .flags = SYNAPTICS_FLIP_X | SYNAPTICS_FLIP_Y | SYNAPTICS_SWAP_XY,
427 .irqflags = IRQF_TRIGGER_LOW,
428};
429
430static const struct i2c_board_info whistler_i2c_touch_info[] = {
431 {
432 I2C_BOARD_INFO("synaptics-rmi-ts", 0x20),
433 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PC6),
434 .platform_data = &synaptics_pdata,
435 },
436};
437
438static int __init whistler_touch_init(void)
439{
440 tegra_gpio_enable(TEGRA_GPIO_PC6);
441 i2c_register_board_info(0, whistler_i2c_touch_info, 1);
442
443 return 0;
444}
445
446static int __init whistler_scroll_init(void)
447{
448 int i;
449 for (i = 0; i < ARRAY_SIZE(scroll_keys); i++)
450 tegra_gpio_enable(scroll_keys[i].gpio);
451
452 return 0;
453}
454
455static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
456 [0] = {
457 .instance = 0,
458 .vbus_irq = MAX8907C_INT_BASE + MAX8907C_IRQ_VCHG_DC_R,
459 .vbus_gpio = USB1_VBUS_GPIO,
460 },
461 [1] = {
462 .instance = 1,
463 .vbus_gpio = -1,
464 },
465 [2] = {
466 .instance = 2,
467 .vbus_gpio = -1,
468 },
469};
470
471static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
472 [0] = {
473 .phy_config = &utmi_phy_config[0],
474 .operating_mode = TEGRA_USB_HOST,
475 .power_down_on_bus_suspend = 1,
476 .default_enable = false,
477 },
478 [1] = {
479 .phy_config = &ulpi_phy_config,
480 .operating_mode = TEGRA_USB_HOST,
481 .power_down_on_bus_suspend = 1,
482 .default_enable = false,
483 },
484 [2] = {
485 .phy_config = &utmi_phy_config[1],
486 .operating_mode = TEGRA_USB_HOST,
487 .power_down_on_bus_suspend = 1,
488 .default_enable = false,
489 },
490};
491
492static struct tegra_otg_platform_data tegra_otg_pdata = {
493 .ehci_device = &tegra_ehci1_device,
494 .ehci_pdata = &tegra_ehci_pdata[0],
495};
496
497static int __init whistler_gps_init(void)
498{
499 tegra_gpio_enable(TEGRA_GPIO_PU4);
500 return 0;
501}
502
503static void whistler_usb_init(void)
504{
505 tegra_usb_phy_init(tegra_usb_phy_pdata, ARRAY_SIZE(tegra_usb_phy_pdata));
506
507 tegra_otg_device.dev.platform_data = &tegra_otg_pdata;
508 platform_device_register(&tegra_otg_device);
509
510}
511
512static void __init tegra_whistler_init(void)
513{
514 int modem_id = tegra_get_modem_id();
515 tegra_clk_init_from_table(whistler_clk_init_table);
516 whistler_pinmux_init();
517 whistler_i2c_init();
518 whistler_uart_init();
519 platform_add_devices(whistler_devices, ARRAY_SIZE(whistler_devices));
520 tegra_ram_console_debug_init();
521 whistler_sdhci_init();
522 whistler_regulator_init();
523 whistler_panel_init();
524 whistler_sensors_init();
525 whistler_touch_init();
526 whistler_kbc_init();
527 whistler_gps_init();
528 whistler_usb_init();
529 whistler_scroll_init();
530 whistler_emc_init();
531 if (modem_id == 0x1)
532 whistler_baseband_init();
533 whistler_setup_bluesleep();
534 tegra_release_bootloader_fb();
535}
536
537int __init tegra_whistler_protected_aperture_init(void)
538{
539 tegra_protected_aperture_init(tegra_grhost_aperture);
540 return 0;
541}
542
543void __init tegra_whistler_reserve(void)
544{
545 if (memblock_reserve(0x0, 4096) < 0)
546 pr_warn("Cannot reserve first 4K of memory for safety\n");
547
548 tegra_reserve(SZ_152M, SZ_3M, SZ_1M);
549 tegra_ram_console_debug_reserve(SZ_1M);
550}
551
552MACHINE_START(WHISTLER, "whistler")
553 .boot_params = 0x00000100,
554 .map_io = tegra_map_common_io,
555 .reserve = tegra_whistler_reserve,
556 .init_early = tegra_init_early,
557 .init_irq = tegra_init_irq,
558 .timer = &tegra_timer,
559 .init_machine = tegra_whistler_init,
560MACHINE_END