[PATCH] regmap: implement regmap_multi_reg_write()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



regmap_multi_reg_write() can be used to write multiple regmap registers
at once. The code is taken from Linux-6.12 and simplified for barebox.

Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
---
 drivers/base/regmap/regmap.c | 36 ++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h       | 26 ++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 1f10424a42..777636c0b3 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -573,6 +573,42 @@ int regmap_field_bulk_alloc(struct regmap *regmap,
 	return 0;
 }
 
+/**
+ * regmap_multi_reg_write() - Write multiple registers to the device
+ *
+ * @map: Register map to write to
+ * @regs: Array of structures containing register,value to be written
+ * @num_regs: Number of registers to write
+ *
+ * Write multiple registers to the device where the set of register, value
+ * pairs are supplied in any order, possibly not all in a single range.
+ *
+ * The 'normal' block write mode will send ultimately send data on the
+ * target bus as R,V1,V2,V3,..,Vn where successively higher registers are
+ * addressed. However, this alternative block multi write mode will send
+ * the data as R1,V1,R2,V2,..,Rn,Vn on the target bus. The target device
+ * must of course support the mode.
+ *
+ * A value of zero will be returned on success, a negative errno will be
+ * returned in error cases.
+ */
+int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs,
+			   int num_regs)
+{
+	int i;
+	int ret;
+
+	for (i = 0; i < num_regs; i++) {
+		ret = regmap_write(map, regs[i].reg, regs[i].def);
+		if (ret != 0)
+			return ret;
+
+		if (regs[i].delay_us)
+			udelay(regs[i].delay_us);
+	}
+	return 0;
+}
+
 /*
  * regmap_register_cdev - register a devfs file for a regmap
  *
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index e38b4f2dc8..c24b877712 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -276,6 +276,32 @@ static inline int regmap_clear_bits(struct regmap *map,
 
 size_t regmap_size_bytes(struct regmap *map);
 
+/**
+ * struct reg_sequence - An individual write from a sequence of writes.
+ *
+ * @reg: Register address.
+ * @def: Register value.
+ * @delay_us: Delay to be applied after the register write in microseconds
+ *
+ * Register/value pairs for sequences of writes with an optional delay in
+ * microseconds to be applied after each write.
+ */
+struct reg_sequence {
+	unsigned int reg;
+	unsigned int def;
+	unsigned int delay_us;
+};
+
+#define REG_SEQ(_reg, _def, _delay_us) {		\
+				.reg = _reg,		\
+				.def = _def,		\
+				.delay_us = _delay_us,	\
+				}
+#define REG_SEQ0(_reg, _def)	REG_SEQ(_reg, _def, 0)
+
+int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs,
+			   int num_regs);
+
 /**
  * regmap_read_poll_timeout - Poll until a condition is met or a timeout occurs
  *
-- 
2.39.5





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux