1 /*
2 * Copyright (c) 2023 The ChromiumOS Authors
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_VOLTAGE_DIVIDER_H_
8 #define ZEPHYR_INCLUDE_DRIVERS_ADC_VOLTAGE_DIVIDER_H_
9
10 #include <zephyr/drivers/adc.h>
11
12 struct voltage_divider_dt_spec {
13 const struct adc_dt_spec port;
14 uint32_t full_ohms;
15 uint32_t output_ohms;
16 };
17
18 /**
19 * @brief Get voltage divider information from devicetree.
20 *
21 * This returns a static initializer for a @p voltage_divider_dt_spec structure
22 * given a devicetree node.
23 *
24 * @param node_id Devicetree node identifier.
25 *
26 * @return Static initializer for an voltage_divider_dt_spec structure.
27 */
28 #define VOLTAGE_DIVIDER_DT_SPEC_GET(node_id) \
29 { \
30 .port = ADC_DT_SPEC_GET(node_id), \
31 .full_ohms = DT_PROP_OR(node_id, full_ohms, 0), \
32 .output_ohms = DT_PROP(node_id, output_ohms), \
33 }
34
35 /**
36 * @brief Calculates the actual voltage from the measured voltage
37 *
38 * @param[in] spec voltage divider specification from Devicetree.
39 * @param[in,out] v_to_v Pointer to the measured voltage on input, and the
40 * corresponding scaled voltage value on output.
41 *
42 * @retval 0 on success
43 * @retval -ENOTSUP if "full_ohms" is not specified
44 */
voltage_divider_scale_dt(const struct voltage_divider_dt_spec * spec,int32_t * v_to_v)45 static inline int voltage_divider_scale_dt(const struct voltage_divider_dt_spec *spec,
46 int32_t *v_to_v)
47 {
48 /* cannot be scaled if "full_ohms" is not specified */
49 if (spec->full_ohms == 0) {
50 return -ENOTSUP;
51 }
52
53 /* voltage scaled by voltage divider values using DT binding */
54 *v_to_v = *v_to_v * spec->full_ohms / spec->output_ohms;
55
56 return 0;
57 }
58
59 #endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_VOLTAGE_DIVIDER_H_ */
60