1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Backlight Lowlevel Control Abstraction 4 * 5 * Copyright (C) 2003,2004 Hewlett-Packard Company 6 * 7 */ 8 9 #ifndef _LINUX_BACKLIGHT_H 10 #define _LINUX_BACKLIGHT_H 11 12 #include <linux/device.h> 13 #include <linux/fb.h> 14 #include <linux/mutex.h> 15 #include <linux/notifier.h> 16 17 /* Notes on locking: 18 * 19 * backlight_device->ops_lock is an internal backlight lock protecting the 20 * ops pointer and no code outside the core should need to touch it. 21 * 22 * Access to update_status() is serialised by the update_lock mutex since 23 * most drivers seem to need this and historically get it wrong. 24 * 25 * Most drivers don't need locking on their get_brightness() method. 26 * If yours does, you need to implement it in the driver. You can use the 27 * update_lock mutex if appropriate. 28 * 29 * Any other use of the locks below is probably wrong. 30 */ 31 32 enum backlight_update_reason { 33 BACKLIGHT_UPDATE_HOTKEY, 34 BACKLIGHT_UPDATE_SYSFS, 35 }; 36 37 enum backlight_type { 38 BACKLIGHT_RAW = 1, 39 BACKLIGHT_PLATFORM, 40 BACKLIGHT_FIRMWARE, 41 BACKLIGHT_TYPE_MAX, 42 }; 43 44 enum backlight_notification { 45 BACKLIGHT_REGISTERED, 46 BACKLIGHT_UNREGISTERED, 47 }; 48 49 enum backlight_scale { 50 BACKLIGHT_SCALE_UNKNOWN = 0, 51 BACKLIGHT_SCALE_LINEAR, 52 BACKLIGHT_SCALE_NON_LINEAR, 53 }; 54 55 struct backlight_device; 56 struct fb_info; 57 58 /** 59 * struct backlight_ops - backlight operations 60 * 61 * The backlight operations are specified when the backlight device is registered. 62 */ 63 struct backlight_ops { 64 /** 65 * @options: Configure how operations are called from the core. 66 * 67 * The options parameter is used to adjust the behaviour of the core. 68 * Set BL_CORE_SUSPENDRESUME to get the update_status() operation called 69 * upon suspend and resume. 70 */ 71 unsigned int options; 72 73 #define BL_CORE_SUSPENDRESUME (1 << 0) 74 75 /** 76 * @update_status: Operation called when properties have changed. 77 * 78 * Notify the backlight driver some property has changed. 79 * The update_status operation is protected by the update_lock. 80 * 81 * The backlight driver is expected to use backlight_is_blank() 82 * to check if the display is blanked and set brightness accordingly. 83 * update_status() is called when any of the properties has changed. 84 * 85 * RETURNS: 86 * 87 * 0 on success, negative error code if any failure occurred. 88 */ 89 int (*update_status)(struct backlight_device *); 90 91 /** 92 * @get_brightness: Return the current backlight brightness. 93 * 94 * The driver may implement this as a readback from the HW. 95 * This operation is optional and if not present then the current 96 * brightness property value is used. 97 * 98 * RETURNS: 99 * 100 * A brightness value which is 0 or a positive number. 101 * On failure a negative error code is returned. 102 */ 103 int (*get_brightness)(struct backlight_device *); 104 105 /** 106 * @check_fb: Check the framebuffer device. 107 * 108 * Check if given framebuffer device is the one bound to this backlight. 109 * This operation is optional and if not implemented it is assumed that the 110 * fbdev is always the one bound to the backlight. 111 * 112 * RETURNS: 113 * 114 * If info is NULL or the info matches the fbdev bound to the backlight return true. 115 * If info does not match the fbdev bound to the backlight return false. 116 */ 117 int (*check_fb)(struct backlight_device *bd, struct fb_info *info); 118 }; 119 120 /* This structure defines all the properties of a backlight */ 121 struct backlight_properties { 122 /* Current User requested brightness (0 - max_brightness) */ 123 int brightness; 124 /* Maximal value for brightness (read-only) */ 125 int max_brightness; 126 /* Current FB Power mode (0: full on, 1..3: power saving 127 modes; 4: full off), see FB_BLANK_XXX */ 128 int power; 129 /* FB Blanking active? (values as for power) */ 130 /* Due to be removed, please use (state & BL_CORE_FBBLANK) */ 131 int fb_blank; 132 /* Backlight type */ 133 enum backlight_type type; 134 /* Flags used to signal drivers of state changes */ 135 unsigned int state; 136 /* Type of the brightness scale (linear, non-linear, ...) */ 137 enum backlight_scale scale; 138 139 #define BL_CORE_SUSPENDED (1 << 0) /* backlight is suspended */ 140 #define BL_CORE_FBBLANK (1 << 1) /* backlight is under an fb blank event */ 141 142 }; 143 144 struct backlight_device { 145 /* Backlight properties */ 146 struct backlight_properties props; 147 148 /* Serialise access to update_status method */ 149 struct mutex update_lock; 150 151 /* This protects the 'ops' field. If 'ops' is NULL, the driver that 152 registered this device has been unloaded, and if class_get_devdata() 153 points to something in the body of that driver, it is also invalid. */ 154 struct mutex ops_lock; 155 const struct backlight_ops *ops; 156 157 /* The framebuffer notifier block */ 158 struct notifier_block fb_notif; 159 160 /* list entry of all registered backlight devices */ 161 struct list_head entry; 162 163 struct device dev; 164 165 /* Multiple framebuffers may share one backlight device */ 166 bool fb_bl_on[FB_MAX]; 167 168 int use_count; 169 }; 170 171 static inline int backlight_update_status(struct backlight_device *bd) 172 { 173 int ret = -ENOENT; 174 175 mutex_lock(&bd->update_lock); 176 if (bd->ops && bd->ops->update_status) 177 ret = bd->ops->update_status(bd); 178 mutex_unlock(&bd->update_lock); 179 180 return ret; 181 } 182 183 /** 184 * backlight_enable - Enable backlight 185 * @bd: the backlight device to enable 186 */ 187 static inline int backlight_enable(struct backlight_device *bd) 188 { 189 if (!bd) 190 return 0; 191 192 bd->props.power = FB_BLANK_UNBLANK; 193 bd->props.fb_blank = FB_BLANK_UNBLANK; 194 bd->props.state &= ~BL_CORE_FBBLANK; 195 196 return backlight_update_status(bd); 197 } 198 199 /** 200 * backlight_disable - Disable backlight 201 * @bd: the backlight device to disable 202 */ 203 static inline int backlight_disable(struct backlight_device *bd) 204 { 205 if (!bd) 206 return 0; 207 208 bd->props.power = FB_BLANK_POWERDOWN; 209 bd->props.fb_blank = FB_BLANK_POWERDOWN; 210 bd->props.state |= BL_CORE_FBBLANK; 211 212 return backlight_update_status(bd); 213 } 214 215 /** 216 * backlight_put - Drop backlight reference 217 * @bd: the backlight device to put 218 */ 219 static inline void backlight_put(struct backlight_device *bd) 220 { 221 if (bd) 222 put_device(&bd->dev); 223 } 224 225 /** 226 * backlight_is_blank - Return true if display is expected to be blank 227 * @bd: the backlight device 228 * 229 * Display is expected to be blank if any of these is true:: 230 * 231 * 1) if power in not UNBLANK 232 * 2) if fb_blank is not UNBLANK 233 * 3) if state indicate BLANK or SUSPENDED 234 * 235 * Returns true if display is expected to be blank, false otherwise. 236 */ 237 static inline bool backlight_is_blank(const struct backlight_device *bd) 238 { 239 return bd->props.power != FB_BLANK_UNBLANK || 240 bd->props.fb_blank != FB_BLANK_UNBLANK || 241 bd->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK); 242 } 243 244 extern struct backlight_device *backlight_device_register(const char *name, 245 struct device *dev, void *devdata, const struct backlight_ops *ops, 246 const struct backlight_properties *props); 247 extern struct backlight_device *devm_backlight_device_register( 248 struct device *dev, const char *name, struct device *parent, 249 void *devdata, const struct backlight_ops *ops, 250 const struct backlight_properties *props); 251 extern void backlight_device_unregister(struct backlight_device *bd); 252 extern void devm_backlight_device_unregister(struct device *dev, 253 struct backlight_device *bd); 254 extern void backlight_force_update(struct backlight_device *bd, 255 enum backlight_update_reason reason); 256 extern int backlight_register_notifier(struct notifier_block *nb); 257 extern int backlight_unregister_notifier(struct notifier_block *nb); 258 extern struct backlight_device *backlight_device_get_by_type(enum backlight_type type); 259 struct backlight_device *backlight_device_get_by_name(const char *name); 260 extern int backlight_device_set_brightness(struct backlight_device *bd, unsigned long brightness); 261 262 #define to_backlight_device(obj) container_of(obj, struct backlight_device, dev) 263 264 static inline void * bl_get_data(struct backlight_device *bl_dev) 265 { 266 return dev_get_drvdata(&bl_dev->dev); 267 } 268 269 struct generic_bl_info { 270 const char *name; 271 int max_intensity; 272 int default_intensity; 273 int limit_mask; 274 void (*set_bl_intensity)(int intensity); 275 void (*kick_battery)(void); 276 }; 277 278 #ifdef CONFIG_OF 279 struct backlight_device *of_find_backlight_by_node(struct device_node *node); 280 #else 281 static inline struct backlight_device * 282 of_find_backlight_by_node(struct device_node *node) 283 { 284 return NULL; 285 } 286 #endif 287 288 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) 289 struct backlight_device *of_find_backlight(struct device *dev); 290 struct backlight_device *devm_of_find_backlight(struct device *dev); 291 #else 292 static inline struct backlight_device *of_find_backlight(struct device *dev) 293 { 294 return NULL; 295 } 296 297 static inline struct backlight_device * 298 devm_of_find_backlight(struct device *dev) 299 { 300 return NULL; 301 } 302 #endif 303 304 #endif 305