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 @@ |
|||||||
|
# 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 @@ |
|||||||
|
/*
|
||||||
|
* 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 @@ |
|||||||
|
# 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 @@ |
|||||||
|
/*
|
||||||
|
* 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