blob: 15b9b8779316bff5a35f55d41ce836ea9fda0888 [file] [log] [blame]
/*
* Copyright (c) 2023 The ChromiumOS Authors
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/adc/voltage_divider.h>
#include <zephyr/drivers/adc/current_sense_amplifier.h>
/* 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;
}