commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=3796f377359c093a16e8f20249d7add697b13b1b
branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/2011R1

Add regmap support to the ASoC framework.

Note that we only use regmap for those drivers which explicitly request it, to
avoid potential regressions.

Signed-off-by: Lars-Peter Clausen <[email protected]>
---
 include/sound/soc.h   |    1 +
 sound/soc/soc-cache.c |   88 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 3a4bd3a..701f310 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -250,6 +250,7 @@ extern struct snd_ac97_bus_ops soc_ac97_ops;
 enum snd_soc_control_type {
 	SND_SOC_I2C = 1,
 	SND_SOC_SPI,
+	SND_SOC_REGMAP,
 };
 
 enum snd_soc_compress_type {
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index d9e9682..3a2c625 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -17,6 +17,7 @@
 #include <linux/lzo.h>
 #include <linux/bitmap.h>
 #include <linux/rbtree.h>
+#include <linux/regmap.h>
 
 #include <trace/events/asoc.h>
 
@@ -389,6 +390,80 @@ static struct {
 	},
 };
 
+#ifdef CONFIG_REGMAP
+
+static int snd_soc_regmap_hw_write(struct snd_soc_codec *codec, unsigned int reg,
+		    unsigned int value)
+{
+	int ret;
+
+	if (!snd_soc_codec_volatile_register(codec, reg) &&
+	    reg < codec->driver->reg_cache_size &&
+	    !codec->cache_bypass) {
+		ret = snd_soc_cache_write(codec, reg, value);
+		if (ret < 0)
+			return -1;
+	}
+
+	if (codec->cache_only) {
+		codec->cache_sync = 1;
+		return 0;
+	}
+
+	return regmap_write(codec->control_data, reg, value);
+}
+
+static unsigned int snd_soc_regmap_hw_read(struct snd_soc_codec *codec, unsigned int reg)
+{
+	int ret;
+	unsigned int val;
+
+	if (reg >= codec->driver->reg_cache_size ||
+	    snd_soc_codec_volatile_register(codec, reg) ||
+	    codec->cache_bypass) {
+		if (codec->cache_only)
+			return -1;
+
+		ret = regmap_read(codec->control_data, reg, &val);
+		if (ret == 0)
+			return val;
+		else
+			return -1;
+	}
+
+	ret = snd_soc_cache_read(codec, reg, &val);
+	if (ret < 0)
+		return -1;
+	return val;
+}
+
+/* Primitive bulk write support for soc-cache.  The data pointed to by
+ * `data' needs to already be in the form the hardware expects.  Any
+ * data written through this function will not go through the cache as
+ * it only handles writing to volatile or out of bounds registers.
+ *
+ * This is currently only supported for devices using the regmap API
+ * wrappers.
+ */
+static int snd_soc_regmap_hw_bulk_write_raw(struct snd_soc_codec *codec,
+				     unsigned int reg,
+				     const void *data, size_t len)
+{
+	/* To ensure that we don't get out of sync with the cache, check
+	 * whether the base register is volatile or if we've directly asked
+	 * to bypass the cache.  Out of bounds registers are considered
+	 * volatile.
+	 */
+	if (!codec->cache_bypass
+	    && !snd_soc_codec_volatile_register(codec, reg)
+	    && reg < codec->driver->reg_cache_size)
+		return -EINVAL;
+
+	return regmap_raw_write(codec->control_data, reg, data, len);
+}
+
+#endif
+
 /**
  * snd_soc_codec_set_cache_io: Set up standard I/O functions.
  *
@@ -414,6 +489,16 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
 {
 	int i;
 
+#ifdef CONFIG_REGMAP
+	if (control == SND_SOC_REGMAP) {
+		codec->write = snd_soc_regmap_hw_write;
+		codec->read = snd_soc_regmap_hw_read;
+		codec->bulk_write_raw = snd_soc_regmap_hw_bulk_write_raw;
+
+		return 0;
+	}
+#endif
+
 	for (i = 0; i < ARRAY_SIZE(io_types); i++)
 		if (io_types[i].addr_bits == addr_bits &&
 		    io_types[i].data_bits == data_bits)
@@ -453,6 +538,9 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
 						   struct spi_device,
 						   dev);
 		break;
+	default:
+		BUG();
+		return -EINVAL;
 	}
 
 	return 0;
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to