root/drivers/iio/accel/kionix-kx022a.c
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2022 ROHM Semiconductors
 *
 * ROHM/KIONIX accelerometer driver
 */

#include <linux/array_size.h>
#include <linux/bitmap.h>
#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/math64.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/string_choices.h>
#include <linux/sysfs.h>
#include <linux/time64.h>
#include <linux/types.h>
#include <linux/units.h>

#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>

#include <asm/byteorder.h>

#include "kionix-kx022a.h"

/*
 * The KX022A has FIFO which can store 43 samples of HiRes data from 2
 * channels. This equals to 43 (samples) * 3 (channels) * 2 (bytes/sample) to
 * 258 bytes of sample data. The quirk to know is that the amount of bytes in
 * the FIFO is advertised via 8 bit register (max value 255). The thing to note
 * is that full 258 bytes of data is indicated using the max value 255.
 */
#define KX022A_FIFO_LENGTH                      43
#define KX022A_FIFO_FULL_VALUE                  255
#define KX022A_SOFT_RESET_WAIT_TIME_US          (5 * USEC_PER_MSEC)
#define KX022A_SOFT_RESET_TOTAL_WAIT_TIME_US    (500 * USEC_PER_MSEC)

/* 3 axis, 2 bytes of data for each of the axis */
#define KX022A_FIFO_SAMPLES_SIZE_BYTES          6
#define KX022A_FIFO_MAX_BYTES                                   \
        (KX022A_FIFO_LENGTH * KX022A_FIFO_SAMPLES_SIZE_BYTES)

enum {
        KX022A_STATE_SAMPLE,
        KX022A_STATE_FIFO,
};

/* kx022a Regmap configs */
static const struct regmap_range kx022a_volatile_ranges[] = {
        {
                .range_min = KX022A_REG_XHP_L,
                .range_max = KX022A_REG_COTR,
        }, {
                .range_min = KX022A_REG_TSCP,
                .range_max = KX022A_REG_INT_REL,
        }, {
                /* The reset bit will be cleared by sensor */
                .range_min = KX022A_REG_CNTL2,
                .range_max = KX022A_REG_CNTL2,
        }, {
                .range_min = KX022A_REG_BUF_STATUS_1,
                .range_max = KX022A_REG_BUF_READ,
        },
};

static const struct regmap_access_table kx022a_volatile_regs = {
        .yes_ranges = &kx022a_volatile_ranges[0],
        .n_yes_ranges = ARRAY_SIZE(kx022a_volatile_ranges),
};

static const struct regmap_range kx022a_precious_ranges[] = {
        {
                .range_min = KX022A_REG_INT_REL,
                .range_max = KX022A_REG_INT_REL,
        },
};

static const struct regmap_access_table kx022a_precious_regs = {
        .yes_ranges = &kx022a_precious_ranges[0],
        .n_yes_ranges = ARRAY_SIZE(kx022a_precious_ranges),
};

/*
 * The HW does not set WHO_AM_I reg as read-only but we don't want to write it
 * so we still include it in the read-only ranges.
 */
static const struct regmap_range kx022a_read_only_ranges[] = {
        {
                .range_min = KX022A_REG_XHP_L,
                .range_max = KX022A_REG_INT_REL,
        }, {
                .range_min = KX022A_REG_BUF_STATUS_1,
                .range_max = KX022A_REG_BUF_STATUS_2,
        }, {
                .range_min = KX022A_REG_BUF_READ,
                .range_max = KX022A_REG_BUF_READ,
        },
};

static const struct regmap_access_table kx022a_ro_regs = {
        .no_ranges = &kx022a_read_only_ranges[0],
        .n_no_ranges = ARRAY_SIZE(kx022a_read_only_ranges),
};

static const struct regmap_range kx022a_write_only_ranges[] = {
        {
                .range_min = KX022A_REG_BTS_WUF_TH,
                .range_max = KX022A_REG_BTS_WUF_TH,
        }, {
                .range_min = KX022A_REG_MAN_WAKE,
                .range_max = KX022A_REG_MAN_WAKE,
        }, {
                .range_min = KX022A_REG_SELF_TEST,
                .range_max = KX022A_REG_SELF_TEST,
        }, {
                .range_min = KX022A_REG_BUF_CLEAR,
                .range_max = KX022A_REG_BUF_CLEAR,
        },
};

static const struct regmap_access_table kx022a_wo_regs = {
        .no_ranges = &kx022a_write_only_ranges[0],
        .n_no_ranges = ARRAY_SIZE(kx022a_write_only_ranges),
};

static const struct regmap_range kx022a_noinc_read_ranges[] = {
        {
                .range_min = KX022A_REG_BUF_READ,
                .range_max = KX022A_REG_BUF_READ,
        },
};

static const struct regmap_access_table kx022a_nir_regs = {
        .yes_ranges = &kx022a_noinc_read_ranges[0],
        .n_yes_ranges = ARRAY_SIZE(kx022a_noinc_read_ranges),
};

static const struct regmap_config kx022a_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
        .volatile_table = &kx022a_volatile_regs,
        .rd_table = &kx022a_wo_regs,
        .wr_table = &kx022a_ro_regs,
        .rd_noinc_table = &kx022a_nir_regs,
        .precious_table = &kx022a_precious_regs,
        .max_register = KX022A_MAX_REGISTER,
        .cache_type = REGCACHE_MAPLE,
};

/* Regmap configs kx132 */
static const struct regmap_range kx132_volatile_ranges[] = {
        {
                .range_min = KX132_REG_XADP_L,
                .range_max = KX132_REG_COTR,
        }, {
                .range_min = KX132_REG_TSCP,
                .range_max = KX132_REG_INT_REL,
        }, {
                /* The reset bit will be cleared by sensor */
                .range_min = KX132_REG_CNTL2,
                .range_max = KX132_REG_CNTL2,
        }, {
                .range_min = KX132_REG_CNTL5,
                .range_max = KX132_REG_CNTL5,
        }, {
                .range_min = KX132_REG_BUF_STATUS_1,
                .range_max = KX132_REG_BUF_READ,
        },
};

static const struct regmap_access_table kx132_volatile_regs = {
        .yes_ranges = &kx132_volatile_ranges[0],
        .n_yes_ranges = ARRAY_SIZE(kx132_volatile_ranges),
};

static const struct regmap_range kx132_precious_ranges[] = {
        {
                .range_min = KX132_REG_INT_REL,
                .range_max = KX132_REG_INT_REL,
        },
};

static const struct regmap_access_table kx132_precious_regs = {
        .yes_ranges = &kx132_precious_ranges[0],
        .n_yes_ranges = ARRAY_SIZE(kx132_precious_ranges),
};

static const struct regmap_range kx132_read_only_ranges[] = {
        {
                .range_min = KX132_REG_XADP_L,
                .range_max = KX132_REG_INT_REL,
        }, {
                .range_min = KX132_REG_BUF_STATUS_1,
                .range_max = KX132_REG_BUF_STATUS_2,
        }, {
                .range_min = KX132_REG_BUF_READ,
                .range_max = KX132_REG_BUF_READ,
        }, {
                /* Kionix reserved registers: should not be written */
                .range_min = 0x28,
                .range_max = 0x28,
        }, {
                .range_min = 0x35,
                .range_max = 0x36,
        }, {
                .range_min = 0x3c,
                .range_max = 0x48,
        }, {
                .range_min = 0x4e,
                .range_max = 0x5c,
        }, {
                .range_min = 0x77,
                .range_max = 0x7f,
        },
};

static const struct regmap_access_table kx132_ro_regs = {
        .no_ranges = &kx132_read_only_ranges[0],
        .n_no_ranges = ARRAY_SIZE(kx132_read_only_ranges),
};

static const struct regmap_range kx132_write_only_ranges[] = {
        {
                .range_min = KX132_REG_SELF_TEST,
                .range_max = KX132_REG_SELF_TEST,
        }, {
                .range_min = KX132_REG_BUF_CLEAR,
                .range_max = KX132_REG_BUF_CLEAR,
        },
};

static const struct regmap_access_table kx132_wo_regs = {
        .no_ranges = &kx132_write_only_ranges[0],
        .n_no_ranges = ARRAY_SIZE(kx132_write_only_ranges),
};

static const struct regmap_range kx132_noinc_read_ranges[] = {
        {
                .range_min = KX132_REG_BUF_READ,
                .range_max = KX132_REG_BUF_READ,
        },
};

static const struct regmap_access_table kx132_nir_regs = {
        .yes_ranges = &kx132_noinc_read_ranges[0],
        .n_yes_ranges = ARRAY_SIZE(kx132_noinc_read_ranges),
};

static const struct regmap_config kx132_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
        .volatile_table = &kx132_volatile_regs,
        .rd_table = &kx132_wo_regs,
        .wr_table = &kx132_ro_regs,
        .rd_noinc_table = &kx132_nir_regs,
        .precious_table = &kx132_precious_regs,
        .max_register = KX132_MAX_REGISTER,
        .cache_type = REGCACHE_MAPLE,
};

struct kx022a_data {
        struct regmap *regmap;
        const struct kx022a_chip_info *chip_info;
        struct iio_trigger *trig;
        struct device *dev;
        struct iio_mount_matrix orientation;
        int64_t timestamp, old_timestamp;

        int irq;
        int inc_reg;
        int ien_reg;

        unsigned int state;
        unsigned int odr_ns;

        bool trigger_enabled;
        /*
         * Prevent toggling the sensor stby/active state (PC1 bit) in the
         * middle of a configuration, or when the fifo is enabled. Also,
         * protect the data stored/retrieved from this structure from
         * concurrent accesses.
         */
        struct mutex mutex;
        u8 watermark;

        __le16 *fifo_buffer;

        /* 3 x 16bit accel data + timestamp */
        __le16 buffer[8] __aligned(IIO_DMA_MINALIGN);
        struct {
                __le16 channels[3];
                aligned_s64 ts;
        } scan;
};

static const struct iio_mount_matrix *
kx022a_get_mount_matrix(const struct iio_dev *idev,
                        const struct iio_chan_spec *chan)
{
        struct kx022a_data *data = iio_priv(idev);

        return &data->orientation;
}

enum {
        AXIS_X,
        AXIS_Y,
        AXIS_Z,
        AXIS_MAX
};

static const unsigned long kx022a_scan_masks[] = {
        BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), 0
};

static const struct iio_chan_spec_ext_info kx022a_ext_info[] = {
        IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, kx022a_get_mount_matrix),
        { }
};

#define KX022A_ACCEL_CHAN(axis, reg, index)                     \
{                                                               \
        .type = IIO_ACCEL,                                      \
        .modified = 1,                                          \
        .channel2 = IIO_MOD_##axis,                             \
        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
                                BIT(IIO_CHAN_INFO_SAMP_FREQ),   \
        .info_mask_shared_by_type_available =                   \
                                BIT(IIO_CHAN_INFO_SCALE) |      \
                                BIT(IIO_CHAN_INFO_SAMP_FREQ),   \
        .ext_info = kx022a_ext_info,                            \
        .address = reg,                                         \
        .scan_index = index,                                    \
        .scan_type = {                                          \
                .sign = 's',                                    \
                .realbits = 16,                                 \
                .storagebits = 16,                              \
                .endianness = IIO_LE,                           \
        },                                                      \
}

static const struct iio_chan_spec kx022a_channels[] = {
        KX022A_ACCEL_CHAN(X, KX022A_REG_XOUT_L, 0),
        KX022A_ACCEL_CHAN(Y, KX022A_REG_YOUT_L, 1),
        KX022A_ACCEL_CHAN(Z, KX022A_REG_ZOUT_L, 2),
        IIO_CHAN_SOFT_TIMESTAMP(3),
};

static const struct iio_chan_spec kx132_channels[] = {
        KX022A_ACCEL_CHAN(X, KX132_REG_XOUT_L, 0),
        KX022A_ACCEL_CHAN(Y, KX132_REG_YOUT_L, 1),
        KX022A_ACCEL_CHAN(Z, KX132_REG_ZOUT_L, 2),
        IIO_CHAN_SOFT_TIMESTAMP(3),
};

/*
 * The sensor HW can support ODR up to 1600 Hz, which is beyond what most of the
 * Linux CPUs can handle without dropping samples. Also, the low power mode is
 * not available for higher sample rates. Thus, the driver only supports 200 Hz
 * and slower ODRs. The slowest is 0.78 Hz.
 */
static const int kx022a_accel_samp_freq_table[][2] = {
        { 0, 780000 },
        { 1, 563000 },
        { 3, 125000 },
        { 6, 250000 },
        { 12, 500000 },
        { 25, 0 },
        { 50, 0 },
        { 100, 0 },
        { 200, 0 },
};

static const unsigned int kx022a_odrs[] = {
        1282051282,
        639795266,
        320 * MEGA,
        160 * MEGA,
        80 * MEGA,
        40 * MEGA,
        20 * MEGA,
        10 * MEGA,
        5 * MEGA,
};

/*
 * range is typically +-2G/4G/8G/16G, distributed over the amount of bits.
 * The scale table can be calculated using
 *      (range / 2^bits) * g = (range / 2^bits) * 9.80665 m/s^2
 *      => KX022A uses 16 bit (HiRes mode - assume the low 8 bits are zeroed
 *      in low-power mode(?) )
 *      => +/-2G  => 4 / 2^16 * 9,80665
 *      => +/-2G  - 0.000598550415
 *         +/-4G  - 0.00119710083
 *         +/-8G  - 0.00239420166
 *         +/-16G - 0.00478840332
 */
static const int kx022a_scale_table[][2] = {
        { 0, 598550 },
        { 0, 1197101 },
        { 0, 2394202 },
        { 0, 4788403 },
};

/* KX134ACR-LBZ ranges are (+/-) 8, 16, 32, 64 G */
static const int kx134acr_lbz_scale_table[][2] = {
        { 0, 2394202 },
        { 0, 4788403 },
        { 0, 9576807 },
        { 0, 19153613 },
};

static int kx022a_read_avail(struct iio_dev *indio_dev,
                             struct iio_chan_spec const *chan,
                             const int **vals, int *type, int *length,
                             long mask)
{
        struct kx022a_data *data = iio_priv(indio_dev);

        switch (mask) {
        case IIO_CHAN_INFO_SAMP_FREQ:
                *vals = (const int *)kx022a_accel_samp_freq_table;
                *length = ARRAY_SIZE(kx022a_accel_samp_freq_table) *
                          ARRAY_SIZE(kx022a_accel_samp_freq_table[0]);
                *type = IIO_VAL_INT_PLUS_MICRO;
                return IIO_AVAIL_LIST;
        case IIO_CHAN_INFO_SCALE:
                *vals = (const int *)data->chip_info->scale_table;
                *length = data->chip_info->scale_table_size;
                *type = IIO_VAL_INT_PLUS_NANO;
                return IIO_AVAIL_LIST;
        default:
                return -EINVAL;
        }
}

#define KX022A_DEFAULT_PERIOD_NS (20 * NSEC_PER_MSEC)

static void kx022a_reg2freq(unsigned int val,  int *val1, int *val2)
{
        *val1 = kx022a_accel_samp_freq_table[val & KX022A_MASK_ODR][0];
        *val2 = kx022a_accel_samp_freq_table[val & KX022A_MASK_ODR][1];
}

static void kx022a_reg2scale(struct kx022a_data *data, unsigned int val,
                             unsigned int *val1, unsigned int *val2)
{
        val &= KX022A_MASK_GSEL;
        val >>= KX022A_GSEL_SHIFT;

        *val1 = data->chip_info->scale_table[val][0];
        *val2 = data->chip_info->scale_table[val][1];
}

static int __kx022a_turn_on_off(struct kx022a_data *data, bool on)
{
        int ret;

        if (on)
                ret = regmap_set_bits(data->regmap, data->chip_info->cntl,
                                      KX022A_MASK_PC1);
        else
                ret = regmap_clear_bits(data->regmap, data->chip_info->cntl,
                                        KX022A_MASK_PC1);
        if (ret)
                dev_err(data->dev, "Turn %s fail %d\n", str_on_off(on), ret);

        return ret;
}

static int kx022a_turn_off_lock(struct kx022a_data *data)
{
        int ret;

        mutex_lock(&data->mutex);
        ret = __kx022a_turn_on_off(data, false);
        if (ret)
                mutex_unlock(&data->mutex);

        return ret;
}

static int kx022a_turn_on_unlock(struct kx022a_data *data)
{
        int ret;

        ret = __kx022a_turn_on_off(data, true);
        mutex_unlock(&data->mutex);

        return ret;
}

static int kx022a_write_raw_get_fmt(struct iio_dev *idev,
                                    struct iio_chan_spec const *chan,
                                    long mask)
{
        switch (mask) {
        case IIO_CHAN_INFO_SCALE:
                return IIO_VAL_INT_PLUS_NANO;
        case IIO_CHAN_INFO_SAMP_FREQ:
                return IIO_VAL_INT_PLUS_MICRO;
        default:
                return -EINVAL;
        }
}

static int __kx022a_write_raw(struct iio_dev *idev,
                              struct iio_chan_spec const *chan,
                              int val, int val2, long mask)
{
        struct kx022a_data *data = iio_priv(idev);
        int ret, n;

        switch (mask) {
        case IIO_CHAN_INFO_SAMP_FREQ:
                n = ARRAY_SIZE(kx022a_accel_samp_freq_table);

                while (n--)
                        if (val == kx022a_accel_samp_freq_table[n][0] &&
                            val2 == kx022a_accel_samp_freq_table[n][1])
                                break;
                if (n < 0)
                        return -EINVAL;

                ret = kx022a_turn_off_lock(data);
                if (ret)
                        return ret;

                ret = regmap_update_bits(data->regmap,
                                         data->chip_info->odcntl,
                                         KX022A_MASK_ODR, n);
                data->odr_ns = kx022a_odrs[n];
                kx022a_turn_on_unlock(data);
                return ret;
        case IIO_CHAN_INFO_SCALE:
                n = data->chip_info->scale_table_size / 2;

                while (n-- > 0)
                        if (val == data->chip_info->scale_table[n][0] &&
                            val2 == data->chip_info->scale_table[n][1])
                                break;
                if (n < 0)
                        return -EINVAL;

                ret = kx022a_turn_off_lock(data);
                if (ret)
                        return ret;

                ret = regmap_update_bits(data->regmap, data->chip_info->cntl,
                                         KX022A_MASK_GSEL,
                                         n << KX022A_GSEL_SHIFT);
                kx022a_turn_on_unlock(data);
                return ret;
        default:
                return -EINVAL;
        }
}

static int kx022a_write_raw(struct iio_dev *idev,
                            struct iio_chan_spec const *chan,
                            int val, int val2, long mask)
{
        int ret;

        /*
         * We should not allow changing scale or frequency when FIFO is running
         * as it will mess the timestamp/scale for samples existing in the
         * buffer. If this turns out to be an issue we can later change logic
         * to internally flush the fifo before reconfiguring so the samples in
         * fifo keep matching the freq/scale settings. (Such setup could cause
         * issues if users trust the watermark to be reached within known
         * time-limit).
         */
        if (!iio_device_claim_direct(idev))
                return -EBUSY;

        ret = __kx022a_write_raw(idev, chan, val, val2, mask);

        iio_device_release_direct(idev);

        return ret;
}

static int kx022a_fifo_set_wmi(struct kx022a_data *data)
{
        u8 threshold;

        threshold = data->watermark;

        return regmap_update_bits(data->regmap, data->chip_info->buf_cntl1,
                                  KX022A_MASK_WM_TH, threshold);
}

static int kx022a_get_axis(struct kx022a_data *data,
                           struct iio_chan_spec const *chan,
                           int *val)
{
        int ret;

        ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer[0],
                               sizeof(__le16));
        if (ret)
                return ret;

        *val = (s16)le16_to_cpu(data->buffer[0]);

        return IIO_VAL_INT;
}

static int kx022a_read_raw(struct iio_dev *idev,
                           struct iio_chan_spec const *chan,
                           int *val, int *val2, long mask)
{
        struct kx022a_data *data = iio_priv(idev);
        unsigned int regval;
        int ret;

        switch (mask) {
        case IIO_CHAN_INFO_RAW:
                if (!iio_device_claim_direct(idev))
                        return -EBUSY;

                mutex_lock(&data->mutex);
                ret = kx022a_get_axis(data, chan, val);
                mutex_unlock(&data->mutex);

                iio_device_release_direct(idev);

                return ret;

        case IIO_CHAN_INFO_SAMP_FREQ:
                ret = regmap_read(data->regmap, data->chip_info->odcntl, &regval);
                if (ret)
                        return ret;

                if ((regval & KX022A_MASK_ODR) >
                    ARRAY_SIZE(kx022a_accel_samp_freq_table)) {
                        dev_err(data->dev, "Invalid ODR\n");
                        return -EINVAL;
                }

                kx022a_reg2freq(regval, val, val2);

                return IIO_VAL_INT_PLUS_MICRO;

        case IIO_CHAN_INFO_SCALE:
                ret = regmap_read(data->regmap, data->chip_info->cntl, &regval);
                if (ret < 0)
                        return ret;

                kx022a_reg2scale(data, regval, val, val2);

                return IIO_VAL_INT_PLUS_NANO;
        }

        return -EINVAL;
};

static int kx022a_set_watermark(struct iio_dev *idev, unsigned int val)
{
        struct kx022a_data *data = iio_priv(idev);

        val = min(data->chip_info->fifo_length, val);

        mutex_lock(&data->mutex);
        data->watermark = val;
        mutex_unlock(&data->mutex);

        return 0;
}

static ssize_t hwfifo_enabled_show(struct device *dev,
                                   struct device_attribute *attr,
                                   char *buf)
{
        struct iio_dev *idev = dev_to_iio_dev(dev);
        struct kx022a_data *data = iio_priv(idev);
        bool state;

        mutex_lock(&data->mutex);
        state = data->state;
        mutex_unlock(&data->mutex);

        return sysfs_emit(buf, "%d\n", state);
}

static ssize_t hwfifo_watermark_show(struct device *dev,
                                     struct device_attribute *attr,
                                     char *buf)
{
        struct iio_dev *idev = dev_to_iio_dev(dev);
        struct kx022a_data *data = iio_priv(idev);
        int wm;

        mutex_lock(&data->mutex);
        wm = data->watermark;
        mutex_unlock(&data->mutex);

        return sysfs_emit(buf, "%d\n", wm);
}

static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0);
static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0);

static const struct iio_dev_attr *kx022a_fifo_attributes[] = {
        &iio_dev_attr_hwfifo_watermark,
        &iio_dev_attr_hwfifo_enabled,
        NULL
};

static int kx022a_drop_fifo_contents(struct kx022a_data *data)
{
        /*
         * We must clear the old time-stamp to avoid computing the timestamps
         * based on samples acquired when buffer was last enabled.
         *
         * We don't need to protect the timestamp as long as we are only
         * called from fifo-disable where we can guarantee the sensor is not
         * triggering interrupts and where the mutex is locked to prevent the
         * user-space access.
         */
        data->timestamp = 0;

        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 kx132_get_fifo_bytes_available(struct kx022a_data *data)
{
        __le16 buf_status;
        int ret, fifo_bytes;

        ret = regmap_bulk_read(data->regmap, data->chip_info->buf_status1,
                               &buf_status, sizeof(buf_status));
        if (ret) {
                dev_err(data->dev, "Error reading buffer status\n");
                return ret;
        }

        fifo_bytes = le16_to_cpu(buf_status);
        fifo_bytes &= data->chip_info->buf_smp_lvl_mask;
        fifo_bytes = min((unsigned int)fifo_bytes, data->chip_info->fifo_length *
                         KX022A_FIFO_SAMPLES_SIZE_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);
        uint64_t sample_period;
        int count, fifo_bytes;
        bool renable = false;
        int64_t tstamp;
        int ret, i;

        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");

        count = fifo_bytes / KX022A_FIFO_SAMPLES_SIZE_BYTES;
        if (!count)
                return 0;

        /*
         * If we are being called from IRQ handler we know the stored timestamp
         * is fairly accurate for the last stored sample. Otherwise, if we are
         * called as a result of a read operation from userspace and hence
         * before the watermark interrupt was triggered, take a timestamp
         * now. We can fall anywhere in between two samples so the error in this
         * case is at most one sample period.
         */
        if (!irq) {
                /*
                 * We need to have the IRQ disabled or we risk of messing-up
                 * the timestamps. If we are ran from IRQ, then the
                 * IRQF_ONESHOT has us covered - but if we are ran by the
                 * user-space read we need to disable the IRQ to be on a safe
                 * side. We do this usng synchronous disable so that if the
                 * IRQ thread is being ran on other CPU we wait for it to be
                 * finished.
                 */
                disable_irq(data->irq);
                renable = true;

                data->old_timestamp = data->timestamp;
                data->timestamp = iio_get_time_ns(idev);
        }

        /*
         * Approximate timestamps for each of the sample based on the sampling
         * frequency, timestamp for last sample and number of samples.
         *
         * We'd better not use the current bandwidth settings to compute the
         * sample period. The real sample rate varies with the device and
         * small variation adds when we store a large number of samples.
         *
         * To avoid this issue we compute the actual sample period ourselves
         * based on the timestamp delta between the last two flush operations.
         */
        if (data->old_timestamp) {
                sample_period = data->timestamp - data->old_timestamp;
                do_div(sample_period, count);
        } else {
                sample_period = data->odr_ns;
        }
        tstamp = data->timestamp - (count - 1) * sample_period;

        if (samples && count > samples) {
                /*
                 * Here we leave some old samples to the buffer. We need to
                 * adjust the timestamp to match the first sample in the buffer
                 * or we will miscalculate the sample_period at next round.
                 */
                data->timestamp -= (count - samples) * sample_period;
                count = samples;
        }

        fifo_bytes = count * KX022A_FIFO_SAMPLES_SIZE_BYTES;
        ret = regmap_noinc_read(data->regmap, data->chip_info->buf_read,
                                data->fifo_buffer, fifo_bytes);
        if (ret)
                goto renable_out;

        for (i = 0; i < count; i++) {
                __le16 *sam = &data->fifo_buffer[i * 3];
                __le16 *chs;
                int bit;

                chs = &data->scan.channels[0];
                for_each_set_bit(bit, idev->active_scan_mask, AXIS_MAX)
                        chs[bit] = sam[bit];

                iio_push_to_buffers_with_timestamp(idev, &data->scan, tstamp);

                tstamp += sample_period;
        }

        ret = count;

renable_out:
        if (renable)
                enable_irq(data->irq);

        return ret;
}

static int kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples)
{
        struct kx022a_data *data = iio_priv(idev);
        int ret;

        mutex_lock(&data->mutex);
        ret = __kx022a_fifo_flush(idev, samples, false);
        mutex_unlock(&data->mutex);

        return ret;
}

static const struct iio_info kx022a_info = {
        .read_raw = &kx022a_read_raw,
        .write_raw = &kx022a_write_raw,
        .write_raw_get_fmt = &kx022a_write_raw_get_fmt,
        .read_avail = &kx022a_read_avail,

        .validate_trigger       = iio_validate_own_trigger,
        .hwfifo_set_watermark   = kx022a_set_watermark,
        .hwfifo_flush_to_buffer = kx022a_fifo_flush,
};

static int kx022a_set_drdy_irq(struct kx022a_data *data, bool en)
{
        if (en)
                return regmap_set_bits(data->regmap, data->chip_info->cntl,
                                       KX022A_MASK_DRDY);

        return regmap_clear_bits(data->regmap, data->chip_info->cntl,
                                 KX022A_MASK_DRDY);
}

static int kx022a_prepare_irq_pin(struct kx022a_data *data)
{
        /* Enable IRQ1 pin. Set polarity to active low */
        int mask = KX022A_MASK_IEN | KX022A_MASK_IPOL |
                   KX022A_MASK_ITYP;
        int val = KX022A_MASK_IEN | KX022A_IPOL_LOW |
                  KX022A_ITYP_LEVEL;
        int ret;

        ret = regmap_update_bits(data->regmap, data->inc_reg, mask, val);
        if (ret)
                return ret;

        /* We enable WMI to IRQ pin only at buffer_enable */
        mask = KX022A_MASK_INS2_DRDY;

        return regmap_set_bits(data->regmap, data->ien_reg, mask);
}

static int kx022a_fifo_disable(struct kx022a_data *data)
{
        int ret = 0;

        guard(mutex)(&data->mutex);
        ret = __kx022a_turn_on_off(data, false);
        if (ret)
                return ret;

        ret = regmap_clear_bits(data->regmap, data->ien_reg, KX022A_MASK_WMI);
        if (ret)
                return ret;

        ret = regmap_clear_bits(data->regmap, data->chip_info->buf_cntl2,
                                KX022A_MASK_BUF_EN);
        if (ret)
                return ret;

        data->state &= ~KX022A_STATE_FIFO;

        kx022a_drop_fifo_contents(data);

        kfree(data->fifo_buffer);

        return __kx022a_turn_on_off(data, true);
}

static int kx022a_buffer_predisable(struct iio_dev *idev)
{
        struct kx022a_data *data = iio_priv(idev);

        if (iio_device_get_current_mode(idev) == INDIO_BUFFER_TRIGGERED)
                return 0;

        return kx022a_fifo_disable(data);
}

static int kx022a_fifo_enable(struct kx022a_data *data)
{
        int ret;

        data->fifo_buffer = kmalloc_array(data->chip_info->fifo_length,
                                          KX022A_FIFO_SAMPLES_SIZE_BYTES,
                                          GFP_KERNEL);
        if (!data->fifo_buffer)
                return -ENOMEM;

        guard(mutex)(&data->mutex);
        ret = __kx022a_turn_on_off(data, false);
        if (ret)
                return ret;

        /* Update watermark to HW */
        ret = kx022a_fifo_set_wmi(data);
        if (ret)
                return ret;

        /* Enable buffer */
        ret = regmap_set_bits(data->regmap, data->chip_info->buf_cntl2,
                              KX022A_MASK_BUF_EN);
        if (ret)
                return ret;

        data->state |= KX022A_STATE_FIFO;
        ret = regmap_set_bits(data->regmap, data->ien_reg,
                              KX022A_MASK_WMI);
        if (ret)
                return ret;

        return __kx022a_turn_on_off(data, true);
}

static int kx022a_buffer_postenable(struct iio_dev *idev)
{
        struct kx022a_data *data = iio_priv(idev);

        /*
         * If we use data-ready trigger, then the IRQ masks should be handled by
         * trigger enable and the hardware buffer is not used but we just update
         * results to the IIO fifo when data-ready triggers.
         */
        if (iio_device_get_current_mode(idev) == INDIO_BUFFER_TRIGGERED)
                return 0;

        return kx022a_fifo_enable(data);
}

static const struct iio_buffer_setup_ops kx022a_buffer_ops = {
        .postenable = kx022a_buffer_postenable,
        .predisable = kx022a_buffer_predisable,
};

static irqreturn_t kx022a_trigger_handler(int irq, void *p)
{
        struct iio_poll_func *pf = p;
        struct iio_dev *idev = pf->indio_dev;
        struct kx022a_data *data = iio_priv(idev);
        int ret;

        ret = regmap_bulk_read(data->regmap, data->chip_info->xout_l, data->buffer,
                               KX022A_FIFO_SAMPLES_SIZE_BYTES);
        if (ret < 0)
                goto err_read;

        iio_push_to_buffers_with_timestamp(idev, data->buffer, data->timestamp);
err_read:
        iio_trigger_notify_done(idev->trig);

        return IRQ_HANDLED;
}

/* Get timestamps and wake the thread if we need to read data */
static irqreturn_t kx022a_irq_handler(int irq, void *private)
{
        struct iio_dev *idev = private;
        struct kx022a_data *data = iio_priv(idev);

        data->old_timestamp = data->timestamp;
        data->timestamp = iio_get_time_ns(idev);

        if (data->state & KX022A_STATE_FIFO || data->trigger_enabled)
                return IRQ_WAKE_THREAD;

        return IRQ_NONE;
}

/*
 * WMI and data-ready IRQs are acked when results are read. If we add
 * TILT/WAKE or other IRQs - then we may need to implement the acking
 * (which is racy).
 */
static irqreturn_t kx022a_irq_thread_handler(int irq, void *private)
{
        struct iio_dev *idev = private;
        struct kx022a_data *data = iio_priv(idev);
        irqreturn_t ret = IRQ_NONE;

        guard(mutex)(&data->mutex);

        if (data->trigger_enabled) {
                iio_trigger_poll_nested(data->trig);
                ret = IRQ_HANDLED;
        }

        if (data->state & KX022A_STATE_FIFO) {
                int ok;

                ok = __kx022a_fifo_flush(idev, data->chip_info->fifo_length, true);
                if (ok > 0)
                        ret = IRQ_HANDLED;
        }

        return ret;
}

static int kx022a_trigger_set_state(struct iio_trigger *trig,
                                    bool state)
{
        struct kx022a_data *data = iio_trigger_get_drvdata(trig);
        int ret = 0;

        guard(mutex)(&data->mutex);

        if (data->trigger_enabled == state)
                return 0;

        if (data->state & KX022A_STATE_FIFO) {
                dev_warn(data->dev, "Can't set trigger when FIFO enabled\n");
                return -EBUSY;
        }

        ret = __kx022a_turn_on_off(data, false);
        if (ret)
                return ret;

        data->trigger_enabled = state;
        ret = kx022a_set_drdy_irq(data, state);
        if (ret)
                return ret;

        return __kx022a_turn_on_off(data, true);
}

static const struct iio_trigger_ops kx022a_trigger_ops = {
        .set_trigger_state = kx022a_trigger_set_state,
};

static int kx022a_chip_init(struct kx022a_data *data)
{
        int ret, val;

        /* Reset the senor */
        ret = regmap_write(data->regmap, data->chip_info->cntl2, KX022A_MASK_SRST);
        if (ret)
                return ret;

        /*
         * According to the power-on procedure documents, there is (at least)
         * 2ms delay required after the software reset. This should be same for
         * all, KX022ACR-Z, KX132-1211, KX132ACR-LBZ and KX134ACR-LBZ.
         *
         * https://fscdn.rohm.com/kionix/en/document/AN010_KX022ACR-Z_Power-on_Procedure_E.pdf
         * https://fscdn.rohm.com/kionix/en/document/TN027-Power-On-Procedure.pdf
         * https://fscdn.rohm.com/kionix/en/document/AN011_KX134ACR-LBZ_Power-on_Procedure_E.pdf
         */
        msleep(2);

        ret = regmap_read_poll_timeout(data->regmap, data->chip_info->cntl2, val,
                                       !(val & KX022A_MASK_SRST),
                                       KX022A_SOFT_RESET_WAIT_TIME_US,
                                       KX022A_SOFT_RESET_TOTAL_WAIT_TIME_US);
        if (ret) {
                dev_err(data->dev, "Sensor reset %s\n",
                        val & KX022A_MASK_SRST ? "timeout" : "fail#");
                return ret;
        }

        ret = regmap_reinit_cache(data->regmap, data->chip_info->regmap_config);
        if (ret) {
                dev_err(data->dev, "Failed to reinit reg cache\n");
                return ret;
        }

        /* set data res 16bit */
        ret = regmap_set_bits(data->regmap, data->chip_info->buf_cntl2,
                              KX022A_MASK_BRES16);
        if (ret) {
                dev_err(data->dev, "Failed to set data resolution\n");
                return ret;
        }

        return kx022a_prepare_irq_pin(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),
        .scale_table                    = kx022a_scale_table,
        .scale_table_size               = ARRAY_SIZE(kx022a_scale_table) *
                                          ARRAY_SIZE(kx022a_scale_table[0]),
        .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");

const struct kx022a_chip_info kx132_chip_info = {
        .name                     = "kx132-1211",
        .regmap_config            = &kx132_regmap_config,
        .channels                 = kx132_channels,
        .num_channels             = ARRAY_SIZE(kx132_channels),
        .scale_table                    = kx022a_scale_table,
        .scale_table_size               = ARRAY_SIZE(kx022a_scale_table) *
                                          ARRAY_SIZE(kx022a_scale_table[0]),
        .fifo_length              = KX132_FIFO_LENGTH,
        .who                      = KX132_REG_WHO,
        .id                       = KX132_ID,
        .cntl                     = KX132_REG_CNTL,
        .cntl2                    = KX132_REG_CNTL2,
        .odcntl                   = KX132_REG_ODCNTL,
        .buf_cntl1                = KX132_REG_BUF_CNTL1,
        .buf_cntl2                = KX132_REG_BUF_CNTL2,
        .buf_clear                = KX132_REG_BUF_CLEAR,
        .buf_status1              = KX132_REG_BUF_STATUS_1,
        .buf_smp_lvl_mask         = KX132_MASK_BUF_SMP_LVL,
        .buf_read                 = KX132_REG_BUF_READ,
        .inc1                     = KX132_REG_INC1,
        .inc4                     = KX132_REG_INC4,
        .inc5                     = KX132_REG_INC5,
        .inc6                     = KX132_REG_INC6,
        .xout_l                   = KX132_REG_XOUT_L,
        .get_fifo_bytes_available = kx132_get_fifo_bytes_available,
};
EXPORT_SYMBOL_NS_GPL(kx132_chip_info, "IIO_KX022A");

const struct kx022a_chip_info kx134_chip_info = {
        .name                     = "kx134-1211",
        .regmap_config            = &kx132_regmap_config,
        .channels                 = kx132_channels,
        .num_channels             = ARRAY_SIZE(kx132_channels),
        .scale_table                    = kx134acr_lbz_scale_table,
        .scale_table_size               = ARRAY_SIZE(kx134acr_lbz_scale_table) *
                                          ARRAY_SIZE(kx134acr_lbz_scale_table[0]),
        .fifo_length              = KX132_FIFO_LENGTH,
        .who                      = KX132_REG_WHO,
        .id                       = KX134_1211_ID,
        .cntl                     = KX132_REG_CNTL,
        .cntl2                    = KX132_REG_CNTL2,
        .odcntl                   = KX132_REG_ODCNTL,
        .buf_cntl1                = KX132_REG_BUF_CNTL1,
        .buf_cntl2                = KX132_REG_BUF_CNTL2,
        .buf_clear                = KX132_REG_BUF_CLEAR,
        .buf_status1              = KX132_REG_BUF_STATUS_1,
        .buf_smp_lvl_mask         = KX132_MASK_BUF_SMP_LVL,
        .buf_read                 = KX132_REG_BUF_READ,
        .inc1                     = KX132_REG_INC1,
        .inc4                     = KX132_REG_INC4,
        .inc5                     = KX132_REG_INC5,
        .inc6                     = KX132_REG_INC6,
        .xout_l                   = KX132_REG_XOUT_L,
        .get_fifo_bytes_available = kx132_get_fifo_bytes_available,
};
EXPORT_SYMBOL_NS_GPL(kx134_chip_info, "IIO_KX022A");

/*
 * Despite the naming, KX132ACR-LBZ is not similar to KX132-1211 but it is
 * exact subset of KX022A. KX132ACR-LBZ is meant to be used for industrial
 * applications and the tap/double tap, free fall and tilt engines were
 * removed. Rest of the registers and functionalities (excluding the ID
 * register) are exact match to what is found in KX022.
 */
const struct kx022a_chip_info kx132acr_chip_info = {
        .name                           = "kx132acr-lbz",
        .regmap_config                  = &kx022a_regmap_config,
        .channels                       = kx022a_channels,
        .num_channels                   = ARRAY_SIZE(kx022a_channels),
        .scale_table                    = kx022a_scale_table,
        .scale_table_size               = ARRAY_SIZE(kx022a_scale_table) *
                                          ARRAY_SIZE(kx022a_scale_table[0]),
        .fifo_length                    = KX022A_FIFO_LENGTH,
        .who                            = KX022A_REG_WHO,
        .id                             = KX132ACR_LBZ_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(kx132acr_chip_info, "IIO_KX022A");

const struct kx022a_chip_info kx134acr_chip_info = {
        .name                           = "kx134acr-lbz",
        .regmap_config                  = &kx022a_regmap_config,
        .channels                       = kx022a_channels,
        .num_channels                   = ARRAY_SIZE(kx022a_channels),
        .scale_table                    = kx134acr_lbz_scale_table,
        .scale_table_size               = ARRAY_SIZE(kx134acr_lbz_scale_table) *
                                          ARRAY_SIZE(kx134acr_lbz_scale_table[0]),
        .fifo_length                    = KX022A_FIFO_LENGTH,
        .who                            = KX022A_REG_WHO,
        .id                             = KX134ACR_LBZ_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(kx134acr_chip_info, "IIO_KX022A");

int kx022a_probe_internal(struct device *dev, const struct kx022a_chip_info *chip_info)
{
        static const char * const regulator_names[] = {"io-vdd", "vdd"};
        struct iio_trigger *indio_trig;
        struct fwnode_handle *fwnode;
        struct kx022a_data *data;
        struct regmap *regmap;
        unsigned int chip_id;
        struct iio_dev *idev;
        int ret, irq;
        char *name;

        regmap = dev_get_regmap(dev, NULL);
        if (!regmap) {
                dev_err(dev, "no regmap\n");
                return -EINVAL;
        }

        fwnode = dev_fwnode(dev);
        if (!fwnode)
                return -ENODEV;

        idev = devm_iio_device_alloc(dev, sizeof(*data));
        if (!idev)
                return -ENOMEM;

        data = iio_priv(idev);
        data->chip_info = chip_info;

        /*
         * VDD is the analog and digital domain voltage supply and
         * IO_VDD is the digital I/O voltage supply.
         */
        ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),
                                             regulator_names);
        if (ret && ret != -ENODEV)
                return dev_err_probe(dev, ret, "failed to enable regulator\n");

        ret = regmap_read(regmap, chip_info->who, &chip_id);
        if (ret)
                return dev_err_probe(dev, ret, "Failed to access sensor\n");

        if (chip_id != chip_info->id)
                dev_warn(dev, "unknown device 0x%x\n", chip_id);

        irq = fwnode_irq_get_byname(fwnode, "INT1");
        if (irq > 0) {
                data->inc_reg = chip_info->inc1;
                data->ien_reg = chip_info->inc4;
        } else {
                irq = fwnode_irq_get_byname(fwnode, "INT2");
                if (irq < 0)
                        return dev_err_probe(dev, irq, "No suitable IRQ\n");

                data->inc_reg = chip_info->inc5;
                data->ien_reg = chip_info->inc6;
        }

        data->regmap = regmap;
        data->dev = dev;
        data->irq = irq;
        data->odr_ns = KX022A_DEFAULT_PERIOD_NS;
        mutex_init(&data->mutex);

        idev->channels = chip_info->channels;
        idev->num_channels = chip_info->num_channels;
        idev->name = chip_info->name;
        idev->info = &kx022a_info;
        idev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
        idev->available_scan_masks = kx022a_scan_masks;

        /* Read the mounting matrix, if present */
        ret = iio_read_mount_matrix(dev, &data->orientation);
        if (ret)
                return ret;

        /* The sensor must be turned off for configuration */
        ret = kx022a_turn_off_lock(data);
        if (ret)
                return ret;

        ret = kx022a_chip_init(data);
        if (ret) {
                mutex_unlock(&data->mutex);
                return ret;
        }

        ret = kx022a_turn_on_unlock(data);
        if (ret)
                return ret;

        ret = devm_iio_triggered_buffer_setup_ext(dev, idev,
                                                  &iio_pollfunc_store_time,
                                                  kx022a_trigger_handler,
                                                  IIO_BUFFER_DIRECTION_IN,
                                                  &kx022a_buffer_ops,
                                                  kx022a_fifo_attributes);

        if (ret)
                return dev_err_probe(data->dev, ret,
                                     "iio_triggered_buffer_setup_ext FAIL\n");
        indio_trig = devm_iio_trigger_alloc(dev, "%sdata-rdy-dev%d", idev->name,
                                            iio_device_id(idev));
        if (!indio_trig)
                return -ENOMEM;

        data->trig = indio_trig;

        indio_trig->ops = &kx022a_trigger_ops;
        iio_trigger_set_drvdata(indio_trig, data);

        /*
         * No need to check for NULL. request_threaded_irq() defaults to
         * dev_name() should the alloc fail.
         */
        name = devm_kasprintf(data->dev, GFP_KERNEL, "%s-kx022a",
                              dev_name(data->dev));

        ret = devm_request_threaded_irq(data->dev, irq, kx022a_irq_handler,
                                        &kx022a_irq_thread_handler,
                                        IRQF_ONESHOT, name, idev);
        if (ret)
                return dev_err_probe(data->dev, ret, "Could not request IRQ\n");

        ret = devm_iio_trigger_register(dev, indio_trig);
        if (ret)
                return dev_err_probe(data->dev, ret,
                                     "Trigger registration failed\n");

        ret = devm_iio_device_register(data->dev, idev);
        if (ret < 0)
                return dev_err_probe(dev, ret,
                                     "Unable to register iio device\n");

        return ret;
}
EXPORT_SYMBOL_NS_GPL(kx022a_probe_internal, "IIO_KX022A");

MODULE_DESCRIPTION("ROHM/Kionix KX022A accelerometer driver");
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
MODULE_LICENSE("GPL");