From: Lars-Peter Clausen <lars@metafoo.de>
To: Daniel Mack <zonque@gmail.com>
Cc: alsa-devel@alsa-project.org, broonie@kernel.org
Subject: Re: [PATCH v3 2/3] ASoC: codecs: adau1701: switch to direct regmap API usage
Date: Fri, 21 Jun 2013 10:09:06 +0200 [thread overview]
Message-ID: <51C40A22.1040503@metafoo.de> (raw)
In-Reply-To: <1371801284-31603-3-git-send-email-zonque@gmail.com>
On 06/21/2013 09:54 AM, Daniel Mack wrote:
> 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>
Acked-by: Lars-Peter Clausen <lars@metafoo.de>
Thanks.
> ---
> 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)
next prev parent reply other threads:[~2013-06-21 8:08 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 ` [PATCH v3 2/3] ASoC: codecs: adau1701: switch to direct regmap API usage Daniel Mack
2013-06-21 8:09 ` Lars-Peter Clausen [this message]
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=51C40A22.1040503@metafoo.de \
--to=lars@metafoo.de \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=zonque@gmail.com \
/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.