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
20
static int genericbl_intensity;
21
static struct backlight_device *generic_backlight_device;
22
static struct generic_bl_info *bl_machinfo;
23
24
/* Flag to signal when the battery is low */
25
#define GENERICBL_BATTLOW       BL_CORE_DRIVER1
26
27
static 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
50
static 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
 */
59
void corgibl_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
}
71
EXPORT_SYMBOL(corgibl_limit_intensity);
72
73
static struct backlight_ops genericbl_ops = {
74
	.options = BL_CORE_SUSPENDRESUME,
75
	.get_brightness = genericbl_get_intensity,
76
	.update_status  = genericbl_send_intensity,
77
};
78
79
static int genericbl_probe(struct platform_device *pdev)
80
{
81
	struct generic_bl_info *machinfo = pdev->dev.platform_data;
82
	const char *name = "generic-bl";
83
	struct backlight_device *bd;
84
85
	bl_machinfo = machinfo;
86
	if (!machinfo->limit_mask)
87
		machinfo->limit_mask = -1;
88
89
	if (machinfo->name)
90
		name = machinfo->name;
91
92
	bd = backlight_device_register (name,
93
		&pdev->dev, NULL, &genericbl_ops);
94
	if (IS_ERR (bd))
95
		return PTR_ERR (bd);
96
97
	platform_set_drvdata(pdev, bd);
98
99
	bd->props.max_brightness = machinfo->max_intensity;
100
	bd->props.power = FB_BLANK_UNBLANK;
101
	bd->props.brightness = machinfo->default_intensity;
102
	backlight_update_status(bd);
103
104
	generic_backlight_device = bd;
105
106
	printk("Generic Backlight Driver Initialized.\n");
107
	return 0;
108
}
109
110
static int genericbl_remove(struct platform_device *pdev)
111
{
112
	struct backlight_device *bd = platform_get_drvdata(pdev);
113
114
	bd->props.power = 0;
115
	bd->props.brightness = 0;
116
	backlight_update_status(bd);
117
118
	backlight_device_unregister(bd);
119
120
	printk("Generic Backlight Driver Unloaded\n");
121
	return 0;
122
}
123
124
static struct platform_driver genericbl_driver = {
125
	.probe		= genericbl_probe,
126
	.remove		= genericbl_remove,
127
	.driver		= {
128
		.name	= "generic-bl",
129
	},
130
};
131
132
static int __init genericbl_init(void)
133
{
134
	return platform_driver_register(&genericbl_driver);
135
}
136
137
static void __exit genericbl_exit(void)
138
{
139
	platform_driver_unregister(&genericbl_driver);
140
}
141
142
module_init(genericbl_init);
143
module_exit(genericbl_exit);
144
145
MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
146
MODULE_DESCRIPTION("Generic Backlight Driver");
147
MODULE_LICENSE("GPL");