4 * Copyright (c) 2016 - 2017 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
27 #include <sys/types.h>
30 #include "core/list.h"
32 #include "standard-vibcore.h"
34 #define CIRCLE_ON_PATH "/sys/class/sec/motor/motor_on"
35 #define CIRCLE_OFF_PATH "/sys/class/sec/motor/motor_off"
39 static int fd_play = -1, fd_stop = -1;
40 static dd_list *handle_list;
41 static guint stop_timer;
42 static int unique_number;
43 static bool state = false;
45 static int stop_device(int device_handle);
46 static bool find_from_list(int handle)
50 elem = DD_LIST_FIND(handle_list, (gpointer)(long)handle);
57 static gboolean timer_cb(void *data)
59 int device_handle = (int)(long)data;
64 _I("stop vibration by timer");
66 found = find_from_list(device_handle);
68 return G_SOURCE_REMOVE;
70 /* stop previous vibration */
72 fd_stop = open(CIRCLE_OFF_PATH, O_RDONLY);
74 return G_SOURCE_REMOVE;
76 ret = read(fd_stop, buf, BUF_SIZE);
79 return G_SOURCE_REMOVE;
83 return G_SOURCE_REMOVE;
86 static int get_device_count(int *count)
88 /* suppose there is just one haptic device */
95 static int open_device(int device_index, int *device_handle)
104 /* if it is the first element */
105 n = DD_LIST_LENGTH(handle_list);
109 fd_play = open(CIRCLE_ON_PATH, O_RDONLY);
111 _E("Failed to open %s : %d", CIRCLE_ON_PATH, errno);
116 fd_stop = open(CIRCLE_OFF_PATH, O_RDONLY);
118 _E("Failed to open %s : %d", CIRCLE_OFF_PATH, errno);
124 if (unique_number == INT_MAX)
127 while (found != true) {
129 elem = DD_LIST_FIND(handle_list, (gpointer)(long)unique_number);
134 /* add info to local list */
135 DD_LIST_APPEND(handle_list, (gpointer)(long)unique_number);
137 *device_handle = unique_number;
141 static int close_device(int device_handle)
146 found = find_from_list(device_handle);
151 fd_stop = open(CIRCLE_OFF_PATH, O_RDONLY);
157 r = stop_device(device_handle);
159 _I("already stopped or failed to stop effect : %d", r);
161 /* unregister existing timer */
163 _D("device handle %d is closed and timer deleted", device_handle);
165 g_source_remove(stop_timer);
170 standard_vibrate_close();
172 DD_LIST_REMOVE(handle_list, (gpointer)(long)device_handle);
174 /* if it is the last element */
175 n = DD_LIST_LENGTH(handle_list);
191 static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
197 found = find_from_list(device_handle);
202 fd_play = open(CIRCLE_ON_PATH, O_RDONLY);
207 /* Zero(0) is the infinitely vibration value */
208 if (duration == HAPTIC_MODULE_DURATION_UNLIMITED)
212 stop_device(device_handle);
215 ret = read(fd_play, buf, BUF_SIZE);
217 _E("failed to play");
223 stop_timer = g_timeout_add(duration, timer_cb, (void *)(long)device_handle);
226 _E("Failed to add timer callback");
229 _D("device handle %d %dms", device_handle, duration);
231 *effect_handle = device_handle;
236 static int vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
238 _E("Not support feature");
242 static int stop_device(int device_handle)
248 found = find_from_list(device_handle);
252 if (cur_h_data.handle > 0 && cur_h_data.handle != device_handle) {
253 _E("Only same handle can stop current vibration");
257 /* Remove duration_timer for vibrate_effect */
258 standard_vibrate_close();
261 fd_stop = open(CIRCLE_OFF_PATH, O_RDONLY);
265 ret = read(fd_stop, buf, BUF_SIZE);
267 _E("failed to stop");
271 g_source_remove(stop_timer);
278 static int get_device_state(int device_index, int *effect_state)
283 *effect_state = state;
287 static int create_effect(unsigned char *vibe_buffer, int max_bufsize, const haptic_module_effect_element *elem_arr, int max_elemcnt)
289 _E("Not support feature");
293 static int get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
295 _E("Not support feature");
299 static int convert_binary(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
301 _E("Not support feature");
304 /* END: Haptic Module APIs */
306 static const struct haptic_plugin_ops default_plugin = {
307 .get_device_count = get_device_count,
308 .open_device = open_device,
309 .close_device = close_device,
310 .vibrate_monotone = vibrate_monotone,
311 .vibrate_buffer = vibrate_buffer,
312 .vibrate_effect = standard_vibrate_effect,
313 .is_supported = standard_is_supported,
314 .stop_device = stop_device,
315 .get_device_state = get_device_state,
316 .create_effect = create_effect,
317 .get_buffer_duration = get_buffer_duration,
318 .convert_binary = convert_binary,
321 static bool is_valid(void)
323 if ((access(CIRCLE_ON_PATH, R_OK) != 0) ||
324 (access(CIRCLE_OFF_PATH, R_OK) != 0)) {
325 _E("Do not support wearable haptic device");
330 standard_config_parse();
333 _I("Support wearable haptic device");
337 static const struct haptic_plugin_ops *load(void)
339 standard_set_vib_function(&vibrate_monotone);
340 return &default_plugin;
343 static const struct haptic_ops std_ops = {
344 .type = HAPTIC_STANDARD,
345 .is_valid = is_valid,
349 HAPTIC_OPS_REGISTER(&std_ops)