regmap: add SLIMbus support
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Mon, 11 Dec 2017 23:43:02 +0000 (23:43 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 19 Dec 2017 10:01:03 +0000 (11:01 +0100)
This patch adds support to read/write SLIMbus value elements.
Currently it only supports byte read/write. Adding this support in
regmap would give codec drivers more flexibility when there are more
than 2 control interfaces like SLIMbus, i2c.

Without this patch each codec driver has to directly call SLIMbus value
element apis, and this could would get messy once we want to add i2c
interface to it.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Reviwed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/regmap/Kconfig
drivers/base/regmap/Makefile
drivers/base/regmap/regmap-slimbus.c [new file with mode: 0644]
include/linux/regmap.h

index 3a1535d812d8c9d393338c30444cc64bb7d09651..cc162b48c6d7706070cc4ded11046acfefe31822 100644 (file)
@@ -21,6 +21,10 @@ config REGMAP_I2C
        tristate
        depends on I2C
 
+config REGMAP_SLIMBUS
+       tristate
+       depends on SLIMBUS
+
 config REGMAP_SPI
        tristate
        depends on SPI
index 0d298c446108e9787e4fdb701fd89b6933ca9c8b..63dec9222892fff95b5d1c2f366cd3d26731951b 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o
 obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
 obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o
 obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
+obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o
 obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
 obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o
 obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
diff --git a/drivers/base/regmap/regmap-slimbus.c b/drivers/base/regmap/regmap-slimbus.c
new file mode 100644 (file)
index 0000000..c90bee8
--- /dev/null
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017, Linaro Ltd.
+
+#include <linux/regmap.h>
+#include <linux/slimbus.h>
+#include <linux/module.h>
+
+#include "internal.h"
+
+static int regmap_slimbus_byte_reg_read(void *context, unsigned int reg,
+                                       unsigned int *val)
+{
+       struct slim_device *sdev = context;
+       int v;
+
+       v = slim_readb(sdev, reg);
+
+       if (v < 0)
+               return v;
+
+       *val = v;
+
+       return 0;
+}
+
+static int regmap_slimbus_byte_reg_write(void *context, unsigned int reg,
+                                        unsigned int val)
+{
+       struct slim_device *sdev = context;
+
+       return slim_writeb(sdev, reg, val);
+}
+
+static struct regmap_bus regmap_slimbus_bus = {
+       .reg_write = regmap_slimbus_byte_reg_write,
+       .reg_read = regmap_slimbus_byte_reg_read,
+       .reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
+       .val_format_endian_default = REGMAP_ENDIAN_LITTLE,
+};
+
+static const struct regmap_bus *regmap_get_slimbus(struct slim_device *slim,
+                                       const struct regmap_config *config)
+{
+       if (config->val_bits == 8 && config->reg_bits == 8)
+               return &regmap_slimbus_bus;
+
+       return ERR_PTR(-ENOTSUPP);
+}
+
+struct regmap *__regmap_init_slimbus(struct slim_device *slimbus,
+                                    const struct regmap_config *config,
+                                    struct lock_class_key *lock_key,
+                                    const char *lock_name)
+{
+       const struct regmap_bus *bus = regmap_get_slimbus(slimbus, config);
+
+       if (IS_ERR(bus))
+               return ERR_CAST(bus);
+
+       return __regmap_init(&slimbus->dev, bus, &slimbus->dev, config,
+                            lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__regmap_init_slimbus);
+
+struct regmap *__devm_regmap_init_slimbus(struct slim_device *slimbus,
+                                         const struct regmap_config *config,
+                                         struct lock_class_key *lock_key,
+                                         const char *lock_name)
+{
+       const struct regmap_bus *bus = regmap_get_slimbus(slimbus, config);
+
+       if (IS_ERR(bus))
+               return ERR_CAST(bus);
+
+       return __devm_regmap_init(&slimbus->dev, bus, &slimbus, config,
+                                 lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__devm_regmap_init_slimbus);
+
+MODULE_LICENSE("GPL v2");
index 15eddc1353bae3a272f6bbae881abe97981c0a6b..b2207737a159ffbe6e30dfa981c6b6b3d233843a 100644 (file)
@@ -24,6 +24,7 @@ struct module;
 struct device;
 struct i2c_client;
 struct irq_domain;
+struct slim_device;
 struct spi_device;
 struct spmi_device;
 struct regmap;
@@ -499,6 +500,10 @@ struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
                                 const struct regmap_config *config,
                                 struct lock_class_key *lock_key,
                                 const char *lock_name);
+struct regmap *__regmap_init_slimbus(struct slim_device *slimbus,
+                                const struct regmap_config *config,
+                                struct lock_class_key *lock_key,
+                                const char *lock_name);
 struct regmap *__regmap_init_spi(struct spi_device *dev,
                                 const struct regmap_config *config,
                                 struct lock_class_key *lock_key,
@@ -615,6 +620,19 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,
        __regmap_lockdep_wrapper(__regmap_init_i2c, #config,            \
                                i2c, config)
 
+/**
+ * regmap_init_slimbus() - Initialise register map
+ *
+ * @slimbus: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_slimbus(slimbus, config)                           \
+       __regmap_lockdep_wrapper(__regmap_init_slimbus, #config,        \
+                               slimbus, config)
+
 /**
  * regmap_init_spi() - Initialise register map
  *