summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2014-04-21 17:53:25 +0200
committerPaul Kocialkowski <contact@paulk.fr>2014-04-21 17:53:25 +0200
commit630a0a55fbb8d3b3a7e7154fd865346987a7b318 (patch)
tree04dabc9bc072ca529789bb3323c6018ba8dd299d
parent526a0c4b954021654e0f44ed8e50ca7c02e2429d (diff)
downloaddevice_goldelico_gta04-630a0a55fbb8d3b3a7e7154fd865346987a7b318.zip
device_goldelico_gta04-630a0a55fbb8d3b3a7e7154fd865346987a7b318.tar.gz
device_goldelico_gta04-630a0a55fbb8d3b3a7e7154fd865346987a7b318.tar.bz2
Vibrator implementation using rumble input
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
-rwxr-xr-xBoardConfig.mk3
-rw-r--r--overlay/packages/inputmethods/LatinIME/java/res/values/config.xml20
-rw-r--r--vibrator/vibrator.c188
3 files changed, 211 insertions, 0 deletions
diff --git a/BoardConfig.mk b/BoardConfig.mk
index e3a564a..d4f6f73 100755
--- a/BoardConfig.mk
+++ b/BoardConfig.mk
@@ -65,6 +65,9 @@ USE_CAMERA_STUB := true
BOARD_HAS_NO_SELECT_BUTTON := true
+# Vibrator
+BOARD_HAS_VIBRATOR_IMPLEMENTATION := ../../device/goldelico/gta04/vibrator/vibrator.c
+
# Boot animation
TARGET_BOOTANIMATION_PRELOAD := true
TARGET_BOOTANIMATION_TEXTURE_CACHE := true
diff --git a/overlay/packages/inputmethods/LatinIME/java/res/values/config.xml b/overlay/packages/inputmethods/LatinIME/java/res/values/config.xml
new file mode 100644
index 0000000..3bab366
--- /dev/null
+++ b/overlay/packages/inputmethods/LatinIME/java/res/values/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Paul Kocialkowski <contact@paulk.fr>
+
+ 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.
+ -->
+
+<resources>
+ <bool name="config_default_vibration_enabled">false</bool>
+</resources>
diff --git a/vibrator/vibrator.c b/vibrator/vibrator.c
new file mode 100644
index 0000000..5d8d203
--- /dev/null
+++ b/vibrator/vibrator.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2014 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * 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 <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <linux/input.h>
+
+#define LOG_TAG "vibrator"
+#include <cutils/log.h>
+
+/*
+ * Globals
+ */
+
+const char rumble_input[] = "twl4030:vibrator";
+
+int rumble_fd = -1;
+int rumble_id = -1;
+
+/*
+ * Input
+ */
+
+void input_event_set(struct input_event *event, int type, int code, int value)
+{
+ if (event == NULL)
+ return;
+
+ memset(event, 0, sizeof(struct input_event));
+
+ event->type = type,
+ event->code = code;
+ event->value = value;
+
+ gettimeofday(&event->time, NULL);
+}
+
+int input_open(const char *name)
+{
+ DIR *d;
+ struct dirent *di;
+
+ char input_name[80] = { 0 };
+ char path[PATH_MAX];
+ char *c;
+ int fd;
+ int rc;
+
+ if (name == NULL)
+ return -EINVAL;
+
+ d = opendir("/dev/input");
+ if (d == NULL)
+ return -1;
+
+ while ((di = readdir(d))) {
+ if (di == NULL || strcmp(di->d_name, ".") == 0 || strcmp(di->d_name, "..") == 0)
+ continue;
+
+ snprintf(path, PATH_MAX, "/dev/input/%s", di->d_name);
+ fd = open(path, O_RDWR | O_NONBLOCK);
+ if (fd < 0)
+ continue;
+
+ rc = ioctl(fd, EVIOCGNAME(sizeof(input_name) - 1), &input_name);
+ if (rc < 0)
+ continue;
+
+ c = strstr((char *) &input_name, "\n");
+ if (c != NULL)
+ *c = '\0';
+
+ if (strcmp(input_name, name) == 0)
+ return fd;
+ else
+ close(fd);
+ }
+
+ return -1;
+}
+
+/*
+ * Vibrator
+ */
+
+int vibrator_exists(void)
+{
+ int fd;
+
+ fd = input_open(rumble_input);
+ if (fd < 0)
+ return 0;
+
+ close(fd);
+
+ return 1;
+}
+
+int sendit(int duration)
+{
+ struct input_event event;
+ struct ff_effect effect;
+ int rc;
+
+ if (rumble_fd < 0)
+ rumble_fd = input_open(rumble_input);
+
+ if (rumble_fd < 0)
+ goto error;
+
+ if (rumble_id >= 0) {
+ input_event_set(&event, EV_FF, rumble_id, 0);
+
+ rc = write(rumble_fd, &event, sizeof(event));
+ if (rc < (int) sizeof(event))
+ goto error;
+
+ ioctl(rumble_fd, EVIOCRMFF, &rumble_id);
+
+ rumble_id = -1;
+ }
+
+ // Previous code should have removed the effect already
+ if (duration == 0) {
+ rc = 0;
+ goto complete;
+ }
+
+ memset(&effect, 0, sizeof(effect));
+ effect.type = FF_RUMBLE;
+ effect.id = -1;
+ effect.replay.length = duration;
+ effect.replay.delay = 0;
+ effect.u.rumble.strong_magnitude = 0xffff;
+
+ rc = ioctl(rumble_fd, EVIOCSFF, &effect);
+ if (rc < 0)
+ goto error;
+
+ rumble_id = effect.id;
+
+ input_event_set(&event, EV_FF, rumble_id, 1);
+
+ rc = write(rumble_fd, &event, sizeof(event));
+ if (rc < (int) sizeof(event))
+ goto error;
+
+ rc = 0;
+ goto complete;
+
+error:
+ if (rumble_fd >= 0) {
+ if (rumble_id >= 0) {
+ input_event_set(&event, EV_FF, rumble_id, 0);
+ write(rumble_fd, &event, sizeof(event));
+
+ ioctl(rumble_fd, EVIOCRMFF, &rumble_id);
+ rumble_id = -1;
+ }
+
+ close(rumble_fd);
+ rumble_fd = -1;
+ }
+
+ rc = -1;
+
+complete:
+ return rc;
+}