aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2016-09-29 15:43:55 -0400
committerMark Brown <broonie@kernel.org>2016-09-29 15:43:55 -0400
commite4cf86a35ca1bc7c2de3ebb34bb5e8aa79c5bca9 (patch)
tree79e5ede0b90bed8e16ab3475034d6b7c8c54806c
parentb669010e5878dfda9c1b494f96fc122b67f8d880 (diff)
parenta114580f8f3e5bdefc14d75d6c3ba7032210b980 (diff)
Merge remote-tracking branch 'asoc/fix/tpa6130a2' into asoc-linus
-rw-r--r--sound/soc/codecs/tpa6130a2.c49
1 files changed, 26 insertions, 23 deletions
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index f1ea052a822e..3b6faed91d7e 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -52,7 +52,7 @@ struct tpa6130a2_data {
52 52
53static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) 53static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
54{ 54{
55 int ret; 55 int ret = 0, ret2;
56 56
57 if (enable) { 57 if (enable) {
58 ret = regulator_enable(data->supply); 58 ret = regulator_enable(data->supply);
@@ -64,20 +64,34 @@ static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
64 /* Power on */ 64 /* Power on */
65 if (data->power_gpio >= 0) 65 if (data->power_gpio >= 0)
66 gpio_set_value(data->power_gpio, 1); 66 gpio_set_value(data->power_gpio, 1);
67
68 /* Sync registers */
69 regcache_cache_only(data->regmap, false);
70 ret = regcache_sync(data->regmap);
71 if (ret != 0) {
72 dev_err(data->dev,
73 "Failed to sync registers: %d\n", ret);
74 goto regcache_sync_failed;
75 }
67 } else { 76 } else {
77 /* Powered off device does not retain registers. While device
78 * is off, any register updates (i.e. volume changes) should
79 * happen in cache only.
80 */
81 regcache_mark_dirty(data->regmap);
82regcache_sync_failed:
83 regcache_cache_only(data->regmap, true);
84
68 /* Power off */ 85 /* Power off */
69 if (data->power_gpio >= 0) 86 if (data->power_gpio >= 0)
70 gpio_set_value(data->power_gpio, 0); 87 gpio_set_value(data->power_gpio, 0);
71 88
72 ret = regulator_disable(data->supply); 89 ret2 = regulator_disable(data->supply);
73 if (ret != 0) { 90 if (ret2 != 0) {
74 dev_err(data->dev, 91 dev_err(data->dev,
75 "Failed to disable supply: %d\n", ret); 92 "Failed to disable supply: %d\n", ret2);
76 return ret; 93 return ret ? ret : ret2;
77 } 94 }
78
79 /* device regs does not match the cache state anymore */
80 regcache_mark_dirty(data->regmap);
81 } 95 }
82 96
83 return ret; 97 return ret;
@@ -88,25 +102,14 @@ static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
88{ 102{
89 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); 103 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
90 struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c); 104 struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c);
91 int ret;
92 105
93 /* before widget power up */
94 if (SND_SOC_DAPM_EVENT_ON(event)) { 106 if (SND_SOC_DAPM_EVENT_ON(event)) {
95 /* Turn on the chip */ 107 /* Before widget power up: turn chip on, sync registers */
96 tpa6130a2_power(data, true); 108 return tpa6130a2_power(data, true);
97 /* Sync the registers */
98 ret = regcache_sync(data->regmap);
99 if (ret < 0) {
100 dev_err(c->dev, "Failed to initialize chip\n");
101 tpa6130a2_power(data, false);
102 return ret;
103 }
104 /* after widget power down */
105 } else { 109 } else {
106 tpa6130a2_power(data, false); 110 /* After widget power down: turn chip off */
111 return tpa6130a2_power(data, false);
107 } 112 }
108
109 return 0;
110} 113}
111 114
112/* 115/*