From a5e5aff2a2bfa87b2d675cd59fb563c522cb4592 Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Tue, 11 Jan 2011 12:24:23 -0800 Subject: [PATCH 1/4] Add support for Ramdisks built with mkimage. Change-Id: Iad755d1918038bbe4c835ac240772d965efb4cf2 --- BoardConfig.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BoardConfig.mk b/BoardConfig.mk index 1648916..8148cde 100644 --- a/BoardConfig.mk +++ b/BoardConfig.mk @@ -23,3 +23,5 @@ TARGET_PREBUILT_KERNEL := device/bn/nookcolor/kernel BOARD_RECOVERY_IGNORE_BOOTABLES := true BOARD_CUSTOM_RECOVERY_KEYMAPPING := ../../device/bn/nookcolor/default_recovery_ui.c + +BOARD_USES_MKIMAGE := true \ No newline at end of file From a4f8087a1073ce5b0039d1b85dc0d2839eeb44a9 Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Tue, 11 Jan 2011 14:29:33 -0800 Subject: [PATCH 2/4] back up bootables Change-Id: I16e4998d31947bd28cd7d2d9c3346e0a567e82ab --- BoardConfig.mk | 1 - recovery.fstab | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/BoardConfig.mk b/BoardConfig.mk index 8148cde..3bcc762 100644 --- a/BoardConfig.mk +++ b/BoardConfig.mk @@ -21,7 +21,6 @@ BOARD_FLASH_BLOCK_SIZE := 131072 TARGET_PREBUILT_KERNEL := device/bn/nookcolor/kernel -BOARD_RECOVERY_IGNORE_BOOTABLES := true BOARD_CUSTOM_RECOVERY_KEYMAPPING := ../../device/bn/nookcolor/default_recovery_ui.c BOARD_USES_MKIMAGE := true \ No newline at end of file diff --git a/recovery.fstab b/recovery.fstab index 70529bb..4fed9f4 100644 --- a/recovery.fstab +++ b/recovery.fstab @@ -4,3 +4,4 @@ /system ext2 /dev/block/mmcblk0p5 /cache ext3 /dev/block/mmcblk0p7 /data ext3 /dev/block/mmcblk0p6 +/boot vfat /dev/block/mmcblk0p1 From 59309b4412c2ff6a2824da24db7d221e11898f39 Mon Sep 17 00:00:00 2001 From: cicada Date: Fri, 7 Jan 2011 10:56:06 -0700 Subject: [PATCH 3/4] adding sensors lib, accelerometer support --- libsensors/Android.mk | 32 ++ libsensors/sensors.c | 722 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 754 insertions(+) create mode 100644 libsensors/Android.mk create mode 100644 libsensors/sensors.c diff --git a/libsensors/Android.mk b/libsensors/Android.mk new file mode 100644 index 0000000..1346283 --- /dev/null +++ b/libsensors/Android.mk @@ -0,0 +1,32 @@ +# 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. + + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# HAL module implemenation, not prelinked and stored in +# hw/..so +LOCAL_MODULE := sensors.nookcolor + +LOCAL_SRC_FILES := sensors.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw + +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_SHARED_LIBRARIES := libcutils + + +include $(BUILD_SHARED_LIBRARY) diff --git a/libsensors/sensors.c b/libsensors/sensors.c new file mode 100644 index 0000000..2f96673 --- /dev/null +++ b/libsensors/sensors.c @@ -0,0 +1,722 @@ +/* + * 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. + * + * + * Based on: blaze sensors lib + */ + +#define LOG_TAG "Sensors" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/*****************************************************************************/ + +#define MAX_NUM_SENSORS 1 + +#define SUPPORTED_SENSORS ((1<d_name[0] == '.' && + (de->d_name[1] == '\0' || + (de->d_name[1] == '.' && de->d_name[2] == '\0'))) + continue; + strcpy(filename, de->d_name); + fd = open(devname, mode); + if (fd>=0) { + char name[80]; + if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { + name[0] = '\0'; + } + if (!strcmp(name, dev_name)) { + LOGD("using %s (name=%s)", dev_name, name); + break; + } + close(fd); + fd = -1; + } + } + closedir(dir); + + if (fd < 0) { + LOGE("Couldn't find or open '%s' driver (%s)", dev_name, strerror(errno)); + } + return fd; +} + + +static int open_dev(struct sensors_control_context_t *dev, int dev_num, int type) +{ + LOGD("Opening device number %i, and type %i", dev_num, type); + if (dev->dev_fd[dev_num][type] < 0) { + if (type == BASE_LOCATION) { + dev->dev_fd[dev_num][type] = open(dDriverList[dev_num].loc, O_RDWR); + LOGE_IF(dev->dev_fd[dev_num][type] < 0, "Couldn't open %s (%s)", + dDriverList[dev_num].loc, strerror(errno)); + } else if(type == ENABLE_LOCATION) { + dev->dev_fd[dev_num][type] = open(dDriverList[dev_num].enable, O_RDWR); + LOGE_IF(dev->dev_fd[dev_num][type] < 0, "Couldn't open %s (%s)", + dDriverList[dev_num].enable, strerror(errno)); + } else if(type == DELAY_LOCATION) { + dev->dev_fd[dev_num][type] = open(dDriverList[dev_num].delay, O_RDWR); + LOGE_IF(dev->dev_fd[dev_num][type] < 0, "Couldn't open %s (%s)", + dDriverList[dev_num].delay, strerror(errno)); + } + + } + return dev->dev_fd[dev_num][type]; +} + +static void close_dev(struct sensors_control_context_t *dev, int dev_num, uint32_t enabled, int type) +{ + if ((dev->dev_fd[dev_num][type] >= 0) && ((enabled & dDriverList[dev_num].mask) == 0)) { + close(dev->dev_fd[dev_num][type]); + dev->dev_fd[dev_num][type] = -1; + } +} + +static int send_event(int fd, uint16_t type, uint16_t code, int32_t value) +{ + struct input_event event; + + memset(&event, 0, sizeof(event)); + + event.type = type; + event.code = code; + event.value = value; + + return write(fd, &event, sizeof(event)); +} + +static int uinput_create(char *name) +{ + struct uinput_user_dev udev; + int i = 0; + + int fd = open_input(name, O_RDWR); + if (fd >= 0) { + return fd; + } + int uinputfd = open("/dev/uinput", O_RDWR); + if(uinputfd < 0) { + LOGE("Can't open uinput device (%s)", strerror(errno)); + return -errno; + } + + memset(&udev, 0, sizeof(udev)); + strncpy(udev.name, name, UINPUT_MAX_NAME_SIZE); + + ioctl(uinputfd, UI_SET_EVBIT, EV_SYN); + ioctl(uinputfd, UI_SET_EVBIT, EV_ABS); + ioctl(uinputfd, UI_SET_EVBIT, EV_REL); + + ioctl(uinputfd, UI_SET_ABSBIT, EVENT_TYPE_ACCEL_X); + ioctl(uinputfd, UI_SET_ABSBIT, EVENT_TYPE_ACCEL_Y); + ioctl(uinputfd, UI_SET_ABSBIT, EVENT_TYPE_ACCEL_Z); + + /* no need to filter since drivers already do */ + for (i = 0; i < ABS_MAX; i++) { + udev.absmax[i] = 8000; + udev.absmin[i] = -8000; + } + + if (write(uinputfd, &udev, sizeof(udev)) < 0) { + LOGE("Can't write uinput device information (%s)", strerror(errno)); + close(uinputfd); + return -errno; + } + + if (ioctl(uinputfd, UI_DEV_CREATE)) + { + LOGE("Can't create uinput device (%s)", strerror(errno)); + close(uinputfd); + return -errno; + } + + return uinputfd; +} + +static void *poll_thread(void *arg) +{ + struct sensors_control_context_t *dev= (struct sensors_control_context_t *)arg; + struct pollfd event_fd[MAX_NUM_DRIVERS]; + + int err = 0; + int i = 0; + int j = 0; + + for (i = 0; i < MAX_NUM_DRIVERS; i++) { + int fd = open_input(dDriverList[i].name, O_RDONLY); + LOGD("Opening the input %s\n", dDriverList[i].name); + if (fd < 0) { + LOGE("invalid file descriptor, fd=%d", fd); + } + + event_fd[i].fd = fd; + event_fd[i].events = POLLIN; + } + + uint32_t new_sensors = 0; + LOGD("starting poll loop for %d drivers", MAX_NUM_DRIVERS); + while(1) { + //LOGD("sensor poll"); + int pollres = poll(event_fd, MAX_NUM_DRIVERS, -1); + if (pollres <= 0) { + if (errno != EINTR) { + LOGW("select failed (errno=%d)\n", errno); + usleep(100000); + } + continue; + } + for (i = 0; i < MAX_NUM_DRIVERS; i++) { + if (event_fd[i].revents) { + if (event_fd[i].revents & POLLIN) { + struct input_event event; + int nread = read(event_fd[i].fd, &event, sizeof(event)); + if (nread == sizeof(event)) { + uint32_t active_sensors = dev->active_sensors; + uint32_t write_event = 0; + //LOGD("event - sensor %d, val %f, type %d, code %d, active sensors %d", i, event.value, event.type, event.code, active_sensors); + if (dev->uinput >= 0) { + if (event.type == EV_REL) { + switch (event.code) { + case EVENT_TYPE_ACCEL_X: + // LOGD("EVENT_TYPE_ACCEL_X"); + new_sensors |= SENSORS_ACCELERATION; + dev->filter_sensors[ID_A].acceleration.x = event.value; + break; + case EVENT_TYPE_ACCEL_Y: + // LOGD("EVENT_TYPE_ACCEL_Y"); + new_sensors |= SENSORS_ACCELERATION; + dev->filter_sensors[ID_A].acceleration.y = event.value; + break; + case EVENT_TYPE_ACCEL_Z: + // LOGD("EVENT_TYPE_ACCEL_Z"); + new_sensors |= SENSORS_ACCELERATION; + dev->filter_sensors[ID_A].acceleration.z = event.value; + break; + } + } else if (event.type == EV_SYN) { + if (event.code == SYN_CONFIG) { + // we use SYN_CONFIG to signal that we need to exit the + // main loop. + LOGD("got empty message: value=%d", event.value); + if (event.value == 0) { + if(!write(dev->uinput, &event, sizeof(event))) + LOGE("%s: failed to write event (%s)", __PRETTY_FUNCTION__, + strerror(errno)); + } + } + while(new_sensors) { + uint32_t i = 31 - __builtin_clz(new_sensors); + new_sensors &= ~(1<uinput, EV_ABS, EVENT_TYPE_ACCEL_X, + dev->filter_sensors[ID_A].acceleration.x); + send_event(dev->uinput, EV_ABS, EVENT_TYPE_ACCEL_Y, + dev->filter_sensors[ID_A].acceleration.y); + send_event(dev->uinput, EV_ABS, EVENT_TYPE_ACCEL_Z, + dev->filter_sensors[ID_A].acceleration.z); + send_event(dev->uinput, EV_SYN, 0, 0); + } + break; + } + } + } + } + } + } + } + } + } + return ((void*)0); +} + + +/*****************************************************************************/ + +static native_handle_t* control__open_data_source(struct sensors_control_context_t *dev) +{ + native_handle_t* handle; + + if (dev->uinput < 0) { + int ufd = uinput_create("sensors"); + if (ufd < 0) { + LOGE("%s: uinput_create failed to create sensors", __PRETTY_FUNCTION__); + return NULL; + } + dev->uinput = ufd; + } + /* need to spawn a thread to listen and handle data */ + if (dev->poll_thread == 0) { + LOGD("Spawning poll thread"); + pthread_create(&dev->poll_thread, NULL, poll_thread, (void*)dev); + } + + int fd = open_input("sensors", O_RDONLY); + if (fd < 0) { + LOGE("%s: open_input failed to find sensors", __PRETTY_FUNCTION__); + return NULL; + } + + handle = native_handle_create(1, 0); + handle->data[0] = fd; + return handle; +} + +static int control__close_data_source(struct sensors_control_context_t *dev) +{ + return 0; +} + +static int control__activate(struct sensors_control_context_t *dev, + int handle, int enabled) +{ + unsigned int flags; + int err = 0; + + if ((handle=SENSORS_HANDLE_BASE+MAX_NUM_SENSORS)) { + LOGD("Max num of sensors is: %d and handle is %d",MAX_NUM_SENSORS, handle); + return -1; + } + + uint32_t handle_mask = (1<active_sensors; + uint32_t new_active = (current_active & ~handle_mask) | (enabled_mask & handle_mask); + + uint32_t current_enabled = dev->active_drivers; + uint32_t new_enabled = new_active; + + uint32_t changed_enabled = current_enabled ^ new_enabled; + + if (changed_enabled) { + if (changed_enabled & SENSORS_ACCELERATION) { + LOGD("Enabling accelerometer"); + int fd = open_dev(dev, ID_CMA, ENABLE_LOCATION); + if (fd >= 0) { + flags = (new_enabled & SENSORS_ACCELERATION) ? 1 : 0; + char buffer[20]; + int bytes = sprintf(buffer, "%d\n", flags); + LOGD("KXTF9 SET ENABLE: flag = %d", flags); + if (write(fd, buffer, bytes) < 0) { + LOGE("KXTF9 SET ENABLE failed(%s)", strerror(errno)); + err = -errno; + } + close_dev(dev, ID_CMA, new_enabled, ENABLE_LOCATION); + } else { + LOGE("ID_CMA open error"); + err = fd; + } + err = 0; + } + + if (err < 0) + return err; + + } + + dev->active_sensors = current_active = new_active; + dev->active_drivers = current_enabled = new_enabled; + + return 0; +} + +static int control__set_delay(struct sensors_control_context_t *dev, int32_t ms) +{ + int delay = ms; + short sdelay = ms; + int err = 0; + int fd = 0; + + if (dev->active_sensors & SENSORS_ACCELERATION) { + fd = open_dev(dev, ID_CMA, DELAY_LOCATION); + if (fd >= 0) { + char buffer[20]; + int bytes = sprintf(buffer, "%d\n", ms); + LOGD("KXTF9 set delay is: delay = %d", ms); + if (write(fd, buffer, bytes) < 0) { + LOGE("KXTF9 set delay failed (%s)", strerror(errno)); + err = -errno; + } + close_dev(dev, ID_CMA, SENSORS_ACCELERATION, DELAY_LOCATION); + } else { + LOGE("ID_CMA open set delay open error"); + err = fd; + } + } + + return err; +} + +static int control__wake(struct sensors_control_context_t *dev) +{ + int err = 0; + int fd = open_input(dDriverList[0].name, O_WRONLY); + if (fd >= 0) { + err = send_event(fd, EV_SYN, SYN_CONFIG, 0); + LOGD_IF(err < 0, "control__wake, err=%d (%s)", errno, strerror(errno)); + close(fd); + } + return err; +} + +/*****************************************************************************/ + +static int data__data_open(struct sensors_data_context_t *dev, native_handle_t* handle) +{ + int i; + memset(&dev->sensors, 0, sizeof(dev->sensors)); + + for (i=0 ; i < MAX_NUM_SENSORS ; i++) { + dev->sensors[i].vector.status = SENSOR_STATUS_ACCURACY_HIGH; + } + + dev->pendingSensors = 0; + dev->events_fd = dup(handle->data[0]); + + native_handle_close(handle); + native_handle_delete(handle); + return 0; +} + +static int data__data_close(struct sensors_data_context_t *dev) +{ + if (dev->events_fd >= 0) { + close(dev->events_fd); + dev->events_fd = -1; + } + return 0; +} + +static int pick_sensor(struct sensors_data_context_t *dev, + sensors_data_t* values) +{ + uint32_t mask = SUPPORTED_SENSORS; + while (mask) { + uint32_t i = 31 - __builtin_clz(mask); + mask &= ~(1<pendingSensors & (1<pendingSensors &= ~(1<sensors[i]; + values->sensor = (1<vector.x, + values->vector.y, + values->vector.z); + return i; + } + } + LOGE("No sensor to return!!! pendingSensors=%08x", dev->pendingSensors); + // we may end-up in a busy loop, slow things down, just in case. + usleep(100000); + return -1; +} + +static int data__poll(struct sensors_data_context_t *dev, sensors_data_t* values) +{ + int fd = dev->events_fd; + if (fd < 0) { + LOGE("data__poll:Invalid file descriptor, fd=%d", fd); + return -1; + } + + // there are pending sensors, returns them now... + if (dev->pendingSensors) { + LOGE("Pending sensors"); + return pick_sensor(dev, values); + } + // wait until we get a complete event for an enabled sensor + uint32_t new_sensors = 0; + while (1) { + /* read the next event */ + struct input_event event; + uint32_t v; + int nread = read(fd, &event, sizeof(event)); + if (nread != sizeof(event)) { + LOGE("Incorrect event size size=%i", nread); + return -1; + } + // LOGD("type: %d code: %d value: %-5d time: %ds", + // event.type, event.code, event.value, + // (int)event.time.tv_sec); + if (event.type == EV_ABS) { + switch (event.code) { + case EVENT_TYPE_ACCEL_X: + new_sensors |= SENSORS_ACCELERATION; + dev->sensors[ID_A].acceleration.y = event.value * CONVERT_A_Y; + break; + case EVENT_TYPE_ACCEL_Y: + new_sensors |= SENSORS_ACCELERATION; + dev->sensors[ID_A].acceleration.x = event.value * CONVERT_A_X; + break; + case EVENT_TYPE_ACCEL_Z: + new_sensors |= SENSORS_ACCELERATION; + dev->sensors[ID_A].acceleration.z = event.value * CONVERT_A_Z; + break; + } + } else if (event.type == EV_SYN) { + if (event.code == SYN_CONFIG) { + // we use SYN_CONFIG to signal that we need to exit the + // main loop. + LOGD("got empty message in data poll: value=%d", event.value); + return 0x7FFFFFFF; + } + if (new_sensors) { + dev->pendingSensors = new_sensors; + int64_t t = event.time.tv_sec*1000000000LL + + event.time.tv_usec*1000; + while (new_sensors) { + uint32_t i = 31 - __builtin_clz(new_sensors); + new_sensors &= ~(1<sensors[i].time = t; + } + return pick_sensor(dev, values); + } + } + } +} + +/*****************************************************************************/ + +static int control__close(struct hw_device_t *dev) +{ + int i = 0; + int j = 0; + struct sensors_control_context_t* ctx = (struct sensors_control_context_t*)dev; + if (ctx) { + control__close_data_source(ctx); + for (i = 0; i < MAX_NUM_DRIVERS; i++) { + for (j = 0; j < MAX_LOCATIONS; j++) { + if (ctx->dev_fd[i][j] >= 0) + close(ctx->dev_fd[i][j]); + } + } + free(ctx); + } + + return 0; +} + +static int data__close(struct hw_device_t *dev) +{ + int i = 0; + struct sensors_data_context_t* ctx = (struct sensors_data_context_t*)dev; + if (ctx) { + if (ctx->events_fd >= 0) { + //LOGD("(device close) about to close fd=%d", ctx->events_fd); + close(ctx->events_fd); + } + free(ctx); + } + return 0; +} + +/** Open a new instance of a sensor device using name */ +static int open_sensors(const struct hw_module_t* module, const char* name, + struct hw_device_t** device) +{ + int i = 0; + int j = 0; + int status = -EINVAL; + if (!strcmp(name, SENSORS_HARDWARE_CONTROL)) { + struct sensors_control_context_t *dev; + dev = malloc(sizeof(*dev)); + memset(dev, 0, sizeof(*dev)); + for (i = 0; i < MAX_NUM_DRIVERS; i++) { + for (j = 0; j < MAX_LOCATIONS; j++) + dev->dev_fd[i][j] = -1; + } + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = module; + dev->device.common.close = control__close; + dev->device.open_data_source = control__open_data_source; + dev->device.close_data_source = control__close_data_source; + dev->device.activate = control__activate; + dev->device.set_delay = control__set_delay; + dev->device.wake = control__wake; + dev->active_sensors = 0; + dev->active_drivers= 0; + dev->uinput = -1; + *device = &dev->device.common; + status = 0; + } else if (!strcmp(name, SENSORS_HARDWARE_DATA)) { + struct sensors_data_context_t *dev; + dev = malloc(sizeof(*dev)); + memset(dev, 0, sizeof(*dev)); + dev->events_fd = -1; + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = module; + dev->device.common.close = data__close; + dev->device.data_open = data__data_open; + dev->device.data_close = data__data_close; + dev->device.poll = data__poll; + *device = &dev->device.common; + status = 0; + } + return status; +} From ccbce5ce3eb61c0cbe79458365e0e07c2e08a2c0 Mon Sep 17 00:00:00 2001 From: Brandon Bennett Date: Thu, 13 Jan 2011 00:21:58 -0700 Subject: [PATCH 4/4] Fix some compliation problems as well as add a comment about what we are doing in postrecovery.sh Change-Id: I5140287dc821377f42b696a2ee2e7b7c9cbfe840 --- libsensors/Android.mk | 14 +++++++++++--- postrecoveryboot.sh | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libsensors/Android.mk b/libsensors/Android.mk index 1346283..e298e56 100644 --- a/libsensors/Android.mk +++ b/libsensors/Android.mk @@ -14,19 +14,27 @@ LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) + +ifneq ($(TARGET_SIMULATOR),true) # HAL module implemenation, not prelinked and stored in # hw/..so +include $(CLEAR_VARS) + LOCAL_MODULE := sensors.nookcolor +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw + +LOCAL_MODULE_TAGS := optional + LOCAL_SRC_FILES := sensors.c LOCAL_PRELINK_MODULE := false -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw LOCAL_SHARED_LIBRARIES := liblog LOCAL_SHARED_LIBRARIES := libcutils - include $(BUILD_SHARED_LIBRARY) + +endif # !TARGET_SIMULATOR + diff --git a/postrecoveryboot.sh b/postrecoveryboot.sh index a24e30a..eebebfa 100755 --- a/postrecoveryboot.sh +++ b/postrecoveryboot.sh @@ -2,6 +2,7 @@ mount /dev/block/mmcblk0p7 /cache +# Resets the boot counter and the bcb instructions mkdir /rom mount /dev/block/mmcblk0p2 /rom echo -n -e "\x00\x00\x00\x00" > /rom/devconf/BootCnt