1d293abc0SKuninori Morimoto // SPDX-License-Identifier: GPL-2.0
2d293abc0SKuninori Morimoto //
3d293abc0SKuninori Morimoto // test-component.c -- Test Audio Component driver
4d293abc0SKuninori Morimoto //
5d293abc0SKuninori Morimoto // Copyright (C) 2020 Renesas Electronics Corporation
6d293abc0SKuninori Morimoto // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7d293abc0SKuninori Morimoto
8d293abc0SKuninori Morimoto #include <linux/slab.h>
9d293abc0SKuninori Morimoto #include <linux/of_device.h>
10d293abc0SKuninori Morimoto #include <linux/of_graph.h>
11d293abc0SKuninori Morimoto #include <linux/module.h>
12d293abc0SKuninori Morimoto #include <linux/workqueue.h>
13d293abc0SKuninori Morimoto #include <sound/pcm.h>
14d293abc0SKuninori Morimoto #include <sound/soc.h>
15d293abc0SKuninori Morimoto
16d293abc0SKuninori Morimoto #define TEST_NAME_LEN 32
17d293abc0SKuninori Morimoto struct test_dai_name {
18d293abc0SKuninori Morimoto char name[TEST_NAME_LEN];
19d293abc0SKuninori Morimoto char name_playback[TEST_NAME_LEN];
20d293abc0SKuninori Morimoto char name_capture[TEST_NAME_LEN];
21d293abc0SKuninori Morimoto };
22d293abc0SKuninori Morimoto
23d293abc0SKuninori Morimoto struct test_priv {
24d293abc0SKuninori Morimoto struct device *dev;
25d293abc0SKuninori Morimoto struct snd_pcm_substream *substream;
26d293abc0SKuninori Morimoto struct delayed_work dwork;
27d293abc0SKuninori Morimoto struct snd_soc_component_driver *component_driver;
28d293abc0SKuninori Morimoto struct snd_soc_dai_driver *dai_driver;
29d293abc0SKuninori Morimoto struct test_dai_name *name;
30d293abc0SKuninori Morimoto };
31d293abc0SKuninori Morimoto
32d293abc0SKuninori Morimoto struct test_adata {
33d293abc0SKuninori Morimoto u32 is_cpu:1;
34d293abc0SKuninori Morimoto u32 cmp_v:1;
35d293abc0SKuninori Morimoto u32 dai_v:1;
36d293abc0SKuninori Morimoto };
37d293abc0SKuninori Morimoto
38d293abc0SKuninori Morimoto #define mile_stone(d) dev_info((d)->dev, "%s() : %s", __func__, (d)->driver->name)
39d293abc0SKuninori Morimoto #define mile_stone_x(dev) dev_info(dev, "%s()", __func__)
40d293abc0SKuninori Morimoto
test_dai_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)41d293abc0SKuninori Morimoto static int test_dai_set_sysclk(struct snd_soc_dai *dai,
42d293abc0SKuninori Morimoto int clk_id, unsigned int freq, int dir)
43d293abc0SKuninori Morimoto {
44d293abc0SKuninori Morimoto mile_stone(dai);
45d293abc0SKuninori Morimoto
46d293abc0SKuninori Morimoto return 0;
47d293abc0SKuninori Morimoto }
48d293abc0SKuninori Morimoto
test_dai_set_pll(struct snd_soc_dai * dai,int pll_id,int source,unsigned int freq_in,unsigned int freq_out)49d293abc0SKuninori Morimoto static int test_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
50d293abc0SKuninori Morimoto unsigned int freq_in, unsigned int freq_out)
51d293abc0SKuninori Morimoto {
52d293abc0SKuninori Morimoto mile_stone(dai);
53d293abc0SKuninori Morimoto
54d293abc0SKuninori Morimoto return 0;
55d293abc0SKuninori Morimoto }
56d293abc0SKuninori Morimoto
test_dai_set_clkdiv(struct snd_soc_dai * dai,int div_id,int div)57d293abc0SKuninori Morimoto static int test_dai_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
58d293abc0SKuninori Morimoto {
59d293abc0SKuninori Morimoto mile_stone(dai);
60d293abc0SKuninori Morimoto
61d293abc0SKuninori Morimoto return 0;
62d293abc0SKuninori Morimoto }
63d293abc0SKuninori Morimoto
test_dai_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)64d293abc0SKuninori Morimoto static int test_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
65d293abc0SKuninori Morimoto {
66d293abc0SKuninori Morimoto unsigned int format = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
67d293abc0SKuninori Morimoto unsigned int clock = fmt & SND_SOC_DAIFMT_CLOCK_MASK;
68d293abc0SKuninori Morimoto unsigned int inv = fmt & SND_SOC_DAIFMT_INV_MASK;
69d444c8d2SCharles Keepax unsigned int master = fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
70d293abc0SKuninori Morimoto char *str;
71d293abc0SKuninori Morimoto
72d293abc0SKuninori Morimoto dev_info(dai->dev, "name : %s", dai->name);
73d293abc0SKuninori Morimoto
74d293abc0SKuninori Morimoto str = "unknown";
75d293abc0SKuninori Morimoto switch (format) {
76d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_I2S:
77d293abc0SKuninori Morimoto str = "i2s";
78d293abc0SKuninori Morimoto break;
79d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_RIGHT_J:
80d293abc0SKuninori Morimoto str = "right_j";
81d293abc0SKuninori Morimoto break;
82d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_LEFT_J:
83d293abc0SKuninori Morimoto str = "left_j";
84d293abc0SKuninori Morimoto break;
85d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_DSP_A:
86d293abc0SKuninori Morimoto str = "dsp_a";
87d293abc0SKuninori Morimoto break;
88d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_DSP_B:
89d293abc0SKuninori Morimoto str = "dsp_b";
90d293abc0SKuninori Morimoto break;
91d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_AC97:
92d293abc0SKuninori Morimoto str = "ac97";
93d293abc0SKuninori Morimoto break;
94d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_PDM:
95d293abc0SKuninori Morimoto str = "pdm";
96d293abc0SKuninori Morimoto break;
97d293abc0SKuninori Morimoto }
98d293abc0SKuninori Morimoto dev_info(dai->dev, "format : %s", str);
99d293abc0SKuninori Morimoto
100d293abc0SKuninori Morimoto if (clock == SND_SOC_DAIFMT_CONT)
101d293abc0SKuninori Morimoto str = "continuous";
102d293abc0SKuninori Morimoto else
103d293abc0SKuninori Morimoto str = "gated";
104d293abc0SKuninori Morimoto dev_info(dai->dev, "clock : %s", str);
105d293abc0SKuninori Morimoto
106d293abc0SKuninori Morimoto str = "unknown";
107d293abc0SKuninori Morimoto switch (master) {
108d444c8d2SCharles Keepax case SND_SOC_DAIFMT_BP_FP:
109d293abc0SKuninori Morimoto str = "clk provider, frame provider";
110d293abc0SKuninori Morimoto break;
111d444c8d2SCharles Keepax case SND_SOC_DAIFMT_BC_FP:
112d293abc0SKuninori Morimoto str = "clk consumer, frame provider";
113d293abc0SKuninori Morimoto break;
114d444c8d2SCharles Keepax case SND_SOC_DAIFMT_BP_FC:
115d293abc0SKuninori Morimoto str = "clk provider, frame consumer";
116d293abc0SKuninori Morimoto break;
117d444c8d2SCharles Keepax case SND_SOC_DAIFMT_BC_FC:
118d293abc0SKuninori Morimoto str = "clk consumer, frame consumer";
119d293abc0SKuninori Morimoto break;
120d293abc0SKuninori Morimoto }
121d293abc0SKuninori Morimoto dev_info(dai->dev, "clock : codec is %s", str);
122d293abc0SKuninori Morimoto
123d293abc0SKuninori Morimoto str = "unknown";
124d293abc0SKuninori Morimoto switch (inv) {
125d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_NB_NF:
126d293abc0SKuninori Morimoto str = "normal bit, normal frame";
127d293abc0SKuninori Morimoto break;
128d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_NB_IF:
129d293abc0SKuninori Morimoto str = "normal bit, invert frame";
130d293abc0SKuninori Morimoto break;
131d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_IB_NF:
132d293abc0SKuninori Morimoto str = "invert bit, normal frame";
133d293abc0SKuninori Morimoto break;
134d293abc0SKuninori Morimoto case SND_SOC_DAIFMT_IB_IF:
135d293abc0SKuninori Morimoto str = "invert bit, invert frame";
136d293abc0SKuninori Morimoto break;
137d293abc0SKuninori Morimoto }
138d293abc0SKuninori Morimoto dev_info(dai->dev, "signal : %s", str);
139d293abc0SKuninori Morimoto
140d293abc0SKuninori Morimoto return 0;
141d293abc0SKuninori Morimoto }
142d293abc0SKuninori Morimoto
test_dai_mute_stream(struct snd_soc_dai * dai,int mute,int stream)143d293abc0SKuninori Morimoto static int test_dai_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
144d293abc0SKuninori Morimoto {
145d293abc0SKuninori Morimoto mile_stone(dai);
146d293abc0SKuninori Morimoto
147d293abc0SKuninori Morimoto return 0;
148d293abc0SKuninori Morimoto }
149d293abc0SKuninori Morimoto
test_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)150d293abc0SKuninori Morimoto static int test_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
151d293abc0SKuninori Morimoto {
152d293abc0SKuninori Morimoto mile_stone(dai);
153d293abc0SKuninori Morimoto
154d293abc0SKuninori Morimoto return 0;
155d293abc0SKuninori Morimoto }
156d293abc0SKuninori Morimoto
test_dai_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)157d293abc0SKuninori Morimoto static void test_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
158d293abc0SKuninori Morimoto {
159d293abc0SKuninori Morimoto mile_stone(dai);
160d293abc0SKuninori Morimoto }
161d293abc0SKuninori Morimoto
test_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)162d293abc0SKuninori Morimoto static int test_dai_hw_params(struct snd_pcm_substream *substream,
163d293abc0SKuninori Morimoto struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
164d293abc0SKuninori Morimoto {
165d293abc0SKuninori Morimoto mile_stone(dai);
166d293abc0SKuninori Morimoto
167d293abc0SKuninori Morimoto return 0;
168d293abc0SKuninori Morimoto }
169d293abc0SKuninori Morimoto
test_dai_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)170d293abc0SKuninori Morimoto static int test_dai_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
171d293abc0SKuninori Morimoto {
172d293abc0SKuninori Morimoto mile_stone(dai);
173d293abc0SKuninori Morimoto
174d293abc0SKuninori Morimoto return 0;
175d293abc0SKuninori Morimoto }
176d293abc0SKuninori Morimoto
test_dai_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)177d293abc0SKuninori Morimoto static int test_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
178d293abc0SKuninori Morimoto {
179d293abc0SKuninori Morimoto mile_stone(dai);
180d293abc0SKuninori Morimoto
181d293abc0SKuninori Morimoto return 0;
182d293abc0SKuninori Morimoto }
183d293abc0SKuninori Morimoto
test_dai_bespoke_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)184d293abc0SKuninori Morimoto static int test_dai_bespoke_trigger(struct snd_pcm_substream *substream,
185d293abc0SKuninori Morimoto int cmd, struct snd_soc_dai *dai)
186d293abc0SKuninori Morimoto {
187d293abc0SKuninori Morimoto mile_stone(dai);
188d293abc0SKuninori Morimoto
189d293abc0SKuninori Morimoto return 0;
190d293abc0SKuninori Morimoto }
191d293abc0SKuninori Morimoto
192d293abc0SKuninori Morimoto static u64 test_dai_formats =
193d293abc0SKuninori Morimoto /*
194d293abc0SKuninori Morimoto * Select below from Sound Card, not auto
195d444c8d2SCharles Keepax * SND_SOC_POSSIBLE_DAIFMT_BP_FP
196d444c8d2SCharles Keepax * SND_SOC_POSSIBLE_DAIFMT_BC_FP
197d444c8d2SCharles Keepax * SND_SOC_POSSIBLE_DAIFMT_BP_FC
198d444c8d2SCharles Keepax * SND_SOC_POSSIBLE_DAIFMT_BC_FC
199d293abc0SKuninori Morimoto */
200d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_I2S |
201d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_RIGHT_J |
202d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
203d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_DSP_A |
204d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_DSP_B |
205d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_AC97 |
206d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_PDM |
207d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_NB_NF |
208d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_NB_IF |
209d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_IB_NF |
210d293abc0SKuninori Morimoto SND_SOC_POSSIBLE_DAIFMT_IB_IF;
211d293abc0SKuninori Morimoto
212d293abc0SKuninori Morimoto static const struct snd_soc_dai_ops test_ops = {
213408c122eSCharles Keepax .set_fmt = test_dai_set_fmt,
214d293abc0SKuninori Morimoto .startup = test_dai_startup,
215d293abc0SKuninori Morimoto .shutdown = test_dai_shutdown,
216d293abc0SKuninori Morimoto .auto_selectable_formats = &test_dai_formats,
217d293abc0SKuninori Morimoto .num_auto_selectable_formats = 1,
218d293abc0SKuninori Morimoto };
219d293abc0SKuninori Morimoto
220d293abc0SKuninori Morimoto static const struct snd_soc_dai_ops test_verbose_ops = {
221d293abc0SKuninori Morimoto .set_sysclk = test_dai_set_sysclk,
222d293abc0SKuninori Morimoto .set_pll = test_dai_set_pll,
223d293abc0SKuninori Morimoto .set_clkdiv = test_dai_set_clkdiv,
224408c122eSCharles Keepax .set_fmt = test_dai_set_fmt,
225d293abc0SKuninori Morimoto .mute_stream = test_dai_mute_stream,
226d293abc0SKuninori Morimoto .startup = test_dai_startup,
227d293abc0SKuninori Morimoto .shutdown = test_dai_shutdown,
228d293abc0SKuninori Morimoto .hw_params = test_dai_hw_params,
229d293abc0SKuninori Morimoto .hw_free = test_dai_hw_free,
230d293abc0SKuninori Morimoto .trigger = test_dai_trigger,
231d293abc0SKuninori Morimoto .bespoke_trigger = test_dai_bespoke_trigger,
232d293abc0SKuninori Morimoto .auto_selectable_formats = &test_dai_formats,
233d293abc0SKuninori Morimoto .num_auto_selectable_formats = 1,
234d293abc0SKuninori Morimoto };
235d293abc0SKuninori Morimoto
236d293abc0SKuninori Morimoto #define STUB_RATES SNDRV_PCM_RATE_8000_384000
237d293abc0SKuninori Morimoto #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
238d293abc0SKuninori Morimoto SNDRV_PCM_FMTBIT_U8 | \
239d293abc0SKuninori Morimoto SNDRV_PCM_FMTBIT_S16_LE | \
240d293abc0SKuninori Morimoto SNDRV_PCM_FMTBIT_U16_LE | \
241d293abc0SKuninori Morimoto SNDRV_PCM_FMTBIT_S24_LE | \
242d293abc0SKuninori Morimoto SNDRV_PCM_FMTBIT_S24_3LE | \
243d293abc0SKuninori Morimoto SNDRV_PCM_FMTBIT_U24_LE | \
244d293abc0SKuninori Morimoto SNDRV_PCM_FMTBIT_S32_LE | \
245d293abc0SKuninori Morimoto SNDRV_PCM_FMTBIT_U32_LE)
246d293abc0SKuninori Morimoto
test_component_probe(struct snd_soc_component * component)247d293abc0SKuninori Morimoto static int test_component_probe(struct snd_soc_component *component)
248d293abc0SKuninori Morimoto {
249d293abc0SKuninori Morimoto mile_stone(component);
250d293abc0SKuninori Morimoto
251d293abc0SKuninori Morimoto return 0;
252d293abc0SKuninori Morimoto }
253d293abc0SKuninori Morimoto
test_component_remove(struct snd_soc_component * component)254d293abc0SKuninori Morimoto static void test_component_remove(struct snd_soc_component *component)
255d293abc0SKuninori Morimoto {
256d293abc0SKuninori Morimoto mile_stone(component);
257d293abc0SKuninori Morimoto }
258d293abc0SKuninori Morimoto
test_component_suspend(struct snd_soc_component * component)259d293abc0SKuninori Morimoto static int test_component_suspend(struct snd_soc_component *component)
260d293abc0SKuninori Morimoto {
261d293abc0SKuninori Morimoto mile_stone(component);
262d293abc0SKuninori Morimoto
263d293abc0SKuninori Morimoto return 0;
264d293abc0SKuninori Morimoto }
265d293abc0SKuninori Morimoto
test_component_resume(struct snd_soc_component * component)266d293abc0SKuninori Morimoto static int test_component_resume(struct snd_soc_component *component)
267d293abc0SKuninori Morimoto {
268d293abc0SKuninori Morimoto mile_stone(component);
269d293abc0SKuninori Morimoto
270d293abc0SKuninori Morimoto return 0;
271d293abc0SKuninori Morimoto }
272d293abc0SKuninori Morimoto
273d293abc0SKuninori Morimoto #define PREALLOC_BUFFER (32 * 1024)
test_component_pcm_construct(struct snd_soc_component * component,struct snd_soc_pcm_runtime * rtd)274d293abc0SKuninori Morimoto static int test_component_pcm_construct(struct snd_soc_component *component,
275d293abc0SKuninori Morimoto struct snd_soc_pcm_runtime *rtd)
276d293abc0SKuninori Morimoto {
277d293abc0SKuninori Morimoto mile_stone(component);
278d293abc0SKuninori Morimoto
279d293abc0SKuninori Morimoto snd_pcm_set_managed_buffer_all(
280d293abc0SKuninori Morimoto rtd->pcm,
281d293abc0SKuninori Morimoto SNDRV_DMA_TYPE_DEV,
282d293abc0SKuninori Morimoto rtd->card->snd_card->dev,
283d293abc0SKuninori Morimoto PREALLOC_BUFFER, PREALLOC_BUFFER);
284d293abc0SKuninori Morimoto
285d293abc0SKuninori Morimoto return 0;
286d293abc0SKuninori Morimoto }
287d293abc0SKuninori Morimoto
test_component_pcm_destruct(struct snd_soc_component * component,struct snd_pcm * pcm)288d293abc0SKuninori Morimoto static void test_component_pcm_destruct(struct snd_soc_component *component,
289d293abc0SKuninori Morimoto struct snd_pcm *pcm)
290d293abc0SKuninori Morimoto {
291d293abc0SKuninori Morimoto mile_stone(component);
292d293abc0SKuninori Morimoto }
293d293abc0SKuninori Morimoto
test_component_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)294d293abc0SKuninori Morimoto static int test_component_set_sysclk(struct snd_soc_component *component,
295d293abc0SKuninori Morimoto int clk_id, int source, unsigned int freq, int dir)
296d293abc0SKuninori Morimoto {
297d293abc0SKuninori Morimoto mile_stone(component);
298d293abc0SKuninori Morimoto
299d293abc0SKuninori Morimoto return 0;
300d293abc0SKuninori Morimoto }
301d293abc0SKuninori Morimoto
test_component_set_pll(struct snd_soc_component * component,int pll_id,int source,unsigned int freq_in,unsigned int freq_out)302d293abc0SKuninori Morimoto static int test_component_set_pll(struct snd_soc_component *component, int pll_id,
303d293abc0SKuninori Morimoto int source, unsigned int freq_in, unsigned int freq_out)
304d293abc0SKuninori Morimoto {
305d293abc0SKuninori Morimoto mile_stone(component);
306d293abc0SKuninori Morimoto
307d293abc0SKuninori Morimoto return 0;
308d293abc0SKuninori Morimoto }
309d293abc0SKuninori Morimoto
test_component_set_jack(struct snd_soc_component * component,struct snd_soc_jack * jack,void * data)310d293abc0SKuninori Morimoto static int test_component_set_jack(struct snd_soc_component *component,
311d293abc0SKuninori Morimoto struct snd_soc_jack *jack, void *data)
312d293abc0SKuninori Morimoto {
313d293abc0SKuninori Morimoto mile_stone(component);
314d293abc0SKuninori Morimoto
315d293abc0SKuninori Morimoto return 0;
316d293abc0SKuninori Morimoto }
317d293abc0SKuninori Morimoto
test_component_seq_notifier(struct snd_soc_component * component,enum snd_soc_dapm_type type,int subseq)318d293abc0SKuninori Morimoto static void test_component_seq_notifier(struct snd_soc_component *component,
319d293abc0SKuninori Morimoto enum snd_soc_dapm_type type, int subseq)
320d293abc0SKuninori Morimoto {
321d293abc0SKuninori Morimoto mile_stone(component);
322d293abc0SKuninori Morimoto }
323d293abc0SKuninori Morimoto
test_component_stream_event(struct snd_soc_component * component,int event)324d293abc0SKuninori Morimoto static int test_component_stream_event(struct snd_soc_component *component, int event)
325d293abc0SKuninori Morimoto {
326d293abc0SKuninori Morimoto mile_stone(component);
327d293abc0SKuninori Morimoto
328d293abc0SKuninori Morimoto return 0;
329d293abc0SKuninori Morimoto }
330d293abc0SKuninori Morimoto
test_component_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)331d293abc0SKuninori Morimoto static int test_component_set_bias_level(struct snd_soc_component *component,
332d293abc0SKuninori Morimoto enum snd_soc_bias_level level)
333d293abc0SKuninori Morimoto {
334d293abc0SKuninori Morimoto mile_stone(component);
335d293abc0SKuninori Morimoto
336d293abc0SKuninori Morimoto return 0;
337d293abc0SKuninori Morimoto }
338d293abc0SKuninori Morimoto
339d293abc0SKuninori Morimoto static const struct snd_pcm_hardware test_component_hardware = {
340d293abc0SKuninori Morimoto /* Random values to keep userspace happy when checking constraints */
341d293abc0SKuninori Morimoto .info = SNDRV_PCM_INFO_INTERLEAVED |
342d293abc0SKuninori Morimoto SNDRV_PCM_INFO_MMAP |
343d293abc0SKuninori Morimoto SNDRV_PCM_INFO_MMAP_VALID,
344d293abc0SKuninori Morimoto .buffer_bytes_max = 32 * 1024,
345d293abc0SKuninori Morimoto .period_bytes_min = 32,
346d293abc0SKuninori Morimoto .period_bytes_max = 8192,
347d293abc0SKuninori Morimoto .periods_min = 1,
348d293abc0SKuninori Morimoto .periods_max = 128,
349d293abc0SKuninori Morimoto .fifo_size = 256,
350d293abc0SKuninori Morimoto };
351d293abc0SKuninori Morimoto
test_component_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)352d293abc0SKuninori Morimoto static int test_component_open(struct snd_soc_component *component,
353d293abc0SKuninori Morimoto struct snd_pcm_substream *substream)
354d293abc0SKuninori Morimoto {
355d293abc0SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
356d293abc0SKuninori Morimoto
357d293abc0SKuninori Morimoto mile_stone(component);
358d293abc0SKuninori Morimoto
359d293abc0SKuninori Morimoto /* BE's dont need dummy params */
360d293abc0SKuninori Morimoto if (!rtd->dai_link->no_pcm)
361d293abc0SKuninori Morimoto snd_soc_set_runtime_hwparams(substream, &test_component_hardware);
362d293abc0SKuninori Morimoto
363d293abc0SKuninori Morimoto return 0;
364d293abc0SKuninori Morimoto }
365d293abc0SKuninori Morimoto
test_component_close(struct snd_soc_component * component,struct snd_pcm_substream * substream)366d293abc0SKuninori Morimoto static int test_component_close(struct snd_soc_component *component,
367d293abc0SKuninori Morimoto struct snd_pcm_substream *substream)
368d293abc0SKuninori Morimoto {
369d293abc0SKuninori Morimoto mile_stone(component);
370d293abc0SKuninori Morimoto
371d293abc0SKuninori Morimoto return 0;
372d293abc0SKuninori Morimoto }
373d293abc0SKuninori Morimoto
test_component_ioctl(struct snd_soc_component * component,struct snd_pcm_substream * substream,unsigned int cmd,void * arg)374d293abc0SKuninori Morimoto static int test_component_ioctl(struct snd_soc_component *component,
375d293abc0SKuninori Morimoto struct snd_pcm_substream *substream,
376d293abc0SKuninori Morimoto unsigned int cmd, void *arg)
377d293abc0SKuninori Morimoto {
378d293abc0SKuninori Morimoto mile_stone(component);
379d293abc0SKuninori Morimoto
380d293abc0SKuninori Morimoto return 0;
381d293abc0SKuninori Morimoto }
382d293abc0SKuninori Morimoto
test_component_hw_params(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)383d293abc0SKuninori Morimoto static int test_component_hw_params(struct snd_soc_component *component,
384d293abc0SKuninori Morimoto struct snd_pcm_substream *substream,
385d293abc0SKuninori Morimoto struct snd_pcm_hw_params *params)
386d293abc0SKuninori Morimoto {
387d293abc0SKuninori Morimoto mile_stone(component);
388d293abc0SKuninori Morimoto
389d293abc0SKuninori Morimoto return 0;
390d293abc0SKuninori Morimoto }
391d293abc0SKuninori Morimoto
test_component_hw_free(struct snd_soc_component * component,struct snd_pcm_substream * substream)392d293abc0SKuninori Morimoto static int test_component_hw_free(struct snd_soc_component *component,
393d293abc0SKuninori Morimoto struct snd_pcm_substream *substream)
394d293abc0SKuninori Morimoto {
395d293abc0SKuninori Morimoto mile_stone(component);
396d293abc0SKuninori Morimoto
397d293abc0SKuninori Morimoto return 0;
398d293abc0SKuninori Morimoto }
399d293abc0SKuninori Morimoto
test_component_prepare(struct snd_soc_component * component,struct snd_pcm_substream * substream)400d293abc0SKuninori Morimoto static int test_component_prepare(struct snd_soc_component *component,
401d293abc0SKuninori Morimoto struct snd_pcm_substream *substream)
402d293abc0SKuninori Morimoto {
403d293abc0SKuninori Morimoto mile_stone(component);
404d293abc0SKuninori Morimoto
405d293abc0SKuninori Morimoto return 0;
406d293abc0SKuninori Morimoto }
407d293abc0SKuninori Morimoto
test_component_timer_stop(struct test_priv * priv)408d293abc0SKuninori Morimoto static void test_component_timer_stop(struct test_priv *priv)
409d293abc0SKuninori Morimoto {
410d293abc0SKuninori Morimoto cancel_delayed_work(&priv->dwork);
411d293abc0SKuninori Morimoto }
412d293abc0SKuninori Morimoto
test_component_timer_start(struct test_priv * priv)413d293abc0SKuninori Morimoto static void test_component_timer_start(struct test_priv *priv)
414d293abc0SKuninori Morimoto {
415d293abc0SKuninori Morimoto schedule_delayed_work(&priv->dwork, msecs_to_jiffies(10));
416d293abc0SKuninori Morimoto }
417d293abc0SKuninori Morimoto
test_component_dwork(struct work_struct * work)418d293abc0SKuninori Morimoto static void test_component_dwork(struct work_struct *work)
419d293abc0SKuninori Morimoto {
420d293abc0SKuninori Morimoto struct test_priv *priv = container_of(work, struct test_priv, dwork.work);
421d293abc0SKuninori Morimoto
422d293abc0SKuninori Morimoto if (priv->substream)
423d293abc0SKuninori Morimoto snd_pcm_period_elapsed(priv->substream);
424d293abc0SKuninori Morimoto
425d293abc0SKuninori Morimoto test_component_timer_start(priv);
426d293abc0SKuninori Morimoto }
427d293abc0SKuninori Morimoto
test_component_trigger(struct snd_soc_component * component,struct snd_pcm_substream * substream,int cmd)428d293abc0SKuninori Morimoto static int test_component_trigger(struct snd_soc_component *component,
429d293abc0SKuninori Morimoto struct snd_pcm_substream *substream, int cmd)
430d293abc0SKuninori Morimoto {
431d293abc0SKuninori Morimoto struct test_priv *priv = dev_get_drvdata(component->dev);
432d293abc0SKuninori Morimoto
433d293abc0SKuninori Morimoto mile_stone(component);
434d293abc0SKuninori Morimoto
435d293abc0SKuninori Morimoto switch (cmd) {
436d293abc0SKuninori Morimoto case SNDRV_PCM_TRIGGER_START:
437d293abc0SKuninori Morimoto test_component_timer_start(priv);
438d293abc0SKuninori Morimoto priv->substream = substream; /* set substream later */
439d293abc0SKuninori Morimoto break;
440d293abc0SKuninori Morimoto case SNDRV_PCM_TRIGGER_STOP:
441d293abc0SKuninori Morimoto priv->substream = NULL;
442d293abc0SKuninori Morimoto test_component_timer_stop(priv);
443d293abc0SKuninori Morimoto }
444d293abc0SKuninori Morimoto
445d293abc0SKuninori Morimoto return 0;
446d293abc0SKuninori Morimoto }
447d293abc0SKuninori Morimoto
test_component_sync_stop(struct snd_soc_component * component,struct snd_pcm_substream * substream)448d293abc0SKuninori Morimoto static int test_component_sync_stop(struct snd_soc_component *component,
449d293abc0SKuninori Morimoto struct snd_pcm_substream *substream)
450d293abc0SKuninori Morimoto {
451d293abc0SKuninori Morimoto mile_stone(component);
452d293abc0SKuninori Morimoto
453d293abc0SKuninori Morimoto return 0;
454d293abc0SKuninori Morimoto }
455d293abc0SKuninori Morimoto
test_component_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)456d293abc0SKuninori Morimoto static snd_pcm_uframes_t test_component_pointer(struct snd_soc_component *component,
457d293abc0SKuninori Morimoto struct snd_pcm_substream *substream)
458d293abc0SKuninori Morimoto {
459d293abc0SKuninori Morimoto struct snd_pcm_runtime *runtime = substream->runtime;
460d293abc0SKuninori Morimoto static int pointer;
461d293abc0SKuninori Morimoto
462d293abc0SKuninori Morimoto if (!runtime)
463d293abc0SKuninori Morimoto return 0;
464d293abc0SKuninori Morimoto
465d293abc0SKuninori Morimoto pointer += 10;
466d293abc0SKuninori Morimoto if (pointer > PREALLOC_BUFFER)
467d293abc0SKuninori Morimoto pointer = 0;
468d293abc0SKuninori Morimoto
469d293abc0SKuninori Morimoto /* mile_stone(component); */
470d293abc0SKuninori Morimoto
471d293abc0SKuninori Morimoto return bytes_to_frames(runtime, pointer);
472d293abc0SKuninori Morimoto }
473d293abc0SKuninori Morimoto
test_component_get_time_info(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct timespec64 * system_ts,struct timespec64 * audio_ts,struct snd_pcm_audio_tstamp_config * audio_tstamp_config,struct snd_pcm_audio_tstamp_report * audio_tstamp_report)474d293abc0SKuninori Morimoto static int test_component_get_time_info(struct snd_soc_component *component,
475d293abc0SKuninori Morimoto struct snd_pcm_substream *substream,
476d293abc0SKuninori Morimoto struct timespec64 *system_ts,
477d293abc0SKuninori Morimoto struct timespec64 *audio_ts,
478d293abc0SKuninori Morimoto struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
479d293abc0SKuninori Morimoto struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
480d293abc0SKuninori Morimoto {
481d293abc0SKuninori Morimoto mile_stone(component);
482d293abc0SKuninori Morimoto
483d293abc0SKuninori Morimoto return 0;
484d293abc0SKuninori Morimoto }
485d293abc0SKuninori Morimoto
test_component_be_hw_params_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)486d293abc0SKuninori Morimoto static int test_component_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
487d293abc0SKuninori Morimoto struct snd_pcm_hw_params *params)
488d293abc0SKuninori Morimoto {
489d293abc0SKuninori Morimoto mile_stone_x(rtd->dev);
490d293abc0SKuninori Morimoto
491d293abc0SKuninori Morimoto return 0;
492d293abc0SKuninori Morimoto }
493d293abc0SKuninori Morimoto
494d293abc0SKuninori Morimoto /* CPU */
495d293abc0SKuninori Morimoto static const struct test_adata test_cpu = { .is_cpu = 1, .cmp_v = 0, .dai_v = 0, };
496d293abc0SKuninori Morimoto static const struct test_adata test_cpu_vv = { .is_cpu = 1, .cmp_v = 1, .dai_v = 1, };
497d293abc0SKuninori Morimoto static const struct test_adata test_cpu_nv = { .is_cpu = 1, .cmp_v = 0, .dai_v = 1, };
498d293abc0SKuninori Morimoto static const struct test_adata test_cpu_vn = { .is_cpu = 1, .cmp_v = 1, .dai_v = 0, };
499d293abc0SKuninori Morimoto /* Codec */
500d293abc0SKuninori Morimoto static const struct test_adata test_codec = { .is_cpu = 0, .cmp_v = 0, .dai_v = 0, };
501d293abc0SKuninori Morimoto static const struct test_adata test_codec_vv = { .is_cpu = 0, .cmp_v = 1, .dai_v = 1, };
502d293abc0SKuninori Morimoto static const struct test_adata test_codec_nv = { .is_cpu = 0, .cmp_v = 0, .dai_v = 1, };
503d293abc0SKuninori Morimoto static const struct test_adata test_codec_vn = { .is_cpu = 0, .cmp_v = 1, .dai_v = 0, };
504d293abc0SKuninori Morimoto
505d293abc0SKuninori Morimoto static const struct of_device_id test_of_match[] = {
506d293abc0SKuninori Morimoto { .compatible = "test-cpu", .data = (void *)&test_cpu, },
507d293abc0SKuninori Morimoto { .compatible = "test-cpu-verbose", .data = (void *)&test_cpu_vv, },
508d293abc0SKuninori Morimoto { .compatible = "test-cpu-verbose-dai", .data = (void *)&test_cpu_nv, },
509d293abc0SKuninori Morimoto { .compatible = "test-cpu-verbose-component", .data = (void *)&test_cpu_vn, },
510d293abc0SKuninori Morimoto { .compatible = "test-codec", .data = (void *)&test_codec, },
511d293abc0SKuninori Morimoto { .compatible = "test-codec-verbose", .data = (void *)&test_codec_vv, },
512d293abc0SKuninori Morimoto { .compatible = "test-codec-verbose-dai", .data = (void *)&test_codec_nv, },
513d293abc0SKuninori Morimoto { .compatible = "test-codec-verbose-component", .data = (void *)&test_codec_vn, },
514d293abc0SKuninori Morimoto {},
515d293abc0SKuninori Morimoto };
516d293abc0SKuninori Morimoto MODULE_DEVICE_TABLE(of, test_of_match);
517d293abc0SKuninori Morimoto
518d293abc0SKuninori Morimoto static const struct snd_soc_dapm_widget widgets[] = {
519d293abc0SKuninori Morimoto /*
520d293abc0SKuninori Morimoto * FIXME
521d293abc0SKuninori Morimoto *
522d293abc0SKuninori Morimoto * Just IN/OUT is OK for now,
523d293abc0SKuninori Morimoto * but need to be updated ?
524d293abc0SKuninori Morimoto */
525d293abc0SKuninori Morimoto SND_SOC_DAPM_INPUT("IN"),
526d293abc0SKuninori Morimoto SND_SOC_DAPM_OUTPUT("OUT"),
527d293abc0SKuninori Morimoto };
528d293abc0SKuninori Morimoto
test_driver_probe(struct platform_device * pdev)529d293abc0SKuninori Morimoto static int test_driver_probe(struct platform_device *pdev)
530d293abc0SKuninori Morimoto {
531d293abc0SKuninori Morimoto struct device *dev = &pdev->dev;
532d293abc0SKuninori Morimoto struct device_node *node = dev->of_node;
533d293abc0SKuninori Morimoto struct device_node *ep;
534befe3045SAmeer Hamza const struct test_adata *adata = of_device_get_match_data(&pdev->dev);
535d293abc0SKuninori Morimoto struct snd_soc_component_driver *cdriv;
536d293abc0SKuninori Morimoto struct snd_soc_dai_driver *ddriv;
537d293abc0SKuninori Morimoto struct test_dai_name *dname;
538d293abc0SKuninori Morimoto struct test_priv *priv;
539d293abc0SKuninori Morimoto int num, ret, i;
540d293abc0SKuninori Morimoto
541d293abc0SKuninori Morimoto num = of_graph_get_endpoint_count(node);
542d293abc0SKuninori Morimoto if (!num) {
543d293abc0SKuninori Morimoto dev_err(dev, "no port exits\n");
544d293abc0SKuninori Morimoto return -EINVAL;
545d293abc0SKuninori Morimoto }
546d293abc0SKuninori Morimoto
547d293abc0SKuninori Morimoto priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
548d293abc0SKuninori Morimoto cdriv = devm_kzalloc(dev, sizeof(*cdriv), GFP_KERNEL);
549d293abc0SKuninori Morimoto ddriv = devm_kzalloc(dev, sizeof(*ddriv) * num, GFP_KERNEL);
550d293abc0SKuninori Morimoto dname = devm_kzalloc(dev, sizeof(*dname) * num, GFP_KERNEL);
551befe3045SAmeer Hamza if (!priv || !cdriv || !ddriv || !dname || !adata)
552d293abc0SKuninori Morimoto return -EINVAL;
553d293abc0SKuninori Morimoto
554d293abc0SKuninori Morimoto priv->dev = dev;
555d293abc0SKuninori Morimoto priv->component_driver = cdriv;
556d293abc0SKuninori Morimoto priv->dai_driver = ddriv;
557d293abc0SKuninori Morimoto priv->name = dname;
558d293abc0SKuninori Morimoto
559d293abc0SKuninori Morimoto INIT_DELAYED_WORK(&priv->dwork, test_component_dwork);
560d293abc0SKuninori Morimoto dev_set_drvdata(dev, priv);
561d293abc0SKuninori Morimoto
562d293abc0SKuninori Morimoto if (adata->is_cpu) {
563d293abc0SKuninori Morimoto cdriv->name = "test_cpu";
564d293abc0SKuninori Morimoto cdriv->pcm_construct = test_component_pcm_construct;
565d293abc0SKuninori Morimoto cdriv->pointer = test_component_pointer;
566d293abc0SKuninori Morimoto cdriv->trigger = test_component_trigger;
567d73130baSCharles Keepax cdriv->legacy_dai_naming = 1;
568d293abc0SKuninori Morimoto } else {
569d293abc0SKuninori Morimoto cdriv->name = "test_codec";
570d293abc0SKuninori Morimoto cdriv->idle_bias_on = 1;
571d293abc0SKuninori Morimoto cdriv->endianness = 1;
572d293abc0SKuninori Morimoto }
573d293abc0SKuninori Morimoto
574d293abc0SKuninori Morimoto cdriv->open = test_component_open;
575d293abc0SKuninori Morimoto cdriv->dapm_widgets = widgets;
576d293abc0SKuninori Morimoto cdriv->num_dapm_widgets = ARRAY_SIZE(widgets);
577d293abc0SKuninori Morimoto
578d293abc0SKuninori Morimoto if (adata->cmp_v) {
579d293abc0SKuninori Morimoto cdriv->probe = test_component_probe;
580d293abc0SKuninori Morimoto cdriv->remove = test_component_remove;
581d293abc0SKuninori Morimoto cdriv->suspend = test_component_suspend;
582d293abc0SKuninori Morimoto cdriv->resume = test_component_resume;
583d293abc0SKuninori Morimoto cdriv->set_sysclk = test_component_set_sysclk;
584d293abc0SKuninori Morimoto cdriv->set_pll = test_component_set_pll;
585d293abc0SKuninori Morimoto cdriv->set_jack = test_component_set_jack;
586d293abc0SKuninori Morimoto cdriv->seq_notifier = test_component_seq_notifier;
587d293abc0SKuninori Morimoto cdriv->stream_event = test_component_stream_event;
588d293abc0SKuninori Morimoto cdriv->set_bias_level = test_component_set_bias_level;
589d293abc0SKuninori Morimoto cdriv->close = test_component_close;
590d293abc0SKuninori Morimoto cdriv->ioctl = test_component_ioctl;
591d293abc0SKuninori Morimoto cdriv->hw_params = test_component_hw_params;
592d293abc0SKuninori Morimoto cdriv->hw_free = test_component_hw_free;
593d293abc0SKuninori Morimoto cdriv->prepare = test_component_prepare;
594d293abc0SKuninori Morimoto cdriv->sync_stop = test_component_sync_stop;
595d293abc0SKuninori Morimoto cdriv->get_time_info = test_component_get_time_info;
596d293abc0SKuninori Morimoto cdriv->be_hw_params_fixup = test_component_be_hw_params_fixup;
597d293abc0SKuninori Morimoto
598d293abc0SKuninori Morimoto if (adata->is_cpu)
599d293abc0SKuninori Morimoto cdriv->pcm_destruct = test_component_pcm_destruct;
600d293abc0SKuninori Morimoto }
601d293abc0SKuninori Morimoto
602d293abc0SKuninori Morimoto i = 0;
603d293abc0SKuninori Morimoto for_each_endpoint_of_node(node, ep) {
604d293abc0SKuninori Morimoto snprintf(dname[i].name, TEST_NAME_LEN, "%s.%d", node->name, i);
605d293abc0SKuninori Morimoto ddriv[i].name = dname[i].name;
606d293abc0SKuninori Morimoto
607d293abc0SKuninori Morimoto snprintf(dname[i].name_playback, TEST_NAME_LEN, "DAI%d Playback", i);
608d293abc0SKuninori Morimoto ddriv[i].playback.stream_name = dname[i].name_playback;
609d293abc0SKuninori Morimoto ddriv[i].playback.channels_min = 1;
610d293abc0SKuninori Morimoto ddriv[i].playback.channels_max = 384;
611d293abc0SKuninori Morimoto ddriv[i].playback.rates = STUB_RATES;
612d293abc0SKuninori Morimoto ddriv[i].playback.formats = STUB_FORMATS;
613d293abc0SKuninori Morimoto
614d293abc0SKuninori Morimoto snprintf(dname[i].name_capture, TEST_NAME_LEN, "DAI%d Capture", i);
615d293abc0SKuninori Morimoto ddriv[i].capture.stream_name = dname[i].name_capture;
616d293abc0SKuninori Morimoto ddriv[i].capture.channels_min = 1;
617d293abc0SKuninori Morimoto ddriv[i].capture.channels_max = 384;
618d293abc0SKuninori Morimoto ddriv[i].capture.rates = STUB_RATES;
619d293abc0SKuninori Morimoto ddriv[i].capture.formats = STUB_FORMATS;
620d293abc0SKuninori Morimoto
621d293abc0SKuninori Morimoto if (adata->dai_v)
622d293abc0SKuninori Morimoto ddriv[i].ops = &test_verbose_ops;
623d293abc0SKuninori Morimoto else
624d293abc0SKuninori Morimoto ddriv[i].ops = &test_ops;
625d293abc0SKuninori Morimoto
626d293abc0SKuninori Morimoto i++;
627d293abc0SKuninori Morimoto }
628d293abc0SKuninori Morimoto
629d293abc0SKuninori Morimoto ret = devm_snd_soc_register_component(dev, cdriv, ddriv, num);
630d293abc0SKuninori Morimoto if (ret < 0)
631d293abc0SKuninori Morimoto return ret;
632d293abc0SKuninori Morimoto
633d293abc0SKuninori Morimoto mile_stone_x(dev);
634d293abc0SKuninori Morimoto
635d293abc0SKuninori Morimoto return 0;
636d293abc0SKuninori Morimoto }
637d293abc0SKuninori Morimoto
test_driver_remove(struct platform_device * pdev)638*53946256SUwe Kleine-König static void test_driver_remove(struct platform_device *pdev)
639d293abc0SKuninori Morimoto {
640d293abc0SKuninori Morimoto mile_stone_x(&pdev->dev);
641d293abc0SKuninori Morimoto }
642d293abc0SKuninori Morimoto
643d293abc0SKuninori Morimoto static struct platform_driver test_driver = {
644d293abc0SKuninori Morimoto .driver = {
645d293abc0SKuninori Morimoto .name = "test-component",
646d293abc0SKuninori Morimoto .of_match_table = test_of_match,
647d293abc0SKuninori Morimoto },
648d293abc0SKuninori Morimoto .probe = test_driver_probe,
649*53946256SUwe Kleine-König .remove_new = test_driver_remove,
650d293abc0SKuninori Morimoto };
651d293abc0SKuninori Morimoto module_platform_driver(test_driver);
652d293abc0SKuninori Morimoto
653d293abc0SKuninori Morimoto MODULE_ALIAS("platform:asoc-test-component");
654d293abc0SKuninori Morimoto MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
655d293abc0SKuninori Morimoto MODULE_DESCRIPTION("ASoC Test Component");
656d293abc0SKuninori Morimoto MODULE_LICENSE("GPL v2");
657