Skip to content

Commit ad56be5

Browse files
committed
fuel_gauge: composite: more flexible data sourcing
Instead of explicitly specifying the source for the voltage and current channels, specify primary and secondary data sources. If the requested sensor channel does not exist on the primary source, the secondary source will be tried. Signed-off-by: Jordan Yates <[email protected]>
1 parent cba56d5 commit ad56be5

File tree

5 files changed

+51
-28
lines changed

5 files changed

+51
-28
lines changed

boards/nordic/thingy53/thingy53_nrf5340_common.dtsi

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595

9696
fuel_gauge: fuel_gauge {
9797
compatible = "zephyr,fuel-gauge-composite";
98-
battery-voltage = <&vbatt>;
98+
source-primary = <&vbatt>;
9999
device-chemistry = "lithium-ion-polymer";
100100
ocv-capacity-table-0 = <BATTERY_OCV_CURVE_LITHIUM_ION_POLYMER_DEFAULT>;
101101
charge-full-design-microamp-hours = <1350000>;

drivers/fuel_gauge/composite/fuel_gauge_composite.c

+38-14
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#include <zephyr/kernel.h>
1515

1616
struct composite_config {
17-
const struct device *battery_voltage;
18-
const struct device *battery_current;
17+
const struct device *source_primary;
18+
const struct device *source_secondary;
1919
int32_t ocv_lookup_table[BATTERY_OCV_TABLE_LEN];
2020
uint32_t charge_capacity_microamp_hours;
2121
enum battery_chemistry chemistry;
@@ -40,6 +40,19 @@ static int composite_fetch(const struct device *dev)
4040
return pm_device_runtime_put(dev);
4141
}
4242

43+
static int composite_channel_get(const struct device *dev, enum sensor_channel chan,
44+
struct sensor_value *val)
45+
{
46+
const struct composite_config *config = dev->config;
47+
int rc;
48+
49+
rc = sensor_channel_get(config->source_primary, chan, val);
50+
if ((rc == -ENOTSUP) && config->source_secondary) {
51+
rc = sensor_channel_get(config->source_secondary, chan, val);
52+
}
53+
return rc;
54+
}
55+
4356
static int composite_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
4457
union fuel_gauge_prop_val *val)
4558
{
@@ -61,9 +74,9 @@ static int composite_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
6174

6275
if (now >= data->next_reading) {
6376
/* Trigger a sample on the input devices */
64-
rc = composite_fetch(config->battery_voltage);
65-
if ((rc == 0) && config->battery_current) {
66-
rc = composite_fetch(config->battery_current);
77+
rc = composite_fetch(config->source_primary);
78+
if ((rc == 0) && config->source_secondary) {
79+
rc = composite_fetch(config->source_secondary);
6780
}
6881
if (rc != 0) {
6982
return rc;
@@ -87,7 +100,7 @@ static int composite_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
87100
val->full_charge_capacity = config->charge_capacity_microamp_hours / 1000;
88101
break;
89102
case FUEL_GAUGE_VOLTAGE:
90-
rc = sensor_channel_get(config->battery_voltage, SENSOR_CHAN_VOLTAGE, &sensor_val);
103+
rc = composite_channel_get(dev, SENSOR_CHAN_VOLTAGE, &sensor_val);
91104
val->voltage = sensor_value_to_micro(&sensor_val);
92105
break;
93106
case FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE:
@@ -96,7 +109,7 @@ static int composite_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
96109
return -ENOTSUP;
97110
}
98111
/* Fetch the voltage from the sensor */
99-
rc = sensor_channel_get(config->battery_voltage, SENSOR_CHAN_VOLTAGE, &sensor_val);
112+
rc = composite_channel_get(dev, SENSOR_CHAN_VOLTAGE, &sensor_val);
100113
voltage = sensor_value_to_micro(&sensor_val);
101114
if (rc == 0) {
102115
/* Convert voltage to state of charge */
@@ -106,10 +119,7 @@ static int composite_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
106119
break;
107120
case FUEL_GAUGE_CURRENT:
108121
case FUEL_GAUGE_AVG_CURRENT:
109-
if (config->battery_current == NULL) {
110-
return -ENOTSUP;
111-
}
112-
rc = sensor_channel_get(config->battery_current, SENSOR_CHAN_CURRENT, &sensor_val);
122+
rc = composite_channel_get(dev, SENSOR_CHAN_CURRENT, &sensor_val);
113123
val->current = sensor_value_to_micro(&sensor_val);
114124
break;
115125
default:
@@ -119,22 +129,36 @@ static int composite_get_prop(const struct device *dev, fuel_gauge_prop_t prop,
119129
return rc;
120130
}
121131

132+
static int fuel_gauge_composite_init(const struct device *dev)
133+
{
134+
const struct composite_config *config = dev->config;
135+
136+
/* Validate sources are ready */
137+
if (!device_is_ready(config->source_primary)) {
138+
return -ENODEV;
139+
}
140+
if (config->source_secondary && !!device_is_ready(config->source_secondary)) {
141+
return -ENODEV;
142+
}
143+
return 0;
144+
}
145+
122146
static DEVICE_API(fuel_gauge, composite_api) = {
123147
.get_property = composite_get_prop,
124148
};
125149

126150
#define COMPOSITE_INIT(inst) \
127151
static const struct composite_config composite_##inst##_config = { \
128-
.battery_voltage = DEVICE_DT_GET(DT_INST_PROP(inst, battery_voltage)), \
129-
.battery_current = DEVICE_DT_GET_OR_NULL(DT_INST_PROP(inst, battery_current)), \
152+
.source_primary = DEVICE_DT_GET(DT_INST_PROP(inst, source_primary)), \
153+
.source_secondary = DEVICE_DT_GET_OR_NULL(DT_INST_PROP(inst, source_secondary)), \
130154
.ocv_lookup_table = \
131155
BATTERY_OCV_TABLE_DT_GET(DT_DRV_INST(inst), ocv_capacity_table_0), \
132156
.charge_capacity_microamp_hours = \
133157
DT_INST_PROP_OR(inst, charge_full_design_microamp_hours, 0), \
134158
.chemistry = BATTERY_CHEMISTRY_DT_GET(inst), \
135159
}; \
136160
static struct composite_data composite_##inst##_data; \
137-
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &composite_##inst##_data, \
161+
DEVICE_DT_INST_DEFINE(inst, fuel_gauge_composite_init, NULL, &composite_##inst##_data, \
138162
&composite_##inst##_config, POST_KERNEL, \
139163
CONFIG_SENSOR_INIT_PRIORITY, &composite_api);
140164

dts/bindings/fuel-gauge/zephyr,fuel-gauge-composite.yaml

+9-10
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,28 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
description: |
5-
Composite fuel-gauge constructed from analog input values
5+
Composite fuel-gauge constructed from sensor devices
66
77
compatible: "zephyr,fuel-gauge-composite"
88

99
include: [fuel-gauge.yaml, battery.yaml]
1010

1111
properties:
12-
battery-voltage:
12+
source-primary:
1313
type: phandle
1414
required: true
1515
description: |
16-
Device to read battery voltage from.
16+
Primary device to read sensor data from.
17+
Device must implement the sensor API.
1718
18-
Device must implement the sensor API and provide the
19-
`SENSOR_CHAN_VOLTAGE` channel.
20-
21-
battery-current:
19+
source-secondary:
2220
type: phandle
2321
description: |
24-
Device to read battery current from.
22+
Secondary device to read sensor data from.
23+
This device will be used if input-primary does not expose
24+
a channel.
2525
26-
Device must implement the sensor API and provide the
27-
`SENSOR_CHAN_CURRENT` channel.
26+
Device must implement the sensor API.
2827
2928
device-chemistry:
3029
required: true

tests/drivers/build_all/fuel_gauge/app.overlay

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
test_fuel_gauge: fuel_gauge {
5757
compatible = "zephyr,fuel-gauge-composite";
5858
status = "okay";
59-
battery-voltage = <&test_vbatt>;
59+
source-primary = <&test_vbatt>;
6060
device-chemistry = "lithium-ion-polymer";
6161
ocv-capacity-table-0 = <0>;
6262
charge-full-design-microamp-hours = <1350000>;

tests/drivers/build_all/sensor/adc.dtsi

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ test_current: current_amp {
3939
test_composite_fuel_gauge: composite_fuel_gauge {
4040
compatible = "zephyr,fuel-gauge-composite";
4141
status = "okay";
42-
battery-voltage = <&test_voltage>;
43-
battery-current = <&test_current>;
42+
source-primary = <&test_voltage>;
43+
source-secondary = <&test_current>;
4444
device-chemistry = "lithium-ion-polymer";
4545
ocv-capacity-table-0 = <BATTERY_OCV_CURVE_LITHIUM_ION_POLYMER_DEFAULT>;
4646
charge-full-design-microamp-hours = <1000000>;

0 commit comments

Comments
 (0)