Release 4.7 sound/soc/soc-core.c
/*
* soc-core.c -- ALSA SoC Audio Layer
*
* Copyright 2005 Wolfson Microelectronics PLC.
* Copyright 2005 Openedhand Ltd.
* Copyright (C) 2010 Slimlogic Ltd.
* Copyright (C) 2010 Texas Instruments Inc.
*
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
* with code, comments and ideas from :-
* Richard Purdie <richard@openedhand.com>
*
* 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.
*
* TODO:
* o Add hw rules to enforce rates, etc.
* o More testing with other codecs/machines.
* o Add more codecs and platforms to ensure good API coverage.
* o Support TDM on PCM and I2S
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dpcm.h>
#include <sound/soc-topology.h>
#include <sound/initval.h>
#define CREATE_TRACE_POINTS
#include <trace/events/asoc.h>
#define NAME_SIZE 32
#ifdef CONFIG_DEBUG_FS
struct dentry *snd_soc_debugfs_root;
EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
#endif
static DEFINE_MUTEX(client_mutex);
static LIST_HEAD(platform_list);
static LIST_HEAD(codec_list);
static LIST_HEAD(component_list);
/*
* This is a timeout to do a DAPM powerdown after a stream is closed().
* It can be used to eliminate pops between different playback streams, e.g.
* between two audio tracks.
*/
static int pmdown_time = 5000;
module_param(pmdown_time, int, 0);
MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
/* returns the minimum number of bytes needed to represent
* a particular given value */
static int min_bytes_needed(unsigned long val)
{
int c = 0;
int i;
for (i = (sizeof val * 8) - 1; i >= 0; --i, ++c)
if (val & (1UL << i))
break;
c = (sizeof val * 8) - c;
if (!c || (c % 8))
c = (c + 8) / 8;
else
c /= 8;
return c;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dimitris papastamos | dimitris papastamos | 92 | 100.00% | 1 | 100.00% |
| Total | 92 | 100.00% | 1 | 100.00% |
/* fill buf which is 'len' bytes with a formatted
* string of the form 'reg: value\n' */
static int format_register_str(struct snd_soc_codec *codec,
unsigned int reg, char *buf, size_t len)
{
int wordsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
int regsize = codec->driver->reg_word_size * 2;
int ret;
/* +2 for ': ' and + 1 for '\n' */
if (wordsize + regsize + 2 + 1 != len)
return -EINVAL;
sprintf(buf, "%.*x: ", wordsize, reg);
buf += wordsize + 2;
ret = snd_soc_read(codec, reg);
if (ret < 0)
memset(buf, 'X', regsize);
else
sprintf(buf, "%.*x", regsize, ret);
buf[regsize] = '\n';
/* no NUL-termination needed */
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dimitris papastamos | dimitris papastamos | 100 | 76.34% | 1 | 33.33% |
takashi iwai | takashi iwai | 26 | 19.85% | 1 | 33.33% |
stephen warren | stephen warren | 5 | 3.82% | 1 | 33.33% |
| Total | 131 | 100.00% | 3 | 100.00% |
/* codec register dump */
static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
size_t count, loff_t pos)
{
int i, step = 1;
int wordsize, regsize;
int len;
size_t total = 0;
loff_t p = 0;
wordsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
regsize = codec->driver->reg_word_size * 2;
len = wordsize + regsize + 2 + 1;
if (!codec->driver->reg_cache_size)
return 0;
if (codec->driver->reg_cache_step)
step = codec->driver->reg_cache_step;
for (i = 0; i < codec->driver->reg_cache_size; i += step) {
/* only support larger than PAGE_SIZE bytes debugfs
* entries for the default case */
if (p >= pos) {
if (total + len >= count - 1)
break;
format_register_str(codec, i, buf + total, len);
total += len;
}
p += len;
}
total = min(total, count - 1);
return total;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dimitris papastamos | dimitris papastamos | 83 | 45.60% | 2 | 25.00% |
mark brown | mark brown | 51 | 28.02% | 2 | 25.00% |
frank mandarino | frank mandarino | 34 | 18.68% | 1 | 12.50% |
liam girdwood | liam girdwood | 8 | 4.40% | 1 | 12.50% |
stephen warren | stephen warren | 5 | 2.75% | 1 | 12.50% |
lars-peter clausen | lars-peter clausen | 1 | 0.55% | 1 | 12.50% |
| Total | 182 | 100.00% | 8 | 100.00% |
static ssize_t codec_reg_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 37 | 84.09% | 3 | 60.00% |
dimitris papastamos | dimitris papastamos | 4 | 9.09% | 1 | 20.00% |
liam girdwood | liam girdwood | 3 | 6.82% | 1 | 20.00% |
| Total | 44 | 100.00% | 5 | 100.00% |
static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
static ssize_t pmdown_time_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
return sprintf(buf, "%ld\n", rtd->pmdown_time);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 39 | 92.86% | 3 | 75.00% |
liam girdwood | liam girdwood | 3 | 7.14% | 1 | 25.00% |
| Total | 42 | 100.00% | 4 | 100.00% |
static ssize_t pmdown_time_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
int ret;
ret = kstrtol(buf, 10, &rtd->pmdown_time);
if (ret)
return ret;
return count;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 57 | 93.44% | 3 | 60.00% |
liam girdwood | liam girdwood | 3 | 4.92% | 1 | 20.00% |
jingoo han | jingoo han | 1 | 1.64% | 1 | 20.00% |
| Total | 61 | 100.00% | 5 | 100.00% |
static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set);
static struct attribute *soc_dev_attrs[] = {
&dev_attr_codec_reg.attr,
&dev_attr_pmdown_time.attr,
NULL
};
static umode_t soc_dev_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int idx)
{
struct device *dev = kobj_to_dev(kobj);
struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
if (attr == &dev_attr_pmdown_time.attr)
return attr->mode; /* always visible */
return rtd->codec ? attr->mode : 0; /* enabled only with codec */
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
takashi iwai | takashi iwai | 66 | 100.00% | 1 | 100.00% |
| Total | 66 | 100.00% | 1 | 100.00% |
static const struct attribute_group soc_dapm_dev_group = {
.attrs = soc_dapm_dev_attrs,
.is_visible = soc_dev_attr_is_visible,
};
static const struct attribute_group soc_dev_roup = {
.attrs = soc_dev_attrs,
.is_visible = soc_dev_attr_is_visible,
};
static const struct attribute_group *soc_dev_attr_groups[] = {
&soc_dapm_dev_group,
&soc_dev_roup,
NULL
};
#ifdef CONFIG_DEBUG_FS
static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
ssize_t ret;
struct snd_soc_codec *codec = file->private_data;
char *buf;
if (*ppos < 0 || !count)
return -EINVAL;
buf = kmalloc(count, GFP_KERNEL);
if (!buf)
return -ENOMEM;
ret = soc_codec_reg_show(codec, buf, count, *ppos);
if (ret >= 0) {
if (copy_to_user(user_buf, buf, ret)) {
kfree(buf);
return -EFAULT;
}
*ppos += ret;
}
kfree(buf);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 83 | 64.84% | 2 | 66.67% |
dimitris papastamos | dimitris papastamos | 45 | 35.16% | 1 | 33.33% |
| Total | 128 | 100.00% | 3 | 100.00% |
static ssize_t codec_reg_write_file(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
char buf[32];
size_t buf_size;
char *start = buf;
unsigned long reg, value;
struct snd_soc_codec *codec = file->private_data;
int ret;
buf_size = min(count, (sizeof(buf)-1));
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
buf[buf_size] = 0;
while (*start == ' ')
start++;
reg = simple_strtoul(start, &start, 16);
while (*start == ' ')
start++;
ret = kstrtoul(start, 16, &value);
if (ret)
return ret;
/* Userspace has been fiddling around behind the kernel's back */
add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
snd_soc_write(codec, reg, value);
return buf_size;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 117 | 70.48% | 4 | 40.00% |
frank mandarino | frank mandarino | 22 | 13.25% | 1 | 10.00% |
liam girdwood | liam girdwood | 12 | 7.23% | 1 | 10.00% |
jingoo han | jingoo han | 11 | 6.63% | 1 | 10.00% |
rusty russell | rusty russell | 2 | 1.20% | 1 | 10.00% |
dimitris papastamos | dimitris papastamos | 1 | 0.60% | 1 | 10.00% |
stephen boyd | stephen boyd | 1 | 0.60% | 1 | 10.00% |
| Total | 166 | 100.00% | 10 | 100.00% |
static const struct file_operations codec_reg_fops = {
.open = simple_open,
.read = codec_reg_read_file,
.write = codec_reg_write_file,
.llseek = default_llseek,
};
static void soc_init_component_debugfs(struct snd_soc_component *component)
{
if (!component->card->debugfs_card_root)
return;
if (component->debugfs_prefix) {
char *name;
name = kasprintf(GFP_KERNEL, "%s:%s",
component->debugfs_prefix, component->name);
if (name) {
component->debugfs_root = debugfs_create_dir(name,
component->card->debugfs_card_root);
kfree(name);
}
} else {
component->debugfs_root = debugfs_create_dir(component->name,
component->card->debugfs_card_root);
}
if (!component->debugfs_root) {
dev_warn(component->dev,
"ASoC: Failed to create component debugfs directory\n");
return;
}
snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component),
component->debugfs_root);
if (component->init_debugfs)
component->init_debugfs(component);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 73 | 52.14% | 5 | 41.67% |
russell king | russell king | 30 | 21.43% | 1 | 8.33% |
mark brown | mark brown | 15 | 10.71% | 3 | 25.00% |
liam girdwood | liam girdwood | 12 | 8.57% | 2 | 16.67% |
frank mandarino | frank mandarino | 10 | 7.14% | 1 | 8.33% |
| Total | 140 | 100.00% | 12 | 100.00% |
static void soc_cleanup_component_debugfs(struct snd_soc_component *component)
{
debugfs_remove_recursive(component->debugfs_root);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 9 | 50.00% | 1 | 25.00% |
lars-peter clausen | lars-peter clausen | 5 | 27.78% | 1 | 25.00% |
frank mandarino | frank mandarino | 3 | 16.67% | 1 | 25.00% |
liam girdwood | liam girdwood | 1 | 5.56% | 1 | 25.00% |
| Total | 18 | 100.00% | 4 | 100.00% |
static void soc_init_codec_debugfs(struct snd_soc_component *component)
{
struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
codec->component.debugfs_root,
codec, &codec_reg_fops);
if (!codec->debugfs_reg)
dev_warn(codec->dev,
"ASoC: Failed to create codec register debugfs file\n");
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
sebastien guiriec | sebastien guiriec | 31 | 52.54% | 1 | 20.00% |
lars-peter clausen | lars-peter clausen | 26 | 44.07% | 3 | 60.00% |
russell king | russell king | 2 | 3.39% | 1 | 20.00% |
| Total | 59 | 100.00% | 5 | 100.00% |
static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
ssize_t len, ret = 0;
struct snd_soc_codec *codec;
if (!buf)
return -ENOMEM;
mutex_lock(&client_mutex);
list_for_each_entry(codec, &codec_list, list) {
len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
codec->component.name);
if (len >= 0)
ret += len;
if (ret > PAGE_SIZE) {
ret = PAGE_SIZE;
break;
}
}
mutex_unlock(&client_mutex);
if (ret >= 0)
ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
kfree(buf);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 133 | 88.67% | 2 | 40.00% |
lars-peter clausen | lars-peter clausen | 14 | 9.33% | 2 | 40.00% |
sebastien guiriec | sebastien guiriec | 3 | 2.00% | 1 | 20.00% |
| Total | 150 | 100.00% | 5 | 100.00% |
static const struct file_operations codec_list_fops = {
.read = codec_list_read_file,
.llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
ssize_t len, ret = 0;
struct snd_soc_component *component;
struct snd_soc_dai *dai;
if (!buf)
return -ENOMEM;
mutex_lock(&client_mutex);
list_for_each_entry(component, &component_list, list) {
list_for_each_entry(dai, &component->dai_list, list) {
len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
dai->name);
if (len >= 0)
ret += len;
if (ret > PAGE_SIZE) {
ret = PAGE_SIZE;
break;
}
}
}
mutex_unlock(&client_mutex);
ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
kfree(buf);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 129 | 82.17% | 2 | 50.00% |
lars-peter clausen | lars-peter clausen | 28 | 17.83% | 2 | 50.00% |
| Total | 157 | 100.00% | 4 | 100.00% |
static const struct file_operations dai_list_fops = {
.read = dai_list_read_file,
.llseek = default_llseek,/* read accesses f_pos */
};
static ssize_t platform_list_read_file(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
ssize_t len, ret = 0;
struct snd_soc_platform *platform;
if (!buf)
return -ENOMEM;
mutex_lock(&client_mutex);
list_for_each_entry(platform, &platform_list, list) {
len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
platform->component.name);
if (len >= 0)
ret += len;
if (ret > PAGE_SIZE) {
ret = PAGE_SIZE;
break;
}
}
mutex_unlock(&client_mutex);
ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
kfree(buf);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mark brown | mark brown | 130 | 90.28% | 2 | 50.00% |
lars-peter clausen | lars-peter clausen | 14 | 9.72% | 2 | 50.00% |
| Total | 144 | 100.00% | 4 | 100.00% |
static const struct file_operations platform_list_fops = {
.read = platform_list_read_file,
.llseek = default_llseek,/* read accesses f_pos */
};
static void soc_init_card_debugfs(struct snd_soc_card *card)
{
if (!snd_soc_debugfs_root)
return;
card->debugfs_card_root = debugfs_create_dir(card->name,
snd_soc_debugfs_root);
if (!card->debugfs_card_root) {
dev_warn(card->dev,
"ASoC: Failed to create card debugfs directory\n");
return;
}
card->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
card->debugfs_card_root,
&card->pop_time);
if (!card->debugfs_pop_time)
dev_warn(card->dev,
"ASoC: Failed to create pop time debugfs file\n");
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jarkko nikula | jarkko nikula | 76 | 89.41% | 2 | 33.33% |
lars-peter clausen | lars-peter clausen | 6 | 7.06% | 1 | 16.67% |
mark brown | mark brown | 1 | 1.18% | 1 | 16.67% |
liam girdwood | liam girdwood | 1 | 1.18% | 1 | 16.67% |
lothar wassmann | lothar wassmann | 1 | 1.18% | 1 | 16.67% |
| Total | 85 | 100.00% | 6 | 100.00% |
static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
{
debugfs_remove_recursive(card->debugfs_card_root);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jarkko nikula | jarkko nikula | 18 | 100.00% | 1 | 100.00% |
| Total | 18 | 100.00% | 1 | 100.00% |
static void snd_soc_debugfs_init(void)
{
snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
pr_warn("ASoC: Failed to create debugfs directory\n");
snd_soc_debugfs_root = NULL;
return;
}
if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
&codec_list_fops))
pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
&dai_list_fops))
pr_warn("ASoC: Failed to create DAI list debugfs file\n");
if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
&platform_list_fops))
pr_warn("ASoC: Failed to create platform list debugfs file\n");
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 105 | 100.00% | 1 | 100.00% |
| Total | 105 | 100.00% | 1 | 100.00% |
static void snd_soc_debugfs_exit(void)
{
debugfs_remove_recursive(snd_soc_debugfs_root);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 13 | 100.00% | 1 | 100.00% |
| Total | 13 | 100.00% | 1 | 100.00% |
#else
#define soc_init_codec_debugfs NULL
static inline void soc_init_component_debugfs(
struct snd_soc_component *component)
{
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
sebastien guiriec | sebastien guiriec | 8 | 72.73% | 1 | 50.00% |
lars-peter clausen | lars-peter clausen | 3 | 27.27% | 1 | 50.00% |
| Total | 11 | 100.00% | 2 | 100.00% |
static inline void soc_cleanup_component_debugfs(
struct snd_soc_component *component)
{
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
sebastien guiriec | sebastien guiriec | 8 | 72.73% | 1 | 50.00% |
lars-peter clausen | lars-peter clausen | 3 | 27.27% | 1 | 50.00% |
| Total | 11 | 100.00% | 2 | 100.00% |
static inline void soc_init_card_debugfs(struct snd_soc_card *card)
{
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
axel lin | axel lin | 11 | 100.00% | 1 | 100.00% |
| Total | 11 | 100.00% | 1 | 100.00% |
static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card)
{
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
axel lin | axel lin | 11 | 100.00% | 1 | 100.00% |
| Total | 11 | 100.00% | 1 | 100.00% |
static inline void snd_soc_debugfs_init(void)
{
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 8 | 100.00% | 1 | 100.00% |
| Total | 8 | 100.00% | 1 | 100.00% |
static inline void snd_soc_debugfs_exit(void)
{
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lars-peter clausen | lars-peter clausen | 8 | 100.00% | 1 | 100.00% |
| Total | 8 | 100.00% | 1 | 100.00% |
#endif
struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
const char *dai_link, int stream)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (rtd->dai_link->no_pcm &&
!strcmp(rtd->dai_link->name, dai_link))
return rtd->pcm->streams[stream].substream;
}
dev_dbg(card->dev, "ASoC: failed to find dai link %s\n", dai_link);
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
liam girdwood | liam girdwood | 66 | 81.48% | 2 | 66.67% |
mengdong lin | mengdong lin | 15 | 18.52% | 1 | 33.33% |
| Total | 81 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream);
static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
{
struct snd_soc_pcm_runtime *rtd;
rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL);
if (!rtd)
return NULL;
rtd->card = card;
rtd->dai_link = dai_link;
rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) *
dai_link->num_codecs,
GFP_KERNEL);
if (!rtd->codec_dais) {
kfree(rtd);
return NULL;
}
return rtd;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mengdong lin | mengdong lin | 62 | 64.58% | 1 | 50.00% |
liam girdwood | liam girdwood | 34 | 35.42% | 1 | 50.00% |
| Total | 96 | 100.00% | 2 | 100.00% |
static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
{
if (rtd && rtd->codec_dais)
kfree(rtd->codec_dais);
kfree(rtd);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mengdong lin | mengdong lin | 23 | 74.19% | 1 | 50.00% |
richard fitzgerald | richard fitzgerald | 8 | 25.81% | 1 | 50.00% |
| Total | 31 | 100.00% | 2 | 100.00% |
static void soc_add_pcm_runtime(struct snd_soc_card *card,
struct snd_soc_pcm_runtime *rtd)
{
list_add_tail(&rtd->list, &card->rtd_list);
rtd->num = card->num_rtd;
card->num_rtd++;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mengdong lin | mengdong lin | 29 | 69.05% | 1 | 14.29% |
mark brown | mark brown | 5 | 11.90% | 2 | 28.57% |
liam girdwood | liam girdwood | 4 | 9.52% | 2 | 28.57% |
frank mandarino | frank mandarino | 3 | 7.14% | 1 | 14.29% |
andrew morton | andrew morton | 1 | 2.38% | 1 | 14.29% |
| Total | 42 | 100.00% | 7 | 100.00% |
static void soc_remove_pcm_runtimes(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd, *_rtd;
list_for_each_entry_safe(rtd, _rtd, &card->rtd_list, list) {
list_del(&rtd->list);
soc_free_pcm_runtime(rtd);
}
card->num_rtd = 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mengdong lin | mengdong lin | 50 | 100.00% | 1 | 100.00% |
| Total | 50 | 100.00% | 1 | 100.00% |
struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
const char *dai_link)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strcmp(rtd->dai_link->name, dai_link))
return rtd;
}
dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link);
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
liam girdwood | liam girdwood | 33 | 52.38% | 2 | 66.67% |
mengdong lin | mengdong lin | 30 | 47.62% | 1 | 33.33% |
| Total | 63 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime);
static void codec2codec_close_delayed_work(struct work_struct *work)
{
/* Currently nothing to do for c2c links
* Since c2c links are internal nodes in the DAPM graph and
* don't interface with the outside world or application layer
* we don't have to do any special handling on close.
*/
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
richard fitzgerald | richard fitzgerald | 12 | 100.00% | 1 | 100.00% |
| Total | 12 | 100.00% | 1 | 100.00% |
#ifdef CONFIG_PM_SLEEP
/* powers down audio subsystem for suspend */
int snd_soc_suspend(struct device *dev)
{
struct snd_soc_card *card = dev_get_drvdata(dev);
struct snd_soc_codec *codec;
struct snd_soc_pcm_runtime *rtd;
int i;
/* If the card is not initialized yet there is nothing to do */
if (!card->instantiated)
return 0;
/* Due to the resume being scheduled into a workqueue we could
* suspend before that's finished - wait for it to complete.
*/
snd_power_lock(card->snd_card);
snd_power_wait(card->snd_card, SNDRV_CTL_POWER_D0);
snd_power_unlock(card->snd_card);
/* we're going to block userspace touching us until resume completes */
snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
/* mute any active DACs */
list_for_each_entry(rtd, &card->rtd_list, list) {
if (rtd->dai_link->ignore_suspend)
continue;
for (i = 0; i < rtd->num_codecs; i++) {
struct snd_soc_dai *dai = rtd->codec_dais[i];
struct snd_soc_dai_driver *drv = dai->driver;
if (drv->ops->digital_mute && dai->playback_active)
drv->ops->digital_mute(dai, 1);
}
}
/* suspend all pcms */
list_for_each_entry(rtd, &card->rtd_list, list) {
if (rtd->dai_link->ignore_suspend)
continue;
snd_pcm_suspend_all(rtd->pcm);
}
if (card->suspend_pre)
card->suspend_pre(card);
list_for_each_entry(rtd, &card->rtd_list, list) {
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
if (rtd->dai_link->ignore_suspend)
continue;
if (cpu_dai->driver->suspend && !cpu_dai->driver->bus_control)
cpu_dai->driver->suspend(cpu_dai);
}
/* close any waiting streams */