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.
22 #include <linux/input.h>
23 #include <csensor_config.h>
24 #include <sys/ioctl.h>
25 #include <pressure_sensor_hal.h>
28 #include <iio_common.h>
33 #define SENSOR_TYPE_PRESSURE "PRESSURE"
34 #define ELEMENT_NAME "NAME"
35 #define ELEMENT_VENDOR "VENDOR"
36 #define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT"
37 #define ELEMENT_RESOLUTION "RESOLUTION"
38 #define ELEMENT_MIN_RANGE "MIN_RANGE"
39 #define ELEMENT_MAX_RANGE "MAX_RANGE"
40 #define ELEMENT_TEMPERATURE_RESOLUTION "TEMPERATURE_RESOLUTION"
41 #define ELEMENT_TEMPERATURE_OFFSET "TEMPERATURE_OFFSET"
42 #define ATTR_VALUE "value"
44 #define SEA_LEVEL_PRESSURE 101325.0
46 #define EVENT_EN_NODE "events/in_pressure_mag_either_en"
47 #define PRESSURE_SCALE "/in_pressure_scale"
48 #define PRESSURE_RAW "/in_pressure_raw"
49 #define TEMP_OFFSET "/in_temp_offset"
50 #define TEMP_SCALE "/in_temp_scale"
51 #define TEMP_RAW "/in_temp_raw"
55 pressure_sensor_hal::pressure_sensor_hal()
58 , m_polling_interval(POLL_1HZ_MS)
62 const string sensorhub_interval_node_name = "pressure_poll_delay";
63 csensor_config &config = csensor_config::get_instance();
65 node_path_info_query query;
67 int input_method = IIO_METHOD;
69 if (!get_model_properties(SENSOR_TYPE_PRESSURE, m_model_id, input_method)) {
70 ERR("Failed to find model_properties");
75 query.input_method = input_method;
76 query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
77 query.sensor_type = SENSOR_TYPE_PRESSURE;
78 query.input_event_key = "pressure_sensor";
79 query.iio_enable_node_name = EVENT_EN_NODE;
80 query.sensorhub_interval_node_name = sensorhub_interval_node_name;
82 if (!get_node_path_info(query, info)) {
83 ERR("Failed to get node info");
86 m_data_node = info.data_node_path;
87 m_pressure_dir = info.base_dir;
88 m_enable_node = info.enable_node_path;
89 m_pressure_node = m_pressure_dir + string(PRESSURE_RAW);
90 m_temp_node = m_pressure_dir + string(TEMP_RAW);
92 INFO("m_data_node:%s",m_data_node.c_str());
93 INFO("m_pressure_dir:%s",m_pressure_dir.c_str());
94 INFO("m_enable_node:%s",m_enable_node.c_str());
96 if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_VENDOR, m_vendor)) {
97 ERR("[VENDOR] is empty\n");
101 INFO("m_vendor = %s", m_vendor.c_str());
103 if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_NAME, m_chip_name)) {
104 ERR("[NAME] is empty\n");
108 INFO("m_chip_name = %s", m_chip_name.c_str());
112 if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_MIN_RANGE, min_range)) {
113 ERR("[MIN_RANGE] is empty\n");
117 m_min_range = (float)min_range;
118 INFO("m_min_range = %f\n",m_min_range);
122 if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_MAX_RANGE, max_range)) {
123 ERR("[MAX_RANGE] is empty\n");
127 m_max_range = (float)max_range;
128 INFO("m_max_range = %f\n",m_max_range);
130 double raw_data_unit;
132 if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) {
133 ERR("[RAW_DATA_UNIT] is empty\n");
137 m_raw_data_unit = (float)(raw_data_unit);
138 INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
142 file_name = m_pressure_dir + string(TEMP_SCALE);
143 if (!read_node_value<int>(file_name, m_temp_scale))
146 file_name = m_pressure_dir + string(TEMP_OFFSET);
147 if (!read_node_value<float>(file_name, m_temp_offset))
150 file_name = m_pressure_dir + string(PRESSURE_SCALE);
151 if (!read_node_value<int>(file_name, m_pressure_scale))
154 INFO("Temperature scale:%d", m_temp_scale);
155 INFO("Temperature offset:%f", m_temp_offset);
156 INFO("Pressure scale:%d", m_pressure_scale);
159 fd = open(m_data_node.c_str(), NO_FLAG);
161 ERR("Could not open event resource");
165 ret = ioctl(fd, IOCTL_IIO_EVENT_FD, &m_node_handle);
169 if ((ret == -1) || (m_node_handle == -1)) {
170 ERR("Failed to retrieve node handle from event node: %s", m_data_node.c_str());
174 INFO("pressure_sensor_hal is created!\n");
177 pressure_sensor_hal::~pressure_sensor_hal()
179 close(m_node_handle);
182 INFO("pressure_sensor_hal is destroyed!\n");
185 string pressure_sensor_hal::get_model_id(void)
190 sensor_type_t pressure_sensor_hal::get_type(void)
192 return PRESSURE_SENSOR;
195 bool pressure_sensor_hal::enable(void)
198 update_sysfs_num(m_enable_node.c_str(), true);
199 set_interval(m_polling_interval);
202 INFO("Pressure sensor real starting");
206 bool pressure_sensor_hal::disable(void)
210 update_sysfs_num(m_enable_node.c_str(), false);
212 INFO("Pressure sensor real stopping");
216 bool pressure_sensor_hal::set_interval(unsigned long val)
218 INFO("set_interval not supported");
222 bool pressure_sensor_hal::update_value(bool wait)
224 iio_event_t pressure_event;
225 fd_set readfds, exceptfds;
227 int raw_pressure_count;
233 FD_SET(m_node_handle, &readfds);
234 FD_SET(m_node_handle, &exceptfds);
245 ret = select(m_node_handle + 1, &readfds, NULL, &exceptfds, &tv);
248 ERR("select error:%s m_node_handle:d", strerror(errno), m_node_handle);
252 DBG("select timeout");
256 if (FD_ISSET(m_node_handle, &exceptfds)) {
257 ERR("select exception occurred!");
261 if (FD_ISSET(m_node_handle, &readfds)) {
262 INFO("pressure event detection!");
263 int len = read(m_node_handle, &pressure_event, sizeof(pressure_event));
266 ERR("Error in read(m_event_fd):%s.", strerror(errno));
269 m_fired_time = pressure_event.timestamp;
270 if (!read_node_value<int>(m_pressure_node, raw_pressure_count))
272 if (!read_node_value<int>(m_temp_node, raw_temp_count))
274 m_pressure = ((float)raw_pressure_count)/((float)m_pressure_scale);
275 m_temperature = m_temp_offset + ((float)raw_temp_count)/((float)m_temp_scale);
278 ERR("No pressure event data available to read");
285 bool pressure_sensor_hal::is_data_ready(bool wait)
288 ret = update_value(wait);
292 int pressure_sensor_hal::get_sensor_data(sensor_data_t &data)
294 AUTOLOCK(m_value_mutex);
295 data.accuracy = SENSOR_ACCURACY_GOOD;
296 data.timestamp = m_fired_time ;
297 data.value_count = 3;
298 data.values[0] = m_pressure;
299 data.values[1] = SEA_LEVEL_PRESSURE;
300 data.values[2] = m_temperature;
306 bool pressure_sensor_hal::get_properties(sensor_properties_s &properties)
308 properties.name = m_chip_name;
309 properties.vendor = m_vendor;
310 properties.min_range = m_min_range;
311 properties.max_range = m_max_range;
312 properties.min_interval = 1;
313 properties.resolution = m_raw_data_unit;
314 properties.fifo_count = 0;
315 properties.max_batch_count = 0;
319 extern "C" void *create(void)
321 pressure_sensor_hal *inst;
324 inst = new pressure_sensor_hal();
326 ERR("pressure_sensor_hal class create fail , errno : %d , errstr : %s\n", err, strerror(err));
333 extern "C" void destroy(void *inst)
335 delete (pressure_sensor_hal*)inst;