sensor-hal: rename interface of HAL for managing it easily
[platform/adaptation/tm1/sensor-hal-tm1.git] / src / plugins / light / light_sensor_hal.cpp
1 /*
2  * light_sensor_hal
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19 #include <fstream>
20 #include <fcntl.h>
21 #include <sys/stat.h>
22 #include <dirent.h>
23 #include <linux/input.h>
24 #include <csensor_config.h>
25 #include <light_sensor_hal.h>
26 #include <sys/ioctl.h>
27
28 using std::ifstream;
29 using std::string;
30
31 #define SENSOR_TYPE_LIGHT               "LIGHT"
32 #define ELEMENT_NAME                    "NAME"
33 #define ELEMENT_VENDOR                  "VENDOR"
34 #define ELEMENT_RAW_DATA_UNIT   "RAW_DATA_UNIT"
35 #define ELEMENT_RESOLUTION              "RESOLUTION"
36 #define ATTR_VALUE                              "value"
37 #define INITIAL_TIME -1
38 #define BIAS    1
39 #define INVALID_VALUE   -1
40 #define INITIAL_VALUE   -1
41
42 light_sensor_hal::light_sensor_hal()
43 : m_polling_interval(POLL_1HZ_MS)
44 , m_adc(INVALID_VALUE)
45 , m_fired_time(INITIAL_TIME)
46 , m_node_handle(INITIAL_VALUE)
47 {
48         const string sensorhub_interval_node_name = "light_poll_delay";
49         csensor_config &config = csensor_config::get_instance();
50
51         node_info_query query;
52         node_info info;
53
54         if (!find_model_id(SENSOR_TYPE_LIGHT, m_model_id)) {
55                 ERR("Failed to find model id");
56                 throw ENXIO;
57
58         }
59
60         query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
61         query.sensor_type = SENSOR_TYPE_LIGHT;
62         query.key = "light_sensor";
63         query.iio_enable_node_name = "light_enable";
64         query.sensorhub_interval_node_name = sensorhub_interval_node_name;
65
66         if (!get_node_info(query, info)) {
67                 ERR("Failed to get node info");
68                 throw ENXIO;
69         }
70
71         show_node_info(info);
72
73         m_data_node = info.data_node_path;
74         m_enable_node = info.enable_node_path;
75         m_interval_node = info.interval_node_path;
76
77         if (!config.get(SENSOR_TYPE_LIGHT, m_model_id, ELEMENT_VENDOR, m_vendor)) {
78                 ERR("[VENDOR] is empty\n");
79                 throw ENXIO;
80         }
81
82         INFO("m_vendor = %s", m_vendor.c_str());
83
84         if (!config.get(SENSOR_TYPE_LIGHT, m_model_id, ELEMENT_NAME, m_chip_name)) {
85                 ERR("[NAME] is empty\n");
86                 throw ENXIO;
87         }
88
89         INFO("m_chip_name = %s\n",m_chip_name.c_str());
90
91         if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) {
92                 ERR("Failed to open handle(%d)", m_node_handle);
93                 throw ENXIO;
94         }
95
96         int clockId = CLOCK_MONOTONIC;
97         if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
98                 ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
99
100         INFO("light_sensor_hal is created!\n");
101 }
102
103 light_sensor_hal::~light_sensor_hal()
104 {
105         close(m_node_handle);
106         m_node_handle = -1;
107
108         INFO("light_sensor_hal is destroyed!\n");
109 }
110
111 string light_sensor_hal::get_model_id(void)
112 {
113         return m_model_id;
114 }
115
116
117 sensor_hal_type_t light_sensor_hal::get_type(void)
118 {
119         return SENSOR_HAL_TYPE_LIGHT;
120 }
121
122 bool light_sensor_hal::enable(void)
123 {
124         AUTOLOCK(m_mutex);
125
126         set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_LIGHT_ENABLE_BIT);
127         set_interval(m_polling_interval);
128
129         m_fired_time = 0;
130         INFO("Light sensor real starting");
131         return true;
132 }
133
134 bool light_sensor_hal::disable(void)
135 {
136         AUTOLOCK(m_mutex);
137
138         set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_LIGHT_ENABLE_BIT);
139
140         INFO("Light sensor real stopping");
141         return true;
142 }
143
144 bool light_sensor_hal::set_interval(unsigned long val)
145 {
146         unsigned long long polling_interval_ns;
147
148         AUTOLOCK(m_mutex);
149
150         polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
151
152         if (!set_node_value(m_interval_node, polling_interval_ns)) {
153                 ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
154                 return false;
155         }
156
157         INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
158         m_polling_interval = val;
159         return true;
160 }
161
162 bool light_sensor_hal::update_value(void)
163 {
164         unsigned short int adc = INITIAL_VALUE;
165
166         struct input_event light_event;
167         DBG("light event detection!");
168
169         int len = read(m_node_handle, &light_event, sizeof(light_event));
170         if (len == -1) {
171                 DBG("read(m_node_handle) is error:%s.\n", strerror(errno));
172                 return false;
173         }
174
175         if (light_event.type == EV_ABS && light_event.code == ABS_MISC) {
176                 adc = light_event.value;
177         } else if (light_event.type == EV_REL && light_event.code == REL_MISC) {
178                 adc = light_event.value - BIAS;
179         } else if (light_event.type == EV_REL && light_event.code == REL_RX) {
180                 adc = light_event.value - BIAS;
181         } else {
182                 DBG("light input event[type = %d, code = %d] is unknown.", light_event.type, light_event.code);
183                 return false;
184         }
185
186         DBG("read event, len : %d, type : %x, code : %x, value : %x",
187                 len, light_event.type, light_event.code, light_event.value);
188
189         DBG("update_value, adc : %d", adc);
190
191         AUTOLOCK(m_value_mutex);
192         m_adc = adc;
193         m_fired_time = sensor_hal_base::get_timestamp(&light_event.time);
194
195         return true;
196 }
197
198 bool light_sensor_hal::is_data_ready(void)
199 {
200         bool ret;
201         ret = update_value();
202         return ret;
203 }
204
205 int light_sensor_hal::get_sensor_data(sensor_data_t &data)
206 {
207         AUTOLOCK(m_value_mutex);
208         data.accuracy = SENSOR_ACCURACY_GOOD;
209         data.timestamp = m_fired_time;
210         data.value_count = 1;
211         data.values[0] = (float) m_adc;
212
213         return 0;
214 }
215
216 bool light_sensor_hal::get_properties(sensor_properties_s &properties)
217 {
218         properties.name = m_chip_name;
219         properties.vendor = m_vendor;
220         properties.min_range = 0;
221         properties.max_range = 65535;
222         properties.min_interval = 1;
223         properties.resolution = 1;
224         properties.fifo_count = 0;
225         properties.max_batch_count = 0;
226         return true;
227 }