Skip to contentSkip to conversation

iio: Support ROHM/Kionix kx022a

RFC PATCH Superseded Matti Vaittinen 7 participants 39 messages Oct 6, 2022 – Oct 24, 2022

Subsystems (4)

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore

Matti Vaittinen

author maintainer
#0 lore raw

v2 cover iio: Support ROHM/Kionix kx022a

Add initial support for ROHM/Kionix kx022a accelerometer

This series is not ready for being merged as such. The first two patches in the series (the new regulator devm interfaces) are already merged to Mark's tree but have not yet found their way to the mainline. This is the reason I marked series as RFC. You can also skip the reviewing of first two patches as they are there just to make the series compile on top of the v6.0-rc7. I will re-spin the series without the patches 0001 and 0002 and drop the RFC tag when the v6.1-rc1 is out.

About the HW:
KX022A accelerometer is a sensor which:
- supports G-ranges of (+/-) 2, 4, 8, and 16G
- can be connected to I2C or SPI
- has internal HW FIFO buffer
- supports various ODRs (output data rates)
- support detecting special events like double tap or motion
- can be configured to wake-up system when events are detected.

About the series:

This series adds support for only getting the accelerometer data and configuring the G-range / ODR via IIO. Motion detection or double-tap detection are not supported by the series. The other quite important but still missing piece is the runtime PM. Nevertheless, the driver should be usable and brings the basic support for getting accelerometer data.

Changelog v2: (More detailed log in individual patches)
- dt-bindings: fixed as suggested by Krzysztof
- dt-bindings: support both INT1 and INT2
- KX022A: multiple fixes as suggested by Jonathan
- fixed SPI driver after some testing

---

Matti Vaittinen (5):
regulator: Add devm helpers for get and enable
regulator: Add devm helpers for get and enable
dt-bindings: iio: Add KX022A accelerometer
iio: accel: Support Kionix/ROHM KX022A accelerometer
MAINTAINERS: Add KX022A maintainer entry

 .../bindings/iio/accel/kionix,kx022a.yaml     |   67 +
 MAINTAINERS                                   |    5 +
 drivers/iio/accel/Kconfig                     |   21 +
 drivers/iio/accel/Makefile                    |    3 +
 drivers/iio/accel/kionix-kx022a-i2c.c         |   53 +
 drivers/iio/accel/kionix-kx022a-spi.c         |   59 +
 drivers/iio/accel/kionix-kx022a.c             | 1138 +++++++++++++++++
 drivers/iio/accel/kionix-kx022a.h             |   81 ++
 drivers/regulator/devres.c                    |  164 +++
 include/linux/regulator/consumer.h            |   27 +
 10 files changed, 1618 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml
 create mode 100644 drivers/iio/accel/kionix-kx022a-i2c.c
 create mode 100644 drivers/iio/accel/kionix-kx022a-spi.c
 create mode 100644 drivers/iio/accel/kionix-kx022a.c
 create mode 100644 drivers/iio/accel/kionix-kx022a.h

base-commit: f76349cf41451c5c42a99f18a9163377e4b364ff

Signature · 14 lines
2.37.3


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 
author maintainer
#1 lore raw

RFC PATCH v2 1/5 regulator: Add devm helpers for get and enable

A few regulator consumer drivers seem to be just getting a regulator, enabling it and registering a devm-action to disable the regulator at the driver detach and then forget about it.

We can simplify this a bit by adding a devm-helper for this pattern. Add devm_regulator_get_enable() and devm_regulator_get_enable_optional()

(cherry picked from commit b6058e052b842a19c8bb639798d8692cd0e7589f)

---

Already in Mark's regulator tree. Not to be merged. Included just for the sake of the completeness. Will be dropped when series is rebased on top of the 6.1-rc1

---
 drivers/regulator/devres.c         | 59 ++++++++++++++++++++++++++++++
 include/linux/regulator/consumer.h | 13 +++++++
 2 files changed, 72 insertions(+)
drivers/regulator/devres.c +59 -0
index 32823a87fd40..3cb3eb49ad8a 100644
@@ -70,6 +70,65 @@ struct regulator *devm_regulator_get_exclusive(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);
 
+static void regulator_action_disable(void *d)
+{
+	struct regulator *r = (struct regulator *)d;
+
+	regulator_disable(r);
+}
+
+static int _devm_regulator_get_enable(struct device *dev, const char *id,
+				      int get_type)
+{
+	struct regulator *r;
+	int ret;
+
+	r = _devm_regulator_get(dev, id, get_type);
+	if (IS_ERR(r))
+		return PTR_ERR(r);
+
+	ret = regulator_enable(r);
+	if (!ret)
+		ret = devm_add_action_or_reset(dev, &regulator_action_disable, r);
+
+	if (ret)
+		devm_regulator_put(r);
+
+	return ret;
+}
+
+/**
+ * devm_regulator_get_enable_optional - Resource managed regulator get and enable
+ * @dev: device to supply
+ * @id:  supply name or regulator ID.
+ *
+ * Get and enable regulator for duration of the device life-time.
+ * regulator_disable() and regulator_put() are automatically called on driver
+ * detach. See regulator_get_optional() and regulator_enable() for more
+ * information.
+ */
+int devm_regulator_get_enable_optional(struct device *dev, const char *id)
+{
+	return _devm_regulator_get_enable(dev, id, OPTIONAL_GET);
+}
+EXPORT_SYMBOL_GPL(devm_regulator_get_enable_optional);
+
+/**
+ * devm_regulator_get_enable - Resource managed regulator get and enable
+ * @dev: device to supply
+ * @id:  supply name or regulator ID.
+ *
+ * Get and enable regulator for duration of the device life-time.
+ * regulator_disable() and regulator_put() are automatically called on driver
+ * detach. See regulator_get() and regulator_enable() for more
+ * information.
+ */
+int devm_regulator_get_enable(struct device *dev, const char *id)
+{
+	return _devm_regulator_get_enable(dev, id, NORMAL_GET);
+}
+EXPORT_SYMBOL_GPL(devm_regulator_get_enable);
+
 /**
  * devm_regulator_get_optional - Resource managed regulator_get_optional()
  * @dev: device to supply
include/linux/regulator/consumer.h +13 -0
index bc6cda706d1f..8e6cf65851b0 100644
@@ -207,6 +207,8 @@ struct regulator *__must_check regulator_get_optional(struct device *dev,
 						      const char *id);
 struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
 							   const char *id);
+int devm_regulator_get_enable(struct device *dev, const char *id);
+int devm_regulator_get_enable_optional(struct device *dev, const char *id);
 void regulator_put(struct regulator *regulator);
 void devm_regulator_put(struct regulator *regulator);
 
@@ -354,6 +356,17 @@ devm_regulator_get_exclusive(struct device *dev, const char *id)
 	return ERR_PTR(-ENODEV);
 }
 
+static inline int devm_regulator_get_enable(struct device *dev, const char *id)
+{
+	return -ENODEV;
+}
+
+static inline int devm_regulator_get_enable_optional(struct device *dev,
+						     const char *id)
+{
+	return -ENODEV;
+}
+
 static inline struct regulator *__must_check
 regulator_get_optional(struct device *dev, const char *id)
 {
Signature · 14 lines
2.37.3


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 
#2 lore raw

Re: [RFC PATCH v2 1/5] regulator: Add devm helpers for get and enable

Quoted 6 lines · Matti Vaittinen

A few regulator consumer drivers seem to be just getting a regulator, enabling it and registering a devm-action to disable the regulator at the driver detach and then forget about it.

We can simplify this a bit by adding a devm-helper for this pattern. Add devm_regulator_get_enable() and devm_regulator_get_enable_optional()

...

Quoted 1 line

(cherry picked from commit b6058e052b842a19c8bb639798d8692cd0e7589f)

Not sure:
- why this is in the commit message
- what it points to, since

$ git show b6058e052b842a19c8bb639798d8692cd0e7589f
 fatal: bad object b6058e052b842a19c8bb639798d8692cd0e7589f
Quoted 3 lines

Already in Mark's regulator tree. Not to be merged. Included just for the sake of the completeness. Will be dropped when series is rebased on top of the 6.1-rc1

Ah, I see, but does it mean the commit has been rebased or you used wrong SHA?

...

drivers/regulator/devres.c struct regulator *devm_regulator_get_exclusive(struct device *dev, · line 75

Quoted 3 lines
drivers/regulator/devres.c +3 -0
+static void regulator_action_disable(void *d)
+{
+	struct regulator *r = (struct regulator *)d;

Cast is not needed.

Quoted 2 lines
(quoted diff) +2 -0
+	regulator_disable(r);
+}
Signature · 2 lines
With Best Regards,
Andy Shevchenko
maintainer
#3 lore raw

Re: [RFC PATCH v2 1/5] regulator: Add devm helpers for get and enable

Quoted 10 lines · On Thu, 6 Oct 2022 19:17:39 +0300 Andy Shevchenko…
Quoted 6 lines · Matti Vaittinen

A few regulator consumer drivers seem to be just getting a regulator, enabling it and registering a devm-action to disable the regulator at the driver detach and then forget about it.

We can simplify this a bit by adding a devm-helper for this pattern. Add devm_regulator_get_enable() and devm_regulator_get_enable_optional()

...

Quoted 7 lines
Quoted 1 line

(cherry picked from commit b6058e052b842a19c8bb639798d8692cd0e7589f)

Not sure:
- why this is in the commit message
- what it points to, since

$ git show b6058e052b842a19c8bb639798d8692cd0e7589f
 fatal: bad object b6058e052b842a19c8bb639798d8692cd0e7589f

These are now upstream in Linus' tree and in my testing branch. I'd not normally advocate working on top of that (because I rebase it), but if it is useful for this series go ahead.

Jonathan

Quoted 18 lines
Quoted 4 lines

Already in Mark's regulator tree. Not to be merged. Included just for the sake of the completeness. Will be dropped when series is rebased on top of the 6.1-rc1

Ah, I see, but does it mean the commit has been rebased or you used wrong SHA?

...

drivers/regulator/devres.c struct regulator *devm_regulator_get_exclusive(struct device *dev, · line 75

Quoted 3 lines
drivers/regulator/devres.c +3 -0
+static void regulator_action_disable(void *d)
+{
+	struct regulator *r = (struct regulator *)d;  

Cast is not needed.

Quoted 2 lines
(quoted diff) +2 -0
+	regulator_disable(r);
+}  
#4 lore raw

Re: [RFC PATCH v2 1/5] regulator: Add devm helpers for get and enable

Quoted 3 lines · Jonathan Cameron
Quoted 1 line · On Thu, 6 Oct 2022 19:17:39 +0300 Andy Shevchenko…

On Thu, Oct 06, 2022 at 05:36:52PM +0300, Matti Vaittinen wrote:

...

Quoted 9 lines
Quoted 7 lines
Quoted 1 line

(cherry picked from commit b6058e052b842a19c8bb639798d8692cd0e7589f)

Not sure:
- why this is in the commit message
- what it points to, since

$ git show b6058e052b842a19c8bb639798d8692cd0e7589f
 fatal: bad object b6058e052b842a19c8bb639798d8692cd0e7589f

These are now upstream in Linus' tree and in my testing branch.

I don't see them. As I pointed out the commit IDs are not in the any of the official trees (subsystem maintainer's or Linus'). Again, read my doubts about the above commit message.

Quoted 8 lines

I'd not normally advocate working on top of that (because I rebase it), but if it is useful for this series go ahead.

Quoted 5 lines
Quoted 3 lines

Already in Mark's regulator tree. Not to be merged. Included just for the sake of the completeness. Will be dropped when series is rebased on top of the 6.1-rc1

Ah, I see, but does it mean the commit has been rebased or you used wrong SHA?

Signature · 2 lines
With Best Regards,
Andy Shevchenko
author maintainer
#5 lore raw

Re: [RFC PATCH v2 1/5] regulator: Add devm helpers for get and enable

In reply to Jonathan Cameron

Hi Jonathan,

Quoted 21 lines · Jonathan Cameron
Quoted 10 lines · On Thu, 6 Oct 2022 19:17:39 +0300 Andy Shevchenko…
Quoted 6 lines · Matti Vaittinen

A few regulator consumer drivers seem to be just getting a regulator, enabling it and registering a devm-action to disable the regulator at the driver detach and then forget about it.

We can simplify this a bit by adding a devm-helper for this pattern. Add devm_regulator_get_enable() and devm_regulator_get_enable_optional()

...

Quoted 7 lines
Quoted 1 line

(cherry picked from commit b6058e052b842a19c8bb639798d8692cd0e7589f)

Not sure:
- why this is in the commit message
- what it points to, since

$ git show b6058e052b842a19c8bb639798d8692cd0e7589f
  fatal: bad object b6058e052b842a19c8bb639798d8692cd0e7589f
Quoted 3 lines

These are now upstream in Linus' tree and in my testing branch. I'd not normally advocate working on top of that (because I rebase it), but if it is useful for this series go ahead.

Thanks for the explanation :)

This series will conflict with my fixup series for triggered-buffer attributes. Hence I though I might combine these two series into one if I need to respin the fixup series. I thought of using the v6.1-rc1 when it is out. (I think the 6.1-rc1 should not be that far away)

OTOH, I just read your another mail which told that there will be one more driver which will conflict with the fixup coming in during this cycle. If that driver lands in your tree before the fix - then I guess I need to rebase the fixup series (and maybe this too) on top of your tree + add conversion of this new driver. I don't think that would be the testing branch though(?)

Yours
-- Matti

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
#6 lore raw

Re: [RFC PATCH v2 1/5] regulator: Add devm helpers for get and enable

Quoted 35 lines · On Mon, 10 Oct 2022 12:24:51 +0300 Matti Vaittinen <[email protected]>…

Hi Jonathan,

Quoted 21 lines · Jonathan Cameron
Quoted 10 lines · On Thu, 6 Oct 2022 19:17:39 +0300 Andy Shevchenko…
Quoted 6 lines · Matti Vaittinen

A few regulator consumer drivers seem to be just getting a regulator, enabling it and registering a devm-action to disable the regulator at the driver detach and then forget about it.

We can simplify this a bit by adding a devm-helper for this pattern. Add devm_regulator_get_enable() and devm_regulator_get_enable_optional()

...

Quoted 7 lines
Quoted 1 line

(cherry picked from commit b6058e052b842a19c8bb639798d8692cd0e7589f)

Not sure:
- why this is in the commit message
- what it points to, since

$ git show b6058e052b842a19c8bb639798d8692cd0e7589f
  fatal: bad object b6058e052b842a19c8bb639798d8692cd0e7589f  
Quoted 3 lines

These are now upstream in Linus' tree and in my testing branch. I'd not normally advocate working on top of that (because I rebase it), but if it is useful for this series go ahead.

Thanks for the explanation :)

This series will conflict with my fixup series for triggered-buffer attributes. Hence I though I might combine these two series into one if I need to respin the fixup series. I thought of using the v6.1-rc1 when it is out. (I think the 6.1-rc1 should not be that far away)

Quoted 6 lines

OTOH, I just read your another mail which told that there will be one more driver which will conflict with the fixup coming in during this cycle. If that driver lands in your tree before the fix - then I guess I need to rebase the fixup series (and maybe this too) on top of your tree
+ add conversion of this new driver. I don't think that would be the testing branch though(?)

I'll be messy, but the majority of that fix series will need to go in during rcX..

The last patch (refactoring one) will need to wait until those are upstream and have worked there way around to be in my togreg branch (I usually rebase that tree only after pull requests, but given this
is going on I may do an earlier pull request than normal.)

That refactoring patch will probably need to cover the new driver. I can do that as a fixup whilst applying it though once we get that far.

Jonathan

Quoted 4 lines

Yours
-- Matti

author maintainer
#7 lore raw

Re: [RFC PATCH v2 1/5] regulator: Add devm helpers for get and enable

In reply to Andy Shevchenko

Hi Andy,

Quoted 15 lines · Andy Shevchenko
Quoted 6 lines · Matti Vaittinen

A few regulator consumer drivers seem to be just getting a regulator, enabling it and registering a devm-action to disable the regulator at the driver detach and then forget about it.

We can simplify this a bit by adding a devm-helper for this pattern. Add devm_regulator_get_enable() and devm_regulator_get_enable_optional()

...

Quoted 1 line

(cherry picked from commit b6058e052b842a19c8bb639798d8692cd0e7589f)

Not sure:
- why this is in the commit message
- what it points to, since

Quoted 8 lines
$ git show b6058e052b842a19c8bb639798d8692cd0e7589f
  fatal: bad object b6058e052b842a19c8bb639798d8692cd0e7589f
Quoted 3 lines

Already in Mark's regulator tree. Not to be merged. Included just for the sake of the completeness. Will be dropped when series is rebased on top of the 6.1-rc1

Ah, I see, but does it mean the commit has been rebased or you used wrong SHA?

I did probably cherry-pick this from my local development branch and not from Mark's tree. Sorry for the confusion. I thought people would ignore these first two patches when reviewing as was requested in cover-letter.

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
#8 lore raw

Re: [RFC PATCH v2 1/5] regulator: Add devm helpers for get and enable

Quoted 8 lines · Matti Vaittinen
Quoted 7 lines · Andy Shevchenko
Quoted 6 lines · Matti Vaittinen

A few regulator consumer drivers seem to be just getting a regulator, enabling it and registering a devm-action to disable the regulator at the driver detach and then forget about it.

We can simplify this a bit by adding a devm-helper for this pattern. Add devm_regulator_get_enable() and devm_regulator_get_enable_optional()

...

Quoted 12 lines
Quoted 12 lines
Quoted 1 line

(cherry picked from commit b6058e052b842a19c8bb639798d8692cd0e7589f)

Not sure:
- why this is in the commit message
- what it points to, since

$ git show b6058e052b842a19c8bb639798d8692cd0e7589f
  fatal: bad object b6058e052b842a19c8bb639798d8692cd0e7589f
Quoted 3 lines

Already in Mark's regulator tree. Not to be merged. Included just for the sake of the completeness. Will be dropped when series is rebased on top of the 6.1-rc1

Quoted 5 lines
Quoted 1 line

Ah, I see, but does it mean the commit has been rebased or you used wrong SHA?

I did probably cherry-pick this from my local development branch and not from Mark's tree. Sorry for the confusion. I thought people would ignore these first two patches when reviewing as was requested in cover-letter.

The solution as pointed out by LKP and which will removes the need of the noise in email and a lot of confusions is to use --base parameter to the patch(es).

Signature · 2 lines
With Best Regards,
Andy Shevchenko
author maintainer
#9 lore raw

RFC PATCH v2 2/5 regulator: Add devm helpers for get and enable

In reply to Matti Vaittinen

A few regulator consumer drivers seem to be just getting a regulator, enabling it and registering a devm-action to disable the regulator at the driver detach and then forget about it.

We can simplify this a bit by adding a devm-helper for this pattern. Add devm_regulator_get_enable() and devm_regulator_get_enable_optional()

---
Already in Mark's regulator tree. Not to be merged. Included just for the sake of the completeness. Will be dropped when series is rebased on top of the 6.1-rc1

---
 drivers/regulator/devres.c         | 105 +++++++++++++++++++++++++++++
 include/linux/regulator/consumer.h |  14 ++++
 2 files changed, 119 insertions(+)
drivers/regulator/devres.c +105 -0
index 3cb3eb49ad8a..3265e75e97ab 100644
@@ -253,6 +253,111 @@ int devm_regulator_bulk_get_const(struct device *dev, int num_consumers,
 }
 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_const);
 
+static int devm_regulator_bulk_match(struct device *dev, void *res,
+				     void *data)
+{
+	struct regulator_bulk_devres *match = res;
+	struct regulator_bulk_data *target = data;
+
+	/*
+	 * We check the put uses same consumer list as the get did.
+	 * We _could_ scan all entries in consumer array and check the
+	 * regulators match but ATM I don't see the need. We can change this
+	 * later if needed.
+	 */
+	return match->consumers == target;
+}
+
+/**
+ * devm_regulator_bulk_put - Resource managed regulator_bulk_put()
+ * @consumers: consumers to free
+ *
+ * Deallocate regulators allocated with devm_regulator_bulk_get(). Normally
+ * this function will not need to be called and the resource management
+ * code will ensure that the resource is freed.
+ */
+void devm_regulator_bulk_put(struct regulator_bulk_data *consumers)
+{
+	int rc;
+	struct regulator *regulator = consumers[0].consumer;
+
+	rc = devres_release(regulator->dev, devm_regulator_bulk_release,
+			    devm_regulator_bulk_match, consumers);
+	if (rc != 0)
+		WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_regulator_bulk_put);
+
+static void devm_regulator_bulk_disable(void *res)
+{
+	struct regulator_bulk_devres *devres = res;
+	int i;
+
+	for (i = 0; i < devres->num_consumers; i++)
+		regulator_disable(devres->consumers[i].consumer);
+}
+
+/**
+ * devm_regulator_bulk_get_enable - managed get'n enable multiple regulators
+ *
+ * @dev:           device to supply
+ * @num_consumers: number of consumers to register
+ * @id:            list of supply names or regulator IDs
+ *
+ * @return 0 on success, an errno on failure.
+ *
+ * This helper function allows drivers to get several regulator
+ * consumers in one operation with management, the regulators will
+ * automatically be freed when the device is unbound.  If any of the
+ * regulators cannot be acquired then any regulators that were
+ * allocated will be freed before returning to the caller.
+ */
+int devm_regulator_bulk_get_enable(struct device *dev, int num_consumers,
+				   const char * const *id)
+{
+	struct regulator_bulk_devres *devres;
+	struct regulator_bulk_data *consumers;
+	int i, ret;
+
+	devres = devm_kmalloc(dev, sizeof(*devres), GFP_KERNEL);
+	if (!devres)
+		return -ENOMEM;
+
+	devres->consumers = devm_kcalloc(dev, num_consumers, sizeof(*consumers),
+					 GFP_KERNEL);
+	consumers = devres->consumers;
+	if (!consumers)
+		return -ENOMEM;
+
+	devres->num_consumers = num_consumers;
+
+	for (i = 0; i < num_consumers; i++)
+		consumers[i].supply = id[i];
+
+	ret = devm_regulator_bulk_get(dev, num_consumers, consumers);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < num_consumers; i++) {
+		ret = regulator_enable(consumers[i].consumer);
+		if (ret)
+			goto unwind;
+	}
+
+	ret = devm_add_action(dev, devm_regulator_bulk_disable, devres);
+	if (!ret)
+		return 0;
+
+unwind:
+	while (--i >= 0)
+		regulator_disable(consumers[i].consumer);
+
+	devm_regulator_bulk_put(consumers);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_enable);
+
 static void devm_rdev_release(struct device *dev, void *res)
 {
 	regulator_unregister(*(struct regulator_dev **)res);
include/linux/regulator/consumer.h +14 -0
index 8e6cf65851b0..ee3b4a014611 100644
@@ -246,12 +246,15 @@ int __must_check regulator_bulk_get(struct device *dev, int num_consumers,
 				    struct regulator_bulk_data *consumers);
 int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers,
 					 struct regulator_bulk_data *consumers);
+void devm_regulator_bulk_put(struct regulator_bulk_data *consumers);
 int __must_check devm_regulator_bulk_get_const(
 	struct device *dev, int num_consumers,
 	const struct regulator_bulk_data *in_consumers,
 	struct regulator_bulk_data **out_consumers);
 int __must_check regulator_bulk_enable(int num_consumers,
 				       struct regulator_bulk_data *consumers);
+int devm_regulator_bulk_get_enable(struct device *dev, int num_consumers,
+				   const char * const *id);
 int regulator_bulk_disable(int num_consumers,
 			   struct regulator_bulk_data *consumers);
 int regulator_bulk_force_disable(int num_consumers,
@@ -388,6 +391,10 @@ static inline void devm_regulator_put(struct regulator *regulator)
 {
 }
 
+static inline void devm_regulator_bulk_put(struct regulator_bulk_data *consumers)
+{
+}
+
 static inline int regulator_register_supply_alias(struct device *dev,
 						  const char *id,
 						  struct device *alias_dev,
@@ -478,6 +485,13 @@ static inline int regulator_bulk_enable(int num_consumers,
 	return 0;
 }
 
+static inline int devm_regulator_bulk_get_enable(struct device *dev,
+						 int num_consumers,
+						 const char * const *id)
+{
+	return 0;
+}
+
 static inline int regulator_bulk_disable(int num_consumers,
 					 struct regulator_bulk_data *consumers)
 {
Signature · 14 lines
2.37.3


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 
author maintainer
#10 lore raw

RFC PATCH v2 3/5 dt-bindings: iio: Add KX022A accelerometer

In reply to Matti Vaittinen

KX022A is a 3-axis Accelerometer from ROHM/Kionix. The sensor features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

Add the basic device tree description for the accelerometer. Only basic accelerometer features are considered as of now - new properties may or may not be needed in the future when rest of the features are supported.

---
RFCv1 => v2:
Based on a review by Krzysztof:
- fix a typo from commit message
- const compatible
- drop unnecessary descriptions/words
- io_vdd-supply => io-vdd-supply
- fix the binding example indentiation
Also,
- change my email address
- support both INT pins

---
 .../bindings/iio/accel/kionix,kx022a.yaml     | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file +67 -0
new file mode 100644
index 000000000000..2919c436e46f
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/accel/kionix,kx022a.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ROHM/Kionix KX022A Accelerometer
+
+maintainers:
+  - Matti Vaittinen <[email protected]>
+
+description: |
+  KX022A is a 3-axis accelerometer supporting +/- 2G, 4G, 8G and 16G ranges,
+  output data-rates from 0.78Hz to 1600Hz and a hardware-fifo buffering.
+  KX022A can be accessed either via I2C or SPI.
+
+properties:
+  compatible:
+    const: kionix,kx022a
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 2
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 2
+    items:
+      enum:
+        - INT1
+        - INT2
+
+  vdd-supply: true
+  io-vdd-supply: true
+
+  mount-matrix:
+    description: |
+      an optional 3x3 mounting rotation matrix.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        accel@1f {
+            compatible = "kionix,kx022a";
+            reg = <0x1f>;
+
+            interrupt-parent = <&gpio1>;
+            interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
+            interrupt-names = "INT1";
+
+            io-vdd-supply = <&iovdd>;
+            vdd-supply = <&vdd>;
+        };
+    };
Signature · 14 lines
2.37.3


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 
#11 lore raw

Re: [RFC PATCH v2 3/5] dt-bindings: iio: Add KX022A accelerometer

Quoted 5 lines · Matti Vaittinen

KX022A is a 3-axis Accelerometer from ROHM/Kionix. The sensor features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

Thank you for your patch. There is something to discuss/improve.

Quoted 9 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file +9 -0
+
+properties:
+  compatible:
+    const: kionix,kx022a
+
+  reg:
+    maxItems: 1
+
+  interrupts:

Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml line 34

Quoted 10 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file +10 -0
+    minItems: 1
+    maxItems: 2
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 2
+    items:
+      enum:
+        - INT1
+        - INT2

This allows any order, which I assume was your intention. However maybe at least fix it a bit like:
minItems: 1
items:
- enum: [ int1, int2]
- const: int2

OTOH, the names are not really descriptive. Do they match pin names?

Best regards,
Krzysztof

author maintainer
#12 lore raw

Re: [RFC PATCH v2 3/5] dt-bindings: iio: Add KX022A accelerometer

Hi dee Ho Krzysztof,

Quoted 22 lines · Krzysztof Kozlowski
Quoted 5 lines · Matti Vaittinen

KX022A is a 3-axis Accelerometer from ROHM/Kionix. The sensor features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

Thank you for your patch. There is something to discuss/improve.

Quoted 13 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file +13 -0
+
+properties:
+  compatible:
+    const: kionix,kx022a
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 2
+
+  interrupt-names:
Quoted 8 lines

Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml line 34

Quoted 6 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file +6 -0
+    minItems: 1
+    maxItems: 2
+    items:
+      enum:
+        - INT1
+        - INT2

This allows any order, which I assume was your intention.

Yes. I don't see real need to restrict ordering - besides, with my yaml/schema skills it'd took eternity to find corrct example(s) ;)

My intention is that the user can give either one of these - or both. Order needs naturally to match the order of IRQs - but this we can't know.

Quoted 6 lines

However maybe
at least fix it a bit like:
minItems: 1
items:
- enum: [ int1, int2]
- const: int2

If you say so XD
I can fix this for v3 :)

Quoted 3 lines

OTOH, the names are not really descriptive. Do they match pin names?

Yes. They match to pin names used in the data-sheet.

Yours
-- Matti

Ps. I've heard this year has not been that good with the mushrooms here in Finland ;)

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
maintainer
#13 lore raw

Re: [RFC PATCH v2 3/5] dt-bindings: iio: Add KX022A accelerometer

Quoted 47 lines · On Thu, 6 Oct 2022 18:32:22 +0300 Matti Vaittinen <[email protected]>…

Hi dee Ho Krzysztof,

Quoted 22 lines · Krzysztof Kozlowski
Quoted 5 lines · Matti Vaittinen

KX022A is a 3-axis Accelerometer from ROHM/Kionix. The sensor features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

Thank you for your patch. There is something to discuss/improve.

Quoted 13 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file +13 -0
+
+properties:
+  compatible:
+    const: kionix,kx022a
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 2
+
+  interrupt-names:
Quoted 8 lines

Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml line 34

Quoted 6 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file +6 -0
+    minItems: 1
+    maxItems: 2
+    items:
+      enum:
+        - INT1
+        - INT2  

This allows any order, which I assume was your intention.

Yes. I don't see real need to restrict ordering - besides, with my yaml/schema skills it'd took eternity to find corrct example(s) ;)

My intention is that the user can give either one of these - or both. Order needs naturally to match the order of IRQs - but this we can't know.

Quoted 6 lines

However maybe
at least fix it a bit like:
minItems: 1
items:
- enum: [ int1, int2]
- const: int2

Quoted 2 lines

If you say so XD
I can fix this for v3 :)

If my limited understanding is correct, one advantage of this restriction is that we can't have

"INT1", "INT1"
though that may be prevented elsewhere...

There is no loss of useful flexibility in how Krzysztof suggested doing it so looks like a good suggestion to me.

Jonathan

author maintainer
#14 lore raw

Re: [RFC PATCH v2 3/5] dt-bindings: iio: Add KX022A accelerometer

Quoted 52 lines · Jonathan Cameron
Quoted 47 lines · On Thu, 6 Oct 2022 18:32:22 +0300 Matti Vaittinen <[email protected]>…

Hi dee Ho Krzysztof,

Quoted 22 lines · Krzysztof Kozlowski
Quoted 5 lines · Matti Vaittinen

KX022A is a 3-axis Accelerometer from ROHM/Kionix. The sensor features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

Thank you for your patch. There is something to discuss/improve.

Quoted 13 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file +13 -0
+
+properties:
+  compatible:
+    const: kionix,kx022a
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 2
+
+  interrupt-names:
Quoted 8 lines

Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml line 34

Quoted 6 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml new file +6 -0
+    minItems: 1
+    maxItems: 2
+    items:
+      enum:
+        - INT1
+        - INT2

This allows any order, which I assume was your intention.

Yes. I don't see real need to restrict ordering - besides, with my yaml/schema skills it'd took eternity to find corrct example(s) ;)

My intention is that the user can give either one of these - or both. Order needs naturally to match the order of IRQs - but this we can't know.

Quoted 6 lines

However maybe
at least fix it a bit like:
minItems: 1
items:
- enum: [ int1, int2]
- const: int2

Quoted 2 lines

If you say so XD
I can fix this for v3 :)

Quoted 8 lines

If my limited understanding is correct, one advantage of this restriction is that we can't have

"INT1", "INT1"
though that may be prevented elsewhere...

There is no loss of useful flexibility in how Krzysztof suggested doing it so looks like a good suggestion to me.

Thanks Krzysztof and Jonathan :) I'll use Krzysztof's suggestion for the v3.

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
author maintainer
#15 lore raw

RFC PATCH v2 4/5 iio: accel: Support Kionix/ROHM KX022A accelerometer

In reply to Matti Vaittinen

KX022A is a 3-axis accelerometer from ROHM/Kionix. The senosr features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ).

Important things to be added include the double-tap, motion detection and wake-up as well as the runtime power management.

NOTE: Filling-up the hardware FIFO should be avoided. During my testing I noticed that filling up the hardware FIFO might mess-up the sample count. My sensor ended up in a state where the amount of data in FIFO was reported to be 0xff bytes, which equals to 42,5 samples. Specification says the FIFO can hold a maximum of 41 samples in HiRes mode. Also, at least once the FIFO was stuck in a state where reading data from hardware FIFO did not decrease the amount of data reported to be in the FIFO - eg. FIFO was "stuck". The code has now an error count and 10 reads with invalid FIFO data count will cause the fifo contents to be dropped.

---
RFCv1 => v2 (mostly based on feedback from Jonathan):
- Fix bunch of typos from the commit message.
- Add missing break; to the kx022a_write_raw()
- Fix SPI driver to use of_match_table
- Fix indentiation in I2C driver
- Drop struct kx022a_trigger
- Drop cross references from Kconfig
- Use /* */ also in file header comments
- Misc minor styling
- Do sensor-reset at probe
- Support both IRQ pins
- Implement read_avail callback
- Use dma aligned buffers for bulk-reads
- Use iio_trigger_poll_chained()
- Use devm consistently
- Drop inclusion of device.h
- Add SPI device ID for module loading
- Add module param for hw fifo / watermark IRQ usage
- Fix io-vdd-supply name to match one in the bindings

---
 drivers/iio/accel/Kconfig             |   21 +
 drivers/iio/accel/Makefile            |    3 +
 drivers/iio/accel/kionix-kx022a-i2c.c |   53 ++
 drivers/iio/accel/kionix-kx022a-spi.c |   59 ++
 drivers/iio/accel/kionix-kx022a.c     | 1138 +++++++++++++++++++++++++
 drivers/iio/accel/kionix-kx022a.h     |   81 ++
 6 files changed, 1355 insertions(+)
 create mode 100644 drivers/iio/accel/kionix-kx022a-i2c.c
 create mode 100644 drivers/iio/accel/kionix-kx022a-spi.c
 create mode 100644 drivers/iio/accel/kionix-kx022a.c
 create mode 100644 drivers/iio/accel/kionix-kx022a.h
drivers/iio/accel/Kconfig +21 -0
index 35798712f811..43f1090e8c59 100644
@@ -409,6 +409,27 @@ config IIO_ST_ACCEL_SPI_3AXIS
 	  To compile this driver as a module, choose M here. The module
 	  will be called st_accel_spi.
 
+config IIO_KX022A
+	tristate
+
+config IIO_KX022A_SPI
+	tristate "Kionix KX022A tri-axis digital accelerometer"
+	depends on I2C
+	select IIO_KX022A
+	select REGMAP_SPI
+	help
+	  Say Y here to enable support for the Kionix KX022A digital tri-axis
+	  accelerometer connected to I2C interface.
+
+config IIO_KX022A_I2C
+	tristate "Kionix KX022A tri-axis digital accelerometer"
+	depends on I2C
+	select IIO_KX022A
+	select REGMAP_I2C
+	help
+	  Say Y here to enable support for the Kionix KX022A digital tri-axis
+	  accelerometer connected to I2C interface.
+
 config KXSD9
 	tristate "Kionix KXSD9 Accelerometer Driver"
 	select IIO_BUFFER
drivers/iio/accel/Makefile +3 -0
index 4d8792668838..7bd654b74f42 100644
@@ -40,6 +40,9 @@ obj-$(CONFIG_FXLS8962AF)	+= fxls8962af-core.o
 obj-$(CONFIG_FXLS8962AF_I2C)	+= fxls8962af-i2c.o
 obj-$(CONFIG_FXLS8962AF_SPI)	+= fxls8962af-spi.o
 obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
+obj-$(CONFIG_IIO_KX022A)	+= kionix-kx022a.o
+obj-$(CONFIG_IIO_KX022A_I2C)	+= kionix-kx022a-i2c.o
+obj-$(CONFIG_IIO_KX022A_SPI)	+= kionix-kx022a-spi.o
 obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
 obj-$(CONFIG_KXSD9)	+= kxsd9.o
 obj-$(CONFIG_KXSD9_SPI)	+= kxsd9-spi.o
drivers/iio/accel/kionix-kx022a-i2c.c new file +53 -0

53 lines not on this page · raw message

drivers/iio/accel/kionix-kx022a-spi.c new file +59 -0

59 lines not on this page · raw message

drivers/iio/accel/kionix-kx022a.c new file +1138 -0

1,138 lines not on this page · raw message

drivers/iio/accel/kionix-kx022a.h new file +81 -0

81 lines not on this page · raw message

Signature · 14 lines
2.37.3


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 
#16 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 22 lines · Matti Vaittinen

KX022A is a 3-axis accelerometer from ROHM/Kionix. The senosr features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ).

Important things to be added include the double-tap, motion detection and wake-up as well as the runtime power management.

NOTE: Filling-up the hardware FIFO should be avoided. During my testing I noticed that filling up the hardware FIFO might mess-up the sample count. My sensor ended up in a state where the amount of data in FIFO was reported to be 0xff bytes, which equals to 42,5 samples. Specification says the FIFO can hold a maximum of 41 samples in HiRes mode. Also, at least once the FIFO was stuck in a state where reading data from hardware FIFO did not decrease the amount of data reported to be in the FIFO - eg. FIFO was "stuck". The code has now an error count and 10 reads with invalid FIFO data count will cause the fifo contents to be dropped.

...

drivers/iio/accel/Kconfig config IIO_ST_ACCEL_SPI_3AXIS · line 422

Quoted 8 lines
drivers/iio/accel/Kconfig +8 -0
+config IIO_KX022A_SPI
+	tristate "Kionix KX022A tri-axis digital accelerometer"
+	depends on I2C
+	select IIO_KX022A
+	select REGMAP_SPI
+	help
+	  Say Y here to enable support for the Kionix KX022A digital tri-axis
+	  accelerometer connected to I2C interface.

Why it tending to get user to choose Y? It might increase the footprint of bootable image and on the embedded platforms it may increase the chances to not fit into (flash) ROM.

Also what will be the module name (see other Kconfig for the pattern)?

drivers/iio/accel/Kconfig config IIO_ST_ACCEL_SPI_3AXIS · line 431

Quoted 8 lines
drivers/iio/accel/Kconfig +8 -0
+config IIO_KX022A_I2C
+	tristate "Kionix KX022A tri-axis digital accelerometer"
+	depends on I2C
+	select IIO_KX022A
+	select REGMAP_I2C
+	help
+	  Say Y here to enable support for the Kionix KX022A digital tri-axis
+	  accelerometer connected to I2C interface.

Ditto.

...

drivers/iio/accel/kionix-kx022a-i2c.c line 48

Quoted 9 lines
drivers/iio/accel/kionix-kx022a-i2c.c new file +8 -0
+static struct i2c_driver kx022a_i2c_driver = {
+	.driver = {
+		.name  = "kx022a-i2c",
+		.of_match_table = kx022a_of_match,
+	  },
+	.probe_new    = kx022a_i2c_probe,
+};
 
+

Redundant blank line.

Quoted 1 line

+module_i2c_driver(kx022a_i2c_driver);

...

drivers/iio/accel/kionix-kx022a-spi.c line 18

Quoted 4 lines
drivers/iio/accel/kionix-kx022a-spi.c new file +4 -0
+static int kx022a_spi_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct regmap *regmap;

Interestingly in the I²C driver you have other style (and I prefer SPI one over that). Can you fix I²C driver to follow this style?

Review

Quoted 1 line
(quoted diff) +1 -0
+	}

Ditto (blank line).

Quoted 2 lines
(quoted diff) +2 -0
+	return kx022a_probe_internal(dev);
+}

...

drivers/iio/accel/kionix-kx022a-spi.c line 54

Quoted 10 lines
drivers/iio/accel/kionix-kx022a-spi.c new file +9 -0
+static struct spi_driver kx022a_spi_driver = {
+	.driver = {
+		.name   = "kx022a-spi",
+		.of_match_table = kx022a_of_match,
+	},
+	.probe = kx022a_spi_probe,
+	.id_table = kx022a_id,
+};
 
+

Redundant blank line.

Quoted 1 line

+module_spi_driver(kx022a_spi_driver);

...

drivers/iio/accel/kionix-kx022a.c line 9

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+#include <linux/delay.h>
 
+#include <linux/gpio.h>

No way. The linux/gpio.h mustn't appear in the new code.

drivers/iio/accel/kionix-kx022a.c line 14

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>

Can this group be placed after units.h (with blank line in between)?

Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/units.h>
+
+#include "kionix-kx022a.h"

...

Quoted 3 lines

+/*
+ * Threshold for deciding our HW fifo is unrecoverably corrupt and should be
+ * cleared

Multi-line comments have to follow English grammar and punctuation, i.e. trailing period.

drivers/iio/accel/kionix-kx022a.c line 31

Quoted 3 lines

+ */

drivers/iio/accel/kionix-kx022a.c new file +2 -0
+#define KXO22A_FIFO_ERR_THRESHOLD 10
+#define KX022A_FIFO_LENGTH 41

Why not to use TAB between definitions and values (also for the rest similar cases)?

...

drivers/iio/accel/kionix-kx022a.c line 35

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+#define KX022A_FIFO_MAX_BYTES (KX022A_FIFO_LENGTH *			\
+			       KX022A_FIFO_SAMPLES_SIZE_BYTES)

Slightly better to read:

#define KX022A_FIFO_MAX_BYTES					\
	(KX022A_FIFO_LENGTH * KX022A_FIFO_SAMPLES_SIZE_BYTES)

...

drivers/iio/accel/kionix-kx022a.c line 38

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+#define KX022A_SOFT_RESET_WAIT_TIME_US (5 * KILO)
+#define KX022A_SOFT_RESET_TOTAL_WAIT_TIME_US (500 * KILO)

For time we have different macros like USEC_PER_MSEC (look into vdso/time64.h).

...

drivers/iio/accel/kionix-kx022a.c line 146

Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+const struct regmap_config kx022a_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_table = &kx022a_volatile_regs,
+	.rd_table = &kx022a_wo_regs,
+	.wr_table = &kx022a_ro_regs,
+	.rd_noinc_table = &kx022a_nir_regs,
+	.precious_table = &kx022a_precious_regs,
+	.max_register = KX022A_MAX_REGISTER,
+	.cache_type = REGCACHE_RBTREE,

No max register? Have you tried debugfs output?

Review

Quoted 2 lines
(quoted diff) +2 -0
+};
+EXPORT_SYMBOL_GPL(kx022a_regmap);

Can we use namespace from day 1?

...

Quoted 1 line

+struct kx022a_data;

Why?

drivers/iio/accel/kionix-kx022a.c line 156

Quoted 6 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+struct kx022a_data {
+	int irq;
+	int inc_reg;
+	int ien_reg;
 
+	struct regmap *regmap;

Putting this as a first member might improve code by making pointer arithmetics better. Have you checked possibilities with bloat-o-meter?

drivers/iio/accel/kionix-kx022a.c line 162

Quoted 7 lines
drivers/iio/accel/kionix-kx022a.c new file +6 -0
+	struct iio_trigger *trig;
+	bool trigger_enabled;
+
+	struct device *dev;
+	unsigned int g_range;
 
+	struct mutex mutex;

No warning from checkpatch? Every lock should be commented what it is for.

Quoted 14 lines
drivers/iio/accel/kionix-kx022a.c new file +14 -0
+	unsigned int state;
+
+	int64_t timestamp, old_timestamp;
+	unsigned int odr_ns;
+
+	struct iio_mount_matrix orientation;
+	u8 watermark;
+	/* 3 x 16bit accel data + timestamp */
+	s16 buffer[8] __aligned(IIO_DMA_MINALIGN);
+	struct {
+		__le16 channels[3];
+		s64 ts __aligned(8);
+	} scan;
+};

...

drivers/iio/accel/kionix-kx022a.c line 191

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+enum {
+	AXIS_X,
+	AXIS_Y,
+	AXIS_Z,
+	AXIS_MAX,

No comma for terminator entry.

Quoted 1 line

+};

...

drivers/iio/accel/kionix-kx022a.c line 196

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+static const unsigned long kx022a_scan_masks[] = {
+					BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
+					0};

Seems broken indentation. The }; is better on a new line.

...

drivers/iio/accel/kionix-kx022a.c line 200

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+static const struct iio_chan_spec_ext_info kx022a_ext_info[] = {
+	IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, kx022a_get_mount_matrix),
 
+	{ },

No comma for the terminator entry.

Quoted 1 line

+};

...

Quoted 11 lines
drivers/iio/accel/kionix-kx022a.c new file +11 -0
+#define KX022A_ACCEL_CHAN(axis, index)						\
+	{								\
+		.type = IIO_ACCEL,					\
+		.modified = 1,						\
+		.channel2 = IIO_MOD_##axis,				\
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
+					BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
+		.info_mask_shared_by_type_available =			\
+					BIT(IIO_CHAN_INFO_SCALE) |	\
+					BIT(IIO_CHAN_INFO_SAMP_FREQ),	\

drivers/iio/accel/kionix-kx022a.c line 223

Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+		.ext_info = kx022a_ext_info,				\
+		.address = KX022A_REG_##axis##OUT_L,			\
+		.scan_index = index,					\
+		.scan_type = {                                          \
+			.sign = 's',					\
+			.realbits = 16,					\
+			.storagebits = 16,				\
+			.endianness = IIO_LE,				\
+		},							\
+	}

It's fine to indent left by one TAB.

...

Quoted 5 lines

+/*
+ * The sensor HW can support ODR up to 1600 Hz - which is beyond what most of
+ * Linux CPUs can handle w/o dropping samples. Also, the low power mode is not
+ * available for higher sample rates. Thus the driver only supports 200 Hz and
+ * slower ODRs. Slowest being 0.78 Hz

Please, check the punctuation.

Quoted 1 line

+ */

...

drivers/iio/accel/kionix-kx022a.c line 247

Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+static const int kx022a_accel_samp_freq_table[][2] = {
+	[0] = { 0, 780000 },
+	[1] = { 1, 563000 },
+	[2] = { 3, 125000 },
+	[3] = { 6, 250000 },
+	[4] = { 12, 500000 },
+	[5] = { 25, 0 },
+	[6] = { 50, 0 },
+	[7] = { 100, 0 },
+	[8] = { 200, 0 }

What do you need the indices for? They are not defines, so are you expecting to shuffle the entries?

Quoted 1 line

+};

...

drivers/iio/accel/kionix-kx022a.c line 251

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+static const unsigned int kx022a_odrs[] = { 1282051282, 639795266, 320 * MEGA,
+	 160 * MEGA, 80 * MEGA, 40 * MEGA, 20 * MEGA, 10 * MEGA, 5 * MEGA };

{ and }; on the new line. And I would suggest to group by 4 or 8, that makes it easier to read / count.

...

Quoted 1 line

+#define KX022A_DEFAULT_PERIOD_NS (20 * MEGA)

NSEC_PER_MSEC ?

...

Quoted 11 lines
drivers/iio/accel/kionix-kx022a.c new file +11 -0
+static int __kx022a_turn_on_unlocked(struct kx022a_data *data)
+{
+	int ret;
+
+	ret = regmap_set_bits(data->regmap, KX022A_REG_CNTL, KX022A_MASK_PC1);
+	if (ret)
+		dev_err(data->dev, "Turn ON fail %d\n", ret);
+
+	return ret;
+}
+

drivers/iio/accel/kionix-kx022a.c line 331

Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+static int __kx022a_turn_off_unlocked(struct kx022a_data *data)
+{
+	int ret;
+
+	ret = regmap_clear_bits(data->regmap, KX022A_REG_CNTL, KX022A_MASK_PC1);
+	if (ret)
+		dev_err(data->dev, "Turn OFF fail %d\n", ret);
+
+	return ret;
+}

With making this a single function with a boolean parameter you may utilise

	if (on)
		ret = set
	else
		ret = clear
	if (ret)
		... str_on_off(on)

...

Review

Quoted 2 lines
(quoted diff) +2 -0
+	ret = __kx022a_turn_off_unlocked(data);
+	ret = __kx022a_turn_on_unlocked(data);

Actually having __ and '_unlocked' seems overkill, I would leave one of them.

...

drivers/iio/accel/kionix-kx022a.c line 378

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+		int n = ARRAY_SIZE(kx022a_accel_samp_freq_table);

You may drop {} in each case and have n defined once for all cases.

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+		while (n-- > 0)

while (n--) ? Or why the 0 is ignored?

drivers/iio/accel/kionix-kx022a.c line 384

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+			if (val == kx022a_accel_samp_freq_table[n][0] &&
+			    kx022a_accel_samp_freq_table[n][1] == val2)
+				break;
 
+		if (n < 0) {

How is it even possible with your conditional?

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+			ret = -EINVAL;
+			goto unlock_out;
+		}

...

drivers/iio/accel/kionix-kx022a.c line 423

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	default:
+		ret = -EINVAL;

break; ?

...

drivers/iio/accel/kionix-kx022a.c line 449

Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c new file +8 -0
+static int kx022a_get_axis(struct kx022a_data *data,
+			   struct iio_chan_spec const *chan,
+			   int *val)
+{
+	int ret;
+
+	ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer,
+			       sizeof(s16));

No endianess awareness (sizeof __le16 / __be16) ?

drivers/iio/accel/kionix-kx022a.c line 453

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+	if (ret)
+		return ret;
+
+	*val = data->buffer[0];

Ditto (get_unaligned_be16/le16 / le16/be16_to_cpup()).

Quoted 2 lines
(quoted diff) +2 -0
+	return IIO_VAL_INT;
+}

...

drivers/iio/accel/kionix-kx022a.c line 517

Quoted 9 lines
drivers/iio/accel/kionix-kx022a.c new file +9 -0
+static int kx022a_validate_trigger(struct iio_dev *idev,
+				   struct iio_trigger *trig)
+{
+	struct kx022a_data *data = iio_priv(idev);
+
+	if (data->trig == trig)
+		return 0;
+
+	return -EINVAL;

Usual pattern is to check for error condition first:

	if (... != trig)
		return -E...

	return 0;
Quoted 1 line

+}

...

drivers/iio/accel/kionix-kx022a.c line 525

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	if (val > KX022A_FIFO_LENGTH)
+		val = KX022A_FIFO_LENGTH;

max() from minmax.h?

...

drivers/iio/accel/kionix-kx022a.c line 546

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	return sprintf(buf, "%d\n", state);

Documentation states it must be sysfs_emit().
Ditto for the rest of the similar cases.

drivers/iio/accel/kionix-kx022a.c line 567

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
+		       kx022a_get_fifo_state, NULL, 0);
+static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
+		       kx022a_get_fifo_watermark, NULL, 0);

_ATTR_RO ?

...

drivers/iio/accel/kionix-kx022a.c line 572

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+static const struct attribute *kx022a_fifo_attributes[] = {
+	&iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+	&iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+	NULL,

No comma for terminator entry.

Quoted 1 line

+};

...

drivers/iio/accel/kionix-kx022a.c line 579

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+	/*
+	 * We must clear the old time-stamp to avoid computing the timestamps
+	 * based on samples acquired when buffer was last enabled

Period!

Quoted 1 line
(quoted diff) +1 -0
+	 */

...

drivers/iio/accel/kionix-kx022a.c line 583

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	return regmap_write(data->regmap, KX022A_REG_BUF_CLEAR, 0xff);

GENMASK() ?

...

drivers/iio/accel/kionix-kx022a.c line 599

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	ret = regmap_read(data->regmap, KX022A_REG_BUF_STATUS_1, &fifo_bytes);
+	if (ret < 0) {

Is ' < 0' part consistent with the rest of similar checks?

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+		dev_err(dev, "Error reading buffer status\n");
+		return ret;
+	}

...

drivers/iio/accel/kionix-kx022a.c line 664

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	if (data->old_timestamp) {
+		sample_period = (data->timestamp - data->old_timestamp);

Too many parentheses.

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+		do_div(sample_period, count);
+	} else {
+		sample_period = data->odr_ns;
+	}

...

drivers/iio/accel/kionix-kx022a.c line 729

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+static int kx022a_set_drdy_irq(struct kx022a_data *data, bool en)
+{
+	if (en)
+		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
+				       KX022A_MASK_DRDY);

I would put redundant 'else' here to have them on the same column, but it's pity we don't have regmap_assign_bits() API (or whatever name you can come up with) to hide this kind of code.

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+	return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
+				 KX022A_MASK_DRDY);
+}

...

drivers/iio/accel/kionix-kx022a.c line 796

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+static int kx022a_fifo_enable(struct kx022a_data *data)
+{
+	int ret = 0;

Redundant assignment.

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+	ret = kx022a_turn_off_lock(data);
+	if (ret)
+		return ret;
 
+}

...

drivers/iio/accel/kionix-kx022a.c line 850

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+	if (!g_kx022a_use_buffer) {
+		dev_err(data->dev, "Neither trigger set nor hw-fifo enabled\n");
 
+

No need in blank line in such cases.

Review

Quoted 2 lines
(quoted diff) +2 -0
+		return -EINVAL;
+	}

Maybe you want to place it here instead?

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	return kx022a_fifo_enable(data);

...

drivers/iio/accel/kionix-kx022a.c line 969

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+	/*
+	 * I've seen I2C read failures if we poll too fast after the sensor
+	 * reset. Slight delay gives I2C block the time to recover.
+	 */
+	msleep(1);

msleep(1) is not doing what you think it is. I recommend to use usleep_range() here.

...

drivers/iio/accel/kionix-kx022a.c line 1008

Quoted 11 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+int kx022a_probe_internal(struct device *dev)
+{
+	static const char * const regulator_names[] = {"io-vdd", "vdd"};
+	struct iio_trigger *indio_trig;
+	struct kx022a_data *data;
+	struct regmap *regmap;
+	unsigned int chip_id;
+	struct iio_dev *idev;
+	int ret, irq;
 
+	if (WARN_ON(!dev))

Huh?! This can be easily transformed to panic followed by oops. Why is it necessary to do so?

drivers/iio/accel/kionix-kx022a.c line 1014

Quoted 7 lines
drivers/iio/accel/kionix-kx022a.c new file +6 -0
+		return -ENODEV;
+
+	regmap = dev_get_regmap(dev, NULL);
+	if (!regmap) {
+		dev_err(dev, "no regmap\n");
 
+

No blank line here as it's usual pattern in ->probe().

drivers/iio/accel/kionix-kx022a.c line 1026

Quoted 12 lines
drivers/iio/accel/kionix-kx022a.c new file +12 -0
+		return -EINVAL;
+	}
+
+	idev = devm_iio_device_alloc(dev, sizeof(*data));
+	if (!idev)
+		return -ENOMEM;
+
+	data = iio_priv(idev);
+
+	/*
+	 * VDD is the analog and digital domain voltage supply
+	 * IO_VDD is the digital I/O voltage supply

You know what...

drivers/iio/accel/kionix-kx022a.c line 1036

Quoted 11 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+	 */
+	ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),
+					     regulator_names);
+	if (ret && ret != -ENODEV)
+		return dev_err_probe(dev, ret, "failed to enable regulator\n");
+
+	ret = regmap_read(regmap, KX022A_REG_WHO, &chip_id);
+	if (ret) {
 
+		dev_err_probe(dev, ret, "Failed to access sensor\n");
+		return ret;

If you are going to use that, use in a form of

	return dev_err_probe(...);
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+	}
+
+	if (chip_id != KX022A_ID) {
+		dev_err(dev, "unsupported device 0x%x\n", chip_id);
+		return -EINVAL;

drivers/iio/accel/kionix-kx022a.c line 1051

Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+	}
+
+	irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT1");
+	if (irq > 0) {
+		data->inc_reg = KX022A_REG_INC1;
+		data->ien_reg = KX022A_REG_INC4;
+	} else {
+		irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT2");
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "No suitable IRQ\n");

Missed check for 0.

Quoted 62 lines
drivers/iio/accel/kionix-kx022a.c new file +62 -0
+		data->inc_reg = KX022A_REG_INC5;
+		data->ien_reg = KX022A_REG_INC6;
+	}
+
+	data->regmap = regmap;
+	data->dev = dev;
+	data->irq = irq;
+	data->odr_ns = KX022A_DEFAULT_PERIOD_NS;
+	mutex_init(&data->mutex);
+
+	idev->channels = kx022a_channels;
+	idev->num_channels = ARRAY_SIZE(kx022a_channels);
+	idev->name = "kx022-accel";
+	idev->info = &kx022a_info;
+	idev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
+	idev->available_scan_masks = kx022a_scan_masks;
+
+	/* Read the mounting matrix, if present */
+	ret = iio_read_mount_matrix(dev, &data->orientation);
+	if (ret)
+		return ret;
+
+	/* The sensor must be turned off for configuration */
+	ret = kx022a_turn_off_lock(data);
+	if (ret)
+		return ret;
+
+	ret = kx022a_chip_init(data);
+	if (ret) {
+		mutex_unlock(&data->mutex);
+		return ret;
+	}
+
+	ret = kx022a_turn_on_unlock(data);
+	if (ret)
+		return ret;
+
+	udelay(100);
+	ret = devm_iio_triggered_buffer_setup_ext(dev, idev,
+						  &iio_pollfunc_store_time,
+						  kx022a_trigger_handler,
+						  IIO_BUFFER_DIRECTION_IN,
+						  &kx022a_buffer_ops,
+						  kx022a_fifo_attributes);
+
+	if (ret)
+		return dev_err_probe(data->dev, ret,
+				     "iio_triggered_buffer_setup_ext FAIL %d\n",
+				     ret);
+	indio_trig = devm_iio_trigger_alloc(dev, "%sdata-rdy-dev%d", idev->name,
+					    iio_device_id(idev));
+	if (!indio_trig)
+		return -ENOMEM;
+
+	data->trig = indio_trig;
+
+	indio_trig->ops = &kx022a_trigger_ops;
+	iio_trigger_set_drvdata(indio_trig, data);
+
+	ret = devm_iio_trigger_register(dev, indio_trig);
+	if (ret)
+		return dev_err_probe(data->dev, ret,

drivers/iio/accel/kionix-kx022a.c line 1124

Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+				     "Trigger registration failed\n");
+
+	ret = devm_iio_device_register(data->dev, idev);
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+				     "Unable to register iio device\n");
+
+	ret = devm_request_threaded_irq(data->dev, irq, kx022a_irq_handler,
+					&kx022a_irq_thread_handler,
+					IRQF_ONESHOT, "kx022", idev);

If you have more than one device, all handlers will be marked with the same name, perhaps dev_name() is better to have here?

drivers/iio/accel/kionix-kx022a.c line 1129

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+	if (ret)
+		return dev_err_probe(data->dev, ret, "Could not request IRQ\n");
+
+	return ret;
+}

To me it feels inconsistency to use dev_err_probe() in the cases when it _might_ be a deferred probe and not use it in the cases we it won't be a deferred probe.

...

drivers/iio/accel/kionix-kx022a.c line 1134

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+module_param(g_kx022a_use_buffer, bool, 0);
+MODULE_PARM_DESC(g_kx022a_use_buffer,
+		 "Buffer samples. Use at own risk. Fifo must not overflow");

Why?! We usually do not allow module parameters in the new code.

...

Quoted 1 line

+#include <linux/regmap.h>

Missed bits.h.

You probably wanted to have

struct device;

as well.

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

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 5 lines · Andy Shevchenko
Quoted 4 lines · Matti Vaittinen

KX022A is a 3-axis accelerometer from ROHM/Kionix. The senosr features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

[]

Quoted 6 lines
Quoted 3 lines

+/*
+ * Threshold for deciding our HW fifo is unrecoverably corrupt and should be
+ * cleared

Multi-line comments have to follow English grammar and punctuation, i.e. trailing period.

I disagree. I think that would be a silly rule to enforce.

#18 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 7 lines · Joe Perches
Quoted 5 lines · Andy Shevchenko
Quoted 4 lines · Matti Vaittinen

KX022A is a 3-axis accelerometer from ROHM/Kionix. The senosr features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

[]

Quoted 8 lines
Quoted 6 lines
Quoted 3 lines

+/*
+ * Threshold for deciding our HW fifo is unrecoverably corrupt and should be
+ * cleared

Multi-line comments have to follow English grammar and punctuation, i.e. trailing period.

I disagree. I think that would be a silly rule to enforce.

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#coding-style-notes

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

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

In reply to Joe Perches
Quoted 7 lines · Joe Perches
Quoted 5 lines · Andy Shevchenko
Quoted 4 lines · Matti Vaittinen

KX022A is a 3-axis accelerometer from ROHM/Kionix. The senosr features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

[]

Quoted 8 lines
Quoted 6 lines
Quoted 3 lines

+/*
+ * Threshold for deciding our HW fifo is unrecoverably corrupt and should be
+ * cleared

Multi-line comments have to follow English grammar and punctuation, i.e. trailing period.

I disagree. I think that would be a silly rule to enforce.

First, you have to read that submission and find at least inconsistency between styles used for different multi-line comment blocks.

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

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

In reply to Andy Shevchenko
Quoted 26 lines · On Thu, 6 Oct 2022 21:32:11 +0300 Andy Shevchenko…
Quoted 22 lines · Matti Vaittinen

KX022A is a 3-axis accelerometer from ROHM/Kionix. The senosr features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ).

Important things to be added include the double-tap, motion detection and wake-up as well as the runtime power management.

NOTE: Filling-up the hardware FIFO should be avoided. During my testing I noticed that filling up the hardware FIFO might mess-up the sample count. My sensor ended up in a state where the amount of data in FIFO was reported to be 0xff bytes, which equals to 42,5 samples. Specification says the FIFO can hold a maximum of 41 samples in HiRes mode. Also, at least once the FIFO was stuck in a state where reading data from hardware FIFO did not decrease the amount of data reported to be in the FIFO - eg. FIFO was "stuck". The code has now an error count and 10 reads with invalid FIFO data count will cause the fifo contents to be dropped.

...

...

Quoted 8 lines

...

drivers/iio/accel/kionix-kx022a.c line 1134

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+module_param(g_kx022a_use_buffer, bool, 0);
+MODULE_PARM_DESC(g_kx022a_use_buffer,
+		 "Buffer samples. Use at own risk. Fifo must not overflow");  

Why?! We usually do not allow module parameters in the new code.

Badly broken hardware - was my suggestion. Alternatives if there are usecases that need to use the fifo, but it can wedge hard in a fashion that is impossible to prevent from the driver? My gut feeling is still drop the support entirely with a strong comment in the code that the hardware is broken in a fashion we don't know how to work around.

Jonathan

#21 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 3 lines · Jonathan Cameron
Quoted 1 line · On Thu, 6 Oct 2022 21:32:11 +0300 Andy Shevchenko…

On Thu, Oct 06, 2022 at 05:38:14PM +0300, Matti Vaittinen wrote:

...

Quoted 11 lines
Quoted 5 lines

drivers/iio/accel/kionix-kx022a.c line 1134

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+module_param(g_kx022a_use_buffer, bool, 0);
+MODULE_PARM_DESC(g_kx022a_use_buffer,
+		 "Buffer samples. Use at own risk. Fifo must not overflow");  

Why?! We usually do not allow module parameters in the new code.

Badly broken hardware - was my suggestion. Alternatives if there are usecases that need to use the fifo, but it can wedge hard in a fashion that is impossible to prevent from the driver? My gut feeling is still drop the support entirely with a strong comment in the code that the hardware is broken in a fashion we don't know how to work around.

I also would drop this from upstream and if anybody curious, provide some kind of GitHub gist for that. Also it needs some communication with a vendor to clarify the things.

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

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 13 lines · Andy Shevchenko
Quoted 3 lines · Jonathan Cameron
Quoted 1 line · On Thu, 6 Oct 2022 21:32:11 +0300 Andy Shevchenko…

On Thu, Oct 06, 2022 at 05:38:14PM +0300, Matti Vaittinen wrote:

...

Quoted 6 lines
Quoted 5 lines
Quoted 3 lines
(quoted diff) +2 -0
+module_param(g_kx022a_use_buffer, bool, 0); 
+MODULE_PARM_DESC(g_kx022a_use_buffer, +		 "Buffer samples. Use

at own risk. Fifo must not overflow");

Why?! We usually do not allow module parameters in the new code.

Quoted 6 lines
Quoted 6 lines

Badly broken hardware - was my suggestion. Alternatives if there are usecases that need to use the fifo, but it can wedge hard in a
fashion that is impossible to prevent from the driver? My gut
feeling is still drop the support entirely with a strong comment in the code that the hardware is broken in a fashion we don't know how to work around.

I did some quick study regarding couple of other Kionix sensors. (like KX122 and old KX022 - without the 'A'). It seems to me that the register interfaces between many of the sensors are largely identical. Extending the driver to support those seems pretty straightforward (scales and resolution may need tweaking, as does the FIFO size) but register contents and even offsets are largely identical.

As said, it seems the Kionix sensors may have different size of internal FIFOs, or even no FIFO at all. So, maybe we could provide a "kionix,fifo-enable" flag (or even "kionix,fifo-size") from device-tree? This would be a way to have the FIFO disabled by default and warn users via dt-binding docs if they decide to explicitly enable the FIFO. (Besides, I believe the FIFO is usable on at least some of the Kionix sensors - because I've heard it is used on a few platforms).

This could give us safe defaults while not shutting the doors from those who wish to use the FIFO. Sure we need a buy-in from Krzysztof / Rob, but that may be less of an obstacle compared to the module param if Greg is so strongly oppsoing those. (And the dt-property could also provide some technical merites as these sensors seem to really have differencies in FIFOs).

Quoted 3 lines

I also would drop this from upstream and if anybody curious, provide
some kind of GitHub gist for that.

Well, I think we all agree that downstream code hosted in some unofficial github repositories are rarely that valuable. They're less reliable, less tested, less reviewed, less secure and pretty much impossible to maintain in a way that interested user could get a version matching his preferred kernel.

There are reasons why I (people) keep sending the drivers to upstream - and why some companies even spend $$ for that. Having this feature in downstream repo is not nearly on same page for user's point of view as is having the support upstream.

Quoted 2 lines

Also it needs some communication
with a vendor to clarify the things.

I do communication with the vendor on a daily basis :] Nowadays Kionix is part of ROHM, and Finland SWDC has been collaboration with Kionix even before they "merged" (but I have not been part of the "sensor team" back then).

Unfortunately, reaching the correct people inside the company is hard and occasionally impossible - long story...

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
#23 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 21 lines · Matti
Quoted 13 lines · Andy Shevchenko
Quoted 3 lines · Jonathan Cameron
Quoted 1 line · On Thu, 6 Oct 2022 21:32:11 +0300 Andy Shevchenko…

On Thu, Oct 06, 2022 at 05:38:14PM +0300, Matti Vaittinen wrote:

...

Quoted 6 lines
Quoted 5 lines
Quoted 3 lines
(quoted diff) +2 -0
+module_param(g_kx022a_use_buffer, bool, 0); 
+MODULE_PARM_DESC(g_kx022a_use_buffer, +		 "Buffer samples. Use

at own risk. Fifo must not overflow");

Why?! We usually do not allow module parameters in the new code.

Quoted 6 lines
Quoted 6 lines

Badly broken hardware - was my suggestion. Alternatives if there are usecases that need to use the fifo, but it can wedge hard in a
fashion that is impossible to prevent from the driver? My gut
feeling is still drop the support entirely with a strong comment in the code that the hardware is broken in a fashion we don't know how to work around.

Quoted 6 lines

I did some quick study regarding couple of other Kionix sensors. (like KX122 and old KX022 - without the 'A'). It seems to me that the register interfaces between many of the sensors are largely identical. Extending the driver to support those seems pretty straightforward (scales and resolution may need tweaking, as does the FIFO size) but register contents and even offsets are largely identical.

Last kionix part I had was a kxsd9 and I don't recall that having a fifo so obviously didn't hit this issue.

Quoted 4 lines

As said, it seems the Kionix sensors may have different size of internal FIFOs, or even no FIFO at all. So, maybe we could provide a "kionix,fifo-enable" flag (or even "kionix,fifo-size") from device-tree?

For device where we don't have reports of this issue, that should be derived from the compatible (or even better a whoami register if there is one). The driver should know the fifo-size if it isn't discoverable.

Quoted 11 lines

This would be a way to have the FIFO disabled by default and warn users via dt-binding docs if they decide to explicitly enable the FIFO. (Besides, I believe the FIFO is usable on at least some of the Kionix sensors - because I've heard it is used on a few platforms).

This could give us safe defaults while not shutting the doors from those who wish to use the FIFO. Sure we need a buy-in from Krzysztof / Rob, but that may be less of an obstacle compared to the module param if Greg is so strongly oppsoing those. (And the dt-property could also provide some technical merites as these sensors seem to really have differencies in FIFOs).

I'm dubious about having this for known broken parts - but I guess you can propose it and see what the dt-maintainers say.

I don't want to see fifo size in the dt binding though.

Quoted 11 lines
Quoted 4 lines

I also would drop this from upstream and if anybody curious, provide
some kind of GitHub gist for that.

Well, I think we all agree that downstream code hosted in some unofficial github repositories are rarely that valuable. They're less reliable, less tested, less reviewed, less secure and pretty much impossible to maintain in a way that interested user could get a version matching his preferred kernel.

Quoted 4 lines

There are reasons why I (people) keep sending the drivers to upstream - and why some companies even spend $$ for that. Having this feature in downstream repo is not nearly on same page for user's point of view as is having the support upstream.

It's not really support if it comes with big warnings and potentially we even taint the kernel of someone turns it on...

Quoted 11 lines
Quoted 3 lines

Also it needs some communication
with a vendor to clarify the things.

I do communication with the vendor on a daily basis :] Nowadays Kionix is part of ROHM, and Finland SWDC has been collaboration with Kionix even before they "merged" (but I have not been part of the "sensor team" back then).

Unfortunately, reaching the correct people inside the company is hard and occasionally impossible - long story...

:)

Jonathan

author maintainer
#24 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 7 lines · Jonathan Cameron
Quoted 4 lines · Matti
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Jonathan Cameron

On Thu, 6 Oct 2022 21:32:11 +0300 Andy Shevchenko
<[email protected]> wrote:

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 1 line
Quoted 1 line · Matti Vaittinen

...

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
(quoted diff) +2 -0
+module_param(g_kx022a_use_buffer, bool, 0);
+MODULE_PARM_DESC(g_kx022a_use_buffer, +		 "Buffer samples. Use

at own risk. Fifo must not overflow");

// snip

Quoted 12 lines
Quoted 11 lines

This would be a way to have the FIFO disabled by default and warn users via dt-binding docs if they decide to explicitly enable the FIFO. (Besides, I believe the FIFO is usable on at least some of the Kionix sensors - because I've heard it is used on a few platforms).

This could give us safe defaults while not shutting the doors from those who wish to use the FIFO. Sure we need a buy-in from Krzysztof / Rob, but that may be less of an obstacle compared to the module param if Greg is so strongly oppsoing those. (And the dt-property could also provide some technical merites as these sensors seem to really have differencies in FIFOs).

Quoted 4 lines

I'm dubious about having this for known broken parts - but I guess you can propose it and see what the dt-maintainers say.

I don't want to see fifo size in the dt binding though.

// snip

Quoted 8 lines
Quoted 8 lines
Quoted 2 lines

Also it needs some communication
with a vendor to clarify the things.

I do communication with the vendor on a daily basis :] Nowadays Kionix is part of ROHM, and Finland SWDC has been collaboration with Kionix even before they "merged" (but I have not been part of the "sensor team" back then).

Quoted 4 lines
Quoted 2 lines

Unfortunately, reaching the correct people inside the company is hard and occasionally impossible - long story...

:)

Just a note. I have done some further investigation (further testing combined with tracing the SPI lines) and also got some answer(s) from the ASIC designers. First thing is that the underlying FIFO is 258 bytes and can hold up-to 43 HiRes samples. This is also fixed in the recent data-sheet. The register informing how many bytes of data is stored in FIFO is still only 8bits. When FIFO is full, the magic value 255 is used to indicate the 258 bytes of data. This explains the strange 42,5 samples (255 bytes) of data being reported.

Furthermore, I've noticed that the FIFO appearing to be "stuck", eg. amount of data stored in FIFO not decreasing when data is read is 100% reproducible. The condition is that the PC1 bit (accelerometer state control) is toggled before the FIFO is read. The issue does not seem to be reproducible if the PC1 is not touched. I have also asked if this is a known limitation.

Anyways, it seems we have a solution to the problem. We simply handle the case when 255 bytes is reported correctly (by reading 258 bytes of valid data) - and we prevent changing the sensor configuration when FIFO is enabled.

I will implement these changes to the v3 and drop both the module-param and the dt-property. Sorry for the hassle and thanks for the patience/support!

Yours
-- Matti

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
#25 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 8 lines · Matti Vaittinen
Quoted 7 lines · Jonathan Cameron
Quoted 5 lines · Matti
Quoted 4 lines · Andy Shevchenko
Quoted 3 lines · Jonathan Cameron
Quoted 1 line · On Thu, 6 Oct 2022 21:32:11 +0300 Andy Shevchenko…

On Thu, Oct 06, 2022 at 05:38:14PM +0300, Matti Vaittinen wrote:

...

Quoted 53 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
(quoted diff) +2 -0
+module_param(g_kx022a_use_buffer, bool, 0);
+MODULE_PARM_DESC(g_kx022a_use_buffer, +		 "Buffer samples. Use

at own risk. Fifo must not overflow");

// snip

Quoted 12 lines
Quoted 11 lines

This would be a way to have the FIFO disabled by default and warn users via dt-binding docs if they decide to explicitly enable the FIFO. (Besides, I believe the FIFO is usable on at least some of the Kionix sensors - because I've heard it is used on a few platforms).

This could give us safe defaults while not shutting the doors from those who wish to use the FIFO. Sure we need a buy-in from Krzysztof / Rob, but that may be less of an obstacle compared to the module param if Greg is so strongly oppsoing those. (And the dt-property could also provide some technical merites as these sensors seem to really have differencies in FIFOs).

Quoted 4 lines

I'm dubious about having this for known broken parts - but I guess you can propose it and see what the dt-maintainers say.

I don't want to see fifo size in the dt binding though.

// snip

Quoted 8 lines
Quoted 8 lines
Quoted 2 lines

Also it needs some communication
with a vendor to clarify the things.

I do communication with the vendor on a daily basis :] Nowadays Kionix is part of ROHM, and Finland SWDC has been collaboration with Kionix even before they "merged" (but I have not been part of the "sensor team" back then).

Quoted 4 lines
Quoted 2 lines

Unfortunately, reaching the correct people inside the company is hard and occasionally impossible - long story...

:)

Just a note. I have done some further investigation (further testing combined with tracing the SPI lines) and also got some answer(s) from the ASIC designers. First thing is that the underlying FIFO is 258 bytes and can hold up-to 43 HiRes samples. This is also fixed in the recent data-sheet. The register informing how many bytes of data is stored in FIFO is still only 8bits. When FIFO is full, the magic value 255 is used to indicate the 258 bytes of data. This explains the strange 42,5 samples (255 bytes) of data being reported.

Furthermore, I've noticed that the FIFO appearing to be "stuck", eg. amount of data stored in FIFO not decreasing when data is read is 100% reproducible. The condition is that the PC1 bit (accelerometer state control) is toggled before the FIFO is read. The issue does not seem to be reproducible if the PC1 is not touched. I have also asked if this is a known limitation.

Quoted 7 lines

Anyways, it seems we have a solution to the problem. We simply handle the case when 255 bytes is reported correctly (by reading 258 bytes of valid data) - and we prevent changing the sensor configuration when FIFO is enabled.

I will implement these changes to the v3 and drop both the module-param and the dt-property. Sorry for the hassle and thanks for the patience/support!

This is very good news, Matti, thanks for pushing this forward and finding better solution!

Signature · 2 lines
With Best Regards,
Andy Shevchenko
author maintainer
#26 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

In reply to Andy Shevchenko

Hello Andy,

Thanks for taking the time and doing the review. Quite a few comments I do agree with. I didn't respond to those unless you asked a question :) Thanks for the help! OTOH, as usual, I do not fully agree with everything - and at some places I would like to get some further information :)

Quoted 26 lines · Andy Shevchenko
Quoted 22 lines · Matti Vaittinen

KX022A is a 3-axis accelerometer from ROHM/Kionix. The senosr features include variable ODRs, I2C and SPI control, FIFO/LIFO with watermark IRQ, tap/motion detection, wake-up & back-to-sleep events, four acceleration ranges (2, 4, 8 and 16g) and probably some other cool features.

Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ).

Important things to be added include the double-tap, motion detection and wake-up as well as the runtime power management.

NOTE: Filling-up the hardware FIFO should be avoided. During my testing I noticed that filling up the hardware FIFO might mess-up the sample count. My sensor ended up in a state where the amount of data in FIFO was reported to be 0xff bytes, which equals to 42,5 samples. Specification says the FIFO can hold a maximum of 41 samples in HiRes mode. Also, at least once the FIFO was stuck in a state where reading data from hardware FIFO did not decrease the amount of data reported to be in the FIFO - eg. FIFO was "stuck". The code has now an error count and 10 reads with invalid FIFO data count will cause the fifo contents to be dropped.

...

Quoted 12 lines

drivers/iio/accel/Kconfig config IIO_ST_ACCEL_SPI_3AXIS · line 422

Quoted 8 lines
drivers/iio/accel/Kconfig +8 -0
+config IIO_KX022A_SPI
+	tristate "Kionix KX022A tri-axis digital accelerometer"
+	depends on I2C
+	select IIO_KX022A
+	select REGMAP_SPI
+	help
+	  Say Y here to enable support for the Kionix KX022A digital tri-axis
+	  accelerometer connected to I2C interface.

Why it tending to get user to choose Y? It might increase the footprint of bootable image and on the embedded platforms it may increase the chances to not fit into (flash) ROM.

It may be just my English skills but to me this is really telling that "say Y to enable support for this IC". For me it does not mean that "Say Y even if you don't have this IC". I am really not seeing the problem here, but as I said - maybe it's just my lack of English skills.

Nevertheless, looking at the top of the IIO/accelerometer/KConfg - plenty of the accelerometer driver KConfig entries seem to use similar pattern. I am nevertheless usually willing to break the pattern if it seems like the right thing ;) Can anyone help me to format better description?

Quoted 1 line

Also what will be the module name (see other Kconfig for the pattern)?

Here the pattern is IMHO improved by cutting the useless text. Even the cross-reference from SPI to I2C and I2C to SPI driver which was in v1 is more useful. Module autoloading for SPI should just work. Adding the module name here seems just a silly habit - which I see many people are breaking. If module name is to be needed, then it should be checked from the Makefile and not trusted that Kconfig text stays up-to-date...

If the module name in config text is generally seen useful (which I doubt), then maybe there should be a script that fetches it from the Makefile?

Quoted 10 lines

drivers/iio/accel/Kconfig config IIO_ST_ACCEL_SPI_3AXIS · line 431

Quoted 8 lines
drivers/iio/accel/Kconfig +8 -0
+config IIO_KX022A_I2C
+	tristate "Kionix KX022A tri-axis digital accelerometer"
+	depends on I2C
+	select IIO_KX022A
+	select REGMAP_I2C
+	help
+	  Say Y here to enable support for the Kionix KX022A digital tri-axis
+	  accelerometer connected to I2C interface.

Ditto.

Ditto.

Quoted 9 lines

drivers/iio/accel/kionix-kx022a-spi.c line 18

Quoted 5 lines
drivers/iio/accel/kionix-kx022a-spi.c new file +4 -0
+static int kx022a_spi_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct regmap *regmap;

Interestingly in the I²C driver you have other style (and I prefer SPI one over that). Can you fix I²C driver to follow this style?

I need to respin this anyways, so yes.

Quoted 3 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+	}

Ditto (blank line).

The blank prior function return? I think I have been told to have blanks preceding returns to make returns more obvious - which I kind of understand.

Quoted 10 lines

...

drivers/iio/accel/kionix-kx022a.c line 14

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>

Can this group be placed after units.h (with blank line in between)?

Why? What's wrong with alphabetical order?

Quoted 6 lines

drivers/iio/accel/kionix-kx022a.c line 31

Quoted 3 lines

+ */

drivers/iio/accel/kionix-kx022a.c new file +2 -0
+#define KXO22A_FIFO_ERR_THRESHOLD 10
+#define KX022A_FIFO_LENGTH 41

Why not to use TAB between definitions and values (also for the rest similar cases)?

Because I don't personally see the benefit. I can still do that as I've heard many people prefer the aligned values.

Quoted 9 lines

drivers/iio/accel/kionix-kx022a.c line 35

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+#define KX022A_FIFO_MAX_BYTES (KX022A_FIFO_LENGTH *			\
+			       KX022A_FIFO_SAMPLES_SIZE_BYTES)

Slightly better to read:

#define KX022A_FIFO_MAX_BYTES					\
	(KX022A_FIFO_LENGTH * KX022A_FIFO_SAMPLES_SIZE_BYTES)

Really? Well, I can change this but don't personally see any improvement.

Quoted 13 lines

drivers/iio/accel/kionix-kx022a.c line 146

Quoted 11 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+const struct regmap_config kx022a_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_table = &kx022a_volatile_regs,
+	.rd_table = &kx022a_wo_regs,
+	.wr_table = &kx022a_ro_regs,
+	.rd_noinc_table = &kx022a_nir_regs,
+	.precious_table = &kx022a_precious_regs,
+	.max_register = KX022A_MAX_REGISTER,
+	.cache_type = REGCACHE_RBTREE,

No max register? Have you tried debugfs output?

Can you please explain what you mean by no max register?

Quoted 4 lines
Quoted 2 lines

+struct kx022a_data;

Why?

Leftover from a removed trigger struct. Thanks.

Quoted 10 lines

drivers/iio/accel/kionix-kx022a.c line 156

Quoted 7 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+struct kx022a_data {
+	int irq;
+	int inc_reg;
+	int ien_reg;
 
+	struct regmap *regmap;

Putting this as a first member might improve code by making pointer arithmetics better. Have you checked possibilities with bloat-o-meter?

No. Amount of combinations is just too huge for me to try randomly reordering structs and running bloat-o-meter. Can you please explain me why you think reordering this would have visible impact and if this is something that is universally true or if such an optimization is architecture dependent?

Quoted 10 lines

drivers/iio/accel/kionix-kx022a.c line 162

Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c new file +6 -0
+	struct iio_trigger *trig;
+	bool trigger_enabled;
+
+	struct device *dev;
+	unsigned int g_range;
 
+	struct mutex mutex;

No warning from checkpatch? Every lock should be commented what it is for.

No. I didn't see a warn from checkpatch with v6.0-rc7. And I am glad I didn't. I am not a fan of statements like "always document a lock" or "never use a goto" - because blindly following such "rules" tend to lead silly corner cases. In lock commenting case it is likely to lead copy-pasting comments for locks which are used for trivial protections. And I am definitely not a fan of boilerplate.

Quoted 17 lines
Quoted 14 lines
drivers/iio/accel/kionix-kx022a.c new file +14 -0
+	unsigned int state;
+
+	int64_t timestamp, old_timestamp;
+	unsigned int odr_ns;
+
+	struct iio_mount_matrix orientation;
+	u8 watermark;
+	/* 3 x 16bit accel data + timestamp */
+	s16 buffer[8] __aligned(IIO_DMA_MINALIGN);
+	struct {
+		__le16 channels[3];
+		s64 ts __aligned(8);
+	} scan;
+};

...

Quoted 7 lines
Quoted 5 lines

+/*
+ * The sensor HW can support ODR up to 1600 Hz - which is beyond what most of
+ * Linux CPUs can handle w/o dropping samples. Also, the low power mode is not
+ * available for higher sample rates. Thus the driver only supports 200 Hz and
+ * slower ODRs. Slowest being 0.78 Hz

Please, check the punctuation.

I admit it. Punctuation rules for English grammar are something I never learned. Actually, in the school I was told to just use short sentences because correct punctuation in English is not trivial. I understand that grammatically correct comments are pleasing to the eye for people who really _know_ English. Yet, even the grammatically incorrect comments can provide value for someone wondering why some code is as it is. Thus, I write the comments the best way I can - even though I am sure there are errors at times :)

I actually just tried running the comment through an online English checker. (Just picked first search result, I think it was called "Reverso" or something like that) Result the checker gave me was "No mistakes detected!"

Can you please suggest me a good tool for checking the grammar (or show me the errors - but that won't scale).

Quoted 5 lines
Quoted 2 lines

+ */

...

Quoted 13 lines

drivers/iio/accel/kionix-kx022a.c line 247

Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+static const int kx022a_accel_samp_freq_table[][2] = {
+	[0] = { 0, 780000 },
+	[1] = { 1, 563000 },
+	[2] = { 3, 125000 },
+	[3] = { 6, 250000 },
+	[4] = { 12, 500000 },
+	[5] = { 25, 0 },
+	[6] = { 50, 0 },
+	[7] = { 100, 0 },
+	[8] = { 200, 0 }

What do you need the indices for? They are not defines, so are you expecting to shuffle the entries?

No. Not expecting to suffle. I think I borrowed the construct from another driver. I am not sure if it had defines for indices though. Sounds like you have a problem with this, right? What would you suggest here?

Quoted 10 lines
Quoted 1 line

+};

...

drivers/iio/accel/kionix-kx022a.c line 251

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+static const unsigned int kx022a_odrs[] = { 1282051282, 639795266, 320 * MEGA,
+	 160 * MEGA, 80 * MEGA, 40 * MEGA, 20 * MEGA, 10 * MEGA, 5 * MEGA };

{ and }; on the new line. And I would suggest to group by 4 or 8, that makes it easier to read / count.

Right. I actually think Jonathan asked me to burn the lines and do 1 item / line already during the v1 review. Thanks for pointing this out.

Quoted 5 lines

...

drivers/iio/accel/kionix-kx022a.c line 378

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+		int n = ARRAY_SIZE(kx022a_accel_samp_freq_table);

You may drop {} in each case and have n defined once for all cases.

Could you please explain how? We use different table depending on the case.

Quoted 5 lines

Review

Quoted 3 lines
(quoted diff) +2 -0
+
+		while (n-- > 0)

while (n--) ? Or why the 0 is ignored?

What do you mean by 0 being ignored? I am sorry but I do have difficulties following some of your comments.

Quoted 8 lines

drivers/iio/accel/kionix-kx022a.c line 384

Quoted 6 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+			if (val == kx022a_accel_samp_freq_table[n][0] &&
+			    kx022a_accel_samp_freq_table[n][1] == val2)
+				break;
 
+		if (n < 0) {

How is it even possible with your conditional?

Eh? Why it would not be possible? I don't see any problem with the code. Could you explain me what you mean?

Quoted 17 lines
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+			ret = -EINVAL;
+			goto unlock_out;
+		}

...

drivers/iio/accel/kionix-kx022a.c line 449

Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c new file +8 -0
+static int kx022a_get_axis(struct kx022a_data *data,
+			   struct iio_chan_spec const *chan,
+			   int *val)
+{
+	int ret;
+
+	ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer,
+			       sizeof(s16));

No endianess awareness (sizeof __le16 / __be16) >

Quoted 6 lines

drivers/iio/accel/kionix-kx022a.c line 453

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+	if (ret)
+		return ret;
+
+	*val = data->buffer[0];

Ditto (get_unaligned_be16/le16 / le16/be16_to_cpup()).

I have probably misunderstood something but I don't see why we should use 'endianess awareness' in drivers? I thought the IIO framework code takes care of the endianes conversions based on scan_type so each individual driver does not need to do that. That however has been just my assumption. I will need to check this. Thanks for pointing it out.

Quoted 10 lines

drivers/iio/accel/kionix-kx022a.c line 525

Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+	return IIO_VAL_INT;
+}
 
...
 
+	if (val > KX022A_FIFO_LENGTH)
+		val = KX022A_FIFO_LENGTH;

max() from minmax.h?

Definitely not. We could use min() to squeeze one line but for my personal preference the open-coded limit check is clearer. Can switch to min() if this is a subsystem standard though.

Quoted 7 lines

...

drivers/iio/accel/kionix-kx022a.c line 579

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+	/*
+	 * We must clear the old time-stamp to avoid computing the timestamps
+	 * based on samples acquired when buffer was last enabled

Period!

Is the use of exclamation mark is really justified? It makes your suggestion feel slightly rude.

Quoted 8 lines
Quoted 2 lines
(quoted diff) +1 -0
+	 */

...

drivers/iio/accel/kionix-kx022a.c line 583

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	return regmap_write(data->regmap, KX022A_REG_BUF_CLEAR, 0xff);

GENMASK() ?

I don't really see a need for GENMASK here. It does not matter what is written to this register.

Quoted 11 lines

...

drivers/iio/accel/kionix-kx022a.c line 729

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+static int kx022a_set_drdy_irq(struct kx022a_data *data, bool en)
+{
+	if (en)
+		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
+				       KX022A_MASK_DRDY);

I would put redundant 'else' here to have them on the same column, but it's pity we don't have regmap_assign_bits() API (or whatever name you can come up with) to hide this kind of code.

Eh, you mean you would put else here even though we return from the if? And then put another return in else, and no return outside the if/else?

I definitely don't like the idea.

We could probably use regmap_update_bits and ternary but in my opinion that would be just much less obvious. I do like the use of set/clear bits which also makes the meaning / "polarity" of bits really clear.

Quoted 10 lines
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+	return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
+				 KX022A_MASK_DRDY);
+}

...

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	if (!g_kx022a_use_buffer) {
+		dev_err(data->dev, "Neither trigger set nor hw-fifo enabled\n");
Quoted 9 lines
Quoted 1 line

+

No need in blank line in such cases.

Review

Quoted 2 lines
(quoted diff) +2 -0
+		return -EINVAL;
+	}

Maybe you want to place it here instead?

Yes.

Quoted 4 lines
Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	return kx022a_fifo_enable(data);

...

Quoted 8 lines

drivers/iio/accel/kionix-kx022a.c line 969

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+	/*
+	 * I've seen I2C read failures if we poll too fast after the sensor
+	 * reset. Slight delay gives I2C block the time to recover.
+	 */
+	msleep(1);

msleep(1) is not doing what you think it is. I recommend to use usleep_range() here.

I think msleep(1) is sleeping 1ms or (likely) quite a bit more. It also allows other things to be scheduled meanwhile and does not do any (in this case) unnecessary real-time (like) constrains. Could you please educate me as to which part I got wrong? And no, I don't really care if the probe is resumed only after 1, 10, 20 or 40ms assuming the CPU has other things to do. (I don't think forcing this to be continued within hard time limit would be beneficial)

Quoted 13 lines

...

Quoted 9 lines
drivers/iio/accel/kionix-kx022a.c new file +9 -0
+int kx022a_probe_internal(struct device *dev)
+{
+	static const char * const regulator_names[] = {"io-vdd", "vdd"};
+	struct iio_trigger *indio_trig;
+	struct kx022a_data *data;
+	struct regmap *regmap;
+	unsigned int chip_id;
+	struct iio_dev *idev;
+	int ret, irq;
Quoted 4 lines

drivers/iio/accel/kionix-kx022a.c line 1008

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	if (WARN_ON(!dev))

Huh?! This can be easily transformed to panic followed by oops. Why is it necessary to do so?

Because the call to this probe is only issued from I2C / SPI wrappers which are part of the same driver. I think missing a dev here means error in this driver - and it should be caught immediately. I don't think this should ever happen unless one developing this driver makes an error.

Well, if there are doubts I can remove this though.

Quoted 18 lines
Quoted 6 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+		return -ENODEV;
 
+	if (chip_id != KX022A_ID) {
+		dev_err(dev, "unsupported device 0x%x\n", chip_id);
+		return -EINVAL;

drivers/iio/accel/kionix-kx022a.c line 1051

Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c new file +10 -0
+	}
+
+	irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT1");
+	if (irq > 0) {
+		data->inc_reg = KX022A_REG_INC1;
+		data->ien_reg = KX022A_REG_INC4;
+	} else {
+		irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT2");
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "No suitable IRQ\n");

Missed check for 0.

Why check for 0? fwnode_irq_get_byname() doc states:
* Return:
* Linux IRQ number on success, or negative errno otherwise.

I don't see 0 indicating a failure?

Quoted 5 lines

To me it feels inconsistency to use dev_err_probe() in the cases when it _might_ be a deferred probe and not use it in the cases we it won't be a deferred probe.

I think we discussed this already. To me it feels better to have inconsistency for hard-coded return values than use dev_err_probe. At times using the "consistency" as a rationale for things feels like excusing the infamous "when you're used to use a hammer as solution, all problems start looking like nails" approach...

Quoted 6 lines

drivers/iio/accel/kionix-kx022a.c line 1134

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+module_param(g_kx022a_use_buffer, bool, 0);
+MODULE_PARM_DESC(g_kx022a_use_buffer,
+		 "Buffer samples. Use at own risk. Fifo must not overflow");

Why?! We usually do not allow module parameters in the new code.

There are still quite a few parameters that have been added during previous cycle. And many of those are to allow behaviour which is undesirable in many cases for those who can benefit from it.

3dbec44d9c94 ("KVM: VMX: Reject kvm_intel if an inconsistent VMCS config is detected")

can serve as a random example.

As explained by the comment:
/*
* Filling up the HW-FIFO can cause nasty problems. Thus we do not
* enable the fifo unless it is explicitly requested by a module param.
* If you are _sure_ your system can serve the interrupts in time you
* can enable the HW fifo. I do not recommend it for sample frequencies
* higher than 2 Hz - and even in that case I would set the watermark
* somewhere near 20 samples (HI-RES) to have magnitude of 10 sec
* safety-margin.
*/

this is also the use-case here.

And yes, using the FIFO regardless of the problems can be beneficial so just dropping the support completely would be counter-productive. I agree with Jonathan that disabling the FIFO by default does probably help avoiding bug reports - but allowing enabling the FIFO with own risk is just giving a hand to those who need it. Thus I'd really like to see the support upstream. We all know that code which is sitting in some downstream git is not likely to help people - and it is the reason why I do upstream code in first place.

Yours
-- Matti

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
#27 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 9 lines · Matti Vaittinen

Hello Andy,

Thanks for taking the time and doing the review. Quite a few comments I do agree with. I didn't respond to those unless you asked a question :) Thanks for the help! OTOH, as usual, I do not fully agree with everything - and at some places I would like to get some further information :)

Quoted 1 line · Andy Shevchenko

On Thu, Oct 06, 2022 at 05:38:14PM +0300, Matti Vaittinen wrote:

...

Quoted 18 lines
Quoted 4 lines
Quoted 4 lines
drivers/iio/accel/Kconfig +4 -0
+config IIO_KX022A_SPI
+	tristate "Kionix KX022A tri-axis digital accelerometer"
+	depends on I2C
+	select IIO_KX022A
Quoted 8 lines

drivers/iio/accel/Kconfig config IIO_ST_ACCEL_SPI_3AXIS · line 422

Quoted 4 lines
drivers/iio/accel/Kconfig +4 -0
+	select REGMAP_SPI
+	help
+	  Say Y here to enable support for the Kionix KX022A digital tri-axis
+	  accelerometer connected to I2C interface.

Why it tending to get user to choose Y? It might increase the footprint of bootable image and on the embedded platforms it may increase the chances to not fit into (flash) ROM.

It may be just my English skills but to me this is really telling that "say Y to enable support for this IC". For me it does not mean that "Say Y even if you don't have this IC". I am really not seeing the problem here, but as I said - maybe it's just my lack of English skills.

Quoted 4 lines

Nevertheless, looking at the top of the IIO/accelerometer/KConfg - plenty of the accelerometer driver KConfig entries seem to use similar pattern. I am nevertheless usually willing to break the pattern if it seems like the right thing ;) Can anyone help me to format better description?

Oh, I didn't know that the rest is also using this pattern. My main objection here is Y vs. M and maybe less insisting tone of the language (it doesn't tell anything like "if you have the sensor".

I leave this to native speaker(s) to propose something here, because for me English is not the one.

Quoted 8 lines
Quoted 1 line

Also what will be the module name (see other Kconfig for the pattern)?

Here the pattern is IMHO improved by cutting the useless text. Even the cross-reference from SPI to I2C and I2C to SPI driver which was in v1 is more useful. Module autoloading for SPI should just work. Adding the module name here seems just a silly habit - which I see many people are breaking. If module name is to be needed, then it should be checked from the Makefile and not trusted that Kconfig text stays up-to-date...

I think the module name is a good thing to have for a user who might be not knowing about Makefile:s and how to derive the module name from that (sometimes it's not so obvious).

Quoted 2 lines

If the module name in config text is generally seen useful (which I doubt), then maybe there should be a script that fetches it from the Makefile?

No idea about this, if it's even possible.

...

Quoted 10 lines
Quoted 1 line

Can you fix I²C driver to follow this style?

I need to respin this anyways, so yes.

Quoted 3 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+	}

Ditto (blank line).

The blank prior function return? I think I have been told to have blanks preceding returns to make returns more obvious - which I kind of understand.

Yes, _adding_ blank line (see what I referred to? To SPI driver as a good example).

...

Quoted 9 lines
Quoted 7 lines

drivers/iio/accel/kionix-kx022a.c line 14

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>

Can this group be placed after units.h (with blank line in between)?

Why? What's wrong with alphabetical order?

Nothing wrong with the order and order is orthogonal to the grouping. My comment is for the latter. The rationale is to easily see generic header group and subsystem related group.

...

Quoted 8 lines
Quoted 5 lines

drivers/iio/accel/kionix-kx022a.c line 31

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+#define KXO22A_FIFO_ERR_THRESHOLD 10
+#define KX022A_FIFO_LENGTH 41

Why not to use TAB between definitions and values (also for the rest similar cases)?

Because I don't personally see the benefit. I can still do that as I've heard many people prefer the aligned values.

For me it's hard to read when they are not on the same column, that's the benefit I see.

...

Quoted 10 lines
Quoted 8 lines

drivers/iio/accel/kionix-kx022a.c line 35

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+#define KX022A_FIFO_MAX_BYTES (KX022A_FIFO_LENGTH *			\
+			       KX022A_FIFO_SAMPLES_SIZE_BYTES)

Slightly better to read:

#define KX022A_FIFO_MAX_BYTES					\
	(KX022A_FIFO_LENGTH * KX022A_FIFO_SAMPLES_SIZE_BYTES)

Really?

Really.

Quoted 1 line

Well, I can change this but don't personally see any improvement.

...

Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+const struct regmap_config kx022a_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_table = &kx022a_volatile_regs,
Quoted 8 lines

drivers/iio/accel/kionix-kx022a.c line 146

Quoted 6 lines
drivers/iio/accel/kionix-kx022a.c new file +6 -0
+	.rd_table = &kx022a_wo_regs,
+	.wr_table = &kx022a_ro_regs,
+	.rd_noinc_table = &kx022a_nir_regs,
+	.precious_table = &kx022a_precious_regs,
+	.max_register = KX022A_MAX_REGISTER,
+	.cache_type = REGCACHE_RBTREE,

No max register? Have you tried debugfs output?

Quoted 1 line

Can you please explain what you mean by no max register?

There is a field which name I don't remember by heart limits the register range. This, in particular is visible when one tries to dump the registers via debugfs.

But I see that it is there, I simply missed it.

...

Quoted 10 lines
Quoted 9 lines

drivers/iio/accel/kionix-kx022a.c line 156

Quoted 6 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+struct kx022a_data {
+	int irq;
+	int inc_reg;
+	int ien_reg;
 
+	struct regmap *regmap;

Putting this as a first member might improve code by making pointer arithmetics better. Have you checked possibilities with bloat-o-meter?

Quoted 5 lines

No. Amount of combinations is just too huge for me to try randomly reordering structs and running bloat-o-meter. Can you please explain me why you think reordering this would have visible impact and if this is something that is universally true or if such an optimization is architecture dependent?

Usually regmap pointer is used more often than, for instance, the 'irq' member, and I believe that moving 'irq' member deeper will be harmless, while moving regmap might be winning.

Quoted 10 lines
Quoted 9 lines

drivers/iio/accel/kionix-kx022a.c line 162

Quoted 7 lines
drivers/iio/accel/kionix-kx022a.c new file +6 -0
+	struct iio_trigger *trig;
+	bool trigger_enabled;
+
+	struct device *dev;
+	unsigned int g_range;
 
+	struct mutex mutex;

No warning from checkpatch? Every lock should be commented what it is for.

Quoted 6 lines

No. I didn't see a warn from checkpatch with v6.0-rc7. And I am glad I didn't. I am not a fan of statements like "always document a lock" or "never use a goto" - because blindly following such "rules" tend to lead silly corner cases. In lock commenting case it is likely to lead copy-pasting comments for locks which are used for trivial protections. And I am definitely not a fan of boilerplate.

So, tell then, what is this lock for? How as a code reader I have to know that?

Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
drivers/iio/accel/kionix-kx022a.c new file +14 -0
+	unsigned int state;
+
+	int64_t timestamp, old_timestamp;
+	unsigned int odr_ns;
+
+	struct iio_mount_matrix orientation;
+	u8 watermark;
+	/* 3 x 16bit accel data + timestamp */
+	s16 buffer[8] __aligned(IIO_DMA_MINALIGN);
+	struct {
+		__le16 channels[3];
+		s64 ts __aligned(8);
+	} scan;
+};

...

Quoted 16 lines
Quoted 6 lines
Quoted 4 lines

+ * The sensor HW can support ODR up to 1600 Hz - which is beyond what most of
+ * Linux CPUs can handle w/o dropping samples. Also, the low power mode is not
+ * available for higher sample rates. Thus the driver only supports 200 Hz and
+ * slower ODRs. Slowest being 0.78 Hz

Please, check the punctuation.

I admit it. Punctuation rules for English grammar are something I never learned. Actually, in the school I was told to just use short sentences because correct punctuation in English is not trivial. I understand that grammatically correct comments are pleasing to the eye for people who really _know_ English. Yet, even the grammatically incorrect comments can provide value for someone wondering why some code is as it is. Thus, I write the comments the best way I can - even though I am sure there are errors at times :)

Quoted 6 lines

I actually just tried running the comment through an online English checker. (Just picked first search result, I think it was called "Reverso" or something like that) Result the checker gave me was "No mistakes detected!"

Can you please suggest me a good tool for checking the grammar (or show me the errors - but that won't scale).

My eyes caught the missed period at the end of the comment (easy to catch), other than that I use these rules:
- Oxford comma;
- commas for the subsentences that do not affect the meaning of the main one if they were dropped.

Rarely I use tools for punctuation as I agree it's not obvious in English.

...

Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+static const int kx022a_accel_samp_freq_table[][2] = {
+	[0] = { 0, 780000 },
+	[1] = { 1, 563000 },
+	[2] = { 3, 125000 },
+	[3] = { 6, 250000 },
Quoted 8 lines

drivers/iio/accel/kionix-kx022a.c line 247

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+	[4] = { 12, 500000 },
+	[5] = { 25, 0 },
+	[6] = { 50, 0 },
+	[7] = { 100, 0 },
+	[8] = { 200, 0 }

What do you need the indices for? They are not defines, so are you expecting to shuffle the entries?

Quoted 3 lines

No. Not expecting to suffle. I think I borrowed the construct from another driver. I am not sure if it had defines for indices though. Sounds like you have a problem with this, right? What would you suggest here?

Drop the indices and add a comma to the last entry (#8 according to your indices). Similar to the rest of the similar cases.

Quoted 1 line
Quoted 1 line
Quoted 1 line

+};

...

Quoted 5 lines
Quoted 3 lines

drivers/iio/accel/kionix-kx022a.c line 378

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+		int n = ARRAY_SIZE(kx022a_accel_samp_freq_table);

You may drop {} in each case and have n defined once for all cases.

Could you please explain how? We use different table depending on the case.

	{
		int n;

		switch (x) {
		case Y:
			n = ARRAY_SIZE(foo);
			...
			break
		case Z:
			n = ARRAY_SIZE(bar);
			...
		}
	}
Quoted 7 lines
Quoted 4 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+		while (n-- > 0)

while (n--) ? Or why the 0 is ignored?

What do you mean by 0 being ignored? I am sorry but I do have difficulties following some of your comments.

Your while loop stops when n == 0. The 0 is not going inside while-loop body...

Quoted 10 lines
Quoted 7 lines

drivers/iio/accel/kionix-kx022a.c line 384

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+			if (val == kx022a_accel_samp_freq_table[n][0] &&
+			    kx022a_accel_samp_freq_table[n][1] == val2)
+				break;
 
+		if (n < 0) {

How is it even possible with your conditional?

Eh? Why it would not be possible? I don't see any problem with the code. Could you explain me what you mean?

...and as a side effect, this condition won't be ever true. Did I miss something?

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+			ret = -EINVAL;
+			goto unlock_out;
+		}

...

Quoted 12 lines
Quoted 11 lines

drivers/iio/accel/kionix-kx022a.c line 449

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer,
+			       sizeof(s16));

No endianess awareness (sizeof __le16 / __be16)

drivers/iio/accel/kionix-kx022a.c line 453

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+	if (ret)
+		return ret;
+
+	*val = data->buffer[0];

Ditto (get_unaligned_be16/le16 / le16/be16_to_cpup()).

Quoted 5 lines

I have probably misunderstood something but I don't see why we should use 'endianess awareness' in drivers? I thought the IIO framework code takes care of the endianes conversions based on scan_type so each individual driver does not need to do that. That however has been just my assumption. I will need to check this. Thanks for pointing it out.

The IIO core uses endianness field only once in iio_show_fixed_type() AFAICS. And it does nothing with it. Maybe Jonathan can shed a light what is it for (I mean the field)?

...

Quoted 8 lines
Quoted 4 lines

drivers/iio/accel/kionix-kx022a.c line 525

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	if (val > KX022A_FIFO_LENGTH)
+		val = KX022A_FIFO_LENGTH;

max() from minmax.h?

Definitely not. We could use min() to squeeze one line but for my personal preference the open-coded limit check is clearer. Can switch to min() if this is a subsystem standard though.

Not sure how min() here would check for >. Are you sure you haven't forgotten to tell me something more?

...

Quoted 6 lines
Quoted 3 lines

drivers/iio/accel/kionix-kx022a.c line 583

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	return regmap_write(data->regmap, KX022A_REG_BUF_CLEAR, 0xff);

GENMASK() ?

I don't really see a need for GENMASK here. It does not matter what is written to this register.

Why not 0? At least it will be aligned to the _CLEAR part without need of any comment. Otherwise it sounds like 0xff is special here.

...

Quoted 8 lines
Quoted 7 lines

drivers/iio/accel/kionix-kx022a.c line 729

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+	if (en)
+		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
+				       KX022A_MASK_DRDY);

I would put redundant 'else' here to have them on the same column, but it's pity we don't have regmap_assign_bits() API (or whatever name you can come up with) to hide this kind of code.

Quoted 8 lines

Eh, you mean you would put else here even though we return from the if? And then put another return in else, and no return outside the if/else?

I definitely don't like the idea.

We could probably use regmap_update_bits and ternary but in my opinion that would be just much less obvious. I do like the use of set/clear bits which also makes the meaning / "polarity" of bits really clear.

The idea behind is simple (and note that I'm usually on the side of _removing_ redundancy)

	if (en)
		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
				       KX022A_MASK_DRDY);
	else
		return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
					 ...

Because the branches are semantically tighten to each other. But it's not a big deal to me.

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
+				 KX022A_MASK_DRDY);

...

Quoted 11 lines
Quoted 4 lines

drivers/iio/accel/kionix-kx022a.c line 1008

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	if (WARN_ON(!dev))

Huh?! This can be easily transformed to panic followed by oops. Why is it necessary to do so?

Because the call to this probe is only issued from I2C / SPI wrappers which are part of the same driver. I think missing a dev here means error in this driver - and it should be caught immediately. I don't think this should ever happen unless one developing this driver makes an error.

Well, if there are doubts I can remove this though.

I guess simple removal is right thing to do in this case.

Quoted 1 line
Quoted 1 line
Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+		return -ENODEV;

...

Quoted 11 lines
Quoted 10 lines

drivers/iio/accel/kionix-kx022a.c line 1051

Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c new file +8 -0
+	irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT1");
+	if (irq > 0) {
+		data->inc_reg = KX022A_REG_INC1;
+		data->ien_reg = KX022A_REG_INC4;
+	} else {
+		irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT2");
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "No suitable IRQ\n");

Missed check for 0.

Quoted 5 lines

Why check for 0? fwnode_irq_get_byname() doc states:
* Return:
* Linux IRQ number on success, or negative errno otherwise.

I don't see 0 indicating a failure?

It's a mislead by documentation. You need to read the fwnode_irq_get() to see what's going on. Feel free to submit a fix for the fwnode_irq_get_byname() kernel doc.

...

Quoted 9 lines
Quoted 3 lines

To me it feels inconsistency to use dev_err_probe() in the cases when it _might_ be a deferred probe and not use it in the cases we it won't be a deferred probe.

I think we discussed this already. To me it feels better to have inconsistency for hard-coded return values than use dev_err_probe. At times using the "consistency" as a rationale for things feels like excusing the infamous "when you're used to use a hammer as solution, all problems start looking like nails" approach...

Yes, just shading my opinion once again.

...

Quoted 6 lines
Quoted 5 lines

drivers/iio/accel/kionix-kx022a.c line 1134

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+module_param(g_kx022a_use_buffer, bool, 0);
+MODULE_PARM_DESC(g_kx022a_use_buffer,
+		 "Buffer samples. Use at own risk. Fifo must not overflow");

Why?! We usually do not allow module parameters in the new code.

Quoted 8 lines

There are still quite a few parameters that have been added during previous cycle. And many of those are to allow behaviour which is undesirable in many cases for those who can benefit from it.

3dbec44d9c94 ("KVM: VMX: Reject kvm_intel if an inconsistent VMCS config is detected")

can serve as a random example.

KVM is quite different by nature to an arbitrary driver of an arbitrary sensor that might appear in the real hardware at hand on 1:100 ratio basis.

Quoted 13 lines

As explained by the comment:
/*
* Filling up the HW-FIFO can cause nasty problems. Thus we do not
* enable the fifo unless it is explicitly requested by a module param.
* If you are _sure_ your system can serve the interrupts in time you
* can enable the HW fifo. I do not recommend it for sample frequencies
* higher than 2 Hz - and even in that case I would set the watermark
* somewhere near 20 samples (HI-RES) to have magnitude of 10 sec
* safety-margin.
*/

this is also the use-case here.

Quoted 7 lines

And yes, using the FIFO regardless of the problems can be beneficial so just dropping the support completely would be counter-productive. I agree with Jonathan that disabling the FIFO by default does probably help avoiding bug reports - but allowing enabling the FIFO with own risk is just giving a hand to those who need it. Thus I'd really like to see the support upstream. We all know that code which is sitting in some downstream git is not likely to help people - and it is the reason why I do upstream code in first place.

I would suggest to split the part that adds parameter (with whatever it does elsewhere) from the basic configuration. In this case the commit message should at least clarify the needs of the parameter.

JFYI: It's Greg KH strong opinion about parameters and I agree with him on that. Note that this subsystem goes via on of the Greg's trees.

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

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 23 lines · Andy Shevchenko
Quoted 9 lines · Matti Vaittinen

Hello Andy,

Thanks for taking the time and doing the review. Quite a few comments I do agree with. I didn't respond to those unless you asked a question :) Thanks for the help! OTOH, as usual, I do not fully agree with everything - and at some places I would like to get some further information :)

Quoted 1 line · Andy Shevchenko

On Thu, Oct 06, 2022 at 05:38:14PM +0300, Matti Vaittinen wrote:

...

Quoted 9 lines
Quoted 9 lines

drivers/iio/accel/Kconfig config IIO_ST_ACCEL_SPI_3AXIS · line 422

Quoted 8 lines
drivers/iio/accel/Kconfig +8 -0
+config IIO_KX022A_SPI
+	tristate "Kionix KX022A tri-axis digital accelerometer"
+	depends on I2C
+	select IIO_KX022A
+	select REGMAP_SPI
+	help
+	  Say Y here to enable support for the Kionix KX022A digital tri-axis
+	  accelerometer connected to I2C interface.
Quoted 2 lines

Oh, I didn't know that the rest is also using this pattern. My main objection here is Y vs. M and maybe less insisting tone of the language

Ah. I didn't notice how this emphasizes Y over M. Now I think I understand your note. Thanks for the explanation.

Quoted 9 lines
Quoted 8 lines
Quoted 1 line

Also what will be the module name (see other Kconfig for the pattern)?

Here the pattern is IMHO improved by cutting the useless text. Even the cross-reference from SPI to I2C and I2C to SPI driver which was in v1 is more useful. Module autoloading for SPI should just work. Adding the module name here seems just a silly habit - which I see many people are breaking. If module name is to be needed, then it should be checked from the Makefile and not trusted that Kconfig text stays up-to-date...

Quoted 3 lines

I think the module name is a good thing to have for a user who might be not knowing about Makefile:s and how to derive the module name from that (sometimes it's not so obvious).

My point is that average users do not really even need to know the module names. For most simple drivers the module name is just the base of the filename. I really doubt there are that many people who

a) do need to know module name
b) read config menu entries but don't know how to find a module name from Makefile
c) want to know module name and can't pair the name from lsmod to module
d) rather look up the config entry than browse the contents of lib/modules/...

It'd be nice to know if anyone reading this mail has actually ever used the module name information placed in Kconfig entry for _anything else_ except for making the Kconfig entry to look a bit more fatty...

Quoted 6 lines
Quoted 3 lines

The blank prior function return? I think I have been told to have blanks preceding returns to make returns more obvious - which I kind of understand.

Yes, _adding_ blank line (see what I referred to? To SPI driver as a good example).

Ah. Thanks. I misunderstood your comment.

Quoted 10 lines

...

Quoted 8 lines
Quoted 7 lines

drivers/iio/accel/kionix-kx022a.c line 14

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>

Can this group be placed after units.h (with blank line in between)?

Quoted 5 lines
Quoted 1 line

Why? What's wrong with alphabetical order?

Nothing wrong with the order and order is orthogonal to the grouping. My comment is for the latter. The rationale is to easily see generic header group and subsystem related group.

I can for sure change this but It'd be nice to know why should the subsystem headers be treated differently from the rest of the headers?

Quoted 2 lines

But I see that it is there, I simply missed it.

Ok.

Quoted 18 lines

...

Quoted 10 lines
Quoted 9 lines

drivers/iio/accel/kionix-kx022a.c line 156

Quoted 6 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+struct kx022a_data {
+	int irq;
+	int inc_reg;
+	int ien_reg;
 
+	struct regmap *regmap;

Putting this as a first member might improve code by making pointer arithmetics better. Have you checked possibilities with bloat-o-meter?

Quoted 5 lines

No. Amount of combinations is just too huge for me to try randomly reordering structs and running bloat-o-meter. Can you please explain me why you think reordering this would have visible impact and if this is something that is universally true or if such an optimization is architecture dependent?

Quoted 3 lines

Usually regmap pointer is used more often than, for instance, the 'irq' member, and I believe that moving 'irq' member deeper will be harmless, while moving regmap might be winning.

So you suggest us to try optimizing the code by placing a pointer to more frequently used member(s) at the top of the struct? I didn't know it would have any impact. I understand arranging the members of frequently copied structs based on sizes so that we can avoid eating space by padding - but I had never heard of things being improved by ordering based on frequency of use. It'd be great to understand the mechanism this optimization is based on?

Quoted 11 lines
Quoted 11 lines
Quoted 10 lines

drivers/iio/accel/kionix-kx022a.c line 162

Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c new file +6 -0
+	struct iio_trigger *trig;
+	bool trigger_enabled;
+
+	struct device *dev;
+	unsigned int g_range;
 
+	struct mutex mutex;

No warning from checkpatch? Every lock should be commented what it is for.

Quoted 8 lines
Quoted 6 lines

No. I didn't see a warn from checkpatch with v6.0-rc7. And I am glad I didn't. I am not a fan of statements like "always document a lock" or "never use a goto" - because blindly following such "rules" tend to lead silly corner cases. In lock commenting case it is likely to lead copy-pasting comments for locks which are used for trivial protections. And I am definitely not a fan of boilerplate.

So, tell then, what is this lock for? How as a code reader I have to know that?

I can add comment to this lock as it does protect more than one thing (and may not be trivial). But I am not at all sure requiring all locks to be documented will have optimal end-result... And no, I don't think checkpatch in v6.0-rc7 did warn about this lock. Do you think checkpatch has been modified to do that?

Quoted 8 lines

...

Quoted 5 lines
Quoted 3 lines

drivers/iio/accel/kionix-kx022a.c line 378

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+		int n = ARRAY_SIZE(kx022a_accel_samp_freq_table);

You may drop {} in each case and have n defined once for all cases.

Could you please explain how? We use different table depending on the case.

Quoted 13 lines
	{
		int n;

		switch (x) {
		case Y:
			n = ARRAY_SIZE(foo);
			...
			break
		case Z:
			n = ARRAY_SIZE(bar);
			...
		}
	}

Ah, sure. I feel a bit stupid :) But thanks for the example!

Quoted 10 lines
Quoted 8 lines
Quoted 5 lines

Review

Quoted 3 lines
(quoted diff) +2 -0
+
+		while (n-- > 0)

while (n--) ? Or why the 0 is ignored?

What do you mean by 0 being ignored? I am sorry but I do have difficulties following some of your comments.

Your while loop stops when n == 0. The 0 is not going inside while-loop body...

I think you are making a mistake here.

Quoted 8 lines
Quoted 8 lines
Quoted 7 lines

drivers/iio/accel/kionix-kx022a.c line 384

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+			if (val == kx022a_accel_samp_freq_table[n][0] &&
+			    kx022a_accel_samp_freq_table[n][1] == val2)
+				break;
 
+		if (n < 0) {

How is it even possible with your conditional?

Quoted 6 lines
Quoted 2 lines

Eh? Why it would not be possible? I don't see any problem with the code. Could you explain me what you mean?

...and as a side effect, this condition won't be ever true. Did I miss something?

Please try running:
#include <stdio.h>

int main()

{
	int n = 2;

	while (n-- > 0)
		printf("in loop n = %d\n", n);

	printf("exit loop n = %d\n", n);

	return 0;
}
Quoted 36 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+			ret = -EINVAL;
+			goto unlock_out;
+		}

...

Quoted 12 lines
Quoted 11 lines

drivers/iio/accel/kionix-kx022a.c line 449

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer,
+			       sizeof(s16));

No endianess awareness (sizeof __le16 / __be16)

drivers/iio/accel/kionix-kx022a.c line 453

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+	if (ret)
+		return ret;
+
+	*val = data->buffer[0];

Ditto (get_unaligned_be16/le16 / le16/be16_to_cpup()).

Quoted 5 lines

I have probably misunderstood something but I don't see why we should use 'endianess awareness' in drivers? I thought the IIO framework code takes care of the endianes conversions based on scan_type so each individual driver does not need to do that. That however has been just my assumption. I will need to check this. Thanks for pointing it out.

The IIO core uses endianness field only once in iio_show_fixed_type() AFAICS. And it does nothing with it. Maybe Jonathan can shed a light what is it for (I mean the field)?

...

Quoted 5 lines
Quoted 4 lines

drivers/iio/accel/kionix-kx022a.c line 525

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	if (val > KX022A_FIFO_LENGTH)
+		val = KX022A_FIFO_LENGTH;

max() from minmax.h?

Quoted 7 lines
Quoted 3 lines

Definitely not. We could use min() to squeeze one line but for my personal preference the open-coded limit check is clearer. Can switch to min() if this is a subsystem standard though.

Not sure how min() here would check for >. Are you sure you haven't forgotten to tell me something more?

Please bear with me if I am wrong here. I have spent the weekend wandering in the forest and I am tired as ....

Anyways, my pretty dizzy brains are telling me that we want to use the val if it is smaller than the KX022A_FIFO_LENGTH. If val is greater, then we use the KX022A_FIFO_LENGTH. This should match with the

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

drivers/iio/accel/kionix-kx022a.c line 525

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	if (val > KX022A_FIFO_LENGTH)
+		val = KX022A_FIFO_LENGTH;

Eg, we always want to use the smaller of the two, right? Hence:

val = min(val, KX022A_FIFO_LENGTH);

would do the same job, right? But for me the open-coded check if val exceeds the FIFO_LENGTH looks more obvious.

Quoted 11 lines

...

Quoted 6 lines
Quoted 3 lines

drivers/iio/accel/kionix-kx022a.c line 583

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	return regmap_write(data->regmap, KX022A_REG_BUF_CLEAR, 0xff);

GENMASK() ?

I don't really see a need for GENMASK here. It does not matter what is written to this register.

Why not 0? At least it will be aligned to the _CLEAR part without need of any comment. Otherwise it sounds like 0xff is special here.

I can change it to 0 if it pleases the audience :) 0xff was just first thing that came to my mind when I read the spec that something should be written to this register.

Quoted 27 lines
Quoted 8 lines
Quoted 7 lines

drivers/iio/accel/kionix-kx022a.c line 729

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+	if (en)
+		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
+				       KX022A_MASK_DRDY);

I would put redundant 'else' here to have them on the same column, but it's pity we don't have regmap_assign_bits() API (or whatever name you can come up with) to hide this kind of code.

Quoted 8 lines

Eh, you mean you would put else here even though we return from the if? And then put another return in else, and no return outside the if/else?

I definitely don't like the idea.

We could probably use regmap_update_bits and ternary but in my opinion that would be just much less obvious. I do like the use of set/clear bits which also makes the meaning / "polarity" of bits really clear.

The idea behind is simple (and note that I'm usually on the side of _removing_ redundancy)

	if (en)
		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
				       KX022A_MASK_DRDY);
	else
		return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
					 ...
Quoted 2 lines

Because the branches are semantically tighten to each other. But it's not a big deal to me.

What I do not really like in above example is that we never reach the end of function body. It is against the expectation - and adding the else has no real meaning when if returns. I actually think that checkpatch could even warn about that construct.

Quoted 20 lines
Quoted 20 lines
Quoted 5 lines
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
+				 KX022A_MASK_DRDY);
Quoted 10 lines

drivers/iio/accel/kionix-kx022a.c line 1051

Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c new file +8 -0
+	irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT1");
+	if (irq > 0) {
+		data->inc_reg = KX022A_REG_INC1;
+		data->ien_reg = KX022A_REG_INC4;
+	} else {
+		irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT2");
+		if (irq < 0)
+			return dev_err_probe(dev, irq, "No suitable IRQ\n");

Missed check for 0.

Why check for 0? fwnode_irq_get_byname() doc states:
* Return:
* Linux IRQ number on success, or negative errno otherwise.

Quoted 5 lines
Quoted 1 line

I don't see 0 indicating a failure?

It's a mislead by documentation. You need to read the fwnode_irq_get() to see what's going on. Feel free to submit a fix for the fwnode_irq_get_byname() kernel doc.

Thanks. I had missed the mapping error.

Quoted 41 lines

...

Quoted 6 lines
Quoted 5 lines

drivers/iio/accel/kionix-kx022a.c line 1134

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+module_param(g_kx022a_use_buffer, bool, 0);
+MODULE_PARM_DESC(g_kx022a_use_buffer,
+		 "Buffer samples. Use at own risk. Fifo must not overflow");

Why?! We usually do not allow module parameters in the new code.

Quoted 8 lines

There are still quite a few parameters that have been added during previous cycle. And many of those are to allow behaviour which is undesirable in many cases for those who can benefit from it.

3dbec44d9c94 ("KVM: VMX: Reject kvm_intel if an inconsistent VMCS config is detected")

can serve as a random example.

KVM is quite different by nature to an arbitrary driver of an arbitrary sensor that might appear in the real hardware at hand on 1:100 ratio basis.

Quoted 13 lines

As explained by the comment:
/*
* Filling up the HW-FIFO can cause nasty problems. Thus we do not
* enable the fifo unless it is explicitly requested by a module param.
* If you are _sure_ your system can serve the interrupts in time you
* can enable the HW fifo. I do not recommend it for sample frequencies
* higher than 2 Hz - and even in that case I would set the watermark
* somewhere near 20 samples (HI-RES) to have magnitude of 10 sec
* safety-margin.
*/

this is also the use-case here.

Quoted 7 lines

And yes, using the FIFO regardless of the problems can be beneficial so just dropping the support completely would be counter-productive. I agree with Jonathan that disabling the FIFO by default does probably help avoiding bug reports - but allowing enabling the FIFO with own risk is just giving a hand to those who need it. Thus I'd really like to see the support upstream. We all know that code which is sitting in some downstream git is not likely to help people - and it is the reason why I do upstream code in first place.

Quoted 3 lines

I would suggest to split the part that adds parameter (with whatever it does elsewhere) from the basic configuration. In this case the commit message should at least clarify the needs of the parameter.

I think adding the parameter in a separate patch is a good idea - even if patching something that was added by earlier patch in the series is often frowned upon.

Quoted 2 lines

JFYI: It's Greg KH strong opinion about parameters and I agree with him on that. Note that this subsystem goes via on of the Greg's trees.

Sure. And if this is not accepted by a maintainer in the chain - then it needs to be re-evaluated, changed or dropped. But at least I can try explaining why I think this is needed / useful.

Thanks for the help once again.

Yours
-- Matti

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
#29 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 4 lines · Matti
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Matti Vaittinen
Quoted 1 line · Andy Shevchenko

On Thu, Oct 06, 2022 at 05:38:14PM +0300, Matti Vaittinen wrote:

(Note, everything I have dropped without comment can be treated
as "yes, I agree on your points". Same applies to the early or the future replies.)

...

Quoted 13 lines
Quoted 9 lines
Quoted 8 lines
Quoted 1 line

Also what will be the module name (see other Kconfig for the pattern)?

Here the pattern is IMHO improved by cutting the useless text. Even the cross-reference from SPI to I2C and I2C to SPI driver which was in v1 is more useful. Module autoloading for SPI should just work. Adding the module name here seems just a silly habit - which I see many people are breaking. If module name is to be needed, then it should be checked from the Makefile and not trusted that Kconfig text stays up-to-date...

Quoted 3 lines

I think the module name is a good thing to have for a user who might be not knowing about Makefile:s and how to derive the module name from that (sometimes it's not so obvious).

Quoted 5 lines

My point is that average users do not really even need to know the module names. For most simple drivers the module name is just the base of the filename. I really doubt there are that many people who

a) do need to know module name

Everyone? When I need to debug the issue (assisted debug or doing myself) it is often good to know:

1) is the driver built as a module;
2) is that module ever loaded;
3) how to find initial module parameters if any
(see /sys/module/$NAME/parameters).

Quoted 2 lines

b) read config menu entries but don't know how to find a module name from Makefile

Isn't it orthogonal? Average user may easily choose everything in the kernel configuration via make menuconfig because it _is_ user interface / tool. Makefile simply is not for the users.

Quoted 1 line

c) want to know module name and can't pair the name from lsmod to module

It's reversed mapping we need.

Quoted 2 lines

d) rather look up the config entry than browse the contents of lib/modules/...

So, I have a module called 'foo-bar.ko' and lsmod shows me 'baz-hell'. How should I know that mapping to begin with?

Quoted 3 lines

It'd be nice to know if anyone reading this mail has actually ever used the module name information placed in Kconfig entry for _anything else_ except for making the Kconfig entry to look a bit more fatty...

That said, I haven't found any good justification from your side to avoid including the module name, while I see the advantages of otherwise.

...

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines

drivers/iio/accel/kionix-kx022a.c line 14

Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>

Can this group be placed after units.h (with blank line in between)?

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Why? What's wrong with alphabetical order?

Nothing wrong with the order and order is orthogonal to the grouping. My comment is for the latter. The rationale is to easily see generic header group and subsystem related group.

I can for sure change this but It'd be nice to know why should the subsystem headers be treated differently from the rest of the headers?

Rationale is based on the rule 'generic headers are included first'. Subsystem's headers can be considered less generic than the rest.

...

Quoted 20 lines
Quoted 16 lines
Quoted 10 lines
Quoted 9 lines

drivers/iio/accel/kionix-kx022a.c line 156

Quoted 6 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+struct kx022a_data {
+	int irq;
+	int inc_reg;
+	int ien_reg;
 
+	struct regmap *regmap;

Putting this as a first member might improve code by making pointer arithmetics better. Have you checked possibilities with bloat-o-meter?

Quoted 5 lines

No. Amount of combinations is just too huge for me to try randomly reordering structs and running bloat-o-meter. Can you please explain me why you think reordering this would have visible impact and if this is something that is universally true or if such an optimization is architecture dependent?

Quoted 3 lines

Usually regmap pointer is used more often than, for instance, the 'irq' member, and I believe that moving 'irq' member deeper will be harmless, while moving regmap might be winning.

Quoted 7 lines

So you suggest us to try optimizing the code by placing a pointer to more frequently used member(s) at the top of the struct? I didn't know it would have any impact. I understand arranging the members of frequently copied structs based on sizes so that we can avoid eating space by padding - but I had never heard of things being improved by ordering based on frequency of use. It'd be great to understand the mechanism this optimization is based on?

It's based on the pointer arithmetics. In some cases it might be a win, in some actually no advantage, that's why it's hard to say just by looking at the code.

Most affected cases are for the embedded data structures, where container_of() is used on top, esp. if most used member of those structures are also appeared first. Often example is:

struct foo {
	struct list_head node;
	...
};

vs.

struct foo {
	...
	struct list_head node;
};

where you may even see by reading the code that list_for_each_entry() will be shorter.

With pointers it's less visible, but still might have a difference.

Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 9 lines

drivers/iio/accel/kionix-kx022a.c line 162

Quoted 7 lines
drivers/iio/accel/kionix-kx022a.c new file +6 -0
+	struct iio_trigger *trig;
+	bool trigger_enabled;
+
+	struct device *dev;
+	unsigned int g_range;
 
+	struct mutex mutex;

No warning from checkpatch? Every lock should be commented what it is for.

No. I didn't see a warn from checkpatch with v6.0-rc7. And I am glad I didn't. I am not a fan of statements like "always document a lock" or "never use a goto" - because blindly following such "rules" tend to lead silly corner cases. In lock commenting case it is likely to lead copy-pasting comments for locks which are used for trivial protections. And I am definitely not a fan of boilerplate.

Quoted 7 lines
Quoted 1 line

So, tell then, what is this lock for? How as a code reader I have to know that?

I can add comment to this lock as it does protect more than one thing (and may not be trivial). But I am not at all sure requiring all locks to be documented will have optimal end-result... And no, I don't think checkpatch in v6.0-rc7 did warn about this lock. Do you think checkpatch has been modified to do that?

In the commit 4a0df2ef4569 ("update checkpatch.pl to version 0.03"):
...
check that spinlock_t and struct mutex use is commented
...

dated back 2007.

...

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+		while (n-- > 0)

while (n--) ? Or why the 0 is ignored?

So, it appears that yours and mine are equivalents, but mine is shorter :-)

...

Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines

drivers/iio/accel/kionix-kx022a.c line 583

Quoted 1 line
drivers/iio/accel/kionix-kx022a.c new file +1 -0
+	return regmap_write(data->regmap, KX022A_REG_BUF_CLEAR, 0xff);

GENMASK() ?

I don't really see a need for GENMASK here. It does not matter what is written to this register.

Quoted 6 lines
Quoted 2 lines

Why not 0? At least it will be aligned to the _CLEAR part without need of any comment. Otherwise it sounds like 0xff is special here.

I can change it to 0 if it pleases the audience :) 0xff was just first thing that came to my mind when I read the spec that something should be written to this register.

At least it will be less confusing in my opinion.

...

Quoted 27 lines
Quoted 27 lines
Quoted 8 lines
Quoted 7 lines

drivers/iio/accel/kionix-kx022a.c line 729

Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+	if (en)
+		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
+				       KX022A_MASK_DRDY);

I would put redundant 'else' here to have them on the same column, but it's pity we don't have regmap_assign_bits() API (or whatever name you can come up with) to hide this kind of code.

Quoted 8 lines

Eh, you mean you would put else here even though we return from the if? And then put another return in else, and no return outside the if/else?

I definitely don't like the idea.

We could probably use regmap_update_bits and ternary but in my opinion that would be just much less obvious. I do like the use of set/clear bits which also makes the meaning / "polarity" of bits really clear.

The idea behind is simple (and note that I'm usually on the side of _removing_ redundancy)

	if (en)
		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
				       KX022A_MASK_DRDY);
	else
		return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
					 ...
Quoted 5 lines
Quoted 2 lines

Because the branches are semantically tighten to each other. But it's not a big deal to me.

What I do not really like in above example is that we never reach the end of function body.

What do you mean by that? Compiler does warn or what?

Quoted 3 lines

It is against the expectation - and adding the
else has no real meaning when if returns. I actually think that checkpatch could even warn about that construct.

No way we ever accept such a thing for checkpatch because it's subjective (very dependant on the code piece). OTOH the proposed pattern is used in many places and left like that in places where I cleaned up the 'else', to leave the semantic tights with the above lines).

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

drivers/iio/accel/kionix-kx022a.c line 732

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
+				 KX022A_MASK_DRDY);

I see that we have a strong disagreement here. I leave it to maintainers.

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

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 31 lines · Andy Shevchenko
Quoted 4 lines · Matti
Quoted 3 lines · Andy Shevchenko
Quoted 2 lines · Matti Vaittinen
Quoted 1 line · Andy Shevchenko

On Thu, Oct 06, 2022 at 05:38:14PM +0300, Matti Vaittinen wrote:

(Note, everything I have dropped without comment can be treated
as "yes, I agree on your points". Same applies to the early or the future replies.)

...

Quoted 13 lines
Quoted 9 lines
Quoted 8 lines
Quoted 1 line

Also what will be the module name (see other Kconfig for the pattern)?

Here the pattern is IMHO improved by cutting the useless text. Even the cross-reference from SPI to I2C and I2C to SPI driver which was in v1 is more useful. Module autoloading for SPI should just work. Adding the module name here seems just a silly habit - which I see many people are breaking. If module name is to be needed, then it should be checked from the Makefile and not trusted that Kconfig text stays up-to-date...

Quoted 3 lines

I think the module name is a good thing to have for a user who might be not knowing about Makefile:s and how to derive the module name from that (sometimes it's not so obvious).

Quoted 5 lines

My point is that average users do not really even need to know the module names. For most simple drivers the module name is just the base of the filename. I really doubt there are that many people who

a) do need to know module name

Quoted 8 lines

Everyone? When I need to debug the issue (assisted debug or doing myself) it is often good to know:

1) is the driver built as a module;
2) is that module ever loaded;
3) how to find initial module parameters if any
(see /sys/module/$NAME/parameters).

Fair enough. Next question is that how often do you launch kernel configuration tool and try finding the correct config option when you need to know the module name? My gut feeling is that average users do not seek this information using config tools. (In my opinion) config is just a wrong place for this information. When you need to debug a module you should not be using the kernel config tool to find debugging guidance. It is just a wrong place. The config tool is for kernel configuration - and at that phase the module name does not matter. At that phase you want to know what support the option gives to you and if you should use it on your system. Name of a module is completely irrelevant.

Quoted 6 lines
Quoted 2 lines

b) read config menu entries but don't know how to find a module name from Makefile

Isn't it orthogonal? Average user may easily choose everything in the kernel configuration via make menuconfig because it _is_ user interface / tool. Makefile simply is not for the users.

Average users use distribution kernels. Some users may compile own kernel - but use config from previous kernel. Some users use "more exotic" boards - and use defconfigs for those. It is really just a handful of people who do read/change a config option for an accelerometer, PMIC, RTC, GPIO-controller or any other such single HW component. And I am pretty sure that those who do, do also understand the syntax of a Makefile.

And still, the moment of doing kernel configuration is not the moment when you need the module name.

Quoted 10 lines
Quoted 1 line

c) want to know module name and can't pair the name from lsmod to module

It's reversed mapping we need.

Quoted 2 lines

d) rather look up the config entry than browse the contents of lib/modules/...

So, I have a module called 'foo-bar.ko' and lsmod shows me 'baz-hell'. How should I know that mapping to begin with?

Quoted 6 lines
Quoted 3 lines

It'd be nice to know if anyone reading this mail has actually ever used the module name information placed in Kconfig entry for _anything else_ except for making the Kconfig entry to look a bit more fatty...

That said, I haven't found any good justification from your side to avoid including the module name, while I see the advantages of otherwise.

The disadvantage is systematically polluting the config entries with irrelevant (to configuration) information. We should focus more on the question if the config entry explains user whether he should or should not enable the piece of config on his system. IMNAHEO (In My Not Always Humble Enough Opinion) all the rest belongs to some other documentation.

Quoted 30 lines

...

Quoted 20 lines
Quoted 16 lines
Quoted 10 lines
Quoted 9 lines

drivers/iio/accel/kionix-kx022a.c line 156

Quoted 6 lines
drivers/iio/accel/kionix-kx022a.c new file +5 -0
+struct kx022a_data {
+	int irq;
+	int inc_reg;
+	int ien_reg;
 
+	struct regmap *regmap;

Putting this as a first member might improve code by making pointer arithmetics better. Have you checked possibilities with bloat-o-meter?

Quoted 5 lines

No. Amount of combinations is just too huge for me to try randomly reordering structs and running bloat-o-meter. Can you please explain me why you think reordering this would have visible impact and if this is something that is universally true or if such an optimization is architecture dependent?

Quoted 3 lines

Usually regmap pointer is used more often than, for instance, the 'irq' member, and I believe that moving 'irq' member deeper will be harmless, while moving regmap might be winning.

Quoted 7 lines

So you suggest us to try optimizing the code by placing a pointer to more frequently used member(s) at the top of the struct? I didn't know it would have any impact. I understand arranging the members of frequently copied structs based on sizes so that we can avoid eating space by padding - but I had never heard of things being improved by ordering based on frequency of use. It'd be great to understand the mechanism this optimization is based on?

Quoted 5 lines

It's based on the pointer arithmetics. In some cases it might be a win, in some actually no advantage, that's why it's hard to say just by looking at the code.

Most affected cases are for the embedded data structures, where container_of() is used on top,

Oh. Do you mean that in some cases when CPU needs some information frequently, it should be at the top of a struct so that no offset needs to be added when information is obtained using a pointer to the struct? Eg. Adding offset to the pointer (pointer arithmetics) is not done when first member of a struct is obtained - resulting maybe one instruction less. So having the most frequently used data as first member of a struct can be beneficial? I assume that if offset needs to be added, then it does not really matter how big the offset is - although naturally the size of the (offset) struct matters when we consider how data fits in cache.

Okay, cool thing to keep in mind when optimizing some really performance critical code in a fixed environment - or when dealing with a set of instructions copied to many places. I am afraid that for a driver intended to be used in different systems the manual optimization results are not really that good. Also, bloat-o-meter results on kernel compiled with my specific optimization settings and compiler would probably not be universally true. (At the moment I do develop the driver using pretty ancient version of a 32-bit arm compiler). (I don't really know the bloat-o-meter but my understanding is that it compares the compiled binaries to find out the differencies)

Quoted 20 lines

esp. if most used member of those structures are also appeared first. Often example is:

struct foo {
	struct list_head node;
	...
};

vs.

struct foo {
	...
	struct list_head node;
};

where you may even see by reading the code that list_for_each_entry() will be shorter.

With pointers it's less visible, but still might have a difference.

Quoted 8 lines

...

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+
+		while (n-- > 0)

while (n--) ? Or why the 0 is ignored?

So, it appears that yours and mine are equivalents, but mine is shorter :-)

Yes. Besides, I actually like looks of while (n--) more than while (n--

Quoted 1 line

0). I think while (n-- > 0) has originated from the code where I

stole the logic :)

Quoted 28 lines
Quoted 28 lines
Quoted 28 lines
Quoted 9 lines
Quoted 8 lines

drivers/iio/accel/kionix-kx022a.c line 729

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +3 -0
+	if (en)
+		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
+				       KX022A_MASK_DRDY);

I would put redundant 'else' here to have them on the same column, but it's pity we don't have regmap_assign_bits() API (or whatever name you can come up with) to hide this kind of code.

Quoted 8 lines

Eh, you mean you would put else here even though we return from the if? And then put another return in else, and no return outside the if/else?

I definitely don't like the idea.

We could probably use regmap_update_bits and ternary but in my opinion that would be just much less obvious. I do like the use of set/clear bits which also makes the meaning / "polarity" of bits really clear.

The idea behind is simple (and note that I'm usually on the side of _removing_ redundancy)

	if (en)
		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
				       KX022A_MASK_DRDY);
	else
		return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
					 ...
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

Because the branches are semantically tighten to each other. But it's not a big deal to me.

What I do not really like in above example is that we never reach the end of function body.

What do you mean by that? Compiler does warn or what?

I don't know if compiler warns about it as I didn't test it. Now that you mentioned it, I think I have seen such warnings from a compiler or some static analyzer (klocwork?) in the past though. What I mean is that:

int foo()

{
	if () {
		...
		return 1;
	} else {
		...
		return 2;
	}
}

construct makes mistakes like:

int foo()

{
	if () {
		...
		return 1;
	} else {
		...
		return 2;
	}

	...

	return 0;
}

easy to make. When one uses:

int foo()

{
	if () {
		...
		return 1;
	}

	...
	return 2;
}

to begin with there is zero room for such confusion.

Quoted 6 lines
Quoted 4 lines

It is against the expectation - and adding the
else has no real meaning when if returns. I actually think that checkpatch could even warn about that construct.

No way we ever accept such a thing for checkpatch because it's subjective

Eh. Are you telling me that there is no subjective stuff in checkpatch? ;)

Quoted 8 lines

(very dependant on the code piece). OTOH the proposed pattern is used in many places and left like that in places where I cleaned up the 'else', to leave the semantic tights with the above lines).

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

drivers/iio/accel/kionix-kx022a.c line 732

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
+				 KX022A_MASK_DRDY);

I see that we have a strong disagreement here. I leave it to maintainers.

Okay, let's hear what others have to say here.

Thanks for all the input this far.

Best Regards
-- Matti

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
#31 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

...

Quoted 41 lines
Quoted 28 lines
Quoted 28 lines
Quoted 28 lines
Quoted 9 lines
Quoted 8 lines

Review

Quoted 4 lines
(quoted diff) +3 -0
+	if (en)
+		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
+				       KX022A_MASK_DRDY);  

I would put redundant 'else' here to have them on the same column, but it's pity we don't have regmap_assign_bits() API (or whatever name you can come up with) to hide this kind of code.

Quoted 8 lines

Eh, you mean you would put else here even though we return from the if? And then put another return in else, and no return outside the if/else?

I definitely don't like the idea.

We could probably use regmap_update_bits and ternary but in my opinion that would be just much less obvious. I do like the use of set/clear bits which also makes the meaning / "polarity" of bits really clear.

The idea behind is simple (and note that I'm usually on the side of _removing_ redundancy)

	if (en)
		return regmap_set_bits(data->regmap, KX022A_REG_CNTL,
				       KX022A_MASK_DRDY);
	else
		return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
					 ...
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

Because the branches are semantically tighten to each other. But it's not a big deal to me.

What I do not really like in above example is that we never reach the end of function body.

What do you mean by that? Compiler does warn or what?

I don't know if compiler warns about it as I didn't test it. Now that you mentioned it, I think I have seen such warnings from a compiler or some static analyzer (klocwork?) in the past though. What I mean is that:

int foo()

Quoted 10 lines
{
	if () {
		...
		return 1;
	} else {
		...
		return 2;
	}
}

For reference, this is the one I'd write if both options are good (or both are bad) and we don't need to worry about reducing indent for readability.

However, I long since decided this was trivial enough not to comment on it in the code of others!

Quoted 16 lines

construct makes mistakes like:

int foo()

{
	if () {
		...
		return 1;
	} else {
		...
		return 2;
	}

	...

	return 0;
}

That should given unreachable code warning unless you've really managed to confuse the compiler / static analysis tooling.

Quoted 29 lines

easy to make. When one uses:

int foo()

{
	if () {
		...
		return 1;
	}

	...
	return 2;
}

to begin with there is zero room for such confusion.

Quoted 6 lines
Quoted 4 lines

It is against the expectation - and adding the
else has no real meaning when if returns. I actually think that checkpatch could even warn about that construct.

No way we ever accept such a thing for checkpatch because it's subjective

Eh. Are you telling me that there is no subjective stuff in checkpatch? ;)

Quoted 4 lines

(very dependant on the code piece). OTOH the proposed pattern is used in many places and left like that in places where I cleaned up the 'else', to leave the semantic tights with the above lines).

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	return regmap_clear_bits(data->regmap, KX022A_REG_CNTL,
+				 KX022A_MASK_DRDY);  

I see that we have a strong disagreement here. I leave it to maintainers.

Okay, let's hear what others have to say here.

Non answer above ;)

Time for the old "Don't let perfect be the enemy of good!"

Quoted 6 lines

Thanks for all the input this far.

Best Regards
-- Matti

author maintainer
#32 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

In reply to Vaittinen, Matti
Quoted 16 lines · Matti
Quoted 15 lines · Andy Shevchenko

On Mon, Oct 10, 2022 at 12:12:34PM +0300, Matti Vaittinen wrote:
...

Quoted 12 lines
Quoted 11 lines

drivers/iio/accel/kionix-kx022a.c line 449

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer,
+			       sizeof(s16));

No endianess awareness (sizeof __le16 / __be16)

drivers/iio/accel/kionix-kx022a.c line 453

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+	if (ret)
+		return ret;
+
+	*val = data->buffer[0];

Ditto (get_unaligned_be16/le16 / le16/be16_to_cpup()).

Quoted 7 lines
Quoted 7 lines
Quoted 5 lines

I have probably misunderstood something but I don't see why we should use 'endianess awareness' in drivers? I thought the IIO framework code takes care of the endianes conversions based on scan_type so each individual driver does not need to do that. That however has been just my assumption. I will need to check this. Thanks for pointing it out.

The IIO core uses endianness field only once in iio_show_fixed_type() AFAICS.

Following is some hand waving and speculation after my quick code read. So, I may be utterly wrong in which case please do correct me...

Anyways, it seems to me that you're correct. The endianness field is only used by the IIO to build the channel information for user-space so that applications reading data can parse it. As far as I understand, the driver does not need to do the conversions for user-space, but the user-space tools should inspect the type information and do the conversion. I think it makes sense as user-space applications may be better equipped to do some maths. It also may be some applications do not want to spend cycles doing the conversion but the conversions can be done later "offline" for the captured raw data. So omitting conversion in the IIO driver kind of makes sense to me.

I haven't thoroughly looked (and I have never used) the in-kernel IIO APIs for getting the data. A quick look at the include/linux/iio/consumer.h allows me to assume the iio_chan_spec can be obtained by the consumer drivers. This should make the endianess information available for the consumer drivers as well. So, again, consumer drivers can parse the raw-format data themself.

I have this far only used the sysfs and iio_generic_buffer on a little-endian machine so I have had no issues with the little-endian data and I have only observed the code. Hence I can not really say if my reasoning is correct - or if it is how IIO has been designed to operate. But based on my quick study I don't see a need for the IIO driver to do endianess conversion to any other format but what is indicated by scan_type. Specifically for KX022A, the data is already 16B LE when read from the sensor. This is also advertised by scan_type so no conversion should be needed (unless, of course, I am mistaken :]).

Quoted 3 lines
Quoted 3 lines

And it does nothing with it. Maybe Jonathan can shed a light what is it for (I mean the field)?

I agree. It'd be great to listen to someone who actually knows what he is talking about and is not just guessing as I am ^_^;

Yours,
-- Matti

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
#33 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 28 lines · On Wed, 12 Oct 2022 10:40:38 +0300 Matti Vaittinen <[email protected]>…
Quoted 16 lines · Matti
Quoted 15 lines · Andy Shevchenko

On Mon, Oct 10, 2022 at 12:12:34PM +0300, Matti Vaittinen wrote:
...

Quoted 12 lines
Quoted 11 lines

drivers/iio/accel/kionix-kx022a.c line 449

Quoted 2 lines
drivers/iio/accel/kionix-kx022a.c new file +2 -0
+	ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer,
+			       sizeof(s16));  

No endianess awareness (sizeof __le16 / __be16)

drivers/iio/accel/kionix-kx022a.c line 453

Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c new file +4 -0
+	if (ret)
+		return ret;
+
+	*val = data->buffer[0];  

Ditto (get_unaligned_be16/le16 / le16/be16_to_cpup()).

Quoted 7 lines
Quoted 7 lines
Quoted 5 lines

I have probably misunderstood something but I don't see why we should use 'endianess awareness' in drivers? I thought the IIO framework code takes care of the endianes conversions based on scan_type so each individual driver does not need to do that. That however has been just my assumption. I will need to check this. Thanks for pointing it out.

The IIO core uses endianness field only once in iio_show_fixed_type() AFAICS.

Following is some hand waving and speculation after my quick code read. So, I may be utterly wrong in which case please do correct me...

Quoted 10 lines

Anyways, it seems to me that you're correct. The endianness field is only used by the IIO to build the channel information for user-space so that applications reading data can parse it. As far as I understand, the driver does not need to do the conversions for user-space, but the user-space tools should inspect the type information and do the conversion. I think it makes sense as user-space applications may be better equipped to do some maths. It also may be some applications do not want to spend cycles doing the conversion but the conversions can be done later "offline" for the captured raw data. So omitting conversion in the IIO driver kind of makes sense to me.

That was indeed the original reasonining for buffered data path (note the endian marker is for scans only which only apply in buffered
/ chardev case).

It's less obvious for the sysfs path as that's inherently slow. We could have made this a problem for the IIO core, but we didn't :)

Quoted 7 lines

I haven't thoroughly looked (and I have never used) the in-kernel IIO APIs for getting the data. A quick look at the include/linux/iio/consumer.h allows me to assume the iio_chan_spec can be obtained by the consumer drivers. This should make the endianess information available for the consumer drivers as well. So, again, consumer drivers can parse the raw-format data themself.

yes consumers should be be endian aware if they are using the callback buffer route to get the data. Now you mention it, we may well have cases where that isn't handled correctly. There are few enough users of that interface that it might well work by coincidence rather than design. oops.

Quoted 10 lines

I have this far only used the sysfs and iio_generic_buffer on a little-endian machine so I have had no issues with the little-endian data and I have only observed the code. Hence I can not really say if my reasoning is correct - or if it is how IIO has been designed to operate. But based on my quick study I don't see a need for the IIO driver to do endianess conversion to any other format but what is indicated by scan_type. Specifically for KX022A, the data is already 16B LE when read from the sensor. This is also advertised by scan_type so no conversion should be needed (unless, of course, I am mistaken :]).

Ah. I'd missed that. Data storage should reflect the read back endianness and for the read_raw path you need to perform the conversion in driver (but not the high perf push to buffers path).

Sure we could probably have handled read_raw in tree as well but we didn't and probably too late to sensibly fix that now. One of many things we'd probably do differently if we were starting again.

J

Quoted 11 lines
Quoted 4 lines
Quoted 4 lines

And it does nothing with it. Maybe Jonathan can shed a light what is it for (I mean the field)?

I agree. It'd be great to listen to someone who actually knows what he is talking about and is not just guessing as I am ^_^;

Yours,
-- Matti

author maintainer
#34 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 42 lines · Jonathan Cameron
Quoted 28 lines · On Wed, 12 Oct 2022 10:40:38 +0300 Matti Vaittinen <[email protected]>…
Quoted 16 lines · Matti
Quoted 15 lines · Andy Shevchenko

On Mon, Oct 10, 2022 at 12:12:34PM +0300, Matti Vaittinen wrote:
...

Quoted 12 lines
Quoted 11 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer,
+			       sizeof(s16));

No endianess awareness (sizeof __le16 / __be16)

Review

Quoted 4 lines
(quoted diff) +4 -0
+	if (ret)
+		return ret;
+
+	*val = data->buffer[0];

Ditto (get_unaligned_be16/le16 / le16/be16_to_cpup()).

Quoted 7 lines
Quoted 7 lines
Quoted 5 lines

I have probably misunderstood something but I don't see why we should use 'endianess awareness' in drivers? I thought the IIO framework code takes care of the endianes conversions based on scan_type so each individual driver does not need to do that. That however has been just my assumption. I will need to check this. Thanks for pointing it out.

The IIO core uses endianness field only once in iio_show_fixed_type() AFAICS.

Following is some hand waving and speculation after my quick code read. So, I may be utterly wrong in which case please do correct me...

Quoted 10 lines

Anyways, it seems to me that you're correct. The endianness field is only used by the IIO to build the channel information for user-space so that applications reading data can parse it. As far as I understand, the driver does not need to do the conversions for user-space, but the user-space tools should inspect the type information and do the conversion. I think it makes sense as user-space applications may be better equipped to do some maths. It also may be some applications do not want to spend cycles doing the conversion but the conversions can be done later "offline" for the captured raw data. So omitting conversion in the IIO driver kind of makes sense to me.

Quoted 3 lines

That was indeed the original reasonining for buffered data path (note the endian marker is for scans only which only apply in buffered
/ chardev case).

So, in a case where we "push_to_buffers" the data, we can leave the data to use the endianess we advertise via endianess info field?

Quoted 2 lines

It's less obvious for the sysfs path as that's inherently slow. We could have made this a problem for the IIO core, but we didn't :)

But again, as far as I understood, the user-space is still expected to read the sysfs field for "scan_elements/in_accel_<channel>_type"? I guess it would be confusing to say "le:s16/16>>0" there while returning CPU native endianess values from sysfs files?

Quoted 24 lines
Quoted 6 lines

I haven't thoroughly looked (and I have never used) the in-kernel IIO APIs for getting the data. A quick look at the include/linux/iio/consumer.h allows me to assume the iio_chan_spec can be obtained by the consumer drivers. This should make the endianess information available for the consumer drivers as well. So, again, consumer drivers can parse the raw-format data themself.

yes consumers should be be endian aware if they are using the callback buffer route to get the data. Now you mention it, we may well have cases where that isn't handled correctly. There are few enough users of that interface that it might well work by coincidence rather than design. oops.

Quoted 10 lines

I have this far only used the sysfs and iio_generic_buffer on a little-endian machine so I have had no issues with the little-endian data and I have only observed the code. Hence I can not really say if my reasoning is correct - or if it is how IIO has been designed to operate. But based on my quick study I don't see a need for the IIO driver to do endianess conversion to any other format but what is indicated by scan_type. Specifically for KX022A, the data is already 16B LE when read from the sensor. This is also advertised by scan_type so no conversion should be needed (unless, of course, I am mistaken :]).

Quoted 3 lines

Ah. I'd missed that. Data storage should reflect the read back endianness and for the read_raw path you need to perform the conversion in driver (but not the high perf push to buffers path).

Oh, really? I think it might be confusing to say "le:s16/16>>0" in "scan_elements/in_accel_<channel>_type" but return something else from the in_accel_<channel>_raw. Especially the "raw" word at the end of the file signals the data is in non converted raw format.

I take your word for that if you say this is what the user-space expects, it just is not what I did expect. Well, I do very little work on the user-space these days ;) Still just to be on safe side - do you mean I should convert the data returned from read_raw to the CPU endianess?

Quoted 3 lines

Sure we could probably have handled read_raw in tree as well but we didn't and probably too late to sensibly fix that now. One of many things we'd probably do differently if we were starting again.

Well, this is pretty usual story :) Predicting the future is hard. My crystal ball ran out of batteries a long ago ;)

Best Regards
-- Matti

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
#35 lore raw

Re: [RFC PATCH v2 4/5] iio: accel: Support Kionix/ROHM KX022A accelerometer

Quoted 43 lines · On Tue, 18 Oct 2022 14:10:59 +0300 Matti Vaittinen <[email protected]>…
Quoted 42 lines · Jonathan Cameron
Quoted 38 lines · On Wed, 12 Oct 2022 10:40:38 +0300 Matti Vaittinen <[email protected]>…
Quoted 16 lines · Matti
Quoted 15 lines · Andy Shevchenko

On Mon, Oct 10, 2022 at 12:12:34PM +0300, Matti Vaittinen wrote:
...

Quoted 12 lines
Quoted 11 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer,
+			       sizeof(s16));  

No endianess awareness (sizeof __le16 / __be16)

Review

Quoted 4 lines
(quoted diff) +4 -0
+	if (ret)
+		return ret;
+
+	*val = data->buffer[0];  

Ditto (get_unaligned_be16/le16 / le16/be16_to_cpup()).

Quoted 7 lines
Quoted 7 lines
Quoted 5 lines

I have probably misunderstood something but I don't see why we should use 'endianess awareness' in drivers? I thought the IIO framework code takes care of the endianes conversions based on scan_type so each individual driver does not need to do that. That however has been just my assumption. I will need to check this. Thanks for pointing it out.

The IIO core uses endianness field only once in iio_show_fixed_type() AFAICS.

Following is some hand waving and speculation after my quick code read. So, I may be utterly wrong in which case please do correct me...

Anyways, it seems to me that you're correct. The endianness field is only used by the IIO to build the channel information for user-space so that applications reading data can parse it. As far as I understand, the driver does not need to do the conversions for user-space, but the user-space tools should inspect the type information and do the conversion. I think it makes sense as user-space applications may be better equipped to do some maths. It also may be some applications do not want to spend cycles doing the conversion but the conversions can be done later "offline" for the captured raw data. So omitting conversion in the IIO driver kind of makes sense to me.

Quoted 6 lines
Quoted 3 lines

That was indeed the original reasonining for buffered data path (note the endian marker is for scans only which only apply in buffered
/ chardev case).

So, in a case where we "push_to_buffers" the data, we can leave the data to use the endianess we advertise via endianess info field?

Exactly.

Quoted 8 lines
Quoted 3 lines

It's less obvious for the sysfs path as that's inherently slow. We could have made this a problem for the IIO core, but we didn't :)

But again, as far as I understood, the user-space is still expected to read the sysfs field for "scan_elements/in_accel_<channel>_type"? I guess it would be confusing to say "le:s16/16>>0" there while returning CPU native endianess values from sysfs files?

Agreed that it is probably less than ideal but that's what the interface is. scan_elements refers to the "scan elements" channels read via sysfs files are not scan elements - scan's are only relevant to buffered readback.

Quoted 34 lines
Quoted 25 lines
Quoted 7 lines

I haven't thoroughly looked (and I have never used) the in-kernel IIO APIs for getting the data. A quick look at the include/linux/iio/consumer.h allows me to assume the iio_chan_spec can be obtained by the consumer drivers. This should make the endianess information available for the consumer drivers as well. So, again, consumer drivers can parse the raw-format data themself.

yes consumers should be be endian aware if they are using the callback buffer route to get the data. Now you mention it, we may well have cases where that isn't handled correctly. There are few enough users of that interface that it might well work by coincidence rather than design. oops.

Quoted 10 lines

I have this far only used the sysfs and iio_generic_buffer on a little-endian machine so I have had no issues with the little-endian data and I have only observed the code. Hence I can not really say if my reasoning is correct - or if it is how IIO has been designed to operate. But based on my quick study I don't see a need for the IIO driver to do endianess conversion to any other format but what is indicated by scan_type. Specifically for KX022A, the data is already 16B LE when read from the sensor. This is also advertised by scan_type so no conversion should be needed (unless, of course, I am mistaken :]).

Quoted 3 lines

Ah. I'd missed that. Data storage should reflect the read back endianness and for the read_raw path you need to perform the conversion in driver (but not the high perf push to buffers path).

Oh, really? I think it might be confusing to say "le:s16/16>>0" in "scan_elements/in_accel_<channel>_type" but return something else from the in_accel_<channel>_raw. Especially the "raw" word at the end of the file signals the data is in non converted raw format.

Quoted 4 lines

I take your word for that if you say this is what the user-space expects, it just is not what I did expect. Well, I do very little work on the user-space these days ;) Still just to be on safe side - do you mean I should convert the data returned from read_raw to the CPU endianess?

yes.

Quoted 7 lines
Quoted 4 lines

Sure we could probably have handled read_raw in tree as well but we didn't and probably too late to sensibly fix that now. One of many things we'd probably do differently if we were starting again.

Well, this is pretty usual story :) Predicting the future is hard. My crystal ball ran out of batteries a long ago ;)

:)

Quoted 4 lines

Best Regards
-- Matti

author maintainer
#36 lore raw

RFC PATCH v2 5/5 MAINTAINERS: Add KX022A maintainer entry

In reply to Matti Vaittinen

Add maintainer entry for ROHM/Kionix KX022A accelerometer senor driver.

---
I can also add myself as a maintainer instead of a reviewer if it better suits iio maintainer. I however don't plan setting up my own public repository and hope the further patches will be merged via IIO tree.

So, as Geert once explained to me - In that case the difference between me as a maintainer vs. a reviewer would be only really relevant to the subsystem (in this case IIO) maintainer. The subsystem maintainer who merges patches is allowed to take in changes acked by downstream maintainer w/o obligation to do thorough review. (Downstream maintainer is to be blamed if things explode :]). If ack is given by a reviewer, then the subsystem maintainer has the full responsibility and should always do the review. Or - this is how I remember our discussion went - feel free to correct me if I am wrong :] In any case - please let me know if you'd rather see M: not R: in front of my name for the kx022a.

---
 MAINTAINERS | 5 +++++
 1 file changed, 5 insertions(+)
MAINTAINERS +5 -0
index f5ca4aefd184..641b4fc2e5e2 100644
@@ -11356,6 +11356,11 @@ F:	drivers/mfd/khadas-mcu.c
 F:	include/linux/mfd/khadas-mcu.h
 F:	drivers/thermal/khadas_mcu_fan.c
 
+KIONIX/ROHM KX022A ACCELEROMETER
+R:	Matti Vaittinen <[email protected]>
+S:	Supported
+F:	drivers/iio/accel/kionix-kx022a*
+
 KMEMLEAK
 M:	Catalin Marinas <[email protected]>
 S:	Maintained
Signature · 14 lines
2.37.3


-- 
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND

~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =] 
maintainer
#37 lore raw

Re: [RFC PATCH v2 5/5] MAINTAINERS: Add KX022A maintainer entry

Quoted 9 lines · On Thu, 6 Oct 2022 17:38:34 +0300 Matti Vaittinen <[email protected]>…

Add maintainer entry for ROHM/Kionix KX022A accelerometer senor driver.

---
I can also add myself as a maintainer instead of a reviewer if it better suits iio maintainer. I however don't plan setting up my own public repository and hope the further patches will be merged via IIO tree.

Quoted 10 lines

So, as Geert once explained to me - In that case the difference between me as a maintainer vs. a reviewer would be only really relevant to the subsystem (in this case IIO) maintainer. The subsystem maintainer who merges patches is allowed to take in changes acked by downstream maintainer w/o obligation to do thorough review. (Downstream maintainer is to be blamed if things explode :]). If ack is given by a reviewer, then the subsystem maintainer has the full responsibility and should always do the review. Or - this is how I remember our discussion went - feel free to correct me if I am wrong :] In any case - please let me know if you'd rather see M: not R: in front of my name for the kx022a.

Entirely up to you. I tend to take a look at all IIO patches but will take a less detailed look if there is a tag from someone I've built up trust with - doesn't matter if they are a maintainer of a particular driver or not. I only ever look at MAINTAINERS when sending out patches, never when reviewing except to perhaps moan that someone wasn't cc'd who should have been!

Jonathan

Quoted 20 lines
---
 MAINTAINERS | 5 +++++
 1 file changed, 5 insertions(+)
MAINTAINERS +5 -0
index f5ca4aefd184..641b4fc2e5e2 100644
@@ -11356,6 +11356,11 @@ F:	drivers/mfd/khadas-mcu.c
 F:	include/linux/mfd/khadas-mcu.h
 F:	drivers/thermal/khadas_mcu_fan.c
 
+KIONIX/ROHM KX022A ACCELEROMETER
+R:	Matti Vaittinen <[email protected]>
+S:	Supported
+F:	drivers/iio/accel/kionix-kx022a*
+
 KMEMLEAK
 M:	Catalin Marinas <[email protected]>
 S:	Maintained
author maintainer
#38 lore raw

Re: [RFC PATCH v2 5/5] MAINTAINERS: Add KX022A maintainer entry

Quoted 24 lines · Jonathan Cameron
Quoted 9 lines · On Thu, 6 Oct 2022 17:38:34 +0300 Matti Vaittinen <[email protected]>…

Add maintainer entry for ROHM/Kionix KX022A accelerometer senor driver.

---
I can also add myself as a maintainer instead of a reviewer if it better suits iio maintainer. I however don't plan setting up my own public repository and hope the further patches will be merged via IIO tree.

Quoted 10 lines

So, as Geert once explained to me - In that case the difference between me as a maintainer vs. a reviewer would be only really relevant to the subsystem (in this case IIO) maintainer. The subsystem maintainer who merges patches is allowed to take in changes acked by downstream maintainer w/o obligation to do thorough review. (Downstream maintainer is to be blamed if things explode :]). If ack is given by a reviewer, then the subsystem maintainer has the full responsibility and should always do the review. Or - this is how I remember our discussion went - feel free to correct me if I am wrong :] In any case - please let me know if you'd rather see M: not R: in front of my name for the kx022a.

Quoted 6 lines

Entirely up to you. I tend to take a look at all IIO patches but will take a less detailed look if there is a tag from someone I've built up trust with - doesn't matter if they are a maintainer of a particular driver or not. I only ever look at MAINTAINERS when sending out patches, never when reviewing except to perhaps moan that someone wasn't cc'd who should have been!

In that case I'll keep the R as I have done with the other corners I've touched.

Yours
-- Matti

Signature · 5 lines
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~