| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * Memsic MXC400xXC Gsensor driver for screen orientation
- *
- */
- #ifndef __GSENSOR_H
- #define __GSENSOR_H
- #include <linux/types.h>
- #include <linux/iio/iio.h>
- #include <linux/i2c.h>
- #include <linux/iio/trigger.h>
- #include <linux/iio/triggered_buffer.h>
- /* Gsensor orientation values (hex per API spec) */
- enum gsensor_orientation_hex
- {
- GSENSOR_ORIENT_UNKNOWN_HEX = 0x00,
- GSENSOR_ORIENT_PORTRAIT_HEX = 0x14,
- GSENSOR_ORIENT_LANDSCAPE_HEX = 0x15,
- GSENSOR_ORIENT_PORTRAIT_FLIP_HEX = 0x16,
- GSENSOR_ORIENT_LANDSCAPE_FLIP_HEX = 0x17,
- };
- /* Gsensor orientation strings */
- #define GSENSOR_ORIENT_PORTRAIT_STR "portrait"
- #define GSENSOR_ORIENT_LANDSCAPE_STR "landscape"
- #define GSENSOR_ORIENT_PORTRAIT_FLIP_STR "portrait_flip"
- #define GSENSOR_ORIENT_LANDSCAPE_FLIP_STR "landscape_flip"
- /* Gsensor mode bits (per API spec) */
- #define GSENSOR_MODE_SOFT_RESET BIT(2) /* EC17: soft reset */
- #define GSENSOR_MODE_INITIALIZED BIT(1) /* EC16: 0=not init, 1=init */
- #define GSENSOR_MODE_INTERRUPT BIT(0) /* 0=poll, 1=interrupt */
- /* Memsic MXC400xXC Register Definitions */
- #define MXC400X_REG_WHO_AM_I 0x00
- #define MXC400X_WHO_AM_I_VALUE 0x20
- #define MXC400X_REG_XOUT_U 0x04
- #define MXC400X_REG_XOUT_L 0x05
- #define MXC400X_REG_YOUT_U 0x06
- #define MXC400X_REG_YOUT_L 0x07
- #define MXC400X_REG_ZOUT_U 0x08
- #define MXC400X_REG_ZOUT_L 0x09
- #define MXC400X_REG_CONTROL 0x0A
- #define MXC400X_CONTROL_MODE_MASK 0x03
- #define MXC400X_CONTROL_MODE_STANDBY 0x00
- #define MXC400X_CONTROL_MODE_ACTIVE 0x01
- #define MXC400X_CONTROL_MODE_RESET 0x02
- #define MXC400X_REG_INT_ENABLE 0x0B
- #define MXC400X_INT_ENABLE_DRDY BIT(0)
- #define MXC400X_REG_INT_STATUS 0x0C
- /* ST LIS2DH12 / SC7A20 register */
- #define ST_ACCEL_WHO_AM_I_ADDR 0x0F
- #define ST_ACCEL_WHO_AM_I_VALUE 0x33 /* LIS2DH12 / SC7A20 */
- #define ST_ACCEL_CTRL_REG1_ADDR 0x20
- #define ST_ACCEL_CTRL_REG4_ADDR 0x23
- #define ST_ACCEL_OUT_X_L_ADDR 0x28
- #define ST_ACCEL_OUT_X_H_ADDR 0x29
- #define ST_ACCEL_OUT_Y_L_ADDR 0x2A
- #define ST_ACCEL_OUT_Y_H_ADDR 0x2B
- #define ST_ACCEL_OUT_Z_L_ADDR 0x2C
- #define ST_ACCEL_OUT_Z_H_ADDR 0x2D
- #define ST_ACCEL_STATUS_REG_ADDR 0x27
- #define ST_ACCEL_STATUS_DRDY 0x07
- /* Driver Constants */
- #define GSENSOR_NUMBER_DATA_CHANNELS 3
- #define GSENSOR_DEBOUNCE_MS 100
- #define MXC400X_SCALE_FACTOR 1000 /* mg per count at 2g range */
- /* Default I2C address */
- #define MXC400X_DEFAULT_I2C_ADDR 0x15
- /* Sensor Settings Structure */
- struct gsensor_fs_avl
- {
- unsigned int num; /* Full scale value in g */
- unsigned int value; /* Register value */
- unsigned int gain; /* Gain in micro g per LSB */
- };
- struct gsensor_odr_avl
- {
- unsigned int hz; /* Output data rate in Hz */
- unsigned int value; /* Register value */
- };
- struct gsensor_settings
- {
- u8 wai; /* WHO_AM_I expected value */
- u8 wai_addr; /* WHO_AM_I register address */
- const char **sensors_supported; /* Supported device names */
- /* Channel configuration */
- const struct iio_chan_spec *ch;
- int num_channels;
- /* ODR configuration */
- struct
- {
- u8 addr;
- u8 mask;
- const struct gsensor_odr_avl *odr_avl;
- int num_odr;
- } odr;
- /* Power mode configuration */
- struct
- {
- u8 addr;
- u8 mask;
- u8 value_on;
- u8 value_off;
- } pw;
- /* Full scale configuration */
- struct
- {
- u8 addr;
- u8 mask;
- const struct gsensor_fs_avl *fs_avl;
- int num_fs;
- } fs;
- /* Block Data Update */
- struct
- {
- u8 addr;
- u8 mask;
- } bdu;
- /* Data ready interrupt */
- struct
- {
- struct
- {
- u8 addr;
- u8 mask;
- } int1;
- u8 addr_ihl;
- u8 mask_ihl;
- struct
- {
- u8 addr;
- u8 mask;
- } stat_drdy;
- } drdy_irq;
- /* SPI/I2C interface mode */
- struct
- {
- u8 addr;
- u8 value;
- } sim;
- bool multi_read_bit;
- unsigned int bootime;
- };
- /* Driver Data Structure */
- struct gsensor_data
- {
- struct i2c_client *client;
- struct device *dev;
- struct mutex lock; /* Protects data access */
- /* Sensor settings */
- const struct gsensor_settings *sensor_settings;
- /* Current configuration */
- const struct gsensor_fs_avl *current_fullscale;
- unsigned int odr;
- /* Orientation data */
- enum gsensor_orientation_hex orientation_hex;
- char orientation_str[32];
- struct delayed_work debounce_work;
- enum gsensor_orientation_hex pending_orientation;
- unsigned long last_change_jiffies;
- /* State */
- bool enabled;
- bool initialized;
- bool interrupt_mode;
- bool irq_enabled;
- /* IIO related */
- struct iio_dev *indio_dev;
- /* Verifone sysfs */
- struct kobject *verifone_kobj;
- /* Regulators (optional) */
- struct regulator *vdd;
- struct regulator *vdd_io;
- };
- /* Core functions */
- int gsensor_common_probe(struct iio_dev *indio_dev);
- void gsensor_common_remove(struct iio_dev *indio_dev);
- const struct gsensor_settings *gsensor_get_settings(const char *name);
- /* Buffer functions */
- int gsensor_allocate_ring(struct iio_dev *indio_dev);
- int gsensor_trig_set_state(struct iio_trigger *trig, bool state);
- int gsensor_allocate_trigger(struct iio_dev *indio_dev);
- extern const struct iio_trigger_ops gsensor_trigger_ops;
- /* Power management */
- int gsensor_power_enable(struct iio_dev *indio_dev);
- int gsensor_power_disable(struct iio_dev *indio_dev);
- /* I2C functions */
- int gsensor_i2c_read(struct device *dev, u8 reg, u8 *data, size_t len);
- int gsensor_i2c_write(struct device *dev, u8 reg, u8 value);
- int gsensor_init_main(void);
- void gsensor_exit_main(void);
- int gsensor_read_raw_data(struct gsensor_data *gs, int *x, int *y, int *z);
- int gsensor_set_enable(struct gsensor_data *gs, bool enable);
- int gsensor_set_dataready_irq(struct gsensor_data *gs, bool enable);
- /* Helper macros */
- #define GSENSOR_DEV_ATTR_SAMP_FREQ_AVAIL() \
- IIO_DEV_ATTR_SAMP_FREQ_AVAIL(gsensor_show_available_odr)
- #define GSENSOR_DEV_ATTR_SCALE_AVAIL() \
- IIO_DEVICE_ATTR(in_accel_scale_available, 0444, \
- gsensor_show_available_scale, NULL, 0)
- #endif /* __GSENSOR_H */
|