/* * Copyright (C) 2012 Renesas Solutions Corp. * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "lights" #include #include #include #include #include #include #include #include #include static pthread_once_t g_init = PTHREAD_ONCE_INIT; static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; static char const * const BACKLIGHT_FILE = "/sys/class/backlight/pwm-backlight.0/brightness"; static int file_write_integer(char const *path, int value) { static int already_warned = 0; char buffer[11]; int bytes; int ret; int fd; LOGV("%s: path %s, value %d", __func__, path, value); fd = open(path, O_RDWR); if (fd < 0) { if (!already_warned) { LOGE("%s: failed to open %s\n", __func__, path); already_warned = 1; } return -errno; } bytes = sprintf(buffer, "%d\n", value); ret = write(fd, buffer, bytes); close(fd); return ret == -1 ? -errno : 0; } static int rgb_to_brightness(struct light_state_t const *state) { int color = state->color & 0x00ffffff; return (77 * ((color >> 16) & 0x00ff) + 150 * ((color >> 8) & 0x00ff) + 29 * (color & 0x00ff)) >> 8; } static int light_set_backlight(struct light_device_t *dev, struct light_state_t const *state) { int brightness = rgb_to_brightness(state); int err; pthread_mutex_lock(&g_lock); err = file_write_integer(BACKLIGHT_FILE, brightness); pthread_mutex_unlock(&g_lock); return err; } static int light_close(struct light_device_t *dev) { free(dev); return 0; } static int light_open(const struct hw_module_t *module, char const *name, struct hw_device_t **device) { int (*set)(struct light_device_t *dev, struct light_state_t const *state); struct light_device_t *dev; LOGV("%s: open with %s", __func__, name); if (!strcmp(LIGHT_ID_BACKLIGHT, name)) set = light_set_backlight; else return -EINVAL; pthread_mutex_init(&g_lock, NULL); dev = malloc(sizeof(*dev)); memset(dev, 0, sizeof(*dev)); dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 0; dev->common.module = (struct hw_module_t *)module; dev->common.close = (int (*)(struct hw_device_t *))light_close; dev->set_light = set; *device = (struct hw_device_t *)dev; return 0; } static struct hw_module_methods_t lights_module_methods = { .open = light_open, }; const struct hw_module_t HAL_MODULE_INFO_SYM = { .tag = HARDWARE_MODULE_TAG, .version_major = 1, .version_minor = 0, .id = LIGHTS_HARDWARE_MODULE_ID, .name = "Backlight Module", .author = "Laurent Pinchart ", .methods = &lights_module_methods, };