[PATCH v9 6/7] iio: accel: kionix-kx022a: Add a function to retrieve number of bytes in buffer

From: Mehdi Djait
Date: Sat Sep 16 2023 - 08:40:19 EST


Since Kionix accelerometers use various numbers of bits to report data, a
device-specific function is required.
Implement the function as a callback in the device-specific chip_info structure

Reviewed-by: Matti Vaittinen <mazziesaccount@xxxxxxxxx>
Signed-off-by: Mehdi Djait <mehdi.djait.k@xxxxxxxxx>
---
drivers/iio/accel/kionix-kx022a.c | 68 +++++++++++++++++--------------
drivers/iio/accel/kionix-kx022a.h | 46 ++++++++++++---------
2 files changed, 64 insertions(+), 50 deletions(-)

diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-kx022a.c
index ab3e5c8a19df..cc7134b1183b 100644
--- a/drivers/iio/accel/kionix-kx022a.c
+++ b/drivers/iio/accel/kionix-kx022a.c
@@ -585,26 +585,33 @@ static int kx022a_drop_fifo_contents(struct kx022a_data *data)
return regmap_write(data->regmap, data->chip_info->buf_clear, 0x0);
}

+static int kx022a_get_fifo_bytes_available(struct kx022a_data *data)
+{
+ int ret, fifo_bytes;
+
+ ret = regmap_read(data->regmap, KX022A_REG_BUF_STATUS_1, &fifo_bytes);
+ if (ret) {
+ dev_err(data->dev, "Error reading buffer status\n");
+ return ret;
+ }
+
+ if (fifo_bytes == KX022A_FIFO_FULL_VALUE)
+ return KX022A_FIFO_MAX_BYTES;
+
+ return fifo_bytes;
+}
+
static int __kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples,
bool irq)
{
struct kx022a_data *data = iio_priv(idev);
- struct device *dev = regmap_get_device(data->regmap);
uint64_t sample_period;
int count, fifo_bytes;
bool renable = false;
int64_t tstamp;
int ret, i;

- ret = regmap_read(data->regmap, KX022A_REG_BUF_STATUS_1, &fifo_bytes);
- if (ret) {
- dev_err(dev, "Error reading buffer status\n");
- return ret;
- }
-
- /* Let's not overflow if we for some reason get bogus value from i2c */
- if (fifo_bytes == KX022A_FIFO_FULL_VALUE)
- fifo_bytes = KX022A_FIFO_MAX_BYTES;
+ fifo_bytes = data->chip_info->get_fifo_bytes_available(data);

if (fifo_bytes % KX022A_FIFO_SAMPLES_SIZE_BYTES)
dev_warn(data->dev, "Bad FIFO alignment. Data may be corrupt\n");
@@ -993,26 +1000,27 @@ static int kx022a_chip_init(struct kx022a_data *data)
}

const struct kx022a_chip_info kx022a_chip_info = {
- .name = "kx022-accel",
- .regmap_config = &kx022a_regmap_config,
- .channels = kx022a_channels,
- .num_channels = ARRAY_SIZE(kx022a_channels),
- .fifo_length = KX022A_FIFO_LENGTH,
- .who = KX022A_REG_WHO,
- .id = KX022A_ID,
- .cntl = KX022A_REG_CNTL,
- .cntl2 = KX022A_REG_CNTL2,
- .odcntl = KX022A_REG_ODCNTL,
- .buf_cntl1 = KX022A_REG_BUF_CNTL1,
- .buf_cntl2 = KX022A_REG_BUF_CNTL2,
- .buf_clear = KX022A_REG_BUF_CLEAR,
- .buf_status1 = KX022A_REG_BUF_STATUS_1,
- .buf_read = KX022A_REG_BUF_READ,
- .inc1 = KX022A_REG_INC1,
- .inc4 = KX022A_REG_INC4,
- .inc5 = KX022A_REG_INC5,
- .inc6 = KX022A_REG_INC6,
- .xout_l = KX022A_REG_XOUT_L,
+ .name = "kx022-accel",
+ .regmap_config = &kx022a_regmap_config,
+ .channels = kx022a_channels,
+ .num_channels = ARRAY_SIZE(kx022a_channels),
+ .fifo_length = KX022A_FIFO_LENGTH,
+ .who = KX022A_REG_WHO,
+ .id = KX022A_ID,
+ .cntl = KX022A_REG_CNTL,
+ .cntl2 = KX022A_REG_CNTL2,
+ .odcntl = KX022A_REG_ODCNTL,
+ .buf_cntl1 = KX022A_REG_BUF_CNTL1,
+ .buf_cntl2 = KX022A_REG_BUF_CNTL2,
+ .buf_clear = KX022A_REG_BUF_CLEAR,
+ .buf_status1 = KX022A_REG_BUF_STATUS_1,
+ .buf_read = KX022A_REG_BUF_READ,
+ .inc1 = KX022A_REG_INC1,
+ .inc4 = KX022A_REG_INC4,
+ .inc5 = KX022A_REG_INC5,
+ .inc6 = KX022A_REG_INC6,
+ .xout_l = KX022A_REG_XOUT_L,
+ .get_fifo_bytes_available = kx022a_get_fifo_bytes_available,
};
EXPORT_SYMBOL_NS_GPL(kx022a_chip_info, IIO_KX022A);

diff --git a/drivers/iio/accel/kionix-kx022a.h b/drivers/iio/accel/kionix-kx022a.h
index 0e5026019213..7ca48e6f2c49 100644
--- a/drivers/iio/accel/kionix-kx022a.h
+++ b/drivers/iio/accel/kionix-kx022a.h
@@ -76,29 +76,34 @@

struct device;

+struct kx022a_data;
+
/**
* struct kx022a_chip_info - Kionix accelerometer chip specific information
*
- * @name: name of the device
- * @regmap_config: pointer to register map configuration
- * @channels: pointer to iio_chan_spec array
- * @num_channels: number of iio_chan_spec channels
- * @fifo_length: number of 16-bit samples in a full buffer
- * @who: WHO_AM_I register
- * @id: WHO_AM_I register value
- * @cntl: control register 1
- * @cntl2: control register 2
- * @odcntl: output data control register
- * @buf_cntl1: buffer control register 1
- * @buf_cntl2: buffer control register 2
- * @buf_clear: buffer clear register
- * @buf_status1: buffer status register 1
- * @buf_read: buffer read register
- * @inc1: interrupt control register 1
- * @inc4: interrupt control register 4
- * @inc5: interrupt control register 5
- * @inc6: interrupt control register 6
- * @xout_l: x-axis output least significant byte
+ * @name: name of the device
+ * @regmap_config: pointer to register map configuration
+ * @channels: pointer to iio_chan_spec array
+ * @num_channels: number of iio_chan_spec channels
+ * @fifo_length: number of 16-bit samples in a full buffer
+ * @who: WHO_AM_I register
+ * @id: WHO_AM_I register value
+ * @cntl: control register 1
+ * @cntl2: control register 2
+ * @odcntl: output data control register
+ * @buf_cntl1: buffer control register 1
+ * @buf_cntl2: buffer control register 2
+ * @buf_clear: buffer clear register
+ * @buf_status1: buffer status register 1
+ * @buf_read: buffer read register
+ * @inc1: interrupt control register 1
+ * @inc4: interrupt control register 4
+ * @inc5: interrupt control register 5
+ * @inc6: interrupt control register 6
+ * @xout_l: x-axis output least significant byte
+ * @get_fifo_bytes_available: function pointer to get amount of acceleration
+ * data bytes currently stored in the sensor's FIFO
+ * buffer
*/
struct kx022a_chip_info {
const char *name;
@@ -121,6 +126,7 @@ struct kx022a_chip_info {
u8 inc5;
u8 inc6;
u8 xout_l;
+ int (*get_fifo_bytes_available)(struct kx022a_data *);
};

int kx022a_probe_internal(struct device *dev, const struct kx022a_chip_info *chip_info);
--
2.30.2