aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhemantbeast <hemantbeast@gmail.com>2017-06-16 10:46:03 +0530
committerhemantbeast <hemantbeast@gmail.com>2017-06-16 10:46:03 +0530
commit909ae8c4e59bdf3eea23526087de13c5a34dd4eb (patch)
treeb8d1f10c92f910039ab91738a1381bafd43663d4
parentb342b5885da76a8169aecc01308e0f15006960cf (diff)
s2: refine lights and leds configs
lights hal from hardware/cyanogen Change-Id: Ie5c282c264d87aa784647f644fac5f3af82b18f8
-rw-r--r--liblight/lights.c301
-rw-r--r--overlay/frameworks/base/core/res/res/values/config.xml83
-rw-r--r--overlay/vendor/cmsdk/cm/res/res/values/config.xml5
-rwxr-xr-xrootdir/init.qcom.rc1
-rwxr-xr-xrootdir/init.target.rc21
5 files changed, 312 insertions, 99 deletions
diff --git a/liblight/lights.c b/liblight/lights.c
index 54c3de2..771955d 100644
--- a/liblight/lights.c
+++ b/liblight/lights.c
@@ -27,8 +27,8 @@
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
+#include <math.h>
-#include <sys/ioctl.h>
#include <sys/types.h>
#include <hardware/lights.h>
@@ -37,13 +37,22 @@
static pthread_once_t g_init = PTHREAD_ONCE_INIT;
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
-static struct light_state_t g_attention;
static struct light_state_t g_notification;
static struct light_state_t g_battery;
+static struct light_state_t g_attention;
char const*const RED_LED_FILE
= "/sys/class/leds/red/brightness";
+char const*const RED_BLINK_FILE
+ = "/sys/class/leds/red/blink";
+
+char const*const GREEN_BLINK_FILE
+ = "/sys/class/leds/green/blink";
+
+char const*const BLUE_BLINK_FILE
+ = "/sys/class/leds/blue/blink";
+
char const*const GREEN_LED_FILE
= "/sys/class/leds/green/brightness";
@@ -53,25 +62,124 @@ char const*const BLUE_LED_FILE
char const*const LCD_FILE
= "/sys/class/leds/lcd-backlight/brightness";
-char const*const LCD_MAX_BRIGHTNESS_FILE
- = "/sys/class/leds/lcd-backlight/max_brightness";
+char const*const RED_BREATH_FILE
+ = "/sys/class/leds/red/led_time";
+
+char const*const GREEN_BREATH_FILE
+ = "/sys/class/leds/green/led_time";
-const char*const BUTTONS_FILE
+char const*const BLUE_BREATH_FILE
+ = "/sys/class/leds/blue/led_time";
+
+char const*const BUTTON_FILE
= "/sys/class/leds/button-backlight/brightness";
-char const*const RED_BLINK_FILE
- = "/sys/class/leds/red/blink";
+struct color {
+ unsigned int r, g, b;
+ float _L, _a, _b;
+};
-char const*const GREEN_BLINK_FILE
- = "/sys/class/leds/green/blink";
+// this hardware only allows primary colors
+static struct color colors[] = {
+ { 255, 0, 0, 0, 0, 0 }, // red
+ { 255, 255, 0, 0, 0, 0 }, // yellow
+ { 0, 255, 0, 0, 0, 0 }, // green
+ { 0, 255, 255, 0, 0, 0 }, // cyan
+ { 0, 0, 255, 0, 0, 0 }, // blue
+ { 255, 0, 255, 0, 0, 0 }, // magenta
+ { 255, 255, 255, 0, 0, 0 }, // white
+ { 127, 127, 127, 0, 0, 0 }, // grey
+ { 0, 0, 0, 0, 0, 0 }, // black
+};
-char const*const BLUE_BLINK_FILE
- = "/sys/class/leds/blue/blink";
+#define MAX_COLOR 9
+
+// Convert RGB to L*a*b colorspace
+// from http://www.brucelindbloom.com
+static void rgb2lab(unsigned int R, unsigned int G, unsigned int B,
+ float *_L, float *_a, float *_b) {
+
+ float r, g, b, X, Y, Z, fx, fy, fz, xr, yr, zr;
+ float Ls, as, bs;
+ float eps = 216.f / 24389.f;
+ float k = 24389.f / 27.f;
+
+ float Xr = 0.964221f; // reference white D50
+ float Yr = 1.0f;
+ float Zr = 0.825211f;
+
+ // RGB to XYZ
+ r = R / 255.f; //R 0..1
+ g = G / 255.f; //G 0..1
+ b = B / 255.f; //B 0..1
+
+ // assuming sRGB (D65)
+ if (r <= 0.04045)
+ r = r / 12;
+ else
+ r = (float) pow((r + 0.055) / 1.055, 2.4);
+
+ if (g <= 0.04045)
+ g = g / 12;
+ else
+ g = (float) pow((g + 0.055) / 1.055, 2.4);
+
+ if (b <= 0.04045)
+ b = b / 12;
+ else
+ b = (float) pow((b + 0.055) / 1.055, 2.4);
+
+
+ X = 0.436052025f * r + 0.385081593f * g + 0.143087414f * b;
+ Y = 0.222491598f * r + 0.71688606f * g + 0.060621486f * b;
+ Z = 0.013929122f * r + 0.097097002f * g + 0.71418547f * b;
+
+ // XYZ to Lab
+ xr = X / Xr;
+ yr = Y / Yr;
+ zr = Z / Zr;
+
+ if (xr > eps)
+ fx = (float) pow(xr, 1 / 3.);
+ else
+ fx = (float) ((k * xr + 16.) / 116.);
+
+ if (yr > eps)
+ fy = (float) pow(yr, 1 / 3.);
+ else
+ fy = (float) ((k * yr + 16.) / 116.);
+
+ if (zr > eps)
+ fz = (float) pow(zr, 1 / 3.);
+ else
+ fz = (float) ((k * zr + 16.) / 116);
+
+ Ls = (116 * fy) - 16;
+ as = 500 * (fx - fy);
+ bs = 200 * (fy - fz);
+
+ *_L = (2.55 * Ls + .5);
+ *_a = (as + .5);
+ *_b = (bs + .5);
+}
/**
* device methods
*/
+void init_globals(void)
+{
+ int i = 0;
+ for (i = 0; i < MAX_COLOR; i++) {
+ rgb2lab(colors[i].r, colors[i].g, colors[i].b,
+ &colors[i]._L, &colors[i]._a, &colors[i]._b);
+ }
+
+ // init the mutex
+ pthread_mutex_init(&g_lock, NULL);
+
+}
+
static int
write_int(char const* path, int value)
{
@@ -95,33 +203,26 @@ write_int(char const* path, int value)
}
static int
-write_str(char const* path, char* value)
+write_str(char const* path, char *value)
{
int fd;
static int already_warned = 0;
fd = open(path, O_RDWR);
if (fd >= 0) {
- char buffer[1024];
- int bytes = snprintf(buffer, sizeof(buffer), "%s\n", value);
- ssize_t amt = write(fd, buffer, (size_t)bytes);
+ char buffer[20];
+ ssize_t amt = write(fd, value, (size_t)strlen(value));
close(fd);
return amt == -1 ? -errno : 0;
} else {
if (already_warned == 0) {
- ALOGE("write_int failed to open %s\n", path);
+ ALOGE("write_str failed to open %s\n", path);
already_warned = 1;
}
return -errno;
}
}
-void init_globals(void)
-{
- // init the mutex
- pthread_mutex_init(&g_lock, NULL);
-}
-
static int
is_lit(struct light_state_t const* state)
{
@@ -136,21 +237,40 @@ rgb_to_brightness(struct light_state_t const* state)
+ (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
}
-static int
-set_light_backlight(struct light_device_t* dev,
- struct light_state_t const* state)
+// find the color with the shortest distance
+static struct color *
+nearest_color(unsigned int r, unsigned int g, unsigned int b)
{
- int err = 0;
- int brightness = rgb_to_brightness(state);
- pthread_mutex_lock(&g_lock);
- err = write_int(LCD_FILE, brightness);
- pthread_mutex_unlock(&g_lock);
- return err;
+ int i = 0;
+ float _L, _a, _b;
+ double L_dist, a_dist, b_dist, total;
+ double distance = 3 * 255;
+
+ struct color *nearest = NULL;
+
+ rgb2lab(r, g, b, &_L, &_a, &_b);
+
+ ALOGV("%s: r=%d g=%d b=%d L=%f a=%f b=%f", __func__,
+ r, g, b, _L, _a, _b);
+
+ for (i = 0; i < MAX_COLOR; i++) {
+ L_dist = pow(_L - colors[i]._L, 2);
+ a_dist = pow(_a - colors[i]._a, 2);
+ b_dist = pow(_b - colors[i]._b, 2);
+ total = sqrt(L_dist + a_dist + b_dist);
+ ALOGV("%s: total %f distance %f", __func__, total, distance);
+ if (total < distance) {
+ nearest = &colors[i];
+ distance = total;
+ }
+ }
+
+ return nearest;
}
static int
-set_light_buttons(struct light_device_t *dev,
- const struct light_state_t *state)
+set_light_backlight(struct light_device_t* dev,
+ struct light_state_t const* state)
{
int err = 0;
int brightness = rgb_to_brightness(state);
@@ -158,7 +278,7 @@ set_light_buttons(struct light_device_t *dev,
return -1;
}
pthread_mutex_lock(&g_lock);
- err = write_int(BUTTONS_FILE, brightness);
+ err = write_int(LCD_FILE, brightness);
pthread_mutex_unlock(&g_lock);
return err;
}
@@ -167,11 +287,24 @@ static int
set_speaker_light_locked(struct light_device_t* dev,
struct light_state_t const* state)
{
- int len;
- int alpha, red, green, blue;
+ int red, green, blue;
int blink;
int onMS, offMS;
unsigned int colorRGB;
+ char breath_pattern[64] = { 0, };
+ struct color *nearest = NULL;
+
+ if(!dev) {
+ return -1;
+ }
+
+ write_int(RED_LED_FILE, 0);
+ write_int(GREEN_LED_FILE, 0);
+ write_int(BLUE_LED_FILE, 0);
+
+ if (state == NULL) {
+ return 0;
+ }
switch (state->flashMode) {
case LIGHT_FLASH_TIMED:
@@ -187,38 +320,62 @@ set_speaker_light_locked(struct light_device_t* dev,
colorRGB = state->color;
- ALOGD("%s: mode %d, colorRGB=%08X, onMS=%d, offMS=%d\n",
- __func__, state->flashMode, colorRGB, onMS, offMS);
+ ALOGD("set_speaker_light_locked mode %d, colorRGB=%08X, onMS=%d, offMS=%d\n",
+ state->flashMode, colorRGB, onMS, offMS);
red = (colorRGB >> 16) & 0xFF;
green = (colorRGB >> 8) & 0xFF;
blue = colorRGB & 0xFF;
- if (onMS > 0 && offMS > 0) {
- blink = 1;
- } else {
- blink = 0;
- }
+ blink = onMS > 0 && offMS > 0;
if (blink) {
- if (red)
- write_int(RED_BLINK_FILE, blink);
- if (green)
- write_int(GREEN_BLINK_FILE, blink);
- if (blue)
- write_int(BLUE_BLINK_FILE, blink);
+ // Driver doesn't permit us to set individual duty cycles, so only
+ // pick pure colors at max brightness when blinking.
+ nearest = nearest_color(red, green, blue);
+
+ red = nearest->r;
+ green = nearest->g;
+ blue = nearest->b;
+
+ // Make sure the values are between 1 and 7 seconds
+ if (onMS < 1000)
+ onMS = 1000;
+ else if (onMS > 7000)
+ onMS = 7000;
+
+ if (offMS < 1000)
+ offMS = 1000;
+ else if (offMS > 7000)
+ offMS = 7000;
+
+ // ramp up, lit, ramp down, unlit. in seconds.
+ sprintf(breath_pattern,"1 %d 1 %d",(int)(onMS/1000),(int)(offMS/1000));
+
} else {
- write_int(RED_LED_FILE, red);
- write_int(GREEN_LED_FILE, green);
- write_int(BLUE_LED_FILE, blue);
+ blink = 0;
+ sprintf(breath_pattern,"1 2 1 2");
}
-return 0;
+ // Do everything with the lights out, then turn up the brightness
+ write_str(RED_BREATH_FILE, breath_pattern);
+ write_int(RED_BLINK_FILE, (blink && red ? 1 : 0));
+ write_str(GREEN_BREATH_FILE, breath_pattern);
+ write_int(GREEN_BLINK_FILE, (blink && green ? 1 : 0));
+ write_str(BLUE_BREATH_FILE, breath_pattern);
+ write_int(BLUE_BLINK_FILE, (blink && blue ? 1 : 0));
+
+ write_int(RED_LED_FILE, red);
+ write_int(GREEN_LED_FILE, green);
+ write_int(BLUE_LED_FILE, blue);
+
+ return 0;
}
static void
-handle_speaker_light_locked(struct light_device_t* dev)
+handle_speaker_battery_locked(struct light_device_t* dev)
{
+ set_speaker_light_locked(dev, NULL);
if (is_lit(&g_attention)) {
set_speaker_light_locked(dev, &g_attention);
} else if (is_lit(&g_notification)) {
@@ -234,7 +391,7 @@ set_light_battery(struct light_device_t* dev,
{
pthread_mutex_lock(&g_lock);
g_battery = *state;
- handle_speaker_light_locked(dev);
+ handle_speaker_battery_locked(dev);
pthread_mutex_unlock(&g_lock);
return 0;
}
@@ -245,7 +402,7 @@ set_light_notifications(struct light_device_t* dev,
{
pthread_mutex_lock(&g_lock);
g_notification = *state;
- handle_speaker_light_locked(dev);
+ handle_speaker_battery_locked(dev);
pthread_mutex_unlock(&g_lock);
return 0;
}
@@ -255,12 +412,36 @@ set_light_attention(struct light_device_t* dev,
struct light_state_t const* state)
{
pthread_mutex_lock(&g_lock);
+
g_attention = *state;
- handle_speaker_light_locked(dev);
+ if (state->flashMode == LIGHT_FLASH_HARDWARE) {
+ if (g_attention.flashOnMS > 0 && g_attention.flashOffMS == 0) {
+ g_attention.flashMode = LIGHT_FLASH_NONE;
+ }
+ } else if (state->flashMode == LIGHT_FLASH_NONE) {
+ g_attention.color = 0;
+ }
+ handle_speaker_battery_locked(dev);
+
pthread_mutex_unlock(&g_lock);
+
return 0;
}
+static int
+set_light_buttons(struct light_device_t* dev,
+ struct light_state_t const* state)
+{
+ int err = 0;
+ if(!dev) {
+ return -1;
+ }
+ pthread_mutex_lock(&g_lock);
+ err = write_int(BUTTON_FILE, state->color & 0xFF);
+ pthread_mutex_unlock(&g_lock);
+ return err;
+}
+
/** Close the lights device */
static int
close_lights(struct light_device_t *dev)
@@ -287,14 +468,14 @@ static int open_lights(const struct hw_module_t* module, char const* name,
if (0 == strcmp(LIGHT_ID_BACKLIGHT, name))
set_light = set_light_backlight;
- else if (0 == strcmp(LIGHT_ID_BUTTONS, name))
- set_light = set_light_buttons;
else if (0 == strcmp(LIGHT_ID_BATTERY, name))
set_light = set_light_battery;
else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
set_light = set_light_notifications;
else if (0 == strcmp(LIGHT_ID_ATTENTION, name))
set_light = set_light_attention;
+ else if (0 == strcmp(LIGHT_ID_BUTTONS, name))
+ set_light = set_light_buttons;
else
return -EINVAL;
@@ -329,7 +510,7 @@ struct hw_module_t HAL_MODULE_INFO_SYM = {
.version_major = 1,
.version_minor = 0,
.id = LIGHTS_HARDWARE_MODULE_ID,
- .name = "S2 Lights Module",
+ .name = "LeEco s2 Lights Module",
.author = "The LineageOS Project",
.methods = &lights_module_methods,
};
diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml
index cff2c5e..5ec2190 100644
--- a/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/overlay/frameworks/base/core/res/res/values/config.xml
@@ -60,21 +60,23 @@
Must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessLevels">
<item>10</item>
- <item>15</item>
+ <item>25</item>
<item>50</item>
- <item>90</item>
+ <item>75</item>
<item>100</item>
<item>150</item>
<item>200</item>
<item>300</item>
<item>400</item>
<item>500</item>
- <item>800</item>
+ <item>750</item>
<item>1000</item>
- <item>1300</item>
- <item>3000</item>
- <item>4000</item>
- <item>8000</item>
+ <item>1250</item>
+ <item>1500</item>
+ <item>1750</item>
+ <item>2500</item>
+ <item>5000</item>
+ <item>10000</item>
<item>20000</item>
<item>30000</item>
</integer-array>
@@ -84,25 +86,27 @@
than the size of the config_autoBrightnessLevels array.
This must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessLcdBacklightValues">
+ <item>20</item>
<item>30</item>
- <item>35</item>
- <item>45</item>
- <item>55</item>
- <item>65</item>
- <item>75</item>
- <item>85</item>
- <item>95</item>
- <item>105</item>
- <item>115</item>
+ <item>40</item>
+ <item>50</item>
+ <item>60</item>
+ <item>70</item>
+ <item>80</item>
+ <item>90</item>
+ <item>100</item>
<item>125</item>
<item>150</item>
- <item>204</item>
- <item>224</item>
+ <item>160</item>
+ <item>180</item>
+ <item>200</item>
+ <item>220</item>
<item>240</item>
<item>255</item>
<item>255</item>
<item>255</item>
<item>255</item>
+ <item>255</item>
</integer-array>
<!-- Array of output values for button backlight corresponding to the LUX values
@@ -110,27 +114,32 @@
than the size of the config_autoBrightnessLevels array.
This must be overridden in platform specific overlays -->
<integer-array name="config_autoBrightnessButtonBacklightValues">
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
- <item>0</item>
+ <item>20</item>
+ <item>30</item>
+ <item>40</item>
+ <item>50</item>
+ <item>60</item>
+ <item>70</item>
+ <item>80</item>
+ <item>90</item>
+ <item>100</item>
+ <item>125</item>
+ <item>150</item>
+ <item>160</item>
+ <item>180</item>
+ <item>200</item>
+ <item>220</item>
+ <item>240</item>
+ <item>255</item>
+ <item>255</item>
+ <item>255</item>
+ <item>255</item>
+ <item>255</item>
</integer-array>
+ <!-- Enable adjusting the button backlight -->
+ <bool name="config_deviceHasVariableButtonBrightness">true</bool>
+
<!-- If this is true, the screen will come on when you unplug usb/power/whatever. -->
<bool name="config_unplugTurnsOnScreen">true</bool>
diff --git a/overlay/vendor/cmsdk/cm/res/res/values/config.xml b/overlay/vendor/cmsdk/cm/res/res/values/config.xml
index acec465..ed20ad5 100644
--- a/overlay/vendor/cmsdk/cm/res/res/values/config.xml
+++ b/overlay/vendor/cmsdk/cm/res/res/values/config.xml
@@ -28,7 +28,10 @@
For example, a device support pulsating, RGB notification and
battery LEDs would set this config to 11. -->
- <integer name="config_deviceLightCapabilities" translatable="false">35</integer>
+ <integer name="config_deviceLightCapabilities" translatable="false">43</integer>
+
+ <!-- Is the notification LED brightness adjustable ? Used to decide if the user can set LED brightness -->
+ <bool name="config_adjustableNotificationLedBrightness">true</bool>
<!-- Default value for proximity check on screen wake
NOTE ! - Enable for devices that have a fast response proximity sensor (ideally < 300ms)-->
diff --git a/rootdir/init.qcom.rc b/rootdir/init.qcom.rc
index 628b499..5792227 100755
--- a/rootdir/init.qcom.rc
+++ b/rootdir/init.qcom.rc
@@ -68,7 +68,6 @@ on boot
chown bluetooth bluetooth /sys/module/hci_uart/parameters/ath_lpm
chown bluetooth bluetooth /sys/module/hci_uart/parameters/ath_btwrite
chown system system /sys/module/sco/parameters/disable_esco
- chown system system /sys/class/leds/red/blink
chown bluetooth bluetooth /sys/module/hci_smd/parameters/hcismd_set
chown system system /sys/module/radio_iris_transport/parameters/fmsmd_set
chmod 0660 /sys/module/bluetooth_power/parameters/power
diff --git a/rootdir/init.target.rc b/rootdir/init.target.rc
index 91e7e93..6960169 100755
--- a/rootdir/init.target.rc
+++ b/rootdir/init.target.rc
@@ -126,13 +126,34 @@ on post-fs-data
# leds
chown system system /sys/module/leds_aw2013/parameters/aw2013_sleep_led
chmod 0666 /sys/module/leds_aw2013/parameters/aw2013_sleep_led
+
chown system system /sys/class/leds/red/blink
+ chown system system /sys/class/leds/red/led_time
+
chown system system /sys/class/leds/green/blink
+ chown system system /sys/class/leds/green/led_time
+
chown system system /sys/class/leds/blue/blink
+ chown system system /sys/class/leds/blue/led_time
+
+ chown system camera /sys/class/leds/led:flash_0/brightness
+ chmod 0664 /sys/class/leds/led:flash_0/brightness
+
+ chown system camera /sys/class/leds/led:flash_1/brightness
+ chmod 0664 /sys/class/leds/led:flash_1/brightness
+
chown system camera /sys/class/leds/led:torch_0/brightness
chmod 0664 /sys/class/leds/led:torch_0/brightness
+
chown system camera /sys/class/leds/led:torch_1/brightness
chmod 0664 /sys/class/leds/led:torch_1/brightness
+
+ chown system camera /sys/class/leds/torch-light0/brightness
+ chmod 0664 /sys/class/leds/torch-light0/brightness
+
+ chown system camera /sys/class/leds/torch-light1/brightness
+ chmod 0664 /sys/class/leds/torch-light1/brightness
+
chown system camera /sys/class/leds/led:switch/brightness
chmod 0664 /sys/class/leds/led:switch/brightness