关于Android LCD和键盘背光亮度

来源:互联网 发布:淘宝360手柄 编辑:程序博客网 时间:2024/04/30 00:05

 应用设计

1.1 设置进度条范围

背光设置是在:设置->声音和显示->亮度,通过进度条来设置的。

 

文件: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);

 下面说的有误:

设置进度条的范围,BRIGHTNESS_DIM = 20  BRIGHTNESS_ON=255,它们的定义在:

应该是上面的:MINIMUM_BACKLIGHT ,MAXIMUM_BACKLIGHT 的值才对

 

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

 

1.2 设置亮度

文件: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;代码通过服务管理器(ServiceManager)获得power服务,然后通过power服务设置亮度。

 

power.setBacklightBrightness的定义在:

 

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

 

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

 

实现IPowerManager.aidl.java的类:

/frameworks/base/services/java/com/android/server/PowerManagerService.java

 

2, Power服务

文件: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转给电源服务,该服务位置如下:

 

文件: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;

 

        }

 

    }

 

由以上代码可知,同时设置了背光、键盘、按钮的亮度。mHardware 是硬件服务,通过该服务调用底层与设备打交道的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);

 

    }

    

    参数说明:int light 表示类型,选项如下:

 

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 表示亮度的控制模式,选项如下:

 

/**

 

     * 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 << 8) | b;

 

可知,亮度值在此进行了修改,即亮度值的格式变成:FFRRGGBB,FF是没有的,RR、GG、BB分别是256色的红绿蓝,并且红绿蓝的值都是一样的亮度值。

 

3 硬件调用

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为LIGHTS_HARDWARE_MODULE_ID的硬件模块,该模块含有6个不同类型的亮度控制。

 

hw_get_module 的实现原理,如下:

 

文件: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) 会按如下顺序去获取如下变量所对应的值,然后返回给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"

 

它们对应的变量为:

 

"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,也就是说要获取的硬件模块为lights. msm7k.so。

 

 

3.2调用硬件

 

setLight_native对应的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);

 

}

 

通过light标识找到对应的light设备,然后再设置亮度。

 

3.3 硬件原型

msm7k的lights对应的硬件原型是在: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,

 

};

 

以上代码对应的是:

 

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

 

也就是说,对不同的亮度设置给予了不同的设置函数。

 

 

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

 

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;

 }

 

 

 就在目录/sys/class/leds创建子目录 lcd-backlight和属性文件brightness

 

当按键或者来的或者改变lcd亮度时,上层对属性文件/sys/class/leds/lcd-backlight/brightness写入背光的亮度数值就

 

调用led_brightness_store

 

调用simple_strtoul(buf, &after, 10);将输入的字符串转换为10进制的数字

执行led_set_brightness

 

执行led_cdev->brightness_set(led_cdev, value

 

调用msm_fb_set_bl_brightness ,因为  .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转换为IC的0--bl_max

 

调用 msm_fb_set_backlight(mfd, bl_lvl, 1);

 

最终改变LCD的背光驱动电路的设置,调节LCD的背光的亮度

 

4.4 键盘背光灯

 

上层对属性文件/sys/class/leds/keyboard-backlight/brightness写入背光的亮度数值

 

(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

 

系统行动执行msm_pmic_led_init(void)

调用 platform_driver_register(&msm_pmic_led_driver);

 

调用msm_pmic_led_probe

 

调用 led_classdev_register(&pdev->dev, &msm_kp_bl_led);

 

就在目录/sys/class/leds创建子目录 keyboard-backlight和属性文件brightness

当按键时,上层对属性文件/sys/class/leds/keyboard-backlight/brightness写入背光的亮度数值就

 

调用led_brightness_store

 

调用simple_strtoul(buf, &after, 10);将输入的字符串转换为10进制的数字

 

执行led_set_brightness

 

执行led_cdev->brightness_set(led_cdev, value

 

调用msm_keypad_bl_led_set ,因为 .brightness_set  = msm_keypad_bl_led_set,

 

调用 ret = pmic_set_led_intensity(LED_KEYPAD, value / MAX_KEYPAD_BL_LEVEL);

最终改变LED驱动电路的设置,调节LED的亮度


原创粉丝点击