Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regmap: Use pad_bits and reg_bits when determining register format.

This change combines any padding bits into the register address bits when
determining register format handlers to use the next byte-divisible
register size.
A reg_shift member is introduced to the regmap struct to enable fixup
of the reg format.
Format handlers now take an extra parameter specifying the number of
bits to shift the value by.

Signed-off-by: Marc Reilly <marc@cpdesign.com.au>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Marc Reilly and committed by
Mark Brown
d939fb9a ea279fc5

+20 -14
+5 -2
drivers/base/regmap/internal.h
··· 26 26 size_t val_bytes; 27 27 void (*format_write)(struct regmap *map, 28 28 unsigned int reg, unsigned int val); 29 - void (*format_reg)(void *buf, unsigned int reg); 30 - void (*format_val)(void *buf, unsigned int val); 29 + void (*format_reg)(void *buf, unsigned int reg, unsigned int shift); 30 + void (*format_val)(void *buf, unsigned int val, unsigned int shift); 31 31 unsigned int (*parse_val)(void *buf); 32 32 }; 33 33 ··· 51 51 52 52 u8 read_flag_mask; 53 53 u8 write_flag_mask; 54 + 55 + /* number of bits to (left) shift the reg value when formatting*/ 56 + int reg_shift; 54 57 55 58 /* regcache specific members */ 56 59 const struct regcache_ops *cache_ops;
+15 -12
drivers/base/regmap/regmap.c
··· 112 112 out[0] = reg >> 2; 113 113 } 114 114 115 - static void regmap_format_8(void *buf, unsigned int val) 115 + static void regmap_format_8(void *buf, unsigned int val, unsigned int shift) 116 116 { 117 117 u8 *b = buf; 118 118 119 - b[0] = val; 119 + b[0] = val << shift; 120 120 } 121 121 122 - static void regmap_format_16(void *buf, unsigned int val) 122 + static void regmap_format_16(void *buf, unsigned int val, unsigned int shift) 123 123 { 124 124 __be16 *b = buf; 125 125 126 - b[0] = cpu_to_be16(val); 126 + b[0] = cpu_to_be16(val << shift); 127 127 } 128 128 129 - static void regmap_format_24(void *buf, unsigned int val) 129 + static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) 130 130 { 131 131 u8 *b = buf; 132 + 133 + val <<= shift; 132 134 133 135 b[0] = val >> 16; 134 136 b[1] = val >> 8; 135 137 b[2] = val; 136 138 } 137 139 138 - static void regmap_format_32(void *buf, unsigned int val) 140 + static void regmap_format_32(void *buf, unsigned int val, unsigned int shift) 139 141 { 140 142 __be32 *b = buf; 141 143 142 - b[0] = cpu_to_be32(val); 144 + b[0] = cpu_to_be32(val << shift); 143 145 } 144 146 145 147 static unsigned int regmap_parse_8(void *buf) ··· 212 210 map->format.pad_bytes = config->pad_bits / 8; 213 211 map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); 214 212 map->format.buf_size += map->format.pad_bytes; 213 + map->reg_shift = config->pad_bits % 8; 215 214 map->dev = dev; 216 215 map->bus = bus; 217 216 map->max_register = config->max_register; ··· 229 226 map->read_flag_mask = bus->read_flag_mask; 230 227 } 231 228 232 - switch (config->reg_bits) { 229 + switch (config->reg_bits + map->reg_shift) { 233 230 case 2: 234 231 switch (config->val_bits) { 235 232 case 6: ··· 457 454 } 458 455 } 459 456 460 - map->format.format_reg(map->work_buf, reg); 457 + map->format.format_reg(map->work_buf, reg, map->reg_shift); 461 458 462 459 u8[0] |= map->write_flag_mask; 463 460 ··· 532 529 return ret; 533 530 } else { 534 531 map->format.format_val(map->work_buf + map->format.reg_bytes 535 - + map->format.pad_bytes, val); 532 + + map->format.pad_bytes, val, 0); 536 533 return _regmap_raw_write(map, reg, 537 534 map->work_buf + 538 535 map->format.reg_bytes + ··· 652 649 u8 *u8 = map->work_buf; 653 650 int ret; 654 651 655 - map->format.format_reg(map->work_buf, reg); 652 + map->format.format_reg(map->work_buf, reg, map->reg_shift); 656 653 657 654 /* 658 655 * Some buses or devices flag reads by setting the high bits in the ··· 760 757 if (ret != 0) 761 758 goto out; 762 759 763 - map->format.format_val(val + (i * val_bytes), v); 760 + map->format.format_val(val + (i * val_bytes), v, 0); 764 761 } 765 762 } 766 763