diff options
Diffstat (limited to 'sound/soc/codecs/tpa6130a2.c')
-rw-r--r-- | sound/soc/codecs/tpa6130a2.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index f1ea052a822e..2e014c80d113 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -52,7 +52,7 @@ struct tpa6130a2_data { static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) { - int ret; + int ret = 0, ret2; if (enable) { ret = regulator_enable(data->supply); @@ -64,7 +64,30 @@ static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) /* Power on */ if (data->power_gpio >= 0) gpio_set_value(data->power_gpio, 1); + + /* Sync registers */ + regcache_cache_only(data->regmap, false); + ret = regcache_sync(data->regmap); + if (ret != 0) { + dev_err(data->dev, + "Failed to sync registers: %d\n", ret); + regcache_cache_only(data->regmap, true); + if (data->power_gpio >= 0) + gpio_set_value(data->power_gpio, 0); + ret2 = regulator_disable(data->supply); + if (ret2 != 0) + dev_err(data->dev, + "Failed to disable supply: %d\n", ret2); + return ret; + } } else { + /* Powered off device does not retain registers. While device + * is off, any register updates (i.e. volume changes) should + * happen in cache only. + */ + regcache_mark_dirty(data->regmap); + regcache_cache_only(data->regmap, true); + /* Power off */ if (data->power_gpio >= 0) gpio_set_value(data->power_gpio, 0); @@ -75,9 +98,6 @@ static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) "Failed to disable supply: %d\n", ret); return ret; } - - /* device regs does not match the cache state anymore */ - regcache_mark_dirty(data->regmap); } return ret; @@ -88,25 +108,14 @@ static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c); - int ret; - /* before widget power up */ if (SND_SOC_DAPM_EVENT_ON(event)) { - /* Turn on the chip */ - tpa6130a2_power(data, true); - /* Sync the registers */ - ret = regcache_sync(data->regmap); - if (ret < 0) { - dev_err(c->dev, "Failed to initialize chip\n"); - tpa6130a2_power(data, false); - return ret; - } - /* after widget power down */ + /* Before widget power up: turn chip on, sync registers */ + return tpa6130a2_power(data, true); } else { - tpa6130a2_power(data, false); + /* After widget power down: turn chip off */ + return tpa6130a2_power(data, false); } - - return 0; } /* @@ -190,7 +199,7 @@ static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = { { "Right PGA", NULL, "Power" }, }; -struct snd_soc_component_driver tpa6130a2_component_driver = { +static const struct snd_soc_component_driver tpa6130a2_component_driver = { .name = "tpa6130a2", .probe = tpa6130a2_component_probe, .dapm_widgets = tpa6130a2_dapm_widgets, |