soc-dapm.c (8990c1bc4be46473ad19bf2fa612ca57286f3df4) | soc-dapm.c (8ddab3f5107c3955e70e87a632d4d179ddba1189) |
---|---|
1/* 2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management 3 * 4 * Copyright 2005 Wolfson Microelectronics PLC. 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the --- 28 unchanged lines hidden (view full) --- 37#include <linux/bitops.h> 38#include <linux/platform_device.h> 39#include <linux/jiffies.h> 40#include <linux/debugfs.h> 41#include <linux/slab.h> 42#include <sound/core.h> 43#include <sound/pcm.h> 44#include <sound/pcm_params.h> | 1/* 2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management 3 * 4 * Copyright 2005 Wolfson Microelectronics PLC. 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the --- 28 unchanged lines hidden (view full) --- 37#include <linux/bitops.h> 38#include <linux/platform_device.h> 39#include <linux/jiffies.h> 40#include <linux/debugfs.h> 41#include <linux/slab.h> 42#include <sound/core.h> 43#include <sound/pcm.h> 44#include <sound/pcm_params.h> |
45#include <sound/soc-dapm.h> | 45#include <sound/soc.h> |
46#include <sound/initval.h> 47 | 46#include <sound/initval.h> 47 |
48#include <trace/events/asoc.h> 49 |
|
48/* dapm power sequences - make this per codec in the future */ 49static int dapm_up_seq[] = { 50 [snd_soc_dapm_pre] = 0, 51 [snd_soc_dapm_supply] = 1, 52 [snd_soc_dapm_micbias] = 2, 53 [snd_soc_dapm_aif_in] = 3, 54 [snd_soc_dapm_aif_out] = 3, 55 [snd_soc_dapm_mic] = 4, 56 [snd_soc_dapm_mux] = 5, 57 [snd_soc_dapm_value_mux] = 5, 58 [snd_soc_dapm_dac] = 6, 59 [snd_soc_dapm_mixer] = 7, 60 [snd_soc_dapm_mixer_named_ctl] = 7, 61 [snd_soc_dapm_pga] = 8, 62 [snd_soc_dapm_adc] = 9, | 50/* dapm power sequences - make this per codec in the future */ 51static int dapm_up_seq[] = { 52 [snd_soc_dapm_pre] = 0, 53 [snd_soc_dapm_supply] = 1, 54 [snd_soc_dapm_micbias] = 2, 55 [snd_soc_dapm_aif_in] = 3, 56 [snd_soc_dapm_aif_out] = 3, 57 [snd_soc_dapm_mic] = 4, 58 [snd_soc_dapm_mux] = 5, 59 [snd_soc_dapm_value_mux] = 5, 60 [snd_soc_dapm_dac] = 6, 61 [snd_soc_dapm_mixer] = 7, 62 [snd_soc_dapm_mixer_named_ctl] = 7, 63 [snd_soc_dapm_pga] = 8, 64 [snd_soc_dapm_adc] = 9, |
65 [snd_soc_dapm_out_drv] = 10, |
|
63 [snd_soc_dapm_hp] = 10, 64 [snd_soc_dapm_spk] = 10, 65 [snd_soc_dapm_post] = 11, 66}; 67 68static int dapm_down_seq[] = { 69 [snd_soc_dapm_pre] = 0, 70 [snd_soc_dapm_adc] = 1, 71 [snd_soc_dapm_hp] = 2, 72 [snd_soc_dapm_spk] = 2, | 66 [snd_soc_dapm_hp] = 10, 67 [snd_soc_dapm_spk] = 10, 68 [snd_soc_dapm_post] = 11, 69}; 70 71static int dapm_down_seq[] = { 72 [snd_soc_dapm_pre] = 0, 73 [snd_soc_dapm_adc] = 1, 74 [snd_soc_dapm_hp] = 2, 75 [snd_soc_dapm_spk] = 2, |
76 [snd_soc_dapm_out_drv] = 2, |
|
73 [snd_soc_dapm_pga] = 4, 74 [snd_soc_dapm_mixer_named_ctl] = 5, 75 [snd_soc_dapm_mixer] = 5, 76 [snd_soc_dapm_dac] = 6, 77 [snd_soc_dapm_mic] = 7, 78 [snd_soc_dapm_micbias] = 8, 79 [snd_soc_dapm_mux] = 9, 80 [snd_soc_dapm_value_mux] = 9, --- 4 unchanged lines hidden (view full) --- 85}; 86 87static void pop_wait(u32 pop_time) 88{ 89 if (pop_time) 90 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); 91} 92 | 77 [snd_soc_dapm_pga] = 4, 78 [snd_soc_dapm_mixer_named_ctl] = 5, 79 [snd_soc_dapm_mixer] = 5, 80 [snd_soc_dapm_dac] = 6, 81 [snd_soc_dapm_mic] = 7, 82 [snd_soc_dapm_micbias] = 8, 83 [snd_soc_dapm_mux] = 9, 84 [snd_soc_dapm_value_mux] = 9, --- 4 unchanged lines hidden (view full) --- 89}; 90 91static void pop_wait(u32 pop_time) 92{ 93 if (pop_time) 94 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); 95} 96 |
93static void pop_dbg(u32 pop_time, const char *fmt, ...) | 97static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...) |
94{ 95 va_list args; | 98{ 99 va_list args; |
100 char *buf; |
|
96 | 101 |
97 va_start(args, fmt); | 102 if (!pop_time) 103 return; |
98 | 104 |
99 if (pop_time) { 100 vprintk(fmt, args); 101 } | 105 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 106 if (buf == NULL) 107 return; |
102 | 108 |
109 va_start(args, fmt); 110 vsnprintf(buf, PAGE_SIZE, fmt, args); 111 dev_info(dev, buf); |
|
103 va_end(args); | 112 va_end(args); |
113 114 kfree(buf); |
|
104} 105 106/* create a new dapm widget */ 107static inline struct snd_soc_dapm_widget *dapm_cnew_widget( 108 const struct snd_soc_dapm_widget *_widget) 109{ 110 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); 111} 112 113/** 114 * snd_soc_dapm_set_bias_level - set the bias level for the system 115 * @card: audio device 116 * @level: level to configure 117 * 118 * Configure the bias (power) levels for the SoC audio device. 119 * 120 * Returns 0 for success else error. 121 */ 122static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, | 115} 116 117/* create a new dapm widget */ 118static inline struct snd_soc_dapm_widget *dapm_cnew_widget( 119 const struct snd_soc_dapm_widget *_widget) 120{ 121 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); 122} 123 124/** 125 * snd_soc_dapm_set_bias_level - set the bias level for the system 126 * @card: audio device 127 * @level: level to configure 128 * 129 * Configure the bias (power) levels for the SoC audio device. 130 * 131 * Returns 0 for success else error. 132 */ 133static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, |
123 struct snd_soc_codec *codec, enum snd_soc_bias_level level) | 134 struct snd_soc_dapm_context *dapm, 135 enum snd_soc_bias_level level) |
124{ 125 int ret = 0; 126 127 switch (level) { 128 case SND_SOC_BIAS_ON: | 136{ 137 int ret = 0; 138 139 switch (level) { 140 case SND_SOC_BIAS_ON: |
129 dev_dbg(codec->dev, "Setting full bias\n"); | 141 dev_dbg(dapm->dev, "Setting full bias\n"); |
130 break; 131 case SND_SOC_BIAS_PREPARE: | 142 break; 143 case SND_SOC_BIAS_PREPARE: |
132 dev_dbg(codec->dev, "Setting bias prepare\n"); | 144 dev_dbg(dapm->dev, "Setting bias prepare\n"); |
133 break; 134 case SND_SOC_BIAS_STANDBY: | 145 break; 146 case SND_SOC_BIAS_STANDBY: |
135 dev_dbg(codec->dev, "Setting standby bias\n"); | 147 dev_dbg(dapm->dev, "Setting standby bias\n"); |
136 break; 137 case SND_SOC_BIAS_OFF: | 148 break; 149 case SND_SOC_BIAS_OFF: |
138 dev_dbg(codec->dev, "Setting bias off\n"); | 150 dev_dbg(dapm->dev, "Setting bias off\n"); |
139 break; 140 default: | 151 break; 152 default: |
141 dev_err(codec->dev, "Setting invalid bias %d\n", level); | 153 dev_err(dapm->dev, "Setting invalid bias %d\n", level); |
142 return -EINVAL; 143 } 144 | 154 return -EINVAL; 155 } 156 |
157 trace_snd_soc_bias_level_start(card, level); 158 |
|
145 if (card && card->set_bias_level) 146 ret = card->set_bias_level(card, level); 147 if (ret == 0) { | 159 if (card && card->set_bias_level) 160 ret = card->set_bias_level(card, level); 161 if (ret == 0) { |
148 if (codec->driver->set_bias_level) 149 ret = codec->driver->set_bias_level(codec, level); | 162 if (dapm->codec && dapm->codec->driver->set_bias_level) 163 ret = dapm->codec->driver->set_bias_level(dapm->codec, level); |
150 else | 164 else |
151 codec->bias_level = level; | 165 dapm->bias_level = level; |
152 } | 166 } |
167 if (ret == 0) { 168 if (card && card->set_bias_level_post) 169 ret = card->set_bias_level_post(card, level); 170 } |
|
153 | 171 |
172 trace_snd_soc_bias_level_done(card, level); 173 |
|
154 return ret; 155} 156 157/* set up initial codec paths */ 158static void dapm_set_path_status(struct snd_soc_dapm_widget *w, 159 struct snd_soc_dapm_path *p, int i) 160{ 161 switch (w->id) { --- 50 unchanged lines hidden (view full) --- 212 for (i = 0; i < e->max; i++) { 213 if (!(strcmp(p->name, e->texts[i])) && item == i) 214 p->connect = 1; 215 } 216 } 217 break; 218 /* does not effect routing - always connected */ 219 case snd_soc_dapm_pga: | 174 return ret; 175} 176 177/* set up initial codec paths */ 178static void dapm_set_path_status(struct snd_soc_dapm_widget *w, 179 struct snd_soc_dapm_path *p, int i) 180{ 181 switch (w->id) { --- 50 unchanged lines hidden (view full) --- 232 for (i = 0; i < e->max; i++) { 233 if (!(strcmp(p->name, e->texts[i])) && item == i) 234 p->connect = 1; 235 } 236 } 237 break; 238 /* does not effect routing - always connected */ 239 case snd_soc_dapm_pga: |
240 case snd_soc_dapm_out_drv: |
|
220 case snd_soc_dapm_output: 221 case snd_soc_dapm_adc: 222 case snd_soc_dapm_input: 223 case snd_soc_dapm_dac: 224 case snd_soc_dapm_micbias: 225 case snd_soc_dapm_vmid: 226 case snd_soc_dapm_supply: 227 case snd_soc_dapm_aif_in: --- 8 unchanged lines hidden (view full) --- 236 case snd_soc_dapm_pre: 237 case snd_soc_dapm_post: 238 p->connect = 0; 239 break; 240 } 241} 242 243/* connect mux widget to its interconnecting audio paths */ | 241 case snd_soc_dapm_output: 242 case snd_soc_dapm_adc: 243 case snd_soc_dapm_input: 244 case snd_soc_dapm_dac: 245 case snd_soc_dapm_micbias: 246 case snd_soc_dapm_vmid: 247 case snd_soc_dapm_supply: 248 case snd_soc_dapm_aif_in: --- 8 unchanged lines hidden (view full) --- 257 case snd_soc_dapm_pre: 258 case snd_soc_dapm_post: 259 p->connect = 0; 260 break; 261 } 262} 263 264/* connect mux widget to its interconnecting audio paths */ |
244static int dapm_connect_mux(struct snd_soc_codec *codec, | 265static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, |
245 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 246 struct snd_soc_dapm_path *path, const char *control_name, 247 const struct snd_kcontrol_new *kcontrol) 248{ 249 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 250 int i; 251 252 for (i = 0; i < e->max; i++) { 253 if (!(strcmp(control_name, e->texts[i]))) { | 266 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 267 struct snd_soc_dapm_path *path, const char *control_name, 268 const struct snd_kcontrol_new *kcontrol) 269{ 270 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 271 int i; 272 273 for (i = 0; i < e->max; i++) { 274 if (!(strcmp(control_name, e->texts[i]))) { |
254 list_add(&path->list, &codec->dapm_paths); | 275 list_add(&path->list, &dapm->card->paths); |
255 list_add(&path->list_sink, &dest->sources); 256 list_add(&path->list_source, &src->sinks); 257 path->name = (char*)e->texts[i]; 258 dapm_set_path_status(dest, path, 0); 259 return 0; 260 } 261 } 262 263 return -ENODEV; 264} 265 266/* connect mixer widget to its interconnecting audio paths */ | 276 list_add(&path->list_sink, &dest->sources); 277 list_add(&path->list_source, &src->sinks); 278 path->name = (char*)e->texts[i]; 279 dapm_set_path_status(dest, path, 0); 280 return 0; 281 } 282 } 283 284 return -ENODEV; 285} 286 287/* connect mixer widget to its interconnecting audio paths */ |
267static int dapm_connect_mixer(struct snd_soc_codec *codec, | 288static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, |
268 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 269 struct snd_soc_dapm_path *path, const char *control_name) 270{ 271 int i; 272 273 /* search for mixer kcontrol */ 274 for (i = 0; i < dest->num_kcontrols; i++) { 275 if (!strcmp(control_name, dest->kcontrols[i].name)) { | 289 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 290 struct snd_soc_dapm_path *path, const char *control_name) 291{ 292 int i; 293 294 /* search for mixer kcontrol */ 295 for (i = 0; i < dest->num_kcontrols; i++) { 296 if (!strcmp(control_name, dest->kcontrols[i].name)) { |
276 list_add(&path->list, &codec->dapm_paths); | 297 list_add(&path->list, &dapm->card->paths); |
277 list_add(&path->list_sink, &dest->sources); 278 list_add(&path->list_source, &src->sinks); 279 path->name = dest->kcontrols[i].name; 280 dapm_set_path_status(dest, path, i); 281 return 0; 282 } 283 } 284 return -ENODEV; 285} 286 287/* update dapm codec register bits */ 288static int dapm_update_bits(struct snd_soc_dapm_widget *widget) 289{ 290 int change, power; 291 unsigned int old, new; 292 struct snd_soc_codec *codec = widget->codec; | 298 list_add(&path->list_sink, &dest->sources); 299 list_add(&path->list_source, &src->sinks); 300 path->name = dest->kcontrols[i].name; 301 dapm_set_path_status(dest, path, i); 302 return 0; 303 } 304 } 305 return -ENODEV; 306} 307 308/* update dapm codec register bits */ 309static int dapm_update_bits(struct snd_soc_dapm_widget *widget) 310{ 311 int change, power; 312 unsigned int old, new; 313 struct snd_soc_codec *codec = widget->codec; |
314 struct snd_soc_dapm_context *dapm = widget->dapm; 315 struct snd_soc_card *card = dapm->card; |
|
293 294 /* check for valid widgets */ 295 if (widget->reg < 0 || widget->id == snd_soc_dapm_input || 296 widget->id == snd_soc_dapm_output || 297 widget->id == snd_soc_dapm_hp || 298 widget->id == snd_soc_dapm_mic || 299 widget->id == snd_soc_dapm_line || 300 widget->id == snd_soc_dapm_spk) 301 return 0; 302 303 power = widget->power; 304 if (widget->invert) 305 power = (power ? 0:1); 306 307 old = snd_soc_read(codec, widget->reg); 308 new = (old & ~(0x1 << widget->shift)) | (power << widget->shift); 309 310 change = old != new; 311 if (change) { | 316 317 /* check for valid widgets */ 318 if (widget->reg < 0 || widget->id == snd_soc_dapm_input || 319 widget->id == snd_soc_dapm_output || 320 widget->id == snd_soc_dapm_hp || 321 widget->id == snd_soc_dapm_mic || 322 widget->id == snd_soc_dapm_line || 323 widget->id == snd_soc_dapm_spk) 324 return 0; 325 326 power = widget->power; 327 if (widget->invert) 328 power = (power ? 0:1); 329 330 old = snd_soc_read(codec, widget->reg); 331 new = (old & ~(0x1 << widget->shift)) | (power << widget->shift); 332 333 change = old != new; 334 if (change) { |
312 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n", | 335 pop_dbg(dapm->dev, card->pop_time, 336 "pop test %s : %s in %d ms\n", |
313 widget->name, widget->power ? "on" : "off", | 337 widget->name, widget->power ? "on" : "off", |
314 codec->pop_time); 315 pop_wait(codec->pop_time); | 338 card->pop_time); 339 pop_wait(card->pop_time); |
316 snd_soc_write(codec, widget->reg, new); 317 } | 340 snd_soc_write(codec, widget->reg, new); 341 } |
318 pr_debug("reg %x old %x new %x change %d\n", widget->reg, 319 old, new, change); | 342 dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg, 343 old, new, change); |
320 return change; 321} 322 323/* create new dapm mixer control */ | 344 return change; 345} 346 347/* create new dapm mixer control */ |
324static int dapm_new_mixer(struct snd_soc_codec *codec, | 348static int dapm_new_mixer(struct snd_soc_dapm_context *dapm, |
325 struct snd_soc_dapm_widget *w) 326{ 327 int i, ret = 0; 328 size_t name_len; 329 struct snd_soc_dapm_path *path; | 349 struct snd_soc_dapm_widget *w) 350{ 351 int i, ret = 0; 352 size_t name_len; 353 struct snd_soc_dapm_path *path; |
354 struct snd_card *card = dapm->codec->card->snd_card; |
|
330 331 /* add kcontrol */ 332 for (i = 0; i < w->num_kcontrols; i++) { 333 334 /* match name */ 335 list_for_each_entry(path, &w->sources, list_sink) { 336 337 /* mixer/mux paths name must match control name */ --- 25 unchanged lines hidden (view full) --- 363 w->kcontrols[i].name); 364 break; 365 } 366 367 path->long_name[name_len - 1] = '\0'; 368 369 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 370 path->long_name); | 355 356 /* add kcontrol */ 357 for (i = 0; i < w->num_kcontrols; i++) { 358 359 /* match name */ 360 list_for_each_entry(path, &w->sources, list_sink) { 361 362 /* mixer/mux paths name must match control name */ --- 25 unchanged lines hidden (view full) --- 388 w->kcontrols[i].name); 389 break; 390 } 391 392 path->long_name[name_len - 1] = '\0'; 393 394 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 395 path->long_name); |
371 ret = snd_ctl_add(codec->card->snd_card, path->kcontrol); | 396 ret = snd_ctl_add(card, path->kcontrol); |
372 if (ret < 0) { | 397 if (ret < 0) { |
373 printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", 374 path->long_name, 375 ret); | 398 dev_err(dapm->dev, 399 "asoc: failed to add dapm kcontrol %s: %d\n", 400 path->long_name, ret); |
376 kfree(path->long_name); 377 path->long_name = NULL; 378 return ret; 379 } 380 } 381 } 382 return ret; 383} 384 385/* create new dapm mux control */ | 401 kfree(path->long_name); 402 path->long_name = NULL; 403 return ret; 404 } 405 } 406 } 407 return ret; 408} 409 410/* create new dapm mux control */ |
386static int dapm_new_mux(struct snd_soc_codec *codec, | 411static int dapm_new_mux(struct snd_soc_dapm_context *dapm, |
387 struct snd_soc_dapm_widget *w) 388{ 389 struct snd_soc_dapm_path *path = NULL; 390 struct snd_kcontrol *kcontrol; | 412 struct snd_soc_dapm_widget *w) 413{ 414 struct snd_soc_dapm_path *path = NULL; 415 struct snd_kcontrol *kcontrol; |
416 struct snd_card *card = dapm->codec->card->snd_card; |
|
391 int ret = 0; 392 393 if (!w->num_kcontrols) { | 417 int ret = 0; 418 419 if (!w->num_kcontrols) { |
394 printk(KERN_ERR "asoc: mux %s has no controls\n", w->name); | 420 dev_err(dapm->dev, "asoc: mux %s has no controls\n", w->name); |
395 return -EINVAL; 396 } 397 398 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); | 421 return -EINVAL; 422 } 423 424 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); |
399 ret = snd_ctl_add(codec->card->snd_card, kcontrol); | 425 ret = snd_ctl_add(card, kcontrol); 426 |
400 if (ret < 0) 401 goto err; 402 403 list_for_each_entry(path, &w->sources, list_sink) 404 path->kcontrol = kcontrol; 405 406 return ret; 407 408err: | 427 if (ret < 0) 428 goto err; 429 430 list_for_each_entry(path, &w->sources, list_sink) 431 path->kcontrol = kcontrol; 432 433 return ret; 434 435err: |
409 printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name); | 436 dev_err(dapm->dev, "asoc: failed to add kcontrol %s\n", w->name); |
410 return ret; 411} 412 413/* create new dapm volume control */ | 437 return ret; 438} 439 440/* create new dapm volume control */ |
414static int dapm_new_pga(struct snd_soc_codec *codec, | 441static int dapm_new_pga(struct snd_soc_dapm_context *dapm, |
415 struct snd_soc_dapm_widget *w) 416{ 417 if (w->num_kcontrols) | 442 struct snd_soc_dapm_widget *w) 443{ 444 if (w->num_kcontrols) |
418 pr_err("asoc: PGA controls not supported: '%s'\n", w->name); | 445 dev_err(w->dapm->dev, 446 "asoc: PGA controls not supported: '%s'\n", w->name); |
419 420 return 0; 421} 422 423/* reset 'walked' bit for each dapm path */ | 447 448 return 0; 449} 450 451/* reset 'walked' bit for each dapm path */ |
424static inline void dapm_clear_walk(struct snd_soc_codec *codec) | 452static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) |
425{ 426 struct snd_soc_dapm_path *p; 427 | 453{ 454 struct snd_soc_dapm_path *p; 455 |
428 list_for_each_entry(p, &codec->dapm_paths, list) | 456 list_for_each_entry(p, &dapm->card->paths, list) |
429 p->walked = 0; 430} 431 432/* We implement power down on suspend by checking the power state of 433 * the ALSA card - when we are suspending the ALSA state for the card 434 * is set to D3. 435 */ 436static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) 437{ | 457 p->walked = 0; 458} 459 460/* We implement power down on suspend by checking the power state of 461 * the ALSA card - when we are suspending the ALSA state for the card 462 * is set to D3. 463 */ 464static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) 465{ |
438 int level = snd_power_get_state(widget->codec->card->snd_card); | 466 int level = snd_power_get_state(widget->dapm->codec->card->snd_card); |
439 440 switch (level) { 441 case SNDRV_CTL_POWER_D3hot: 442 case SNDRV_CTL_POWER_D3cold: 443 if (widget->ignore_suspend) | 467 468 switch (level) { 469 case SNDRV_CTL_POWER_D3hot: 470 case SNDRV_CTL_POWER_D3cold: 471 if (widget->ignore_suspend) |
444 pr_debug("%s ignoring suspend\n", widget->name); | 472 dev_dbg(widget->dapm->dev, "%s ignoring suspend\n", 473 widget->name); |
445 return widget->ignore_suspend; 446 default: 447 return 1; 448 } 449} 450 451/* 452 * Recursively check for a completed path to an active or physically connected --- 114 unchanged lines hidden (view full) --- 567 * widgets. 568 */ 569static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) 570{ 571 int ret; 572 573 /* call any power change event handlers */ 574 if (w->event) | 474 return widget->ignore_suspend; 475 default: 476 return 1; 477 } 478} 479 480/* 481 * Recursively check for a completed path to an active or physically connected --- 114 unchanged lines hidden (view full) --- 596 * widgets. 597 */ 598static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) 599{ 600 int ret; 601 602 /* call any power change event handlers */ 603 if (w->event) |
575 pr_debug("power %s event for %s flags %x\n", | 604 dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n", |
576 w->power ? "on" : "off", 577 w->name, w->event_flags); 578 579 /* power up pre event */ 580 if (w->power && w->event && 581 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { 582 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); 583 if (ret < 0) --- 32 unchanged lines hidden (view full) --- 616 617/* Generic check to see if a widget should be powered. 618 */ 619static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 620{ 621 int in, out; 622 623 in = is_connected_input_ep(w); | 605 w->power ? "on" : "off", 606 w->name, w->event_flags); 607 608 /* power up pre event */ 609 if (w->power && w->event && 610 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { 611 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); 612 if (ret < 0) --- 32 unchanged lines hidden (view full) --- 645 646/* Generic check to see if a widget should be powered. 647 */ 648static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 649{ 650 int in, out; 651 652 in = is_connected_input_ep(w); |
624 dapm_clear_walk(w->codec); | 653 dapm_clear_walk(w->dapm); |
625 out = is_connected_output_ep(w); | 654 out = is_connected_output_ep(w); |
626 dapm_clear_walk(w->codec); | 655 dapm_clear_walk(w->dapm); |
627 return out != 0 && in != 0; 628} 629 630/* Check to see if an ADC has power */ 631static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) 632{ 633 int in; 634 635 if (w->active) { 636 in = is_connected_input_ep(w); | 656 return out != 0 && in != 0; 657} 658 659/* Check to see if an ADC has power */ 660static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) 661{ 662 int in; 663 664 if (w->active) { 665 in = is_connected_input_ep(w); |
637 dapm_clear_walk(w->codec); | 666 dapm_clear_walk(w->dapm); |
638 return in != 0; 639 } else { 640 return dapm_generic_check_power(w); 641 } 642} 643 644/* Check to see if a DAC has power */ 645static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) 646{ 647 int out; 648 649 if (w->active) { 650 out = is_connected_output_ep(w); | 667 return in != 0; 668 } else { 669 return dapm_generic_check_power(w); 670 } 671} 672 673/* Check to see if a DAC has power */ 674static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) 675{ 676 int out; 677 678 if (w->active) { 679 out = is_connected_output_ep(w); |
651 dapm_clear_walk(w->codec); | 680 dapm_clear_walk(w->dapm); |
652 return out != 0; 653 } else { 654 return dapm_generic_check_power(w); 655 } 656} 657 658/* Check to see if a power supply is needed */ 659static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) --- 9 unchanged lines hidden (view full) --- 669 670 if (path->sink && path->sink->power_check && 671 path->sink->power_check(path->sink)) { 672 power = 1; 673 break; 674 } 675 } 676 | 681 return out != 0; 682 } else { 683 return dapm_generic_check_power(w); 684 } 685} 686 687/* Check to see if a power supply is needed */ 688static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) --- 9 unchanged lines hidden (view full) --- 698 699 if (path->sink && path->sink->power_check && 700 path->sink->power_check(path->sink)) { 701 power = 1; 702 break; 703 } 704 } 705 |
677 dapm_clear_walk(w->codec); | 706 dapm_clear_walk(w->dapm); |
678 679 return power; 680} 681 682static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 683 struct snd_soc_dapm_widget *b, 684 int sort[]) 685{ | 707 708 return power; 709} 710 711static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 712 struct snd_soc_dapm_widget *b, 713 int sort[]) 714{ |
686 if (a->codec != b->codec) 687 return (unsigned long)a - (unsigned long)b; | |
688 if (sort[a->id] != sort[b->id]) 689 return sort[a->id] - sort[b->id]; 690 if (a->reg != b->reg) 691 return a->reg - b->reg; | 715 if (sort[a->id] != sort[b->id]) 716 return sort[a->id] - sort[b->id]; 717 if (a->reg != b->reg) 718 return a->reg - b->reg; |
719 if (a->dapm != b->dapm) 720 return (unsigned long)a->dapm - (unsigned long)b->dapm; |
|
692 693 return 0; 694} 695 696/* Insert a widget in order into a DAPM power sequence. */ 697static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, 698 struct list_head *list, 699 int sort[]) --- 4 unchanged lines hidden (view full) --- 704 if (dapm_seq_compare(new_widget, w, sort) < 0) { 705 list_add_tail(&new_widget->power_list, &w->power_list); 706 return; 707 } 708 709 list_add_tail(&new_widget->power_list, list); 710} 711 | 721 722 return 0; 723} 724 725/* Insert a widget in order into a DAPM power sequence. */ 726static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, 727 struct list_head *list, 728 int sort[]) --- 4 unchanged lines hidden (view full) --- 733 if (dapm_seq_compare(new_widget, w, sort) < 0) { 734 list_add_tail(&new_widget->power_list, &w->power_list); 735 return; 736 } 737 738 list_add_tail(&new_widget->power_list, list); 739} 740 |
741static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm, 742 struct snd_soc_dapm_widget *w, int event) 743{ 744 struct snd_soc_card *card = dapm->card; 745 const char *ev_name; 746 int power, ret; 747 748 switch (event) { 749 case SND_SOC_DAPM_PRE_PMU: 750 ev_name = "PRE_PMU"; 751 power = 1; 752 break; 753 case SND_SOC_DAPM_POST_PMU: 754 ev_name = "POST_PMU"; 755 power = 1; 756 break; 757 case SND_SOC_DAPM_PRE_PMD: 758 ev_name = "PRE_PMD"; 759 power = 0; 760 break; 761 case SND_SOC_DAPM_POST_PMD: 762 ev_name = "POST_PMD"; 763 power = 0; 764 break; 765 default: 766 BUG(); 767 return; 768 } 769 770 if (w->power != power) 771 return; 772 773 if (w->event && (w->event_flags & event)) { 774 pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n", 775 w->name, ev_name); 776 trace_snd_soc_dapm_widget_event_start(w, event); 777 ret = w->event(w, NULL, event); 778 trace_snd_soc_dapm_widget_event_done(w, event); 779 if (ret < 0) 780 pr_err("%s: %s event failed: %d\n", 781 ev_name, w->name, ret); 782 } 783} 784 |
|
712/* Apply the coalesced changes from a DAPM sequence */ | 785/* Apply the coalesced changes from a DAPM sequence */ |
713static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, | 786static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, |
714 struct list_head *pending) 715{ | 787 struct list_head *pending) 788{ |
789 struct snd_soc_card *card = dapm->card; |
|
716 struct snd_soc_dapm_widget *w; | 790 struct snd_soc_dapm_widget *w; |
717 int reg, power, ret; | 791 int reg, power; |
718 unsigned int value = 0; 719 unsigned int mask = 0; 720 unsigned int cur_mask; 721 722 reg = list_first_entry(pending, struct snd_soc_dapm_widget, 723 power_list)->reg; 724 725 list_for_each_entry(w, pending, power_list) { --- 4 unchanged lines hidden (view full) --- 730 power = !w->power; 731 else 732 power = w->power; 733 734 mask |= cur_mask; 735 if (power) 736 value |= cur_mask; 737 | 792 unsigned int value = 0; 793 unsigned int mask = 0; 794 unsigned int cur_mask; 795 796 reg = list_first_entry(pending, struct snd_soc_dapm_widget, 797 power_list)->reg; 798 799 list_for_each_entry(w, pending, power_list) { --- 4 unchanged lines hidden (view full) --- 804 power = !w->power; 805 else 806 power = w->power; 807 808 mask |= cur_mask; 809 if (power) 810 value |= cur_mask; 811 |
738 pop_dbg(codec->pop_time, | 812 pop_dbg(dapm->dev, card->pop_time, |
739 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", 740 w->name, reg, value, mask); 741 | 813 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", 814 w->name, reg, value, mask); 815 |
742 /* power up pre event */ 743 if (w->power && w->event && 744 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { 745 pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n", 746 w->name); 747 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); 748 if (ret < 0) 749 pr_err("%s: pre event failed: %d\n", 750 w->name, ret); 751 } 752 753 /* power down pre event */ 754 if (!w->power && w->event && 755 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { 756 pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n", 757 w->name); 758 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); 759 if (ret < 0) 760 pr_err("%s: pre event failed: %d\n", 761 w->name, ret); 762 } | 816 /* Check for events */ 817 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMU); 818 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMD); |
763 } 764 765 if (reg >= 0) { | 819 } 820 821 if (reg >= 0) { |
766 pop_dbg(codec->pop_time, | 822 pop_dbg(dapm->dev, card->pop_time, |
767 "pop test : Applying 0x%x/0x%x to %x in %dms\n", | 823 "pop test : Applying 0x%x/0x%x to %x in %dms\n", |
768 value, mask, reg, codec->pop_time); 769 pop_wait(codec->pop_time); 770 snd_soc_update_bits(codec, reg, mask, value); | 824 value, mask, reg, card->pop_time); 825 pop_wait(card->pop_time); 826 snd_soc_update_bits(dapm->codec, reg, mask, value); |
771 } 772 773 list_for_each_entry(w, pending, power_list) { | 827 } 828 829 list_for_each_entry(w, pending, power_list) { |
774 /* power up post event */ 775 if (w->power && w->event && 776 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 777 pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n", 778 w->name); 779 ret = w->event(w, 780 NULL, SND_SOC_DAPM_POST_PMU); 781 if (ret < 0) 782 pr_err("%s: post event failed: %d\n", 783 w->name, ret); 784 } 785 786 /* power down post event */ 787 if (!w->power && w->event && 788 (w->event_flags & SND_SOC_DAPM_POST_PMD)) { 789 pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n", 790 w->name); 791 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); 792 if (ret < 0) 793 pr_err("%s: post event failed: %d\n", 794 w->name, ret); 795 } | 830 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMU); 831 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMD); |
796 } 797} 798 799/* Apply a DAPM power sequence. 800 * 801 * We walk over a pre-sorted list of widgets to apply power to. In 802 * order to minimise the number of writes to the device required 803 * multiple widgets will be updated in a single write where possible. 804 * Currently anything that requires more than a single write is not 805 * handled. 806 */ | 832 } 833} 834 835/* Apply a DAPM power sequence. 836 * 837 * We walk over a pre-sorted list of widgets to apply power to. In 838 * order to minimise the number of writes to the device required 839 * multiple widgets will be updated in a single write where possible. 840 * Currently anything that requires more than a single write is not 841 * handled. 842 */ |
807static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, 808 int event, int sort[]) | 843static void dapm_seq_run(struct snd_soc_dapm_context *dapm, 844 struct list_head *list, int event, int sort[]) |
809{ 810 struct snd_soc_dapm_widget *w, *n; 811 LIST_HEAD(pending); 812 int cur_sort = -1; 813 int cur_reg = SND_SOC_NOPM; 814 int ret; 815 816 list_for_each_entry_safe(w, n, list, power_list) { 817 ret = 0; 818 819 /* Do we need to apply any queued changes? */ 820 if (sort[w->id] != cur_sort || w->reg != cur_reg) { 821 if (!list_empty(&pending)) | 845{ 846 struct snd_soc_dapm_widget *w, *n; 847 LIST_HEAD(pending); 848 int cur_sort = -1; 849 int cur_reg = SND_SOC_NOPM; 850 int ret; 851 852 list_for_each_entry_safe(w, n, list, power_list) { 853 ret = 0; 854 855 /* Do we need to apply any queued changes? */ 856 if (sort[w->id] != cur_sort || w->reg != cur_reg) { 857 if (!list_empty(&pending)) |
822 dapm_seq_run_coalesced(codec, &pending); | 858 dapm_seq_run_coalesced(dapm, &pending); |
823 824 INIT_LIST_HEAD(&pending); 825 cur_sort = -1; 826 cur_reg = SND_SOC_NOPM; 827 } 828 829 switch (w->id) { 830 case snd_soc_dapm_pre: --- 36 unchanged lines hidden (view full) --- 867 /* Queue it up for application */ 868 cur_sort = sort[w->id]; 869 cur_reg = w->reg; 870 list_move(&w->power_list, &pending); 871 break; 872 } 873 874 if (ret < 0) | 859 860 INIT_LIST_HEAD(&pending); 861 cur_sort = -1; 862 cur_reg = SND_SOC_NOPM; 863 } 864 865 switch (w->id) { 866 case snd_soc_dapm_pre: --- 36 unchanged lines hidden (view full) --- 903 /* Queue it up for application */ 904 cur_sort = sort[w->id]; 905 cur_reg = w->reg; 906 list_move(&w->power_list, &pending); 907 break; 908 } 909 910 if (ret < 0) |
875 pr_err("Failed to apply widget power: %d\n", 876 ret); | 911 dev_err(w->dapm->dev, 912 "Failed to apply widget power: %d\n", ret); |
877 } 878 879 if (!list_empty(&pending)) | 913 } 914 915 if (!list_empty(&pending)) |
880 dapm_seq_run_coalesced(codec, &pending); | 916 dapm_seq_run_coalesced(dapm, &pending); |
881} 882 883/* 884 * Scan each dapm widget for complete audio path. 885 * A complete path is a route that has valid endpoints i.e.:- 886 * 887 * o DAC to output pin. 888 * o Input Pin to ADC. 889 * o Input pin to Output pin (bypass, sidetone) 890 * o DAC to ADC (loopback). 891 */ | 917} 918 919/* 920 * Scan each dapm widget for complete audio path. 921 * A complete path is a route that has valid endpoints i.e.:- 922 * 923 * o DAC to output pin. 924 * o Input Pin to ADC. 925 * o Input pin to Output pin (bypass, sidetone) 926 * o DAC to ADC (loopback). 927 */ |
892static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | 928static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) |
893{ | 929{ |
894 struct snd_soc_card *card = codec->card; | 930 struct snd_soc_card *card = dapm->codec->card; |
895 struct snd_soc_dapm_widget *w; 896 LIST_HEAD(up_list); 897 LIST_HEAD(down_list); 898 int ret = 0; 899 int power; 900 int sys_power = 0; 901 | 931 struct snd_soc_dapm_widget *w; 932 LIST_HEAD(up_list); 933 LIST_HEAD(down_list); 934 int ret = 0; 935 int power; 936 int sys_power = 0; 937 |
938 trace_snd_soc_dapm_start(card); 939 |
|
902 /* Check which widgets we need to power and store them in 903 * lists indicating if they should be powered up or down. 904 */ | 940 /* Check which widgets we need to power and store them in 941 * lists indicating if they should be powered up or down. 942 */ |
905 list_for_each_entry(w, &codec->dapm_widgets, list) { | 943 list_for_each_entry(w, &dapm->widgets, list) { |
906 switch (w->id) { 907 case snd_soc_dapm_pre: 908 dapm_seq_insert(w, &down_list, dapm_down_seq); 909 break; 910 case snd_soc_dapm_post: 911 dapm_seq_insert(w, &up_list, dapm_up_seq); 912 break; 913 --- 6 unchanged lines hidden (view full) --- 920 else 921 power = 1; 922 if (power) 923 sys_power = 1; 924 925 if (w->power == power) 926 continue; 927 | 944 switch (w->id) { 945 case snd_soc_dapm_pre: 946 dapm_seq_insert(w, &down_list, dapm_down_seq); 947 break; 948 case snd_soc_dapm_post: 949 dapm_seq_insert(w, &up_list, dapm_up_seq); 950 break; 951 --- 6 unchanged lines hidden (view full) --- 958 else 959 power = 1; 960 if (power) 961 sys_power = 1; 962 963 if (w->power == power) 964 continue; 965 |
966 trace_snd_soc_dapm_widget_power(w, power); 967 |
|
928 if (power) 929 dapm_seq_insert(w, &up_list, dapm_up_seq); 930 else 931 dapm_seq_insert(w, &down_list, dapm_down_seq); 932 933 w->power = power; 934 break; 935 } 936 } 937 938 /* If there are no DAPM widgets then try to figure out power from the 939 * event type. 940 */ | 968 if (power) 969 dapm_seq_insert(w, &up_list, dapm_up_seq); 970 else 971 dapm_seq_insert(w, &down_list, dapm_down_seq); 972 973 w->power = power; 974 break; 975 } 976 } 977 978 /* If there are no DAPM widgets then try to figure out power from the 979 * event type. 980 */ |
941 if (list_empty(&codec->dapm_widgets)) { | 981 if (list_empty(&dapm->widgets)) { |
942 switch (event) { 943 case SND_SOC_DAPM_STREAM_START: 944 case SND_SOC_DAPM_STREAM_RESUME: 945 sys_power = 1; 946 break; | 982 switch (event) { 983 case SND_SOC_DAPM_STREAM_START: 984 case SND_SOC_DAPM_STREAM_RESUME: 985 sys_power = 1; 986 break; |
987 case SND_SOC_DAPM_STREAM_STOP: 988 sys_power = !!dapm->codec->active; 989 break; |
|
947 case SND_SOC_DAPM_STREAM_SUSPEND: 948 sys_power = 0; 949 break; 950 case SND_SOC_DAPM_STREAM_NOP: | 990 case SND_SOC_DAPM_STREAM_SUSPEND: 991 sys_power = 0; 992 break; 993 case SND_SOC_DAPM_STREAM_NOP: |
951 switch (codec->bias_level) { | 994 switch (dapm->bias_level) { |
952 case SND_SOC_BIAS_STANDBY: 953 case SND_SOC_BIAS_OFF: 954 sys_power = 0; 955 break; 956 default: 957 sys_power = 1; 958 break; 959 } 960 break; 961 default: 962 break; 963 } 964 } 965 | 995 case SND_SOC_BIAS_STANDBY: 996 case SND_SOC_BIAS_OFF: 997 sys_power = 0; 998 break; 999 default: 1000 sys_power = 1; 1001 break; 1002 } 1003 break; 1004 default: 1005 break; 1006 } 1007 } 1008 |
966 if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { 967 ret = snd_soc_dapm_set_bias_level(card, codec, | 1009 if (sys_power && dapm->bias_level == SND_SOC_BIAS_OFF) { 1010 ret = snd_soc_dapm_set_bias_level(card, dapm, |
968 SND_SOC_BIAS_STANDBY); 969 if (ret != 0) | 1011 SND_SOC_BIAS_STANDBY); 1012 if (ret != 0) |
970 pr_err("Failed to turn on bias: %d\n", ret); | 1013 dev_err(dapm->dev, 1014 "Failed to turn on bias: %d\n", ret); |
971 } 972 973 /* If we're changing to all on or all off then prepare */ | 1015 } 1016 1017 /* If we're changing to all on or all off then prepare */ |
974 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || 975 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { 976 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_PREPARE); | 1018 if ((sys_power && dapm->bias_level == SND_SOC_BIAS_STANDBY) || 1019 (!sys_power && dapm->bias_level == SND_SOC_BIAS_ON)) { 1020 ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_PREPARE); |
977 if (ret != 0) | 1021 if (ret != 0) |
978 pr_err("Failed to prepare bias: %d\n", ret); | 1022 dev_err(dapm->dev, 1023 "Failed to prepare bias: %d\n", ret); |
979 } 980 981 /* Power down widgets first; try to avoid amplifying pops. */ | 1024 } 1025 1026 /* Power down widgets first; try to avoid amplifying pops. */ |
982 dapm_seq_run(codec, &down_list, event, dapm_down_seq); | 1027 dapm_seq_run(dapm, &down_list, event, dapm_down_seq); |
983 984 /* Now power up. */ | 1028 1029 /* Now power up. */ |
985 dapm_seq_run(codec, &up_list, event, dapm_up_seq); | 1030 dapm_seq_run(dapm, &up_list, event, dapm_up_seq); |
986 987 /* If we just powered the last thing off drop to standby bias */ | 1031 1032 /* If we just powered the last thing off drop to standby bias */ |
988 if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { 989 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_STANDBY); | 1033 if (dapm->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { 1034 ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); |
990 if (ret != 0) | 1035 if (ret != 0) |
991 pr_err("Failed to apply standby bias: %d\n", ret); | 1036 dev_err(dapm->dev, 1037 "Failed to apply standby bias: %d\n", ret); |
992 } 993 994 /* If we're in standby and can support bias off then do that */ | 1038 } 1039 1040 /* If we're in standby and can support bias off then do that */ |
995 if (codec->bias_level == SND_SOC_BIAS_STANDBY && 996 codec->idle_bias_off) { 997 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); | 1041 if (dapm->bias_level == SND_SOC_BIAS_STANDBY && 1042 dapm->idle_bias_off) { 1043 ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_OFF); |
998 if (ret != 0) | 1044 if (ret != 0) |
999 pr_err("Failed to turn off bias: %d\n", ret); | 1045 dev_err(dapm->dev, 1046 "Failed to turn off bias: %d\n", ret); |
1000 } 1001 1002 /* If we just powered up then move to active bias */ | 1047 } 1048 1049 /* If we just powered up then move to active bias */ |
1003 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { 1004 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_ON); | 1050 if (dapm->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { 1051 ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_ON); |
1005 if (ret != 0) | 1052 if (ret != 0) |
1006 pr_err("Failed to apply active bias: %d\n", ret); | 1053 dev_err(dapm->dev, 1054 "Failed to apply active bias: %d\n", ret); |
1007 } 1008 | 1055 } 1056 |
1009 pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n", 1010 codec->pop_time); 1011 pop_wait(codec->pop_time); | 1057 pop_dbg(dapm->dev, card->pop_time, 1058 "DAPM sequencing finished, waiting %dms\n", card->pop_time); 1059 pop_wait(card->pop_time); |
1012 | 1060 |
1061 trace_snd_soc_dapm_done(card); 1062 |
|
1013 return 0; 1014} 1015 1016#ifdef CONFIG_DEBUG_FS 1017static int dapm_widget_power_open_file(struct inode *inode, struct file *file) 1018{ 1019 file->private_data = inode->i_private; 1020 return 0; --- 9 unchanged lines hidden (view full) --- 1030 ssize_t ret; 1031 struct snd_soc_dapm_path *p = NULL; 1032 1033 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 1034 if (!buf) 1035 return -ENOMEM; 1036 1037 in = is_connected_input_ep(w); | 1063 return 0; 1064} 1065 1066#ifdef CONFIG_DEBUG_FS 1067static int dapm_widget_power_open_file(struct inode *inode, struct file *file) 1068{ 1069 file->private_data = inode->i_private; 1070 return 0; --- 9 unchanged lines hidden (view full) --- 1080 ssize_t ret; 1081 struct snd_soc_dapm_path *p = NULL; 1082 1083 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 1084 if (!buf) 1085 return -ENOMEM; 1086 1087 in = is_connected_input_ep(w); |
1038 dapm_clear_walk(w->codec); | 1088 dapm_clear_walk(w->dapm); |
1039 out = is_connected_output_ep(w); | 1089 out = is_connected_output_ep(w); |
1040 dapm_clear_walk(w->codec); | 1090 dapm_clear_walk(w->dapm); |
1041 1042 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d", 1043 w->name, w->power ? "On" : "Off", in, out); 1044 1045 if (w->reg >= 0) 1046 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1047 " - R%d(0x%x) bit %d", 1048 w->reg, w->reg, w->shift); --- 33 unchanged lines hidden (view full) --- 1082} 1083 1084static const struct file_operations dapm_widget_power_fops = { 1085 .open = dapm_widget_power_open_file, 1086 .read = dapm_widget_power_read_file, 1087 .llseek = default_llseek, 1088}; 1089 | 1091 1092 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d", 1093 w->name, w->power ? "On" : "Off", in, out); 1094 1095 if (w->reg >= 0) 1096 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1097 " - R%d(0x%x) bit %d", 1098 w->reg, w->reg, w->shift); --- 33 unchanged lines hidden (view full) --- 1132} 1133 1134static const struct file_operations dapm_widget_power_fops = { 1135 .open = dapm_widget_power_open_file, 1136 .read = dapm_widget_power_read_file, 1137 .llseek = default_llseek, 1138}; 1139 |
1090void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) | 1140void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) |
1091{ 1092 struct snd_soc_dapm_widget *w; 1093 struct dentry *d; 1094 | 1141{ 1142 struct snd_soc_dapm_widget *w; 1143 struct dentry *d; 1144 |
1095 if (!codec->debugfs_dapm) | 1145 if (!dapm->debugfs_dapm) |
1096 return; 1097 | 1146 return; 1147 |
1098 list_for_each_entry(w, &codec->dapm_widgets, list) { | 1148 list_for_each_entry(w, &dapm->widgets, list) { |
1099 if (!w->name) 1100 continue; 1101 1102 d = debugfs_create_file(w->name, 0444, | 1149 if (!w->name) 1150 continue; 1151 1152 d = debugfs_create_file(w->name, 0444, |
1103 codec->debugfs_dapm, w, | 1153 dapm->debugfs_dapm, w, |
1104 &dapm_widget_power_fops); 1105 if (!d) | 1154 &dapm_widget_power_fops); 1155 if (!d) |
1106 printk(KERN_WARNING 1107 "ASoC: Failed to create %s debugfs file\n", 1108 w->name); | 1156 dev_warn(w->dapm->dev, 1157 "ASoC: Failed to create %s debugfs file\n", 1158 w->name); |
1109 } 1110} 1111#else | 1159 } 1160} 1161#else |
1112void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) | 1162void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) |
1113{ 1114} 1115#endif 1116 1117/* test and update the power status of a mux widget */ 1118static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1119 struct snd_kcontrol *kcontrol, int change, 1120 int mux, struct soc_enum *e) --- 4 unchanged lines hidden (view full) --- 1125 if (widget->id != snd_soc_dapm_mux && 1126 widget->id != snd_soc_dapm_value_mux) 1127 return -ENODEV; 1128 1129 if (!change) 1130 return 0; 1131 1132 /* find dapm widget path assoc with kcontrol */ | 1163{ 1164} 1165#endif 1166 1167/* test and update the power status of a mux widget */ 1168static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1169 struct snd_kcontrol *kcontrol, int change, 1170 int mux, struct soc_enum *e) --- 4 unchanged lines hidden (view full) --- 1175 if (widget->id != snd_soc_dapm_mux && 1176 widget->id != snd_soc_dapm_value_mux) 1177 return -ENODEV; 1178 1179 if (!change) 1180 return 0; 1181 1182 /* find dapm widget path assoc with kcontrol */ |
1133 list_for_each_entry(path, &widget->codec->dapm_paths, list) { | 1183 list_for_each_entry(path, &widget->dapm->card->paths, list) { |
1134 if (path->kcontrol != kcontrol) 1135 continue; 1136 1137 if (!path->name || !e->texts[mux]) 1138 continue; 1139 1140 found = 1; 1141 /* we now need to match the string in the enum to the path */ 1142 if (!(strcmp(path->name, e->texts[mux]))) 1143 path->connect = 1; /* new connection */ 1144 else 1145 path->connect = 0; /* old connection must be powered down */ 1146 } 1147 1148 if (found) | 1184 if (path->kcontrol != kcontrol) 1185 continue; 1186 1187 if (!path->name || !e->texts[mux]) 1188 continue; 1189 1190 found = 1; 1191 /* we now need to match the string in the enum to the path */ 1192 if (!(strcmp(path->name, e->texts[mux]))) 1193 path->connect = 1; /* new connection */ 1194 else 1195 path->connect = 0; /* old connection must be powered down */ 1196 } 1197 1198 if (found) |
1149 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); | 1199 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); |
1150 1151 return 0; 1152} 1153 1154/* test and update the power status of a mixer or switch widget */ 1155static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1156 struct snd_kcontrol *kcontrol, int connect) 1157{ 1158 struct snd_soc_dapm_path *path; 1159 int found = 0; 1160 1161 if (widget->id != snd_soc_dapm_mixer && 1162 widget->id != snd_soc_dapm_mixer_named_ctl && 1163 widget->id != snd_soc_dapm_switch) 1164 return -ENODEV; 1165 1166 /* find dapm widget path assoc with kcontrol */ | 1200 1201 return 0; 1202} 1203 1204/* test and update the power status of a mixer or switch widget */ 1205static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1206 struct snd_kcontrol *kcontrol, int connect) 1207{ 1208 struct snd_soc_dapm_path *path; 1209 int found = 0; 1210 1211 if (widget->id != snd_soc_dapm_mixer && 1212 widget->id != snd_soc_dapm_mixer_named_ctl && 1213 widget->id != snd_soc_dapm_switch) 1214 return -ENODEV; 1215 1216 /* find dapm widget path assoc with kcontrol */ |
1167 list_for_each_entry(path, &widget->codec->dapm_paths, list) { | 1217 list_for_each_entry(path, &widget->dapm->card->paths, list) { |
1168 if (path->kcontrol != kcontrol) 1169 continue; 1170 1171 /* found, now check type */ 1172 found = 1; 1173 path->connect = connect; 1174 break; 1175 } 1176 1177 if (found) | 1218 if (path->kcontrol != kcontrol) 1219 continue; 1220 1221 /* found, now check type */ 1222 found = 1; 1223 path->connect = connect; 1224 break; 1225 } 1226 1227 if (found) |
1178 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); | 1228 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); |
1179 1180 return 0; 1181} 1182 1183/* show dapm widget status in sys fs */ 1184static ssize_t dapm_widget_show(struct device *dev, 1185 struct device_attribute *attr, char *buf) 1186{ 1187 struct snd_soc_pcm_runtime *rtd = 1188 container_of(dev, struct snd_soc_pcm_runtime, dev); 1189 struct snd_soc_codec *codec =rtd->codec; 1190 struct snd_soc_dapm_widget *w; 1191 int count = 0; 1192 char *state = "not set"; 1193 | 1229 1230 return 0; 1231} 1232 1233/* show dapm widget status in sys fs */ 1234static ssize_t dapm_widget_show(struct device *dev, 1235 struct device_attribute *attr, char *buf) 1236{ 1237 struct snd_soc_pcm_runtime *rtd = 1238 container_of(dev, struct snd_soc_pcm_runtime, dev); 1239 struct snd_soc_codec *codec =rtd->codec; 1240 struct snd_soc_dapm_widget *w; 1241 int count = 0; 1242 char *state = "not set"; 1243 |
1194 list_for_each_entry(w, &codec->dapm_widgets, list) { | 1244 list_for_each_entry(w, &codec->dapm.widgets, list) { |
1195 1196 /* only display widgets that burnm power */ 1197 switch (w->id) { 1198 case snd_soc_dapm_hp: 1199 case snd_soc_dapm_mic: 1200 case snd_soc_dapm_spk: 1201 case snd_soc_dapm_line: 1202 case snd_soc_dapm_micbias: 1203 case snd_soc_dapm_dac: 1204 case snd_soc_dapm_adc: 1205 case snd_soc_dapm_pga: | 1245 1246 /* only display widgets that burnm power */ 1247 switch (w->id) { 1248 case snd_soc_dapm_hp: 1249 case snd_soc_dapm_mic: 1250 case snd_soc_dapm_spk: 1251 case snd_soc_dapm_line: 1252 case snd_soc_dapm_micbias: 1253 case snd_soc_dapm_dac: 1254 case snd_soc_dapm_adc: 1255 case snd_soc_dapm_pga: |
1256 case snd_soc_dapm_out_drv: |
|
1206 case snd_soc_dapm_mixer: 1207 case snd_soc_dapm_mixer_named_ctl: 1208 case snd_soc_dapm_supply: 1209 if (w->name) 1210 count += sprintf(buf + count, "%s: %s\n", 1211 w->name, w->power ? "On":"Off"); 1212 break; 1213 default: 1214 break; 1215 } 1216 } 1217 | 1257 case snd_soc_dapm_mixer: 1258 case snd_soc_dapm_mixer_named_ctl: 1259 case snd_soc_dapm_supply: 1260 if (w->name) 1261 count += sprintf(buf + count, "%s: %s\n", 1262 w->name, w->power ? "On":"Off"); 1263 break; 1264 default: 1265 break; 1266 } 1267 } 1268 |
1218 switch (codec->bias_level) { | 1269 switch (codec->dapm.bias_level) { |
1219 case SND_SOC_BIAS_ON: 1220 state = "On"; 1221 break; 1222 case SND_SOC_BIAS_PREPARE: 1223 state = "Prepare"; 1224 break; 1225 case SND_SOC_BIAS_STANDBY: 1226 state = "Standby"; --- 15 unchanged lines hidden (view full) --- 1242} 1243 1244static void snd_soc_dapm_sys_remove(struct device *dev) 1245{ 1246 device_remove_file(dev, &dev_attr_dapm_widget); 1247} 1248 1249/* free all dapm widgets and resources */ | 1270 case SND_SOC_BIAS_ON: 1271 state = "On"; 1272 break; 1273 case SND_SOC_BIAS_PREPARE: 1274 state = "Prepare"; 1275 break; 1276 case SND_SOC_BIAS_STANDBY: 1277 state = "Standby"; --- 15 unchanged lines hidden (view full) --- 1293} 1294 1295static void snd_soc_dapm_sys_remove(struct device *dev) 1296{ 1297 device_remove_file(dev, &dev_attr_dapm_widget); 1298} 1299 1300/* free all dapm widgets and resources */ |
1250static void dapm_free_widgets(struct snd_soc_codec *codec) | 1301static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) |
1251{ 1252 struct snd_soc_dapm_widget *w, *next_w; 1253 struct snd_soc_dapm_path *p, *next_p; 1254 | 1302{ 1303 struct snd_soc_dapm_widget *w, *next_w; 1304 struct snd_soc_dapm_path *p, *next_p; 1305 |
1255 list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) { | 1306 list_for_each_entry_safe(w, next_w, &dapm->widgets, list) { |
1256 list_del(&w->list); | 1307 list_del(&w->list); |
1308 /* 1309 * remove source and sink paths associated to this widget. 1310 * While removing the path, remove reference to it from both 1311 * source and sink widgets so that path is removed only once. 1312 */ 1313 list_for_each_entry_safe(p, next_p, &w->sources, list_sink) { 1314 list_del(&p->list_sink); 1315 list_del(&p->list_source); 1316 list_del(&p->list); 1317 kfree(p->long_name); 1318 kfree(p); 1319 } 1320 list_for_each_entry_safe(p, next_p, &w->sinks, list_source) { 1321 list_del(&p->list_sink); 1322 list_del(&p->list_source); 1323 list_del(&p->list); 1324 kfree(p->long_name); 1325 kfree(p); 1326 } 1327 kfree(w->name); |
|
1257 kfree(w); 1258 } | 1328 kfree(w); 1329 } |
1259 1260 list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) { 1261 list_del(&p->list); 1262 kfree(p->long_name); 1263 kfree(p); 1264 } | |
1265} 1266 | 1330} 1331 |
1267static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, | 1332static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, |
1268 const char *pin, int status) 1269{ 1270 struct snd_soc_dapm_widget *w; 1271 | 1333 const char *pin, int status) 1334{ 1335 struct snd_soc_dapm_widget *w; 1336 |
1272 list_for_each_entry(w, &codec->dapm_widgets, list) { | 1337 list_for_each_entry(w, &dapm->widgets, list) { |
1273 if (!strcmp(w->name, pin)) { | 1338 if (!strcmp(w->name, pin)) { |
1274 pr_debug("dapm: %s: pin %s\n", codec->name, pin); | 1339 dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n", 1340 pin, status); |
1275 w->connected = status; 1276 /* Allow disabling of forced pins */ 1277 if (status == 0) 1278 w->force = 0; 1279 return 0; 1280 } 1281 } 1282 | 1341 w->connected = status; 1342 /* Allow disabling of forced pins */ 1343 if (status == 0) 1344 w->force = 0; 1345 return 0; 1346 } 1347 } 1348 |
1283 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); | 1349 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); |
1284 return -EINVAL; 1285} 1286 1287/** 1288 * snd_soc_dapm_sync - scan and power dapm paths | 1350 return -EINVAL; 1351} 1352 1353/** 1354 * snd_soc_dapm_sync - scan and power dapm paths |
1289 * @codec: audio codec | 1355 * @dapm: DAPM context |
1290 * 1291 * Walks all dapm audio paths and powers widgets according to their 1292 * stream or path usage. 1293 * 1294 * Returns 0 for success. 1295 */ | 1356 * 1357 * Walks all dapm audio paths and powers widgets according to their 1358 * stream or path usage. 1359 * 1360 * Returns 0 for success. 1361 */ |
1296int snd_soc_dapm_sync(struct snd_soc_codec *codec) | 1362int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) |
1297{ | 1363{ |
1298 return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); | 1364 return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); |
1299} 1300EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1301 | 1365} 1366EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1367 |
1302static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, | 1368static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, |
1303 const struct snd_soc_dapm_route *route) 1304{ 1305 struct snd_soc_dapm_path *path; 1306 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; | 1369 const struct snd_soc_dapm_route *route) 1370{ 1371 struct snd_soc_dapm_path *path; 1372 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; |
1307 const char *sink = route->sink; | 1373 const char *sink; |
1308 const char *control = route->control; | 1374 const char *control = route->control; |
1309 const char *source = route->source; | 1375 const char *source; 1376 char prefixed_sink[80]; 1377 char prefixed_source[80]; |
1310 int ret = 0; 1311 | 1378 int ret = 0; 1379 |
1380 if (dapm->codec->name_prefix) { 1381 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", 1382 dapm->codec->name_prefix, route->sink); 1383 sink = prefixed_sink; 1384 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", 1385 dapm->codec->name_prefix, route->source); 1386 source = prefixed_source; 1387 } else { 1388 sink = route->sink; 1389 source = route->source; 1390 } 1391 |
|
1312 /* find src and dest widgets */ | 1392 /* find src and dest widgets */ |
1313 list_for_each_entry(w, &codec->dapm_widgets, list) { | 1393 list_for_each_entry(w, &dapm->widgets, list) { |
1314 1315 if (!wsink && !(strcmp(w->name, sink))) { 1316 wsink = w; 1317 continue; 1318 } 1319 if (!wsource && !(strcmp(w->name, source))) { 1320 wsource = w; 1321 } --- 26 unchanged lines hidden (view full) --- 1348 wsink->id == snd_soc_dapm_hp || 1349 wsink->id == snd_soc_dapm_line || 1350 wsink->id == snd_soc_dapm_input) 1351 wsource->ext = 1; 1352 } 1353 1354 /* connect static paths */ 1355 if (control == NULL) { | 1394 1395 if (!wsink && !(strcmp(w->name, sink))) { 1396 wsink = w; 1397 continue; 1398 } 1399 if (!wsource && !(strcmp(w->name, source))) { 1400 wsource = w; 1401 } --- 26 unchanged lines hidden (view full) --- 1428 wsink->id == snd_soc_dapm_hp || 1429 wsink->id == snd_soc_dapm_line || 1430 wsink->id == snd_soc_dapm_input) 1431 wsource->ext = 1; 1432 } 1433 1434 /* connect static paths */ 1435 if (control == NULL) { |
1356 list_add(&path->list, &codec->dapm_paths); | 1436 list_add(&path->list, &dapm->card->paths); |
1357 list_add(&path->list_sink, &wsink->sources); 1358 list_add(&path->list_source, &wsource->sinks); 1359 path->connect = 1; 1360 return 0; 1361 } 1362 1363 /* connect dynamic paths */ 1364 switch(wsink->id) { 1365 case snd_soc_dapm_adc: 1366 case snd_soc_dapm_dac: 1367 case snd_soc_dapm_pga: | 1437 list_add(&path->list_sink, &wsink->sources); 1438 list_add(&path->list_source, &wsource->sinks); 1439 path->connect = 1; 1440 return 0; 1441 } 1442 1443 /* connect dynamic paths */ 1444 switch(wsink->id) { 1445 case snd_soc_dapm_adc: 1446 case snd_soc_dapm_dac: 1447 case snd_soc_dapm_pga: |
1448 case snd_soc_dapm_out_drv: |
|
1368 case snd_soc_dapm_input: 1369 case snd_soc_dapm_output: 1370 case snd_soc_dapm_micbias: 1371 case snd_soc_dapm_vmid: 1372 case snd_soc_dapm_pre: 1373 case snd_soc_dapm_post: 1374 case snd_soc_dapm_supply: 1375 case snd_soc_dapm_aif_in: 1376 case snd_soc_dapm_aif_out: | 1449 case snd_soc_dapm_input: 1450 case snd_soc_dapm_output: 1451 case snd_soc_dapm_micbias: 1452 case snd_soc_dapm_vmid: 1453 case snd_soc_dapm_pre: 1454 case snd_soc_dapm_post: 1455 case snd_soc_dapm_supply: 1456 case snd_soc_dapm_aif_in: 1457 case snd_soc_dapm_aif_out: |
1377 list_add(&path->list, &codec->dapm_paths); | 1458 list_add(&path->list, &dapm->card->paths); |
1378 list_add(&path->list_sink, &wsink->sources); 1379 list_add(&path->list_source, &wsource->sinks); 1380 path->connect = 1; 1381 return 0; 1382 case snd_soc_dapm_mux: 1383 case snd_soc_dapm_value_mux: | 1459 list_add(&path->list_sink, &wsink->sources); 1460 list_add(&path->list_source, &wsource->sinks); 1461 path->connect = 1; 1462 return 0; 1463 case snd_soc_dapm_mux: 1464 case snd_soc_dapm_value_mux: |
1384 ret = dapm_connect_mux(codec, wsource, wsink, path, control, | 1465 ret = dapm_connect_mux(dapm, wsource, wsink, path, control, |
1385 &wsink->kcontrols[0]); 1386 if (ret != 0) 1387 goto err; 1388 break; 1389 case snd_soc_dapm_switch: 1390 case snd_soc_dapm_mixer: 1391 case snd_soc_dapm_mixer_named_ctl: | 1466 &wsink->kcontrols[0]); 1467 if (ret != 0) 1468 goto err; 1469 break; 1470 case snd_soc_dapm_switch: 1471 case snd_soc_dapm_mixer: 1472 case snd_soc_dapm_mixer_named_ctl: |
1392 ret = dapm_connect_mixer(codec, wsource, wsink, path, control); | 1473 ret = dapm_connect_mixer(dapm, wsource, wsink, path, control); |
1393 if (ret != 0) 1394 goto err; 1395 break; 1396 case snd_soc_dapm_hp: 1397 case snd_soc_dapm_mic: 1398 case snd_soc_dapm_line: 1399 case snd_soc_dapm_spk: | 1474 if (ret != 0) 1475 goto err; 1476 break; 1477 case snd_soc_dapm_hp: 1478 case snd_soc_dapm_mic: 1479 case snd_soc_dapm_line: 1480 case snd_soc_dapm_spk: |
1400 list_add(&path->list, &codec->dapm_paths); | 1481 list_add(&path->list, &dapm->card->paths); |
1401 list_add(&path->list_sink, &wsink->sources); 1402 list_add(&path->list_source, &wsource->sinks); 1403 path->connect = 0; 1404 return 0; 1405 } 1406 return 0; 1407 1408err: | 1482 list_add(&path->list_sink, &wsink->sources); 1483 list_add(&path->list_source, &wsource->sinks); 1484 path->connect = 0; 1485 return 0; 1486 } 1487 return 0; 1488 1489err: |
1409 printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source, 1410 control, sink); | 1490 dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n", 1491 source, control, sink); |
1411 kfree(path); 1412 return ret; 1413} 1414 1415/** 1416 * snd_soc_dapm_add_routes - Add routes between DAPM widgets | 1492 kfree(path); 1493 return ret; 1494} 1495 1496/** 1497 * snd_soc_dapm_add_routes - Add routes between DAPM widgets |
1417 * @codec: codec | 1498 * @dapm: DAPM context |
1418 * @route: audio routes 1419 * @num: number of routes 1420 * 1421 * Connects 2 dapm widgets together via a named audio path. The sink is 1422 * the widget receiving the audio signal, whilst the source is the sender 1423 * of the audio signal. 1424 * 1425 * Returns 0 for success else error. On error all resources can be freed 1426 * with a call to snd_soc_card_free(). 1427 */ | 1499 * @route: audio routes 1500 * @num: number of routes 1501 * 1502 * Connects 2 dapm widgets together via a named audio path. The sink is 1503 * the widget receiving the audio signal, whilst the source is the sender 1504 * of the audio signal. 1505 * 1506 * Returns 0 for success else error. On error all resources can be freed 1507 * with a call to snd_soc_card_free(). 1508 */ |
1428int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, | 1509int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, |
1429 const struct snd_soc_dapm_route *route, int num) 1430{ 1431 int i, ret; 1432 1433 for (i = 0; i < num; i++) { | 1510 const struct snd_soc_dapm_route *route, int num) 1511{ 1512 int i, ret; 1513 1514 for (i = 0; i < num; i++) { |
1434 ret = snd_soc_dapm_add_route(codec, route); | 1515 ret = snd_soc_dapm_add_route(dapm, route); |
1435 if (ret < 0) { | 1516 if (ret < 0) { |
1436 printk(KERN_ERR "Failed to add route %s->%s\n", 1437 route->source, 1438 route->sink); | 1517 dev_err(dapm->dev, "Failed to add route %s->%s\n", 1518 route->source, route->sink); |
1439 return ret; 1440 } 1441 route++; 1442 } 1443 1444 return 0; 1445} 1446EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); 1447 1448/** 1449 * snd_soc_dapm_new_widgets - add new dapm widgets | 1519 return ret; 1520 } 1521 route++; 1522 } 1523 1524 return 0; 1525} 1526EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); 1527 1528/** 1529 * snd_soc_dapm_new_widgets - add new dapm widgets |
1450 * @codec: audio codec | 1530 * @dapm: DAPM context |
1451 * 1452 * Checks the codec for any new dapm widgets and creates them if found. 1453 * 1454 * Returns 0 for success. 1455 */ | 1531 * 1532 * Checks the codec for any new dapm widgets and creates them if found. 1533 * 1534 * Returns 0 for success. 1535 */ |
1456int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) | 1536int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) |
1457{ 1458 struct snd_soc_dapm_widget *w; 1459 | 1537{ 1538 struct snd_soc_dapm_widget *w; 1539 |
1460 list_for_each_entry(w, &codec->dapm_widgets, list) | 1540 list_for_each_entry(w, &dapm->widgets, list) |
1461 { 1462 if (w->new) 1463 continue; 1464 1465 switch(w->id) { 1466 case snd_soc_dapm_switch: 1467 case snd_soc_dapm_mixer: 1468 case snd_soc_dapm_mixer_named_ctl: 1469 w->power_check = dapm_generic_check_power; | 1541 { 1542 if (w->new) 1543 continue; 1544 1545 switch(w->id) { 1546 case snd_soc_dapm_switch: 1547 case snd_soc_dapm_mixer: 1548 case snd_soc_dapm_mixer_named_ctl: 1549 w->power_check = dapm_generic_check_power; |
1470 dapm_new_mixer(codec, w); | 1550 dapm_new_mixer(dapm, w); |
1471 break; 1472 case snd_soc_dapm_mux: 1473 case snd_soc_dapm_value_mux: 1474 w->power_check = dapm_generic_check_power; | 1551 break; 1552 case snd_soc_dapm_mux: 1553 case snd_soc_dapm_value_mux: 1554 w->power_check = dapm_generic_check_power; |
1475 dapm_new_mux(codec, w); | 1555 dapm_new_mux(dapm, w); |
1476 break; 1477 case snd_soc_dapm_adc: 1478 case snd_soc_dapm_aif_out: 1479 w->power_check = dapm_adc_check_power; 1480 break; 1481 case snd_soc_dapm_dac: 1482 case snd_soc_dapm_aif_in: 1483 w->power_check = dapm_dac_check_power; 1484 break; 1485 case snd_soc_dapm_pga: | 1556 break; 1557 case snd_soc_dapm_adc: 1558 case snd_soc_dapm_aif_out: 1559 w->power_check = dapm_adc_check_power; 1560 break; 1561 case snd_soc_dapm_dac: 1562 case snd_soc_dapm_aif_in: 1563 w->power_check = dapm_dac_check_power; 1564 break; 1565 case snd_soc_dapm_pga: |
1566 case snd_soc_dapm_out_drv: |
|
1486 w->power_check = dapm_generic_check_power; | 1567 w->power_check = dapm_generic_check_power; |
1487 dapm_new_pga(codec, w); | 1568 dapm_new_pga(dapm, w); |
1488 break; 1489 case snd_soc_dapm_input: 1490 case snd_soc_dapm_output: 1491 case snd_soc_dapm_micbias: 1492 case snd_soc_dapm_spk: 1493 case snd_soc_dapm_hp: 1494 case snd_soc_dapm_mic: 1495 case snd_soc_dapm_line: --- 4 unchanged lines hidden (view full) --- 1500 case snd_soc_dapm_vmid: 1501 case snd_soc_dapm_pre: 1502 case snd_soc_dapm_post: 1503 break; 1504 } 1505 w->new = 1; 1506 } 1507 | 1569 break; 1570 case snd_soc_dapm_input: 1571 case snd_soc_dapm_output: 1572 case snd_soc_dapm_micbias: 1573 case snd_soc_dapm_spk: 1574 case snd_soc_dapm_hp: 1575 case snd_soc_dapm_mic: 1576 case snd_soc_dapm_line: --- 4 unchanged lines hidden (view full) --- 1581 case snd_soc_dapm_vmid: 1582 case snd_soc_dapm_pre: 1583 case snd_soc_dapm_post: 1584 break; 1585 } 1586 w->new = 1; 1587 } 1588 |
1508 dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); | 1589 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); |
1509 return 0; 1510} 1511EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); 1512 1513/** 1514 * snd_soc_dapm_get_volsw - dapm mixer get callback 1515 * @kcontrol: mixer control 1516 * @ucontrol: control element information --- 367 unchanged lines hidden (view full) --- 1884 struct snd_ctl_elem_value *ucontrol) 1885{ 1886 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1887 const char *pin = (const char *)kcontrol->private_value; 1888 1889 mutex_lock(&codec->mutex); 1890 1891 ucontrol->value.integer.value[0] = | 1590 return 0; 1591} 1592EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); 1593 1594/** 1595 * snd_soc_dapm_get_volsw - dapm mixer get callback 1596 * @kcontrol: mixer control 1597 * @ucontrol: control element information --- 367 unchanged lines hidden (view full) --- 1965 struct snd_ctl_elem_value *ucontrol) 1966{ 1967 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1968 const char *pin = (const char *)kcontrol->private_value; 1969 1970 mutex_lock(&codec->mutex); 1971 1972 ucontrol->value.integer.value[0] = |
1892 snd_soc_dapm_get_pin_status(codec, pin); | 1973 snd_soc_dapm_get_pin_status(&codec->dapm, pin); |
1893 1894 mutex_unlock(&codec->mutex); 1895 1896 return 0; 1897} 1898EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); 1899 1900/** --- 6 unchanged lines hidden (view full) --- 1907 struct snd_ctl_elem_value *ucontrol) 1908{ 1909 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1910 const char *pin = (const char *)kcontrol->private_value; 1911 1912 mutex_lock(&codec->mutex); 1913 1914 if (ucontrol->value.integer.value[0]) | 1974 1975 mutex_unlock(&codec->mutex); 1976 1977 return 0; 1978} 1979EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); 1980 1981/** --- 6 unchanged lines hidden (view full) --- 1988 struct snd_ctl_elem_value *ucontrol) 1989{ 1990 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1991 const char *pin = (const char *)kcontrol->private_value; 1992 1993 mutex_lock(&codec->mutex); 1994 1995 if (ucontrol->value.integer.value[0]) |
1915 snd_soc_dapm_enable_pin(codec, pin); | 1996 snd_soc_dapm_enable_pin(&codec->dapm, pin); |
1916 else | 1997 else |
1917 snd_soc_dapm_disable_pin(codec, pin); | 1998 snd_soc_dapm_disable_pin(&codec->dapm, pin); |
1918 | 1999 |
1919 snd_soc_dapm_sync(codec); | 2000 snd_soc_dapm_sync(&codec->dapm); |
1920 1921 mutex_unlock(&codec->mutex); 1922 1923 return 0; 1924} 1925EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 1926 1927/** 1928 * snd_soc_dapm_new_control - create new dapm control | 2001 2002 mutex_unlock(&codec->mutex); 2003 2004 return 0; 2005} 2006EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 2007 2008/** 2009 * snd_soc_dapm_new_control - create new dapm control |
1929 * @codec: audio codec | 2010 * @dapm: DAPM context |
1930 * @widget: widget template 1931 * 1932 * Creates a new dapm control based upon the template. 1933 * 1934 * Returns 0 for success else error. 1935 */ | 2011 * @widget: widget template 2012 * 2013 * Creates a new dapm control based upon the template. 2014 * 2015 * Returns 0 for success else error. 2016 */ |
1936int snd_soc_dapm_new_control(struct snd_soc_codec *codec, | 2017int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, |
1937 const struct snd_soc_dapm_widget *widget) 1938{ 1939 struct snd_soc_dapm_widget *w; | 2018 const struct snd_soc_dapm_widget *widget) 2019{ 2020 struct snd_soc_dapm_widget *w; |
2021 size_t name_len; |
|
1940 1941 if ((w = dapm_cnew_widget(widget)) == NULL) 1942 return -ENOMEM; 1943 | 2022 2023 if ((w = dapm_cnew_widget(widget)) == NULL) 2024 return -ENOMEM; 2025 |
1944 w->codec = codec; | 2026 name_len = strlen(widget->name) + 1; 2027 if (dapm->codec->name_prefix) 2028 name_len += 1 + strlen(dapm->codec->name_prefix); 2029 w->name = kmalloc(name_len, GFP_KERNEL); 2030 if (w->name == NULL) { 2031 kfree(w); 2032 return -ENOMEM; 2033 } 2034 if (dapm->codec->name_prefix) 2035 snprintf(w->name, name_len, "%s %s", 2036 dapm->codec->name_prefix, widget->name); 2037 else 2038 snprintf(w->name, name_len, "%s", widget->name); 2039 2040 w->dapm = dapm; 2041 w->codec = dapm->codec; |
1945 INIT_LIST_HEAD(&w->sources); 1946 INIT_LIST_HEAD(&w->sinks); 1947 INIT_LIST_HEAD(&w->list); | 2042 INIT_LIST_HEAD(&w->sources); 2043 INIT_LIST_HEAD(&w->sinks); 2044 INIT_LIST_HEAD(&w->list); |
1948 list_add(&w->list, &codec->dapm_widgets); | 2045 list_add(&w->list, &dapm->widgets); |
1949 1950 /* machine layer set ups unconnected pins and insertions */ 1951 w->connected = 1; 1952 return 0; 1953} 1954EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); 1955 1956/** 1957 * snd_soc_dapm_new_controls - create new dapm controls | 2046 2047 /* machine layer set ups unconnected pins and insertions */ 2048 w->connected = 1; 2049 return 0; 2050} 2051EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); 2052 2053/** 2054 * snd_soc_dapm_new_controls - create new dapm controls |
1958 * @codec: audio codec | 2055 * @dapm: DAPM context |
1959 * @widget: widget array 1960 * @num: number of widgets 1961 * 1962 * Creates new DAPM controls based upon the templates. 1963 * 1964 * Returns 0 for success else error. 1965 */ | 2056 * @widget: widget array 2057 * @num: number of widgets 2058 * 2059 * Creates new DAPM controls based upon the templates. 2060 * 2061 * Returns 0 for success else error. 2062 */ |
1966int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, | 2063int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, |
1967 const struct snd_soc_dapm_widget *widget, 1968 int num) 1969{ 1970 int i, ret; 1971 1972 for (i = 0; i < num; i++) { | 2064 const struct snd_soc_dapm_widget *widget, 2065 int num) 2066{ 2067 int i, ret; 2068 2069 for (i = 0; i < num; i++) { |
1973 ret = snd_soc_dapm_new_control(codec, widget); | 2070 ret = snd_soc_dapm_new_control(dapm, widget); |
1974 if (ret < 0) { | 2071 if (ret < 0) { |
1975 printk(KERN_ERR 1976 "ASoC: Failed to create DAPM control %s: %d\n", 1977 widget->name, ret); | 2072 dev_err(dapm->dev, 2073 "ASoC: Failed to create DAPM control %s: %d\n", 2074 widget->name, ret); |
1978 return ret; 1979 } 1980 widget++; 1981 } 1982 return 0; 1983} 1984EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 1985 | 2075 return ret; 2076 } 2077 widget++; 2078 } 2079 return 0; 2080} 2081EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 2082 |
1986 1987/** 1988 * snd_soc_dapm_stream_event - send a stream event to the dapm core 1989 * @codec: audio codec 1990 * @stream: stream name 1991 * @event: stream event 1992 * 1993 * Sends a stream event to the dapm core. The core then makes any 1994 * necessary widget power changes. 1995 * 1996 * Returns 0 for success else error. 1997 */ 1998int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, | 2083static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, |
1999 const char *stream, int event) 2000{ | 2084 const char *stream, int event) 2085{ |
2001 struct snd_soc_codec *codec = rtd->codec; | |
2002 struct snd_soc_dapm_widget *w; 2003 | 2086 struct snd_soc_dapm_widget *w; 2087 |
2004 if (stream == NULL) 2005 return 0; 2006 2007 mutex_lock(&codec->mutex); 2008 list_for_each_entry(w, &codec->dapm_widgets, list) | 2088 list_for_each_entry(w, &dapm->widgets, list) |
2009 { 2010 if (!w->sname) 2011 continue; | 2089 { 2090 if (!w->sname) 2091 continue; |
2012 pr_debug("widget %s\n %s stream %s event %d\n", 2013 w->name, w->sname, stream, event); | 2092 dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", 2093 w->name, w->sname, stream, event); |
2014 if (strstr(w->sname, stream)) { 2015 switch(event) { 2016 case SND_SOC_DAPM_STREAM_START: 2017 w->active = 1; 2018 break; 2019 case SND_SOC_DAPM_STREAM_STOP: 2020 w->active = 0; 2021 break; 2022 case SND_SOC_DAPM_STREAM_SUSPEND: 2023 case SND_SOC_DAPM_STREAM_RESUME: 2024 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 2025 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 2026 break; 2027 } 2028 } 2029 } 2030 | 2094 if (strstr(w->sname, stream)) { 2095 switch(event) { 2096 case SND_SOC_DAPM_STREAM_START: 2097 w->active = 1; 2098 break; 2099 case SND_SOC_DAPM_STREAM_STOP: 2100 w->active = 0; 2101 break; 2102 case SND_SOC_DAPM_STREAM_SUSPEND: 2103 case SND_SOC_DAPM_STREAM_RESUME: 2104 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 2105 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 2106 break; 2107 } 2108 } 2109 } 2110 |
2031 dapm_power_widgets(codec, event); | 2111 dapm_power_widgets(dapm, event); 2112} 2113 2114/** 2115 * snd_soc_dapm_stream_event - send a stream event to the dapm core 2116 * @rtd: PCM runtime data 2117 * @stream: stream name 2118 * @event: stream event 2119 * 2120 * Sends a stream event to the dapm core. The core then makes any 2121 * necessary widget power changes. 2122 * 2123 * Returns 0 for success else error. 2124 */ 2125int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, 2126 const char *stream, int event) 2127{ 2128 struct snd_soc_codec *codec = rtd->codec; 2129 2130 if (stream == NULL) 2131 return 0; 2132 2133 mutex_lock(&codec->mutex); 2134 soc_dapm_stream_event(&codec->dapm, stream, event); |
2032 mutex_unlock(&codec->mutex); 2033 return 0; 2034} 2035EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); 2036 2037/** 2038 * snd_soc_dapm_enable_pin - enable pin. | 2135 mutex_unlock(&codec->mutex); 2136 return 0; 2137} 2138EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); 2139 2140/** 2141 * snd_soc_dapm_enable_pin - enable pin. |
2039 * @codec: SoC codec | 2142 * @dapm: DAPM context |
2040 * @pin: pin name 2041 * 2042 * Enables input/output pin and its parents or children widgets iff there is 2043 * a valid audio route and active audio stream. 2044 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2045 * do any widget power switching. 2046 */ | 2143 * @pin: pin name 2144 * 2145 * Enables input/output pin and its parents or children widgets iff there is 2146 * a valid audio route and active audio stream. 2147 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2148 * do any widget power switching. 2149 */ |
2047int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin) | 2150int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) |
2048{ | 2151{ |
2049 return snd_soc_dapm_set_pin(codec, pin, 1); | 2152 return snd_soc_dapm_set_pin(dapm, pin, 1); |
2050} 2051EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 2052 2053/** 2054 * snd_soc_dapm_force_enable_pin - force a pin to be enabled | 2153} 2154EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 2155 2156/** 2157 * snd_soc_dapm_force_enable_pin - force a pin to be enabled |
2055 * @codec: SoC codec | 2158 * @dapm: DAPM context |
2056 * @pin: pin name 2057 * 2058 * Enables input/output pin regardless of any other state. This is 2059 * intended for use with microphone bias supplies used in microphone 2060 * jack detection. 2061 * 2062 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2063 * do any widget power switching. 2064 */ | 2159 * @pin: pin name 2160 * 2161 * Enables input/output pin regardless of any other state. This is 2162 * intended for use with microphone bias supplies used in microphone 2163 * jack detection. 2164 * 2165 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2166 * do any widget power switching. 2167 */ |
2065int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, const char *pin) | 2168int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, 2169 const char *pin) |
2066{ 2067 struct snd_soc_dapm_widget *w; 2068 | 2170{ 2171 struct snd_soc_dapm_widget *w; 2172 |
2069 list_for_each_entry(w, &codec->dapm_widgets, list) { | 2173 list_for_each_entry(w, &dapm->widgets, list) { |
2070 if (!strcmp(w->name, pin)) { | 2174 if (!strcmp(w->name, pin)) { |
2071 pr_debug("dapm: %s: pin %s\n", codec->name, pin); | 2175 dev_dbg(w->dapm->dev, 2176 "dapm: force enable pin %s\n", pin); |
2072 w->connected = 1; 2073 w->force = 1; 2074 return 0; 2075 } 2076 } 2077 | 2177 w->connected = 1; 2178 w->force = 1; 2179 return 0; 2180 } 2181 } 2182 |
2078 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); | 2183 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); |
2079 return -EINVAL; 2080} 2081EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); 2082 2083/** 2084 * snd_soc_dapm_disable_pin - disable pin. | 2184 return -EINVAL; 2185} 2186EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); 2187 2188/** 2189 * snd_soc_dapm_disable_pin - disable pin. |
2085 * @codec: SoC codec | 2190 * @dapm: DAPM context |
2086 * @pin: pin name 2087 * 2088 * Disables input/output pin and its parents or children widgets. 2089 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2090 * do any widget power switching. 2091 */ | 2191 * @pin: pin name 2192 * 2193 * Disables input/output pin and its parents or children widgets. 2194 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2195 * do any widget power switching. 2196 */ |
2092int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin) | 2197int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, 2198 const char *pin) |
2093{ | 2199{ |
2094 return snd_soc_dapm_set_pin(codec, pin, 0); | 2200 return snd_soc_dapm_set_pin(dapm, pin, 0); |
2095} 2096EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 2097 2098/** 2099 * snd_soc_dapm_nc_pin - permanently disable pin. | 2201} 2202EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 2203 2204/** 2205 * snd_soc_dapm_nc_pin - permanently disable pin. |
2100 * @codec: SoC codec | 2206 * @dapm: DAPM context |
2101 * @pin: pin name 2102 * 2103 * Marks the specified pin as being not connected, disabling it along 2104 * any parent or child widgets. At present this is identical to 2105 * snd_soc_dapm_disable_pin() but in future it will be extended to do 2106 * additional things such as disabling controls which only affect 2107 * paths through the pin. 2108 * 2109 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2110 * do any widget power switching. 2111 */ | 2207 * @pin: pin name 2208 * 2209 * Marks the specified pin as being not connected, disabling it along 2210 * any parent or child widgets. At present this is identical to 2211 * snd_soc_dapm_disable_pin() but in future it will be extended to do 2212 * additional things such as disabling controls which only affect 2213 * paths through the pin. 2214 * 2215 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2216 * do any widget power switching. 2217 */ |
2112int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin) | 2218int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) |
2113{ | 2219{ |
2114 return snd_soc_dapm_set_pin(codec, pin, 0); | 2220 return snd_soc_dapm_set_pin(dapm, pin, 0); |
2115} 2116EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); 2117 2118/** 2119 * snd_soc_dapm_get_pin_status - get audio pin status | 2221} 2222EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); 2223 2224/** 2225 * snd_soc_dapm_get_pin_status - get audio pin status |
2120 * @codec: audio codec | 2226 * @dapm: DAPM context |
2121 * @pin: audio signal pin endpoint (or start point) 2122 * 2123 * Get audio pin status - connected or disconnected. 2124 * 2125 * Returns 1 for connected otherwise 0. 2126 */ | 2227 * @pin: audio signal pin endpoint (or start point) 2228 * 2229 * Get audio pin status - connected or disconnected. 2230 * 2231 * Returns 1 for connected otherwise 0. 2232 */ |
2127int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) | 2233int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, 2234 const char *pin) |
2128{ 2129 struct snd_soc_dapm_widget *w; 2130 | 2235{ 2236 struct snd_soc_dapm_widget *w; 2237 |
2131 list_for_each_entry(w, &codec->dapm_widgets, list) { | 2238 list_for_each_entry(w, &dapm->widgets, list) { |
2132 if (!strcmp(w->name, pin)) 2133 return w->connected; 2134 } 2135 2136 return 0; 2137} 2138EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); 2139 2140/** 2141 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint | 2239 if (!strcmp(w->name, pin)) 2240 return w->connected; 2241 } 2242 2243 return 0; 2244} 2245EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); 2246 2247/** 2248 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint |
2142 * @codec: audio codec | 2249 * @dapm: DAPM context |
2143 * @pin: audio signal pin endpoint (or start point) 2144 * 2145 * Mark the given endpoint or pin as ignoring suspend. When the 2146 * system is disabled a path between two endpoints flagged as ignoring 2147 * suspend will not be disabled. The path must already be enabled via 2148 * normal means at suspend time, it will not be turned on if it was not 2149 * already enabled. 2150 */ | 2250 * @pin: audio signal pin endpoint (or start point) 2251 * 2252 * Mark the given endpoint or pin as ignoring suspend. When the 2253 * system is disabled a path between two endpoints flagged as ignoring 2254 * suspend will not be disabled. The path must already be enabled via 2255 * normal means at suspend time, it will not be turned on if it was not 2256 * already enabled. 2257 */ |
2151int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin) | 2258int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, 2259 const char *pin) |
2152{ 2153 struct snd_soc_dapm_widget *w; 2154 | 2260{ 2261 struct snd_soc_dapm_widget *w; 2262 |
2155 list_for_each_entry(w, &codec->dapm_widgets, list) { | 2263 list_for_each_entry(w, &dapm->widgets, list) { |
2156 if (!strcmp(w->name, pin)) { 2157 w->ignore_suspend = 1; 2158 return 0; 2159 } 2160 } 2161 | 2264 if (!strcmp(w->name, pin)) { 2265 w->ignore_suspend = 1; 2266 return 0; 2267 } 2268 } 2269 |
2162 pr_err("Unknown DAPM pin: %s\n", pin); | 2270 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); |
2163 return -EINVAL; 2164} 2165EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); 2166 2167/** 2168 * snd_soc_dapm_free - free dapm resources 2169 * @card: SoC device 2170 * 2171 * Free all dapm widgets and resources. 2172 */ | 2271 return -EINVAL; 2272} 2273EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); 2274 2275/** 2276 * snd_soc_dapm_free - free dapm resources 2277 * @card: SoC device 2278 * 2279 * Free all dapm widgets and resources. 2280 */ |
2173void snd_soc_dapm_free(struct snd_soc_codec *codec) | 2281void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) |
2174{ | 2282{ |
2175 snd_soc_dapm_sys_remove(codec->dev); 2176 dapm_free_widgets(codec); | 2283 snd_soc_dapm_sys_remove(dapm->dev); 2284 dapm_free_widgets(dapm); |
2177} 2178EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 2179 | 2285} 2286EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 2287 |
2180static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec) | 2288static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) |
2181{ 2182 struct snd_soc_dapm_widget *w; 2183 LIST_HEAD(down_list); 2184 int powerdown = 0; 2185 | 2289{ 2290 struct snd_soc_dapm_widget *w; 2291 LIST_HEAD(down_list); 2292 int powerdown = 0; 2293 |
2186 list_for_each_entry(w, &codec->dapm_widgets, list) { | 2294 list_for_each_entry(w, &dapm->widgets, list) { |
2187 if (w->power) { 2188 dapm_seq_insert(w, &down_list, dapm_down_seq); 2189 w->power = 0; 2190 powerdown = 1; 2191 } 2192 } 2193 2194 /* If there were no widgets to power down we're already in 2195 * standby. 2196 */ 2197 if (powerdown) { | 2295 if (w->power) { 2296 dapm_seq_insert(w, &down_list, dapm_down_seq); 2297 w->power = 0; 2298 powerdown = 1; 2299 } 2300 } 2301 2302 /* If there were no widgets to power down we're already in 2303 * standby. 2304 */ 2305 if (powerdown) { |
2198 snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_PREPARE); 2199 dapm_seq_run(codec, &down_list, 0, dapm_down_seq); 2200 snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_STANDBY); | 2306 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE); 2307 dapm_seq_run(dapm, &down_list, 0, dapm_down_seq); 2308 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY); |
2201 } 2202} 2203 2204/* 2205 * snd_soc_dapm_shutdown - callback for system shutdown 2206 */ 2207void snd_soc_dapm_shutdown(struct snd_soc_card *card) 2208{ 2209 struct snd_soc_codec *codec; 2210 | 2309 } 2310} 2311 2312/* 2313 * snd_soc_dapm_shutdown - callback for system shutdown 2314 */ 2315void snd_soc_dapm_shutdown(struct snd_soc_card *card) 2316{ 2317 struct snd_soc_codec *codec; 2318 |
2211 list_for_each_entry(codec, &card->codec_dev_list, list) 2212 soc_dapm_shutdown_codec(codec); 2213 2214 snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); | 2319 list_for_each_entry(codec, &card->codec_dev_list, list) { 2320 soc_dapm_shutdown_codec(&codec->dapm); 2321 snd_soc_dapm_set_bias_level(card, &codec->dapm, SND_SOC_BIAS_OFF); 2322 } |
2215} 2216 2217/* Module information */ 2218MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk"); 2219MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 2220MODULE_LICENSE("GPL"); | 2323} 2324 2325/* Module information */ 2326MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk"); 2327MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 2328MODULE_LICENSE("GPL"); |