Release 4.7 sound/soc/soc-dapm.c
/*
* soc-dapm.c -- ALSA SoC Dynamic Audio Power Management
*
* Copyright 2005 Wolfson Microelectronics PLC.
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* Features:
* o Changes power status of internal codec blocks depending on the
* dynamic configuration of codec internal audio paths and active
* DACs/ADCs.
* o Platform power domain - can support external components i.e. amps and
* mic/headphone insertion events.
* o Automatic Mic Bias support
* o Jack insertion power event initiation - e.g. hp insertion will enable
* sinks, dacs, etc
* o Delayed power down of audio subsystem to reduce pops between a quick
* device reopen.
*
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/async.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/bitops.h>
#include <linux/platform_device.h>
#include <linux/jiffies.h>
#include <linux/debugfs.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <trace/events/asoc.h>
#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
#define SND_SOC_DAPM_DIR_REVERSE(x) ((x == SND_SOC_DAPM_DIR_IN) ? \
SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN)
#define snd_soc_dapm_for_each_direction(dir) \
for ((dir) = SND_SOC_DAPM_DIR_IN; (dir) <= SND_SOC_DAPM_DIR_OUT; \
(dir)++)
static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink,
const char *control,
int (*connected)(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink));
struct snd_soc_dapm_widget *
snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
struct snd_soc_dapm_widget *
snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
/* dapm power sequences - make this per codec in the future */
static int dapm_up_seq[] = {
[snd_soc_dapm_pre] = 0,
[snd_soc_dapm_regulator_supply] = 1,
[snd_soc_dapm_clock_supply] = 1,
[snd_soc_dapm_supply] = 2,
[snd_soc_dapm_micbias] = 3,
[snd_soc_dapm_dai_link] = 2,
[snd_soc_dapm_dai_in] = 4,
[snd_soc_dapm_dai_out] = 4,
[snd_soc_dapm_aif_in] = 4,
[snd_soc_dapm_aif_out] = 4,
[snd_soc_dapm_mic] = 5,
[snd_soc_dapm_mux] = 6,
[snd_soc_dapm_demux] = 6,
[snd_soc_dapm_dac] = 7,
[snd_soc_dapm_switch] = 8,
[snd_soc_dapm_mixer] = 8,
[snd_soc_dapm_mixer_named_ctl] = 8,
[snd_soc_dapm_pga] = 9,
[snd_soc_dapm_adc] = 10,
[snd_soc_dapm_out_drv] = 11,
[snd_soc_dapm_hp] = 11,
[snd_soc_dapm_spk] = 11,
[snd_soc_dapm_line] = 11,
[snd_soc_dapm_kcontrol] = 12,
[snd_soc_dapm_post] = 13,
};
static int dapm_down_seq[] = {
[snd_soc_dapm_pre] = 0,
[snd_soc_dapm_kcontrol] = 1,
[snd_soc_dapm_adc] = 2,
[snd_soc_dapm_hp] = 3,
[snd_soc_dapm_spk] = 3,
[snd_soc_dapm_line] = 3,
[snd_soc_dapm_out_drv] = 3,
[snd_soc_dapm_pga] = 4,
[snd_soc_dapm_switch] = 5,
[snd_soc_dapm_mixer_named_ctl] = 5,
[snd_soc_dapm_mixer] = 5,
[snd_soc_dapm_dac] = 6,
[snd_soc_dapm_mic] = 7,
[snd_soc_dapm_micbias] = 8,
[snd_soc_dapm_mux] = 9,
[snd_soc_dapm_demux] = 9,
[snd_soc_dapm_aif_in] = 10,
[snd_soc_dapm_aif_out] = 10,
[snd_soc_dapm_dai_in] = 10,
[snd_soc_dapm_dai_out] = 10,
[snd_soc_dapm_dai_link] = 11,
[snd_soc_dapm_supply] = 12,
[snd_soc_dapm_clock_supply] = 13,
[snd_soc_dapm_regulator_supply] = 13,
[snd_soc_dapm_post] = 14,
};
static void dapm_assert_locked(struct snd_soc_dapm_context *dapm)
{
if (dapm->card && dapm->card->instantiated)
lockdep_assert_held(&dapm->card->dapm_mutex);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 33 | 100.00% | 1 | 100.00% |
| Total | 33 | 100.00% | 1 | 100.00% |
static void pop_wait(u32 pop_time)
{
if (pop_time)
schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 19 | 90.48% | 1 | 50.00% |
troy kisky | troy kisky | 2 | 9.52% | 1 | 50.00% |
| Total | 21 | 100.00% | 2 | 100.00% |
static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
{
va_list args;
char *buf;
if (!pop_time)
return;
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (buf == NULL)
return;
va_start(args, fmt);
vsnprintf(buf, PAGE_SIZE, fmt, args);
dev_info(dev, "%s", buf);
va_end(args);
kfree(buf);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jarkko nikula | jarkko nikula | 48 | 55.17% | 1 | 25.00% |
mark brown | mark brown | 34 | 39.08% | 1 | 25.00% |
troy kisky | troy kisky | 3 | 3.45% | 1 | 25.00% |
takashi iwai | takashi iwai | 2 | 2.30% | 1 | 25.00% |
| Total | 87 | 100.00% | 4 | 100.00% |
static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w)
{
return !list_empty(&w->dirty);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 21 | 100.00% | 1 | 100.00% |
| Total | 21 | 100.00% | 1 | 100.00% |
static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason)
{
dapm_assert_locked(w->dapm);
if (!dapm_dirty_widget(w)) {
dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n",
w->name, reason);
list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 67 | 100.00% | 4 | 100.00% |
| Total | 67 | 100.00% | 4 | 100.00% |
/*
* Common implementation for dapm_widget_invalidate_input_paths() and
* dapm_widget_invalidate_output_paths(). The function is inlined since the
* combined size of the two specialized functions is only marginally larger then
* the size of the generic function and at the same time the fast path of the
* specialized functions is significantly smaller than the generic function.
*/
static __always_inline void dapm_widget_invalidate_paths(
struct snd_soc_dapm_widget *w, enum snd_soc_dapm_direction dir)
{
enum snd_soc_dapm_direction rdir = SND_SOC_DAPM_DIR_REVERSE(dir);
struct snd_soc_dapm_widget *node;
struct snd_soc_dapm_path *p;
LIST_HEAD(list);
dapm_assert_locked(w->dapm);
if (w->endpoints[dir] == -1)
return;
list_add_tail(&w->work_list, &list);
w->endpoints[dir] = -1;
list_for_each_entry(w, &list, work_list) {
snd_soc_dapm_widget_for_each_path(w, dir, p) {
if (p->is_supply || p->weak || !p->connect)
continue;
node = p->node[rdir];
if (node->endpoints[dir] != -1) {
node->endpoints[dir] = -1;
list_add_tail(&node->work_list, &list);
}
}
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 161 | 100.00% | 3 | 100.00% |
| Total | 161 | 100.00% | 3 | 100.00% |
/*
* dapm_widget_invalidate_input_paths() - Invalidate the cached number of
* input paths
* @w: The widget for which to invalidate the cached number of input paths
*
* Resets the cached number of inputs for the specified widget and all widgets
* that can be reached via outcoming paths from the widget.
*
* This function must be called if the number of output paths for a widget might
* have changed. E.g. if the source state of a widget changes or a path is added
* or activated with the widget as the sink.
*/
static void dapm_widget_invalidate_input_paths(struct snd_soc_dapm_widget *w)
{
dapm_widget_invalidate_paths(w, SND_SOC_DAPM_DIR_IN);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 18 | 100.00% | 2 | 100.00% |
| Total | 18 | 100.00% | 2 | 100.00% |
/*
* dapm_widget_invalidate_output_paths() - Invalidate the cached number of
* output paths
* @w: The widget for which to invalidate the cached number of output paths
*
* Resets the cached number of outputs for the specified widget and all widgets
* that can be reached via incoming paths from the widget.
*
* This function must be called if the number of output paths for a widget might
* have changed. E.g. if the sink state of a widget changes or a path is added
* or activated with the widget as the source.
*/
static void dapm_widget_invalidate_output_paths(struct snd_soc_dapm_widget *w)
{
dapm_widget_invalidate_paths(w, SND_SOC_DAPM_DIR_OUT);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 18 | 100.00% | 2 | 100.00% |
| Total | 18 | 100.00% | 2 | 100.00% |
/*
* dapm_path_invalidate() - Invalidates the cached number of inputs and outputs
* for the widgets connected to a path
* @p: The path to invalidate
*
* Resets the cached number of inputs for the sink of the path and the cached
* number of outputs for the source of the path.
*
* This function must be called when a path is added, removed or the connected
* state changes.
*/
static void dapm_path_invalidate(struct snd_soc_dapm_path *p)
{
/*
* Weak paths or supply paths do not influence the number of input or
* output paths of their neighbors.
*/
if (p->weak || p->is_supply)
return;
/*
* The number of connected endpoints is the sum of the number of
* connected endpoints of all neighbors. If a node with 0 connected
* endpoints is either connected or disconnected that sum won't change,
* so there is no need to re-check the path.
*/
if (p->source->endpoints[SND_SOC_DAPM_DIR_IN] != 0)
dapm_widget_invalidate_input_paths(p->sink);
if (p->sink->endpoints[SND_SOC_DAPM_DIR_OUT] != 0)
dapm_widget_invalidate_output_paths(p->source);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 64 | 100.00% | 2 | 100.00% |
| Total | 64 | 100.00% | 2 | 100.00% |
void dapm_mark_endpoints_dirty(struct snd_soc_card *card)
{
struct snd_soc_dapm_widget *w;
mutex_lock(&card->dapm_mutex);
list_for_each_entry(w, &card->widgets, list) {
if (w->is_ep) {
dapm_mark_dirty(w, "Rechecking endpoints");
if (w->is_ep & SND_SOC_DAPM_EP_SINK)
dapm_widget_invalidate_output_paths(w);
if (w->is_ep & SND_SOC_DAPM_EP_SOURCE)
dapm_widget_invalidate_input_paths(w);
}
}
mutex_unlock(&card->dapm_mutex);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 48 | 58.54% | 1 | 25.00% |
lars-peter clausen | lars-peter clausen | 34 | 41.46% | 3 | 75.00% |
| Total | 82 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(dapm_mark_endpoints_dirty);
/* create a new dapm widget */
static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
const struct snd_soc_dapm_widget *_widget)
{
return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
richard purdie | richard purdie | 23 | 79.31% | 1 | 50.00% |
takashi iwai | takashi iwai | 6 | 20.69% | 1 | 50.00% |
| Total | 29 | 100.00% | 2 | 100.00% |
struct dapm_kcontrol_data {
unsigned int value;
struct snd_soc_dapm_widget *widget;
struct list_head paths;
struct snd_soc_dapm_widget_list *wlist;
};
static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
struct snd_kcontrol *kcontrol, const char *ctrl_name)
{
struct dapm_kcontrol_data *data;
struct soc_mixer_control *mc;
struct soc_enum *e;
const char *name;
int ret;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
INIT_LIST_HEAD(&data->paths);
switch (widget->id) {
case snd_soc_dapm_switch:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
mc = (struct soc_mixer_control *)kcontrol->private_value;
if (mc->autodisable) {
struct snd_soc_dapm_widget template;
name = kasprintf(GFP_KERNEL, "%s %s", ctrl_name,
"Autodisable");
if (!name) {
ret = -ENOMEM;
goto err_data;
}
memset(&template, 0, sizeof(template));
template.reg = mc->reg;
template.mask = (1 << fls(mc->max)) - 1;
template.shift = mc->shift;
if (mc->invert)
template.off_val = mc->max;
else
template.off_val = 0;
template.on_val = template.off_val;
template.id = snd_soc_dapm_kcontrol;
template.name = name;
data->value = template.on_val;
data->widget =
snd_soc_dapm_new_control_unlocked(widget->dapm,
&template);
kfree(name);
if (!data->widget) {
ret = -ENOMEM;
goto err_data;
}
}
break;
case snd_soc_dapm_demux:
case snd_soc_dapm_mux:
e = (struct soc_enum *)kcontrol->private_value;
if (e->autodisable) {
struct snd_soc_dapm_widget template;
name = kasprintf(GFP_KERNEL, "%s %s", ctrl_name,
"Autodisable");
if (!name) {
ret = -ENOMEM;
goto err_data;
}
memset(&template, 0, sizeof(template));
template.reg = e->reg;
template.mask = e->mask << e->shift_l;
template.shift = e->shift_l;
template.off_val = snd_soc_enum_item_to_val(e, 0);
template.on_val = template.off_val;
template.id = snd_soc_dapm_kcontrol;
template.name = name;
data->value = template.on_val;
data->widget = snd_soc_dapm_new_control_unlocked(
widget->dapm, &template);
kfree(name);
if (!data->widget) {
ret = -ENOMEM;
goto err_data;
}
snd_soc_dapm_add_path(widget->dapm, data->widget,
widget, NULL, NULL);
}
break;
default:
break;
}
kcontrol->private_data = data;
return 0;
err_data:
kfree(data);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 262 | 53.91% | 9 | 69.23% |
charles keepax | charles keepax | 223 | 45.88% | 3 | 23.08% |
liam girdwood | liam girdwood | 1 | 0.21% | 1 | 7.69% |
| Total | 486 | 100.00% | 13 | 100.00% |
static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl);
kfree(data->wlist);
kfree(data);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 33 | 100.00% | 2 | 100.00% |
| Total | 33 | 100.00% | 2 | 100.00% |
static struct snd_soc_dapm_widget_list *dapm_kcontrol_get_wlist(
const struct snd_kcontrol *kcontrol)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
return data->wlist;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 29 | 100.00% | 2 | 100.00% |
| Total | 29 | 100.00% | 2 | 100.00% |
static int dapm_kcontrol_add_widget(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_widget *widget)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
struct snd_soc_dapm_widget_list *new_wlist;
unsigned int n;
if (data->wlist)
n = data->wlist->num_widgets + 1;
else
n = 1;
new_wlist = krealloc(data->wlist,
sizeof(*new_wlist) + sizeof(widget) * n, GFP_KERNEL);
if (!new_wlist)
return -ENOMEM;
new_wlist->widgets[n - 1] = widget;
new_wlist->num_widgets = n;
data->wlist = new_wlist;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 115 | 100.00% | 3 | 100.00% |
| Total | 115 | 100.00% | 3 | 100.00% |
static void dapm_kcontrol_add_path(const struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_path *path)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
list_add_tail(&path->list_kcontrol, &data->paths);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 40 | 100.00% | 2 | 100.00% |
| Total | 40 | 100.00% | 2 | 100.00% |
static bool dapm_kcontrol_is_powered(const struct snd_kcontrol *kcontrol)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
if (!data->widget)
return true;
return data->widget->power;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 39 | 100.00% | 2 | 100.00% |
| Total | 39 | 100.00% | 2 | 100.00% |
static struct list_head *dapm_kcontrol_get_path_list(
const struct snd_kcontrol *kcontrol)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
return &data->paths;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 30 | 100.00% | 1 | 100.00% |
| Total | 30 | 100.00% | 1 | 100.00% |
#define dapm_kcontrol_for_each_path(path, kcontrol) \
list_for_each_entry(path, dapm_kcontrol_get_path_list(kcontrol), \
list_kcontrol)
unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
return data->value;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 27 | 100.00% | 1 | 100.00% |
| Total | 27 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(dapm_kcontrol_get_value);
static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
unsigned int value)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
if (data->value == value)
return false;
if (data->widget)
data->widget->on_val = value;
data->value = value;
return true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 60 | 100.00% | 2 | 100.00% |
| Total | 60 | 100.00% | 2 | 100.00% |
/**
* snd_soc_dapm_kcontrol_widget() - Returns the widget associated to a
* kcontrol
* @kcontrol: The kcontrol
*/
struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(
struct snd_kcontrol *kcontrol)
{
return dapm_kcontrol_get_wlist(kcontrol)->widgets[0];
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mythri p k | mythri p k | 23 | 100.00% | 1 | 100.00% |
| Total | 23 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_widget);
/**
* snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a
* kcontrol
* @kcontrol: The kcontrol
*
* Note: This function must only be used on kcontrols that are known to have
* been registered for a CODEC. Otherwise the behaviour is undefined.
*/
struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
struct snd_kcontrol *kcontrol)
{
return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->dapm;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 25 | 100.00% | 3 | 100.00% |
| Total | 25 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_dapm);
static void dapm_reset(struct snd_soc_card *card)
{
struct snd_soc_dapm_widget *w;
lockdep_assert_held(&card->dapm_mutex);
memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
list_for_each_entry(w, &card->widgets, list) {
w->new_power = w->power;
w->power_checked = false;
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
liam girdwood | liam girdwood | 49 | 75.38% | 1 | 33.33% |
lars-peter clausen | lars-peter clausen | 8 | 12.31% | 1 | 33.33% |
mark brown | mark brown | 8 | 12.31% | 1 | 33.33% |
| Total | 65 | 100.00% | 3 | 100.00% |
static const char *soc_dapm_prefix(struct snd_soc_dapm_context *dapm)
{
if (!dapm->component)
return NULL;
return dapm->component->name_prefix;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 30 | 100.00% | 1 | 100.00% |
| Total | 30 | 100.00% | 1 | 100.00% |
static int soc_dapm_read(struct snd_soc_dapm_context *dapm, int reg,
unsigned int *value)
{
if (!dapm->component)
return -EIO;
return snd_soc_component_read(dapm->component, reg, value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
liam girdwood | liam girdwood | 22 | 52.38% | 2 | 40.00% |
lars-peter clausen | lars-peter clausen | 14 | 33.33% | 2 | 40.00% |
arun shamanna lakshmi | arun shamanna lakshmi | 6 | 14.29% | 1 | 20.00% |
| Total | 42 | 100.00% | 5 | 100.00% |
static int soc_dapm_update_bits(struct snd_soc_dapm_context *dapm,
int reg, unsigned int mask, unsigned int value)
{
if (!dapm->component)
return -EIO;
return snd_soc_component_update_bits(dapm->component, reg,
mask, value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 27 | 57.45% | 3 | 50.00% |
liam girdwood | liam girdwood | 19 | 40.43% | 2 | 33.33% |
mark brown | mark brown | 1 | 2.13% | 1 | 16.67% |
| Total | 47 | 100.00% | 6 | 100.00% |
static int soc_dapm_test_bits(struct snd_soc_dapm_context *dapm,
int reg, unsigned int mask, unsigned int value)
{
if (!dapm->component)
return -EIO;
return snd_soc_component_test_bits(dapm->component, reg, mask, value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 39 | 82.98% | 2 | 50.00% |
liam girdwood | liam girdwood | 8 | 17.02% | 2 | 50.00% |
| Total | 47 | 100.00% | 4 | 100.00% |
static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
{
if (dapm->component)
snd_soc_component_async_complete(dapm->component);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 20 | 83.33% | 2 | 50.00% |
lars-peter clausen | lars-peter clausen | 3 | 12.50% | 1 | 25.00% |
liam girdwood | liam girdwood | 1 | 4.17% | 1 | 25.00% |
| Total | 24 | 100.00% | 4 | 100.00% |
static struct snd_soc_dapm_widget *
dapm_wcache_lookup(struct snd_soc_dapm_wcache *wcache, const char *name)
{
struct snd_soc_dapm_widget *w = wcache->widget;
struct list_head *wlist;
const int depth = 2;
int i = 0;
if (w) {
wlist = &w->dapm->card->widgets;
list_for_each_entry_from(w, wlist, list) {
if (!strcmp(name, w->name))
return w;
if (++i == depth)
break;
}
}
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
charles keepax | charles keepax | 96 | 100.00% | 1 | 100.00% |
| Total | 96 | 100.00% | 1 | 100.00% |
static inline void dapm_wcache_update(struct snd_soc_dapm_wcache *wcache,
struct snd_soc_dapm_widget *w)
{
wcache->widget = w;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
charles keepax | charles keepax | 14 | 60.87% | 1 | 25.00% |
lars-peter clausen | lars-peter clausen | 8 | 34.78% | 2 | 50.00% |
liam girdwood | liam girdwood | 1 | 4.35% | 1 | 25.00% |
| Total | 23 | 100.00% | 4 | 100.00% |
/**
* snd_soc_dapm_force_bias_level() - Sets the DAPM bias level
* @dapm: The DAPM context for which to set the level
* @level: The level to set
*
* Forces the DAPM bias level to a specific state. It will call the bias level
* callback of DAPM context with the specified level. This will even happen if
* the context is already at the same level. Furthermore it will not go through
* the normal bias level sequencing, meaning any intermediate states between the
* current and the target state will not be entered.
*
* Note that the change in bias level is only temporary and the next time
* snd_soc_dapm_sync() is called the state will be set to the level as
* determined by the DAPM core. The function is mainly intended to be used to
* used during probe or resume from suspend to power up the device so
* initialization can be done, before the DAPM core takes over.
*/
int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level)
{
int ret = 0;
if (dapm->set_bias_level)
ret = dapm->set_bias_level(dapm, level);
if (ret == 0)
dapm->bias_level = level;
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 34 | 66.67% | 2 | 40.00% |
mark brown | mark brown | 16 | 31.37% | 2 | 40.00% |
liam girdwood | liam girdwood | 1 | 1.96% | 1 | 20.00% |
| Total | 51 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL_GPL(snd_soc_dapm_force_bias_level);
/**
* snd_soc_dapm_set_bias_level - set the bias level for the system
* @dapm: DAPM context
* @level: level to configure
*
* Configure the bias (power) levels for the SoC audio device.
*
* Returns 0 for success else error.
*/
static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level)
{
struct snd_soc_card *card = dapm->card;
int ret = 0;
trace_snd_soc_bias_level_start(card, level);
if (card && card->set_bias_level)
ret = card->set_bias_level(card, dapm, level);
if (ret != 0)
goto out;
if (!card || dapm != &card->dapm)
ret = snd_soc_dapm_force_bias_level(dapm, level);
if (ret != 0)
goto out;
if (card && card->set_bias_level_post)
ret = card->set_bias_level_post(card, dapm, level);
out:
trace_snd_soc_bias_level_done(card, level);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 113 | 87.60% | 8 | 72.73% |
liam girdwood | liam girdwood | 10 | 7.75% | 2 | 18.18% |
lars-peter clausen | lars-peter clausen | 6 | 4.65% | 1 | 9.09% |
| Total | 129 | 100.00% | 11 | 100.00% |
/* connect mux widget to its interconnecting audio paths */
static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_path *path, const char *control_name,
struct snd_soc_dapm_widget *w)
{
const struct snd_kcontrol_new *kcontrol = &w->kcontrol_news[0];
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val, item;
int i;
if (e->reg != SND_SOC_NOPM) {
soc_dapm_read(dapm, e->reg, &val);
val = (val >> e->shift_l) & e->mask;
item = snd_soc_enum_val_to_item(e, val);
} else {
/* since a virtual mux has no backing registers to
* decide which path to connect, it will try to match
* with the first enumeration. This is to ensure
* that the default mux choice (the first) will be
* correctly powered up during initialization.
*/
item = 0;
}
for (i = 0; i < e->items; i++) {
if (!(strcmp(control_name, e->texts[i]))) {
path->name = e->texts[i];
if (i == item)
path->connect = 1;
else
path->connect = 0;
return 0;
}
}
return -ENODEV;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
richard purdie | richard purdie | 96 | 50.79% | 1 | 6.67% |
lars-peter clausen | lars-peter clausen | 65 | 34.39% | 7 | 46.67% |
dimitris papastamos | dimitris papastamos | 12 | 6.35% | 1 | 6.67% |
jon smirl | jon smirl | 9 | 4.76% | 2 | 13.33% |
arun shamanna lakshmi | arun shamanna lakshmi | 3 | 1.59% | 1 | 6.67% |
liam girdwood | liam girdwood | 2 | 1.06% | 1 | 6.67% |
benoit thebaudeau | benoit thebaudeau | 1 | 0.53% | 1 | 6.67% |
takashi iwai | takashi iwai | 1 | 0.53% | 1 | 6.67% |
| Total | 189 | 100.00% | 15 | 100.00% |
/* set up initial codec paths */
static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i)
{
struct soc_mixer_control *mc = (struct soc_mixer_control *)
p->sink->kcontrol_news[