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>
28 #include <sensor_common.h>
29 #include <sensor_log.h>
31 #include "accel_device.h"
33 #define GRAVITY 9.80665
35 #define RAW_DATA_TO_G_UNIT(X) (((float)(X))/((float)G_TO_MG))
36 #define RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(X) (GRAVITY * (RAW_DATA_TO_G_UNIT(X)))
38 #define MIN_RANGE(RES) (-((1 << (RES))/2))
39 #define MAX_RANGE(RES) (((1 << (RES))/2)-1)
41 #define MODEL_NAME "K2HH"
42 #define VENDOR "ST Microelectronics"
44 #define RAW_DATA_UNIT 0.122
45 #define MIN_INTERVAL 1
46 #define MAX_BATCH_COUNT 0
48 #define SENSOR_NAME "SENSOR_ACCELEROMETER"
49 #define SENSOR_TYPE_ACCEL "ACCEL"
51 #define INPUT_NAME "accelerometer_sensor"
52 #define ACCEL_SENSORHUB_POLL_NODE_NAME "accel_poll_delay"
54 static sensor_info_t sensor_info = {
57 type: SENSOR_DEVICE_ACCELEROMETER,
58 event_type: (SENSOR_DEVICE_ACCELEROMETER << SENSOR_EVENT_SHIFT) | RAW_DATA_EVENT,
59 model_name: MODEL_NAME,
61 min_range: MIN_RANGE(RESOLUTION) * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(RAW_DATA_UNIT),
62 max_range: MAX_RANGE(RESOLUTION) * RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(RAW_DATA_UNIT),
63 resolution: RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(RAW_DATA_UNIT),
64 min_interval: MIN_INTERVAL,
65 max_batch_count: MAX_BATCH_COUNT,
66 wakeup_supported: false
69 accel_device::accel_device()
74 , m_polling_interval(1000)
76 , m_sensorhub_controlled(false)
78 const std::string sensorhub_interval_node_name = ACCEL_SENSORHUB_POLL_NODE_NAME;
80 node_info_query query;
83 query.sensorhub_controlled = m_sensorhub_controlled = util::is_sensorhub_controlled(sensorhub_interval_node_name);
84 query.sensor_type = SENSOR_TYPE_ACCEL;
85 query.key = INPUT_NAME;
86 query.iio_enable_node_name = "accel_enable";
87 query.sensorhub_interval_node_name = sensorhub_interval_node_name;
89 if (!util::get_node_info(query, info)) {
90 _E("Failed to get node info");
94 util::show_node_info(info);
96 m_method = info.method;
97 m_data_node = info.data_node_path;
98 m_enable_node = info.enable_node_path;
99 m_interval_node = info.interval_node_path;
101 m_node_handle = open(m_data_node.c_str(), O_RDONLY);
103 if (m_node_handle < 0) {
104 _ERRNO(errno, _E, "accel handle open fail for accel processor");
108 if (m_method == INPUT_EVENT_METHOD) {
109 if (!util::set_monotonic_clock(m_node_handle))
112 update_value = [=]() {
113 return this->update_value_input_event();
116 if (!info.buffer_length_node_path.empty())
117 util::set_node_value(info.buffer_length_node_path, 480);
119 if (!info.buffer_enable_node_path.empty())
120 util::set_node_value(info.buffer_enable_node_path, 1);
122 update_value = [=]() {
123 return this->update_value_iio();
127 _I("accel_sensor is created!");
130 accel_device::~accel_device()
132 close(m_node_handle);
135 _I("accel_sensor is destroyed!");
138 int accel_device::get_poll_fd()
140 return m_node_handle;
143 int accel_device::get_sensors(const sensor_info_t **sensors)
145 *sensors = &sensor_info;
150 bool accel_device::enable(uint32_t id)
152 util::set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_ACCELEROMETER_ENABLE_BIT);
153 set_interval(id, m_polling_interval);
156 _I("Enable accelerometer sensor");
160 bool accel_device::disable(uint32_t id)
162 util::set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_ACCELEROMETER_ENABLE_BIT);
164 _I("Disable accelerometer sensor");
168 bool accel_device::set_interval(uint32_t id, unsigned long val)
170 unsigned long long polling_interval_ns;
172 polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
174 if (!util::set_node_value(m_interval_node, polling_interval_ns)) {
175 _E("Failed to set polling resource: %s", m_interval_node.c_str());
179 _I("Interval is changed from %dms to %dms", m_polling_interval, val);
180 m_polling_interval = val;
184 bool accel_device::update_value_input_event(void)
186 int accel_raw[3] = {0,};
188 int read_input_cnt = 0;
189 const int INPUT_MAX_BEFORE_SYN = 10;
190 unsigned long long fired_time = 0;
195 struct input_event accel_input;
196 _D("accel event detection!");
198 while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
199 int len = read(m_node_handle, &accel_input, sizeof(accel_input));
200 if (len != sizeof(accel_input)) {
201 _E("accel_file read fail, read_len = %d",len);
207 if (accel_input.type == EV_REL) {
208 switch (accel_input.code) {
210 accel_raw[0] = (int)accel_input.value;
214 accel_raw[1] = (int)accel_input.value;
218 accel_raw[2] = (int)accel_input.value;
222 _E("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code);
226 } else if (accel_input.type == EV_SYN) {
228 fired_time = util::get_timestamp(&accel_input.time);
230 _E("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code);
236 _E("EV_SYN didn't come until %d inputs had come", read_input_cnt);
247 m_fired_time = fired_time;
249 _D("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
254 bool accel_device::update_value_iio(void)
261 } __attribute__((packed)) data;
265 pfd.fd = m_node_handle;
266 pfd.events = POLLIN | POLLERR;
269 int ret = poll(&pfd, 1, -1);
272 _ERRNO(errno, _E, "Failed to poll from m_node_handle:%d", m_node_handle);
275 _E("poll timeout m_node_handle:%d", m_node_handle);
279 if (pfd.revents & POLLERR) {
280 _E("poll exception occurred! m_node_handle:%d", m_node_handle);
284 if (!(pfd.revents & POLLIN)) {
285 _E("poll nothing to read! m_node_handle:%d, pfd.revents = %d", m_node_handle, pfd.revents);
289 int len = read(m_node_handle, &data, sizeof(data));
291 if (len != sizeof(data)) {
292 _E("Failed to read data, m_node_handle:%d read_len:%d", m_node_handle, len);
299 m_fired_time = data.timestamp;
301 _D("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
306 int accel_device::read_fd(uint32_t **ids)
308 if (!update_value()) {
309 _D("Failed to update value");
314 event_ids.push_back(sensor_info.id);
316 *ids = &event_ids[0];
318 return event_ids.size();
321 int accel_device::get_data(uint32_t id, sensor_data_t **data, int *length)
324 sensor_data_t *sensor_data;
325 sensor_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
326 retvm_if(!sensor_data, -ENOMEM, "Memory allocation failed");
328 sensor_data->accuracy = SENSOR_ACCURACY_GOOD;
329 sensor_data->timestamp = m_fired_time;
330 sensor_data->value_count = 3;
331 sensor_data->values[0] = m_x;
332 sensor_data->values[1] = m_y;
333 sensor_data->values[2] = m_z;
335 raw_to_base(sensor_data);
338 *length = sizeof(sensor_data_t);
343 void accel_device::raw_to_base(sensor_data_t *data)
345 data->value_count = 3;
346 data->values[0] = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(data->values[0] * RAW_DATA_UNIT);
347 data->values[1] = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(data->values[1] * RAW_DATA_UNIT);
348 data->values[2] = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(data->values[2] * RAW_DATA_UNIT);