2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <sys/types.h>
23 #include <linux/input.h>
24 #include <sys/ioctl.h>
29 #include <sensor_common.h>
30 #include <sensor_log.h>
32 #include "gyro_device.h"
34 #define MODEL_NAME "ICM20610"
35 #define VENDOR "Invensense"
37 #define RAW_DATA_UNIT 61.04
38 #define MIN_INTERVAL 5
39 #define MAX_BATCH_COUNT 30
41 #define SENSOR_NAME "SENSOR_GYROSCOPE"
42 #define SENSOR_TYPE_GYRO "GYRO"
44 #define INPUT_NAME "gyro_sensor"
45 #define GYRO_SENSORHUB_POLL_NODE_NAME "gyro_poll_delay"
47 #define DPS_TO_MDPS 1000
48 #define RAW_DATA_TO_DPS_UNIT(X) ((float)(X)/((float)DPS_TO_MDPS))
49 #define MIN_RANGE(RES) (-((1 << (RES))/2))
50 #define MAX_RANGE(RES) (((1 << (RES))/2)-1)
52 static sensor_info_t sensor_info = {
55 type: SENSOR_DEVICE_GYROSCOPE,
56 event_type: (SENSOR_DEVICE_GYROSCOPE << SENSOR_EVENT_SHIFT) | RAW_DATA_EVENT,
57 model_name: MODEL_NAME,
59 min_range: MIN_RANGE(RESOLUTION) * RAW_DATA_TO_DPS_UNIT(RAW_DATA_UNIT),
60 max_range: MAX_RANGE(RESOLUTION) * RAW_DATA_TO_DPS_UNIT(RAW_DATA_UNIT),
61 resolution: RAW_DATA_TO_DPS_UNIT(RAW_DATA_UNIT),
62 min_interval: MIN_INTERVAL,
63 max_batch_count: MAX_BATCH_COUNT,
64 wakeup_supported: false
67 gyro_device::gyro_device()
72 , m_polling_interval(1000)
74 , m_sensorhub_controlled(false)
76 const std::string sensorhub_interval_node_name = GYRO_SENSORHUB_POLL_NODE_NAME;
78 node_info_query query;
81 query.sensorhub_controlled = m_sensorhub_controlled = util::is_sensorhub_controlled(sensorhub_interval_node_name);
82 query.sensor_type = SENSOR_TYPE_GYRO;
83 query.key = INPUT_NAME;
84 query.iio_enable_node_name = "gyro_enable";
85 query.sensorhub_interval_node_name = sensorhub_interval_node_name;
87 if (!util::get_node_info(query, info)) {
88 _E("Failed to get node info");
92 util::show_node_info(info);
94 m_method = info.method;
95 m_data_node = info.data_node_path;
96 m_enable_node = info.enable_node_path;
97 m_interval_node = info.interval_node_path;
99 m_node_handle = open(m_data_node.c_str(), O_RDONLY);
101 if (m_node_handle < 0) {
102 _ERRNO(errno, _E, "Failed to open gyro handle");
106 if (m_method == INPUT_EVENT_METHOD) {
107 if (!util::set_monotonic_clock(m_node_handle))
110 update_value = [=]() {
111 return this->update_value_input_event();
114 if (!info.buffer_length_node_path.empty())
115 util::set_node_value(info.buffer_length_node_path, 600);
117 if (!info.buffer_enable_node_path.empty())
118 util::set_node_value(info.buffer_enable_node_path, 1);
120 update_value = [=]() {
121 return this->update_value_iio();
125 _I("gyro_device is created!");
128 gyro_device::~gyro_device()
130 close(m_node_handle);
133 _I("gyro_device is destroyed!");
136 int gyro_device::get_poll_fd(void)
138 return m_node_handle;
141 int gyro_device::get_sensors(const sensor_info_t **sensors)
143 *sensors = &sensor_info;
148 bool gyro_device::enable(uint32_t id)
150 util::set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_GYROSCOPE_ENABLE_BIT);
151 set_interval(id, m_polling_interval);
154 _I("Enable gyroscope sensor");
158 bool gyro_device::disable(uint32_t id)
160 util::set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_GYROSCOPE_ENABLE_BIT);
162 _I("Disable gyroscope sensor");
166 bool gyro_device::set_interval(uint32_t id, unsigned long val)
168 unsigned long long polling_interval_ns;
170 polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
172 if (!util::set_node_value(m_interval_node, polling_interval_ns)) {
173 _E("Failed to set polling resource: %s", m_interval_node.c_str());
177 _I("Interval is changed from %dms to %dms", m_polling_interval, val);
178 m_polling_interval = val;
182 bool gyro_device::update_value_input_event(void)
184 int gyro_raw[3] = {0, };
186 int read_input_cnt = 0;
187 const int INPUT_MAX_BEFORE_SYN = 10;
188 unsigned long long fired_time = 0;
193 struct input_event gyro_input;
194 _D("gyro event detection!");
196 while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
197 int len = read(m_node_handle, &gyro_input, sizeof(gyro_input));
198 if (len != sizeof(gyro_input)) {
199 _E("gyro_file read fail, read_len = %d", len);
205 if (gyro_input.type == EV_REL) {
206 switch (gyro_input.code) {
208 gyro_raw[0] = (int)gyro_input.value;
212 gyro_raw[1] = (int)gyro_input.value;
216 gyro_raw[2] = (int)gyro_input.value;
220 _E("gyro_input event[type = %d, code = %d] is unknown.", gyro_input.type, gyro_input.code);
224 } else if (gyro_input.type == EV_SYN) {
226 fired_time = util::get_timestamp(&gyro_input.time);
228 _E("gyro_input event[type = %d, code = %d] is unknown.", gyro_input.type, gyro_input.code);
234 _E("EV_SYN didn't come until %d inputs had come", read_input_cnt);
245 m_fired_time = fired_time;
247 _D("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
252 bool gyro_device::update_value_iio(void)
259 } __attribute__((packed)) data;
263 pfd.fd = m_node_handle;
264 pfd.events = POLLIN | POLLERR;
267 int ret = poll(&pfd, 1, -1);
270 _ERRNO(errno, _E, "Failed to poll from m_node_handle:%d", m_node_handle);
273 _E("poll timeout m_node_handle:%d", m_node_handle);
277 if (pfd.revents & POLLERR) {
278 _E("poll exception occurred! m_node_handle:%d", m_node_handle);
282 if (!(pfd.revents & POLLIN)) {
283 _E("poll nothing to read! m_node_handle:%d, pfd.revents = %d", m_node_handle, pfd.revents);
287 int len = read(m_node_handle, &data, sizeof(data));
289 if (len != sizeof(data)) {
290 _E("Failed to read data, m_node_handle:%d read_len:%d", m_node_handle, len);
297 m_fired_time = NSEC_TO_MSEC(data.timestamp);
299 _D("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
304 int gyro_device::read_fd(uint32_t **ids)
306 if (!update_value()) {
307 _D("Failed to update value");
312 event_ids.push_back(sensor_info.id);
314 *ids = &event_ids[0];
316 return event_ids.size();
319 int gyro_device::get_data(uint32_t id, sensor_data_t **data, int *length)
321 sensor_data_t *sensor_data;
322 sensor_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
323 retvm_if(!sensor_data, -ENOMEM, "Memory allocation failed");
325 sensor_data->accuracy = SENSOR_ACCURACY_GOOD;
326 sensor_data->timestamp = m_fired_time;
327 sensor_data->value_count = 3;
328 sensor_data->values[0] = m_x;
329 sensor_data->values[1] = m_y;
330 sensor_data->values[2] = m_z;
332 raw_to_base(sensor_data);
335 *length = sizeof(sensor_data_t);
340 void gyro_device::raw_to_base(sensor_data_t *data)
342 data->values[0] = data->values[0] * RAW_DATA_TO_DPS_UNIT(RAW_DATA_UNIT);
343 data->values[1] = data->values[1] * RAW_DATA_TO_DPS_UNIT(RAW_DATA_UNIT);
344 data->values[2] = data->values[2] * RAW_DATA_TO_DPS_UNIT(RAW_DATA_UNIT);