// SPDX-License-Identifier: GPL-2.0
/*
* NXP FXLS8962AF/FXLS8964AF Accelerometer Core Driver
*
* Copyright 2021 Connected Cars A/S
*
* Datasheet:
* https://www.nxp.com/docs/en/data-sheet/FXLS8962AF.pdf
* https://www.nxp.com/docs/en/data-sheet/FXLS8964AF.pdf
*
* Errata:
* https://www.nxp.com/docs/en/errata/ES_FXLS8962AF.pdf
*/
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
#include <linux/iio/buffer.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/sysfs.h>
#include "fxls8962af.h"
#define FXLS8962AF_INT_STATUS 0x00
#define FXLS8962AF_INT_STATUS_SRC_BOOT BIT(0)
#define FXLS8962AF_INT_STATUS_SRC_SDCD_OT BIT(4)
#define FXLS8962AF_INT_STATUS_SRC_BUF BIT(5)
#define FXLS8962AF_INT_STATUS_SRC_DRDY BIT(7)
#define FXLS8962AF_TEMP_OUT 0x01
#define FXLS8962AF_VECM_LSB 0x02
#define FXLS8962AF_OUT_X_LSB 0x04
#define FXLS8962AF_OUT_Y_LSB 0x06
#define FXLS8962AF_OUT_Z_LSB 0x08
#define FXLS8962AF_BUF_STATUS 0x0b
#define FXLS8962AF_BUF_STATUS_BUF_CNT GENMASK(5, 0)
#define FXLS8962AF_BUF_STATUS_BUF_OVF BIT(6)
#define FXLS8962AF_BUF_STATUS_BUF_WMRK BIT(7)
#define FXLS8962AF_BUF_X_LSB 0x0c
#define FXLS8962AF_BUF_Y_LSB 0x0e
#define FXLS8962AF_BUF_Z_LSB 0x10
#define FXLS8962AF_PROD_REV 0x12
#define FXLS8962AF_WHO_AM_I 0x13
#define FXLS8962AF_SYS_MODE 0x14
#define FXLS8962AF_SENS_CONFIG1 0x15
#define FXLS8962AF_SENS_CONFIG1_ACTIVE BIT(0)
#define FXLS8962AF_SENS_CONFIG1_RST BIT(7)
#define FXLS8962AF_SC1_FSR_MASK GENMASK(2, 1)
#define FXLS8962AF_SC1_FSR_PREP(x) FIELD_PREP(FXLS8962AF_SC1_FSR_MASK, (x))
#define FXLS8962AF_SC1_FSR_GET(x) FIELD_GET(FXLS8962AF_SC1_FSR_MASK, (x))
#define FXLS8962AF_SENS_CONFIG2 0x16
#define FXLS8962AF_SENS_CONFIG3 0x17
#define FXLS8962AF_SC3_WAKE_ODR_MASK GENMASK(7, 4)
#define FXLS8962AF_SC3_WAKE_ODR_PREP(x) FIELD_PREP(FXLS8962AF_SC3_WAKE_ODR_MASK, (x))
#define FXLS8962AF_SC3_WAKE_ODR_GET(x) FIELD_GET(FXLS8962AF_SC3_WAKE_ODR_MASK, (x))
#define FXLS8962AF_SENS_CONFIG4 0x18
#define FXLS8962AF_SC4_INT_PP_OD_MASK BIT(1)
#define FXLS8962AF_SC4_INT_PP_OD_PREP(x) FIELD_PREP(FXLS8962AF_SC4_INT_PP_OD_MASK, (x))
#define FXLS8962AF_SC4_INT_POL_MASK BIT(0)
#define FXLS8962AF_SC4_INT_POL_PREP(x) FIELD_PREP(FXLS8962AF_SC4_INT_POL_MASK, (x))
#define FXLS8962AF_SENS_CONFIG5 0x19
#define FXLS8962AF_WAKE_IDLE_LSB 0x1b
#define FXLS8962AF_SLEEP_IDLE_LSB 0x1c
#define FXLS8962AF_ASLP_COUNT_LSB 0x1e
#define FXLS8962AF_INT_EN 0x20
#define FXLS8962AF_INT_EN_SDCD_OT_EN BIT(5)
#define FXLS8962AF_INT_EN_BUF_EN BIT(6)
#define FXLS8962AF_INT_PIN_SEL 0x21
#define FXLS8962AF_INT_PIN_SEL_MASK GENMASK(7, 0)
#define FXLS8962AF_INT_PIN_SEL_INT1 0x00
#define FXLS8962AF_INT_PIN_SEL_INT2 GENMASK(7, 0)
#define FXLS8962AF_OFF_X 0x22
#define FXLS8962AF_OFF_Y 0x23
#define FXLS8962AF_OFF_Z 0x24
#define FXLS8962AF_BUF_CONFIG1 0x26
#define FXLS8962AF_BC1_BUF_MODE_MASK GENMASK(6, 5)
#define FXLS8962AF_BC1_BUF_MODE_PREP(x) FIELD_PREP(FXLS8962AF_BC1_BUF_MODE_MASK, (x))
#define FXLS8962AF_BUF_CONFIG2 0x27
#define FXLS8962AF_BUF_CONFIG2_BUF_WMRK GENMASK(5, 0)
#define FXLS8962AF_ORIENT_STATUS 0x28
#define FXLS8962AF_ORIENT_CONFIG 0x29
#define FXLS8962AF_ORIENT_DBCOUNT 0x2a
#define FXLS8962AF_ORIENT_BF_ZCOMP 0x2b
#define FXLS8962AF_ORIENT_THS_REG 0x2c
#define FXLS8962AF_SDCD_INT_SRC1 0x2d
#define FXLS8962AF_SDCD_INT_SRC1_X_OT BIT(5)
#define FXLS8962AF_SDCD_INT_SRC1_X_POL BIT(4)
#define FXLS8962AF_SDCD_INT_SRC1_Y_OT BIT(3)
#define FXLS8962AF_SDCD_INT_SRC1_Y_POL BIT(2)
#define FXLS8962AF_SDCD_INT_SRC1_Z_OT BIT(1)
#define FXLS8962AF_SDCD_INT_SRC1_Z_POL BIT(0)
#define FXLS8962AF_SDCD_INT_SRC2 0x2e
#define FXLS8962AF_SDCD_CONFIG1 0x2f
#define FXLS8962AF_SDCD_CONFIG1_Z_OT_EN BIT(3)
#define FXLS8962AF_SDCD_CONFIG1_Y_OT_EN BIT(4)
#define FXLS8962AF_SDCD_CONFIG1_X_OT_EN BIT(5)
#define FXLS8962AF_SDCD_CONFIG1_OT_ELE BIT(7)
#define FXLS8962AF_SDCD_CONFIG2 0x30
#define FXLS8962AF_SDCD_CONFIG2_SDCD_EN BIT(7)
#define FXLS8962AF_SC2_REF_UPDM_AC GENMASK(6, 5)
#define FXLS8962AF_SDCD_OT_DBCNT 0x31
#define FXLS8962AF_SDCD_WT_DBCNT 0x32
#define FXLS8962AF_SDCD_LTHS_LSB 0x33
#define FXLS8962AF_SDCD_UTHS_LSB 0x35
#define FXLS8962AF_SELF_TEST_CONFIG1 0x37
#define FXLS8962AF_SELF_TEST_CONFIG2 0x38
#define FXLS8962AF_MAX_REG 0x38
#define FXLS8962AF_DEVICE_ID 0x62
#define FXLS8964AF_DEVICE_ID 0x84
/* Raw temp channel offset */
#define FXLS8962AF_TEMP_CENTER_VAL 25
#define FXLS8962AF_AUTO_SUSPEND_DELAY_MS 2000
#define FXLS8962AF_FIFO_LENGTH 32
#define FXLS8962AF_SCALE_TABLE_LEN 4
#define FXLS8962AF_SAMP_FREQ_TABLE_LEN 13
static const int fxls8962af_scale_table[FXLS8962AF_SCALE_TABLE_LEN][2] = {
{0, IIO_G_TO_M_S_2(980000)},
{0, IIO_G_TO_M_S_2(1950000)},
{0, IIO_G_TO_M_S_2(3910000)},
{0, IIO_G_TO_M_S_2(7810000)},
};
static const int fxls8962af_samp_freq_table[FXLS8962AF_SAMP_FREQ_TABLE_LEN][2] = {
{3200, 0}, {1600, 0}, {800, 0}, {400, 0}, {200, 0}, {100, 0},
{50, 0}, {25, 0}, {12, 500000}, {6, 250000}, {3, 125000},
{1, 563000}, {0, 781000},
};
struct fxls8962af_chip_info {
const char *name;