Commit f40f2dc0 authored by spiiroin's avatar spiiroin

Use ambient light sensor to tune display brightness in lpm_on state

Add ALS profile configuration for use with lpm_on state. Should stay
relatively dim indoors, saturates to 100% brightness at the same level
as lowest display brightness profile.

Setup a datapipe for communicating lpm brightness changes between display
and brightness filtering plugins.

Set standby override flag for ambient light sensor so that it can be
powered on in lpm_on state too.

[mce] Use ambient light sensor to tune display brightness in lpm_on state. Fixes JB#18791
parent 0617156b
......@@ -81,3 +81,8 @@ LevelsProfile0=30;33;36;39;42;45;48;51;54;57;64;68;72;76;80;84;88;92;96;100
LimitsProfile0=1;2;3;6;11;20;36;66;121;220;489;599;732;896;1095;1340;1639;2005;2453;3000
LevelsProfile0=30;33;36;39;42;45;48;51;54;57;64;68;72;76;80;84;88;92;96;100
[BrightnessLPM]
LimitsProfile0=1;4;27;99;700;778;864;960;1066;1184;1315;1460;1622;1801;2000
LevelsProfile0=1;2;3;4;5;15;24;34;43;53;62;72;81;91;100
......@@ -940,6 +940,14 @@ static void mce_sensorfw_als_start_sensor(void)
if( !mce_sensorfw_start_sensor(als_name, als_iface, als_sid) )
goto EXIT;
/* ALS is used in lpm display states; from sensord point of view
* this means display is off and thus we need to set the standby
* override flag */
/* No error checking here; failures will be logged when
* we get reply message from sensord */
mce_sensorfw_set_standby_override(als_name, als_iface, als_sid, true);
als_have = true;
/* There is no quarantee that we get sensor input
......
......@@ -1082,6 +1082,8 @@ int main(int argc, char **argv)
0, GINT_TO_POINTER(3));
setup_datapipe(&led_brightness_pipe, READ_WRITE, DONT_FREE_CACHE,
0, GINT_TO_POINTER(0));
setup_datapipe(&lpm_brightness_pipe, READ_WRITE, DONT_FREE_CACHE,
0, GINT_TO_POINTER(0));
setup_datapipe(&led_pattern_activate_pipe, READ_ONLY, FREE_CACHE,
0, NULL);
setup_datapipe(&led_pattern_deactivate_pipe, READ_ONLY, FREE_CACHE,
......@@ -1266,6 +1268,7 @@ EXIT:
free_datapipe(&led_pattern_deactivate_pipe);
free_datapipe(&led_pattern_activate_pipe);
free_datapipe(&led_brightness_pipe);
free_datapipe(&lpm_brightness_pipe);
free_datapipe(&display_brightness_pipe);
free_datapipe(&display_state_pipe);
free_datapipe(&display_state_req_pipe);
......
......@@ -273,6 +273,10 @@ typedef enum {
/** LED brightness */
datapipe_struct led_brightness_pipe;
/** LPM brightness */
datapipe_struct lpm_brightness_pipe;
/** State of device; read only */
datapipe_struct device_inactive_pipe;
/** LED pattern to activate; read only */
......
......@@ -252,6 +252,7 @@ static void mdy_datapipe_submode_cb(gconstpointer data);
static gpointer mdy_datapipe_display_state_filter_cb(gpointer data);
static void mdy_datapipe_display_state_cb(gconstpointer data);
static void mdy_datapipe_display_brightness_cb(gconstpointer data);
static void mdy_datapipe_lpm_brightness_cb(gconstpointer data);
static void mdy_datapipe_display_state_req_cb(gconstpointer data);
static void mdy_datapipe_audio_route_cb(gconstpointer data);
static void mdy_datapipe_charger_state_cb(gconstpointer data);
......@@ -305,6 +306,8 @@ static void mdy_brightness_stop_fade_timer(void);
static void mdy_brightness_start_fade_timer(gint step_time);
static void mdy_brightness_set_fade_target(gint new_brightness);
static void mdy_brightness_set_on_level(gint hbm_and_level);
static void mdy_brightness_set_dim_level(void);
static void mdy_brightness_set_lpm_level(gint level);
/* ------------------------------------------------------------------------- *
* CONTENT_ADAPTIVE_BACKLIGHT_CONTROL
......@@ -1098,6 +1101,30 @@ EXIT:
return;
}
/** Handle lpm_brightness_pipe notifications
*
* @note A brightness request is only sent if the value changed
*
* @param data The display brightness stored in a pointer
*/
static void mdy_datapipe_lpm_brightness_cb(gconstpointer data)
{
static gint curr = -1;
gint prev = curr;
curr = GPOINTER_TO_INT(data);
mce_log(LL_DEBUG, "input: %d -> %d", prev, curr);
if( curr == prev )
goto EXIT;
mdy_brightness_set_lpm_level(curr);
EXIT:
return;
}
/* Cached audio routing state */
static audio_route_t audio_route = AUDIO_ROUTE_HANDSET;
......@@ -1388,6 +1415,8 @@ static void mdy_datapipe_init(void)
mdy_datapipe_display_state_cb);
append_output_trigger_to_datapipe(&display_brightness_pipe,
mdy_datapipe_display_brightness_cb);
append_output_trigger_to_datapipe(&lpm_brightness_pipe,
mdy_datapipe_lpm_brightness_cb);
append_output_trigger_to_datapipe(&charger_state_pipe,
mdy_datapipe_charger_state_cb);
......@@ -1446,6 +1475,8 @@ static void mdy_datapipe_quit(void)
mdy_datapipe_audio_route_cb);
remove_output_trigger_from_datapipe(&display_brightness_pipe,
mdy_datapipe_display_brightness_cb);
remove_output_trigger_from_datapipe(&lpm_brightness_pipe,
mdy_datapipe_lpm_brightness_cb);
remove_output_trigger_from_datapipe(&display_state_pipe,
mdy_datapipe_display_state_cb);
remove_output_trigger_from_datapipe(&display_state_req_pipe,
......@@ -1964,6 +1995,38 @@ static void mdy_brightness_set_dim_level(void)
USE_INDATA);
}
static void mdy_brightness_set_lpm_level(gint level)
{
/* Map from: 1-100% to: 1-hw_max */
int brightness = mce_xlat_int(1, 100,
1, mdy_brightness_level_maximum,
level);
mce_log(LL_DEBUG, "mdy_brightness_level_display_lpm: %d -> %d",
mdy_brightness_level_display_lpm, brightness);
mdy_brightness_level_display_lpm = brightness;
/* Take updated values in use */
switch( display_state ) {
case MCE_DISPLAY_LPM_ON:
mdy_brightness_set_fade_target(mdy_brightness_level_display_lpm);
break;
default:
case MCE_DISPLAY_OFF:
case MCE_DISPLAY_LPM_OFF:
case MCE_DISPLAY_DIM:
case MCE_DISPLAY_ON:
case MCE_DISPLAY_UNDEF:
case MCE_DISPLAY_POWER_DOWN:
case MCE_DISPLAY_POWER_UP:
break;
}
return;
}
static void mdy_brightness_set_on_level(gint hbm_and_level)
{
gint new_brightness = (hbm_and_level >> 0) & 0xff;
......@@ -2002,17 +2065,13 @@ static void mdy_brightness_set_on_level(gint hbm_and_level)
/* Re-evaluate dim brightness too */
mdy_brightness_set_dim_level();
/* Re-evaluate lpm brightness too */
// TODO: ALS config & sensor input processing
/* Note: The lpm brightness is handled separately */
/* Take updated values in use */
switch( display_state ) {
case MCE_DISPLAY_OFF:
case MCE_DISPLAY_LPM_OFF:
break;
case MCE_DISPLAY_LPM_ON:
mdy_brightness_set_fade_target(mdy_brightness_level_display_lpm);
break;
case MCE_DISPLAY_DIM:
......@@ -4338,6 +4397,15 @@ static void mdy_display_state_enter_post(void)
mdy_hbm_rethink();
mdy_orientation_sensor_rethink();
/* Determine the minimum brightness level above which to use
* smooth transitions. Since both lpm and dimmed brightness
* are now dynamic and lpm brightness can be greater than
* dimmed brightness, use: limit = min(dimmed_brightness-1, lpm)
*/
gint consider_off_level = mdy_brightness_level_display_dim - 1;
if( consider_off_level > mdy_brightness_level_display_lpm )
consider_off_level = mdy_brightness_level_display_lpm;
switch( display_state ) {
case MCE_DISPLAY_POWER_DOWN:
case MCE_DISPLAY_OFF:
......@@ -4357,7 +4425,7 @@ static void mdy_display_state_enter_post(void)
break;
case MCE_DISPLAY_DIM:
if( mdy_brightness_level_cached <= mdy_brightness_level_display_lpm ) {
if( mdy_brightness_level_cached <= consider_off_level ) {
/* If we unblank, switch on display immediately */
mdy_brightness_force_level(mdy_brightness_level_display_dim);
} else {
......@@ -4367,7 +4435,7 @@ static void mdy_display_state_enter_post(void)
break;
case MCE_DISPLAY_ON:
if( mdy_brightness_level_cached <= mdy_brightness_level_display_lpm ) {
if( mdy_brightness_level_cached <= consider_off_level ) {
/* If we unblank, switch on display immediately */
mdy_brightness_force_level(mdy_brightness_level_display_on);
} else {
......@@ -6955,6 +7023,13 @@ static void mdy_gconf_sanitize_brightness_settings(void)
mdy_brightness_level_display_on);
mce_log(LL_DEBUG, "mdy_brightness_level_display_dim = %d",
mdy_brightness_level_display_dim);
/* Drive the initial lpm brightness value through datapipe.
* Actual value will change only if sensor is enabled, producing
* input and lpm als config is in place. */
execute_datapipe(&lpm_brightness_pipe,
GINT_TO_POINTER(mdy_brightness_level_display_lpm),
USE_INDATA, CACHE_INDATA);
}
/** Get initial gconf valus and start tracking changes
......
......@@ -147,6 +147,12 @@ static als_filter_t lut_led =
.id = "Led",
};
/** ALS filtering state for low power mode display simulation */
static als_filter_t lut_lpm =
{
.id = "LPM",
};
static gboolean set_color_profile(const gchar *id);
static gboolean save_color_profile(const gchar *id);
......@@ -387,6 +393,8 @@ static void run_datapipes(void)
USE_CACHE, DONT_CACHE_INDATA);
execute_datapipe(&led_brightness_pipe, NULL,
USE_CACHE, DONT_CACHE_INDATA);
execute_datapipe(&lpm_brightness_pipe, NULL,
USE_CACHE, DONT_CACHE_INDATA);
execute_datapipe(&key_backlight_pipe, NULL,
USE_CACHE, DONT_CACHE_INDATA);
}
......@@ -447,8 +455,10 @@ static void rethink_als_status(void)
if( want_data )
mce_sensorfw_als_set_notify(als_lux_changed);
else
else {
mce_sensorfw_als_set_notify(0);
als_lux_changed(-1);
}
if( enable_old == enable_new )
goto EXIT;
......@@ -466,6 +476,7 @@ static void rethink_als_status(void)
als_filter_clear_threshold(&lut_display);
als_filter_clear_threshold(&lut_led);
als_filter_clear_threshold(&lut_key);
als_filter_clear_threshold(&lut_lpm);
}
run_datapipes();
......@@ -567,6 +578,29 @@ EXIT:
return GINT_TO_POINTER(value * scale / 100);
}
/** Ambient Light Sensor filter for LPM brightness
*
* @param data The un-processed brightness setting (1-100) stored in a pointer
* @return The processed brightness value
*/
static gpointer lpm_brightness_filter(gpointer data)
{
int value = GPOINTER_TO_INT(data);
if( lut_lpm.profiles < 1 )
goto EXIT;
if( als_lux_latest < 0 )
goto EXIT;
/* Note: Input value is ignored and output is
* determined only by the als config */
value = als_filter_run(&lut_lpm, 0, als_lux_latest);
EXIT:
return GINT_TO_POINTER(value);
}
/**
* Ambient Light Sensor filter for keyboard backlight brightness
*
......@@ -1056,6 +1090,7 @@ const gchar *g_module_check_init(GModule *module)
als_filter_load_config(&lut_display);
als_filter_load_config(&lut_led);
als_filter_load_config(&lut_key);
als_filter_load_config(&lut_lpm);
/* Get intial display state */
display_state = display_state_get();
......@@ -1065,6 +1100,8 @@ const gchar *g_module_check_init(GModule *module)
display_brightness_filter);
append_filter_to_datapipe(&led_brightness_pipe,
led_brightness_filter);
append_filter_to_datapipe(&lpm_brightness_pipe,
lpm_brightness_filter);
append_filter_to_datapipe(&key_backlight_pipe,
key_backlight_filter);
append_output_trigger_to_datapipe(&display_state_pipe,
......@@ -1139,6 +1176,8 @@ void g_module_unload(GModule *module)
key_backlight_filter);
remove_filter_from_datapipe(&led_brightness_pipe,
led_brightness_filter);
remove_filter_from_datapipe(&lpm_brightness_pipe,
lpm_brightness_filter);
remove_filter_from_datapipe(&display_brightness_pipe,
display_brightness_filter);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment