cregit-Linux how code gets into the kernel

Release 4.7 sound/soc/soc-dapm.c

Directory: sound/soc
/*
 * 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

PersonTokensPropCommitsCommitProp
mark brownmark brown33100.00%1100.00%
Total33100.00%1100.00%


static void pop_wait(u32 pop_time) { if (pop_time) schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown1990.48%150.00%
troy kiskytroy kisky29.52%150.00%
Total21100.00%2100.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

PersonTokensPropCommitsCommitProp
jarkko nikulajarkko nikula4855.17%125.00%
mark brownmark brown3439.08%125.00%
troy kiskytroy kisky33.45%125.00%
takashi iwaitakashi iwai22.30%125.00%
Total87100.00%4100.00%


static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w) { return !list_empty(&w->dirty); }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown21100.00%1100.00%
Total21100.00%1100.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

PersonTokensPropCommitsCommitProp
mark brownmark brown67100.00%4100.00%
Total67100.00%4100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen161100.00%3100.00%
Total161100.00%3100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen18100.00%2100.00%
Total18100.00%2100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen18100.00%2100.00%
Total18100.00%2100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen64100.00%2100.00%
Total64100.00%2100.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

PersonTokensPropCommitsCommitProp
mark brownmark brown4858.54%125.00%
lars-peter clausenlars-peter clausen3441.46%375.00%
Total82100.00%4100.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

PersonTokensPropCommitsCommitProp
richard purdierichard purdie2379.31%150.00%
takashi iwaitakashi iwai620.69%150.00%
Total29100.00%2100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen26253.91%969.23%
charles keepaxcharles keepax22345.88%323.08%
liam girdwoodliam girdwood10.21%17.69%
Total486100.00%13100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen33100.00%2100.00%
Total33100.00%2100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen29100.00%2100.00%
Total29100.00%2100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen115100.00%3100.00%
Total115100.00%3100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen40100.00%2100.00%
Total40100.00%2100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen39100.00%2100.00%
Total39100.00%2100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen30100.00%1100.00%
Total30100.00%1100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen27100.00%1100.00%
Total27100.00%1100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen60100.00%2100.00%
Total60100.00%2100.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

PersonTokensPropCommitsCommitProp
mythri p kmythri p k23100.00%1100.00%
Total23100.00%1100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen25100.00%3100.00%
Total25100.00%3100.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

PersonTokensPropCommitsCommitProp
liam girdwoodliam girdwood4975.38%133.33%
lars-peter clausenlars-peter clausen812.31%133.33%
mark brownmark brown812.31%133.33%
Total65100.00%3100.00%


static const char *soc_dapm_prefix(struct snd_soc_dapm_context *dapm) { if (!dapm->component) return NULL; return dapm->component->name_prefix; }

Contributors

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen30100.00%1100.00%
Total30100.00%1100.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

PersonTokensPropCommitsCommitProp
liam girdwoodliam girdwood2252.38%240.00%
lars-peter clausenlars-peter clausen1433.33%240.00%
arun shamanna lakshmiarun shamanna lakshmi614.29%120.00%
Total42100.00%5100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen2757.45%350.00%
liam girdwoodliam girdwood1940.43%233.33%
mark brownmark brown12.13%116.67%
Total47100.00%6100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen3982.98%250.00%
liam girdwoodliam girdwood817.02%250.00%
Total47100.00%4100.00%


static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) { if (dapm->component) snd_soc_component_async_complete(dapm->component); }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown2083.33%250.00%
lars-peter clausenlars-peter clausen312.50%125.00%
liam girdwoodliam girdwood14.17%125.00%
Total24100.00%4100.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

PersonTokensPropCommitsCommitProp
charles keepaxcharles keepax96100.00%1100.00%
Total96100.00%1100.00%


static inline void dapm_wcache_update(struct snd_soc_dapm_wcache *wcache, struct snd_soc_dapm_widget *w) { wcache->widget = w; }

Contributors

PersonTokensPropCommitsCommitProp
charles keepaxcharles keepax1460.87%125.00%
lars-peter clausenlars-peter clausen834.78%250.00%
liam girdwoodliam girdwood14.35%125.00%
Total23100.00%4100.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

PersonTokensPropCommitsCommitProp
lars-peter clausenlars-peter clausen3466.67%240.00%
mark brownmark brown1631.37%240.00%
liam girdwoodliam girdwood11.96%120.00%
Total51100.00%5100.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

PersonTokensPropCommitsCommitProp
mark brownmark brown11387.60%872.73%
liam girdwoodliam girdwood107.75%218.18%
lars-peter clausenlars-peter clausen64.65%19.09%
Total129100.00%11100.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

PersonTokensPropCommitsCommitProp
richard purdierichard purdie9650.79%16.67%
lars-peter clausenlars-peter clausen6534.39%746.67%
dimitris papastamosdimitris papastamos126.35%16.67%
jon smirljon smirl94.76%213.33%
arun shamanna lakshmiarun shamanna lakshmi31.59%16.67%
liam girdwoodliam girdwood21.06%16.67%
benoit thebaudeaubenoit thebaudeau10.53%16.67%
takashi iwaitakashi iwai10.53%16.67%
Total189100.00%15100.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[