ASoC: ak4642: fixup: mute needs +1 step
[linux-flexiantxendom0.git] / sound / soc / codecs / ak4642.c
index 4be0570..1c4999d 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/soc.h>
 #include <sound/initval.h>
 #include <sound/tlv.h>
  * min : 0xFE : -115.0 dB
  * mute: 0xFF
  */
-static const DECLARE_TLV_DB_SCALE(out_tlv, -11500, 50, 1);
+static const DECLARE_TLV_DB_SCALE(out_tlv, -11550, 50, 1);
 
 static const struct snd_kcontrol_new ak4642_snd_controls[] = {
 
@@ -156,81 +157,22 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
 struct ak4642_priv {
        unsigned int sysclk;
        enum snd_soc_control_type control_type;
-       void *control_data;
 };
 
 /*
  * ak4642 register cache
  */
-static const u16 ak4642_reg[AK4642_CACHEREGNUM] = {
-       0x0000, 0x0000, 0x0001, 0x0000,
-       0x0002, 0x0000, 0x0000, 0x0000,
-       0x00e1, 0x00e1, 0x0018, 0x0000,
-       0x00e1, 0x0018, 0x0011, 0x0008,
-       0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000, 0x0000, 0x0000, 0x0000,
-       0x0000,
-};
-
-/*
- * read ak4642 register cache
- */
-static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec,
-       unsigned int reg)
-{
-       u16 *cache = codec->reg_cache;
-       if (reg >= AK4642_CACHEREGNUM)
-               return -1;
-       return cache[reg];
-}
-
-/*
- * write ak4642 register cache
- */
-static inline void ak4642_write_reg_cache(struct snd_soc_codec *codec,
-       u16 reg, unsigned int value)
-{
-       u16 *cache = codec->reg_cache;
-       if (reg >= AK4642_CACHEREGNUM)
-               return;
-
-       cache[reg] = value;
-}
-
-/*
- * write to the AK4642 register space
- */
-static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg,
-       unsigned int value)
-{
-       u8 data[2];
-
-       /* data is
-        *   D15..D8 AK4642 register offset
-        *   D7...D0 register data
-        */
-       data[0] = reg & 0xff;
-       data[1] = value & 0xff;
-
-       if (codec->hw_write(codec->control_data, data, 2) == 2) {
-               ak4642_write_reg_cache(codec, reg, value);
-               return 0;
-       } else
-               return -EIO;
-}
-
-static int ak4642_sync(struct snd_soc_codec *codec)
-{
-       u16 *cache = codec->reg_cache;
-       int i, r = 0;
-
-       for (i = 0; i < AK4642_CACHEREGNUM; i++)
-               r |= ak4642_write(codec, i, cache[i]);
-
-       return r;
+static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
+       0x00, 0x00, 0x01, 0x00,
+       0x02, 0x00, 0x00, 0x00,
+       0xe1, 0xe1, 0x18, 0x00,
+       0xe1, 0x18, 0x11, 0x08,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00,
 };
 
 static int ak4642_dai_startup(struct snd_pcm_substream *substream,
@@ -252,8 +194,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
                 */
                snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
                snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
-               ak4642_write(codec, L_IVC, 0x91); /* volume */
-               ak4642_write(codec, R_IVC, 0x91); /* volume */
+               snd_soc_write(codec, L_IVC, 0x91); /* volume */
+               snd_soc_write(codec, R_IVC, 0x91); /* volume */
                snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
                                                     PMVCM | PMMIN | PMDAC);
                snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
@@ -272,9 +214,9 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
                 * This operation came from example code of
                 * "ASAHI KASEI AK4642" (japanese) manual p94.
                 */
-               ak4642_write(codec, SG_SL1, PMMP | MGAIN0);
-               ak4642_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
-               ak4642_write(codec, ALC_CTL1, ALC | LMTH0);
+               snd_soc_write(codec, SG_SL1, PMMP | MGAIN0);
+               snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
+               snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
                snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
                                                     PMVCM | PMADL);
                snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
@@ -357,7 +299,7 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        default:
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, PW_MGMT2, MS, data);
+       snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data);
        snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
 
        /* format type */
@@ -462,7 +404,7 @@ static struct snd_soc_dai_driver ak4642_dai = {
 
 static int ak4642_resume(struct snd_soc_codec *codec)
 {
-       ak4642_sync(codec);
+       snd_soc_cache_sync(codec);
        return 0;
 }
 
@@ -470,11 +412,15 @@ static int ak4642_resume(struct snd_soc_codec *codec)
 static int ak4642_probe(struct snd_soc_codec *codec)
 {
        struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
+       int ret;
 
        dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
 
-       codec->hw_write         = (hw_write_t)i2c_master_send;
-       codec->control_data     = ak4642->control_data;
+       ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+               return ret;
+       }
 
        snd_soc_add_controls(codec, ak4642_snd_controls,
                             ARRAY_SIZE(ak4642_snd_controls));
@@ -485,8 +431,6 @@ static int ak4642_probe(struct snd_soc_codec *codec)
 static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
        .probe                  = ak4642_probe,
        .resume                 = ak4642_resume,
-       .read                   = ak4642_read_reg_cache,
-       .write                  = ak4642_write,
        .reg_cache_size         = ARRAY_SIZE(ak4642_reg),
        .reg_word_size          = sizeof(u8),
        .reg_cache_default      = ak4642_reg,
@@ -504,7 +448,6 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
                return -ENOMEM;
 
        i2c_set_clientdata(i2c, ak4642);
-       ak4642->control_data = i2c;
        ak4642->control_type = SND_SOC_I2C;
 
        ret =  snd_soc_register_codec(&i2c->dev,