mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Guenter Roeck <linux@roeck-us.net>
To: Mark Brown <broonie@kernel.org>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Frank Li <Frank.Li@nxp.com>
Subject: Re: regmap I3C support
Date: Thu, 14 Nov 2024 22:58:05 -0800	[thread overview]
Message-ID: <7b23e033-5cde-44e9-be97-10296833863b@roeck-us.net> (raw)
In-Reply-To: <ZzYyu4ptPtYT6vJC@finisterre.sirena.org.uk>

On Thu, Nov 14, 2024 at 05:26:19PM +0000, Mark Brown wrote:
> On Thu, Nov 14, 2024 at 06:45:52AM -0800, Guenter Roeck wrote:
> 
> > We now use
> 
> > config SENSORS_TMP108
> >         tristate "Texas Instruments TMP108"
> >         depends on I2C
> >         depends on I3C || !I3C
> >         select REGMAP_I2C
> >         select REGMAP_I3C if I3C
> 
> > and in the i3c_probe function
> 
> > #ifdef CONFIG_REGMAP_I3C
> >         regmap = devm_regmap_init_i3c(i3cdev, &tmp108_regmap_config);
> > #else
> >         regmap = ERR_PTR(-ENODEV);
> > #endif
> >         if (IS_ERR(regmap))
> 
> > Clumsy, and not my preferred solution, but it works.
> 
> Right, so the fact that I3C depends on I2C deals with a lot of the
> problems that plague the I2C/SPI combination.  Ugh.  I guess the helper
> should be OK and there's not much doing for I2C/SPI.

Is it really that difficult for I2C and SPI ? The patch below seems to work
for the LTC2947 driver. It doesn't even need dummies (the compiler drops
the unused code), though I am not sure if that can be relied on. I thought
that dummy functions are needed, but maybe I am wrong.

The Kconfig for the combined ltc2947 driver is

config SENSORS_LTC2947
        tristate "Analog Devices LTC2947 High Precision Power and Energy Monitor"
        depends on I2C || SPI
        depends on I2C || I2C=n
        select REGMAP_I2C if I2C
        select REGMAP_SPI if SPI
        help
	...

Guenter

---
From 8b72bcea4f399b3ffbea07256c5e48af63dfd230 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Thu, 14 Nov 2024 17:30:01 -0800
Subject: [PATCH] Add infrastructure for supporting both I2C and SPI in single
 driver

Add support for register and unregister functions for drivers supporting
both I2C and SPI. Support situations where only one of the protocols is
enabled.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 include/linux/i2c_spi.h | 81 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 include/linux/i2c_spi.h

diff --git a/include/linux/i2c_spi.h b/include/linux/i2c_spi.h
new file mode 100644
index 000000000000..3a8d32355338
--- /dev/null
+++ b/include/linux/i2c_spi.h
@@ -0,0 +1,81 @@
+/*---------------------------------------------------------------------------
+ *
+ * i2c_spi.h
+ *     Copyright (c) 2024 Guenter Roeck <linux@roeck-us.net>
+ *
+ * API functions to support both I2C and SPI in a single driver.
+ */
+
+#ifndef I2C_SPI_H
+#define I2C_SPI_H
+
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+
+/**
+ * i2c_spi_driver_register() - Register an I2C and a SPI driver
+ * @i2cdrv: the I2C driver to register
+ * @spidrv: the SPI driver to register
+ *
+ * This function registers both @i2cdev and @spidev, and fails if one of these
+ * registrations fails. This is mainly useful for devices that support both I2C
+ * and SPI modes.
+ * Note that the function only registers drivers for the enabled protocol(s).
+ * If neither I2C nor SPI are enabled, it does nothing.
+ *
+ * Return: 0 if enabled registrations succeeded, a negative error code otherwise.
+ */
+static inline int i2c_spi_driver_register(struct i2c_driver *i2cdrv,
+					  struct spi_driver *spidrv)
+{
+	int ret = 0;
+
+	if (IS_ENABLED(CONFIG_I2C))
+		ret = i2c_add_driver(i2cdrv);
+	if (ret || !IS_ENABLED(CONFIG_SPI))
+		return ret;
+
+	ret = spi_register_driver(spidrv);
+	if (ret && IS_ENABLED(CONFIG_I2C))
+		i2c_del_driver(i2cdrv);
+
+	return ret;
+}
+
+/**
+ * i2c_spi_driver_unregister() - Unregister an I2C and a SPI driver
+ * @i2cdrv: the I2C driver to register
+ * @spidrv: the SPI driver to register
+ *
+ * This function unregisters both @i2cdrv and @i3cdrv.
+ * Note that the function only unregisters drivers for the enabled protocol(s).
+ */
+static inline void i2c_spi_driver_unregister(struct i2c_driver *i2cdrv,
+					     struct spi_driver *spidrv)
+{
+	if (IS_ENABLED(CONFIG_SPI))
+		spi_unregister_driver(spidrv);
+
+	if (IS_ENABLED(CONFIG_I2C))
+		i2c_del_driver(i2cdrv);
+}
+
+/**
+ * module_i2c_spi_driver() - Register a module providing an I2C and a SPI
+ *			     driver
+ * @__i2cdrv: the I2C driver to register
+ * @__spidrv: the SPI driver to register
+ *
+ * Provide generic init/exit functions that simply register/unregister an I2C
+ * and a SPI driver.
+ * This macro can be used even if CONFIG_I2C and/or CONFIG_SPI are disabled,
+ * in this case, only the enabled driver(s) driver will be registered.
+ * Should be used by any driver that does not require extra init/cleanup steps.
+ */
+#define module_i2c_spi_driver(__i2cdrv, __spidrv)	\
+	module_driver(__i2cdrv,				\
+		      i2c_spi_driver_register,		\
+		      i2c_spi_driver_unregister,	\
+		      __spidrv)
+
+#endif /* I2C_SPI_H */
-- 
2.45.2



  reply	other threads:[~2024-11-15  6:58 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-11 19:07 Guenter Roeck
2024-11-13 14:01 ` Mark Brown
2024-11-13 14:15   ` Guenter Roeck
2024-11-13 14:41     ` Mark Brown
2024-11-13 20:16       ` Guenter Roeck
2024-11-14 11:31         ` Mark Brown
2024-11-14 14:45           ` Guenter Roeck
2024-11-14 17:26             ` Mark Brown
2024-11-15  6:58               ` Guenter Roeck [this message]
2024-11-15 15:06                 ` Mark Brown
2024-11-15 15:46                   ` Guenter Roeck
2024-11-16  4:35               ` Guenter Roeck
2024-11-19 17:46                 ` Mark Brown
2024-11-19 18:41                   ` Guenter Roeck
2024-11-19 19:30                     ` Frank Li
2024-11-19 21:57                       ` Guenter Roeck
2024-11-19 22:22                         ` Frank Li

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=7b23e033-5cde-44e9-be97-10296833863b@roeck-us.net \
    --to=linux@roeck-us.net \
    --cc=Frank.Li@nxp.com \
    --cc=broonie@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /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

all inboxes | Powered by JetHome®