root/drivers/video/backlight/tosa_lcd.c

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

DEFINITIONS

This source file includes following definitions.
  1. tosa_tg_send
  2. tosa_bl_enable
  3. tosa_lcd_tg_init
  4. tosa_lcd_tg_on
  5. tosa_lcd_tg_off
  6. tosa_lcd_set_power
  7. tosa_lcd_get_power
  8. tosa_lcd_set_mode
  9. tosa_lcd_probe
  10. tosa_lcd_remove
  11. tosa_lcd_suspend
  12. tosa_lcd_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  LCD / Backlight control code for Sharp SL-6000x (tosa)
   4  *
   5  *  Copyright (c) 2005          Dirk Opfer
   6  *  Copyright (c) 2007,2008     Dmitry Baryshkov
   7  */
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/module.h>
  11 #include <linux/device.h>
  12 #include <linux/spi/spi.h>
  13 #include <linux/i2c.h>
  14 #include <linux/slab.h>
  15 #include <linux/gpio.h>
  16 #include <linux/delay.h>
  17 #include <linux/lcd.h>
  18 #include <linux/fb.h>
  19 
  20 #include <asm/mach/sharpsl_param.h>
  21 
  22 #include <mach/tosa.h>
  23 
  24 #define POWER_IS_ON(pwr)        ((pwr) <= FB_BLANK_NORMAL)
  25 
  26 #define TG_REG0_VQV     0x0001
  27 #define TG_REG0_COLOR   0x0002
  28 #define TG_REG0_UD      0x0004
  29 #define TG_REG0_LR      0x0008
  30 
  31 #define DAC_BASE        0x4e
  32 
  33 struct tosa_lcd_data {
  34         struct spi_device *spi;
  35         struct lcd_device *lcd;
  36         struct i2c_client *i2c;
  37 
  38         int lcd_power;
  39         bool is_vga;
  40 };
  41 
  42 static int tosa_tg_send(struct spi_device *spi, int adrs, uint8_t data)
  43 {
  44         u8 buf[1];
  45         struct spi_message msg;
  46         struct spi_transfer xfer = {
  47                 .len            = 1,
  48                 .cs_change      = 0,
  49                 .tx_buf         = buf,
  50         };
  51 
  52         buf[0] = ((adrs & 0x07) << 5) | (data & 0x1f);
  53         spi_message_init(&msg);
  54         spi_message_add_tail(&xfer, &msg);
  55 
  56         return spi_sync(spi, &msg);
  57 }
  58 
  59 int tosa_bl_enable(struct spi_device *spi, int enable)
  60 {
  61         /* bl_enable GP04=1 otherwise GP04=0*/
  62         return tosa_tg_send(spi, TG_GPODR2, enable ? 0x01 : 0x00);
  63 }
  64 EXPORT_SYMBOL(tosa_bl_enable);
  65 
  66 static void tosa_lcd_tg_init(struct tosa_lcd_data *data)
  67 {
  68         /* TG on */
  69         gpio_set_value(TOSA_GPIO_TG_ON, 0);
  70 
  71         mdelay(60);
  72 
  73         /* delayed 0clk TCTL signal for VGA */
  74         tosa_tg_send(data->spi, TG_TPOSCTL, 0x00);
  75         /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */
  76         tosa_tg_send(data->spi, TG_GPOSR, 0x02);
  77 }
  78 
  79 static void tosa_lcd_tg_on(struct tosa_lcd_data *data)
  80 {
  81         struct spi_device *spi = data->spi;
  82         int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
  83 
  84         if (data->is_vga)
  85                 value |= TG_REG0_VQV;
  86 
  87         tosa_tg_send(spi, TG_PNLCTL, value);
  88 
  89         /* TG LCD pannel power up */
  90         tosa_tg_send(spi, TG_PINICTL, 0x4);
  91         mdelay(50);
  92 
  93         /* TG LCD GVSS */
  94         tosa_tg_send(spi, TG_PINICTL, 0x0);
  95 
  96         if (!data->i2c) {
  97                 /*
  98                  * after the pannel is powered up the first time,
  99                  * we can access the i2c bus so probe for the DAC
 100                  */
 101                 struct i2c_adapter *adap = i2c_get_adapter(0);
 102                 struct i2c_board_info info = {
 103                         .type   = "tosa-bl",
 104                         .addr   = DAC_BASE,
 105                         .platform_data = data->spi,
 106                 };
 107                 data->i2c = i2c_new_device(adap, &info);
 108         }
 109 }
 110 
 111 static void tosa_lcd_tg_off(struct tosa_lcd_data *data)
 112 {
 113         struct spi_device *spi = data->spi;
 114 
 115         /* TG LCD VHSA off */
 116         tosa_tg_send(spi, TG_PINICTL, 0x4);
 117         mdelay(50);
 118 
 119         /* TG LCD signal off */
 120         tosa_tg_send(spi, TG_PINICTL, 0x6);
 121         mdelay(50);
 122 
 123         /* TG Off */
 124         gpio_set_value(TOSA_GPIO_TG_ON, 1);
 125         mdelay(100);
 126 }
 127 
 128 int tosa_lcd_set_power(struct lcd_device *lcd, int power)
 129 {
 130         struct tosa_lcd_data *data = lcd_get_data(lcd);
 131 
 132         if (POWER_IS_ON(power) && !POWER_IS_ON(data->lcd_power))
 133                 tosa_lcd_tg_on(data);
 134 
 135         if (!POWER_IS_ON(power) && POWER_IS_ON(data->lcd_power))
 136                 tosa_lcd_tg_off(data);
 137 
 138         data->lcd_power = power;
 139         return 0;
 140 }
 141 
 142 static int tosa_lcd_get_power(struct lcd_device *lcd)
 143 {
 144         struct tosa_lcd_data *data = lcd_get_data(lcd);
 145 
 146         return data->lcd_power;
 147 }
 148 
 149 static int tosa_lcd_set_mode(struct lcd_device *lcd, struct fb_videomode *mode)
 150 {
 151         struct tosa_lcd_data *data = lcd_get_data(lcd);
 152 
 153         if (mode->xres == 320 || mode->yres == 320)
 154                 data->is_vga = false;
 155         else
 156                 data->is_vga = true;
 157 
 158         if (POWER_IS_ON(data->lcd_power))
 159                 tosa_lcd_tg_on(data);
 160 
 161         return 0;
 162 }
 163 
 164 static struct lcd_ops tosa_lcd_ops = {
 165         .set_power = tosa_lcd_set_power,
 166         .get_power = tosa_lcd_get_power,
 167         .set_mode = tosa_lcd_set_mode,
 168 };
 169 
 170 static int tosa_lcd_probe(struct spi_device *spi)
 171 {
 172         int ret;
 173         struct tosa_lcd_data *data;
 174 
 175         data = devm_kzalloc(&spi->dev, sizeof(struct tosa_lcd_data),
 176                                 GFP_KERNEL);
 177         if (!data)
 178                 return -ENOMEM;
 179 
 180         data->is_vga = true; /* default to VGA mode */
 181 
 182         /*
 183          * bits_per_word cannot be configured in platform data
 184          */
 185         spi->bits_per_word = 8;
 186 
 187         ret = spi_setup(spi);
 188         if (ret < 0)
 189                 return ret;
 190 
 191         data->spi = spi;
 192         spi_set_drvdata(spi, data);
 193 
 194         ret = devm_gpio_request_one(&spi->dev, TOSA_GPIO_TG_ON,
 195                                 GPIOF_OUT_INIT_LOW, "tg #pwr");
 196         if (ret < 0)
 197                 return ret;
 198 
 199         mdelay(60);
 200 
 201         tosa_lcd_tg_init(data);
 202 
 203         tosa_lcd_tg_on(data);
 204 
 205         data->lcd = devm_lcd_device_register(&spi->dev, "tosa-lcd", &spi->dev,
 206                                         data, &tosa_lcd_ops);
 207 
 208         if (IS_ERR(data->lcd)) {
 209                 ret = PTR_ERR(data->lcd);
 210                 data->lcd = NULL;
 211                 goto err_register;
 212         }
 213 
 214         return 0;
 215 
 216 err_register:
 217         tosa_lcd_tg_off(data);
 218         return ret;
 219 }
 220 
 221 static int tosa_lcd_remove(struct spi_device *spi)
 222 {
 223         struct tosa_lcd_data *data = spi_get_drvdata(spi);
 224 
 225         i2c_unregister_device(data->i2c);
 226 
 227         tosa_lcd_tg_off(data);
 228 
 229         return 0;
 230 }
 231 
 232 #ifdef CONFIG_PM_SLEEP
 233 static int tosa_lcd_suspend(struct device *dev)
 234 {
 235         struct tosa_lcd_data *data = dev_get_drvdata(dev);
 236 
 237         tosa_lcd_tg_off(data);
 238 
 239         return 0;
 240 }
 241 
 242 static int tosa_lcd_resume(struct device *dev)
 243 {
 244         struct tosa_lcd_data *data = dev_get_drvdata(dev);
 245 
 246         tosa_lcd_tg_init(data);
 247         if (POWER_IS_ON(data->lcd_power))
 248                 tosa_lcd_tg_on(data);
 249         else
 250                 tosa_lcd_tg_off(data);
 251 
 252         return 0;
 253 }
 254 #endif
 255 
 256 static SIMPLE_DEV_PM_OPS(tosa_lcd_pm_ops, tosa_lcd_suspend, tosa_lcd_resume);
 257 
 258 static struct spi_driver tosa_lcd_driver = {
 259         .driver = {
 260                 .name           = "tosa-lcd",
 261                 .pm             = &tosa_lcd_pm_ops,
 262         },
 263         .probe          = tosa_lcd_probe,
 264         .remove         = tosa_lcd_remove,
 265 };
 266 
 267 module_spi_driver(tosa_lcd_driver);
 268 
 269 MODULE_AUTHOR("Dmitry Baryshkov");
 270 MODULE_LICENSE("GPL v2");
 271 MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA");
 272 MODULE_ALIAS("spi:tosa-lcd");

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