1
0
Fork 0

Merge series "ASoC: soc-dai: add snd_soc_dai_xxx()" from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

We have soc-dai.c today. DAI related functions
should be implemented in it.
These patches are v2 of doing it.

Link: https://lore.kernel.org/r/871rofunaq.wl-kuninori.morimoto.gx@renesas.com

Kuninori Morimoto (17):
  ASoC: soc-dai: add soc_dai_err()
  ASoC: soc-dai: don't overwide dai->driver->ops
  ASoC: soc-dai: add snd_soc_pcm_dai_new()
  ASoC: soc-dai: add snd_soc_pcm_dai_prepare()
  ASoC: soc-dai: add snd_soc_pcm_dai_trigger()
  ASoC: soc-dai: add snd_soc_pcm_dai_bespoke_trigger()
  ASoC: soc-dai: add snd_soc_pcm_dai_probe()
  ASoC: soc-dai: add snd_soc_pcm_dai_remove()
  ASoC: soc-dai: add snd_soc_dai_compr_start()
  ASoC: soc-dai: add snd_soc_dai_compr_shutdown()
  ASoC: soc-dai: add snd_soc_dai_compr_trigger()
  ASoC: soc-dai: add snd_soc_dai_compr_set_params()
  ASoC: soc-dai: add snd_soc_dai_compr_get_params()
  ASoC: soc-dai: add snd_soc_dai_compr_ack()
  ASoC: soc-dai: add snd_soc_dai_compr_pointer()
  ASoC: soc-dai: add snd_soc_dai_compr_set_metadata()
  ASoC: soc-dai: add snd_soc_dai_compr_get_metadata()

 include/sound/soc-dai.h  |  41 +++-
 sound/soc/soc-compress.c | 104 ++++-----
 sound/soc/soc-core.c     |  85 +-------
 sound/soc/soc-dai.c      | 453 +++++++++++++++++++++++++++++----------
 sound/soc/soc-pcm.c      |  50 +----
 5 files changed, 434 insertions(+), 299 deletions(-)

--
2.17.1
alistair/sunxi64-5.8
Mark Brown 2020-04-29 17:21:35 +01:00
commit 79ca782533
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
5 changed files with 441 additions and 306 deletions

View File

@ -154,22 +154,47 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
int snd_soc_dai_prepare(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
int snd_soc_dai_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream, int cmd);
int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream, int cmd);
snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
void snd_soc_dai_suspend(struct snd_soc_dai *dai);
void snd_soc_dai_resume(struct snd_soc_dai *dai);
int snd_soc_dai_probe(struct snd_soc_dai *dai);
int snd_soc_dai_remove(struct snd_soc_dai *dai);
int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
struct snd_soc_pcm_runtime *rtd, int num);
bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream);
int snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime *rtd, int order);
int snd_soc_pcm_dai_remove(struct snd_soc_pcm_runtime *rtd, int order);
int snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime *rtd);
int snd_soc_pcm_dai_prepare(struct snd_pcm_substream *substream);
int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, int cmd);
int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream,
int cmd);
int snd_soc_dai_compr_startup(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream);
void snd_soc_dai_compr_shutdown(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream);
int snd_soc_dai_compr_trigger(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream, int cmd);
int snd_soc_dai_compr_set_params(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_params *params);
int snd_soc_dai_compr_get_params(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_codec *params);
int snd_soc_dai_compr_ack(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
size_t bytes);
int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_tstamp *tstamp);
int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata);
int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata);
struct snd_soc_dai_ops {
/*
* DAI clocking configuration, all optional.

View File

@ -87,15 +87,9 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
if (ret < 0) {
dev_err(cpu_dai->dev,
"Compress ASoC: can't open interface %s: %d\n",
cpu_dai->name, ret);
goto out;
}
}
ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
if (ret < 0)
goto out;
ret = soc_compr_components_open(cstream, &component);
if (ret < 0)
@ -120,8 +114,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
machine_err:
soc_compr_components_free(cstream, component);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
snd_soc_dai_compr_shutdown(cpu_dai, cstream);
out:
mutex_unlock(&rtd->card->pcm_mutex);
pm_err:
@ -178,15 +171,9 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
goto out;
}
if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
if (ret < 0) {
dev_err(cpu_dai->dev,
"Compress ASoC: can't open interface %s: %d\n",
cpu_dai->name, ret);
goto out;
}
}
ret = snd_soc_dai_compr_startup(cpu_dai, cstream);
if (ret < 0)
goto out;
ret = soc_compr_components_open(cstream, &component);
if (ret < 0)
@ -216,8 +203,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
machine_err:
soc_compr_components_free(cstream, component);
open_err:
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
snd_soc_dai_compr_shutdown(cpu_dai, cstream);
out:
dpcm_path_put(&list);
be_err:
@ -256,8 +242,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
soc_compr_components_free(cstream, NULL);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
snd_soc_dai_compr_shutdown(cpu_dai, cstream);
snd_soc_dapm_stream_stop(rtd, stream);
@ -313,8 +298,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
soc_compr_components_free(cstream, NULL);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
snd_soc_dai_compr_shutdown(cpu_dai, cstream);
mutex_unlock(&fe->card->mutex);
return 0;
@ -354,8 +338,9 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
if (ret < 0)
goto out;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
if (ret < 0)
goto out;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@ -388,11 +373,9 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) {
ret = cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
if (ret < 0)
goto out;
}
ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd);
if (ret < 0)
goto out;
ret = soc_compr_components_trigger(cstream, cmd);
if (ret < 0)
@ -460,11 +443,9 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
* that these callbacks will configure everything for this compress
* path, like configuring a PCM port for a CODEC.
*/
if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
if (ret < 0)
goto err;
}
ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
if (ret < 0)
goto err;
ret = soc_compr_components_set_params(cstream, params);
if (ret < 0)
@ -530,11 +511,9 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
if (ret < 0)
goto out;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
if (ret < 0)
goto out;
}
ret = snd_soc_dai_compr_set_params(cpu_dai, cstream, params);
if (ret < 0)
goto out;
ret = soc_compr_components_set_params(cstream, params);
if (ret < 0)
@ -565,11 +544,9 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_params) {
ret = cpu_dai->driver->cops->get_params(cstream, params, cpu_dai);
if (ret < 0)
goto err;
}
ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params);
if (ret < 0)
goto err;
for_each_rtd_components(rtd, i, component) {
if (!component->driver->compress_ops ||
@ -641,11 +618,9 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->ack) {
ret = cpu_dai->driver->cops->ack(cstream, bytes, cpu_dai);
if (ret < 0)
goto err;
}
ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes);
if (ret < 0)
goto err;
for_each_rtd_components(rtd, i, component) {
if (!component->driver->compress_ops ||
@ -673,8 +648,9 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp);
if (ret < 0)
goto out;
for_each_rtd_components(rtd, i, component) {
if (!component->driver->compress_ops ||
@ -685,7 +661,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
component, cstream, tstamp);
break;
}
out:
mutex_unlock(&rtd->card->pcm_mutex);
return ret;
}
@ -721,11 +697,9 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
int i, ret;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
if (ret < 0)
return ret;
}
ret = snd_soc_dai_compr_set_metadata(cpu_dai, cstream, metadata);
if (ret < 0)
return ret;
for_each_rtd_components(rtd, i, component) {
if (!component->driver->compress_ops ||
@ -749,11 +723,9 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
int i, ret;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
if (ret < 0)
return ret;
}
ret = snd_soc_dai_compr_get_metadata(cpu_dai, cstream, metadata);
if (ret < 0)
return ret;
for_each_rtd_components(rtd, i, component) {
if (!component->driver->compress_ops ||

View File

@ -742,9 +742,6 @@ static inline void soc_resume_init(struct snd_soc_card *card)
}
#endif
static const struct snd_soc_dai_ops null_dai_ops = {
};
static struct device_node
*soc_component_to_node(struct snd_soc_component *component)
{
@ -1039,27 +1036,6 @@ _err_defer:
}
EXPORT_SYMBOL_GPL(snd_soc_add_pcm_runtime);
static int soc_dai_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai;
int i, ret = 0;
for_each_rtd_dais(rtd, i, dai) {
struct snd_soc_dai_driver *drv = dai->driver;
if (drv->pcm_new)
ret = drv->pcm_new(rtd, dai);
if (ret < 0) {
dev_err(dai->dev,
"ASoC: Failed to bind %s with pcm device\n",
dai->name);
return ret;
}
}
return 0;
}
static int soc_init_pcm_runtime(struct snd_soc_card *card,
struct snd_soc_pcm_runtime *rtd)
{
@ -1124,7 +1100,7 @@ static int soc_init_pcm_runtime(struct snd_soc_card *card,
return ret;
}
return soc_dai_pcm_new(rtd);
return snd_soc_pcm_dai_new(rtd);
}
static void soc_set_name_prefix(struct snd_soc_card *card,
@ -1280,64 +1256,23 @@ err_probe:
return ret;
}
static void soc_remove_dai(struct snd_soc_dai *dai, int order)
{
int err;
if (!dai || !dai->probed || !dai->driver ||
dai->driver->remove_order != order)
return;
err = snd_soc_dai_remove(dai);
if (err < 0)
dev_err(dai->dev,
"ASoC: failed to remove %s: %d\n",
dai->name, err);
dai->probed = 0;
}
static int soc_probe_dai(struct snd_soc_dai *dai, int order)
{
int ret;
if (dai->probed ||
dai->driver->probe_order != order)
return 0;
ret = snd_soc_dai_probe(dai);
if (ret < 0) {
dev_err(dai->dev, "ASoC: failed to probe DAI %s: %d\n",
dai->name, ret);
return ret;
}
dai->probed = 1;
return 0;
}
static void soc_remove_link_dais(struct snd_soc_card *card)
{
int i;
struct snd_soc_dai *dai;
struct snd_soc_pcm_runtime *rtd;
int order;
for_each_comp_order(order) {
for_each_card_rtds(card, rtd) {
/* remove DAIs */
for_each_rtd_dais(rtd, i, dai)
soc_remove_dai(dai, order);
/* remove all rtd connected DAIs in good order */
snd_soc_pcm_dai_remove(rtd, order);
}
}
}
static int soc_probe_link_dais(struct snd_soc_card *card)
{
struct snd_soc_dai *dai;
struct snd_soc_pcm_runtime *rtd;
int i, order, ret;
int order, ret;
for_each_comp_order(order) {
for_each_card_rtds(card, rtd) {
@ -1346,12 +1281,10 @@ static int soc_probe_link_dais(struct snd_soc_card *card)
"ASoC: probe %s dai link %d late %d\n",
card->name, rtd->num, order);
/* probe the CPU DAI */
for_each_rtd_dais(rtd, i, dai) {
ret = soc_probe_dai(dai, order);
if (ret)
return ret;
}
/* probe all rtd connected DAIs in good order */
ret = snd_soc_pcm_dai_probe(rtd, order);
if (ret)
return ret;
}
}
@ -2406,8 +2339,6 @@ struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
dai->component = component;
dai->dev = dev;
dai->driver = dai_drv;
if (!dai->driver->ops)
dai->driver->ops = &null_dai_ops;
/* see for_each_component_dais */
list_add_tail(&dai->list, &component->dai_list);

View File

@ -9,6 +9,24 @@
#include <sound/soc.h>
#include <sound/soc-dai.h>
#define soc_dai_ret(dai, ret) _soc_dai_ret(dai, __func__, ret)
static inline int _soc_dai_ret(struct snd_soc_dai *dai,
const char *func, int ret)
{
switch (ret) {
case -EPROBE_DEFER:
case -ENOTSUPP:
case 0:
break;
default:
dev_err(dai->dev,
"ASoC: error at %s on %s: %d\n",
func, dai->name, ret);
}
return ret;
}
/**
* snd_soc_dai_set_sysclk - configure DAI system or master clock.
* @dai: DAI
@ -21,11 +39,16 @@
int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
unsigned int freq, int dir)
{
if (dai->driver->ops->set_sysclk)
return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
int ret;
return snd_soc_component_set_sysclk(dai->component, clk_id, 0,
freq, dir);
if (dai->driver->ops &&
dai->driver->ops->set_sysclk)
ret = dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
else
ret = snd_soc_component_set_sysclk(dai->component, clk_id, 0,
freq, dir);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
@ -42,10 +65,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
int div_id, int div)
{
if (dai->driver->ops->set_clkdiv)
return dai->driver->ops->set_clkdiv(dai, div_id, div);
else
return -EINVAL;
int ret = -EINVAL;
if (dai->driver->ops &&
dai->driver->ops->set_clkdiv)
ret = dai->driver->ops->set_clkdiv(dai, div_id, div);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
@ -62,12 +88,17 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
unsigned int freq_in, unsigned int freq_out)
{
if (dai->driver->ops->set_pll)
return dai->driver->ops->set_pll(dai, pll_id, source,
freq_in, freq_out);
int ret;
return snd_soc_component_set_pll(dai->component, pll_id, source,
freq_in, freq_out);
if (dai->driver->ops &&
dai->driver->ops->set_pll)
ret = dai->driver->ops->set_pll(dai, pll_id, source,
freq_in, freq_out);
else
ret = snd_soc_component_set_pll(dai->component, pll_id, source,
freq_in, freq_out);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
@ -80,10 +111,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
*/
int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
{
if (dai->driver->ops->set_bclk_ratio)
return dai->driver->ops->set_bclk_ratio(dai, ratio);
else
return -EINVAL;
int ret = -EINVAL;
if (dai->driver->ops &&
dai->driver->ops->set_bclk_ratio)
ret = dai->driver->ops->set_bclk_ratio(dai, ratio);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio);
@ -96,9 +130,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio);
*/
int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
if (dai->driver->ops->set_fmt == NULL)
return -ENOTSUPP;
return dai->driver->ops->set_fmt(dai, fmt);
int ret = -ENOTSUPP;
if (dai->driver->ops &&
dai->driver->ops->set_fmt)
ret = dai->driver->ops->set_fmt(dai, fmt);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
@ -153,7 +191,10 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask,
int slots, int slot_width)
{
if (dai->driver->ops->xlate_tdm_slot_mask)
int ret = -ENOTSUPP;
if (dai->driver->ops &&
dai->driver->ops->xlate_tdm_slot_mask)
dai->driver->ops->xlate_tdm_slot_mask(slots,
&tx_mask, &rx_mask);
else
@ -162,11 +203,11 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
dai->tx_mask = tx_mask;
dai->rx_mask = rx_mask;
if (dai->driver->ops->set_tdm_slot)
return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
if (dai->driver->ops &&
dai->driver->ops->set_tdm_slot)
ret = dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
slots, slot_width);
else
return -ENOTSUPP;
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
@ -186,11 +227,13 @@ int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
unsigned int tx_num, unsigned int *tx_slot,
unsigned int rx_num, unsigned int *rx_slot)
{
if (dai->driver->ops->set_channel_map)
return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
rx_num, rx_slot);
else
return -ENOTSUPP;
int ret = -ENOTSUPP;
if (dai->driver->ops &&
dai->driver->ops->set_channel_map)
ret = dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
rx_num, rx_slot);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
@ -208,11 +251,13 @@ int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
unsigned int *tx_num, unsigned int *tx_slot,
unsigned int *rx_num, unsigned int *rx_slot)
{
if (dai->driver->ops->get_channel_map)
return dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
rx_num, rx_slot);
else
return -ENOTSUPP;
int ret = -ENOTSUPP;
if (dai->driver->ops &&
dai->driver->ops->get_channel_map)
ret = dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
rx_num, rx_slot);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
@ -225,10 +270,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
*/
int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
{
if (dai->driver->ops->set_tristate)
return dai->driver->ops->set_tristate(dai, tristate);
else
return -EINVAL;
int ret = -EINVAL;
if (dai->driver->ops &&
dai->driver->ops->set_tristate)
ret = dai->driver->ops->set_tristate(dai, tristate);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
@ -243,13 +291,17 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
int direction)
{
if (dai->driver->ops->mute_stream)
return dai->driver->ops->mute_stream(dai, mute, direction);
int ret = -ENOTSUPP;
if (dai->driver->ops &&
dai->driver->ops->mute_stream)
ret = dai->driver->ops->mute_stream(dai, mute, direction);
else if (direction == SNDRV_PCM_STREAM_PLAYBACK &&
dai->driver->ops &&
dai->driver->ops->digital_mute)
return dai->driver->ops->digital_mute(dai, mute);
else
return -ENOTSUPP;
ret = dai->driver->ops->digital_mute(dai, mute);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
@ -258,35 +310,27 @@ int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
int ret;
int ret = 0;
/* perform any topology hw_params fixups before DAI */
if (rtd->dai_link->be_hw_params_fixup) {
ret = rtd->dai_link->be_hw_params_fixup(rtd, params);
if (ret < 0) {
dev_err(rtd->dev,
"ASoC: hw_params topology fixup failed %d\n",
ret);
return ret;
}
if (ret < 0)
goto end;
}
if (dai->driver->ops->hw_params) {
if (dai->driver->ops &&
dai->driver->ops->hw_params)
ret = dai->driver->ops->hw_params(substream, params, dai);
if (ret < 0) {
dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
dai->name, ret);
return ret;
}
}
return 0;
end:
return soc_dai_ret(dai, ret);
}
void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream)
{
if (dai->driver->ops->hw_free)
if (dai->driver->ops &&
dai->driver->ops->hw_free)
dai->driver->ops->hw_free(substream, dai);
}
@ -295,85 +339,40 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
{
int ret = 0;
if (dai->driver->ops->startup)
if (dai->driver->ops &&
dai->driver->ops->startup)
ret = dai->driver->ops->startup(substream, dai);
return ret;
return soc_dai_ret(dai, ret);
}
void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream)
{
if (dai->driver->ops->shutdown)
if (dai->driver->ops &&
dai->driver->ops->shutdown)
dai->driver->ops->shutdown(substream, dai);
}
int snd_soc_dai_prepare(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream)
{
int ret = 0;
if (dai->driver->ops->prepare)
ret = dai->driver->ops->prepare(substream, dai);
return ret;
}
int snd_soc_dai_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream,
int cmd)
{
int ret = 0;
if (dai->driver->ops->trigger)
ret = dai->driver->ops->trigger(substream, cmd, dai);
return ret;
}
int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream,
int cmd)
{
int ret = 0;
if (dai->driver->ops->bespoke_trigger)
ret = dai->driver->ops->bespoke_trigger(substream, cmd, dai);
return ret;
}
snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream)
{
int delay = 0;
if (dai->driver->ops->delay)
if (dai->driver->ops &&
dai->driver->ops->delay)
delay = dai->driver->ops->delay(substream, dai);
return delay;
}
int snd_soc_dai_probe(struct snd_soc_dai *dai)
{
if (dai->driver->probe)
return dai->driver->probe(dai);
return 0;
}
int snd_soc_dai_remove(struct snd_soc_dai *dai)
{
if (dai->driver->remove)
return dai->driver->remove(dai);
return 0;
}
int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
struct snd_soc_pcm_runtime *rtd, int num)
{
int ret = -ENOTSUPP;
if (dai->driver->compress_new)
return dai->driver->compress_new(rtd, num);
return -ENOTSUPP;
ret = dai->driver->compress_new(rtd, num);
return soc_dai_ret(dai, ret);
}
/*
@ -388,3 +387,239 @@ bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
/* If the codec specifies any channels at all, it supports the stream */
return stream->channels_min;
}
int snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime *rtd, int order)
{
struct snd_soc_dai *dai;
int i;
for_each_rtd_dais(rtd, i, dai) {
if (dai->driver->probe_order != order)
continue;
if (dai->driver->probe) {
int ret = dai->driver->probe(dai);
if (ret < 0)
return soc_dai_ret(dai, ret);
}
dai->probed = 1;
}
return 0;
}
int snd_soc_pcm_dai_remove(struct snd_soc_pcm_runtime *rtd, int order)
{
struct snd_soc_dai *dai;
int i, r, ret = 0;
for_each_rtd_dais(rtd, i, dai) {
if (dai->driver->remove_order != order)
continue;
if (dai->probed &&
dai->driver->remove) {
r = dai->driver->remove(dai);
if (r < 0)
ret = r; /* use last error */
}
dai->probed = 0;
}
return ret;
}
int snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *dai;
int i, ret = 0;
for_each_rtd_dais(rtd, i, dai) {
if (dai->driver->pcm_new) {
ret = dai->driver->pcm_new(rtd, dai);
if (ret < 0)
return soc_dai_ret(dai, ret);
}
}
return 0;
}
int snd_soc_pcm_dai_prepare(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *dai;
int i, ret;
for_each_rtd_dais(rtd, i, dai) {
if (dai->driver->ops &&
dai->driver->ops->prepare) {
ret = dai->driver->ops->prepare(substream, dai);
if (ret < 0)
return soc_dai_ret(dai, ret);
}
}
return 0;
}
int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *dai;
int i, ret;
for_each_rtd_dais(rtd, i, dai) {
if (dai->driver->ops &&
dai->driver->ops->trigger) {
ret = dai->driver->ops->trigger(substream, cmd, dai);
if (ret < 0)
return soc_dai_ret(dai, ret);
}
}
return 0;
}
int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *dai;
int i, ret;
for_each_rtd_dais(rtd, i, dai) {
if (dai->driver->ops &&
dai->driver->ops->bespoke_trigger) {
ret = dai->driver->ops->bespoke_trigger(substream,
cmd, dai);
if (ret < 0)
return soc_dai_ret(dai, ret);
}
}
return 0;
}
int snd_soc_dai_compr_startup(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream)
{
int ret = 0;
if (dai->driver->cops &&
dai->driver->cops->startup)
ret = dai->driver->cops->startup(cstream, dai);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_compr_startup);
void snd_soc_dai_compr_shutdown(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream)
{
if (dai->driver->cops &&
dai->driver->cops->shutdown)
dai->driver->cops->shutdown(cstream, dai);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_compr_shutdown);
int snd_soc_dai_compr_trigger(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream, int cmd)
{
int ret = 0;
if (dai->driver->cops &&
dai->driver->cops->trigger)
ret = dai->driver->cops->trigger(cstream, cmd, dai);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_compr_trigger);
int snd_soc_dai_compr_set_params(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_params *params)
{
int ret = 0;
if (dai->driver->cops &&
dai->driver->cops->set_params)
ret = dai->driver->cops->set_params(cstream, params, dai);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_compr_set_params);
int snd_soc_dai_compr_get_params(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_codec *params)
{
int ret = 0;
if (dai->driver->cops &&
dai->driver->cops->get_params)
ret = dai->driver->cops->get_params(cstream, params, dai);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_compr_get_params);
int snd_soc_dai_compr_ack(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
size_t bytes)
{
int ret = 0;
if (dai->driver->cops &&
dai->driver->cops->ack)
ret = dai->driver->cops->ack(cstream, bytes, dai);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_compr_ack);
int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_tstamp *tstamp)
{
int ret = 0;
if (dai->driver->cops &&
dai->driver->cops->pointer)
ret = dai->driver->cops->pointer(cstream, tstamp, dai);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_compr_pointer);
int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata)
{
int ret = 0;
if (dai->driver->cops &&
dai->driver->cops->set_metadata)
ret = dai->driver->cops->set_metadata(cstream, metadata, dai);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_compr_set_metadata);
int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata)
{
int ret = 0;
if (dai->driver->cops &&
dai->driver->cops->get_metadata)
ret = dai->driver->cops->get_metadata(cstream, metadata, dai);
return soc_dai_ret(dai, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_dai_compr_get_metadata);

View File

@ -950,13 +950,10 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
}
}
for_each_rtd_dais(rtd, i, dai) {
ret = snd_soc_dai_prepare(dai, substream);
if (ret < 0) {
dev_err(dai->dev,
"ASoC: DAI prepare error: %d\n", ret);
goto out;
}
ret = snd_soc_pcm_dai_prepare(substream);
if (ret < 0) {
dev_err(rtd->dev, "ASoC: DAI prepare error: %d\n", ret);
goto out;
}
/* cancel any delayed stream shutdown that is pending */
@ -1195,7 +1192,6 @@ static int soc_pcm_trigger_start(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_component *component;
struct snd_soc_dai *dai;
int i, ret;
ret = soc_rtd_trigger(rtd, substream, cmd);
@ -1208,27 +1204,18 @@ static int soc_pcm_trigger_start(struct snd_pcm_substream *substream, int cmd)
return ret;
}
for_each_rtd_dais(rtd, i, dai) {
ret = snd_soc_dai_trigger(dai, substream, cmd);
if (ret < 0)
return ret;
}
return 0;
return snd_soc_pcm_dai_trigger(substream, cmd);
}
static int soc_pcm_trigger_stop(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_component *component;
struct snd_soc_dai *dai;
int i, ret;
for_each_rtd_dais(rtd, i, dai) {
ret = snd_soc_dai_trigger(dai, substream, cmd);
if (ret < 0)
return ret;
}
ret = snd_soc_pcm_dai_trigger(substream, cmd);
if (ret < 0)
return ret;
for_each_rtd_components(rtd, i, component) {
ret = snd_soc_component_trigger(component, substream, cmd);
@ -1265,21 +1252,6 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
return ret;
}
static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *dai;
int i, ret;
for_each_rtd_dais(rtd, i, dai) {
ret = snd_soc_dai_bespoke_trigger(dai, substream, cmd);
if (ret < 0)
return ret;
}
return 0;
}
/*
* soc level wrapper for pointer callback
* If cpu_dai, codec_dai, component driver has the delay callback, then
@ -2483,7 +2455,7 @@ static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd %d\n",
fe->dai_link->name, cmd);
ret = soc_pcm_bespoke_trigger(substream, cmd);
ret = snd_soc_pcm_dai_bespoke_trigger(substream, cmd);
break;
default:
dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd,
@ -2628,7 +2600,7 @@ static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd stop\n",
fe->dai_link->name);
err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP);
err = snd_soc_pcm_dai_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP);
if (err < 0)
dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err);
} else {
@ -2706,7 +2678,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd start\n",
fe->dai_link->name);
ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START);
ret = snd_soc_pcm_dai_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START);
if (ret < 0) {
dev_err(fe->dev,"ASoC: bespoke trigger FE failed %d\n", ret);
goto hw_free;