// SPDX-License-Identifier: GPL-2.0-only
/*
* BMG160 Gyro Sensor driver
* Copyright (c) 2014, Intel Corporation.
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/events.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/regmap.h>
#include "bmg160.h"
#define BMG160_IRQ_NAME "bmg160_event"
#define BMG160_REG_CHIP_ID 0x00
#define BMG160_CHIP_ID_VAL 0x0F
#define BMG160_REG_PMU_LPW 0x11
#define BMG160_MODE_NORMAL 0x00
#define BMG160_MODE_DEEP_SUSPEND 0x20
#define BMG160_MODE_SUSPEND 0x80
#define BMG160_REG_RANGE 0x0F
#define BMG160_RANGE_2000DPS 0
#define BMG160_RANGE_1000DPS 1
#define BMG160_RANGE_500DPS 2
#define BMG160_RANGE_250DPS 3
#define BMG160_RANGE_125DPS 4
#define BMG160_REG_PMU_BW 0x10
#define BMG160_NO_FILTER 0
#define BMG160_DEF_BW 100
#define BMG160_REG_PMU_BW_RES BIT(7)
#define BMG160_GYRO_REG_RESET 0x14
#define BMG160_GYRO_RESET_VAL 0xb6
#define BMG160_REG_INT_MAP_0 0x17
#define BMG160_INT_MAP_0_BIT_ANY BIT(1)
#define BMG160_REG_INT_MAP_1 0x18
#define BMG160_INT_MAP_1_BIT_NEW_DATA BIT(0)
#define BMG160_REG_INT_RST_LATCH 0x21
#define BMG160_INT_MODE_LATCH_RESET 0x80
#define BMG160_INT_MODE_LATCH_INT 0x0F
#define BMG160_INT_MODE_NON_LATCH_INT 0x00
#define BMG160_REG_INT_EN_0 0x15
#define BMG160_DATA_ENABLE_INT BIT(7)
#define BMG160_REG_INT_EN_1 0x16
#define BMG160_INT1_BIT_OD BIT(1)
#define BMG160_REG_XOUT_L 0x02
#define BMG160_AXIS_TO_REG(axis) (BMG160_REG_XOUT_L + (axis * 2))
#define BMG160_REG_SLOPE_THRES 0x1B
#define BMG160_SLOPE_THRES_MASK 0x0F
#define BMG160_REG_MOTION_INTR 0x1C
#define BMG160_INT_MOTION_X BIT(0)
#define BMG160_INT_MOTION_Y BIT(1)
#define BMG160_INT_MOTION_Z BIT(2)
#define BMG160_ANY_DUR_MASK 0x30
#define BMG160_ANY_DUR_SHIFT 4
#define BMG160_REG_INT_STATUS_2 0x0B
#define BMG160_ANY_MOTION_MASK 0x07
#define BMG160_ANY_MOTION_BIT_X BIT(0)
#define BMG160_ANY_MOTION_BIT_Y BIT(1)
#define BMG160_ANY_MOTION_BIT_Z BIT(2)
#define BMG160_REG_TEMP 0x08
#define BMG160_TEMP_CENTER_VAL 23
#define BMG160_MAX_STARTUP_TIME_MS 80
#define BMG160_AUTO_SUSPEND_DELAY_MS 2000
struct bmg160_data {
struct regmap *regmap;
struct iio_trigger *dready_trig;
struct iio_trigger *motion_trig;
struct iio_mount_matrix orientation;
struct mutex mutex;
s16 buffer[8];
u32 dps_range;
int ev_enable_state;
int slope_thres;
bool dready_trigger_on;
bool motion_trigger_on;
int irq;
};
enum bmg160_axis {
AXIS_X,
AXIS_Y,
AXIS_Z,
AXIS_MAX,
};
static const struct {
int odr;
int filter;
int bw_bits;
} bmg160_samp_freq_table[] = { {100, 32, 0x07},
{200, 64, 0x06},
{100, 12, 0x05},
{200, 23, 0x04},
{400, 47, 0x03},
{1000, 116, 0x02},
{2000, 230, 0x01} };
static const struct {
int scale;
int dps_range;
} bmg160_scale_table[] = { { 1065, BMG160_RANGE_2000DPS},
{ 532, BMG160_RANGE_1000DPS},
{ 266, BMG160_RANGE_500DPS},
{ 133, BMG160_RANGE_250DPS},
{ 66, BMG160_RANGE_125DPS} };
static int bmg160_set_mode(struct bmg160_data *data,