[PATCH 1/2] regulator: ltc7871: Add driver for LTC7871

Celine Joy A. Capua posted 2 patches 12 months ago
[PATCH 1/2] regulator: ltc7871: Add driver for LTC7871
Posted by Celine Joy A. Capua 12 months ago
Add ADI LTC7871 buck-boost controller driver support.

Signed-off-by: Celine Joy A. Capua <celinejoy.capua@analog.com>
---
 drivers/regulator/Kconfig             |  11 +
 drivers/regulator/Makefile            |   1 +
 drivers/regulator/ltc7871-regulator.c | 405 ++++++++++++++++++++++++++++++++++
 3 files changed, 417 insertions(+)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 39297f7d8177193e51c99bc2b360c6d9936e62fe..500e8d7a198c597a479f80866a9733ebf945e15f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -566,6 +566,17 @@ config REGULATOR_LTC3676
 	  This enables support for the LTC3676
 	  8-output regulators controlled via I2C.
 
+config REGULATOR_LTC7871
+	tristate "LTC7871 six-phase buck-boost voltage regulator driver with SPI"
+	depends on SPI && OF
+	help
+	  This driver controls an Analog Devices LTC7871 high performance
+	  bidirectional buck or boost switching regulator controller
+	  that operates in either buck or boost mode on demand.
+
+	  Say M here if you want to include support for the regulator as a
+	  module.
+
 config REGULATOR_MAX14577
 	tristate "Maxim 14577/77836 regulator"
 	depends on MFD_MAX14577
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 3d5a803dce8a0556ba9557fa069c6e37593b3c69..47e26fcf39db39da542a7bc4df05b214c4b7cc0f 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
 obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
 obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
 obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
+obj-$(CONFIG_REGULATOR_LTC7871) += ltc7871-regulator.o
 obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
 obj-$(CONFIG_REGULATOR_MAX5970) += max5970-regulator.o
diff --git a/drivers/regulator/ltc7871-regulator.c b/drivers/regulator/ltc7871-regulator.c
new file mode 100644
index 0000000000000000000000000000000000000000..eeea952f9362e48e0f6b85309a0c273f77776cb0
--- /dev/null
+++ b/drivers/regulator/ltc7871-regulator.c
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Analog Devices LTC7871 Voltage Regulator Driver
+ *
+ * Copyright 2025 Analog Devices Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/crc8.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/spi/spi.h>
+
+#define LTC7871_REG_FAULT		0x01
+#define LTC7871_REG_CONFIG2		0x06
+#define LTC7871_REG_CHIP_CTRL		0x07
+#define LTC7871_REG_IDAC_VLOW		0x08
+#define LTC7871_REG_IDAC_VHIGH		0x09
+#define LTC7871_REG_SETCUR		0x0A
+#define LTC7871_REG_SSFM		0x0B
+
+#define LTC7871_FAULT_OVER_TEMP		BIT(0)
+#define LTC7871_FAULT_VHIGH_UV		BIT(4)
+#define LTC7871_FAULT_VHIGH_OV		BIT(5)
+#define LTC7871_FAULT_VLOW_OV		BIT(6)
+
+#define LTC7871_MASK_CONFIG2_BUCK_BOOST	BIT(0)
+
+#define LTC7871_MASK_CHIP_CTRL_WP	BIT(0)
+
+#define	LTC7871_MASK_SSFM_FREQ_SPREAD	GENMASK(4, 3)
+#define	LTC7871_MASK_SSFM_MOD_SIG_FREQ	GENMASK(2, 0)
+
+#define LTC7871_CRC_INIT		0x41
+#define LTC7871_CRC8_POLY		0x7
+#define LTC7871_DATA_POS		1
+#define LTC7871_CRC_POS			2
+#define LTC7871_FRAME_SIZE		3
+
+#define LTC7871_IDAC_MAX		63
+#define LTC7871_IDAC_MIN		-64
+
+DECLARE_CRC8_TABLE(ltc7871_crc8_table);
+
+struct ltc7871 {
+	struct spi_device *spi;
+	struct regulator_dev *rdev;
+	bool enable_chip_ctrl_wp;
+	bool regulator_mode;
+	u32 ra_ext;
+	u32 rb_ext;
+	u32 rc_ext;
+	u32 rd_ext;
+	u32 r1;
+	u32 r2;
+	u32 max_vol;
+	u32 min_vol;
+	s32 idac_setcur_uA;
+	const char *freq_spread_percentage;
+	u32 switching_freq_divider;
+};
+
+static const char * const ltc7871_freq_spread_percentage[] = {
+	"+-12%",
+	"+-15%",
+	"+-10%",
+	"+-8%",
+};
+
+static const unsigned int ltc7871_switching_freq_divider[] = {
+	512,
+	1024,
+	2048,
+	4096,
+	256,
+	128,
+	64,
+};
+
+static int ltc7871_reg_read(struct spi_device *spi, u8 reg, int *val)
+{
+	int ret;
+	struct spi_transfer t;
+	u8 crc;
+	u8 rx_buf[LTC7871_FRAME_SIZE] = {0};
+	u8 tx_buf[LTC7871_FRAME_SIZE] = {0};
+
+	tx_buf[0] = reg << 1 | 1;
+
+	t.tx_buf = tx_buf;
+	t.rx_buf = rx_buf;
+	t.len = LTC7871_FRAME_SIZE;
+
+	crc = crc8(ltc7871_crc8_table, rx_buf, LTC7871_CRC_POS,
+		   LTC7871_CRC_INIT);
+
+	ret = spi_sync_transfer(spi, &t, 1);
+	if (ret < 0)
+		return ret;
+
+	if (rx_buf[LTC7871_CRC_POS] != crc)
+		return -EIO;
+
+	return 0;
+}
+
+static int ltc7871_reg_write(struct spi_device *spi, u8 reg, int val)
+{
+	struct spi_transfer t;
+	u8 rx_buf[LTC7871_FRAME_SIZE] = {0};
+	u8 tx_buf[LTC7871_FRAME_SIZE] = {0};
+
+	tx_buf[0] = reg << 1;
+	tx_buf[1] = val;
+	tx_buf[2] = crc8(ltc7871_crc8_table, tx_buf, LTC7871_CRC_POS, LTC7871_CRC_INIT);
+
+	t.tx_buf = tx_buf;
+	t.rx_buf = rx_buf;
+	t.len = LTC7871_FRAME_SIZE;
+
+	return spi_sync_transfer(spi, &t, 1);
+}
+
+static int ltc7871_get_error_flags(struct regulator_dev *rdev,
+				   unsigned int *flags)
+{
+	u32 val;
+	int ret;
+	struct ltc7871 *ltc7871 = rdev_get_drvdata(rdev);
+
+	ret = ltc7871_reg_read(ltc7871->spi, LTC7871_REG_FAULT, &val);
+	if (ret)
+		return ret;
+
+	*flags = 0;
+
+	if (FIELD_GET(LTC7871_FAULT_VHIGH_OV, val) ||
+	    FIELD_GET(LTC7871_FAULT_VLOW_OV, val))
+		*flags |= REGULATOR_ERROR_OVER_VOLTAGE_WARN;
+
+	if (FIELD_GET(LTC7871_FAULT_VHIGH_UV, val))
+		*flags |= REGULATOR_ERROR_UNDER_VOLTAGE;
+
+	if (FIELD_GET(LTC7871_FAULT_OVER_TEMP, val))
+		*flags |= REGULATOR_ERROR_OVER_TEMP;
+
+	return 0;
+}
+
+static s64 _ltc7871_dac_to_uV(struct ltc7871 *ltc7871, u32 dac_val)
+{
+	s64 tmp;
+
+	tmp = 1200 * (1000 + (div_s64(ltc7871->r2 * 1000, ltc7871->r1)));
+	tmp = tmp - dac_val * ltc7871->r2;
+
+	return tmp;
+}
+
+static s64 _ltc7871_uV_to_dac(struct ltc7871 *ltc7871, s32 uV)
+{
+	s64 tmp;
+
+	tmp = 1200 * (1000 + (div_s64(ltc7871->r2 * 1000, ltc7871->r1))) - uV;
+	tmp = div_s64(tmp, ltc7871->r2);
+
+	return tmp;
+}
+
+static int ltc7871_set_voltage_sel(struct regulator_dev *rdev,
+				   unsigned int sel)
+{
+	int reg;
+	int addr;
+	struct ltc7871 *ltc7871 = rdev_get_drvdata(rdev);
+
+	if (sel < ltc7871->min_vol || sel > ltc7871->max_vol)
+		return -EINVAL;
+
+	if (ltc7871->regulator_mode)
+		addr = LTC7871_REG_IDAC_VLOW;
+	else
+		addr = LTC7871_REG_IDAC_VHIGH;
+
+	reg = _ltc7871_uV_to_dac(ltc7871, sel);
+
+	return ltc7871_reg_write(ltc7871->spi, addr, reg);
+}
+
+static int ltc7871_get_voltage_sel(struct regulator_dev *rdev)
+{
+	int reg, ret;
+	int addr;
+	struct ltc7871 *ltc7871 = rdev_get_drvdata(rdev);
+
+	if (ltc7871->regulator_mode)
+		addr = LTC7871_REG_IDAC_VLOW;
+	else
+		addr = LTC7871_REG_IDAC_VHIGH;
+
+	ret = ltc7871_reg_read(ltc7871->spi, addr, &reg);
+	if (ret < 0)
+		return ret;
+
+	return _ltc7871_dac_to_uV(ltc7871, reg);
+}
+
+static int ltc7871_get_prop_index(const u32 *table, size_t table_size, u32 value)
+{
+	int i;
+
+	for (i = 0; i < table_size; i++)
+		if (table[i] == value)
+			return i;
+
+	return -EINVAL;
+}
+
+static int ltc7871_parse_fw(struct ltc7871 *chip)
+{
+	int reg, ret;
+	int val1, val2;
+
+	/* Setting default values based on datasheet and DC2886A Schematic */
+	chip->idac_setcur_uA = 0;
+	chip->freq_spread_percentage = "+-12%";
+	chip->switching_freq_divider = 512;
+	chip->enable_chip_ctrl_wp = 0;
+	chip->ra_ext = 10000;
+	chip->rb_ext = 107000;
+	chip->rc_ext = 12700;
+	chip->rd_ext = 499000;
+
+	ret = device_property_read_u32(&chip->spi->dev, "adi,ra-external-ohms",
+				 &chip->ra_ext);
+	if (!ret) {
+		if (!chip->ra_ext)
+			return -EINVAL;
+	}
+
+	ret = device_property_read_u32(&chip->spi->dev, "adi,rb-external-ohms",
+				 &chip->rb_ext);
+	if (!ret) {
+		if (!chip->rb_ext)
+			return -EINVAL;
+	}
+
+	ret = device_property_read_u32(&chip->spi->dev, "adi,rc-external-ohms",
+				 &chip->rc_ext);
+	if (!ret) {
+		if (!chip->rc_ext)
+			return -EINVAL;
+	}
+
+	ret = device_property_read_u32(&chip->spi->dev, "adi,rd-external-ohms",
+				 &chip->rd_ext);
+	if (!ret) {
+		if (!chip->rd_ext)
+			return -EINVAL;
+	}
+
+	ret = ltc7871_reg_read(chip->spi, LTC7871_REG_CONFIG2, &reg);
+	if (ret < 0)
+		return ret;
+
+	chip->regulator_mode = FIELD_GET(LTC7871_MASK_CONFIG2_BUCK_BOOST, reg);
+
+	if (chip->regulator_mode) {
+		chip->r1 = chip->ra_ext;
+		chip->r2 = chip->rb_ext;
+	} else {
+		chip->r1 = chip->rc_ext;
+		chip->r2 = chip->rd_ext;
+	}
+	chip->min_vol = _ltc7871_dac_to_uV(chip, LTC7871_IDAC_MAX);
+	chip->max_vol = _ltc7871_dac_to_uV(chip, LTC7871_IDAC_MIN);
+
+	ret = ltc7871_reg_read(chip->spi, LTC7871_REG_CHIP_CTRL, &reg);
+	if (ret < 0)
+		return ret;
+
+	chip->enable_chip_ctrl_wp = device_property_read_bool(&chip->spi->dev,
+						"adi,enable-chip-ctrl-wp");
+	val1 = FIELD_PREP(LTC7871_MASK_CHIP_CTRL_WP, chip->enable_chip_ctrl_wp) | reg;
+	ret = ltc7871_reg_write(chip->spi, LTC7871_REG_CHIP_CTRL, val1);
+	if (ret)
+		return ret;
+
+	ret = device_property_read_u32(&chip->spi->dev, "adi,idac-setcur-microamp",
+				 &chip->idac_setcur_uA);
+	if (!ret) {
+		if (chip->idac_setcur_uA < LTC7871_IDAC_MIN ||
+		    chip->idac_setcur_uA > LTC7871_IDAC_MAX) {
+			return -EINVAL;
+		}
+
+		ret = ltc7871_reg_write(chip->spi, LTC7871_REG_SETCUR,
+					chip->idac_setcur_uA);
+		if (ret)
+			return ret;
+	}
+	ret = device_property_match_property_string(&chip->spi->dev,
+			"adi,freq-spread-percentage",
+			ltc7871_freq_spread_percentage,
+			ARRAY_SIZE(ltc7871_freq_spread_percentage));
+
+	if (ret >= 0)
+		val1 = FIELD_PREP(LTC7871_MASK_SSFM_FREQ_SPREAD, ret);
+	else
+		val1 = 0;
+
+	ret = device_property_read_u32(&chip->spi->dev,
+				       "adi,switching-freq-divider",
+				       &chip->switching_freq_divider);
+	if (!ret) {
+		ret = ltc7871_get_prop_index(ltc7871_switching_freq_divider,
+					     ARRAY_SIZE(ltc7871_switching_freq_divider),
+					     chip->switching_freq_divider);
+		if (ret < 0)
+			return ret;
+
+		val2 = FIELD_PREP(LTC7871_MASK_SSFM_MOD_SIG_FREQ, ret);
+	}
+
+	return ltc7871_reg_write(chip->spi, LTC7871_REG_SSFM, val1 | val2);
+}
+
+static const struct regulator_ops ltc7871_regulator_ops = {
+	.set_voltage_sel = ltc7871_set_voltage_sel,
+	.get_voltage_sel = ltc7871_get_voltage_sel,
+	.get_error_flags = ltc7871_get_error_flags,
+};
+
+static const struct regulator_desc ltc7871_regulator_desc = {
+	.ops = &ltc7871_regulator_ops,
+	.name = "ltc7871",
+	.type = REGULATOR_VOLTAGE,
+	.owner = THIS_MODULE,
+};
+
+static int ltc7871_probe(struct spi_device *spi)
+{
+	int ret;
+	struct regulator_init_data *init_data;
+	struct device *dev = &spi->dev;
+	struct regulator_config config = { };
+	struct ltc7871 *chip;
+
+	init_data = of_get_regulator_init_data(dev, spi->dev.of_node,
+					       &ltc7871_regulator_desc);
+	if (!init_data)
+		return -EINVAL;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	crc8_populate_msb(ltc7871_crc8_table, LTC7871_CRC8_POLY);
+
+	chip->spi = spi;
+
+	ret = ltc7871_parse_fw(chip);
+	if (ret < 0)
+		return ret;
+
+	config.dev = dev;
+	config.init_data = init_data;
+	config.driver_data = chip;
+
+	chip->rdev = devm_regulator_register(dev, &ltc7871_regulator_desc,
+					     &config);
+
+	return PTR_ERR_OR_ZERO(chip->rdev);
+}
+
+static const struct of_device_id ltc7871_of_match[] = {
+	{ .compatible = "adi,ltc7871", },
+	{ .compatible = "adi,ltc7872", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ltc7871_of_match);
+
+static const struct spi_device_id ltc7871_id[] = {
+	{"ltc7871" },
+	{"ltc7872" },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, ltc7871_id);
+
+static struct spi_driver ltc7871_driver = {
+	.driver = {
+		.name = "ltc7871",
+		.of_match_table = ltc7871_of_match,
+	},
+	.probe = ltc7871_probe,
+	.id_table = ltc7871_id,
+};
+module_spi_driver(ltc7871_driver);
+
+MODULE_DESCRIPTION("LTC7871 Voltage Regulator Driver");
+MODULE_AUTHOR("Celine Joy Capua <celinejoy.capua@analog.com>");
+MODULE_LICENSE("GPL");

-- 
2.34.1
Re: [PATCH 1/2] regulator: ltc7871: Add driver for LTC7871
Posted by kernel test robot 12 months ago
Hi Celine,

kernel test robot noticed the following build warnings:

[auto build test WARNING on fff64b15e3d1e9bd9246db1f5e0b84e7e561b79f]

url:    https://github.com/intel-lab-lkp/linux/commits/Celine-Joy-A-Capua/regulator-ltc7871-Add-driver-for-LTC7871/20250210-103432
base:   fff64b15e3d1e9bd9246db1f5e0b84e7e561b79f
patch link:    https://lore.kernel.org/r/20250210-staging-ltc7871-v1-1-c593ad86aab2%40analog.com
patch subject: [PATCH 1/2] regulator: ltc7871: Add driver for LTC7871
config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20250211/202502110205.DShIOHH0-lkp@intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250211/202502110205.DShIOHH0-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202502110205.DShIOHH0-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/regulator/ltc7871-regulator.c:11:
   In file included from include/linux/module.h:19:
   In file included from include/linux/elf.h:6:
   In file included from arch/s390/include/asm/elf.h:181:
   In file included from arch/s390/include/asm/mmu_context.h:11:
   In file included from arch/s390/include/asm/pgalloc.h:18:
   In file included from include/linux/mm.h:2224:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/regulator/ltc7871-regulator.c:318:6: warning: variable 'val2' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
     318 |         if (!ret) {
         |             ^~~~
   drivers/regulator/ltc7871-regulator.c:328:63: note: uninitialized use occurs here
     328 |         return ltc7871_reg_write(chip->spi, LTC7871_REG_SSFM, val1 | val2);
         |                                                                      ^~~~
   drivers/regulator/ltc7871-regulator.c:318:2: note: remove the 'if' if its condition is always true
     318 |         if (!ret) {
         |         ^~~~~~~~~
   drivers/regulator/ltc7871-regulator.c:225:16: note: initialize the variable 'val2' to silence this warning
     225 |         int val1, val2;
         |                       ^
         |                        = 0
   4 warnings generated.


vim +318 drivers/regulator/ltc7871-regulator.c

   221	
   222	static int ltc7871_parse_fw(struct ltc7871 *chip)
   223	{
   224		int reg, ret;
   225		int val1, val2;
   226	
   227		/* Setting default values based on datasheet and DC2886A Schematic */
   228		chip->idac_setcur_uA = 0;
   229		chip->freq_spread_percentage = "+-12%";
   230		chip->switching_freq_divider = 512;
   231		chip->enable_chip_ctrl_wp = 0;
   232		chip->ra_ext = 10000;
   233		chip->rb_ext = 107000;
   234		chip->rc_ext = 12700;
   235		chip->rd_ext = 499000;
   236	
   237		ret = device_property_read_u32(&chip->spi->dev, "adi,ra-external-ohms",
   238					 &chip->ra_ext);
   239		if (!ret) {
   240			if (!chip->ra_ext)
   241				return -EINVAL;
   242		}
   243	
   244		ret = device_property_read_u32(&chip->spi->dev, "adi,rb-external-ohms",
   245					 &chip->rb_ext);
   246		if (!ret) {
   247			if (!chip->rb_ext)
   248				return -EINVAL;
   249		}
   250	
   251		ret = device_property_read_u32(&chip->spi->dev, "adi,rc-external-ohms",
   252					 &chip->rc_ext);
   253		if (!ret) {
   254			if (!chip->rc_ext)
   255				return -EINVAL;
   256		}
   257	
   258		ret = device_property_read_u32(&chip->spi->dev, "adi,rd-external-ohms",
   259					 &chip->rd_ext);
   260		if (!ret) {
   261			if (!chip->rd_ext)
   262				return -EINVAL;
   263		}
   264	
   265		ret = ltc7871_reg_read(chip->spi, LTC7871_REG_CONFIG2, &reg);
   266		if (ret < 0)
   267			return ret;
   268	
   269		chip->regulator_mode = FIELD_GET(LTC7871_MASK_CONFIG2_BUCK_BOOST, reg);
   270	
   271		if (chip->regulator_mode) {
   272			chip->r1 = chip->ra_ext;
   273			chip->r2 = chip->rb_ext;
   274		} else {
   275			chip->r1 = chip->rc_ext;
   276			chip->r2 = chip->rd_ext;
   277		}
   278		chip->min_vol = _ltc7871_dac_to_uV(chip, LTC7871_IDAC_MAX);
   279		chip->max_vol = _ltc7871_dac_to_uV(chip, LTC7871_IDAC_MIN);
   280	
   281		ret = ltc7871_reg_read(chip->spi, LTC7871_REG_CHIP_CTRL, &reg);
   282		if (ret < 0)
   283			return ret;
   284	
   285		chip->enable_chip_ctrl_wp = device_property_read_bool(&chip->spi->dev,
   286							"adi,enable-chip-ctrl-wp");
   287		val1 = FIELD_PREP(LTC7871_MASK_CHIP_CTRL_WP, chip->enable_chip_ctrl_wp) | reg;
   288		ret = ltc7871_reg_write(chip->spi, LTC7871_REG_CHIP_CTRL, val1);
   289		if (ret)
   290			return ret;
   291	
   292		ret = device_property_read_u32(&chip->spi->dev, "adi,idac-setcur-microamp",
   293					 &chip->idac_setcur_uA);
   294		if (!ret) {
   295			if (chip->idac_setcur_uA < LTC7871_IDAC_MIN ||
   296			    chip->idac_setcur_uA > LTC7871_IDAC_MAX) {
   297				return -EINVAL;
   298			}
   299	
   300			ret = ltc7871_reg_write(chip->spi, LTC7871_REG_SETCUR,
   301						chip->idac_setcur_uA);
   302			if (ret)
   303				return ret;
   304		}
   305		ret = device_property_match_property_string(&chip->spi->dev,
   306				"adi,freq-spread-percentage",
   307				ltc7871_freq_spread_percentage,
   308				ARRAY_SIZE(ltc7871_freq_spread_percentage));
   309	
   310		if (ret >= 0)
   311			val1 = FIELD_PREP(LTC7871_MASK_SSFM_FREQ_SPREAD, ret);
   312		else
   313			val1 = 0;
   314	
   315		ret = device_property_read_u32(&chip->spi->dev,
   316					       "adi,switching-freq-divider",
   317					       &chip->switching_freq_divider);
 > 318		if (!ret) {
   319			ret = ltc7871_get_prop_index(ltc7871_switching_freq_divider,
   320						     ARRAY_SIZE(ltc7871_switching_freq_divider),
   321						     chip->switching_freq_divider);
   322			if (ret < 0)
   323				return ret;
   324	
   325			val2 = FIELD_PREP(LTC7871_MASK_SSFM_MOD_SIG_FREQ, ret);
   326		}
   327	
   328		return ltc7871_reg_write(chip->spi, LTC7871_REG_SSFM, val1 | val2);
   329	}
   330	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH 1/2] regulator: ltc7871: Add driver for LTC7871
Posted by Krzysztof Kozlowski 12 months ago
On Mon, Feb 10, 2025 at 10:30:52AM +0800, Celine Joy A. Capua wrote:
> +	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
> +	if (!chip)
> +		return -ENOMEM;
> +
> +	crc8_populate_msb(ltc7871_crc8_table, LTC7871_CRC8_POLY);
> +
> +	chip->spi = spi;
> +
> +	ret = ltc7871_parse_fw(chip);
> +	if (ret < 0)
> +		return ret;
> +
> +	config.dev = dev;
> +	config.init_data = init_data;
> +	config.driver_data = chip;
> +
> +	chip->rdev = devm_regulator_register(dev, &ltc7871_regulator_desc,
> +					     &config);
> +
> +	return PTR_ERR_OR_ZERO(chip->rdev);
> +}
> +
> +static const struct of_device_id ltc7871_of_match[] = {
> +	{ .compatible = "adi,ltc7871", },
> +	{ .compatible = "adi,ltc7872", },


This means devices are compatible?

> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, ltc7871_of_match);
> +
> +static const struct spi_device_id ltc7871_id[] = {
> +	{"ltc7871" },
> +	{"ltc7872" },
> +	{ },

Keep your code consistent. In OF table you have comma after each
compatible, but not here. Space before field, but not here. No trailing
comma on last entry, but it is here. I don't care about the actual
style, just write something consistent, not random.

Best regards,
Krzysztof