summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Wang <leozwang@google.com>2016-01-21 17:26:22 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2016-01-21 17:26:22 +0000
commitbf1b58e742f1695522890556f073e3ade74538c5 (patch)
tree8605bb5feff55d5fdd0b109e89f15500585e686e
parentbf4b10d14721b5821815a22bb77db0c30e476d3f (diff)
parent116a6144f05ec30a1643255b3f3c3c51e01073af (diff)
downloadfreescale-bf1b58e742f1695522890556f073e3ade74538c5.tar.gz
Merge "Added the light HAL for Brillo" into mnc-brillo-dev
-rw-r--r--peripheral/lights/Android.mk26
-rw-r--r--peripheral/lights/fsl_lights.c290
-rw-r--r--peripheral/lights/peripheral.mk15
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.
+#