liblights: Scale brightness if necessary
authorChristopher N. Hesse <raymanfx@gmail.com>
Mon, 5 Dec 2016 21:11:55 +0000 (22:11 +0100)
committerChristopher N. Hesse <raymanfx@gmail.com>
Mon, 30 Jan 2017 22:02:16 +0000 (22:02 +0000)
Change-Id: Ia9fdbe0c0f709e8e2e16f9cd2fb757c6f53e7c50

liblights/include/samsung_lights.h
liblights/lights.c

index b853b0ed92f1b5c10829cfda09c6da3f9cec5cfe..ab0630e8dceae69193089a86b4c055753533af06 100644 (file)
@@ -25,6 +25,7 @@
  * device tree.
  */
 #define PANEL_BRIGHTNESS_NODE "/sys/class/backlight/panel/brightness"
+#define PANEL_MAX_BRIGHTNESS_NODE "/sys/class/backlight/panel/max_brightness"
 #define BUTTON_BRIGHTNESS_NODE "/sys/class/sec/sec_touchkey/brightness"
 #define LED_BLINK_NODE "/sys/class/sec/led/led_blink"
 
index 6da32e2e768f8ac1e406374e431704162c3cbd4e..14946c5c5e5f021e3fdf00316c262b99a0d6f60a 100644 (file)
 
 #define COLOR_MASK 0x00ffffff
 
+#define MAX_INPUT_BRIGHTNESS 255
+
 static pthread_once_t g_init = PTHREAD_ONCE_INIT;
 static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
 
+struct backlight_config {
+    int cur_brightness, max_brightness;
+};
+
 struct led_config {
     unsigned int color;
     int delay_on, delay_off;
 };
 
+static struct backlight_config g_backlight; // For panel backlight
 static struct led_config g_leds[3]; // For battery, notifications, and attention.
 static int g_cur_led = -1;          // Presently showing LED of the above.
 
@@ -51,6 +58,38 @@ void init_g_lock(void)
     pthread_mutex_init(&g_lock, NULL);
 }
 
+static int read_int(char const *path)
+{
+    int fd, len;
+    int num_bytes = 10;
+    char buf[11];
+    int retval;
+
+    fd = open(path, O_RDONLY);
+    if (fd < 0) {
+        ALOGE("%s: failed to open %s\n", __func__, path);
+        goto fail;
+    }
+
+    len = read(fd, buf, num_bytes - 1);
+    if (len < 0) {
+        ALOGE("%s: failed to read from %s\n", __func__, path);
+        goto fail;
+    }
+
+    buf[len] = '\0';
+    close(fd);
+
+    // no endptr, decimal base
+    retval = strtol(buf, NULL, 10);
+    return retval == 0 ? -1 : retval;
+
+fail:
+    if (fd >= 0)
+        close(fd);
+    return -1;
+}
+
 static int write_int(char const *path, int value)
 {
     int fd;
@@ -112,9 +151,23 @@ static int set_light_backlight(struct light_device_t *dev __unused,
 {
     int err = 0;
     int brightness = rgb_to_brightness(state);
+    int max_brightness = g_backlight.max_brightness;
+
+    /*
+     * If our max panel brightness is > 255, apply linear scaling across the
+     * accepted range.
+     */
+    if (max_brightness > MAX_INPUT_BRIGHTNESS) {
+        int old_brightness = brightness;
+        brightness = brightness * max_brightness / MAX_INPUT_BRIGHTNESS;
+        ALOGV("%s: scaling brightness %d => %d\n", __func__,
+            old_brightness, brightness);
+    }
 
     pthread_mutex_lock(&g_lock);
     err = write_int(PANEL_BRIGHTNESS_NODE, brightness);
+    if (err == 0)
+        g_backlight.cur_brightness = brightness;
 
     pthread_mutex_unlock(&g_lock);
     return err;
@@ -306,6 +359,14 @@ static int open_lights(const struct hw_module_t *module, char const *name,
     else
         return -EINVAL;
 
+    int max_brightness = read_int(PANEL_MAX_BRIGHTNESS_NODE);
+    if (max_brightness < 0) {
+        ALOGE("%s: failed to read max panel brightness, fallback to 255!",
+            __func__);
+        max_brightness = 255;
+    }
+    g_backlight.max_brightness = max_brightness;
+
     pthread_once(&g_init, init_g_lock);
 
     struct light_device_t *dev = malloc(sizeof(struct light_device_t));