sys: linear_range: allow out-of-range values/windows

The existing linear_range API did not allow values or windows outside of
the linear range (returned -EINVAL). With this change values are allowed
outside of the range, being adjusted to the edge values (min/max)
instead. In the case of windows, it is allowed to have partial
intersection. In both cases, the API assigns a valid index (nearest) and
returns -ERANGE. This change is useful because the main client of the
linear range API, regulators, needs such behavior. For example, If an
application specifies a voltage range from 1.0V to 1.5V and the
regulator supports from 1.2V to 2.7V, the regulator can configure a
voltage that satisfies the condition: 1.2V.  With the current API, the
input would be refused because 1.0V lies outside of the 1.2V-2.7V range.

Also, for constant ranges, the minimum index is returned.

Tests have been updated/extended accordingly.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
Gerard Marull-Paretas 2023-01-12 18:04:45 +01:00 committed by Carles Cufí
commit e086738b88
4 changed files with 95 additions and 60 deletions

View file

@ -149,7 +149,7 @@ static int regulator_npm6001_buck012_set_voltage(
int ret;
ret = linear_range_get_win_index(range, min_uv, max_uv, &idx);
if (ret < 0) {
if (ret == -EINVAL) {
return ret;
}
@ -205,7 +205,7 @@ static int regulator_npm6001_buck3_set_voltage(const struct device *dev,
int ret;
ret = linear_range_get_win_index(&buck3_range, min_uv, max_uv, &idx);
if (ret < 0) {
if (ret == -EINVAL) {
return ret;
}

View file

@ -218,7 +218,7 @@ static int regulator_pca9420_set_voltage(const struct device *dev,
ret = linear_range_group_get_win_index(config->desc->ranges,
config->desc->num_ranges, min_uv,
max_uv, &idx);
if (ret < 0) {
if (ret == -EINVAL) {
return ret;
}
@ -327,7 +327,7 @@ static int regulator_pca9420_init(const struct device *dev)
ret = linear_range_group_get_win_index(
config->desc->ranges, config->desc->num_ranges,
config->modes_uv[i], config->modes_uv[i], &idx);
if (ret < 0) {
if (ret == -EINVAL) {
return ret;
}