diff options
Diffstat (limited to 'peripheral')
-rw-r--r-- | peripheral/lights/Android.mk | 26 | ||||
-rw-r--r-- | peripheral/lights/fsl_lights.c | 290 | ||||
-rw-r--r-- | peripheral/lights/peripheral.mk | 15 |
3 files changed, 331 insertions, 0 deletions
diff --git a/peripheral/lights/Android.mk b/peripheral/lights/Android.mk new file mode 100644 index 0000000..039c11c --- /dev/null +++ b/peripheral/lights/Android.mk @@ -0,0 +1,26 @@ +# 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. + +ifeq ($(findstring imx, $(soc_name)), imx) +LOCAL_PATH := $(call my-dir) + +# HAL module implemenation, not prelinked and stored in hw/ +include $(CLEAR_VARS) +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_SHARED_LIBRARIES := liblog libcutils +LOCAL_SRC_FILES := fsl_lights.c +LOCAL_MODULE := lights.$(soc_name) +LOCAL_MODULE_TAGS := eng +include $(BUILD_SHARED_LIBRARY) +endif diff --git a/peripheral/lights/fsl_lights.c b/peripheral/lights/fsl_lights.c new file mode 100644 index 0000000..4da732e --- /dev/null +++ b/peripheral/lights/fsl_lights.c @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * Copyright 2009-2015 Freescale Semiconductor, Inc. + * + * 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 <hardware/lights.h> +#include <fcntl.h> +#include <errno.h> +#include <stdlib.h> +#include <cutils/log.h> +#include <cutils/atomic.h> +#include <cutils/properties.h> +#include <pthread.h> +#include <string.h> + +#define MAX_BRIGHTNESS 7 +#define MAX_NODEPATH_LEN 256 +#define DEF_BACKLIGHT_DEV "backlight.0" +#define DEF_BACKLIGHT_PATH "/sys/class/backlight/" + +#define DEF_LED_DEV "led0" +#define DEF_LED_PATH "/sys/class/leds/" + +#define LED_NODE_DELAY_OFF "delay_off" +#define LED_NODE_DELAY_ON "delay_on" +#define LED_NODE_TRIGGER "trigger" +#define LED_NODE_BRIGHTNESS "brightness" +#define LED_MODE_TIMER "timer" +#define LED_MODE_NONE "none" + +#define _ASSERT(X) \ + do { \ + if (X < 0) { \ + pthread_mutex_unlock(&light_lock); \ + return -1; \ + } \ + } while (0) + +#define _UNUSED(x) \ + do { \ + (void) (x); \ + } while (0) + +/*****************************************************************************/ + +static pthread_once_t light_lock_init = PTHREAD_ONCE_INIT; +static pthread_mutex_t light_lock = PTHREAD_MUTEX_INITIALIZER; + +struct lights_module_t { + struct hw_module_t common; +}; + +static int lights_device_open(const struct hw_module_t* module, + const char* name, struct hw_device_t** device); + +static struct hw_module_methods_t lights_module_methods = { + .open= lights_device_open +}; + +struct lights_module_t HAL_MODULE_INFO_SYM = { + .common= { + .tag= HARDWARE_MODULE_TAG, + .version_major= 1, + .version_minor= 0, + .id= LIGHTS_HARDWARE_MODULE_ID, + .name= "Lights module", + .author= "Freescale Semiconductor", + .methods= &lights_module_methods, + } +}; + +static char max_path[MAX_NODEPATH_LEN], path[MAX_NODEPATH_LEN]; +// **************************************************************************** +// module +// **************************************************************************** +void init_lock(void) +{ + pthread_mutex_init(&light_lock, NULL); +} + +int set_light_notify_parameters(const char* node, const char* paras, ...) { + FILE* file = NULL; + va_list args; + char node_path[MAX_NODEPATH_LEN]; + char buf[32]; + + va_start(args, paras); + vsprintf(buf, paras, args); + va_end(args); + + memset(node_path, 0, MAX_NODEPATH_LEN); + snprintf(node_path, MAX_NODEPATH_LEN, "%s%s/%s", DEF_LED_PATH, DEF_LED_DEV, node); + file = fopen(node_path, "w"); + if (!file) { + ALOGE("Failed to open light node file %s", node_path); + return -1; + } + ALOGV("Will write %s to be:%s", node_path, buf); + int ret = fprintf(file, "%s", buf); + if (ret < 0) { + ALOGE("Failed to set light notify parameters %s to be:%s", node_path, buf); + } + fclose(file); + return ret; + +} + +static int set_light_notify(struct light_device_t* dev, + struct light_state_t const* state) { + + ALOGD("led light set to be %d mode flashOnMS=%d, flashOffMS=%d", + state->flashMode, state->flashOnMS, state->flashOffMS); + _UNUSED(dev); + pthread_mutex_lock(&light_lock); + int ret; + + if (state->flashOnMS < 0 || + state->flashOffMS < 0) { + ALOGW("Wrong flashOnMs or flashOnMs configured!"); + return -EINVAL; + } + + switch (state->flashMode) { + case LIGHT_FLASH_TIMED: + //The trigger node must be setup first. + _ASSERT(set_light_notify_parameters(LED_NODE_TRIGGER, "%s", LED_MODE_TIMER)); + _ASSERT(set_light_notify_parameters(LED_NODE_DELAY_OFF, "%d", state->flashOffMS)); + _ASSERT(set_light_notify_parameters(LED_NODE_DELAY_ON, "%d", state->flashOnMS)); + break; + case LIGHT_FLASH_NONE: + _ASSERT(set_light_notify_parameters(LED_NODE_TRIGGER, "%s", LED_MODE_NONE)); + break; + default: + ALOGW("Unsupported flashMode:%d", state->flashMode); + _ASSERT(set_light_notify_parameters(LED_NODE_TRIGGER, "%s", LED_MODE_NONE)); + } + + pthread_mutex_unlock(&light_lock); + + return 0; +} +static int set_light_backlight(struct light_device_t* dev, + struct light_state_t const* state) +{ + _UNUSED(dev); + int result = -1; + unsigned int color = state->color; + unsigned int brightness = 0, max_brightness = 0; + unsigned int i = 0; + char max_brightness_str[9] = {'\0'}; + FILE *file; + + pthread_mutex_lock(&light_lock); + + brightness = ((77*((color>>16)&0x00ff)) + (150*((color>>8)&0x00ff)) + + (29*(color&0x00ff))) >> 8; + ALOGV("set_light, get brightness=%d", brightness); + + file = fopen(max_path, "r"); + if (!file) { + ALOGE("can not open file %s\n", max_path); + return result; + } + fread(max_brightness_str, 8, 1, file); + fclose(file); + + max_brightness = atoi((char *) max_brightness_str); + /* Any brightness greater than 0, should have at least backlight on. */ + if (max_brightness < MAX_BRIGHTNESS) + brightness = max_brightness *(brightness + MAX_BRIGHTNESS / max_brightness - 1) / MAX_BRIGHTNESS; + else + brightness = max_brightness * brightness / MAX_BRIGHTNESS; + + if (brightness > max_brightness) { + brightness = max_brightness; + } + + ALOGV("set_light, max_brightness=%d, target brightness=%d", + max_brightness, brightness); + + file = fopen(path, "w"); + if (!file) { + ALOGE("can not open file %s\n", path); + return result; + } + fprintf(file, "%d", brightness); + fclose(file); + result = 0; + + pthread_mutex_unlock(&light_lock); + + return result; +} + +static int light_close(struct hw_device_t *dev) +{ + struct light_device_t *device = (struct light_device_t*)dev; + if (device) + free(device); + return 0; +} + +/*****************************************************************************/ +static int lights_device_open(const struct hw_module_t* module, + const char* name, struct hw_device_t** device) +{ + int status = -EINVAL; + ALOGV("lights_device_open\n"); + pthread_once(&light_lock_init, init_lock); + if (!strcmp(name, LIGHT_ID_BACKLIGHT) ) { + ALOGD("lights backlight device open"); + struct light_device_t *dev = NULL; + char value[PROPERTY_VALUE_MAX]; + + dev = (struct light_device_t*) malloc(sizeof(*dev)); + if (dev == NULL) + return status; + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->common.tag = HARDWARE_DEVICE_TAG; + dev->common.version = 0; + dev->common.module = (struct hw_module_t*) module; + dev->common.close = light_close; + + dev->set_light = set_light_backlight; + + *device = &dev->common; + + property_get("hw.backlight.dev", value, DEF_BACKLIGHT_DEV); + if (strlcpy(path, DEF_BACKLIGHT_PATH, MAX_NODEPATH_LEN) >= MAX_NODEPATH_LEN) { + free(dev); + return status; + } + strcat(path, value); + if (strlcpy(max_path, path, MAX_NODEPATH_LEN) >= MAX_NODEPATH_LEN) { + free(dev); + return status; + } + strcat(max_path, "/max_brightness"); + strcat(path, "/brightness"); + + ALOGI("max backlight file is %s\n", max_path); + ALOGI("backlight brightness file is %s\n", path); + + status = 0; + } else if (!strcmp(name, LIGHT_ID_NOTIFICATIONS)) { + ALOGD("lights led device open"); + struct light_device_t *led_dev = NULL; + led_dev = (struct light_device_t *) malloc(sizeof(*led_dev)); + if (led_dev == NULL) { + return status; + } + memset(led_dev, 0, sizeof(*led_dev)); + led_dev->common.tag = HARDWARE_DEVICE_TAG; + led_dev->common.version = 1; + led_dev->common.module = (struct hw_module_t*) module; + led_dev->common.close = light_close; + + led_dev->set_light = set_light_notify; + + *device = &led_dev->common; + + status = 0; + + } else { + *device = NULL; + ALOGW("Unsupported light hal:%s", name); + } + + + /* todo other lights device init */ + return status; +} diff --git a/peripheral/lights/peripheral.mk b/peripheral/lights/peripheral.mk new file mode 100644 index 0000000..2e80bb9 --- /dev/null +++ b/peripheral/lights/peripheral.mk @@ -0,0 +1,15 @@ +# +# Copyright 2015 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. +# |