1/* 2 * Generic Backlight Driver 3 * 4 * Copyright (c) 2004-2008 Richard Purdie 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 */ 11 12#include <linux/module.h> 13#include <linux/kernel.h> 14#include <linux/init.h> 15#include <linux/platform_device.h> 16#include <linux/mutex.h> 17#include <linux/fb.h> 18#include <linux/backlight.h> 19 20static int genericbl_intensity; 21static struct backlight_device *generic_backlight_device; 22static struct generic_bl_info *bl_machinfo; 23 24/* Flag to signal when the battery is low */ 25#define GENERICBL_BATTLOW BL_CORE_DRIVER1 26 27static int genericbl_send_intensity(struct backlight_device *bd) 28{ 29 int intensity = bd->props.brightness; 30 31 if (bd->props.power != FB_BLANK_UNBLANK) 32 intensity = 0; 33 if (bd->props.state & BL_CORE_FBBLANK) 34 intensity = 0; 35 if (bd->props.state & BL_CORE_SUSPENDED) 36 intensity = 0; 37 if (bd->props.state & GENERICBL_BATTLOW) 38 intensity &= bl_machinfo->limit_mask; 39 40 bl_machinfo->set_bl_intensity(intensity); 41 42 genericbl_intensity = intensity; 43 44 if (bl_machinfo->kick_battery) 45 bl_machinfo->kick_battery(); 46 47 return 0; 48} 49 50static int genericbl_get_intensity(struct backlight_device *bd) 51{ 52 return genericbl_intensity; 53} 54 55/* 56 * Called when the battery is low to limit the backlight intensity. 57 * If limit==0 clear any limit, otherwise limit the intensity 58 */ 59void genericbl_limit_intensity(int limit) 60{ 61 struct backlight_device *bd = generic_backlight_device; 62 63 mutex_lock(&bd->ops_lock); 64 if (limit) 65 bd->props.state |= GENERICBL_BATTLOW; 66 else 67 bd->props.state &= ~GENERICBL_BATTLOW; 68 backlight_update_status(generic_backlight_device); 69 mutex_unlock(&bd->ops_lock); 70} 71EXPORT_SYMBOL(genericbl_limit_intensity); 72 73static const struct backlight_ops genericbl_ops = { 74 .options = BL_CORE_SUSPENDRESUME, 75 .get_brightness = genericbl_get_intensity, 76 .update_status = genericbl_send_intensity, 77}; 78 79static int genericbl_probe(struct platform_device *pdev) 80{ 81 struct backlight_properties props; 82 struct generic_bl_info *machinfo = pdev->dev.platform_data; 83 const char *name = "generic-bl"; 84 struct backlight_device *bd; 85 86 bl_machinfo = machinfo; 87 if (!machinfo->limit_mask) 88 machinfo->limit_mask = -1; 89 90 if (machinfo->name) 91 name = machinfo->name; 92 93 memset(&props, 0, sizeof(struct backlight_properties)); 94 props.type = BACKLIGHT_RAW; 95 props.max_brightness = machinfo->max_intensity; 96 bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops, 97 &props); 98 if (IS_ERR (bd)) 99 return PTR_ERR (bd); 100 101 platform_set_drvdata(pdev, bd); 102 103 bd->props.power = FB_BLANK_UNBLANK; 104 bd->props.brightness = machinfo->default_intensity; 105 backlight_update_status(bd); 106 107 generic_backlight_device = bd; 108 109 printk("Generic Backlight Driver Initialized.\n"); 110 return 0; 111} 112 113static int genericbl_remove(struct platform_device *pdev) 114{ 115 struct backlight_device *bd = platform_get_drvdata(pdev); 116 117 bd->props.power = 0; 118 bd->props.brightness = 0; 119 backlight_update_status(bd); 120 121 backlight_device_unregister(bd); 122 123 printk("Generic Backlight Driver Unloaded\n"); 124 return 0; 125} 126 127static struct platform_driver genericbl_driver = { 128 .probe = genericbl_probe, 129 .remove = genericbl_remove, 130 .driver = { 131 .name = "generic-bl", 132 }, 133}; 134 135module_platform_driver(genericbl_driver); 136 137MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); 138MODULE_DESCRIPTION("Generic Backlight Driver"); 139MODULE_LICENSE("GPL"); 140