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, ®);
+ 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, ®);
+ 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, ®);
+ 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 = <c7871_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,
+ <c7871_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, <c7871_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
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, ®);
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, ®);
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
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, <c7871_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
© 2016 - 2026 Red Hat, Inc.