android中的背光驱动层次分析
目录(?)[+]
- Android的Setting
- Android的背光JNI层
- Android的背光HAL层
- Linux的背光内核层
- Linux的背光驱动层
- 总结
其实Android的底层就是Linux,所以其驱动本质就是Linux驱动,但是这些Linux驱动是服务上层Android的,所以需遵循上Android的一些接口规范。所以涉及到的Android驱动都应应密切关注上层传递的接口。本文介绍的LCD背光驱动就是从上层一直往下层展现,但是笔者毕竟不是专注于Android上层,碍于知识不充裕,所以对上层的东西介绍得相对简单。
1.Android的Setting
- public class BrightnessPreference extends SeekBarDialogPreference implements
- SeekBar.OnSeekBarChangeListener, CheckBox.OnCheckedChangeListener {
- private SeekBar mSeekBar;
- private CheckBox mCheckBox;
- private int mOldBrightness;
- private int mOldAutomatic;
- private boolean mAutomaticAvailable;
- private boolean mRestoredOldState;
- // Backlight range is from 0 - 255. Need to make sure that user
- // doesn't set the backlight to 0 and get stuck
- private int mScreenBrightnessDim =
- ...
- public class BrightnessPreference extends SeekBarDialogPreference implements
- SeekBar.OnSeekBarChangeListener, CheckBox.OnCheckedChangeListener {
- private SeekBar mSeekBar;
- private CheckBox mCheckBox;
- private int mOldBrightness;
- private int mOldAutomatic;
- private boolean mAutomaticAvailable;
- private boolean mRestoredOldState;
- // Backlight range is from 0 - 255. Need to make sure that user
- // doesn't set the backlight to 0 and get stuck
- private int mScreenBrightnessDim =
- ...
Android的最上层已经将背光亮度量化为了[0,255]个等级,并且提示注意不要设置为0,所以在进行最低层的背光驱动编写时,可以合理按这个范围部署背光的亮度。
2.Android的背光JNI层
3.Android的背光HAL层
- /*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #define LOG_TAG "lights"
- #include <cutils/log.h>
- #include <stdint.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <pthread.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <hardware/lights.h>
- /******************************************************************************/
- static pthread_once_t g_init = PTHREAD_ONCE_INIT;
- static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
- char const*const LCD_FILE
- = "/sys/class/leds/lcd-backlight/brightness";
- char const*const KEYBOARD_FILE
- = "/sys/class/leds/keyboard-backlight/brightness";
- char const*const CHARGING_LED_FILE
- = "/sys/class/leds/battery-led/brightness";
- /*RGB file descriptors */
- char const*const RED_LED_FILE
- = "/sys/class/leds/red/brightness";
- char const*const RED_DELAY_ON_FILE
- = "/sys/class/leds/red/delay_on";
- char const*const RED_DELAY_OFF_FILE
- = "/sys/class/leds/red/delay_off";
- char const*const GREEN_LED_FILE
- = "/sys/class/leds/green/brightness";
- char const*const GREEN_DELAY_ON_FILE
- = "/sys/class/leds/green/delay_on";
- char const*const GREEN_DELAY_OFF_FILE
- = "/sys/class/leds/green/delay_off";
- char const*const BLUE_LED_FILE
- = "/sys/class/leds/blue/brightness";
- char const*const BLUE_DELAY_ON_FILE
- = "/sys/class/leds/blue/delay_on";
- char const*const BLUE_DELAY_OFF_FILE
- = "/sys/class/leds/blue/delay_off";
- ...
- /*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #define LOG_TAG "lights"
- #include <cutils/log.h>
- #include <stdint.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <pthread.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <hardware/lights.h>
- /******************************************************************************/
- static pthread_once_t g_init = PTHREAD_ONCE_INIT;
- static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
- char const*const LCD_FILE
- = "/sys/class/leds/lcd-backlight/brightness";
- char const*const KEYBOARD_FILE
- = "/sys/class/leds/keyboard-backlight/brightness";
- char const*const CHARGING_LED_FILE
- = "/sys/class/leds/battery-led/brightness";
- /*RGB file descriptors */
- char const*const RED_LED_FILE
- = "/sys/class/leds/red/brightness";
- char const*const RED_DELAY_ON_FILE
- = "/sys/class/leds/red/delay_on";
- char const*const RED_DELAY_OFF_FILE
- = "/sys/class/leds/red/delay_off";
- char const*const GREEN_LED_FILE
- = "/sys/class/leds/green/brightness";
- char const*const GREEN_DELAY_ON_FILE
- = "/sys/class/leds/green/delay_on";
- char const*const GREEN_DELAY_OFF_FILE
- = "/sys/class/leds/green/delay_off";
- char const*const BLUE_LED_FILE
- = "/sys/class/leds/blue/brightness";
- char const*const BLUE_DELAY_ON_FILE
- = "/sys/class/leds/blue/delay_on";
- char const*const BLUE_DELAY_OFF_FILE
- = "/sys/class/leds/blue/delay_off";
- ...
- 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);
- err = write_int(LCD_FILE, brightness);
- pthread_mutex_unlock(&g_lock);
- return err;
- }
- 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);
- err = write_int(LCD_FILE, brightness);
- pthread_mutex_unlock(&g_lock);
- return err;
- }
这里关注一下LCD背光的sys文件节点:"/sys/class/leds/lcd-backlight/brightness"
4.Linux的背光内核层
- 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;
- leds_class->dev_attrs = led_class_attrs;
- return 0;
- }
- 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;
- leds_class->dev_attrs = led_class_attrs;
- return 0;
- }
好明显,正是由于它创建了sys class,名字为”leds“,所以上面的背光sys文件节点"/sys/class/leds/”就有了来由,那么剩下的“../lcd-backlight/brightness"又是怎么来的呢?看看一个注册led设备类的函数.
- /**
- * 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)
- {
- 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);
- #ifdef CONFIG_LEDS_TRIGGERS
- init_rwsem(&led_cdev->trigger_lock);
- ...
- /**
- * 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)
- {
- 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);
- #ifdef CONFIG_LEDS_TRIGGERS
- init_rwsem(&led_cdev->trigger_lock);
- ...
这个注册函数的接口最终会被我们要开发的背光驱动调用,这个接口在/sys/class/leds/下又创建了一个设备接口,名字是led_cdev->name。好明显这里的led_cdev->name应该就是”lcd-backlight“,究竟是不是真的这样呢?继续看。
- static struct device_attribute led_class_attrs[] = {
- __ATTR(brightness, 0644, led_brightness_show, led_brightness_store),
- __ATTR(max_brightness, 0444, led_max_brightness_show, NULL),
- #ifdef CONFIG_LEDS_TRIGGERS
- __ATTR(trigger, 0644, led_trigger_show, led_trigger_store),
- #endif
- __ATTR_NULL,
- };
- static struct device_attribute led_class_attrs[] = {
- __ATTR(brightness, 0644, led_brightness_show, led_brightness_store),
- __ATTR(max_brightness, 0444, led_max_brightness_show, NULL),
- #ifdef CONFIG_LEDS_TRIGGERS
- __ATTR(trigger, 0644, led_trigger_show, led_trigger_store),
- #endif
- __ATTR_NULL,
- };
看到了属性名字为”brightness“,这似乎越来越接近解释"/sys/class/leds/lcd-backlight/brightness"的由来了。
- struct display_led_data {
- struct led_classdev pri_display_class_dev;
- struct led_classdev sec_display_class_dev;
- struct omap4_disp_led_platform_data *led_pdata;
- struct mutex pri_disp_lock;
- struct mutex sec_disp_lock;
- };
- static int omap4_XXX_display_probe(struct platform_device *pdev)
- {
- int ret;
- struct display_led_data *info;
- pr_info("%s:Enter\n", __func__);
- if (pdev->dev.platform_data == NULL) {
- pr_err("%s: platform data required\n", __func__);
- return -ENODEV;
- }
- info = kzalloc(sizeof(struct display_led_data), GFP_KERNEL);
- if (info == NULL) {
- ret = -ENOMEM;
- return ret;
- }
- info->led_pdata = pdev->dev.platform_data;
- platform_set_drvdata(pdev, info);
- info->pri_display_class_dev.name = "lcd-backlight";
- info->pri_display_class_dev.brightness_set = omap4_xxx_primary_disp_store;
- ...
- ret = led_classdev_register(&pdev->dev,
- &info->pri_display_class_dev);
- if (ret < 0) {
- pr_err("%s: Register led class failed\n", __func__);
- kfree(info);
- return ret;
- }
- if (info->led_pdata->flags & LEDS_CTRL_AS_TWO_DISPLAYS) {
- pr_info("%s: Configuring the secondary LED\n", __func__);
- info->sec_display_class_dev.name = "lcd-backlight2";
- info->sec_display_class_dev.brightness_set =
- omap4_mirage_secondary_disp_store;
- info->sec_display_class_dev.max_brightness = LED_OFF;
- mutex_init(&info->sec_disp_lock);
- ret = led_classdev_register(&pdev->dev,
- &info->sec_display_class_dev);
- ...
- struct display_led_data {
- struct led_classdev pri_display_class_dev;
- struct led_classdev sec_display_class_dev;
- struct omap4_disp_led_platform_data *led_pdata;
- struct mutex pri_disp_lock;
- struct mutex sec_disp_lock;
- };
- static int omap4_XXX_display_probe(struct platform_device *pdev)
- {
- int ret;
- struct display_led_data *info;
- pr_info("%s:Enter\n", __func__);
- if (pdev->dev.platform_data == NULL) {
- pr_err("%s: platform data required\n", __func__);
- return -ENODEV;
- }
- info = kzalloc(sizeof(struct display_led_data), GFP_KERNEL);
- if (info == NULL) {
- ret = -ENOMEM;
- return ret;
- }
- info->led_pdata = pdev->dev.platform_data;
- platform_set_drvdata(pdev, info);
- info->pri_display_class_dev.name = "lcd-backlight";
- info->pri_display_class_dev.brightness_set = omap4_xxx_primary_disp_store;
- ...
- ret = led_classdev_register(&pdev->dev,
- &info->pri_display_class_dev);
- if (ret < 0) {
- pr_err("%s: Register led class failed\n", __func__);
- kfree(info);
- return ret;
- }
- if (info->led_pdata->flags & LEDS_CTRL_AS_TWO_DISPLAYS) {
- pr_info("%s: Configuring the secondary LED\n", __func__);
- info->sec_display_class_dev.name = "lcd-backlight2";
- info->sec_display_class_dev.brightness_set =
- omap4_mirage_secondary_disp_store;
- info->sec_display_class_dev.max_brightness = LED_OFF;
- mutex_init(&info->sec_disp_lock);
- ret = led_classdev_register(&pdev->dev,
- &info->sec_display_class_dev);
- ...
需关注这里设置了info->pri_display_class_dev.name = "lcd-backlight";,然后调用led_classdev_register函数注册,所以完美解释了
6.总结
android中的背光驱动层次分析相关推荐
- android中倒计时控件CountDownTimer分析
android中倒计时控件CountDownTimer分析1 示例代码 new CountDownTimer(10000, 1000) {public void onTick(long millisU ...
- Android中app卡顿原因分析示例
http://www.cnblogs.com/zhucai/p/weibo-graphics-performance-analyse.html 朱才 专注于Android图形动画 MIUI工程师 博客 ...
- android viewgroup 事件,android中viewgroup的事件传递分析
在上一篇中我们分析了从view的dispatchTouchEvent到onTouchListener的onTouch回调到onTouchEvent到onClickLisener的onClickandr ...
- Android中启动Activity(startActivity)流程图分析
在上篇博文< Android中ActivityManagerService与应用程序(客户端)通信模型分析>中,我们从宏观架构上掌握 ActivityManagerService与应用程序 ...
- Android中init与受精卵Zygote分析,以及添加自己开机启动的系统服务
最近在做云游戏的项目,由于需要购买硬件,系统提供Android源码需要自己编译.所以特地学习一下记录一下Android的启动(我的是AOSP7.1然后+厂商系统补丁) 先上图: 目录 一. 启动流程硬 ...
- Android 中的混音器 AudioMixer 实现分析
Android framework 的音频处理模库 libaudioprocessing (位于 frameworks/av/media/libaudioprocessing) 提供了混音器组件 Au ...
- Android中ViewStub的使用与分析
文章目录 1.ViewStub的简单使用 1.1 简单说明 1.2 简单示例 2.结合源码分析问题 2.1 第二次调用inflate()加载会抛出空指针异常 2.2 第二次通过调用setVisibil ...
- android 设备驱动 位置,android中各个部件驱动在源码中的位置
Android的专用驱动:Ashmem.binder.logger Ashmem:匿名共享内存驱动 Logger:轻量级的log驱动 Binder:基于OpenBinder驱动,为android平台提 ...
- Android中相机(Camera)画面旋转角度分析:手机摄像头的“正向”、手机画面自然方向、相机画面的偏转角度
#.概述: 1.如同人眼看东西分上下一样,摄像头也有其"正向",正常情况下,Android手机后置.前置摄像头的"正向"朝向为手机的"右侧" ...
最新文章
- 从 Kafka 看时间轮算法设计
- Java实用教程 课堂测试(2021C++补考题目)
- 现代操作系统:进程和线程总结
- winCE下Unicode编码
- t3显示乱码_打开T3出现乱码是什么原因,如下图
- python ssl socket_Python使用Socket(Https)Post登录百度的实现代码
- 02_HBase集群部署
- Android程序开发:简单电话拨号器
- 爱的十个秘密--8.沟通的力量
- matlab肆,matlab入门教程
- OpenG 编程指南英文整理
- boost电路输出电流公式_Boost电路的参数计算及仿真
- 数学知识学习之——商空间(Quotient Spaces)
- chrome 打包安装插件
- 26.看前端视频的感悟,来自碎碎念记录
- 社会兼职工作实践报告
- java下载图片到本地,例如从网上下载图片,下载淘宝图片,下载百度图片等
- DeepLab系列总结
- BSV 上的 Schnorr 签名
- Java内存区域和GC机制
热门文章
- jsb.reflection.callStaticMethod
- python 手动清除内存gc
- 小程序---wxParse解决图片大小不适应小程序页面问题
- ilo4服务器远程,HP服务器ilo远程管理端口设置
- 二类医疗器械定义及分类
- 软件测试的概念及详细分类的介绍
- 如何用HTML制作一个房子,一分钟,教会你农村自建房该怎么设计!小白学了都能上手画出设计图!...
- HDU4417 Super Mario (主席树模板)
- Ubuntu安装Kinect驱动(openni、NITE、Sensor)及遇到的问题
- MySQL Java JDBC