xref: /linux/sound/soc/generic/test-component.c (revision 3fd6c59042dbba50391e30862beac979491145fe)
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_mute_stream(struct snd_soc_dai * dai,int mute,int stream)143  static int test_dai_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
144  {
145  	mile_stone(dai);
146  
147  	return 0;
148  }
149  
test_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)150  static int test_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
151  {
152  	mile_stone(dai);
153  
154  	return 0;
155  }
156  
test_dai_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)157  static void test_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
158  {
159  	mile_stone(dai);
160  }
161  
test_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)162  static int test_dai_hw_params(struct snd_pcm_substream *substream,
163  			      struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
164  {
165  	mile_stone(dai);
166  
167  	return 0;
168  }
169  
test_dai_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)170  static int test_dai_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
171  {
172  	mile_stone(dai);
173  
174  	return 0;
175  }
176  
test_dai_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)177  static int test_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
178  {
179  	mile_stone(dai);
180  
181  	return 0;
182  }
183  
184  static const u64 test_dai_formats =
185  	/*
186  	 * Select below from Sound Card, not auto
187  	 *	SND_SOC_POSSIBLE_DAIFMT_BP_FP
188  	 *	SND_SOC_POSSIBLE_DAIFMT_BC_FP
189  	 *	SND_SOC_POSSIBLE_DAIFMT_BP_FC
190  	 *	SND_SOC_POSSIBLE_DAIFMT_BC_FC
191  	 */
192  	SND_SOC_POSSIBLE_DAIFMT_I2S	|
193  	SND_SOC_POSSIBLE_DAIFMT_RIGHT_J	|
194  	SND_SOC_POSSIBLE_DAIFMT_LEFT_J	|
195  	SND_SOC_POSSIBLE_DAIFMT_DSP_A	|
196  	SND_SOC_POSSIBLE_DAIFMT_DSP_B	|
197  	SND_SOC_POSSIBLE_DAIFMT_AC97	|
198  	SND_SOC_POSSIBLE_DAIFMT_PDM	|
199  	SND_SOC_POSSIBLE_DAIFMT_NB_NF	|
200  	SND_SOC_POSSIBLE_DAIFMT_NB_IF	|
201  	SND_SOC_POSSIBLE_DAIFMT_IB_NF	|
202  	SND_SOC_POSSIBLE_DAIFMT_IB_IF;
203  
204  static const struct snd_soc_dai_ops test_ops = {
205  	.set_fmt		= test_dai_set_fmt,
206  	.startup		= test_dai_startup,
207  	.shutdown		= test_dai_shutdown,
208  	.auto_selectable_formats	= &test_dai_formats,
209  	.num_auto_selectable_formats	= 1,
210  };
211  
212  static const struct snd_soc_dai_ops test_verbose_ops = {
213  	.set_sysclk		= test_dai_set_sysclk,
214  	.set_pll		= test_dai_set_pll,
215  	.set_clkdiv		= test_dai_set_clkdiv,
216  	.set_fmt		= test_dai_set_fmt,
217  	.mute_stream		= test_dai_mute_stream,
218  	.startup		= test_dai_startup,
219  	.shutdown		= test_dai_shutdown,
220  	.hw_params		= test_dai_hw_params,
221  	.hw_free		= test_dai_hw_free,
222  	.trigger		= test_dai_trigger,
223  	.auto_selectable_formats	= &test_dai_formats,
224  	.num_auto_selectable_formats	= 1,
225  };
226  
227  #define STUB_RATES	SNDRV_PCM_RATE_CONTINUOUS
228  #define STUB_FORMATS	(SNDRV_PCM_FMTBIT_S8		| \
229  			 SNDRV_PCM_FMTBIT_U8		| \
230  			 SNDRV_PCM_FMTBIT_S16_LE	| \
231  			 SNDRV_PCM_FMTBIT_U16_LE	| \
232  			 SNDRV_PCM_FMTBIT_S24_LE	| \
233  			 SNDRV_PCM_FMTBIT_S24_3LE	| \
234  			 SNDRV_PCM_FMTBIT_U24_LE	| \
235  			 SNDRV_PCM_FMTBIT_S32_LE	| \
236  			 SNDRV_PCM_FMTBIT_U32_LE)
237  
test_component_probe(struct snd_soc_component * component)238  static int test_component_probe(struct snd_soc_component *component)
239  {
240  	mile_stone(component);
241  
242  	return 0;
243  }
244  
test_component_remove(struct snd_soc_component * component)245  static void test_component_remove(struct snd_soc_component *component)
246  {
247  	mile_stone(component);
248  }
249  
test_component_suspend(struct snd_soc_component * component)250  static int test_component_suspend(struct snd_soc_component *component)
251  {
252  	mile_stone(component);
253  
254  	return 0;
255  }
256  
test_component_resume(struct snd_soc_component * component)257  static int test_component_resume(struct snd_soc_component *component)
258  {
259  	mile_stone(component);
260  
261  	return 0;
262  }
263  
264  #define PREALLOC_BUFFER		(32 * 1024)
test_component_pcm_construct(struct snd_soc_component * component,struct snd_soc_pcm_runtime * rtd)265  static int test_component_pcm_construct(struct snd_soc_component *component,
266  					struct snd_soc_pcm_runtime *rtd)
267  {
268  	mile_stone(component);
269  
270  	snd_pcm_set_managed_buffer_all(
271  		rtd->pcm,
272  		SNDRV_DMA_TYPE_DEV,
273  		rtd->card->snd_card->dev,
274  		PREALLOC_BUFFER, PREALLOC_BUFFER);
275  
276  	return 0;
277  }
278  
test_component_pcm_destruct(struct snd_soc_component * component,struct snd_pcm * pcm)279  static void test_component_pcm_destruct(struct snd_soc_component *component,
280  					struct snd_pcm *pcm)
281  {
282  	mile_stone(component);
283  }
284  
test_component_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)285  static int test_component_set_sysclk(struct snd_soc_component *component,
286  				     int clk_id, int source, unsigned int freq, int dir)
287  {
288  	mile_stone(component);
289  
290  	return 0;
291  }
292  
test_component_set_pll(struct snd_soc_component * component,int pll_id,int source,unsigned int freq_in,unsigned int freq_out)293  static int test_component_set_pll(struct snd_soc_component *component, int pll_id,
294  				  int source, unsigned int freq_in, unsigned int freq_out)
295  {
296  	mile_stone(component);
297  
298  	return 0;
299  }
300  
test_component_set_jack(struct snd_soc_component * component,struct snd_soc_jack * jack,void * data)301  static int test_component_set_jack(struct snd_soc_component *component,
302  				   struct snd_soc_jack *jack,  void *data)
303  {
304  	mile_stone(component);
305  
306  	return 0;
307  }
308  
test_component_seq_notifier(struct snd_soc_component * component,enum snd_soc_dapm_type type,int subseq)309  static void test_component_seq_notifier(struct snd_soc_component *component,
310  					enum snd_soc_dapm_type type, int subseq)
311  {
312  	mile_stone(component);
313  }
314  
test_component_stream_event(struct snd_soc_component * component,int event)315  static int test_component_stream_event(struct snd_soc_component *component, int event)
316  {
317  	mile_stone(component);
318  
319  	return 0;
320  }
321  
test_component_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)322  static int test_component_set_bias_level(struct snd_soc_component *component,
323  					 enum snd_soc_bias_level level)
324  {
325  	mile_stone(component);
326  
327  	return 0;
328  }
329  
330  static const struct snd_pcm_hardware test_component_hardware = {
331  	/* Random values to keep userspace happy when checking constraints */
332  	.info			= SNDRV_PCM_INFO_INTERLEAVED	|
333  				  SNDRV_PCM_INFO_MMAP		|
334  				  SNDRV_PCM_INFO_MMAP_VALID,
335  	.buffer_bytes_max	= 32 * 1024,
336  	.period_bytes_min	= 32,
337  	.period_bytes_max	= 8192,
338  	.periods_min		= 1,
339  	.periods_max		= 128,
340  	.fifo_size		= 256,
341  };
342  
test_component_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)343  static int test_component_open(struct snd_soc_component *component,
344  			       struct snd_pcm_substream *substream)
345  {
346  	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
347  
348  	mile_stone(component);
349  
350  	/* BE's dont need dummy params */
351  	if (!rtd->dai_link->no_pcm)
352  		snd_soc_set_runtime_hwparams(substream, &test_component_hardware);
353  
354  	return 0;
355  }
356  
test_component_close(struct snd_soc_component * component,struct snd_pcm_substream * substream)357  static int test_component_close(struct snd_soc_component *component,
358  				struct snd_pcm_substream *substream)
359  {
360  	mile_stone(component);
361  
362  	return 0;
363  }
364  
test_component_ioctl(struct snd_soc_component * component,struct snd_pcm_substream * substream,unsigned int cmd,void * arg)365  static int test_component_ioctl(struct snd_soc_component *component,
366  				struct snd_pcm_substream *substream,
367  				unsigned int cmd, void *arg)
368  {
369  	mile_stone(component);
370  
371  	return 0;
372  }
373  
test_component_hw_params(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)374  static int test_component_hw_params(struct snd_soc_component *component,
375  				    struct snd_pcm_substream *substream,
376  				    struct snd_pcm_hw_params *params)
377  {
378  	mile_stone(component);
379  
380  	return 0;
381  }
382  
test_component_hw_free(struct snd_soc_component * component,struct snd_pcm_substream * substream)383  static int test_component_hw_free(struct snd_soc_component *component,
384  				  struct snd_pcm_substream *substream)
385  {
386  	mile_stone(component);
387  
388  	return 0;
389  }
390  
test_component_prepare(struct snd_soc_component * component,struct snd_pcm_substream * substream)391  static int test_component_prepare(struct snd_soc_component *component,
392  				  struct snd_pcm_substream *substream)
393  {
394  	mile_stone(component);
395  
396  	return 0;
397  }
398  
test_component_timer_stop(struct test_priv * priv)399  static void test_component_timer_stop(struct test_priv *priv)
400  {
401  	cancel_delayed_work(&priv->dwork);
402  }
403  
test_component_timer_start(struct test_priv * priv)404  static void test_component_timer_start(struct test_priv *priv)
405  {
406  	schedule_delayed_work(&priv->dwork, msecs_to_jiffies(10));
407  }
408  
test_component_dwork(struct work_struct * work)409  static void test_component_dwork(struct work_struct *work)
410  {
411  	struct test_priv *priv = container_of(work, struct test_priv, dwork.work);
412  
413  	if (priv->substream)
414  		snd_pcm_period_elapsed(priv->substream);
415  
416  	test_component_timer_start(priv);
417  }
418  
test_component_trigger(struct snd_soc_component * component,struct snd_pcm_substream * substream,int cmd)419  static int test_component_trigger(struct snd_soc_component *component,
420  				  struct snd_pcm_substream *substream, int cmd)
421  {
422  	struct test_priv *priv = dev_get_drvdata(component->dev);
423  
424  	mile_stone(component);
425  
426  	switch (cmd) {
427  	case SNDRV_PCM_TRIGGER_START:
428  		test_component_timer_start(priv);
429  		priv->substream = substream; /* set substream later */
430  		break;
431  	case SNDRV_PCM_TRIGGER_STOP:
432  		priv->substream = NULL;
433  		test_component_timer_stop(priv);
434  	}
435  
436  	return 0;
437  }
438  
test_component_sync_stop(struct snd_soc_component * component,struct snd_pcm_substream * substream)439  static int test_component_sync_stop(struct snd_soc_component *component,
440  				    struct snd_pcm_substream *substream)
441  {
442  	mile_stone(component);
443  
444  	return 0;
445  }
446  
test_component_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)447  static snd_pcm_uframes_t test_component_pointer(struct snd_soc_component *component,
448  						struct snd_pcm_substream *substream)
449  {
450  	struct snd_pcm_runtime *runtime = substream->runtime;
451  	static int pointer;
452  
453  	if (!runtime)
454  		return 0;
455  
456  	pointer += 10;
457  	if (pointer > PREALLOC_BUFFER)
458  		pointer = 0;
459  
460  	/* mile_stone(component); */
461  
462  	return bytes_to_frames(runtime, pointer);
463  }
464  
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)465  static int test_component_get_time_info(struct snd_soc_component *component,
466  					struct snd_pcm_substream *substream,
467  					struct timespec64 *system_ts,
468  					struct timespec64 *audio_ts,
469  					struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
470  					struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
471  {
472  	mile_stone(component);
473  
474  	return 0;
475  }
476  
test_component_be_hw_params_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)477  static int test_component_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
478  					     struct snd_pcm_hw_params *params)
479  {
480  	mile_stone_x(rtd->dev);
481  
482  	return 0;
483  }
484  
485  /* CPU */
486  static const struct test_adata test_cpu		= { .is_cpu = 1, .cmp_v = 0, .dai_v = 0, };
487  static const struct test_adata test_cpu_vv	= { .is_cpu = 1, .cmp_v = 1, .dai_v = 1, };
488  static const struct test_adata test_cpu_nv	= { .is_cpu = 1, .cmp_v = 0, .dai_v = 1, };
489  static const struct test_adata test_cpu_vn	= { .is_cpu = 1, .cmp_v = 1, .dai_v = 0, };
490  /* Codec */
491  static const struct test_adata test_codec	= { .is_cpu = 0, .cmp_v = 0, .dai_v = 0, };
492  static const struct test_adata test_codec_vv	= { .is_cpu = 0, .cmp_v = 1, .dai_v = 1, };
493  static const struct test_adata test_codec_nv	= { .is_cpu = 0, .cmp_v = 0, .dai_v = 1, };
494  static const struct test_adata test_codec_vn	= { .is_cpu = 0, .cmp_v = 1, .dai_v = 0, };
495  
496  static const struct of_device_id test_of_match[] = {
497  	{ .compatible = "test-cpu",			.data = (void *)&test_cpu,    },
498  	{ .compatible = "test-cpu-verbose",		.data = (void *)&test_cpu_vv, },
499  	{ .compatible = "test-cpu-verbose-dai",		.data = (void *)&test_cpu_nv, },
500  	{ .compatible = "test-cpu-verbose-component",	.data = (void *)&test_cpu_vn, },
501  	{ .compatible = "test-codec",			.data = (void *)&test_codec,    },
502  	{ .compatible = "test-codec-verbose",		.data = (void *)&test_codec_vv, },
503  	{ .compatible = "test-codec-verbose-dai",	.data = (void *)&test_codec_nv, },
504  	{ .compatible = "test-codec-verbose-component",	.data = (void *)&test_codec_vn, },
505  	{},
506  };
507  MODULE_DEVICE_TABLE(of, test_of_match);
508  
509  static const struct snd_soc_dapm_widget widgets[] = {
510  	/*
511  	 * FIXME
512  	 *
513  	 * Just IN/OUT is OK for now,
514  	 * but need to be updated ?
515  	 */
516  	SND_SOC_DAPM_INPUT("IN"),
517  	SND_SOC_DAPM_OUTPUT("OUT"),
518  };
519  
test_driver_probe(struct platform_device * pdev)520  static int test_driver_probe(struct platform_device *pdev)
521  {
522  	struct device *dev = &pdev->dev;
523  	struct device_node *node = dev->of_node;
524  	const struct test_adata *adata = of_device_get_match_data(&pdev->dev);
525  	struct snd_soc_component_driver *cdriv;
526  	struct snd_soc_dai_driver *ddriv;
527  	struct test_dai_name *dname;
528  	struct test_priv *priv;
529  	int num, ret, i;
530  
531  	num = of_graph_get_endpoint_count(node);
532  	if (!num) {
533  		dev_err(dev, "no port exits\n");
534  		return -EINVAL;
535  	}
536  
537  	priv	= devm_kzalloc(dev, sizeof(*priv),		GFP_KERNEL);
538  	cdriv	= devm_kzalloc(dev, sizeof(*cdriv),		GFP_KERNEL);
539  	ddriv	= devm_kzalloc(dev, sizeof(*ddriv) * num,	GFP_KERNEL);
540  	dname	= devm_kzalloc(dev, sizeof(*dname) * num,	GFP_KERNEL);
541  	if (!priv || !cdriv || !ddriv || !dname || !adata)
542  		return -EINVAL;
543  
544  	priv->dev		= dev;
545  	priv->component_driver	= cdriv;
546  	priv->dai_driver	= ddriv;
547  	priv->name		= dname;
548  
549  	INIT_DELAYED_WORK(&priv->dwork, test_component_dwork);
550  	dev_set_drvdata(dev, priv);
551  
552  	if (adata->is_cpu) {
553  		cdriv->name			= "test_cpu";
554  		cdriv->pcm_construct		= test_component_pcm_construct;
555  		cdriv->pointer			= test_component_pointer;
556  		cdriv->trigger			= test_component_trigger;
557  		cdriv->legacy_dai_naming	= 1;
558  	} else {
559  		cdriv->name			= "test_codec";
560  		cdriv->idle_bias_on		= 1;
561  		cdriv->endianness		= 1;
562  	}
563  
564  	cdriv->open		= test_component_open;
565  	cdriv->dapm_widgets	= widgets;
566  	cdriv->num_dapm_widgets	= ARRAY_SIZE(widgets);
567  
568  	if (adata->cmp_v) {
569  		cdriv->probe			= test_component_probe;
570  		cdriv->remove			= test_component_remove;
571  		cdriv->suspend			= test_component_suspend;
572  		cdriv->resume			= test_component_resume;
573  		cdriv->set_sysclk		= test_component_set_sysclk;
574  		cdriv->set_pll			= test_component_set_pll;
575  		cdriv->set_jack			= test_component_set_jack;
576  		cdriv->seq_notifier		= test_component_seq_notifier;
577  		cdriv->stream_event		= test_component_stream_event;
578  		cdriv->set_bias_level		= test_component_set_bias_level;
579  		cdriv->close			= test_component_close;
580  		cdriv->ioctl			= test_component_ioctl;
581  		cdriv->hw_params		= test_component_hw_params;
582  		cdriv->hw_free			= test_component_hw_free;
583  		cdriv->prepare			= test_component_prepare;
584  		cdriv->sync_stop		= test_component_sync_stop;
585  		cdriv->get_time_info		= test_component_get_time_info;
586  		cdriv->be_hw_params_fixup	= test_component_be_hw_params_fixup;
587  
588  		if (adata->is_cpu)
589  			cdriv->pcm_destruct	= test_component_pcm_destruct;
590  	}
591  
592  	i = 0;
593  	for_each_of_graph_port(node, port) {
594  		snprintf(dname[i].name, TEST_NAME_LEN, "%s.%d", node->name, i);
595  		ddriv[i].name = dname[i].name;
596  
597  		snprintf(dname[i].name_playback, TEST_NAME_LEN, "DAI%d Playback", i);
598  		ddriv[i].playback.stream_name	= dname[i].name_playback;
599  		ddriv[i].playback.channels_min	= 1;
600  		ddriv[i].playback.channels_max	= 384;
601  		ddriv[i].playback.rates		= STUB_RATES;
602  		ddriv[i].playback.formats	= STUB_FORMATS;
603  
604  		snprintf(dname[i].name_capture, TEST_NAME_LEN, "DAI%d Capture", i);
605  		ddriv[i].capture.stream_name	= dname[i].name_capture;
606  		ddriv[i].capture.channels_min	= 1;
607  		ddriv[i].capture.channels_max	= 384;
608  		ddriv[i].capture.rates		= STUB_RATES;
609  		ddriv[i].capture.formats	= STUB_FORMATS;
610  
611  		if (adata->dai_v)
612  			ddriv[i].ops = &test_verbose_ops;
613  		else
614  			ddriv[i].ops = &test_ops;
615  
616  		i++;
617  	}
618  
619  	ret = devm_snd_soc_register_component(dev, cdriv, ddriv, num);
620  	if (ret < 0)
621  		return ret;
622  
623  	mile_stone_x(dev);
624  
625  	return 0;
626  }
627  
test_driver_remove(struct platform_device * pdev)628  static void test_driver_remove(struct platform_device *pdev)
629  {
630  	mile_stone_x(&pdev->dev);
631  }
632  
633  static struct platform_driver test_driver = {
634  	.driver = {
635  		.name = "test-component",
636  		.of_match_table = test_of_match,
637  	},
638  	.probe  = test_driver_probe,
639  	.remove = test_driver_remove,
640  };
641  module_platform_driver(test_driver);
642  
643  MODULE_ALIAS("platform:asoc-test-component");
644  MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
645  MODULE_DESCRIPTION("ASoC Test Component");
646  MODULE_LICENSE("GPL v2");
647