diff options
-rw-r--r-- | include/hardware/vibrator.h | 68 | ||||
-rw-r--r-- | modules/Android.mk | 2 | ||||
-rw-r--r-- | modules/vibrator/Android.mk | 30 | ||||
-rw-r--r-- | modules/vibrator/vibrator.c | 135 |
4 files changed, 234 insertions, 1 deletions
diff --git a/include/hardware/vibrator.h b/include/hardware/vibrator.h new file mode 100644 index 0000000..795d23e --- /dev/null +++ b/include/hardware/vibrator.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2013 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. + */ + +#ifndef _HARDWARE_VIBRATOR_H +#define _HARDWARE_VIBRATOR_H + +#include <hardware/hardware.h> + +__BEGIN_DECLS + +#define VIBRATOR_API_VERSION HARDWARE_MODULE_API_VERSION(1,0) + +/** + * The id of this module + */ +#define VIBRATOR_HARDWARE_MODULE_ID "vibrator" + +/** + * The id of the main vibrator device + */ +#define VIBRATOR_DEVICE_ID_MAIN "main_vibrator" + +struct vibrator_device; +typedef struct vibrator_device { + struct hw_device_t common; + + /** Turn on vibrator + * + * What happens when this function is called while the the timeout of a + * previous call has not expired is implementation dependent. + * + * @param timeout_ms number of milliseconds to vibrate + * + * @return 0 in case of success, negative errno code else + */ + int (*vibrator_on)(struct vibrator_device* vibradev, unsigned int timeout_ms); + + /** Turn off vibrator + * + * It is not guaranteed that the vibrator will be immediately stopped: the + * behaviour is implementation dependent. + * + * @return 0 in case of success, negative errno code else + */ + int (*vibrator_off)(struct vibrator_device* vibradev); +} vibrator_device_t; + +static inline int vibrator_open(const struct hw_module_t* module, vibrator_device_t** device) +{ + return module->methods->open(module, VIBRATOR_DEVICE_ID_MAIN, (struct hw_device_t**)device); +} + +__END_DECLS + +#endif // _HARDWARE_VIBRATOR_H diff --git a/modules/Android.mk b/modules/Android.mk index b2d5a2a..de41f6f 100644 --- a/modules/Android.mk +++ b/modules/Android.mk @@ -1,3 +1,3 @@ hardware_modules := gralloc hwcomposer audio nfc nfc-nci local_time \ - power usbaudio audio_remote_submix camera consumerir + power usbaudio audio_remote_submix camera consumerir vibrator include $(call all-named-subdir-makefiles,$(hardware_modules)) diff --git a/modules/vibrator/Android.mk b/modules/vibrator/Android.mk new file mode 100644 index 0000000..bbba114 --- /dev/null +++ b/modules/vibrator/Android.mk @@ -0,0 +1,30 @@ +# Copyright (C) 2012 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) + +LOCAL_MODULE := vibrator.default + +# HAL module implementation stored in +# hw/<VIBRATOR_HARDWARE_MODULE_ID>.default.so +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_C_INCLUDES := hardware/libhardware +LOCAL_SRC_FILES := vibrator.c +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) + diff --git a/modules/vibrator/vibrator.c b/modules/vibrator/vibrator.c new file mode 100644 index 0000000..ce4c03c --- /dev/null +++ b/modules/vibrator/vibrator.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2013 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. + */ + +#include <hardware/vibrator.h> +#include <hardware/hardware.h> + +#include <cutils/log.h> + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <math.h> + +static const char THE_DEVICE[] = "/sys/class/timed_output/vibrator/enable"; + +static int vibra_exists() { + int fd; + + fd = TEMP_FAILURE_RETRY(open(THE_DEVICE, O_RDWR)); + if(fd < 0) { + ALOGE("Vibrator file does not exist : %d", fd); + return 0; + } + + close(fd); + return 1; +} + +static int sendit(unsigned int timeout_ms) +{ + int to_write, written, ret, fd; + + char value[20]; /* large enough for millions of years */ + + fd = TEMP_FAILURE_RETRY(open(THE_DEVICE, O_RDWR)); + if(fd < 0) { + return -errno; + } + + to_write = snprintf(value, sizeof(value), "%u\n", timeout_ms); + written = TEMP_FAILURE_RETRY(write(fd, value, to_write)); + + if (written == -1) { + ret = -errno; + } else if (written != to_write) { + /* even though EAGAIN is an errno value that could be set + by write() in some cases, none of them apply here. So, this return + value can be clearly identified when debugging and suggests the + caller that it may try to call vibraror_on() again */ + ret = -EAGAIN; + } else { + ret = 0; + } + + errno = 0; + close(fd); + + return ret; +} + +static int vibra_on(vibrator_device_t* vibradev __unused, unsigned int timeout_ms) +{ + /* constant on, up to maximum allowed time */ + return sendit(timeout_ms); +} + +static int vibra_off(vibrator_device_t* vibradev __unused) +{ + return sendit(0); +} + +static int vibra_close(hw_device_t *device) +{ + free(device); + return 0; +} + +static int vibra_open(const hw_module_t* module, const char* id __unused, + hw_device_t** device __unused) { + if (!vibra_exists()) { + ALOGE("Vibrator device does not exist. Cannot start vibrator"); + return -ENODEV; + } + + vibrator_device_t *vibradev = calloc(1, sizeof(vibrator_device_t)); + + if (!vibradev) { + ALOGE("Can not allocate memory for the vibrator device"); + return -ENOMEM; + } + + vibradev->common.tag = HARDWARE_DEVICE_TAG; + vibradev->common.module = (hw_module_t *) module; + vibradev->common.version = HARDWARE_DEVICE_API_VERSION(1,0); + vibradev->common.close = vibra_close; + + vibradev->vibrator_on = vibra_on; + vibradev->vibrator_off = vibra_off; + + *device = (hw_device_t *) vibradev; + + return 0; +} + +/*===========================================================================*/ +/* Default vibrator HW module interface definition */ +/*===========================================================================*/ + +static struct hw_module_methods_t vibrator_module_methods = { + .open = vibra_open, +}; + +struct hw_module_t HAL_MODULE_INFO_SYM = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = VIBRATOR_API_VERSION, + .hal_api_version = HARDWARE_HAL_API_VERSION, + .id = VIBRATOR_HARDWARE_MODULE_ID, + .name = "Default vibrator HAL", + .author = "The Android Open Source Project", + .methods = &vibrator_module_methods, +}; |