blob: b6d88a64b5c0e32687598588bac05ba2d555cf1f [file] [log] [blame]
/*
* Copyright 2023 Google LLC
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <zephyr/device.h>
#include <zephyr/input/input_analog_axis.h>
#include <zephyr/input/input_analog_axis_settings.h>
#include <zephyr/logging/log.h>
#include <zephyr/settings/settings.h>
#include <zephyr/sys/printk.h>
LOG_MODULE_REGISTER(analog_axis_settings, CONFIG_INPUT_LOG_LEVEL);
#define ANALOG_AXIS_SETTINGS_PATH_MAX 32
#define MAX_AXES CONFIG_INPUT_ANALOG_AXIS_SETTINGS_MAX_AXES
static void analog_axis_calibration_log(const struct device *dev)
{
struct analog_axis_calibration cal;
int i;
for (i = 0; i < analog_axis_num_axes(dev); i++) {
analog_axis_calibration_get(dev, i, &cal);
LOG_INF("%s: ch: %d min: %d max: %d deadzone: %d",
dev->name, i, cal.in_min, cal.in_max, cal.in_deadzone);
}
}
static int analog_axis_calibration_load(const char *key, size_t len_rd,
settings_read_cb read_cb, void *cb_arg)
{
const struct device *dev;
struct analog_axis_calibration cal[MAX_AXES];
int axes;
char dev_name[ANALOG_AXIS_SETTINGS_PATH_MAX];
const char *next;
int nlen;
ssize_t len;
nlen = settings_name_next(key, &next);
if (nlen + 1 > sizeof(dev_name)) {
LOG_ERR("Setting name too long: %d", nlen);
return -EINVAL;
}
memcpy(dev_name, key, nlen);
dev_name[nlen] = '\0';
dev = device_get_binding(dev_name);
if (dev == NULL) {
LOG_ERR("Cannot restore: device %s not available", dev_name);
return -ENODEV;
}
len = read_cb(cb_arg, cal, sizeof(cal));
if (len < 0) {
LOG_ERR("Data restore error: %d", len);
}
axes = analog_axis_num_axes(dev);
if (len != sizeof(struct analog_axis_calibration) * axes) {
LOG_ERR("Invalid settings data length: %d, expected %d",
len, sizeof(struct analog_axis_calibration) * axes);
return -EIO;
}
for (int i = 0; i < axes; i++) {
analog_axis_calibration_set(dev, i, &cal[i]);
}
analog_axis_calibration_log(dev);
return 0;
}
SETTINGS_STATIC_HANDLER_DEFINE(analog_axis, "aa-cal", NULL,
analog_axis_calibration_load, NULL, NULL);
int analog_axis_calibration_save(const struct device *dev)
{
struct analog_axis_calibration cal[MAX_AXES];
int axes;
char path[ANALOG_AXIS_SETTINGS_PATH_MAX];
int ret;
analog_axis_calibration_log(dev);
ret = snprintk(path, sizeof(path), "aa-cal/%s", dev->name);
if (ret < 0) {
return -EINVAL;
}
axes = analog_axis_num_axes(dev);
for (int i = 0; i < axes; i++) {
analog_axis_calibration_get(dev, i, &cal[i]);
}
ret = settings_save_one(path, &cal[0],
sizeof(struct analog_axis_calibration) * axes);
if (ret < 0) {
LOG_ERR("Settings save errord: %d", ret);
return ret;
}
return 0;
}