summaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ak4535.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ak4535.c')
-rw-r--r--sound/soc/codecs/ak4535.c110
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,