linux背光系统--背光渐变

在3.14.28内核中背光控制相关的模块如下图所示

在pwm子系统加入渐变;

新增接口compute_duty_cycle_gradual(输入为两个亮度等级之间的pwm等级分为n级,输出为n级内第m级的pwm等级);

修改接口pwm_backlight_update_status(输入为pwm等级,渐变时间)

linux背光系统--背光渐变_第1张图片


原始接口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 */

};


你可能感兴趣的:(背光系统)