^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Freescale MMA9551L Intelligent Motion-Sensing Platform driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2014, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/iio/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "mma9551_core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define MMA9551_DRV_NAME "mma9551"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define MMA9551_IRQ_NAME "mma9551_event"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define MMA9551_GPIO_COUNT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* Tilt application (inclination in IIO terms). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define MMA9551_TILT_XZ_ANG_REG 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define MMA9551_TILT_YZ_ANG_REG 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define MMA9551_TILT_XY_ANG_REG 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MMA9551_TILT_ANGFLG BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define MMA9551_TILT_QUAD_REG 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define MMA9551_TILT_XY_QUAD_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MMA9551_TILT_YZ_QUAD_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MMA9551_TILT_XZ_QUAD_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MMA9551_TILT_CFG_REG 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MMA9551_TILT_ANG_THRESH_MASK GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define MMA9551_DEFAULT_SAMPLE_RATE 122 /* Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Tilt events are mapped to the first three GPIO pins. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) enum mma9551_tilt_axis {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) mma9551_x = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) mma9551_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) mma9551_z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct mma9551_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int event_enabled[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int irqs[MMA9551_GPIO_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int mma9551_read_incli_chan(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u8 quad_shift, angle, quadrant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u16 reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) switch (chan->channel2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) case IIO_MOD_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) reg_addr = MMA9551_TILT_YZ_ANG_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) quad_shift = MMA9551_TILT_YZ_QUAD_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case IIO_MOD_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) reg_addr = MMA9551_TILT_XZ_ANG_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) quad_shift = MMA9551_TILT_XZ_QUAD_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case IIO_MOD_Z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) reg_addr = MMA9551_TILT_XY_ANG_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) quad_shift = MMA9551_TILT_XY_QUAD_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ret = mma9551_set_power_state(client, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) reg_addr, &angle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) goto out_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) MMA9551_TILT_QUAD_REG, &quadrant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) goto out_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) angle &= ~MMA9551_TILT_ANGFLG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) quadrant = (quadrant >> quad_shift) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (quadrant == 1 || quadrant == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *val = 90 * (quadrant + 1) - angle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *val = angle + 90 * quadrant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) out_poweroff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mma9551_set_power_state(client, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int mma9551_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case IIO_INCLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ret = mma9551_read_incli_chan(data->client, chan, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) case IIO_ACCEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ret = mma9551_read_accel_chan(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) chan, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case IIO_ACCEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return mma9551_read_accel_scale(val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return -EINVAL;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int mma9551_read_event_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) enum iio_event_direction dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case IIO_INCLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* IIO counts axes from 1, because IIO_NO_MOD is 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return data->event_enabled[chan->channel2 - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int mma9551_config_incli_event(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) enum iio_modifier axis,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) enum mma9551_tilt_axis mma_axis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* IIO counts axes from 1, because IIO_NO_MOD is 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mma_axis = axis - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (data->event_enabled[mma_axis] == state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (state == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ret = mma9551_gpio_config(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) (enum mma9551_gpio_pin)mma_axis,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) MMA9551_APPID_NONE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ret = mma9551_set_power_state(data->client, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int bitnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Bit 7 of each angle register holds the angle flag. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) switch (axis) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case IIO_MOD_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bitnum = 7 + 8 * MMA9551_TILT_YZ_ANG_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case IIO_MOD_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) bitnum = 7 + 8 * MMA9551_TILT_XZ_ANG_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case IIO_MOD_Z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) bitnum = 7 + 8 * MMA9551_TILT_XY_ANG_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ret = mma9551_set_power_state(data->client, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ret = mma9551_gpio_config(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) (enum mma9551_gpio_pin)mma_axis,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) MMA9551_APPID_TILT, bitnum, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) mma9551_set_power_state(data->client, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^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) data->event_enabled[mma_axis] = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int mma9551_write_event_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case IIO_INCLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ret = mma9551_config_incli_event(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) chan->channel2, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return -EINVAL;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static int mma9551_write_event_value(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) enum iio_event_info info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case IIO_INCLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (val2 != 0 || val < 1 || val > 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ret = mma9551_update_config_bits(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) MMA9551_APPID_TILT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) MMA9551_TILT_CFG_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) MMA9551_TILT_ANG_THRESH_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int mma9551_read_event_value(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) enum iio_event_info info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case IIO_INCLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ret = mma9551_read_config_byte(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) MMA9551_APPID_TILT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) MMA9551_TILT_CFG_REG, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) *val = tmp & MMA9551_TILT_ANG_THRESH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *val2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -EINVAL;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static const struct iio_event_spec mma9551_incli_event = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .type = IIO_EV_TYPE_ROC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .dir = IIO_EV_DIR_RISING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .mask_separate = BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
^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) #define MMA9551_INCLI_CHANNEL(axis) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .type = IIO_INCLI, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .channel2 = axis, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .event_spec = &mma9551_incli_event, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .num_event_specs = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static const struct iio_chan_spec mma9551_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) MMA9551_ACCEL_CHANNEL(IIO_MOD_X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) MMA9551_ACCEL_CHANNEL(IIO_MOD_Y),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) MMA9551_ACCEL_CHANNEL(IIO_MOD_Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) MMA9551_INCLI_CHANNEL(IIO_MOD_X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) MMA9551_INCLI_CHANNEL(IIO_MOD_Y),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) MMA9551_INCLI_CHANNEL(IIO_MOD_Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static const struct iio_info mma9551_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .read_raw = mma9551_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .read_event_config = mma9551_read_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .write_event_config = mma9551_write_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .read_event_value = mma9551_read_event_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .write_event_value = mma9551_write_event_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static irqreturn_t mma9551_event_handler(int irq, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct iio_dev *indio_dev = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int i, ret, mma_axis = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (irq == data->irqs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) mma_axis = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) break;
^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) if (mma_axis == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* IRQ was triggered on 4th line, which we don't use. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) dev_warn(&data->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) "irq triggered on unused line %d\n", data->irqs[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) switch (mma_axis) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) case mma9551_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) reg = MMA9551_TILT_YZ_ANG_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case mma9551_y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) reg = MMA9551_TILT_XZ_ANG_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case mma9551_z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) reg = MMA9551_TILT_XY_ANG_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * Read the angle even though we don't use it, otherwise we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * won't get any further interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = mma9551_read_status_byte(data->client, MMA9551_APPID_TILT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) dev_err(&data->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) "error %d reading tilt register in IRQ\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) goto out;
^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) iio_push_event(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) IIO_MOD_EVENT_CODE(IIO_INCLI, 0, (mma_axis + 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return IRQ_HANDLED;
^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 int mma9551_init(struct mma9551_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = mma9551_read_version(data->client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return mma9551_set_device_state(data->client, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int mma9551_gpio_probe(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct gpio_desc *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct device *dev = &data->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) for (i = 0; i < MMA9551_GPIO_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) gpio = devm_gpiod_get_index(dev, NULL, i, GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (IS_ERR(gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) dev_err(dev, "acpi gpio get index failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return PTR_ERR(gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ret = gpiod_to_irq(gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) data->irqs[i] = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ret = devm_request_threaded_irq(dev, data->irqs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) NULL, mma9551_event_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) IRQF_TRIGGER_RISING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) MMA9551_IRQ_NAME, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) dev_err(dev, "request irq %d failed\n", data->irqs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) dev_dbg(dev, "gpio resource, no:%d irq:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) desc_to_gpio(gpio), data->irqs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static const char *mma9551_match_acpi_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) const struct acpi_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) id = acpi_match_device(dev->driver->acpi_match_table, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return dev_name(dev);
^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 mma9551_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct mma9551_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) const char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) name = id->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) else if (ACPI_HANDLE(&client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) name = mma9551_match_acpi_device(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ret = mma9551_init(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) mutex_init(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) indio_dev->channels = mma9551_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) indio_dev->num_channels = ARRAY_SIZE(mma9551_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) indio_dev->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) indio_dev->info = &mma9551_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret = mma9551_gpio_probe(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) goto out_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = pm_runtime_set_active(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) goto out_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) pm_runtime_set_autosuspend_delay(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) MMA9551_AUTO_SUSPEND_DELAY_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) pm_runtime_use_autosuspend(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) dev_err(&client->dev, "unable to register iio device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) goto err_pm_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) err_pm_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) pm_runtime_dont_use_autosuspend(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) out_poweroff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) mma9551_set_device_state(client, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int mma9551_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct iio_dev *indio_dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) pm_runtime_set_suspended(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) pm_runtime_put_noidle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) mma9551_set_device_state(data->client, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int mma9551_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ret = mma9551_set_device_state(data->client, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dev_err(&data->client->dev, "powering off device failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static int mma9551_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ret = mma9551_set_device_state(data->client, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) mma9551_sleep(MMA9551_DEFAULT_SAMPLE_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static int mma9551_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ret = mma9551_set_device_state(data->client, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static int mma9551_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct mma9551_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ret = mma9551_set_device_state(data->client, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static const struct dev_pm_ops mma9551_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) SET_SYSTEM_SLEEP_PM_OPS(mma9551_suspend, mma9551_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) SET_RUNTIME_PM_OPS(mma9551_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) mma9551_runtime_resume, NULL)
^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 const struct acpi_device_id mma9551_acpi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {"MMA9551", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static const struct i2c_device_id mma9551_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {"mma9551", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) MODULE_DEVICE_TABLE(i2c, mma9551_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static struct i2c_driver mma9551_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .name = MMA9551_DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .acpi_match_table = ACPI_PTR(mma9551_acpi_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) .pm = &mma9551_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .probe = mma9551_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .remove = mma9551_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .id_table = mma9551_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) module_i2c_driver(mma9551_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) MODULE_DESCRIPTION("MMA9551L motion-sensing platform driver");