root/drivers/video/backlight/locomolcd.c

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

DEFINITIONS

This source file includes following definitions.
  1. locomolcd_on
  2. locomolcd_off
  3. locomolcd_power
  4. locomolcd_set_intensity
  5. locomolcd_get_intensity
  6. locomolcd_suspend
  7. locomolcd_resume
  8. locomolcd_probe
  9. locomolcd_remove
  10. locomolcd_init
  11. locomolcd_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Backlight control code for Sharp Zaurus SL-5500
   4  *
   5  * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
   6  * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
   7  *
   8  * This driver assumes single CPU. That's okay, because collie is
   9  * slightly old hardware, and no one is going to retrofit second CPU to
  10  * old PDA.
  11  */
  12 
  13 /* LCD power functions */
  14 #include <linux/module.h>
  15 #include <linux/init.h>
  16 #include <linux/delay.h>
  17 #include <linux/device.h>
  18 #include <linux/interrupt.h>
  19 #include <linux/fb.h>
  20 #include <linux/backlight.h>
  21 
  22 #include <asm/hardware/locomo.h>
  23 #include <asm/irq.h>
  24 #include <asm/mach/sharpsl_param.h>
  25 #include <asm/mach-types.h>
  26 
  27 #include "../../../arch/arm/mach-sa1100/generic.h"
  28 
  29 static struct backlight_device *locomolcd_bl_device;
  30 static struct locomo_dev *locomolcd_dev;
  31 static unsigned long locomolcd_flags;
  32 #define LOCOMOLCD_SUSPENDED     0x01
  33 
  34 static void locomolcd_on(int comadj)
  35 {
  36         locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
  37         locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 1);
  38         mdelay(2);
  39 
  40         locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
  41         locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 1);
  42         mdelay(2);
  43 
  44         locomo_m62332_senddata(locomolcd_dev, comadj, 0);
  45         mdelay(5);
  46 
  47         locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
  48         locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 1);
  49         mdelay(10);
  50 
  51         /* TFTCRST | CPSOUT=0 | CPSEN */
  52         locomo_writel(0x01, locomolcd_dev->mapbase + LOCOMO_TC);
  53 
  54         /* Set CPSD */
  55         locomo_writel(6, locomolcd_dev->mapbase + LOCOMO_CPSD);
  56 
  57         /* TFTCRST | CPSOUT=0 | CPSEN */
  58         locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
  59         mdelay(10);
  60 
  61         locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
  62         locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 1);
  63 }
  64 
  65 static void locomolcd_off(int comadj)
  66 {
  67         /* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
  68         locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
  69         mdelay(1);
  70 
  71         locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
  72         mdelay(110);
  73 
  74         locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
  75         mdelay(700);
  76 
  77         /* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
  78         locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
  79         locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
  80         locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
  81 }
  82 
  83 void locomolcd_power(int on)
  84 {
  85         int comadj = sharpsl_param.comadj;
  86         unsigned long flags;
  87 
  88         local_irq_save(flags);
  89 
  90         if (!locomolcd_dev) {
  91                 local_irq_restore(flags);
  92                 return;
  93         }
  94 
  95         /* read comadj */
  96         if (comadj == -1 && machine_is_collie())
  97                 comadj = 128;
  98         if (comadj == -1 && machine_is_poodle())
  99                 comadj = 118;
 100 
 101         if (on)
 102                 locomolcd_on(comadj);
 103         else
 104                 locomolcd_off(comadj);
 105 
 106         local_irq_restore(flags);
 107 }
 108 EXPORT_SYMBOL(locomolcd_power);
 109 
 110 static int current_intensity;
 111 
 112 static int locomolcd_set_intensity(struct backlight_device *bd)
 113 {
 114         int intensity = bd->props.brightness;
 115 
 116         if (bd->props.power != FB_BLANK_UNBLANK)
 117                 intensity = 0;
 118         if (bd->props.fb_blank != FB_BLANK_UNBLANK)
 119                 intensity = 0;
 120         if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
 121                 intensity = 0;
 122 
 123         switch (intensity) {
 124         /*
 125          * AC and non-AC are handled differently,
 126          * but produce same results in sharp code?
 127          */
 128         case 0:
 129                 locomo_frontlight_set(locomolcd_dev, 0, 0, 161);
 130                 break;
 131         case 1:
 132                 locomo_frontlight_set(locomolcd_dev, 117, 0, 161);
 133                 break;
 134         case 2:
 135                 locomo_frontlight_set(locomolcd_dev, 163, 0, 148);
 136                 break;
 137         case 3:
 138                 locomo_frontlight_set(locomolcd_dev, 194, 0, 161);
 139                 break;
 140         case 4:
 141                 locomo_frontlight_set(locomolcd_dev, 194, 1, 161);
 142                 break;
 143         default:
 144                 return -ENODEV;
 145         }
 146         current_intensity = intensity;
 147         return 0;
 148 }
 149 
 150 static int locomolcd_get_intensity(struct backlight_device *bd)
 151 {
 152         return current_intensity;
 153 }
 154 
 155 static const struct backlight_ops locomobl_data = {
 156         .get_brightness = locomolcd_get_intensity,
 157         .update_status  = locomolcd_set_intensity,
 158 };
 159 
 160 #ifdef CONFIG_PM_SLEEP
 161 static int locomolcd_suspend(struct device *dev)
 162 {
 163         locomolcd_flags |= LOCOMOLCD_SUSPENDED;
 164         locomolcd_set_intensity(locomolcd_bl_device);
 165         return 0;
 166 }
 167 
 168 static int locomolcd_resume(struct device *dev)
 169 {
 170         locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
 171         locomolcd_set_intensity(locomolcd_bl_device);
 172         return 0;
 173 }
 174 #endif
 175 
 176 static SIMPLE_DEV_PM_OPS(locomolcd_pm_ops, locomolcd_suspend, locomolcd_resume);
 177 
 178 static int locomolcd_probe(struct locomo_dev *ldev)
 179 {
 180         struct backlight_properties props;
 181         unsigned long flags;
 182 
 183         local_irq_save(flags);
 184         locomolcd_dev = ldev;
 185 
 186         locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
 187 
 188         /*
 189          * the poodle_lcd_power function is called for the first time
 190          * from fs_initcall, which is before locomo is activated.
 191          * We need to recall poodle_lcd_power here
 192          */
 193         if (machine_is_poodle())
 194                 locomolcd_power(1);
 195 
 196         local_irq_restore(flags);
 197 
 198         memset(&props, 0, sizeof(struct backlight_properties));
 199         props.type = BACKLIGHT_RAW;
 200         props.max_brightness = 4;
 201         locomolcd_bl_device = backlight_device_register("locomo-bl",
 202                                                         &ldev->dev, NULL,
 203                                                         &locomobl_data, &props);
 204 
 205         if (IS_ERR(locomolcd_bl_device))
 206                 return PTR_ERR(locomolcd_bl_device);
 207 
 208         /* Set up frontlight so that screen is readable */
 209         locomolcd_bl_device->props.brightness = 2;
 210         locomolcd_set_intensity(locomolcd_bl_device);
 211 
 212         return 0;
 213 }
 214 
 215 static int locomolcd_remove(struct locomo_dev *dev)
 216 {
 217         unsigned long flags;
 218 
 219         locomolcd_bl_device->props.brightness = 0;
 220         locomolcd_bl_device->props.power = 0;
 221         locomolcd_set_intensity(locomolcd_bl_device);
 222 
 223         backlight_device_unregister(locomolcd_bl_device);
 224         local_irq_save(flags);
 225         locomolcd_dev = NULL;
 226         local_irq_restore(flags);
 227         return 0;
 228 }
 229 
 230 static struct locomo_driver poodle_lcd_driver = {
 231         .drv = {
 232                 .name   = "locomo-backlight",
 233                 .pm     = &locomolcd_pm_ops,
 234         },
 235         .devid  = LOCOMO_DEVID_BACKLIGHT,
 236         .probe  = locomolcd_probe,
 237         .remove = locomolcd_remove,
 238 };
 239 
 240 static int __init locomolcd_init(void)
 241 {
 242         return locomo_driver_register(&poodle_lcd_driver);
 243 }
 244 
 245 static void __exit locomolcd_exit(void)
 246 {
 247         locomo_driver_unregister(&poodle_lcd_driver);
 248 }
 249 
 250 module_init(locomolcd_init);
 251 module_exit(locomolcd_exit);
 252 
 253 MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz>");
 254 MODULE_DESCRIPTION("Collie LCD driver");
 255 MODULE_LICENSE("GPL");

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