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