ASoC: wm8962: Optimise power consumption for IN4 DC measurement usage
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 24 Jan 2012 21:07:55 +0000 (21:07 +0000)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 24 Jan 2012 21:19:45 +0000 (21:19 +0000)
When the hardware is configured with one or both of the IN4 inputs used
for DC measurement (with no DC blocking capacitor connected) then we can
improve power consumption slightly in idle modes by applying a register
write sequence. Provide platform data to enable this, implemented using
a regmap patch.

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

index 1750bed7c2f6ed66d92152c089e810e0332b1251..79e6d427b8582b3f9460c25b5fc4fe4bcc086580 100644 (file)
@@ -49,6 +49,12 @@ struct wm8962_pdata {
        bool irq_active_low;
 
        bool spk_mono;   /* Speaker outputs tied together as mono */
+
+       /**
+        * This flag should be set if one or both IN4 inputs is wired
+        * in a DC measurement configuration.
+        */
+       bool in4_dc_measure;
 };
 
 #endif
index cc4049e9174b6f8a51c2a3647b85297c32976fac..2a654fd42d122fb0ccfd063348ca385f65d57a79 100644 (file)
@@ -3638,6 +3638,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
        .volatile_register = wm8962_soc_volatile,
 };
 
+/* Improve power consumption for IN4 DC measurement mode */
+static const struct reg_default wm8962_dc_measure[] = {
+       { 0xfd, 0x1 },
+       { 0xcc, 0x40 },
+       { 0xfd, 0 },
+};
+
 static const struct regmap_config wm8962_regmap = {
        .reg_bits = 16,
        .val_bits = 16,
@@ -3653,6 +3660,7 @@ static const struct regmap_config wm8962_regmap = {
 static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
                                      const struct i2c_device_id *id)
 {
+       struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev);
        struct wm8962_priv *wm8962;
        unsigned int reg;
        int ret, i;
@@ -3731,6 +3739,16 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
                goto err_regmap;
        }
 
+       if (pdata && pdata->in4_dc_measure) {
+               ret = regmap_register_patch(wm8962->regmap,
+                                           wm8962_dc_measure,
+                                           ARRAY_SIZE(wm8962_dc_measure));
+               if (ret != 0)
+                       dev_err(&i2c->dev,
+                               "Failed to configure for DC mesurement: %d\n",
+                               ret);
+       }
+
        regcache_cache_only(wm8962->regmap, true);
 
        ret = snd_soc_register_codec(&i2c->dev,