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