Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/meson/meson-codec-glue.c
26436 views
1
// SPDX-License-Identifier: GPL-2.0
2
//
3
// Copyright (c) 2019 BayLibre, SAS.
4
// Author: Jerome Brunet <[email protected]>
5
6
#include <linux/module.h>
7
#include <sound/pcm_params.h>
8
#include <sound/soc.h>
9
#include <sound/soc-dai.h>
10
11
#include "meson-codec-glue.h"
12
13
static struct snd_soc_dapm_widget *
14
meson_codec_glue_get_input(struct snd_soc_dapm_widget *w)
15
{
16
struct snd_soc_dapm_path *p;
17
struct snd_soc_dapm_widget *in;
18
19
snd_soc_dapm_widget_for_each_source_path(w, p) {
20
if (!p->connect)
21
continue;
22
23
/* Check that we still are in the same component */
24
if (snd_soc_dapm_to_component(w->dapm) !=
25
snd_soc_dapm_to_component(p->source->dapm))
26
continue;
27
28
if (p->source->id == snd_soc_dapm_dai_in)
29
return p->source;
30
31
in = meson_codec_glue_get_input(p->source);
32
if (in)
33
return in;
34
}
35
36
return NULL;
37
}
38
39
static void meson_codec_glue_input_set_data(struct snd_soc_dai *dai,
40
struct meson_codec_glue_input *data)
41
{
42
snd_soc_dai_dma_data_set_playback(dai, data);
43
}
44
45
struct meson_codec_glue_input *
46
meson_codec_glue_input_get_data(struct snd_soc_dai *dai)
47
{
48
return snd_soc_dai_dma_data_get_playback(dai);
49
}
50
EXPORT_SYMBOL_GPL(meson_codec_glue_input_get_data);
51
52
static struct meson_codec_glue_input *
53
meson_codec_glue_output_get_input_data(struct snd_soc_dapm_widget *w)
54
{
55
struct snd_soc_dapm_widget *in =
56
meson_codec_glue_get_input(w);
57
struct snd_soc_dai *dai;
58
59
if (WARN_ON(!in))
60
return NULL;
61
62
dai = in->priv;
63
64
return meson_codec_glue_input_get_data(dai);
65
}
66
67
int meson_codec_glue_input_hw_params(struct snd_pcm_substream *substream,
68
struct snd_pcm_hw_params *params,
69
struct snd_soc_dai *dai)
70
{
71
struct meson_codec_glue_input *data =
72
meson_codec_glue_input_get_data(dai);
73
74
data->params.rates = snd_pcm_rate_to_rate_bit(params_rate(params));
75
data->params.rate_min = params_rate(params);
76
data->params.rate_max = params_rate(params);
77
data->params.formats = 1ULL << (__force int) params_format(params);
78
data->params.channels_min = params_channels(params);
79
data->params.channels_max = params_channels(params);
80
data->params.sig_bits = dai->driver->playback.sig_bits;
81
82
return 0;
83
}
84
EXPORT_SYMBOL_GPL(meson_codec_glue_input_hw_params);
85
86
int meson_codec_glue_input_set_fmt(struct snd_soc_dai *dai,
87
unsigned int fmt)
88
{
89
struct meson_codec_glue_input *data =
90
meson_codec_glue_input_get_data(dai);
91
92
/* Save the source stream format for the downstream link */
93
data->fmt = fmt;
94
return 0;
95
}
96
EXPORT_SYMBOL_GPL(meson_codec_glue_input_set_fmt);
97
98
int meson_codec_glue_output_startup(struct snd_pcm_substream *substream,
99
struct snd_soc_dai *dai)
100
{
101
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
102
struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget_capture(dai);
103
struct meson_codec_glue_input *in_data = meson_codec_glue_output_get_input_data(w);
104
105
if (!in_data)
106
return -ENODEV;
107
108
if (WARN_ON(!rtd->dai_link->c2c_params)) {
109
dev_warn(dai->dev, "codec2codec link expected\n");
110
return -EINVAL;
111
}
112
113
/* Replace link params with the input params */
114
rtd->dai_link->c2c_params = &in_data->params;
115
rtd->dai_link->num_c2c_params = 1;
116
117
return snd_soc_runtime_set_dai_fmt(rtd, in_data->fmt);
118
}
119
EXPORT_SYMBOL_GPL(meson_codec_glue_output_startup);
120
121
int meson_codec_glue_input_dai_probe(struct snd_soc_dai *dai)
122
{
123
struct meson_codec_glue_input *data;
124
125
data = kzalloc(sizeof(*data), GFP_KERNEL);
126
if (!data)
127
return -ENOMEM;
128
129
meson_codec_glue_input_set_data(dai, data);
130
return 0;
131
}
132
EXPORT_SYMBOL_GPL(meson_codec_glue_input_dai_probe);
133
134
int meson_codec_glue_input_dai_remove(struct snd_soc_dai *dai)
135
{
136
struct meson_codec_glue_input *data =
137
meson_codec_glue_input_get_data(dai);
138
139
kfree(data);
140
return 0;
141
}
142
EXPORT_SYMBOL_GPL(meson_codec_glue_input_dai_remove);
143
144
MODULE_AUTHOR("Jerome Brunet <[email protected]>");
145
MODULE_DESCRIPTION("Amlogic Codec Glue Helpers");
146
MODULE_LICENSE("GPL v2");
147
148
149