lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <7b23e033-5cde-44e9-be97-10296833863b@roeck-us.net>
Date: Thu, 14 Nov 2024 22:58:05 -0800
From: Guenter Roeck <linux@...ck-us.net>
To: Mark Brown <broonie@...nel.org>
Cc: "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	Frank Li <Frank.Li@....com>
Subject: Re: regmap I3C support

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@...ck-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@...ck-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@...ck-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



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ