Chinaunix首页 | 论坛 | 博客
  • 博客访问: 641101
  • 博文数量: 75
  • 博客积分: 7001
  • 博客等级: 少将
  • 技术积分: 1465
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-11 17:39
文章分类

全部博文(75)

文章存档

2010年(1)

2009年(25)

2008年(49)

我的朋友

分类: LINUX

2009-08-24 23:00:25

Backlight framework in linux-2.6.29

 

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;

 

         pr_debug("backlight_device_register: name=%s\n", name);

 

         new_bd = kzalloc(sizeof(struct backlight_device), GFP_KERNEL);

<-- allocate space for new backlight device.

         if (!new_bd)

                   return ERR_PTR(-ENOMEM);

 

         mutex_init(&new_bd->update_lock);

         mutex_init(&new_bd->ops_lock);

 

         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;

}

 

Let’s see the properties then.

 

static struct device_attribute bl_device_attributes[] = {

         __ATTR(bl_power, 0644, backlight_show_power, backlight_store_power),

         __ATTR(brightness, 0644, backlight_show_brightness,

                        backlight_store_brightness),

         __ATTR(actual_brightness, 0444, backlight_show_actual_brightness,

                        NULL),

         __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),

         __ATTR_NULL,

};

 

static ssize_t backlight_show_power(struct device *dev,

                   struct device_attribute *attr,char *buf)

{

         struct backlight_device *bd = to_backlight_device(dev);

 

         return sprintf(buf, "%d\n", bd->props.power); < —— return the current power state

}

 

static ssize_t backlight_store_power(struct device *dev,

                   struct device_attribute *attr, const char *buf, size_t count)

{

         int rc;

         struct backlight_device *bd = to_backlight_device(dev);

         unsigned long power;

 

         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);

 

         return rc;

}

 

static ssize_t backlight_show_brightness(struct device *dev,

                   struct device_attribute *attr, char *buf)

{

         struct backlight_device *bd = to_backlight_device(dev);

 

         return sprintf(buf, "%d\n", bd->props.brightness); <—— return the current brightness

}

 

static ssize_t backlight_store_brightness(struct device *dev,

                   struct device_attribute *attr, const char *buf, size_t count)

{

         int rc;

         struct backlight_device *bd = to_backlight_device(dev);

         unsigned long brightness;

 

         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

 

                            rc = count;

                   }

         }

         mutex_unlock(&bd->ops_lock);

 

         return rc;

}

 

static ssize_t backlight_show_max_brightness(struct device *dev,

                   struct device_attribute *attr, char *buf)

{

         struct backlight_device *bd = to_backlight_device(dev);

 

         return sprintf(buf, "%d\n", bd->props.max_brightness);

<—— return the maximum brightness

}

 

static ssize_t backlight_show_actual_brightness(struct device *dev,

                   struct device_attribute *attr, char *buf)

{

         int rc = -ENXIO;

         struct backlight_device *bd = to_backlight_device(dev);

 

         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.

 

My implementation for xxx platform:

文件:xxx_backlight.rar
大小:3KB
下载:下载


 

阅读(2840) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~