linux/drivers/video/omap/lcd_ams_delta.c
<<
>>
Prefs
   1/*
   2 * Based on drivers/video/omap/lcd_inn1510.c
   3 *
   4 * LCD panel support for the Amstrad E3 (Delta) videophone.
   5 *
   6 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms of the GNU General Public License as published by the
  10 * Free Software Foundation; either version 2 of the License, or (at your
  11 * option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful, but
  14 * WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16 * General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License along
  19 * with this program; if not, write to the Free Software Foundation, Inc.,
  20 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21 */
  22
  23#include <linux/module.h>
  24#include <linux/platform_device.h>
  25#include <linux/io.h>
  26#include <linux/delay.h>
  27#include <linux/lcd.h>
  28
  29#include <plat/board-ams-delta.h>
  30#include <mach/hardware.h>
  31
  32#include "omapfb.h"
  33
  34#define AMS_DELTA_DEFAULT_CONTRAST      112
  35
  36#define AMS_DELTA_MAX_CONTRAST          0x00FF
  37#define AMS_DELTA_LCD_POWER             0x0100
  38
  39
  40/* LCD class device section */
  41
  42static int ams_delta_lcd;
  43
  44static int ams_delta_lcd_set_power(struct lcd_device *dev, int power)
  45{
  46        if (power == FB_BLANK_UNBLANK) {
  47                if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) {
  48                        omap_writeb(ams_delta_lcd & AMS_DELTA_MAX_CONTRAST,
  49                                        OMAP_PWL_ENABLE);
  50                        omap_writeb(1, OMAP_PWL_CLK_ENABLE);
  51                        ams_delta_lcd |= AMS_DELTA_LCD_POWER;
  52                }
  53        } else {
  54                if (ams_delta_lcd & AMS_DELTA_LCD_POWER) {
  55                        omap_writeb(0, OMAP_PWL_ENABLE);
  56                        omap_writeb(0, OMAP_PWL_CLK_ENABLE);
  57                        ams_delta_lcd &= ~AMS_DELTA_LCD_POWER;
  58                }
  59        }
  60        return 0;
  61}
  62
  63static int ams_delta_lcd_set_contrast(struct lcd_device *dev, int value)
  64{
  65        if ((value >= 0) && (value <= AMS_DELTA_MAX_CONTRAST)) {
  66                omap_writeb(value, OMAP_PWL_ENABLE);
  67                ams_delta_lcd &= ~AMS_DELTA_MAX_CONTRAST;
  68                ams_delta_lcd |= value;
  69        }
  70        return 0;
  71}
  72
  73#ifdef CONFIG_LCD_CLASS_DEVICE
  74static int ams_delta_lcd_get_power(struct lcd_device *dev)
  75{
  76        if (ams_delta_lcd & AMS_DELTA_LCD_POWER)
  77                return FB_BLANK_UNBLANK;
  78        else
  79                return FB_BLANK_POWERDOWN;
  80}
  81
  82static int ams_delta_lcd_get_contrast(struct lcd_device *dev)
  83{
  84        if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER))
  85                return 0;
  86
  87        return ams_delta_lcd & AMS_DELTA_MAX_CONTRAST;
  88}
  89
  90static struct lcd_ops ams_delta_lcd_ops = {
  91        .get_power = ams_delta_lcd_get_power,
  92        .set_power = ams_delta_lcd_set_power,
  93        .get_contrast = ams_delta_lcd_get_contrast,
  94        .set_contrast = ams_delta_lcd_set_contrast,
  95};
  96#endif
  97
  98
  99/* omapfb panel section */
 100
 101static int ams_delta_panel_init(struct lcd_panel *panel,
 102                struct omapfb_device *fbdev)
 103{
 104        return 0;
 105}
 106
 107static void ams_delta_panel_cleanup(struct lcd_panel *panel)
 108{
 109}
 110
 111static int ams_delta_panel_enable(struct lcd_panel *panel)
 112{
 113        ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP,
 114                        AMS_DELTA_LATCH2_LCD_NDISP);
 115        ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN,
 116                        AMS_DELTA_LATCH2_LCD_VBLEN);
 117        return 0;
 118}
 119
 120static void ams_delta_panel_disable(struct lcd_panel *panel)
 121{
 122        ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, 0);
 123        ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP, 0);
 124}
 125
 126static unsigned long ams_delta_panel_get_caps(struct lcd_panel *panel)
 127{
 128        return 0;
 129}
 130
 131static struct lcd_panel ams_delta_panel = {
 132        .name           = "ams-delta",
 133        .config         = 0,
 134
 135        .bpp            = 12,
 136        .data_lines     = 16,
 137        .x_res          = 480,
 138        .y_res          = 320,
 139        .pixel_clock    = 4687,
 140        .hsw            = 3,
 141        .hfp            = 1,
 142        .hbp            = 1,
 143        .vsw            = 1,
 144        .vfp            = 0,
 145        .vbp            = 0,
 146        .pcd            = 0,
 147        .acb            = 37,
 148
 149        .init           = ams_delta_panel_init,
 150        .cleanup        = ams_delta_panel_cleanup,
 151        .enable         = ams_delta_panel_enable,
 152        .disable        = ams_delta_panel_disable,
 153        .get_caps       = ams_delta_panel_get_caps,
 154};
 155
 156
 157/* platform driver section */
 158
 159static int ams_delta_panel_probe(struct platform_device *pdev)
 160{
 161        struct lcd_device *lcd_device = NULL;
 162#ifdef CONFIG_LCD_CLASS_DEVICE
 163        int ret;
 164
 165        lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL,
 166                                                &ams_delta_lcd_ops);
 167
 168        if (IS_ERR(lcd_device)) {
 169                ret = PTR_ERR(lcd_device);
 170                dev_err(&pdev->dev, "failed to register device\n");
 171                return ret;
 172        }
 173
 174        platform_set_drvdata(pdev, lcd_device);
 175        lcd_device->props.max_contrast = AMS_DELTA_MAX_CONTRAST;
 176#endif
 177
 178        ams_delta_lcd_set_contrast(lcd_device, AMS_DELTA_DEFAULT_CONTRAST);
 179        ams_delta_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
 180
 181        omapfb_register_panel(&ams_delta_panel);
 182        return 0;
 183}
 184
 185static int ams_delta_panel_remove(struct platform_device *pdev)
 186{
 187        return 0;
 188}
 189
 190static int ams_delta_panel_suspend(struct platform_device *pdev,
 191                pm_message_t mesg)
 192{
 193        return 0;
 194}
 195
 196static int ams_delta_panel_resume(struct platform_device *pdev)
 197{
 198        return 0;
 199}
 200
 201struct platform_driver ams_delta_panel_driver = {
 202        .probe          = ams_delta_panel_probe,
 203        .remove         = ams_delta_panel_remove,
 204        .suspend        = ams_delta_panel_suspend,
 205        .resume         = ams_delta_panel_resume,
 206        .driver         = {
 207                .name   = "lcd_ams_delta",
 208                .owner  = THIS_MODULE,
 209        },
 210};
 211
 212static int __init ams_delta_panel_drv_init(void)
 213{
 214        return platform_driver_register(&ams_delta_panel_driver);
 215}
 216
 217static void __exit ams_delta_panel_drv_cleanup(void)
 218{
 219        platform_driver_unregister(&ams_delta_panel_driver);
 220}
 221
 222module_init(ams_delta_panel_drv_init);
 223module_exit(ams_delta_panel_drv_cleanup);
 224