linux/drivers/iio/accel/msa311.c

// SPDX-License-Identifier: GPL-2.0
/*
 * MEMSensing digital 3-Axis accelerometer
 *
 * MSA311 is a tri-axial, low-g accelerometer with I2C digital output for
 * sensitivity consumer applications. It has dynamic user-selectable full
 * scales range of +-2g/+-4g/+-8g/+-16g and allows acceleration measurements
 * with output data rates from 1Hz to 1000Hz.
 *
 * MSA311 is available in an ultra small (2mm x 2mm, height 0.95mm) LGA package
 * and is guaranteed to operate over -40C to +85C.
 *
 * This driver supports following MSA311 features:
 *     - IIO interface
 *     - Different power modes: NORMAL, SUSPEND
 *     - ODR (Output Data Rate) selection
 *     - Scale selection
 *     - IIO triggered buffer
 *     - NEW_DATA interrupt + trigger
 *
 * Below features to be done:
 *     - Motion Events: ACTIVE, TAP, ORIENT, FREEFALL
 *     - Low Power mode
 *
 * Copyright (c) 2022, SberDevices. All Rights Reserved.
 *
 * Author: Dmitry Rokosov <[email protected]>
 */

#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/string_choices.h>
#include <linux/units.h>

#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>

#define MSA311_SOFT_RESET_REG
#define MSA311_PARTID_REG
#define MSA311_ACC_X_REG
#define MSA311_ACC_Y_REG
#define MSA311_ACC_Z_REG
#define MSA311_MOTION_INT_REG
#define MSA311_DATA_INT_REG
#define MSA311_TAP_ACTIVE_STS_REG
#define MSA311_ORIENT_STS_REG
#define MSA311_RANGE_REG
#define MSA311_ODR_REG
#define MSA311_PWR_MODE_REG
#define MSA311_SWAP_POLARITY_REG
#define MSA311_INT_SET_0_REG
#define MSA311_INT_SET_1_REG
#define MSA311_INT_MAP_0_REG
#define MSA311_INT_MAP_1_REG
#define MSA311_INT_CONFIG_REG
#define MSA311_INT_LATCH_REG
#define MSA311_FREEFALL_DUR_REG
#define MSA311_FREEFALL_TH_REG
#define MSA311_FREEFALL_HY_REG
#define MSA311_ACTIVE_DUR_REG
#define MSA311_ACTIVE_TH_REG
#define MSA311_TAP_DUR_REG
#define MSA311_TAP_TH_REG
#define MSA311_ORIENT_HY_REG
#define MSA311_Z_BLOCK_REG
#define MSA311_OFFSET_X_REG
#define MSA311_OFFSET_Y_REG
#define MSA311_OFFSET_Z_REG

enum msa311_fields {};

static const struct reg_field msa311_reg_fields[] =;

#define MSA311_WHO_AM_I

/*
 * Possible Full Scale ranges
 *
 * Axis data is 12-bit signed value, so
 *
 * fs0 = (2 + 2) * 9.81 / (2^11) = 0.009580
 * fs1 = (4 + 4) * 9.81 / (2^11) = 0.019160
 * fs2 = (8 + 8) * 9.81 / (2^11) = 0.038320
 * fs3 = (16 + 16) * 9.81 / (2^11) = 0.076641
 */
enum {};

struct iio_decimal_fract {};

static const struct iio_decimal_fract msa311_fs_table[] =;

/* Possible Output Data Rate values */
enum {};

static const struct iio_decimal_fract msa311_odr_table[] =;

/* All supported power modes */
#define MSA311_PWR_MODE_NORMAL
#define MSA311_PWR_MODE_LOW
#define MSA311_PWR_MODE_UNKNOWN
#define MSA311_PWR_MODE_SUSPEND
static const char * const msa311_pwr_modes[] =;

/* Autosuspend delay */
#define MSA311_PWR_SLEEP_DELAY_MS

/* Possible INT1 types and levels */
enum {};

enum {};

/* Latch INT modes */
#define MSA311_LATCH_INT_NOT_LATCHED
#define MSA311_LATCH_INT_250MS
#define MSA311_LATCH_INT_500MS
#define MSA311_LATCH_INT_1S
#define MSA311_LATCH_INT_2S
#define MSA311_LATCH_INT_4S
#define MSA311_LATCH_INT_8S
#define MSA311_LATCH_INT_1MS
#define MSA311_LATCH_INT_2MS
#define MSA311_LATCH_INT_25MS
#define MSA311_LATCH_INT_50MS
#define MSA311_LATCH_INT_100MS
#define MSA311_LATCH_INT_LATCHED

static const struct regmap_range msa311_readonly_registers[] =;

static const struct regmap_access_table msa311_writeable_table =;

static const struct regmap_range msa311_writeonly_registers[] =;

static const struct regmap_access_table msa311_readable_table =;

static const struct regmap_range msa311_volatile_registers[] =;

static const struct regmap_access_table msa311_volatile_table =;

static const struct regmap_config msa311_regmap_config =;

#define MSA311_GENMASK(field)

/**
 * struct msa311_priv - MSA311 internal private state
 * @regs: Underlying I2C bus adapter used to abstract slave
 *        register accesses
 * @fields: Abstract objects for each registers fields access
 * @dev: Device handler associated with appropriate bus client
 * @lock: Protects msa311 device state between setup and data access routines
 *        (power transitions, samp_freq/scale tune, retrieving axes data, etc)
 * @chip_name: Chip name in the format "msa311-%02x" % partid
 * @new_data_trig: Optional NEW_DATA interrupt driven trigger used
 *                 to notify external consumers a new sample is ready
 */
struct msa311_priv {};

enum msa311_si {};

#define MSA311_ACCEL_CHANNEL(axis)

static const struct iio_chan_spec msa311_channels[] =;

/**
 * msa311_get_odr() - Read Output Data Rate (ODR) value from MSA311 accel
 * @msa311: MSA311 internal private state
 * @odr: output ODR value
 *
 * This function should be called under msa311->lock.
 *
 * Return: 0 on success, -ERRNO in other failures
 */
static int msa311_get_odr(struct msa311_priv *msa311, unsigned int *odr)
{}

/**
 * msa311_set_odr() - Setup Output Data Rate (ODR) value for MSA311 accel
 * @msa311: MSA311 internal private state
 * @odr: requested ODR value
 *
 * This function should be called under msa311->lock. Possible ODR values:
 *     - 1Hz (not available in normal mode)
 *     - 1.95Hz (not available in normal mode)
 *     - 3.9Hz
 *     - 7.81Hz
 *     - 15.63Hz
 *     - 31.25Hz
 *     - 62.5Hz
 *     - 125Hz
 *     - 250Hz
 *     - 500Hz
 *     - 1000Hz
 *
 * Return: 0 on success, -EINVAL for bad ODR value in the certain power mode,
 *         -ERRNO in other failures
 */
static int msa311_set_odr(struct msa311_priv *msa311, unsigned int odr)
{}

/**
 * msa311_wait_for_next_data() - Wait next accel data available after resume
 * @msa311: MSA311 internal private state
 *
 * Return: 0 on success, -EINTR if msleep() was interrupted,
 *         -ERRNO in other failures
 */
static int msa311_wait_for_next_data(struct msa311_priv *msa311)
{}

/**
 * msa311_set_pwr_mode() - Install certain MSA311 power mode
 * @msa311: MSA311 internal private state
 * @mode: Power mode can be equal to NORMAL or SUSPEND
 *
 * This function should be called under msa311->lock.
 *
 * Return: 0 on success, -ERRNO on failure
 */
static int msa311_set_pwr_mode(struct msa311_priv *msa311, unsigned int mode)
{}

/**
 * msa311_get_axis() - Read MSA311 accel data for certain IIO channel axis spec
 * @msa311: MSA311 internal private state
 * @chan: IIO channel specification
 * @axis: Output accel axis data for requested IIO channel spec
 *
 * This function should be called under msa311->lock.
 *
 * Return: 0 on success, -EINVAL for unknown IIO channel specification,
 *         -ERRNO in other failures
 */
static int msa311_get_axis(struct msa311_priv *msa311,
			   const struct iio_chan_spec * const chan,
			   __le16 *axis)
{}

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

static int msa311_read_scale(struct iio_dev *indio_dev, int *val, int *val2)
{}

static int msa311_read_samp_freq(struct iio_dev *indio_dev,
				 int *val, int *val2)
{}

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

static int msa311_read_avail(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     const int **vals, int *type,
			     int *length, long mask)
{}

static int msa311_write_scale(struct iio_dev *indio_dev, int val, int val2)
{}

static int msa311_write_samp_freq(struct iio_dev *indio_dev, int val, int val2)
{}

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

static int msa311_debugfs_reg_access(struct iio_dev *indio_dev,
				     unsigned int reg, unsigned int writeval,
				     unsigned int *readval)
{}

static int msa311_buffer_preenable(struct iio_dev *indio_dev)
{}

static int msa311_buffer_postdisable(struct iio_dev *indio_dev)
{}

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

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

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

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

static const struct iio_info msa311_info =;

static const struct iio_buffer_setup_ops msa311_buffer_setup_ops =;

static const struct iio_trigger_ops msa311_new_data_trig_ops =;

static int msa311_check_partid(struct msa311_priv *msa311)
{}

static int msa311_soft_reset(struct msa311_priv *msa311)
{}

static int msa311_chip_init(struct msa311_priv *msa311)
{}

static int msa311_setup_interrupts(struct msa311_priv *msa311)
{}

static int msa311_regmap_init(struct msa311_priv *msa311)
{}

static void msa311_powerdown(void *msa311)
{}

static int msa311_probe(struct i2c_client *i2c)
{}

static int msa311_runtime_suspend(struct device *dev)
{}

static int msa311_runtime_resume(struct device *dev)
{}

static DEFINE_RUNTIME_DEV_PM_OPS(msa311_pm_ops, msa311_runtime_suspend,
				 msa311_runtime_resume, NULL);

static const struct i2c_device_id msa311_i2c_id[] =;
MODULE_DEVICE_TABLE(i2c, msa311_i2c_id);

static const struct of_device_id msa311_of_match[] =;
MODULE_DEVICE_TABLE(of, msa311_of_match);

static struct i2c_driver msa311_driver =;
module_i2c_driver();

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