linux/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
<<
>>
Prefs
   1/*
   2 * LCD panel driver for Sharp LS037V7DW01
   3 *
   4 * Copyright (C) 2008 Nokia Corporation
   5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of the GNU General Public License version 2 as published by
   9 * the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include <linux/module.h>
  21#include <linux/delay.h>
  22#include <linux/device.h>
  23#include <linux/fb.h>
  24#include <linux/err.h>
  25#include <linux/slab.h>
  26#include <linux/gpio.h>
  27
  28#include <video/omapdss.h>
  29#include <video/omap-panel-data.h>
  30
  31static struct omap_video_timings sharp_ls_timings = {
  32        .x_res = 480,
  33        .y_res = 640,
  34
  35        .pixel_clock    = 19200,
  36
  37        .hsw            = 2,
  38        .hfp            = 1,
  39        .hbp            = 28,
  40
  41        .vsw            = 1,
  42        .vfp            = 1,
  43        .vbp            = 1,
  44
  45        .vsync_level    = OMAPDSS_SIG_ACTIVE_LOW,
  46        .hsync_level    = OMAPDSS_SIG_ACTIVE_LOW,
  47        .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
  48        .de_level       = OMAPDSS_SIG_ACTIVE_HIGH,
  49        .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
  50};
  51
  52static inline struct panel_sharp_ls037v7dw01_data
  53*get_panel_data(const struct omap_dss_device *dssdev)
  54{
  55        return (struct panel_sharp_ls037v7dw01_data *) dssdev->data;
  56}
  57
  58static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
  59{
  60        struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev);
  61        int r;
  62
  63        if (!pd)
  64                return -EINVAL;
  65
  66        dssdev->panel.timings = sharp_ls_timings;
  67
  68        if (gpio_is_valid(pd->mo_gpio)) {
  69                r = devm_gpio_request_one(dssdev->dev, pd->mo_gpio,
  70                                GPIOF_OUT_INIT_LOW, "lcd MO");
  71                if (r)
  72                        return r;
  73        }
  74
  75        if (gpio_is_valid(pd->lr_gpio)) {
  76                r = devm_gpio_request_one(dssdev->dev, pd->lr_gpio,
  77                                GPIOF_OUT_INIT_HIGH, "lcd LR");
  78                if (r)
  79                        return r;
  80        }
  81
  82        if (gpio_is_valid(pd->ud_gpio)) {
  83                r = devm_gpio_request_one(dssdev->dev, pd->ud_gpio,
  84                                GPIOF_OUT_INIT_HIGH, "lcd UD");
  85                if (r)
  86                        return r;
  87        }
  88
  89        if (gpio_is_valid(pd->resb_gpio)) {
  90                r = devm_gpio_request_one(dssdev->dev, pd->resb_gpio,
  91                                GPIOF_OUT_INIT_LOW, "lcd RESB");
  92                if (r)
  93                        return r;
  94        }
  95
  96        if (gpio_is_valid(pd->ini_gpio)) {
  97                r = devm_gpio_request_one(dssdev->dev, pd->ini_gpio,
  98                                GPIOF_OUT_INIT_LOW, "lcd INI");
  99                if (r)
 100                        return r;
 101        }
 102
 103        return 0;
 104}
 105
 106static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev)
 107{
 108}
 109
 110static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 111{
 112        struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev);
 113        int r = 0;
 114
 115        if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 116                return 0;
 117
 118        omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
 119        omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
 120
 121        r = omapdss_dpi_display_enable(dssdev);
 122        if (r)
 123                goto err0;
 124
 125        /* wait couple of vsyncs until enabling the LCD */
 126        msleep(50);
 127
 128        if (gpio_is_valid(pd->resb_gpio))
 129                gpio_set_value_cansleep(pd->resb_gpio, 1);
 130
 131        if (gpio_is_valid(pd->ini_gpio))
 132                gpio_set_value_cansleep(pd->ini_gpio, 1);
 133
 134        return 0;
 135err0:
 136        return r;
 137}
 138
 139static void sharp_ls_power_off(struct omap_dss_device *dssdev)
 140{
 141        struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev);
 142
 143        if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 144                return;
 145
 146        if (gpio_is_valid(pd->ini_gpio))
 147                gpio_set_value_cansleep(pd->ini_gpio, 0);
 148
 149        if (gpio_is_valid(pd->resb_gpio))
 150                gpio_set_value_cansleep(pd->resb_gpio, 0);
 151
 152        /* wait at least 5 vsyncs after disabling the LCD */
 153
 154        msleep(100);
 155
 156        omapdss_dpi_display_disable(dssdev);
 157}
 158
 159static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
 160{
 161        int r;
 162        r = sharp_ls_power_on(dssdev);
 163        dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 164        return r;
 165}
 166
 167static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
 168{
 169        sharp_ls_power_off(dssdev);
 170        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 171}
 172
 173static struct omap_dss_driver sharp_ls_driver = {
 174        .probe          = sharp_ls_panel_probe,
 175        .remove         = __exit_p(sharp_ls_panel_remove),
 176
 177        .enable         = sharp_ls_panel_enable,
 178        .disable        = sharp_ls_panel_disable,
 179
 180        .driver         = {
 181                .name   = "sharp_ls_panel",
 182                .owner  = THIS_MODULE,
 183        },
 184};
 185
 186static int __init sharp_ls_panel_drv_init(void)
 187{
 188        return omap_dss_register_driver(&sharp_ls_driver);
 189}
 190
 191static void __exit sharp_ls_panel_drv_exit(void)
 192{
 193        omap_dss_unregister_driver(&sharp_ls_driver);
 194}
 195
 196module_init(sharp_ls_panel_drv_init);
 197module_exit(sharp_ls_panel_drv_exit);
 198MODULE_LICENSE("GPL");
 199