#define INPUT_NAME "accelerometer_sensor"
#define ACCEL_SENSORHUB_POLL_NODE_NAME "accel_poll_delay"
-#define SCAN_EL_DIR "scan_elements/"
-#define SCALE_AVAILABLE_NODE "in_accel_scale_available"
-#define ACCEL_RINGBUF_LEN 32
-#define SEC_MSEC 1000
-#define MSEC_TO_FREQ(VAL) ((SEC_MSEC) / (VAL))
-#define NSEC_TO_MUSEC(VAL) ((VAL) / 1000)
-
accel_sensor_hal::accel_sensor_hal()
: m_x(-1)
, m_y(-1)
const string sensorhub_interval_node_name = "accel_poll_delay";
csensor_config &config = csensor_config::get_instance();
- node_path_info_query query;
- node_path_info info;
- int input_method = IIO_METHOD;
+ node_info_query query;
+ node_info info;
- if (!get_model_properties(SENSOR_TYPE_ACCEL, m_model_id, input_method)) {
- ERR("Failed to find model_properties");
+ if (!find_model_id(SENSOR_TYPE_ACCEL, m_model_id)) {
+ ERR("Failed to find model id");
throw ENXIO;
}
- query.input_method = input_method;
query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
query.sensor_type = SENSOR_TYPE_ACCEL;
- query.input_event_key = "accelerometer_sensor";
+ query.key = "accelerometer_sensor";
query.iio_enable_node_name = "accel_enable";
query.sensorhub_interval_node_name = sensorhub_interval_node_name;
- if (!get_node_path_info(query, info)) {
+ if (!get_node_info(query, info)) {
ERR("Failed to get node info");
throw ENXIO;
}
- show_node_path_info(info);
+ show_node_info(info);
+ m_method = info.method;
m_data_node = info.data_node_path;
+ m_enable_node = info.enable_node_path;
m_interval_node = info.interval_node_path;
- m_accel_dir = info.base_dir;
- m_trigger_path = info.trigger_node_path;
- m_buffer_enable_node_path = info.buffer_enable_node_path;
- m_buffer_length_node_path = info.buffer_length_node_path;
- m_available_freq_node_path = info.available_freq_node_path;
- m_available_scale_node_path = m_accel_dir + string(SCALE_AVAILABLE_NODE);
if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_VENDOR, m_vendor)) {
ERR("[VENDOR] is empty\n");
INFO("m_chip_name = %s\n",m_chip_name.c_str());
- if (input_method == IIO_METHOD) {
- m_trigger_name = m_model_id + "-trigger";
- if (!verify_iio_trigger(m_trigger_name)) {
- ERR("Failed verify trigger");
- throw ENXIO;
- }
- string scan_dir = m_accel_dir + "scan_elements/";
- if (!get_generic_channel_names(scan_dir, string("_type"), m_generic_channel_names))
- ERR ("Failed to find any input channels");
- else
- {
- INFO ("generic channel names:");
- for (vector <string>::iterator it = m_generic_channel_names.begin();
- it != m_generic_channel_names.end(); ++it) {
- INFO ("%s", it->c_str());
- }
- }
- }
-
long resolution;
if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_RESOLUTION, resolution)) {
}
m_raw_data_unit = (float)(raw_data_unit);
+ INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
- m_node_handle = open(m_data_node.c_str(), O_RDONLY | O_NONBLOCK);
- if (m_node_handle < 0) {
+ if ((m_node_handle = open(m_data_node.c_str(), O_RDWR)) < 0) {
ERR("accel handle open fail for accel processor, error:%s\n", strerror(errno));
throw ENXIO;
}
- if (setup_channels() == true)
- INFO("IIO channel setup successful");
- else {
- ERR("IIO channel setup failed");
- throw ENXIO;
- }
+ if (m_method == INPUT_EVENT_METHOD) {
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
-// int clockId = CLOCK_MONOTONIC;
-// if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) {
-// ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
-// throw ENXIO;
-// }
+ update_value = [=](bool wait) {
+ return this->update_value_input_event(wait);
+ };
+ } else {
+ if (!info.buffer_length_node_path.empty())
+ set_node_value(info.buffer_length_node_path, 480);
+
+ if (!info.buffer_enable_node_path.empty())
+ set_node_value(info.buffer_enable_node_path, 1);
+
+ update_value = [=](bool wait) {
+ return this->update_value_iio(wait);
+ };
+ }
- INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
INFO("accel_sensor is created!\n");
}
accel_sensor_hal::~accel_sensor_hal()
{
- enable_resource(false);
- if (m_data != NULL)
- delete []m_data;
-
close(m_node_handle);
m_node_handle = -1;
return ACCELEROMETER_SENSOR;
}
-bool accel_sensor_hal::add_accel_channels_to_array(void)
+bool accel_sensor_hal::enable(void)
{
- int i = 0;
- m_channels = (struct channel_parameters*) malloc(sizeof(struct channel_parameters) * m_generic_channel_names.size());
- for (vector <string>::iterator it = m_generic_channel_names.begin();
- it != m_generic_channel_names.end(); ++it) {
- if (add_channel_to_array(m_accel_dir.c_str(), it->c_str() , &m_channels[i++]) < 0) {
- ERR("Failed to add channel %s to channel array", it->c_str());
- return false;
- }
- }
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_ACCELEROMETER_ENABLE_BIT);
+ set_interval(m_polling_interval);
+
+ m_fired_time = 0;
+ INFO("Accel sensor real starting");
return true;
}
-bool accel_sensor_hal::setup_channels(void)
+bool accel_sensor_hal::disable(void)
{
- int freq, i;
- double sf;
+ AUTOLOCK(m_mutex);
- enable_resource(true);
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_ACCELEROMETER_ENABLE_BIT);
- if (!add_accel_channels_to_array()) {
- ERR("Failed to add channels to array!");
- return false;
- }
+ INFO("Accel sensor real stopping");
+ return true;
+}
- INFO("Sorting channels by index");
- sort_channels_by_index(m_channels, m_generic_channel_names.size());
- INFO("Sorting channels by index completed");
+bool accel_sensor_hal::set_interval(unsigned long val)
+{
+ unsigned long long polling_interval_ns;
- m_scan_size = get_channel_array_size(m_channels, m_generic_channel_names.size());
- if (m_scan_size == 0) {
- ERR("Channel array size is zero");
- return false;
- }
+ AUTOLOCK(m_mutex);
- m_data = new (std::nothrow) char[m_scan_size * ACCEL_RINGBUF_LEN];
- if (m_data == NULL) {
- ERR("Couldn't create data buffer\n");
- return false;
- }
+ polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
- FILE *fp = NULL;
- fp = fopen(m_available_freq_node_path.c_str(), "r");
- if (!fp) {
- ERR("Fail to open available frequencies file:%s\n", m_available_freq_node_path.c_str());
+ if (!set_node_value(m_interval_node, polling_interval_ns)) {
+ ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
return false;
}
- for (i = 0; i < MAX_FREQ_COUNT; i++)
- m_sample_freq[i] = 0;
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
+}
- i = 0;
- while (fscanf(fp, "%d", &freq) > 0)
- m_sample_freq[i++] = freq;
+bool accel_sensor_hal::update_value_input_event(bool wait)
+{
+ int accel_raw[3] = {0,};
+ bool x,y,z;
+ int read_input_cnt = 0;
+ const int INPUT_MAX_BEFORE_SYN = 10;
+ unsigned long long fired_time = 0;
+ bool syn = false;
+
+ x = y = z = false;
+
+ struct input_event accel_input;
+ DBG("accel event detection!");
+
+ while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
+ int len = read(m_node_handle, &accel_input, sizeof(accel_input));
+ if (len != sizeof(accel_input)) {
+ ERR("accel_file read fail, read_len = %d\n",len);
+ return false;
+ }
- m_sample_freq_count = i;
+ ++read_input_cnt;
+
+ if (accel_input.type == EV_REL) {
+ switch (accel_input.code) {
+ case REL_X:
+ accel_raw[0] = (int)accel_input.value;
+ x = true;
+ break;
+ case REL_Y:
+ accel_raw[1] = (int)accel_input.value;
+ y = true;
+ break;
+ case REL_Z:
+ accel_raw[2] = (int)accel_input.value;
+ z = true;
+ break;
+ default:
+ ERR("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code);
+ return false;
+ break;
+ }
+ } else if (accel_input.type == EV_SYN) {
+ syn = true;
+ fired_time = sensor_hal::get_timestamp(&accel_input.time);
+ } else {
+ ERR("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code);
+ return false;
+ }
+ }
- fp = fopen(m_available_scale_node_path.c_str(), "r");
- if (!fp) {
- ERR("Fail to open available scale factors file:%s\n", m_available_scale_node_path.c_str());
+ if (syn == false) {
+ ERR("EV_SYN didn't come until %d inputs had come", read_input_cnt);
return false;
}
- for (i = 0; i < MAX_SCALING_COUNT; i++)
- m_scale_factor[i] = 0;
+ AUTOLOCK(m_value_mutex);
- i = 0;
+ if (x)
+ m_x = accel_raw[0];
+ if (y)
+ m_y = accel_raw[1];
+ if (z)
+ m_z = accel_raw[2];
- while (fscanf(fp, "%lf", &sf) > 0)
- m_scale_factor[i++] = sf;
+ m_fired_time = fired_time;
- m_scale_factor_count = i;
+ DBG("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
return true;
}
-void accel_sensor_hal::decode_data(void)
+
+bool accel_sensor_hal::update_value_iio(bool wait)
{
- AUTOLOCK(m_value_mutex);
+ const int READ_LEN = 14;
+ char data[READ_LEN] = {0,};
- m_x = convert_bytes_to_int(*(unsigned short int *)(m_data + m_channels[0].buf_index), &m_channels[0]);
- m_y = convert_bytes_to_int(*(unsigned short int *)(m_data + m_channels[1].buf_index), &m_channels[1]);
- m_z = convert_bytes_to_int(*(unsigned short int *)(m_data + m_channels[2].buf_index), &m_channels[2]);
+ struct pollfd pfd;
- long long int val = *(long long int *)(m_data + m_channels[3].buf_index);
- if ((val >> m_channels[3].valid_bits) & 1)
- val = (val & m_channels[3].mask) | ~m_channels[3].mask;
+ pfd.fd = m_node_handle;
+ pfd.events = POLLIN | POLLERR;
+ pfd.revents = 0;
- m_fired_time = (unsigned long long int)(NSEC_TO_MUSEC(val));
- DBG("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
-}
-bool accel_sensor_hal::setup_trigger(const char* trig_name, bool verify)
-{
- int ret = 0;
+ int ret = poll(&pfd, 1, -1);
- ret = update_sysfs_string(m_trigger_path.c_str(), trig_name);
- if (ret < 0) {
- ERR("failed to write to current_trigger,%s,%s\n", m_trigger_path.c_str(), trig_name);
+ if (ret == -1) {
+ ERR("poll error:%s m_node_handle:d", strerror(errno), m_node_handle);
+ return false;
+ } else if (!ret) {
+ ERR("poll timeout m_node_handle:%d", m_node_handle);
return false;
}
- INFO("current_trigger setup successfully\n");
- return true;
-}
-bool accel_sensor_hal::setup_buffer(int enable)
-{
- int ret;
- ret = update_sysfs_num(m_buffer_length_node_path.c_str(), ACCEL_RINGBUF_LEN, true);
- if (ret < 0) {
- ERR("failed to write to buffer/length\n");
+ if (pfd.revents & POLLERR) {
+ ERR("poll exception occurred! m_node_handle:%d", m_node_handle);
return false;
}
- INFO("buffer/length setup successfully\n");
- ret = update_sysfs_num(m_buffer_enable_node_path.c_str(), enable, true);
- if (ret < 0) {
- ERR("failed to write to buffer/enable\n");
+ if (!(pfd.revents & POLLIN)) {
+ ERR("poll nothing to read! m_node_handle:%d, pfd.revents = %d", m_node_handle, pfd.revents);
return false;
}
- if (enable)
- INFO("buffer enabled\n");
- else
- INFO("buffer disabled\n");
- return true;
-}
+ int len = read(m_node_handle, data, sizeof(data));
-bool accel_sensor_hal::enable_resource(bool enable)
-{
- string temp;
- if(enable)
- setup_trigger(m_trigger_name.c_str(), enable);
- else
- setup_trigger("NULL", enable);
-
- for (vector <string>::iterator it = m_generic_channel_names.begin();
- it != m_generic_channel_names.end(); ++it) {
- temp = m_accel_dir + string(SCAN_EL_DIR) + *it + string("_en");
- if (update_sysfs_num(temp.c_str(), enable) < 0)
- return false;
+ if (len != sizeof(data)) {
+ ERR("Failed to read data, m_node_handle:%d read_len:%d", m_node_handle, len);
+ return false;
}
- setup_buffer(enable);
- return true;
-}
-bool accel_sensor_hal::enable(void)
-{
- AUTOLOCK(m_mutex);
+ AUTOLOCK(m_value_mutex);
- if (!enable_resource(true))
- return false;
+ m_x = *((short *)(data));
+ m_y = *((short *)(data + 2));
+ m_z = *((short *)(data + 4));
- set_interval(m_polling_interval);
+ m_fired_time = *((long long*)(data + 6));
- m_fired_time = 0;
- INFO("Accel sensor real starting");
- return true;
-}
+ INFO("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
-bool accel_sensor_hal::disable(void)
-{
- AUTOLOCK(m_mutex);
-
- if (!enable_resource(false))
- return false;
-
- INFO("Accel sensor real stopping");
return true;
-}
-
-bool accel_sensor_hal::set_interval(unsigned long ms_interval)
-{
- int freq, i;
-
- freq = (int)(MSEC_TO_FREQ(ms_interval));
-
- for (i=0; i < m_sample_freq_count; i++) {
- if (freq == m_sample_freq[i]) {
- if (update_sysfs_num(m_interval_node.c_str(), freq, true) == 0) {
- INFO("Interval is changed from %lums to %lums]", m_polling_interval, ms_interval);
- m_polling_interval = ms_interval;
- return true;
- }
- else {
- ERR("Failed to set data %lu\n", ms_interval);
- return false;
- }
- }
- }
- DBG("The interval not supported: %lu\n", ms_interval);
- ERR("Failed to set data %lu\n", ms_interval);
- return false;
-}
-
-bool accel_sensor_hal::update_value(bool wait)
-{
- int i;
- struct pollfd pfd;
- ssize_t read_size;
- const int TIMEOUT = 1000;
-
- pfd.fd = m_node_handle;
- pfd.events = POLLIN;
- if (wait)
- poll(&pfd, 1, TIMEOUT);
- else
- poll(&pfd, 1, 0);
-
- read_size = read(m_node_handle, m_data, ACCEL_RINGBUF_LEN * m_scan_size);
- if (read_size <= 0) {
- ERR("Accel:No data available\n");
- return false;
- }
- else {
- for (i = 0; i < (read_size / m_scan_size); i++)
- decode_data();
- }
- return true;
}
bool accel_sensor_hal::is_data_ready(bool wait)
return true;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- accel_sensor_hal *inst;
+ accel_sensor_hal *sensor;
try {
- inst = new accel_sensor_hal();
+ sensor = new(std::nothrow) accel_sensor_hal;
} catch (int err) {
- ERR("accel_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (accel_sensor_hal*)inst;
+ module->sensors.push_back(sensor);
+ return module;
}