linux/drivers/video/omap/lcd_ldp.c
<<
>>
Prefs
   1/*
   2 * LCD panel support for the TI LDP board
   3 *
   4 * Copyright (C) 2007 WindRiver
   5 * Author: Stanley Miao <stanley.miao@windriver.com>
   6 *
   7 * Derived from drivers/video/omap/lcd-2430sdp.c
   8 *
   9 * This program is free software; you can redistribute it and/or modify it
  10 * under the terms of the GNU General Public License as published by the
  11 * Free Software Foundation; either version 2 of the License, or (at your
  12 * option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful, but
  15 * WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License along
  20 * with this program; if not, write to the Free Software Foundation, Inc.,
  21 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  22 */
  23
  24#include <linux/module.h>
  25#include <linux/platform_device.h>
  26#include <linux/delay.h>
  27#include <linux/i2c/twl4030.h>
  28
  29#include <mach/gpio.h>
  30#include <mach/mux.h>
  31#include <mach/omapfb.h>
  32#include <asm/mach-types.h>
  33
  34#define LCD_PANEL_BACKLIGHT_GPIO        (15 + OMAP_MAX_GPIO_LINES)
  35#define LCD_PANEL_ENABLE_GPIO           (7 + OMAP_MAX_GPIO_LINES)
  36
  37#define LCD_PANEL_RESET_GPIO            55
  38#define LCD_PANEL_QVGA_GPIO             56
  39
  40#ifdef CONFIG_FB_OMAP_LCD_VGA
  41#define LCD_XRES                480
  42#define LCD_YRES                640
  43#define LCD_PIXCLOCK_MAX        41700
  44#else
  45#define LCD_XRES                240
  46#define LCD_YRES                320
  47#define LCD_PIXCLOCK_MAX        185186
  48#endif
  49
  50#define PM_RECEIVER             TWL4030_MODULE_PM_RECEIVER
  51#define ENABLE_VAUX2_DEDICATED  0x09
  52#define ENABLE_VAUX2_DEV_GRP    0x20
  53#define ENABLE_VAUX3_DEDICATED  0x03
  54#define ENABLE_VAUX3_DEV_GRP    0x20
  55
  56#define ENABLE_VPLL2_DEDICATED          0x05
  57#define ENABLE_VPLL2_DEV_GRP            0xE0
  58#define TWL4030_VPLL2_DEV_GRP           0x33
  59#define TWL4030_VPLL2_DEDICATED         0x36
  60
  61#define t2_out(c, r, v) twl4030_i2c_write_u8(c, r, v)
  62
  63
  64static int ldp_panel_init(struct lcd_panel *panel,
  65                                struct omapfb_device *fbdev)
  66{
  67        gpio_request(LCD_PANEL_RESET_GPIO, "lcd reset");
  68        gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga");
  69        gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd panel");
  70        gpio_request(LCD_PANEL_BACKLIGHT_GPIO, "lcd backlight");
  71
  72        gpio_direction_output(LCD_PANEL_QVGA_GPIO, 0);
  73        gpio_direction_output(LCD_PANEL_RESET_GPIO, 0);
  74        gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
  75        gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
  76
  77#ifdef CONFIG_FB_OMAP_LCD_VGA
  78        gpio_set_value(LCD_PANEL_QVGA_GPIO, 0);
  79#else
  80        gpio_set_value(LCD_PANEL_QVGA_GPIO, 1);
  81#endif
  82        gpio_set_value(LCD_PANEL_RESET_GPIO, 1);
  83
  84        return 0;
  85}
  86
  87static void ldp_panel_cleanup(struct lcd_panel *panel)
  88{
  89        gpio_free(LCD_PANEL_BACKLIGHT_GPIO);
  90        gpio_free(LCD_PANEL_ENABLE_GPIO);
  91        gpio_free(LCD_PANEL_QVGA_GPIO);
  92        gpio_free(LCD_PANEL_RESET_GPIO);
  93}
  94
  95static int ldp_panel_enable(struct lcd_panel *panel)
  96{
  97        if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
  98                        TWL4030_VPLL2_DEDICATED))
  99                return -EIO;
 100        if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
 101                        TWL4030_VPLL2_DEV_GRP))
 102                return -EIO;
 103
 104        gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
 105        gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 1);
 106
 107        if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEDICATED,
 108                                TWL4030_VAUX3_DEDICATED))
 109                return -EIO;
 110        if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEV_GRP,
 111                                TWL4030_VAUX3_DEV_GRP))
 112                return -EIO;
 113
 114        return 0;
 115}
 116
 117static void ldp_panel_disable(struct lcd_panel *panel)
 118{
 119        gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
 120        gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
 121
 122        t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
 123        t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
 124        msleep(4);
 125}
 126
 127static unsigned long ldp_panel_get_caps(struct lcd_panel *panel)
 128{
 129        return 0;
 130}
 131
 132struct lcd_panel ldp_panel = {
 133        .name           = "ldp",
 134        .config         = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
 135                          OMAP_LCDC_INV_HSYNC,
 136
 137        .bpp            = 16,
 138        .data_lines     = 18,
 139        .x_res          = LCD_XRES,
 140        .y_res          = LCD_YRES,
 141        .hsw            = 3,            /* hsync_len (4) - 1 */
 142        .hfp            = 3,            /* right_margin (4) - 1 */
 143        .hbp            = 39,           /* left_margin (40) - 1 */
 144        .vsw            = 1,            /* vsync_len (2) - 1 */
 145        .vfp            = 2,            /* lower_margin */
 146        .vbp            = 7,            /* upper_margin (8) - 1 */
 147
 148        .pixel_clock    = LCD_PIXCLOCK_MAX,
 149
 150        .init           = ldp_panel_init,
 151        .cleanup        = ldp_panel_cleanup,
 152        .enable         = ldp_panel_enable,
 153        .disable        = ldp_panel_disable,
 154        .get_caps       = ldp_panel_get_caps,
 155};
 156
 157static int ldp_panel_probe(struct platform_device *pdev)
 158{
 159        omapfb_register_panel(&ldp_panel);
 160        return 0;
 161}
 162
 163static int ldp_panel_remove(struct platform_device *pdev)
 164{
 165        return 0;
 166}
 167
 168static int ldp_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
 169{
 170        return 0;
 171}
 172
 173static int ldp_panel_resume(struct platform_device *pdev)
 174{
 175        return 0;
 176}
 177
 178struct platform_driver ldp_panel_driver = {
 179        .probe          = ldp_panel_probe,
 180        .remove         = ldp_panel_remove,
 181        .suspend        = ldp_panel_suspend,
 182        .resume         = ldp_panel_resume,
 183        .driver         = {
 184                .name   = "ldp_lcd",
 185                .owner  = THIS_MODULE,
 186        },
 187};
 188
 189static int __init ldp_panel_drv_init(void)
 190{
 191        return platform_driver_register(&ldp_panel_driver);
 192}
 193
 194static void __exit ldp_panel_drv_exit(void)
 195{
 196        platform_driver_unregister(&ldp_panel_driver);
 197}
 198
 199module_init(ldp_panel_drv_init);
 200module_exit(ldp_panel_drv_exit);
 201