Skip to content

Commit

Permalink
ASoC: Convert wm8804 to direct regmap API usage
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Brown committed Jan 20, 2012
1 parent f649f1a commit 891271c
Showing 1 changed file with 62 additions and 53 deletions.
115 changes: 62 additions & 53 deletions sound/soc/codecs/wm8804.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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,
Expand All @@ -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; \
}
Expand Down Expand Up @@ -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:
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand All @@ -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)
{
Expand All @@ -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,
Expand All @@ -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;
}

Expand All @@ -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;
}
Expand Down

0 comments on commit 891271c

Please sign in to comment.