4 * Copyright (c) 2014 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.
22 #include <linux/input.h>
23 #include <csensor_config.h>
24 #include <rv_raw_sensor_hal.h>
25 #include <sys/ioctl.h>
31 #define SENSOR_TYPE_RV_RAW "ROTATION_VECTOR"
32 #define ELEMENT_NAME "NAME"
33 #define ELEMENT_VENDOR "VENDOR"
34 #define ATTR_VALUE "value"
36 rv_raw_sensor_hal::rv_raw_sensor_hal()
41 , m_polling_interval(POLL_1HZ_MS)
43 const string sensorhub_interval_node_name = "rot_poll_delay";
44 csensor_config &config = csensor_config::get_instance();
46 node_info_query query;
49 if (!find_model_id(SENSOR_TYPE_RV_RAW, m_model_id)) {
50 ERR("Failed to find model id");
55 query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
56 query.sensor_type = SENSOR_TYPE_RV_RAW;
57 query.key = "rot_sensor";
58 query.iio_enable_node_name = "rot_enable";
59 query.sensorhub_interval_node_name = sensorhub_interval_node_name;
61 if (!get_node_info(query, info)) {
62 ERR("Failed to get node info");
68 m_data_node = info.data_node_path;
69 m_enable_node = info.enable_node_path;
70 m_interval_node = info.interval_node_path;
72 if (!config.get(SENSOR_TYPE_RV_RAW, m_model_id, ELEMENT_VENDOR, m_vendor)) {
73 ERR("[VENDOR] is empty\n");
77 INFO("m_vendor = %s", m_vendor.c_str());
79 if (!config.get(SENSOR_TYPE_RV_RAW, m_model_id, ELEMENT_NAME, m_chip_name)) {
80 ERR("[NAME] is empty\n");
84 INFO("m_chip_name = %s", m_chip_name.c_str());
86 if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) {
87 ERR("Failed to open handle(%d)", m_node_handle);
91 int clockId = CLOCK_MONOTONIC;
92 if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
93 ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
95 INFO("rv_raw_sensor_hal is created!\n");
98 rv_raw_sensor_hal::~rv_raw_sensor_hal()
100 close(m_node_handle);
103 INFO("rv_raw_sensor_hal is destroyed!\n");
106 string rv_raw_sensor_hal::get_model_id(void)
111 sensor_hal_type_t rv_raw_sensor_hal::get_type(void)
113 return SENSOR_HAL_TYPE_RV_RAW;
116 bool rv_raw_sensor_hal::enable(void)
120 set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_ROTATION_VECTOR_ENABLE_BIT);
121 set_interval(m_polling_interval);
124 INFO("Rotation vector raw sensor real starting");
128 bool rv_raw_sensor_hal::disable(void)
132 set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_ROTATION_VECTOR_ENABLE_BIT);
134 INFO("Rotation vector raw sensor real stopping");
138 bool rv_raw_sensor_hal::set_interval(unsigned long val)
140 unsigned long long polling_interval_ns;
144 polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
146 if (!set_node_value(m_interval_node, polling_interval_ns)) {
147 ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
151 INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
152 m_polling_interval = val;
156 bool rv_raw_sensor_hal::update_value(void)
158 int rot_raw[5] = {0,};
159 bool quat_a,quat_b,quat_c,quat_d,acc_rot;
160 int read_input_cnt = 0;
161 const int INPUT_MAX_BEFORE_SYN = 10;
162 unsigned long long fired_time = 0;
165 quat_a = quat_b = quat_c = quat_d = acc_rot = false;
167 struct input_event rot_input;
168 DBG("geo event detection!");
170 while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
171 int len = read(m_node_handle, &rot_input, sizeof(rot_input));
172 if (len != sizeof(rot_input)) {
173 ERR("rot_file read fail, read_len = %d\n",len);
179 if (rot_input.type == EV_REL) {
180 switch (rot_input.code) {
182 rot_raw[0] = (int)rot_input.value;
186 rot_raw[1] = (int)rot_input.value;
190 rot_raw[2] = (int)rot_input.value;
194 rot_raw[3] = (int)rot_input.value;
198 rot_raw[4] = (int)rot_input.value;
202 ERR("rot_input event[type = %d, code = %d] is unknown.", rot_input.type, rot_input.code);
206 } else if (rot_input.type == EV_SYN) {
208 fired_time = sensor_hal_base::get_timestamp(&rot_input.time);
210 ERR("rot_input event[type = %d, code = %d] is unknown.", rot_input.type, rot_input.code);
215 AUTOLOCK(m_value_mutex);
218 m_quat_a = rot_raw[0];
220 m_quat_b = rot_raw[1];
222 m_quat_c = rot_raw[2];
224 m_quat_d = rot_raw[3];
226 m_accuracy = rot_raw[4] - 1; /* accuracy bias: -1 */
228 m_fired_time = fired_time;
230 DBG("m_quat_a = %d, m_quat_a = %d, m_quat_a = %d, m_quat_d = %d, m_accuracy = %d, time = %lluus",
231 m_quat_a, m_quat_a, m_quat_a, m_quat_d, m_accuracy, m_fired_time);
236 bool rv_raw_sensor_hal::is_data_ready(void)
239 ret = update_value();
243 int rv_raw_sensor_hal::get_sensor_data(sensor_data_t &data)
245 const float QUAT_SIG_FIGS = 1000000.0f;
247 data.accuracy = (m_accuracy == 1) ? 0 : m_accuracy; /* hdst 0 and 1 are needed to calibrate */
248 data.timestamp = m_fired_time;
249 data.value_count = 4;
250 data.values[0] = (float)m_quat_a / QUAT_SIG_FIGS;
251 data.values[1] = (float)m_quat_b / QUAT_SIG_FIGS;
252 data.values[2] = (float)m_quat_c / QUAT_SIG_FIGS;
253 data.values[3] = (float)m_quat_d / QUAT_SIG_FIGS;
257 bool rv_raw_sensor_hal::get_properties(sensor_properties_s &properties)
259 properties.name = m_chip_name;
260 properties.vendor = m_vendor;
261 properties.min_range = 0;
262 properties.max_range = 1200;
263 properties.min_interval = 1;
264 properties.resolution = 1;
265 properties.fifo_count = 0;
266 properties.max_batch_count = 0;