1022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker/*
2022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker * Copyright (C) 2013 The Android Open Source Project
3022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker *
4022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker * Licensed under the Apache License, Version 2.0 (the "License");
5022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker * you may not use this file except in compliance with the License.
6022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker * You may obtain a copy of the License at
7022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker *
8022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker *      http://www.apache.org/licenses/LICENSE-2.0
9022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker *
10022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker * Unless required by applicable law or agreed to in writing, software
11022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker * distributed under the License is distributed on an "AS IS" BASIS,
12022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker * See the License for the specific language governing permissions and
14022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker * limitations under the License.
15022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker */
16022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
17022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker#include <hardware/vibrator.h>
18022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker#include <hardware/hardware.h>
19022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
20022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker#include <cutils/log.h>
21022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
2207c085565a3b24bb658d05b8aa08fb7420725602Elliott Hughes#include <malloc.h>
23022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker#include <stdio.h>
24022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker#include <unistd.h>
25022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker#include <fcntl.h>
26022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker#include <errno.h>
27022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker#include <math.h>
28022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
29022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Beckerstatic const char THE_DEVICE[] = "/sys/class/timed_output/vibrator/enable";
30022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
31022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Beckerstatic int vibra_exists() {
32022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    int fd;
33022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
34022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    fd = TEMP_FAILURE_RETRY(open(THE_DEVICE, O_RDWR));
35022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    if(fd < 0) {
36022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        ALOGE("Vibrator file does not exist : %d", fd);
37022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        return 0;
38022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    }
39022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
40022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    close(fd);
41022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    return 1;
42022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker}
43022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
44022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Beckerstatic int sendit(unsigned int timeout_ms)
45022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker{
46022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    int to_write, written, ret, fd;
47022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
48022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    char value[20]; /* large enough for millions of years */
49022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
50022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    fd = TEMP_FAILURE_RETRY(open(THE_DEVICE, O_RDWR));
51022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    if(fd < 0) {
52022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        return -errno;
53022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    }
54022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
55022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    to_write = snprintf(value, sizeof(value), "%u\n", timeout_ms);
56022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    written = TEMP_FAILURE_RETRY(write(fd, value, to_write));
57022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
58022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    if (written == -1) {
59022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        ret = -errno;
60022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    } else if (written != to_write) {
61022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        /* even though EAGAIN is an errno value that could be set
62022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker           by write() in some cases, none of them apply here.  So, this return
63022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker           value can be clearly identified when debugging and suggests the
64022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker           caller that it may try to call vibraror_on() again */
65022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        ret = -EAGAIN;
66022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    } else {
67022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        ret = 0;
68022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    }
69022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
70022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    errno = 0;
71022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    close(fd);
72022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
73022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    return ret;
74022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker}
75022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
76022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Beckerstatic int vibra_on(vibrator_device_t* vibradev __unused, unsigned int timeout_ms)
77022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker{
78022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    /* constant on, up to maximum allowed time */
79022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    return sendit(timeout_ms);
80022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker}
81022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
82022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Beckerstatic int vibra_off(vibrator_device_t* vibradev __unused)
83022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker{
84022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    return sendit(0);
85022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker}
86022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
87022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Beckerstatic int vibra_close(hw_device_t *device)
88022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker{
89022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    free(device);
90022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    return 0;
91022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker}
92022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
93022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Beckerstatic int vibra_open(const hw_module_t* module, const char* id __unused,
94022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker                      hw_device_t** device __unused) {
95022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    if (!vibra_exists()) {
96022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        ALOGE("Vibrator device does not exist. Cannot start vibrator");
97022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        return -ENODEV;
98022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    }
99022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
100022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    vibrator_device_t *vibradev = calloc(1, sizeof(vibrator_device_t));
101022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
102022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    if (!vibradev) {
103022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        ALOGE("Can not allocate memory for the vibrator device");
104022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker        return -ENOMEM;
105022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    }
106022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
107022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    vibradev->common.tag = HARDWARE_DEVICE_TAG;
108022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    vibradev->common.module = (hw_module_t *) module;
109022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    vibradev->common.version = HARDWARE_DEVICE_API_VERSION(1,0);
110022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    vibradev->common.close = vibra_close;
111022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
112022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    vibradev->vibrator_on = vibra_on;
113022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    vibradev->vibrator_off = vibra_off;
114022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
115022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    *device = (hw_device_t *) vibradev;
116022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
117022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    return 0;
118022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker}
119022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
120022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker/*===========================================================================*/
121022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker/* Default vibrator HW module interface definition                           */
122022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker/*===========================================================================*/
123022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
124022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Beckerstatic struct hw_module_methods_t vibrator_module_methods = {
125022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    .open = vibra_open,
126022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker};
127022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker
128022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Beckerstruct hw_module_t HAL_MODULE_INFO_SYM = {
129022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    .tag = HARDWARE_MODULE_TAG,
130022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    .module_api_version = VIBRATOR_API_VERSION,
131022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    .hal_api_version = HARDWARE_HAL_API_VERSION,
132022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    .id = VIBRATOR_HARDWARE_MODULE_ID,
133022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    .name = "Default vibrator HAL",
134022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    .author = "The Android Open Source Project",
135022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker    .methods = &vibrator_module_methods,
136022224fbf883bb1600a69e4537b9a80eed35fbb8Vincent Becker};
137