diff --git a/drivers/comparator/CMakeLists.txt b/drivers/comparator/CMakeLists.txt index 20aa301af7d..d0dc726bf58 100644 --- a/drivers/comparator/CMakeLists.txt +++ b/drivers/comparator/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_USERSPACE comparator_handlers.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NRF_COMP comparator_nrf_comp.c) +zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NRF_LPCOMP comparator_nrf_lpcomp.c) diff --git a/drivers/comparator/Kconfig b/drivers/comparator/Kconfig index 84ea5c74baa..819936024b9 100644 --- a/drivers/comparator/Kconfig +++ b/drivers/comparator/Kconfig @@ -19,5 +19,6 @@ config COMPARATOR_INIT_PRIORITY Comparator device driver initialization priority. rsource "Kconfig.nrf_comp" +rsource "Kconfig.nrf_lpcomp" endif # COMPARATOR diff --git a/drivers/comparator/Kconfig.nrf_lpcomp b/drivers/comparator/Kconfig.nrf_lpcomp new file mode 100644 index 00000000000..f33de46f15d --- /dev/null +++ b/drivers/comparator/Kconfig.nrf_lpcomp @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config COMPARATOR_NRF_LPCOMP + bool "Nordic LPCOMP comparator driver" + default y + depends on DT_HAS_NORDIC_NRF_LPCOMP_ENABLED + select NRFX_LPCOMP diff --git a/drivers/comparator/comparator_nrf_lpcomp.c b/drivers/comparator/comparator_nrf_lpcomp.c new file mode 100644 index 00000000000..6c6710d337d --- /dev/null +++ b/drivers/comparator/comparator_nrf_lpcomp.c @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include + +#include + +#define DT_DRV_COMPAT nordic_nrf_lpcomp + +#define SHIM_NRF_LPCOMP_DT_INST_REFSEL(inst) \ + _CONCAT(COMP_NRF_LPCOMP_REFSEL_, DT_INST_STRING_TOKEN(inst, refsel)) + +#define SHIM_NRF_LPCOMP_DT_INST_REFSEL_IS_AREF(inst) \ + DT_INST_ENUM_HAS_VALUE(inst, refsel, AREF) + +#define SHIM_NRF_LPCOMP_DT_INST_EXTREFSEL(inst) \ + _CONCAT(COMP_NRF_LPCOMP_EXTREFSEL_, DT_INST_STRING_TOKEN(inst, extrefsel)) + +#define SHIM_NRF_LPCOMP_DT_INST_ENABLE_HYST(inst) \ + DT_INST_PROP(inst, enable_hyst) + +#define SHIM_NRF_LPCOMP_DT_INST_PSEL(inst) \ + _CONCAT(COMP_NRF_LPCOMP_PSEL_, DT_INST_STRING_TOKEN(inst, psel)) + +struct shim_nrf_lpcomp_data { + nrfx_lpcomp_config_t config; + uint32_t event_mask; + bool started; + atomic_t triggered; + comparator_callback_t callback; + void *user_data; +}; + +#if (NRF_LPCOMP_HAS_AIN_AS_PIN) +static const uint32_t shim_nrf_lpcomp_ain_map[] = { +#if defined(CONFIG_SOC_NRF54H20) || defined(CONFIG_SOC_NRF9280) + NRF_PIN_PORT_TO_PIN_NUMBER(0U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(1U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(2U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(3U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(4U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(5U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(6U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(7U, 1), +#elif defined(CONFIG_SOC_NRF54L15) + NRF_PIN_PORT_TO_PIN_NUMBER(4U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(5U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(6U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(7U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(11U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(12U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(13U, 1), + NRF_PIN_PORT_TO_PIN_NUMBER(14U, 1), +#endif +}; +#endif + +#if (NRF_LPCOMP_HAS_AIN_AS_PIN) +BUILD_ASSERT(COMP_NRF_LPCOMP_PSEL_AIN0 == 0); +BUILD_ASSERT(COMP_NRF_LPCOMP_PSEL_AIN7 == 7); +BUILD_ASSERT(COMP_NRF_LPCOMP_EXTREFSEL_AIN0 == 0); +BUILD_ASSERT(COMP_NRF_LPCOMP_EXTREFSEL_AIN1 == 1); +#endif + +#if (LPCOMP_REFSEL_RESOLUTION == 8) +BUILD_ASSERT((SHIM_NRF_LPCOMP_DT_INST_REFSEL(0) < COMP_NRF_LPCOMP_REFSEL_VDD_1_16) || + (SHIM_NRF_LPCOMP_DT_INST_REFSEL(0) > COMP_NRF_LPCOMP_REFSEL_VDD_15_16)); +#endif + +#if SHIM_NRF_LPCOMP_DT_INST_ENABLE_HYST(0) +BUILD_ASSERT(NRF_LPCOMP_HAS_HYST); +#endif + +static struct shim_nrf_lpcomp_data shim_nrf_lpcomp_data0; + +static const struct comp_nrf_lpcomp_config shim_nrf_lpcomp_config0 = { + .psel = SHIM_NRF_LPCOMP_DT_INST_PSEL(0), +#if SHIM_NRF_LPCOMP_DT_INST_REFSEL_IS_AREF(0) + .extrefsel = SHIM_NRF_LPCOMP_DT_INST_EXTREFSEL(0), +#endif + .refsel = SHIM_NRF_LPCOMP_DT_INST_REFSEL(0), + .enable_hyst = SHIM_NRF_LPCOMP_DT_INST_ENABLE_HYST(0), +}; + +#if CONFIG_PM_DEVICE +static bool shim_nrf_lpcomp_is_resumed(void) +{ + enum pm_device_state state; + + (void)pm_device_state_get(DEVICE_DT_INST_GET(0), &state); + return state == PM_DEVICE_STATE_ACTIVE; +} +#else +static bool shim_nrf_lpcomp_is_resumed(void) +{ + return true; +} +#endif + +static void shim_nrf_lpcomp_start(void) +{ + if (shim_nrf_lpcomp_data0.started) { + return; + } + + nrfx_lpcomp_start(shim_nrf_lpcomp_data0.event_mask, 0); + shim_nrf_lpcomp_data0.started = true; +} + +static void shim_nrf_lpcomp_stop(void) +{ + if (!shim_nrf_lpcomp_data0.started) { + return; + } + + nrfx_lpcomp_stop(); + shim_nrf_lpcomp_data0.started = false; +} + +static int shim_nrf_lpcomp_pm_callback(const struct device *dev, enum pm_device_action action) +{ + ARG_UNUSED(dev); + + ARG_UNUSED(dev); + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + shim_nrf_lpcomp_start(); + break; + +#if CONFIG_PM_DEVICE + case PM_DEVICE_ACTION_SUSPEND: + shim_nrf_lpcomp_stop(); + break; +#endif + + default: + return -ENOTSUP; + } + + return 0; +} + +#if (NRF_LPCOMP_HAS_AIN_AS_PIN) +static int shim_nrf_lpcomp_psel_to_nrf(enum comp_nrf_lpcomp_psel shim, + nrf_lpcomp_input_t *nrf) +{ + if (shim >= ARRAY_SIZE(shim_nrf_lpcomp_ain_map)) { + return -EINVAL; + } + + *nrf = shim_nrf_lpcomp_ain_map[(uint32_t)shim]; + return 0; +} +#else +static int shim_nrf_lpcomp_psel_to_nrf(enum comp_nrf_lpcomp_psel shim, + nrf_lpcomp_input_t *nrf) +{ + switch (shim) { + case COMP_NRF_LPCOMP_PSEL_AIN0: + *nrf = NRF_LPCOMP_INPUT_0; + break; + + case COMP_NRF_LPCOMP_PSEL_AIN1: + *nrf = NRF_LPCOMP_INPUT_1; + break; + + case COMP_NRF_LPCOMP_PSEL_AIN2: + *nrf = NRF_LPCOMP_INPUT_2; + break; + + case COMP_NRF_LPCOMP_PSEL_AIN3: + *nrf = NRF_LPCOMP_INPUT_3; + break; + + case COMP_NRF_LPCOMP_PSEL_AIN4: + *nrf = NRF_LPCOMP_INPUT_4; + break; + + case COMP_NRF_LPCOMP_PSEL_AIN5: + *nrf = NRF_LPCOMP_INPUT_5; + break; + + case COMP_NRF_LPCOMP_PSEL_AIN6: + *nrf = NRF_LPCOMP_INPUT_6; + break; + + case COMP_NRF_LPCOMP_PSEL_AIN7: + *nrf = NRF_LPCOMP_INPUT_7; + break; + + default: + return -EINVAL; + } + + return 0; +} +#endif + +#if (NRF_LPCOMP_HAS_AIN_AS_PIN) +static int shim_nrf_lpcomp_extrefsel_to_nrf(enum comp_nrf_lpcomp_extrefsel shim, + nrf_lpcomp_ext_ref_t *nrf) +{ + if (shim >= ARRAY_SIZE(shim_nrf_lpcomp_ain_map)) { + return -EINVAL; + } + + *nrf = shim_nrf_lpcomp_ain_map[shim]; + return 0; +} +#else +static int shim_nrf_lpcomp_extrefsel_to_nrf(enum comp_nrf_lpcomp_extrefsel shim, + nrf_lpcomp_ext_ref_t *nrf) +{ + switch (shim) { + case COMP_NRF_LPCOMP_EXTREFSEL_AIN0: + *nrf = NRF_LPCOMP_EXT_REF_REF0; + break; + + case COMP_NRF_LPCOMP_EXTREFSEL_AIN1: + *nrf = NRF_LPCOMP_EXT_REF_REF1; + break; + + default: + return -EINVAL; + } + + return 0; +} +#endif + +static int shim_nrf_lpcomp_refsel_to_nrf(enum comp_nrf_lpcomp_refsel shim, + nrf_lpcomp_ref_t *nrf) +{ + switch (shim) { + case COMP_NRF_LPCOMP_REFSEL_VDD_1_8: + *nrf = NRF_LPCOMP_REF_SUPPLY_1_8; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_2_8: + *nrf = NRF_LPCOMP_REF_SUPPLY_2_8; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_3_8: + *nrf = NRF_LPCOMP_REF_SUPPLY_3_8; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_4_8: + *nrf = NRF_LPCOMP_REF_SUPPLY_4_8; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_5_8: + *nrf = NRF_LPCOMP_REF_SUPPLY_5_8; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_6_8: + *nrf = NRF_LPCOMP_REF_SUPPLY_6_8; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_7_8: + *nrf = NRF_LPCOMP_REF_SUPPLY_7_8; + break; + +#if (LPCOMP_REFSEL_RESOLUTION == 16) + case COMP_NRF_LPCOMP_REFSEL_VDD_1_16: + *nrf = NRF_LPCOMP_REF_SUPPLY_1_16; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_3_16: + *nrf = NRF_LPCOMP_REF_SUPPLY_3_16; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_5_16: + *nrf = NRF_LPCOMP_REF_SUPPLY_5_16; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_7_16: + *nrf = NRF_LPCOMP_REF_SUPPLY_7_16; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_9_16: + *nrf = NRF_LPCOMP_REF_SUPPLY_9_16; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_11_16: + *nrf = NRF_LPCOMP_REF_SUPPLY_11_16; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_13_16: + *nrf = NRF_LPCOMP_REF_SUPPLY_13_16; + break; + + case COMP_NRF_LPCOMP_REFSEL_VDD_15_16: + *nrf = NRF_LPCOMP_REF_SUPPLY_15_16; + break; +#endif + + case COMP_NRF_LPCOMP_REFSEL_AREF: + *nrf = NRF_LPCOMP_REF_EXT_REF; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int shim_nrf_lpcomp_config_to_nrf(const struct comp_nrf_lpcomp_config *shim, + nrfx_lpcomp_config_t *nrf) +{ + if (shim_nrf_lpcomp_refsel_to_nrf(shim->refsel, &nrf->reference)) { + return -EINVAL; + } + + if (shim_nrf_lpcomp_extrefsel_to_nrf(shim->extrefsel, &nrf->ext_ref)) { + return -EINVAL; + } + +#if NRF_LPCOMP_HAS_HYST + if (shim->enable_hyst) { + nrf->hyst = NRF_LPCOMP_HYST_ENABLED; + } else { + nrf->hyst = NRF_LPCOMP_HYST_NOHYST; + } +#else + if (shim->enable_hyst) { + return -EINVAL; + } +#endif + + if (shim_nrf_lpcomp_psel_to_nrf(shim->psel, &nrf->input)) { + return -EINVAL; + } + + return 0; +} + +static void shim_nrf_lpcomp_reconfigure(void) +{ + (void)nrfx_lpcomp_reconfigure(&shim_nrf_lpcomp_data0.config); +} + +static int shim_nrf_lpcomp_get_output(const struct device *dev) +{ + ARG_UNUSED(dev); + + return nrfx_lpcomp_sample(); +} + +static int shim_nrf_lpcomp_set_trigger(const struct device *dev, + enum comparator_trigger trigger) +{ + shim_nrf_lpcomp_stop(); + + switch (trigger) { + case COMPARATOR_TRIGGER_NONE: + shim_nrf_lpcomp_data0.event_mask = 0; + shim_nrf_lpcomp_data0.config.detection = NRF_LPCOMP_DETECT_CROSS; + break; + + case COMPARATOR_TRIGGER_RISING_EDGE: + shim_nrf_lpcomp_data0.event_mask = NRF_LPCOMP_INT_UP_MASK; + shim_nrf_lpcomp_data0.config.detection = NRF_LPCOMP_DETECT_UP; + break; + + case COMPARATOR_TRIGGER_FALLING_EDGE: + shim_nrf_lpcomp_data0.event_mask = NRF_LPCOMP_INT_DOWN_MASK; + shim_nrf_lpcomp_data0.config.detection = NRF_LPCOMP_DETECT_DOWN; + break; + + case COMPARATOR_TRIGGER_BOTH_EDGES: + shim_nrf_lpcomp_data0.event_mask = NRF_LPCOMP_INT_CROSS_MASK; + shim_nrf_lpcomp_data0.config.detection = NRF_LPCOMP_DETECT_CROSS; + break; + } + + shim_nrf_lpcomp_reconfigure(); + + if (shim_nrf_lpcomp_is_resumed()) { + shim_nrf_lpcomp_start(); + } + + return 0; +} + +static int shim_nrf_lpcomp_set_trigger_callback(const struct device *dev, + comparator_callback_t callback, + void *user_data) +{ + shim_nrf_lpcomp_stop(); + + shim_nrf_lpcomp_data0.callback = callback; + shim_nrf_lpcomp_data0.user_data = user_data; + + if (callback != NULL && atomic_test_and_clear_bit(&shim_nrf_lpcomp_data0.triggered, 0)) { + callback(dev, user_data); + } + + if (shim_nrf_lpcomp_is_resumed()) { + shim_nrf_lpcomp_start(); + } + + return 0; +} + +static int shim_nrf_lpcomp_trigger_is_pending(const struct device *dev) +{ + ARG_UNUSED(dev); + + return atomic_test_and_clear_bit(&shim_nrf_lpcomp_data0.triggered, 0); +} + +static const struct comparator_driver_api shim_nrf_lpcomp_api = { + .get_output = shim_nrf_lpcomp_get_output, + .set_trigger = shim_nrf_lpcomp_set_trigger, + .set_trigger_callback = shim_nrf_lpcomp_set_trigger_callback, + .trigger_is_pending = shim_nrf_lpcomp_trigger_is_pending, +}; + +int comp_nrf_lpcomp_configure(const struct device *dev, + const struct comp_nrf_lpcomp_config *config) +{ + nrfx_lpcomp_config_t nrf = {}; + + if (shim_nrf_lpcomp_config_to_nrf(config, &nrf)) { + return -EINVAL; + } + + memcpy(&shim_nrf_lpcomp_data0.config, &nrf, sizeof(shim_nrf_lpcomp_data0.config)); + + shim_nrf_lpcomp_stop(); + shim_nrf_lpcomp_reconfigure(); + if (shim_nrf_lpcomp_is_resumed()) { + shim_nrf_lpcomp_start(); + } + + return 0; +} + +static void shim_nrf_lpcomp_event_handler(nrf_lpcomp_event_t event) +{ + ARG_UNUSED(event); + + if (shim_nrf_lpcomp_data0.callback == NULL) { + atomic_set_bit(&shim_nrf_lpcomp_data0.triggered, 0); + return; + } + + shim_nrf_lpcomp_data0.callback(DEVICE_DT_INST_GET(0), shim_nrf_lpcomp_data0.user_data); + atomic_clear_bit(&shim_nrf_lpcomp_data0.triggered, 0); +} + +static int shim_nrf_lpcomp_init(const struct device *dev) +{ + IRQ_CONNECT(DT_INST_IRQN(0), + DT_INST_IRQ(0, priority), + nrfx_isr, + nrfx_lpcomp_irq_handler, + 0); + + irq_enable(DT_INST_IRQN(0)); + + (void)shim_nrf_lpcomp_config_to_nrf(&shim_nrf_lpcomp_config0, + &shim_nrf_lpcomp_data0.config); + + if (nrfx_lpcomp_init(&shim_nrf_lpcomp_data0.config, + shim_nrf_lpcomp_event_handler) != NRFX_SUCCESS) { + return -ENODEV; + } + + return pm_device_driver_init(dev, shim_nrf_lpcomp_pm_callback); +} + +PM_DEVICE_DT_INST_DEFINE(0, shim_nrf_lpcomp_pm_callback); + +DEVICE_DT_INST_DEFINE(0, + shim_nrf_lpcomp_init, + PM_DEVICE_DT_INST_GET(0), + NULL, + NULL, + POST_KERNEL, + CONFIG_COMPARATOR_INIT_PRIORITY, + &shim_nrf_lpcomp_api); diff --git a/dts/bindings/comparator/nordic,nrf-lpcomp.yaml b/dts/bindings/comparator/nordic,nrf-lpcomp.yaml new file mode 100644 index 00000000000..8f9cd91a6b7 --- /dev/null +++ b/dts/bindings/comparator/nordic,nrf-lpcomp.yaml @@ -0,0 +1,83 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic nRF LPCOMP (analog Low-Power COMParator) + + The following example displays the minimum node layout: + + comp: comp@deadbeef { + compatible = "nordic,nrf-lpcomp"; + reg = <0xdeadbeef 0x1000>; + interrupts = <0 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + Enabling the comparator node requires setting the default + configuration of the comparator. + + The following example displays enabling the comparator + using an internal reference: + + &comp { + status = "okay"; + psel = "AIN0"; + refsel = "VDD_4_8"; + hyst = "ENABLED"; + }; + + To select an external reference, select the "AREF" + reference and add the external reference: + + &comp { + ... + refsel = "AREF"; + extrefsel = "AIN1"; + ... + }; + +compatible: "nordic,nrf-lpcomp" + +include: base.yaml + +properties: + psel: + type: string + enum: + - "AIN0" + - "AIN1" + - "AIN2" + - "AIN3" + - "AIN4" + - "AIN5" + - "AIN6" + - "AIN7" + + extrefsel: + type: string + enum: + - "AIN0" + - "AIN1" + + refsel: + type: string + enum: + - "VDD_1_8" + - "VDD_2_8" + - "VDD_3_8" + - "VDD_4_8" + - "VDD_5_8" + - "VDD_6_8" + - "VDD_7_8" + - "VDD_1_16" + - "VDD_3_16" + - "VDD_5_16" + - "VDD_7_16" + - "VDD_9_16" + - "VDD_11_16" + - "VDD_13_16" + - "VDD_15_16" + - "AREF" + + enable-hyst: + type: boolean diff --git a/dts/bindings/sensor/nordic,nrf-lpcomp.yaml b/dts/bindings/sensor/nordic,nrf-lpcomp.yaml deleted file mode 100644 index 132b0980ac5..00000000000 --- a/dts/bindings/sensor/nordic,nrf-lpcomp.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2022, Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: Nordic nRF family LPCOMP (Low-power Comparator) - -compatible: "nordic,nrf-lpcomp" - -include: base.yaml - -properties: - reg: - required: true - - interrupts: - required: true - - "#io-channel-cells": - type: int - const: 1 - required: true - -io-channel-cells: - - input diff --git a/include/zephyr/drivers/comparator/nrf_lpcomp.h b/include/zephyr/drivers/comparator/nrf_lpcomp.h new file mode 100644 index 00000000000..e1f2343a8de --- /dev/null +++ b/include/zephyr/drivers/comparator/nrf_lpcomp.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_COMP_NRF_LPCOMP_H_ +#define ZEPHYR_INCLUDE_DRIVERS_COMP_NRF_LPCOMP_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Positive input selection */ +enum comp_nrf_lpcomp_psel { + /** AIN0 external input */ + COMP_NRF_LPCOMP_PSEL_AIN0, + /** AIN1 external input */ + COMP_NRF_LPCOMP_PSEL_AIN1, + /** AIN2 external input */ + COMP_NRF_LPCOMP_PSEL_AIN2, + /** AIN3 external input */ + COMP_NRF_LPCOMP_PSEL_AIN3, + /** AIN4 external input */ + COMP_NRF_LPCOMP_PSEL_AIN4, + /** AIN5 external input */ + COMP_NRF_LPCOMP_PSEL_AIN5, + /** AIN6 external input */ + COMP_NRF_LPCOMP_PSEL_AIN6, + /** AIN7 external input */ + COMP_NRF_LPCOMP_PSEL_AIN7, +}; + +/** External reference selection */ +enum comp_nrf_lpcomp_extrefsel { + /** AIN0 external input */ + COMP_NRF_LPCOMP_EXTREFSEL_AIN0, + /** AIN1 external input */ + COMP_NRF_LPCOMP_EXTREFSEL_AIN1, +}; + +/** Reference selection */ +enum comp_nrf_lpcomp_refsel { + /** Use (VDD * (1/8)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_1_8, + /** Use (VDD * (2/8)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_2_8, + /** Use (VDD * (3/8)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_3_8, + /** Use (VDD * (4/8)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_4_8, + /** Use (VDD * (5/8)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_5_8, + /** Use (VDD * (6/8)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_6_8, + /** Use (VDD * (7/8)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_7_8, + /** Use (VDD * (1/16)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_1_16, + /** Use (VDD * (3/16)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_3_16, + /** Use (VDD * (5/16)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_5_16, + /** Use (VDD * (7/16)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_7_16, + /** Use (VDD * (9/16)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_9_16, + /** Use (VDD * (11/16)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_11_16, + /** Use (VDD * (13/16)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_13_16, + /** Use (VDD * (15/16)) as reference */ + COMP_NRF_LPCOMP_REFSEL_VDD_15_16, + /** Use external analog reference */ + COMP_NRF_LPCOMP_REFSEL_AREF, +}; + +/** + * @brief Configuration structure + * + * @note extrefsel is only used if refsel == COMP_NRF_LPCOMP_REFSEL_AREF + */ +struct comp_nrf_lpcomp_config { + /** Positive input selection */ + enum comp_nrf_lpcomp_psel psel; + /** External reference selection */ + enum comp_nrf_lpcomp_extrefsel extrefsel; + /** Reference selection */ + enum comp_nrf_lpcomp_refsel refsel; + /** Hysteresis configuration */ + bool enable_hyst; +}; + +/** + * @brief Configure comparator + * + * @param dev Comparator device instance + * @param config Configuration + * + * @retval 0 if successful + * @retval negative errno-code otherwise + */ +int comp_nrf_lpcomp_configure(const struct device *dev, + const struct comp_nrf_lpcomp_config *config); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_COMP_NRF_LPCOMP_H_ */