summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/backlight/pwm_bl.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index d6d2b6407d7e..746eebc411df 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -387,6 +387,31 @@ int pwm_backlight_brightness_default(struct device *dev,
}
#endif
+static bool pwm_backlight_is_linear(struct platform_pwm_backlight_data *data)
+{
+ unsigned int nlevels = data->max_brightness + 1;
+ unsigned int min_val = data->levels[0];
+ unsigned int max_val = data->levels[nlevels - 1];
+ /*
+ * Multiplying by 128 means that even in pathological cases such
+ * as (max_val - min_val) == nlevels the error at max_val is less
+ * than 1%.
+ */
+ unsigned int slope = (128 * (max_val - min_val)) / nlevels;
+ unsigned int margin = (max_val - min_val) / 20; /* 5% */
+ int i;
+
+ for (i = 1; i < nlevels; i++) {
+ unsigned int linear_value = min_val + ((i * slope) / 128);
+ unsigned int delta = abs(linear_value - data->levels[i]);
+
+ if (delta > margin)
+ return false;
+ }
+
+ return true;
+}
+
static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
{
struct device_node *node = pb->dev->of_node;
@@ -550,6 +575,11 @@ static int pwm_backlight_probe(struct platform_device *pdev)
pb->levels = data->levels;
}
+
+ if (pwm_backlight_is_linear(data))
+ props.scale = BACKLIGHT_SCALE_LINEAR;
+ else
+ props.scale = BACKLIGHT_SCALE_NON_LINEAR;
} else if (!data->max_brightness) {
/*
* If no brightness levels are provided and max_brightness is