The framework adds support for low-level
control of the LCD backlight, which include support for brightness and power.
To make your backlight driver registered
into the kernel, the framework provides the only backlight_device_register()
API function, which will create “bl_power”, “brightness”, “actual_brightnes”
and “max_brightness” files under /sys/class/backlight/your_backlight_driver/.
These files represent the properties of your backlight driver, for example, “bl_power”
denotes which power state, your backlight driver is in now; writing values to “brightness”
will reduce or increase the “brightness”, and read to “actual_brightness”, “max_brightness”
returns the current value of brightness and maximum brightness, respectively.
/**
*
backlight_device_register - create and register a new object of
* backlight_device class.
* @name: the
name of the new object(must be the same as the name of the
* respective framebuffer device).
* @parent: a
pointer to the parent device
* @devdata: an
optional pointer to be stored for private driver use. The
* methods may retrieve it by using
bl_get_data(bd).
* @ops: the
backlight operations structure.
*
* Creates and
registers new backlight device. Returns either an
* ERR_PTR() or
a pointer to the newly allocated device.
*/
struct backlight_device
*backlight_device_register(const char *name,
struct
device *parent, void *devdata, struct backlight_ops *ops)
{
struct
backlight_device *new_bd;
int rc;
new_bd->dev.class
= backlight_class; ――the class of your backlight driver will resides in.
new_bd->dev.parent
= parent; —— designates the
parent of your backlight device.
new_bd->dev.release
= bl_device_release;
dev_set_name(&new_bd->dev,
name); —— assign the
device name.
dev_set_drvdata(&new_bd->dev,
devdata); —— stored for private driver use
rc =
device_register(&new_bd->dev); ——
register the new created backlight device.
if (rc)
{
kfree(new_bd);
return
ERR_PTR(rc);
}
rc =
backlight_register_fb(new_bd);
if (rc)
{
device_unregister(&new_bd->dev);
return
ERR_PTR(rc);
}
new_bd->ops
= ops; —— assign the
operating functions, the hardware-related part needs to be implemented by you.
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex);
if
(!pmac_backlight)
pmac_backlight
= new_bd;
mutex_unlock(&pmac_backlight_mutex);
#endif
return
new_bd;
}
The initialization of backlight_class should be prior to the registration of
backlight device for any Lcd device, so, make use of postcore_initcall(backlight_class_init);
static int __init backlight_class_init(void)
{
backlight_class
= class_create(THIS_MODULE, "backlight"); ——
create backlight class
if
(IS_ERR(backlight_class)) {
printk(KERN_WARNING
"Unable to create backlight class; errno = %ld\n",
PTR_ERR(backlight_class));
return
PTR_ERR(backlight_class);
}
backlight_class->dev_attrs
= bl_device_attributes;—— assign the properties of the classs
backlight_class->suspend
= backlight_suspend;
backlight_class->resume
= backlight_resume;
return
0;
}
rc
= strict_strtoul(buf, 0, &power);
if
(rc)
return
rc;
rc
= -ENXIO;
mutex_lock(&bd->ops_lock);
if
(bd->ops) {
pr_debug("backlight:
set power to %lu\n", power);
if
(bd->props.power != power) {
bd->props.power
= power; —— change the power state to the assigned state
backlight_update_status(bd);
—— update to the assigned power state
}
rc
= count;
}
mutex_unlock(&bd->ops_lock);
rc
= strict_strtoul(buf, 0, &brightness);
if
(rc)
return
rc;
rc
= -ENXIO;
mutex_lock(&bd->ops_lock);
if
(bd->ops) {
if
(brightness > bd->props.max_brightness)
rc
= -EINVAL;
else
{
pr_debug("backlight:
set brightness to %lu\n",
brightness);
bd->props.brightness
= brightness;
—— change the brightness to
the assigned state
backlight_update_status(bd);
—— update to the assigned brightness value
mutex_lock(&bd->ops_lock);
if
(bd->ops && bd->ops->get_brightness)
rc
= sprintf(buf, "%d\n", bd->ops->get_brightness(bd));
—— return the current
brightness
mutex_unlock(&bd->ops_lock);
return
rc;
}
Drivers/vedio/backlight/omap_bl.c is a good example for
your reference to implement your own backlight driver.