Skip to contentSkip to conversation

Add support for Bosch BNO055 IMU

PATCH Superseded Andrea Merello 5 participants 32 messages Apr 15, 2022 – Apr 28, 2022

Subsystems (3)

v4 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v4 cover Add support for Bosch BNO055 IMU

From: Andrea Merello <[email protected]>

This series (tries to) add support for Bosch BNO055 IMU to Linux IIO subsystem. It is made up several patches:

1/13 to 7/12: add some IIO modifiers, and their documentation, to the IIO
core layer, in order to being able to expose the linear acceleration and Euler angles among standard attributes. Also update the IIO event monitor tool

7/13: fix binary attributes didn't work with IIO

8/13 to 11/13: add the core IIO BNO055 driver and documentation for sysfs
attributes and DT bindings

12/13: adds serdev BNO055 driver to actually use the IMU via serial line

13/13: adds I2C BNO055 driver to actually use the IMU via I2C wiring

14/13: add a documentation file that describe the bno055 driver and
specifically the calibration

Differences wrt v3:

- use binary attribute for calibration data
- introduce trace events (instead of dev_dbg()) for bno055 serial driver
- changed serial driver name bno055_sl -> bno055_ser
- fix quaternion unit
- make the driver return error, instead of reading zeroes, when trying to access fusion data, but fusion is disabled
- make serial driver code more readable and use more kernel helpers when possible
- address issues found by 0day
- fix accel range unit in doc
- fix debugfs directory was not ever removed
- add of_device_id table in I2C driver
- use probe_new() instead of probe in I2C driver
- some other trivial improvements and fixes

Differences wrt other BNO055 drivers:

Previously at least another driver for the very same chip has been posted to the Linux ML [0], but it has been never merged, and it seems no one cared of it since quite a long time.

This driver differs from the above driver on the following aspects:

- This driver supports also serial access (to be reliable, reset pin is required to be wired)

- The above driver tried to support all IMU HW modes by allowing to choose one in the DT, and adapting IIO attributes accordingly. This driver does not rely on DT for this, instead settings are done via sysfs attributes. All IIO attributes are always exposed; more on this later on. This driver however supports only a subset of the HW-supported modes.

- This driver has some support for managing the IMU calibration

Supported operation modes:

- AMG (accelerometer, magnetometer and gyroscope) mode, which provides raw (uncalibrated) measurements from the said sensors, and allows for setting some parameters about them (e.g. filter cut-off frequency, max sensor ranges, etc).

- Fusion mode, which still provides AMG measures, while it also provides other data calculated by the IMU (e.g. rotation angles, linear acceleration, etc). In this mode user has no freedom to set any sensor parameter, since the HW locks them. Autocalibration and correction is performed by the IMU.

IIO attributes exposing sensors parameters are always present, but in fusion modes the available values are constrained to just the one used by the HW. This is reflected in the '*_available' IIO attributes.

Trying to set a not-supported value always falls back to the closest supported one, which in this case is just the one in use by the HW.

IIO attributes for unavailable measurements (e.g. Euler angles in AMG mode) can't be read (return -EBUSY, or refuse to enable buffer).

IMU calibration:

The IMU supports for two sets of calibration parameters:

- SIC matrix. user-provided; this driver doesn't currently support it

- Offset and radius parameters. The IMU automatically finds out them when it is running in fusion mode; supported by this driver.

The driver provides access to autocalibration flags (i.e. you can known if the IMU has successfully autocalibrated) and to 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 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 changes on each device).

In AMG 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 and read as zero.

Access protocols and serdev module:

The serial protocol is quite simple, but there are tricks to make it really works. Those tricks and workarounds are documented in the driver source file.

The core BNO055 driver tries to group readings in burst when appropriate, in order to optimize triggered buffer operation. The threshold for splitting a burst (i.e. max number of unused bytes in the middle of a burst that will be throw away) is provided to the core driver by the lowlevel access driver (either serdev or I2C) at probe time.

[0] https://www.spinics.net/lists/linux-iio/msg25508.html

Andrea Merello (14):
iio: add modifiers for linear acceleration
iio: document linear acceleration modifiers
iio: event_monitor: add linear acceleration modifiers
iio: add modifers for pitch, yaw, roll
iio: document pitch, yaw, roll modifiers
iio: event_monitor: add pitch, yaw and roll modifiers
iio: add support for binary attributes
iio: imu: add Bosch Sensortec BNO055 core driver
iio: document bno055 private sysfs attributes
iio: document "serial_number" sysfs attribute
dt-bindings: iio: imu: add documentation for Bosch BNO055 bindings
iio: imu: add BNO055 serdev driver
iio: imu: add BNO055 I2C driver
docs: iio: add documentation for BNO055 driver

 Documentation/ABI/testing/sysfs-bus-iio       |   25 +
 .../ABI/testing/sysfs-bus-iio-bno055          |   81 +
 .../bindings/iio/imu/bosch,bno055.yaml        |   59 +
 Documentation/iio/bno055.rst                  |   50 +
 Documentation/iio/index.rst                   |    2 +
 drivers/iio/imu/Kconfig                       |    1 +
 drivers/iio/imu/Makefile                      |    1 +
 drivers/iio/imu/bno055/Kconfig                |   31 +
 drivers/iio/imu/bno055/Makefile               |    7 +
 drivers/iio/imu/bno055/bno055.c               | 1715 +++++++++++++++++
 drivers/iio/imu/bno055/bno055.h               |   12 +
 drivers/iio/imu/bno055/bno055_i2c.c           |   56 +
 drivers/iio/imu/bno055/bno055_ser.c           |  556 ++++++
 drivers/iio/imu/bno055/bno055_ser_trace.h     |  114 ++
 drivers/iio/industrialio-core.c               |   10 +-
 include/uapi/linux/iio/types.h                |    7 +-
 tools/iio/iio_event_monitor.c                 |    6 +
 17 files changed, 2731 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-bno055
 create mode 100644 Documentation/devicetree/bindings/iio/imu/bosch,bno055.yaml
 create mode 100644 Documentation/iio/bno055.rst
 create mode 100644 drivers/iio/imu/bno055/Kconfig
 create mode 100644 drivers/iio/imu/bno055/Makefile
 create mode 100644 drivers/iio/imu/bno055/bno055.c
 create mode 100644 drivers/iio/imu/bno055/bno055.h
 create mode 100644 drivers/iio/imu/bno055/bno055_i2c.c
 create mode 100644 drivers/iio/imu/bno055/bno055_ser.c
 create mode 100644 drivers/iio/imu/bno055/bno055_ser_trace.h

--
2.17.1

#1 lore raw

PATCH v4 1/14 iio: add modifiers for linear acceleration

From: Andrea Merello <[email protected]>

This patch is preparatory for adding the Bosh BNO055 IMU driver. The said IMU can report raw accelerations (among x, y and z axis) as well as the so called "linear accelerations" (again, among x, y and z axis) which is basically the acceleration after subtracting gravity.

This patch adds IIO_MOD_LINEAR_X, IIO_MOD_LINEAR_Y and IIO_MOD_LINEAR_Z modifiers to te IIO core.

---
 drivers/iio/industrialio-core.c | 3 +++
 include/uapi/linux/iio/types.h  | 4 +++-
 2 files changed, 6 insertions(+), 1 deletion(-)
drivers/iio/industrialio-core.c +3 -0
index 2f48e9a97274..d087b2607cc9 100644
@@ -134,6 +134,9 @@ 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",
 };
 
 /* relies on pairs of these shared then separate */
include/uapi/linux/iio/types.h +3 -1
index 472cead10d8d..0993f6b697fc 100644
@@ -95,6 +95,9 @@ enum iio_modifier {
 	IIO_MOD_ETHANOL,
 	IIO_MOD_H2,
 	IIO_MOD_O2,
+	IIO_MOD_LINEAR_X,
+	IIO_MOD_LINEAR_Y,
+	IIO_MOD_LINEAR_Z,
 };
 
 enum iio_event_type {
@@ -115,4 +118,3 @@ enum iio_event_direction {
 };
 
 #endif /* _UAPI_IIO_TYPES_H_ */
-
Signature · 1 line
2.17.1
#2 lore raw

PATCH v4 2/14 iio: document linear acceleration modifiers

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

This patch introduces ABI documentation for new iio modifiers used for reporting "linear acceleration" measures.

---
 Documentation/ABI/testing/sysfs-bus-iio | 9 +++++++++
 1 file changed, 9 insertions(+)
Documentation/ABI/testing/sysfs-bus-iio +9 -0
index d4ccc68fdcf0..aadddd43bf22 100644
@@ -233,6 +233,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:	5.19
+Contact:	[email protected]
+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
Signature · 1 line
2.17.1
#3 lore raw

PATCH v4 3/14 iio: event_monitor: add linear acceleration modifiers

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

---
 tools/iio/iio_event_monitor.c | 3 +++
 1 file changed, 3 insertions(+)
tools/iio/iio_event_monitor.c +3 -0
index 2f4581658859..1fee44abb836 100644
@@ -122,6 +122,9 @@ 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",
 };
 
 static bool event_is_known(struct iio_event_data *event)
Signature · 1 line
2.17.1
#5 lore raw

PATCH v4 4/14 iio: add modifers for pitch, yaw, roll

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

This patch adds modifiers for reporting rotations as euler angles (i.e. yaw, pitch and roll).

---
 drivers/iio/industrialio-core.c | 3 +++
 include/uapi/linux/iio/types.h  | 3 +++
 2 files changed, 6 insertions(+)
drivers/iio/industrialio-core.c +3 -0
index d087b2607cc9..aa5f98d3b334 100644
@@ -137,6 +137,9 @@ static const char * const iio_modifier_names[] = {
 	[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 */
include/uapi/linux/iio/types.h +3 -0
index 0993f6b697fc..4853701ba70d 100644
@@ -98,6 +98,9 @@ enum iio_modifier {
 	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 {
Signature · 1 line
2.17.1
#6 lore raw

Re: [v4 04/14] iio: add modifers for pitch, yaw, roll

Quoted 5 lines · Andrea Merello

From: Andrea Merello <[email protected]>

This patch adds modifiers for reporting rotations as euler angles (i.e. yaw, pitch and roll).

s/This patch adds/Add/

Please, read the Submitting Patches documentation where it explicitly tells.

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#7 lore raw

PATCH v4 5/14 iio: document pitch, yaw, roll modifiers

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

This patch introduces ABI documentation for new modifiers used for reporting rotations expressed as euler angles (i.e. yaw, pitch, roll).

It looks like we have some unit inconsistency along various IIO modifiers:
it seems that incli is in deg, angl is in radians and rot isn't documented, but at least the adis16209 driver has rot in deg.

Here we use deg (so angl is the only one using radians).

---
 Documentation/ABI/testing/sysfs-bus-iio | 9 +++++++++
 1 file changed, 9 insertions(+)
Documentation/ABI/testing/sysfs-bus-iio +9 -0
index aadddd43bf22..2a6954ea1c71 100644
@@ -2039,3 +2039,12 @@ Description:
 		Available range for the forced calibration value, expressed as:
 
 		- a range specified as "[min step max]"
+
+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:	5.19
+Contact:	[email protected]
+Description:
+		Raw (unscaled) euler angles readings. Units after
+		application of scale are deg.
Signature · 1 line
2.17.1
#8 lore raw

PATCH v4 6/14 iio: event_monitor: add pitch, yaw and roll modifiers

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

---
 tools/iio/iio_event_monitor.c | 3 +++
 1 file changed, 3 insertions(+)
tools/iio/iio_event_monitor.c +3 -0
index 1fee44abb836..ee3f78c47655 100644
@@ -125,6 +125,9 @@ static const char * const iio_modifier_names[] = {
 	[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)
Signature · 1 line
2.17.1
#9 lore raw

PATCH v4 7/14 iio: add support for binary attributes

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

When a IIO device is registered, the IIO core creates an attribute group on its own, where it puts the channel attributes, and where it copies the attributes in indio_dev->info->attrs.

Unfortunately it doesn't take care of binary attributes (i.e. it only consider indio_dev->info->attrs->attrs, and it ignores indio_dev->info->attrs->bin_attrs).

This patch fixes this.

Note that while it is necessary to copy the non-binary attributes because the IIO layer needs more room to add the channels attribute, it should be enough to assign the bin_attrs pointer to the binary attributes pointed by indio_dev->info->attrs->bin_attrs.

---
 drivers/iio/industrialio-core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/iio/industrialio-core.c +3 -1
index aa5f98d3b334..aef30f0b9465 100644
@@ -1567,7 +1567,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,
@@ -1575,6 +1575,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. */
Signature · 1 line
2.17.1
#10 lore raw

PATCH v4 8/14 iio: imu: add Bosch Sensortec BNO055 core driver

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

This patch adds a core driver for the BNO055 IMU from Bosch. This IMU can be connected via both serial and I2C busses; separate patches will add support for them.

The driver supports "AMG" (Accelerometer, Magnetometer, Gyroscope) mode, that provides raw data from the said internal sensors, and a couple of "fusion" modes (i.e. the IMU also do calculations in order to provide euler angles, quaternions, linear acceleration and gravity measurements).

In fusion modes the AMG data is still available (with some calibration refinements done by the IMU), but certain settings such as low pass filters cut-off frequency and sensors ranges are fixed, while in AMG mode they can be customized; this is why AMG mode can still be interesting.

---
 drivers/iio/imu/Kconfig         |    1 +
 drivers/iio/imu/Makefile        |    1 +
 drivers/iio/imu/bno055/Kconfig  |    4 +
 drivers/iio/imu/bno055/Makefile |    3 +
 drivers/iio/imu/bno055/bno055.c | 1715 +++++++++++++++++++++++++++++++
 drivers/iio/imu/bno055/bno055.h |   12 +
 6 files changed, 1736 insertions(+)
 create mode 100644 drivers/iio/imu/bno055/Kconfig
 create mode 100644 drivers/iio/imu/bno055/Makefile
 create mode 100644 drivers/iio/imu/bno055/bno055.c
 create mode 100644 drivers/iio/imu/bno055/bno055.h
drivers/iio/imu/Kconfig +1 -0
index 001ca2c3ff95..f1d7d4b5e222 100644
@@ -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
drivers/iio/imu/Makefile +1 -0
index c82748096c77..6eb612034722 100644
@@ -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
drivers/iio/imu/bno055/Kconfig new file +4 -0
new file mode 100644
index 000000000000..d0ab3221fba5
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config BOSCH_BNO055_IIO
+	tristate
drivers/iio/imu/bno055/Makefile new file +3 -0
new file mode 100644
index 000000000000..56cc4de60a7e
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_BOSCH_BNO055_IIO) += bno055.o
drivers/iio/imu/bno055/bno055.c new file +1715 -0

1,715 lines not on this page · raw message

drivers/iio/imu/bno055/bno055.h new file +12 -0
new file mode 100644
index 000000000000..2ccb373c61cd
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef __BNO055_H__
+#define __BNO055_H__
+
+#include <linux/regmap.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
Signature · 1 line
2.17.1
maintainer
#11 lore raw

Re: [v4 08/14] iio: imu: add Bosch Sensortec BNO055 core driver

Quoted 11 lines · On Fri, 15 Apr 2022 14:59:59 +0200 Andrea Merello <[email protected]>…

From: Andrea Merello <[email protected]>

This patch adds a core driver for the BNO055 IMU from Bosch. This IMU can be connected via both serial and I2C busses; separate patches will add support for them.

The driver supports "AMG" (Accelerometer, Magnetometer, Gyroscope) mode, that provides raw data from the said internal sensors, and a couple of "fusion" modes (i.e. the IMU also do calculations in order to provide euler angles, quaternions, linear acceleration and gravity measurements).

Quoted 6 lines

In fusion modes the AMG data is still available (with some calibration refinements done by the IMU), but certain settings such as low pass filters cut-off frequency and sensors ranges are fixed, while in AMG mode they can be customized; this is why AMG mode can still be interesting.

Hi Andrea,

A few trivial things from me on this read through.

I haven't commented on a lot of the patches because I was happy with them.

Other than the small changes requested from me, we mostly need to get device tree review of the binding and allow time for others to take another look.

Thanks,

Jonathan

Quoted 1 line

---

...

Quoted 6 lines
drivers/iio/imu/bno055/bno055.c new file +6 -0
+
+static int bno055_read_simple_chan(struct iio_dev *indio_dev,
+				   struct iio_chan_spec const *chan,
+				   int *val, int *val2, long mask)
+{
+	struct bno055_priv *priv = iio_priv(indio_dev);

drivers/iio/imu/bno055/bno055.c line 663

Quoted 10 lines
drivers/iio/imu/bno055/bno055.c new file +10 -0
+	__le16 raw_val;
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = regmap_bulk_read(priv->regmap, chan->address,
+				       &raw_val, sizeof(raw_val));
+		if (ret < 0)
+			return ret;
+		*val = (s16)le16_to_cpu(raw_val);

Hmm. I'd ever so slightly prefer

sign_extend32(le16_to_cpu(raw_val), 15) as it makes it extremely clear what is going on and hopefully the compiler can do a good job of optimising it either way. If you strongly prefer the current approach I'll cope :)

Quoted 18 lines
drivers/iio/imu/bno055/bno055.c new file +18 -0
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_OFFSET:
+		if (priv->operation_mode != BNO055_OPR_MODE_AMG) {
+			*val = 0;
+		} else {
+			ret = regmap_bulk_read(priv->regmap,
+					       chan->address +
+					       BNO055_REG_OFFSET_ADDR,
+					       &raw_val, sizeof(raw_val));
+			if (ret < 0)
+				return ret;
+			/*
+			 * IMU reports sensor offests; IIO wants correction
+			 * offset, thus we need the 'minus' here.
+			 */
+			*val = -(s16)le16_to_cpu(raw_val);
+		}
+		return IIO_VAL_INT;

...

Quoted 1 line

+}

...

Quoted 19 lines
drivers/iio/imu/bno055/bno055.c new file +19 -0
+
+static int bno055_read_quaternion(struct iio_dev *indio_dev,
+				  struct iio_chan_spec const *chan,
+				  int size, int *vals, int *val_len,
+				  long mask)
+{
+	struct bno055_priv *priv = iio_priv(indio_dev);
+	__le16 raw_vals[4];
+	int i, ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		if (size < 4)
+			return -EINVAL;
+		ret = regmap_bulk_read(priv->regmap,
+				       BNO055_QUAT_DATA_W_LSB_REG,
+				       raw_vals, sizeof(raw_vals));
+		if (ret < 0)
+			return ret;

drivers/iio/imu/bno055/bno055.c line 864

Quoted 10 lines
drivers/iio/imu/bno055/bno055.c new file +10 -0
+		for (i = 0; i < 4; i++)
+			vals[i] = (s16)le16_to_cpu(raw_vals[i]);
+		*val_len = 4;
+		return IIO_VAL_INT_MULTIPLE;
+	case IIO_CHAN_INFO_SCALE:
+		/* Table 3-31: 1 quaternion = 2^14 LSB */
+		if (size < 2)
+			return -EINVAL;
+		vals[0] = 14;
+		vals[1] = 1 << 14;

This looks odd. As you are using FRACTIONAL_LOG2, I think that should just be
vals[0] = 1;
vals[1] = 14;

Quoted 6 lines
drivers/iio/imu/bno055/bno055.c new file +6 -0
+		return IIO_VAL_FRACTIONAL_LOG2;
+	default:
+		return -EINVAL;
+	}
+}
+

...

drivers/iio/imu/bno055/bno055.c line 1558

Quoted 5 lines
drivers/iio/imu/bno055/bno055.c new file +5 -0
+
+static void bno055_clk_disable(void *arg)
+{
+	clk_disable_unprepare((struct clk *)arg);
+}

Hopefully one day: https://lore.kernel.org/all/CAHp75VdH4vGr57v6tfkRuxh-3agRKO8C08+DH8dsB1HnPfnz5Q@mail.gmail.com/
will get merged... Until then, this is the best we can do.

drivers/iio/imu/bno055/bno055.c line 1563

Quoted 5 lines
drivers/iio/imu/bno055/bno055.c new file +5 -0
+
+int bno055_probe(struct device *dev, struct regmap *regmap,
+		 int xfer_burst_break_thr, bool sw_reset)
+{
+	const struct firmware *caldata;

See comment below. I think you need to set this to NULL here

drivers/iio/imu/bno055/bno055.c line 1614

Quoted 6 lines
drivers/iio/imu/bno055/bno055.c new file +6 -0
+
+	ret = regmap_read(priv->regmap, BNO055_CHIP_ID_REG, &val);
+	if (ret)
+		return ret;
+
+	if (val != BNO055_CHIP_ID_MAGIC) {

We've run into this a few times recently. Traditionally IIO has been very restrictive on allowing drivers to probe if the Who Am I type values don't match. That causes problems for backwards compatibility in device tree - e.g. (with made up compatible part number 055b :) compatible = "bosch,bno055b", "bosch,bno055"

The viewpoint of the dt maintainers is that we should assume the dt is correct and at most warn about missmatched IDs before trying to carry on. So to avoid hitting that again please relax this to a warning and cross your fingers after this point if it doesn't match. I'm fine on the firmware question because we know we are dealing with buggy firmware. Ideally we'll get some working firmware additions at somepoint then we can just label the bad firmwares and assume one less bug in the ones that don't match :)

Quoted 17 lines
drivers/iio/imu/bno055/bno055.c new file +17 -0
+		dev_err(dev, "Unrecognized chip ID 0x%x", val);
+		return -ENODEV;
+	}
+
+	/*
+	 * In case we haven't a HW reset pin, we can still reset the chip via
+	 * register write. This is probably nonsense in case we can't even
+	 * communicate with the chip or the chip isn't the one we expect (i.e.
+	 * we don't write to unknown chips), so we perform SW reset only after
+	 * chip magic ID check
+	 */
+	if (!priv->reset_gpio) {
+		ret = bno055_system_reset(priv);
+		if (ret)
+			return ret;
+	}
+

...

drivers/iio/imu/bno055/bno055.c line 1656

Quoted 8 lines
drivers/iio/imu/bno055/bno055.c new file +8 -0
+	ret = regmap_bulk_read(priv->regmap, BNO055_UID_LOWER_REG,
+			       priv->uid, BNO055_UID_LEN);
+	if (ret)
+		return ret;
+
+	/*
+	 * This has nothing to do with the IMU firmware, this is for sensor
+	 * calibration data.

I'd not say what it isn't. What it is will be enough.

	/* Sensor calibration data */
Quoted 4 lines
drivers/iio/imu/bno055/bno055.c new file +4 -0
+	 */
+	fw_name_buf = kasprintf(GFP_KERNEL,
+				BNO055_FW_UID_NAME,
+				BNO055_UID_LEN, priv->uid);

drivers/iio/imu/bno055/bno055.c line 1670

Quoted 10 lines
drivers/iio/imu/bno055/bno055.c new file +10 -0
+	if (!fw_name_buf)
+		return -ENOMEM;
+
+	ret = request_firmware(&caldata, fw_name_buf, dev);
+	kfree(fw_name_buf);
+	if (ret)
+		ret = request_firmware(&caldata, BNO055_FW_GENERIC_NAME, dev);
+
+	if (ret)
+		dev_notice(dev, "Calibration file load failed. See instruction in kernel Documentation/iio/bno055.rst");

If no calibration files are found, is caldata guaranteed to have been set to NULL? I'm not seeing that in the documentation, so even if it is true today it might not be in future and I think that leaves you referencing a variable that may not
have been set. Probably just set caldata_data = NULL where you define
the local variable at top of this function.

Quoted 11 lines
drivers/iio/imu/bno055/bno055.c new file +11 -0
+
+	if (caldata) {
+		caldata_data = caldata->data;
+		caldata_size = caldata->size;
+	}
+	ret = bno055_init(priv, caldata_data, caldata_size);
+	if (caldata)
+		release_firmware(caldata);
+	if (ret)
+		return ret;
+
#12 lore raw

Re: [v4 08/14] iio: imu: add Bosch Sensortec BNO055 core driver

Il giorno ven 15 apr 2022 alle ore 19:35 Jonathan Cameron <[email protected]> ha scritto:

Quoted 27 lines
Quoted 11 lines · On Fri, 15 Apr 2022 14:59:59 +0200 Andrea Merello <[email protected]>…

From: Andrea Merello <[email protected]>

This patch adds a core driver for the BNO055 IMU from Bosch. This IMU can be connected via both serial and I2C busses; separate patches will add support for them.

The driver supports "AMG" (Accelerometer, Magnetometer, Gyroscope) mode, that provides raw data from the said internal sensors, and a couple of "fusion" modes (i.e. the IMU also do calculations in order to provide euler angles, quaternions, linear acceleration and gravity measurements).

Quoted 6 lines

In fusion modes the AMG data is still available (with some calibration refinements done by the IMU), but certain settings such as low pass filters cut-off frequency and sensors ranges are fixed, while in AMG mode they can be customized; this is why AMG mode can still be interesting.

Hi Andrea,

A few trivial things from me on this read through.

I haven't commented on a lot of the patches because I was happy with them.

Quoted 7 lines

Other than the small changes requested from me, we mostly need to get device tree review of the binding and allow time for others to take another look.

Thanks,

Jonathan

Ok, good! As usual, just a few inline comments, ok for the rest.

Quoted 5 lines

drivers/iio/imu/bno055/bno055.c line 1563

Quoted 4 lines
drivers/iio/imu/bno055/bno055.c new file +4 -0
+int bno055_probe(struct device *dev, struct regmap *regmap,
+              int xfer_burst_break_thr, bool sw_reset)
+{
+     const struct firmware *caldata;

See comment below. I think you need to set this to NULL here

Hum. I'm confused here: I think I did set it to NULL (is some later LOC) in V2, but you argued against it, because hopefully request_firmware() does it by itself.
https://www.spinics.net/lists/linux-iio/msg64896.html

What has changed or what I've missed? Was your original point just to move the NULL assignment back at declaration time?

Quoted 14 lines

drivers/iio/imu/bno055/bno055.c line 1614

Quoted 7 lines
drivers/iio/imu/bno055/bno055.c new file +6 -0
+
+     ret = regmap_read(priv->regmap, BNO055_CHIP_ID_REG, &val);
+     if (ret)
+             return ret;
+
+     if (val != BNO055_CHIP_ID_MAGIC) {

We've run into this a few times recently. Traditionally IIO has been very restrictive on allowing drivers to probe if the Who Am I type values don't match. That causes problems for backwards compatibility in device tree - e.g. (with made up compatible part number 055b :) compatible = "bosch,bno055b", "bosch,bno055"

Quoted 8 lines

The viewpoint of the dt maintainers is that we should assume the dt is correct and at most warn about missmatched IDs before trying to carry on. So to avoid hitting that again please relax this to a warning and cross your fingers after this point if it doesn't match. I'm fine on the firmware question because we know we are dealing with buggy firmware. Ideally we'll get some working firmware additions at somepoint then we can just label the bad firmwares and assume one less bug in the ones that don't match :)

To be honest my point wasn't about the correctness of the DT at all..

I've hit this several times when I was switching my test board from serial to i2c and vice-versa, because I made wrong connections or I forgot to switch FPGA image (which contains the serial IP here). I got my test script failing because the IIO device didn't pop up at all, which is better than getting e.g. random data. In the real world people may have less chance to have to worry about this, but they may when e.g. they have an RPi and a hand-wired IMU.

.. IOW I'm seeing this as a hardware self-test rather than a SW check.. But if the DT thing makes this a no-go, then I can live with the warning, and e.g. by making my script to check the kernel log..

maintainer
#13 lore raw

Re: [v4 08/14] iio: imu: add Bosch Sensortec BNO055 core driver

Quoted 45 lines · On Tue, 19 Apr 2022 09:10:54 +0200 Andrea Merello <[email protected]>…

Il giorno ven 15 apr 2022 alle ore 19:35 Jonathan Cameron <[email protected]> ha scritto:

Quoted 27 lines
Quoted 11 lines · On Fri, 15 Apr 2022 14:59:59 +0200 Andrea Merello <[email protected]>…

From: Andrea Merello <[email protected]>

This patch adds a core driver for the BNO055 IMU from Bosch. This IMU can be connected via both serial and I2C busses; separate patches will add support for them.

The driver supports "AMG" (Accelerometer, Magnetometer, Gyroscope) mode, that provides raw data from the said internal sensors, and a couple of "fusion" modes (i.e. the IMU also do calculations in order to provide euler angles, quaternions, linear acceleration and gravity measurements).

Quoted 6 lines

In fusion modes the AMG data is still available (with some calibration refinements done by the IMU), but certain settings such as low pass filters cut-off frequency and sensors ranges are fixed, while in AMG mode they can be customized; this is why AMG mode can still be interesting.

Hi Andrea,

A few trivial things from me on this read through.

I haven't commented on a lot of the patches because I was happy with them.

Quoted 7 lines

Other than the small changes requested from me, we mostly need to get device tree review of the binding and allow time for others to take another look.

Thanks,

Jonathan

Ok, good! As usual, just a few inline comments, ok for the rest.

Quoted 5 lines

drivers/iio/imu/bno055/bno055.c line 1563

Quoted 4 lines
drivers/iio/imu/bno055/bno055.c new file +4 -0
+int bno055_probe(struct device *dev, struct regmap *regmap,
+              int xfer_burst_break_thr, bool sw_reset)
+{
+     const struct firmware *caldata;  

See comment below. I think you need to set this to NULL here

Quoted 7 lines

Hum. I'm confused here: I think I did set it to NULL (is some later LOC) in V2, but you argued against it, because hopefully request_firmware() does it by itself.
https://www.spinics.net/lists/linux-iio/msg64896.html

What has changed or what I've missed? Was your original point just to move the NULL assignment back at declaration time?

Oops. Not sure what I was smoking that day.

Moving back to declaration time is a good idea though.

Quoted 34 lines
Quoted 15 lines

drivers/iio/imu/bno055/bno055.c line 1614

Quoted 8 lines
drivers/iio/imu/bno055/bno055.c new file +6 -0
+
+     ret = regmap_read(priv->regmap, BNO055_CHIP_ID_REG, &val);
+     if (ret)
+             return ret;
+
+     if (val != BNO055_CHIP_ID_MAGIC) {  

We've run into this a few times recently. Traditionally IIO has been very restrictive on allowing drivers to probe if the Who Am I type values don't match. That causes problems for backwards compatibility in device tree - e.g. (with made up compatible part number 055b :) compatible = "bosch,bno055b", "bosch,bno055"

Quoted 8 lines

The viewpoint of the dt maintainers is that we should assume the dt is correct and at most warn about missmatched IDs before trying to carry on. So to avoid hitting that again please relax this to a warning and cross your fingers after this point if it doesn't match. I'm fine on the firmware question because we know we are dealing with buggy firmware. Ideally we'll get some working firmware additions at somepoint then we can just label the bad firmwares and assume one less bug in the ones that don't match :)

To be honest my point wasn't about the correctness of the DT at all..

I've hit this several times when I was switching my test board from serial to i2c and vice-versa, because I made wrong connections or I forgot to switch FPGA image (which contains the serial IP here). I got my test script failing because the IIO device didn't pop up at all, which is better than getting e.g. random data. In the real world people may have less chance to have to worry about this, but they may when e.g. they have an RPi and a hand-wired IMU.

Quoted 3 lines

.. IOW I'm seeing this as a hardware self-test rather than a SW check.. But if the DT thing makes this a no-go, then I can live with the warning, and e.g. by making my script to check the kernel log..

Hmm. I wonder if we can get the best of both worlds. Given there is a WHOAMI and these very rarely / never take the value of all 0's or all 1's (what you'd see with a wiring error) maybe we can sanity check against those to provide the hardware self-test element. Then accept any 'sane' value of WHOAMI, but with a warning?

Jonathan

#14 lore raw

Re: [v4 08/14] iio: imu: add Bosch Sensortec BNO055 core driver

Il giorno dom 24 apr 2022 alle ore 19:37 Jonathan Cameron <[email protected]> ha scritto:

Quoted 27 lines
Quoted 23 lines · On Tue, 19 Apr 2022 09:10:54 +0200 Andrea Merello <[email protected]>…

Il giorno ven 15 apr 2022 alle ore 19:35 Jonathan Cameron <[email protected]> ha scritto:

Quoted 21 lines
Quoted 17 lines · On Fri, 15 Apr 2022 14:59:59 +0200 Andrea Merello <[email protected]>…

From: Andrea Merello <[email protected]>

This patch adds a core driver for the BNO055 IMU from Bosch. This IMU can be connected via both serial and I2C busses; separate patches will add support for them.

The driver supports "AMG" (Accelerometer, Magnetometer, Gyroscope) mode, that provides raw data from the said internal sensors, and a couple of "fusion" modes (i.e. the IMU also do calculations in order to provide euler angles, quaternions, linear acceleration and gravity measurements).

In fusion modes the AMG data is still available (with some calibration refinements done by the IMU), but certain settings such as low pass filters cut-off frequency and sensors ranges are fixed, while in AMG mode they can be customized; this is why AMG mode can still be interesting.

[...]

Quoted 37 lines
Quoted 33 lines
Quoted 14 lines

drivers/iio/imu/bno055/bno055.c line 1614

Quoted 7 lines
drivers/iio/imu/bno055/bno055.c new file +6 -0
+
+     ret = regmap_read(priv->regmap, BNO055_CHIP_ID_REG, &val);
+     if (ret)
+             return ret;
+
+     if (val != BNO055_CHIP_ID_MAGIC) {

We've run into this a few times recently. Traditionally IIO has been very restrictive on allowing drivers to probe if the Who Am I type values don't match. That causes problems for backwards compatibility in device tree - e.g. (with made up compatible part number 055b :) compatible = "bosch,bno055b", "bosch,bno055"

Quoted 8 lines

The viewpoint of the dt maintainers is that we should assume the dt is correct and at most warn about missmatched IDs before trying to carry on. So to avoid hitting that again please relax this to a warning and cross your fingers after this point if it doesn't match. I'm fine on the firmware question because we know we are dealing with buggy firmware. Ideally we'll get some working firmware additions at somepoint then we can just label the bad firmwares and assume one less bug in the ones that don't match :)

To be honest my point wasn't about the correctness of the DT at all..

I've hit this several times when I was switching my test board from serial to i2c and vice-versa, because I made wrong connections or I forgot to switch FPGA image (which contains the serial IP here). I got my test script failing because the IIO device didn't pop up at all, which is better than getting e.g. random data. In the real world people may have less chance to have to worry about this, but they may when e.g. they have an RPi and a hand-wired IMU.

Quoted 3 lines

.. IOW I'm seeing this as a hardware self-test rather than a SW check.. But if the DT thing makes this a no-go, then I can live with the warning, and e.g. by making my script to check the kernel log..

Quoted 5 lines

Hmm. I wonder if we can get the best of both worlds. Given there is a WHOAMI and these very rarely / never take the value of all 0's or all 1's (what you'd see with a wiring error) maybe we can sanity check against those to provide the hardware self-test element. Then accept any 'sane' value of WHOAMI, but with a warning?

While trying to do this and testing it, I've realized that indeed when the BUS is broken (e.g. incorrect wiring) the probe() fails even earlier. When we are unable to communicate with the device, this is caught by the lower layer protocols (e.g. I2C sees no ACK, I suppose), so there is no need to fail here; the IIO device doesn't eventually pop up anyway.

So, I now revert my previous request to keep a check to bail out for crazy IDs here :) ; I'd say we can just relax the check to just a warning as you said before, without the need for checking for 0x00 and 0xff..

Quoted 3 lines

Jonathan

maintainer
#15 lore raw

Re: [v4 08/14] iio: imu: add Bosch Sensortec BNO055 core driver

Quoted 75 lines · On Tue, 26 Apr 2022 11:28:53 +0200 Andrea Merello <[email protected]>…

Il giorno dom 24 apr 2022 alle ore 19:37 Jonathan Cameron <[email protected]> ha scritto:

Quoted 27 lines
Quoted 23 lines · On Tue, 19 Apr 2022 09:10:54 +0200 Andrea Merello <[email protected]>…

Il giorno ven 15 apr 2022 alle ore 19:35 Jonathan Cameron <[email protected]> ha scritto:

Quoted 21 lines
Quoted 17 lines · On Fri, 15 Apr 2022 14:59:59 +0200 Andrea Merello <[email protected]>…

From: Andrea Merello <[email protected]>

This patch adds a core driver for the BNO055 IMU from Bosch. This IMU can be connected via both serial and I2C busses; separate patches will add support for them.

The driver supports "AMG" (Accelerometer, Magnetometer, Gyroscope) mode, that provides raw data from the said internal sensors, and a couple of "fusion" modes (i.e. the IMU also do calculations in order to provide euler angles, quaternions, linear acceleration and gravity measurements).

In fusion modes the AMG data is still available (with some calibration refinements done by the IMU), but certain settings such as low pass filters cut-off frequency and sensors ranges are fixed, while in AMG mode they can be customized; this is why AMG mode can still be interesting.

[...]

Quoted 37 lines
Quoted 33 lines
Quoted 14 lines

drivers/iio/imu/bno055/bno055.c line 1614

Quoted 7 lines
drivers/iio/imu/bno055/bno055.c new file +6 -0
+
+     ret = regmap_read(priv->regmap, BNO055_CHIP_ID_REG, &val);
+     if (ret)
+             return ret;
+
+     if (val != BNO055_CHIP_ID_MAGIC) {  

We've run into this a few times recently. Traditionally IIO has been very restrictive on allowing drivers to probe if the Who Am I type values don't match. That causes problems for backwards compatibility in device tree - e.g. (with made up compatible part number 055b :) compatible = "bosch,bno055b", "bosch,bno055"

Quoted 8 lines

The viewpoint of the dt maintainers is that we should assume the dt is correct and at most warn about missmatched IDs before trying to carry on. So to avoid hitting that again please relax this to a warning and cross your fingers after this point if it doesn't match. I'm fine on the firmware question because we know we are dealing with buggy firmware. Ideally we'll get some working firmware additions at somepoint then we can just label the bad firmwares and assume one less bug in the ones that don't match :)

To be honest my point wasn't about the correctness of the DT at all..

I've hit this several times when I was switching my test board from serial to i2c and vice-versa, because I made wrong connections or I forgot to switch FPGA image (which contains the serial IP here). I got my test script failing because the IIO device didn't pop up at all, which is better than getting e.g. random data. In the real world people may have less chance to have to worry about this, but they may when e.g. they have an RPi and a hand-wired IMU.

Quoted 3 lines

.. IOW I'm seeing this as a hardware self-test rather than a SW check.. But if the DT thing makes this a no-go, then I can live with the warning, and e.g. by making my script to check the kernel log..

Quoted 5 lines

Hmm. I wonder if we can get the best of both worlds. Given there is a WHOAMI and these very rarely / never take the value of all 0's or all 1's (what you'd see with a wiring error) maybe we can sanity check against those to provide the hardware self-test element. Then accept any 'sane' value of WHOAMI, but with a warning?

Quoted 6 lines

While trying to do this and testing it, I've realized that indeed when the BUS is broken (e.g. incorrect wiring) the probe() fails even earlier. When we are unable to communicate with the device, this is caught by the lower layer protocols (e.g. I2C sees no ACK, I suppose), so there is no need to fail here; the IIO device doesn't eventually pop up anyway.

Ah. Good point. I was thinking we had SPI which is the one where a lack of reply is harder to detect. For I2C we are definitely fine and I guess the serial protocol protects against this as well.

Great that indeed makes things simpler.

Jonathan

Quoted 9 lines

So, I now revert my previous request to keep a check to bail out for crazy IDs here :) ; I'd say we can just relax the check to just a warning as you said before, without the need for checking for 0x00 and 0xff..

Quoted 3 lines

Jonathan

#16 lore raw

PATCH v4 9/14 iio: document bno055 private sysfs attributes

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

This patch adds ABI documentation for bno055 driver private sysfs attributes.

---
 .../ABI/testing/sysfs-bus-iio-bno055          | 81 +++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-bno055
Documentation/ABI/testing/sysfs-bus-iio-bno055 new file +81 -0
new file mode 100644
index 000000000000..22a5c6dc90dc
@@ -0,0 +1,81 @@
+What:		/sys/bus/iio/devices/iio:deviceX/in_accel_raw_range
+KernelVersion:	5.19
+Contact:	[email protected]
+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:	5.19
+Contact:	[email protected]
+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:	5.19
+Contact:	[email protected]
+Description:
+		List of allowed values for in_accel_raw_range attribute
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_anglvel_raw_range_available
+KernelVersion:	5.19
+Contact:	[email protected]
+Description:
+		List of allowed values for in_anglvel_raw_range attribute
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_magn_calibration_fast_enable
+KernelVersion:	5.19
+Contact:	[email protected]
+Description:
+		Can be 1 or 0. Enables/disables the "Fast Magnetometer
+		Calibration" HW function.
+
+What:		/sys/bus/iio/devices/iio:deviceX/fusion_enable
+KernelVersion:	5.19
+Contact:	[email protected]
+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:	5.19
+Contact:	[email protected]
+Description:
+		Reports the binary calibration data blob for the IMU sensors.
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_accel_calibration_auto_status
+KernelVersion:	5.19
+Contact:	[email protected]
+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:	5.19
+Contact:	[email protected]
+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:	5.19
+Contact:	[email protected]
+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:	5.19
+Contact:	[email protected]
+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.
Signature · 1 line
2.17.1
#17 lore raw

PATCH v4 10/14 iio: document "serial_number" sysfs attribute

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

This patch adds ABI documentation for the new "serial_number" sysfs attribute. The first user is the bno055 IIO driver.

---
 Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
 1 file changed, 7 insertions(+)
Documentation/ABI/testing/sysfs-bus-iio +7 -0
index 2a6954ea1c71..3be613f64843 100644
@@ -2048,3 +2048,10 @@ Contact:	[email protected]
 Description:
 		Raw (unscaled) euler angles readings. Units after
 		application of scale are deg.
+
+What:		/sys/bus/iio/devices/iio:deviceX/serial_number
+KernelVersion:	5.19
+Contact:	[email protected]
+Description:
+		An example format is 16-bytes, 2-digits-per-byte, HEX-string
+		representing the sensor unique ID number.
Signature · 1 line
2.17.1
#18 lore raw

Re: [v4 10/14] iio: document "serial_number" sysfs attribute

Quoted 15 lines · Andrea Merello

From: Andrea Merello <[email protected]>

This patch adds ABI documentation for the new "serial_number" sysfs attribute. The first user is the bno055 IIO driver.

---
  Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
  1 file changed, 7 insertions(+)
Documentation/ABI/testing/sysfs-bus-iio +0 -0
index 2a6954ea1c71..3be613f64843 100644

Documentation/ABI/testing/sysfs-bus-iio Contact: [email protected] · line 2052

Quoted 5 lines
Documentation/ABI/testing/sysfs-bus-iio +2 -0
@@ -2048,3 +2048,10 @@ Contact:	[email protected]
  Description:
  		Raw (unscaled) euler angles readings. Units after
  		application of scale are deg.
+
+What:		/sys/bus/iio/devices/iio:deviceX/serial_number

Can we make this serialnumber? IIO uses underscores to separate different parts of the name and to a machine (e.g. libiio) serial_number looks like a channel called serial with an attribute called number.

Quoted 5 lines
Documentation/ABI/testing/sysfs-bus-iio +5 -0
+KernelVersion:	5.19
+Contact:	[email protected]
+Description:
+		An example format is 16-bytes, 2-digits-per-byte, HEX-string
+		representing the sensor unique ID number.
maintainer
#19 lore raw

Re: [v4 10/14] iio: document "serial_number" sysfs attribute

Quoted 11 lines · On Tue, 19 Apr 2022 09:41:54 +0200 Lars-Peter Clausen <[email protected]> wrote:
Quoted 10 lines · Andrea Merello

From: Andrea Merello <[email protected]>

This patch adds ABI documentation for the new "serial_number" sysfs attribute. The first user is the bno055 IIO driver.

---
  Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
  1 file changed, 7 insertions(+)
Quoted 14 lines

Documentation/ABI/testing/sysfs-bus-iio Contact: [email protected] · line 2052

Quoted 10 lines
Documentation/ABI/testing/sysfs-bus-iio +2 -0
index 2a6954ea1c71..3be613f64843 100644
@@ -2048,3 +2048,10 @@ Contact:	[email protected]
  Description:
  		Raw (unscaled) euler angles readings. Units after
  		application of scale are deg.
+
+What:		/sys/bus/iio/devices/iio:deviceX/serial_number  

Can we make this serialnumber? IIO uses underscores to separate different parts of the name and to a machine (e.g. libiio) serial_number looks like a channel called serial with an attribute called number.

Works for me.

J

Quoted 9 lines
Quoted 7 lines
Documentation/ABI/testing/sysfs-bus-iio +5 -0
+KernelVersion:	5.19
+Contact:	[email protected]
+Description:
+		An example format is 16-bytes, 2-digits-per-byte, HEX-string
+		representing the sensor unique ID number.  
#20 lore raw

PATCH v4 11/14 dt-bindings: iio: imu: add documentation for Bosch BNO055 bindings

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

Introduce new documentation file for the Bosch BNO055 IMU

---
 .../bindings/iio/imu/bosch,bno055.yaml        | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/imu/bosch,bno055.yaml
Documentation/devicetree/bindings/iio/imu/bosch,bno055.yaml new file +59 -0
new file mode 100644
index 000000000000..e0d06db161a9
@@ -0,0 +1,59 @@
+# 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 <[email protected]>
+
+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>;
+      };
+    };
Signature · 1 line
2.17.1
maintainer Reviewed-by on v4 11/14
#21 lore raw

Re: [v4 11/14] dt-bindings: iio: imu: add documentation for Bosch BNO055 bindings

Quoted 1 line · Andrea Merello

From: Andrea Merello <[email protected]>

For the subject:

dt-bindings: iio/imu: Add Bosch BNO055

Quoted 8 lines

Introduce new documentation file for the Bosch BNO055 IMU

---
 .../bindings/iio/imu/bosch,bno055.yaml        | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/imu/bosch,bno055.yaml

With the subject fixed:

#22 lore raw

PATCH v4 12/14 iio: imu: add BNO055 serdev driver

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

This path adds a serdev driver for communicating to a BNO055 IMU via serial bus, and it enables the BNO055 core driver to work in this scenario.

---
 drivers/iio/imu/bno055/Kconfig            |  16 +
 drivers/iio/imu/bno055/Makefile           |   3 +
 drivers/iio/imu/bno055/bno055_ser.c       | 556 ++++++++++++++++++++++
 drivers/iio/imu/bno055/bno055_ser_trace.h | 114 +++++
 4 files changed, 689 insertions(+)
 create mode 100644 drivers/iio/imu/bno055/bno055_ser.c
 create mode 100644 drivers/iio/imu/bno055/bno055_ser_trace.h
drivers/iio/imu/bno055/Kconfig +16 -0
index d0ab3221fba5..5a1a574c9770 100644
@@ -2,3 +2,19 @@
 
 config BOSCH_BNO055_IIO
 	tristate
+
+config BOSCH_BNO055_SERIAL
+	tristate "Bosch BNO055 attached via UART"
+	depends on SERIAL_DEV_BUS
+	select BOSCH_BNO055_IIO
+	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_SERDEV_TRACING
+       bool "trace events for the BNO055 serdev driver"
+       depends on EVENT_TRACING && BOSCH_BNO055_SERIAL
+       help
+         Enable this to enable trace events for the BNO055 serdev driver.
drivers/iio/imu/bno055/Makefile +3 -0
index 56cc4de60a7e..20128b1a1afc 100644
@@ -1,3 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_BOSCH_BNO055_IIO) += bno055.o
+obj-$(CONFIG_BOSCH_BNO055_SERIAL) += bno055_ser.o
+
+CFLAGS_bno055_ser.o := -I$(src)
drivers/iio/imu/bno055/bno055_ser.c new file +556 -0

556 lines not on this page · raw message

drivers/iio/imu/bno055/bno055_ser_trace.h new file +114 -0

114 lines not on this page · raw message

Signature · 1 line
2.17.1
maintainer
#23 lore raw

Re: [v4 12/14] iio: imu: add BNO055 serdev driver

Quoted 7 lines · On Fri, 15 Apr 2022 15:00:03 +0200 Andrea Merello <[email protected]>…

From: Andrea Merello <[email protected]>

This path adds a serdev driver for communicating to a BNO055 IMU via serial bus, and it enables the BNO055 core driver to work in this scenario.

Hi Andrea

A few really trivial things in here from me.

Jonathan

drivers/iio/imu/bno055/Makefile line 6

Quoted 13 lines

---

drivers/iio/imu/bno055/Makefile +3 -0
index 56cc4de60a7e..20128b1a1afc 100644
@@ -1,3 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_BOSCH_BNO055_IIO) += bno055.o
+obj-$(CONFIG_BOSCH_BNO055_SERIAL) += bno055_ser.o
+
+CFLAGS_bno055_ser.o := -I$(src)

Via a bit of grepping I can see other instances of this pattern which point out that it's to do with allowing the tracing framework to see trace.h. Perhaps a similar comment here would be good (if nothing else I doubt I'll remember why this magic is here in a few years time!)

Quoted 6 lines
drivers/iio/imu/bno055/bno055_ser.c new file +0 -0
new file mode 100644
index 000000000000..360dfb0ee20a
@@ -0,0 +1,556 @@

...

Quoted 13 lines
drivers/iio/imu/bno055/bno055_ser.c new file +13 -0
+
+struct bno055_ser_priv {
+	struct serdev_device *serdev;
+	struct completion cmd_complete;
+	enum {
+		CMD_NONE,
+		CMD_READ,
+		CMD_WRITE,
+	} expect_response;
+	int expected_data_len;
+	u8 *response_buf;
+
+	/**

drivers/iio/imu/bno055/bno055_ser.c line 142

Quoted 10 lines
drivers/iio/imu/bno055/bno055_ser.c new file +10 -0
+	 * enum cmd_status - represent the status of a command sent to the HW.
+	 * @STATUS_CRIT: The command failed: the serial communication failed.
+	 * @STATUS_OK:   The command executed successfully.
+	 * @STATUS_FAIL: The command failed: HW responded with an error.
+	 */
+	enum {
+		STATUS_CRIT = -1,
+		STATUS_OK = 0,
+		STATUS_FAIL = 1,
+	} cmd_status;

Locks need documentation to say what scope they cover. In this case I think it is most but not quite all of this structure. See comment on completion below.

Quoted 17 lines
drivers/iio/imu/bno055/bno055_ser.c new file +17 -0
+	struct mutex lock;
+
+	/* Only accessed in RX callback context. No lock needed. */
+	struct {
+		enum {
+			RX_IDLE,
+			RX_START,
+			RX_DATA,
+		} state;
+		int databuf_count;
+		int expected_len;
+		int type;
+	} rx;
+
+	/* Never accessed in behalf of RX callback context. No lock needed */
+	bool cmd_stale;
+};

...

Quoted 18 lines
drivers/iio/imu/bno055/bno055_ser.c new file +18 -0
+
+/*
+ * Handler for received data; this is called from the reicever callback whenever
+ * it got some packet from the serial bus. The status tell us whether the
+ * packet is valid (i.e. header ok && received payload len consistent wrt the
+ * header). It's now our responsability to check whether this is what we
+ * expected, of whether we got some unexpected, yet valid, packet.
+ */
+static void bno055_ser_handle_rx(struct bno055_ser_priv *priv, int status)
+{
+	mutex_lock(&priv->lock);
+	switch (priv->expect_response) {
+	case CMD_NONE:
+		dev_warn(&priv->serdev->dev, "received unexpected, yet valid, data from sensor");
+		mutex_unlock(&priv->lock);
+		return;
+
+	case CMD_READ:

drivers/iio/imu/bno055/bno055_ser.c line 351

Quoted 10 lines
drivers/iio/imu/bno055/bno055_ser.c new file +10 -0
+		priv->cmd_status = status;
+		if (status == STATUS_OK &&
+		    priv->rx.databuf_count != priv->expected_data_len) {
+			/*
+			 * If we got here, then the lower layer serial protocol
+			 * seems consistent with itself; if we got an unexpected
+			 * amount of data then signal it as a non critical error
+			 */
+			priv->cmd_status = STATUS_FAIL;
+			dev_warn(&priv->serdev->dev, "received an unexpected amount of, yet valid, data from sensor");

Wrap the line after dev,
Whilst it'll still be a very long line we can make it shorter with no loss of readability, whilst still not breaking the string (which would make it hard to grep for).

drivers/iio/imu/bno055/bno055_ser.c line 361

Quoted 10 lines
drivers/iio/imu/bno055/bno055_ser.c new file +10 -0
+		}
+		break;
+
+	case CMD_WRITE:
+		priv->cmd_status = status;
+		break;
+	}
+
+	priv->expect_response = CMD_NONE;
+	complete(&priv->cmd_complete);

I argued with myself a bit on whether the complete() should be inside the lock or not - but then concluded it doesn't really matter and moving it out is probably premature optimisation... Maybe it's worth moving it out simply so that it's clear the lock isn't needed to protect it, or am I missing something?

Quoted 46 lines
drivers/iio/imu/bno055/bno055_ser.c new file +46 -0
+	mutex_unlock(&priv->lock);
+}
+
+/*
+ * Serdev receiver FSM. This tracks the serial communication and parse the
+ * header. It pushes packets to bno055_ser_handle_rx(), eventually communicating
+ * failures (i.e. malformed packets).
+ * Ideally it doesn't know anything about upper layer (i.e. if this is the
+ * packet we were really expecting), but since we copies the payload into the
+ * receiver buffer (that is not valid when i.e. we don't expect data), we
+ * snoop a bit in the upper layer..
+ * Also, we assume to RX one pkt per time (i.e. the HW doesn't send anything
+ * unless we require to AND we don't queue more than one request per time).
+ */
+static int bno055_ser_receive_buf(struct serdev_device *serdev,
+				  const unsigned char *buf, size_t size)
+{
+	int status;
+	struct bno055_ser_priv *priv = serdev_device_get_drvdata(serdev);
+	int remaining = size;
+
+	if (size == 0)
+		return 0;
+
+	trace_recv(size, buf);
+	switch (priv->rx.state) {
+	case RX_IDLE:
+		/*
+		 * New packet.
+		 * Check for its 1st byte, that identifies the pkt type.
+		 */
+		if (buf[0] != 0xEE && buf[0] != 0xBB) {
+			dev_err(&priv->serdev->dev,
+				"Invalid packet start %x", buf[0]);
+			bno055_ser_handle_rx(priv, STATUS_CRIT);
+			break;
+		}
+		priv->rx.type = buf[0];
+		priv->rx.state = RX_START;
+		remaining--;
+		buf++;
+		priv->rx.databuf_count = 0;
+		fallthrough;
+
+	case RX_START:
+		/*

drivers/iio/imu/bno055/bno055_ser.c line 417

Quoted 10 lines
drivers/iio/imu/bno055/bno055_ser.c new file +10 -0
+		 * Packet RX in progress, we expect either 1-byte len or 1-byte
+		 * status depending by the packet type.
+		 */
+		if (remaining == 0)
+			break;
+
+		if (priv->rx.type == 0xEE) {
+			if (remaining > 1) {
+				dev_err(&priv->serdev->dev, "EE pkt. Extra data received");
+				status = STATUS_CRIT;

Trivial, but this blank line doesn't add anything so drop it.

Quoted 15 lines
drivers/iio/imu/bno055/bno055_ser.c new file +15 -0
+
+			} else {
+				status = (buf[0] == 1) ? STATUS_OK : STATUS_FAIL;
+			}
+			bno055_ser_handle_rx(priv, status);
+			priv->rx.state = RX_IDLE;
+			break;
+
+		} else {
+			/*priv->rx.type == 0xBB */
+			priv->rx.state = RX_DATA;
+			priv->rx.expected_len = buf[0];
+			remaining--;
+			buf++;
+		}

drivers/iio/imu/bno055/bno055_ser.c line 442

Quoted 10 lines
drivers/iio/imu/bno055/bno055_ser.c new file +10 -0
+		fallthrough;
+
+	case RX_DATA:
+		/* Header parsed; now receiving packet data payload */
+		if (remaining == 0)
+			break;
+
+		if (priv->rx.databuf_count + remaining > priv->rx.expected_len) {
+			/*
+			 * This is a inconsistency in serial protocol, we lost

an inconsistency

Quoted 42 lines
drivers/iio/imu/bno055/bno055_ser.c new file +42 -0
+			 * sync and we don't know how to handle further data
+			 */
+			dev_err(&priv->serdev->dev, "BB pkt. Extra data received");
+			bno055_ser_handle_rx(priv, STATUS_CRIT);
+			priv->rx.state = RX_IDLE;
+			break;
+		}
+
+		mutex_lock(&priv->lock);
+		/*
+		 * NULL e.g. when read cmd is stale or when no read cmd is
+		 * actually pending.
+		 */
+		if (priv->response_buf &&
+		    /*
+		     * Snoop on the upper layer protocol stuff to make sure not
+		     * to write to an invalid memory. Apart for this, let's the
+		     * upper layer manage any inconsistency wrt expected data
+		     * len (as long as the serial protocol is consistent wrt
+		     * itself (i.e. response header is consistent with received
+		     * response len.
+		     */
+		    (priv->rx.databuf_count + remaining <= priv->expected_data_len))
+			memcpy(priv->response_buf + priv->rx.databuf_count,
+			       buf, remaining);
+		mutex_unlock(&priv->lock);
+
+		priv->rx.databuf_count += remaining;
+
+		/*
+		 * Reached expected len advertised by the IMU for the current
+		 * packet. Pass it to the upper layer (for us it is just valid).
+		 */
+		if (priv->rx.databuf_count == priv->rx.expected_len) {
+			bno055_ser_handle_rx(priv, STATUS_OK);
+			priv->rx.state = RX_IDLE;
+		}
+		break;
+	}
+
+	return size;
+}
#24 lore raw

Re: [v4 12/14] iio: imu: add BNO055 serdev driver

Quoted 2 lines · Jonathan Cameron

On Fri, 15 Apr 2022 15:00:03 +0200
Andrea Merello <[email protected]> wrote:

...

Quoted 6 lines
Quoted 1 line

+CFLAGS_bno055_ser.o := -I$(src)

Via a bit of grepping I can see other instances of this pattern which point out that it's to do with allowing the tracing framework to see trace.h. Perhaps a similar comment here would be good (if nothing else I doubt I'll remember why this magic is here in a few years time!)

Can be done better way, see dwc3 or drivers/base/ trace point implementations.

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#25 lore raw

Re: [v4 12/14] iio: imu: add BNO055 serdev driver

Il giorno sab 16 apr 2022 alle ore 10:45 Andy Shevchenko <[email protected]> ha scritto:

Quoted 7 lines · Jonathan Cameron
Quoted 2 lines

On Fri, 15 Apr 2022 15:00:03 +0200
Andrea Merello <[email protected]> wrote:

...

Quoted 8 lines
Quoted 6 lines
Quoted 1 line

+CFLAGS_bno055_ser.o := -I$(src)

Via a bit of grepping I can see other instances of this pattern which point out that it's to do with allowing the tracing framework to see trace.h. Perhaps a similar comment here would be good (if nothing else I doubt I'll remember why this magic is here in a few years time!)

Can be done better way, see dwc3 or drivers/base/ trace point implementations.

May you elaborate, please? It appears that both dwc3 and driver/base use this same trick of tweaking the CFLAGS in the Makefile in order to fix the header file thing. What I see is different is that they both use an (almost empty) trace.c file. Is this what you are suggesting?

Quoted 4 lines

--
With Best Regards,
Andy Shevchenko

#26 lore raw

Re: [v4 12/14] iio: imu: add BNO055 serdev driver

Quoted 5 lines · Andrea Merello

Il giorno sab 16 apr 2022 alle ore 10:45 Andy Shevchenko <[email protected]> ha scritto:

Quoted 3 lines · Jonathan Cameron
Quoted 2 lines

On Fri, 15 Apr 2022 15:00:03 +0200
Andrea Merello <[email protected]> wrote:

...

Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Quoted 1 line

+CFLAGS_bno055_ser.o := -I$(src)

Via a bit of grepping I can see other instances of this pattern which point out that it's to do with allowing the tracing framework to see trace.h. Perhaps a similar comment here would be good (if nothing else I doubt I'll remember why this magic is here in a few years time!)

Quoted 6 lines
Quoted 1 line

Can be done better way, see dwc3 or drivers/base/ trace point implementations.

May you elaborate, please? It appears that both dwc3 and driver/base use this same trick of tweaking the CFLAGS in the Makefile in order to fix the header file thing. What I see is different is that they both use an (almost empty) trace.c file. Is this what you are suggesting?

There are two differences in your code:
1) no separate c module, which...
2) is built depending on CONFIG_TRACE.

Hence, no need to have a separate ugly config option.

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#27 lore raw

Re: [v4 12/14] iio: imu: add BNO055 serdev driver

In reply to Jonathan Cameron

Il giorno ven 15 apr 2022 alle ore 18:40 Jonathan Cameron <[email protected]> ha scritto:

Quoted 6 lines
Quoted 2 lines · On Fri, 15 Apr 2022 15:00:03 +0200 Andrea Merello <[email protected]>…

From: Andrea Merello <[email protected]>

Quoted 8 lines
Quoted 5 lines

This path adds a serdev driver for communicating to a BNO055 IMU via serial bus, and it enables the BNO055 core driver to work in this scenario.

Hi Andrea

A few really trivial things in here from me.

Few inline comments below; OK for all indeed.

Quoted 17 lines
Quoted 17 lines
drivers/iio/imu/bno055/bno055_ser.c new file +17 -0
+struct bno055_ser_priv {
+     struct serdev_device *serdev;
+     struct completion cmd_complete;
+     enum {
+             CMD_NONE,
+             CMD_READ,
+             CMD_WRITE,
+     } expect_response;
+     int expected_data_len;
+     u8 *response_buf;
+
+     /**
+      * enum cmd_status - represent the status of a command sent to the HW.
+      * @STATUS_CRIT: The command failed: the serial communication failed.
+      * @STATUS_OK:   The command executed successfully.
+      * @STATUS_FAIL: The command failed: HW responded with an error.
+      */
Quoted 8 lines

drivers/iio/imu/bno055/bno055_ser.c line 142

Quoted 5 lines
drivers/iio/imu/bno055/bno055_ser.c new file +5 -0
+     enum {
+             STATUS_CRIT = -1,
+             STATUS_OK = 0,
+             STATUS_FAIL = 1,
+     } cmd_status;

Locks need documentation to say what scope they cover. In this case I think it is most but not quite all of this structure.

I admit my comments here are awkward: I've put a couple of comment that indicate what doesn't need the lock.. I'll change to do the reverse (comment on what need the lock)

Quoted 20 lines

See comment on completion below.

Quoted 17 lines
drivers/iio/imu/bno055/bno055_ser.c new file +17 -0
+     struct mutex lock;
+
+     /* Only accessed in RX callback context. No lock needed. */
+     struct {
+             enum {
+                     RX_IDLE,
+                     RX_START,
+                     RX_DATA,
+             } state;
+             int databuf_count;
+             int expected_len;
+             int type;
+     } rx;
+
+     /* Never accessed in behalf of RX callback context. No lock needed */
+     bool cmd_stale;
+};

[...]

Quoted 7 lines
Quoted 7 lines
drivers/iio/imu/bno055/bno055_ser.c new file +7 -0
+             }
+             break;
+
+     case CMD_WRITE:
+             priv->cmd_status = status;
+             break;
+     }
Quoted 8 lines

drivers/iio/imu/bno055/bno055_ser.c line 361

Quoted 3 lines
drivers/iio/imu/bno055/bno055_ser.c new file +3 -0
+
+     priv->expect_response = CMD_NONE;
+     complete(&priv->cmd_complete);

I argued with myself a bit on whether the complete() should be inside the lock or not - but then concluded it doesn't really matter and moving it out is probably premature optimisation... Maybe it's worth moving it out simply so that it's clear the lock isn't needed to protect it, or am I missing something?

It should make no real difference to move the complete() out of the lock.

I think I put it inside the lock because of the (paranoid, and hopefully not really required - would mean we have been too strict with completion timeout) reinit_completion(). On serdev rx handler side (i.e. bno055_ser_handle_rx()) we clear expect_response and complete(), on the other side (bno055_ser_send_cmd()) we set expect_response and clear spurious completed state, before issuing the command and waiting for outcome. This looks symmetric, but those two shouldn't really race in practice.

Quoted 4 lines
Quoted 4 lines
drivers/iio/imu/bno055/bno055_ser.c new file +4 -0
+     mutex_unlock(&priv->lock);
+}
+
+/*
#28 lore raw

PATCH v4 13/14 iio: imu: add BNO055 I2C driver

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

This path adds an I2C driver for communicating to a BNO055 IMU via I2C bus and it enables the BNO055 core driver to work in this scenario.

---
 drivers/iio/imu/bno055/Kconfig      | 11 ++++++
 drivers/iio/imu/bno055/Makefile     |  1 +
 drivers/iio/imu/bno055/bno055_i2c.c | 56 +++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)
 create mode 100644 drivers/iio/imu/bno055/bno055_i2c.c
drivers/iio/imu/bno055/Kconfig +11 -0
index 5a1a574c9770..38b461646c02 100644
@@ -18,3 +18,14 @@ config BOSCH_BNO055_SERDEV_TRACING
        depends on EVENT_TRACING && BOSCH_BNO055_SERIAL
        help
          Enable this to enable trace events for the BNO055 serdev driver.
+
+config BOSCH_BNO055_I2C
+	tristate "Bosch BNO055 attached via I2C bus"
+	depends on I2C
+	select REGMAP_I2C
+	select BOSCH_BNO055_IIO
+	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.
drivers/iio/imu/bno055/Makefile +1 -0
index 20128b1a1afc..20f911aad94b 100644
@@ -2,5 +2,6 @@
 
 obj-$(CONFIG_BOSCH_BNO055_IIO) += bno055.o
 obj-$(CONFIG_BOSCH_BNO055_SERIAL) += bno055_ser.o
+obj-$(CONFIG_BOSCH_BNO055_I2C) += bno055_i2c.o
 
 CFLAGS_bno055_ser.o := -I$(src)
drivers/iio/imu/bno055/bno055_i2c.c new file +56 -0

56 lines not on this page · raw message

Signature · 1 line
2.17.1
maintainer
#29 lore raw

Re: [v4 13/14] iio: imu: add BNO055 I2C driver

Quoted 6 lines · On Fri, 15 Apr 2022 15:00:04 +0200 Andrea Merello <[email protected]>…

From: Andrea Merello <[email protected]>

This path adds an I2C driver for communicating to a BNO055 IMU via I2C bus and it enables the BNO055 core driver to work in this scenario.

One trivial comment inline.

...

Quoted 18 lines
drivers/iio/imu/bno055/Makefile +1 -0
index 20128b1a1afc..20f911aad94b 100644
@@ -2,5 +2,6 @@
 
 obj-$(CONFIG_BOSCH_BNO055_IIO) += bno055.o
 obj-$(CONFIG_BOSCH_BNO055_SERIAL) += bno055_ser.o
+obj-$(CONFIG_BOSCH_BNO055_I2C) += bno055_i2c.o
 
 CFLAGS_bno055_ser.o := -I$(src)
drivers/iio/imu/bno055/bno055_i2c.c new file +1 -0
new file mode 100644
index 000000000000..d59bb4e661be
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0

drivers/iio/imu/bno055/bno055_i2c.c line 11

Quoted 10 lines
drivers/iio/imu/bno055/bno055_i2c.c new file +10 -0
+/*
+ * Support for I2C-interfaced Bosch BNO055 IMU.
+ *
+ * Copyright (C) 2021-2022 Istituto Italiano di Tecnologia
+ * Electronic Design Laboratory
+ * Written by Andrea Merello <[email protected]>
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>

Please add an include of
mod_devicetable.h for the struct of_device_id etc definitions

Quoted 45 lines
drivers/iio/imu/bno055/bno055_i2c.c new file +45 -0
+#include <linux/regmap.h>
+
+#include "bno055.h"
+
+#define BNO055_I2C_XFER_BURST_BREAK_THRESHOLD 3 /* FIXME */
+
+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 = of_match_ptr(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");
#30 lore raw

PATCH v4 14/14 docs: iio: add documentation for BNO055 driver

In reply to Andrea Merello

From: Andrea Merello <[email protected]>

The bno055 driver is rather complex and have some oddities and not-obvious things that worth to document (e.g. calibration files)

---
 Documentation/iio/bno055.rst | 50 ++++++++++++++++++++++++++++++++++++
 Documentation/iio/index.rst  |  2 ++
 2 files changed, 52 insertions(+)
 create mode 100644 Documentation/iio/bno055.rst
Documentation/iio/bno055.rst new file +50 -0
new file mode 100644
index 000000000000..af21376d7a25
@@ -0,0 +1,50 @@
+.. 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.
Documentation/iio/index.rst +2 -0
index 58b7a4ebac51..1b7292c58cd0 100644
@@ -10,3 +10,5 @@ Industrial I/O
    iio_configfs
 
    ep93xx_adc
+
+   bno055
Signature · 1 line
2.17.1
#31 lore raw
In reply to Andrea Merello
Quoted 16 lines · Andrea Merello

From: Andrea Merello <[email protected]>

This series (tries to) add support for Bosch BNO055 IMU to Linux IIO subsystem. It is made up several patches:

1/13 to 7/12: add some IIO modifiers, and their documentation, to the IIO
core layer, in order to being able to expose the linear acceleration and Euler angles among standard attributes. Also update the IIO event monitor tool

7/13: fix binary attributes didn't work with IIO

8/13 to 11/13: add the core IIO BNO055 driver and documentation for sysfs
attributes and DT bindings

Quoted 6 lines

12/13: adds serdev BNO055 driver to actually use the IMU via serial line

13/13: adds I2C BNO055 driver to actually use the IMU via I2C wiring

14/13: add a documentation file that describe the bno055 driver and
specifically the calibration

Thanks for a new version.
So far I have noticed the issues with more than one patch:
1) missed commit message;
2) non-imperative mode of speaking in the commit messages.

Please, take your time to refresh the Submitting Patches documentation and fix your series accordingly.

Signature · 2 lines
With Best Regards,
Andy Shevchenko