root/drivers/video/backlight/l4f00242t03.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. l4f00242t03_reset
  2. l4f00242t03_lcd_init
  3. l4f00242t03_lcd_powerdown
  4. l4f00242t03_lcd_power_get
  5. l4f00242t03_lcd_power_set
  6. l4f00242t03_probe
  7. l4f00242t03_remove
  8. l4f00242t03_shutdown

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * l4f00242t03.c -- support for Epson L4F00242T03 LCD
   4  *
   5  * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
   6  *
   7  * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
   8  *      Inspired by Marek Vasut work in l4f00242t03.c
   9  */
  10 
  11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12 
  13 #include <linux/device.h>
  14 #include <linux/kernel.h>
  15 #include <linux/delay.h>
  16 #include <linux/module.h>
  17 #include <linux/gpio.h>
  18 #include <linux/lcd.h>
  19 #include <linux/slab.h>
  20 #include <linux/regulator/consumer.h>
  21 
  22 #include <linux/spi/spi.h>
  23 #include <linux/spi/l4f00242t03.h>
  24 
  25 struct l4f00242t03_priv {
  26         struct spi_device       *spi;
  27         struct lcd_device       *ld;
  28         int lcd_state;
  29         struct regulator *io_reg;
  30         struct regulator *core_reg;
  31 };
  32 
  33 static void l4f00242t03_reset(unsigned int gpio)
  34 {
  35         pr_debug("l4f00242t03_reset.\n");
  36         gpio_set_value(gpio, 1);
  37         mdelay(100);
  38         gpio_set_value(gpio, 0);
  39         mdelay(10);     /* tRES >= 100us */
  40         gpio_set_value(gpio, 1);
  41         mdelay(20);
  42 }
  43 
  44 #define param(x) ((x) | 0x100)
  45 
  46 static void l4f00242t03_lcd_init(struct spi_device *spi)
  47 {
  48         struct l4f00242t03_pdata *pdata = dev_get_platdata(&spi->dev);
  49         struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
  50         const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };
  51         int ret;
  52 
  53         dev_dbg(&spi->dev, "initializing LCD\n");
  54 
  55         ret = regulator_set_voltage(priv->io_reg, 1800000, 1800000);
  56         if (ret) {
  57                 dev_err(&spi->dev, "failed to set the IO regulator voltage.\n");
  58                 return;
  59         }
  60         ret = regulator_enable(priv->io_reg);
  61         if (ret) {
  62                 dev_err(&spi->dev, "failed to enable the IO regulator.\n");
  63                 return;
  64         }
  65 
  66         ret = regulator_set_voltage(priv->core_reg, 2800000, 2800000);
  67         if (ret) {
  68                 dev_err(&spi->dev, "failed to set the core regulator voltage.\n");
  69                 regulator_disable(priv->io_reg);
  70                 return;
  71         }
  72         ret = regulator_enable(priv->core_reg);
  73         if (ret) {
  74                 dev_err(&spi->dev, "failed to enable the core regulator.\n");
  75                 regulator_disable(priv->io_reg);
  76                 return;
  77         }
  78 
  79         l4f00242t03_reset(pdata->reset_gpio);
  80 
  81         gpio_set_value(pdata->data_enable_gpio, 1);
  82         msleep(60);
  83         spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16));
  84 }
  85 
  86 static void l4f00242t03_lcd_powerdown(struct spi_device *spi)
  87 {
  88         struct l4f00242t03_pdata *pdata = dev_get_platdata(&spi->dev);
  89         struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
  90 
  91         dev_dbg(&spi->dev, "Powering down LCD\n");
  92 
  93         gpio_set_value(pdata->data_enable_gpio, 0);
  94 
  95         regulator_disable(priv->io_reg);
  96         regulator_disable(priv->core_reg);
  97 }
  98 
  99 static int l4f00242t03_lcd_power_get(struct lcd_device *ld)
 100 {
 101         struct l4f00242t03_priv *priv = lcd_get_data(ld);
 102 
 103         return priv->lcd_state;
 104 }
 105 
 106 static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power)
 107 {
 108         struct l4f00242t03_priv *priv = lcd_get_data(ld);
 109         struct spi_device *spi = priv->spi;
 110 
 111         const u16 slpout = 0x11;
 112         const u16 dison = 0x29;
 113 
 114         const u16 slpin = 0x10;
 115         const u16 disoff = 0x28;
 116 
 117         if (power <= FB_BLANK_NORMAL) {
 118                 if (priv->lcd_state <= FB_BLANK_NORMAL) {
 119                         /* Do nothing, the LCD is running */
 120                 } else if (priv->lcd_state < FB_BLANK_POWERDOWN) {
 121                         dev_dbg(&spi->dev, "Resuming LCD\n");
 122 
 123                         spi_write(spi, (const u8 *)&slpout, sizeof(u16));
 124                         msleep(60);
 125                         spi_write(spi, (const u8 *)&dison, sizeof(u16));
 126                 } else {
 127                         /* priv->lcd_state == FB_BLANK_POWERDOWN */
 128                         l4f00242t03_lcd_init(spi);
 129                         priv->lcd_state = FB_BLANK_VSYNC_SUSPEND;
 130                         l4f00242t03_lcd_power_set(priv->ld, power);
 131                 }
 132         } else if (power < FB_BLANK_POWERDOWN) {
 133                 if (priv->lcd_state <= FB_BLANK_NORMAL) {
 134                         /* Send the display in standby */
 135                         dev_dbg(&spi->dev, "Standby the LCD\n");
 136 
 137                         spi_write(spi, (const u8 *)&disoff, sizeof(u16));
 138                         msleep(60);
 139                         spi_write(spi, (const u8 *)&slpin, sizeof(u16));
 140                 } else if (priv->lcd_state < FB_BLANK_POWERDOWN) {
 141                         /* Do nothing, the LCD is already in standby */
 142                 } else {
 143                         /* priv->lcd_state == FB_BLANK_POWERDOWN */
 144                         l4f00242t03_lcd_init(spi);
 145                         priv->lcd_state = FB_BLANK_UNBLANK;
 146                         l4f00242t03_lcd_power_set(ld, power);
 147                 }
 148         } else {
 149                 /* power == FB_BLANK_POWERDOWN */
 150                 if (priv->lcd_state != FB_BLANK_POWERDOWN) {
 151                         /* Clear the screen before shutting down */
 152                         spi_write(spi, (const u8 *)&disoff, sizeof(u16));
 153                         msleep(60);
 154                         l4f00242t03_lcd_powerdown(spi);
 155                 }
 156         }
 157 
 158         priv->lcd_state = power;
 159 
 160         return 0;
 161 }
 162 
 163 static struct lcd_ops l4f_ops = {
 164         .set_power      = l4f00242t03_lcd_power_set,
 165         .get_power      = l4f00242t03_lcd_power_get,
 166 };
 167 
 168 static int l4f00242t03_probe(struct spi_device *spi)
 169 {
 170         struct l4f00242t03_priv *priv;
 171         struct l4f00242t03_pdata *pdata = dev_get_platdata(&spi->dev);
 172         int ret;
 173 
 174         if (pdata == NULL) {
 175                 dev_err(&spi->dev, "Uninitialized platform data.\n");
 176                 return -EINVAL;
 177         }
 178 
 179         priv = devm_kzalloc(&spi->dev, sizeof(struct l4f00242t03_priv),
 180                                 GFP_KERNEL);
 181         if (priv == NULL)
 182                 return -ENOMEM;
 183 
 184         spi_set_drvdata(spi, priv);
 185         spi->bits_per_word = 9;
 186         spi_setup(spi);
 187 
 188         priv->spi = spi;
 189 
 190         ret = devm_gpio_request_one(&spi->dev, pdata->reset_gpio,
 191                         GPIOF_OUT_INIT_HIGH, "lcd l4f00242t03 reset");
 192         if (ret) {
 193                 dev_err(&spi->dev,
 194                         "Unable to get the lcd l4f00242t03 reset gpio.\n");
 195                 return ret;
 196         }
 197 
 198         ret = devm_gpio_request_one(&spi->dev, pdata->data_enable_gpio,
 199                         GPIOF_OUT_INIT_LOW, "lcd l4f00242t03 data enable");
 200         if (ret) {
 201                 dev_err(&spi->dev,
 202                         "Unable to get the lcd l4f00242t03 data en gpio.\n");
 203                 return ret;
 204         }
 205 
 206         priv->io_reg = devm_regulator_get(&spi->dev, "vdd");
 207         if (IS_ERR(priv->io_reg)) {
 208                 dev_err(&spi->dev, "%s: Unable to get the IO regulator\n",
 209                        __func__);
 210                 return PTR_ERR(priv->io_reg);
 211         }
 212 
 213         priv->core_reg = devm_regulator_get(&spi->dev, "vcore");
 214         if (IS_ERR(priv->core_reg)) {
 215                 dev_err(&spi->dev, "%s: Unable to get the core regulator\n",
 216                        __func__);
 217                 return PTR_ERR(priv->core_reg);
 218         }
 219 
 220         priv->ld = devm_lcd_device_register(&spi->dev, "l4f00242t03", &spi->dev,
 221                                         priv, &l4f_ops);
 222         if (IS_ERR(priv->ld))
 223                 return PTR_ERR(priv->ld);
 224 
 225         /* Init the LCD */
 226         l4f00242t03_lcd_init(spi);
 227         priv->lcd_state = FB_BLANK_VSYNC_SUSPEND;
 228         l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_UNBLANK);
 229 
 230         dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n");
 231 
 232         return 0;
 233 }
 234 
 235 static int l4f00242t03_remove(struct spi_device *spi)
 236 {
 237         struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
 238 
 239         l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
 240         return 0;
 241 }
 242 
 243 static void l4f00242t03_shutdown(struct spi_device *spi)
 244 {
 245         struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
 246 
 247         if (priv)
 248                 l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
 249 
 250 }
 251 
 252 static struct spi_driver l4f00242t03_driver = {
 253         .driver = {
 254                 .name   = "l4f00242t03",
 255         },
 256         .probe          = l4f00242t03_probe,
 257         .remove         = l4f00242t03_remove,
 258         .shutdown       = l4f00242t03_shutdown,
 259 };
 260 
 261 module_spi_driver(l4f00242t03_driver);
 262 
 263 MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
 264 MODULE_DESCRIPTION("EPSON L4F00242T03 LCD");
 265 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */