1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/platform_device.h>
29#include <linux/input.h>
30#include <linux/delay.h>
31#include <linux/gpio.h>
32#include <linux/gpio_keys.h>
33#include <linux/i2c.h>
34#include <linux/i2c-gpio.h>
35#include <linux/htcpld.h>
36#include <linux/leds.h>
37#include <linux/spi/spi.h>
38#include <linux/spi/ads7846.h>
39#include <linux/omapfb.h>
40#include <linux/platform_data/keypad-omap.h>
41
42#include <asm/mach-types.h>
43#include <asm/mach/arch.h>
44
45#include <mach/omap7xx.h>
46#include "mmc.h"
47
48#include <mach/irqs.h>
49#include <mach/usb.h>
50
51#include "common.h"
52
53
54#define OMAP_LCDC_CONTROL (0xfffec000 + 0x00)
55#define OMAP_LCDC_STATUS (0xfffec000 + 0x10)
56#define OMAP_DMA_LCD_CCR (0xfffee300 + 0xc2)
57#define OMAP_DMA_LCD_CTRL (0xfffee300 + 0xc4)
58#define OMAP_LCDC_CTRL_LCD_EN (1 << 0)
59#define OMAP_LCDC_STAT_DONE (1 << 0)
60
61
62#define HTCHERALD_GPIO_POWER 139
63#define HTCHERALD_GPIO_SLIDE 174
64#define HTCHERALD_GIRQ_BTNS 141
65
66
67#define HTCHERALD_GPIO_TS 76
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131#define HTCPLD_GPIO_START_OFFSET (OMAP_MAX_GPIO_LINES + 16)
132#define HTCPLD_IRQ(chip, offset) (OMAP_IRQ_END + 8 * (chip) + (offset))
133#define HTCPLD_BASE(chip, offset) \
134 (HTCPLD_GPIO_START_OFFSET + 8 * (chip) + (offset))
135
136#define HTCPLD_GPIO_LED_DPAD HTCPLD_BASE(0, 0)
137#define HTCPLD_GPIO_LED_KBD HTCPLD_BASE(1, 0)
138#define HTCPLD_GPIO_LED_CAPS HTCPLD_BASE(1, 5)
139#define HTCPLD_GPIO_LED_RED_FLASH HTCPLD_BASE(2, 1)
140#define HTCPLD_GPIO_LED_RED_SOLID HTCPLD_BASE(2, 2)
141#define HTCPLD_GPIO_LED_GREEN_FLASH HTCPLD_BASE(2, 3)
142#define HTCPLD_GPIO_LED_GREEN_SOLID HTCPLD_BASE(2, 4)
143#define HTCPLD_GPIO_LED_WIFI HTCPLD_BASE(2, 5)
144#define HTCPLD_GPIO_LED_BT HTCPLD_BASE(2, 6)
145#define HTCPLD_GPIO_LED_VIBRATE HTCPLD_BASE(3, 3)
146#define HTCPLD_GPIO_LED_ALT HTCPLD_BASE(3, 4)
147
148#define HTCPLD_GPIO_RIGHT_KBD HTCPLD_BASE(6, 7)
149#define HTCPLD_GPIO_UP_KBD HTCPLD_BASE(6, 6)
150#define HTCPLD_GPIO_LEFT_KBD HTCPLD_BASE(6, 5)
151#define HTCPLD_GPIO_DOWN_KBD HTCPLD_BASE(6, 4)
152
153#define HTCPLD_GPIO_RIGHT_DPAD HTCPLD_BASE(7, 7)
154#define HTCPLD_GPIO_UP_DPAD HTCPLD_BASE(7, 6)
155#define HTCPLD_GPIO_LEFT_DPAD HTCPLD_BASE(7, 5)
156#define HTCPLD_GPIO_DOWN_DPAD HTCPLD_BASE(7, 4)
157#define HTCPLD_GPIO_ENTER_DPAD HTCPLD_BASE(7, 3)
158
159
160
161
162
163#define HTCPLD_GPIO_INT_RESET_HI HTCPLD_BASE(2, 7)
164#define HTCPLD_GPIO_INT_RESET_LO HTCPLD_BASE(2, 0)
165
166
167#define HTCPLD_IRQ_RIGHT_KBD HTCPLD_IRQ(0, 7)
168#define HTCPLD_IRQ_UP_KBD HTCPLD_IRQ(0, 6)
169#define HTCPLD_IRQ_LEFT_KBD HTCPLD_IRQ(0, 5)
170#define HTCPLD_IRQ_DOWN_KBD HTCPLD_IRQ(0, 4)
171
172
173#define HTCPLD_IRQ_RIGHT_DPAD HTCPLD_IRQ(1, 7)
174#define HTCPLD_IRQ_UP_DPAD HTCPLD_IRQ(1, 6)
175#define HTCPLD_IRQ_LEFT_DPAD HTCPLD_IRQ(1, 5)
176#define HTCPLD_IRQ_DOWN_DPAD HTCPLD_IRQ(1, 4)
177#define HTCPLD_IRQ_ENTER_DPAD HTCPLD_IRQ(1, 3)
178
179
180
181static const unsigned int htc_herald_keymap[] = {
182 KEY(0, 0, KEY_RECORD),
183 KEY(1, 0, KEY_CAMERA),
184 KEY(2, 0, KEY_PHONE),
185 KEY(3, 0, KEY_VOLUMEUP),
186 KEY(4, 0, KEY_F2),
187 KEY(5, 0, KEY_MAIL),
188 KEY(6, 0, KEY_DIRECTORY),
189 KEY(0, 1, KEY_LEFTCTRL),
190 KEY(1, 1, KEY_COMMA),
191 KEY(2, 1, KEY_M),
192 KEY(3, 1, KEY_K),
193 KEY(4, 1, KEY_SLASH),
194 KEY(5, 1, KEY_I),
195 KEY(6, 1, KEY_U),
196 KEY(0, 2, KEY_LEFTALT),
197 KEY(1, 2, KEY_TAB),
198 KEY(2, 2, KEY_N),
199 KEY(3, 2, KEY_J),
200 KEY(4, 2, KEY_ENTER),
201 KEY(5, 2, KEY_H),
202 KEY(6, 2, KEY_Y),
203 KEY(0, 3, KEY_SPACE),
204 KEY(1, 3, KEY_L),
205 KEY(2, 3, KEY_B),
206 KEY(3, 3, KEY_V),
207 KEY(4, 3, KEY_BACKSPACE),
208 KEY(5, 3, KEY_G),
209 KEY(6, 3, KEY_T),
210 KEY(0, 4, KEY_CAPSLOCK),
211 KEY(1, 4, KEY_C),
212 KEY(2, 4, KEY_F),
213 KEY(3, 4, KEY_R),
214 KEY(4, 4, KEY_O),
215 KEY(5, 4, KEY_E),
216 KEY(6, 4, KEY_D),
217 KEY(0, 5, KEY_X),
218 KEY(1, 5, KEY_Z),
219 KEY(2, 5, KEY_S),
220 KEY(3, 5, KEY_W),
221 KEY(4, 5, KEY_P),
222 KEY(5, 5, KEY_Q),
223 KEY(6, 5, KEY_A),
224 KEY(0, 6, KEY_CONNECT),
225 KEY(2, 6, KEY_CANCEL),
226 KEY(3, 6, KEY_VOLUMEDOWN),
227 KEY(4, 6, KEY_F1),
228 KEY(5, 6, KEY_WWW),
229 KEY(6, 6, KEY_CALENDAR),
230};
231
232static const struct matrix_keymap_data htc_herald_keymap_data = {
233 .keymap = htc_herald_keymap,
234 .keymap_size = ARRAY_SIZE(htc_herald_keymap),
235};
236
237static struct omap_kp_platform_data htcherald_kp_data = {
238 .rows = 7,
239 .cols = 7,
240 .delay = 20,
241 .rep = true,
242 .keymap_data = &htc_herald_keymap_data,
243};
244
245static struct resource kp_resources[] = {
246 [0] = {
247 .start = INT_7XX_MPUIO_KEYPAD,
248 .end = INT_7XX_MPUIO_KEYPAD,
249 .flags = IORESOURCE_IRQ,
250 },
251};
252
253static struct platform_device kp_device = {
254 .name = "omap-keypad",
255 .id = -1,
256 .dev = {
257 .platform_data = &htcherald_kp_data,
258 },
259 .num_resources = ARRAY_SIZE(kp_resources),
260 .resource = kp_resources,
261};
262
263
264static struct gpio_keys_button herald_gpio_keys_table[] = {
265 {BTN_0, HTCHERALD_GPIO_POWER, 1, "POWER", EV_KEY, 1, 20},
266 {SW_LID, HTCHERALD_GPIO_SLIDE, 0, "SLIDE", EV_SW, 1, 20},
267
268 {KEY_LEFT, HTCPLD_GPIO_LEFT_KBD, 1, "LEFT", EV_KEY, 1, 20},
269 {KEY_RIGHT, HTCPLD_GPIO_RIGHT_KBD, 1, "RIGHT", EV_KEY, 1, 20},
270 {KEY_UP, HTCPLD_GPIO_UP_KBD, 1, "UP", EV_KEY, 1, 20},
271 {KEY_DOWN, HTCPLD_GPIO_DOWN_KBD, 1, "DOWN", EV_KEY, 1, 20},
272
273 {KEY_LEFT, HTCPLD_GPIO_LEFT_DPAD, 1, "DLEFT", EV_KEY, 1, 20},
274 {KEY_RIGHT, HTCPLD_GPIO_RIGHT_DPAD, 1, "DRIGHT", EV_KEY, 1, 20},
275 {KEY_UP, HTCPLD_GPIO_UP_DPAD, 1, "DUP", EV_KEY, 1, 20},
276 {KEY_DOWN, HTCPLD_GPIO_DOWN_DPAD, 1, "DDOWN", EV_KEY, 1, 20},
277 {KEY_ENTER, HTCPLD_GPIO_ENTER_DPAD, 1, "DENTER", EV_KEY, 1, 20},
278};
279
280static struct gpio_keys_platform_data herald_gpio_keys_data = {
281 .buttons = herald_gpio_keys_table,
282 .nbuttons = ARRAY_SIZE(herald_gpio_keys_table),
283 .rep = true,
284};
285
286static struct platform_device herald_gpiokeys_device = {
287 .name = "gpio-keys",
288 .id = -1,
289 .dev = {
290 .platform_data = &herald_gpio_keys_data,
291 },
292};
293
294
295static struct gpio_led gpio_leds[] = {
296 {"dpad", NULL, HTCPLD_GPIO_LED_DPAD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
297 {"kbd", NULL, HTCPLD_GPIO_LED_KBD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
298 {"vibrate", NULL, HTCPLD_GPIO_LED_VIBRATE, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
299 {"green_solid", NULL, HTCPLD_GPIO_LED_GREEN_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
300 {"green_flash", NULL, HTCPLD_GPIO_LED_GREEN_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
301 {"red_solid", "mmc0", HTCPLD_GPIO_LED_RED_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
302 {"red_flash", NULL, HTCPLD_GPIO_LED_RED_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
303 {"wifi", NULL, HTCPLD_GPIO_LED_WIFI, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
304 {"bt", NULL, HTCPLD_GPIO_LED_BT, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
305 {"caps", NULL, HTCPLD_GPIO_LED_CAPS, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
306 {"alt", NULL, HTCPLD_GPIO_LED_ALT, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
307};
308
309static struct gpio_led_platform_data gpio_leds_data = {
310 .leds = gpio_leds,
311 .num_leds = ARRAY_SIZE(gpio_leds),
312};
313
314static struct platform_device gpio_leds_device = {
315 .name = "leds-gpio",
316 .id = 0,
317 .dev = {
318 .platform_data = &gpio_leds_data,
319 },
320};
321
322
323
324static struct resource htcpld_resources[] = {
325 [0] = {
326 .flags = IORESOURCE_IRQ,
327 },
328};
329
330static struct htcpld_chip_platform_data htcpld_chips[] = {
331 [0] = {
332 .addr = 0x03,
333 .reset = 0x04,
334 .num_gpios = 8,
335 .gpio_out_base = HTCPLD_BASE(0, 0),
336 .gpio_in_base = HTCPLD_BASE(4, 0),
337 },
338 [1] = {
339 .addr = 0x04,
340 .reset = 0x8e,
341 .num_gpios = 8,
342 .gpio_out_base = HTCPLD_BASE(1, 0),
343 .gpio_in_base = HTCPLD_BASE(5, 0),
344 },
345 [2] = {
346 .addr = 0x05,
347 .reset = 0x80,
348 .num_gpios = 8,
349 .gpio_out_base = HTCPLD_BASE(2, 0),
350 .gpio_in_base = HTCPLD_BASE(6, 0),
351 .irq_base = HTCPLD_IRQ(0, 0),
352 .num_irqs = 8,
353 },
354 [3] = {
355 .addr = 0x06,
356 .reset = 0x40,
357 .num_gpios = 8,
358 .gpio_out_base = HTCPLD_BASE(3, 0),
359 .gpio_in_base = HTCPLD_BASE(7, 0),
360 .irq_base = HTCPLD_IRQ(1, 0),
361 .num_irqs = 8,
362 },
363};
364
365static struct htcpld_core_platform_data htcpld_pfdata = {
366 .int_reset_gpio_hi = HTCPLD_GPIO_INT_RESET_HI,
367 .int_reset_gpio_lo = HTCPLD_GPIO_INT_RESET_LO,
368 .i2c_adapter_id = 1,
369
370 .chip = htcpld_chips,
371 .num_chip = ARRAY_SIZE(htcpld_chips),
372};
373
374static struct platform_device htcpld_device = {
375 .name = "i2c-htcpld",
376 .id = -1,
377 .resource = htcpld_resources,
378 .num_resources = ARRAY_SIZE(htcpld_resources),
379 .dev = {
380 .platform_data = &htcpld_pfdata,
381 },
382};
383
384
385static struct omap_usb_config htcherald_usb_config __initdata = {
386 .otg = 0,
387 .register_host = 0,
388 .register_dev = 1,
389 .hmc_mode = 4,
390 .pins[0] = 2,
391};
392
393
394static struct omap_lcd_config htcherald_lcd_config __initdata = {
395 .ctrl_name = "internal",
396};
397
398static struct platform_device lcd_device = {
399 .name = "lcd_htcherald",
400 .id = -1,
401};
402
403
404#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
405static struct omap_mmc_platform_data htc_mmc1_data = {
406 .nr_slots = 1,
407 .switch_slot = NULL,
408 .slots[0] = {
409 .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
410 .name = "mmcblk",
411 .nomux = 1,
412 .wires = 4,
413 .switch_pin = -1,
414 },
415};
416
417static struct omap_mmc_platform_data *htc_mmc_data[1];
418#endif
419
420
421
422static struct platform_device *devices[] __initdata = {
423 &kp_device,
424 &lcd_device,
425 &htcpld_device,
426 &gpio_leds_device,
427 &herald_gpiokeys_device,
428};
429
430
431
432
433static const struct ads7846_platform_data htcherald_ts_platform_data = {
434 .model = 7846,
435 .keep_vref_on = 1,
436 .x_plate_ohms = 496,
437 .gpio_pendown = HTCHERALD_GPIO_TS,
438 .pressure_max = 10000,
439 .pressure_min = 5000,
440 .x_min = 528,
441 .x_max = 3760,
442 .y_min = 624,
443 .y_max = 3760,
444};
445
446static struct spi_board_info __initdata htcherald_spi_board_info[] = {
447 {
448 .modalias = "ads7846",
449 .platform_data = &htcherald_ts_platform_data,
450 .max_speed_hz = 2500000,
451 .bus_num = 2,
452 .chip_select = 1,
453 }
454};
455
456
457
458
459
460static void __init htcherald_lcd_init(void)
461{
462 u32 reg;
463 unsigned int tries = 200;
464
465
466 reg = omap_readl(OMAP_LCDC_CONTROL);
467 if (reg & OMAP_LCDC_CTRL_LCD_EN) {
468 reg &= ~OMAP_LCDC_CTRL_LCD_EN;
469 omap_writel(reg, OMAP_LCDC_CONTROL);
470
471
472 while (!(omap_readl(OMAP_LCDC_STATUS) & OMAP_LCDC_STAT_DONE)) {
473 tries--;
474 if (!tries)
475 break;
476 }
477 if (!tries)
478 pr_err("Timeout waiting for end of frame -- LCD may not be available\n");
479
480
481 reg = omap_readw(OMAP_DMA_LCD_CCR);
482 reg &= ~(1 << 7);
483 omap_writew(reg, OMAP_DMA_LCD_CCR);
484
485 reg = omap_readw(OMAP_DMA_LCD_CTRL);
486 reg &= ~(1 << 8);
487 omap_writew(reg, OMAP_DMA_LCD_CTRL);
488 }
489}
490
491static void __init htcherald_map_io(void)
492{
493 omap7xx_map_io();
494
495
496
497
498
499 htcherald_lcd_init();
500
501 printk(KERN_INFO "htcherald_map_io done.\n");
502}
503
504static void __init htcherald_disable_watchdog(void)
505{
506
507 if (omap_readl(OMAP_WDT_TIMER_MODE) & 0x8000) {
508
509
510
511
512 printk(KERN_WARNING "OMAP850 Watchdog seems to be activated, disabling it for now.\n");
513 omap_writel(0xF5, OMAP_WDT_TIMER_MODE);
514 omap_writel(0xA0, OMAP_WDT_TIMER_MODE);
515 }
516}
517
518#define HTCHERALD_GPIO_USB_EN1 33
519#define HTCHERALD_GPIO_USB_EN2 73
520#define HTCHERALD_GPIO_USB_DM 35
521#define HTCHERALD_GPIO_USB_DP 36
522
523static void __init htcherald_usb_enable(void)
524{
525 unsigned int tries = 20;
526 unsigned int value = 0;
527
528
529 if (gpio_request(HTCHERALD_GPIO_USB_EN1, "herald_usb") < 0)
530 goto err1;
531
532 if (gpio_request(HTCHERALD_GPIO_USB_EN2, "herald_usb") < 0)
533 goto err2;
534
535 if (gpio_request(HTCHERALD_GPIO_USB_DM, "herald_usb") < 0)
536 goto err3;
537
538 if (gpio_request(HTCHERALD_GPIO_USB_DP, "herald_usb") < 0)
539 goto err4;
540
541
542 do {
543
544 gpio_direction_output(HTCHERALD_GPIO_USB_EN1, 0);
545 } while ((value = gpio_get_value(HTCHERALD_GPIO_USB_EN1)) == 1 &&
546 --tries);
547
548 if (value == 1)
549 printk(KERN_WARNING "Unable to reset USB, trying to continue\n");
550
551 gpio_direction_output(HTCHERALD_GPIO_USB_EN2, 0);
552 gpio_direction_input(HTCHERALD_GPIO_USB_DM);
553 gpio_direction_input(HTCHERALD_GPIO_USB_DP);
554
555 goto done;
556
557err4:
558 gpio_free(HTCHERALD_GPIO_USB_DM);
559err3:
560 gpio_free(HTCHERALD_GPIO_USB_EN2);
561err2:
562 gpio_free(HTCHERALD_GPIO_USB_EN1);
563err1:
564 printk(KERN_ERR "Unabled to request GPIO for USB\n");
565done:
566 printk(KERN_INFO "USB setup complete.\n");
567}
568
569static void __init htcherald_init(void)
570{
571 printk(KERN_INFO "HTC Herald init.\n");
572
573
574 htcpld_resources[0].start = gpio_to_irq(HTCHERALD_GIRQ_BTNS);
575 htcpld_resources[0].end = gpio_to_irq(HTCHERALD_GIRQ_BTNS);
576 platform_add_devices(devices, ARRAY_SIZE(devices));
577
578 htcherald_disable_watchdog();
579
580 htcherald_usb_enable();
581 omap1_usb_init(&htcherald_usb_config);
582
583 htcherald_spi_board_info[0].irq = gpio_to_irq(HTCHERALD_GPIO_TS);
584 spi_register_board_info(htcherald_spi_board_info,
585 ARRAY_SIZE(htcherald_spi_board_info));
586
587 omap_register_i2c_bus(1, 100, NULL, 0);
588
589#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
590 htc_mmc_data[0] = &htc_mmc1_data;
591 omap1_init_mmc(htc_mmc_data, 1);
592#endif
593
594 omapfb_set_lcd_config(&htcherald_lcd_config);
595}
596
597MACHINE_START(HERALD, "HTC Herald")
598
599
600 .atag_offset = 0x100,
601 .map_io = htcherald_map_io,
602 .init_early = omap1_init_early,
603 .init_irq = omap1_init_irq,
604 .init_machine = htcherald_init,
605 .init_late = omap1_init_late,
606 .init_time = omap1_timer_init,
607 .restart = omap1_restart,
608MACHINE_END
609