在3.14.28内核中背光控制相关的模块如下图所示
在pwm子系统加入渐变;
新增接口compute_duty_cycle_gradual(输入为两个亮度等级之间的pwm等级分为n级,输出为n级内第m级的pwm等级);
修改接口pwm_backlight_update_status(输入为pwm等级,渐变时间)
原始接口compute_duty_cycle
static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness) { unsigned int lth = pb->lth_brightness; int duty_cycle; if (pb->levels) duty_cycle = pb->levels[brightness]; else duty_cycle = brightness; return (duty_cycle * (pb->period - lth) / pb->scale) + lth; }
新增接口compute_duty_cycle_gradual 接口代码如下
static int compute_duty_cycle_gradual(struct pwm_bl_data *pb, int brightness, int old_brightness, int cur_range, int total_range) { unsigned int lth = pb->lth_brightness; int duty_cycle; int old_duty_cycle; int i_gap; int i_range; if (pb->levels) { duty_cycle = pb->levels[brightness]; old_duty_cycle = pb->levels[old_brightness]; } else { duty_cycle = brightness; } duty_cycle = duty_cycle * 100; old_duty_cycle = old_duty_cycle * 100; i_gap = duty_cycle - old_duty_cycle; i_range = i_gap / total_range; duty_cycle = (old_duty_cycle + i_range * cur_range) / 100; return (duty_cycle * (pb->period - lth) / pb->scale) + lth; }
同步修改的pwm_backlight_update_status接口
static int pwm_backlight_update_status(struct backlight_device *bl) { struct pwm_bl_data *pb = bl_get_data(bl); int brightness = bl->props.brightness; int old_brightness = bl->props.old_brightness; int duty_cycle; int total_range; int cur_range; if (bl->props.power != FB_BLANK_UNBLANK || bl->props.fb_blank != FB_BLANK_UNBLANK || bl->props.state & BL_CORE_FBBLANK) brightness = 0; if (pb->notify) brightness = pb->notify(pb->dev, brightness); total_range = 20; for (cur_range = 1; cur_range <= total_range; cur_range++) { if (brightness > 0) { //duty_cycle = compute_duty_cycle(pb, brightness); duty_cycle = compute_duty_cycle_gradual(pb, brightness, old_brightness, cur_range, total_range); pwm_config(pb->pwm, duty_cycle, pb->period); pwm_backlight_power_on(pb, brightness); } else { // pwm_backlight_power_off(pb); duty_cycle = compute_duty_cycle_gradual(pb, brightness, old_brightness, cur_range, total_range); pwm_config(pb->pwm, duty_cycle, pb->period); pwm_backlight_power_on(pb, brightness); } if (pb->notify_after) pb->notify_after(pb->dev, brightness); msleep(8); } bl->props.old_brightness = brightness; if (brightness == 0) { pwm_backlight_power_off(pb); } return 0; }
此外在还要增加一个记录上次背光亮度等级的变量 old_brightness
struct backlight_properties { /* Current User requested brightness (0 - max_brightness) */ int brightness; /* Maximal value for brightness (read-only) */ int max_brightness; /* Current FB Power mode (0: full on, 1..3: power saving modes; 4: full off), see FB_BLANK_XXX */ int power; /* FB Blanking active? (values as for power) */ /* Due to be removed, please use (state & BL_CORE_FBBLANK) */ int fb_blank; /* Backlight type */ enum backlight_type type; /* Flags used to signal drivers of state changes */ /* Upper 4 bits are reserved for driver internal use */ unsigned int state; /* add by bi xiongqin for backlight gradual */ int old_brightness; #define BL_CORE_SUSPENDED (1 << 0) /* backlight is suspended */ #define BL_CORE_FBBLANK (1 << 1) /* backlight is under an fb blank event */ #define BL_CORE_DRIVER4 (1 << 28) /* reserved for driver specific use */ #define BL_CORE_DRIVER3 (1 << 29) /* reserved for driver specific use */ #define BL_CORE_DRIVER2 (1 << 30) /* reserved for driver specific use */ #define BL_CORE_DRIVER1 (1 << 31) /* reserved for driver specific use */ };