e69ce68d40
Initializers must be compile time constants (not expressions!) for clang to be happy. Clang rightfully pointed out that the callback_list member of sensing_connection was being initialized using an expression that was not compile-time constant. The macros passed along a pointer created by taking the address of a global constant and then at initialization time attempting to dereference it using the * operator. So in the end the compiler has identifier its trying to first take the address of and then later dereference in an initializer. Clang didn't appreciate this, though gcc seemed to be just fine. Actually clang 17 might work just fine with this as well, but clang 16 (the clang I tried) didn't like it at all. Instead store the pointer to the callback list rather than copying the struct. This could be done the other way and not passing a pointer through the macros perhaps. Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
158 lines
3.4 KiB
C
158 lines
3.4 KiB
C
/*
|
|
* Copyright (c) 2023 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/sensing/sensing.h>
|
|
#include <zephyr/sensing/sensing_sensor.h>
|
|
#include <stdlib.h>
|
|
#include "sensor_mgmt.h"
|
|
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_DECLARE(sensing, CONFIG_SENSING_LOG_LEVEL);
|
|
|
|
/* sensing_open_sensor is normally called by applications: hid, chre, zephyr main, etc */
|
|
int sensing_open_sensor(const struct sensing_sensor_info *sensor_info,
|
|
struct sensing_callback_list *cb_list,
|
|
sensing_sensor_handle_t *handle)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (sensor_info == NULL || handle == NULL) {
|
|
return -ENODEV;
|
|
}
|
|
|
|
STRUCT_SECTION_FOREACH(sensing_sensor, sensor) {
|
|
if (sensor_info == sensor->info) {
|
|
ret = open_sensor(sensor, (struct sensing_connection **)handle);
|
|
if (ret) {
|
|
return -EINVAL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return sensing_register_callback(*handle, cb_list);
|
|
}
|
|
|
|
int sensing_open_sensor_by_dt(const struct device *dev,
|
|
struct sensing_callback_list *cb_list,
|
|
sensing_sensor_handle_t *handle)
|
|
{
|
|
int ret = 0;
|
|
struct sensing_sensor *sensor;
|
|
|
|
if (handle == NULL) {
|
|
return -ENODEV;
|
|
}
|
|
|
|
sensor = get_sensor_by_dev(dev);
|
|
if (sensor == NULL) {
|
|
LOG_ERR("cannot get sensor from dev:%p", dev);
|
|
return -ENODEV;
|
|
}
|
|
|
|
ret = open_sensor(sensor, (struct sensing_connection **)handle);
|
|
if (ret) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
return sensing_register_callback(*handle, cb_list);
|
|
}
|
|
|
|
/* sensing_close_sensor is normally called by applications: hid, chre, zephyr main, etc */
|
|
int sensing_close_sensor(sensing_sensor_handle_t *handle)
|
|
{
|
|
if (handle == NULL) {
|
|
return -ENODEV;
|
|
}
|
|
|
|
return close_sensor((struct sensing_connection **)handle);
|
|
}
|
|
|
|
int sensing_set_config(sensing_sensor_handle_t handle,
|
|
struct sensing_sensor_config *configs,
|
|
int count)
|
|
{
|
|
struct sensing_sensor_config *cfg;
|
|
int i, ret = 0;
|
|
|
|
if (handle == NULL || configs == NULL) {
|
|
return -ENODEV;
|
|
}
|
|
|
|
if (count <= 0 || count > SENSING_SENSOR_ATTRIBUTE_MAX) {
|
|
LOG_ERR("invalid config count:%d", count);
|
|
return -EINVAL;
|
|
}
|
|
|
|
for (i = 0; i < count; i++) {
|
|
cfg = &configs[i];
|
|
switch (cfg->attri) {
|
|
case SENSING_SENSOR_ATTRIBUTE_INTERVAL:
|
|
ret |= set_interval(handle, cfg->interval);
|
|
break;
|
|
|
|
case SENSING_SENSOR_ATTRIBUTE_SENSITIVITY:
|
|
ret |= set_sensitivity(handle, cfg->data_field, cfg->sensitivity);
|
|
break;
|
|
|
|
case SENSING_SENSOR_ATTRIBUTE_LATENCY:
|
|
break;
|
|
|
|
default:
|
|
ret = -EINVAL;
|
|
LOG_ERR("invalid config attribute:%d\n", cfg->attri);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int sensing_get_config(sensing_sensor_handle_t handle,
|
|
struct sensing_sensor_config *configs,
|
|
int count)
|
|
{
|
|
struct sensing_sensor_config *cfg;
|
|
int i, ret = 0;
|
|
|
|
if (handle == NULL || configs == NULL) {
|
|
return -ENODEV;
|
|
}
|
|
|
|
if (count <= 0 || count > SENSING_SENSOR_ATTRIBUTE_MAX) {
|
|
LOG_ERR("invalid config count:%d", count);
|
|
return -EINVAL;
|
|
}
|
|
|
|
for (i = 0; i < count; i++) {
|
|
cfg = &configs[i];
|
|
switch (cfg->attri) {
|
|
case SENSING_SENSOR_ATTRIBUTE_INTERVAL:
|
|
ret |= get_interval(handle, &cfg->interval);
|
|
break;
|
|
|
|
case SENSING_SENSOR_ATTRIBUTE_SENSITIVITY:
|
|
ret |= get_sensitivity(handle, cfg->data_field, &cfg->sensitivity);
|
|
break;
|
|
|
|
case SENSING_SENSOR_ATTRIBUTE_LATENCY:
|
|
break;
|
|
|
|
default:
|
|
ret = -EINVAL;
|
|
LOG_ERR("invalid config attribute:%d\n", cfg->attri);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
const struct sensing_sensor_info *sensing_get_sensor_info(sensing_sensor_handle_t handle)
|
|
{
|
|
return get_sensor_info(handle);
|
|
}
|