linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stephan Gerhold <stephan@gerhold.net>
To: Jonathan Cameron <jic23@kernel.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>,
	Rob Herring <robh+dt@kernel.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	Hans de Goede <hdegoede@redhat.com>,
	Andy Shevchenko <andy.shevchenko@gmail.com>,
	~postmarketos/upstreaming@lists.sr.ht,
	Nikita Travkin <nikita@trvn.ru>,
	Stephan Gerhold <stephan@gerhold.net>
Subject: [PATCH 3/4] iio: accel: bmc150: Make it possible to configure INT2 instead of INT1
Date: Mon, 19 Jul 2021 13:21:55 +0200	[thread overview]
Message-ID: <20210719112156.27087-4-stephan@gerhold.net> (raw)
In-Reply-To: <20210719112156.27087-1-stephan@gerhold.net>

Some Bosch accelerometers have two interrupt pins (INT1 and INT2).
At the moment, the driver uses only the first one, which is fine for
most situations. However, some boards might only have INT2 connected
for some reason.

Add the necessary bits and configuration to set up INT2. Then try
to detect this situation at least for device tree setups by checking
if the first interrupt (the one picked by the I2C/SPI core) is actually
named "INT2" using the interrupt-names property.

of_irq_get_byname() returns either 0 or some error code in case
the driver probed without device tree, so in all other cases we fall
back to configuring INT1 as before.

Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
 drivers/iio/accel/bmc150-accel-core.c | 71 ++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c
index 5ce384ebe6c7..8d3dd3c2bcc2 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -10,6 +10,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
+#include <linux/of_irq.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/iio/iio.h>
@@ -57,12 +58,18 @@
 #define BMC150_ACCEL_RESET_VAL			0xB6
 
 #define BMC150_ACCEL_REG_INT_MAP_0		0x19
-#define BMC150_ACCEL_INT_MAP_0_BIT_SLOPE	BIT(2)
+#define BMC150_ACCEL_INT_MAP_0_BIT_INT1_SLOPE	BIT(2)
 
 #define BMC150_ACCEL_REG_INT_MAP_1		0x1A
-#define BMC150_ACCEL_INT_MAP_1_BIT_DATA		BIT(0)
-#define BMC150_ACCEL_INT_MAP_1_BIT_FWM		BIT(1)
-#define BMC150_ACCEL_INT_MAP_1_BIT_FFULL	BIT(2)
+#define BMC150_ACCEL_INT_MAP_1_BIT_INT1_DATA	BIT(0)
+#define BMC150_ACCEL_INT_MAP_1_BIT_INT1_FWM	BIT(1)
+#define BMC150_ACCEL_INT_MAP_1_BIT_INT1_FFULL	BIT(2)
+#define BMC150_ACCEL_INT_MAP_1_BIT_INT2_FFULL	BIT(5)
+#define BMC150_ACCEL_INT_MAP_1_BIT_INT2_FWM	BIT(6)
+#define BMC150_ACCEL_INT_MAP_1_BIT_INT2_DATA	BIT(7)
+
+#define BMC150_ACCEL_REG_INT_MAP_2		0x1B
+#define BMC150_ACCEL_INT_MAP_2_BIT_INT2_SLOPE	BIT(2)
 
 #define BMC150_ACCEL_REG_INT_RST_LATCH		0x21
 #define BMC150_ACCEL_INT_MODE_LATCH_RESET	0x80
@@ -81,6 +88,7 @@
 
 #define BMC150_ACCEL_REG_INT_OUT_CTRL		0x20
 #define BMC150_ACCEL_INT_OUT_CTRL_INT1_LVL	BIT(0)
+#define BMC150_ACCEL_INT_OUT_CTRL_INT2_LVL	BIT(2)
 
 #define BMC150_ACCEL_REG_INT_5			0x27
 #define BMC150_ACCEL_SLOPE_DUR_MASK		0x03
@@ -476,21 +484,24 @@ static bool bmc150_apply_acpi_orientation(struct device *dev,
 }
 #endif
 
-static const struct bmc150_accel_interrupt_info {
+struct bmc150_accel_interrupt_info {
 	u8 map_reg;
 	u8 map_bitmask;
 	u8 en_reg;
 	u8 en_bitmask;
-} bmc150_accel_interrupts[BMC150_ACCEL_INTERRUPTS] = {
+};
+
+static const struct bmc150_accel_interrupt_info
+bmc150_accel_interrupts_int1[BMC150_ACCEL_INTERRUPTS] = {
 	{ /* data ready interrupt */
 		.map_reg = BMC150_ACCEL_REG_INT_MAP_1,
-		.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_DATA,
+		.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_INT1_DATA,
 		.en_reg = BMC150_ACCEL_REG_INT_EN_1,
 		.en_bitmask = BMC150_ACCEL_INT_EN_BIT_DATA_EN,
 	},
 	{  /* motion interrupt */
 		.map_reg = BMC150_ACCEL_REG_INT_MAP_0,
-		.map_bitmask = BMC150_ACCEL_INT_MAP_0_BIT_SLOPE,
+		.map_bitmask = BMC150_ACCEL_INT_MAP_0_BIT_INT1_SLOPE,
 		.en_reg = BMC150_ACCEL_REG_INT_EN_0,
 		.en_bitmask =  BMC150_ACCEL_INT_EN_BIT_SLP_X |
 			BMC150_ACCEL_INT_EN_BIT_SLP_Y |
@@ -498,19 +509,55 @@ static const struct bmc150_accel_interrupt_info {
 	},
 	{ /* fifo watermark interrupt */
 		.map_reg = BMC150_ACCEL_REG_INT_MAP_1,
-		.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_FWM,
+		.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_INT1_FWM,
+		.en_reg = BMC150_ACCEL_REG_INT_EN_1,
+		.en_bitmask = BMC150_ACCEL_INT_EN_BIT_FWM_EN,
+	},
+};
+
+static const struct bmc150_accel_interrupt_info
+bmc150_accel_interrupts_int2[BMC150_ACCEL_INTERRUPTS] = {
+	{ /* data ready interrupt */
+		.map_reg = BMC150_ACCEL_REG_INT_MAP_1,
+		.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_INT2_DATA,
+		.en_reg = BMC150_ACCEL_REG_INT_EN_1,
+		.en_bitmask = BMC150_ACCEL_INT_EN_BIT_DATA_EN,
+	},
+	{  /* motion interrupt */
+		.map_reg = BMC150_ACCEL_REG_INT_MAP_2,
+		.map_bitmask = BMC150_ACCEL_INT_MAP_2_BIT_INT2_SLOPE,
+		.en_reg = BMC150_ACCEL_REG_INT_EN_0,
+		.en_bitmask =  BMC150_ACCEL_INT_EN_BIT_SLP_X |
+			BMC150_ACCEL_INT_EN_BIT_SLP_Y |
+			BMC150_ACCEL_INT_EN_BIT_SLP_Z
+	},
+	{ /* fifo watermark interrupt */
+		.map_reg = BMC150_ACCEL_REG_INT_MAP_1,
+		.map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_INT2_FWM,
 		.en_reg = BMC150_ACCEL_REG_INT_EN_1,
 		.en_bitmask = BMC150_ACCEL_INT_EN_BIT_FWM_EN,
 	},
 };
 
 static void bmc150_accel_interrupts_setup(struct iio_dev *indio_dev,
-					  struct bmc150_accel_data *data)
+					  struct bmc150_accel_data *data, int irq)
 {
+	const struct bmc150_accel_interrupt_info *irq_info = NULL;
+	struct device *dev = regmap_get_device(data->regmap);
 	int i;
 
+	/*
+	 * For now we map all interrupts to the same output pin.
+	 * However, some boards may have just INT2 (and not INT1) connected,
+	 * so we try to detect which IRQ it is based on the interrupt-names.
+	 * Without interrupt-names, we assume the irq belongs to INT1.
+	 */
+	irq_info = bmc150_accel_interrupts_int1;
+	if (irq == of_irq_get_byname(dev->of_node, "INT2"))
+		irq_info = bmc150_accel_interrupts_int2;
+
 	for (i = 0; i < BMC150_ACCEL_INTERRUPTS; i++)
-		data->interrupts[i].info = &bmc150_accel_interrupts[i];
+		data->interrupts[i].info = &irq_info[i];
 }
 
 static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
@@ -1714,7 +1761,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
 			goto err_buffer_cleanup;
 		}
 
-		bmc150_accel_interrupts_setup(indio_dev, data);
+		bmc150_accel_interrupts_setup(indio_dev, data, irq);
 
 		ret = bmc150_accel_triggers_setup(indio_dev, data);
 		if (ret)
-- 
2.32.0


  parent reply	other threads:[~2021-07-19 11:26 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-19 11:21 [PATCH 0/4] iio: accel: bmc150: Add support for INT2 and BMC156 Stephan Gerhold
2021-07-19 11:21 ` [PATCH 1/4] dt-bindings: iio: accel: bma255: Add interrupt-names Stephan Gerhold
2021-07-19 13:57   ` Linus Walleij
2021-07-24 16:00   ` Jonathan Cameron
2021-07-19 11:21 ` [PATCH 2/4] dt-bindings: iio: accel: bma255: Add bosch,bmc156_accel Stephan Gerhold
2021-07-19 13:58   ` Linus Walleij
2021-07-24 16:03   ` Jonathan Cameron
2021-07-29 19:10     ` Rob Herring
2021-07-29 19:10   ` Rob Herring
2021-07-19 11:21 ` Stephan Gerhold [this message]
2021-07-19 14:07   ` [PATCH 3/4] iio: accel: bmc150: Make it possible to configure INT2 instead of INT1 Linus Walleij
2021-07-19 15:01     ` Andy Shevchenko
2021-07-19 15:10       ` Stephan Gerhold
2021-07-19 16:19         ` Andy Shevchenko
2021-07-19 17:26           ` Stephan Gerhold
2021-07-19 18:05             ` Andy Shevchenko
2021-07-19 18:36               ` Stephan Gerhold
2021-07-20 15:04                 ` Andy Shevchenko
2021-07-24 16:19                   ` Jonathan Cameron
2021-07-24 18:06               ` Jonathan Cameron
2021-07-19 11:21 ` [PATCH 4/4] iio: accel: bmc150: Add support for BMC156 Stephan Gerhold
2021-07-19 14:08   ` Linus Walleij
2021-07-24 16:12   ` Jonathan Cameron
2021-07-27 18:32     ` Stephan Gerhold
2021-07-31 18:04       ` Jonathan Cameron
2021-07-19 12:34 ` [PATCH 0/4] iio: accel: bmc150: Add support for INT2 and BMC156 Andy Shevchenko
2021-07-19 12:42   ` Stephan Gerhold

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210719112156.27087-4-stephan@gerhold.net \
    --to=stephan@gerhold.net \
    --cc=andy.shevchenko@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=hdegoede@redhat.com \
    --cc=jic23@kernel.org \
    --cc=lars@metafoo.de \
    --cc=linus.walleij@linaro.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=nikita@trvn.ru \
    --cc=robh+dt@kernel.org \
    --cc=~postmarketos/upstreaming@lists.sr.ht \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).