diff options
| author | hemantbeast <hemantbeast@gmail.com> | 2017-06-16 10:46:03 +0530 |
|---|---|---|
| committer | hemantbeast <hemantbeast@gmail.com> | 2017-06-16 10:46:03 +0530 |
| commit | 909ae8c4e59bdf3eea23526087de13c5a34dd4eb (patch) | |
| tree | b8d1f10c92f910039ab91738a1381bafd43663d4 | |
| parent | b342b5885da76a8169aecc01308e0f15006960cf (diff) | |
s2: refine lights and leds configs
lights hal from hardware/cyanogen
Change-Id: Ie5c282c264d87aa784647f644fac5f3af82b18f8
| -rw-r--r-- | liblight/lights.c | 301 | ||||
| -rw-r--r-- | overlay/frameworks/base/core/res/res/values/config.xml | 83 | ||||
| -rw-r--r-- | overlay/vendor/cmsdk/cm/res/res/values/config.xml | 5 | ||||
| -rwxr-xr-x | rootdir/init.qcom.rc | 1 | ||||
| -rwxr-xr-x | rootdir/init.target.rc | 21 |
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 |
