/* * Copyright (c) 2023 The ChromiumOS Authors * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include /* The devicetree node identifier for the adc aliases. */ #define VBUS_V_MEAS_NODE DT_ALIAS(vbus) #define VBUS_C_MEAS_NODE DT_ALIAS(cbus) static const struct voltage_divider_dt_spec adc_vbus_v = VOLTAGE_DIVIDER_DT_SPEC_GET(VBUS_V_MEAS_NODE); static const struct current_sense_amplifier_dt_spec adc_vbus_c = CURRENT_SENSE_AMPLIFIER_DT_SPEC_GET(VBUS_C_MEAS_NODE); int meas_vbus_v(int32_t *v) { int ret; int32_t sample_buffer = 0; /* Structure defining an ADC sampling sequence */ struct adc_sequence sequence = { .buffer = &sample_buffer, /* buffer size in bytes, not number of samples */ .buffer_size = sizeof(sample_buffer), .calibrate = true, }; adc_sequence_init_dt(&adc_vbus_v.port, &sequence); ret = adc_read_dt(&adc_vbus_v.port, &sequence); if (ret != 0) { return ret; } *v = sample_buffer; ret = adc_raw_to_millivolts_dt(&adc_vbus_v.port, v); if (ret != 0) { return ret; } ret = voltage_divider_scale_dt(&adc_vbus_v, v); if (ret != 0) { return ret; } return 0; } int meas_vbus_c(int32_t *c) { int ret; int32_t sample_buffer = 0; /* Structure defining an ADC sampling sequence */ struct adc_sequence sequence = { .buffer = &sample_buffer, /* buffer size in bytes, not number of samples */ .buffer_size = sizeof(sample_buffer), .calibrate = true, }; adc_sequence_init_dt(&adc_vbus_c.port, &sequence); ret = adc_read(adc_vbus_c.port.dev, &sequence); if (ret != 0) { return ret; } *c = sample_buffer; ret = adc_raw_to_millivolts_dt(&adc_vbus_c.port, c); if (ret != 0) { return ret; } /* prescaling the voltage offset */ *c -= adc_vbus_c.port.vref_mv / 2; current_sense_amplifier_scale_dt(&adc_vbus_c, c); return 0; } int meas_init(void) { int ret; ret = adc_channel_setup_dt(&adc_vbus_v.port); if (ret != 0) { return ret; } ret = adc_channel_setup_dt(&adc_vbus_c.port); if (ret != 0) { return ret; } return 0; }