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

iio: accel: adxl345: use regmap cache for INT mapping

Use regmap cache to replace the maintenance of the interrupt mapping
state by a member variable intio. The interrupt mapping is initialized
when the driver is probed, and it is perfectly cacheable.

The patch will still leave the function set_interrupts(). A follow up
patch takes care of it, when cleaning up the INT enable register
variable.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
Link: https://patch.msgid.link/20250313165049.48305-2-l.rubusch@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Lothar Rubusch and committed by
Jonathan Cameron
f184a095 0de3748d

+49 -23
+4
drivers/iio/accel/adxl345.h
··· 111 111 */ 112 112 #define ADXL375_USCALE 480000 113 113 114 + struct regmap; 115 + 116 + bool adxl345_is_volatile_reg(struct device *dev, unsigned int reg); 117 + 114 118 struct adxl345_chip_info { 115 119 const char *name; 116 120 int uscale;
+41 -23
drivers/iio/accel/adxl345_core.c
··· 36 36 struct regmap *regmap; 37 37 bool fifo_delay; /* delay: delay is needed for SPI */ 38 38 int irq; 39 - u8 intio; 40 39 u8 int_map; 41 40 u8 watermark; 42 41 u8 fifo_mode; ··· 75 76 0 76 77 }; 77 78 79 + bool adxl345_is_volatile_reg(struct device *dev, unsigned int reg) 80 + { 81 + switch (reg) { 82 + case ADXL345_REG_DATA_AXIS(0): 83 + case ADXL345_REG_DATA_AXIS(1): 84 + case ADXL345_REG_DATA_AXIS(2): 85 + case ADXL345_REG_DATA_AXIS(3): 86 + case ADXL345_REG_DATA_AXIS(4): 87 + case ADXL345_REG_DATA_AXIS(5): 88 + case ADXL345_REG_ACT_TAP_STATUS: 89 + case ADXL345_REG_FIFO_STATUS: 90 + case ADXL345_REG_INT_SOURCE: 91 + return true; 92 + default: 93 + return false; 94 + } 95 + } 96 + EXPORT_SYMBOL_NS_GPL(adxl345_is_volatile_reg, "IIO_ADXL345"); 97 + 78 98 /** 79 99 * adxl345_set_measure_en() - Enable and disable measuring. 80 100 * ··· 116 98 117 99 static int adxl345_set_interrupts(struct adxl345_state *st) 118 100 { 119 - int ret; 120 - unsigned int int_enable = st->int_map; 121 - unsigned int int_map; 122 - 123 - /* 124 - * Any bits set to 0 in the INT map register send their respective 125 - * interrupts to the INT1 pin, whereas bits set to 1 send their respective 126 - * interrupts to the INT2 pin. The intio shall convert this accordingly. 127 - */ 128 - int_map = st->intio ? st->int_map : ~st->int_map; 129 - 130 - ret = regmap_write(st->regmap, ADXL345_REG_INT_MAP, int_map); 131 - if (ret) 132 - return ret; 133 - 134 - return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, int_enable); 101 + return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); 135 102 } 136 103 137 104 static int adxl345_read_raw(struct iio_dev *indio_dev, ··· 268 265 269 266 static int adxl345_set_fifo(struct adxl345_state *st) 270 267 { 268 + unsigned int intio; 271 269 int ret; 272 270 273 271 /* FIFO should only be configured while in standby mode */ ··· 276 272 if (ret < 0) 277 273 return ret; 278 274 275 + ret = regmap_read(st->regmap, ADXL345_REG_INT_MAP, &intio); 276 + if (ret) 277 + return ret; 278 + 279 279 ret = regmap_write(st->regmap, ADXL345_REG_FIFO_CTL, 280 280 FIELD_PREP(ADXL345_FIFO_CTL_SAMPLES_MSK, 281 281 st->watermark) | 282 - FIELD_PREP(ADXL345_FIFO_CTL_TRIGGER_MSK, 283 - st->intio) | 282 + FIELD_PREP(ADXL345_FIFO_CTL_TRIGGER_MSK, intio) | 284 283 FIELD_PREP(ADXL345_FIFO_CTL_MODE_MSK, 285 284 st->fifo_mode)); 286 285 if (ret < 0) ··· 499 492 struct adxl345_state *st; 500 493 struct iio_dev *indio_dev; 501 494 u32 regval; 495 + u8 intio = ADXL345_INT1; 502 496 unsigned int data_format_mask = (ADXL345_DATA_FORMAT_RANGE | 503 497 ADXL345_DATA_FORMAT_JUSTIFY | 504 498 ADXL345_DATA_FORMAT_FULL_RES | ··· 564 556 if (ret < 0) 565 557 return ret; 566 558 567 - st->intio = ADXL345_INT1; 568 559 st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT1"); 569 560 if (st->irq < 0) { 570 - st->intio = ADXL345_INT2; 561 + intio = ADXL345_INT2; 571 562 st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT2"); 572 563 if (st->irq < 0) 573 - st->intio = ADXL345_INT_NONE; 564 + intio = ADXL345_INT_NONE; 574 565 } 575 566 576 - if (st->intio != ADXL345_INT_NONE) { 567 + if (intio != ADXL345_INT_NONE) { 568 + /* 569 + * Any bits set to 0 in the INT map register send their respective 570 + * interrupts to the INT1 pin, whereas bits set to 1 send their respective 571 + * interrupts to the INT2 pin. The intio shall convert this accordingly. 572 + */ 573 + regval = intio ? 0xff : 0; 574 + 575 + ret = regmap_write(st->regmap, ADXL345_REG_INT_MAP, regval); 576 + if (ret) 577 + return ret; 578 + 577 579 /* FIFO_STREAM mode is going to be activated later */ 578 580 ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, &adxl345_buffer_ops); 579 581 if (ret)
+2
drivers/iio/accel/adxl345_i2c.c
··· 17 17 static const struct regmap_config adxl345_i2c_regmap_config = { 18 18 .reg_bits = 8, 19 19 .val_bits = 8, 20 + .volatile_reg = adxl345_is_volatile_reg, 21 + .cache_type = REGCACHE_MAPLE, 20 22 }; 21 23 22 24 static int adxl345_i2c_probe(struct i2c_client *client)
+2
drivers/iio/accel/adxl345_spi.c
··· 19 19 .val_bits = 8, 20 20 /* Setting bits 7 and 6 enables multiple-byte read */ 21 21 .read_flag_mask = BIT(7) | BIT(6), 22 + .volatile_reg = adxl345_is_volatile_reg, 23 + .cache_type = REGCACHE_MAPLE, 22 24 }; 23 25 24 26 static int adxl345_spi_setup(struct device *dev, struct regmap *regmap)