mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly
@ 2026-11-05  0:09 Victor Chernyakin
  2026-11-05  0:09 ` [RFC PATCH 1/2] regmap: add regmap_reg_field_* APIs Victor Chernyakin
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Victor Chernyakin @ 2026-11-05  0:09 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, Victor Chernyakin

Working with the existing regmap_field_* APIs requires you to define
a reg_field, then use one of the regmap_field_*_alloc functions to turn
it into a dynamically allocated regmap_field. But reg_field and
regmap_field are practically the same struct; all the *_alloc functions do
is shuffle fields around. So this RFC proposes adding functions that
cut out the middleman and take reg_field directly. Patch 1 adds two
of them: regmap_reg_field_read and regmap_reg_field_write.

Patch 2 ports a driver to use these new functions. The result is
shorter and simpler, since all the code to perform the allocations
and manage the resulting regmap_fields goes away. In theory,
there should also be a performance benefit (we're doing fewer allocations
and have less duplicated state), but I haven't benchmarked it, so take that
with a grain of salt.

If we like this approach, I can post a v2 that adds regmap_reg_field_*
analogs for all the regmap_field_* functions, not just the two you see here.


This is not actually a new idea! Both it and the current *_alloc approach
were suggested as alternatives right when the regmap_field_* APIs were
being added [1]. The *_alloc approach was chosen without much
discussion, but I think (and Patch 2 demonstrates, I hope) that
this approach is the cleaner one.

[1] https://lore.kernel.org/20130604210137.GV31367@sirena.org.uk

Victor Chernyakin (2):
  regmap: add regmap_reg_field_* APIs
  iio: accel: msa311: use regmap_reg_field_* functions

 drivers/iio/accel/msa311.c | 297 +++++++++++++------------------------
 include/linux/regmap.h     |  61 ++++++--
 2 files changed, 158 insertions(+), 200 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC PATCH 1/2] regmap: add regmap_reg_field_* APIs
  2026-11-05  0:09 [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly Victor Chernyakin
@ 2026-11-05  0:09 ` Victor Chernyakin
  2026-11-05  0:09 ` [RFC PATCH 2/2] iio: accel: msa311: use regmap_reg_field_* functions Victor Chernyakin
  2026-11-05  0:19 ` [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly Mark Brown
  2 siblings, 0 replies; 6+ messages in thread
From: Victor Chernyakin @ 2026-11-05  0:09 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, Victor Chernyakin

These functions are equivalent to their regmap_field_* counterparts,
but allow working with reg_field directly, without having to
allocate and manage regmap_fields.

Signed-off-by: Victor Chernyakin <chernyakin.victor.j@outlook.com>
---
 include/linux/regmap.h | 61 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index c8aebd148e08..b4131495d993 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -11,6 +11,7 @@
  */
 
+#include <linux/bitfield.h>
 #include <linux/bug.h>
 #include <linux/cleanup.h>
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -1463,18 +1464,18 @@ struct reg_field {
 	unsigned int id_offset;
 };
 
-#define REG_FIELD(_reg, _lsb, _msb) {		\
-				.reg = _reg,	\
-				.lsb = _lsb,	\
-				.msb = _msb,	\
+#define REG_FIELD(_reg, _lsb, _msb) (struct reg_field){	\
+				.reg = _reg,		\
+				.lsb = _lsb,		\
+				.msb = _msb,		\
 				}
 
-#define REG_FIELD_ID(_reg, _lsb, _msb, _size, _offset) {	\
-				.reg = _reg,			\
-				.lsb = _lsb,			\
-				.msb = _msb,			\
-				.id_size = _size,		\
-				.id_offset = _offset,		\
+#define REG_FIELD_ID(_reg, _lsb, _msb, _size, _offset) (struct reg_field){ \
+				.reg = _reg,				   \
+				.lsb = _lsb,				   \
+				.msb = _msb,				   \
+				.id_size = _size,			   \
+				.id_offset = _offset,			   \
 				}
 
 struct regmap_field *regmap_field_alloc(struct regmap *regmap,
@@ -1583,6 +1584,30 @@ regmap_fields_force_update_bits(struct regmap_field *field, unsigned int id,
 					      NULL, false, true);
 }
 
+static inline int
+regmap_reg_field_read(struct regmap *regmap, struct reg_field field,
+		      unsigned int *val)
+{
+	int ret;
+
+	ret = regmap_read(regmap, field.reg, val);
+	if (ret)
+		return ret;
+
+	*val = field_get(GENMASK(field.msb, field.lsb), *val);
+
+	return ret;
+}
+
+static inline int
+regmap_reg_field_write(struct regmap *regmap, struct reg_field field,
+		       unsigned int val)
+{
+	return regmap_update_bits(regmap, field.reg,
+				  GENMASK(field.msb, field.lsb),
+				  val << field.lsb);
+}
+
 /**
  * struct regmap_irq_type - IRQ type definitions.
  *
@@ -2071,6 +2096,22 @@ regmap_fields_force_update_bits(struct regmap_field *field, unsigned int id,
 	return -EINVAL;
 }
 
+static inline int
+regmap_reg_field_read(struct regmap *regmap, struct reg_field field,
+		      unsigned int *val)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int
+regmap_reg_field_write(struct regmap *regmap, struct reg_field field,
+		       unsigned int val)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
 static inline int regmap_get_val_bytes(struct regmap *map)
 {
 	WARN_ONCE(1, "regmap API is disabled");
-- 
2.53.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC PATCH 2/2] iio: accel: msa311: use regmap_reg_field_* functions
  2026-11-05  0:09 [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly Victor Chernyakin
  2026-11-05  0:09 ` [RFC PATCH 1/2] regmap: add regmap_reg_field_* APIs Victor Chernyakin
@ 2026-11-05  0:09 ` Victor Chernyakin
  2026-11-05 10:36   ` Andy Shevchenko
  2026-11-05  0:19 ` [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly Mark Brown
  2 siblings, 1 reply; 6+ messages in thread
From: Victor Chernyakin @ 2026-11-05  0:09 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: David Lechner, Nuno Sá,
	Andy Shevchenko, Uwe Kleine-König (The Capable Hub),
	Pan Chuang, Victor Chernyakin, Takashi Sakamoto, linux-iio,
	linux-kernel

Simplify the driver by using the new regmap_reg_field_* functions.
regmap_reg_field_FOO is equivalent to regmap_field_FOO, but takes
a reg_field directly instead of a regmap_field.

Tested by compiling.

Signed-off-by: Victor Chernyakin <chernyakin.victor.j@outlook.com>
---
 drivers/iio/accel/msa311.c | 297 +++++++++++++------------------------
 1 file changed, 107 insertions(+), 190 deletions(-)

diff --git a/drivers/iio/accel/msa311.c b/drivers/iio/accel/msa311.c
index caf9b1b6397f..191109ae92b1 100644
--- a/drivers/iio/accel/msa311.c
+++ b/drivers/iio/accel/msa311.c
@@ -75,137 +75,85 @@
 #define MSA311_OFFSET_Y_REG       0x39
 #define MSA311_OFFSET_Z_REG       0x3A
 
-enum msa311_fields {
-	/* Soft_Reset */
-	F_SOFT_RESET_I2C, F_SOFT_RESET_SPI,
-	/* Motion_Interrupt */
-	F_ORIENT_INT, F_S_TAP_INT, F_D_TAP_INT, F_ACTIVE_INT, F_FREEFALL_INT,
-	/* Data_Interrupt */
-	F_NEW_DATA_INT,
-	/* Tap_Active_Status */
-	F_TAP_SIGN, F_TAP_FIRST_X, F_TAP_FIRST_Y, F_TAP_FIRST_Z, F_ACTV_SIGN,
-	F_ACTV_FIRST_X, F_ACTV_FIRST_Y, F_ACTV_FIRST_Z,
-	/* Orientation_Status */
-	F_ORIENT_Z, F_ORIENT_X_Y,
-	/* Range */
-	F_FS,
-	/* ODR */
-	F_X_AXIS_DIS, F_Y_AXIS_DIS, F_Z_AXIS_DIS, F_ODR,
-	/* Power Mode/Bandwidth */
-	F_PWR_MODE, F_LOW_POWER_BW,
-	/* Swap_Polarity */
-	F_X_POLARITY, F_Y_POLARITY, F_Z_POLARITY, F_X_Y_SWAP,
-	/* Int_Set_0 */
-	F_ORIENT_INT_EN, F_S_TAP_INT_EN, F_D_TAP_INT_EN, F_ACTIVE_INT_EN_Z,
-	F_ACTIVE_INT_EN_Y, F_ACTIVE_INT_EN_X,
-	/* Int_Set_1 */
-	F_NEW_DATA_INT_EN, F_FREEFALL_INT_EN,
-	/* Int_Map_0 */
-	F_INT1_ORIENT, F_INT1_S_TAP, F_INT1_D_TAP, F_INT1_ACTIVE,
-	F_INT1_FREEFALL,
-	/* Int_Map_1 */
-	F_INT1_NEW_DATA,
-	/* Int_Config */
-	F_INT1_OD, F_INT1_LVL,
-	/* Int_Latch */
-	F_RESET_INT, F_LATCH_INT,
-	/* Freefall_Hy */
-	F_FREEFALL_MODE, F_FREEFALL_HY,
-	/* Active_Dur */
-	F_ACTIVE_DUR,
-	/* Tap_Dur */
-	F_TAP_QUIET, F_TAP_SHOCK, F_TAP_DUR,
-	/* Tap_Th */
-	F_TAP_TH,
-	/* Orient_Hy */
-	F_ORIENT_HYST, F_ORIENT_BLOCKING, F_ORIENT_MODE,
-	/* Z_Block */
-	F_Z_BLOCKING,
-	/* End of register map */
-	F_MAX_FIELDS,
-};
-
-static const struct reg_field msa311_reg_fields[] = {
-	/* Soft_Reset */
-	[F_SOFT_RESET_I2C] = REG_FIELD(MSA311_SOFT_RESET_REG, 2, 2),
-	[F_SOFT_RESET_SPI] = REG_FIELD(MSA311_SOFT_RESET_REG, 5, 5),
-	/* Motion_Interrupt */
-	[F_ORIENT_INT] = REG_FIELD(MSA311_MOTION_INT_REG, 6, 6),
-	[F_S_TAP_INT] = REG_FIELD(MSA311_MOTION_INT_REG, 5, 5),
-	[F_D_TAP_INT] = REG_FIELD(MSA311_MOTION_INT_REG, 4, 4),
-	[F_ACTIVE_INT] = REG_FIELD(MSA311_MOTION_INT_REG, 2, 2),
-	[F_FREEFALL_INT] = REG_FIELD(MSA311_MOTION_INT_REG, 0, 0),
-	/* Data_Interrupt */
-	[F_NEW_DATA_INT] = REG_FIELD(MSA311_DATA_INT_REG, 0, 0),
-	/* Tap_Active_Status */
-	[F_TAP_SIGN] = REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 7, 7),
-	[F_TAP_FIRST_X] = REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 6, 6),
-	[F_TAP_FIRST_Y] = REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 5, 5),
-	[F_TAP_FIRST_Z] = REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 4, 4),
-	[F_ACTV_SIGN] = REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 3, 3),
-	[F_ACTV_FIRST_X] = REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 2, 2),
-	[F_ACTV_FIRST_Y] = REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 1, 1),
-	[F_ACTV_FIRST_Z] = REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 0, 0),
-	/* Orientation_Status */
-	[F_ORIENT_Z] = REG_FIELD(MSA311_ORIENT_STS_REG, 6, 6),
-	[F_ORIENT_X_Y] = REG_FIELD(MSA311_ORIENT_STS_REG, 4, 5),
-	/* Range */
-	[F_FS] = REG_FIELD(MSA311_RANGE_REG, 0, 1),
-	/* ODR */
-	[F_X_AXIS_DIS] = REG_FIELD(MSA311_ODR_REG, 7, 7),
-	[F_Y_AXIS_DIS] = REG_FIELD(MSA311_ODR_REG, 6, 6),
-	[F_Z_AXIS_DIS] = REG_FIELD(MSA311_ODR_REG, 5, 5),
-	[F_ODR] = REG_FIELD(MSA311_ODR_REG, 0, 3),
-	/* Power Mode/Bandwidth */
-	[F_PWR_MODE] = REG_FIELD(MSA311_PWR_MODE_REG, 6, 7),
-	[F_LOW_POWER_BW] = REG_FIELD(MSA311_PWR_MODE_REG, 1, 4),
-	/* Swap_Polarity */
-	[F_X_POLARITY] = REG_FIELD(MSA311_SWAP_POLARITY_REG, 3, 3),
-	[F_Y_POLARITY] = REG_FIELD(MSA311_SWAP_POLARITY_REG, 2, 2),
-	[F_Z_POLARITY] = REG_FIELD(MSA311_SWAP_POLARITY_REG, 1, 1),
-	[F_X_Y_SWAP] = REG_FIELD(MSA311_SWAP_POLARITY_REG, 0, 0),
-	/* Int_Set_0 */
-	[F_ORIENT_INT_EN] = REG_FIELD(MSA311_INT_SET_0_REG, 6, 6),
-	[F_S_TAP_INT_EN] = REG_FIELD(MSA311_INT_SET_0_REG, 5, 5),
-	[F_D_TAP_INT_EN] = REG_FIELD(MSA311_INT_SET_0_REG, 4, 4),
-	[F_ACTIVE_INT_EN_Z] = REG_FIELD(MSA311_INT_SET_0_REG, 2, 2),
-	[F_ACTIVE_INT_EN_Y] = REG_FIELD(MSA311_INT_SET_0_REG, 1, 1),
-	[F_ACTIVE_INT_EN_X] = REG_FIELD(MSA311_INT_SET_0_REG, 0, 0),
-	/* Int_Set_1 */
-	[F_NEW_DATA_INT_EN] = REG_FIELD(MSA311_INT_SET_1_REG, 4, 4),
-	[F_FREEFALL_INT_EN] = REG_FIELD(MSA311_INT_SET_1_REG, 3, 3),
-	/* Int_Map_0 */
-	[F_INT1_ORIENT] = REG_FIELD(MSA311_INT_MAP_0_REG, 6, 6),
-	[F_INT1_S_TAP] = REG_FIELD(MSA311_INT_MAP_0_REG, 5, 5),
-	[F_INT1_D_TAP] = REG_FIELD(MSA311_INT_MAP_0_REG, 4, 4),
-	[F_INT1_ACTIVE] = REG_FIELD(MSA311_INT_MAP_0_REG, 2, 2),
-	[F_INT1_FREEFALL] = REG_FIELD(MSA311_INT_MAP_0_REG, 0, 0),
-	/* Int_Map_1 */
-	[F_INT1_NEW_DATA] = REG_FIELD(MSA311_INT_MAP_1_REG, 0, 0),
-	/* Int_Config */
-	[F_INT1_OD] = REG_FIELD(MSA311_INT_CONFIG_REG, 1, 1),
-	[F_INT1_LVL] = REG_FIELD(MSA311_INT_CONFIG_REG, 0, 0),
-	/* Int_Latch */
-	[F_RESET_INT] = REG_FIELD(MSA311_INT_LATCH_REG, 7, 7),
-	[F_LATCH_INT] = REG_FIELD(MSA311_INT_LATCH_REG, 0, 3),
-	/* Freefall_Hy */
-	[F_FREEFALL_MODE] = REG_FIELD(MSA311_FREEFALL_HY_REG, 2, 2),
-	[F_FREEFALL_HY] = REG_FIELD(MSA311_FREEFALL_HY_REG, 0, 1),
-	/* Active_Dur */
-	[F_ACTIVE_DUR] = REG_FIELD(MSA311_ACTIVE_DUR_REG, 0, 1),
-	/* Tap_Dur */
-	[F_TAP_QUIET] = REG_FIELD(MSA311_TAP_DUR_REG, 7, 7),
-	[F_TAP_SHOCK] = REG_FIELD(MSA311_TAP_DUR_REG, 6, 6),
-	[F_TAP_DUR] = REG_FIELD(MSA311_TAP_DUR_REG, 0, 2),
-	/* Tap_Th */
-	[F_TAP_TH] = REG_FIELD(MSA311_TAP_TH_REG, 0, 4),
-	/* Orient_Hy */
-	[F_ORIENT_HYST] = REG_FIELD(MSA311_ORIENT_HY_REG, 4, 6),
-	[F_ORIENT_BLOCKING] = REG_FIELD(MSA311_ORIENT_HY_REG, 2, 3),
-	[F_ORIENT_MODE] = REG_FIELD(MSA311_ORIENT_HY_REG, 0, 1),
-	/* Z_Block */
-	[F_Z_BLOCKING] = REG_FIELD(MSA311_Z_BLOCK_REG, 0, 3),
-};
+/* Soft_Reset */
+#define MSA311_F_SOFT_RESET_I2C	REG_FIELD(MSA311_SOFT_RESET_REG, 2, 2)
+#define MSA311_F_SOFT_RESET_SPI	REG_FIELD(MSA311_SOFT_RESET_REG, 5, 5)
+/* Motion_Interrupt */
+#define MSA311_F_ORIENT_INT	REG_FIELD(MSA311_MOTION_INT_REG, 6, 6)
+#define MSA311_F_S_TAP_INT	REG_FIELD(MSA311_MOTION_INT_REG, 5, 5)
+#define MSA311_F_D_TAP_INT	REG_FIELD(MSA311_MOTION_INT_REG, 4, 4)
+#define MSA311_F_ACTIVE_INT	REG_FIELD(MSA311_MOTION_INT_REG, 2, 2)
+#define MSA311_F_FREEFALL_INT	REG_FIELD(MSA311_MOTION_INT_REG, 0, 0)
+/* Data_Interrupt */
+#define MSA311_F_NEW_DATA_INT	REG_FIELD(MSA311_DATA_INT_REG, 0, 0)
+/* Tap_Active_Status */
+#define MSA311_F_TAP_SIGN	REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 7, 7)
+#define MSA311_F_TAP_FIRST_X	REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 6, 6)
+#define MSA311_F_TAP_FIRST_Y	REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 5, 5)
+#define MSA311_F_TAP_FIRST_Z	REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 4, 4)
+#define MSA311_F_ACTV_SIGN	REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 3, 3)
+#define MSA311_F_ACTV_FIRST_X	REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 2, 2)
+#define MSA311_F_ACTV_FIRST_Y	REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 1, 1)
+#define MSA311_F_ACTV_FIRST_Z	REG_FIELD(MSA311_TAP_ACTIVE_STS_REG, 0, 0)
+/* Orientation_Status */
+#define MSA311_F_ORIENT_Z	REG_FIELD(MSA311_ORIENT_STS_REG, 6, 6)
+#define MSA311_F_ORIENT_X_Y	REG_FIELD(MSA311_ORIENT_STS_REG, 4, 5)
+/* Range */
+#define MSA311_F_FS		REG_FIELD(MSA311_RANGE_REG, 0, 1)
+/* ODR */
+#define MSA311_F_X_AXIS_DIS	REG_FIELD(MSA311_ODR_REG, 7, 7)
+#define MSA311_F_Y_AXIS_DIS	REG_FIELD(MSA311_ODR_REG, 6, 6)
+#define MSA311_F_Z_AXIS_DIS	REG_FIELD(MSA311_ODR_REG, 5, 5)
+#define MSA311_F_ODR		REG_FIELD(MSA311_ODR_REG, 0, 3)
+/* Power Mode/Bandwidth */
+#define MSA311_F_PWR_MODE	REG_FIELD(MSA311_PWR_MODE_REG, 6, 7)
+#define MSA311_F_LOW_POWER_BW	REG_FIELD(MSA311_PWR_MODE_REG, 1, 4)
+/* Swap_Polarity */
+#define MSA311_F_X_POLARITY	REG_FIELD(MSA311_SWAP_POLARITY_REG, 3, 3)
+#define MSA311_F_Y_POLARITY	REG_FIELD(MSA311_SWAP_POLARITY_REG, 2, 2)
+#define MSA311_F_Z_POLARITY	REG_FIELD(MSA311_SWAP_POLARITY_REG, 1, 1)
+#define MSA311_F_X_Y_SWAP	REG_FIELD(MSA311_SWAP_POLARITY_REG, 0, 0)
+/* Int_Set_0 */
+#define MSA311_F_ORIENT_INT_EN		REG_FIELD(MSA311_INT_SET_0_REG, 6, 6)
+#define MSA311_F_S_TAP_INT_EN		REG_FIELD(MSA311_INT_SET_0_REG, 5, 5)
+#define MSA311_F_D_TAP_INT_EN		REG_FIELD(MSA311_INT_SET_0_REG, 4, 4)
+#define MSA311_F_ACTIVE_INT_EN_Z	REG_FIELD(MSA311_INT_SET_0_REG, 2, 2)
+#define MSA311_F_ACTIVE_INT_EN_Y	REG_FIELD(MSA311_INT_SET_0_REG, 1, 1)
+#define MSA311_F_ACTIVE_INT_EN_X	REG_FIELD(MSA311_INT_SET_0_REG, 0, 0)
+/* Int_Set_1 */
+#define MSA311_F_NEW_DATA_INT_EN	REG_FIELD(MSA311_INT_SET_1_REG, 4, 4)
+#define MSA311_F_FREEFALL_INT_EN	REG_FIELD(MSA311_INT_SET_1_REG, 3, 3)
+/* Int_Map_0 */
+#define MSA311_F_INT1_ORIENT	REG_FIELD(MSA311_INT_MAP_0_REG, 6, 6)
+#define MSA311_F_INT1_S_TAP	REG_FIELD(MSA311_INT_MAP_0_REG, 5, 5)
+#define MSA311_F_INT1_D_TAP	REG_FIELD(MSA311_INT_MAP_0_REG, 4, 4)
+#define MSA311_F_INT1_ACTIVE	REG_FIELD(MSA311_INT_MAP_0_REG, 2, 2)
+#define MSA311_F_INT1_FREEFALL	REG_FIELD(MSA311_INT_MAP_0_REG, 0, 0)
+/* Int_Map_1 */
+#define MSA311_F_INT1_NEW_DATA	REG_FIELD(MSA311_INT_MAP_1_REG, 0, 0)
+/* Int_Config */
+#define MSA311_F_INT1_OD	REG_FIELD(MSA311_INT_CONFIG_REG, 1, 1)
+#define MSA311_F_INT1_LVL	REG_FIELD(MSA311_INT_CONFIG_REG, 0, 0)
+/* Int_Latch */
+#define MSA311_F_RESET_INT	REG_FIELD(MSA311_INT_LATCH_REG, 7, 7)
+#define MSA311_F_LATCH_INT	REG_FIELD(MSA311_INT_LATCH_REG, 0, 3)
+/* Freefall_Hy */
+#define MSA311_F_FREEFALL_MODE	REG_FIELD(MSA311_FREEFALL_HY_REG, 2, 2)
+#define MSA311_F_FREEFALL_HY	REG_FIELD(MSA311_FREEFALL_HY_REG, 0, 1)
+/* Active_Dur */
+#define MSA311_F_ACTIVE_DUR	REG_FIELD(MSA311_ACTIVE_DUR_REG, 0, 1)
+/* Tap_Dur */
+#define MSA311_F_TAP_QUIET	REG_FIELD(MSA311_TAP_DUR_REG, 7, 7)
+#define MSA311_F_TAP_SHOCK	REG_FIELD(MSA311_TAP_DUR_REG, 6, 6)
+#define MSA311_F_TAP_DUR	REG_FIELD(MSA311_TAP_DUR_REG, 0, 2)
+/* Tap_Th */
+#define MSA311_F_TAP_TH		REG_FIELD(MSA311_TAP_TH_REG, 0, 4)
+/* Orient_Hy */
+#define MSA311_F_ORIENT_HYST		REG_FIELD(MSA311_ORIENT_HY_REG, 4, 6)
+#define MSA311_F_ORIENT_BLOCKING	REG_FIELD(MSA311_ORIENT_HY_REG, 2, 3)
+#define MSA311_F_ORIENT_MODE		REG_FIELD(MSA311_ORIENT_HY_REG, 0, 1)
+/* Z_Block */
+#define MSA311_F_Z_BLOCKING	REG_FIELD(MSA311_Z_BLOCK_REG, 0, 3)
 
 #define MSA311_WHO_AM_I 0x13
 
@@ -334,11 +282,7 @@ static const struct regmap_config msa311_regmap_config = {
 	.cache_type = REGCACHE_MAPLE,
 };
 
-#define MSA311_GENMASK(field) ({                \
-	typeof(&(msa311_reg_fields)[0]) _field; \
-	_field = &msa311_reg_fields[(field)];   \
-	GENMASK(_field->msb, _field->lsb);      \
-})
+#define MSA311_GENMASK(field) GENMASK((field).msb, (field).lsb)
 
 /**
  * struct msa311_priv - MSA311 internal private state
@@ -354,7 +298,6 @@ static const struct regmap_config msa311_regmap_config = {
  */
 struct msa311_priv {
 	struct regmap *regs;
-	struct regmap_field *fields[F_MAX_FIELDS];
 
 	struct device *dev;
 	struct mutex lock;
@@ -410,7 +353,7 @@ static int msa311_get_odr(struct msa311_priv *msa311, unsigned int *odr)
 {
 	int err;
 
-	err = regmap_field_read(msa311->fields[F_ODR], odr);
+	err = regmap_reg_field_read(msa311->regs, MSA311_F_ODR, odr);
 	if (err)
 		return err;
 
@@ -453,7 +396,7 @@ static int msa311_set_odr(struct msa311_priv *msa311, unsigned int odr)
 	bool good_odr;
 	int err;
 
-	err = regmap_field_read(msa311->fields[F_PWR_MODE], &pwr_mode);
+	err = regmap_reg_field_read(msa311->regs, MSA311_F_PWR_MODE, &pwr_mode);
 	if (err)
 		return err;
 
@@ -472,7 +415,7 @@ static int msa311_set_odr(struct msa311_priv *msa311, unsigned int odr)
 		return -EINVAL;
 	}
 
-	return regmap_field_write(msa311->fields[F_ODR], odr);
+	return regmap_reg_field_write(msa311->regs, MSA311_F_ODR, odr);
 }
 
 /**
@@ -538,11 +481,11 @@ static int msa311_set_pwr_mode(struct msa311_priv *msa311, unsigned int mode)
 
 	dev_dbg(dev, "transition to %s mode\n", msa311_pwr_modes[mode]);
 
-	err = regmap_field_read(msa311->fields[F_PWR_MODE], &prev_mode);
+	err = regmap_reg_field_read(msa311->regs, MSA311_F_PWR_MODE, &prev_mode);
 	if (err)
 		return err;
 
-	err = regmap_field_write(msa311->fields[F_PWR_MODE], mode);
+	err = regmap_reg_field_write(msa311->regs, MSA311_F_PWR_MODE, mode);
 	if (err)
 		return err;
 
@@ -634,7 +577,7 @@ static int msa311_read_scale(struct iio_dev *indio_dev, int *val, int *val2)
 	int err;
 
 	mutex_lock(&msa311->lock);
-	err = regmap_field_read(msa311->fields[F_FS], &fs);
+	err = regmap_reg_field_read(msa311->regs, MSA311_F_FS, &fs);
 	mutex_unlock(&msa311->lock);
 	if (err) {
 		dev_err(dev, "can't get actual scale (%pe)\n", ERR_PTR(err));
@@ -734,7 +677,7 @@ static int msa311_write_scale(struct iio_dev *indio_dev, int val, int val2)
 		/* Do not check msa311_fs_table[fs].integral, it's always 0 */
 		if (val2 == msa311_fs_table[fs].microfract) {
 			mutex_lock(&msa311->lock);
-			err = regmap_field_write(msa311->fields[F_FS], fs);
+			err = regmap_reg_field_write(msa311->regs, MSA311_F_FS, fs);
 			mutex_unlock(&msa311->lock);
 			break;
 		}
@@ -863,7 +806,7 @@ static int msa311_set_new_data_trig_state(struct iio_trigger *trig, bool state)
 	int err;
 
 	mutex_lock(&msa311->lock);
-	err = regmap_field_write(msa311->fields[F_NEW_DATA_INT_EN], state);
+	err = regmap_reg_field_write(msa311->regs, MSA311_F_NEW_DATA_INT_EN, state);
 	mutex_unlock(&msa311->lock);
 	if (err)
 		dev_err(dev,
@@ -934,8 +877,8 @@ static irqreturn_t msa311_irq_thread(int irq, void *p)
 	 * specification it's cleared automatically after a fixed time.
 	 * So just check that is enabled by driver logic.
 	 */
-	err = regmap_field_read(msa311->fields[F_NEW_DATA_INT_EN],
-				&new_data_int_enabled);
+	err = regmap_reg_field_read(msa311->regs, MSA311_F_NEW_DATA_INT_EN,
+				    &new_data_int_enabled);
 
 	mutex_unlock(&msa311->lock);
 	if (err) {
@@ -995,8 +938,8 @@ static int msa311_soft_reset(struct msa311_priv *msa311)
 	int err;
 
 	err = regmap_write(msa311->regs, MSA311_SOFT_RESET_REG,
-			   MSA311_GENMASK(F_SOFT_RESET_I2C) |
-			   MSA311_GENMASK(F_SOFT_RESET_SPI));
+			   MSA311_GENMASK(MSA311_F_SOFT_RESET_I2C) |
+			   MSA311_GENMASK(MSA311_F_SOFT_RESET_SPI));
 	if (err)
 		return dev_err_probe(dev, err, "can't soft reset all logic\n");
 
@@ -1029,9 +972,9 @@ static int msa311_chip_init(struct msa311_priv *msa311)
 
 	/* Disable all axes by default */
 	err = regmap_clear_bits(msa311->regs, MSA311_ODR_REG,
-				MSA311_GENMASK(F_X_AXIS_DIS) |
-				MSA311_GENMASK(F_Y_AXIS_DIS) |
-				MSA311_GENMASK(F_Z_AXIS_DIS));
+				MSA311_GENMASK(MSA311_F_X_AXIS_DIS) |
+				MSA311_GENMASK(MSA311_F_Y_AXIS_DIS) |
+				MSA311_GENMASK(MSA311_F_Z_AXIS_DIS));
 	if (err)
 		return dev_err_probe(dev, err, "can't enable all axes\n");
 
@@ -1074,30 +1017,30 @@ static int msa311_setup_interrupts(struct msa311_priv *msa311)
 		return dev_err_probe(dev, err,
 				     "can't register newdata trigger\n");
 
-	err = regmap_field_write(msa311->fields[F_INT1_OD],
-				 MSA311_INT1_OD_PUSH_PULL);
+	err = regmap_reg_field_write(msa311->regs, MSA311_F_INT1_OD,
+				     MSA311_INT1_OD_PUSH_PULL);
 	if (err)
 		return dev_err_probe(dev, err,
 				     "can't enable push-pull interrupt\n");
 
-	err = regmap_field_write(msa311->fields[F_INT1_LVL],
-				 MSA311_INT1_LVL_HIGH);
+	err = regmap_reg_field_write(msa311->regs, MSA311_F_INT1_LVL,
+				     MSA311_INT1_LVL_HIGH);
 	if (err)
 		return dev_err_probe(dev, err,
 				     "can't set active interrupt level\n");
 
-	err = regmap_field_write(msa311->fields[F_LATCH_INT],
-				 MSA311_LATCH_INT_LATCHED);
+	err = regmap_reg_field_write(msa311->regs, MSA311_F_LATCH_INT,
+				     MSA311_LATCH_INT_LATCHED);
 	if (err)
 		return dev_err_probe(dev, err,
 				     "can't latch interrupt\n");
 
-	err = regmap_field_write(msa311->fields[F_RESET_INT], 1);
+	err = regmap_reg_field_write(msa311->regs, MSA311_F_RESET_INT, 1);
 	if (err)
 		return dev_err_probe(dev, err,
 				     "can't reset interrupt\n");
 
-	err = regmap_field_write(msa311->fields[F_INT1_NEW_DATA], 1);
+	err = regmap_reg_field_write(msa311->regs, MSA311_F_INT1_NEW_DATA, 1);
 	if (err)
 		return dev_err_probe(dev, err,
 				     "can't map new data interrupt\n");
@@ -1105,33 +1048,6 @@ static int msa311_setup_interrupts(struct msa311_priv *msa311)
 	return 0;
 }
 
-static int msa311_regmap_init(struct msa311_priv *msa311)
-{
-	struct regmap_field **fields = msa311->fields;
-	struct device *dev = msa311->dev;
-	struct i2c_client *i2c = to_i2c_client(dev);
-	struct regmap *regmap;
-	int i;
-
-	regmap = devm_regmap_init_i2c(i2c, &msa311_regmap_config);
-	if (IS_ERR(regmap))
-		return dev_err_probe(dev, PTR_ERR(regmap),
-				     "failed to register i2c regmap\n");
-
-	msa311->regs = regmap;
-
-	for (i = 0; i < F_MAX_FIELDS; i++) {
-		fields[i] = devm_regmap_field_alloc(dev,
-						    msa311->regs,
-						    msa311_reg_fields[i]);
-		if (IS_ERR(msa311->fields[i]))
-			return dev_err_probe(dev, PTR_ERR(msa311->fields[i]),
-					     "can't alloc field[%d]\n", i);
-	}
-
-	return 0;
-}
-
 static void msa311_powerdown(void *msa311)
 {
 	msa311_set_pwr_mode(msa311, MSA311_PWR_MODE_SUSPEND);
@@ -1152,9 +1068,10 @@ static int msa311_probe(struct i2c_client *i2c)
 	msa311->dev = dev;
 	i2c_set_clientdata(i2c, indio_dev);
 
-	err = msa311_regmap_init(msa311);
-	if (err)
-		return err;
+	msa311->regs = devm_regmap_init_i2c(i2c, &msa311_regmap_config);
+	if (IS_ERR(msa311->regs))
+		return dev_err_probe(dev, PTR_ERR(msa311->regs),
+				     "failed to register i2c regmap\n");
 
 	mutex_init(&msa311->lock);
 
-- 
2.53.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly
  2026-11-05  0:09 [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly Victor Chernyakin
  2026-11-05  0:09 ` [RFC PATCH 1/2] regmap: add regmap_reg_field_* APIs Victor Chernyakin
  2026-11-05  0:09 ` [RFC PATCH 2/2] iio: accel: msa311: use regmap_reg_field_* functions Victor Chernyakin
@ 2026-11-05  0:19 ` Mark Brown
  2026-11-05  0:23   ` Victor Chernyakin
  2 siblings, 1 reply; 6+ messages in thread
From: Mark Brown @ 2026-11-05  0:19 UTC (permalink / raw)
  To: Victor Chernyakin; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 463 bytes --]

On Wed, Nov 04, 2026 at 06:09:48PM -0600, Victor Chernyakin wrote:

> This is not actually a new idea! Both it and the current *_alloc approach
> were suggested as alternatives right when the regmap_field_* APIs were
> being added [1]. The *_alloc approach was chosen without much
> discussion, but I think (and Patch 2 demonstrates, I hope) that
> this approach is the cleaner one.

The demonstration in patch 2 would be a lot clearer had I been sent
patch 2...

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly
  2026-11-05  0:19 ` [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly Mark Brown
@ 2026-11-05  0:23   ` Victor Chernyakin
  0 siblings, 0 replies; 6+ messages in thread
From: Victor Chernyakin @ 2026-11-05  0:23 UTC (permalink / raw)
  To: broonie; +Cc: chernyakin.victor.j, linux-kernel

> > This is not actually a new idea! Both it and the current *_alloc approach
> > were suggested as alternatives right when the regmap_field_* APIs were
> > being added [1]. The *_alloc approach was chosen without much
> > discussion, but I think (and Patch 2 demonstrates, I hope) that
> > this approach is the cleaner one.
> 
> The demonstration in patch 2 would be a lot clearer had I been sent
> patch 2...

That's what I get for just blindly using get_maintainer.pl, sorry
about that. Sent it to you now.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH 2/2] iio: accel: msa311: use regmap_reg_field_* functions
  2026-11-05  0:09 ` [RFC PATCH 2/2] iio: accel: msa311: use regmap_reg_field_* functions Victor Chernyakin
@ 2026-11-05 10:36   ` Andy Shevchenko
  0 siblings, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2026-11-05 10:36 UTC (permalink / raw)
  To: Victor Chernyakin
  Cc: Jonathan Cameron, David Lechner, Nuno Sá,
	Andy Shevchenko, Uwe Kleine-König (The Capable Hub),
	Pan Chuang, Takashi Sakamoto, linux-iio, linux-kernel

On Wed, Nov 04, 2026 at 06:09:50PM -0600, Victor Chernyakin wrote:
> Simplify the driver by using the new regmap_reg_field_* functions.
> regmap_reg_field_FOO is equivalent to regmap_field_FOO, but takes
> a reg_field directly instead of a regmap_field.

I have just proposed REG_FIELD_GENMASK() macro, this change may rely on it
20261105103533.1426533-1-andriy.shevchenko@linux.intel.com if it comes through.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-11-05 10:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-05  0:09 [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly Victor Chernyakin
2026-11-05  0:09 ` [RFC PATCH 1/2] regmap: add regmap_reg_field_* APIs Victor Chernyakin
2026-11-05  0:09 ` [RFC PATCH 2/2] iio: accel: msa311: use regmap_reg_field_* functions Victor Chernyakin
2026-11-05 10:36   ` Andy Shevchenko
2026-11-05  0:19 ` [RFC PATCH 0/2] regmap: add APIs to bypass regmap_field and work with reg_field directly Mark Brown
2026-11-05  0:23   ` Victor Chernyakin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®