root/drivers/video/backlight/aat2870_bl.c

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

DEFINITIONS

This source file includes following definitions.
  1. aat2870_brightness
  2. aat2870_bl_enable
  3. aat2870_bl_disable
  4. aat2870_bl_update_status
  5. aat2870_bl_check_fb
  6. aat2870_bl_probe
  7. aat2870_bl_remove
  8. aat2870_bl_init
  9. aat2870_bl_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/drivers/video/backlight/aat2870_bl.c
   4  *
   5  * Copyright (c) 2011, NVIDIA Corporation.
   6  * Author: Jin Park <jinyoungp@nvidia.com>
   7  */
   8 
   9 #include <linux/module.h>
  10 #include <linux/kernel.h>
  11 #include <linux/init.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/mutex.h>
  14 #include <linux/delay.h>
  15 #include <linux/fb.h>
  16 #include <linux/backlight.h>
  17 #include <linux/mfd/aat2870.h>
  18 
  19 struct aat2870_bl_driver_data {
  20         struct platform_device *pdev;
  21         struct backlight_device *bd;
  22 
  23         int channels;
  24         int max_current;
  25         int brightness; /* current brightness */
  26 };
  27 
  28 static inline int aat2870_brightness(struct aat2870_bl_driver_data *aat2870_bl,
  29                                      int brightness)
  30 {
  31         struct backlight_device *bd = aat2870_bl->bd;
  32         int val;
  33 
  34         val = brightness * (aat2870_bl->max_current - 1);
  35         val /= bd->props.max_brightness;
  36 
  37         return val;
  38 }
  39 
  40 static inline int aat2870_bl_enable(struct aat2870_bl_driver_data *aat2870_bl)
  41 {
  42         struct aat2870_data *aat2870
  43                         = dev_get_drvdata(aat2870_bl->pdev->dev.parent);
  44 
  45         return aat2870->write(aat2870, AAT2870_BL_CH_EN,
  46                               (u8)aat2870_bl->channels);
  47 }
  48 
  49 static inline int aat2870_bl_disable(struct aat2870_bl_driver_data *aat2870_bl)
  50 {
  51         struct aat2870_data *aat2870
  52                         = dev_get_drvdata(aat2870_bl->pdev->dev.parent);
  53 
  54         return aat2870->write(aat2870, AAT2870_BL_CH_EN, 0x0);
  55 }
  56 
  57 static int aat2870_bl_update_status(struct backlight_device *bd)
  58 {
  59         struct aat2870_bl_driver_data *aat2870_bl = bl_get_data(bd);
  60         struct aat2870_data *aat2870 =
  61                         dev_get_drvdata(aat2870_bl->pdev->dev.parent);
  62         int brightness = bd->props.brightness;
  63         int ret;
  64 
  65         if ((brightness < 0) || (bd->props.max_brightness < brightness)) {
  66                 dev_err(&bd->dev, "invalid brightness, %d\n", brightness);
  67                 return -EINVAL;
  68         }
  69 
  70         dev_dbg(&bd->dev, "brightness=%d, power=%d, state=%d\n",
  71                  bd->props.brightness, bd->props.power, bd->props.state);
  72 
  73         if ((bd->props.power != FB_BLANK_UNBLANK) ||
  74                         (bd->props.state & BL_CORE_FBBLANK) ||
  75                         (bd->props.state & BL_CORE_SUSPENDED))
  76                 brightness = 0;
  77 
  78         ret = aat2870->write(aat2870, AAT2870_BLM,
  79                              (u8)aat2870_brightness(aat2870_bl, brightness));
  80         if (ret < 0)
  81                 return ret;
  82 
  83         if (brightness == 0) {
  84                 ret = aat2870_bl_disable(aat2870_bl);
  85                 if (ret < 0)
  86                         return ret;
  87         } else if (aat2870_bl->brightness == 0) {
  88                 ret = aat2870_bl_enable(aat2870_bl);
  89                 if (ret < 0)
  90                         return ret;
  91         }
  92 
  93         aat2870_bl->brightness = brightness;
  94 
  95         return 0;
  96 }
  97 
  98 static int aat2870_bl_check_fb(struct backlight_device *bd, struct fb_info *fi)
  99 {
 100         return 1;
 101 }
 102 
 103 static const struct backlight_ops aat2870_bl_ops = {
 104         .options = BL_CORE_SUSPENDRESUME,
 105         .update_status = aat2870_bl_update_status,
 106         .check_fb = aat2870_bl_check_fb,
 107 };
 108 
 109 static int aat2870_bl_probe(struct platform_device *pdev)
 110 {
 111         struct aat2870_bl_platform_data *pdata = dev_get_platdata(&pdev->dev);
 112         struct aat2870_bl_driver_data *aat2870_bl;
 113         struct backlight_device *bd;
 114         struct backlight_properties props;
 115         int ret = 0;
 116 
 117         if (!pdata) {
 118                 dev_err(&pdev->dev, "No platform data\n");
 119                 ret = -ENXIO;
 120                 goto out;
 121         }
 122 
 123         if (pdev->id != AAT2870_ID_BL) {
 124                 dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id);
 125                 ret = -EINVAL;
 126                 goto out;
 127         }
 128 
 129         aat2870_bl = devm_kzalloc(&pdev->dev,
 130                                   sizeof(struct aat2870_bl_driver_data),
 131                                   GFP_KERNEL);
 132         if (!aat2870_bl) {
 133                 ret = -ENOMEM;
 134                 goto out;
 135         }
 136 
 137         memset(&props, 0, sizeof(struct backlight_properties));
 138 
 139         props.type = BACKLIGHT_RAW;
 140         bd = devm_backlight_device_register(&pdev->dev, "aat2870-backlight",
 141                                         &pdev->dev, aat2870_bl, &aat2870_bl_ops,
 142                                         &props);
 143         if (IS_ERR(bd)) {
 144                 dev_err(&pdev->dev,
 145                         "Failed allocate memory for backlight device\n");
 146                 ret = PTR_ERR(bd);
 147                 goto out;
 148         }
 149 
 150         aat2870_bl->pdev = pdev;
 151         platform_set_drvdata(pdev, aat2870_bl);
 152 
 153         aat2870_bl->bd = bd;
 154 
 155         if (pdata->channels > 0)
 156                 aat2870_bl->channels = pdata->channels;
 157         else
 158                 aat2870_bl->channels = AAT2870_BL_CH_ALL;
 159 
 160         if (pdata->max_current > 0)
 161                 aat2870_bl->max_current = pdata->max_current;
 162         else
 163                 aat2870_bl->max_current = AAT2870_CURRENT_27_9;
 164 
 165         if (pdata->max_brightness > 0)
 166                 bd->props.max_brightness = pdata->max_brightness;
 167         else
 168                 bd->props.max_brightness = 255;
 169 
 170         aat2870_bl->brightness = 0;
 171         bd->props.power = FB_BLANK_UNBLANK;
 172         bd->props.brightness = bd->props.max_brightness;
 173 
 174         ret = aat2870_bl_update_status(bd);
 175         if (ret < 0) {
 176                 dev_err(&pdev->dev, "Failed to initialize\n");
 177                 return ret;
 178         }
 179 
 180         return 0;
 181 
 182 out:
 183         return ret;
 184 }
 185 
 186 static int aat2870_bl_remove(struct platform_device *pdev)
 187 {
 188         struct aat2870_bl_driver_data *aat2870_bl = platform_get_drvdata(pdev);
 189         struct backlight_device *bd = aat2870_bl->bd;
 190 
 191         bd->props.power = FB_BLANK_POWERDOWN;
 192         bd->props.brightness = 0;
 193         backlight_update_status(bd);
 194 
 195         return 0;
 196 }
 197 
 198 static struct platform_driver aat2870_bl_driver = {
 199         .driver = {
 200                 .name   = "aat2870-backlight",
 201         },
 202         .probe          = aat2870_bl_probe,
 203         .remove         = aat2870_bl_remove,
 204 };
 205 
 206 static int __init aat2870_bl_init(void)
 207 {
 208         return platform_driver_register(&aat2870_bl_driver);
 209 }
 210 subsys_initcall(aat2870_bl_init);
 211 
 212 static void __exit aat2870_bl_exit(void)
 213 {
 214         platform_driver_unregister(&aat2870_bl_driver);
 215 }
 216 module_exit(aat2870_bl_exit);
 217 
 218 MODULE_DESCRIPTION("AnalogicTech AAT2870 Backlight");
 219 MODULE_LICENSE("GPL");
 220 MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");

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