linux/drivers/iio/accel/bmc150-accel-core.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * 3-axis accelerometer driver supporting many Bosch-Sensortec chips
 * Copyright (c) 2014, Intel Corporation.
 */

#include <linux/module.h>
#include <linux/i2c.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/property.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/events.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>

#include "bmc150-accel.h"

#define BMC150_ACCEL_DRV_NAME
#define BMC150_ACCEL_IRQ_NAME

#define BMC150_ACCEL_REG_CHIP_ID

#define BMC150_ACCEL_REG_INT_STATUS_2
#define BMC150_ACCEL_ANY_MOTION_MASK
#define BMC150_ACCEL_ANY_MOTION_BIT_X
#define BMC150_ACCEL_ANY_MOTION_BIT_Y
#define BMC150_ACCEL_ANY_MOTION_BIT_Z
#define BMC150_ACCEL_ANY_MOTION_BIT_SIGN

#define BMC150_ACCEL_REG_PMU_LPW
#define BMC150_ACCEL_PMU_MODE_MASK
#define BMC150_ACCEL_PMU_MODE_SHIFT
#define BMC150_ACCEL_PMU_BIT_SLEEP_DUR_MASK
#define BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT

#define BMC150_ACCEL_REG_PMU_RANGE

#define BMC150_ACCEL_DEF_RANGE_2G
#define BMC150_ACCEL_DEF_RANGE_4G
#define BMC150_ACCEL_DEF_RANGE_8G
#define BMC150_ACCEL_DEF_RANGE_16G

/* Default BW: 125Hz */
#define BMC150_ACCEL_REG_PMU_BW
#define BMC150_ACCEL_DEF_BW

#define BMC150_ACCEL_REG_RESET
#define BMC150_ACCEL_RESET_VAL

#define BMC150_ACCEL_REG_INT_MAP_0
#define BMC150_ACCEL_INT_MAP_0_BIT_INT1_SLOPE

#define BMC150_ACCEL_REG_INT_MAP_1
#define BMC150_ACCEL_INT_MAP_1_BIT_INT1_DATA
#define BMC150_ACCEL_INT_MAP_1_BIT_INT1_FWM
#define BMC150_ACCEL_INT_MAP_1_BIT_INT1_FFULL
#define BMC150_ACCEL_INT_MAP_1_BIT_INT2_FFULL
#define BMC150_ACCEL_INT_MAP_1_BIT_INT2_FWM
#define BMC150_ACCEL_INT_MAP_1_BIT_INT2_DATA

#define BMC150_ACCEL_REG_INT_MAP_2
#define BMC150_ACCEL_INT_MAP_2_BIT_INT2_SLOPE

#define BMC150_ACCEL_REG_INT_RST_LATCH
#define BMC150_ACCEL_INT_MODE_LATCH_RESET
#define BMC150_ACCEL_INT_MODE_LATCH_INT
#define BMC150_ACCEL_INT_MODE_NON_LATCH_INT

#define BMC150_ACCEL_REG_INT_EN_0
#define BMC150_ACCEL_INT_EN_BIT_SLP_X
#define BMC150_ACCEL_INT_EN_BIT_SLP_Y
#define BMC150_ACCEL_INT_EN_BIT_SLP_Z

#define BMC150_ACCEL_REG_INT_EN_1
#define BMC150_ACCEL_INT_EN_BIT_DATA_EN
#define BMC150_ACCEL_INT_EN_BIT_FFULL_EN
#define BMC150_ACCEL_INT_EN_BIT_FWM_EN

#define BMC150_ACCEL_REG_INT_OUT_CTRL
#define BMC150_ACCEL_INT_OUT_CTRL_INT1_LVL
#define BMC150_ACCEL_INT_OUT_CTRL_INT2_LVL

#define BMC150_ACCEL_REG_INT_5
#define BMC150_ACCEL_SLOPE_DUR_MASK

#define BMC150_ACCEL_REG_INT_6
#define BMC150_ACCEL_SLOPE_THRES_MASK

/* Slope duration in terms of number of samples */
#define BMC150_ACCEL_DEF_SLOPE_DURATION
/* in terms of multiples of g's/LSB, based on range */
#define BMC150_ACCEL_DEF_SLOPE_THRESHOLD

#define BMC150_ACCEL_REG_XOUT_L

#define BMC150_ACCEL_MAX_STARTUP_TIME_MS

/* Sleep Duration values */
#define BMC150_ACCEL_SLEEP_500_MICRO
#define BMC150_ACCEL_SLEEP_1_MS
#define BMC150_ACCEL_SLEEP_2_MS
#define BMC150_ACCEL_SLEEP_4_MS
#define BMC150_ACCEL_SLEEP_6_MS
#define BMC150_ACCEL_SLEEP_10_MS
#define BMC150_ACCEL_SLEEP_25_MS
#define BMC150_ACCEL_SLEEP_50_MS
#define BMC150_ACCEL_SLEEP_100_MS
#define BMC150_ACCEL_SLEEP_500_MS
#define BMC150_ACCEL_SLEEP_1_SEC

#define BMC150_ACCEL_REG_TEMP
#define BMC150_ACCEL_TEMP_CENTER_VAL

#define BMC150_ACCEL_AXIS_TO_REG(axis)
#define BMC150_AUTO_SUSPEND_DELAY_MS

#define BMC150_ACCEL_REG_FIFO_STATUS
#define BMC150_ACCEL_REG_FIFO_CONFIG0
#define BMC150_ACCEL_REG_FIFO_CONFIG1
#define BMC150_ACCEL_REG_FIFO_DATA
#define BMC150_ACCEL_FIFO_LENGTH

enum bmc150_accel_axis {};

enum bmc150_power_modes {};

struct bmc150_scale_info {};

struct bmc150_accel_chip_info {};

static const struct {} bmc150_accel_samp_freq_table[] =;

static __maybe_unused const struct {} bmc150_accel_sample_upd_time[] =;

static const struct {} bmc150_accel_sleep_value_table[] =;

const struct regmap_config bmc150_regmap_conf =;
EXPORT_SYMBOL_NS_GPL();

static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
				 enum bmc150_power_modes mode,
				 int dur_us)
{}

static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
			       int val2)
{}

static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
{}

static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
					 bool state)
{}

static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val,
			       int *val2)
{}

#ifdef CONFIG_PM
static int bmc150_accel_get_startup_times(struct bmc150_accel_data *data)
{}

static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
{}
#else
static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
{
	return 0;
}
#endif

#ifdef CONFIG_ACPI
/*
 * Support for getting accelerometer information from BOSC0200 ACPI nodes.
 *
 * There are 2 variants of the BOSC0200 ACPI node. Some 2-in-1s with 360 degree
 * hinges declare 2 I2C ACPI-resources for 2 accelerometers, 1 in the display
 * and 1 in the base of the 2-in-1. On these 2-in-1s the ROMS ACPI object
 * contains the mount-matrix for the sensor in the display and ROMK contains
 * the mount-matrix for the sensor in the base. On devices using a single
 * sensor there is a ROTM ACPI object which contains the mount-matrix.
 *
 * Here is an incomplete list of devices known to use 1 of these setups:
 *
 * Yoga devices with 2 accelerometers using ROMS + ROMK for the mount-matrices:
 * Lenovo Thinkpad Yoga 11e 3th gen
 * Lenovo Thinkpad Yoga 11e 4th gen
 *
 * Tablets using a single accelerometer using ROTM for the mount-matrix:
 * Chuwi Hi8 Pro (CWI513)
 * Chuwi Vi8 Plus (CWI519)
 * Chuwi Hi13
 * Irbis TW90
 * Jumper EZpad mini 3
 * Onda V80 plus
 * Predia Basic Tablet
 */
static bool bmc150_apply_bosc0200_acpi_orientation(struct device *dev,
						   struct iio_mount_matrix *orientation)
{}

static bool bmc150_apply_dual250e_acpi_orientation(struct device *dev,
						   struct iio_mount_matrix *orientation)
{}

static bool bmc150_apply_acpi_orientation(struct device *dev,
					  struct iio_mount_matrix *orientation)
{}
#else
static bool bmc150_apply_acpi_orientation(struct device *dev,
					  struct iio_mount_matrix *orientation)
{
	return false;
}
#endif

struct bmc150_accel_interrupt_info {};

static const struct bmc150_accel_interrupt_info
bmc150_accel_interrupts_int1[BMC150_ACCEL_INTERRUPTS] =;

static const struct bmc150_accel_interrupt_info
bmc150_accel_interrupts_int2[BMC150_ACCEL_INTERRUPTS] =;

static void bmc150_accel_interrupts_setup(struct iio_dev *indio_dev,
					  struct bmc150_accel_data *data, int irq)
{}

static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
				      bool state)
{}

static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
{}

static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
{}

static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
				 struct iio_chan_spec const *chan,
				 int *val)
{}

static int bmc150_accel_read_raw(struct iio_dev *indio_dev,
				 struct iio_chan_spec const *chan,
				 int *val, int *val2, long mask)
{}

static int bmc150_accel_write_raw(struct iio_dev *indio_dev,
				  struct iio_chan_spec const *chan,
				  int val, int val2, long mask)
{}

static int bmc150_accel_read_event(struct iio_dev *indio_dev,
				   const struct iio_chan_spec *chan,
				   enum iio_event_type type,
				   enum iio_event_direction dir,
				   enum iio_event_info info,
				   int *val, int *val2)
{}

static int bmc150_accel_write_event(struct iio_dev *indio_dev,
				    const struct iio_chan_spec *chan,
				    enum iio_event_type type,
				    enum iio_event_direction dir,
				    enum iio_event_info info,
				    int val, int val2)
{}

static int bmc150_accel_read_event_config(struct iio_dev *indio_dev,
					  const struct iio_chan_spec *chan,
					  enum iio_event_type type,
					  enum iio_event_direction dir)
{}

static int bmc150_accel_write_event_config(struct iio_dev *indio_dev,
					   const struct iio_chan_spec *chan,
					   enum iio_event_type type,
					   enum iio_event_direction dir,
					   int state)
{}

static int bmc150_accel_validate_trigger(struct iio_dev *indio_dev,
					 struct iio_trigger *trig)
{}

static ssize_t bmc150_accel_get_fifo_watermark(struct device *dev,
					       struct device_attribute *attr,
					       char *buf)
{}

static ssize_t bmc150_accel_get_fifo_state(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{}

static const struct iio_mount_matrix *
bmc150_accel_get_mount_matrix(const struct iio_dev *indio_dev,
				const struct iio_chan_spec *chan)
{}

static const struct iio_chan_spec_ext_info bmc150_accel_ext_info[] =;

IIO_STATIC_CONST_DEVICE_ATTR();
IIO_STATIC_CONST_DEVICE_ATTR();
static IIO_DEVICE_ATTR(hwfifo_enabled, S_IRUGO,
		       bmc150_accel_get_fifo_state, NULL, 0);
static IIO_DEVICE_ATTR(hwfifo_watermark, S_IRUGO,
		       bmc150_accel_get_fifo_watermark, NULL, 0);

static const struct iio_dev_attr *bmc150_accel_fifo_attributes[] =;

static int bmc150_accel_set_watermark(struct iio_dev *indio_dev, unsigned val)
{}

/*
 * We must read at least one full frame in one burst, otherwise the rest of the
 * frame data is discarded.
 */
static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
				      char *buffer, int samples)
{}

static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
				     unsigned samples, bool irq)
{}

static int bmc150_accel_fifo_flush(struct iio_dev *indio_dev, unsigned samples)
{}

static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
		"15.620000 31.260000 62.50000 125 250 500 1000 2000");

static struct attribute *bmc150_accel_attributes[] =;

static const struct attribute_group bmc150_accel_attrs_group =;

static const struct iio_event_spec bmc150_accel_event =;

#define BMC150_ACCEL_CHANNEL(_axis, bits)

#define BMC150_ACCEL_CHANNELS(bits)

static const struct iio_chan_spec bma222e_accel_channels[] =;
static const struct iio_chan_spec bma250e_accel_channels[] =;
static const struct iio_chan_spec bmc150_accel_channels[] =;
static const struct iio_chan_spec bma280_accel_channels[] =;

/*
 * The range for the Bosch sensors is typically +-2g/4g/8g/16g, distributed
 * over the amount of bits (see above). The scale table can be calculated using
 *     (range / 2^bits) * g = (range / 2^bits) * 9.80665 m/s^2
 * e.g. for +-2g and 12 bits: (4 / 2^12) * 9.80665 m/s^2 = 0.0095768... m/s^2
 * Multiply 10^6 and round to get the values listed below.
 */
static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] =;

static const struct iio_info bmc150_accel_info =;

static const struct iio_info bmc150_accel_info_fifo =;

static const unsigned long bmc150_accel_scan_masks[] =;

static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
{}

static void bmc150_accel_trig_reen(struct iio_trigger *trig)
{}

static int bmc150_accel_trigger_set_state(struct iio_trigger *trig,
					  bool state)
{}

static const struct iio_trigger_ops bmc150_accel_trigger_ops =;

static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
{}

static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
{}

static irqreturn_t bmc150_accel_irq_handler(int irq, void *private)
{}

static const struct {} bmc150_accel_triggers[BMC150_ACCEL_TRIGGERS] =;

static void bmc150_accel_unregister_triggers(struct bmc150_accel_data *data,
					     int from)
{}

static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
				       struct bmc150_accel_data *data)
{}

#define BMC150_ACCEL_FIFO_MODE_STREAM
#define BMC150_ACCEL_FIFO_MODE_FIFO
#define BMC150_ACCEL_FIFO_MODE_BYPASS

static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
{}

static int bmc150_accel_buffer_preenable(struct iio_dev *indio_dev)
{}

static int bmc150_accel_buffer_postenable(struct iio_dev *indio_dev)
{}

static int bmc150_accel_buffer_predisable(struct iio_dev *indio_dev)
{}

static int bmc150_accel_buffer_postdisable(struct iio_dev *indio_dev)
{}

static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops =;

static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
{}

int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
			    enum bmc150_type type, const char *name,
			    bool block_supported)
{}
EXPORT_SYMBOL_NS_GPL();

void bmc150_accel_core_remove(struct device *dev)
{}
EXPORT_SYMBOL_NS_GPL();

#ifdef CONFIG_PM_SLEEP
static int bmc150_accel_suspend(struct device *dev)
{}

static int bmc150_accel_resume(struct device *dev)
{}
#endif

#ifdef CONFIG_PM
static int bmc150_accel_runtime_suspend(struct device *dev)
{}

static int bmc150_accel_runtime_resume(struct device *dev)
{}
#endif

const struct dev_pm_ops bmc150_accel_pm_ops =;
EXPORT_SYMBOL_NS_GPL();

MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_DESCRIPTION();