Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * mma8452.c - Support for following Freescale / NXP 3-axis accelerometers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * device name	digital output	7-bit I2C slave address (pin selectable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * MMA8451Q	14 bit		0x1c / 0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * MMA8452Q	12 bit		0x1c / 0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * MMA8453Q	10 bit		0x1c / 0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * MMA8652FC	12 bit		0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * MMA8653FC	10 bit		0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * FXLS8471Q	14 bit		0x1e / 0x1d / 0x1c / 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * Copyright 2015 Martin Kepplinger <martink@posteo.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * Copyright 2014 Peter Meerwald <pmeerw@pmeerw.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  * TODO: orientation events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/iio/trigger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/iio/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define MMA8452_STATUS				0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define  MMA8452_STATUS_DRDY			(BIT(2) | BIT(1) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define MMA8452_OUT_X				0x01 /* MSB first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define MMA8452_OUT_Y				0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define MMA8452_OUT_Z				0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define MMA8452_INT_SRC				0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define MMA8452_WHO_AM_I			0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define MMA8452_DATA_CFG			0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define  MMA8452_DATA_CFG_FS_MASK		GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define  MMA8452_DATA_CFG_FS_2G			0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define  MMA8452_DATA_CFG_FS_4G			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define  MMA8452_DATA_CFG_FS_8G			2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define  MMA8452_DATA_CFG_HPF_MASK		BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define MMA8452_HP_FILTER_CUTOFF		0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define  MMA8452_HP_FILTER_CUTOFF_SEL_MASK	GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define MMA8452_FF_MT_CFG			0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define  MMA8452_FF_MT_CFG_OAE			BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define  MMA8452_FF_MT_CFG_ELE			BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define MMA8452_FF_MT_SRC			0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define  MMA8452_FF_MT_SRC_XHE			BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define  MMA8452_FF_MT_SRC_YHE			BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define  MMA8452_FF_MT_SRC_ZHE			BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define MMA8452_FF_MT_THS			0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define  MMA8452_FF_MT_THS_MASK			0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define MMA8452_FF_MT_COUNT			0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define MMA8452_FF_MT_CHAN_SHIFT	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define MMA8452_TRANSIENT_CFG			0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define  MMA8452_TRANSIENT_CFG_CHAN(chan)	BIT(chan + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define  MMA8452_TRANSIENT_CFG_HPF_BYP		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define  MMA8452_TRANSIENT_CFG_ELE		BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define MMA8452_TRANSIENT_SRC			0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define  MMA8452_TRANSIENT_SRC_XTRANSE		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define  MMA8452_TRANSIENT_SRC_YTRANSE		BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define  MMA8452_TRANSIENT_SRC_ZTRANSE		BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define MMA8452_TRANSIENT_THS			0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define  MMA8452_TRANSIENT_THS_MASK		GENMASK(6, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define MMA8452_TRANSIENT_COUNT			0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define MMA8452_TRANSIENT_CHAN_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define MMA8452_CTRL_REG1			0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define  MMA8452_CTRL_ACTIVE			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define  MMA8452_CTRL_DR_MASK			GENMASK(5, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define  MMA8452_CTRL_DR_SHIFT			3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define  MMA8452_CTRL_DR_DEFAULT		0x4 /* 50 Hz sample frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define MMA8452_CTRL_REG2			0x2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define  MMA8452_CTRL_REG2_RST			BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define  MMA8452_CTRL_REG2_MODS_SHIFT		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define  MMA8452_CTRL_REG2_MODS_MASK		0x1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define MMA8452_CTRL_REG4			0x2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define MMA8452_CTRL_REG5			0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #define MMA8452_OFF_X				0x2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define MMA8452_OFF_Y				0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define MMA8452_OFF_Z				0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define MMA8452_MAX_REG				0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define  MMA8452_INT_DRDY			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define  MMA8452_INT_FF_MT			BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define  MMA8452_INT_TRANS			BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #define MMA8451_DEVICE_ID			0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define MMA8452_DEVICE_ID			0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define MMA8453_DEVICE_ID			0x3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define MMA8652_DEVICE_ID			0x4a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #define MMA8653_DEVICE_ID			0x5a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #define FXLS8471_DEVICE_ID			0x6a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #define MMA8452_AUTO_SUSPEND_DELAY_MS		2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) struct mma8452_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	u8 ctrl_reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	u8 data_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	const struct mma_chip_info *chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	int sleep_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	struct regulator *vdd_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	struct regulator *vddio_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	/* Ensure correct alignment of time stamp when present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 		__be16 channels[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		s64 ts __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	} buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)   * struct mma8452_event_regs - chip specific data related to events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123)   * @ev_cfg:			event config register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)   * @ev_cfg_ele:			latch bit in event config register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)   * @ev_cfg_chan_shift:		number of the bit to enable events in X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)   *				direction; in event config register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)   * @ev_src:			event source register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)   * @ev_ths:			event threshold register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)   * @ev_ths_mask:		mask for the threshold value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)   * @ev_count:			event count (period) register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131)   *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132)   * Since not all chips supported by the driver support comparing high pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133)   * filtered data for events (interrupts), different interrupt sources are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134)   * used for different chips and the relevant registers are included here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135)   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) struct mma8452_event_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 		u8 ev_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		u8 ev_cfg_ele;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 		u8 ev_cfg_chan_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		u8 ev_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		u8 ev_ths;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		u8 ev_ths_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		u8 ev_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) static const struct mma8452_event_regs ff_mt_ev_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		.ev_cfg = MMA8452_FF_MT_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		.ev_cfg_ele = MMA8452_FF_MT_CFG_ELE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		.ev_cfg_chan_shift = MMA8452_FF_MT_CHAN_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 		.ev_src = MMA8452_FF_MT_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		.ev_ths = MMA8452_FF_MT_THS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		.ev_ths_mask = MMA8452_FF_MT_THS_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		.ev_count = MMA8452_FF_MT_COUNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) static const struct mma8452_event_regs trans_ev_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		.ev_cfg = MMA8452_TRANSIENT_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		.ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		.ev_cfg_chan_shift = MMA8452_TRANSIENT_CHAN_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		.ev_src = MMA8452_TRANSIENT_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		.ev_ths = MMA8452_TRANSIENT_THS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		.ev_ths_mask = MMA8452_TRANSIENT_THS_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		.ev_count = MMA8452_TRANSIENT_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  * struct mma_chip_info - chip specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * @chip_id:			WHO_AM_I register's value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  * @channels:			struct iio_chan_spec matching the device's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  *				capabilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  * @num_channels:		number of channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)  * @mma_scales:			scale factors for converting register values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173)  *				to m/s^2; 3 modes: 2g, 4g, 8g; 2 integers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174)  *				per mode: m/s^2 and micro m/s^2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  * @all_events:			all events supported by this chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176)  * @enabled_events:		event flags enabled and handled by this driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) struct mma_chip_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	u8 chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	const struct iio_chan_spec *channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	int num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	const int mma_scales[3][2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	int all_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	int enabled_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	idx_x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	idx_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	idx_z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	idx_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) static int mma8452_drdy(struct mma8452_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	int tries = 150;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	while (tries-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		int ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 			MMA8452_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 		if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		if (data->sleep_val <= 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 			usleep_range(data->sleep_val * 250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 				     data->sleep_val * 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 			msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	dev_err(&data->client->dev, "data not ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) static int mma8452_set_runtime_pm_state(struct i2c_client *client, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		ret = pm_runtime_get_sync(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		pm_runtime_mark_last_busy(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		ret = pm_runtime_put_autosuspend(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 			"failed to change power state to %d\n", on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 			pm_runtime_put_noidle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) static int mma8452_read(struct mma8452_data *data, __be16 buf[3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	int ret = mma8452_drdy(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	ret = mma8452_set_runtime_pm_state(data->client, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	ret = i2c_smbus_read_i2c_block_data(data->client, MMA8452_OUT_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 					    3 * sizeof(__be16), (u8 *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	ret = mma8452_set_runtime_pm_state(data->client, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) static ssize_t mma8452_show_int_plus_micros(char *buf, const int (*vals)[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 					    int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	size_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	while (n-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 				 vals[n][0], vals[n][1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	/* replace trailing space by newline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	buf[len - 1] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 					     int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	while (n-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		if (val == vals[n][0] && val2 == vals[n][1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 			return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) static unsigned int mma8452_get_odr_index(struct mma8452_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	return (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			MMA8452_CTRL_DR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) static const int mma8452_samp_freq[8][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	{800, 0}, {400, 0}, {200, 0}, {100, 0}, {50, 0}, {12, 500000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	{6, 250000}, {1, 560000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) /* Datasheet table: step time "Relationship with the ODR" (sample frequency) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) static const unsigned int mma8452_time_step_us[4][8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	{ 1250, 2500, 5000, 10000, 20000, 20000, 20000, 20000 },  /* normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	{ 1250, 2500, 5000, 10000, 20000, 80000, 80000, 80000 },  /* l p l n */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	{ 1250, 2500, 2500, 2500, 2500, 2500, 2500, 2500 },	  /* high res*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	{ 1250, 2500, 5000, 10000, 20000, 80000, 160000, 160000 } /* l p */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) /* Datasheet table "High-Pass Filter Cutoff Options" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) static const int mma8452_hp_filter_cutoff[4][8][4][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	{ /* normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },		/* 800 Hz sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },		/* 400 Hz sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	{ {8, 0}, {4, 0}, {2, 0}, {1, 0} },		/* 200 Hz sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	{ {4, 0}, {2, 0}, {1, 0}, {0, 500000} },	/* 100 Hz sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} },	/* 50 Hz sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} },	/* 12.5 Hz sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} },	/* 6.25 Hz sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }	/* 1.56 Hz sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	{ /* low noise low power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	{ {8, 0}, {4, 0}, {2, 0}, {1, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	{ {4, 0}, {2, 0}, {1, 0}, {0, 500000} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	{ {0, 500000}, {0, 250000}, {0, 125000}, {0, 063000} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	{ {0, 500000}, {0, 250000}, {0, 125000}, {0, 063000} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	{ {0, 500000}, {0, 250000}, {0, 125000}, {0, 063000} }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	{ /* high resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	{ /* low power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	{ {8, 0}, {4, 0}, {2, 0}, {1, 0} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	{ {4, 0}, {2, 0}, {1, 0}, {0, 500000} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	{ {1, 0}, {0, 500000}, {0, 250000}, {0, 125000} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	{ {0, 250000}, {0, 125000}, {0, 063000}, {0, 031000} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	{ {0, 250000}, {0, 125000}, {0, 063000}, {0, 031000} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	{ {0, 250000}, {0, 125000}, {0, 063000}, {0, 031000} }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) /* Datasheet table "MODS Oversampling modes averaging values at each ODR" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) static const u16 mma8452_os_ratio[4][8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	/* 800 Hz, 400 Hz, ... , 1.56 Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	{ 2, 4, 4, 4, 4, 16, 32, 128 },		/* normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	{ 2, 4, 4, 4, 4, 4, 8, 32 },		/* low power low noise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	{ 2, 4, 8, 16, 32, 128, 256, 1024 },	/* high resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	{ 2, 2, 2, 2, 2, 2, 4, 16 }		/* low power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) static int mma8452_get_power_mode(struct mma8452_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	reg = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 				       MMA8452_CTRL_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	return ((reg & MMA8452_CTRL_REG2_MODS_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		MMA8452_CTRL_REG2_MODS_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 					    struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 					    char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	return mma8452_show_int_plus_micros(buf, mma8452_samp_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 					    ARRAY_SIZE(mma8452_samp_freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) static ssize_t mma8452_show_scale_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 					struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 					char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	struct mma8452_data *data = iio_priv(i2c_get_clientdata(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 					     to_i2c_client(dev)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	return mma8452_show_int_plus_micros(buf, data->chip_info->mma_scales,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		ARRAY_SIZE(data->chip_info->mma_scales));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) static ssize_t mma8452_show_hp_cutoff_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 					    struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 					    char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	i = mma8452_get_odr_index(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	j = mma8452_get_power_mode(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	if (j < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		return j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	return mma8452_show_int_plus_micros(buf, mma8452_hp_filter_cutoff[j][i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		ARRAY_SIZE(mma8452_hp_filter_cutoff[0][0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) static ssize_t mma8452_show_os_ratio_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 					   struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 					   char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	int i = mma8452_get_odr_index(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	u16 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	size_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	for (j = 0; j < ARRAY_SIZE(mma8452_os_ratio); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		if (val == mma8452_os_ratio[j][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		val = mma8452_os_ratio[j][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	buf[len - 1] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		       mma8452_show_scale_avail, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) static IIO_DEVICE_ATTR(in_accel_filter_high_pass_3db_frequency_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		       0444, mma8452_show_hp_cutoff_avail, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) static IIO_DEVICE_ATTR(in_accel_oversampling_ratio_available, 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		       mma8452_show_os_ratio_avail, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) static int mma8452_get_samp_freq_index(struct mma8452_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 				       int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	return mma8452_get_int_plus_micros_index(mma8452_samp_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 						 ARRAY_SIZE(mma8452_samp_freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 						 val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) static int mma8452_get_scale_index(struct mma8452_data *data, int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	return mma8452_get_int_plus_micros_index(data->chip_info->mma_scales,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			ARRAY_SIZE(data->chip_info->mma_scales), val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) static int mma8452_get_hp_filter_index(struct mma8452_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 				       int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	i = mma8452_get_odr_index(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	j = mma8452_get_power_mode(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	if (j < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		return j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	return mma8452_get_int_plus_micros_index(mma8452_hp_filter_cutoff[j][i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		ARRAY_SIZE(mma8452_hp_filter_cutoff[0][0]), val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) static int mma8452_read_hp_filter(struct mma8452_data *data, int *hz, int *uHz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	int j, i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	ret = i2c_smbus_read_byte_data(data->client, MMA8452_HP_FILTER_CUTOFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	i = mma8452_get_odr_index(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	j = mma8452_get_power_mode(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	if (j < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		return j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	ret &= MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	*hz = mma8452_hp_filter_cutoff[j][i][ret][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	*uHz = mma8452_hp_filter_cutoff[j][i][ret][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) static int mma8452_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			    struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 			    int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	__be16 buffer[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		ret = mma8452_read(data, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		*val = sign_extend32(be16_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 			buffer[chan->scan_index]) >> chan->scan_type.shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 			chan->scan_type.realbits - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		*val = data->chip_info->mma_scales[i][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		*val2 = data->chip_info->mma_scales[i][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		i = mma8452_get_odr_index(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		*val = mma8452_samp_freq[i][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		*val2 = mma8452_samp_freq[i][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	case IIO_CHAN_INFO_CALIBBIAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 					       MMA8452_OFF_X +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 					       chan->scan_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		*val = sign_extend32(ret, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		if (data->data_cfg & MMA8452_DATA_CFG_HPF_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 			ret = mma8452_read_hp_filter(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 			*val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			*val2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		ret = mma8452_get_power_mode(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		i = mma8452_get_odr_index(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		*val = mma8452_os_ratio[ret][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) static int mma8452_calculate_sleep(struct mma8452_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	int ret, i = mma8452_get_odr_index(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	if (mma8452_samp_freq[i][0] > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		ret = 1000 / mma8452_samp_freq[i][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		ret = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	return ret == 0 ? 1 : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) static int mma8452_standby(struct mma8452_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 					data->ctrl_reg1 & ~MMA8452_CTRL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) static int mma8452_active(struct mma8452_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 					 data->ctrl_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) /* returns >0 if active, 0 if in standby and <0 on error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) static int mma8452_is_active(struct mma8452_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	reg = i2c_smbus_read_byte_data(data->client, MMA8452_CTRL_REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	return reg & MMA8452_CTRL_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	int is_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	is_active = mma8452_is_active(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	if (is_active < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		ret = is_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	/* config can only be changed when in standby */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	if (is_active > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		ret = mma8452_standby(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 			goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	ret = i2c_smbus_write_byte_data(data->client, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	if (is_active > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		ret = mma8452_active(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 			goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) static int mma8452_set_power_mode(struct mma8452_data *data, u8 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	reg = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 				       MMA8452_CTRL_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	reg &= ~MMA8452_CTRL_REG2_MODS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	reg |= mode << MMA8452_CTRL_REG2_MODS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	return mma8452_change_config(data, MMA8452_CTRL_REG2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) /* returns >0 if in freefall mode, 0 if not or <0 if an error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) static int mma8452_freefall_mode_enabled(struct mma8452_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	val = i2c_smbus_read_byte_data(data->client, MMA8452_FF_MT_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	return !(val & MMA8452_FF_MT_CFG_OAE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) static int mma8452_set_freefall_mode(struct mma8452_data *data, bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	if ((state && mma8452_freefall_mode_enabled(data)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	    (!state && !(mma8452_freefall_mode_enabled(data))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	val = i2c_smbus_read_byte_data(data->client, MMA8452_FF_MT_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		val |= BIT(idx_x + MMA8452_FF_MT_CHAN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		val |= BIT(idx_y + MMA8452_FF_MT_CHAN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		val |= BIT(idx_z + MMA8452_FF_MT_CHAN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		val &= ~MMA8452_FF_MT_CFG_OAE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		val &= ~BIT(idx_x + MMA8452_FF_MT_CHAN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		val &= ~BIT(idx_y + MMA8452_FF_MT_CHAN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		val &= ~BIT(idx_z + MMA8452_FF_MT_CHAN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		val |= MMA8452_FF_MT_CFG_OAE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	return mma8452_change_config(data, MMA8452_FF_MT_CFG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) static int mma8452_set_hp_filter_frequency(struct mma8452_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 					   int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	int i, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	i = mma8452_get_hp_filter_index(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	if (i < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	reg = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 				       MMA8452_HP_FILTER_CUTOFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	reg |= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	return mma8452_change_config(data, MMA8452_HP_FILTER_CUTOFF, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) static int mma8452_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			     struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			     int val, int val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		i = mma8452_get_samp_freq_index(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 			ret = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		data->sleep_val = mma8452_calculate_sleep(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		ret = mma8452_change_config(data, MMA8452_CTRL_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 					    data->ctrl_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		i = mma8452_get_scale_index(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			ret = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		data->data_cfg |= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		ret = mma8452_change_config(data, MMA8452_DATA_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 					    data->data_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	case IIO_CHAN_INFO_CALIBBIAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		if (val < -128 || val > 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		ret = mma8452_change_config(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 					    MMA8452_OFF_X + chan->scan_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 					    val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		if (val == 0 && val2 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 			data->data_cfg &= ~MMA8452_DATA_CFG_HPF_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			data->data_cfg |= MMA8452_DATA_CFG_HPF_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			ret = mma8452_set_hp_filter_frequency(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		ret = mma8452_change_config(data, MMA8452_DATA_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 					     data->data_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		ret = mma8452_get_odr_index(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		for (i = 0; i < ARRAY_SIZE(mma8452_os_ratio); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 			if (mma8452_os_ratio[i][ret] == val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 				ret = mma8452_set_power_mode(data, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) static int mma8452_get_event_regs(struct mma8452_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		const struct iio_chan_spec *chan, enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		const struct mma8452_event_regs **ev_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	if (!chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	case IIO_ACCEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 			if ((data->chip_info->all_events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 					& MMA8452_INT_TRANS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 				(data->chip_info->enabled_events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 					& MMA8452_INT_TRANS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 				*ev_reg = &trans_ev_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 				*ev_reg = &ff_mt_ev_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			*ev_reg = &ff_mt_ev_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) static int mma8452_read_event_value(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 			       const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			       enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 			       enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 			       enum iio_event_info info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 			       int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	int ret, us, power_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	const struct mma8452_event_regs *ev_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	ret = mma8452_get_event_regs(data, chan, dir, &ev_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	case IIO_EV_INFO_VALUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		ret = i2c_smbus_read_byte_data(data->client, ev_regs->ev_ths);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		*val = ret & ev_regs->ev_ths_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	case IIO_EV_INFO_PERIOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		ret = i2c_smbus_read_byte_data(data->client, ev_regs->ev_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		power_mode = mma8452_get_power_mode(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		if (power_mode < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			return power_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		us = ret * mma8452_time_step_us[power_mode][
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 				mma8452_get_odr_index(data)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		*val = us / USEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		*val2 = us % USEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 					       MMA8452_TRANSIENT_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		if (ret & MMA8452_TRANSIENT_CFG_HPF_BYP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 			*val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			*val2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			ret = mma8452_read_hp_filter(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) static int mma8452_write_event_value(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 				const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 				enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 				enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 				enum iio_event_info info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 				int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	int ret, reg, steps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	const struct mma8452_event_regs *ev_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	ret = mma8452_get_event_regs(data, chan, dir, &ev_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	case IIO_EV_INFO_VALUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		if (val < 0 || val > ev_regs->ev_ths_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		return mma8452_change_config(data, ev_regs->ev_ths, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	case IIO_EV_INFO_PERIOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		ret = mma8452_get_power_mode(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		steps = (val * USEC_PER_SEC + val2) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 				mma8452_time_step_us[ret][
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 					mma8452_get_odr_index(data)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		if (steps < 0 || steps > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		return mma8452_change_config(data, ev_regs->ev_count, steps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		reg = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 					       MMA8452_TRANSIENT_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 			return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		if (val == 0 && val2 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			reg |= MMA8452_TRANSIENT_CFG_HPF_BYP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			reg &= ~MMA8452_TRANSIENT_CFG_HPF_BYP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			ret = mma8452_set_hp_filter_frequency(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) static int mma8452_read_event_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 				     const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 				     enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 				     enum iio_event_direction dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	const struct mma8452_event_regs *ev_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	ret = mma8452_get_event_regs(data, chan, dir, &ev_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		return mma8452_freefall_mode_enabled(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 				ev_regs->ev_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		return !!(ret & BIT(chan->scan_index +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 				ev_regs->ev_cfg_chan_shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) static int mma8452_write_event_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 				      const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 				      enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 				      enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 				      int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	int val, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	const struct mma8452_event_regs *ev_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	ret = mma8452_get_event_regs(data, chan, dir, &ev_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	ret = mma8452_set_runtime_pm_state(data->client, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		return mma8452_set_freefall_mode(data, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		val = i2c_smbus_read_byte_data(data->client, ev_regs->ev_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 			return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 			if (mma8452_freefall_mode_enabled(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 				val &= ~BIT(idx_x + ev_regs->ev_cfg_chan_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 				val &= ~BIT(idx_y + ev_regs->ev_cfg_chan_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 				val &= ~BIT(idx_z + ev_regs->ev_cfg_chan_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 				val |= MMA8452_FF_MT_CFG_OAE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 			val |= BIT(chan->scan_index +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 					ev_regs->ev_cfg_chan_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 			if (mma8452_freefall_mode_enabled(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 			val &= ~BIT(chan->scan_index +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 					ev_regs->ev_cfg_chan_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		val |= ev_regs->ev_cfg_ele;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		return mma8452_change_config(data, ev_regs->ev_cfg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static void mma8452_transient_interrupt(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	s64 ts = iio_get_time_ns(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	int src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	src = i2c_smbus_read_byte_data(data->client, MMA8452_TRANSIENT_SRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	if (src < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	if (src & MMA8452_TRANSIENT_SRC_XTRANSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		iio_push_event(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 			       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 						  IIO_EV_TYPE_MAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 						  IIO_EV_DIR_RISING),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 			       ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	if (src & MMA8452_TRANSIENT_SRC_YTRANSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		iio_push_event(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 						  IIO_EV_TYPE_MAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 						  IIO_EV_DIR_RISING),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			       ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	if (src & MMA8452_TRANSIENT_SRC_ZTRANSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		iio_push_event(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 						  IIO_EV_TYPE_MAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 						  IIO_EV_DIR_RISING),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 			       ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static irqreturn_t mma8452_interrupt(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	struct iio_dev *indio_dev = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	int ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	int src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	src = i2c_smbus_read_byte_data(data->client, MMA8452_INT_SRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	if (src < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	if (!(src & (data->chip_info->enabled_events | MMA8452_INT_DRDY)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	if (src & MMA8452_INT_DRDY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		iio_trigger_poll_chained(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	if (src & MMA8452_INT_FF_MT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		if (mma8452_freefall_mode_enabled(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			s64 ts = iio_get_time_ns(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 			iio_push_event(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 				       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 							  IIO_MOD_X_AND_Y_AND_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 							  IIO_EV_TYPE_MAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 							  IIO_EV_DIR_FALLING),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 					ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	if (src & MMA8452_INT_TRANS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		mma8452_transient_interrupt(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static irqreturn_t mma8452_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	ret = mma8452_read(data, data->buffer.channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 					   iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static int mma8452_reg_access_dbg(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 				  unsigned int reg, unsigned int writeval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 				  unsigned int *readval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	if (reg > MMA8452_MAX_REG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	if (!readval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		return mma8452_change_config(data, reg, writeval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	ret = i2c_smbus_read_byte_data(data->client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	*readval = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static const struct iio_event_spec mma8452_freefall_event[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		.type = IIO_EV_TYPE_MAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		.dir = IIO_EV_DIR_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 					BIT(IIO_EV_INFO_PERIOD) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 					BIT(IIO_EV_INFO_HIGH_PASS_FILTER_3DB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) static const struct iio_event_spec mma8652_freefall_event[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		.type = IIO_EV_TYPE_MAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		.dir = IIO_EV_DIR_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 					BIT(IIO_EV_INFO_PERIOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static const struct iio_event_spec mma8452_transient_event[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		.type = IIO_EV_TYPE_MAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		.dir = IIO_EV_DIR_RISING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 					BIT(IIO_EV_INFO_PERIOD) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 					BIT(IIO_EV_INFO_HIGH_PASS_FILTER_3DB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) static const struct iio_event_spec mma8452_motion_event[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		.type = IIO_EV_TYPE_MAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		.dir = IIO_EV_DIR_RISING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 					BIT(IIO_EV_INFO_PERIOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)  * Threshold is configured in fixed 8G/127 steps regardless of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)  * currently selected scale for measurement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) static IIO_CONST_ATTR_NAMED(accel_transient_scale, in_accel_scale, "0.617742");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static struct attribute *mma8452_event_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	&iio_const_attr_accel_transient_scale.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) static struct attribute_group mma8452_event_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	.attrs = mma8452_event_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) #define MMA8452_FREEFALL_CHANNEL(modifier) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	.type = IIO_ACCEL, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	.modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	.channel2 = modifier, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	.scan_index = -1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	.event_spec = mma8452_freefall_event, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	.num_event_specs = ARRAY_SIZE(mma8452_freefall_event), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) #define MMA8652_FREEFALL_CHANNEL(modifier) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	.type = IIO_ACCEL, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	.modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	.channel2 = modifier, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	.scan_index = -1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	.event_spec = mma8652_freefall_event, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	.num_event_specs = ARRAY_SIZE(mma8652_freefall_event), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) #define MMA8452_CHANNEL(axis, idx, bits) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	.type = IIO_ACCEL, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	.modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	.channel2 = IIO_MOD_##axis, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			      BIT(IIO_CHAN_INFO_CALIBBIAS), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 			BIT(IIO_CHAN_INFO_SCALE) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 			BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	.scan_index = idx, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	.scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		.sign = 's', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		.realbits = (bits), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		.storagebits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		.shift = 16 - (bits), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		.endianness = IIO_BE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	}, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	.event_spec = mma8452_transient_event, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	.num_event_specs = ARRAY_SIZE(mma8452_transient_event), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) #define MMA8652_CHANNEL(axis, idx, bits) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	.type = IIO_ACCEL, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	.modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	.channel2 = IIO_MOD_##axis, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		BIT(IIO_CHAN_INFO_CALIBBIAS), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		BIT(IIO_CHAN_INFO_SCALE) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	.scan_index = idx, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	.scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		.sign = 's', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		.realbits = (bits), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		.storagebits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		.shift = 16 - (bits), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 		.endianness = IIO_BE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	}, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	.event_spec = mma8452_motion_event, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	.num_event_specs = ARRAY_SIZE(mma8452_motion_event), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) static const struct iio_chan_spec mma8451_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	MMA8452_CHANNEL(X, idx_x, 14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	MMA8452_CHANNEL(Y, idx_y, 14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	MMA8452_CHANNEL(Z, idx_z, 14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	IIO_CHAN_SOFT_TIMESTAMP(idx_ts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	MMA8452_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) static const struct iio_chan_spec mma8452_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	MMA8452_CHANNEL(X, idx_x, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	MMA8452_CHANNEL(Y, idx_y, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	MMA8452_CHANNEL(Z, idx_z, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	IIO_CHAN_SOFT_TIMESTAMP(idx_ts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	MMA8452_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) static const struct iio_chan_spec mma8453_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	MMA8452_CHANNEL(X, idx_x, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	MMA8452_CHANNEL(Y, idx_y, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	MMA8452_CHANNEL(Z, idx_z, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	IIO_CHAN_SOFT_TIMESTAMP(idx_ts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	MMA8452_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static const struct iio_chan_spec mma8652_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	MMA8652_CHANNEL(X, idx_x, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	MMA8652_CHANNEL(Y, idx_y, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	MMA8652_CHANNEL(Z, idx_z, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	IIO_CHAN_SOFT_TIMESTAMP(idx_ts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	MMA8652_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static const struct iio_chan_spec mma8653_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	MMA8652_CHANNEL(X, idx_x, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	MMA8652_CHANNEL(Y, idx_y, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	MMA8652_CHANNEL(Z, idx_z, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	IIO_CHAN_SOFT_TIMESTAMP(idx_ts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	MMA8652_FREEFALL_CHANNEL(IIO_MOD_X_AND_Y_AND_Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	mma8451,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	mma8452,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	mma8453,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	mma8652,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	mma8653,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	fxls8471,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) static const struct mma_chip_info mma_chip_info_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	[mma8451] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 		.name = "mma8451",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		.chip_id = MMA8451_DEVICE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		.channels = mma8451_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 		.num_channels = ARRAY_SIZE(mma8451_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 		 * Hardware has fullscale of -2G, -4G, -8G corresponding to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		 * raw value -8192 for 14 bit, -2048 for 12 bit or -512 for 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		 * bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		 * The userspace interface uses m/s^2 and we declare micro units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		 * So scale factor for 12 bit here is given by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		 *	g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		.mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		 * Although we enable the interrupt sources once and for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		 * all here the event detection itself is not enabled until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 		 * userspace asks for it by mma8452_write_event_config()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 		.all_events = MMA8452_INT_DRDY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 					MMA8452_INT_TRANS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 		.enabled_events = MMA8452_INT_TRANS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	[mma8452] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		.name = "mma8452",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 		.chip_id = MMA8452_DEVICE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		.channels = mma8452_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		.num_channels = ARRAY_SIZE(mma8452_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		.mma_scales = { {0, 9577}, {0, 19154}, {0, 38307} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		 * Although we enable the interrupt sources once and for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		 * all here the event detection itself is not enabled until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 		 * userspace asks for it by mma8452_write_event_config()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		.all_events = MMA8452_INT_DRDY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 					MMA8452_INT_TRANS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 		.enabled_events = MMA8452_INT_TRANS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	[mma8453] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 		.name = "mma8453",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 		.chip_id = MMA8453_DEVICE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 		.channels = mma8453_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		.num_channels = ARRAY_SIZE(mma8453_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 		.mma_scales = { {0, 38307}, {0, 76614}, {0, 153228} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 		 * Although we enable the interrupt sources once and for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		 * all here the event detection itself is not enabled until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		 * userspace asks for it by mma8452_write_event_config()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 		.all_events = MMA8452_INT_DRDY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 					MMA8452_INT_TRANS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		.enabled_events = MMA8452_INT_TRANS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	[mma8652] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		.name = "mma8652",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		.chip_id = MMA8652_DEVICE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		.channels = mma8652_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		.num_channels = ARRAY_SIZE(mma8652_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		.mma_scales = { {0, 9577}, {0, 19154}, {0, 38307} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 		.all_events = MMA8452_INT_DRDY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		.enabled_events = MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	[mma8653] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 		.name = "mma8653",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		.chip_id = MMA8653_DEVICE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		.channels = mma8653_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		.num_channels = ARRAY_SIZE(mma8653_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		.mma_scales = { {0, 38307}, {0, 76614}, {0, 153228} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		 * Although we enable the interrupt sources once and for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		 * all here the event detection itself is not enabled until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		 * userspace asks for it by mma8452_write_event_config()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		.all_events = MMA8452_INT_DRDY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 		.enabled_events = MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	[fxls8471] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		.name = "fxls8471",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 		.chip_id = FXLS8471_DEVICE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 		.channels = mma8451_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 		.num_channels = ARRAY_SIZE(mma8451_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		.mma_scales = { {0, 2394}, {0, 4788}, {0, 9577} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		 * Although we enable the interrupt sources once and for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		 * all here the event detection itself is not enabled until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		 * userspace asks for it by mma8452_write_event_config()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		.all_events = MMA8452_INT_DRDY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 					MMA8452_INT_TRANS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		.enabled_events = MMA8452_INT_TRANS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 					MMA8452_INT_FF_MT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) static struct attribute *mma8452_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	&iio_dev_attr_in_accel_filter_high_pass_3db_frequency_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	&iio_dev_attr_in_accel_oversampling_ratio_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) static const struct attribute_group mma8452_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	.attrs = mma8452_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) static const struct iio_info mma8452_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	.attrs = &mma8452_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	.read_raw = &mma8452_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	.write_raw = &mma8452_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	.event_attrs = &mma8452_event_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	.read_event_value = &mma8452_read_event_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	.write_event_value = &mma8452_write_event_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	.read_event_config = &mma8452_read_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	.write_event_config = &mma8452_write_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	.debugfs_reg_access = &mma8452_reg_access_dbg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) static const unsigned long mma8452_scan_masks[] = {0x7, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) static int mma8452_data_rdy_trigger_set_state(struct iio_trigger *trig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 					      bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	int reg, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	ret = mma8452_set_runtime_pm_state(data->client, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	reg = i2c_smbus_read_byte_data(data->client, MMA8452_CTRL_REG4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		reg |= MMA8452_INT_DRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		reg &= ~MMA8452_INT_DRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	return mma8452_change_config(data, MMA8452_CTRL_REG4, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) static const struct iio_trigger_ops mma8452_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	.set_trigger_state = mma8452_data_rdy_trigger_set_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	.validate_device = iio_trigger_validate_own_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) static int mma8452_trigger_setup(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	struct iio_trigger *trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	trig = devm_iio_trigger_alloc(&data->client->dev, "%s-dev%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 				      indio_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 				      indio_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	if (!trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	trig->dev.parent = &data->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	trig->ops = &mma8452_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	iio_trigger_set_drvdata(trig, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	ret = iio_trigger_register(trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	indio_dev->trig = iio_trigger_get(trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) static void mma8452_trigger_cleanup(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	if (indio_dev->trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		iio_trigger_unregister(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) static int mma8452_reset(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	ret = i2c_smbus_write_byte_data(client,	MMA8452_CTRL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 					MMA8452_CTRL_REG2_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	for (i = 0; i < 10; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 		usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 		ret = i2c_smbus_read_byte_data(client, MMA8452_CTRL_REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 		if (ret == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 			continue; /* I2C comm reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		if (!(ret & MMA8452_CTRL_REG2_RST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) static const struct of_device_id mma8452_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	{ .compatible = "fsl,mma8451", .data = &mma_chip_info_table[mma8451] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	{ .compatible = "fsl,mma8452", .data = &mma_chip_info_table[mma8452] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	{ .compatible = "fsl,mma8453", .data = &mma_chip_info_table[mma8453] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	{ .compatible = "fsl,mma8652", .data = &mma_chip_info_table[mma8652] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	{ .compatible = "fsl,mma8653", .data = &mma_chip_info_table[mma8653] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	{ .compatible = "fsl,fxls8471", .data = &mma_chip_info_table[fxls8471] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) MODULE_DEVICE_TABLE(of, mma8452_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) static int mma8452_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 			 const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	struct mma8452_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	data->chip_info = device_get_match_data(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	if (!data->chip_info && id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		data->chip_info = &mma_chip_info_table[id->driver_data];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		dev_err(&client->dev, "unknown device model\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	if (IS_ERR(data->vdd_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		return dev_err_probe(&client->dev, PTR_ERR(data->vdd_reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 				     "failed to get VDD regulator!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	data->vddio_reg = devm_regulator_get(&client->dev, "vddio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	if (IS_ERR(data->vddio_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 		return dev_err_probe(&client->dev, PTR_ERR(data->vddio_reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 				     "failed to get VDDIO regulator!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	ret = regulator_enable(data->vdd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		dev_err(&client->dev, "failed to enable VDD regulator!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	ret = regulator_enable(data->vddio_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		dev_err(&client->dev, "failed to enable VDDIO regulator!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		goto disable_regulator_vdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		goto disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	case MMA8451_DEVICE_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	case MMA8452_DEVICE_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	case MMA8453_DEVICE_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	case MMA8652_DEVICE_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	case MMA8653_DEVICE_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	case FXLS8471_DEVICE_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 		if (ret == data->chip_info->chip_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		goto disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	dev_info(&client->dev, "registering %s accelerometer; ID 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		 data->chip_info->name, data->chip_info->chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	indio_dev->info = &mma8452_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	indio_dev->name = data->chip_info->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	indio_dev->channels = data->chip_info->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	indio_dev->num_channels = data->chip_info->num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	indio_dev->available_scan_masks = mma8452_scan_masks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	ret = mma8452_reset(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 		goto disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	data->data_cfg = MMA8452_DATA_CFG_FS_2G;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 					data->data_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 		goto disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	 * By default set transient threshold to max to avoid events if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	 * enabling without configuring threshold.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	ret = i2c_smbus_write_byte_data(client, MMA8452_TRANSIENT_THS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 					MMA8452_TRANSIENT_THS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 		goto disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	if (client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 		int irq2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		irq2 = of_irq_get_byname(client->dev.of_node, "INT2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		if (irq2 == client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 			dev_dbg(&client->dev, "using interrupt line INT2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 			ret = i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 						MMA8452_CTRL_REG5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 						data->chip_info->all_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 				goto disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 			dev_dbg(&client->dev, "using interrupt line INT1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 		ret = i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 					MMA8452_CTRL_REG4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 					data->chip_info->enabled_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 			goto disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		ret = mma8452_trigger_setup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 			goto disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	data->ctrl_reg1 = MMA8452_CTRL_ACTIVE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 			  (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	data->sleep_val = mma8452_calculate_sleep(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 					data->ctrl_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 		goto trigger_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 					 mma8452_trigger_handler, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 		goto trigger_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	if (client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 		ret = devm_request_threaded_irq(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 						client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 						NULL, mma8452_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 						client->name, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 			goto buffer_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	ret = pm_runtime_set_active(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 		goto buffer_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	pm_runtime_set_autosuspend_delay(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 					 MMA8452_AUTO_SUSPEND_DELAY_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	pm_runtime_use_autosuspend(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 		goto buffer_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	ret = mma8452_set_freefall_mode(data, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 		goto unregister_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) unregister_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) buffer_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) trigger_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	mma8452_trigger_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) disable_regulators:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	regulator_disable(data->vddio_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) disable_regulator_vdd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	regulator_disable(data->vdd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) static int mma8452_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	pm_runtime_set_suspended(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	pm_runtime_put_noidle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	mma8452_trigger_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	mma8452_standby(iio_priv(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	regulator_disable(data->vddio_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	regulator_disable(data->vdd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) static int mma8452_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	ret = mma8452_standby(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		dev_err(&data->client->dev, "powering off device failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	ret = regulator_disable(data->vddio_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		dev_err(dev, "failed to disable VDDIO regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	ret = regulator_disable(data->vdd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 		dev_err(dev, "failed to disable VDD regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) static int mma8452_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	struct mma8452_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	int ret, sleep_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	ret = regulator_enable(data->vdd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 		dev_err(dev, "failed to enable VDD regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	ret = regulator_enable(data->vddio_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 		dev_err(dev, "failed to enable VDDIO regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		regulator_disable(data->vdd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	ret = mma8452_active(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 		goto runtime_resume_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	ret = mma8452_get_odr_index(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	sleep_val = 1000 / mma8452_samp_freq[ret][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	if (sleep_val < 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 		usleep_range(sleep_val * 1000, 20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 		msleep_interruptible(sleep_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) runtime_resume_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	regulator_disable(data->vddio_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	regulator_disable(data->vdd_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) static const struct dev_pm_ops mma8452_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	SET_RUNTIME_PM_OPS(mma8452_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 			   mma8452_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) static const struct i2c_device_id mma8452_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	{ "mma8451", mma8451 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	{ "mma8452", mma8452 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	{ "mma8453", mma8453 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	{ "mma8652", mma8652 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	{ "mma8653", mma8653 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	{ "fxls8471", fxls8471 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) MODULE_DEVICE_TABLE(i2c, mma8452_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) static struct i2c_driver mma8452_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 		.name	= "mma8452",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 		.of_match_table = mma8452_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 		.pm	= &mma8452_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	.probe = mma8452_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	.remove = mma8452_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	.id_table = mma8452_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) module_i2c_driver(mma8452_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) MODULE_DESCRIPTION("Freescale / NXP MMA8452 accelerometer driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) MODULE_LICENSE("GPL");