xref: /openbmc/linux/sound/soc/generic/test-component.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
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