From 3dba54b92da8f1d68569c3929605ee0131e33f9f Mon Sep 17 00:00:00 2001 From: Nick Ward Date: Sat, 23 Sep 2023 01:34:09 +1000 Subject: [PATCH] drivers: current sense amp: add pm Enable power management for current sense amp. Signed-off-by: Nick Ward --- drivers/sensor/current_amp/current_amp.c | 59 ++++++++++++++++++- .../iio/afe/current-sense-amplifier.yaml | 8 +++ .../drivers/adc/current_sense_amplifier.h | 3 + 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/drivers/sensor/current_amp/current_amp.c b/drivers/sensor/current_amp/current_amp.c index 8a62a1e61f5..d760e4b34b0 100644 --- a/drivers/sensor/current_amp/current_amp.c +++ b/drivers/sensor/current_amp/current_amp.c @@ -8,7 +8,9 @@ #include #include +#include #include +#include #include LOG_MODULE_REGISTER(current_amp, CONFIG_SENSOR_LOG_LEVEL); @@ -73,6 +75,40 @@ static const struct sensor_driver_api current_api = { .channel_get = get, }; +#ifdef CONFIG_PM_DEVICE +static int pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct current_sense_amplifier_dt_spec *config = dev->config; + int ret; + + if (config->power_gpio.port == NULL) { + LOG_ERR("PM not supported"); + return -ENOTSUP; + } + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = gpio_pin_set_dt(&config->power_gpio, 1); + if (ret != 0) { + LOG_ERR("failed to set GPIO for PM resume"); + return ret; + } + break; + case PM_DEVICE_ACTION_SUSPEND: + ret = gpio_pin_set_dt(&config->power_gpio, 0); + if (ret != 0) { + LOG_ERR("failed to set GPIO for PM suspend"); + return ret; + } + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif + static int current_init(const struct device *dev) { const struct current_sense_amplifier_dt_spec *config = dev->config; @@ -84,6 +120,21 @@ static int current_init(const struct device *dev) return -ENODEV; } +#ifdef CONFIG_PM_DEVICE + if (config->power_gpio.port != NULL) { + if (!gpio_is_ready_dt(&config->power_gpio)) { + LOG_ERR("Power GPIO is not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->power_gpio, GPIO_OUTPUT_ACTIVE); + if (ret != 0) { + LOG_ERR("failed to config GPIO: %d", ret); + return ret; + } + } +#endif + ret = adc_channel_setup_dt(&config->port); if (ret != 0) { LOG_ERR("setup: %d", ret); @@ -108,8 +159,10 @@ static int current_init(const struct device *dev) static const struct current_sense_amplifier_dt_spec current_amp_##inst##_config = \ CURRENT_SENSE_AMPLIFIER_DT_SPEC_GET(DT_DRV_INST(inst)); \ \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, ¤t_init, NULL, ¤t_amp_##inst##_data, \ - ¤t_amp_##inst##_config, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, ¤t_api); + PM_DEVICE_DT_INST_DEFINE(inst, pm_action); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, ¤t_init, PM_DEVICE_DT_INST_GET(inst), \ + ¤t_amp_##inst##_data, ¤t_amp_##inst##_config, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, ¤t_api); DT_INST_FOREACH_STATUS_OKAY(CURRENT_SENSE_AMPLIFIER_INIT) diff --git a/dts/bindings/iio/afe/current-sense-amplifier.yaml b/dts/bindings/iio/afe/current-sense-amplifier.yaml index e50bda74fe4..777116d0cff 100644 --- a/dts/bindings/iio/afe/current-sense-amplifier.yaml +++ b/dts/bindings/iio/afe/current-sense-amplifier.yaml @@ -37,3 +37,11 @@ properties: default: 1 description: | Amplifier gain divider. The default is <1>. + + power-gpios: + type: phandle-array + description: | + Control power to the current amplifier. + + If present the corresponding GPIO must be set to an active level + to enable the current amplifier. diff --git a/include/zephyr/drivers/adc/current_sense_amplifier.h b/include/zephyr/drivers/adc/current_sense_amplifier.h index 6035eeb4ed2..888167b1ae9 100644 --- a/include/zephyr/drivers/adc/current_sense_amplifier.h +++ b/include/zephyr/drivers/adc/current_sense_amplifier.h @@ -8,12 +8,14 @@ #define ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_AMPLIFIER_H_ #include +#include struct current_sense_amplifier_dt_spec { const struct adc_dt_spec port; uint32_t sense_micro_ohms; uint32_t sense_gain_mult; uint32_t sense_gain_div; + struct gpio_dt_spec power_gpio; }; /** @@ -32,6 +34,7 @@ struct current_sense_amplifier_dt_spec { .sense_micro_ohms = DT_PROP(node_id, sense_resistor_micro_ohms), \ .sense_gain_mult = DT_PROP(node_id, sense_gain_mult), \ .sense_gain_div = DT_PROP(node_id, sense_gain_div), \ + .power_gpio = GPIO_DT_SPEC_GET_OR(node_id, power_gpios, {0}), \ } /**