Fixing build error with new dlog format
[platform/adaptation/tm2/sensor-hal-tm2.git] / src / ultraviolet / uv_device.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22
23 #include <linux/input.h>
24 #include <sys/ioctl.h>
25 #include <poll.h>
26
27 #include <util.h>
28 #include <sensor_common.h>
29 #include <sensor_log.h>
30
31 #include "uv_device.h"
32
33 #define MODEL_NAME "MAX86902_UV"
34 #define VENDOR "MAXIM"
35 #define RESOLUTION 1
36 #define RAW_DATA_UNIT 0.0002289
37 #define MIN_INTERVAL 10
38 #define MAX_BATCH_COUNT 0
39
40 #define SENSOR_NAME "ULTRAVIOLET_SENSOR"
41 #define SENSOR_TYPE_ULTRAVIOLET         "ULTRAVIOLET"
42
43 #define INPUT_NAME "uv_sensor"
44 #define UV_SENSORHUB_POLL_NODE_NAME "uv_poll_dealy"
45 #define IIO_ENABLE_NAME "uv_enable"
46
47 #define BIAS    1
48
49 static sensor_info_t sensor_info = {
50         id: 0x1,
51         name: SENSOR_NAME,
52         type: SENSOR_DEVICE_ULTRAVIOLET,
53         event_type: (SENSOR_DEVICE_ULTRAVIOLET << SENSOR_EVENT_SHIFT) | RAW_DATA_EVENT,
54         model_name: MODEL_NAME,
55         vendor: VENDOR,
56         min_range: 0,
57         max_range: 15,
58         resolution: 0,
59         min_interval: 0,
60         max_batch_count: 0,
61         wakeup_supported: false
62 };
63
64 uv_device::uv_device()
65 : m_node_handle(-1)
66 , m_ultraviolet(0)
67 , m_hrm_temp(0)
68 , m_polling_interval(1000)
69 , m_fired_time(0)
70 , m_sensorhub_controlled(false)
71 {
72         const std::string sensorhub_interval_node_name = UV_SENSORHUB_POLL_NODE_NAME;
73
74         node_info_query query;
75         node_info info;
76
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;
82
83         if (!util::get_node_info(query, info)) {
84                 _E("Failed to get node info");
85                 throw ENXIO;
86         }
87
88         util::show_node_info(info);
89
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;
94
95         m_node_handle = open(m_data_node.c_str(), O_RDONLY);
96
97         if (m_node_handle < 0) {
98                 _ERRNO(errno, _E, "Failed to open uv handle");
99                 throw ENXIO;
100         }
101
102         if (m_method == INPUT_EVENT_METHOD) {
103                 if (!util::set_monotonic_clock(m_node_handle))
104                         throw ENXIO;
105         }
106
107         update_value = [=]() {
108                 return this->update_value_input_event();
109         };
110
111         _I("uv_sensor is created!");
112 }
113
114 uv_device::~uv_device()
115 {
116         close(m_node_handle);
117         m_node_handle = -1;
118
119         _I("uv_sensor is destroyed!");
120 }
121
122 int uv_device::get_poll_fd()
123 {
124         return m_node_handle;
125 }
126
127 int uv_device::get_sensors(const sensor_info_t **sensors)
128 {
129         *sensors = &sensor_info;
130
131         return 1;
132 }
133
134 bool uv_device::enable(uint32_t id)
135 {
136         util::set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_UV_SENSOR);
137         set_interval(id, m_polling_interval);
138
139         m_fired_time = 0;
140         _I("Enable uverometer sensor");
141         return true;
142 }
143
144 bool uv_device::disable(uint32_t id)
145 {
146         util::set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_UV_SENSOR);
147
148         _I("Disable uverometer sensor");
149         return true;
150 }
151
152 bool uv_device::set_interval(uint32_t id, unsigned long val)
153 {
154         unsigned long long polling_interval_ns;
155
156         polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
157
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());
160                 return false;
161         }
162
163         _I("Interval is changed from %lu ms to %lu ms", m_polling_interval, val);
164         m_polling_interval = val;
165         return true;
166 }
167
168 bool uv_device::update_value_input_event(void)
169 {
170         int ultraviolet_raw = -1;
171         int hrm_temp = -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;
176         bool syn = false;
177
178         struct input_event ultraviolet_event;
179         _D("ultraviolet event detection!");
180
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);
185                         return false;
186                 }
187
188                 ++read_input_cnt;
189
190                 if (ultraviolet_event.type == EV_REL && ultraviolet_event.code == REL_X) {
191                         ultraviolet_raw = (int)ultraviolet_event.value - BIAS;
192                         ultraviolet = true;
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) {
196                         syn = true;
197                         fired_time = util::get_timestamp(&ultraviolet_event.time);
198                 } else {
199                         _E("ultraviolet event[type = %d, code = %d] is unknown.", ultraviolet_event.type, ultraviolet_event.code);
200                         return false;
201                 }
202         }
203
204         if (syn == false) {
205                 _E("EV_SYN didn't come until %d inputs had come", read_input_cnt);
206                 return false;
207         }
208
209         if (ultraviolet)
210                 m_ultraviolet = ultraviolet_raw;
211
212         m_hrm_temp = hrm_temp;
213         m_fired_time = fired_time;
214
215         _D("m_ultraviolet = %d(%d), time = %lluus", m_ultraviolet, m_hrm_temp, m_fired_time);
216
217         return true;
218 }
219
220 int uv_device::read_fd(uint32_t **ids)
221 {
222         if (!update_value()) {
223                 _D("Failed to update value");
224                 return false;
225         }
226
227         event_ids.clear();
228         event_ids.push_back(sensor_info.id);
229
230         *ids = &event_ids[0];
231
232         return event_ids.size();
233 }
234
235 int uv_device::get_data(uint32_t id, sensor_data_t **data, int *length)
236 {
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");
240
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;
246
247         raw_to_base(sensor_data);
248
249         *data = sensor_data;
250         *length = sizeof(sensor_data_t);
251
252         return 0;
253 }
254
255 void uv_device::raw_to_base(sensor_data_t *data)
256 {
257         data->values[0] = data->values[0] * RAW_DATA_UNIT;
258 }