.shift = wshift, .invert = winvert, \
.event = wevent, .event_flags = wflags}
-/* generic register modifier widget */
+/* generic widgets */
#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
{ .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \
.reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \
.on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
+#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
+{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
+ .shift = wshift, .invert = winvert, .event = wevent, \
+ .event_flags = wflags}
/* dapm kcontrol types */
#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
snd_soc_dapm_vmid, /* codec bias/vmid - to minimise pops */
snd_soc_dapm_pre, /* machine specific pre widget - exec first */
snd_soc_dapm_post, /* machine specific post widget - exec last */
+ snd_soc_dapm_supply, /* power/clock supply */
};
/*
/* dapm power sequences - make this per codec in the future */
static int dapm_up_seq[] = {
- snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic,
- snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac,
- snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga,
- snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post
+ snd_soc_dapm_pre, snd_soc_dapm_supply, snd_soc_dapm_micbias,
+ snd_soc_dapm_mic, snd_soc_dapm_mux, snd_soc_dapm_value_mux,
+ snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl,
+ snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
+ snd_soc_dapm_post
};
static int dapm_down_seq[] = {
snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer,
snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias,
- snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post
+ snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_supply,
+ snd_soc_dapm_post
};
static int dapm_status = 1;
case snd_soc_dapm_dac:
case snd_soc_dapm_micbias:
case snd_soc_dapm_vmid:
+ case snd_soc_dapm_supply:
p->connect = 1;
break;
/* does effect routing - dynamically connected */
struct snd_soc_dapm_path *path;
int con = 0;
+ if (widget->id == snd_soc_dapm_supply)
+ return 0;
+
if (widget->id == snd_soc_dapm_adc && widget->active)
return 1;
struct snd_soc_dapm_path *path;
int con = 0;
+ if (widget->id == snd_soc_dapm_supply)
+ return 0;
+
/* active stream ? */
if (widget->id == snd_soc_dapm_dac && widget->active)
return 1;
}
}
+/* Check to see if a power supply is needed */
+static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
+{
+ struct snd_soc_dapm_path *path;
+ int power = 0;
+
+ /* Check if one of our outputs is connected */
+ list_for_each_entry(path, &w->sinks, list_source) {
+ if (path->sink && path->sink->power_check &&
+ path->sink->power_check(path->sink)) {
+ power = 1;
+ break;
+ }
+ }
+
+ dapm_clear_walk(w->codec);
+
+ return power;
+}
+
/*
* Scan a single DAPM widget for a complete audio path and update the
* power status appropriately.
case snd_soc_dapm_pga:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
+ case snd_soc_dapm_supply:
if (w->name) {
in = is_connected_input_ep(w);
dapm_clear_walk(w->codec);
case snd_soc_dapm_pga:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
+ case snd_soc_dapm_supply:
if (w->name)
count += sprintf(buf + count, "%s: %s\n",
w->name, w->power ? "On":"Off");
case snd_soc_dapm_vmid:
case snd_soc_dapm_pre:
case snd_soc_dapm_post:
+ case snd_soc_dapm_supply:
list_add(&path->list, &codec->dapm_paths);
list_add(&path->list_sink, &wsink->sources);
list_add(&path->list_source, &wsource->sinks);
case snd_soc_dapm_line:
w->power_check = dapm_generic_check_power;
break;
+ case snd_soc_dapm_supply:
+ w->power_check = dapm_supply_check_power;
case snd_soc_dapm_vmid:
case snd_soc_dapm_pre:
case snd_soc_dapm_post: