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.
23 #include <sys/ioctl.h>
25 #include <linux/input.h>
27 #include <proxi_sensor_hal.h>
30 using config::CConfig;
32 #define NODE_NAME "name"
33 #define NODE_INPUT "input"
34 #define NODE_ENABLE "enable"
35 #define SENSOR_NODE "/sys/class/sensors/"
36 #define SENSORHUB_NODE "/sys/class/sensors/ssp_sensor/"
37 #define INPUT_DEVICE_NODE "/sys/class/input/"
38 #define DEV_INPUT_NODE "/dev/input/event/"
40 #define INITIAL_VALUE -1
41 #define INITIAL_TIME 0
42 #define PROXI_CODE 0x0019
44 #define SENSOR_TYPE_PROXI "PROXI"
45 #define ELEMENT_NAME "NAME"
46 #define ELEMENT_VENDOR "VENDOR"
47 #define ATTR_VALUE "value"
49 #define INPUT_NAME "proximity_sensor"
51 proxi_sensor_hal::proxi_sensor_hal()
52 : m_state(PROXIMITY_STATE_FAR)
53 , m_node_handle(INITIAL_VALUE)
54 , m_fired_time(INITIAL_TIME)
55 , m_sensorhub_supported(false)
57 if (!check_hw_node()) {
58 ERR("check_hw_node() fail");
62 CConfig &config = CConfig::get_instance();
64 if (!config.get(SENSOR_TYPE_PROXI, m_model_id, ELEMENT_VENDOR, m_vendor)) {
65 ERR("[VENDOR] is empty");
69 INFO("m_vendor = %s", m_vendor.c_str());
71 if (!config.get(SENSOR_TYPE_PROXI, m_model_id, ELEMENT_NAME, m_chip_name)) {
72 ERR("[NAME] is empty");
76 INFO("m_chip_name = %s", m_chip_name.c_str());
78 if ((m_node_handle = open(m_resource.c_str(), O_RDWR)) < 0) {
79 ERR("Failed to open handle(%d)", m_node_handle);
83 int clockId = CLOCK_MONOTONIC;
85 if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) {
86 ERR("Fail to set monotonic timestamp for %s", m_resource.c_str());
90 INFO("proxi_sensor_hal is created!");
93 proxi_sensor_hal::~proxi_sensor_hal()
96 m_node_handle = INITIAL_VALUE;
98 INFO("proxi_sensor_hal is destroyed!");
101 string proxi_sensor_hal::get_model_id(void)
106 sensor_type_t proxi_sensor_hal::get_type(void)
108 return PROXIMITY_SENSOR;
111 bool proxi_sensor_hal::enable_resource(string &resource_node, bool enable)
113 int prev_status, status;
115 fp = fopen(resource_node.c_str(), "r");
118 ERR("Fail to open a resource file: %s", resource_node.c_str());
122 if (fscanf(fp, "%d", &prev_status) < 0) {
123 ERR("Failed to get data from %s", resource_node.c_str());
131 if (m_sensorhub_supported)
132 status = prev_status | (1 << SENSORHUB_PROXIMITY_ENABLE_BIT);
136 if (m_sensorhub_supported)
137 status = prev_status ^ (1 << SENSORHUB_PROXIMITY_ENABLE_BIT);
142 fp = fopen(resource_node.c_str(), "w");
145 ERR("Failed to open a resource file: %s", resource_node.c_str());
149 if (fprintf(fp, "%d", status) < 0) {
150 ERR("Failed to enable a resource file: %s", resource_node.c_str());
161 bool proxi_sensor_hal::enable(void)
165 enable_resource(m_enable_resource, true);
168 INFO("Proxi sensor real starting");
172 bool proxi_sensor_hal::disable(void)
176 enable_resource(m_enable_resource, false);
177 INFO("Proxi sensor real stopping");
181 bool proxi_sensor_hal::update_value(bool wait)
183 struct input_event proxi_event;
184 fd_set readfds, exceptfds;
188 FD_SET(m_node_handle, &readfds);
189 FD_SET(m_node_handle, &exceptfds);
192 ret = select(m_node_handle + 1, &readfds, NULL, &exceptfds, NULL);
195 ERR("select error:%s m_node_handle:d", strerror(errno), m_node_handle);
198 DBG("select timeout");
202 if (FD_ISSET(m_node_handle, &exceptfds)) {
203 ERR("select exception occurred!");
207 if (FD_ISSET(m_node_handle, &readfds)) {
208 INFO("proxi event detection!");
209 int len = read(m_node_handle, &proxi_event, sizeof(proxi_event));
212 DBG("read(m_node_handle) is error:%s.", strerror(errno));
216 DBG("read event, len : %d , type : %x , code : %x , value : %x", len, proxi_event.type, proxi_event.code, proxi_event.value);
218 if ((proxi_event.type == EV_ABS) && (proxi_event.code == PROXI_CODE)) {
219 AUTOLOCK(m_value_mutex);
221 if (proxi_event.value == PROXIMITY_NODE_STATE_FAR) {
222 INFO("PROXIMITY_STATE_FAR state occured");
223 m_state = PROXIMITY_STATE_FAR;
224 } else if (proxi_event.value == PROXIMITY_NODE_STATE_NEAR) {
225 INFO("PROXIMITY_STATE_NEAR state occured");
226 m_state = PROXIMITY_STATE_NEAR;
228 ERR("PROXIMITY_STATE Unknown: %d", proxi_event.value);
232 m_fired_time = sensor_hal::get_timestamp(&proxi_event.time);
237 ERR("select nothing to read!!!");
244 bool proxi_sensor_hal::is_data_ready(bool wait)
247 ret = update_value(wait);
251 int proxi_sensor_hal::get_sensor_data(sensor_data_t &data)
253 AUTOLOCK(m_value_mutex);
254 data.data_accuracy = SENSOR_ACCURACY_UNDEFINED;
255 data.data_unit_idx = SENSOR_UNIT_STATE_ON_OFF;
256 data.timestamp = m_fired_time;
258 data.values[0] = m_state;
262 bool proxi_sensor_hal::get_properties(sensor_properties_t &properties)
264 properties.sensor_unit_idx = SENSOR_UNIT_STATE_ON_OFF;
265 properties.sensor_min_range = 0;
266 properties.sensor_max_range = 1;
267 snprintf(properties.sensor_name, sizeof(properties.sensor_name), "%s", m_chip_name.c_str());
268 snprintf(properties.sensor_vendor, sizeof(properties.sensor_vendor), "%s", m_vendor.c_str());
269 properties.sensor_resolution = 1;
273 bool proxi_sensor_hal::is_sensorhub_supported(void)
275 DIR *main_dir = NULL;
276 main_dir = opendir(SENSORHUB_NODE);
279 INFO("Sensor Hub is not supported");
283 INFO("It supports sensor hub");
288 bool proxi_sensor_hal::check_hw_node(void)
292 DIR *main_dir = NULL;
293 struct dirent *dir_entry = NULL;
294 bool find_node = false;
296 INFO("======================start check_hw_node=============================");
298 m_sensorhub_supported = is_sensorhub_supported();
299 main_dir = opendir(SENSOR_NODE);
302 ERR("Directory open failed to collect data");
306 while ((!find_node) && (dir_entry = readdir(main_dir))) {
307 if ((strncasecmp(dir_entry->d_name , ".", 1 ) != 0) && (strncasecmp(dir_entry->d_name , "..", 2 ) != 0) && (dir_entry->d_ino != 0)) {
308 name_node = string(SENSOR_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
310 ifstream infile(name_node.c_str());
317 if (CConfig::get_instance().is_supported(SENSOR_TYPE_PROXI, hw_name) == true) {
318 m_name = m_model_id = hw_name;
319 INFO("m_model_id = %s", m_model_id.c_str());
329 main_dir = opendir(INPUT_DEVICE_NODE);
332 ERR("Directory open failed to collect data");
338 while ((!find_node) && (dir_entry = readdir(main_dir))) {
339 if (strncasecmp(dir_entry->d_name, NODE_INPUT, 5) == 0) {
340 name_node = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_NAME);
341 ifstream infile(name_node.c_str());
348 if (hw_name == string(INPUT_NAME)) {
349 INFO("name_node = %s", name_node.c_str());
350 DBG("Find H/W for proxi_sensor");
354 dir_name = string(dir_entry->d_name);
355 unsigned found = dir_name.find_first_not_of(NODE_INPUT);
356 m_resource = string(DEV_INPUT_NODE) + dir_name.substr(found);
358 if (m_sensorhub_supported)
359 m_enable_resource = string(SENSORHUB_NODE) + string(NODE_ENABLE);
361 m_enable_resource = string(INPUT_DEVICE_NODE) + string(dir_entry->d_name) + string("/") + string(NODE_ENABLE);
372 INFO("m_resource = %s", m_resource.c_str());
373 INFO("m_enable_resource = %s", m_enable_resource.c_str());
379 extern "C" void *create(void)
381 proxi_sensor_hal *inst;
384 inst = new proxi_sensor_hal();
386 ERR("Failed to create proxi_sensor_hal class, errno : %d, errstr : %s", err, strerror(err));
393 extern "C" void destroy(void *inst)
395 delete (proxi_sensor_hal *)inst;