162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#include <linux/iio/iio.h> 362306a36Sopenharmony_ci#include <linux/mutex.h> 462306a36Sopenharmony_ci#include <linux/regmap.h> 562306a36Sopenharmony_ci#include <linux/regulator/consumer.h> 662306a36Sopenharmony_ci#include <linux/i2c.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci/** 962306a36Sopenharmony_ci * enum mpu3050_fullscale - indicates the full range of the sensor in deg/sec 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_cienum mpu3050_fullscale { 1262306a36Sopenharmony_ci FS_250_DPS = 0, 1362306a36Sopenharmony_ci FS_500_DPS, 1462306a36Sopenharmony_ci FS_1000_DPS, 1562306a36Sopenharmony_ci FS_2000_DPS, 1662306a36Sopenharmony_ci}; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/** 1962306a36Sopenharmony_ci * enum mpu3050_lpf - indicates the low pass filter width 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_cienum mpu3050_lpf { 2262306a36Sopenharmony_ci /* This implicity sets sample frequency to 8 kHz */ 2362306a36Sopenharmony_ci LPF_256_HZ_NOLPF = 0, 2462306a36Sopenharmony_ci /* All others sets the sample frequency to 1 kHz */ 2562306a36Sopenharmony_ci LPF_188_HZ, 2662306a36Sopenharmony_ci LPF_98_HZ, 2762306a36Sopenharmony_ci LPF_42_HZ, 2862306a36Sopenharmony_ci LPF_20_HZ, 2962306a36Sopenharmony_ci LPF_10_HZ, 3062306a36Sopenharmony_ci LPF_5_HZ, 3162306a36Sopenharmony_ci LPF_2100_HZ_NOLPF, 3262306a36Sopenharmony_ci}; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cienum mpu3050_axis { 3562306a36Sopenharmony_ci AXIS_X = 0, 3662306a36Sopenharmony_ci AXIS_Y, 3762306a36Sopenharmony_ci AXIS_Z, 3862306a36Sopenharmony_ci AXIS_MAX, 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/** 4262306a36Sopenharmony_ci * struct mpu3050 - instance state container for the device 4362306a36Sopenharmony_ci * @dev: parent device for this instance 4462306a36Sopenharmony_ci * @orientation: mounting matrix, flipped axis etc 4562306a36Sopenharmony_ci * @map: regmap to reach the registers 4662306a36Sopenharmony_ci * @lock: serialization lock to marshal all requests 4762306a36Sopenharmony_ci * @irq: the IRQ used for this device 4862306a36Sopenharmony_ci * @regs: the regulators to power this device 4962306a36Sopenharmony_ci * @fullscale: the current fullscale setting for the device 5062306a36Sopenharmony_ci * @lpf: digital low pass filter setting for the device 5162306a36Sopenharmony_ci * @divisor: base frequency divider: divides 8 or 1 kHz 5262306a36Sopenharmony_ci * @calibration: the three signed 16-bit calibration settings that 5362306a36Sopenharmony_ci * get written into the offset registers for each axis to compensate 5462306a36Sopenharmony_ci * for DC offsets 5562306a36Sopenharmony_ci * @trig: trigger for the MPU-3050 interrupt, if present 5662306a36Sopenharmony_ci * @hw_irq_trigger: hardware interrupt trigger is in use 5762306a36Sopenharmony_ci * @irq_actl: interrupt is active low 5862306a36Sopenharmony_ci * @irq_latch: latched IRQ, this means that it is a level IRQ 5962306a36Sopenharmony_ci * @irq_opendrain: the interrupt line shall be configured open drain 6062306a36Sopenharmony_ci * @pending_fifo_footer: tells us if there is a pending footer in the FIFO 6162306a36Sopenharmony_ci * that we have to read out first when handling the FIFO 6262306a36Sopenharmony_ci * @hw_timestamp: latest hardware timestamp from the trigger IRQ, when in 6362306a36Sopenharmony_ci * use 6462306a36Sopenharmony_ci * @i2cmux: an I2C mux reflecting the fact that this sensor is a hub with 6562306a36Sopenharmony_ci * a pass-through I2C interface coming out of it: this device needs to be 6662306a36Sopenharmony_ci * powered up in order to reach devices on the other side of this mux 6762306a36Sopenharmony_ci */ 6862306a36Sopenharmony_cistruct mpu3050 { 6962306a36Sopenharmony_ci struct device *dev; 7062306a36Sopenharmony_ci struct iio_mount_matrix orientation; 7162306a36Sopenharmony_ci struct regmap *map; 7262306a36Sopenharmony_ci struct mutex lock; 7362306a36Sopenharmony_ci int irq; 7462306a36Sopenharmony_ci struct regulator_bulk_data regs[2]; 7562306a36Sopenharmony_ci enum mpu3050_fullscale fullscale; 7662306a36Sopenharmony_ci enum mpu3050_lpf lpf; 7762306a36Sopenharmony_ci u8 divisor; 7862306a36Sopenharmony_ci s16 calibration[3]; 7962306a36Sopenharmony_ci struct iio_trigger *trig; 8062306a36Sopenharmony_ci bool hw_irq_trigger; 8162306a36Sopenharmony_ci bool irq_actl; 8262306a36Sopenharmony_ci bool irq_latch; 8362306a36Sopenharmony_ci bool irq_opendrain; 8462306a36Sopenharmony_ci bool pending_fifo_footer; 8562306a36Sopenharmony_ci s64 hw_timestamp; 8662306a36Sopenharmony_ci struct i2c_mux_core *i2cmux; 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/* Probe called from different transports */ 9062306a36Sopenharmony_ciint mpu3050_common_probe(struct device *dev, 9162306a36Sopenharmony_ci struct regmap *map, 9262306a36Sopenharmony_ci int irq, 9362306a36Sopenharmony_ci const char *name); 9462306a36Sopenharmony_civoid mpu3050_common_remove(struct device *dev); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* PM ops */ 9762306a36Sopenharmony_ciextern const struct dev_pm_ops mpu3050_dev_pm_ops; 98