Commit 4314a0b7 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-6.1b' of...

Merge tag 'iio-for-6.1b' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-next

Jonathan writes:

Second set of IIO new device support, features and cleanup for the 6.1 cycle.

Normal mixed bag of new device support with continuing trend that most new
devices are supported by extending existing drivers - a positive sign perhaps
that device manufacturers have somewhat stabilized their interfaces across
product generations. The BNO055 driver was however a substantial addition
including several additions to the IIO core.

There are a number of significant patch sets under review, so if the 6.0
cycle runs long I may send a 3rd pull request.

New device support
* adi,adxl313
  - Support for the ADXL312 and ADXL314 accelerometers.
* bosch,bmp280
  - Support for the BMP380 family of pressures sensors.
    Included considerable refactoring and modernization of the bmp280
    driver.
* bosch,bno055
  - New driver for this i2c/serial attached complex IMU.
* lltc,ltc2497
  - Support for the LTC2499 16 channel, 24bit ADC.
* st,pressure
  - Support for the LPS22DF pressure sensor
* st,lsm6dsx
  - Support for the LSM6DSTX (Mainly adding the ID and WAI)

Features
* core - to support the bosch,bno055 requirements
  - Support for linear acceleration channel type (effect  of gravity removed)
  - Pitch, yaw and roll modifiers for angle channels.
  - Standard serialnumber attribute documentation.
  - Binary attributes - to allow for calibration save and restore.
* adi,ad7923
  - Support extended range (wider supported input voltage range).
* bosch,bmp280
  - Add filter controls for some supported parts.
* microchip,mcp3911
  - Buffered capture support for this ADC.
  - Data ready interrupt support, including hiz control for line.
  - Oversampling ratio support.
* st,stm32-adc
  - Support ID registers on parts where they are present, providing
    discoverability of some features.

Fixes - late breaking fixes that I judged could wait for the merge window.
* adi,ad5593r
  - Add a missing STOP condition between address write and data read.
  - Check for related i2c functionality.
* adi,ad7923
  - Fix shift reporting for some variants supported by the driver.
* infinion,dps310
  - Work around a hardware issue where a chip can hang by adding a
    timeout and reset path.

Cleanups
* Continuing work to switch to new pm macros.
* MAINTAINERS
  - Drop duplication of wild card covered entry in ADI block and
    add missing entries to cover ltc294x binding files.
* bosch,bma400
  - Fix trivial smatch warning.
* bosch,bmp280
  - Fix broken links to datasheets
* lltc,ltc2497
  - Fix missing entry for ltc2499
* mexelis,mlx90614
  - Switch to get_avail() callback for _available attributes.
* microchip,mcp3911
  - Move to devm_ resource management for all elements of probe()

* tag 'iio-for-6.1b' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (57 commits)
  iio: adc: mcp3911: add support for oversampling ratio
  dt-bindings: iio: adc: mcp3911: add microchip,data-ready-hiz entry
  iio: adc: mcp3911: add support for interrupts
  iio: adc: mcp3911: add support for buffers
  iio: adc: mcp3911: use resource-managed version of iio_device_register
  iio: accel: bma400: Fix smatch warning based on use of unintialized value.
  iio: light: st_uvis25: Use EXPORT_NS_SIMPLE_DEV_PM_OPS()
  iio: accel: bmi088: Use EXPORT_NS_GPL_RUNTIME_DEV_PM_OPS() and pm_ptr()
  iio: proximity: srf04: Use pm_ptr() to remove unused struct dev_pm_ops
  iio: proximity: sx9360: Switch to DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr()
  iio: proximity: sx9324: Switch to DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr()
  iio: proximity: sx9310: Switch to DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr()
  docs: iio: add documentation for BNO055 driver
  iio: imu: add BNO055 I2C driver
  iio: imu: add BNO055 serdev driver
  dt-bindings: iio/imu: Add Bosch BNO055
  iio: document "serialnumber" sysfs attribute
  iio: document bno055 private sysfs attributes
  iio: imu: add Bosch Sensortec BNO055 core driver
  iio: add support for binary attributes
  ...
parents 3e081438 6d965885
......@@ -260,6 +260,15 @@ Description:
Has all of the equivalent parameters as per voltageY. Units
after application of scale and offset are m/s^2.
What: /sys/bus/iio/devices/iio:deviceX/in_accel_linear_x_raw
What: /sys/bus/iio/devices/iio:deviceX/in_accel_linear_y_raw
What: /sys/bus/iio/devices/iio:deviceX/in_accel_linear_z_raw
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
As per in_accel_X_raw attributes, but minus the
acceleration due to gravity.
What: /sys/bus/iio/devices/iio:deviceX/in_gravity_x_raw
What: /sys/bus/iio/devices/iio:deviceX/in_gravity_y_raw
What: /sys/bus/iio/devices/iio:deviceX/in_gravity_z_raw
......@@ -2137,3 +2146,19 @@ Contact: linux-iio@vger.kernel.org
Description:
Lists all available time values between upper peak to lower
peak. Units in seconds.
What: /sys/bus/iio/devices/iio:deviceX/in_rot_yaw_raw
What: /sys/bus/iio/devices/iio:deviceX/in_rot_pitch_raw
What: /sys/bus/iio/devices/iio:deviceX/in_rot_roll_raw
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled) euler angles readings. Units after
application of scale are deg.
What: /sys/bus/iio/devices/iio:deviceX/serialnumber
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
An example format is 16-bytes, 2-digits-per-byte, HEX-string
representing the sensor unique ID number.
What: /sys/bus/iio/devices/iio:deviceX/in_accel_raw_range
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled) range for acceleration readings. Unit after
application of scale is m/s^2. Note that this doesn't affects
the scale (which should be used when changing the maximum and
minimum readable value affects also the reading scaling factor).
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_raw_range
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Range for angular velocity readings in radians per second. Note
that this does not affects the scale (which should be used when
changing the maximum and minimum readable value affects also the
reading scaling factor).
What: /sys/bus/iio/devices/iio:deviceX/in_accel_raw_range_available
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
List of allowed values for in_accel_raw_range attribute
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_raw_range_available
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
List of allowed values for in_anglvel_raw_range attribute
What: /sys/bus/iio/devices/iio:deviceX/in_magn_calibration_fast_enable
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Can be 1 or 0. Enables/disables the "Fast Magnetometer
Calibration" HW function.
What: /sys/bus/iio/devices/iio:deviceX/fusion_enable
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Can be 1 or 0. Enables/disables the "sensor fusion" (a.k.a.
NDOF) HW function.
What: /sys/bus/iio/devices/iio:deviceX/calibration_data
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Reports the binary calibration data blob for the IMU sensors.
What: /sys/bus/iio/devices/iio:deviceX/in_accel_calibration_auto_status
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Reports the autocalibration status for the accelerometer sensor.
Can be 0 (calibration non even enabled) or 1 to 5 where the greater
the number, the better the calibration status.
What: /sys/bus/iio/devices/iio:deviceX/in_gyro_calibration_auto_status
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Reports the autocalibration status for the gyroscope sensor.
Can be 0 (calibration non even enabled) or 1 to 5 where the greater
the number, the better the calibration status.
What: /sys/bus/iio/devices/iio:deviceX/in_magn_calibration_auto_status
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Reports the autocalibration status for the magnetometer sensor.
Can be 0 (calibration non even enabled) or 1 to 5 where the greater
the number, the better the calibration status.
What: /sys/bus/iio/devices/iio:deviceX/sys_calibration_auto_status
KernelVersion: 6.1
Contact: linux-iio@vger.kernel.org
Description:
Reports the status for the IMU overall autocalibration.
Can be 0 (calibration non even enabled) or 1 to 5 where the greater
the number, the better the calibration status.
......@@ -4,20 +4,24 @@
$id: http://devicetree.org/schemas/iio/accel/adi,adxl313.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices ADXL313 3-Axis Digital Accelerometer
title: Analog Devices ADXL312, ADXL313, and ADXL314 3-Axis Digital Accelerometers
maintainers:
- Lucas Stankus <lucas.p.stankus@gmail.com>
description: |
Analog Devices ADXL313 3-Axis Digital Accelerometer that supports
both I2C & SPI interfaces.
Analog Devices ADXL312, ADXL313, and ADXL314 3-Axis Digital Accelerometer that
support both I2C & SPI interfaces.
https://www.analog.com/en/products/adxl312.html
https://www.analog.com/en/products/adxl313.html
https://www.analog.com/en/products/adxl314.html
properties:
compatible:
enum:
- adi,adxl312
- adi,adxl313
- adi,adxl314
reg:
maxItems: 1
......
......@@ -36,6 +36,10 @@ properties:
description: |
The regulator supply for ADC reference voltage.
adi,range-double:
description: Sets the analog input range from 0 to 2xVREF.
type: boolean
'#address-cells':
const: 1
......
......@@ -13,10 +13,14 @@ description: |
16bit ADC supporting up to 16 single ended or 8 differential inputs.
I2C interface.
https://www.analog.com/media/en/technical-documentation/data-sheets/2497fb.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2499fe.pdf
properties:
compatible:
const:
lltc,ltc2497
enum:
- lltc,ltc2497
- lltc,ltc2499
reg: true
vref-supply: true
......
......@@ -36,6 +36,13 @@ properties:
description: IRQ line of the ADC
maxItems: 1
microchip,data-ready-hiz:
description:
Data Ready Pin Inactive State Control
true = The DR pin state is high-impedance
false = The DR pin state is logic high
type: boolean
microchip,device-addr:
description: Device address when multiple MCP3911 chips are present on the same SPI bus.
$ref: /schemas/types.yaml#/definitions/uint32
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/imu/bosch,bno055.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Bosch BNO055
maintainers:
- Andrea Merello <andrea.merello@iit.it>
description: |
Inertial Measurement Unit with Accelerometer, Gyroscope, Magnetometer and
internal MCU for sensor fusion
https://www.bosch-sensortec.com/products/smart-sensors/bno055/
properties:
compatible:
enum:
- bosch,bno055
reg:
maxItems: 1
reset-gpios:
maxItems: 1
clocks:
maxItems: 1
required:
- compatible
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
serial {
imu {
compatible = "bosch,bno055";
reset-gpios = <&gpio0 54 GPIO_ACTIVE_LOW>;
clocks = <&imu_clk>;
};
};
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
imu@28 {
compatible = "bosch,bno055";
reg = <0x28>;
reset-gpios = <&gpio0 54 GPIO_ACTIVE_LOW>;
clocks = <&imu_clk>;
};
};
......@@ -35,6 +35,9 @@ properties:
- items:
- const: st,asm330lhhx
- const: st,lsm6dsr
- items:
- const: st,lsm6dstx
- const: st,lsm6dst
reg:
maxItems: 1
......
......@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/iio/pressure/bmp085.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: BMP085/BMP180/BMP280/BME280 pressure iio sensors
title: BMP085/BMP180/BMP280/BME280/BMP380 pressure iio sensors
maintainers:
- Andreas Klinger <ak@it-klinger.de>
......@@ -16,6 +16,7 @@ description: |
https://www.bosch-sensortec.com/bst/products/all_products/bmp180
https://www.bosch-sensortec.com/bst/products/all_products/bmp280
https://www.bosch-sensortec.com/bst/products/all_products/bme280
https://www.bosch-sensortec.com/bst/products/all_products/bmp380
properties:
compatible:
......@@ -24,6 +25,7 @@ properties:
- bosch,bmp180
- bosch,bmp280
- bosch,bme280
- bosch,bmp380
reg:
maxItems: 1
......
......@@ -73,6 +73,7 @@ properties:
- description: STMicroelectronics Pressure Sensors
enum:
- st,lps001wp-press
- st,lps22df
- st,lps22hb-press
- st,lps22hh
- st,lps25h-press
......@@ -141,6 +142,7 @@ allOf:
- st,lis2mdl
- st,lis3l02dq
- st,lis3lv02dl-accel
- st,lps22df
- st,lps22hb-press
- st,lps22hh
- st,lps25h-press
......
.. SPDX-License-Identifier: GPL-2.0
==============================
BNO055 driver
==============================
1. Overview
===========
This driver supports Bosch BNO055 IMUs (on both serial and I2C busses).
Accelerometer, magnetometer and gyroscope measures are always provided.
When "fusion_enable" sysfs attribute is set to 1, orientation (both Euler
angles and quaternion), linear velocity and gravity vector are also
provided, but some sensor settings (e.g. low pass filtering and range)
became locked (the IMU firmware controls them).
This driver supports also IIO buffers.
2. Calibration
==============
The IMU continuously performs an autocalibration procedure if (and only if)
operating in fusion mode. The magnetometer autocalibration can however be
disabled writing 0 in the sysfs in_magn_calibration_fast_enable attribute.
The driver provides access to autocalibration flags (i.e. you can known if
the IMU has successfully autocalibrated) and to the calibration data blob.
The user can save this blob in a firmware file (i.e. in /lib/firmware) that
the driver looks for at probe time. If found, then the IMU is initialized
with this calibration data. This saves the user from performing the
calibration procedure every time (which consist of moving the IMU in
various way).
The driver looks for calibration data file using two different names: first
a file whose name is suffixed with the IMU unique ID (exposed in sysfs as
serial_number) is searched for; this is useful when there is more than one
IMU instance. If this file is not found, then a "generic" calibration file
is searched for (which can be used when only one IMU is present, without
struggling with fancy names, that change on each device).
Valid calibration file names would be e.g.
bno055-caldata-0e7c26a33541515120204a35342b04ff.dat
bno055-caldata.dat
In non-fusion mode the IIO 'offset' attributes provide access to the
offsets from calibration data (if any), so that the user can apply them to
the accel, angvel and magn IIO attributes. In fusion mode they are not
needed (the IMU firmware internally applies those corrections) and they
read as zero.
......@@ -10,3 +10,5 @@ Industrial I/O
iio_configfs
ep93xx_adc
bno055
......@@ -1319,7 +1319,8 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523
F: Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350
F: Documentation/devicetree/bindings/iio/*/adi,*
F: Documentation/devicetree/bindings/iio/dac/adi,ad5758.yaml
F: Documentation/devicetree/bindings/iio/adc/lltc,ltc2496.yaml
F: Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml
F: drivers/iio/*/ad*
F: drivers/iio/adc/ltc249*
F: drivers/iio/amplifiers/hmc425a.c
......
......@@ -8,6 +8,8 @@
#ifndef _ADXL313_H_
#define _ADXL313_H_
#include <linux/iio/iio.h>
/* ADXL313 register definitions */
#define ADXL313_REG_DEVID0 0x00
#define ADXL313_REG_DEVID1 0x01
......@@ -26,6 +28,7 @@
#define ADXL313_REG_FIFO_STATUS 0x39
#define ADXL313_DEVID0 0xAD
#define ADXL313_DEVID0_ADXL312_314 0xE5
#define ADXL313_DEVID1 0x1D
#define ADXL313_PARTID 0xCB
#define ADXL313_SOFT_RESET 0x52
......@@ -37,18 +40,46 @@
#define ADXL313_MEASUREMENT_MODE BIT(3)
#define ADXL313_RANGE_MSK GENMASK(1, 0)
#define ADXL313_RANGE_4G 3
#define ADXL313_RANGE_MAX 3
#define ADXL313_FULL_RES BIT(3)
#define ADXL313_SPI_3WIRE BIT(6)
#define ADXL313_I2C_DISABLE BIT(6)
extern const struct regmap_access_table adxl312_readable_regs_table;
extern const struct regmap_access_table adxl313_readable_regs_table;
extern const struct regmap_access_table adxl314_readable_regs_table;
extern const struct regmap_access_table adxl312_writable_regs_table;
extern const struct regmap_access_table adxl313_writable_regs_table;
extern const struct regmap_access_table adxl314_writable_regs_table;
enum adxl313_device_type {
ADXL312,
ADXL313,
ADXL314,
};
struct adxl313_data {
struct regmap *regmap;
const struct adxl313_chip_info *chip_info;
struct mutex lock; /* lock to protect transf_buf */
__le16 transf_buf __aligned(IIO_DMA_MINALIGN);
};
struct adxl313_chip_info {
const char *name;
enum adxl313_device_type type;
int scale_factor;
bool variable_range;
bool soft_reset;
int (*check_id)(struct device *dev, struct adxl313_data *data);
};
extern const struct adxl313_chip_info adxl31x_chip_info[];
int adxl313_core_probe(struct device *dev,
struct regmap *regmap,
const char *name,
const struct adxl313_chip_info *chip_info,
int (*setup)(struct device *, struct regmap *));
#endif /* _ADXL313_H_ */
......@@ -8,12 +8,18 @@
*/
#include <linux/bitfield.h>
#include <linux/iio/iio.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include "adxl313.h"
static const struct regmap_range adxl312_readable_reg_range[] = {
regmap_reg_range(ADXL313_REG_DEVID0, ADXL313_REG_DEVID0),
regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)),
regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL),
regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_FIFO_STATUS),
};
static const struct regmap_range adxl313_readable_reg_range[] = {
regmap_reg_range(ADXL313_REG_DEVID0, ADXL313_REG_XID),
regmap_reg_range(ADXL313_REG_SOFT_RESET, ADXL313_REG_SOFT_RESET),
......@@ -22,12 +28,109 @@ static const struct regmap_range adxl313_readable_reg_range[] = {
regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_FIFO_STATUS),
};
const struct regmap_access_table adxl312_readable_regs_table = {
.yes_ranges = adxl312_readable_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl312_readable_reg_range),
};
EXPORT_SYMBOL_NS_GPL(adxl312_readable_regs_table, IIO_ADXL313);
const struct regmap_access_table adxl313_readable_regs_table = {
.yes_ranges = adxl313_readable_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl313_readable_reg_range),
};
EXPORT_SYMBOL_NS_GPL(adxl313_readable_regs_table, IIO_ADXL313);
const struct regmap_access_table adxl314_readable_regs_table = {
.yes_ranges = adxl312_readable_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl312_readable_reg_range),
};
EXPORT_SYMBOL_NS_GPL(adxl314_readable_regs_table, IIO_ADXL313);
static int adxl312_check_id(struct device *dev,
struct adxl313_data *data)
{
unsigned int regval;
int ret;
ret = regmap_read(data->regmap, ADXL313_REG_DEVID0, &regval);
if (ret)
return ret;
if (regval != ADXL313_DEVID0_ADXL312_314)
dev_warn(dev, "Invalid manufacturer ID: %#02x\n", regval);
return 0;
}
static int adxl313_check_id(struct device *dev,
struct adxl313_data *data)
{
unsigned int regval;
int ret;
ret = regmap_read(data->regmap, ADXL313_REG_DEVID0, &regval);
if (ret)
return ret;
if (regval != ADXL313_DEVID0)
dev_warn(dev, "Invalid manufacturer ID: 0x%02x\n", regval);
/* Check DEVID1 and PARTID */
if (regval == ADXL313_DEVID0) {
ret = regmap_read(data->regmap, ADXL313_REG_DEVID1, &regval);
if (ret)
return ret;
if (regval != ADXL313_DEVID1)
dev_warn(dev, "Invalid mems ID: 0x%02x\n", regval);
ret = regmap_read(data->regmap, ADXL313_REG_PARTID, &regval);
if (ret)
return ret;
if (regval != ADXL313_PARTID)
dev_warn(dev, "Invalid device ID: 0x%02x\n", regval);
}
return 0;
}
const struct adxl313_chip_info adxl31x_chip_info[] = {
[ADXL312] = {
.name = "adxl312",
.type = ADXL312,
.scale_factor = 28425072,
.variable_range = true,
.soft_reset = false,
.check_id = &adxl312_check_id,
},
[ADXL313] = {
.name = "adxl313",
.type = ADXL313,
.scale_factor = 9576806,
.variable_range = true,
.soft_reset = true,
.check_id = &adxl313_check_id,
},
[ADXL314] = {
.name = "adxl314",
.type = ADXL314,
.scale_factor = 478858719,
.variable_range = false,
.soft_reset = false,
.check_id = &adxl312_check_id,
},
};
EXPORT_SYMBOL_NS_GPL(adxl31x_chip_info, IIO_ADXL313);
static const struct regmap_range adxl312_writable_reg_range[] = {
regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)),
regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL),
regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_INT_MAP),
regmap_reg_range(ADXL313_REG_DATA_FORMAT, ADXL313_REG_DATA_FORMAT),
regmap_reg_range(ADXL313_REG_FIFO_CTL, ADXL313_REG_FIFO_CTL),
};
static const struct regmap_range adxl313_writable_reg_range[] = {
regmap_reg_range(ADXL313_REG_SOFT_RESET, ADXL313_REG_SOFT_RESET),
regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)),
......@@ -37,17 +140,23 @@ static const struct regmap_range adxl313_writable_reg_range[] = {
regmap_reg_range(ADXL313_REG_FIFO_CTL, ADXL313_REG_FIFO_CTL),
};
const struct regmap_access_table adxl312_writable_regs_table = {
.yes_ranges = adxl312_writable_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl312_writable_reg_range),
};
EXPORT_SYMBOL_NS_GPL(adxl312_writable_regs_table, IIO_ADXL313);
const struct regmap_access_table adxl313_writable_regs_table = {
.yes_ranges = adxl313_writable_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl313_writable_reg_range),
};
EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, IIO_ADXL313);
struct adxl313_data {
struct regmap *regmap;
struct mutex lock; /* lock to protect transf_buf */
__le16 transf_buf __aligned(IIO_DMA_MINALIGN);
const struct regmap_access_table adxl314_writable_regs_table = {
.yes_ranges = adxl312_writable_reg_range,
.n_yes_ranges = ARRAY_SIZE(adxl312_writable_reg_range),
};
EXPORT_SYMBOL_NS_GPL(adxl314_writable_regs_table, IIO_ADXL313);
static const int adxl313_odr_freqs[][2] = {
[0] = { 6, 250000 },
......@@ -156,12 +265,10 @@ static int adxl313_read_raw(struct iio_dev *indio_dev,
*val = sign_extend32(ret, chan->scan_type.realbits - 1);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
/*
* Scale for any g range is given in datasheet as
* 1024 LSB/g = 0.0009765625 * 9.80665 = 0.009576806640625 m/s^2
*/
*val = 0;
*val2 = 9576806;
*val2 = data->chip_info->scale_factor;
return IIO_VAL_INT_PLUS_NANO;
case IIO_CHAN_INFO_CALIBBIAS:
ret = regmap_read(data->regmap,
......@@ -170,7 +277,7 @@ static int adxl313_read_raw(struct iio_dev *indio_dev,
return ret;
/*
* 8-bit resolution at +/- 0.5g, that is 4x accel data scale
* 8-bit resolution at minimum range, that is 4x accel data scale
* factor at full resolution
*/
*val = sign_extend32(regval, 7) * 4;
......@@ -198,7 +305,7 @@ static int adxl313_write_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS:
/*
* 8-bit resolution at +/- 0.5g, that is 4x accel data scale
* 8-bit resolution at minimum range, that is 4x accel data scale
* factor at full resolution
*/
if (clamp_val(val, -128 * 4, 127 * 4) != val)
......@@ -223,14 +330,18 @@ static const struct iio_info adxl313_info = {
static int adxl313_setup(struct device *dev, struct adxl313_data *data,
int (*setup)(struct device *, struct regmap *))
{
unsigned int regval;
int ret;
/* Ensures the device is in a consistent state after start up */
ret = regmap_write(data->regmap, ADXL313_REG_SOFT_RESET,
ADXL313_SOFT_RESET);
if (ret)
return ret;
/*
* If sw reset available, ensures the device is in a consistent
* state after start up
*/
if (data->chip_info->soft_reset) {
ret = regmap_write(data->regmap, ADXL313_REG_SOFT_RESET,
ADXL313_SOFT_RESET);
if (ret)
return ret;
}
if (setup) {
ret = setup(dev, data->regmap);
......@@ -238,46 +349,25 @@ static int adxl313_setup(struct device *dev, struct adxl313_data *data,
return ret;
}
ret = regmap_read(data->regmap, ADXL313_REG_DEVID0, &regval);
ret = data->chip_info->check_id(dev, data);
if (ret)
return ret;
if (regval != ADXL313_DEVID0) {
dev_err(dev, "Invalid manufacturer ID: 0x%02x\n", regval);
return -ENODEV;
}
ret = regmap_read(data->regmap, ADXL313_REG_DEVID1, &regval);
if (ret)
return ret;
if (regval != ADXL313_DEVID1) {
dev_err(dev, "Invalid mems ID: 0x%02x\n", regval);
return -ENODEV;
}
ret = regmap_read(data->regmap, ADXL313_REG_PARTID, &regval);
if (ret)
return ret;
/* Sets the range to maximum, full resolution, if applicable */
if (data->chip_info->variable_range) {
ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT,
ADXL313_RANGE_MSK,
FIELD_PREP(ADXL313_RANGE_MSK, ADXL313_RANGE_MAX));
if (ret)
return ret;
if (regval != ADXL313_PARTID) {
dev_err(dev, "Invalid device ID: 0x%02x\n", regval);
return -ENODEV;
/* Enables full resolution */
ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT,
ADXL313_FULL_RES, ADXL313_FULL_RES);
if (ret)
return ret;
}
/* Sets the range to +/- 4g */
ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT,
ADXL313_RANGE_MSK,
FIELD_PREP(ADXL313_RANGE_MSK, ADXL313_RANGE_4G));
if (ret)
return ret;
/* Enables full resolution */
ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT,
ADXL313_FULL_RES, ADXL313_FULL_RES);
if (ret)
return ret;
/* Enables measurement mode */
return regmap_update_bits(data->regmap, ADXL313_REG_POWER_CTL,
ADXL313_POWER_CTL_MSK,
......@@ -288,7 +378,7 @@ static int adxl313_setup(struct device *dev, struct adxl313_data *data,
* adxl313_core_probe() - probe and setup for adxl313 accelerometer
* @dev: Driver model representation of the device
* @regmap: Register map of the device
* @name: Device name buffer reference
* @chip_info: Structure containing device specific data
* @setup: Setup routine to be executed right before the standard device
* setup, can also be set to NULL if not required
*
......@@ -296,7 +386,7 @@ static int adxl313_setup(struct device *dev, struct adxl313_data *data,
*/
int adxl313_core_probe(struct device *dev,
struct regmap *regmap,
const char *name,
const struct adxl313_chip_info *chip_info,
int (*setup)(struct device *, struct regmap *))
{
struct adxl313_data *data;
......@@ -309,9 +399,11 @@ int adxl313_core_probe(struct device *dev,
data = iio_priv(indio_dev);
data->regmap = regmap;
data->chip_info = chip_info;
mutex_init(&data->lock);
indio_dev->name = name;
indio_dev->name = chip_info->name;
indio_dev->info = &adxl313_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = adxl313_channels;
......
......@@ -14,42 +14,72 @@
#include "adxl313.h"
static const struct regmap_config adxl313_i2c_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.rd_table = &adxl313_readable_regs_table,
.wr_table = &adxl313_writable_regs_table,
.max_register = 0x39,
static const struct regmap_config adxl31x_i2c_regmap_config[] = {
[ADXL312] = {
.reg_bits = 8,
.val_bits = 8,
.rd_table = &adxl312_readable_regs_table,
.wr_table = &adxl312_writable_regs_table,
.max_register = 0x39,
},
[ADXL313] = {
.reg_bits = 8,
.val_bits = 8,
.rd_table = &adxl313_readable_regs_table,
.wr_table = &adxl313_writable_regs_table,
.max_register = 0x39,
},
[ADXL314] = {
.reg_bits = 8,
.val_bits = 8,
.rd_table = &adxl314_readable_regs_table,
.wr_table = &adxl314_writable_regs_table,
.max_register = 0x39,
},
};
static int adxl313_i2c_probe(struct i2c_client *client)
{
struct regmap *regmap;
regmap = devm_regmap_init_i2c(client, &adxl313_i2c_regmap_config);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "Error initializing i2c regmap: %ld\n",
PTR_ERR(regmap));
return PTR_ERR(regmap);
}
return adxl313_core_probe(&client->dev, regmap, client->name, NULL);
}
static const struct i2c_device_id adxl313_i2c_id[] = {
{ "adxl313" },
{ .name = "adxl312", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] },
{ .name = "adxl313", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] },
{ .name = "adxl314", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] },
{ }
};
MODULE_DEVICE_TABLE(i2c, adxl313_i2c_id);
static const struct of_device_id adxl313_of_match[] = {
{ .compatible = "adi,adxl313" },
{ .compatible = "adi,adxl312", .data = &adxl31x_chip_info[ADXL312] },
{ .compatible = "adi,adxl313", .data = &adxl31x_chip_info[ADXL313] },
{ .compatible = "adi,adxl314", .data = &adxl31x_chip_info[ADXL314] },
{ }
};
MODULE_DEVICE_TABLE(of, adxl313_of_match);
static int adxl313_i2c_probe(struct i2c_client *client)
{
const struct adxl313_chip_info *chip_data;
struct regmap *regmap;
/*
* Retrieves device specific data as a pointer to a
* adxl313_chip_info structure
*/
chip_data = device_get_match_data(&client->dev);
if (!chip_data)
chip_data = (const struct adxl313_chip_info *)i2c_match_id(adxl313_i2c_id, client)->driver_data;
regmap = devm_regmap_init_i2c(client,
&adxl31x_i2c_regmap_config[chip_data->type]);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "Error initializing i2c regmap: %ld\n",
PTR_ERR(regmap));
return PTR_ERR(regmap);
}
return adxl313_core_probe(&client->dev, regmap, chip_data, NULL);
}
static struct i2c_driver adxl313_i2c_driver = {
.driver = {
.name = "adxl313_i2c",
......
......@@ -11,17 +11,38 @@
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/property.h>
#include "adxl313.h"
static const struct regmap_config adxl313_spi_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.rd_table = &adxl313_readable_regs_table,
.wr_table = &adxl313_writable_regs_table,
.max_register = 0x39,
/* Setting bits 7 and 6 enables multiple-byte read */
.read_flag_mask = BIT(7) | BIT(6),
static const struct regmap_config adxl31x_spi_regmap_config[] = {
[ADXL312] = {
.reg_bits = 8,
.val_bits = 8,
.rd_table = &adxl312_readable_regs_table,
.wr_table = &adxl312_writable_regs_table,
.max_register = 0x39,
/* Setting bits 7 and 6 enables multiple-byte read */
.read_flag_mask = BIT(7) | BIT(6),
},
[ADXL313] = {
.reg_bits = 8,
.val_bits = 8,
.rd_table = &adxl313_readable_regs_table,
.wr_table = &adxl313_writable_regs_table,
.max_register = 0x39,
/* Setting bits 7 and 6 enables multiple-byte read */
.read_flag_mask = BIT(7) | BIT(6),
},
[ADXL314] = {
.reg_bits = 8,
.val_bits = 8,
.rd_table = &adxl314_readable_regs_table,
.wr_table = &adxl314_writable_regs_table,
.max_register = 0x39,
/* Setting bits 7 and 6 enables multiple-byte read */
.read_flag_mask = BIT(7) | BIT(6),
},
};
static int adxl313_spi_setup(struct device *dev, struct regmap *regmap)
......@@ -42,7 +63,7 @@ static int adxl313_spi_setup(struct device *dev, struct regmap *regmap)
static int adxl313_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
const struct adxl313_chip_info *chip_data;
struct regmap *regmap;
int ret;
......@@ -51,26 +72,40 @@ static int adxl313_spi_probe(struct spi_device *spi)
if (ret)
return ret;
regmap = devm_regmap_init_spi(spi, &adxl313_spi_regmap_config);
/*
* Retrieves device specific data as a pointer to a
* adxl313_chip_info structure
*/
chip_data = device_get_match_data(&spi->dev);
if (!chip_data)
chip_data = (const struct adxl313_chip_info *)spi_get_device_id(spi)->driver_data;
regmap = devm_regmap_init_spi(spi,
&adxl31x_spi_regmap_config[chip_data->type]);
if (IS_ERR(regmap)) {
dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
PTR_ERR(regmap));
return PTR_ERR(regmap);
}
return adxl313_core_probe(&spi->dev, regmap, id->name,
&adxl313_spi_setup);
return adxl313_core_probe(&spi->dev, regmap,
chip_data, &adxl313_spi_setup);
}
static const struct spi_device_id adxl313_spi_id[] = {
{ "adxl313" },
{ .name = "adxl312", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] },
{ .name = "adxl313", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL313] },
{ .name = "adxl314", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL314] },
{ }
};
MODULE_DEVICE_TABLE(spi, adxl313_spi_id);
static const struct of_device_id adxl313_of_match[] = {
{ .compatible = "adi,adxl313" },
{ .compatible = "adi,adxl312", .data = &adxl31x_chip_info[ADXL312] },
{ .compatible = "adi,adxl313", .data = &adxl31x_chip_info[ADXL313] },
{ .compatible = "adi,adxl314", .data = &adxl31x_chip_info[ADXL314] },
{ }
};
......
......@@ -1184,7 +1184,8 @@ static int bma400_activity_event_en(struct bma400_data *data,
enum iio_event_direction dir,
int state)
{
int ret, reg, msk, value, field_value;
int ret, reg, msk, value;
int field_value = 0;
switch (dir) {
case IIO_EV_DIR_RISING:
......
......@@ -606,7 +606,7 @@ void bmi088_accel_core_remove(struct device *dev)
}
EXPORT_SYMBOL_NS_GPL(bmi088_accel_core_remove, IIO_BMI088);
static int __maybe_unused bmi088_accel_runtime_suspend(struct device *dev)
static int bmi088_accel_runtime_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmi088_accel_data *data = iio_priv(indio_dev);
......@@ -614,7 +614,7 @@ static int __maybe_unused bmi088_accel_runtime_suspend(struct device *dev)
return bmi088_accel_power_down(data);
}
static int __maybe_unused bmi088_accel_runtime_resume(struct device *dev)
static int bmi088_accel_runtime_resume(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmi088_accel_data *data = iio_priv(indio_dev);
......@@ -622,13 +622,10 @@ static int __maybe_unused bmi088_accel_runtime_resume(struct device *dev)
return bmi088_accel_power_up(data);
}
const struct dev_pm_ops bmi088_accel_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(bmi088_accel_runtime_suspend,
bmi088_accel_runtime_resume, NULL)
};
EXPORT_SYMBOL_NS_GPL(bmi088_accel_pm_ops, IIO_BMI088);
EXPORT_NS_GPL_RUNTIME_DEV_PM_OPS(bmi088_accel_pm_ops,
bmi088_accel_runtime_suspend,
bmi088_accel_runtime_resume, NULL,
IIO_BMI088);
MODULE_AUTHOR("Niek van Agt <niek.van.agt@topicproducts.com>");
MODULE_LICENSE("GPL v2");
......
......@@ -80,7 +80,7 @@ MODULE_DEVICE_TABLE(spi, bmi088_accel_id);
static struct spi_driver bmi088_accel_driver = {
.driver = {
.name = "bmi088_accel_spi",
.pm = &bmi088_accel_pm_ops,
.pm = pm_ptr(&bmi088_accel_pm_ops),
.of_match_table = bmi088_of_match,
},
.probe = bmi088_accel_probe,
......
......@@ -732,6 +732,8 @@ config MCP3422
config MCP3911
tristate "Microchip Technology MCP3911 driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Microchip Technology's MCP3911
analog to digital converter.
......
......@@ -8,6 +8,7 @@
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/spi/spi.h>
......@@ -93,6 +94,7 @@ enum ad7923_id {
.sign = 'u', \
.realbits = (bits), \
.storagebits = 16, \
.shift = 12 - (bits), \
.endianness = IIO_BE, \
}, \
}
......@@ -268,7 +270,8 @@ static int ad7923_read_raw(struct iio_dev *indio_dev,
return ret;
if (chan->address == EXTRACT(ret, 12, 4))
*val = EXTRACT(ret, 0, 12);
*val = EXTRACT(ret, chan->scan_type.shift,
chan->scan_type.realbits);
else
return -EIO;
......@@ -298,6 +301,7 @@ static void ad7923_regulator_disable(void *data)
static int ad7923_probe(struct spi_device *spi)
{
u32 ad7923_range = AD7923_RANGE;
struct ad7923_state *st;
struct iio_dev *indio_dev;
const struct ad7923_chip_info *info;
......@@ -309,8 +313,11 @@ static int ad7923_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
if (device_property_read_bool(&spi->dev, "adi,range-double"))
ad7923_range = 0;
st->spi = spi;
st->settings = AD7923_CODING | AD7923_RANGE |
st->settings = AD7923_CODING | ad7923_range |
AD7923_PM_MODE_WRITE(AD7923_PM_MODE_OPS);
info = &ad7923_chip_info[spi_get_device_id(spi)->driver_data];
......
......@@ -15,6 +15,7 @@
#include <linux/iio/driver.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include "ltc2497.h"
......@@ -74,6 +75,7 @@ static int ltc2496_probe(struct spi_device *spi)
spi_set_drvdata(spi, indio_dev);
st->spi = spi;
st->common_ddata.result_and_measure = ltc2496_result_and_measure;
st->common_ddata.chip_info = device_get_match_data(dev);
return ltc2497core_probe(dev, indio_dev);
}
......@@ -85,8 +87,13 @@ static void ltc2496_remove(struct spi_device *spi)
ltc2497core_remove(indio_dev);
}
static const struct ltc2497_chip_info ltc2496_info = {
.resolution = 16,
.name = NULL,
};
static const struct of_device_id ltc2496_of_match[] = {
{ .compatible = "lltc,ltc2496", },
{ .compatible = "lltc,ltc2496", .data = &ltc2496_info, },
{},
};
MODULE_DEVICE_TABLE(of, ltc2496_of_match);
......
......@@ -95,7 +95,7 @@ static int ltc2497core_read_raw(struct iio_dev *indio_dev,
return ret;
*val = ret / 1000;
*val2 = 17;
*val2 = ddata->chip_info->resolution + 1;
return IIO_VAL_FRACTIONAL_LOG2;
......@@ -169,7 +169,15 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev)
struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);
int ret;
indio_dev->name = dev_name(dev);
/*
* Keep using dev_name() for the iio_dev's name on some of the parts,
* since updating it would result in a ABI breakage.
*/
if (ddata->chip_info->name)
indio_dev->name = ddata->chip_info->name;
else
indio_dev->name = dev_name(dev);
indio_dev->info = &ltc2497core_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = ltc2497core_channel;
......
......@@ -12,18 +12,31 @@
#include <linux/iio/driver.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include <asm/unaligned.h>
#include "ltc2497.h"
enum ltc2497_chip_type {
TYPE_LTC2497,
TYPE_LTC2499,
};
struct ltc2497_driverdata {
/* this must be the first member */
struct ltc2497core_driverdata common_ddata;
struct i2c_client *client;
u32 recv_size;
u32 sub_lsb;
/*
* DMA (thus cache coherency maintenance) may require the
* transfer buffers to live in their own cache lines.
*/
__be32 buf __aligned(IIO_DMA_MINALIGN);
union {
__be32 d32;
u8 d8[3];
} data __aligned(IIO_DMA_MINALIGN);
};
static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
......@@ -34,13 +47,43 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
int ret;
if (val) {
ret = i2c_master_recv(st->client, (char *)&st->buf, 3);
if (st->recv_size == 3)
ret = i2c_master_recv(st->client, (char *)&st->data.d8,
st->recv_size);
else
ret = i2c_master_recv(st->client, (char *)&st->data.d32,
st->recv_size);
if (ret < 0) {
dev_err(&st->client->dev, "i2c_master_recv failed\n");
return ret;
}
*val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
/*
* The data format is 16/24 bit 2s complement, but with an upper sign bit on the
* resolution + 1 position, which is set for positive values only. Given this
* bit's value, subtracting BIT(resolution + 1) from the ADC's result is
* equivalent to a sign extension.
*/
if (st->recv_size == 3) {
*val = (get_unaligned_be24(st->data.d8) >> st->sub_lsb)
- BIT(ddata->chip_info->resolution + 1);
} else {
*val = (be32_to_cpu(st->data.d32) >> st->sub_lsb)
- BIT(ddata->chip_info->resolution + 1);
}
/*
* The part started a new conversion at the end of the above i2c
* transfer, so if the address didn't change since the last call
* everything is fine and we can return early.
* If not (which should only happen when some sort of bulk
* conversion is implemented) we have to program the new
* address. Note that this probably fails as the conversion that
* was triggered above is like not complete yet and the two
* operations have to be done in a single transfer.
*/
if (ddata->addr_prev == address)
return 0;
}
ret = i2c_smbus_write_byte(st->client,
......@@ -54,9 +97,11 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
static int ltc2497_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
const struct ltc2497_chip_info *chip_info;
struct iio_dev *indio_dev;
struct ltc2497_driverdata *st;
struct device *dev = &client->dev;
u32 resolution;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
I2C_FUNC_SMBUS_WRITE_BYTE))
......@@ -71,6 +116,15 @@ static int ltc2497_probe(struct i2c_client *client,
st->client = client;
st->common_ddata.result_and_measure = ltc2497_result_and_measure;
chip_info = device_get_match_data(dev);
if (!chip_info)
chip_info = (const struct ltc2497_chip_info *)id->driver_data;
st->common_ddata.chip_info = chip_info;
resolution = chip_info->resolution;
st->sub_lsb = 31 - (resolution + 1);
st->recv_size = BITS_TO_BYTES(resolution) + 1;
return ltc2497core_probe(dev, indio_dev);
}
......@@ -83,14 +137,27 @@ static int ltc2497_remove(struct i2c_client *client)
return 0;
}
static const struct ltc2497_chip_info ltc2497_info[] = {
[TYPE_LTC2497] = {
.resolution = 16,
.name = NULL,
},
[TYPE_LTC2499] = {
.resolution = 24,
.name = "ltc2499",
},
};
static const struct i2c_device_id ltc2497_id[] = {
{ "ltc2497", 0 },
{ "ltc2497", (kernel_ulong_t)&ltc2497_info[TYPE_LTC2497] },
{ "ltc2499", (kernel_ulong_t)&ltc2497_info[TYPE_LTC2499] },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2497_id);
static const struct of_device_id ltc2497_of_match[] = {
{ .compatible = "lltc,ltc2497", },
{ .compatible = "lltc,ltc2497", .data = &ltc2497_info[TYPE_LTC2497] },
{ .compatible = "lltc,ltc2499", .data = &ltc2497_info[TYPE_LTC2499] },
{},
};
MODULE_DEVICE_TABLE(of, ltc2497_of_match);
......
......@@ -4,9 +4,15 @@
#define LTC2497_CONFIG_DEFAULT LTC2497_ENABLE
#define LTC2497_CONVERSION_TIME_MS 150ULL
struct ltc2497_chip_info {
u32 resolution;
const char *name;
};
struct ltc2497core_driverdata {
struct regulator *ref;
ktime_t time_prev;
const struct ltc2497_chip_info *chip_info;
u8 addr_prev;
int (*result_and_measure)(struct ltc2497core_driverdata *ddata,
u8 address, int *val);
......
This diff is collapsed.
......@@ -9,6 +9,7 @@
*
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/irqchip/chained_irq.h>
......@@ -62,6 +63,7 @@ struct stm32_adc_priv;
* @regs: common registers for all instances
* @clk_sel: clock selection routine
* @max_clk_rate_hz: maximum analog clock rate (Hz, from datasheet)
* @ipid: adc identification number
* @has_syscfg: SYSCFG capability flags
* @num_irqs: number of interrupt lines
* @num_adcs: maximum number of ADC instances in the common registers
......@@ -70,6 +72,7 @@ struct stm32_adc_priv_cfg {
const struct stm32_adc_common_regs *regs;
int (*clk_sel)(struct platform_device *, struct stm32_adc_priv *);
u32 max_clk_rate_hz;
u32 ipid;
unsigned int has_syscfg;
unsigned int num_irqs;
unsigned int num_adcs;
......@@ -78,6 +81,7 @@ struct stm32_adc_priv_cfg {
/**
* struct stm32_adc_priv - stm32 ADC core private data
* @irq: irq(s) for ADC block
* @nb_adc_max: actual maximum number of instance per ADC block
* @domain: irq domain reference
* @aclk: clock reference for the analog circuitry
* @bclk: bus clock common for all ADCs, depends on part used
......@@ -95,6 +99,7 @@ struct stm32_adc_priv_cfg {
*/
struct stm32_adc_priv {
int irq[STM32_ADC_MAX_ADCS];
unsigned int nb_adc_max;
struct irq_domain *domain;
struct clk *aclk;
struct clk *bclk;
......@@ -354,7 +359,7 @@ static void stm32_adc_irq_handler(struct irq_desc *desc)
* before invoking the interrupt handler (e.g. call ISR only for
* IRQ-enabled ADCs).
*/
for (i = 0; i < priv->cfg->num_adcs; i++) {
for (i = 0; i < priv->nb_adc_max; i++) {
if ((status & priv->cfg->regs->eoc_msk[i] &&
stm32_adc_eoc_enabled(priv, i)) ||
(status & priv->cfg->regs->ovr_msk[i]))
......@@ -424,7 +429,7 @@ static void stm32_adc_irq_remove(struct platform_device *pdev,
int hwirq;
unsigned int i;
for (hwirq = 0; hwirq < STM32_ADC_MAX_ADCS; hwirq++)
for (hwirq = 0; hwirq < priv->nb_adc_max; hwirq++)
irq_dispose_mapping(irq_find_mapping(priv->domain, hwirq));
irq_domain_remove(priv->domain);
......@@ -642,6 +647,49 @@ static int stm32_adc_core_switches_probe(struct device *dev,
return 0;
}
static int stm32_adc_probe_identification(struct platform_device *pdev,
struct stm32_adc_priv *priv)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
const char *compat;
int ret, count = 0;
u32 id, val;
if (!priv->cfg->ipid)
return 0;
id = FIELD_GET(STM32MP1_IPIDR_MASK,
readl_relaxed(priv->common.base + STM32MP1_ADC_IPDR));
if (id != priv->cfg->ipid) {
dev_err(&pdev->dev, "Unexpected IP version: 0x%x", id);
return -EINVAL;
}
for_each_child_of_node(np, child) {
ret = of_property_read_string(child, "compatible", &compat);
if (ret)
continue;
/* Count child nodes with stm32 adc compatible */
if (strstr(compat, "st,stm32") && strstr(compat, "adc"))
count++;
}
val = readl_relaxed(priv->common.base + STM32MP1_ADC_HWCFGR0);
priv->nb_adc_max = FIELD_GET(STM32MP1_ADCNUM_MASK, val);
if (count > priv->nb_adc_max) {
dev_err(&pdev->dev, "Unexpected child number: %d", count);
return -EINVAL;
}
val = readl_relaxed(priv->common.base + STM32MP1_ADC_VERR);
dev_dbg(&pdev->dev, "ADC version: %lu.%lu\n",
FIELD_GET(STM32MP1_MAJREV_MASK, val),
FIELD_GET(STM32MP1_MINREV_MASK, val));
return 0;
}
static int stm32_adc_probe(struct platform_device *pdev)
{
struct stm32_adc_priv *priv;
......@@ -661,6 +709,7 @@ static int stm32_adc_probe(struct platform_device *pdev)
priv->cfg = (const struct stm32_adc_priv_cfg *)
of_match_device(dev->driver->of_match_table, dev)->data;
priv->nb_adc_max = priv->cfg->num_adcs;
spin_lock_init(&priv->common.lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
......@@ -703,6 +752,10 @@ static int stm32_adc_probe(struct platform_device *pdev)
if (ret)
goto err_pm_stop;
ret = stm32_adc_probe_identification(pdev, priv);
if (ret < 0)
goto err_hw_stop;
ret = regulator_get_voltage(priv->vref);
if (ret < 0) {
dev_err(&pdev->dev, "vref get voltage failed, %d\n", ret);
......@@ -811,8 +864,8 @@ static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = {
.clk_sel = stm32h7_adc_clk_sel,
.max_clk_rate_hz = 36000000,
.has_syscfg = HAS_VBOOSTER | HAS_ANASWVDD,
.ipid = STM32MP15_IPIDR_NUMBER,
.num_irqs = 2,
.num_adcs = 2,
};
static const struct of_device_id stm32_adc_of_match[] = {
......
......@@ -24,6 +24,7 @@
* | 0x300 | Master & Slave common regs |
* --------------------------------------------------------
*/
/* Maximum ADC instances number per ADC block for all supported SoCs */
#define STM32_ADC_MAX_ADCS 3
#define STM32_ADC_OFFSET 0x100
#define STM32_ADCX_COMN_OFFSET 0x300
......@@ -105,6 +106,12 @@
/* STM32MP1 - ADC2 instance option register */
#define STM32MP1_ADC2_OR 0xD0
/* STM32MP1 - Identification registers */
#define STM32MP1_ADC_HWCFGR0 0x3F0
#define STM32MP1_ADC_VERR 0x3F4
#define STM32MP1_ADC_IPDR 0x3F8
#define STM32MP1_ADC_SIDR 0x3FC
/* STM32H7 - common registers for all ADC instances */
#define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00)
#define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08)
......@@ -181,6 +188,30 @@ enum stm32h7_adc_dmngt {
/* STM32MP1_ADC2_OR - bit fields */
#define STM32MP1_VDDCOREEN BIT(0)
/* STM32MP1_ADC_HWCFGR0 - bit fields */
#define STM32MP1_ADCNUM_SHIFT 0
#define STM32MP1_ADCNUM_MASK GENMASK(3, 0)
#define STM32MP1_MULPIPE_SHIFT 4
#define STM32MP1_MULPIPE_MASK GENMASK(7, 4)
#define STM32MP1_OPBITS_SHIFT 8
#define STM32MP1_OPBITS_MASK GENMASK(11, 8)
#define STM32MP1_IDLEVALUE_SHIFT 12
#define STM32MP1_IDLEVALUE_MASK GENMASK(15, 12)
/* STM32MP1_ADC_VERR - bit fields */
#define STM32MP1_MINREV_SHIFT 0
#define STM32MP1_MINREV_MASK GENMASK(3, 0)
#define STM32MP1_MAJREV_SHIFT 4
#define STM32MP1_MAJREV_MASK GENMASK(7, 4)
/* STM32MP1_ADC_IPDR - bit fields */
#define STM32MP1_IPIDR_MASK GENMASK(31, 0)
/* STM32MP1_ADC_SIDR - bit fields */
#define STM32MP1_SIDR_MASK GENMASK(31, 0)
#define STM32MP15_IPIDR_NUMBER 0x00110005
/**
* struct stm32_adc_common - stm32 ADC driver common data (for all instances)
* @base: control registers base cpu addr
......
......@@ -13,6 +13,8 @@
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <asm/unaligned.h>
#define AD5593R_MODE_CONF (0 << 4)
#define AD5593R_MODE_DAC_WRITE (1 << 4)
#define AD5593R_MODE_ADC_READBACK (4 << 4)
......@@ -20,6 +22,24 @@
#define AD5593R_MODE_GPIO_READBACK (6 << 4)
#define AD5593R_MODE_REG_READBACK (7 << 4)
static int ad5593r_read_word(struct i2c_client *i2c, u8 reg, u16 *value)
{
int ret;
u8 buf[2];
ret = i2c_smbus_write_byte(i2c, reg);
if (ret < 0)
return ret;
ret = i2c_master_recv(i2c, buf, sizeof(buf));
if (ret < 0)
return ret;
*value = get_unaligned_be16(buf);
return 0;
}
static int ad5593r_write_dac(struct ad5592r_state *st, unsigned chan, u16 value)
{
struct i2c_client *i2c = to_i2c_client(st->dev);
......@@ -38,13 +58,7 @@ static int ad5593r_read_adc(struct ad5592r_state *st, unsigned chan, u16 *value)
if (val < 0)
return (int) val;
val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_ADC_READBACK);
if (val < 0)
return (int) val;
*value = (u16) val;
return 0;
return ad5593r_read_word(i2c, AD5593R_MODE_ADC_READBACK, value);
}
static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value)
......@@ -58,25 +72,19 @@ static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value)
static int ad5593r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value)
{
struct i2c_client *i2c = to_i2c_client(st->dev);
s32 val;
val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_REG_READBACK | reg);
if (val < 0)
return (int) val;
*value = (u16) val;
return 0;
return ad5593r_read_word(i2c, AD5593R_MODE_REG_READBACK | reg, value);
}
static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value)
{
struct i2c_client *i2c = to_i2c_client(st->dev);
s32 val;
u16 val;
int ret;
val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_GPIO_READBACK);
if (val < 0)
return (int) val;
ret = ad5593r_read_word(i2c, AD5593R_MODE_GPIO_READBACK, &val);
if (ret)
return ret;
*value = (u8) val;
......@@ -94,6 +102,10 @@ static const struct ad5592r_rw_ops ad5593r_rw_ops = {
static int ad5593r_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
if (!i2c_check_functionality(i2c->adapter,
I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
return -EOPNOTSUPP;
return ad5592r_probe(&i2c->dev, id->name, &ad5593r_rw_ops);
}
......
......@@ -52,6 +52,7 @@ config ADIS16480
ADIS16485, ADIS16488 inertial sensors.
source "drivers/iio/imu/bmi160/Kconfig"
source "drivers/iio/imu/bno055/Kconfig"
config FXOS8700
tristate
......
......@@ -15,6 +15,7 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
obj-y += bmi160/
obj-y += bno055/
obj-$(CONFIG_FXOS8700) += fxos8700_core.o
obj-$(CONFIG_FXOS8700_I2C) += fxos8700_i2c.o
......
# SPDX-License-Identifier: GPL-2.0
config BOSCH_BNO055
tristate
config BOSCH_BNO055_SERIAL
tristate "Bosch BNO055 attached via UART"
depends on SERIAL_DEV_BUS
select BOSCH_BNO055
help
Enable this to support Bosch BNO055 IMUs attached via UART.
This driver can also be built as a module. If so, the module will be
called bno055_sl.
config BOSCH_BNO055_I2C
tristate "Bosch BNO055 attached via I2C bus"
depends on I2C
select REGMAP_I2C
select BOSCH_BNO055
help
Enable this to support Bosch BNO055 IMUs attached via I2C bus.
This driver can also be built as a module. If so, the module will be
called bno055_i2c.
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_BOSCH_BNO055) += bno055.o
obj-$(CONFIG_BOSCH_BNO055_SERIAL) += bno055_ser.o
bno055_ser-y := bno055_ser_core.o
# define_trace.h needs to know how to find our header
CFLAGS_bno055_ser_trace.o := -I$(src)
bno055_ser-$(CONFIG_TRACING) += bno055_ser_trace.o
obj-$(CONFIG_BOSCH_BNO055_I2C) += bno055_i2c.o
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef __BNO055_H__
#define __BNO055_H__
#include <linux/regmap.h>
#include <linux/types.h>
struct device;
int bno055_probe(struct device *dev, struct regmap *regmap,
int xfer_burst_break_thr, bool sw_reset);
extern const struct regmap_config bno055_regmap_config;
#endif
// SPDX-License-Identifier: GPL-2.0
/*
* Support for I2C-interfaced Bosch BNO055 IMU.
*
* Copyright (C) 2021-2022 Istituto Italiano di Tecnologia
* Electronic Design Laboratory
* Written by Andrea Merello <andrea.merello@iit.it>
*/
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include "bno055.h"
#define BNO055_I2C_XFER_BURST_BREAK_THRESHOLD 3
static int bno055_i2c_probe(struct i2c_client *client)
{
struct regmap *regmap;
regmap = devm_regmap_init_i2c(client, &bno055_regmap_config);
if (IS_ERR(regmap))
return dev_err_probe(&client->dev, PTR_ERR(regmap),
"Unable to init register map");
return bno055_probe(&client->dev, regmap,
BNO055_I2C_XFER_BURST_BREAK_THRESHOLD, true);
}
static const struct i2c_device_id bno055_i2c_id[] = {
{"bno055", 0},
{ }
};
MODULE_DEVICE_TABLE(i2c, bno055_i2c_id);
static const struct of_device_id __maybe_unused bno055_i2c_of_match[] = {
{ .compatible = "bosch,bno055" },
{ }
};
MODULE_DEVICE_TABLE(of, bno055_i2c_of_match);
static struct i2c_driver bno055_driver = {
.driver = {
.name = "bno055-i2c",
.of_match_table = bno055_i2c_of_match,
},
.probe_new = bno055_i2c_probe,
.id_table = bno055_i2c_id,
};
module_i2c_driver(bno055_driver);
MODULE_AUTHOR("Andrea Merello");
MODULE_DESCRIPTION("Bosch BNO055 I2C interface");
MODULE_IMPORT_NS(IIO_BNO055);
MODULE_LICENSE("GPL");
This diff is collapsed.
//SPDX-License-Identifier: GPL-2.0
/*
* bno055_ser Trace Support
* Copyright (C) 2022 Istituto Italiano di Tecnologia
* Electronic Design Laboratory
*
* Based on:
* Device core Trace Support
* Copyright (C) 2021, Intel Corporation
*/
#define CREATE_TRACE_POINTS
#include "bno055_ser_trace.h"
/* SPDX-License-Identifier: GPL-2.0 */
#if !defined(__BNO055_SERDEV_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ)
#define __BNO055_SERDEV_TRACE_H__
#include <linux/tracepoint.h>
#undef TRACE_SYSTEM
#define TRACE_SYSTEM bno055_ser
TRACE_EVENT(send_chunk,
TP_PROTO(int len, const u8 *data),
TP_ARGS(len, data),
TP_STRUCT__entry(
__field(int, len)
__dynamic_array(u8, chunk, len)
),
TP_fast_assign(
__entry->len = len;
memcpy(__get_dynamic_array(chunk),
data, __entry->len);
),
TP_printk("len: %d, data: = %*ph",
__entry->len, __entry->len, __get_dynamic_array(chunk)
)
);
TRACE_EVENT(cmd_retry,
TP_PROTO(bool read, int addr, int retry),
TP_ARGS(read, addr, retry),
TP_STRUCT__entry(
__field(bool, read)
__field(int, addr)
__field(int, retry)
),
TP_fast_assign(
__entry->read = read;
__entry->addr = addr;
__entry->retry = retry;
),
TP_printk("%s addr 0x%x retry #%d",
__entry->read ? "read" : "write",
__entry->addr, __entry->retry
)
);
TRACE_EVENT(write_reg,
TP_PROTO(u8 addr, u8 value),
TP_ARGS(addr, value),
TP_STRUCT__entry(
__field(u8, addr)
__field(u8, value)
),
TP_fast_assign(
__entry->addr = addr;
__entry->value = value;
),
TP_printk("reg 0x%x = 0x%x",
__entry->addr, __entry->value
)
);
TRACE_EVENT(read_reg,
TP_PROTO(int addr, size_t len),
TP_ARGS(addr, len),
TP_STRUCT__entry(
__field(int, addr)
__field(size_t, len)
),
TP_fast_assign(
__entry->addr = addr;
__entry->len = len;
),
TP_printk("reg 0x%x (len %zu)",
__entry->addr, __entry->len
)
);
TRACE_EVENT(recv,
TP_PROTO(size_t len, const unsigned char *buf),
TP_ARGS(len, buf),
TP_STRUCT__entry(
__field(size_t, len)
__dynamic_array(unsigned char, buf, len)
),
TP_fast_assign(
__entry->len = len;
memcpy(__get_dynamic_array(buf),
buf, __entry->len);
),
TP_printk("len: %zu, data: = %*ph",
__entry->len, (int)__entry->len, __get_dynamic_array(buf)
)
);
#endif /* __BNO055_SERDEV_TRACE_H__ || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE bno055_ser_trace
/* This part must be outside protection */
#include <trace/define_trace.h>
......@@ -12,7 +12,7 @@ config IIO_ST_LSM6DSX
Say yes here to build support for STMicroelectronics LSM6DSx imu
sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm,
ism330dlc, lsm6dso, lsm6dsox, asm330lhh, asm330lhhx, lsm6dsr,
lsm6ds3tr-c, ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop,
lsm6ds3tr-c, ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, lsm6dstx,
the accelerometer/gyroscope of lsm9ds1 and lsm6dst.
To compile this driver as a module, choose M here: the module
......
......@@ -32,6 +32,7 @@
#define ST_LSM6DST_DEV_NAME "lsm6dst"
#define ST_LSM6DSOP_DEV_NAME "lsm6dsop"
#define ST_ASM330LHHX_DEV_NAME "asm330lhhx"
#define ST_LSM6DSTX_DEV_NAME "lsm6dstx"
enum st_lsm6dsx_hw_id {
ST_LSM6DS3_ID,
......@@ -51,6 +52,7 @@ enum st_lsm6dsx_hw_id {
ST_LSM6DST_ID,
ST_LSM6DSOP_ID,
ST_ASM330LHHX_ID,
ST_LSM6DSTX_ID,
ST_LSM6DSX_MAX_ID,
};
......
......@@ -15,7 +15,7 @@
* value of the decimation factor and ODR set for each FIFO data set.
*
* LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/LSM6DSRX/ISM330DHCX/
* LSM6DST/LSM6DSOP:
* LSM6DST/LSM6DSOP/LSM6DSTX:
* The FIFO buffer can be configured to store data from gyroscope and
* accelerometer. Each sample is queued with a tag (1B) indicating data
* source (gyroscope, accelerometer, hw timer).
......
......@@ -26,7 +26,8 @@
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
* - FIFO size: 4KB
*
* - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP:
* - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/
* LSM6DSTX:
* - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416,
* 833
* - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
......@@ -791,6 +792,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.hw_id = ST_ASM330LHHX_ID,
.name = ST_ASM330LHHX_DEV_NAME,
.wai = 0x6b,
}, {
.hw_id = ST_LSM6DSTX_ID,
.name = ST_LSM6DSTX_DEV_NAME,
.wai = 0x6d,
},
},
.channels = {
......
......@@ -105,6 +105,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
.compatible = "st,asm330lhhx",
.data = (void *)ST_ASM330LHHX_ID,
},
{
.compatible = "st,lsm6dstx",
.data = (void *)ST_LSM6DSTX_ID,
},
{},
};
MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
......@@ -127,6 +131,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
{ ST_LSM6DST_DEV_NAME, ST_LSM6DST_ID },
{ ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID },
{ ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID },
{ ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID },
{},
};
MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
......
......@@ -105,6 +105,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
.compatible = "st,asm330lhhx",
.data = (void *)ST_ASM330LHHX_ID,
},
{
.compatible = "st,lsm6dstx",
.data = (void *)ST_LSM6DSTX_ID,
},
{},
};
MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
......@@ -127,6 +131,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
{ ST_LSM6DST_DEV_NAME, ST_LSM6DST_ID },
{ ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID },
{ ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID },
{ ST_LSM6DSTX_DEV_NAME, ST_LSM6DSTX_ID },
{},
};
MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
......
......@@ -134,6 +134,12 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_ETHANOL] = "ethanol",
[IIO_MOD_H2] = "h2",
[IIO_MOD_O2] = "o2",
[IIO_MOD_LINEAR_X] = "linear_x",
[IIO_MOD_LINEAR_Y] = "linear_y",
[IIO_MOD_LINEAR_Z] = "linear_z",
[IIO_MOD_PITCH] = "pitch",
[IIO_MOD_YAW] = "yaw",
[IIO_MOD_ROLL] = "roll",
};
/* relies on pairs of these shared then separate */
......@@ -1570,7 +1576,7 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
ret = -ENOMEM;
goto error_clear_attrs;
}
/* Copy across original attributes */
/* Copy across original attributes, and point to original binary attributes */
if (indio_dev->info->attrs) {
memcpy(iio_dev_opaque->chan_attr_group.attrs,
indio_dev->info->attrs->attrs,
......@@ -1578,6 +1584,8 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
*attrcount_orig);
iio_dev_opaque->chan_attr_group.is_visible =
indio_dev->info->attrs->is_visible;
iio_dev_opaque->chan_attr_group.bin_attrs =
indio_dev->info->attrs->bin_attrs;
}
attrn = attrcount_orig;
/* Add all elements from the list. */
......
......@@ -325,7 +325,7 @@ int st_uvis25_probe(struct device *dev, int irq, struct regmap *regmap)
}
EXPORT_SYMBOL_NS(st_uvis25_probe, IIO_UVIS25);
static int __maybe_unused st_uvis25_suspend(struct device *dev)
static int st_uvis25_suspend(struct device *dev)
{
struct iio_dev *iio_dev = dev_get_drvdata(dev);
struct st_uvis25_hw *hw = iio_priv(iio_dev);
......@@ -334,7 +334,7 @@ static int __maybe_unused st_uvis25_suspend(struct device *dev)
ST_UVIS25_REG_ODR_MASK, 0);
}
static int __maybe_unused st_uvis25_resume(struct device *dev)
static int st_uvis25_resume(struct device *dev)
{
struct iio_dev *iio_dev = dev_get_drvdata(dev);
struct st_uvis25_hw *hw = iio_priv(iio_dev);
......@@ -346,10 +346,7 @@ static int __maybe_unused st_uvis25_resume(struct device *dev)
return 0;
}
const struct dev_pm_ops st_uvis25_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(st_uvis25_suspend, st_uvis25_resume)
};
EXPORT_SYMBOL_NS(st_uvis25_pm_ops, IIO_UVIS25);
EXPORT_NS_SIMPLE_DEV_PM_OPS(st_uvis25_pm_ops, st_uvis25_suspend, st_uvis25_resume, IIO_UVIS25);
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>");
MODULE_DESCRIPTION("STMicroelectronics uvis25 sensor driver");
......
......@@ -55,7 +55,7 @@ MODULE_DEVICE_TABLE(i2c, st_uvis25_i2c_id_table);
static struct i2c_driver st_uvis25_driver = {
.driver = {
.name = "st_uvis25_i2c",
.pm = &st_uvis25_pm_ops,
.pm = pm_sleep_ptr(&st_uvis25_pm_ops),
.of_match_table = st_uvis25_i2c_of_match,
},
.probe = st_uvis25_i2c_probe,
......
......@@ -55,7 +55,7 @@ MODULE_DEVICE_TABLE(spi, st_uvis25_spi_id_table);
static struct spi_driver st_uvis25_driver = {
.driver = {
.name = "st_uvis25_spi",
.pm = &st_uvis25_pm_ops,
.pm = pm_sleep_ptr(&st_uvis25_pm_ops),
.of_match_table = st_uvis25_spi_of_match,
},
.probe = st_uvis25_spi_probe,
......
......@@ -17,14 +17,14 @@ config ABP060MG
will be called abp060mg.
config BMP280
tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver"
tristate "Bosch Sensortec BMP180/BMP280/BMP380 pressure sensor I2C driver"
depends on (I2C || SPI_MASTER)
select REGMAP
select BMP280_I2C if (I2C)
select BMP280_SPI if (SPI_MASTER)
help
Say yes here to build support for Bosch Sensortec BMP180 and BMP280
pressure and temperature sensors. Also supports the BME280 with
Say yes here to build support for Bosch Sensortec BMP180, BMP280 and
BMP380 pressure and temperature sensors. Also supports the BME280 with
an additional humidity sensor channel.
To compile this driver as a module, choose M here: the core module
......
This diff is collapsed.
......@@ -19,6 +19,9 @@ static int bmp280_i2c_probe(struct i2c_client *client,
case BME280_CHIP_ID:
regmap_config = &bmp280_regmap_config;
break;
case BMP380_CHIP_ID:
regmap_config = &bmp380_regmap_config;
break;
default:
return -EINVAL;
}
......@@ -37,19 +40,21 @@ static int bmp280_i2c_probe(struct i2c_client *client,
}
static const struct of_device_id bmp280_of_i2c_match[] = {
{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
{ .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID },
{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
{ .compatible = "bosch,bmp380", .data = (void *)BMP380_CHIP_ID },
{ },
};
MODULE_DEVICE_TABLE(of, bmp280_of_i2c_match);
static const struct i2c_device_id bmp280_i2c_id[] = {
{"bmp280", BMP280_CHIP_ID },
{"bmp180", BMP180_CHIP_ID },
{"bmp085", BMP180_CHIP_ID },
{"bmp180", BMP180_CHIP_ID },
{"bmp280", BMP280_CHIP_ID },
{"bme280", BME280_CHIP_ID },
{"bmp380", BMP380_CHIP_ID },
{ },
};
MODULE_DEVICE_TABLE(i2c, bmp280_i2c_id);
......
......@@ -72,6 +72,49 @@ static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg)
}
}
static bool bmp380_is_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case BMP380_REG_CMD:
case BMP380_REG_CONFIG:
case BMP380_REG_FIFO_CONFIG_1:
case BMP380_REG_FIFO_CONFIG_2:
case BMP380_REG_FIFO_WATERMARK_LSB:
case BMP380_REG_FIFO_WATERMARK_MSB:
case BMP380_REG_POWER_CONTROL:
case BMP380_REG_INT_CONTROL:
case BMP380_REG_IF_CONFIG:
case BMP380_REG_ODR:
case BMP380_REG_OSR:
return true;
default:
return false;
}
}
static bool bmp380_is_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case BMP380_REG_TEMP_XLSB:
case BMP380_REG_TEMP_LSB:
case BMP380_REG_TEMP_MSB:
case BMP380_REG_PRESS_XLSB:
case BMP380_REG_PRESS_LSB:
case BMP380_REG_PRESS_MSB:
case BMP380_REG_SENSOR_TIME_XLSB:
case BMP380_REG_SENSOR_TIME_LSB:
case BMP380_REG_SENSOR_TIME_MSB:
case BMP380_REG_INT_STATUS:
case BMP380_REG_FIFO_DATA:
case BMP380_REG_STATUS:
case BMP380_REG_ERROR:
case BMP380_REG_EVENT:
return true;
default:
return false;
}
}
const struct regmap_config bmp280_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
......@@ -83,3 +126,15 @@ const struct regmap_config bmp280_regmap_config = {
.volatile_reg = bmp280_is_volatile_reg,
};
EXPORT_SYMBOL_NS(bmp280_regmap_config, IIO_BMP280);
const struct regmap_config bmp380_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = BMP380_REG_CMD,
.cache_type = REGCACHE_RBTREE,
.writeable_reg = bmp380_is_writeable_reg,
.volatile_reg = bmp380_is_volatile_reg,
};
EXPORT_SYMBOL_NS(bmp380_regmap_config, IIO_BMP280);
......@@ -66,6 +66,9 @@ static int bmp280_spi_probe(struct spi_device *spi)
case BME280_CHIP_ID:
regmap_config = &bmp280_regmap_config;
break;
case BMP380_CHIP_ID:
regmap_config = &bmp380_regmap_config;
break;
default:
return -EINVAL;
}
......@@ -92,6 +95,7 @@ static const struct of_device_id bmp280_of_spi_match[] = {
{ .compatible = "bosch,bmp181", },
{ .compatible = "bosch,bmp280", },
{ .compatible = "bosch,bme280", },
{ .compatible = "bosch,bmp380", },
{ },
};
MODULE_DEVICE_TABLE(of, bmp280_of_spi_match);
......@@ -101,6 +105,7 @@ static const struct spi_device_id bmp280_spi_id[] = {
{ "bmp181", BMP180_CHIP_ID },
{ "bmp280", BMP280_CHIP_ID },
{ "bme280", BME280_CHIP_ID },
{ "bmp380", BMP380_CHIP_ID },
{ }
};
MODULE_DEVICE_TABLE(spi, bmp280_spi_id);
......
......@@ -3,6 +3,87 @@
#include <linux/device.h>
#include <linux/regmap.h>
/* BMP380 specific registers */
#define BMP380_REG_CMD 0x7E
#define BMP380_REG_CONFIG 0x1F
#define BMP380_REG_ODR 0x1D
#define BMP380_REG_OSR 0x1C
#define BMP380_REG_POWER_CONTROL 0x1B
#define BMP380_REG_IF_CONFIG 0x1A
#define BMP380_REG_INT_CONTROL 0x19
#define BMP380_REG_INT_STATUS 0x11
#define BMP380_REG_EVENT 0x10
#define BMP380_REG_STATUS 0x03
#define BMP380_REG_ERROR 0x02
#define BMP380_REG_ID 0x00
#define BMP380_REG_FIFO_CONFIG_1 0x18
#define BMP380_REG_FIFO_CONFIG_2 0x17
#define BMP380_REG_FIFO_WATERMARK_MSB 0x16
#define BMP380_REG_FIFO_WATERMARK_LSB 0x15
#define BMP380_REG_FIFO_DATA 0x14
#define BMP380_REG_FIFO_LENGTH_MSB 0x13
#define BMP380_REG_FIFO_LENGTH_LSB 0x12
#define BMP380_REG_SENSOR_TIME_MSB 0x0E
#define BMP380_REG_SENSOR_TIME_LSB 0x0D
#define BMP380_REG_SENSOR_TIME_XLSB 0x0C
#define BMP380_REG_TEMP_MSB 0x09
#define BMP380_REG_TEMP_LSB 0x08
#define BMP380_REG_TEMP_XLSB 0x07
#define BMP380_REG_PRESS_MSB 0x06
#define BMP380_REG_PRESS_LSB 0x05
#define BMP380_REG_PRESS_XLSB 0x04
#define BMP380_REG_CALIB_TEMP_START 0x31
#define BMP380_CALIB_REG_COUNT 21
#define BMP380_FILTER_MASK GENMASK(3, 1)
#define BMP380_FILTER_OFF 0
#define BMP380_FILTER_1X 1
#define BMP380_FILTER_3X 2
#define BMP380_FILTER_7X 3
#define BMP380_FILTER_15X 4
#define BMP380_FILTER_31X 5
#define BMP380_FILTER_63X 6
#define BMP380_FILTER_127X 7
#define BMP380_OSRS_TEMP_MASK GENMASK(5, 3)
#define BMP380_OSRS_PRESS_MASK GENMASK(2, 0)
#define BMP380_ODRS_MASK GENMASK(4, 0)
#define BMP380_CTRL_SENSORS_MASK GENMASK(1, 0)
#define BMP380_CTRL_SENSORS_PRESS_EN BIT(0)
#define BMP380_CTRL_SENSORS_TEMP_EN BIT(1)
#define BMP380_MODE_MASK GENMASK(5, 4)
#define BMP380_MODE_SLEEP 0
#define BMP380_MODE_FORCED 1
#define BMP380_MODE_NORMAL 3
#define BMP380_MIN_TEMP -4000
#define BMP380_MAX_TEMP 8500
#define BMP380_MIN_PRES 3000000
#define BMP380_MAX_PRES 12500000
#define BMP380_CMD_NOOP 0x00
#define BMP380_CMD_EXTMODE_EN_MID 0x34
#define BMP380_CMD_FIFO_FLUSH 0xB0
#define BMP380_CMD_SOFT_RESET 0xB6
#define BMP380_STATUS_CMD_RDY_MASK BIT(4)
#define BMP380_STATUS_DRDY_PRESS_MASK BIT(5)
#define BMP380_STATUS_DRDY_TEMP_MASK BIT(6)
#define BMP380_ERR_FATAL_MASK BIT(0)
#define BMP380_ERR_CMD_MASK BIT(1)
#define BMP380_ERR_CONF_MASK BIT(2)
#define BMP380_TEMP_SKIPPED 0x800000
#define BMP380_PRESS_SKIPPED 0x800000
/* BMP280 specific registers */
#define BMP280_REG_HUMIDITY_LSB 0xFE
#define BMP280_REG_HUMIDITY_MSB 0xFD
......@@ -13,6 +94,9 @@
#define BMP280_REG_PRESS_LSB 0xF8
#define BMP280_REG_PRESS_MSB 0xF7
/* Helper mask to truncate excess 4 bits on pressure and temp readings */
#define BMP280_MEAS_TRIM_MASK GENMASK(24, 4)
#define BMP280_REG_CONFIG 0xF5
#define BMP280_REG_CTRL_MEAS 0xF4
#define BMP280_REG_STATUS 0xF3
......@@ -32,44 +116,46 @@
#define BMP280_REG_COMP_PRESS_START 0x8E
#define BMP280_COMP_PRESS_REG_COUNT 18
#define BMP280_FILTER_MASK (BIT(4) | BIT(3) | BIT(2))
#define BMP280_COMP_H5_MASK GENMASK(15, 4)
#define BMP280_CONTIGUOUS_CALIB_REGS (BMP280_COMP_TEMP_REG_COUNT + \
BMP280_COMP_PRESS_REG_COUNT)
#define BMP280_FILTER_MASK GENMASK(4, 2)
#define BMP280_FILTER_OFF 0
#define BMP280_FILTER_2X BIT(2)
#define BMP280_FILTER_4X BIT(3)
#define BMP280_FILTER_8X (BIT(3) | BIT(2))
#define BMP280_FILTER_16X BIT(4)
#define BMP280_FILTER_2X 1
#define BMP280_FILTER_4X 2
#define BMP280_FILTER_8X 3
#define BMP280_FILTER_16X 4
#define BMP280_OSRS_HUMIDITY_MASK (BIT(2) | BIT(1) | BIT(0))
#define BMP280_OSRS_HUMIDITIY_X(osrs_h) ((osrs_h) << 0)
#define BMP280_OSRS_HUMIDITY_MASK GENMASK(2, 0)
#define BMP280_OSRS_HUMIDITY_SKIP 0
#define BMP280_OSRS_HUMIDITY_1X BMP280_OSRS_HUMIDITIY_X(1)
#define BMP280_OSRS_HUMIDITY_2X BMP280_OSRS_HUMIDITIY_X(2)
#define BMP280_OSRS_HUMIDITY_4X BMP280_OSRS_HUMIDITIY_X(3)
#define BMP280_OSRS_HUMIDITY_8X BMP280_OSRS_HUMIDITIY_X(4)
#define BMP280_OSRS_HUMIDITY_16X BMP280_OSRS_HUMIDITIY_X(5)
#define BMP280_OSRS_HUMIDITY_1X 1
#define BMP280_OSRS_HUMIDITY_2X 2
#define BMP280_OSRS_HUMIDITY_4X 3
#define BMP280_OSRS_HUMIDITY_8X 4
#define BMP280_OSRS_HUMIDITY_16X 5
#define BMP280_OSRS_TEMP_MASK (BIT(7) | BIT(6) | BIT(5))
#define BMP280_OSRS_TEMP_MASK GENMASK(7, 5)
#define BMP280_OSRS_TEMP_SKIP 0
#define BMP280_OSRS_TEMP_X(osrs_t) ((osrs_t) << 5)
#define BMP280_OSRS_TEMP_1X BMP280_OSRS_TEMP_X(1)
#define BMP280_OSRS_TEMP_2X BMP280_OSRS_TEMP_X(2)
#define BMP280_OSRS_TEMP_4X BMP280_OSRS_TEMP_X(3)
#define BMP280_OSRS_TEMP_8X BMP280_OSRS_TEMP_X(4)
#define BMP280_OSRS_TEMP_16X BMP280_OSRS_TEMP_X(5)
#define BMP280_OSRS_PRESS_MASK (BIT(4) | BIT(3) | BIT(2))
#define BMP280_OSRS_TEMP_1X 1
#define BMP280_OSRS_TEMP_2X 2
#define BMP280_OSRS_TEMP_4X 3
#define BMP280_OSRS_TEMP_8X 4
#define BMP280_OSRS_TEMP_16X 5
#define BMP280_OSRS_PRESS_MASK GENMASK(4, 2)
#define BMP280_OSRS_PRESS_SKIP 0
#define BMP280_OSRS_PRESS_X(osrs_p) ((osrs_p) << 2)
#define BMP280_OSRS_PRESS_1X BMP280_OSRS_PRESS_X(1)
#define BMP280_OSRS_PRESS_2X BMP280_OSRS_PRESS_X(2)
#define BMP280_OSRS_PRESS_4X BMP280_OSRS_PRESS_X(3)
#define BMP280_OSRS_PRESS_8X BMP280_OSRS_PRESS_X(4)
#define BMP280_OSRS_PRESS_16X BMP280_OSRS_PRESS_X(5)
#define BMP280_MODE_MASK (BIT(1) | BIT(0))
#define BMP280_OSRS_PRESS_1X 1
#define BMP280_OSRS_PRESS_2X 2
#define BMP280_OSRS_PRESS_4X 3
#define BMP280_OSRS_PRESS_8X 4
#define BMP280_OSRS_PRESS_16X 5
#define BMP280_MODE_MASK GENMASK(1, 0)
#define BMP280_MODE_SLEEP 0
#define BMP280_MODE_FORCED BIT(0)
#define BMP280_MODE_NORMAL (BIT(1) | BIT(0))
#define BMP280_MODE_FORCED 1
#define BMP280_MODE_NORMAL 3
/* BMP180 specific registers */
#define BMP180_REG_OUT_XLSB 0xF8
......@@ -79,19 +165,22 @@
#define BMP180_REG_CALIB_START 0xAA
#define BMP180_REG_CALIB_COUNT 22
#define BMP180_MEAS_CTRL_MASK GENMASK(4, 0)
#define BMP180_MEAS_TEMP 0x0E
#define BMP180_MEAS_PRESS 0x14
#define BMP180_MEAS_SCO BIT(5)
#define BMP180_MEAS_TEMP (0x0E | BMP180_MEAS_SCO)
#define BMP180_MEAS_PRESS_X(oss) ((oss) << 6 | 0x14 | BMP180_MEAS_SCO)
#define BMP180_MEAS_PRESS_1X BMP180_MEAS_PRESS_X(0)
#define BMP180_MEAS_PRESS_2X BMP180_MEAS_PRESS_X(1)
#define BMP180_MEAS_PRESS_4X BMP180_MEAS_PRESS_X(2)
#define BMP180_MEAS_PRESS_8X BMP180_MEAS_PRESS_X(3)
#define BMP180_OSRS_PRESS_MASK GENMASK(7, 6)
#define BMP180_MEAS_PRESS_1X 0
#define BMP180_MEAS_PRESS_2X 1
#define BMP180_MEAS_PRESS_4X 2
#define BMP180_MEAS_PRESS_8X 3
/* BMP180 and BMP280 common registers */
#define BMP280_REG_CTRL_MEAS 0xF4
#define BMP280_REG_RESET 0xE0
#define BMP280_REG_ID 0xD0
#define BMP380_CHIP_ID 0x50
#define BMP180_CHIP_ID 0x55
#define BMP280_CHIP_ID 0x58
#define BME280_CHIP_ID 0x60
......@@ -105,6 +194,7 @@
/* Regmap configurations */
extern const struct regmap_config bmp180_regmap_config;
extern const struct regmap_config bmp280_regmap_config;
extern const struct regmap_config bmp380_regmap_config;
/* Probe called from different transports */
int bmp280_common_probe(struct device *dev,
......
This diff is collapsed.
......@@ -22,6 +22,7 @@ enum st_press_type {
LPS33HW,
LPS35HW,
LPS22HH,
LPS22DF,
ST_PRESS_MAX,
};
......@@ -32,6 +33,7 @@ enum st_press_type {
#define LPS33HW_PRESS_DEV_NAME "lps33hw"
#define LPS35HW_PRESS_DEV_NAME "lps35hw"
#define LPS22HH_PRESS_DEV_NAME "lps22hh"
#define LPS22DF_PRESS_DEV_NAME "lps22df"
/**
* struct st_sensors_platform_data - default press platform data
......
......@@ -552,6 +552,76 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
.multi_read_bit = false,
.bootime = 2,
},
{
/*
* CUSTOM VALUES FOR LPS22DF SENSOR
* See LPS22DF datasheet:
* http://www.st.com/resource/en/datasheet/lps22df.pdf
*/
.wai = 0xb4,
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = {
[0] = LPS22DF_PRESS_DEV_NAME,
},
.ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
.num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
.odr = {
.addr = 0x10,
.mask = 0x78,
.odr_avl = {
{ .hz = 1, .value = 0x01 },
{ .hz = 4, .value = 0x02 },
{ .hz = 10, .value = 0x03 },
{ .hz = 25, .value = 0x04 },
{ .hz = 50, .value = 0x05 },
{ .hz = 75, .value = 0x06 },
{ .hz = 100, .value = 0x07 },
{ .hz = 200, .value = 0x08 },
},
},
.pw = {
.addr = 0x10,
.mask = 0x78,
.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
},
.fs = {
.fs_avl = {
/*
* Pressure and temperature sensitivity values
* as defined in table 2 of LPS22DF datasheet.
*/
[0] = {
.num = ST_PRESS_FS_AVL_1260MB,
.gain = ST_PRESS_KPASCAL_NANO_SCALE,
.gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
},
},
},
.bdu = {
.addr = 0x11,
.mask = BIT(3),
},
.drdy_irq = {
.int1 = {
.addr = 0x13,
.mask = BIT(5),
.addr_od = 0x12,
.mask_od = BIT(1),
},
.addr_ihl = 0x12,
.mask_ihl = BIT(3),
.stat_drdy = {
.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
.mask = 0x03,
},
},
.sim = {
.addr = 0x0E,
.value = BIT(5),
},
.multi_read_bit = false,
.bootime = 2,
},
};
static int st_press_write_raw(struct iio_dev *indio_dev,
......
......@@ -47,6 +47,10 @@ static const struct of_device_id st_press_of_match[] = {
.compatible = "st,lps22hh",
.data = LPS22HH_PRESS_DEV_NAME,
},
{
.compatible = "st,lps22df",
.data = LPS22DF_PRESS_DEV_NAME,
},
{},
};
MODULE_DEVICE_TABLE(of, st_press_of_match);
......@@ -67,6 +71,7 @@ static const struct i2c_device_id st_press_id_table[] = {
{ LPS33HW_PRESS_DEV_NAME, LPS33HW },
{ LPS35HW_PRESS_DEV_NAME, LPS35HW },
{ LPS22HH_PRESS_DEV_NAME, LPS22HH },
{ LPS22DF_PRESS_DEV_NAME, LPS22DF },
{},
};
MODULE_DEVICE_TABLE(i2c, st_press_id_table);
......
......@@ -51,6 +51,10 @@ static const struct of_device_id st_press_of_match[] = {
.compatible = "st,lps22hh",
.data = LPS22HH_PRESS_DEV_NAME,
},
{
.compatible = "st,lps22df",
.data = LPS22DF_PRESS_DEV_NAME,
},
{},
};
MODULE_DEVICE_TABLE(of, st_press_of_match);
......@@ -97,6 +101,7 @@ static const struct spi_device_id st_press_id_table[] = {
{ LPS33HW_PRESS_DEV_NAME },
{ LPS35HW_PRESS_DEV_NAME },
{ LPS22HH_PRESS_DEV_NAME },
{ LPS22DF_PRESS_DEV_NAME },
{ "lps001wp-press" },
{ "lps25h-press", },
{ "lps331ap-press" },
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -95,6 +95,12 @@ enum iio_modifier {
IIO_MOD_ETHANOL,
IIO_MOD_H2,
IIO_MOD_O2,
IIO_MOD_LINEAR_X,
IIO_MOD_LINEAR_Y,
IIO_MOD_LINEAR_Z,
IIO_MOD_PITCH,
IIO_MOD_YAW,
IIO_MOD_ROLL,
};
enum iio_event_type {
......@@ -118,4 +124,3 @@ enum iio_event_direction {
};
#endif /* _UAPI_IIO_TYPES_H_ */
......@@ -125,6 +125,12 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_PM4] = "pm4",
[IIO_MOD_PM10] = "pm10",
[IIO_MOD_O2] = "o2",
[IIO_MOD_LINEAR_X] = "linear_x",
[IIO_MOD_LINEAR_Y] = "linear_y",
[IIO_MOD_LINEAR_Z] = "linear_z",
[IIO_MOD_PITCH] = "pitch",
[IIO_MOD_YAW] = "yaw",
[IIO_MOD_ROLL] = "roll",
};
static bool event_is_known(struct iio_event_data *event)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment