diff --git a/drivers/mfd/CMakeLists.txt b/drivers/mfd/CMakeLists.txt index 8fe7ac34cae..5a7f5faee90 100644 --- a/drivers/mfd/CMakeLists.txt +++ b/drivers/mfd/CMakeLists.txt @@ -21,3 +21,4 @@ zephyr_library_sources_ifdef(CONFIG_MFD_ITE_IT8801 mfd_ite_it8801.c) zephyr_library_sources_ifdef(CONFIG_MFD_ITE_IT8801_ALTCTRL mfd_it8801_altctrl.c) zephyr_library_sources_ifdef(CONFIG_MFD_AW9523B mfd_aw9523b.c) zephyr_library_sources_ifdef(CONFIG_MFD_DS3231 mfd_ds3231.c) +zephyr_library_sources_ifdef(CONFIG_MFD_MAX22017 mfd_max22017.c) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b11e3dfd4b2..0ccb41f6ba1 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -25,6 +25,7 @@ source "drivers/mfd/Kconfig.aw9523b" source "drivers/mfd/Kconfig.bd8lb600fs" source "drivers/mfd/Kconfig.ds3231" source "drivers/mfd/Kconfig.max20335" +source "drivers/mfd/Kconfig.max22017" source "drivers/mfd/Kconfig.max31790" source "drivers/mfd/Kconfig.nct38xx" source "drivers/mfd/Kconfig.npm1300" diff --git a/drivers/mfd/Kconfig.max22017 b/drivers/mfd/Kconfig.max22017 new file mode 100644 index 00000000000..8a28f19614e --- /dev/null +++ b/drivers/mfd/Kconfig.max22017 @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +config MFD_MAX22017 + bool "Analog Devices MAX22017 DAC/GPIO chip" + default y + depends on SPI + select CRC + depends on DT_HAS_ADI_MAX22017_ENABLED + help + Enable the driver for the Analog Devices MAX22017 DAC/GPIO chip diff --git a/drivers/mfd/mfd_max22017.c b/drivers/mfd/mfd_max22017.c new file mode 100644 index 00000000000..a4b7d6fa155 --- /dev/null +++ b/drivers/mfd/mfd_max22017.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2024 Analog Devices Inc. + * Copyright (c) 2024 Baylibre SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_max22017 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(mfd_max22017, CONFIG_MFD_LOG_LEVEL); + +#include + +struct max22017_config { + struct spi_dt_spec spi; + const struct gpio_dt_spec gpio_reset; + const struct gpio_dt_spec gpio_int; + bool crc_mode; +}; + +int max22017_reg_read(const struct device *dev, uint8_t addr, uint16_t *value) +{ + int ret; + const struct max22017_config *config = dev->config; + const struct max22017_data *data = dev->data; + uint8_t rxbuffer[4] = {0}; + size_t recv_len = 3; + + *value = 0; + addr = FIELD_PREP(MAX22017_SPI_TRANS_ADDR, addr) | FIELD_PREP(MAX22017_SPI_TRANS_DIR, 1); + + if (data->crc_enabled) { + recv_len += 1; + } + + const struct spi_buf txb[] = { + { + .buf = &addr, + .len = 1, + }, + }; + const struct spi_buf rxb[] = { + { + .buf = rxbuffer, + .len = recv_len, + }, + }; + + struct spi_buf_set tx = { + .buffers = txb, + .count = ARRAY_SIZE(txb), + }; + + struct spi_buf_set rx = { + .buffers = rxb, + .count = ARRAY_SIZE(rxb), + }; + + ret = spi_transceive_dt(&config->spi, &tx, &rx); + + if (ret) { + return ret; + } + + if (!data->crc_enabled) { + goto out_skip_crc; + } + + uint8_t crc_in[] = {addr, rxbuffer[1], rxbuffer[2]}; + + ret = crc8(crc_in, 3, MAX22017_CRC_POLY, 0, true); + + if (ret != rxbuffer[3]) { + LOG_ERR("Reg read: CRC Mismatch calculated / read: %x / %x", ret, rxbuffer[3]); + return -EINVAL; + } + +out_skip_crc: + *value = rxbuffer[1] | rxbuffer[2] << 8; + *value = sys_be16_to_cpu(*value); + + return 0; +} + +int max22017_reg_write(const struct device *dev, uint8_t addr, uint16_t value) +{ + uint8_t crc; + size_t crc_len = 0; + const struct max22017_config *config = dev->config; + const struct max22017_data *data = dev->data; + + addr = FIELD_PREP(MAX22017_SPI_TRANS_ADDR, addr) | FIELD_PREP(MAX22017_SPI_TRANS_DIR, 0); + value = sys_cpu_to_be16(value); + + if (data->crc_enabled) { + uint8_t crc_in[] = {addr, ((uint8_t *)&value)[0], ((uint8_t *)&value)[1]}; + + crc_len = 1; + crc = crc8(crc_in, 3, MAX22017_CRC_POLY, 0, true); + } + + const struct spi_buf buf[] = { + { + .buf = &addr, + .len = 1, + }, + { + .buf = &value, + .len = 2, + }, + { + .buf = &crc, + .len = crc_len, + }, + }; + + struct spi_buf_set tx = { + .buffers = buf, + .count = ARRAY_SIZE(buf), + }; + + return spi_write_dt(&config->spi, &tx); +} + +static int max22017_reset(const struct device *dev) +{ + int ret = 0; + uint16_t ao_sta; + const struct max22017_config *config = dev->config; + + if (config->gpio_reset.port != NULL) { + ret = gpio_pin_set_dt(&config->gpio_reset, 0); + if (ret) { + return ret; + } + k_sleep(K_MSEC(100)); + ret = gpio_pin_set_dt(&config->gpio_reset, 1); + k_sleep(K_MSEC(500)); + } else { + ret = max22017_reg_write(dev, MAX22017_GEN_RST_CTRL_OFF, + FIELD_PREP(MAX22017_GEN_RST_CTRL_GEN_RST, 1)); + if (ret) { + return ret; + } + k_sleep(K_MSEC(100)); + ret = max22017_reg_write(dev, MAX22017_GEN_RST_CTRL_OFF, + FIELD_PREP(MAX22017_GEN_RST_CTRL_GEN_RST, 0)); + if (ret) { + return ret; + } + k_sleep(K_MSEC(500)); + ret = max22017_reg_read(dev, MAX22017_AO_STA_OFF, &ao_sta); + if (ret) { + return ret; + } + if (FIELD_GET(MAX22017_AO_STA_BUSY_STA, ao_sta)) { + ret = -EBUSY; + } + } + return ret; +} + +static void max22017_isr(const struct device *dev, struct gpio_callback *gpio_cb, uint32_t pins) +{ + struct max22017_data *data = CONTAINER_OF(gpio_cb, struct max22017_data, callback_int); + int ret; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = k_work_submit(&data->int_work); + if (ret < 0) { + LOG_WRN("Could not submit int work: %d", ret); + } + + k_mutex_unlock(&data->lock); +} + +static void max22017_int_worker(struct k_work *work) +{ + struct max22017_data *data = CONTAINER_OF(work, struct max22017_data, int_work); + const struct device *dev = data->dev; + int ret; + uint16_t gen_int; + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_read(dev, MAX22017_GEN_INT_OFF, &gen_int); + if (ret) { + LOG_ERR("Unable to read GEN_INT register"); + goto fail; + } + + if (FIELD_GET(MAX22017_GEN_INT_FAIL_INT, gen_int)) { + LOG_ERR("Boot failure"); + } + + ret = FIELD_GET(MAX22017_GEN_INT_CONV_OVF_INT, gen_int); + if (ret) { + LOG_ERR("Conversion failure on channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + ret = FIELD_GET(MAX22017_GEN_INT_OPENWIRE_DTCT_INT, gen_int); + if (ret) { + LOG_ERR("Openwire detected on channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + if (FIELD_GET(MAX22017_GEN_INT_HVDD_INT, gen_int)) { + LOG_ERR("HVDD/HVSS voltage difference below 1.5V"); + } + + if (FIELD_GET(MAX22017_GEN_INT_TMOUT_INT, gen_int)) { + LOG_ERR("SPI transaction timeout"); + } + + ret = FIELD_GET(MAX22017_GEN_INT_THSHDN_INT, gen_int); + if (ret) { + LOG_ERR("Thermal shutdown AO channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + ret = FIELD_GET(MAX22017_GEN_INT_THWRNG_INT, gen_int); + if (ret) { + LOG_ERR("Thermal warning AO channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + ret = FIELD_GET(MAX22017_GEN_INT_OVC_INT, gen_int); + if (ret) { + LOG_ERR("Over current on channels: %s %s", (ret & BIT(0)) ? "0" : "", + (ret & BIT(1)) ? "1" : ""); + } + + if (FIELD_GET(MAX22017_GEN_INT_CRC_INT, gen_int)) { + LOG_ERR("CRC Error"); + } + + ret = FIELD_GET(MAX22017_GEN_INT_GPI_INT, gen_int); + if (ret) { + LOG_INF("GPI Interrupt: %d", ret); +#ifdef CONFIG_GPIO_MAX22017 + uint16_t gpi_sta, lsb; + + ret = max22017_reg_read(dev, MAX22017_GEN_GPI_INT_STA_OFF, &gpi_sta); + if (ret) { + goto fail; + } + + /* Aggregate both positive and negative edge together */ + gpi_sta = FIELD_GET(MAX22017_GEN_GPI_INT_GPI_NEG_EDGE_INT, gpi_sta) | + FIELD_GET(MAX22017_GEN_GPI_INT_GPI_POS_EDGE_INT, gpi_sta); + while (gpi_sta) { + lsb = LSB_GET(gpi_sta); + gpio_fire_callbacks(&data->callbacks_gpi, dev, lsb); + gpi_sta &= ~lsb; + } +#endif + } +fail: + k_mutex_unlock(&data->lock); +} + +static int max22017_init(const struct device *dev) +{ + const struct max22017_config *config = dev->config; + struct max22017_data *data = dev->data; + uint16_t version; + int ret; + uint16_t gen_cnfg = 0, gen_int_en = 0; + + if (!spi_is_ready_dt(&config->spi)) { + LOG_ERR("SPI spi %s not ready", config->spi.bus->name); + return -ENODEV; + } + + if (config->gpio_reset.port != NULL) { + ret = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE); + if (ret) { + LOG_ERR("failed to initialize GPIO reset pin"); + return ret; + } + } + + ret = max22017_reset(dev); + if (ret) { + LOG_ERR("failed to reset MAX22017"); + return ret; + } + + data->dev = dev; + k_work_init(&data->int_work, max22017_int_worker); + k_mutex_init(&data->lock); + + if (config->gpio_int.port) { + ret = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT); + if (ret) { + LOG_ERR("failed to initialize GPIO interrupt pin"); + goto fail; + } + + ret = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + if (ret) { + LOG_ERR("failed to configure interrupt pin"); + goto fail; + } + + gpio_init_callback(&data->callback_int, max22017_isr, BIT(config->gpio_int.pin)); + ret = gpio_add_callback(config->gpio_int.port, &data->callback_int); + if (ret) { + LOG_ERR("failed to add data ready callback"); + goto fail; + } + } + + k_mutex_lock(&data->lock, K_FOREVER); + + ret = max22017_reg_write(dev, MAX22017_AO_CNFG_OFF, 0); + if (ret) { + return ret; + } + + ret = max22017_reg_write(dev, MAX22017_AO_DATA_CHn_OFF(0), 0); + if (ret) { + goto fail; + } + + ret = max22017_reg_write(dev, MAX22017_AO_DATA_CHn_OFF(1), 0); + if (ret) { + goto fail; + } + + if (config->crc_mode) { + gen_cnfg |= FIELD_PREP(MAX22017_GEN_CNFG_CRC_EN, 1); + gen_int_en |= FIELD_PREP(MAX22017_GEN_INTEN_CRC_INTEN, 1); + } + + ret = max22017_reg_write(dev, MAX22017_GEN_INTEN_OFF, gen_int_en); + if (ret) { + goto fail; + } + + ret = max22017_reg_write(dev, MAX22017_GEN_CNFG_OFF, gen_cnfg); + if (ret) { + goto fail; + } + + if (config->crc_mode) { + data->crc_enabled = true; + } + + ret = max22017_reg_read(dev, MAX22017_GEN_ID_OFF, &version); + if (ret) { + LOG_ERR("Unable to read MAX22017 version over SPI: %d", ret); + goto fail; + } + + LOG_INF("MAX22017 version: 0x%lx 0x%lx", FIELD_GET(MAX22017_GEN_ID_PROD_ID, version), + FIELD_GET(MAX22017_GEN_ID_REV_ID, version)); + +fail: + k_mutex_unlock(&data->lock); + return ret; +} + +#define INST_DT_MAX22017(index) \ + static const struct max22017_config max22017_config_##index = { \ + .spi = SPI_DT_SPEC_INST_GET(index, SPI_OP_MODE_MASTER | SPI_WORD_SET(8U), 0U), \ + .gpio_int = GPIO_DT_SPEC_INST_GET_OR(index, int_gpios, {0}), \ + .gpio_reset = GPIO_DT_SPEC_INST_GET_OR(index, rst_gpios, {0}), \ + .crc_mode = DT_INST_PROP_OR(index, crc_mode, 0), \ + }; \ + \ + static struct max22017_data max22017_data_##index; \ + \ + DEVICE_DT_INST_DEFINE(index, max22017_init, NULL, &max22017_data_##index, \ + &max22017_config_##index, POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, \ + NULL); + +DT_INST_FOREACH_STATUS_OKAY(INST_DT_MAX22017); diff --git a/dts/bindings/mfd/adi,max22017.yaml b/dts/bindings/mfd/adi,max22017.yaml new file mode 100644 index 00000000000..06bf2d8a639 --- /dev/null +++ b/dts/bindings/mfd/adi,max22017.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Analog Devices Inc. +# Copyright (c) 2024 BayLibre SAS +# SPDX-License-Identifier: Apache-2.0 + +include: spi-device.yaml + +description: Analog MAX22017 DAC/GPIO chip common properties + +properties: + rst-gpios: + description: Reset pin for max22017. + type: phandle-array + + crc-mode: + description: Enables CRC over SPI. + type: boolean + + int-gpios: + description: Interrupt gpio + type: phandle-array + +compatible: "adi,max22017" diff --git a/include/zephyr/drivers/mfd/max22017.h b/include/zephyr/drivers/mfd/max22017.h new file mode 100644 index 00000000000..a8f837020ab --- /dev/null +++ b/include/zephyr/drivers/mfd/max22017.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2024 Analog Devices Inc. + * Copyright (c) 2024 Baylibre SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_MFD_MAX22017_H_ +#define ZEPHYR_INCLUDE_DRIVERS_MFD_MAX22017_H_ + +#include + +#define MAX22017_LDAC_TOGGLE_TIME 200 +#define MAX22017_MAX_CHANNEL 2 +#define MAX22017_CRC_POLY 0x8c /* reversed 0x31 poly for crc8-maxim */ + +#define MAX22017_GEN_ID_OFF 0x00 +#define MAX22017_GEN_ID_PROD_ID GENMASK(15, 8) +#define MAX22017_GEN_ID_REV_ID GENMASK(7, 0) + +#define MAX22017_GEN_SERIAL_MSB_OFF 0x01 +#define MAX22017_GEN_SERIAL_MSB_SERIAL_MSB GENMASK(15, 0) + +#define MAX22017_GEN_SERIAL_LSB_OFF 0x02 +#define MAX22017_GEN_SERIAL_LSB_SERIAL_LSB GENMASK(15, 0) + +#define MAX22017_GEN_CNFG_OFF 0x03 +#define MAX22017_GEN_CNFG_OPENWIRE_DTCT_CNFG GENMASK(15, 14) +#define MAX22017_GEN_CNFG_TMOUT_SEL GENMASK(13, 10) +#define MAX22017_GEN_CNFG_TMOUT_CNFG BIT(9) +#define MAX22017_GEN_CNFG_TMOUT_EN BIT(8) +#define MAX22017_GEN_CNFG_THSHDN_CNFG GENMASK(7, 6) +#define MAX22017_GEN_CNFG_OVC_SHDN_CNFG GENMASK(5, 4) +#define MAX22017_GEN_CNFG_OVC_CNFG GENMASK(3, 2) +#define MAX22017_GEN_CNFG_CRC_EN BIT(1) +#define MAX22017_GEN_CNFG_DACREF_SEL BIT(0) + +#define MAX22017_GEN_GPIO_CTRL_OFF 0x04 +#define MAX22017_GEN_GPIO_CTRL_GPIO_EN GENMASK(13, 8) +#define MAX22017_GEN_GPIO_CTRL_GPIO_DIR GENMASK(5, 0) + +#define MAX22017_GEN_GPIO_DATA_OFF 0x05 +#define MAX22017_GEN_GPIO_DATA_GPO_DATA GENMASK(13, 8) +#define MAX22017_GEN_GPIO_DATA_GPI_DATA GENMASK(5, 0) + +#define MAX22017_GEN_GPI_INT_OFF 0x06 +#define MAX22017_GEN_GPI_INT_GPI_POS_EDGE_INT GENMASK(13, 8) +#define MAX22017_GEN_GPI_INT_GPI_NEG_EDGE_INT GENMASK(5, 0) + +#define MAX22017_GEN_GPI_INT_STA_OFF 0x07 +#define MAX22017_GEN_GPI_INT_STA_GPI_POS_EDGE_INT_STA GENMASK(13, 8) +#define MAX22017_GEN_GPI_INT_STA_GPI_NEG_EDGE_INT_STA GENMASK(5, 0) + +#define MAX22017_GEN_INT_OFF 0x08 +#define MAX22017_GEN_INT_FAIL_INT BIT(15) +#define MAX22017_GEN_INT_CONV_OVF_INT GENMASK(13, 12) +#define MAX22017_GEN_INT_OPENWIRE_DTCT_INT GENMASK(11, 10) +#define MAX22017_GEN_INT_HVDD_INT BIT(9) +#define MAX22017_GEN_INT_TMOUT_INT BIT(8) +#define MAX22017_GEN_INT_THSHDN_INT GENMASK(7, 6) +#define MAX22017_GEN_INT_THWRNG_INT GENMASK(5, 4) +#define MAX22017_GEN_INT_OVC_INT GENMASK(3, 2) +#define MAX22017_GEN_INT_CRC_INT BIT(1) +#define MAX22017_GEN_INT_GPI_INT BIT(0) + +#define MAX22017_GEN_INTEN_OFF 0x09 +#define MAX22017_GEN_INTEN_CONV_OVF_INTEN GENMASK(13, 12) +#define MAX22017_GEN_INTEN_OPENWIRE_DTCT_INTEN GENMASK(11, 10) +#define MAX22017_GEN_INTEN_HVDD_INTEN BIT(9) +#define MAX22017_GEN_INTEN_TMOUT_INTEN BIT(8) +#define MAX22017_GEN_INTEN_THSHDN_INTEN GENMASK(7, 6) +#define MAX22017_GEN_INTEN_THWRNG_INTEN GENMASK(5, 4) +#define MAX22017_GEN_INTEN_OVC_INTEN GENMASK(3, 2) +#define MAX22017_GEN_INTEN_CRC_INTEN BIT(1) +#define MAX22017_GEN_INTEN_GPI_INTEN BIT(0) + +#define MAX22017_GEN_RST_CTRL_OFF 0x0A +#define MAX22017_GEN_RST_CTRL_AO_COEFF_RELOAD GENMASK(15, 14) +#define MAX22017_GEN_RST_CTRL_GEN_RST BIT(9) + +#define MAX22017_AO_CMD_OFF 0x40 +#define MAX22017_AO_CMD_AO_LD_CTRL GENMASK(15, 14) + +#define MAX22017_AO_STA_OFF 0x41 +#define MAX22017_AO_STA_BUSY_STA GENMASK(15, 14) +#define MAX22017_AO_STA_SLEW_STA GENMASK(13, 12) +#define MAX22017_AO_STA_FAIL_STA BIT(0) + +#define MAX22017_AO_CNFG_OFF 0x42 +#define MAX22017_AO_CNFG_AO_LD_CNFG GENMASK(15, 14) +#define MAX22017_AO_CNFG_AO_CM_SENSE GENMASK(13, 12) +#define MAX22017_AO_CNFG_AO_UNI GENMASK(11, 10) +#define MAX22017_AO_CNFG_AO_MODE GENMASK(9, 8) +#define MAX22017_AO_CNFG_AO_OPENWIRE_DTCT_LMT GENMASK(5, 4) +#define MAX22017_AO_CNFG_AI_EN GENMASK(3, 2) +#define MAX22017_AO_CNFG_AO_EN GENMASK(1, 0) + +#define MAX22017_AO_SLEW_RATE_CHn_OFF(n) (0x43 + n) +#define MAX22017_AO_SLEW_RATE_CHn_AO_SR_EN_CHn BIT(5) +#define MAX22017_AO_SLEW_RATE_CHn_AO_SR_SEL_CHn BIT(4) +#define MAX22017_AO_SLEW_RATE_CHn_AO_SR_STEP_SIZE_CHn GENMASK(3, 2) +#define MAX22017_AO_SLEW_RATE_CHn_AO_SR_UPDATE_RATE_CHn GENMASK(1, 0) + +#define MAX22017_AO_DATA_CHn_OFF(n) (0x45 + n) +#define MAX22017_AO_DATA_CHn_AO_DATA_CH GENMASK(15, 0) + +#define MAX22017_AO_OFFSET_CORR_CHn_OFF(n) (0x47 + (2 * n)) +#define MAX22017_AO_OFFSET_CORR_CHn_AO_OFFSET_CH GENMASK(15, 0) + +#define MAX22017_AO_GAIN_CORR_CHn_OFF(n) (0x48 + (2 * n)) +#define MAX22017_AO_GAIN_CORR_CHn_AO_GAIN_CH GENMASK(15, 0) + +#define MAX22017_SPI_TRANS_ADDR GENMASK(7, 1) +#define MAX22017_SPI_TRANS_DIR BIT(0) +#define MAX22017_SPI_TRANS_PAYLOAD GENMASK(15, 0) + +/** + * @defgroup mdf_interface_max22017 MFD MAX22017 interface + * @ingroup mfd_interfaces + * @{ + */ + +/** + * @brief Read register from max22017 + * + * @param dev max22017 mfd device + * @param addr register address to read from + * @param value pointer to buffer for received data + * @retval 0 If successful + * @retval -errno In case of any error (see spi_transceive_dt()) + */ +int max22017_reg_read(const struct device *dev, uint8_t addr, uint16_t *value); + +/** + * @brief Write register to max22017 + * + * @param dev max22017 mfd device + * @param addr register address to write to + * @param value content to write + * @retval 0 If successful + * @retval -errno In case of any error (see spi_write_dt()) + */ +int max22017_reg_write(const struct device *dev, uint8_t addr, uint16_t value); + +/** + * @} + */ + +struct max22017_data { + const struct device *dev; + struct k_mutex lock; + struct k_work int_work; + struct gpio_callback callback_int; + bool crc_enabled; +#ifdef CONFIG_GPIO_MAX22017 + sys_slist_t callbacks_gpi; +#endif +}; + +#endif /* ZEPHYR_INCLUDE_DRIVERS_MFD_MAX22017_H_ */