All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Mack <zonque@gmail.com>
To: alsa-devel@alsa-project.org
Cc: broonie@kernel.org, lars@metafoo.de, Daniel Mack <zonque@gmail.com>
Subject: [PATCH v3 2/3] ASoC: codecs: adau1701: switch to direct regmap API usage
Date: Fri, 21 Jun 2013 09:54:43 +0200	[thread overview]
Message-ID: <1371801284-31603-3-git-send-email-zonque@gmail.com> (raw)
In-Reply-To: <1371801284-31603-1-git-send-email-zonque@gmail.com>

The hardware I/O has to be open-coded due to registers of unequal sizes.
Other than that, the transition is straight forward.

Signed-off-by: Daniel Mack <zonque@gmail.com>
---
 sound/soc/codecs/adau1701.c | 120 +++++++++++++++++++++++++++++++-------------
 1 file changed, 85 insertions(+), 35 deletions(-)

diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 6bc566f..c48f4c5 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -16,6 +16,7 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/of_device.h>
+#include <linux/regmap.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -24,16 +25,16 @@
 #include "sigmadsp.h"
 #include "adau1701.h"
 
-#define ADAU1701_DSPCTRL	0x1c
-#define ADAU1701_SEROCTL	0x1e
-#define ADAU1701_SERICTL	0x1f
+#define ADAU1701_DSPCTRL	0x081c
+#define ADAU1701_SEROCTL	0x081e
+#define ADAU1701_SERICTL	0x081f
 
-#define ADAU1701_AUXNPOW	0x22
+#define ADAU1701_AUXNPOW	0x0822
 
-#define ADAU1701_OSCIPOW	0x26
-#define ADAU1701_DACSET		0x27
+#define ADAU1701_OSCIPOW	0x0826
+#define ADAU1701_DACSET		0x0827
 
-#define ADAU1701_NUM_REGS	0x28
+#define ADAU1701_MAX_REGISTER	0x0828
 
 #define ADAU1701_DSPCTRL_CR		(1 << 2)
 #define ADAU1701_DSPCTRL_DAM		(1 << 3)
@@ -95,6 +96,7 @@ struct adau1701 {
 	unsigned int dai_fmt;
 	unsigned int pll_clkdiv;
 	unsigned int sysclk;
+	struct regmap *regmap;
 };
 
 static const struct snd_kcontrol_new adau1701_controls[] = {
@@ -126,7 +128,7 @@ static const struct snd_soc_dapm_route adau1701_dapm_routes[] = {
 	{ "ADC", NULL, "IN1" },
 };
 
-static unsigned int adau1701_register_size(struct snd_soc_codec *codec,
+static unsigned int adau1701_register_size(struct device *dev,
 		unsigned int reg)
 {
 	switch (reg) {
@@ -140,33 +142,42 @@ static unsigned int adau1701_register_size(struct snd_soc_codec *codec,
 		return 1;
 	}
 
-	dev_err(codec->dev, "Unsupported register address: %d\n", reg);
+	dev_err(dev, "Unsupported register address: %d\n", reg);
 	return 0;
 }
 
-static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,
-		unsigned int value)
+static bool adau1701_volatile_reg(struct device *dev, unsigned int reg)
 {
+	switch (reg) {
+	case ADAU1701_DACSET:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static int adau1701_reg_write(void *context, unsigned int reg,
+			      unsigned int value)
+{
+	struct i2c_client *client = context;
 	unsigned int i;
 	unsigned int size;
 	uint8_t buf[4];
 	int ret;
 
-	size = adau1701_register_size(codec, reg);
+	size = adau1701_register_size(&client->dev, reg);
 	if (size == 0)
 		return -EINVAL;
 
-	snd_soc_cache_write(codec, reg, value);
-
-	buf[0] = 0x08;
-	buf[1] = reg;
+	buf[0] = reg >> 8;
+	buf[1] = reg & 0xff;
 
 	for (i = size + 1; i >= 2; --i) {
 		buf[i] = value;
 		value >>= 8;
 	}
 
-	ret = i2c_master_send(to_i2c_client(codec->dev), buf, size + 2);
+	ret = i2c_master_send(client, buf, size + 2);
 	if (ret == size + 2)
 		return 0;
 	else if (ret < 0)
@@ -175,16 +186,45 @@ static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,
 		return -EIO;
 }
 
-static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg)
+static int adau1701_reg_read(void *context, unsigned int reg,
+			     unsigned int *value)
 {
-	unsigned int value;
-	unsigned int ret;
+	int ret;
+	unsigned int i;
+	unsigned int size;
+	uint8_t send_buf[2], recv_buf[3];
+	struct i2c_client *client = context;
+	struct i2c_msg msgs[2];
+
+	size = adau1701_register_size(&client->dev, reg);
+	if (size == 0)
+		return -EINVAL;
 
-	ret = snd_soc_cache_read(codec, reg, &value);
-	if (ret)
+	send_buf[0] = reg >> 8;
+	send_buf[1] = reg & 0xff;
+
+	msgs[0].addr = client->addr;
+	msgs[0].len = sizeof(send_buf);
+	msgs[0].buf = send_buf;
+	msgs[0].flags = 0;
+
+	msgs[1].addr = client->addr;
+	msgs[1].len = size;
+	msgs[1].buf = recv_buf;
+	msgs[1].flags = I2C_M_RD;
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret < 0)
 		return ret;
+	else if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
 
-	return value;
+	*value = 0;
+
+	for (i = 0; i < size; i++)
+		*value |= recv_buf[i] << (i * 8);
+
+	return 0;
 }
 
 static void adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
@@ -224,6 +264,9 @@ static void adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
 	gpio_set_value(adau1701->gpio_nreset, 1);
 	/* power-up time may be as long as 85ms */
 	mdelay(85);
+
+	regcache_mark_dirty(adau1701->regmap);
+	regcache_sync(adau1701->regmap);
 }
 
 static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
@@ -406,8 +449,8 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 	adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 
-	snd_soc_write(codec, ADAU1701_SERICTL, serictl);
-	snd_soc_update_bits(codec, ADAU1701_SEROCTL,
+	regmap_write(adau1701->regmap, ADAU1701_SERICTL, serictl);
+	regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL,
 		~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl);
 
 	return 0;
@@ -522,8 +565,6 @@ static int adau1701_probe(struct snd_soc_codec *codec)
 	struct i2c_client *client = to_i2c_client(codec->dev);
 	struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
 
-	codec->control_data = to_i2c_client(codec->dev);
-
 	/* initalize with pre-configured pll mode settings */
 	adau1701_reset(codec, adau1701->pll_clkdiv);
 
@@ -533,8 +574,8 @@ static int adau1701_probe(struct snd_soc_codec *codec)
 		return ret;
 	}
 
-	snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
-	snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
+	regmap_write(adau1701->regmap, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
+	regmap_write(adau1701->regmap, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
 
 	return 0;
 }
@@ -544,9 +585,6 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
 	.set_bias_level		= adau1701_set_bias_level,
 	.idle_bias_off		= true,
 
-	.reg_cache_size		= ADAU1701_NUM_REGS,
-	.reg_word_size		= sizeof(u16),
-
 	.controls		= adau1701_controls,
 	.num_controls		= ARRAY_SIZE(adau1701_controls),
 	.dapm_widgets		= adau1701_dapm_widgets,
@@ -554,12 +592,19 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
 	.dapm_routes		= adau1701_dapm_routes,
 	.num_dapm_routes	= ARRAY_SIZE(adau1701_dapm_routes),
 
-	.write			= adau1701_write,
-	.read			= adau1701_read,
-
 	.set_sysclk		= adau1701_set_sysclk,
 };
 
+static const struct regmap_config adau1701_regmap = {
+	.reg_bits		= 16,
+	.val_bits		= 32,
+	.max_register		= ADAU1701_MAX_REGISTER,
+	.cache_type		= REGCACHE_RBTREE,
+	.volatile_reg		= adau1701_volatile_reg,
+	.reg_write		= adau1701_reg_write,
+	.reg_read		= adau1701_reg_read,
+};
+
 static int adau1701_i2c_probe(struct i2c_client *client,
 			      const struct i2c_device_id *id)
 {
@@ -573,6 +618,11 @@ static int adau1701_i2c_probe(struct i2c_client *client,
 	if (!adau1701)
 		return -ENOMEM;
 
+	adau1701->regmap = devm_regmap_init(dev, NULL, client,
+					    &adau1701_regmap);
+	if (IS_ERR(adau1701->regmap))
+		return PTR_ERR(adau1701->regmap);
+
 	if (dev->of_node) {
 		gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
 		if (gpio_nreset < 0 && gpio_nreset != -ENOENT)
-- 
1.8.1.4

  parent reply	other threads:[~2013-06-21  7:54 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-21  7:54 [PATCH v3 0/3] ASoC: codecs: some more improvements for adau1701 Daniel Mack
2013-06-21  7:54 ` [PATCH v3 1/3] ASoC: codecs: adau1701: allow configuration of PLL mode pins Daniel Mack
2013-06-21  8:09   ` Lars-Peter Clausen
2013-06-21 15:00   ` Mark Brown
2013-06-21 17:46     ` Daniel Mack
2013-06-22 22:10       ` [ucm] Adding list for caching multiple opened control devices sajeesh sidharthan
2013-06-24 17:09         ` Daniel Mack
2013-06-25  6:10           ` Takashi Iwai
2013-06-21  7:54 ` Daniel Mack [this message]
2013-06-21  8:09   ` [PATCH v3 2/3] ASoC: codecs: adau1701: switch to direct regmap API usage Lars-Peter Clausen
2013-06-21  7:54 ` [PATCH v3 3/3] ASoC: codecs: adau1701: add support for pin muxing Daniel Mack
2013-06-21  8:09   ` Lars-Peter Clausen

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=1371801284-31603-3-git-send-email-zonque@gmail.com \
    --to=zonque@gmail.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=lars@metafoo.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.