linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] ASoC: AC'97 regmap support and conversion
@ 2014-11-18 18:45 Lars-Peter Clausen
  2014-11-18 18:45 ` [PATCH 1/4] regmap: ac97: Add generic AC'97 callbacks Lars-Peter Clausen
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Lars-Peter Clausen @ 2014-11-18 18:45 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, linux-kernel, Lars-Peter Clausen

This series contains the final pieces for the AC'97 conversion to regmap.
The first patch adds a regmap backend for AC'97 devices that will use the
AC'97 bus of the device to perform reads and writes. The second patch adds a
bit of plumbing to the ASoC framework that it makes it possible to assign a
regmap instance to ASoC CODEC (or component) after it has been registered.
This is necessary since for AC'97 drivers we allocate the AC'97 device in
the CODEC drivers probe callback. For now the series only converts the
ad1980 driver, others might follow later.

- Lars 

Lars-Peter Clausen (3):
  ASoC: Add helper functions for deferred regmap setup
  ASoC: ad1980: Convert to regmap
  ASoC: ad1980: Remove ac97_read/ac97_write wrappers

Mark Brown (1):
  regmap: ac97: Add generic AC'97 callbacks

 drivers/base/regmap/Kconfig       |   5 +-
 drivers/base/regmap/Makefile      |   1 +
 drivers/base/regmap/regmap-ac97.c | 114 +++++++++++++++++++++++++
 include/linux/regmap.h            |   7 ++
 include/sound/soc.h               |  35 ++++++++
 sound/soc/codecs/Kconfig          |   1 +
 sound/soc/codecs/ad1980.c         | 173 +++++++++++++++++++++-----------------
 sound/soc/soc-core.c              |  58 ++++++++++---
 8 files changed, 306 insertions(+), 88 deletions(-)
 create mode 100644 drivers/base/regmap/regmap-ac97.c

-- 
1.8.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] regmap: ac97: Add generic AC'97 callbacks
  2014-11-18 18:45 [PATCH 0/4] ASoC: AC'97 regmap support and conversion Lars-Peter Clausen
@ 2014-11-18 18:45 ` Lars-Peter Clausen
  2014-11-19 10:24   ` [alsa-devel] " Lars-Peter Clausen
  2014-11-19 10:37   ` Mark Brown
  2014-11-18 18:45 ` [PATCH 2/4] ASoC: Add helper functions for deferred regmap setup Lars-Peter Clausen
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 10+ messages in thread
From: Lars-Peter Clausen @ 2014-11-18 18:45 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, linux-kernel, Mark Brown

From: Mark Brown <broonie@linaro.org>

Use the recently added support for bus operations to provide a standard
mapping for AC'97 register I/O.

Signed-off-by: Mark Brown <broonie@linaro.org>
---
Changes from the original version:
	* Add ac97_regmap_bus and made regmap_ac97_reg_{write,read} static
	* Use ac97->bus->ops instead of passing the ops separately
---
 drivers/base/regmap/Kconfig       |   5 +-
 drivers/base/regmap/Makefile      |   1 +
 drivers/base/regmap/regmap-ac97.c | 114 ++++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h            |   7 +++
 4 files changed, 126 insertions(+), 1 deletion(-)
 create mode 100644 drivers/base/regmap/regmap-ac97.c

diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
index 8a3f51f..db9d00c3 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -3,12 +3,15 @@
 # subsystems should select the appropriate symbols.
 
 config REGMAP
-	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_MMIO || REGMAP_IRQ)
+	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
 	select LZO_COMPRESS
 	select LZO_DECOMPRESS
 	select IRQ_DOMAIN if REGMAP_IRQ
 	bool
 
+config REGMAP_AC97
+	tristate
+
 config REGMAP_I2C
 	tristate
 	depends on I2C
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
index a7c670b..0a53365 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_REGMAP) += regmap.o regcache.o
 obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o regcache-flat.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_SPI) += regmap-spi.o
 obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o
diff --git a/drivers/base/regmap/regmap-ac97.c b/drivers/base/regmap/regmap-ac97.c
new file mode 100644
index 0000000..e4c45d2
--- /dev/null
+++ b/drivers/base/regmap/regmap-ac97.c
@@ -0,0 +1,114 @@
+/*
+ * Register map access API - AC'97 support
+ *
+ * Copyright 2013 Linaro Ltd.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include <sound/ac97_codec.h>
+
+bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case AC97_RESET:
+	case AC97_POWERDOWN:
+	case AC97_INT_PAGING:
+	case AC97_EXTENDED_ID:
+	case AC97_EXTENDED_STATUS:
+	case AC97_EXTENDED_MID:
+	case AC97_EXTENDED_MSTATUS:
+	case AC97_GPIO_STATUS:
+	case AC97_MISC_AFE:
+	case AC97_VENDOR_ID1:
+	case AC97_VENDOR_ID2:
+	case AC97_CODEC_CLASS_REV:
+	case AC97_PCI_SVID:
+	case AC97_PCI_SID:
+	case AC97_FUNC_SELECT:
+	case AC97_FUNC_INFO:
+	case AC97_SENSE_INFO:
+		return true;
+	default:
+		return false;
+	}
+}
+EXPORT_SYMBOL_GPL(regmap_ac97_default_volatile);
+
+static int regmap_ac97_reg_read(void *context, unsigned int reg,
+	unsigned int *val)
+{
+	struct snd_ac97 *ac97 = context;
+
+	*val = ac97->bus->ops->read(ac97, reg);
+
+	return 0;
+}
+
+static int regmap_ac97_reg_write(void *context, unsigned int reg,
+	unsigned int val)
+{
+	struct snd_ac97 *ac97 = context;
+
+	ac97->bus->ops->write(ac97, reg, val);
+
+	return 0;
+}
+
+static const struct regmap_bus ac97_regmap_bus = {
+		.reg_write = regmap_ac97_reg_write,
+		.reg_read = regmap_ac97_reg_read,
+};
+
+/**
+ * regmap_init_ac97(): Initialise AC'97 register map
+ *
+ * @ac97: 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.
+ */
+struct regmap *regmap_init_ac97(struct snd_ac97 *ac97,
+				const struct regmap_config *config)
+{
+	return regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config);
+}
+EXPORT_SYMBOL_GPL(regmap_init_ac97);
+
+/**
+ * devm_regmap_init_ac97(): Initialise AC'97 register map
+ *
+ * @ac97: 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.  The regmap will be automatically freed by the
+ * device management code.
+ */
+struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97,
+				     const struct regmap_config *config)
+{
+	return devm_regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config);
+}
+EXPORT_SYMBOL_GPL(devm_regmap_init_ac97);
+
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index c5ed83f..4419b99 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -27,6 +27,7 @@ struct spmi_device;
 struct regmap;
 struct regmap_range_cfg;
 struct regmap_field;
+struct snd_ac97;
 
 /* An enum of all the supported cache types */
 enum regcache_type {
@@ -340,6 +341,8 @@ struct regmap *regmap_init_spmi_ext(struct spmi_device *dev,
 struct regmap *regmap_init_mmio_clk(struct device *dev, const char *clk_id,
 				    void __iomem *regs,
 				    const struct regmap_config *config);
+struct regmap *regmap_init_ac97(struct snd_ac97 *ac97,
+				const struct regmap_config *config);
 
 struct regmap *devm_regmap_init(struct device *dev,
 				const struct regmap_bus *bus,
@@ -356,6 +359,10 @@ struct regmap *devm_regmap_init_spmi_ext(struct spmi_device *dev,
 struct regmap *devm_regmap_init_mmio_clk(struct device *dev, const char *clk_id,
 					 void __iomem *regs,
 					 const struct regmap_config *config);
+struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97,
+				     const struct regmap_config *config);
+
+bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
 
 /**
  * regmap_init_mmio(): Initialise register map
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] ASoC: Add helper functions for deferred regmap setup
  2014-11-18 18:45 [PATCH 0/4] ASoC: AC'97 regmap support and conversion Lars-Peter Clausen
  2014-11-18 18:45 ` [PATCH 1/4] regmap: ac97: Add generic AC'97 callbacks Lars-Peter Clausen
@ 2014-11-18 18:45 ` Lars-Peter Clausen
  2014-11-19 10:46   ` Mark Brown
  2014-11-18 18:45 ` [PATCH 3/4] ASoC: ad1980: Convert to regmap Lars-Peter Clausen
  2014-11-18 18:45 ` [PATCH 4/4] ASoC: ad1980: Remove ac97_read/ac97_write wrappers Lars-Peter Clausen
  3 siblings, 1 reply; 10+ messages in thread
From: Lars-Peter Clausen @ 2014-11-18 18:45 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, linux-kernel, Lars-Peter Clausen

Some drivers (most notably the AC'97 drivers) do not have access to their
regmap struct when the component/codec is registered. For those drivers the
automatic regmap setup will not work and needs to be done manually,
typically from the component/CODEC drivers probe callback.

This patch adds a set of helper function to handle deferred regmap
initialization as well as early regmap tear-down.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 include/sound/soc.h  | 35 +++++++++++++++++++++++++++++++
 sound/soc/soc-core.c | 58 ++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 86b2c77..879e2b3 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1283,6 +1283,41 @@ void snd_soc_component_async_complete(struct snd_soc_component *component);
 int snd_soc_component_test_bits(struct snd_soc_component *component,
 	unsigned int reg, unsigned int mask, unsigned int value);
 
+void snd_soc_component_init_regmap(struct snd_soc_component *component,
+	struct regmap *regmap);
+void snd_soc_component_exit_regmap(struct snd_soc_component *component);
+
+/**
+ * snd_soc_codec_init_regmap() - Initialize regmap instance for the CODEC
+ * @codec: The CODEC for which to initialize the regmap instance
+ * @regmap: The regmap instance that should be used by the CODEC
+ *
+ * This function allows deferred assignment of the regmap instance that is
+ * associated with the CODEC. Only use this if the regmap instance is not yet
+ * ready when the CODEC is registered. The function must also be called before
+ * the first IO attempt of the CODEC.
+ */
+static inline void snd_soc_codec_init_regmap(struct snd_soc_codec *codec,
+	struct regmap *regmap)
+{
+	snd_soc_component_init_regmap(&codec->component, regmap);
+}
+
+/**
+ * snd_soc_codec_exit_regmap() - De-initialize regmap instance for the CODEC
+ * @codec: The CODEC for which to de-initialize the regmap instance
+ *
+ * Calls regmap_exit() on the regmap instance associated to the CODEC and
+ * removes the regmap instance from the CODEC.
+ *
+ * This function should only be used if snd_soc_codec_init_regmap() was used to
+ * initialize the regmap instance.
+ */
+static inline void snd_soc_codec_exit_regmap(struct snd_soc_codec *codec)
+{
+	snd_soc_component_exit_regmap(&codec->component);
+}
+
 /* device driver data */
 
 static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 649dd8b..cc52ea1 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2603,22 +2603,58 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
 	return 0;
 }
 
-static void snd_soc_component_init_regmap(struct snd_soc_component *component)
+static void snd_soc_component_setup_regmap(struct snd_soc_component *component)
 {
-	if (!component->regmap)
-		component->regmap = dev_get_regmap(component->dev, NULL);
-	if (component->regmap) {
-		int val_bytes = regmap_get_val_bytes(component->regmap);
-		/* Errors are legitimate for non-integer byte multiples */
-		if (val_bytes > 0)
-			component->val_bytes = val_bytes;
-	}
+	int val_bytes = regmap_get_val_bytes(component->regmap);
+
+	/* Errors are legitimate for non-integer byte multiples */
+	if (val_bytes > 0)
+		component->val_bytes = val_bytes;
+}
+
+/**
+ * snd_soc_component_init_regmap() - Initialize regmap instance for the component
+ * @component: The component for which to initialize the regmap instance
+ * @regmap: The regmap instance that should be used by the component
+ *
+ * This function allows deferred assignment of the regmap instance that is
+ * associated with the component. Only use this if the regmap instance is not
+ * yet ready when the component is registered. The function must also be called
+ * before the first IO attempt of the component.
+ */
+void snd_soc_component_init_regmap(struct snd_soc_component *component,
+	struct regmap *regmap)
+{
+	component->regmap = regmap;
+	snd_soc_component_setup_regmap(component);
 }
+EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);
+
+/**
+ * snd_soc_component_exit_regmap() - De-initialize regmap instance for the component
+ * @component: The component for which to de-initialize the regmap instance
+ *
+ * Calls regmap_exit() on the regmap instance associated to the component and
+ * removes the regmap instance from the component.
+ *
+ * This function should only be used if snd_soc_component_init_regmap() was used
+ * to initialize the regmap instance.
+ */
+void snd_soc_component_exit_regmap(struct snd_soc_component *component)
+{
+	regmap_exit(component->regmap);
+	component->regmap = NULL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
 
 static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
 {
-	if (!component->write && !component->read)
-		snd_soc_component_init_regmap(component);
+	if (!component->write && !component->read) {
+		if (!component->regmap)
+			component->regmap = dev_get_regmap(component->dev, NULL);
+		if (component->regmap)
+			snd_soc_component_setup_regmap(component);
+	}
 
 	list_add(&component->list, &component_list);
 }
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] ASoC: ad1980: Convert to regmap
  2014-11-18 18:45 [PATCH 0/4] ASoC: AC'97 regmap support and conversion Lars-Peter Clausen
  2014-11-18 18:45 ` [PATCH 1/4] regmap: ac97: Add generic AC'97 callbacks Lars-Peter Clausen
  2014-11-18 18:45 ` [PATCH 2/4] ASoC: Add helper functions for deferred regmap setup Lars-Peter Clausen
@ 2014-11-18 18:45 ` Lars-Peter Clausen
  2014-11-19 10:49   ` Mark Brown
  2014-11-18 18:45 ` [PATCH 4/4] ASoC: ad1980: Remove ac97_read/ac97_write wrappers Lars-Peter Clausen
  3 siblings, 1 reply; 10+ messages in thread
From: Lars-Peter Clausen @ 2014-11-18 18:45 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, linux-kernel, Lars-Peter Clausen

This patch converts the ad1980 driver to use regmap for its IO.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/codecs/Kconfig  |   1 +
 sound/soc/codecs/ad1980.c | 141 ++++++++++++++++++++++++++++------------------
 2 files changed, 88 insertions(+), 54 deletions(-)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 072b784..883c577 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -226,6 +226,7 @@ config SND_SOC_AD193X_I2C
 	select SND_SOC_AD193X
 
 config SND_SOC_AD1980
+	select REGMAP_AC97
 	tristate
 
 config SND_SOC_AD73311
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 93bd47d..5fd4a29 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -24,32 +24,86 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
+#include <linux/regmap.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/ac97_codec.h>
 #include <sound/initval.h>
 #include <sound/soc.h>
 
-/*
- * AD1980 register cache
- */
-static const u16 ad1980_reg[] = {
-	0x0090, 0x8000, 0x8000, 0x8000, /* 0 - 6  */
-	0x0000, 0x0000, 0x8008, 0x8008, /* 8 - e  */
-	0x8808, 0x8808, 0x0000, 0x8808, /* 10 - 16 */
-	0x8808, 0x0000, 0x8000, 0x0000, /* 18 - 1e */
-	0x0000, 0x0000, 0x0000, 0x0000, /* 20 - 26 */
-	0x03c7, 0x0000, 0xbb80, 0xbb80, /* 28 - 2e */
-	0xbb80, 0xbb80, 0x0000, 0x8080, /* 30 - 36 */
-	0x8080, 0x2000, 0x0000, 0x0000, /* 38 - 3e */
-	0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
-	0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
-	0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
-	0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
-	0x8080, 0x0000, 0x0000, 0x0000, /* 60 - 66 */
-	0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
-	0x0000, 0x0000, 0x1001, 0x0000, /* 70 - 76 */
-	0x0000, 0x0000, 0x4144, 0x5370  /* 78 - 7e */
+static const struct reg_default ad1980_reg_defaults[] = {
+	{ 0x02, 0x8000 },
+	{ 0x04, 0x8000 },
+	{ 0x06, 0x8000 },
+	{ 0x0c, 0x8008 },
+	{ 0x0e, 0x8008 },
+	{ 0x10, 0x8808 },
+	{ 0x12, 0x8808 },
+	{ 0x16, 0x8808 },
+	{ 0x18, 0x8808 },
+	{ 0x1a, 0x0000 },
+	{ 0x1c, 0x8000 },
+	{ 0x20, 0x0000 },
+	{ 0x28, 0x03c7 },
+	{ 0x2c, 0xbb80 },
+	{ 0x2e, 0xbb80 },
+	{ 0x30, 0xbb80 },
+	{ 0x32, 0xbb80 },
+	{ 0x36, 0x8080 },
+	{ 0x38, 0x8080 },
+	{ 0x3a, 0x2000 },
+	{ 0x60, 0x0000 },
+	{ 0x62, 0x0000 },
+	{ 0x72, 0x0000 },
+	{ 0x74, 0x1001 },
+	{ 0x76, 0x0000 },
+};
+
+static bool ad1980_readable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case AC97_RESET ... AC97_MASTER_MONO:
+	case AC97_PHONE ... AC97_CD:
+	case AC97_AUX ... AC97_GENERAL_PURPOSE:
+	case AC97_POWERDOWN ... AC97_PCM_LR_ADC_RATE:
+	case AC97_SPDIF:
+	case AC97_CODEC_CLASS_REV:
+	case AC97_PCI_SVID:
+	case AC97_AD_CODEC_CFG:
+	case AC97_AD_JACK_SPDIF:
+	case AC97_AD_SERIAL_CFG:
+	case AC97_VENDOR_ID1:
+	case AC97_VENDOR_ID2:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool ad1980_writeable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case AC97_VENDOR_ID1:
+	case AC97_VENDOR_ID2:
+		return false;
+	default:
+		return ad1980_readable_reg(dev, reg);
+	}
+}
+
+static const struct regmap_config ad1980_regmap_config = {
+	.reg_bits = 16,
+	.reg_stride = 2,
+	.val_bits = 16,
+	.max_register = 0x7e,
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = regmap_ac97_default_volatile,
+	.readable_reg = ad1980_readable_reg,
+	.writeable_reg = ad1980_writeable_reg,
+
+	.reg_defaults = ad1980_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(ad1980_reg_defaults),
 };
 
 static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line",
@@ -135,39 +189,13 @@ static const struct snd_soc_dapm_route ad1980_dapm_routes[] = {
 static unsigned int ac97_read(struct snd_soc_codec *codec,
 	unsigned int reg)
 {
-	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
-	u16 *cache = codec->reg_cache;
-
-	switch (reg) {
-	case AC97_RESET:
-	case AC97_INT_PAGING:
-	case AC97_POWERDOWN:
-	case AC97_EXTENDED_STATUS:
-	case AC97_VENDOR_ID1:
-	case AC97_VENDOR_ID2:
-		return soc_ac97_ops->read(ac97, reg);
-	default:
-		reg = reg >> 1;
-
-		if (reg >= ARRAY_SIZE(ad1980_reg))
-			return -EINVAL;
-
-		return cache[reg];
-	}
+	return snd_soc_read(codec, reg);
 }
 
 static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
 	unsigned int val)
 {
-	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
-	u16 *cache = codec->reg_cache;
-
-	soc_ac97_ops->write(ac97, reg, val);
-	reg = reg >> 1;
-	if (reg < ARRAY_SIZE(ad1980_reg))
-		cache[reg] = val;
-
-	return 0;
+	return snd_soc_write(codec, reg, val);
 }
 
 static struct snd_soc_dai_driver ad1980_dai = {
@@ -219,6 +247,7 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
 static int ad1980_soc_probe(struct snd_soc_codec *codec)
 {
 	struct snd_ac97 *ac97;
+	struct regmap *regmap;
 	int ret;
 	u16 vendor_id2;
 	u16 ext_status;
@@ -230,6 +259,13 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
 		return ret;
 	}
 
+	regmap = regmap_init_ac97(ac97, &ad1980_regmap_config);
+	if (IS_ERR(regmap)) {
+		ret = PTR_ERR(regmap);
+		goto err_free_ac97;
+	}
+
+	snd_soc_codec_init_regmap(codec, regmap);
 	snd_soc_codec_set_drvdata(codec, ac97);
 
 	ret = ad1980_reset(codec, 0);
@@ -268,6 +304,8 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
 	return 0;
 
 reset_err:
+	snd_soc_codec_exit_regmap(codec);
+err_free_ac97:
 	snd_soc_free_ac97_codec(ac97);
 	return ret;
 }
@@ -276,6 +314,7 @@ static int ad1980_soc_remove(struct snd_soc_codec *codec)
 {
 	struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
 
+	snd_soc_codec_exit_regmap(codec);
 	snd_soc_free_ac97_codec(ac97);
 	return 0;
 }
@@ -283,12 +322,6 @@ static int ad1980_soc_remove(struct snd_soc_codec *codec)
 static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
 	.probe = 	ad1980_soc_probe,
 	.remove = 	ad1980_soc_remove,
-	.reg_cache_size = ARRAY_SIZE(ad1980_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = ad1980_reg,
-	.reg_cache_step = 2,
-	.write = ac97_write,
-	.read = ac97_read,
 
 	.controls = ad1980_snd_ac97_controls,
 	.num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls),
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] ASoC: ad1980: Remove ac97_read/ac97_write wrappers
  2014-11-18 18:45 [PATCH 0/4] ASoC: AC'97 regmap support and conversion Lars-Peter Clausen
                   ` (2 preceding siblings ...)
  2014-11-18 18:45 ` [PATCH 3/4] ASoC: ad1980: Convert to regmap Lars-Peter Clausen
@ 2014-11-18 18:45 ` Lars-Peter Clausen
  2014-11-19 10:49   ` Mark Brown
  3 siblings, 1 reply; 10+ messages in thread
From: Lars-Peter Clausen @ 2014-11-18 18:45 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, linux-kernel, Lars-Peter Clausen

Since the regmap conversion ac97_read/ac97_write are just simple wrappers
around snd_soc_read/snd_soc_write. Use those instead directly and remove the
wrappers.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 sound/soc/codecs/ad1980.c | 36 ++++++++++++------------------------
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 5fd4a29..2860eef 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -186,18 +186,6 @@ static const struct snd_soc_dapm_route ad1980_dapm_routes[] = {
 	{ "HP_OUT_R", NULL, "Playback" },
 };
 
-static unsigned int ac97_read(struct snd_soc_codec *codec,
-	unsigned int reg)
-{
-	return snd_soc_read(codec, reg);
-}
-
-static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
-	unsigned int val)
-{
-	return snd_soc_write(codec, reg, val);
-}
-
 static struct snd_soc_dai_driver ad1980_dai = {
 	.name = "ad1980-hifi",
 	.playback = {
@@ -222,7 +210,7 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
 	do {
 		if (try_warm && soc_ac97_ops->warm_reset) {
 			soc_ac97_ops->warm_reset(ac97);
-			if (ac97_read(codec, AC97_RESET) == 0x0090)
+			if (snd_soc_read(codec, AC97_RESET) == 0x0090)
 				return 1;
 		}
 
@@ -233,9 +221,9 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
 		 * case the first nibble of data is eaten by the addr. (Tag is
 		 * always 16 bit)
 		 */
-		ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
+		snd_soc_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
 
-		if (ac97_read(codec, AC97_RESET)  == 0x0090)
+		if (snd_soc_read(codec, AC97_RESET)  == 0x0090)
 			return 0;
 	} while (retry_cnt++ < 10);
 
@@ -273,12 +261,12 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
 		goto reset_err;
 
 	/* Read out vendor ID to make sure it is ad1980 */
-	if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) {
+	if (snd_soc_read(codec, AC97_VENDOR_ID1) != 0x4144) {
 		ret = -ENODEV;
 		goto reset_err;
 	}
 
-	vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2);
+	vendor_id2 = snd_soc_read(codec, AC97_VENDOR_ID2);
 
 	if (vendor_id2 != 0x5370) {
 		if (vendor_id2 != 0x5374) {
@@ -291,15 +279,15 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
 	}
 
 	/* unmute captures and playbacks volume */
-	ac97_write(codec, AC97_MASTER, 0x0000);
-	ac97_write(codec, AC97_PCM, 0x0000);
-	ac97_write(codec, AC97_REC_GAIN, 0x0000);
-	ac97_write(codec, AC97_CENTER_LFE_MASTER, 0x0000);
-	ac97_write(codec, AC97_SURROUND_MASTER, 0x0000);
+	snd_soc_write(codec, AC97_MASTER, 0x0000);
+	snd_soc_write(codec, AC97_PCM, 0x0000);
+	snd_soc_write(codec, AC97_REC_GAIN, 0x0000);
+	snd_soc_write(codec, AC97_CENTER_LFE_MASTER, 0x0000);
+	snd_soc_write(codec, AC97_SURROUND_MASTER, 0x0000);
 
 	/*power on LFE/CENTER/Surround DACs*/
-	ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
-	ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
+	ext_status = snd_soc_read(codec, AC97_EXTENDED_STATUS);
+	snd_soc_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
 
 	return 0;
 
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [alsa-devel] [PATCH 1/4] regmap: ac97: Add generic AC'97 callbacks
  2014-11-18 18:45 ` [PATCH 1/4] regmap: ac97: Add generic AC'97 callbacks Lars-Peter Clausen
@ 2014-11-19 10:24   ` Lars-Peter Clausen
  2014-11-19 10:37   ` Mark Brown
  1 sibling, 0 replies; 10+ messages in thread
From: Lars-Peter Clausen @ 2014-11-19 10:24 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, linux-kernel, Mark Brown

On 11/18/2014 07:45 PM, Lars-Peter Clausen wrote:
> From: Mark Brown <broonie@linaro.org>
>
> Use the recently added support for bus operations to provide a standard
> mapping for AC'97 register I/O.
>
> Signed-off-by: Mark Brown <broonie@linaro.org>

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>

Sorry for that.

> ---
> Changes from the original version:
> 	* Add ac97_regmap_bus and made regmap_ac97_reg_{write,read} static
> 	* Use ac97->bus->ops instead of passing the ops separately
> ---
>   drivers/base/regmap/Kconfig       |   5 +-
>   drivers/base/regmap/Makefile      |   1 +
>   drivers/base/regmap/regmap-ac97.c | 114 ++++++++++++++++++++++++++++++++++++++
>   include/linux/regmap.h            |   7 +++
>   4 files changed, 126 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/base/regmap/regmap-ac97.c
>
> diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
> index 8a3f51f..db9d00c3 100644
> --- a/drivers/base/regmap/Kconfig
> +++ b/drivers/base/regmap/Kconfig
> @@ -3,12 +3,15 @@
>   # subsystems should select the appropriate symbols.
>
>   config REGMAP
> -	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_MMIO || REGMAP_IRQ)
> +	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
>   	select LZO_COMPRESS
>   	select LZO_DECOMPRESS
>   	select IRQ_DOMAIN if REGMAP_IRQ
>   	bool
>
> +config REGMAP_AC97
> +	tristate
> +
>   config REGMAP_I2C
>   	tristate
>   	depends on I2C
> diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
> index a7c670b..0a53365 100644
> --- a/drivers/base/regmap/Makefile
> +++ b/drivers/base/regmap/Makefile
> @@ -1,6 +1,7 @@
>   obj-$(CONFIG_REGMAP) += regmap.o regcache.o
>   obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o regcache-flat.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_SPI) += regmap-spi.o
>   obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o
> diff --git a/drivers/base/regmap/regmap-ac97.c b/drivers/base/regmap/regmap-ac97.c
> new file mode 100644
> index 0000000..e4c45d2
> --- /dev/null
> +++ b/drivers/base/regmap/regmap-ac97.c
> @@ -0,0 +1,114 @@
> +/*
> + * Register map access API - AC'97 support
> + *
> + * Copyright 2013 Linaro Ltd.  All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +#include <sound/ac97_codec.h>
> +
> +bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case AC97_RESET:
> +	case AC97_POWERDOWN:
> +	case AC97_INT_PAGING:
> +	case AC97_EXTENDED_ID:
> +	case AC97_EXTENDED_STATUS:
> +	case AC97_EXTENDED_MID:
> +	case AC97_EXTENDED_MSTATUS:
> +	case AC97_GPIO_STATUS:
> +	case AC97_MISC_AFE:
> +	case AC97_VENDOR_ID1:
> +	case AC97_VENDOR_ID2:
> +	case AC97_CODEC_CLASS_REV:
> +	case AC97_PCI_SVID:
> +	case AC97_PCI_SID:
> +	case AC97_FUNC_SELECT:
> +	case AC97_FUNC_INFO:
> +	case AC97_SENSE_INFO:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +EXPORT_SYMBOL_GPL(regmap_ac97_default_volatile);
> +
> +static int regmap_ac97_reg_read(void *context, unsigned int reg,
> +	unsigned int *val)
> +{
> +	struct snd_ac97 *ac97 = context;
> +
> +	*val = ac97->bus->ops->read(ac97, reg);
> +
> +	return 0;
> +}
> +
> +static int regmap_ac97_reg_write(void *context, unsigned int reg,
> +	unsigned int val)
> +{
> +	struct snd_ac97 *ac97 = context;
> +
> +	ac97->bus->ops->write(ac97, reg, val);
> +
> +	return 0;
> +}
> +
> +static const struct regmap_bus ac97_regmap_bus = {
> +		.reg_write = regmap_ac97_reg_write,
> +		.reg_read = regmap_ac97_reg_read,
> +};
> +
> +/**
> + * regmap_init_ac97(): Initialise AC'97 register map
> + *
> + * @ac97: 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.
> + */
> +struct regmap *regmap_init_ac97(struct snd_ac97 *ac97,
> +				const struct regmap_config *config)
> +{
> +	return regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config);
> +}
> +EXPORT_SYMBOL_GPL(regmap_init_ac97);
> +
> +/**
> + * devm_regmap_init_ac97(): Initialise AC'97 register map
> + *
> + * @ac97: 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.  The regmap will be automatically freed by the
> + * device management code.
> + */
> +struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97,
> +				     const struct regmap_config *config)
> +{
> +	return devm_regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config);
> +}
> +EXPORT_SYMBOL_GPL(devm_regmap_init_ac97);
> +
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/regmap.h b/include/linux/regmap.h
> index c5ed83f..4419b99 100644
> --- a/include/linux/regmap.h
> +++ b/include/linux/regmap.h
> @@ -27,6 +27,7 @@ struct spmi_device;
>   struct regmap;
>   struct regmap_range_cfg;
>   struct regmap_field;
> +struct snd_ac97;
>
>   /* An enum of all the supported cache types */
>   enum regcache_type {
> @@ -340,6 +341,8 @@ struct regmap *regmap_init_spmi_ext(struct spmi_device *dev,
>   struct regmap *regmap_init_mmio_clk(struct device *dev, const char *clk_id,
>   				    void __iomem *regs,
>   				    const struct regmap_config *config);
> +struct regmap *regmap_init_ac97(struct snd_ac97 *ac97,
> +				const struct regmap_config *config);
>
>   struct regmap *devm_regmap_init(struct device *dev,
>   				const struct regmap_bus *bus,
> @@ -356,6 +359,10 @@ struct regmap *devm_regmap_init_spmi_ext(struct spmi_device *dev,
>   struct regmap *devm_regmap_init_mmio_clk(struct device *dev, const char *clk_id,
>   					 void __iomem *regs,
>   					 const struct regmap_config *config);
> +struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97,
> +				     const struct regmap_config *config);
> +
> +bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
>
>   /**
>    * regmap_init_mmio(): Initialise register map
>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] regmap: ac97: Add generic AC'97 callbacks
  2014-11-18 18:45 ` [PATCH 1/4] regmap: ac97: Add generic AC'97 callbacks Lars-Peter Clausen
  2014-11-19 10:24   ` [alsa-devel] " Lars-Peter Clausen
@ 2014-11-19 10:37   ` Mark Brown
  1 sibling, 0 replies; 10+ messages in thread
From: Mark Brown @ 2014-11-19 10:37 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Liam Girdwood, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 244 bytes --]

On Tue, Nov 18, 2014 at 07:45:51PM +0100, Lars-Peter Clausen wrote:
> From: Mark Brown <broonie@linaro.org>
> 
> Use the recently added support for bus operations to provide a standard
> mapping for AC'97 register I/O.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] ASoC: Add helper functions for deferred regmap setup
  2014-11-18 18:45 ` [PATCH 2/4] ASoC: Add helper functions for deferred regmap setup Lars-Peter Clausen
@ 2014-11-19 10:46   ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2014-11-19 10:46 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Liam Girdwood, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 371 bytes --]

On Tue, Nov 18, 2014 at 07:45:52PM +0100, Lars-Peter Clausen wrote:
> Some drivers (most notably the AC'97 drivers) do not have access to their
> regmap struct when the component/codec is registered. For those drivers the
> automatic regmap setup will not work and needs to be done manually,
> typically from the component/CODEC drivers probe callback.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/4] ASoC: ad1980: Convert to regmap
  2014-11-18 18:45 ` [PATCH 3/4] ASoC: ad1980: Convert to regmap Lars-Peter Clausen
@ 2014-11-19 10:49   ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2014-11-19 10:49 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Liam Girdwood, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 152 bytes --]

On Tue, Nov 18, 2014 at 07:45:53PM +0100, Lars-Peter Clausen wrote:
> This patch converts the ad1980 driver to use regmap for its IO.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] ASoC: ad1980: Remove ac97_read/ac97_write wrappers
  2014-11-18 18:45 ` [PATCH 4/4] ASoC: ad1980: Remove ac97_read/ac97_write wrappers Lars-Peter Clausen
@ 2014-11-19 10:49   ` Mark Brown
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2014-11-19 10:49 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Liam Girdwood, alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 253 bytes --]

On Tue, Nov 18, 2014 at 07:45:54PM +0100, Lars-Peter Clausen wrote:
> Since the regmap conversion ac97_read/ac97_write are just simple wrappers
> around snd_soc_read/snd_soc_write. Use those instead directly and remove the
> wrappers.

Applied, thanks.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-11-19 10:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-18 18:45 [PATCH 0/4] ASoC: AC'97 regmap support and conversion Lars-Peter Clausen
2014-11-18 18:45 ` [PATCH 1/4] regmap: ac97: Add generic AC'97 callbacks Lars-Peter Clausen
2014-11-19 10:24   ` [alsa-devel] " Lars-Peter Clausen
2014-11-19 10:37   ` Mark Brown
2014-11-18 18:45 ` [PATCH 2/4] ASoC: Add helper functions for deferred regmap setup Lars-Peter Clausen
2014-11-19 10:46   ` Mark Brown
2014-11-18 18:45 ` [PATCH 3/4] ASoC: ad1980: Convert to regmap Lars-Peter Clausen
2014-11-19 10:49   ` Mark Brown
2014-11-18 18:45 ` [PATCH 4/4] ASoC: ad1980: Remove ac97_read/ac97_write wrappers Lars-Peter Clausen
2014-11-19 10:49   ` Mark Brown

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).