ASoC: Convert wm8804 to direct regmap API usage
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Thu, 29 Dec 2011 19:58:06 +0000 (19:58 +0000)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 20 Jan 2012 13:58:23 +0000 (13:58 +0000)
The register map for this device is actually fairly sparse so the rbtree
should be beneficial.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
sound/soc/codecs/wm8804.c

index a9f1eb334f7b46d2444aedbbdc86391099b74252..8abe3757a979b7149c61abe6b7b39f61a480043a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/of_device.h>
 #include <linux/spi/spi.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -35,45 +36,33 @@ static const char *wm8804_supply_names[WM8804_NUM_SUPPLIES] = {
        "DVDD"
 };
 
-static const u8 wm8804_reg_defs[] = {
-       0x05,     /* R0  - RST/DEVID1 */
-       0x88,     /* R1  - DEVID2 */
-       0x04,     /* R2  - DEVREV */
-       0x21,     /* R3  - PLL1 */
-       0xFD,     /* R4  - PLL2 */
-       0x36,     /* R5  - PLL3 */
-       0x07,     /* R6  - PLL4 */
-       0x16,     /* R7  - PLL5 */
-       0x18,     /* R8  - PLL6 */
-       0xFF,     /* R9  - SPDMODE */
-       0x00,     /* R10 - INTMASK */
-       0x00,     /* R11 - INTSTAT */
-       0x00,     /* R12 - SPDSTAT */
-       0x00,     /* R13 - RXCHAN1 */
-       0x00,     /* R14 - RXCHAN2 */
-       0x00,     /* R15 - RXCHAN3 */
-       0x00,     /* R16 - RXCHAN4 */
-       0x00,     /* R17 - RXCHAN5 */
-       0x00,     /* R18 - SPDTX1 */
-       0x00,     /* R19 - SPDTX2 */
-       0x00,     /* R20 - SPDTX3 */
-       0x71,     /* R21 - SPDTX4 */
-       0x0B,     /* R22 - SPDTX5 */
-       0x70,     /* R23 - GPO0 */
-       0x57,     /* R24 - GPO1 */
-       0x00,     /* R25 */
-       0x42,     /* R26 - GPO2 */
-       0x06,     /* R27 - AIFTX */
-       0x06,     /* R28 - AIFRX */
-       0x80,     /* R29 - SPDRX1 */
-       0x07,     /* R30 - PWRDN */
+static const struct reg_default wm8804_reg_defaults[] = {
+       { 3,  0x21 },     /* R3  - PLL1 */
+       { 4,  0xFD },     /* R4  - PLL2 */
+       { 5,  0x36 },     /* R5  - PLL3 */
+       { 6,  0x07 },     /* R6  - PLL4 */
+       { 7,  0x16 },     /* R7  - PLL5 */
+       { 8,  0x18 },     /* R8  - PLL6 */
+       { 9,  0xFF },     /* R9  - SPDMODE */
+       { 10, 0x00 },     /* R10 - INTMASK */
+       { 18, 0x00 },     /* R18 - SPDTX1 */
+       { 19, 0x00 },     /* R19 - SPDTX2 */
+       { 20, 0x00 },     /* R20 - SPDTX3 */
+       { 21, 0x71 },     /* R21 - SPDTX4 */
+       { 22, 0x0B },     /* R22 - SPDTX5 */
+       { 23, 0x70 },     /* R23 - GPO0 */
+       { 24, 0x57 },     /* R24 - GPO1 */
+       { 26, 0x42 },     /* R26 - GPO2 */
+       { 27, 0x06 },     /* R27 - AIFTX */
+       { 28, 0x06 },     /* R28 - AIFRX */
+       { 29, 0x80 },     /* R29 - SPDRX1 */
+       { 30, 0x07 },     /* R30 - PWRDN */
 };
 
 struct wm8804_priv {
-       enum snd_soc_control_type control_type;
+       struct regmap *regmap;
        struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
        struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
-       struct snd_soc_codec *codec;
 };
 
 static int txsrc_get(struct snd_kcontrol *kcontrol,
@@ -94,7 +83,7 @@ static int wm8804_regulator_event_##n(struct notifier_block *nb, \
        struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \
                                                  disable_nb[n]); \
        if (event & REGULATOR_EVENT_DISABLE) { \
-               wm8804->codec->cache_sync = 1; \
+               regcache_mark_dirty(wm8804->regmap);    \
        } \
        return 0; \
 }
@@ -176,7 +165,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8804_volatile(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case WM8804_RST_DEVID1:
@@ -189,12 +178,10 @@ static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg)
        case WM8804_RXCHAN3:
        case WM8804_RXCHAN4:
        case WM8804_RXCHAN5:
-               return 1;
+               return true;
        default:
-               break;
+               return false;
        }
-
-       return 0;
 }
 
 static int wm8804_reset(struct snd_soc_codec *codec)
@@ -506,7 +493,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
                                        ret);
                                return ret;
                        }
-                       snd_soc_cache_sync(codec);
+                       regcache_sync(wm8804->regmap);
                }
                /* power down the OSC and the PLL */
                snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
@@ -561,11 +548,11 @@ static int wm8804_probe(struct snd_soc_codec *codec)
        int i, id1, id2, ret;
 
        wm8804 = snd_soc_codec_get_drvdata(codec);
-       wm8804->codec = codec;
 
        codec->dapm.idle_bias_off = 1;
+       codec->control_data = wm8804->regmap;
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type);
+       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
                return ret;
@@ -618,8 +605,7 @@ static int wm8804_probe(struct snd_soc_codec *codec)
 
        id2 = (id2 << 8) | id1;
 
-       if (id2 != ((wm8804_reg_defs[WM8804_DEVID2] << 8)
-                       | wm8804_reg_defs[WM8804_RST_DEVID1])) {
+       if (id2 != 0x8805) {
                dev_err(codec->dev, "Invalid device ID: %#x\n", id2);
                ret = -EINVAL;
                goto err_reg_enable;
@@ -692,10 +678,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
        .suspend = wm8804_suspend,
        .resume = wm8804_resume,
        .set_bias_level = wm8804_set_bias_level,
-       .reg_cache_size = ARRAY_SIZE(wm8804_reg_defs),
-       .reg_word_size = sizeof(u8),
-       .reg_cache_default = wm8804_reg_defs,
-       .volatile_register = wm8804_volatile,
 
        .controls = wm8804_snd_controls,
        .num_controls = ARRAY_SIZE(wm8804_snd_controls),
@@ -707,6 +689,18 @@ static const struct of_device_id wm8804_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, wm8804_of_match);
 
+static struct regmap_config wm8804_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = WM8804_MAX_REGISTER,
+       .volatile_reg = wm8804_volatile,
+
+       .cache_type = REGCACHE_RBTREE,
+       .reg_defaults = wm8804_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults),
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8804_spi_probe(struct spi_device *spi)
 {
@@ -717,7 +711,12 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi)
        if (!wm8804)
                return -ENOMEM;
 
-       wm8804->control_type = SND_SOC_SPI;
+       wm8804->regmap = regmap_init_spi(spi, &wm8804_regmap_config);
+       if (IS_ERR(wm8804->regmap)) {
+               ret = PTR_ERR(wm8804->regmap);
+               return ret;
+       }
+
        spi_set_drvdata(spi, wm8804);
 
        ret = snd_soc_register_codec(&spi->dev,
@@ -728,7 +727,9 @@ static int __devinit wm8804_spi_probe(struct spi_device *spi)
 
 static int __devexit wm8804_spi_remove(struct spi_device *spi)
 {
+       struct wm8804_priv *wm8804 = spi_get_drvdata(spi);
        snd_soc_unregister_codec(&spi->dev);
+       regmap_exit(wm8804->regmap);
        return 0;
 }
 
@@ -754,18 +755,26 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c,
        if (!wm8804)
                return -ENOMEM;
 
-       wm8804->control_type = SND_SOC_I2C;
        i2c_set_clientdata(i2c, wm8804);
 
        ret = snd_soc_register_codec(&i2c->dev,
                                     &soc_codec_dev_wm8804, &wm8804_dai, 1);
+       if (ret != 0)
+               goto err;
 
+       return 0;
+
+err:
+       regmap_exit(wm8804->regmap);
        return ret;
 }
 
-static __devexit int wm8804_i2c_remove(struct i2c_client *client)
+static __devexit int wm8804_i2c_remove(struct i2c_client *i2c)
 {
-       snd_soc_unregister_codec(&client->dev);
+       struct wm8804_priv *wm8804 = i2c_get_clientdata(i2c);
+
+       snd_soc_unregister_codec(&i2c->dev);
+       regmap_exit(wm8804->regmap);
 
        return 0;
 }