diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/mach-tegra/board-kai.c | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'arch/arm/mach-tegra/board-kai.c')
-rw-r--r-- | arch/arm/mach-tegra/board-kai.c | 854 |
1 files changed, 854 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-kai.c b/arch/arm/mach-tegra/board-kai.c new file mode 100644 index 00000000000..487f26ad7a2 --- /dev/null +++ b/arch/arm/mach-tegra/board-kai.c | |||
@@ -0,0 +1,854 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-kai.c | ||
3 | * | ||
4 | * Copyright (c) 2012, 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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/ctype.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/serial_8250.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/dma-mapping.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/i2c-tegra.h> | ||
31 | #include <linux/gpio.h> | ||
32 | #include <linux/input.h> | ||
33 | #include <linux/platform_data/tegra_usb.h> | ||
34 | #include <linux/spi/spi.h> | ||
35 | #include <linux/tegra_uart.h> | ||
36 | #include <linux/memblock.h> | ||
37 | #include <linux/spi-tegra.h> | ||
38 | #include <linux/nfc/pn544.h> | ||
39 | #include <linux/skbuff.h> | ||
40 | #include <linux/ti_wilink_st.h> | ||
41 | #include <linux/regulator/consumer.h> | ||
42 | #include <linux/smb349-charger.h> | ||
43 | #include <linux/max17048_battery.h> | ||
44 | #include <linux/leds.h> | ||
45 | #include <linux/i2c/at24.h> | ||
46 | |||
47 | #include <mach/clk.h> | ||
48 | #include <mach/iomap.h> | ||
49 | #include <mach/irqs.h> | ||
50 | #include <mach/pinmux.h> | ||
51 | #include <mach/iomap.h> | ||
52 | #include <mach/io.h> | ||
53 | #include <mach/i2s.h> | ||
54 | #include <mach/tegra_rt5640_pdata.h> | ||
55 | #include <asm/mach-types.h> | ||
56 | #include <asm/mach/arch.h> | ||
57 | #include <mach/usb_phy.h> | ||
58 | #include <mach/thermal.h> | ||
59 | |||
60 | #include "board.h" | ||
61 | #include "clock.h" | ||
62 | #include "board-kai.h" | ||
63 | #include "devices.h" | ||
64 | #include "gpio-names.h" | ||
65 | #include "fuse.h" | ||
66 | #include "pm.h" | ||
67 | #include "wdt-recovery.h" | ||
68 | |||
69 | /* All units are in millicelsius */ | ||
70 | static struct tegra_thermal_data thermal_data = { | ||
71 | .temp_throttle = 85000, | ||
72 | .temp_shutdown = 90000, | ||
73 | .temp_offset = TDIODE_OFFSET, /* temps based on tdiode */ | ||
74 | #ifdef CONFIG_TEGRA_EDP_LIMITS | ||
75 | .edp_offset = TDIODE_OFFSET, /* edp based on tdiode */ | ||
76 | .hysteresis_edp = 3000, | ||
77 | #endif | ||
78 | #ifdef CONFIG_TEGRA_THERMAL_SYSFS | ||
79 | .tc1 = 0, | ||
80 | .tc2 = 1, | ||
81 | .passive_delay = 2000, | ||
82 | #else | ||
83 | .hysteresis_throttle = 1000, | ||
84 | #endif | ||
85 | }; | ||
86 | |||
87 | /* !!!TODO: Change for kai (Taken from Ventana) */ | ||
88 | static struct tegra_utmip_config utmi_phy_config[] = { | ||
89 | [0] = { | ||
90 | .hssync_start_delay = 0, | ||
91 | .idle_wait_delay = 17, | ||
92 | .elastic_limit = 16, | ||
93 | .term_range_adj = 6, | ||
94 | .xcvr_setup = 15, | ||
95 | .xcvr_setup_offset = 0, | ||
96 | .xcvr_use_fuses = 1, | ||
97 | .xcvr_lsfslew = 2, | ||
98 | .xcvr_lsrslew = 2, | ||
99 | }, | ||
100 | [1] = { | ||
101 | .hssync_start_delay = 0, | ||
102 | .idle_wait_delay = 17, | ||
103 | .elastic_limit = 16, | ||
104 | .term_range_adj = 6, | ||
105 | .xcvr_setup = 15, | ||
106 | .xcvr_setup_offset = 0, | ||
107 | .xcvr_use_fuses = 1, | ||
108 | .xcvr_lsfslew = 2, | ||
109 | .xcvr_lsrslew = 2, | ||
110 | }, | ||
111 | [2] = { | ||
112 | .hssync_start_delay = 0, | ||
113 | .idle_wait_delay = 17, | ||
114 | .elastic_limit = 16, | ||
115 | .term_range_adj = 6, | ||
116 | .xcvr_setup = 8, | ||
117 | .xcvr_setup_offset = 0, | ||
118 | .xcvr_use_fuses = 1, | ||
119 | .xcvr_lsfslew = 2, | ||
120 | .xcvr_lsrslew = 2, | ||
121 | }, | ||
122 | }; | ||
123 | |||
124 | /* wl128x BT, FM, GPS connectivity chip */ | ||
125 | struct ti_st_plat_data kai_wilink_pdata = { | ||
126 | .nshutdown_gpio = TEGRA_GPIO_PU0, | ||
127 | .dev_name = BLUETOOTH_UART_DEV_NAME, | ||
128 | .flow_cntrl = 1, | ||
129 | .baud_rate = 3000000, | ||
130 | }; | ||
131 | |||
132 | static struct platform_device wl128x_device = { | ||
133 | .name = "kim", | ||
134 | .id = -1, | ||
135 | .dev.platform_data = &kai_wilink_pdata, | ||
136 | }; | ||
137 | |||
138 | static struct platform_device btwilink_device = { | ||
139 | .name = "btwilink", | ||
140 | .id = -1, | ||
141 | }; | ||
142 | |||
143 | static noinline void __init kai_bt_st(void) | ||
144 | { | ||
145 | pr_info("kai_bt_st"); | ||
146 | |||
147 | platform_device_register(&wl128x_device); | ||
148 | platform_device_register(&btwilink_device); | ||
149 | tegra_gpio_enable(TEGRA_GPIO_PU0); | ||
150 | } | ||
151 | |||
152 | static struct resource kai_bluesleep_resources[] = { | ||
153 | [0] = { | ||
154 | .name = "host_wake", | ||
155 | .start = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6), | ||
156 | .end = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PU6), | ||
157 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | ||
158 | }, | ||
159 | }; | ||
160 | |||
161 | static struct platform_device kai_bluesleep_device = { | ||
162 | .name = "tibluesleep", | ||
163 | .id = 0, | ||
164 | .num_resources = ARRAY_SIZE(kai_bluesleep_resources), | ||
165 | .resource = kai_bluesleep_resources, | ||
166 | }; | ||
167 | |||
168 | static noinline void __init kai_tegra_setup_tibluesleep(void) | ||
169 | { | ||
170 | platform_device_register(&kai_bluesleep_device); | ||
171 | tegra_gpio_enable(TEGRA_GPIO_PU6); | ||
172 | } | ||
173 | |||
174 | static __initdata struct tegra_clk_init_table kai_clk_init_table[] = { | ||
175 | /* name parent rate enabled */ | ||
176 | { "pll_m", NULL, 0, false}, | ||
177 | { "hda", "pll_p", 108000000, false}, | ||
178 | { "hda2codec_2x", "pll_p", 48000000, false}, | ||
179 | { "pwm", "pll_p", 3187500, false}, | ||
180 | { "blink", "clk_32k", 32768, true}, | ||
181 | { "i2s1", "pll_a_out0", 0, false}, | ||
182 | { "i2s3", "pll_a_out0", 0, false}, | ||
183 | { "i2s4", "pll_a_out0", 0, false}, | ||
184 | { "spdif_out", "pll_a_out0", 0, false}, | ||
185 | { "d_audio", "clk_m", 12000000, false}, | ||
186 | { "dam0", "clk_m", 12000000, false}, | ||
187 | { "dam1", "clk_m", 12000000, false}, | ||
188 | { "dam2", "clk_m", 12000000, false}, | ||
189 | { "audio1", "i2s1_sync", 0, false}, | ||
190 | { "audio3", "i2s3_sync", 0, false}, | ||
191 | { "vi_sensor", "pll_p", 150000000, false}, | ||
192 | { "i2c1", "pll_p", 3200000, false}, | ||
193 | { "i2c2", "pll_p", 3200000, false}, | ||
194 | { "i2c3", "pll_p", 3200000, false}, | ||
195 | { "i2c4", "pll_p", 3200000, false}, | ||
196 | { "i2c5", "pll_p", 3200000, false}, | ||
197 | { NULL, NULL, 0, 0}, | ||
198 | }; | ||
199 | |||
200 | static struct pn544_i2c_platform_data nfc_pdata = { | ||
201 | .irq_gpio = TEGRA_GPIO_PX0, | ||
202 | .ven_gpio = TEGRA_GPIO_PS7, | ||
203 | .firm_gpio = TEGRA_GPIO_PR3, | ||
204 | }; | ||
205 | |||
206 | static struct i2c_board_info __initdata kai_nfc_board_info[] = { | ||
207 | { | ||
208 | I2C_BOARD_INFO("pn544", 0x28), | ||
209 | .platform_data = &nfc_pdata, | ||
210 | .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_PX0), | ||
211 | }, | ||
212 | }; | ||
213 | |||
214 | static struct tegra_i2c_platform_data kai_i2c1_platform_data = { | ||
215 | .adapter_nr = 0, | ||
216 | .bus_count = 1, | ||
217 | .bus_clk_rate = { 100000, 0 }, | ||
218 | .scl_gpio = {TEGRA_GPIO_PC4, 0}, | ||
219 | .sda_gpio = {TEGRA_GPIO_PC5, 0}, | ||
220 | .arb_recovery = arb_lost_recovery, | ||
221 | }; | ||
222 | |||
223 | static struct tegra_i2c_platform_data kai_i2c2_platform_data = { | ||
224 | .adapter_nr = 1, | ||
225 | .bus_count = 1, | ||
226 | .bus_clk_rate = { 100000, 0 }, | ||
227 | .is_clkon_always = true, | ||
228 | .scl_gpio = {TEGRA_GPIO_PT5, 0}, | ||
229 | .sda_gpio = {TEGRA_GPIO_PT6, 0}, | ||
230 | .arb_recovery = arb_lost_recovery, | ||
231 | }; | ||
232 | |||
233 | static struct tegra_i2c_platform_data kai_i2c3_platform_data = { | ||
234 | .adapter_nr = 2, | ||
235 | .bus_count = 1, | ||
236 | .bus_clk_rate = { 100000, 0 }, | ||
237 | .scl_gpio = {TEGRA_GPIO_PBB1, 0}, | ||
238 | .sda_gpio = {TEGRA_GPIO_PBB2, 0}, | ||
239 | .arb_recovery = arb_lost_recovery, | ||
240 | }; | ||
241 | |||
242 | static struct tegra_i2c_platform_data kai_i2c4_platform_data = { | ||
243 | .adapter_nr = 3, | ||
244 | .bus_count = 1, | ||
245 | .bus_clk_rate = { 100000, 0 }, | ||
246 | .scl_gpio = {TEGRA_GPIO_PV4, 0}, | ||
247 | .sda_gpio = {TEGRA_GPIO_PV5, 0}, | ||
248 | .arb_recovery = arb_lost_recovery, | ||
249 | }; | ||
250 | |||
251 | static struct tegra_i2c_platform_data kai_i2c5_platform_data = { | ||
252 | .adapter_nr = 4, | ||
253 | .bus_count = 1, | ||
254 | .bus_clk_rate = { 400000, 0 }, | ||
255 | .scl_gpio = {TEGRA_GPIO_PZ6, 0}, | ||
256 | .sda_gpio = {TEGRA_GPIO_PZ7, 0}, | ||
257 | .arb_recovery = arb_lost_recovery, | ||
258 | }; | ||
259 | |||
260 | struct max17048_battery_model max17048_mdata = { | ||
261 | .rcomp = 170, | ||
262 | .soccheck_A = 252, | ||
263 | .soccheck_B = 254, | ||
264 | .bits = 19, | ||
265 | .alert_threshold = 0x00, | ||
266 | .one_percent_alerts = 0x40, | ||
267 | .alert_on_reset = 0x40, | ||
268 | .rcomp_seg = 0x0800, | ||
269 | .hibernate = 0x3080, | ||
270 | .vreset = 0x9696, | ||
271 | .valert = 0xD4AA, | ||
272 | .ocvtest = 55600, | ||
273 | }; | ||
274 | |||
275 | |||
276 | static struct at24_platform_data eeprom_info = { | ||
277 | .byte_len = (256*1024)/8, | ||
278 | .page_size = 64, | ||
279 | .flags = AT24_FLAG_ADDR16, | ||
280 | .setup = get_mac_addr, | ||
281 | }; | ||
282 | |||
283 | static struct i2c_board_info kai_i2c4_max17048_board_info[] = { | ||
284 | { | ||
285 | I2C_BOARD_INFO("max17048", 0x36), | ||
286 | .platform_data = &max17048_mdata, | ||
287 | }, | ||
288 | }; | ||
289 | |||
290 | static struct i2c_board_info kai_eeprom_mac_add = { | ||
291 | I2C_BOARD_INFO("at24", 0x56), | ||
292 | .platform_data = &eeprom_info, | ||
293 | }; | ||
294 | |||
295 | static struct i2c_board_info kai_i2c4_smb349_board_info[] = { | ||
296 | { | ||
297 | I2C_BOARD_INFO("smb349", 0x1B), | ||
298 | .irq = MAX77663_GPIO_BASE + MAX77663_GPIO1, | ||
299 | }, | ||
300 | }; | ||
301 | |||
302 | static struct i2c_board_info __initdata rt5640_board_info = { | ||
303 | I2C_BOARD_INFO("rt5640", 0x1c), | ||
304 | .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ), | ||
305 | }; | ||
306 | |||
307 | static struct i2c_board_info __initdata rt5639_board_info = { | ||
308 | I2C_BOARD_INFO("rt5639", 0x1c), | ||
309 | .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ), | ||
310 | }; | ||
311 | |||
312 | static void kai_i2c_init(void) | ||
313 | { | ||
314 | struct board_info board_info; | ||
315 | |||
316 | tegra_get_board_info(&board_info); | ||
317 | |||
318 | tegra_i2c_device1.dev.platform_data = &kai_i2c1_platform_data; | ||
319 | tegra_i2c_device2.dev.platform_data = &kai_i2c2_platform_data; | ||
320 | tegra_i2c_device3.dev.platform_data = &kai_i2c3_platform_data; | ||
321 | tegra_i2c_device4.dev.platform_data = &kai_i2c4_platform_data; | ||
322 | tegra_i2c_device5.dev.platform_data = &kai_i2c5_platform_data; | ||
323 | |||
324 | platform_device_register(&tegra_i2c_device5); | ||
325 | platform_device_register(&tegra_i2c_device4); | ||
326 | platform_device_register(&tegra_i2c_device3); | ||
327 | platform_device_register(&tegra_i2c_device2); | ||
328 | platform_device_register(&tegra_i2c_device1); | ||
329 | |||
330 | i2c_register_board_info(4, kai_i2c4_smb349_board_info, | ||
331 | ARRAY_SIZE(kai_i2c4_smb349_board_info)); | ||
332 | |||
333 | if (board_info.fab == BOARD_FAB_A00) | ||
334 | i2c_register_board_info(4, &rt5640_board_info, 1); | ||
335 | else | ||
336 | i2c_register_board_info(4, &rt5639_board_info, 1); | ||
337 | |||
338 | i2c_register_board_info(4, &kai_eeprom_mac_add, 1); | ||
339 | |||
340 | i2c_register_board_info(4, kai_i2c4_max17048_board_info, | ||
341 | ARRAY_SIZE(kai_i2c4_max17048_board_info)); | ||
342 | |||
343 | i2c_register_board_info(0, kai_nfc_board_info, 1); | ||
344 | } | ||
345 | |||
346 | static struct platform_device *kai_uart_devices[] __initdata = { | ||
347 | &tegra_uarta_device, | ||
348 | &tegra_uartb_device, | ||
349 | &tegra_uartc_device, | ||
350 | &tegra_uartd_device, | ||
351 | &tegra_uarte_device, | ||
352 | }; | ||
353 | static struct uart_clk_parent uart_parent_clk[] = { | ||
354 | [0] = {.name = "clk_m"}, | ||
355 | [1] = {.name = "pll_p"}, | ||
356 | #ifndef CONFIG_TEGRA_PLLM_RESTRICTED | ||
357 | [2] = {.name = "pll_m"}, | ||
358 | #endif | ||
359 | }; | ||
360 | |||
361 | static struct tegra_uart_platform_data kai_uart_pdata; | ||
362 | static struct tegra_uart_platform_data kai_loopback_uart_pdata; | ||
363 | |||
364 | static void __init uart_debug_init(void) | ||
365 | { | ||
366 | int debug_port_id; | ||
367 | |||
368 | debug_port_id = get_tegra_uart_debug_port_id(); | ||
369 | if (debug_port_id < 0) | ||
370 | debug_port_id = 3; | ||
371 | |||
372 | switch (debug_port_id) { | ||
373 | case 0: | ||
374 | /* UARTA is the debug port. */ | ||
375 | pr_info("Selecting UARTA as the debug console\n"); | ||
376 | kai_uart_devices[0] = &debug_uarta_device; | ||
377 | debug_uart_clk = clk_get_sys("serial8250.0", "uarta"); | ||
378 | debug_uart_port_base = ((struct plat_serial8250_port *)( | ||
379 | debug_uarta_device.dev.platform_data))->mapbase; | ||
380 | break; | ||
381 | |||
382 | case 1: | ||
383 | /* UARTB is the debug port. */ | ||
384 | pr_info("Selecting UARTB as the debug console\n"); | ||
385 | kai_uart_devices[1] = &debug_uartb_device; | ||
386 | debug_uart_clk = clk_get_sys("serial8250.0", "uartb"); | ||
387 | debug_uart_port_base = ((struct plat_serial8250_port *)( | ||
388 | debug_uartb_device.dev.platform_data))->mapbase; | ||
389 | break; | ||
390 | |||
391 | case 2: | ||
392 | /* UARTC is the debug port. */ | ||
393 | pr_info("Selecting UARTC as the debug console\n"); | ||
394 | kai_uart_devices[2] = &debug_uartc_device; | ||
395 | debug_uart_clk = clk_get_sys("serial8250.0", "uartc"); | ||
396 | debug_uart_port_base = ((struct plat_serial8250_port *)( | ||
397 | debug_uartc_device.dev.platform_data))->mapbase; | ||
398 | break; | ||
399 | |||
400 | case 3: | ||
401 | /* UARTD is the debug port. */ | ||
402 | pr_info("Selecting UARTD as the debug console\n"); | ||
403 | kai_uart_devices[3] = &debug_uartd_device; | ||
404 | debug_uart_clk = clk_get_sys("serial8250.0", "uartd"); | ||
405 | debug_uart_port_base = ((struct plat_serial8250_port *)( | ||
406 | debug_uartd_device.dev.platform_data))->mapbase; | ||
407 | break; | ||
408 | |||
409 | case 4: | ||
410 | /* UARTE is the debug port. */ | ||
411 | pr_info("Selecting UARTE as the debug console\n"); | ||
412 | kai_uart_devices[4] = &debug_uarte_device; | ||
413 | debug_uart_clk = clk_get_sys("serial8250.0", "uarte"); | ||
414 | debug_uart_port_base = ((struct plat_serial8250_port *)( | ||
415 | debug_uarte_device.dev.platform_data))->mapbase; | ||
416 | break; | ||
417 | |||
418 | default: | ||
419 | pr_info("The debug console id %d is invalid, Assuming UARTA", | ||
420 | debug_port_id); | ||
421 | kai_uart_devices[0] = &debug_uarta_device; | ||
422 | debug_uart_clk = clk_get_sys("serial8250.0", "uarta"); | ||
423 | debug_uart_port_base = ((struct plat_serial8250_port *)( | ||
424 | debug_uarta_device.dev.platform_data))->mapbase; | ||
425 | break; | ||
426 | } | ||
427 | } | ||
428 | |||
429 | static void __init kai_uart_init(void) | ||
430 | { | ||
431 | struct clk *c; | ||
432 | int i; | ||
433 | |||
434 | for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) { | ||
435 | c = tegra_get_clock_by_name(uart_parent_clk[i].name); | ||
436 | if (IS_ERR_OR_NULL(c)) { | ||
437 | pr_err("Not able to get the clock for %s\n", | ||
438 | uart_parent_clk[i].name); | ||
439 | continue; | ||
440 | } | ||
441 | uart_parent_clk[i].parent_clk = c; | ||
442 | uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c); | ||
443 | } | ||
444 | kai_uart_pdata.parent_clk_list = uart_parent_clk; | ||
445 | kai_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk); | ||
446 | kai_loopback_uart_pdata.parent_clk_list = uart_parent_clk; | ||
447 | kai_loopback_uart_pdata.parent_clk_count = | ||
448 | ARRAY_SIZE(uart_parent_clk); | ||
449 | kai_loopback_uart_pdata.is_loopback = true; | ||
450 | tegra_uarta_device.dev.platform_data = &kai_uart_pdata; | ||
451 | tegra_uartb_device.dev.platform_data = &kai_uart_pdata; | ||
452 | tegra_uartc_device.dev.platform_data = &kai_uart_pdata; | ||
453 | tegra_uartd_device.dev.platform_data = &kai_uart_pdata; | ||
454 | /* UARTE is used for loopback test purpose */ | ||
455 | tegra_uarte_device.dev.platform_data = &kai_loopback_uart_pdata; | ||
456 | |||
457 | /* Register low speed only if it is selected */ | ||
458 | if (!is_tegra_debug_uartport_hs()) { | ||
459 | uart_debug_init(); | ||
460 | /* Clock enable for the debug channel */ | ||
461 | if (!IS_ERR_OR_NULL(debug_uart_clk)) { | ||
462 | pr_info("The debug console clock name is %s\n", | ||
463 | debug_uart_clk->name); | ||
464 | c = tegra_get_clock_by_name("pll_p"); | ||
465 | if (IS_ERR_OR_NULL(c)) | ||
466 | pr_err("Not getting the parent clock pll_p\n"); | ||
467 | else | ||
468 | clk_set_parent(debug_uart_clk, c); | ||
469 | |||
470 | clk_enable(debug_uart_clk); | ||
471 | clk_set_rate(debug_uart_clk, clk_get_rate(c)); | ||
472 | } else { | ||
473 | pr_err("Not getting the clock %s for debug console\n", | ||
474 | debug_uart_clk->name); | ||
475 | } | ||
476 | } | ||
477 | |||
478 | platform_add_devices(kai_uart_devices, | ||
479 | ARRAY_SIZE(kai_uart_devices)); | ||
480 | } | ||
481 | |||
482 | static struct platform_device tegra_camera = { | ||
483 | .name = "tegra_camera", | ||
484 | .id = -1, | ||
485 | }; | ||
486 | |||
487 | static struct platform_device *kai_spi_devices[] __initdata = { | ||
488 | &tegra_spi_device4, | ||
489 | &tegra_spi_device1, | ||
490 | }; | ||
491 | |||
492 | static struct spi_clk_parent spi_parent_clk[] = { | ||
493 | [0] = {.name = "pll_p"}, | ||
494 | #ifndef CONFIG_TEGRA_PLLM_RESTRICTED | ||
495 | [1] = {.name = "pll_m"}, | ||
496 | [2] = {.name = "clk_m"}, | ||
497 | #else | ||
498 | [1] = {.name = "clk_m"}, | ||
499 | #endif | ||
500 | }; | ||
501 | |||
502 | static struct tegra_spi_platform_data kai_spi_pdata = { | ||
503 | .is_dma_based = true, | ||
504 | .max_dma_buffer = (16 * 1024), | ||
505 | .is_clkon_always = false, | ||
506 | .max_rate = 100000000, | ||
507 | }; | ||
508 | |||
509 | static void __init kai_spi_init(void) | ||
510 | { | ||
511 | int i; | ||
512 | struct clk *c; | ||
513 | |||
514 | for (i = 0; i < ARRAY_SIZE(spi_parent_clk); ++i) { | ||
515 | c = tegra_get_clock_by_name(spi_parent_clk[i].name); | ||
516 | if (IS_ERR_OR_NULL(c)) { | ||
517 | pr_err("Not able to get the clock for %s\n", | ||
518 | spi_parent_clk[i].name); | ||
519 | continue; | ||
520 | } | ||
521 | spi_parent_clk[i].parent_clk = c; | ||
522 | spi_parent_clk[i].fixed_clk_rate = clk_get_rate(c); | ||
523 | } | ||
524 | kai_spi_pdata.parent_clk_list = spi_parent_clk; | ||
525 | kai_spi_pdata.parent_clk_count = ARRAY_SIZE(spi_parent_clk); | ||
526 | tegra_spi_device4.dev.platform_data = &kai_spi_pdata; | ||
527 | platform_add_devices(kai_spi_devices, | ||
528 | ARRAY_SIZE(kai_spi_devices)); | ||
529 | |||
530 | } | ||
531 | |||
532 | static struct resource tegra_rtc_resources[] = { | ||
533 | [0] = { | ||
534 | .start = TEGRA_RTC_BASE, | ||
535 | .end = TEGRA_RTC_BASE + TEGRA_RTC_SIZE - 1, | ||
536 | .flags = IORESOURCE_MEM, | ||
537 | }, | ||
538 | [1] = { | ||
539 | .start = INT_RTC, | ||
540 | .end = INT_RTC, | ||
541 | .flags = IORESOURCE_IRQ, | ||
542 | }, | ||
543 | }; | ||
544 | |||
545 | static struct platform_device tegra_rtc_device = { | ||
546 | .name = "tegra_rtc", | ||
547 | .id = -1, | ||
548 | .resource = tegra_rtc_resources, | ||
549 | .num_resources = ARRAY_SIZE(tegra_rtc_resources), | ||
550 | }; | ||
551 | |||
552 | static struct tegra_rt5640_platform_data kai_audio_pdata = { | ||
553 | .gpio_spkr_en = TEGRA_GPIO_SPKR_EN, | ||
554 | .gpio_hp_det = TEGRA_GPIO_HP_DET, | ||
555 | .gpio_hp_mute = -1, | ||
556 | .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN, | ||
557 | .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN, | ||
558 | }; | ||
559 | |||
560 | static struct platform_device kai_audio_device = { | ||
561 | .name = "tegra-snd-rt5640", | ||
562 | .id = 0, | ||
563 | .dev = { | ||
564 | .platform_data = &kai_audio_pdata, | ||
565 | }, | ||
566 | }; | ||
567 | |||
568 | static struct gpio_led kai_led_info[] = { | ||
569 | { | ||
570 | .name = "statled", | ||
571 | .default_trigger = "default-on", | ||
572 | .gpio = TEGRA_GPIO_STAT_LED, | ||
573 | .active_low = 1, | ||
574 | .retain_state_suspended = 0, | ||
575 | .default_state = LEDS_GPIO_DEFSTATE_OFF, | ||
576 | }, | ||
577 | }; | ||
578 | |||
579 | static struct gpio_led_platform_data kai_leds_pdata = { | ||
580 | .leds = kai_led_info, | ||
581 | .num_leds = ARRAY_SIZE(kai_led_info), | ||
582 | }; | ||
583 | |||
584 | static struct platform_device kai_leds_gpio_device = { | ||
585 | .name = "leds-gpio", | ||
586 | .id = -1, | ||
587 | .dev = { | ||
588 | .platform_data = &kai_leds_pdata, | ||
589 | }, | ||
590 | }; | ||
591 | |||
592 | static struct platform_device *kai_devices[] __initdata = { | ||
593 | &tegra_pmu_device, | ||
594 | &tegra_rtc_device, | ||
595 | &tegra_udc_device, | ||
596 | #if defined(CONFIG_TEGRA_IOVMM_SMMU) || defined(CONFIG_TEGRA_IOMMU_SMMU) | ||
597 | &tegra_smmu_device, | ||
598 | #endif | ||
599 | &tegra_wdt_device, | ||
600 | #if defined(CONFIG_TEGRA_AVP) | ||
601 | &tegra_avp_device, | ||
602 | #endif | ||
603 | &tegra_camera, | ||
604 | #if defined(CONFIG_CRYPTO_DEV_TEGRA_SE) | ||
605 | &tegra_se_device, | ||
606 | #endif | ||
607 | &tegra_ahub_device, | ||
608 | &tegra_dam_device0, | ||
609 | &tegra_dam_device1, | ||
610 | &tegra_dam_device2, | ||
611 | &tegra_i2s_device1, | ||
612 | &tegra_i2s_device3, | ||
613 | &tegra_i2s_device4, | ||
614 | &tegra_spdif_device, | ||
615 | &spdif_dit_device, | ||
616 | &bluetooth_dit_device, | ||
617 | &tegra_pcm_device, | ||
618 | &kai_audio_device, | ||
619 | &kai_leds_gpio_device, | ||
620 | &tegra_hda_device, | ||
621 | #if defined(CONFIG_CRYPTO_DEV_TEGRA_AES) | ||
622 | &tegra_aes_device, | ||
623 | #endif | ||
624 | }; | ||
625 | |||
626 | static __initdata struct tegra_clk_init_table spi_clk_init_table[] = { | ||
627 | /* name parent rate enabled */ | ||
628 | { "sbc1", "pll_p", 52000000, true}, | ||
629 | { NULL, NULL, 0, 0}, | ||
630 | }; | ||
631 | |||
632 | static __initdata struct tegra_clk_init_table touch_clk_init_table[] = { | ||
633 | /* name parent rate enabled */ | ||
634 | { "extern3", "pll_p", 41000000, true}, | ||
635 | { "clk_out_3", "extern3", 40800000, true}, | ||
636 | { NULL, NULL, 0, 0}, | ||
637 | }; | ||
638 | |||
639 | static int __init kai_touch_init(void) | ||
640 | { | ||
641 | int touch_id; | ||
642 | |||
643 | tegra_gpio_enable(KAI_TS_ID1); | ||
644 | tegra_gpio_enable(KAI_TS_ID2); | ||
645 | |||
646 | gpio_request(KAI_TS_ID1, "touch-id1"); | ||
647 | gpio_direction_input(KAI_TS_ID1); | ||
648 | |||
649 | gpio_request(KAI_TS_ID2, "touch-id2"); | ||
650 | gpio_direction_input(KAI_TS_ID2); | ||
651 | |||
652 | touch_id = gpio_get_value(KAI_TS_ID1) << 1; | ||
653 | touch_id |= gpio_get_value(KAI_TS_ID2); | ||
654 | |||
655 | pr_info("touch-id %d\n", touch_id); | ||
656 | |||
657 | /* Disable TS_ID GPIO to save power */ | ||
658 | gpio_direction_output(KAI_TS_ID1, 0); | ||
659 | tegra_pinmux_set_pullupdown(KAI_TS_ID1_PG, TEGRA_PUPD_NORMAL); | ||
660 | tegra_pinmux_set_tristate(KAI_TS_ID1_PG, TEGRA_TRI_TRISTATE); | ||
661 | gpio_direction_output(KAI_TS_ID2, 0); | ||
662 | tegra_pinmux_set_pullupdown(KAI_TS_ID2_PG, TEGRA_PUPD_NORMAL); | ||
663 | tegra_pinmux_set_tristate(KAI_TS_ID2_PG, TEGRA_TRI_TRISTATE); | ||
664 | |||
665 | switch (touch_id) { | ||
666 | case 0: | ||
667 | pr_info("Raydium PCB based touch init\n"); | ||
668 | tegra_clk_init_from_table(spi_clk_init_table); | ||
669 | touch_init_raydium(TEGRA_GPIO_PZ3, TEGRA_GPIO_PN5, 0); | ||
670 | break; | ||
671 | case 1: | ||
672 | pr_info("Raydium On-Board touch init\n"); | ||
673 | tegra_clk_init_from_table(spi_clk_init_table); | ||
674 | tegra_clk_init_from_table(touch_clk_init_table); | ||
675 | clk_enable(tegra_get_clock_by_name("clk_out_3")); | ||
676 | |||
677 | touch_init_raydium(TEGRA_GPIO_PZ3, TEGRA_GPIO_PN5, 1); | ||
678 | break; | ||
679 | case 3: | ||
680 | pr_info("Synaptics PCB based touch init\n"); | ||
681 | touch_init_synaptics_kai(); | ||
682 | break; | ||
683 | default: | ||
684 | pr_err("touch_id error, no touch %d\n", touch_id); | ||
685 | } | ||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { | ||
690 | [0] = { | ||
691 | .phy_config = &utmi_phy_config[0], | ||
692 | .operating_mode = TEGRA_USB_HOST, | ||
693 | .power_down_on_bus_suspend = 1, | ||
694 | .default_enable = true, | ||
695 | }, | ||
696 | [1] = { | ||
697 | .phy_config = &utmi_phy_config[1], | ||
698 | .operating_mode = TEGRA_USB_HOST, | ||
699 | .power_down_on_bus_suspend = 1, | ||
700 | .default_enable = false, | ||
701 | }, | ||
702 | }; | ||
703 | |||
704 | static struct tegra_otg_platform_data tegra_otg_pdata = { | ||
705 | .ehci_device = &tegra_ehci1_device, | ||
706 | .ehci_pdata = &tegra_ehci_pdata[0], | ||
707 | }; | ||
708 | |||
709 | #ifdef CONFIG_USB_SUPPORT | ||
710 | static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { | ||
711 | [0] = { | ||
712 | .instance = 0, | ||
713 | .vbus_gpio = -1, | ||
714 | .vbus_irq = MAX77663_IRQ_BASE + | ||
715 | MAX77663_IRQ_ACOK_RISING, | ||
716 | }, | ||
717 | [1] = { | ||
718 | .instance = 1, | ||
719 | .vbus_gpio = -1, | ||
720 | }, | ||
721 | }; | ||
722 | |||
723 | static void kai_usb_init(void) | ||
724 | { | ||
725 | tegra_usb_phy_init(tegra_usb_phy_pdata, | ||
726 | ARRAY_SIZE(tegra_usb_phy_pdata)); | ||
727 | |||
728 | tegra_otg_device.dev.platform_data = &tegra_otg_pdata; | ||
729 | platform_device_register(&tegra_otg_device); | ||
730 | |||
731 | tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1]; | ||
732 | platform_device_register(&tegra_ehci2_device); | ||
733 | } | ||
734 | |||
735 | static void kai_modem_init(void) | ||
736 | { | ||
737 | int ret; | ||
738 | |||
739 | tegra_gpio_enable(TEGRA_GPIO_W_DISABLE); | ||
740 | tegra_gpio_enable(TEGRA_GPIO_MODEM_RSVD1); | ||
741 | tegra_gpio_enable(TEGRA_GPIO_MODEM_RSVD2); | ||
742 | |||
743 | ret = gpio_request(TEGRA_GPIO_W_DISABLE, "w_disable_gpio"); | ||
744 | if (ret < 0) | ||
745 | pr_err("%s: gpio_request failed for gpio %d\n", | ||
746 | __func__, TEGRA_GPIO_W_DISABLE); | ||
747 | else | ||
748 | gpio_direction_output(TEGRA_GPIO_W_DISABLE, 1); | ||
749 | |||
750 | |||
751 | ret = gpio_request(TEGRA_GPIO_MODEM_RSVD1, "Port_V_PIN_0"); | ||
752 | if (ret < 0) | ||
753 | pr_err("%s: gpio_request failed for gpio %d\n", | ||
754 | __func__, TEGRA_GPIO_MODEM_RSVD1); | ||
755 | else | ||
756 | gpio_direction_input(TEGRA_GPIO_MODEM_RSVD1); | ||
757 | |||
758 | |||
759 | ret = gpio_request(TEGRA_GPIO_MODEM_RSVD2, "Port_H_PIN_7"); | ||
760 | if (ret < 0) | ||
761 | pr_err("%s: gpio_request failed for gpio %d\n", | ||
762 | __func__, TEGRA_GPIO_MODEM_RSVD2); | ||
763 | else | ||
764 | gpio_direction_output(TEGRA_GPIO_MODEM_RSVD2, 1); | ||
765 | |||
766 | } | ||
767 | |||
768 | #else | ||
769 | static void kai_usb_init(void) { } | ||
770 | static void kai_modem_init(void) { } | ||
771 | #endif | ||
772 | |||
773 | static void kai_audio_init(void) | ||
774 | { | ||
775 | struct board_info board_info; | ||
776 | |||
777 | tegra_get_board_info(&board_info); | ||
778 | |||
779 | if (board_info.fab == BOARD_FAB_A01) { | ||
780 | kai_audio_pdata.codec_name = "rt5639.4-001c"; | ||
781 | kai_audio_pdata.codec_dai_name = "rt5639-aif1"; | ||
782 | } else if (board_info.fab == BOARD_FAB_A00) { | ||
783 | kai_audio_pdata.codec_name = "rt5640.4-001c"; | ||
784 | kai_audio_pdata.codec_dai_name = "rt5640-aif1"; | ||
785 | } | ||
786 | } | ||
787 | |||
788 | static void kai_nfc_init(void) | ||
789 | { | ||
790 | tegra_gpio_enable(TEGRA_GPIO_PX0); | ||
791 | tegra_gpio_enable(TEGRA_GPIO_PP3); | ||
792 | tegra_gpio_enable(TEGRA_GPIO_PO7); | ||
793 | } | ||
794 | |||
795 | static void __init tegra_kai_init(void) | ||
796 | { | ||
797 | tegra_thermal_init(&thermal_data); | ||
798 | tegra_clk_init_from_table(kai_clk_init_table); | ||
799 | kai_pinmux_init(); | ||
800 | kai_i2c_init(); | ||
801 | kai_spi_init(); | ||
802 | kai_usb_init(); | ||
803 | #ifdef CONFIG_TEGRA_EDP_LIMITS | ||
804 | kai_edp_init(); | ||
805 | #endif | ||
806 | kai_uart_init(); | ||
807 | kai_tsensor_init(); | ||
808 | kai_audio_init(); | ||
809 | platform_add_devices(kai_devices, ARRAY_SIZE(kai_devices)); | ||
810 | tegra_ram_console_debug_init(); | ||
811 | kai_sdhci_init(); | ||
812 | kai_regulator_init(); | ||
813 | kai_suspend_init(); | ||
814 | kai_touch_init(); | ||
815 | kai_keys_init(); | ||
816 | kai_panel_init(); | ||
817 | kai_bt_st(); | ||
818 | kai_tegra_setup_tibluesleep(); | ||
819 | kai_nfc_init(); | ||
820 | kai_sensors_init(); | ||
821 | kai_pins_state_init(); | ||
822 | kai_emc_init(); | ||
823 | tegra_release_bootloader_fb(); | ||
824 | kai_modem_init(); | ||
825 | #ifdef CONFIG_TEGRA_WDT_RECOVERY | ||
826 | tegra_wdt_recovery_init(); | ||
827 | #endif | ||
828 | } | ||
829 | |||
830 | static void __init kai_ramconsole_reserve(unsigned long size) | ||
831 | { | ||
832 | tegra_ram_console_debug_reserve(SZ_1M); | ||
833 | } | ||
834 | |||
835 | static void __init tegra_kai_reserve(void) | ||
836 | { | ||
837 | #if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM) | ||
838 | /* support 1920X1200 with 24bpp */ | ||
839 | tegra_reserve(0, SZ_8M + SZ_1M, SZ_8M + SZ_1M); | ||
840 | #else | ||
841 | tegra_reserve(SZ_128M, SZ_8M, SZ_8M); | ||
842 | #endif | ||
843 | kai_ramconsole_reserve(SZ_1M); | ||
844 | } | ||
845 | |||
846 | MACHINE_START(KAI, "kai") | ||
847 | .boot_params = 0x80000100, | ||
848 | .map_io = tegra_map_common_io, | ||
849 | .reserve = tegra_kai_reserve, | ||
850 | .init_early = tegra_init_early, | ||
851 | .init_irq = tegra_init_irq, | ||
852 | .timer = &tegra_timer, | ||
853 | .init_machine = tegra_kai_init, | ||
854 | MACHINE_END | ||