From 6eb93c2fb0efff7e297e0980b53c87847c4dcb8d Mon Sep 17 00:00:00 2001 From: Aldrin Abacan Date: Fri, 17 Jan 2025 16:02:20 +0800 Subject: [PATCH] drivers: power: ltc7871: Add driver support for LTC7871 Add initial header and source files for LTC7871 driver. Signed-off-by: Aldrin Abacan --- drivers/power/ltc7871/ltc7871.c | 756 ++++++++++++++++++++++++++++++++ drivers/power/ltc7871/ltc7871.h | 318 ++++++++++++++ 2 files changed, 1074 insertions(+) create mode 100644 drivers/power/ltc7871/ltc7871.c create mode 100644 drivers/power/ltc7871/ltc7871.h diff --git a/drivers/power/ltc7871/ltc7871.c b/drivers/power/ltc7871/ltc7871.c new file mode 100644 index 00000000000..0681427e4da --- /dev/null +++ b/drivers/power/ltc7871/ltc7871.c @@ -0,0 +1,756 @@ +/***************************************************************************//** + * @file ltc7871.c + * @brief Source file for the LTC7871 Driver + * @author Aldrin Abacan (aldrin.abacan@analog.com) +******************************************************************************** + * Copyright 2024(c) Analog Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#include +#include +#include +#include "no_os_alloc.h" +#include "no_os_delay.h" +#include "no_os_error.h" +#include "no_os_print_log.h" +#include "ltc7871.h" + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Compute the PEC. + * @param data - Data buffer. + * @param len - Buffer length. + * @return 8-bit CRC value + */ +uint8_t ltc7871_get_pec_byte(uint8_t *data, uint8_t len) +{ + uint8_t pec = 0x41; // Initial PEC value + + for (int8_t idx = 0 ; idx < len; idx++) { + uint8_t byte = data[idx]; + + for (int bit = 7; bit >= 0; bit--) { + uint8_t din = (byte >> bit) & 0x01; + uint8_t in0 = din ^ ((pec >> 7) & 0x01); + uint8_t in1 = ((pec >> 0) & 0x01) ^ in0; + uint8_t in2 = ((pec >> 1) & 0x01) ^ in0; + + pec = (pec << 1) & 0xF8; // Shift left and clear LSB + if (in2) pec |= 0x04; // Set bit 2 + if (in1) pec |= 0x02; // Set bit 1 + if (in0) pec |= 0x01; // Set bit 0 + } + } + + return pec; +} +/** + * @brief Register Read + * @param dev - The device structure + * @param reg - The register value + * @param data - The data read from the device. + * @return 0 in case of success, negative code otherwise + */ +int ltc7871_reg_read(struct ltc7871_dev *dev, uint8_t reg, uint8_t *data) +{ + int ret; + uint8_t r_buf[3] = {0}; + uint8_t r_buf_check[2] = {0}; + + if (!dev || !data) + return -EINVAL; + + r_buf[0] = r_buf_check[0] = reg << 1 | LTC7871_SPI_READ; + + ret = no_os_spi_write_and_read(dev->spi, r_buf, 3); + if (ret) + return ret; + + r_buf_check[1] = r_buf[1]; + uint8_t pec = ltc7871_get_pec_byte(r_buf_check, 2); + + if (r_buf[2] != pec) + return -EBADMSG; + + *data = r_buf[1]; + return 0; +} + +/** + * @brief Register Write + * @param dev - The device structure + * @param reg - The register value + * @param data - The data written to the device + * @return 0 in case of success, negative code otherwise + */ +int ltc7871_reg_write(struct ltc7871_dev *dev, uint8_t reg, uint8_t data) +{ + uint8_t w_buf[3] = {0}; + + if (!dev) + return -EINVAL; + + w_buf[0] = reg << 1 | LTC7871_SPI_WRITE; + w_buf[1] = data; + w_buf[2] = ltc7871_get_pec_byte(w_buf, 2); + + return no_os_spi_write_and_read(dev->spi, w_buf, 3); + +} + +/** + * @brief Write to LTC7871 device register with mask. + * @param dev - LTC7871 device descriptor + * @param address - Register address. + * @param mask - Mask to be applied. + * @param data - Data to be written. + * @return 0 in case of succes, negative error code otherwise +*/ +int ltc7871_reg_write_mask(struct ltc7871_dev *dev, uint8_t address, + uint8_t mask, uint8_t data) +{ + int ret; + uint8_t reg_data; + + if (!dev) + return -EINVAL; + + ret = ltc7871_reg_read(dev, address, ®_data); + if (ret) + return ret; + + reg_data &= ~mask; + reg_data |= no_os_field_prep(mask, data); + + return ltc7871_reg_write(dev, address, reg_data); +} + +/** + * @brief gets mfr fault bit. + * @param dev - LTC7871 device descriptor + * @param status - m askfault status to get. + * @param value - status value to be returned. + * @return 0 in case of succes, negative error code otherwise +*/ +int ltc7871_get_mfr_fault(struct ltc7871_dev *dev, uint8_t status, bool *value) +{ + int ret; + uint8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_MFR_FAULT, &data); + if (ret) + return ret; + + *value = no_os_field_get(status, data); + + return 0; +} + +/** + * @brief gets status for overcurrent condition status. + * @param dev - LTC7871 device descriptor + * @param status - mask fault status to get. (0-5) + * @param value - status value to be returned. + * @return 0 in case of succes, negative error code otherwise +*/ +int ltc7871_get_mfr_oc_fault(struct ltc7871_dev *dev, uint8_t status, + bool *value) +{ + int ret; + uint8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_MFR_OC_FAULT, &data); + if (ret) + return ret; + + *value = no_os_field_get(status, data); + + return 0; +} + +/** + * @brief gets status for negative overcurrent fault condition status. + * @param dev - LTC7871 device descriptor + * @param status - mask fault status to get. (0-5) + * @param value - status value to be returned. + * @return 0 in case of succes, negative error code otherwise +*/ +int ltc7871_get_mfr_noc_fault(struct ltc7871_dev *dev, uint8_t status, + bool *value) +{ + int ret; + uint8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_MFR_NOC_FAULT, &data); + if (ret) + return ret; + + *value = no_os_field_get(status, data); + + return 0; +} + +/** + * @brief gets configuration of the controller programmed by the pins. + * @param dev - LTC7871 device descriptor + * @param config - configuration to get. + * @param value - status value to be returned. + * @return 0 in case of succes, negative error code otherwise +*/ +int ltc7871_get_mfr_config1_setting(struct ltc7871_dev *dev, uint8_t config, + uint8_t *value) +{ + int ret; + uint8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_MFR_CONFIG1, &data); + if (ret) + return ret; + + *value = no_os_field_get(config, data); + + return 0; +} + +/** + * @brief gets configuration of the controller programmed by the pins. + * @param dev - LTC7871 device descriptor + * @param config - configuration to get. + * @param value - status value to be returned. + * @return 0 in case of succes, negative error code otherwise +*/ +int ltc7871_get_mfr_config2_setting(struct ltc7871_dev *dev, uint8_t config, + uint8_t *value) +{ + int ret; + uint8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_MFR_CONFIG2, &data); + if (ret) + return ret; + + *value = no_os_field_get(config, data); + + return 0; +} + +/** + * @brief gets status. + * @param dev - LTC7871 device descriptor + * @param status_mask - status mask to be acquire. + * @param status - status value. + * @return 0 in case of succes, negative error code otherwise +*/ +int ltc7871_get_mfr_status(struct ltc7871_dev *dev, uint8_t status_mask, + bool *status) +{ + int ret; + uint8_t data; + + if (!dev || !status) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_MFR_STATUS, &data); + if (ret) + return ret; + + *status = no_os_field_get(status_mask, data); + + return 0; +} + +/** + * @brief Reset all R/W registers. + * @param dev - LTC7871 device descriptor + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_reset(struct ltc7871_dev *dev) +{ + int ret; + + if (!dev) + return -EINVAL; + + ret = ltc7871_reg_write_mask(dev, LTC7871_CHIP_CTRL, + LTC7871_RESET_MASK, SET); + if (ret) + return ret; + + return 0; +} + +/** + * @brief Clear PEC fault bit. + * @param dev - LTC7871 device descriptor + * @return 0 in case of success, negative error code otherwise + */ +int ltc7871_clear_pec_fault(struct ltc7871_dev *dev) +{ + int ret; + + if (!dev) + return -EINVAL; + + ret = ltc7871_reg_write_mask(dev, LTC7871_CHIP_CTRL, + LTC7871_CML_MASK, SET); + if (ret) + return ret; + + return 0; +} + +/** + * @brief Read PEC fault bit. + * @param dev - LTC7871 device descriptor + * @param value - fault bit value. + * @return 0 in case of success, negative error code otherwise + */ +int ltc7871_read_pec_fault(struct ltc7871_dev *dev, bool *value) +{ + int ret; + uint8_t data; + + if (!dev) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_CHIP_CTRL, &data); + if (ret) + return ret; + + *value = no_os_field_get(LTC7871_CML_MASK, data); + + return 0; +} + +/** + * @brief set write protect bit. + * @param dev - LTC7871 device descriptor + * @param value - 1 if enable wp, 0 if disable + * @return 0 in case of success, negative error code otherwise + */ +int ltc7871_set_write_protect(struct ltc7871_dev *dev, bool value) +{ + int ret; + + if (!dev) + return -EINVAL; + + ret = ltc7871_reg_write_mask(dev, LTC7871_CHIP_CTRL, + LTC7871_WP_MASK, value); + if (ret) + return ret; + + return 0; +} + +/** + * @brief Read Write Protect bit for IDAC registers, and MFR_SSFM register. + * @param dev - LTC7871 device descriptor + * @param value - value of write protect bit + * @return 0 in case of success, negative error code otherwise + */ +int ltc7871_is_write_protected(struct ltc7871_dev *dev, bool *value) +{ + int ret; + uint8_t data; + + if (!dev) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_CHIP_CTRL, &data); + if (ret) + return ret; + + *value = no_os_field_get(LTC7871_WP_MASK, data); + + return 0; +} + +/** + * @brief get the current DAC value to program the VLOW voltage. + * @param dev - LTC7871 device descriptor + * @param value - DAC Value + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_get_mfr_idac_vlow(struct ltc7871_dev *dev, int8_t *value) +{ + int ret; + int8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_IDAC_VLOW, &data); + if (ret) + return ret; + + *value = no_os_field_get(LTC7871_MFR_IDAC_VLOW_MASK, data); + + return 0; +} + +/** + * @brief stores the current DAC value to program the VLOW voltage. + * @param dev - LTC7871 device descriptor + * @param value - DAC value + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_set_mfr_idac_vlow(struct ltc7871_dev *dev, int8_t value) +{ + int ret; + + if (!dev) + return -EINVAL; + + bool wp; + ret = ltc7871_is_write_protected(dev, &wp); + if (ret) + return ret; + + if (!wp) { + ret = ltc7871_reg_write_mask(dev, LTC7871_IDAC_VLOW, + LTC7871_MFR_IDAC_VLOW_MASK, value); + if (ret) + return ret; + } + + return 0; +} + +/** + * @brief get the current DAC value to program the VHIGH voltage. + * @param dev - LTC7871 device descriptor + * @param value - DAC Value + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_get_mfr_idac_vhigh(struct ltc7871_dev *dev, int8_t *value) +{ + int ret; + int8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_IDAC_VHIGH, &data); + if (ret) + return ret; + + *value = no_os_field_get(LTC7871_MFR_IDAC_VHIGH_MASK, data); + + return 0; +} + +/** + * @brief stores the current DAC value to program the VHIGH voltage. + * @param dev - LTC7871 device descriptor + * @param value - DAC value + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_set_mfr_idac_vhigh(struct ltc7871_dev *dev, int8_t value) +{ + int ret; + + if (!dev) + return -EINVAL; + + bool wp; + ret = ltc7871_is_write_protected(dev, &wp); + if (ret) + return ret; + + if (!wp) { + ret = ltc7871_reg_write_mask(dev, LTC7871_IDAC_VHIGH, + LTC7871_MFR_IDAC_VHIGH_MASK, value); + if (ret) + return ret; + } + + return 0; +} + +/** + * @brief get the current DAC value to program the sourcing current of the SETCUR pin. + * @param dev - LTC7871 device descriptor + * @param value - DAC Value + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_get_mfr_idac_setcur(struct ltc7871_dev *dev, int8_t *value) +{ + int ret; + int8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_IDAC_SETCUR, &data); + if (ret) + return ret; + + *value = no_os_field_get(LTC7871_MFR_IDAC_SETCUR_MASK, data); + + return 0; +} + +/** + * @brief stores the current DAC value to program the sourcing current of the SETCUR pin. + * @param dev - LTC7871 device descriptor + * @param value - DAC value + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_set_mfr_idac_setcur(struct ltc7871_dev *dev, int8_t value) +{ + int ret; + + if (!dev) + return -EINVAL; + + bool wp; + ret = ltc7871_is_write_protected(dev, &wp); + if (ret) + return ret; + + if (!wp) { + ret = ltc7871_reg_write_mask(dev, LTC7871_IDAC_SETCUR, + LTC7871_MFR_IDAC_SETCUR_MASK, value); + if (ret) + return ret; + } + + return 0; +} + +/** + * @brief Get Frequency Spread Range. + * @param dev - LTC7871 device descriptor + * @param value - Frequencey Spread range + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_get_freq_spread_range(struct ltc7871_dev *dev, uint8_t *value) +{ + int ret; + uint8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_MFR_SSFM, &data); + if (ret) + return ret; + + *value = no_os_field_get(LTC7871_MFR_SSFM_FSR_MASK, data); + + return 0; +} + +/** + * @brief Set Frequency Spread Range. + * @param dev - LTC7871 device descriptor + * @param value - Frequency Spread Range value + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_set_freq_spread_range(struct ltc7871_dev *dev, + enum ltc7871_ssfm_fsr value) +{ + int ret; + + if (!dev) + return -EINVAL; + + bool wp; + ret = ltc7871_is_write_protected(dev, &wp); + if (ret) + return ret; + + if (!wp) { + ret = ltc7871_reg_write_mask(dev, LTC7871_MFR_SSFM, + LTC7871_MFR_SSFM_FSR_MASK, value); + if (ret) + return ret; + } + + return 0; +} + +/** + * @brief Get Modulation Signal Frequency. + * @param dev - LTC7871 device descriptor + * @param value - Modulation signal frequency value + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_get_mod_freq(struct ltc7871_dev *dev, uint8_t *value) +{ + int ret; + uint8_t data; + + if (!dev || !value) + return -EINVAL; + + ret = ltc7871_reg_read(dev, LTC7871_MFR_SSFM, &data); + if (ret) + return ret; + + *value = no_os_field_get(LTC7871_MFR_SSFM_MSF_MASK, data); + + return 0; +} + +/** + * @brief Set Modulation Signal Frequency. + * @param dev - LTC7871 device descriptor + * @param value - Modulation signal frequency value + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_set_mod_freq(struct ltc7871_dev *dev, enum ltc7871_ssfm_msf value) +{ + int ret; + + if (!dev) + return -EINVAL; + + bool wp; + ret = ltc7871_is_write_protected(dev, &wp); + if (ret) + return ret; + + if (!wp) { + ret = ltc7871_reg_write_mask(dev, LTC7871_MFR_SSFM, + LTC7871_MFR_SSFM_MSF_MASK, value); + if (ret) + return ret; + } + + return 0; +} + +/** + * @brief Set PWMEN pin of LTC7871 device. + * @param dev - LTC7871 device descriptor + * @param value Set SWEN pin of LTC7871 device. + * @return- 0 in case of succes, negative error code otherwise +*/ +int ltc7871_set_pwmen_pin(struct ltc7871_dev *dev, uint8_t value) +{ + if (!dev) + return -EINVAL; + + return no_os_gpio_set_value(dev->gpio_pwmen, value); +} + +/** + * @brief Get EN pin of LTC7871 device. + * @param dev - LTC7871 device descriptor + * @param value - EN pin value. + * @return 0 in case of succes, negative error code otherwise + */ +int ltc7871_get_pwmen_pin(struct ltc7871_dev *dev, uint8_t *value) +{ + if (!dev || !value) + return -EINVAL; + + return no_os_gpio_get_value(dev->gpio_pwmen, value); +} + +/** + * @brief Initialize the LTC7871 device. + * @param device - LTC7871 device descriptor + * @param init_param - Initialization parameter containing information about the + * LTC7871 device to be initialized. + * @return 0 in case of succes, negative error code otherwise +*/ +int ltc7871_init(struct ltc7871_dev **device, + struct ltc7871_init_param *init_param) +{ + struct ltc7871_dev *dev; + int ret; + + if (!device || !init_param) + return -EINVAL; + + dev = (struct ltc7871_dev *)no_os_calloc(1, sizeof(*dev)); + if (!dev) + return -ENOMEM; + + ret = no_os_spi_init(&dev->spi, init_param->spi); + if (ret) { + goto free_desc; + } + + ret = no_os_gpio_get_optional(&dev->gpio_pwmen, init_param->gpio_pwmen); + if (ret) + goto free_desc; + + ret = no_os_gpio_direction_output(dev->gpio_pwmen, NO_OS_GPIO_LOW); + if (ret) + goto free_desc; + + ret = ltc7871_reset(dev); + + *device = dev; + + return 0; + + +free_desc: + ltc7871_remove(dev); + + return ret; +} + +/** + * @brief Free the resources allocated by the LT7871_init() + * @param dev - LTC7871 device descriptor + * @return- 0 in case of succes, negative error code otherwise +*/ +int ltc7871_remove(struct ltc7871_dev *dev) +{ + if (!dev) + return -ENODEV; + + no_os_gpio_remove(dev->gpio_pwmen); + no_os_spi_remove(dev->spi); + no_os_free(dev); + + return 0; +} diff --git a/drivers/power/ltc7871/ltc7871.h b/drivers/power/ltc7871/ltc7871.h new file mode 100644 index 00000000000..2518656624b --- /dev/null +++ b/drivers/power/ltc7871/ltc7871.h @@ -0,0 +1,318 @@ +/***************************************************************************//** + * @file LTC7871.h + * @brief Header file for the LTC7871 Driver + * @author Aldrin Abacan (aldrin.abacan@analog.com) + ******************************************************************************* + * Copyright 2024(c) Analog Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ + +#ifndef __LTC7871_H__ +#define __LTC7871_H__ + +#include +#include +#include +#include "no_os_gpio.h" +#include "no_os_spi.h" +#include "no_os_units.h" +#include "no_os_util.h" + +#define SET 1 +#define CLEAR 0 + +#define LTC7871_CRC_POLYNOMIAL 0x07 + +#define LTC7871_FRAME_SIZE 3 +#define LTC7871_NUM_REGISTERS 8 + +/* Miscellaneous Definitions*/ +#define LTC7871_SPI_READ 0x01 +#define LTC7871_SPI_WRITE 0x00 + +// LTC7871 SPI Command +#define LTC7871_STATUS_ACQUISITION_COMMAND 0xF0 +#define LTC7871_DATA_WRITE_COMMAND 0xF2 +#define LTC7871_DATA_READ_COMMAND 0xF4 + +// LTC7871 SPI Command Size in Bytes +#define LTC7871_STATUS_ACQUISITION_COMMAND_SIZE 4 +#define LTC7871_DATA_WRITE_COMMAND_SIZE 8 +#define LTC7871_DATA_READ_COMMAND_SIZE 8 + +// LTC7871 SPI Register Address +#define LTC7871_MFR_FAULT 0x01 +#define LTC7871_MFR_OC_FAULT 0x02 +#define LTC7871_MFR_NOC_FAULT 0x03 +#define LTC7871_MFR_STATUS 0x04 +#define LTC7871_MFR_CONFIG1 0x05 +#define LTC7871_MFR_CONFIG2 0x06 +#define LTC7871_CHIP_CTRL 0x07 +#define LTC7871_IDAC_VLOW 0x08 +#define LTC7871_IDAC_VHIGH 0x09 +#define LTC7871_IDAC_SETCUR 0x0A +#define LTC7871_MFR_SSFM 0x0B + +// LTC7871 SPI Register Mask +#define LTC7871_MFR_FAULT_MASK NO_OS_GENMASK(6, 0) +#define LTC7871_MFR_OC_FAULT_MASK NO_OS_GENMASK(6, 0) +#define LTC7871_MFR_NOC_FAULT_MASK NO_OS_GENMASK(6, 0) +#define LTC7871_MFR_NOC_FAULT_MASK NO_OS_GENMASK(6, 0) +#define LTC7871_MFR_STATUS_MASK NO_OS_GENMASK(2, 0) +#define LTC7871_MFR_CONFIG1_MASK NO_OS_GENMASK(5, 0) +#define LTC7871_MFR_CONFIG2_MASK NO_OS_GENMASK(4, 0) +#define LTC7871_MFR_CHIP_CTRL_MASK NO_OS_GENMASK(2, 0) +#define LTC7871_MFR_SSFM_MASK NO_OS_GENMASK(8, 0) + + +// LTC7871 MFR_FAULT register bits +#define LTC7871_VLOW_OV_MASK NO_OS_BIT(6) +#define LTC7871_VHIGH_OV_MASK NO_OS_BIT(5) +#define LTC7871_VHIGH_UV_MASK NO_OS_BIT(4) +#define LTC7871_DRVCC_UV_MASK NO_OS_BIT(3) +#define LTC7871_V5_UV_MASK NO_OS_BIT(2) +#define LTC7871_VREF_BAD_MASK NO_OS_BIT(1) +#define LTC7871_OVER_TEMP_MASK NO_OS_BIT(0) + +// LTC7871 MFR_OC_FAULT register bits +#define LTC7871_OC_FAULT_6_MASK NO_OS_BIT(5) +#define LTC7871_OC_FAULT_5_MASK NO_OS_BIT(4) +#define LTC7871_OC_FAULT_4_MASK NO_OS_BIT(3) +#define LTC7871_OC_FAULT_3_MASK NO_OS_BIT(2) +#define LTC7871_OC_FAULT_2_MASK NO_OS_BIT(1) +#define LTC7871_OC_FAULT_1_MASK NO_OS_BIT(0) + +// LTC7871 MFR_NOC_FAULT register bits +#define LTC7871_NOC_FAULT_6_MASK NO_OS_BIT(5) +#define LTC7871_NOC_FAULT_5_MASK NO_OS_BIT(4) +#define LTC7871_NOC_FAULT_4_MASK NO_OS_BIT(3) +#define LTC7871_NOC_FAULT_3_MASK NO_OS_BIT(2) +#define LTC7871_NOC_FAULT_2_MASK NO_OS_BIT(1) +#define LTC7871_NOC_FAULT_1_MASK NO_OS_BIT(0) + +// LTC7871 MFR_STATUS register bits +#define LTC7871_SS_DONE_MASK NO_OS_BIT(2) +#define LTC7871_MAX_CURRENT_MASK NO_OS_BIT(1) +#define LTC7871_PGOOD_MASK NO_OS_BIT(0) + +// LTC7871 MFR_CONFIG1 register bits +#define LTC7871_SERCUR_WARNING_MASK NO_OS_BIT(5) +#define LTC7871_DRVCC_SET_MASK NO_OS_GENMASK(4, 3) +#define LTC7871_ILIM_SET_MASK NO_OS_GENMASK(2, 0) + +// LTC7871 MFR_CONFIG2 register bits +#define LTC7871_BURST_MASK NO_OS_BIT(4) +#define LTC7871_DCM_MASK NO_OS_BIT(3) +#define LTC7871_HIZ_MASK NO_OS_BIT(2) +#define LTC7871_SPRD_MASK NO_OS_BIT(1) +#define LTC7871_BUCK_BOOST_MASK NO_OS_BIT(0) + +// LTC7871 MFR_CHIP_CTRL register bits +#define LTC7871_CML_MASK NO_OS_BIT(2) +#define LTC7871_RESET_MASK NO_OS_BIT(1) +#define LTC7871_WP_MASK NO_OS_BIT(0) + +// LTC7871 MFR_IDAC_VLOW register bits +#define LTC7871_MFR_IDAC_VLOW_MASK NO_OS_GENMASK(6, 0) + +// LTC7871 MFR_IDAC_VHIGH register bits +#define LTC7871_MFR_IDAC_VHIGH_MASK NO_OS_GENMASK(6, 0) + +// LTC7871 MFR_IDAC_SETCUR register bits +#define LTC7871_MFR_IDAC_SETCUR_MASK NO_OS_GENMASK(4, 0) + +// LTC7871 MFR_SSFM register bits +#define LTC7871_MFR_SSFM_FSR_MASK NO_OS_GENMASK(4, 3) +#define LTC7871_MFR_SSFM_MSF_MASK NO_OS_GENMASK(2, 0) + + +/** + * @enum ltc7871_ssfm_fsr + * @brief Frequency Spread Range control bits + */ +enum ltc7871_ssfm_fsr { + /** +/-12%*/ + LTC7871_SSFM_FSR_12, + /** +/-15%*/ + LTC7871_SSFM_FSR_15, + /** +/-10%*/ + LTC7871_SSFM_FSR_10, + /** +/-8%*/ + LTC7871_SSFM_FSR_8 +}; + +/** + * @enum ltc7871_ssfm_msf + * @brief Modulation Signal Frequency control bits + */ +enum ltc7871_ssfm_msf { + /** Controller Switching Frequency/512*/ + LTC7871_SSFM_MSF_512, + /** Controller Switching Frequency/1024*/ + LTC7871_SSFM_MSF_1024, + /** Controller Switching Frequency/2048*/ + LTC7871_SSFM_MSF_2048, + /** Controller Switching Frequency/4096*/ + LTC7871_SSFM_MSF_4096, + /** Controller Switching Frequency/256*/ + LTC7871_SSFM_MSF_256, + /** Controller Switching Frequency/128*/ + LTC7871_SSFM_MSF_128, + /** Controller Switching Frequency/64*/ + LTC7871_SSFM_MSF_64, + /** Controller Switching Frequency/512*/ + LTC7871_SSFM_MSF_512U +}; + +/** + * @enum ltc7871_ctrl_wp + * @brief Frequency Spread Range control bits + */ +enum ltc7871_ctrl_wp { + /** enable write protect*/ + LTC7871_CTRL_WP_ENABLE, + /** disable write protect*/ + LTC7871_CTRL_WP_DISABLE +}; + +/** + * @struct ltc7871_init_param + * @brief Initialization parameter for the LTC7871 device. + */ +struct ltc7871_init_param { + struct no_os_spi_init_param *spi; + struct no_os_gpio_init_param *gpio_pwmen; +}; + +/** + * @struct ltc7871_dev + * @brief Device descriptor for ltc7871. + */ +struct ltc7871_dev { + struct no_os_spi_desc *spi; + struct no_os_gpio_desc *gpio_pwmen; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ +/** Register Read */ +uint8_t ltc7871_get_pec_byte(uint8_t *data, uint8_t len); + +/** Register Read */ +int ltc7871_reg_read(struct ltc7871_dev *dev, uint8_t reg, uint8_t *data); + +/** Register Write */ +int ltc7871_reg_write(struct ltc7871_dev *dev, uint8_t reg, uint8_t data); + +/** Register mask Write */ +int ltc7871_reg_write_mask(struct ltc7871_dev *dev, uint8_t address, + uint8_t mask, uint8_t data); + +/**Read Most critical fault status */ +int ltc7871_get_mfr_fault(struct ltc7871_dev *dev, uint8_t status, bool *value); + +/**Read overcurrent condition status */ +int ltc7871_get_mfr_oc_fault(struct ltc7871_dev *dev, uint8_t status, + bool *value); + +/**Read negative overcurrent condition status */ +int ltc7871_get_mfr_noc_fault(struct ltc7871_dev *dev, uint8_t status, + bool *value); + +/**gets configuration of the controller programmed by the pins.*/ +int ltc7871_get_mfr_config1_setting(struct ltc7871_dev *dev, + uint8_t config, uint8_t *value); + +/**gets configuration of the controller programmed by the pins.*/ +int ltc7871_get_mfr_config2_setting(struct ltc7871_dev *dev, + uint8_t config, uint8_t *value); + +/**gets status */ +int ltc7871_get_mfr_status(struct ltc7871_dev *dev, uint8_t status_mask, + bool *status); + +/**Reset all R/W registers */ +int ltc7871_reset(struct ltc7871_dev *dev); + +/**Clear PEC fault bit */ +int ltc7871_clear_pec_fault(struct ltc7871_dev *dev); + +/**Read PEC fault bit */ +int ltc7871_read_pec_fault(struct ltc7871_dev *dev, bool *value); + +/**et write protect bit */ +int ltc7871_set_write_protect(struct ltc7871_dev *dev, bool value); + +/**Read Write Protect bit for IDAC registers, and MFR_SSFM register */ +int ltc7871_is_write_protected(struct ltc7871_dev *dev, bool *value); + +/**get the current DAC value to program the VLOW voltage.*/ +int ltc7871_get_mfr_idac_vlow(struct ltc7871_dev *dev, int8_t *value); + +/**stores the current DAC value to program the VLOW voltage. */ +int ltc7871_set_mfr_idac_vlow(struct ltc7871_dev *dev, int8_t value); + +/**get the current DAC value to program the VHIGH voltage.*/ +int ltc7871_get_mfr_idac_vhigh(struct ltc7871_dev *dev, int8_t *value); + +/**stores the current DAC value to program the VHIGH voltage. */ +int ltc7871_set_mfr_idac_vhigh(struct ltc7871_dev *dev, int8_t value); + +/**get the current DAC value to program the sourcing current of the SETCUR pin.*/ +int ltc7871_get_mfr_idac_setcur(struct ltc7871_dev *dev, int8_t *value); + +/**stores the current DAC value to program the sourcing current of the SETCUR pin. */ +int ltc7871_set_mfr_idac_setcur(struct ltc7871_dev *dev, int8_t value); + +/**Get Frequency Spread Range.*/ +int ltc7871_get_freq_spread_range(struct ltc7871_dev *dev, uint8_t *value); + +/**Set Frequency Spread Range */ +int ltc7871_set_freq_spread_range(struct ltc7871_dev *dev, + enum ltc7871_ssfm_fsr value); + +/**Get Modulation Signal Frequency */ +int ltc7871_get_mod_freq(struct ltc7871_dev *dev, uint8_t *value); + +/**Set Modulation Signal Frequency */ +int ltc7871_set_mod_freq(struct ltc7871_dev *dev, enum ltc7871_ssfm_msf value); + +/** Set PWMEN pin of LTC7871 device. */ +int ltc7871_set_pwmen_pin(struct ltc7871_dev *dev, uint8_t value); + +/** Get PWMEN pin */ +int ltc7871_get_pwmen_pin(struct ltc7871_dev *dev, uint8_t *value); + +/** Initialize the LTC7871 device descriptor. */ +int ltc7871_init(struct ltc7871_dev **device, + struct ltc7871_init_param *init_param); + +/** Remove resources allocated by the init function. */ +int ltc7871_remove(struct ltc7871_dev *dev); + +#endif /** __LTC7871_H__ */