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 "uv_device.h"
33 #define MODEL_NAME "MAX86902_UV"
34 #define VENDOR "MAXIM"
36 #define RAW_DATA_UNIT 0.0002289
37 #define MIN_INTERVAL 10
38 #define MAX_BATCH_COUNT 0
40 #define SENSOR_NAME "ULTRAVIOLET_SENSOR"
41 #define SENSOR_TYPE_ULTRAVIOLET "ULTRAVIOLET"
43 #define INPUT_NAME "uv_sensor"
44 #define UV_SENSORHUB_POLL_NODE_NAME "uv_poll_dealy"
45 #define IIO_ENABLE_NAME "uv_enable"
49 static sensor_info_t sensor_info = {
52 type: SENSOR_DEVICE_ULTRAVIOLET,
53 event_type: (SENSOR_DEVICE_ULTRAVIOLET << SENSOR_EVENT_SHIFT) | RAW_DATA_EVENT,
54 model_name: MODEL_NAME,
61 wakeup_supported: false
64 uv_device::uv_device()
68 , m_polling_interval(1000)
70 , m_sensorhub_controlled(false)
72 const std::string sensorhub_interval_node_name = UV_SENSORHUB_POLL_NODE_NAME;
74 node_info_query query;
77 query.sensorhub_controlled = m_sensorhub_controlled = util::is_sensorhub_controlled(sensorhub_interval_node_name);
78 query.sensor_type = SENSOR_TYPE_ULTRAVIOLET;
79 query.key = INPUT_NAME;
80 query.iio_enable_node_name = IIO_ENABLE_NAME;
81 query.sensorhub_interval_node_name = sensorhub_interval_node_name;
83 if (!util::get_node_info(query, info)) {
84 _E("Failed to get node info");
88 util::show_node_info(info);
90 m_method = info.method;
91 m_data_node = info.data_node_path;
92 m_enable_node = info.enable_node_path;
93 m_interval_node = info.interval_node_path;
95 m_node_handle = open(m_data_node.c_str(), O_RDONLY);
97 if (m_node_handle < 0) {
98 _ERRNO(errno, _E, "Failed to open uv handle");
102 if (m_method == INPUT_EVENT_METHOD) {
103 if (!util::set_monotonic_clock(m_node_handle))
107 update_value = [=]() {
108 return this->update_value_input_event();
111 _I("uv_sensor is created!");
114 uv_device::~uv_device()
116 close(m_node_handle);
119 _I("uv_sensor is destroyed!");
122 int uv_device::get_poll_fd()
124 return m_node_handle;
127 int uv_device::get_sensors(const sensor_info_t **sensors)
129 *sensors = &sensor_info;
134 bool uv_device::enable(uint32_t id)
136 util::set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_UV_SENSOR);
137 set_interval(id, m_polling_interval);
140 _I("Enable uverometer sensor");
144 bool uv_device::disable(uint32_t id)
146 util::set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_UV_SENSOR);
148 _I("Disable uverometer sensor");
152 bool uv_device::set_interval(uint32_t id, unsigned long val)
154 unsigned long long polling_interval_ns;
156 polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
158 if (!util::set_node_value(m_interval_node, polling_interval_ns)) {
159 _E("Failed to set polling resource: %s", m_interval_node.c_str());
163 _I("Interval is changed from %lu ms to %lu ms", m_polling_interval, val);
164 m_polling_interval = val;
168 bool uv_device::update_value_input_event(void)
170 int ultraviolet_raw = -1;
172 bool ultraviolet = false;
173 int read_input_cnt = 0;
174 const int INPUT_MAX_BEFORE_SYN = 10;
175 unsigned long long fired_time = 0;
178 struct input_event ultraviolet_event;
179 _D("ultraviolet event detection!");
181 while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
182 int len = read(m_node_handle, &ultraviolet_event, sizeof(ultraviolet_event));
183 if (len != sizeof(ultraviolet_event)) {
184 _E("ultraviolet file read fail, read_len = %d\n", len);
190 if (ultraviolet_event.type == EV_REL && ultraviolet_event.code == REL_X) {
191 ultraviolet_raw = (int)ultraviolet_event.value - BIAS;
193 } else if (ultraviolet_event.type == EV_REL && ultraviolet_event.code == REL_Y) {
194 hrm_temp = (int)ultraviolet_event.value - BIAS;
195 } else if (ultraviolet_event.type == EV_SYN) {
197 fired_time = util::get_timestamp(&ultraviolet_event.time);
199 _E("ultraviolet event[type = %d, code = %d] is unknown.", ultraviolet_event.type, ultraviolet_event.code);
205 _E("EV_SYN didn't come until %d inputs had come", read_input_cnt);
210 m_ultraviolet = ultraviolet_raw;
212 m_hrm_temp = hrm_temp;
213 m_fired_time = fired_time;
215 _D("m_ultraviolet = %d(%d), time = %lluus", m_ultraviolet, m_hrm_temp, m_fired_time);
220 int uv_device::read_fd(uint32_t **ids)
222 if (!update_value()) {
223 _D("Failed to update value");
228 event_ids.push_back(sensor_info.id);
230 *ids = &event_ids[0];
232 return event_ids.size();
235 int uv_device::get_data(uint32_t id, sensor_data_t **data, int *length)
237 sensor_data_t *sensor_data;
238 sensor_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
239 retvm_if(!sensor_data, -ENOMEM, "Memory allocation failed");
241 sensor_data->accuracy = SENSOR_ACCURACY_GOOD;
242 sensor_data->timestamp = m_fired_time;
243 sensor_data->value_count = 2;
244 sensor_data->values[0] = m_ultraviolet;
245 sensor_data->values[1] = m_ultraviolet;
247 raw_to_base(sensor_data);
250 *length = sizeof(sensor_data_t);
255 void uv_device::raw_to_base(sensor_data_t *data)
257 data->values[0] = data->values[0] * RAW_DATA_UNIT;