diff options
Diffstat (limited to 'sound/soc/codecs/ak4535.c')
-rw-r--r-- | sound/soc/codecs/ak4535.c | 110 |
1 files changed, 23 insertions, 87 deletions
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index e1a214ee757..95d782d86e7 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -34,74 +34,16 @@ struct ak4535_priv { unsigned int sysclk; enum snd_soc_control_type control_type; - void *control_data; }; /* * ak4535 register cache */ -static const u16 ak4535_reg[AK4535_CACHEREGNUM] = { - 0x0000, 0x0080, 0x0000, 0x0003, - 0x0002, 0x0000, 0x0011, 0x0001, - 0x0000, 0x0040, 0x0036, 0x0010, - 0x0000, 0x0000, 0x0057, 0x0000, -}; - -/* - * read ak4535 register cache - */ -static inline unsigned int ak4535_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - if (reg >= AK4535_CACHEREGNUM) - return -1; - return cache[reg]; -} - -/* - * write ak4535 register cache - */ -static inline void ak4535_write_reg_cache(struct snd_soc_codec *codec, - u16 reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - if (reg >= AK4535_CACHEREGNUM) - return; - cache[reg] = value; -} - -/* - * write to the AK4535 register space - */ -static int ak4535_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 data[2]; - - /* data is - * D15..D8 AK4535 register offset - * D7...D0 register data - */ - data[0] = reg & 0xff; - data[1] = value & 0xff; - - ak4535_write_reg_cache(codec, reg, value); - if (codec->hw_write(codec->control_data, data, 2) == 2) - return 0; - else - return -EIO; -} - -static int ak4535_sync(struct snd_soc_codec *codec) -{ - u16 *cache = codec->reg_cache; - int i, r = 0; - - for (i = 0; i < AK4535_CACHEREGNUM; i++) - r |= ak4535_write(codec, i, cache[i]); - - return r; +static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { + 0x00, 0x80, 0x00, 0x03, + 0x02, 0x00, 0x11, 0x01, + 0x00, 0x40, 0x36, 0x10, + 0x00, 0x00, 0x57, 0x00, }; static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; @@ -304,7 +246,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); - u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); + u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5); int rate = params_rate(params), fs = 256; if (rate) @@ -323,7 +265,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream, } /* set rate */ - ak4535_write(codec, AK4535_MODE2, mode2); + snd_soc_write(codec, AK4535_MODE2, mode2); return 0; } @@ -348,44 +290,37 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai, /* use 32 fs for BCLK to save power */ mode1 |= 0x4; - ak4535_write(codec, AK4535_MODE1, mode1); + snd_soc_write(codec, AK4535_MODE1, mode1); return 0; } static int ak4535_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); + u16 mute_reg = snd_soc_read(codec, AK4535_DAC); if (!mute) - ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); + snd_soc_write(codec, AK4535_DAC, mute_reg & ~0x20); else - ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); + snd_soc_write(codec, AK4535_DAC, mute_reg | 0x20); return 0; } static int ak4535_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 i, mute_reg; - switch (level) { case SND_SOC_BIAS_ON: - mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); - ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); + snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0); break; case SND_SOC_BIAS_PREPARE: - mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); - ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); + snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0x20); break; case SND_SOC_BIAS_STANDBY: - i = ak4535_read_reg_cache(codec, AK4535_PM1); - ak4535_write(codec, AK4535_PM1, i | 0x80); - i = ak4535_read_reg_cache(codec, AK4535_PM2); - ak4535_write(codec, AK4535_PM2, i & (~0x80)); + snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0x80); + snd_soc_update_bits(codec, AK4535_PM2, 0x80, 0); break; case SND_SOC_BIAS_OFF: - i = ak4535_read_reg_cache(codec, AK4535_PM1); - ak4535_write(codec, AK4535_PM1, i & (~0x80)); + snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0); break; } codec->dapm.bias_level = level; @@ -428,7 +363,7 @@ static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state) static int ak4535_resume(struct snd_soc_codec *codec) { - ak4535_sync(codec); + snd_soc_cache_sync(codec); ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } @@ -436,11 +371,15 @@ static int ak4535_resume(struct snd_soc_codec *codec) static int ak4535_probe(struct snd_soc_codec *codec) { struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); + int ret; printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); - codec->control_data = ak4535->control_data; - + ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } /* power on device */ ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -461,8 +400,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { .remove = ak4535_remove, .suspend = ak4535_suspend, .resume = ak4535_resume, - .read = ak4535_read_reg_cache, - .write = ak4535_write, .set_bias_level = ak4535_set_bias_level, .reg_cache_size = ARRAY_SIZE(ak4535_reg), .reg_word_size = sizeof(u8), @@ -485,7 +422,6 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, return -ENOMEM; i2c_set_clientdata(i2c, ak4535); - ak4535->control_data = i2c; ak4535->control_type = SND_SOC_I2C; ret = snd_soc_register_codec(&i2c->dev, |