linux/drivers/video/fbdev/omap/lcd_ams_delta.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Based on drivers/video/omap/lcd_inn1510.c
   4 *
   5 * LCD panel support for the Amstrad E3 (Delta) videophone.
   6 *
   7 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/platform_device.h>
  12#include <linux/io.h>
  13#include <linux/delay.h>
  14#include <linux/gpio/consumer.h>
  15#include <linux/lcd.h>
  16
  17#include <mach/hardware.h>
  18
  19#include "omapfb.h"
  20
  21#define AMS_DELTA_DEFAULT_CONTRAST      112
  22
  23#define AMS_DELTA_MAX_CONTRAST          0x00FF
  24#define AMS_DELTA_LCD_POWER             0x0100
  25
  26
  27/* LCD class device section */
  28
  29static int ams_delta_lcd;
  30static struct gpio_desc *gpiod_vblen;
  31static struct gpio_desc *gpiod_ndisp;
  32
  33static int ams_delta_lcd_set_power(struct lcd_device *dev, int power)
  34{
  35        if (power == FB_BLANK_UNBLANK) {
  36                if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) {
  37                        omap_writeb(ams_delta_lcd & AMS_DELTA_MAX_CONTRAST,
  38                                        OMAP_PWL_ENABLE);
  39                        omap_writeb(1, OMAP_PWL_CLK_ENABLE);
  40                        ams_delta_lcd |= AMS_DELTA_LCD_POWER;
  41                }
  42        } else {
  43                if (ams_delta_lcd & AMS_DELTA_LCD_POWER) {
  44                        omap_writeb(0, OMAP_PWL_ENABLE);
  45                        omap_writeb(0, OMAP_PWL_CLK_ENABLE);
  46                        ams_delta_lcd &= ~AMS_DELTA_LCD_POWER;
  47                }
  48        }
  49        return 0;
  50}
  51
  52static int ams_delta_lcd_set_contrast(struct lcd_device *dev, int value)
  53{
  54        if ((value >= 0) && (value <= AMS_DELTA_MAX_CONTRAST)) {
  55                omap_writeb(value, OMAP_PWL_ENABLE);
  56                ams_delta_lcd &= ~AMS_DELTA_MAX_CONTRAST;
  57                ams_delta_lcd |= value;
  58        }
  59        return 0;
  60}
  61
  62#ifdef CONFIG_LCD_CLASS_DEVICE
  63static int ams_delta_lcd_get_power(struct lcd_device *dev)
  64{
  65        if (ams_delta_lcd & AMS_DELTA_LCD_POWER)
  66                return FB_BLANK_UNBLANK;
  67        else
  68                return FB_BLANK_POWERDOWN;
  69}
  70
  71static int ams_delta_lcd_get_contrast(struct lcd_device *dev)
  72{
  73        if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER))
  74                return 0;
  75
  76        return ams_delta_lcd & AMS_DELTA_MAX_CONTRAST;
  77}
  78
  79static struct lcd_ops ams_delta_lcd_ops = {
  80        .get_power = ams_delta_lcd_get_power,
  81        .set_power = ams_delta_lcd_set_power,
  82        .get_contrast = ams_delta_lcd_get_contrast,
  83        .set_contrast = ams_delta_lcd_set_contrast,
  84};
  85#endif
  86
  87
  88/* omapfb panel section */
  89
  90static int ams_delta_panel_enable(struct lcd_panel *panel)
  91{
  92        gpiod_set_value(gpiod_ndisp, 1);
  93        gpiod_set_value(gpiod_vblen, 1);
  94        return 0;
  95}
  96
  97static void ams_delta_panel_disable(struct lcd_panel *panel)
  98{
  99        gpiod_set_value(gpiod_vblen, 0);
 100        gpiod_set_value(gpiod_ndisp, 0);
 101}
 102
 103static struct lcd_panel ams_delta_panel = {
 104        .name           = "ams-delta",
 105        .config         = 0,
 106
 107        .bpp            = 12,
 108        .data_lines     = 16,
 109        .x_res          = 480,
 110        .y_res          = 320,
 111        .pixel_clock    = 4687,
 112        .hsw            = 3,
 113        .hfp            = 1,
 114        .hbp            = 1,
 115        .vsw            = 1,
 116        .vfp            = 0,
 117        .vbp            = 0,
 118        .pcd            = 0,
 119        .acb            = 37,
 120
 121        .enable         = ams_delta_panel_enable,
 122        .disable        = ams_delta_panel_disable,
 123};
 124
 125
 126/* platform driver section */
 127
 128static int ams_delta_panel_probe(struct platform_device *pdev)
 129{
 130        struct lcd_device *lcd_device = NULL;
 131        int ret;
 132
 133        gpiod_vblen = devm_gpiod_get(&pdev->dev, "vblen", GPIOD_OUT_LOW);
 134        if (IS_ERR(gpiod_vblen)) {
 135                ret = PTR_ERR(gpiod_vblen);
 136                dev_err(&pdev->dev, "VBLEN GPIO request failed (%d)\n", ret);
 137                return ret;
 138        }
 139
 140        gpiod_ndisp = devm_gpiod_get(&pdev->dev, "ndisp", GPIOD_OUT_LOW);
 141        if (IS_ERR(gpiod_ndisp)) {
 142                ret = PTR_ERR(gpiod_ndisp);
 143                dev_err(&pdev->dev, "NDISP GPIO request failed (%d)\n", ret);
 144                return ret;
 145        }
 146
 147#ifdef CONFIG_LCD_CLASS_DEVICE
 148        lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL,
 149                                                &ams_delta_lcd_ops);
 150
 151        if (IS_ERR(lcd_device)) {
 152                ret = PTR_ERR(lcd_device);
 153                dev_err(&pdev->dev, "failed to register device\n");
 154                return ret;
 155        }
 156
 157        platform_set_drvdata(pdev, lcd_device);
 158        lcd_device->props.max_contrast = AMS_DELTA_MAX_CONTRAST;
 159#endif
 160
 161        ams_delta_lcd_set_contrast(lcd_device, AMS_DELTA_DEFAULT_CONTRAST);
 162        ams_delta_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
 163
 164        omapfb_register_panel(&ams_delta_panel);
 165        return 0;
 166}
 167
 168static struct platform_driver ams_delta_panel_driver = {
 169        .probe          = ams_delta_panel_probe,
 170        .driver         = {
 171                .name   = "lcd_ams_delta",
 172        },
 173};
 174
 175module_platform_driver(ams_delta_panel_driver);
 176
 177MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
 178MODULE_DESCRIPTION("LCD panel support for the Amstrad E3 (Delta) videophone");
 179MODULE_LICENSE("GPL");
 180