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.
21 #include <linux/input.h>
22 #include <csensor_config.h>
23 #include <accel_sensor_hal.h>
29 #define GRAVITY 9.80665
31 #define RAW_DATA_TO_G_UNIT(X) (((float)(X))/((float)G_TO_MG))
32 #define RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(X) (GRAVITY * (RAW_DATA_TO_G_UNIT(X)))
34 #define MIN_RANGE(RES) (-((1 << (RES))/2))
35 #define MAX_RANGE(RES) (((1 << (RES))/2)-1)
37 #define SENSOR_TYPE_ACCEL "ACCEL"
38 #define ELEMENT_NAME "NAME"
39 #define ELEMENT_VENDOR "VENDOR"
40 #define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT"
41 #define ELEMENT_RESOLUTION "RESOLUTION"
43 #define ATTR_VALUE "value"
45 #define INPUT_NAME "accelerometer_sensor"
46 #define ACCEL_SENSORHUB_POLL_NODE_NAME "accel_poll_delay"
48 accel_sensor_hal::accel_sensor_hal()
53 , m_polling_interval(POLL_1HZ_MS)
56 const string sensorhub_interval_node_name = "accel_poll_delay";
57 csensor_config &config = csensor_config::get_instance();
59 node_info_query query;
62 if (!find_model_id(SENSOR_TYPE_ACCEL, m_model_id)) {
63 ERR("Failed to find model id");
67 query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
68 query.sensor_type = SENSOR_TYPE_ACCEL;
69 query.key = "accelerometer_sensor";
70 query.iio_enable_node_name = "accel_enable";
71 query.sensorhub_interval_node_name = sensorhub_interval_node_name;
73 if (!get_node_info(query, info)) {
74 ERR("Failed to get node info");
80 m_method = info.method;
81 m_data_node = info.data_node_path;
82 m_enable_node = info.enable_node_path;
83 m_interval_node = info.interval_node_path;
85 if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_VENDOR, m_vendor)) {
86 ERR("[VENDOR] is empty\n");
90 INFO("m_vendor = %s", m_vendor.c_str());
92 if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_NAME, m_chip_name)) {
93 ERR("[NAME] is empty\n");
97 INFO("m_chip_name = %s\n",m_chip_name.c_str());
101 if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_RESOLUTION, resolution)) {
102 ERR("[RESOLUTION] is empty\n");
106 m_resolution = (int)resolution;
108 INFO("m_resolution = %d\n",m_resolution);
110 double raw_data_unit;
112 if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) {
113 ERR("[RAW_DATA_UNIT] is empty\n");
117 m_raw_data_unit = (float)(raw_data_unit);
118 INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
120 if ((m_node_handle = open(m_data_node.c_str(), O_RDWR)) < 0) {
121 ERR("accel handle open fail for accel processor, error:%s\n", strerror(errno));
125 if (m_method == INPUT_EVENT_METHOD) {
126 int clockId = CLOCK_MONOTONIC;
127 if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
128 ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
130 update_value = [=]() {
131 return this->update_value_input_event();
134 if (!info.buffer_length_node_path.empty())
135 set_node_value(info.buffer_length_node_path, 480);
137 if (!info.buffer_enable_node_path.empty())
138 set_node_value(info.buffer_enable_node_path, 1);
140 update_value = [=]() {
141 return this->update_value_iio();
145 INFO("accel_sensor is created!\n");
148 accel_sensor_hal::~accel_sensor_hal()
150 close(m_node_handle);
153 INFO("accel_sensor is destroyed!\n");
156 string accel_sensor_hal::get_model_id(void)
161 sensor_hal_type_t accel_sensor_hal::get_type(void)
163 return SENSOR_HAL_TYPE_ACCELEROMETER;
166 bool accel_sensor_hal::enable(void)
168 set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_ACCELEROMETER_ENABLE_BIT);
169 set_interval(m_polling_interval);
172 INFO("Accel sensor real starting");
176 bool accel_sensor_hal::disable(void)
178 set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_ACCELEROMETER_ENABLE_BIT);
180 INFO("Accel sensor real stopping");
184 bool accel_sensor_hal::set_interval(unsigned long val)
186 unsigned long long polling_interval_ns;
187 polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
189 if (!set_node_value(m_interval_node, polling_interval_ns)) {
190 ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
194 INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
195 m_polling_interval = val;
199 bool accel_sensor_hal::update_value_input_event()
201 int accel_raw[3] = {0,};
203 int read_input_cnt = 0;
204 const int INPUT_MAX_BEFORE_SYN = 10;
205 unsigned long long fired_time = 0;
210 struct input_event accel_input;
211 DBG("accel event detection!");
213 while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
214 int len = read(m_node_handle, &accel_input, sizeof(accel_input));
215 if (len != sizeof(accel_input)) {
216 ERR("accel_file read fail, read_len = %d\n",len);
222 if (accel_input.type == EV_REL) {
223 switch (accel_input.code) {
225 accel_raw[0] = (int)accel_input.value;
229 accel_raw[1] = (int)accel_input.value;
233 accel_raw[2] = (int)accel_input.value;
237 ERR("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code);
241 } else if (accel_input.type == EV_SYN) {
243 fired_time = sensor_hal_base::get_timestamp(&accel_input.time);
245 ERR("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code);
251 ERR("EV_SYN didn't come until %d inputs had come", read_input_cnt);
262 m_fired_time = fired_time;
264 DBG("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
269 bool accel_sensor_hal::update_value_iio()
271 const int READ_LEN = 14;
272 char data[READ_LEN] = {0,};
276 pfd.fd = m_node_handle;
277 pfd.events = POLLIN | POLLERR;
280 int ret = poll(&pfd, 1, -1);
283 ERR("poll error:%s m_node_handle:d", strerror(errno), m_node_handle);
286 ERR("poll timeout m_node_handle:%d", m_node_handle);
290 if (pfd.revents & POLLERR) {
291 ERR("poll exception occurred! m_node_handle:%d", m_node_handle);
295 if (!(pfd.revents & POLLIN)) {
296 ERR("poll nothing to read! m_node_handle:%d, pfd.revents = %d", m_node_handle, pfd.revents);
300 int len = read(m_node_handle, data, sizeof(data));
302 if (len != sizeof(data)) {
303 ERR("Failed to read data, m_node_handle:%d read_len:%d", m_node_handle, len);
307 short *short_data = (short *)(data);
309 m_y = *((short *)(data + 2));
310 m_z = *((short *)(data + 4));
312 m_fired_time = *((long long*)(data + 6));
314 INFO("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
319 bool accel_sensor_hal::is_data_ready(void)
322 ret = update_value();
326 int accel_sensor_hal::get_sensor_data(sensor_data_t &data)
328 data.accuracy = SENSOR_ACCURACY_GOOD;
329 data.timestamp = m_fired_time;
330 data.value_count = 3;
331 data.values[0] = m_x;
332 data.values[1] = m_y;
333 data.values[2] = m_z;
338 bool accel_sensor_hal::get_properties(sensor_properties_s &properties)
340 properties.name = m_chip_name;
341 properties.vendor = m_vendor;
342 properties.min_range = MIN_RANGE(m_resolution)* RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(m_raw_data_unit);
343 properties.max_range = MAX_RANGE(m_resolution)* RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(m_raw_data_unit);
344 properties.min_interval = 1;
345 properties.resolution = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(m_raw_data_unit);
346 properties.fifo_count = 0;
347 properties.max_batch_count = 0;