linux-omap-pm 2.6.29: merge in touchbook updates from AI repo
[openembedded.git] / recipes / linux / linux-omap-pm-2.6.29 / omap3-touchbook / board-omap3touchbook.c
1 /*
2  * linux/arch/arm/mach-omap2/board-omap3touchbook.c
3  *
4  * Copyright (C) 2009 Always Innovating
5  *
6  * Modified from mach-omap2/board-omap3beagleboard.c
7  *
8  * Initial code: GrĂ©goire Gentil, Tim Yamin
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 as
12  * published by the Free Software Foundation.
13  */
14
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/platform_device.h>
18 #include <linux/delay.h>
19 #include <linux/err.h>
20 #include <linux/clk.h>
21 #include <linux/io.h>
22 #include <linux/leds.h>
23 #include <linux/gpio.h>
24 #include <linux/input.h>
25 #include <linux/gpio_keys.h>
26
27 #include <linux/mtd/mtd.h>
28 #include <linux/mtd/partitions.h>
29 #include <linux/mtd/nand.h>
30
31 #include <mach/mcspi.h>
32 #include <linux/spi/spi.h>
33 #include <linux/spi/ads7846.h>
34 #include <linux/mma7455l.h>
35
36 #include <mach/dmtimer.h>
37 #include <linux/backlight.h>
38
39 #include <linux/regulator/machine.h>
40 #include <linux/i2c/twl4030.h>
41 #include <linux/omapfb.h>
42
43 #include <mach/hardware.h>
44 #include <asm/mach-types.h>
45 #include <asm/mach/arch.h>
46 #include <asm/mach/map.h>
47 #include <asm/mach/flash.h>
48
49 #include <mach/board.h>
50 #include <mach/usb.h>
51 #include <mach/common.h>
52 #include <mach/gpmc.h>
53 #include <mach/nand.h>
54 #include <mach/mux.h>
55 #include <mach/omap-pm.h>
56 #include <mach/clock.h>
57 #include <mach/display.h>
58
59
60 #include "twl4030-generic-scripts.h"
61 #include "mmc-twl4030.h"
62 #include "pm.h"
63 #include "omap3-opp.h"
64
65
66 #define GPMC_CS0_BASE  0x60
67 #define GPMC_CS_SIZE   0x30
68
69 #define NAND_BLOCK_SIZE         SZ_128K
70
71 #define OMAP3_AC_GPIO           136 //Int1 DRDY
72 #define OMAP3_TS_GPIO           162
73 #define OMAP3_CHACHA_GPIO       154
74 #define TB_BL_PWM_TIMER         9
75 #define TB_KILL_POWER_GPIO      168
76
77 unsigned int ai_revision = 2;
78
79 static struct mtd_partition omap3touchbook_nand_partitions[] = {
80         /* All the partition sizes are listed in terms of NAND block size */
81         {
82                 .name           = "X-Loader",
83                 .offset         = 0,
84                 .size           = 4 * NAND_BLOCK_SIZE,
85                 .mask_flags     = MTD_WRITEABLE,        /* force read-only */
86         },
87         {
88                 .name           = "U-Boot",
89                 .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x80000 */
90                 .size           = 15 * NAND_BLOCK_SIZE,
91                 .mask_flags     = MTD_WRITEABLE,        /* force read-only */
92         },
93         {
94                 .name           = "U-Boot Env",
95                 .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x260000 */
96                 .size           = 1 * NAND_BLOCK_SIZE,
97         },
98         {
99                 .name           = "Kernel",
100                 .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x280000 */
101                 .size           = 32 * NAND_BLOCK_SIZE,
102         },
103         {
104                 .name           = "File System",
105                 .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x680000 */
106                 .size           = MTDPART_SIZ_FULL,
107         },
108 };
109
110 static struct omap_nand_platform_data omap3touchbook_nand_data = {
111         .options        = NAND_BUSWIDTH_16,
112         .parts          = omap3touchbook_nand_partitions,
113         .nr_parts       = ARRAY_SIZE(omap3touchbook_nand_partitions),
114         .dma_channel    = -1,           /* disable DMA in OMAP NAND driver */
115         .nand_setup     = NULL,
116         .dev_ready      = NULL,
117 };
118
119 static struct resource omap3touchbook_nand_resource = {
120         .flags          = IORESOURCE_MEM,
121 };
122
123 static struct platform_device omap3touchbook_nand_device = {
124         .name           = "omap2-nand",
125         .id             = -1,
126         .dev            = {
127                 .platform_data  = &omap3touchbook_nand_data,
128         },
129         .num_resources  = 1,
130         .resource       = &omap3touchbook_nand_resource,
131 };
132
133 #include "sdram-micron-mt46h32m32lf-6.h"
134
135 static struct omap_uart_config omap3_touchbook_uart_config __initdata = {
136         .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
137 };
138
139 static struct twl4030_usb_data touchbook_usb_data = {
140         .usb_mode       = T2_USB_MODE_ULPI,
141 };
142
143 static struct twl4030_hsmmc_info mmc[] = {
144         {
145                 .mmc            = 1,
146                 .wires          = 8,
147                 .gpio_wp        = 29,
148         },
149         {}      /* Terminator */
150 };
151
152 static struct regulator_consumer_supply touchbook_vmmc1_supply = {
153         .supply                 = "vmmc",
154 };
155
156 static struct regulator_consumer_supply touchbook_vsim_supply = {
157         .supply                 = "vmmc_aux",
158 };
159
160 static struct gpio_led gpio_leds[];
161
162 static int touchbook_twl_gpio_setup(struct device *dev,
163                 unsigned gpio, unsigned ngpio)
164 {
165         /* gpio + 0 is "mmc0_cd" (input/IRQ) */
166         omap_cfg_reg(AH8_34XX_GPIO29);
167         mmc[0].gpio_cd = gpio + 0;
168         twl4030_mmc_init(mmc);
169
170         /* link regulators to MMC adapters */
171         touchbook_vmmc1_supply.dev = mmc[0].dev;
172         touchbook_vsim_supply.dev = mmc[0].dev;
173
174         /* REVISIT: need ehci-omap hooks for external VBUS
175          * power switch and overcurrent detect
176          */
177
178 #if 0 /* TODO: This needs to be modified to not rely on u-boot */
179         gpio_request(gpio + 1, "EHCI_nOC");
180         gpio_direction_input(gpio + 1);
181
182         /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
183         gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
184         gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
185
186         /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
187         gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
188 #endif
189         return 0;
190 }
191
192 static struct twl4030_gpio_platform_data touchbook_gpio_data = {
193         .gpio_base      = OMAP_MAX_GPIO_LINES,
194         .irq_base       = TWL4030_GPIO_IRQ_BASE,
195         .irq_end        = TWL4030_GPIO_IRQ_END,
196         .use_leds       = true,
197         .pullups        = BIT(1),
198         .pulldowns      = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
199                                 | BIT(15) | BIT(16) | BIT(17),
200         .setup          = touchbook_twl_gpio_setup,
201 };
202
203 static struct platform_device omap3_touchbook_lcd_device = {
204         .name           = "omap3touchbook_lcd",
205         .id             = -1,
206 };
207
208 static struct regulator_consumer_supply touchbook_vdac_supply = {
209         .supply         = "vdac",
210         .dev            = &omap3_touchbook_lcd_device.dev,
211 };
212
213 static struct regulator_consumer_supply touchbook_vdvi_supply = {
214         .supply         = "vdvi",
215         .dev            = &omap3_touchbook_lcd_device.dev,
216 };
217
218 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
219 static struct regulator_init_data touchbook_vmmc1 = {
220         .constraints = {
221                 .min_uV                 = 1850000,
222                 .max_uV                 = 3150000,
223                 .valid_modes_mask       = REGULATOR_MODE_NORMAL
224                                         | REGULATOR_MODE_STANDBY,
225                 .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
226                                         | REGULATOR_CHANGE_MODE
227                                         | REGULATOR_CHANGE_STATUS,
228         },
229         .num_consumer_supplies  = 1,
230         .consumer_supplies      = &touchbook_vmmc1_supply,
231 };
232
233 /* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
234 static struct regulator_init_data touchbook_vsim = {
235         .constraints = {
236                 .min_uV                 = 1800000,
237                 .max_uV                 = 3000000,
238                 .valid_modes_mask       = REGULATOR_MODE_NORMAL
239                                         | REGULATOR_MODE_STANDBY,
240                 .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
241                                         | REGULATOR_CHANGE_MODE
242                                         | REGULATOR_CHANGE_STATUS,
243         },
244         .num_consumer_supplies  = 1,
245         .consumer_supplies      = &touchbook_vsim_supply,
246 };
247
248 /* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
249 static struct regulator_init_data touchbook_vdac = {
250         .constraints = {
251                 .min_uV                 = 1800000,
252                 .max_uV                 = 1800000,
253                 .valid_modes_mask       = REGULATOR_MODE_NORMAL
254                                         | REGULATOR_MODE_STANDBY,
255                 .valid_ops_mask         = REGULATOR_CHANGE_MODE
256                                         | REGULATOR_CHANGE_STATUS,
257         },
258         .num_consumer_supplies  = 1,
259         .consumer_supplies      = &touchbook_vdac_supply,
260 };
261
262 /* VPLL2 for digital video outputs */
263 static struct regulator_init_data touchbook_vpll2 = {
264         .constraints = {
265                 .name                   = "VDVI",
266                 .min_uV                 = 1800000,
267                 .max_uV                 = 1800000,
268                 .valid_modes_mask       = REGULATOR_MODE_NORMAL
269                                         | REGULATOR_MODE_STANDBY,
270                 .valid_ops_mask         = REGULATOR_CHANGE_MODE
271                                         | REGULATOR_CHANGE_STATUS,
272         },
273         .num_consumer_supplies  = 1,
274         .consumer_supplies      = &touchbook_vdvi_supply,
275 };
276
277 static const struct twl4030_resconfig touchbook_resconfig[] = {
278         /* disable regulators that u-boot left enabled; the
279          * devices' drivers should be managing these.
280          */
281         { .resource = RES_VAUX3, },     /* not even connected! */
282         { .resource = RES_VMMC1, },
283         { .resource = RES_VSIM, },
284         { .resource = RES_VPLL2, },
285         { .resource = RES_VDAC, },
286         { .resource = RES_VUSB_1V5, },
287         { .resource = RES_VUSB_1V8, },
288         { .resource = RES_VUSB_3V1, },
289         { 0, },
290 };
291
292 static struct twl4030_power_data touchbook_power_data = {
293         .resource_config        = touchbook_resconfig,
294         /* REVISIT can't use GENERIC3430_T2SCRIPTS_DATA;
295          * among other things, it makes reboot fail.
296          */
297 };
298
299 static struct twl4030_bci_platform_data touchbook_bci_data = {
300         .tblsize                = 0,
301         .no_backup_battery      = 1,
302 };
303
304 static struct twl4030_madc_platform_data touchbook_madc_data = {
305         .irq_line       = 1,
306 };
307
308 static struct twl4030_platform_data touchbook_twldata = {
309         .irq_base       = TWL4030_IRQ_BASE,
310         .irq_end        = TWL4030_IRQ_END,
311
312         /* platform_data for children goes here */
313         .usb            = &touchbook_usb_data,
314         .gpio           = &touchbook_gpio_data,
315         .power          = &touchbook_power_data,
316         .vmmc1          = &touchbook_vmmc1,
317         .vsim           = &touchbook_vsim,
318         .vdac           = &touchbook_vdac,
319         .vpll2          = &touchbook_vpll2,
320
321         /* TouchBook BCI */
322         .bci            = &touchbook_bci_data,
323         .madc           = &touchbook_madc_data,
324 };
325
326 static struct i2c_board_info __initdata touchbook_i2c_boardinfo[] = {
327         {
328                 I2C_BOARD_INFO("twl4030", 0x48),
329                 .flags = I2C_CLIENT_WAKE,
330                 .irq = INT_34XX_SYS_NIRQ,
331                 .platform_data = &touchbook_twldata,
332         },
333 };
334
335 static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = {
336         {
337                 I2C_BOARD_INFO("bq27200", 0x55),
338         },
339 //      {
340 //              I2C_BOARD_INFO("chacha_mt8c", 0x40),
341 //              .irq = OMAP_GPIO_IRQ(OMAP3_CHACHA_GPIO),
342 //      },
343 };
344
345 static void __init omap3_touchbook_i2c_init(void)
346 {
347         int ret;
348
349         /* Standard TouchBook bus */
350         omap_register_i2c_bus(1, 2600, touchbook_i2c_boardinfo,
351                         ARRAY_SIZE(touchbook_i2c_boardinfo));
352
353         /* Additional TouchBook bus */
354         omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo,
355                         ARRAY_SIZE(touchBook_i2c_boardinfo));
356
357 /*      ret = gpio_request(OMAP3_CHACHA_GPIO, "chacha_mt8c");
358         if (ret < 0) {
359                 printk(KERN_ERR "Failed to request GPIO %d for chacha_mt8c IRQ\n", OMAP3_CHACHA_GPIO);
360                 return;
361         }
362
363         gpio_direction_input(OMAP3_CHACHA_GPIO);*/
364         return;
365 }
366
367 static void __init omap3_ads7846_init(void)
368 {
369         if (gpio_request(OMAP3_TS_GPIO, "ads7846_pen_down")) {
370                 printk(KERN_ERR "Failed to request GPIO %d for "
371                                 "ads7846 pen down IRQ\n", OMAP3_TS_GPIO);
372                 return;
373         }
374
375         gpio_direction_input(OMAP3_TS_GPIO);
376         omap_set_gpio_debounce(OMAP3_TS_GPIO, 1);
377         omap_set_gpio_debounce_time(OMAP3_TS_GPIO, 0xa);
378 }
379
380 static struct ads7846_platform_data ads7846_config = {
381         .x_min                  = 100,
382         .y_min                  = 265,
383         .x_max                  = 3950,
384         .y_max                  = 3750,
385         .x_plate_ohms           = 40,
386         .pressure_max           = 255,
387         .debounce_max           = 10,
388         .debounce_tol           = 5,
389         .debounce_rep           = 1,
390         .gpio_pendown           = OMAP3_TS_GPIO,
391         .keep_vref_on           = 1,
392 };
393
394 static struct omap2_mcspi_device_config ads7846_mcspi_config = {
395         .turbo_mode     = 0,
396         .single_channel = 1,    /* 0: slave, 1: master */
397 };
398
399 static struct spi_board_info omap3_ads7846_spi_board_info[] __initdata = {
400         {
401                 .modalias               = "ads7846",
402                 .bus_num                = 4,
403                 .chip_select            = 0,
404                 .max_speed_hz           = 1500000,
405                 .controller_data        = &ads7846_mcspi_config, //(void *) 161,
406                 .irq                    = OMAP_GPIO_IRQ(OMAP3_TS_GPIO),
407                 .platform_data          = &ads7846_config,
408         }
409 };
410
411 static void __init omap3_touchbook_init_irq(void)
412 {
413         omap2_init_common_hw(mt46h32m32lf6_sdrc_params, omap3_mpu_rate_table,
414                                                  omap3_dsp_rate_table, omap3_l3_rate_table);
415         omap_init_irq();
416         omap_gpio_init();
417 }
418
419 static struct gpio_led gpio_leds[] = {
420         {
421                 .name                   = "touchbook::usr0",
422                 .default_trigger        = "heartbeat",
423                 .gpio                   = 150,
424         },
425         {
426                 .name                   = "touchbook::usr1",
427                 .default_trigger        = "mmc0",
428                 .gpio                   = 149,
429         },
430         {
431                 .name                   = "touchbook::pmu_stat",
432                 .gpio                   = -EINVAL,      /* gets replaced */
433                 .active_low             = true,
434         },
435 };
436
437 static struct gpio_led_platform_data gpio_led_info = {
438         .leds           = gpio_leds,
439         .num_leds       = ARRAY_SIZE(gpio_leds),
440 };
441
442 static struct platform_device leds_gpio = {
443         .name   = "leds-gpio",
444         .id     = -1,
445         .dev    = {
446                 .platform_data  = &gpio_led_info,
447         },
448 };
449
450 static struct gpio_keys_button gpio_buttons[] = {
451         {
452                 .code                   = BTN_EXTRA,
453                 .gpio                   = 7,
454                 .desc                   = "user",
455                 .wakeup                 = 1,
456         },
457         {
458                 .code                   = KEY_POWER,
459                 .gpio                   = 183,
460                 .desc                   = "power",
461                 .wakeup                 = 1,
462                 .active_low             = 1,
463         },
464 };
465
466 static struct gpio_keys_platform_data gpio_key_info = {
467         .buttons        = gpio_buttons,
468         .nbuttons       = ARRAY_SIZE(gpio_buttons),
469 };
470
471 static struct platform_device keys_gpio = {
472         .name   = "gpio-keys",
473         .id     = -1,
474         .dev    = {
475                 .platform_data  = &gpio_key_info,
476         },
477 };
478
479 /* DSS */
480
481 static int touchbook_enable_dvi(struct omap_display *display)
482 {
483         if (display->hw_config.panel_reset_gpio != -1)
484                 gpio_set_value(display->hw_config.panel_reset_gpio, 1);
485
486         return 0;
487 }
488
489 static void touchbook_disable_dvi(struct omap_display *display)
490 {
491         if (display->hw_config.panel_reset_gpio != -1)
492                 gpio_set_value(display->hw_config.panel_reset_gpio, 0);
493 }
494
495 static struct omap_dss_display_config touchbook_display_data_dvi = {
496         .type = OMAP_DISPLAY_TYPE_DPI,
497         .name = "dvi",
498         .panel_name = "panel-generic",
499         .u.dpi.data_lines = 24,
500         .panel_reset_gpio = 176,
501         .panel_enable = touchbook_enable_dvi,
502         .panel_disable = touchbook_disable_dvi,
503 };
504
505
506 static int touchbook_panel_enable_tv(struct omap_display *display)
507 {
508 #define ENABLE_VDAC_DEDICATED           0x03
509 #define ENABLE_VDAC_DEV_GRP             0x20
510
511         twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
512                         ENABLE_VDAC_DEDICATED,
513                         TWL4030_VDAC_DEDICATED);
514         twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
515                         ENABLE_VDAC_DEV_GRP, TWL4030_VDAC_DEV_GRP);
516
517         return 0;
518 }
519
520 static void touchbook_panel_disable_tv(struct omap_display *display)
521 {
522         twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
523                         TWL4030_VDAC_DEDICATED);
524         twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
525                         TWL4030_VDAC_DEV_GRP);
526 }
527
528 static struct omap_dss_display_config touchbook_display_data_tv = {
529         .type = OMAP_DISPLAY_TYPE_VENC,
530         .name = "tv",
531         .u.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
532         .panel_enable = touchbook_panel_enable_tv,
533         .panel_disable = touchbook_panel_disable_tv,
534 };
535
536 static struct omap_dss_board_info touchbook_dss_data = {
537         .num_displays = 2,
538         .displays = {
539                 &touchbook_display_data_dvi,
540                 &touchbook_display_data_tv,
541         }
542 };
543
544 static struct platform_device touchbook_dss_device = {
545         .name          = "omapdss",
546         .id            = -1,
547         .dev            = {
548                 .platform_data = &touchbook_dss_data,
549         },
550 };
551
552 static void __init touchbook_display_init(void)
553 {
554         int r;
555
556         r = gpio_request(touchbook_display_data_dvi.panel_reset_gpio, "DVI reset");
557         if (r < 0) {
558                 printk(KERN_ERR "Unable to get DVI reset GPIO\n");
559                 return;
560         }
561
562         gpio_direction_output(touchbook_display_data_dvi.panel_reset_gpio, 0);
563 }
564
565 static struct omap_board_config_kernel omap3_touchbook_config[] __initdata = {
566         { OMAP_TAG_UART,        &omap3_touchbook_uart_config },
567 };
568
569 static struct platform_device *omap3_touchbook_devices[] __initdata = {
570         &touchbook_dss_device,
571         &leds_gpio,
572         &keys_gpio,
573 };
574
575 static void __init omap3touchbook_flash_init(void)
576 {
577         u8 cs = 0;
578         u8 nandcs = GPMC_CS_NUM + 1;
579
580         u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
581
582         /* find out the chip-select on which NAND exists */
583         while (cs < GPMC_CS_NUM) {
584                 u32 ret = 0;
585                 ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
586
587                 if ((ret & 0xC00) == 0x800) {
588                         printk(KERN_INFO "Found NAND on CS%d\n", cs);
589                         if (nandcs > GPMC_CS_NUM)
590                                 nandcs = cs;
591                 }
592                 cs++;
593         }
594
595         if (nandcs > GPMC_CS_NUM) {
596                 printk(KERN_INFO "NAND: Unable to find configuration "
597                                  "in GPMC\n ");
598                 return;
599         }
600
601         if (nandcs < GPMC_CS_NUM) {
602                 omap3touchbook_nand_data.cs = nandcs;
603                 omap3touchbook_nand_data.gpmc_cs_baseaddr = (void *)
604                         (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
605                 omap3touchbook_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
606
607                 printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
608                 if (platform_device_register(&omap3touchbook_nand_device) < 0)
609                         printk(KERN_ERR "Unable to register NAND device\n");
610         }
611 }
612
613 static void __init omap3_mma7455l_init(void)
614 {
615         int ret;
616
617         ret = gpio_request(OMAP3_AC_GPIO, "mma7455l");
618         if (ret < 0) {
619                 printk(KERN_ERR "Failed to request GPIO %d for mma7455l IRQ\n", OMAP3_AC_GPIO);
620                 return;
621         }
622
623         gpio_direction_input(OMAP3_AC_GPIO);
624 }
625
626 static struct mma7455l_platform_data mma7455l_config = {
627         .calibration_x = -4, //26 for Beagleboard
628         .calibration_y = 28, //44 for Beagleboard
629         .calibration_z = -28, //26 for Beagleboard
630 };
631
632 static struct omap2_mcspi_device_config mma7455l_mcspi_config = {
633         .turbo_mode     = 0,
634         .single_channel = 1,    /* 0: slave, 1: master */
635 };
636
637 static struct spi_board_info omap3_mma7455l_spi_board_info[] __initdata = {
638         {
639                 .modalias               = "mma7455l",
640                 .bus_num                = 3,
641                 .chip_select            = 0,
642                 .max_speed_hz           = 200000,
643                 .irq                    = OMAP_GPIO_IRQ(OMAP3_AC_GPIO),
644                 .controller_data        = &mma7455l_mcspi_config, //(void *) 135,
645                 .platform_data          = &mma7455l_config,
646         }
647 };
648
649 static int touchbook_backlight_brightness = 50;
650 static struct omap_dm_timer *touchbook_backlight_pwm;
651
652 static int touchbook_backlight_read(struct backlight_device *bd)
653 {
654         return touchbook_backlight_brightness;
655 }
656
657 static int touchbook_backlight_update(struct backlight_device *bd)
658 {
659         int value = bd->props.brightness;
660         touchbook_backlight_brightness = value;
661
662         /* Frequency calculation:
663            - For 200Hz PWM, you want to load -164 (=> -32768Hz / 200Hz).
664            - Minimum duty cycle for the backlight is 15%.
665            - You have (164*0.85) => ~140 levels of brightness.
666         */
667
668         /* Halve input brightness */
669         value /= 2;
670
671         /* For maximum brightness, just stop the timer... */
672         if(value != bd->props.max_brightness)
673         {
674                 /* Load the appropriate value for 200Hz PWM */
675                 u32 period = clk_get_rate(omap_dm_timer_get_fclk(touchbook_backlight_pwm)) / 200;
676
677                 /* Minimum duty cycle is 15% */
678                 u32 minimum = (period * 3) / 20;
679                 u32 maximum = (period * 17) / 20;
680
681                 /* Work out match value */
682                 u32 match = (maximum * value) / 100;
683
684                 /* Start... */
685                 omap_dm_timer_set_load(touchbook_backlight_pwm, 1, 0xFFFFFFFF - period - 1);
686                 omap_dm_timer_set_match(touchbook_backlight_pwm, 1, 0xFFFFFFFF - minimum - match);
687                 omap_dm_timer_write_counter(touchbook_backlight_pwm, -1);
688                 //omap_dm_timer_stop(touchbook_backlight_pwm);
689                 omap_dm_timer_start(touchbook_backlight_pwm);
690         }
691         else
692                 omap_dm_timer_stop(touchbook_backlight_pwm);
693
694
695         return 0;
696 }
697
698 static struct backlight_ops touchbook_backlight_properties = {
699         .get_brightness = touchbook_backlight_read,
700         .update_status = touchbook_backlight_update,
701 };
702
703 static void __init omap3_touchbook_backlight_init(void)
704 {
705         static struct backlight_device *bd;
706         bd = backlight_device_register("touchbook", NULL, NULL, &touchbook_backlight_properties);
707
708         if(bd)
709         {
710                 touchbook_backlight_pwm = omap_dm_timer_request_specific(TB_BL_PWM_TIMER);
711                 omap_dm_timer_enable(touchbook_backlight_pwm);
712                 omap_dm_timer_set_source(touchbook_backlight_pwm, OMAP_TIMER_SRC_SYS_CLK);
713                 omap_dm_timer_set_pwm(touchbook_backlight_pwm, 1, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE);
714
715                 bd->props.max_brightness = 100;
716                 bd->props.brightness = touchbook_backlight_brightness;
717         }
718
719         touchbook_backlight_update(bd);
720 }
721
722 static void omap3_touchbook_poweroff(void)
723 {
724         int r;
725
726         r = gpio_request(TB_KILL_POWER_GPIO, "DVI reset");
727         if (r < 0) {
728                 printk(KERN_ERR "Unable to get kill power GPIO\n");
729                 return;
730         }
731
732         gpio_direction_output(TB_KILL_POWER_GPIO, 0);
733 }
734
735 static int __init ai_revision_instance(char *str)
736 {
737         if (!str)
738                 return -EINVAL;
739
740         ai_revision = simple_strtoul(str, NULL, 10);
741
742         return 0;
743 }
744
745 static void __init omap3_touchbook_init(void)
746 {
747         pm_power_off = omap3_touchbook_poweroff;
748
749         omap3_touchbook_i2c_init();
750         platform_add_devices(omap3_touchbook_devices,
751                         ARRAY_SIZE(omap3_touchbook_devices));
752         omap_board_config = omap3_touchbook_config;
753         omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config);
754         omap_serial_init();
755
756         omap_cfg_reg(J25_34XX_GPIO170);
757
758         omap3touchbook_flash_init();
759         touchbook_display_init();
760         omap3_touchbook_backlight_init();
761
762         /* Touch Book */
763         spi_register_board_info(omap3_ads7846_spi_board_info, ARRAY_SIZE(omap3_ads7846_spi_board_info));
764         spi_register_board_info(omap3_mma7455l_spi_board_info, ARRAY_SIZE(omap3_mma7455l_spi_board_info));
765
766         omap3_ads7846_init();
767         omap3_mma7455l_init();
768
769         usb_musb_init();
770         usb_ehci_init();
771 }
772
773 static void __init omap3_touchbook_map_io(void)
774 {
775         omap2_set_globals_343x();
776         omap2_map_common_io();
777 }
778
779 early_param("air", ai_revision_instance);
780
781 MACHINE_START(OMAP3_TOUCHBOOK, "OMAP3 Touch Book")
782         /* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */
783         .phys_io        = 0x48000000,
784         .io_pg_offst    = ((0xd8000000) >> 18) & 0xfffc,
785         .boot_params    = 0x80000100,
786         .map_io         = omap3_touchbook_map_io,
787         .init_irq       = omap3_touchbook_init_irq,
788         .init_machine   = omap3_touchbook_init,
789         .timer          = &omap_timer,
790 MACHINE_END