linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/5] regmap: Add Parity bit Calculation to regmaps
@ 2021-12-22 18:43 linuxkernel
  2021-12-22 18:43 ` [RFC PATCH v2 1/5] " linuxkernel
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: linuxkernel @ 2021-12-22 18:43 UTC (permalink / raw)
  To: linux-kernel; +Cc: broonie

From: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>

this patch set adds parity bit calculation to regmaps

this allow support for devices that require parity bits in their
communications.

e.g. the texas instruments TPS92518-Q1 which requires a parity bit in the
7th bit of a 16 bit spi frame
or the TPS92518-Q1 which requires a parity bit in the 1st bit of a 16 bit
spi frame

parity aimed to work devices where parity in reg block
e.g. TPS65311-Q1 and TPS92518-Q1

TPS65311-Q1 frame format	[PWRRRRRRDDDDDDDD]
TPS92518-Q1	frame format	[WRRRRRPDDDDDDDDD]
P - parity bit, W - Read/Write bit, R - register, D -register data

TPS65311-Q1 parity mask 0x8000 (1000000000000000)
TPS92518-Q1	parity mask	0x0200 (0000001000000000)


calculates parity bit based up parity function defined by
regmap_config->parity_calc

regmap_config->parity_calc defaults to regmap_parity_calc_even()

adds alternate parity function regmap_parity_calc_odd()

calculates parity bit for writes if regmap_config->parity_write_mask is > 0
calculates parity bit for reads if regmap_config->parity_read_mask is > 0

parity is not calculated when bus implements reg_update_bits()


Altered the regmap_format_X_X_write functions to account for padding bits
allowing masks to write to either end of register address for formatted writes

Altered formatted_write to apply write and parity masks

Added parsers for 9 bit data format which are written by formatted write

Christopher Tyerman (5):
  Add Parity bit Calculation to regmaps
  Altered regmap_format_X_X_write functions to account for padding bits
  Added setting of writemap to formatted write
  Add Parity Calculation to formatted write
  Add parser for X_9 formats

 drivers/base/regmap/internal.h |   6 +
 drivers/base/regmap/regmap.c   | 259 +++++++++++++++++++++++++++++++--
 include/linux/regmap.h         |  32 ++++
 3 files changed, 287 insertions(+), 10 deletions(-)


base-commit: 02d6fdecb9c38de19065f6bed8d5214556fd061d
-- 
2.25.1


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

* [RFC PATCH v2 1/5] Add Parity bit Calculation to regmaps
  2021-12-22 18:43 [RFC PATCH v2 0/5] regmap: Add Parity bit Calculation to regmaps linuxkernel
@ 2021-12-22 18:43 ` linuxkernel
  2022-01-05 16:51   ` Mark Brown
  2021-12-22 18:43 ` [RFC PATCH v2 2/5] Altered regmap_format_X_X_write functions to account for padding bits linuxkernel
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: linuxkernel @ 2021-12-22 18:43 UTC (permalink / raw)
  To: linux-kernel; +Cc: broonie

From: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>

regmap.h

Added bitmasks "parity_read_mask" and "parity_write_mask" for read
and write operations to regmap_config bit mask defines location of
the parity bit.

Added optional callback "parity_calc" to regmap_config to
calculate parity bit value

Added regmap_parity_calc_even() and regmap_parity_calc_odd()
functions to regmap_config for standard parity calculations.

internal.h

Added bitmasks "parity_read_mask" and "parity_write_mask" for read
and write operations to regmap bit mask defines location of
the parity bit.

Added optional callback "parity_calc" to regmap to
calculate parity bit value

Added regmap_parity_calc_even() and regmap_parity_calc_odd()
functions to regmap to for standard parity calculations.

regmap.c

Added parity8(), parity16(), parity32() and parity64() bitwise parity
bit calculation functions for different unsigned integer sizes.

Added parity_even() parity calculation for unsigned int that
uses appropriate parityX fixed size function

Added regmap_parity_calc_even() that calculate bool value of even
parity bit from read/write mask, reg and val using appropriate
combinations of parityX functions

Added regmap_parity_calc_odd() that just boolean complement of
regmap_parity_calc_even()

Altered *__regmap_init to copy parity_read_mask, parity_write_mask
and parity_calc to from config to map and assign default
regmap_parity_calc_even() to map->parity_calc if map->parity_calc()
undefined.

Added regmap_set_work_buf_parity_mask() that sets the parity bit in
provided workbuf to calculated parity value using assigned
map->parity_calc() using rwmask, reg and val for calculation
and mask for bit location

Altered _regmap_raw_write_impl() to calculate parity by adding call
to regmap_set_work_buf_parity_mask()

Altered _regmap_raw_read() to calculate parity by adding call
to regmap_set_work_buf_parity_mask()

	modified:   drivers/base/regmap/internal.h
	modified:   drivers/base/regmap/regmap.c
	modified:   include/linux/regmap.h

Signed-off-by: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>
---
 drivers/base/regmap/internal.h |   6 ++
 drivers/base/regmap/regmap.c   | 168 ++++++++++++++++++++++++++++++++-
 include/linux/regmap.h         |  32 +++++++
 3 files changed, 204 insertions(+), 2 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index b1905916f7af..78df50694cf4 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -168,6 +168,12 @@ struct regmap {
 
 	/* if set, the regmap core can sleep */
 	bool can_sleep;
+
+	unsigned long parity_write_mask;
+	unsigned long parity_read_mask;
+
+	bool (*parity_calc)(unsigned long rwmask, unsigned int reg,
+						const void *val, size_t val_len);
 };
 
 struct regcache_ops {
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 2d74f9f82aa9..05c104659381 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -57,6 +57,13 @@ static int _regmap_bus_reg_write(void *context, unsigned int reg,
 static int _regmap_bus_raw_write(void *context, unsigned int reg,
 				 unsigned int val);
 
+static bool parity_even(uint v);
+
+static bool parity8_even(u8 v);
+static bool parity16_even(u16 v);
+static bool parity32_even(u32 v);
+static bool parity64_even(u64 v);
+
 bool regmap_reg_in_ranges(unsigned int reg,
 			  const struct regmap_range *ranges,
 			  unsigned int nranges)
@@ -892,6 +899,14 @@ struct regmap *__regmap_init(struct device *dev,
 		map->reg_update_bits = bus->reg_update_bits;
 	}
 
+	map->parity_write_mask = config->parity_write_mask;
+	map->parity_read_mask = config->parity_read_mask;
+
+	if (config->parity_calc)
+		map->parity_calc = config->parity_calc;
+	else
+		map->parity_calc = regmap_parity_calc_even;
+
 	reg_endian = regmap_get_reg_endian(bus, config);
 	val_endian = regmap_get_val_endian(dev, bus, config);
 
@@ -1655,6 +1670,31 @@ static void regmap_set_work_buf_flag_mask(struct regmap *map, int max_bytes,
 		buf[i] |= (mask >> (8 * i)) & 0xff;
 }
 
+static void regmap_set_work_buf_parity_mask(struct regmap *map, int max_bytes,
+					  unsigned long mask, unsigned long rwmask,
+					  unsigned int reg, const void *val, size_t val_len)
+{
+
+	bool paritybit;
+	u8 *buf;
+	int i;
+
+	if (!mask || !map->work_buf)
+		return;
+
+	paritybit = map->parity_calc(rwmask, reg, val, val_len);
+
+
+	if (paritybit) {
+		buf = map->work_buf;
+
+		for (i = 0; i < max_bytes; i++)
+			buf[i] |= (mask >> (8 * i)) & 0xff;
+	}
+}
+
+
+
 static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
 				  const void *val, size_t val_len, bool noinc)
 {
@@ -1736,7 +1776,12 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
 
 	map->format.format_reg(map->work_buf, reg, map->reg_shift);
 	regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
-				      map->write_flag_mask);
+								  map->write_flag_mask);
+
+
+	regmap_set_work_buf_parity_mask(map, map->format.reg_bytes,
+				map->parity_write_mask, map->write_flag_mask, reg, val, val_len);
+
 
 	/*
 	 * Essentially all I/O mechanisms will be faster with a single
@@ -1748,6 +1793,9 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
 		val = work_val;
 	}
 
+
+
+
 	if (map->async && map->bus->async_write) {
 		struct regmap_async *async;
 
@@ -2674,7 +2722,12 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 
 	map->format.format_reg(map->work_buf, reg, map->reg_shift);
 	regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
-				      map->read_flag_mask);
+						map->read_flag_mask);
+
+	regmap_set_work_buf_parity_mask(map, map->format.reg_bytes,
+						map->parity_read_mask, map->read_flag_mask, reg,
+						val, val_len);
+
 	trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes);
 
 	ret = map->bus->read(map->bus_context, map->work_buf,
@@ -3340,3 +3393,114 @@ static int __init regmap_initcall(void)
 	return 0;
 }
 postcore_initcall(regmap_initcall);
+
+
+/**
+ * regmap_parity_calc_even() - calculates Value of parity bit for even parity
+ *
+ * @rwmask: value of the read/write mask
+ * @reg: value of register
+ * @val: pointer to value of data
+ * @val_len: size of val
+ *
+ * Calculate the value of the parity bit for even parity
+ */
+bool regmap_parity_calc_even(unsigned long rwmask, unsigned int reg,
+							 const void *val, size_t val_len)
+{
+	bool paritybuf = 0;
+	uint count = 0;
+
+	while (count < val_len) {
+		if (val_len - count >= 8) {
+			paritybuf ^= parity64_even(*(u64 *)val+count);
+			count += 8;
+		} else if (val_len - count >= 4) {
+			paritybuf ^= parity32_even(*(u32 *)val+count);
+			count += 4;
+		} else if (val_len - count >= 2) {
+			paritybuf ^= parity16_even(*(u16 *)val+count);
+			count += 2;
+		} else if (val_len - count >= 1) {
+			paritybuf ^= parity8_even(*(u8 *)val+count);
+			count += 1;
+		}
+	}
+
+	return (parity_even(rwmask) ^ parity_even(reg) ^ paritybuf);
+}
+EXPORT_SYMBOL_GPL(regmap_parity_calc_even);
+
+/**
+ * regmap_parity_calc_odd() - calculates Value of parity bit for odd parity
+ *
+ * @rwmask: value of the read/write mask
+ * @reg: value of register
+ * @val: pointer to value of data
+ * @val_len: size of val
+ *
+ * Calculate the value of the parity bit for odd parity
+ */
+
+bool regmap_parity_calc_odd(unsigned long rwmask, unsigned int reg,
+							const void *val, size_t val_len)
+{
+	return !(regmap_parity_calc_even(rwmask, reg, val, val_len));
+
+
+}
+EXPORT_SYMBOL_GPL(regmap_parity_calc_odd);
+
+static bool parity_even(uint v)
+{
+	switch (sizeof(v)) {
+	case 1:
+		return parity8_even((u8)v);
+	case 2:
+		return parity16_even((u16)v);
+	case 4:
+		return parity32_even((u32)v);
+	case 8:
+	default:
+		return parity64_even((u64)v);
+
+	}
+}
+static bool parity8_even(u8 v)
+{
+	v ^= v >> 4;
+	v ^= v >> 2;
+	v ^= v >> 1;
+	return v & 1;
+}
+
+
+static bool parity16_even(u16 v)
+{
+	v ^= v >> 8;
+	v ^= v >> 4;
+	v ^= v >> 2;
+	v ^= v >> 1;
+	return v & 1;
+}
+
+static bool parity32_even(u32 v)
+{
+	v ^= v >> 16;
+	v ^= v >> 8;
+	v ^= v >> 4;
+	v ^= v >> 2;
+	v ^= v >> 1;
+	return v & 1;
+}
+
+static bool parity64_even(u64 v)
+{
+	v ^= v >> 32;
+	v ^= v >> 16;
+	v ^= v >> 8;
+	v ^= v >> 4;
+	v ^= v >> 2;
+	v ^= v >> 1;
+	return v & 1;
+}
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 22652e5fbc38..511fc9228e1d 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -354,6 +354,10 @@ typedef void (*regmap_unlock)(void *);
  * @hwlock_mode: The hardware spinlock mode, should be HWLOCK_IRQSTATE,
  *		 HWLOCK_IRQ or 0.
  * @can_sleep: Optional, specifies whether regmap operations can sleep.
+ *
+ * @parity_read_mask: bit mask of location of parity bit for reads
+ * @parity_write_mask: bit mask of location of parity bit for writes
+ * @parity_calc: Optional callback to calculate parity, defaults to even parity
  */
 struct regmap_config {
 	const char *name;
@@ -416,6 +420,12 @@ struct regmap_config {
 	unsigned int hwlock_mode;
 
 	bool can_sleep;
+
+	unsigned long parity_read_mask;
+	unsigned long parity_write_mask;
+	bool (*parity_calc)(unsigned long rwmask, unsigned int reg,
+						const void *val, size_t val_len);
+
 };
 
 /**
@@ -1237,6 +1247,11 @@ static inline int regmap_clear_bits(struct regmap *map,
 
 int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits);
 
+bool regmap_parity_calc_even(unsigned long rwmask, unsigned int reg,
+								const void *val, size_t val_len);
+bool regmap_parity_calc_odd(unsigned long rwmask, unsigned int reg,
+								const void *val, size_t val_len);
+
 /**
  * struct reg_field - Description of an register field
  *
@@ -1866,6 +1881,23 @@ static inline struct device *regmap_get_device(struct regmap *map)
 	return NULL;
 }
 
+static inline bool regmap_parity_calc_even(unsigned long rwmask, unsigned int reg,
+						const void *val, size_t val_len)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return NULL;
+}
+
+static inline bool regmap_parity_calc_odd(unsigned long rwmask, unsigned int reg,
+						const void *val, size_t val_len)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return NULL;
+}
+
+
 #endif
 
+
+
 #endif
-- 
2.25.1


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

* [RFC PATCH v2 2/5] Altered regmap_format_X_X_write functions to account for padding bits
  2021-12-22 18:43 [RFC PATCH v2 0/5] regmap: Add Parity bit Calculation to regmaps linuxkernel
  2021-12-22 18:43 ` [RFC PATCH v2 1/5] " linuxkernel
@ 2021-12-22 18:43 ` linuxkernel
  2021-12-22 18:43 ` [RFC PATCH v2 3/5] Added setting of writemap to formatted write linuxkernel
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: linuxkernel @ 2021-12-22 18:43 UTC (permalink / raw)
  To: linux-kernel; +Cc: broonie

From: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>

Altered regmap_format_X_X_write functions to account for padding bits by
adjusting reg position shifts by value of map->reg_shift

as map->format.format_write is selected based on
(config->reg_bits + map->reg_shift) each regmap_format_X_X_write needs
to account for map->reg_shift or will be misaligned if padding bits
greater than zero

	modified:   drivers/base/regmap/regmap.c

Signed-off-by: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>
---
 drivers/base/regmap/regmap.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 05c104659381..05c65312a9b3 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -220,9 +220,14 @@ static void regmap_format_12_20_write(struct regmap *map,
 				     unsigned int reg, unsigned int val)
 {
 	u8 *out = map->work_buf;
+	u8 shift = map->reg_shift;
 
-	out[0] = reg >> 4;
-	out[1] = (reg << 4) | (val >> 16);
+	if (shift <= 4)
+		out[0] = reg >> (4 - shift);
+	else
+		out[0] = reg << (shift - 4);
+
+	out[1] = (reg << 4 + shift) | (val >> 16);
 	out[2] = val >> 8;
 	out[3] = val;
 }
@@ -232,42 +237,52 @@ static void regmap_format_2_6_write(struct regmap *map,
 				     unsigned int reg, unsigned int val)
 {
 	u8 *out = map->work_buf;
+	u8 shift = map->reg_shift;
 
-	*out = (reg << 6) | val;
+	*out = (reg << (6 + shift) | val);
 }
 
 static void regmap_format_4_12_write(struct regmap *map,
 				     unsigned int reg, unsigned int val)
 {
+	u8 shift = map->reg_shift;
 	__be16 *out = map->work_buf;
-	*out = cpu_to_be16((reg << 12) | val);
+
+	*out = cpu_to_be16((reg << (12 + shift)) | val);
 }
 
 static void regmap_format_7_9_write(struct regmap *map,
 				    unsigned int reg, unsigned int val)
 {
+	u8 shift = map->reg_shift;
 	__be16 *out = map->work_buf;
-	*out = cpu_to_be16((reg << 9) | val);
+
+	*out = cpu_to_be16((reg << (9 + shift)) | val);
 }
 
 static void regmap_format_7_17_write(struct regmap *map,
 				    unsigned int reg, unsigned int val)
 {
+	u8 shift = map->reg_shift;
 	u8 *out = map->work_buf;
 
 	out[2] = val;
 	out[1] = val >> 8;
-	out[0] = (val >> 16) | (reg << 1);
+	out[0] = (val >> 16) | (reg << (1 + shift));
 }
 
 static void regmap_format_10_14_write(struct regmap *map,
 				    unsigned int reg, unsigned int val)
 {
+	u8 shift = map->reg_shift;
 	u8 *out = map->work_buf;
 
 	out[2] = val;
-	out[1] = (val >> 8) | (reg << 6);
-	out[0] = reg >> 2;
+	out[1] = (val >> 8) | (reg << (6 + shift));
+	if (shift <= 2)
+		out[0] = reg >> (2 - shift);
+	else
+		out[0] = reg << (shift - 2);
 }
 
 static void regmap_format_8(void *buf, unsigned int val, unsigned int shift)
-- 
2.25.1


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

* [RFC PATCH v2 3/5] Added setting of writemap to formatted write
  2021-12-22 18:43 [RFC PATCH v2 0/5] regmap: Add Parity bit Calculation to regmaps linuxkernel
  2021-12-22 18:43 ` [RFC PATCH v2 1/5] " linuxkernel
  2021-12-22 18:43 ` [RFC PATCH v2 2/5] Altered regmap_format_X_X_write functions to account for padding bits linuxkernel
@ 2021-12-22 18:43 ` linuxkernel
  2021-12-22 18:43 ` [RFC PATCH v2 4/5] Add Parity Calculation " linuxkernel
  2021-12-22 18:43 ` [RFC PATCH v2 5/5] Add parser for X_9 formats linuxkernel
  4 siblings, 0 replies; 7+ messages in thread
From: linuxkernel @ 2021-12-22 18:43 UTC (permalink / raw)
  To: linux-kernel; +Cc: broonie

From: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>

Added regmap_set_work_buf_flag_mask to _regmap_bus_formatted_write
to ensure correct write bit value set when writemask defined

	modified:   drivers/base/regmap/regmap.c

Signed-off-by: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>
---
 drivers/base/regmap/regmap.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 05c65312a9b3..0761c854ae3b 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1969,6 +1969,9 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
 
 	map->format.format_write(map, reg, val);
 
+	regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
+					      map->write_flag_mask);
+
 	trace_regmap_hw_write_start(map, reg, 1);
 
 	ret = map->bus->write(map->bus_context, map->work_buf,
-- 
2.25.1


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

* [RFC PATCH v2 4/5] Add Parity Calculation to formatted write
  2021-12-22 18:43 [RFC PATCH v2 0/5] regmap: Add Parity bit Calculation to regmaps linuxkernel
                   ` (2 preceding siblings ...)
  2021-12-22 18:43 ` [RFC PATCH v2 3/5] Added setting of writemap to formatted write linuxkernel
@ 2021-12-22 18:43 ` linuxkernel
  2021-12-22 18:43 ` [RFC PATCH v2 5/5] Add parser for X_9 formats linuxkernel
  4 siblings, 0 replies; 7+ messages in thread
From: linuxkernel @ 2021-12-22 18:43 UTC (permalink / raw)
  To: linux-kernel; +Cc: broonie

From: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>

Altered formated write to set parity bit according to parity_write_mask

	modified:   drivers/base/regmap/regmap.c

Signed-off-by: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>
---
 drivers/base/regmap/regmap.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 0761c854ae3b..177f2010a490 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1972,6 +1972,10 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
 	regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
 					      map->write_flag_mask);
 
+	regmap_set_work_buf_parity_mask(map, map->format.reg_bytes,
+						map->parity_write_mask, map->write_flag_mask, reg,
+						&val, sizeof(val));
+
 	trace_regmap_hw_write_start(map, reg, 1);
 
 	ret = map->bus->write(map->bus_context, map->work_buf,
-- 
2.25.1


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

* [RFC PATCH v2 5/5] Add parser for X_9 formats
  2021-12-22 18:43 [RFC PATCH v2 0/5] regmap: Add Parity bit Calculation to regmaps linuxkernel
                   ` (3 preceding siblings ...)
  2021-12-22 18:43 ` [RFC PATCH v2 4/5] Add Parity Calculation " linuxkernel
@ 2021-12-22 18:43 ` linuxkernel
  4 siblings, 0 replies; 7+ messages in thread
From: linuxkernel @ 2021-12-22 18:43 UTC (permalink / raw)
  To: linux-kernel; +Cc: broonie

From: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>

added 9 bit Parser functions

these operate in same way as 16 bit parsers but mask out higher bits

regmap_parse_9_be()
regmap_parse_9_be_inplace()
regmap_parse_9_le()
regmap_parse_9_le_inplace()
regmap_parse_9_native()

	modified:   drivers/base/regmap/regmap.c

Signed-off-by: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>
---
 drivers/base/regmap/regmap.c | 53 ++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 177f2010a490..40579975209a 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -370,6 +370,39 @@ static unsigned int regmap_parse_8(const void *buf)
 	return b[0];
 }
 
+static unsigned int regmap_parse_9_be(const void *buf)
+{
+	return get_unaligned_be16(buf) & 0x1FF;
+}
+
+static unsigned int regmap_parse_9_le(const void *buf)
+{
+
+	return get_unaligned_le16(buf) & 0x1FF;
+}
+
+static void regmap_parse_9_be_inplace(void *buf)
+{
+	u16 v = get_unaligned_be16(buf) & 0x1FF;
+
+	memcpy(buf, &v, sizeof(v));
+}
+
+static void regmap_parse_9_le_inplace(void *buf)
+{
+	u16 v = get_unaligned_le16(buf) & 0x1FF;
+
+	memcpy(buf, &v, sizeof(v));
+}
+
+static unsigned int regmap_parse_9_native(const void *buf)
+{
+	u16 v;
+
+	memcpy(&v, buf, sizeof(v));
+	return v & 0x1FF;
+}
+
 static unsigned int regmap_parse_16_be(const void *buf)
 {
 	return get_unaligned_be16(buf);
@@ -1052,6 +1085,26 @@ struct regmap *__regmap_init(struct device *dev,
 		map->format.parse_val = regmap_parse_8;
 		map->format.parse_inplace = regmap_parse_inplace_noop;
 		break;
+	case 9:
+		switch (val_endian) {
+		case REGMAP_ENDIAN_BIG:
+			//map->format.format_val = regmap_format_9_be;
+			map->format.parse_val = regmap_parse_9_be;
+			map->format.parse_inplace = regmap_parse_9_be_inplace;
+			break;
+		case REGMAP_ENDIAN_LITTLE:
+			//map->format.format_val = regmap_format_9_le;
+			map->format.parse_val = regmap_parse_9_le;
+			map->format.parse_inplace = regmap_parse_9_le_inplace;
+			break;
+		case REGMAP_ENDIAN_NATIVE:
+			//map->format.format_val = regmap_format_9_native;
+			map->format.parse_val = regmap_parse_9_native;
+			break;
+		default:
+			goto err_hwlock;
+		}
+		break;
 	case 16:
 		switch (val_endian) {
 		case REGMAP_ENDIAN_BIG:
-- 
2.25.1


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

* Re: [RFC PATCH v2 1/5] Add Parity bit Calculation to regmaps
  2021-12-22 18:43 ` [RFC PATCH v2 1/5] " linuxkernel
@ 2022-01-05 16:51   ` Mark Brown
  0 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2022-01-05 16:51 UTC (permalink / raw)
  To: linuxkernel; +Cc: linux-kernel

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

On Wed, Dec 22, 2021 at 06:43:36PM +0000, linuxkernel@fbautosys.co.uk wrote:
> From: Christopher Tyerman <c.tyerman@firebladeautomationsystems.co.uk>
> 
> regmap.h
> 
> Added bitmasks "parity_read_mask" and "parity_write_mask" for read
> and write operations to regmap_config bit mask defines location of
> the parity bit.
> 
> Added optional callback "parity_calc" to regmap_config to
> calculate parity bit value

This is still more a list of changes in the code rather than a normal
changelog which is making it really hard to review - I'm getting lost
with the patch description trying to figure out what the idea here is or
how this is all supposed to fit together.  Like I said last time please
look at submitting-patches.rst.  It's probably also useful to look at
how other kernel changelogs are written and follow a similar style.

Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.

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

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

end of thread, other threads:[~2022-01-05 16:51 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-22 18:43 [RFC PATCH v2 0/5] regmap: Add Parity bit Calculation to regmaps linuxkernel
2021-12-22 18:43 ` [RFC PATCH v2 1/5] " linuxkernel
2022-01-05 16:51   ` Mark Brown
2021-12-22 18:43 ` [RFC PATCH v2 2/5] Altered regmap_format_X_X_write functions to account for padding bits linuxkernel
2021-12-22 18:43 ` [RFC PATCH v2 3/5] Added setting of writemap to formatted write linuxkernel
2021-12-22 18:43 ` [RFC PATCH v2 4/5] Add Parity Calculation " linuxkernel
2021-12-22 18:43 ` [RFC PATCH v2 5/5] Add parser for X_9 formats linuxkernel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).