Android LCD和键盘 背光亮度设置(4)

举例,背光设置,背光对应的代码如下:

char const*const LCD_FILE

= "/sys/class/leds/lcd-backlight/brightness";

static int

rgb_to_brightness(struct light_state_t const* state)

{

int color = state->color & 0x00ffffff;

return ((77*((color>>16)&0x00ff))

+ (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;

}

static int

set_light_backlight(struct light_device_t* dev,

struct light_state_t const* state)

{

int err = 0;

int brightness = rgb_to_brightness(state);

pthread_mutex_lock(&g_lock);

g_backlight = brightness;

err = write_int(LCD_FILE, brightness);

if (g_haveTrackballLight) {

handle_trackball_light_locked(dev);

}

pthread_mutex_unlock(&g_lock);

return err;

}

也就是往文件/sys/class/leds/lcd-backlight/brightness写入亮度值,然后驱动会根据该文件更改背光的亮度。LCD_FILE的路径根据实际情况更改,同时需要在init.rc 修改其权限,使其可写rgb_to_brightness也根据实际更改,比如要直接亮度值控制,那只要获取r,g,b其中的一个值就行了,如:

static int

rgb_to_brightness(struct light_state_t const* state)

{

int color = state->color & 0x000000ff;

return color;

}

4,led类驱动

4.1,驱动创建leds类,系统启动时执行leds_init在目录/sys/class/创建子目录leds

kernel\drivers\leds\Led-class.c

static int __init leds_init(void)
{
 leds_class = class_create(THIS_MODULE, "leds");
 if (IS_ERR(leds_class))
  return PTR_ERR(leds_class);
 leds_class->suspend = led_suspend;
 leds_class->resume = led_resume;
 return 0;
}

4.2,led_classdev_register,调用这个函数就在目录/sys/class/leds创建子目录led_cdev->name和属性文件brightness

对brightness文件写就执行led_brightness_store,对brightness文件读就执行led_brightness_show,为下面的lcd,led注册做好准备

kernel\drivers\leds\Led-class.c

static ssize_t led_brightness_show(struct device *dev,
  struct device_attribute *attr, char *buf)
{
 struct led_classdev *led_cdev = dev_get_drvdata(dev);

/* no lock needed for this */
 led_update_brightness(led_cdev);

return sprintf(buf, "%u\n", led_cdev->brightness);
}

static ssize_t led_brightness_store(struct device *dev,
  struct device_attribute *attr, const char *buf, size_t size)
{
 struct led_classdev *led_cdev = dev_get_drvdata(dev);
 ssize_t ret = -EINVAL;
 char *after;
 unsigned long state = simple_strtoul(buf, &after, 10);
 size_t count = after - buf;

if (*after && isspace(*after))
  count++;

if (count == size) {
  ret = count;

if (state == LED_OFF)
   led_trigger_remove(led_cdev);
  led_set_brightness(led_cdev, state);
 }

return ret;
}

static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);


/**
 * led_classdev_register - register a new object of led_classdev class.
 * @parent: The device to register.
 * @led_cdev: the led_classdev structure for this device.
 */
int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
{
 int rc;

led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
          "%s", led_cdev->name);
 if (IS_ERR(led_cdev->dev))
  return PTR_ERR(led_cdev->dev);

/* register the attributes */
 rc = device_create_file(led_cdev->dev, &dev_attr_brightness);
 if (rc)
  goto err_out;

#ifdef CONFIG_LEDS_TRIGGERS
 init_rwsem(&led_cdev->trigger_lock);
#endif
 /* add to the list of leds */
 down_write(&leds_list_lock);
 list_add_tail(&led_cdev->node, &leds_list);
 up_write(&leds_list_lock);

led_update_brightness(led_cdev);

#ifdef CONFIG_LEDS_TRIGGERS
 rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
 if (rc)
  goto err_out_led_list;

led_trigger_set_default(led_cdev);
#endif

printk(KERN_INFO "Registered led device: %s\n",
   led_cdev->name);

return 0;

#ifdef CONFIG_LEDS_TRIGGERS
err_out_led_list:
 device_remove_file(led_cdev->dev, &dev_attr_brightness);
 list_del(&led_cdev->node);
#endif
err_out:
 device_unregister(led_cdev->dev);
 return rc;
}
EXPORT_SYMBOL_GPL(led_classdev_register);

4.3,lcd驱动调用led_classdev_register,在目录/sys/class/leds创建子目录lcd-backlight和属性文件brightness

kernel\drivers\video\msm\Msm_fb.c

static int lcd_backlight_registered;

static void msm_fb_set_bl_brightness(struct led_classdev *led_cdev,
     enum led_brightness value)
{
 struct msm_fb_data_type *mfd = dev_get_drvdata(led_cdev->dev->parent);
 int bl_lvl;

if (value > MAX_BACKLIGHT_BRIGHTNESS)
  value = MAX_BACKLIGHT_BRIGHTNESS;

/* This maps Android backlight level 0 to 255 into
    driver backlight level 0 to bl_max with rounding */
 bl_lvl = (2 * value * mfd->panel_info.bl_max + MAX_BACKLIGHT_BRIGHTNESS)
  /(2 * MAX_BACKLIGHT_BRIGHTNESS);

if (!bl_lvl && value)
  bl_lvl = 1;

msm_fb_set_backlight(mfd, bl_lvl, 1);
}

static struct led_classdev backlight_led = {
 .name  = "lcd-backlight",
 .brightness = MAX_BACKLIGHT_BRIGHTNESS,
 .brightness_set = msm_fb_set_bl_brightness,
};

if (!lcd_backlight_registered) {
  if (led_classdev_register(&pdev->dev, &backlight_led))
   printk(KERN_ERR "led_classdev_register failed\n");
  else
   lcd_backlight_registered = 1;
 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwxsww.html