Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 293373
b: refs/heads/master
c: 888df39
h: refs/heads/master
i:
  293371: a57f1bb
v: v3
  • Loading branch information
Mark Brown committed Feb 17, 2012
1 parent bf156da commit 61e1b08
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3056557f3b2387d4ac99ca8af14956cd2bf003c2
refs/heads/master: 888df395ebc5c88cde45478660197ca46665efe2
4 changes: 4 additions & 0 deletions trunk/include/sound/soc-dai.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/list.h>

struct snd_pcm_substream;
struct snd_soc_dapm_widget;

/*
* DAI hardware audio formats.
Expand Down Expand Up @@ -238,6 +239,9 @@ struct snd_soc_dai {
unsigned char pop_wait:1;
unsigned char probed:1;

struct snd_soc_dapm_widget *playback_widget;
struct snd_soc_dapm_widget *capture_widget;

/* DAI DMA data */
void *playback_dma_data;
void *capture_dma_data;
Expand Down
4 changes: 4 additions & 0 deletions trunk/include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,9 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget,
int num);
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
struct snd_soc_dai *dai);
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);

/* dapm path setup */
int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
Expand Down Expand Up @@ -425,6 +428,7 @@ enum snd_soc_dapm_type {
snd_soc_dapm_aif_in, /* audio interface input */
snd_soc_dapm_aif_out, /* audio interface output */
snd_soc_dapm_siggen, /* signal generator */
snd_soc_dapm_dai, /* link to DAI structure */
};

/*
Expand Down
11 changes: 11 additions & 0 deletions trunk/sound/soc/soc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
{
int ret = 0;
const struct snd_soc_codec_driver *driver = codec->driver;
struct snd_soc_dai *dai;

codec->card = card;
codec->dapm.card = card;
Expand All @@ -1024,6 +1025,14 @@ static int soc_probe_codec(struct snd_soc_card *card,
snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
driver->num_dapm_widgets);

/* Create DAPM widgets for each DAI stream */
list_for_each_entry(dai, &dai_list, list) {
if (dai->dev != codec->dev)
continue;

snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
}

codec->dapm.idle_bias_off = driver->idle_bias_off;

if (driver->probe) {
Expand Down Expand Up @@ -1500,6 +1509,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
}
}

snd_soc_dapm_link_dai_widgets(card);

if (card->controls)
snd_soc_add_card_controls(card, card->controls, card->num_controls);

Expand Down
135 changes: 127 additions & 8 deletions trunk/sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ static int dapm_up_seq[] = {
[snd_soc_dapm_supply] = 1,
[snd_soc_dapm_regulator_supply] = 1,
[snd_soc_dapm_micbias] = 2,
[snd_soc_dapm_dai] = 3,
[snd_soc_dapm_aif_in] = 3,
[snd_soc_dapm_aif_out] = 3,
[snd_soc_dapm_mic] = 4,
Expand Down Expand Up @@ -86,6 +87,7 @@ static int dapm_down_seq[] = {
[snd_soc_dapm_value_mux] = 9,
[snd_soc_dapm_aif_in] = 10,
[snd_soc_dapm_aif_out] = 10,
[snd_soc_dapm_dai] = 10,
[snd_soc_dapm_regulator_supply] = 11,
[snd_soc_dapm_supply] = 11,
[snd_soc_dapm_post] = 12,
Expand Down Expand Up @@ -365,6 +367,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
case snd_soc_dapm_regulator_supply:
case snd_soc_dapm_aif_in:
case snd_soc_dapm_aif_out:
case snd_soc_dapm_dai:
case snd_soc_dapm_hp:
case snd_soc_dapm_mic:
case snd_soc_dapm_spk:
Expand Down Expand Up @@ -522,17 +525,17 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
* for widgets so cut the prefix off
* the front of the widget name.
*/
snprintf(path->long_name, name_len, "%s %s",
w->name + prefix_len,
snprintf((char *)path->long_name, name_len,
"%s %s", w->name + prefix_len,
w->kcontrol_news[i].name);
break;
case snd_soc_dapm_mixer_named_ctl:
snprintf(path->long_name, name_len, "%s",
w->kcontrol_news[i].name);
snprintf((char *)path->long_name, name_len,
"%s", w->kcontrol_news[i].name);
break;
}

path->long_name[name_len - 1] = '\0';
((char *)path->long_name)[name_len - 1] = '\0';

path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
wlist, path->long_name,
Expand Down Expand Up @@ -566,7 +569,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
struct snd_soc_dapm_widget_list *wlist;
int shared, wlistentries;
size_t wlistsize;
char *name;
const char *name;

if (w->num_kcontrols != 1) {
dev_err(dapm->dev,
Expand Down Expand Up @@ -702,6 +705,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
switch (widget->id) {
case snd_soc_dapm_adc:
case snd_soc_dapm_aif_out:
case snd_soc_dapm_dai:
if (widget->active) {
widget->outputs = snd_soc_dapm_suspend_check(widget);
return widget->outputs;
Expand Down Expand Up @@ -773,6 +777,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
switch (widget->id) {
case snd_soc_dapm_dac:
case snd_soc_dapm_aif_in:
case snd_soc_dapm_dai:
if (widget->active) {
widget->inputs = snd_soc_dapm_suspend_check(widget);
return widget->inputs;
Expand Down Expand Up @@ -892,6 +897,13 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
return out != 0 && in != 0;
}

static int dapm_dai_check_power(struct snd_soc_dapm_widget *w)
{
DAPM_UPDATE_STAT(w, power_checks);

return w->active;
}

/* Check to see if an ADC has power */
static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
{
Expand Down Expand Up @@ -2049,6 +2061,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
case snd_soc_dapm_regulator_supply:
case snd_soc_dapm_aif_in:
case snd_soc_dapm_aif_out:
case snd_soc_dapm_dai:
list_add(&path->list, &dapm->card->paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
Expand Down Expand Up @@ -2732,10 +2745,10 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
return NULL;
}
if (dapm->codec && dapm->codec->name_prefix)
snprintf(w->name, name_len, "%s %s",
snprintf((char *)w->name, name_len, "%s %s",
dapm->codec->name_prefix, widget->name);
else
snprintf(w->name, name_len, "%s", widget->name);
snprintf((char *)w->name, name_len, "%s", widget->name);

switch (w->id) {
case snd_soc_dapm_switch:
Expand Down Expand Up @@ -2771,6 +2784,9 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
case snd_soc_dapm_regulator_supply:
w->power_check = dapm_supply_check_power;
break;
case snd_soc_dapm_dai:
w->power_check = dapm_dai_check_power;
break;
default:
w->power_check = dapm_always_on_check_power;
break;
Expand Down Expand Up @@ -2822,6 +2838,109 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);

int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
struct snd_soc_dai *dai)
{
struct snd_soc_dapm_widget template;
struct snd_soc_dapm_widget *w;

WARN_ON(dapm->dev != dai->dev);

memset(&template, 0, sizeof(template));
template.reg = SND_SOC_NOPM;

if (dai->driver->playback.stream_name) {
template.id = snd_soc_dapm_dai;
template.name = dai->driver->playback.stream_name;
template.sname = dai->driver->playback.stream_name;

dev_dbg(dai->dev, "adding %s widget\n",
template.name);

w = snd_soc_dapm_new_control(dapm, &template);
if (!w) {
dev_err(dapm->dev, "Failed to create %s widget\n",
dai->driver->playback.stream_name);
}

w->priv = dai;
dai->playback_widget = w;
}

if (dai->driver->capture.stream_name) {
template.id = snd_soc_dapm_dai;
template.name = dai->driver->capture.stream_name;
template.sname = dai->driver->capture.stream_name;

dev_dbg(dai->dev, "adding %s widget\n",
template.name);

w = snd_soc_dapm_new_control(dapm, &template);
if (!w) {
dev_err(dapm->dev, "Failed to create %s widget\n",
dai->driver->capture.stream_name);
}

w->priv = dai;
dai->capture_widget = w;
}

return 0;
}

int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
{
struct snd_soc_dapm_widget *dai_w, *w;
struct snd_soc_dai *dai;
struct snd_soc_dapm_route r;

memset(&r, 0, sizeof(r));

/* For each DAI widget... */
list_for_each_entry(dai_w, &card->widgets, list) {
if (dai_w->id != snd_soc_dapm_dai)
continue;

dai = dai_w->priv;

/* ...find all widgets with the same stream and link them */
list_for_each_entry(w, &card->widgets, list) {
if (w->dapm != dai_w->dapm)
continue;

if (w->id == snd_soc_dapm_dai)
continue;

if (!w->sname)
continue;

if (dai->driver->playback.stream_name &&
strstr(w->sname,
dai->driver->playback.stream_name)) {
r.source = dai->playback_widget->name;
r.sink = w->name;
dev_dbg(dai->dev, "%s -> %s\n",
r.source, r.sink);

snd_soc_dapm_add_route(w->dapm, &r);
}

if (dai->driver->capture.stream_name &&
strstr(w->sname,
dai->driver->capture.stream_name)) {
r.source = w->name;
r.sink = dai->capture_widget->name;
dev_dbg(dai->dev, "%s -> %s\n",
r.source, r.sink);

snd_soc_dapm_add_route(w->dapm, &r);
}
}
}

return 0;
}

static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
int stream, struct snd_soc_dai *dai,
int event)
Expand Down

0 comments on commit 61e1b08

Please sign in to comment.