diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 398cb37e86219a954ff3632886c1780f9c9518c5..ac0b8f91f815e720fe0a3b642ed2ee3346c38269 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -345,6 +345,27 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo) } #endif +static const __devinitdata struct reg_default wm8994_revc_patch[] = { + { 0x102, 0x3 }, + { 0x56, 0x3 }, + { 0x817, 0x0 }, + { 0x102, 0x0 }, +}; + +static const __devinitdata struct reg_default wm8958_reva_patch[] = { + { 0x102, 0x3 }, + { 0xcb, 0x81 }, + { 0x817, 0x0 }, + { 0x102, 0x0 }, +}; + +static const __devinitdata struct reg_default wm1811_reva_patch[] = { + { 0x102, 0x3 }, + { 0x5d, 0x7e }, + { 0x5e, 0x0 }, + { 0x102, 0x0 }, +}; + /* * Instantiate the generic non-control parts of the device. */ @@ -352,8 +373,9 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) { struct wm8994_pdata *pdata = wm8994->dev->platform_data; struct regmap_config *regmap_config; + const struct reg_default *regmap_patch = NULL; const char *devname; - int ret, i; + int ret, i, patch_regs; int pulls = 0; dev_set_drvdata(wm8994->dev, wm8994); @@ -474,15 +496,42 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) "revision %c not fully supported\n", 'A' + wm8994->revision); break; + case 2: + case 3: + regmap_patch = wm8994_revc_patch; + patch_regs = ARRAY_SIZE(wm8994_revc_patch); + break; + default: + break; + } + break; + + case WM8958: + switch (wm8994->revision) { + case 0: + regmap_patch = wm8958_reva_patch; + patch_regs = ARRAY_SIZE(wm8958_reva_patch); + break; default: break; } break; + case WM1811: /* Revision C did not change the relevant layer */ if (wm8994->revision > 1) wm8994->revision++; + switch (wm8994->revision) { + case 0: + case 1: + regmap_patch = wm1811_reva_patch; + patch_regs = ARRAY_SIZE(wm1811_reva_patch); + break; + default: + break; + } break; + default: break; } @@ -512,6 +561,16 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) return ret; } + if (regmap_patch) { + ret = regmap_register_patch(wm8994->regmap, regmap_patch, + patch_regs); + if (ret != 0) { + dev_err(wm8994->dev, "Failed to register patch: %d\n", + ret); + goto err_regmap; + } + } + if (pdata) { wm8994->irq_base = pdata->irq_base; wm8994->gpio_base = pdata->gpio_base; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index ec69a6c152fea9a8b55a7c16c1f3935fb3dc305d..7c686abf8bd9a43a2366b1373da3df8bd56a8bc8 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2099,26 +2099,9 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { switch (control->type) { - case WM8994: - if (wm8994->revision < 4) { - /* Tweak DC servo and DSP - * configuration for improved - * performance. */ - snd_soc_write(codec, 0x102, 0x3); - snd_soc_write(codec, 0x56, 0x3); - snd_soc_write(codec, 0x817, 0); - snd_soc_write(codec, 0x102, 0); - } - break; - case WM8958: if (wm8994->revision == 0) { /* Optimise performance for rev A */ - snd_soc_write(codec, 0x102, 0x3); - snd_soc_write(codec, 0xcb, 0x81); - snd_soc_write(codec, 0x817, 0); - snd_soc_write(codec, 0x102, 0); - snd_soc_update_bits(codec, WM8958_CHARGE_PUMP_2, WM8958_CP_DISCH, @@ -2126,13 +2109,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, } break; - case WM1811: - if (wm8994->revision < 2) { - snd_soc_write(codec, 0x102, 0x3); - snd_soc_write(codec, 0x5d, 0x7e); - snd_soc_write(codec, 0x5e, 0x0); - snd_soc_write(codec, 0x102, 0x0); - } + default: break; }