1b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi/* 2b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * Copyright (C) 2008 The Android Open Source Project 3b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * 4b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * Licensed under the Apache License, Version 2.0 (the "License"); 5b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * you may not use this file except in compliance with the License. 6b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * You may obtain a copy of the License at 7b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * 8b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * http://www.apache.org/licenses/LICENSE-2.0 9b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * 10b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * Unless required by applicable law or agreed to in writing, software 11b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * distributed under the License is distributed on an "AS IS" BASIS, 12b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * See the License for the specific language governing permissions and 14b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * limitations under the License. 15b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi */ 16b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 17b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 18b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi// #define LOG_NDEBUG 0 19b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 20b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <cutils/log.h> 21b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 22b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <stdint.h> 23b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <string.h> 24b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <unistd.h> 25b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <errno.h> 26b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <fcntl.h> 274f88e2f118c88f6af28a93e68b5d93d71602c284Elliott Hughes#include <malloc.h> 28b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <pthread.h> 29b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 30b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <sys/ioctl.h> 31b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <sys/types.h> 32b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 33b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#include <hardware/lights.h> 34b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 35b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi/******************************************************************************/ 36b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 37c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke#define MAX_PATH_SIZE 80 38c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke 39b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic pthread_once_t g_init = PTHREAD_ONCE_INIT; 40b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; 41b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic struct light_state_t g_notification; 42b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic struct light_state_t g_battery; 43b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int g_attention = 0; 44b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 45b514889338b512bdb2550f93c5514af2f1580866Sungmin Choichar const*const RED_LED_FILE 46b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi = "/sys/class/leds/red/brightness"; 47b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 48b514889338b512bdb2550f93c5514af2f1580866Sungmin Choichar const*const GREEN_LED_FILE 49b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi = "/sys/class/leds/green/brightness"; 50b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 51b514889338b512bdb2550f93c5514af2f1580866Sungmin Choichar const*const BLUE_LED_FILE 52b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi = "/sys/class/leds/blue/brightness"; 53b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 54c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burkechar const*const WHITE_LED_FILE 55c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke = "/sys/class/leds/white/brightness"; 56c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke 57b514889338b512bdb2550f93c5514af2f1580866Sungmin Choichar const*const LCD_FILE 58b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi = "/sys/class/leds/lcd-backlight/brightness"; 59b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 60c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burkechar const*const LED_FREQ_FILE 61c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke = "/sys/class/leds/%s/device/grpfreq"; 62d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryu 63c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burkechar const*const LED_PWM_FILE 64c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke = "/sys/class/leds/%s/device/grppwm"; 65d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryu 66c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burkechar const*const LED_BLINK_FILE 67c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke = "/sys/class/leds/%s/device/blink"; 68d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryu 69d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryuchar const*const LED_LOCK_UPDATE_FILE 70c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke = "/sys/class/leds/%s/device/lock"; 71d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryu 72b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi/** 73b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * device methods 74b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi */ 75b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 76b514889338b512bdb2550f93c5514af2f1580866Sungmin Choivoid init_globals(void) 77b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 78b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi // init the mutex 79b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pthread_mutex_init(&g_lock, NULL); 80b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 81b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 82b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int 83b514889338b512bdb2550f93c5514af2f1580866Sungmin Choiwrite_int(char const* path, int value) 84b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 85b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int fd; 86b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi static int already_warned = 0; 87b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 88b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi fd = open(path, O_RDWR); 89b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi if (fd >= 0) { 90b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi char buffer[20]; 91b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int bytes = sprintf(buffer, "%d\n", value); 92b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int amt = write(fd, buffer, bytes); 93b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi close(fd); 94b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return amt == -1 ? -errno : 0; 95b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } else { 96b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi if (already_warned == 0) { 97b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi ALOGE("write_int failed to open %s\n", path); 98b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi already_warned = 1; 99b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } 100b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return -errno; 101b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } 102b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 103b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 104b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int 105c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burkeis_avail(char const* path) 106c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke{ 107c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke int fd = open(path, O_RDWR); 108c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke if (fd >= 0) { 109c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke close(fd); 110c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke return 1; 111c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke } else { 112c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke return 0; 113c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke } 114c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke} 115c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke 116c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burkestatic int 117b514889338b512bdb2550f93c5514af2f1580866Sungmin Choiis_lit(struct light_state_t const* state) 118b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 119b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return state->color & 0x00ffffff; 120b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 121b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 122b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int 123b514889338b512bdb2550f93c5514af2f1580866Sungmin Choirgb_to_brightness(struct light_state_t const* state) 124b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 125b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int color = state->color & 0x00ffffff; 126b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return ((77*((color>>16)&0x00ff)) 127b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8; 128b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 129b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 130b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int 131b514889338b512bdb2550f93c5514af2f1580866Sungmin Choiset_light_backlight(struct light_device_t* dev, 132b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi struct light_state_t const* state) 133b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 134b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int err = 0; 135b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int brightness = rgb_to_brightness(state); 136b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pthread_mutex_lock(&g_lock); 137b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi err = write_int(LCD_FILE, brightness); 138b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pthread_mutex_unlock(&g_lock); 139b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return err; 140b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 141b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 142b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int 143b514889338b512bdb2550f93c5514af2f1580866Sungmin Choiset_speaker_light_locked(struct light_device_t* dev, 144b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi struct light_state_t const* state) 145b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 1466d5467dc95f3e970eb81d6a7ea5b3bcc3b015078Andreas Gampe int rgb; 147b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int blink, freq, pwm; 148b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int onMS, offMS; 149b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi unsigned int colorRGB; 150b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 151b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi switch (state->flashMode) { 152b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi case LIGHT_FLASH_TIMED: 153b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi onMS = state->flashOnMS; 154b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi offMS = state->flashOffMS; 155b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi break; 156b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi case LIGHT_FLASH_NONE: 157b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi default: 158b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi onMS = 0; 159b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi offMS = 0; 160b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi break; 161b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } 162b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 163b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi colorRGB = state->color; 164b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 165b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#if 0 166d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryu ALOGD("set_speaker_light_locked mode %d, colorRGB=%08X, onMS=%d, offMS=%d\n", 167d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryu state->flashMode, colorRGB, onMS, offMS); 168b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi#endif 169b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 170b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi if (onMS > 0 && offMS > 0) { 171b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int totalMS = onMS + offMS; 172b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 173b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi // the LED appears to blink about once per second if freq is 20 174b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi // 1000ms / 20 = 50 175b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi freq = totalMS / 50; 176b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi // pwm specifies the ratio of ON versus OFF 177b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi // pwm = 0 -> always off 178b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi // pwm = 255 => always on 179b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pwm = (onMS * 255) / totalMS; 180b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 181b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi // the low 4 bits are ignored, so round up if necessary 182b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi if (pwm > 0 && pwm < 16) 183b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pwm = 16; 184b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 185b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi blink = 1; 186b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } else { 187b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi blink = 0; 188b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi freq = 0; 189b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pwm = 0; 190b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } 191b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 192c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke // Prefer RGB LEDs, fallback to white LED 193c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke rgb = is_avail(RED_LED_FILE) && is_avail(GREEN_LED_FILE) && is_avail(BLUE_LED_FILE); 194c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke 195c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke char lock_update_file[MAX_PATH_SIZE]; 196c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke char freq_file[MAX_PATH_SIZE]; 197c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke char pwm_file[MAX_PATH_SIZE]; 198c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke char blink_file[MAX_PATH_SIZE]; 199c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke sprintf(lock_update_file, LED_LOCK_UPDATE_FILE, rgb ? "red" : "white"); 200c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke sprintf(freq_file, LED_FREQ_FILE, rgb ? "red" : "white"); 201c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke sprintf(pwm_file, LED_PWM_FILE, rgb ? "red" : "white"); 202c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke sprintf(blink_file, LED_BLINK_FILE, rgb ? "red" : "white"); 203d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryu 204c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke write_int(lock_update_file, 1); // for LED On/Off synchronization 205c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke 206c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke if (rgb) { 207c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke write_int(RED_LED_FILE, (colorRGB >> 16) & 0xFF); 208c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke write_int(GREEN_LED_FILE, (colorRGB >> 8) & 0xFF); 209c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke write_int(BLUE_LED_FILE, colorRGB & 0xFF); 210c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke } else { 211c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke // See hardware/libhardware/include/hardware/lights.h 212c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke int brightness = ((77 * ((colorRGB >> 16) & 0xFF)) + 213c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke (150 * ((colorRGB >> 8) & 0xFF)) + 214c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke (29 * (colorRGB & 0xFF))) >> 8; 215c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke write_int(WHITE_LED_FILE, (int) brightness); 216c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke } 217d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryu 218b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi if (blink) { 219c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke write_int(freq_file, freq); 220c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke write_int(pwm_file, pwm); 221b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } 222c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke write_int(blink_file, blink); 223d57c7d55c9aef7fdae6c47bf03d84a3122b80847samin.ryu 224c43e1d92df36e0542cdeee04a09c8137d0265aecDave Burke write_int(lock_update_file, 0); 225b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 226b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return 0; 227b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 228b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 229b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic void 230b514889338b512bdb2550f93c5514af2f1580866Sungmin Choihandle_speaker_battery_locked(struct light_device_t* dev) 231b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 232b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi if (is_lit(&g_battery)) { 233b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi set_speaker_light_locked(dev, &g_battery); 234b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } else { 235b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi set_speaker_light_locked(dev, &g_notification); 236b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } 237b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 238b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 239b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int 240b514889338b512bdb2550f93c5514af2f1580866Sungmin Choiset_light_notifications(struct light_device_t* dev, 241b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi struct light_state_t const* state) 242b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 243b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pthread_mutex_lock(&g_lock); 244b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi g_notification = *state; 245b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi handle_speaker_battery_locked(dev); 246b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pthread_mutex_unlock(&g_lock); 247b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return 0; 248b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 249b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 250b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int 251b514889338b512bdb2550f93c5514af2f1580866Sungmin Choiset_light_attention(struct light_device_t* dev, 252b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi struct light_state_t const* state) 253b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 254b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pthread_mutex_lock(&g_lock); 255b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi if (state->flashMode == LIGHT_FLASH_HARDWARE) { 256b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi g_attention = state->flashOnMS; 257b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } else if (state->flashMode == LIGHT_FLASH_NONE) { 258b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi g_attention = 0; 259b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } 260b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi handle_speaker_battery_locked(dev); 261b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pthread_mutex_unlock(&g_lock); 262b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return 0; 263b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 264b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 265b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 266b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi/** Close the lights device */ 267b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int 268b514889338b512bdb2550f93c5514af2f1580866Sungmin Choiclose_lights(struct light_device_t *dev) 269b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 270b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi if (dev) { 271b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi free(dev); 272b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi } 273b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return 0; 274b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 275b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 276b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 277b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi/******************************************************************************/ 278b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 279b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi/** 280b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * module methods 281b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi */ 282b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 283b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi/** Open a new instance of a lights device using name */ 284b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic int open_lights(const struct hw_module_t* module, char const* name, 285b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi struct hw_device_t** device) 286b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi{ 287b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi int (*set_light)(struct light_device_t* dev, 288b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi struct light_state_t const* state); 289b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 290b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) 291b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi set_light = set_light_backlight; 292b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name)) 293b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi set_light = set_light_notifications; 294b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi else if (0 == strcmp(LIGHT_ID_ATTENTION, name)) 295b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi set_light = set_light_attention; 296b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi else 297b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return -EINVAL; 298b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 299b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi pthread_once(&g_init, init_globals); 300b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 301b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi struct light_device_t *dev = malloc(sizeof(struct light_device_t)); 302b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi memset(dev, 0, sizeof(*dev)); 303b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 304b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi dev->common.tag = HARDWARE_DEVICE_TAG; 305b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi dev->common.version = 0; 306b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi dev->common.module = (struct hw_module_t*)module; 307b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi dev->common.close = (int (*)(struct hw_device_t*))close_lights; 308b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi dev->set_light = set_light; 309b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 310b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi *device = (struct hw_device_t*)dev; 311b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi return 0; 312b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi} 313b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 314b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistatic struct hw_module_methods_t lights_module_methods = { 315b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi .open = open_lights, 316b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi}; 317b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi 318b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi/* 319b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi * The lights Module 320b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi */ 321b514889338b512bdb2550f93c5514af2f1580866Sungmin Choistruct hw_module_t HAL_MODULE_INFO_SYM = { 322b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi .tag = HARDWARE_MODULE_TAG, 323b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi .version_major = 1, 324b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi .version_minor = 0, 325b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi .id = LIGHTS_HARDWARE_MODULE_ID, 326b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi .name = "lights Module", 327b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi .author = "Google, Inc.", 328b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi .methods = &lights_module_methods, 329b514889338b512bdb2550f93c5514af2f1580866Sungmin Choi}; 330