]> git.karo-electronics.de Git - linux-beck.git/commitdiff
ASoC: adau1701: switch to direct regmap API usage
authorDaniel Mack <zonque@gmail.com>
Mon, 24 Jun 2013 14:31:31 +0000 (16:31 +0200)
committerMark Brown <broonie@linaro.org>
Tue, 25 Jun 2013 09:32:13 +0000 (10:32 +0100)
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>
Signed-off-by: Mark Brown <broonie@linaro.org>
sound/soc/codecs/adau1701.c

index 770d90ee5f92b56f5ef56d60f970a312e9f3e9bd..881bab4a65aab3e937be32379c867cb3d5c96b01 100644 (file)
@@ -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>
 #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)
@@ -97,6 +98,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[] = {
@@ -128,7 +130,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) {
@@ -142,33 +144,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)
@@ -177,16 +188,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;
+
+       *value = 0;
+
+       for (i = 0; i < size; i++)
+               *value |= recv_buf[i] << (i * 8);
 
-       return value;
+       return 0;
 }
 
 static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
@@ -242,8 +282,11 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
                }
        }
 
-       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);
+
+       regcache_mark_dirty(adau1701->regmap);
+       regcache_sync(adau1701->regmap);
 
        return 0;
 }
@@ -429,8 +472,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;
@@ -567,9 +610,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,
@@ -577,12 +617,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)
 {
@@ -596,6 +643,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)