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

gpio: stmpe: Rework registers access

This update allows to use registers map as following :
regs[reg_index + offset] instead of
regs[reg_index] + offset

This makes code clearer and will facilitate the addition of STMPE1600
on which LSB and MSB registers are respectively located at addr and addr + 1.
Despite for all others STMPE variant, LSB and MSB registers are respectively
located in reverse order at addr + 1 and addr.

For variant which have 3 registers's bank, we use LSB,CSB and MSB indexes
which contains respectively LSB (or LOW), CSB (or MID) and MSB (or HIGH)
register addresses (STMPE1801/STMPE24xx).
For variant which have 2 registers's bank, we use LSB and CSB indexes only.
In this case the CSB index contains the MSB regs address (STMPE 1601).

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Patrice Chotard and committed by
Lee Jones
43db289d 897ac667

+27 -21
+27 -21
drivers/gpio/gpio-stmpe.c
··· 20 20 */ 21 21 enum { REG_RE, REG_FE, REG_IE }; 22 22 23 + enum { LSB, CSB, MSB }; 24 + 23 25 #define CACHE_NR_REGS 3 24 26 /* No variant has more than 24 GPIOs */ 25 27 #define CACHE_NR_BANKS (24 / 8) ··· 41 39 { 42 40 struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); 43 41 struct stmpe *stmpe = stmpe_gpio->stmpe; 44 - u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB] - (offset / 8); 42 + u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB + (offset / 8)]; 45 43 u8 mask = 1 << (offset % 8); 46 44 int ret; 47 45 ··· 57 55 struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); 58 56 struct stmpe *stmpe = stmpe_gpio->stmpe; 59 57 int which = val ? STMPE_IDX_GPSR_LSB : STMPE_IDX_GPCR_LSB; 60 - u8 reg = stmpe->regs[which] - (offset / 8); 58 + u8 reg = stmpe->regs[which + (offset / 8)]; 61 59 u8 mask = 1 << (offset % 8); 62 60 63 61 /* ··· 91 89 { 92 90 struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); 93 91 struct stmpe *stmpe = stmpe_gpio->stmpe; 94 - u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); 92 + u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset / 8)]; 95 93 u8 mask = 1 << (offset % 8); 96 94 97 95 stmpe_gpio_set(chip, offset, val); ··· 104 102 { 105 103 struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); 106 104 struct stmpe *stmpe = stmpe_gpio->stmpe; 107 - u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); 105 + u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset / 8)]; 108 106 u8 mask = 1 << (offset % 8); 109 107 110 108 return stmpe_set_bits(stmpe, reg, mask, 0); ··· 175 173 struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc); 176 174 struct stmpe *stmpe = stmpe_gpio->stmpe; 177 175 int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); 178 - static const u8 regmap[] = { 179 - [REG_RE] = STMPE_IDX_GPRER_LSB, 180 - [REG_FE] = STMPE_IDX_GPFER_LSB, 181 - [REG_IE] = STMPE_IDX_IEGPIOR_LSB, 176 + static const u8 regmap[CACHE_NR_REGS][CACHE_NR_BANKS] = { 177 + [REG_RE][LSB] = STMPE_IDX_GPRER_LSB, 178 + [REG_RE][CSB] = STMPE_IDX_GPRER_CSB, 179 + [REG_RE][MSB] = STMPE_IDX_GPRER_MSB, 180 + [REG_FE][LSB] = STMPE_IDX_GPFER_LSB, 181 + [REG_FE][CSB] = STMPE_IDX_GPFER_CSB, 182 + [REG_FE][MSB] = STMPE_IDX_GPFER_MSB, 183 + [REG_IE][LSB] = STMPE_IDX_IEGPIOR_LSB, 184 + [REG_IE][CSB] = STMPE_IDX_IEGPIOR_CSB, 185 + [REG_IE][MSB] = STMPE_IDX_IEGPIOR_MSB, 182 186 }; 183 187 int i, j; 184 188 ··· 202 194 continue; 203 195 204 196 stmpe_gpio->oldregs[i][j] = new; 205 - stmpe_reg_write(stmpe, stmpe->regs[regmap[i]] - j, new); 197 + stmpe_reg_write(stmpe, stmpe->regs[regmap[i][j]], new); 206 198 } 207 199 } 208 200 ··· 238 230 struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc); 239 231 struct stmpe *stmpe = stmpe_gpio->stmpe; 240 232 const char *label = gpiochip_is_requested(gc, offset); 241 - int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); 242 233 bool val = !!stmpe_gpio_get(gc, offset); 243 - u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); 234 + u8 bank = offset / 8; 235 + u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB + bank]; 244 236 u8 mask = 1 << (offset % 8); 245 237 int ret; 246 238 u8 dir; ··· 281 273 case STMPE1601: 282 274 case STMPE2401: 283 275 case STMPE2403: 284 - edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB] + 285 - num_banks - 1 - (offset / 8); 276 + edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_LSB + bank]; 286 277 ret = stmpe_reg_read(stmpe, edge_det_reg); 287 278 if (ret < 0) 288 279 return; 289 280 edge_det = !!(ret & mask); 290 281 291 282 case STMPE1801: 292 - rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB] - 293 - (offset / 8); 294 - fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB] - 295 - (offset / 8); 283 + rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB + bank]; 284 + fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB + bank]; 285 + 296 286 ret = stmpe_reg_read(stmpe, rise_reg); 297 287 if (ret < 0) 298 288 return; ··· 301 295 fall = !!(ret & mask); 302 296 303 297 case STMPE801: 304 - irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB] - 305 - (offset / 8); 298 + irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB + bank]; 306 299 break; 307 300 308 301 default: ··· 383 378 */ 384 379 if (stmpe->partnum != STMPE801 || stmpe->partnum != STMPE1801) { 385 380 stmpe_reg_write(stmpe, statmsbreg + i, status[i]); 386 - stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB] 387 - + i, status[i]); 381 + stmpe_reg_write(stmpe, 382 + stmpe->regs[STMPE_IDX_GPEDR_LSB + i], 383 + status[i]); 388 384 } 389 385 } 390 386