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