Android 4.0 ROM亮度相關(guān)

亮度設(shè)置
應(yīng)用設(shè)計(jì)
1.1 設(shè)置進(jìn)度條范圍
背光設(shè)置是在:設(shè)置->聲音和顯示->亮度鸵赖,通過(guò)進(jìn)度條來(lái)設(shè)置的曲饱。

文件:
packages/apps/Settings/src/com/Android/settings/BrightnessPreference.java

private static final int MINIMUM_BACKLIGHT = Android.os.Power.BRIGHTNESS_DIM + 10;  
private static final int MAXIMUM_BACKLIGHT = Android.os.Power.BRIGHTNESS_ON;  
  
mSeekBar.setMax(MAXIMUM_BACKLIGHT - MINIMUM_BACKLIGHT);  

設(shè)置進(jìn)度條的范圍溉卓,BRIGHTNESS_DIM = 20 BRIGHTNESS_ON=255添谊,它們的定義在:

frameworks/base/core/java/Android/os/Power.java

1.2 設(shè)置亮度
文件:packages/apps/Settings/src/com/Android/settings/BrightnessPreference.java

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {  
  
       setMode(isChecked ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC  
  
                : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);  
  
        if (!isChecked) {  
  
            setBrightness(mSeekBar.getProgress() + MINIMUM_BACKLIGHT);  
  
        }  
  
    }  
  
private void setBrightness(int brightness) {  
  
        try {  
  
            IPowerManager power = IPowerManager.Stub.asInterface(  
  
                    ServiceManager.getService("power"));  
  
            if (power != null) {  
  
                power.setBacklightBrightness(brightness);  
  
            }  
  
        } catch (RemoteException doe) {  
  
             
  
        }         
  
}  

由以上代碼可知策肝,brightness的范圍是:20~255;代碼通過(guò)服務(wù)管理器(ServiceManager)獲得power服務(wù)删豺,然后通過(guò)power服務(wù)設(shè)置亮度吸奴。

power.setBacklightBrightness的定義在:

rameworks/base/core/java/Android/os/IPowerManager.aidl.java

frameworks/base/core/java/Android/os/PowerManager.java

2允扇, Power服務(wù)
文件:frameworks/base/core/java/Android/os/Power.java

/**

 * Brightness value for dim backlight 

 */ 

public static final int BRIGHTNESS_DIM = 20; 

/** 

 * Brightness value for fully on 

 */ 

public static final int BRIGHTNESS_ON = 255;

文件:frameworks/base/core/java/Android/os/PowerManager.java

/** 
 
     * sets the brightness of the backlights (screen, keyboard, button). 
 
     * 
 
     * @param brightness value from 0 to 255 
 
     * 
 
     * {@hide} 
 
     */  
  
    public void setBacklightBrightness(int brightness)  
  
    {  
  
        try {  
  
            mService.setBacklightBrightness(brightness);  
  
        } catch (RemoteException e) {  
  
        }  
  
}  

電源管理器(powermager)將brightness轉(zhuǎn)給電源服務(wù),該服務(wù)位置如下:

文件:frameworks/base/services/java/com/Android/server/PowerManagerService.java

public void setBacklightBrightness(int brightness) {  
  
        mContext.enforceCallingOrSelfPermission(Android.Manifest.permission.DEVICE_POWER, null);  
  
        // Don't let applications turn the screen all the way off  
  
        brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);  
  
        mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BACKLIGHT, brightness,  
  
                HardwareService.BRIGHTNESS_MODE_USER);  
  
        mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD,  
  
            (mKeyboardVisible ? brightness : 0), HardwareService.BRIGHTNESS_MODE_USER);  
  
        mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, brightness,  
  
            HardwareService.BRIGHTNESS_MODE_USER);  
  
        long identity = Binder.clearCallingIdentity();  
  
        try {  
  
            mBatteryStats.noteScreenBrightness(brightness);  
  
        } catch (RemoteException e) {  
  
            Log.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);  
  
        } finally {  
  
            Binder.restoreCallingIdentity(identity);  
  
        }  
  
        // update our animation state  
  
        if (ANIMATE_SCREEN_LIGHTS) {  
  
            mScreenBrightness.curValue = brightness;  
  
            mScreenBrightness.animating = false;  
  
            mScreenBrightness.targetValue = -1;  
  
        }  
  
        if (ANIMATE_KEYBOARD_LIGHTS) {  
  
            mKeyboardBrightness.curValue = brightness;  
  
            mKeyboardBrightness.animating = false;  
  
            mKeyboardBrightness.targetValue = -1;  
  
        }  
  
        if (ANIMATE_BUTTON_LIGHTS) {  
  
            mButtonBrightness.curValue = brightness;  
  
            mButtonBrightness.animating = false;  
  
            mButtonBrightness.targetValue = -1;  
  
        }  
  
    }  

由以上代碼可知则奥,同時(shí)設(shè)置了背光考润、鍵盤、按鈕的亮度逞度。mHardware 是硬件服務(wù)额划,通過(guò)該服務(wù)調(diào)用底層與設(shè)備打交道的C\C++代碼,setLightBrightness_UNCHECKED原型如下:

文件:frameworks/base/services\java\com\Android\server\HardwareService.java

void setLightBrightness_UNCHECKED(int light, int brightness, int brightnessMode) {  
  
        int b = brightness & 0x000000ff;  
  
        b = 0xff000000 | (b << 16) | (b << 8) | b;  
  
        setLight_native(mNativePointer, light, b, LIGHT_FLASH_NONE, 0, 0, brightnessMode);  
  
    }  

參數(shù)說(shuō)明:int light 表示類型档泽,選項(xiàng)如下:

static final int LIGHT_ID_BACKLIGHT = 0;

static final int LIGHT_ID_KEYBOARD = 1; 

static final int LIGHT_ID_BUTTONS = 2; 
static final int LIGHT_ID_BATTERY = 3; 

static final int LIGHT_ID_NOTIFICATIONS = 4; 

static final int LIGHT_ID_ATTENTION = 5;

int brightness 表示亮度值

int brightnessMode 表示亮度的控制模式俊戳,選項(xiàng)如下:

/**

 * Light brightness is managed by a user setting. 

 */ 

static final int BRIGHTNESS_MODE_USER = 0; 

/** 

 * Light brightness is managed by a light sensor. 

 */ 

static final int BRIGHTNESS_MODE_SENSOR = 1;

由代碼:

int b = brightness & 0x000000ff;

    b = 0xff000000 | (b << 16) | (b <<![image](http://upload-images.jianshu.io/upload_images/6455097-06496e56f4b158c0.gif?imageMogr2/auto-orient/strip)

| b;

可知,亮度值在此進(jìn)行了修改馆匿,即亮度值的格式變成:FFRRGGBB抑胎,F(xiàn)F是沒(méi)有的,RR渐北、GG阿逃、BB分別是256色的紅綠藍(lán),并且紅綠藍(lán)的值都是一樣的亮度值。

3 硬件調(diào)用
3.1獲取硬件
文件:frameworks/base/services/jni/com_Android_server_HardwareService.cpp

enum {  
  
    LIGHT_INDEX_BACKLIGHT = 0,  
  
    LIGHT_INDEX_KEYBOARD = 1,  
  
    LIGHT_INDEX_BUTTONS = 2,  
  
    LIGHT_INDEX_BATTERY = 3,  
  
    LIGHT_INDEX_NOTIFICATIONS = 4,  
  
    LIGHT_INDEX_ATTENTION = 5,  
  
    LIGHT_COUNT  
  
};  
  
#define LIGHTS_HARDWARE_MODULE_ID "lights"  
  
static jint init_native(JNIEnv *env, jobject clazz)  
  
{  
  
    int err;  
  
    hw_module_t* module;  
  
    Devices* devices;  
  
     
  
    devices = (Devices*)malloc(sizeof(Devices));  
  
    err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);  
  
    if (err == 0) {  
  
        devices->lights[LIGHT_INDEX_BACKLIGHT]  
  
                = get_device(module, LIGHT_ID_BACKLIGHT);  
  
        devices->lights[LIGHT_INDEX_KEYBOARD]  
  
                = get_device(module, LIGHT_ID_KEYBOARD);  
  
        devices->lights[LIGHT_INDEX_BUTTONS]  
  
                = get_device(module, LIGHT_ID_BUTTONS);  
  
        devices->lights[LIGHT_INDEX_BATTERY]  
  
                = get_device(module, LIGHT_ID_BATTERY);  
  
        devices->lights[LIGHT_INDEX_NOTIFICATIONS]  
  
                = get_device(module, LIGHT_ID_NOTIFICATIONS);  
  
        devices->lights[LIGHT_INDEX_ATTENTION]  
  
                = get_device(module, LIGHT_ID_ATTENTION);  
  
    } else {  
  
        memset(devices, 0, sizeof(Devices));  
  
    }  
  
    return (jint)devices;  
  
}  

用hw_get_module獲取ID為L(zhǎng)IGHTS_HARDWARE_MODULE_ID的硬件模塊恃锉,該模塊含有6個(gè)不同類型的亮度控制搀菩。

hw_get_module 的實(shí)現(xiàn)原理,如下:

文件:hardware/libhardware/Hardware.c

#define HAL_LIBRARY_PATH "/system/lib/hw"  
  
static const char *variant_keys[] = {  
  
    "ro.hardware",  /* This goes first so that it can pick up a different 
 
                       file on the emulator. */  
  
    "ro.product.board",  
  
    "ro.board.platform",  
  
    "ro.arch"  
  
};  
  
static const int HAL_VARIANT_KEYS_COUNT =  
  
    (sizeof(variant_keys)/sizeof(variant_keys[0]));  
  
int hw_get_module(const char *id, const struct hw_module_t **module)  
  
{  
  
    int status;  
  
    int i;  
  
    const struct hw_module_t *hmi = NULL;  
  
    char prop[PATH_MAX];  
  
    char path[PATH_MAX];  
  
    /* 
 
     * Here we rely on the fact that calling dlopen multiple times on 
 
     * the same .so will simply increment a refcount (and not load 
 
     * a new copy of the library). 
 
     * We also assume that dlopen() is thread-safe. 
 
     */  
  
    /* Loop through the configuration variants looking for a module */  
  
    for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {  
  
        if (i < HAL_VARIANT_KEYS_COUNT) {  
  
            if (property_get(variant_keys[i], prop, NULL) == 0) {  
  
                continue;  
  
            }  
  
            snprintf(path, sizeof(path), "%s/%s.%s.so",  
  
                    HAL_LIBRARY_PATH, id, prop);  
  
        } else {  
  
            snprintf(path, sizeof(path), "%s/%s.default.so",  
  
                    HAL_LIBRARY_PATH, id);  
  
        }  
  
        if (access(path, R_OK)) {  
  
            continue;  
  
        }  
  
        /* we found a library matching this id/variant */  
  
        break;  
  
    }  
  
    status = -ENOENT;  
  
    if (i < HAL_VARIANT_KEYS_COUNT+1) {  
  
        /* load the module, if this fails, we're doomed, and we should not try 
 
         * to load a different variant. */  
  
        status = load(id, path, module);  
  
    }  
  
    return status;  
  
}  

property_get(variant_keys[i], prop, NULL) 會(huì)按如下順序去獲取如下變量所對(duì)應(yīng)的值破托,然后返回給prop:

"ro.hardware", /* This goes first so that it can pick up a different

                   file on the emulator. */ 

"ro.product.board", 

"ro.board.platform", 

"ro.arch"

它們對(duì)應(yīng)的變量為:

"ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"

"ro.board.platform=$TARGET_BOARD_PLATFORM"

如vendor/htc/dream-open/BoardConfig.mk里定義的TARGET_BOARD_PLATFORM := msm7k肪跋,則prop返回” msm7k ”,所以path = /system/lib/hw/lights. msm7k.so土砂,也就是說(shuō)要獲取的硬件模塊為lights. msm7k.so州既。

3.2調(diào)用硬件

setLight_native對(duì)應(yīng)的jni C/C++代碼是:

文件:frameworks/base/services/jni/com_Android_server_HardwareService.cpp

static void setLight_native(JNIEnv *env, jobject clazz, int ptr,  
        int light, int colorARGB, int flashMode, int onMS, int offMS, int brightnessMode)  
  
{  
  
    Devices* devices = (Devices*)ptr;  
  
    light_state_t state;  
  
    if (light < 0 || light >= LIGHT_COUNT || devices->lights[light] == NULL) {  
  
        return ;  
  
    }  
  
    memset(&state, 0, sizeof(light_state_t));  
  
    state.color = colorARGB;  
  
    state.flashMode = flashMode;  
  
    state.flashOnMS = onMS;  
  
    state.flashOffMS = offMS;  
  
    state.brightnessMode = brightnessMode;  
  
    devices->lights[light]->set_light(devices->lights[light], &state);  
  
}  

通過(guò)light標(biāo)識(shí)找到對(duì)應(yīng)的light設(shè)備,然后再設(shè)置亮度萝映。

3.3 硬件原型
msm7k的lights對(duì)應(yīng)的硬件原型是在:hardware/msm7k/liblights

文件:hardware/msm7k/liblights/Android.mk

LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw

LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM)

也就是生成模塊:/system/lib/hw/lights. msm7k.so

文件:hardware/msm7k/liblights/lights.c

/** Open a new instance of a lights device using name */  
  
static int open_lights(const struct hw_module_t* module, char const* name,  
  
        struct hw_device_t** device)  
  
{  
  
    int (*set_light)(struct light_device_t* dev,  
  
            struct light_state_t const* state);  
  
    if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {  
  
        set_light = set_light_backlight;  
  
    }  
  
    else if (0 == strcmp(LIGHT_ID_KEYBOARD, name)) {  
  
        set_light = set_light_keyboard;  
  
    }  
  
    else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {  
  
        set_light = set_light_buttons;  
  
    }  
  
    else if (0 == strcmp(LIGHT_ID_BATTERY, name)) {  
  
        set_light = set_light_battery;  
  
    }  
  
    else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name)) {  
  
        set_light = set_light_notifications;  
  
    }  
  
    else if (0 == strcmp(LIGHT_ID_ATTENTION, name)) {  
  
        set_light = set_light_attention;  
  
    }  
  
    else {  
  
        return -EINVAL;  
  
    }  
  
    pthread_once(&g_init, init_globals);  
  
    struct light_device_t *dev = malloc(sizeof(struct light_device_t));  
  
    memset(dev, 0, sizeof(*dev));  
  
    dev->common.tag = HARDWARE_DEVICE_TAG;  
  
    dev->common.version = 0;  
  
    dev->common.module = (struct hw_module_t*)module;  
  
    dev->common.close = (int (*)(struct hw_device_t*))close_lights;  
  
    dev->set_light = set_light;  
  
    *device = (struct hw_device_t*)dev;  
  
    return 0;  
  
}  
  
static struct hw_module_methods_t lights_module_methods = {  
  
    .open =  open_lights,  
  
};  

以上代碼對(duì)應(yīng)的是:

devices->lights[LIGHT_INDEX_BACKLIGHT]

            = get_device(module, LIGHT_ID_BACKLIGHT); 

    devices->lights[LIGHT_INDEX_KEYBOARD] 

            = get_device(module, LIGHT_ID_KEYBOARD); 

    devices->lights[LIGHT_INDEX_BUTTONS] 

            = get_device(module, LIGHT_ID_BUTTONS); 

    devices->lights[LIGHT_INDEX_BATTERY] 

            = get_device(module, LIGHT_ID_BATTERY); 

    devices->lights[LIGHT_INDEX_NOTIFICATIONS] 

            = get_device(module, LIGHT_ID_NOTIFICATIONS); 

    devices->lights[LIGHT_INDEX_ATTENTION] 

            = get_device(module, LIGHT_ID_ATTENTION); 

也就是說(shuō)吴叶,對(duì)不同的亮度設(shè)置給予了不同的設(shè)置函數(shù)。

舉例序臂,背光設(shè)置蚌卤,背光對(duì)應(yīng)的代碼如下:

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寫入亮度值,然后驅(qū)動(dòng)會(huì)根據(jù)該文件更改背光的亮度贸宏。LCD_FILE的路徑根據(jù)實(shí)際情況更改造寝,同時(shí)需要在init.rc 修改其權(quán)限,使其可寫rgb_to_brightness也根據(jù)實(shí)際更改吭练,比如要直接亮度值控制诫龙,那只要獲取r,g,b其中的一個(gè)值就行了,如:

static int

rgb_to_brightness(struct light_state_t const* state)

{

int color = state->color & 0x000000ff; 

return color; 

}

4鲫咽,led類驅(qū)動(dòng)

4.1签赃,驅(qū)動(dòng)創(chuàng)建leds類,系統(tǒng)啟動(dòng)時(shí)執(zhí)行l(wèi)eds_init在目錄/sys/class/創(chuàng)建子目錄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锦聊,調(diào)用這個(gè)函數(shù)就在目錄/sys/class/leds創(chuàng)建子目錄led_cdev->name和屬性文件brightness

對(duì)brightness文件寫就執(zhí)行l(wèi)ed_brightness_store,對(duì)brightness文件讀就執(zhí)行l(wèi)ed_brightness_show箩绍,為下面的lcd孔庭,led注冊(cè)做好準(zhǔn)備

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驅(qū)動(dòng)調(diào)用led_classdev_register材蛛,在目錄/sys/class/leds創(chuàng)建子目錄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;  
 }  

就在目錄/sys/class/leds創(chuàng)建子目錄 lcd-backlight和屬性文件brightness

當(dāng)按鍵或者來(lái)的或者改變lcd亮度時(shí)圆到,上層對(duì)屬性文件/sys/class/leds/lcd-backlight/brightness寫入背光的亮度數(shù)值就

調(diào)用led_brightness_store

調(diào)用simple_strtoul(buf, &after, 10);將輸入的字符串轉(zhuǎn)換為10進(jìn)制的數(shù)字
執(zhí)行l(wèi)ed_set_brightness

執(zhí)行l(wèi)ed_cdev->brightness_set(led_cdev, value

調(diào)用msm_fb_set_bl_brightness ,因?yàn)? .brightness_set = msm_fb_set_bl_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);
將輸入的0--255轉(zhuǎn)換為IC的0--bl_max

調(diào)用 msm_fb_set_backlight(mfd, bl_lvl, 1);

最終改變LCD的背光驅(qū)動(dòng)電路的設(shè)置卑吭,調(diào)節(jié)LCD的背光的亮度

4.4 鍵盤背光燈

上層對(duì)屬性文件/sys/class/leds/keyboard-backlight/brightness寫入背光的亮度數(shù)值

(kernel\drivers\leds\Leds-msm-pmic.c

#define MAX_KEYPAD_BL_LEVEL 16  
  
static void msm_keypad_bl_led_set(struct led_classdev *led_cdev,  
 enum led_brightness value)  
{  
 int ret;  
  
 ret = pmic_set_led_intensity(LED_KEYPAD, value / MAX_KEYPAD_BL_LEVEL);  
 if (ret)  
  dev_err(led_cdev->dev, "can't set keypad backlight\n");  
}  
  
static struct led_classdev msm_kp_bl_led = {  
 .name   = "keyboard-backlight",  
 .brightness_set  = msm_keypad_bl_led_set,  
 .brightness  = LED_OFF,  
};  
  
static int msm_pmic_led_probe(struct platform_device *pdev)  
{  
 int rc;  
  
 rc = led_classdev_register(&pdev->dev, &msm_kp_bl_led);  
 if (rc) {  
  dev_err(&pdev->dev, "unable to register led class driver\n");  
  return rc;  
 }  
 msm_keypad_bl_led_set(&msm_kp_bl_led, LED_OFF);  
 return rc;  
}  
  
static int __devexit msm_pmic_led_remove(struct platform_device *pdev)  
{  
 led_classdev_unregister(&msm_kp_bl_led);  
  
 return 0;  
}  
  
#ifdef CONFIG_PM  
static int msm_pmic_led_suspend(struct platform_device *dev,  
  pm_message_t state)  
{  
 led_classdev_suspend(&msm_kp_bl_led);  
  
 return 0;  
}  
  
static int msm_pmic_led_resume(struct platform_device *dev)  
{  
 led_classdev_resume(&msm_kp_bl_led);  
  
 return 0;  
}  
#else  
#define msm_pmic_led_suspend NULL  
#define msm_pmic_led_resume NULL  
#endif  
  
static struct platform_driver msm_pmic_led_driver = {  
 .probe  = msm_pmic_led_probe,  
 .remove  = __devexit_p(msm_pmic_led_remove),  
 .suspend = msm_pmic_led_suspend,  
 .resume  = msm_pmic_led_resume,  
 .driver  = {  
  .name = "pmic-leds",  
  .owner = THIS_MODULE,  
 },  
};  
  
static int __init msm_pmic_led_init(void)  
{  
 return platform_driver_register(&msm_pmic_led_driver);  
}  
module_init(msm_pmic_led_init);  
  
static void __exit msm_pmic_led_exit(void)  
{  
 platform_driver_unregister(&msm_pmic_led_driver);  
}  
module_exit(msm_pmic_led_exit);  

MODULE_DESCRIPTION("MSM PMIC LEDs driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:p
系統(tǒng)行動(dòng)執(zhí)行msm_pmic_led_init(void)
調(diào)用 platform_driver_register(&msm_pmic_led_driver);

調(diào)用msm_pmic_led_probe

調(diào)用 led_classdev_register(&pdev->dev, &msm_kp_bl_led);

就在目錄/sys/class/leds創(chuàng)建子目錄 keyboard-backlight和屬性文件brightness
當(dāng)按鍵時(shí)芽淡,上層對(duì)屬性文件/sys/class/leds/keyboard-backlight/brightness寫入背光的亮度數(shù)值就

調(diào)用led_brightness_store

調(diào)用simple_strtoul(buf, &after, 10);將輸入的字符串轉(zhuǎn)換為10進(jìn)制的數(shù)字

執(zhí)行l(wèi)ed_set_brightness

執(zhí)行l(wèi)ed_cdev->brightness_set(led_cdev, value

調(diào)用msm_keypad_bl_led_set ,因?yàn)?.brightness_set = msm_keypad_bl_led_set,

調(diào)用 ret = pmic_set_led_intensity(LED_KEYPAD, value / MAX_KEYPAD_BL_LEVEL);
最終改變LED驅(qū)動(dòng)電路的設(shè)置豆赏,調(diào)節(jié)LED的亮度

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挣菲,一起剝皮案震驚了整個(gè)濱河市富稻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌白胀,老刑警劉巖椭赋,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異或杠,居然都是意外死亡纹份,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門廷痘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人件已,你說(shuō)我怎么就攤上這事笋额。” “怎么了篷扩?”我有些...
    開(kāi)封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵兄猩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我鉴未,道長(zhǎng)枢冤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任铜秆,我火速辦了婚禮淹真,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘连茧。我一直安慰自己核蘸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布啸驯。 她就那樣靜靜地躺著客扎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪罚斗。 梳的紋絲不亂的頭發(fā)上徙鱼,一...
    開(kāi)封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音针姿,去河邊找鬼袱吆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛搓幌,可吹牛的內(nèi)容都是我干的杆故。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼溉愁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼处铛!你這毒婦竟也來(lái)了饲趋?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤撤蟆,失蹤者是張志新(化名)和其女友劉穎奕塑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體家肯,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡龄砰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了讨衣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片换棚。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖反镇,靈堂內(nèi)的尸體忽然破棺而出固蚤,到底是詐尸還是另有隱情,我是刑警寧澤歹茶,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布夕玩,位于F島的核電站,受9級(jí)特大地震影響惊豺,放射性物質(zhì)發(fā)生泄漏燎孟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一尸昧、第九天 我趴在偏房一處隱蔽的房頂上張望揩页。 院中可真熱鬧,春花似錦彻磁、人聲如沸碍沐。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)累提。三九已至,卻和暖如春磁浇,著一層夾襖步出監(jiān)牢的瞬間斋陪,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工置吓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留无虚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓衍锚,卻偏偏與公主長(zhǎng)得像友题,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子戴质,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 我們按下電源鍵就會(huì)滅屏度宦,再按一下就會(huì)喚醒屏幕踢匣,這個(gè)是怎樣的過(guò)程呢。 電源鍵有許多額外功能戈抄,為了能讓這個(gè)主題更加清晰...
    CocoDoll閱讀 6,347評(píng)論 0 7
  • 可以通過(guò)echo(寫)和cat(讀)來(lái)設(shè)置背光亮度 E:\adbTools>adb shell MeizuM8cL...
    超__越閱讀 1,400評(píng)論 0 0
  • pull 到電腦的當(dāng)前路徑下 push 到安卓系統(tǒng)文件路徑 查看sdcard剩余存儲(chǔ)空間 檢查文件系統(tǒng)的磁盤空間占...
    Amano閱讀 13,982評(píng)論 1 6
  • #風(fēng)光水韻# 太陽(yáng)自律地 躲進(jìn)大地的懷里 灑下他熱烈的吻 好多親著湖的臉龐 風(fēng)搖動(dòng)著水 跳躍的舞動(dòng)的歡呼的 喜悅化...
    青霜王閱讀 138評(píng)論 0 1
  • 今天离唬,陪兒子去省圖書館,我也是第一次去划鸽。 回想上一次去圖書館還是在大學(xué)的時(shí)候输莺,畢業(yè)十余年,每每夢(mèng)回校園裸诽,也曾夢(mèng)到過(guò)...
    長(zhǎng)白雪0924閱讀 299評(píng)論 0 1