Browse Source
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>pull/64956/head
7 changed files with 286 additions and 0 deletions
@ -0,0 +1,10 @@
@@ -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. |
@ -0,0 +1,169 @@
@@ -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); |
@ -0,0 +1,13 @@
@@ -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 |
@ -0,0 +1,91 @@
@@ -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 new issue