Skip to content

Commit

Permalink
hoge
Browse files Browse the repository at this point in the history
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  • Loading branch information
morimoto committed Jun 23, 2022
1 parent 51f8b02 commit 654b6b4
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 100 deletions.
24 changes: 19 additions & 5 deletions include/sound/soc-dai.h
Expand Up @@ -13,6 +13,7 @@

#include <linux/list.h>
#include <sound/asoc.h>
#include <sound/soc-component.h>

struct snd_pcm_substream;
struct snd_soc_dapm_widget;
Expand Down Expand Up @@ -218,7 +219,9 @@ void snd_soc_dai_suspend(struct snd_soc_dai *dai);
void snd_soc_dai_resume(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);
bool snd_soc_dai_valid_via_txrx(struct snd_soc_dai *dai, enum snd_soc_dir txrx);
bool snd_soc_dai_valid_via_stream(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai, int stream);
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link);
void snd_soc_dai_action(struct snd_soc_dai *dai,
int stream, int action);
Expand Down Expand Up @@ -491,13 +494,24 @@ struct snd_soc_dai {
unsigned int probed:1;
};

static inline struct snd_soc_pcm_stream *
snd_soc_dai_get_pcm_stream(const struct snd_soc_dai *dai, int stream)
#define snd_soc_convert_stream_to_txrx_for_cpu(stream) snd_soc_convert_stream_to_txrx(0, stream)
#define snd_soc_convert_stream_to_txrx_for_codec(stream) snd_soc_convert_stream_to_txrx(1, stream)
enum snd_soc_dir snd_soc_convert_stream_to_txrx(int is_codec, int stream);
enum snd_soc_dir snd_soc_convert_stream_to_txrx_via_dai(struct snd_soc_pcm_runtime *rtd, const struct snd_soc_dai *dai, int stream);

#define snd_soc_dai_get_stream_info_tx(dai) snd_soc_dai_get_stream_info_by_txrx(dai, SNDRV_DIR_TX)
#define snd_soc_dai_get_stream_info_rx(dai) snd_soc_dai_get_stream_info_by_txrx(dai, SNDRV_DIR_RX)
static inline struct snd_soc_pcm_stream_info *
snd_soc_dai_get_stream_info_by_txrx(const struct snd_soc_dai *dai, enum snd_soc_dir txrx)
{
return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
&dai->driver->playback : &dai->driver->capture;
return &dai->driver->stream_info[txrx];
}

#define snd_soc_dai_get_stream_info_playback(rtd, dai) snd_soc_dai_get_stream_info_by_stream(rtd, dai, SNDRV_PCM_STREAM_PLAYBACK)
#define snd_soc_dai_get_stream_info_capture(rtd, dai) snd_soc_dai_get_stream_info_by_stream(rtd, dai, SNDRV_PCM_STREAM_CAPTURE)
#define snd_soc_dai_get_stream_info_by_stream(rtd, dai, stream) \
snd_soc_dai_get_stream_info_by_txrx(dai, snd_soc_convert_stream_to_txrx_via_dai(rtd, dai, stream))

static inline
struct snd_soc_dapm_widget *snd_soc_dai_get_widget(
struct snd_soc_dai *dai, int stream)
Expand Down
28 changes: 14 additions & 14 deletions sound/soc/soc-component.c
Expand Up @@ -918,20 +918,6 @@ int snd_soc_component_test_bits(struct snd_soc_component *component,
}
EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);

int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i;

/* FIXME: use 1st pointer */
for_each_rtd_components(rtd, i, component)
if (component->driver->pointer)
return component->driver->pointer(component, substream);

return 0;
}

static bool snd_soc_component_is_codec_on_rtd(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_component *component)
{
Expand All @@ -946,6 +932,20 @@ static bool snd_soc_component_is_codec_on_rtd(struct snd_soc_pcm_runtime *rtd,
return false;
}

int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_component *component;
int i;

/* FIXME: use 1st pointer */
for_each_rtd_components(rtd, i, component)
if (component->driver->pointer)
return component->driver->pointer(component, substream);

return 0;
}

void snd_soc_pcm_component_delay(struct snd_pcm_substream *substream,
snd_pcm_sframes_t *cpu_delay,
snd_pcm_sframes_t *codec_delay)
Expand Down
7 changes: 7 additions & 0 deletions sound/soc/soc-core.c
Expand Up @@ -51,6 +51,8 @@ static LIST_HEAD(unbind_card_list);
#define for_each_component(component) \
list_for_each_entry(component, &component_list, list)

struct snd_soc_pcm_stream_params null_stream_param = { };

/*
* This is used if driver don't need to have CPU/Codec/Platform
* dai_link. see soc.h
Expand Down Expand Up @@ -2497,6 +2499,11 @@ struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
dai_drv->stream_info[SNDRV_DIR_RX].params = &dai_drv->capture_;
}

if (!dai_drv->stream_info[SNDRV_DIR_TX].params)
dai_drv->stream_info[SNDRV_DIR_TX].params = &null_stream_param;
if (!dai_drv->stream_info[SNDRV_DIR_RX].params)
dai_drv->stream_info[SNDRV_DIR_RX].params = &null_stream_param;

/* see for_each_component_dais */
list_add_tail(&dai->list, &component->dai_list);
component->num_dai++;
Expand Down
67 changes: 58 additions & 9 deletions sound/soc/soc-dai.c
Expand Up @@ -32,6 +32,35 @@ static inline int _soc_dai_ret(struct snd_soc_dai *dai,
return ret;
}

static bool snd_soc_dai_is_codec(struct snd_soc_pcm_runtime *rtd, const struct snd_soc_dai *dai)
{
struct snd_soc_dai *_dai;
int i;

for_each_rtd_codec_dais(rtd, i, _dai)
if (_dai == dai)
return true;

return false;
}

enum snd_soc_dir snd_soc_convert_stream_to_txrx(int is_codec, int stream)
{
/* see [TX/RX image] */
if (( is_codec && (stream == SNDRV_PCM_STREAM_CAPTURE)) ||
(!is_codec && (stream == SNDRV_PCM_STREAM_PLAYBACK)))
return SNDRV_DIR_TX;
else
return SNDRV_DIR_RX;
}

enum snd_soc_dir snd_soc_convert_stream_to_txrx_via_dai(struct snd_soc_pcm_runtime *rtd, const struct snd_soc_dai *dai, int stream)
{
int is_codec = snd_soc_dai_is_codec(rtd, dai);

return snd_soc_convert_stream_to_txrx(is_codec, stream);
}

/*
* We might want to check substream by using list.
* In such case, we can update these macros.
Expand Down Expand Up @@ -462,16 +491,32 @@ int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
}

/*
* snd_soc_dai_stream_valid() - check if a DAI supports the given stream
* snd_soc_dai_valid_via_txrx() - check if a DAI supports the given stream
*
* Returns true if the DAI supports the indicated stream type.
*/
bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
bool snd_soc_dai_valid_via_txrx(struct snd_soc_dai *dai, enum snd_soc_dir txrx)
{
struct snd_soc_pcm_stream *stream = snd_soc_dai_get_pcm_stream(dai, dir);
struct snd_soc_pcm_stream_info *si = snd_soc_dai_get_stream_info_by_txrx(dai, txrx);

/* If the codec specifies any channels at all, it supports the stream */
return stream->channels_min;
if (!si->params || !si->params->channels_min)
return false;

return true;
}

/*
* snd_soc_dai_valid_via_stream() - check if a DAI supports the given stream
*
* Returns true if the DAI supports the indicated stream type.
*/
bool snd_soc_dai_valid_via_stream(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai, int stream)
{
int txrx = snd_soc_convert_stream_to_txrx_via_dai(rtd, dai, stream);

return snd_soc_dai_valid_via_txrx(dai, txrx);
}

/*
Expand All @@ -480,31 +525,35 @@ bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link)
{
bool supported[SNDRV_PCM_STREAM_LAST + 1];
int direction;
int stream;

for_each_pcm_streams(direction) {
for_each_pcm_streams(stream) {
struct snd_soc_dai_link_component *cpu;
struct snd_soc_dai_link_component *codec;
struct snd_soc_dai *dai;
bool supported_cpu = false;
bool supported_codec = false;
int txrx;
int i;

txrx = snd_soc_convert_stream_to_txrx_for_cpu(stream);
for_each_link_cpus(dai_link, i, cpu) {
dai = snd_soc_find_dai_with_mutex(cpu);
if (dai && snd_soc_dai_stream_valid(dai, direction)) {
if (dai && snd_soc_dai_valid_via_txrx(dai, txrx)) {
supported_cpu = true;
break;
}
}

txrx = snd_soc_convert_stream_to_txrx_for_codec(stream);
for_each_link_codecs(dai_link, i, codec) {
dai = snd_soc_find_dai_with_mutex(codec);
if (dai && snd_soc_dai_stream_valid(dai, direction)) {
if (dai && snd_soc_dai_valid_via_txrx(dai, txrx)) {
supported_codec = true;
break;
}
}
supported[direction] = supported_cpu && supported_codec;
supported[stream] = supported_cpu && supported_codec;
}

dai_link->dpcm_playback = supported[SNDRV_PCM_STREAM_PLAYBACK];
Expand Down
4 changes: 2 additions & 2 deletions sound/soc/soc-dapm.c
Expand Up @@ -3834,7 +3834,7 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
struct snd_soc_dai *source, *sink;
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_pcm_hw_params *params = NULL;
const struct snd_soc_pcm_stream *config = NULL;
const struct snd_soc_pcm_stream_params *config = NULL;
struct snd_pcm_runtime *runtime = NULL;
unsigned int fmt;
int ret = 0;
Expand Down Expand Up @@ -3880,7 +3880,7 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
* either party on the link to alter the configuration if
* necessary
*/
config = rtd->dai_link->params + rtd->params_select;
config = (rtd->dai_link->c2c_params + rtd->params_select);
if (WARN_ON(!config)) {
dev_err(w->dapm->dev, "ASoC: link config missing\n");
ret = -EINVAL;
Expand Down

0 comments on commit 654b6b4

Please sign in to comment.