1671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru/* 2671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * Copyright (C) 2012 The Android Open Source Project 3671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * 4671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * Licensed under the Apache License, Version 2.0 (the "License"); 5671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * you may not use this file except in compliance with the License. 6671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * You may obtain a copy of the License at 7671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * 8671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * http://www.apache.org/licenses/LICENSE-2.0 9671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * 10671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software 11671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS, 12671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * See the License for the specific language governing permissions and 14671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * limitations under the License. 15671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru */ 16671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 17671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#define LOG_TAG "lights" 18671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#define LOGE ALOGE 19671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 20671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <cutils/log.h> 21671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 22671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <stdint.h> 23671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <string.h> 24671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <unistd.h> 25671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <errno.h> 26671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <fcntl.h> 27671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 28671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <sys/ioctl.h> 29671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <sys/types.h> 30671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 31671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <hardware/lights.h> 32671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru#include <hardware/hardware.h> 33671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 34671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Querustatic pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; 35671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 36671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Querustatic int write_int(char const *path, int value) 37671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru{ 38671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int fd; 39671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru static int already_warned = -1; 40671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru fd = open(path, O_RDWR); 41671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru if (fd >= 0) { 42671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru char buffer[20]; 43671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int bytes = sprintf(buffer, "%d\n", value); 44671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int amt = write(fd, buffer, bytes); 45671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru close(fd); 46671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru return amt == -1 ? -errno : 0; 47671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru } else { 48671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru if (already_warned == -1) { 49671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru LOGE("write_int failed to open %s\n", path); 50671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru already_warned = 1; 51671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru } 52671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru return -errno; 53671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru } 54671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru} 55671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 56671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Querustatic int rgb_to_brightness(struct light_state_t const *state) 57671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru{ 58671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int color = state->color & 0x00ffffff; 59671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru return ((77 * ((color >> 16) & 0x00ff)) 60671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru + (150 * ((color >> 8) & 0x00ff)) + 61671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru (29 * (color & 0x00ff))) >> 8; 62671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru} 63671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 64671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Querustatic int set_light_backlight(struct light_device_t *dev, 65671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru struct light_state_t const *state) 66671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru{ 67671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int err = 0; 68671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int brightness = rgb_to_brightness(state); 69671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru //+++ power save 70671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int range_num = 1; 71671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int old_brightness_range_indexs[] = {160,255}; 72671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int new_brightness_range_indexs[] = {160,182}; 73671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int old_brightness = brightness; 74671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int i=0; 75671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int old_brightness_in_range = -1;// 0:1~10 , 1:10~102 , 2:102~255 76671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru for(i=0;i<range_num;i++){ 77671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int t_range_min = old_brightness_range_indexs[i]; 78671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int t_range_max = old_brightness_range_indexs[i+1]; 79671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru if( brightness>=t_range_min && brightness<=t_range_max){ 80671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru old_brightness_in_range = i; 81671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru break; 82671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru } 83671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru } 84671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru if(old_brightness_in_range>=0){ 85671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int old_br_min = old_brightness_range_indexs[old_brightness_in_range]; 86671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int olb_br_max = old_brightness_range_indexs[old_brightness_in_range+1]; 87671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int new_br_min = new_brightness_range_indexs[old_brightness_in_range]; 88671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int new_br_max = new_brightness_range_indexs[old_brightness_in_range+1]; 89671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int new_brightness = new_br_min + 90671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru (new_br_max-new_br_min)*(old_brightness-old_br_min)/(olb_br_max-old_br_min); 91671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru brightness = new_brightness; 92671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru } 93671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru //--- 94671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru pthread_mutex_lock(&g_lock); 95671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru err = write_int("/sys/class/backlight/pwm-backlight/brightness", 96671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru brightness); 97671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru pthread_mutex_unlock(&g_lock); 98671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 99671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru return err; 100671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru} 101671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 102671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru/** Close the lights device */ 103671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Querustatic int close_lights(struct light_device_t *dev) 104671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru{ 105671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru if (dev) 106671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru free(dev); 107671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru return 0; 108671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru} 109671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 110671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru/** Open a new instance of a lights device using name */ 111671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Querustatic int open_lights(const struct hw_module_t *module, char const *name, 112671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru struct hw_device_t **device) 113671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru{ 114671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru pthread_t lighting_poll_thread; 115671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 116671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru int (*set_light) (struct light_device_t *dev, 117671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru struct light_state_t const *state); 118671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 119671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) 120671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru set_light = set_light_backlight; 121671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru else 122671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru return -EINVAL; 123671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 124671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru pthread_mutex_init(&g_lock, NULL); 125671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 126671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru struct light_device_t *dev = malloc(sizeof(struct light_device_t)); 127671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru memset(dev, 0, sizeof(*dev)); 128671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 129671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru dev->common.tag = HARDWARE_DEVICE_TAG; 130671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru dev->common.version = 0; 131671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru dev->common.module = (struct hw_module_t *)module; 132671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru dev->common.close = (int (*)(struct hw_device_t *))close_lights; 133671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru dev->set_light = set_light; 134671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 135671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru *device = (struct hw_device_t *)dev; 136671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 137671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru return 0; 138671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru} 139671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 140671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Querustatic struct hw_module_methods_t lights_methods = 141671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru{ 142671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru .open = open_lights, 143671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru}; 144671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru 145671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru/* 146671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru * The backlight Module 147671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru */ 148671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Querustruct hw_module_t HAL_MODULE_INFO_SYM = 149671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru{ 150671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru .tag = HARDWARE_MODULE_TAG, 151671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru .version_major = 1, 152671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru .version_minor = 0, 153671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru .id = LIGHTS_HARDWARE_MODULE_ID, 154671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru .name = "NVIDIA Kai lights module", 155671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru .author = "NVIDIA", 156671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru .methods = &lights_methods, 157671476b0aa1b2b8a3d0bd0b1adb800a759030d13Jean-Baptiste Queru}; 158