diff options
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r-- | sound/soc/soc-dapm.c | 88 |
1 files changed, 45 insertions, 43 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 03cb7c05ebec..035cab85cb66 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -112,43 +112,41 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget( | |||
112 | 112 | ||
113 | /** | 113 | /** |
114 | * snd_soc_dapm_set_bias_level - set the bias level for the system | 114 | * snd_soc_dapm_set_bias_level - set the bias level for the system |
115 | * @socdev: audio device | 115 | * @card: audio device |
116 | * @level: level to configure | 116 | * @level: level to configure |
117 | * | 117 | * |
118 | * Configure the bias (power) levels for the SoC audio device. | 118 | * Configure the bias (power) levels for the SoC audio device. |
119 | * | 119 | * |
120 | * Returns 0 for success else error. | 120 | * Returns 0 for success else error. |
121 | */ | 121 | */ |
122 | static int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, | 122 | static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, |
123 | enum snd_soc_bias_level level) | 123 | struct snd_soc_codec *codec, enum snd_soc_bias_level level) |
124 | { | 124 | { |
125 | struct snd_soc_card *card = socdev->card; | ||
126 | struct snd_soc_codec *codec = socdev->card->codec; | ||
127 | int ret = 0; | 125 | int ret = 0; |
128 | 126 | ||
129 | switch (level) { | 127 | switch (level) { |
130 | case SND_SOC_BIAS_ON: | 128 | case SND_SOC_BIAS_ON: |
131 | dev_dbg(socdev->dev, "Setting full bias\n"); | 129 | dev_dbg(codec->dev, "Setting full bias\n"); |
132 | break; | 130 | break; |
133 | case SND_SOC_BIAS_PREPARE: | 131 | case SND_SOC_BIAS_PREPARE: |
134 | dev_dbg(socdev->dev, "Setting bias prepare\n"); | 132 | dev_dbg(codec->dev, "Setting bias prepare\n"); |
135 | break; | 133 | break; |
136 | case SND_SOC_BIAS_STANDBY: | 134 | case SND_SOC_BIAS_STANDBY: |
137 | dev_dbg(socdev->dev, "Setting standby bias\n"); | 135 | dev_dbg(codec->dev, "Setting standby bias\n"); |
138 | break; | 136 | break; |
139 | case SND_SOC_BIAS_OFF: | 137 | case SND_SOC_BIAS_OFF: |
140 | dev_dbg(socdev->dev, "Setting bias off\n"); | 138 | dev_dbg(codec->dev, "Setting bias off\n"); |
141 | break; | 139 | break; |
142 | default: | 140 | default: |
143 | dev_err(socdev->dev, "Setting invalid bias %d\n", level); | 141 | dev_err(codec->dev, "Setting invalid bias %d\n", level); |
144 | return -EINVAL; | 142 | return -EINVAL; |
145 | } | 143 | } |
146 | 144 | ||
147 | if (card->set_bias_level) | 145 | if (card && card->set_bias_level) |
148 | ret = card->set_bias_level(card, level); | 146 | ret = card->set_bias_level(card, level); |
149 | if (ret == 0) { | 147 | if (ret == 0) { |
150 | if (codec->set_bias_level) | 148 | if (codec->driver->set_bias_level) |
151 | ret = codec->set_bias_level(codec, level); | 149 | ret = codec->driver->set_bias_level(codec, level); |
152 | else | 150 | else |
153 | codec->bias_level = level; | 151 | codec->bias_level = level; |
154 | } | 152 | } |
@@ -370,7 +368,7 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, | |||
370 | 368 | ||
371 | path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, | 369 | path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, |
372 | path->long_name); | 370 | path->long_name); |
373 | ret = snd_ctl_add(codec->card, path->kcontrol); | 371 | ret = snd_ctl_add(codec->card->snd_card, path->kcontrol); |
374 | if (ret < 0) { | 372 | if (ret < 0) { |
375 | printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", | 373 | printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", |
376 | path->long_name, | 374 | path->long_name, |
@@ -398,7 +396,7 @@ static int dapm_new_mux(struct snd_soc_codec *codec, | |||
398 | } | 396 | } |
399 | 397 | ||
400 | kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); | 398 | kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); |
401 | ret = snd_ctl_add(codec->card, kcontrol); | 399 | ret = snd_ctl_add(codec->card->snd_card, kcontrol); |
402 | if (ret < 0) | 400 | if (ret < 0) |
403 | goto err; | 401 | goto err; |
404 | 402 | ||
@@ -437,9 +435,9 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec) | |||
437 | */ | 435 | */ |
438 | static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) | 436 | static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) |
439 | { | 437 | { |
440 | struct snd_soc_codec *codec = widget->codec; | 438 | int level = snd_power_get_state(widget->codec->card->snd_card); |
441 | 439 | ||
442 | switch (snd_power_get_state(codec->card)) { | 440 | switch (level) { |
443 | case SNDRV_CTL_POWER_D3hot: | 441 | case SNDRV_CTL_POWER_D3hot: |
444 | case SNDRV_CTL_POWER_D3cold: | 442 | case SNDRV_CTL_POWER_D3cold: |
445 | if (widget->ignore_suspend) | 443 | if (widget->ignore_suspend) |
@@ -893,7 +891,7 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, | |||
893 | */ | 891 | */ |
894 | static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | 892 | static int dapm_power_widgets(struct snd_soc_codec *codec, int event) |
895 | { | 893 | { |
896 | struct snd_soc_device *socdev = codec->socdev; | 894 | struct snd_soc_card *card = codec->card; |
897 | struct snd_soc_dapm_widget *w; | 895 | struct snd_soc_dapm_widget *w; |
898 | LIST_HEAD(up_list); | 896 | LIST_HEAD(up_list); |
899 | LIST_HEAD(down_list); | 897 | LIST_HEAD(down_list); |
@@ -966,7 +964,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
966 | } | 964 | } |
967 | 965 | ||
968 | if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { | 966 | if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { |
969 | ret = snd_soc_dapm_set_bias_level(socdev, | 967 | ret = snd_soc_dapm_set_bias_level(card, codec, |
970 | SND_SOC_BIAS_STANDBY); | 968 | SND_SOC_BIAS_STANDBY); |
971 | if (ret != 0) | 969 | if (ret != 0) |
972 | pr_err("Failed to turn on bias: %d\n", ret); | 970 | pr_err("Failed to turn on bias: %d\n", ret); |
@@ -975,8 +973,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
975 | /* If we're changing to all on or all off then prepare */ | 973 | /* If we're changing to all on or all off then prepare */ |
976 | if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || | 974 | if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || |
977 | (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { | 975 | (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { |
978 | ret = snd_soc_dapm_set_bias_level(socdev, | 976 | ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_PREPARE); |
979 | SND_SOC_BIAS_PREPARE); | ||
980 | if (ret != 0) | 977 | if (ret != 0) |
981 | pr_err("Failed to prepare bias: %d\n", ret); | 978 | pr_err("Failed to prepare bias: %d\n", ret); |
982 | } | 979 | } |
@@ -989,8 +986,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
989 | 986 | ||
990 | /* If we just powered the last thing off drop to standby bias */ | 987 | /* If we just powered the last thing off drop to standby bias */ |
991 | if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { | 988 | if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { |
992 | ret = snd_soc_dapm_set_bias_level(socdev, | 989 | ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_STANDBY); |
993 | SND_SOC_BIAS_STANDBY); | ||
994 | if (ret != 0) | 990 | if (ret != 0) |
995 | pr_err("Failed to apply standby bias: %d\n", ret); | 991 | pr_err("Failed to apply standby bias: %d\n", ret); |
996 | } | 992 | } |
@@ -998,15 +994,14 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
998 | /* If we're in standby and can support bias off then do that */ | 994 | /* If we're in standby and can support bias off then do that */ |
999 | if (codec->bias_level == SND_SOC_BIAS_STANDBY && | 995 | if (codec->bias_level == SND_SOC_BIAS_STANDBY && |
1000 | codec->idle_bias_off) { | 996 | codec->idle_bias_off) { |
1001 | ret = snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF); | 997 | ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); |
1002 | if (ret != 0) | 998 | if (ret != 0) |
1003 | pr_err("Failed to turn off bias: %d\n", ret); | 999 | pr_err("Failed to turn off bias: %d\n", ret); |
1004 | } | 1000 | } |
1005 | 1001 | ||
1006 | /* If we just powered up then move to active bias */ | 1002 | /* If we just powered up then move to active bias */ |
1007 | if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { | 1003 | if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { |
1008 | ret = snd_soc_dapm_set_bias_level(socdev, | 1004 | ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_ON); |
1009 | SND_SOC_BIAS_ON); | ||
1010 | if (ret != 0) | 1005 | if (ret != 0) |
1011 | pr_err("Failed to apply active bias: %d\n", ret); | 1006 | pr_err("Failed to apply active bias: %d\n", ret); |
1012 | } | 1007 | } |
@@ -1188,8 +1183,9 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, | |||
1188 | static ssize_t dapm_widget_show(struct device *dev, | 1183 | static ssize_t dapm_widget_show(struct device *dev, |
1189 | struct device_attribute *attr, char *buf) | 1184 | struct device_attribute *attr, char *buf) |
1190 | { | 1185 | { |
1191 | struct snd_soc_device *devdata = dev_get_drvdata(dev); | 1186 | struct snd_soc_pcm_runtime *rtd = |
1192 | struct snd_soc_codec *codec = devdata->card->codec; | 1187 | container_of(dev, struct snd_soc_pcm_runtime, dev); |
1188 | struct snd_soc_codec *codec =rtd->codec; | ||
1193 | struct snd_soc_dapm_widget *w; | 1189 | struct snd_soc_dapm_widget *w; |
1194 | int count = 0; | 1190 | int count = 0; |
1195 | char *state = "not set"; | 1191 | char *state = "not set"; |
@@ -1998,9 +1994,10 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); | |||
1998 | * | 1994 | * |
1999 | * Returns 0 for success else error. | 1995 | * Returns 0 for success else error. |
2000 | */ | 1996 | */ |
2001 | int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, | 1997 | int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, |
2002 | char *stream, int event) | 1998 | const char *stream, int event) |
2003 | { | 1999 | { |
2000 | struct snd_soc_codec *codec = rtd->codec; | ||
2004 | struct snd_soc_dapm_widget *w; | 2001 | struct snd_soc_dapm_widget *w; |
2005 | 2002 | ||
2006 | if (stream == NULL) | 2003 | if (stream == NULL) |
@@ -2168,25 +2165,19 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); | |||
2168 | 2165 | ||
2169 | /** | 2166 | /** |
2170 | * snd_soc_dapm_free - free dapm resources | 2167 | * snd_soc_dapm_free - free dapm resources |
2171 | * @socdev: SoC device | 2168 | * @card: SoC device |
2172 | * | 2169 | * |
2173 | * Free all dapm widgets and resources. | 2170 | * Free all dapm widgets and resources. |
2174 | */ | 2171 | */ |
2175 | void snd_soc_dapm_free(struct snd_soc_device *socdev) | 2172 | void snd_soc_dapm_free(struct snd_soc_codec *codec) |
2176 | { | 2173 | { |
2177 | struct snd_soc_codec *codec = socdev->card->codec; | 2174 | snd_soc_dapm_sys_remove(codec->dev); |
2178 | |||
2179 | snd_soc_dapm_sys_remove(socdev->dev); | ||
2180 | dapm_free_widgets(codec); | 2175 | dapm_free_widgets(codec); |
2181 | } | 2176 | } |
2182 | EXPORT_SYMBOL_GPL(snd_soc_dapm_free); | 2177 | EXPORT_SYMBOL_GPL(snd_soc_dapm_free); |
2183 | 2178 | ||
2184 | /* | 2179 | static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec) |
2185 | * snd_soc_dapm_shutdown - callback for system shutdown | ||
2186 | */ | ||
2187 | void snd_soc_dapm_shutdown(struct snd_soc_device *socdev) | ||
2188 | { | 2180 | { |
2189 | struct snd_soc_codec *codec = socdev->card->codec; | ||
2190 | struct snd_soc_dapm_widget *w; | 2181 | struct snd_soc_dapm_widget *w; |
2191 | LIST_HEAD(down_list); | 2182 | LIST_HEAD(down_list); |
2192 | int powerdown = 0; | 2183 | int powerdown = 0; |
@@ -2203,12 +2194,23 @@ void snd_soc_dapm_shutdown(struct snd_soc_device *socdev) | |||
2203 | * standby. | 2194 | * standby. |
2204 | */ | 2195 | */ |
2205 | if (powerdown) { | 2196 | if (powerdown) { |
2206 | snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_PREPARE); | 2197 | snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_PREPARE); |
2207 | dapm_seq_run(codec, &down_list, 0, dapm_down_seq); | 2198 | dapm_seq_run(codec, &down_list, 0, dapm_down_seq); |
2208 | snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_STANDBY); | 2199 | snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_STANDBY); |
2209 | } | 2200 | } |
2201 | } | ||
2202 | |||
2203 | /* | ||
2204 | * snd_soc_dapm_shutdown - callback for system shutdown | ||
2205 | */ | ||
2206 | void snd_soc_dapm_shutdown(struct snd_soc_card *card) | ||
2207 | { | ||
2208 | struct snd_soc_codec *codec; | ||
2209 | |||
2210 | list_for_each_entry(codec, &card->codec_dev_list, list) | ||
2211 | soc_dapm_shutdown_codec(codec); | ||
2210 | 2212 | ||
2211 | snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF); | 2213 | snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); |
2212 | } | 2214 | } |
2213 | 2215 | ||
2214 | /* Module information */ | 2216 | /* Module information */ |