drivers: mfd: add AD5592 MFD driver
This commit introduces a driver for Analog AD5592 8-channel, configurable ADC/DAC/GPIO chip. Signed-off-by: Bartosz Bilas <b.bilas@grinn-global.com>
This commit is contained in:
parent
d2c101d466
commit
9bdff044f0
|
@ -373,6 +373,7 @@
|
|||
/drivers/led_strip/ @mbolivar-ampere
|
||||
/drivers/lora/ @Mani-Sadhasivam
|
||||
/drivers/mbox/ @carlocaione
|
||||
/drivers/mfd/mfd_ad5592.c @bbilas
|
||||
/drivers/mfd/mfd_max20335.c @bbilas
|
||||
/drivers/misc/ @tejlmand
|
||||
/drivers/misc/ft8xx/ @hubertmis
|
||||
|
|
|
@ -8,3 +8,4 @@ zephyr_library_sources_ifdef(CONFIG_MFD_NCT38XX mfd_nct38xx.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_MFD_NPM1300 mfd_npm1300.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MFD_NPM6001 mfd_npm6001.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MFD_AXP192 mfd_axp192.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MFD_AD5592 mfd_ad5592.c)
|
||||
|
|
|
@ -18,6 +18,7 @@ config MFD_INIT_PRIORITY
|
|||
help
|
||||
Multi-function devices initialization priority.
|
||||
|
||||
source "drivers/mfd/Kconfig.ad5592"
|
||||
source "drivers/mfd/Kconfig.axp192"
|
||||
source "drivers/mfd/Kconfig.max20335"
|
||||
source "drivers/mfd/Kconfig.nct38xx"
|
||||
|
|
10
drivers/mfd/Kconfig.ad5592
Normal file
10
drivers/mfd/Kconfig.ad5592
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2023 Grinn
|
||||
# SPDX -License-Identifier: Apache-2.0
|
||||
|
||||
config MFD_AD5592
|
||||
bool "Analog AD5592 SPI configurable ADC/DAC/GPIO chip"
|
||||
default y
|
||||
depends on DT_HAS_ADI_AD5592_ENABLED
|
||||
depends on SPI
|
||||
help
|
||||
Enable driver for Analog AD5592.
|
169
drivers/mfd/mfd_ad5592.c
Normal file
169
drivers/mfd/mfd_ad5592.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Grinn
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT adi_ad5592
|
||||
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
|
||||
#include <zephyr/drivers/mfd/ad5592.h>
|
||||
|
||||
#define AD5592_GPIO_READBACK_EN BIT(10)
|
||||
#define AD5592_LDAC_READBACK_EN BIT(6)
|
||||
#define AD5592_REG_SOFTWARE_RESET 0x0FU
|
||||
#define AD5592_SOFTWARE_RESET_MAGIC_VAL 0xDAC
|
||||
#define AD5592_REV_VAL_MASK 0x3FF
|
||||
#define AD5592_REG_SHIFT_VAL 11
|
||||
#define AD5592_REG_READBACK_SHIFT_VAL 2
|
||||
|
||||
#define AD5592_SPI_SPEC_CONF (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | \
|
||||
SPI_OP_MODE_MASTER | SPI_MODE_CPOL)
|
||||
|
||||
struct mfd_ad5592_config {
|
||||
struct gpio_dt_spec reset_gpio;
|
||||
struct spi_dt_spec bus;
|
||||
};
|
||||
|
||||
int mfd_ad5592_read_raw(const struct device *dev, uint16_t *val)
|
||||
{
|
||||
const struct mfd_ad5592_config *config = dev->config;
|
||||
uint16_t nop_msg = 0;
|
||||
|
||||
struct spi_buf tx_buf[] = {
|
||||
{
|
||||
.buf = &nop_msg,
|
||||
.len = sizeof(nop_msg)
|
||||
}
|
||||
};
|
||||
|
||||
const struct spi_buf_set tx = {
|
||||
.buffers = tx_buf,
|
||||
.count = 1
|
||||
};
|
||||
|
||||
struct spi_buf rx_buf[] = {
|
||||
{
|
||||
.buf = val,
|
||||
.len = sizeof(uint16_t)
|
||||
}
|
||||
};
|
||||
|
||||
const struct spi_buf_set rx = {
|
||||
.buffers = rx_buf,
|
||||
.count = 1
|
||||
};
|
||||
|
||||
return spi_transceive_dt(&config->bus, &tx, &rx);
|
||||
}
|
||||
|
||||
int mfd_ad5592_write_raw(const struct device *dev, uint16_t val)
|
||||
{
|
||||
const struct mfd_ad5592_config *config = dev->config;
|
||||
|
||||
struct spi_buf tx_buf[] = {
|
||||
{
|
||||
.buf = &val,
|
||||
.len = sizeof(val)
|
||||
}
|
||||
};
|
||||
|
||||
const struct spi_buf_set tx = {
|
||||
.buffers = tx_buf,
|
||||
.count = 1
|
||||
};
|
||||
|
||||
return spi_write_dt(&config->bus, &tx);
|
||||
}
|
||||
|
||||
int mfd_ad5592_read_reg(const struct device *dev, uint8_t reg, uint8_t reg_data, uint16_t *val)
|
||||
{
|
||||
uint16_t data;
|
||||
uint16_t msg;
|
||||
int ret;
|
||||
|
||||
switch (reg) {
|
||||
case AD5592_REG_GPIO_INPUT_EN:
|
||||
msg = sys_cpu_to_be16(AD5592_GPIO_READBACK_EN |
|
||||
(AD5592_REG_GPIO_INPUT_EN << AD5592_REG_SHIFT_VAL) |
|
||||
reg_data);
|
||||
break;
|
||||
default:
|
||||
msg = sys_cpu_to_be16(AD5592_LDAC_READBACK_EN |
|
||||
(AD5592_REG_READ_AND_LDAC << AD5592_REG_SHIFT_VAL) |
|
||||
reg << AD5592_REG_READBACK_SHIFT_VAL);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = mfd_ad5592_write_raw(dev, msg);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_ad5592_read_raw(dev, &data);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*val = sys_be16_to_cpu(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mfd_ad5592_write_reg(const struct device *dev, uint8_t reg, uint16_t val)
|
||||
{
|
||||
uint16_t msg = sys_cpu_to_be16((reg << AD5592_REG_SHIFT_VAL) | (val & AD5592_REV_VAL_MASK));
|
||||
|
||||
return mfd_ad5592_write_raw(dev, msg);
|
||||
}
|
||||
|
||||
static int mfd_add592_software_reset(const struct device *dev)
|
||||
{
|
||||
return mfd_ad5592_write_reg(dev,
|
||||
AD5592_REG_SOFTWARE_RESET,
|
||||
AD5592_SOFTWARE_RESET_MAGIC_VAL);
|
||||
}
|
||||
|
||||
static int mfd_ad5592_init(const struct device *dev)
|
||||
{
|
||||
const struct mfd_ad5592_config *config = dev->config;
|
||||
int ret;
|
||||
|
||||
if (!spi_is_ready_dt(&config->bus)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!gpio_is_ready_dt(&config->reset_gpio)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_INACTIVE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add592_software_reset(dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MFD_AD5592_DEFINE(inst) \
|
||||
static const struct mfd_ad5592_config mfd_ad5592_config_##inst = { \
|
||||
.reset_gpio = GPIO_DT_SPEC_INST_GET(inst, reset_gpios), \
|
||||
.bus = SPI_DT_SPEC_INST_GET(inst, AD5592_SPI_SPEC_CONF, 0), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, mfd_ad5592_init, NULL, \
|
||||
NULL, \
|
||||
&mfd_ad5592_config_##inst, \
|
||||
POST_KERNEL, \
|
||||
CONFIG_MFD_INIT_PRIORITY, \
|
||||
NULL);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(MFD_AD5592_DEFINE);
|
13
dts/bindings/mfd/adi,ad5592.yaml
Normal file
13
dts/bindings/mfd/adi,ad5592.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Copyright (C) 2023 Grinn
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Analog AD5592 ADC/DAC/GPIO chip
|
||||
|
||||
compatible: "adi,ad5592"
|
||||
|
||||
include: spi-device.yaml
|
||||
|
||||
properties:
|
||||
reset-gpios:
|
||||
type: phandle-array
|
||||
description: RESET pin
|
91
include/zephyr/drivers/mfd/ad5592.h
Normal file
91
include/zephyr/drivers/mfd/ad5592.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Grinn
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_MFD_AD5592_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_MFD_AD5592_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <zephyr/device.h>
|
||||
|
||||
#define AD5592_REG_SEQ_ADC 0x02U
|
||||
#define AD5592_REG_ADC_CONFIG 0x04U
|
||||
#define AD5592_REG_LDAC_EN 0x05U
|
||||
#define AD5592_REG_GPIO_PULLDOWN 0x06U
|
||||
#define AD5592_REG_READ_AND_LDAC 0x07U
|
||||
#define AD5592_REG_GPIO_OUTPUT_EN 0x08U
|
||||
#define AD5592_REG_GPIO_SET 0x09U
|
||||
#define AD5592_REG_GPIO_INPUT_EN 0x0AU
|
||||
#define AD5592_REG_PD_REF_CTRL 0x0BU
|
||||
|
||||
#define AD5592_EN_REF BIT(9)
|
||||
|
||||
#define AD5592_PIN_MAX 8U
|
||||
|
||||
/**
|
||||
* @defgroup mdf_interface_ad5592 MFD AD5592 interface
|
||||
* @ingroup mfd_interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Read raw data from the chip
|
||||
*
|
||||
* @param[in] dev Pointer to MFD device
|
||||
* @param[in] val Pointer to data buffer
|
||||
*
|
||||
* @retval 0 if success
|
||||
* @retval negative errno if failure
|
||||
*/
|
||||
int mfd_ad5592_read_raw(const struct device *dev, uint16_t *val);
|
||||
|
||||
/**
|
||||
* @brief Write raw data to chip
|
||||
*
|
||||
* @param[in] dev Pointer to MFD device
|
||||
* @param[in] val Data to be written
|
||||
*
|
||||
*
|
||||
* @retval 0 if success
|
||||
* @retval negative errno if failure
|
||||
*/
|
||||
int mfd_ad5592_write_raw(const struct device *dev, uint16_t val);
|
||||
|
||||
/**
|
||||
* @brief Read data from provided register
|
||||
*
|
||||
* @param[in] dev Pointer to MFD device
|
||||
* @param[in] reg Register to be read
|
||||
* @param[in] reg_data Additional data passed to selected register
|
||||
* @param[in] val Pointer to data buffer
|
||||
*
|
||||
* @retval 0 if success
|
||||
* @retval negative errno if failure
|
||||
*/
|
||||
int mfd_ad5592_read_reg(const struct device *dev, uint8_t reg, uint8_t reg_data, uint16_t *val);
|
||||
|
||||
/**
|
||||
* @brief Write data to provided register
|
||||
*
|
||||
* @param[in] dev Pointer to MFD device
|
||||
* @param[in] reg Register to be written
|
||||
* @param[in] val Data to be written
|
||||
*
|
||||
* @retval 0 if success
|
||||
* @retval negative errno if failure
|
||||
*/
|
||||
int mfd_ad5592_write_reg(const struct device *dev, uint8_t reg, uint16_t val);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_MFD_AD5952_H_ */
|
Loading…
Reference in a new issue