* [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
* 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
* [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
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).