sensor-hal: proxi: fix the value of proximity
[platform/adaptation/tm1/sensor-hal-tm1.git] / src / proxi / proxi.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 #include <linux/input.h>
23 #include <util.h>
24 #include <sensor_logs.h>
25
26 #include "proxi.h"
27
28 #define MODEL_NAME "IMS1911"
29 #define VENDOR "ITM"
30 #define MIN_RANGE 0
31 #define MAX_RANGE 5
32 #define RESOLUTION 1
33 #define MIN_INTERVAL 1
34 #define MAX_BATCH_COUNT 0
35
36 #define SENSORHUB_PROXIMITY_ENABLE_BIT 7
37
38 #define RAW_DATA_TO_DISTANCE(x) ((x) * 5)
39
40 static const sensor_info_t sensor_info = {
41         id: 0x1,
42         name: "Proximity Sensor",
43         type: SENSOR_DEVICE_PROXIMITY,
44         event_type: (SENSOR_DEVICE_PROXIMITY << 16) | 0x0001,
45         model_name: MODEL_NAME,
46         vendor: VENDOR,
47         min_range: MIN_RANGE,
48         max_range: MAX_RANGE,
49         resolution: RESOLUTION,
50         min_interval: MIN_INTERVAL,
51         max_batch_count: MAX_BATCH_COUNT,
52         wakeup_supported: false
53 };
54
55 std::vector<uint32_t> proxi_device::event_ids;
56
57 proxi_device::proxi_device()
58 : m_node_handle(-1)
59 , m_state(-1)
60 , m_fired_time(0)
61 , m_sensorhub_controlled(false)
62 {
63         const std::string sensorhub_interval_node_name = "prox_poll_delay";
64
65         node_info_query query;
66         node_info info;
67
68         query.sensorhub_controlled = m_sensorhub_controlled = util::is_sensorhub_controlled(sensorhub_interval_node_name);
69         query.sensor_type = "PROXI";
70         query.key = "proximity_sensor";
71         query.iio_enable_node_name = "proximity_enable";
72         query.sensorhub_interval_node_name = sensorhub_interval_node_name;
73
74         if (!util::get_node_info(query, info)) {
75                 ERR("Failed to get node info");
76                 throw ENXIO;
77         }
78
79         util::show_node_info(info);
80
81         m_data_node = info.data_node_path;
82         m_enable_node = info.enable_node_path;
83
84         if ((m_node_handle = open(m_data_node.c_str(), O_RDWR)) < 0) {
85                 ERR("accel handle open fail for accel processor, error:%s", strerror(errno));
86                 throw ENXIO;
87         }
88
89         INFO("proxi_device is created!");
90 }
91
92 proxi_device::~proxi_device()
93 {
94         close(m_node_handle);
95         m_node_handle = -1;
96
97         INFO("proxi_device is destroyed!");
98 }
99
100 int proxi_device::get_poll_fd()
101 {
102         return m_node_handle;
103 }
104
105 int proxi_device::get_sensors(const sensor_info_t **sensors)
106 {
107         *sensors = &sensor_info;
108
109         return 1;
110 }
111
112 bool proxi_device::enable(uint32_t id)
113 {
114         util::set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_PROXIMITY_ENABLE_BIT);
115
116         m_fired_time = 0;
117         INFO("Enable proximity sensor");
118         return true;
119 }
120
121 bool proxi_device::disable(uint32_t id)
122 {
123         util::set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_PROXIMITY_ENABLE_BIT);
124
125         INFO("Disable proximity sensor");
126         return true;
127 }
128
129 bool proxi_device::set_interval(uint32_t id, unsigned long interval_ms)
130 {
131         return true;
132 }
133
134 bool proxi_device::set_batch_latency(uint32_t id, unsigned long val)
135 {
136         return false;
137 }
138
139 bool proxi_device::set_attribute_int(uint32_t id, int32_t attribute, int32_t value)
140 {
141         return false;
142 }
143
144 bool proxi_device::set_attribute_str(uint32_t id, int32_t attribute, char *value, int value_len)
145 {
146         return false;
147 }
148
149 bool proxi_device::update_value_input_event(void)
150 {
151         struct input_event proxi_event;
152         DBG("proxi event detection!");
153
154         int len = read(m_node_handle, &proxi_event, sizeof(proxi_event));
155
156         if (len == -1) {
157                 DBG("read(m_node_handle) is error:%s", strerror(errno));
158                 return false;
159         }
160
161         if ((proxi_event.type == EV_ABS) && (proxi_event.code == ABS_DISTANCE)) {
162                 m_state = proxi_event.value;
163                 m_fired_time = util::get_timestamp(&proxi_event.time);
164
165                 DBG("m_state = %d, time = %lluus", m_state, m_fired_time);
166
167                 return true;
168         }
169
170         return false;
171 }
172
173 int proxi_device::read_fd(uint32_t **ids)
174 {
175         if (!update_value_input_event()) {
176                 DBG("Failed to update value");
177                 return false;
178         }
179
180         event_ids.clear();
181         event_ids.push_back(sensor_info.id);
182
183         *ids = &event_ids[0];
184
185         return event_ids.size();
186 }
187
188 int proxi_device::get_data(uint32_t id, sensor_data_t **data, int *length)
189 {
190         int remains = 1;
191         sensor_data_t *sensor_data;
192         sensor_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
193
194         sensor_data->accuracy = SENSOR_ACCURACY_GOOD;
195         sensor_data->timestamp = m_fired_time;
196         sensor_data->value_count = 1;
197         sensor_data->values[0] = RAW_DATA_TO_DISTANCE(m_state);
198
199         *data = sensor_data;
200         *length = sizeof(sensor_data_t);
201
202         return --remains;
203 }
204
205 bool proxi_device::flush(uint32_t id)
206 {
207         return false;
208 }