2 * Copyright (c) 2017 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.
18 #include "hrm_raw_device.h"
22 #include <linux/input.h>
26 #include "sensor_common.h"
27 #include "sensor_log.h"
29 #define MODEL_NAME "AD45251"
30 #define VENDOR "ANALOG DEVICES"
32 #define MAX_RANGE 1000
34 #define RAW_DATA_UNIT 1
35 #define MIN_INTERVAL 1
36 #define MAX_BATCH_COUNT 0
38 #define SENSOR_NAME "SENSOR_HRM_RAW"
39 #define SENSOR_TYPE_HRM_RAW "HRM_RAW"
41 #define INPUT_NAME "hrm_raw_sensor"
42 #define HRM_SENSORHUB_POLL_NODE_NAME "hrm_poll_delay"
44 #define INDEX_HRM_RAW 0x1
45 #define INDEX_HRM_LED_GREEN 0x2
47 #define POLL_1HZ_MS 1000
49 #define INPUT_MAX_BEFORE_SYN 20
50 #define INPUT_EVENT_BIAS 1
51 #define INPUT_VALUE_COUNT 10
55 static sensor_info_t sensor_info[] = {
59 type: SENSOR_DEVICE_HRM_RAW,
60 event_type: (SENSOR_DEVICE_HRM_RAW << SENSOR_EVENT_SHIFT) | RAW_DATA_EVENT,
61 model_name: MODEL_NAME,
65 resolution: RAW_DATA_UNIT,
66 min_interval: MIN_INTERVAL,
67 max_batch_count: MAX_BATCH_COUNT,
68 wakeup_supported: false
71 id: INDEX_HRM_LED_GREEN,
72 name: "HRM LED GREEN SENSOR",
73 type: SENSOR_DEVICE_HRM_LED_GREEN,
74 event_type: (SENSOR_DEVICE_HRM_LED_GREEN << SENSOR_EVENT_SHIFT) | RAW_DATA_EVENT,
75 model_name: MODEL_NAME,
79 resolution: RAW_DATA_UNIT,
80 min_interval: MIN_INTERVAL,
81 max_batch_count: MAX_BATCH_COUNT,
82 wakeup_supported: false
86 hrm_raw_device::hrm_raw_device()
89 , m_polling_interval(POLL_1HZ_MS)
90 , m_raw_interval(POLL_1HZ_MS)
91 , m_led_green_interval(POLL_1HZ_MS)
92 , m_interval_supported(false)
93 , m_sensorhub_controlled(false)
96 const std::string sensorhub_interval_node_name = HRM_SENSORHUB_POLL_NODE_NAME;
98 node_info_query query;
101 query.sensorhub_controlled = m_sensorhub_controlled = util::is_sensorhub_controlled(sensorhub_interval_node_name);
102 query.sensor_type = SENSOR_TYPE_HRM_RAW;
103 query.key = INPUT_NAME;
104 query.iio_enable_node_name = "hrm_raw_enable";
105 query.sensorhub_interval_node_name = sensorhub_interval_node_name;
107 if (!util::get_node_info(query, info)) {
108 _E("Failed to get node info");
112 util::show_node_info(info);
114 m_data_node = info.data_node_path;
115 m_enable_node = info.enable_node_path;
116 m_interval_node = info.interval_node_path;
118 if (access(m_interval_node.c_str(), F_OK) == 0)
119 m_interval_supported = true;
121 m_node_handle = open(m_data_node.c_str(), O_RDONLY);
123 if (m_node_handle < 0) {
124 _ERRNO(errno, _E, "Failed to open node[%s]", m_data_node.c_str());
128 if (!util::set_monotonic_clock(m_node_handle))
131 _I("hrm_raw_device is created");
134 hrm_raw_device::~hrm_raw_device()
136 close(m_node_handle);
139 _I("hrm_raw_device is destroyed");
142 int hrm_raw_device::get_poll_fd(void)
144 return m_node_handle;
147 int hrm_raw_device::get_sensors(const sensor_info_t **sensors)
149 retvm_if(sensors == NULL || sensors == nullptr, SENSOR_ERROR_INVALID_PARAMETER, "%s:NULL interface", SENSOR_NAME);
150 *sensors = sensor_info;
155 bool hrm_raw_device::enable(uint32_t id)
157 retvm_if(id == 0 || id > MAX_ID, false, "%s:Invalid ID Received", SENSOR_NAME);
164 util::set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_HRM_RAW_ENABLE_BIT);
165 if (m_interval_supported)
166 set_interval(id, m_polling_interval);
168 m_data.timestamp = 0;
169 _I("Enable HRM Raw sensor");
173 bool hrm_raw_device::disable(uint32_t id)
175 retvm_if(id == 0 || id > MAX_ID, false, "%s:Invalid ID Received", SENSOR_NAME);
182 util::set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_HRM_RAW_ENABLE_BIT);
185 _I("Disable HRM Raw sensor");
189 bool hrm_raw_device::set_interval(uint32_t id, unsigned long val)
191 unsigned long interval = 100;
192 unsigned long long polling_interval_ns;
193 retvm_if(id == 0 || id > MAX_ID, false, "%s:Invalid ID Received", SENSOR_NAME);
195 if (!m_interval_supported)
198 if (id == INDEX_HRM_LED_GREEN)
199 interval = (val > m_raw_interval)?m_raw_interval:val;
201 interval = (val > m_led_green_interval)?m_led_green_interval:val;
203 polling_interval_ns = ((unsigned long long)(interval) * 1000llu * 1000llu);
205 if (!util::set_node_value(m_interval_node, polling_interval_ns)) {
206 _E("Failed to set polling resource: %s", m_interval_node.c_str());
210 _I("Interval is changed from %lu ms to %lu ms", m_polling_interval, interval);
211 m_polling_interval = interval;
213 if (id == INDEX_HRM_LED_GREEN)
214 m_led_green_interval = val;
216 m_raw_interval = val;
221 bool hrm_raw_device::update_value_input_event(void)
224 int read_input_cnt = 0;
226 struct input_event hrm_raw_input;
228 while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
229 int len = read(m_node_handle, &hrm_raw_input, sizeof(hrm_raw_input));
230 if (len != sizeof(hrm_raw_input)) {
231 _E("hrm_raw_file read fail, read_len = %d", len);
237 if (hrm_raw_input.type == EV_REL) {
238 index = hrm_raw_input.code - REL_X;
240 /* Check an avaiable value REL_X(0x00) ~ REL_MISC(0x09) */
241 if (index >= INPUT_VALUE_COUNT) {
242 _E("hrm_raw_input event[type = %d, code = %d] is unknown.", hrm_raw_input.type, index);
245 m_data.values[index] = (unsigned int)hrm_raw_input.value - INPUT_EVENT_BIAS;
246 _I("SRINIEVENT: EV_REL input had come, val:%d, index[%d]", hrm_raw_input.value, index);
247 } else if (hrm_raw_input.type == EV_SYN) {
249 m_data.timestamp = util::get_timestamp(&hrm_raw_input.time);
250 m_data.value_count = INPUT_VALUE_COUNT;
252 _I("SRINIEVENT: EV_SYN input had come, val:%d, index[%d]", hrm_raw_input.value, index);
254 _E("hrm_raw_input event[type = %d, code = %d] is unknown.", hrm_raw_input.type, hrm_raw_input.code);
260 _E("EV_SYN didn't come until %d inputs had come", read_input_cnt);
266 int hrm_raw_device::read_fd(uint32_t **ids)
268 retvm_if(ids == NULL || ids == nullptr, SENSOR_ERROR_INVALID_PARAMETER, "%s:NULL interface", SENSOR_NAME);
270 if (!update_value_input_event()) {
271 _D("Failed to update value");
277 int size = ARRAY_SIZE(sensor_info);
279 for (int i = 0; i < size; ++i)
280 event_ids.push_back(sensor_info[i].id);
282 *ids = &event_ids[0];
284 return event_ids.size();
287 int hrm_raw_device::get_data(uint32_t id, sensor_data_t **data, int *length)
290 sensor_data_t *sensor_data;
291 retvm_if(data == NULL || data == nullptr, SENSOR_ERROR_INVALID_PARAMETER, "%s:NULL data interface", SENSOR_NAME);
292 retvm_if(length == NULL || length == nullptr, SENSOR_ERROR_INVALID_PARAMETER, "%s:NULL length interface", SENSOR_NAME);
293 retvm_if(id == 0 || id > MAX_ID, SENSOR_ERROR_INVALID_PARAMETER, "%s:Invalid ID Received", SENSOR_NAME);
295 sensor_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
296 retvm_if(!sensor_data, -ENOMEM, "Memory allocation failed");
298 sensor_data->accuracy = SENSOR_ACCURACY_GOOD;
299 sensor_data->timestamp = m_data.timestamp;
301 if (id == INDEX_HRM_LED_GREEN) {
302 sensor_data->value_count = 1;
303 sensor_data->values[0] = m_data.values[5];
305 sensor_data->value_count = m_data.value_count;
306 memcpy(sensor_data->values, m_data.values, m_data.value_count * sizeof(m_data.values[0]));
308 _I("SRINIHAL: Sensor Data:%.2f, id: %d", sensor_data->values[0], id);
310 *length = sizeof(sensor_data_t);