]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/mips/jz4740/board-qi_lb60.c
Merge remote-tracking branches 'asoc/topic/wm8904', 'asoc/topic/wm8955' and 'asoc...
[mirror_ubuntu-zesty-kernel.git] / arch / mips / jz4740 / board-qi_lb60.c
CommitLineData
e6b78c4f
LPC
1/*
2 * linux/arch/mips/jz4740/board-qi_lb60.c
3 *
4 * QI_LB60 board support
5 *
6 * Copyright (c) 2009 Qi Hardware inc.,
7 * Author: Xiangfu Liu <xiangfu@qi-hardware.com>
fe749aab 8 * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
e6b78c4f
LPC
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 or later
12 * as published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/gpio.h>
0a6d3158 18#include <linux/gpio/machine.h>
e6b78c4f
LPC
19
20#include <linux/input.h>
21#include <linux/gpio_keys.h>
22#include <linux/input/matrix_keypad.h>
23#include <linux/spi/spi.h>
24#include <linux/spi/spi_gpio.h>
25#include <linux/power_supply.h>
26#include <linux/power/jz4740-battery.h>
0b4cf181 27#include <linux/power/gpio-charger.h>
e6b78c4f 28
5b235dc2 29#include <asm/mach-jz4740/gpio.h>
e6b78c4f
LPC
30#include <asm/mach-jz4740/jz4740_fb.h>
31#include <asm/mach-jz4740/jz4740_mmc.h>
32#include <asm/mach-jz4740/jz4740_nand.h>
33
34#include <linux/regulator/fixed.h>
35#include <linux/regulator/machine.h>
36
37#include <linux/leds_pwm.h>
38
39#include <asm/mach-jz4740/platform.h>
40
41#include "clock.h"
42
43static bool is_avt2;
44
45/* GPIOs */
46#define QI_LB60_GPIO_SD_CD JZ_GPIO_PORTD(0)
47#define QI_LB60_GPIO_SD_VCC_EN_N JZ_GPIO_PORTD(2)
48
49#define QI_LB60_GPIO_KEYOUT(x) (JZ_GPIO_PORTC(10) + (x))
50#define QI_LB60_GPIO_KEYIN(x) (JZ_GPIO_PORTD(18) + (x))
51#define QI_LB60_GPIO_KEYIN8 JZ_GPIO_PORTD(26)
52
53/* NAND */
54static struct nand_ecclayout qi_lb60_ecclayout_1gb = {
c8fb4022 55 .eccbytes = 36,
e6b78c4f 56 .eccpos = {
70342287 57 6, 7, 8, 9, 10, 11, 12, 13,
e6b78c4f
LPC
58 14, 15, 16, 17, 18, 19, 20, 21,
59 22, 23, 24, 25, 26, 27, 28, 29,
60 30, 31, 32, 33, 34, 35, 36, 37,
61 38, 39, 40, 41
c8fb4022 62 },
e6b78c4f
LPC
63 .oobfree = {
64 { .offset = 2, .length = 4 },
65 { .offset = 42, .length = 22 }
66 },
67};
68
69/* Early prototypes of the QI LB60 had only 1GB of NAND.
25985edc 70 * In order to support these devices as well the partition and ecc layout is
b595076a 71 * initialized depending on the NAND size */
e6b78c4f
LPC
72static struct mtd_partition qi_lb60_partitions_1gb[] = {
73 {
74 .name = "NAND BOOT partition",
75 .offset = 0 * 0x100000,
76 .size = 4 * 0x100000,
77 },
78 {
79 .name = "NAND KERNEL partition",
80 .offset = 4 * 0x100000,
81 .size = 4 * 0x100000,
82 },
83 {
84 .name = "NAND ROOTFS partition",
85 .offset = 8 * 0x100000,
86 .size = (504 + 512) * 0x100000,
87 },
88};
89
90static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
c8fb4022 91 .eccbytes = 72,
e6b78c4f
LPC
92 .eccpos = {
93 12, 13, 14, 15, 16, 17, 18, 19,
94 20, 21, 22, 23, 24, 25, 26, 27,
95 28, 29, 30, 31, 32, 33, 34, 35,
96 36, 37, 38, 39, 40, 41, 42, 43,
97 44, 45, 46, 47, 48, 49, 50, 51,
98 52, 53, 54, 55, 56, 57, 58, 59,
99 60, 61, 62, 63, 64, 65, 66, 67,
100 68, 69, 70, 71, 72, 73, 74, 75,
101 76, 77, 78, 79, 80, 81, 82, 83
c8fb4022 102 },
e6b78c4f
LPC
103 .oobfree = {
104 { .offset = 2, .length = 10 },
105 { .offset = 84, .length = 44 },
106 },
107};
108
109static struct mtd_partition qi_lb60_partitions_2gb[] = {
110 {
111 .name = "NAND BOOT partition",
112 .offset = 0 * 0x100000,
113 .size = 4 * 0x100000,
114 },
115 {
116 .name = "NAND KERNEL partition",
117 .offset = 4 * 0x100000,
118 .size = 4 * 0x100000,
119 },
120 {
121 .name = "NAND ROOTFS partition",
122 .offset = 8 * 0x100000,
123 .size = (504 + 512 + 1024) * 0x100000,
124 },
125};
126
127static void qi_lb60_nand_ident(struct platform_device *pdev,
128 struct nand_chip *chip, struct mtd_partition **partitions,
129 int *num_partitions)
130{
131 if (chip->page_shift == 12) {
132 chip->ecc.layout = &qi_lb60_ecclayout_2gb;
133 *partitions = qi_lb60_partitions_2gb;
134 *num_partitions = ARRAY_SIZE(qi_lb60_partitions_2gb);
135 } else {
136 chip->ecc.layout = &qi_lb60_ecclayout_1gb;
137 *partitions = qi_lb60_partitions_1gb;
138 *num_partitions = ARRAY_SIZE(qi_lb60_partitions_1gb);
139 }
140}
141
142static struct jz_nand_platform_data qi_lb60_nand_pdata = {
143 .ident_callback = qi_lb60_nand_ident,
56635d79 144 .banks = { 1 },
e6b78c4f
LPC
145};
146
cd145af9
LPC
147static struct gpiod_lookup_table qi_lb60_nand_gpio_table = {
148 .dev_id = "jz4740-nand.0",
149 .table = {
150 GPIO_LOOKUP("Bank C", 30, "busy", 0),
151 { },
152 },
153};
154
155
e6b78c4f
LPC
156/* Keyboard*/
157
158#define KEY_QI_QI KEY_F13
159#define KEY_QI_UPRED KEY_RIGHTALT
160#define KEY_QI_VOLUP KEY_VOLUMEUP
161#define KEY_QI_VOLDOWN KEY_VOLUMEDOWN
162#define KEY_QI_FN KEY_LEFTCTRL
163
164static const uint32_t qi_lb60_keymap[] = {
165 KEY(0, 0, KEY_F1), /* S2 */
166 KEY(0, 1, KEY_F2), /* S3 */
167 KEY(0, 2, KEY_F3), /* S4 */
168 KEY(0, 3, KEY_F4), /* S5 */
169 KEY(0, 4, KEY_F5), /* S6 */
170 KEY(0, 5, KEY_F6), /* S7 */
171 KEY(0, 6, KEY_F7), /* S8 */
172
173 KEY(1, 0, KEY_Q), /* S10 */
174 KEY(1, 1, KEY_W), /* S11 */
175 KEY(1, 2, KEY_E), /* S12 */
176 KEY(1, 3, KEY_R), /* S13 */
177 KEY(1, 4, KEY_T), /* S14 */
178 KEY(1, 5, KEY_Y), /* S15 */
179 KEY(1, 6, KEY_U), /* S16 */
180 KEY(1, 7, KEY_I), /* S17 */
181 KEY(2, 0, KEY_A), /* S18 */
182 KEY(2, 1, KEY_S), /* S19 */
183 KEY(2, 2, KEY_D), /* S20 */
184 KEY(2, 3, KEY_F), /* S21 */
185 KEY(2, 4, KEY_G), /* S22 */
186 KEY(2, 5, KEY_H), /* S23 */
187 KEY(2, 6, KEY_J), /* S24 */
188 KEY(2, 7, KEY_K), /* S25 */
189 KEY(3, 0, KEY_ESC), /* S26 */
190 KEY(3, 1, KEY_Z), /* S27 */
191 KEY(3, 2, KEY_X), /* S28 */
192 KEY(3, 3, KEY_C), /* S29 */
193 KEY(3, 4, KEY_V), /* S30 */
194 KEY(3, 5, KEY_B), /* S31 */
195 KEY(3, 6, KEY_N), /* S32 */
196 KEY(3, 7, KEY_M), /* S33 */
197 KEY(4, 0, KEY_TAB), /* S34 */
198 KEY(4, 1, KEY_CAPSLOCK), /* S35 */
199 KEY(4, 2, KEY_BACKSLASH), /* S36 */
200 KEY(4, 3, KEY_APOSTROPHE), /* S37 */
201 KEY(4, 4, KEY_COMMA), /* S38 */
202 KEY(4, 5, KEY_DOT), /* S39 */
203 KEY(4, 6, KEY_SLASH), /* S40 */
204 KEY(4, 7, KEY_UP), /* S41 */
205 KEY(5, 0, KEY_O), /* S42 */
206 KEY(5, 1, KEY_L), /* S43 */
207 KEY(5, 2, KEY_EQUAL), /* S44 */
208 KEY(5, 3, KEY_QI_UPRED), /* S45 */
209 KEY(5, 4, KEY_SPACE), /* S46 */
210 KEY(5, 5, KEY_QI_QI), /* S47 */
211 KEY(5, 6, KEY_RIGHTCTRL), /* S48 */
212 KEY(5, 7, KEY_LEFT), /* S49 */
213 KEY(6, 0, KEY_F8), /* S50 */
214 KEY(6, 1, KEY_P), /* S51 */
215 KEY(6, 2, KEY_BACKSPACE),/* S52 */
216 KEY(6, 3, KEY_ENTER), /* S53 */
217 KEY(6, 4, KEY_QI_VOLUP), /* S54 */
218 KEY(6, 5, KEY_QI_VOLDOWN), /* S55 */
219 KEY(6, 6, KEY_DOWN), /* S56 */
220 KEY(6, 7, KEY_RIGHT), /* S57 */
221
222 KEY(7, 0, KEY_LEFTSHIFT), /* S58 */
70342287 223 KEY(7, 1, KEY_LEFTALT), /* S59 */
e6b78c4f
LPC
224 KEY(7, 2, KEY_QI_FN), /* S60 */
225};
226
227static const struct matrix_keymap_data qi_lb60_keymap_data = {
228 .keymap = qi_lb60_keymap,
229 .keymap_size = ARRAY_SIZE(qi_lb60_keymap),
230};
231
232static const unsigned int qi_lb60_keypad_cols[] = {
233 QI_LB60_GPIO_KEYOUT(0),
234 QI_LB60_GPIO_KEYOUT(1),
235 QI_LB60_GPIO_KEYOUT(2),
236 QI_LB60_GPIO_KEYOUT(3),
237 QI_LB60_GPIO_KEYOUT(4),
238 QI_LB60_GPIO_KEYOUT(5),
239 QI_LB60_GPIO_KEYOUT(6),
240 QI_LB60_GPIO_KEYOUT(7),
241};
242
243static const unsigned int qi_lb60_keypad_rows[] = {
244 QI_LB60_GPIO_KEYIN(0),
245 QI_LB60_GPIO_KEYIN(1),
246 QI_LB60_GPIO_KEYIN(2),
247 QI_LB60_GPIO_KEYIN(3),
248 QI_LB60_GPIO_KEYIN(4),
249 QI_LB60_GPIO_KEYIN(5),
fe749aab 250 QI_LB60_GPIO_KEYIN(6),
e6b78c4f
LPC
251 QI_LB60_GPIO_KEYIN8,
252};
253
254static struct matrix_keypad_platform_data qi_lb60_pdata = {
255 .keymap_data = &qi_lb60_keymap_data,
256 .col_gpios = qi_lb60_keypad_cols,
257 .row_gpios = qi_lb60_keypad_rows,
258 .num_col_gpios = ARRAY_SIZE(qi_lb60_keypad_cols),
259 .num_row_gpios = ARRAY_SIZE(qi_lb60_keypad_rows),
260 .col_scan_delay_us = 10,
261 .debounce_ms = 10,
262 .wakeup = 1,
263 .active_low = 1,
264};
265
266static struct platform_device qi_lb60_keypad = {
267 .name = "matrix-keypad",
268 .id = -1,
269 .dev = {
270 .platform_data = &qi_lb60_pdata,
271 },
272};
273
274/* Display */
275static struct fb_videomode qi_lb60_video_modes[] = {
276 {
277 .name = "320x240",
278 .xres = 320,
279 .yres = 240,
280 .refresh = 30,
281 .left_margin = 140,
282 .right_margin = 273,
283 .upper_margin = 20,
284 .lower_margin = 2,
285 .hsync_len = 1,
286 .vsync_len = 1,
287 .sync = 0,
288 .vmode = FB_VMODE_NONINTERLACED,
289 },
290};
291
292static struct jz4740_fb_platform_data qi_lb60_fb_pdata = {
293 .width = 60,
294 .height = 45,
295 .num_modes = ARRAY_SIZE(qi_lb60_video_modes),
296 .modes = qi_lb60_video_modes,
297 .bpp = 24,
298 .lcd_type = JZ_LCD_TYPE_8BIT_SERIAL,
299 .pixclk_falling_edge = 1,
300};
301
302struct spi_gpio_platform_data spigpio_platform_data = {
303 .sck = JZ_GPIO_PORTC(23),
304 .mosi = JZ_GPIO_PORTC(22),
305 .miso = -1,
306 .num_chipselect = 1,
307};
308
309static struct platform_device spigpio_device = {
310 .name = "spi_gpio",
311 .id = 1,
312 .dev = {
313 .platform_data = &spigpio_platform_data,
314 },
315};
316
317static struct spi_board_info qi_lb60_spi_board_info[] = {
318 {
319 .modalias = "ili8960",
320 .controller_data = (void *)JZ_GPIO_PORTC(21),
321 .chip_select = 0,
322 .bus_num = 1,
323 .max_speed_hz = 30 * 1000,
324 .mode = SPI_3WIRE,
325 },
326};
327
328/* Battery */
329static struct jz_battery_platform_data qi_lb60_battery_pdata = {
70342287 330 .gpio_charge = JZ_GPIO_PORTC(27),
e6b78c4f
LPC
331 .gpio_charge_active_low = 1,
332 .info = {
333 .name = "battery",
334 .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
335 .voltage_max_design = 4200000,
336 .voltage_min_design = 3600000,
337 },
338};
339
340/* GPIO Key: power */
341static struct gpio_keys_button qi_lb60_gpio_keys_buttons[] = {
342 [0] = {
343 .code = KEY_POWER,
344 .gpio = JZ_GPIO_PORTD(29),
345 .active_low = 1,
346 .desc = "Power",
347 .wakeup = 1,
348 },
349};
350
351static struct gpio_keys_platform_data qi_lb60_gpio_keys_data = {
352 .nbuttons = ARRAY_SIZE(qi_lb60_gpio_keys_buttons),
353 .buttons = qi_lb60_gpio_keys_buttons,
354};
355
356static struct platform_device qi_lb60_gpio_keys = {
70342287 357 .name = "gpio-keys",
e6b78c4f
LPC
358 .id = -1,
359 .dev = {
360 .platform_data = &qi_lb60_gpio_keys_data,
361 }
362};
363
364static struct jz4740_mmc_platform_data qi_lb60_mmc_pdata = {
365 .gpio_card_detect = QI_LB60_GPIO_SD_CD,
366 .gpio_read_only = -1,
367 .gpio_power = QI_LB60_GPIO_SD_VCC_EN_N,
368 .power_active_low = 1,
369};
370
371/* OHCI */
372static struct regulator_consumer_supply avt2_usb_regulator_consumer =
373 REGULATOR_SUPPLY("vbus", "jz4740-ohci");
374
375static struct regulator_init_data avt2_usb_regulator_init_data = {
376 .num_consumer_supplies = 1,
377 .consumer_supplies = &avt2_usb_regulator_consumer,
378 .constraints = {
379 .name = "USB power",
380 .min_uV = 5000000,
381 .max_uV = 5000000,
382 .valid_modes_mask = REGULATOR_MODE_NORMAL,
383 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
384 },
385};
386
387static struct fixed_voltage_config avt2_usb_regulator_data = {
388 .supply_name = "USB power",
389 .microvolts = 5000000,
390 .gpio = JZ_GPIO_PORTB(17),
391 .init_data = &avt2_usb_regulator_init_data,
392};
393
394static struct platform_device avt2_usb_regulator_device = {
395 .name = "reg-fixed-voltage",
396 .id = -1,
397 .dev = {
398 .platform_data = &avt2_usb_regulator_data,
399 }
400};
401
402/* beeper */
403static struct platform_device qi_lb60_pwm_beeper = {
404 .name = "pwm-beeper",
405 .id = -1,
406 .dev = {
407 .platform_data = (void *)4,
408 },
409};
410
0b4cf181
LPC
411/* charger */
412static char *qi_lb60_batteries[] = {
413 "battery",
414};
415
416static struct gpio_charger_platform_data qi_lb60_charger_pdata = {
417 .name = "usb",
418 .type = POWER_SUPPLY_TYPE_USB,
419 .gpio = JZ_GPIO_PORTD(28),
420 .gpio_active_low = 1,
421 .supplied_to = qi_lb60_batteries,
422 .num_supplicants = ARRAY_SIZE(qi_lb60_batteries),
423};
424
425static struct platform_device qi_lb60_charger_device = {
426 .name = "gpio-charger",
427 .dev = {
428 .platform_data = &qi_lb60_charger_pdata,
429 },
430};
431
b33005f3
AL
432/* audio */
433static struct platform_device qi_lb60_audio_device = {
434 .name = "qi-lb60-audio",
435 .id = -1,
436};
0b4cf181 437
218e18a3
LPC
438static struct gpiod_lookup_table qi_lb60_audio_gpio_table = {
439 .dev_id = "qi-lb60-audio",
440 .table = {
441 GPIO_LOOKUP("Bank B", 29, "snd", 0),
442 GPIO_LOOKUP("Bank D", 4, "amp", 0),
443 { },
444 },
445};
446
e6b78c4f
LPC
447static struct platform_device *jz_platform_devices[] __initdata = {
448 &jz4740_udc_device,
c330fd90 449 &jz4740_udc_xceiv_device,
e6b78c4f
LPC
450 &jz4740_mmc_device,
451 &jz4740_nand_device,
452 &qi_lb60_keypad,
453 &spigpio_device,
454 &jz4740_framebuffer_device,
455 &jz4740_pcm_device,
456 &jz4740_i2s_device,
457 &jz4740_codec_device,
458 &jz4740_rtc_device,
459 &jz4740_adc_device,
f6b8a570 460 &jz4740_pwm_device,
cdcb90ad 461 &jz4740_dma_device,
e6b78c4f
LPC
462 &qi_lb60_gpio_keys,
463 &qi_lb60_pwm_beeper,
0b4cf181 464 &qi_lb60_charger_device,
b33005f3 465 &qi_lb60_audio_device,
e6b78c4f
LPC
466};
467
468static void __init board_gpio_setup(void)
469{
470 /* We only need to enable/disable pullup here for pins used in generic
25985edc 471 * drivers. Everything else is done by the drivers themselves. */
e6b78c4f
LPC
472 jz_gpio_disable_pullup(QI_LB60_GPIO_SD_VCC_EN_N);
473 jz_gpio_disable_pullup(QI_LB60_GPIO_SD_CD);
474}
475
476static int __init qi_lb60_init_platform_devices(void)
477{
478 jz4740_framebuffer_device.dev.platform_data = &qi_lb60_fb_pdata;
479 jz4740_nand_device.dev.platform_data = &qi_lb60_nand_pdata;
480 jz4740_adc_device.dev.platform_data = &qi_lb60_battery_pdata;
481 jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_pdata;
482
218e18a3 483 gpiod_add_lookup_table(&qi_lb60_audio_gpio_table);
cd145af9 484 gpiod_add_lookup_table(&qi_lb60_nand_gpio_table);
218e18a3 485
e6b78c4f
LPC
486 spi_register_board_info(qi_lb60_spi_board_info,
487 ARRAY_SIZE(qi_lb60_spi_board_info));
488
489 if (is_avt2) {
490 platform_device_register(&avt2_usb_regulator_device);
491 platform_device_register(&jz4740_usb_ohci_device);
492 }
493
494 return platform_add_devices(jz_platform_devices,
495 ARRAY_SIZE(jz_platform_devices));
496
497}
498
e6b78c4f
LPC
499static __init int board_avt2(char *str)
500{
501 qi_lb60_mmc_pdata.card_detect_active_low = 1;
502 is_avt2 = true;
503
504 return 1;
505}
506__setup("avt2", board_avt2);
507
508static int __init qi_lb60_board_setup(void)
509{
510 printk(KERN_INFO "Qi Hardware JZ4740 QI %s setup\n",
511 is_avt2 ? "AVT2" : "LB60");
512
513 board_gpio_setup();
514
515 if (qi_lb60_init_platform_devices())
ab75dc02 516 panic("Failed to initialize platform devices");
e6b78c4f
LPC
517
518 return 0;
519}
520arch_initcall(qi_lb60_board_setup);