在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;
}
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;
}
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 */
};