1c72fcc34Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause
2c72fcc34Sopenharmony_ci//
3c72fcc34Sopenharmony_ci// Copyright(c) 2021 Intel Corporation. All rights reserved.
4c72fcc34Sopenharmony_ci//
5c72fcc34Sopenharmony_ci// Author: Jaska Uimonen <jaska.uimonen@linux.intel.com>
6c72fcc34Sopenharmony_ci
7c72fcc34Sopenharmony_ci#include "aconfig.h"
8c72fcc34Sopenharmony_ci#include <stdint.h>
9c72fcc34Sopenharmony_ci#include <errno.h>
10c72fcc34Sopenharmony_ci#include <stdio.h>
11c72fcc34Sopenharmony_ci#include <stdlib.h>
12c72fcc34Sopenharmony_ci#include <string.h>
13c72fcc34Sopenharmony_ci#include <alsa/input.h>
14c72fcc34Sopenharmony_ci#include <alsa/output.h>
15c72fcc34Sopenharmony_ci#include <alsa/conf.h>
16c72fcc34Sopenharmony_ci#include <alsa/error.h>
17c72fcc34Sopenharmony_ci#include "intel-nhlt.h"
18c72fcc34Sopenharmony_ci#include "ssp-nhlt.h"
19c72fcc34Sopenharmony_ci#include "ssp/ssp-process.h"
20c72fcc34Sopenharmony_ci#include "ssp/ssp-internal.h"
21c72fcc34Sopenharmony_ci
22c72fcc34Sopenharmony_cistatic int set_mn_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
23c72fcc34Sopenharmony_ci{
24c72fcc34Sopenharmony_ci	long m_div;
25c72fcc34Sopenharmony_ci	long n_div;
26c72fcc34Sopenharmony_ci	long ret;
27c72fcc34Sopenharmony_ci
28c72fcc34Sopenharmony_ci	struct dai_values ssp_mn_data[] = {
29c72fcc34Sopenharmony_ci		{"m_div", SND_CONFIG_TYPE_INTEGER, NULL, &m_div, NULL},
30c72fcc34Sopenharmony_ci		{"n_div", SND_CONFIG_TYPE_INTEGER, NULL, &n_div, NULL},
31c72fcc34Sopenharmony_ci	};
32c72fcc34Sopenharmony_ci
33c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_mn_data[0], ARRAY_SIZE(ssp_mn_data), cfg, top,
34c72fcc34Sopenharmony_ci			      "Class.Base.mn_config");
35c72fcc34Sopenharmony_ci	if (ret < 0)
36c72fcc34Sopenharmony_ci		return ret;
37c72fcc34Sopenharmony_ci
38c72fcc34Sopenharmony_ci	return ssp_mn_set_params(nhlt, m_div, n_div);
39c72fcc34Sopenharmony_ci}
40c72fcc34Sopenharmony_ci
41c72fcc34Sopenharmony_cistatic int set_clk_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
42c72fcc34Sopenharmony_ci{
43c72fcc34Sopenharmony_ci	long clock_warm_up;
44c72fcc34Sopenharmony_ci	long mclk;
45c72fcc34Sopenharmony_ci	long warm_up_ovr;
46c72fcc34Sopenharmony_ci	long clock_stop_delay;
47c72fcc34Sopenharmony_ci	long keep_running;
48c72fcc34Sopenharmony_ci	long clock_stop_ovr;
49c72fcc34Sopenharmony_ci	long ret;
50c72fcc34Sopenharmony_ci
51c72fcc34Sopenharmony_ci	struct dai_values ssp_clk_data[] = {
52c72fcc34Sopenharmony_ci		{"clock_warm_up", SND_CONFIG_TYPE_INTEGER, NULL, &clock_warm_up, NULL},
53c72fcc34Sopenharmony_ci		{"mclk", SND_CONFIG_TYPE_INTEGER, NULL, &mclk, NULL},
54c72fcc34Sopenharmony_ci		{"warm_up_ovr", SND_CONFIG_TYPE_INTEGER, NULL, &warm_up_ovr, NULL},
55c72fcc34Sopenharmony_ci		{"clock_stop_delay", SND_CONFIG_TYPE_INTEGER, NULL, &clock_stop_delay, NULL},
56c72fcc34Sopenharmony_ci		{"keep_running", SND_CONFIG_TYPE_INTEGER, NULL, &keep_running, NULL},
57c72fcc34Sopenharmony_ci		{"clock_stop_ovr", SND_CONFIG_TYPE_INTEGER, NULL, &clock_stop_ovr, NULL},
58c72fcc34Sopenharmony_ci	};
59c72fcc34Sopenharmony_ci
60c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_clk_data[0], ARRAY_SIZE(ssp_clk_data), cfg, top,
61c72fcc34Sopenharmony_ci			      "Class.Base.clk_config");
62c72fcc34Sopenharmony_ci	if (ret < 0)
63c72fcc34Sopenharmony_ci		return ret;
64c72fcc34Sopenharmony_ci
65c72fcc34Sopenharmony_ci	return ssp_clk_set_params(nhlt, clock_warm_up, mclk, warm_up_ovr, clock_stop_delay,
66c72fcc34Sopenharmony_ci				  keep_running, clock_stop_ovr);
67c72fcc34Sopenharmony_ci}
68c72fcc34Sopenharmony_ci
69c72fcc34Sopenharmony_cistatic int set_tr_start_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
70c72fcc34Sopenharmony_ci{
71c72fcc34Sopenharmony_ci	long sampling_frequency;
72c72fcc34Sopenharmony_ci	long bit_depth;
73c72fcc34Sopenharmony_ci	long channel_map;
74c72fcc34Sopenharmony_ci	long channel_config;
75c72fcc34Sopenharmony_ci	long interleaving_style;
76c72fcc34Sopenharmony_ci	long number_of_channels;
77c72fcc34Sopenharmony_ci	long valid_bit_depth;
78c72fcc34Sopenharmony_ci	long sample_type;
79c72fcc34Sopenharmony_ci	long ret;
80c72fcc34Sopenharmony_ci
81c72fcc34Sopenharmony_ci	struct dai_values ssp_tr_data[] = {
82c72fcc34Sopenharmony_ci		{"sampling_frequency", SND_CONFIG_TYPE_INTEGER, NULL, &sampling_frequency, NULL},
83c72fcc34Sopenharmony_ci		{"bit_depth", SND_CONFIG_TYPE_INTEGER, NULL, &bit_depth, NULL},
84c72fcc34Sopenharmony_ci		{"channel_map", SND_CONFIG_TYPE_INTEGER, NULL, &channel_map, NULL},
85c72fcc34Sopenharmony_ci		{"channel_config", SND_CONFIG_TYPE_INTEGER, NULL, &channel_config, NULL},
86c72fcc34Sopenharmony_ci		{"interleaving_style", SND_CONFIG_TYPE_INTEGER, NULL, &interleaving_style, NULL},
87c72fcc34Sopenharmony_ci		{"number_of_channels", SND_CONFIG_TYPE_INTEGER, NULL, &number_of_channels, NULL},
88c72fcc34Sopenharmony_ci		{"valid_bit_depth", SND_CONFIG_TYPE_INTEGER, NULL, &valid_bit_depth, NULL},
89c72fcc34Sopenharmony_ci		{"sample_type", SND_CONFIG_TYPE_INTEGER, NULL, &sample_type, NULL},
90c72fcc34Sopenharmony_ci	};
91c72fcc34Sopenharmony_ci
92c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_tr_data[0], ARRAY_SIZE(ssp_tr_data), cfg, top,
93c72fcc34Sopenharmony_ci			      "Class.Base.tr_start_config");
94c72fcc34Sopenharmony_ci	if (ret < 0)
95c72fcc34Sopenharmony_ci		return ret;
96c72fcc34Sopenharmony_ci
97c72fcc34Sopenharmony_ci	return ssp_tr_start_set_params(nhlt, sampling_frequency, bit_depth, channel_map,
98c72fcc34Sopenharmony_ci				       channel_config, interleaving_style, number_of_channels,
99c72fcc34Sopenharmony_ci				       valid_bit_depth,sample_type);
100c72fcc34Sopenharmony_ci}
101c72fcc34Sopenharmony_ci
102c72fcc34Sopenharmony_cistatic int set_tr_stop_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
103c72fcc34Sopenharmony_ci{
104c72fcc34Sopenharmony_ci	long sampling_frequency;
105c72fcc34Sopenharmony_ci	long bit_depth;
106c72fcc34Sopenharmony_ci	long channel_map;
107c72fcc34Sopenharmony_ci	long channel_config;
108c72fcc34Sopenharmony_ci	long interleaving_style;
109c72fcc34Sopenharmony_ci	long number_of_channels;
110c72fcc34Sopenharmony_ci	long valid_bit_depth;
111c72fcc34Sopenharmony_ci	long sample_type;
112c72fcc34Sopenharmony_ci	long ret;
113c72fcc34Sopenharmony_ci
114c72fcc34Sopenharmony_ci	struct dai_values ssp_tr_data[] = {
115c72fcc34Sopenharmony_ci		{"sampling_frequency", SND_CONFIG_TYPE_INTEGER, NULL, &sampling_frequency, NULL},
116c72fcc34Sopenharmony_ci		{"bit_depth", SND_CONFIG_TYPE_INTEGER, NULL, &bit_depth, NULL},
117c72fcc34Sopenharmony_ci		{"channel_map", SND_CONFIG_TYPE_INTEGER, NULL, &channel_map, NULL},
118c72fcc34Sopenharmony_ci		{"channel_config", SND_CONFIG_TYPE_INTEGER, NULL, &channel_config, NULL},
119c72fcc34Sopenharmony_ci		{"interleaving_style", SND_CONFIG_TYPE_INTEGER, NULL, &interleaving_style, NULL},
120c72fcc34Sopenharmony_ci		{"number_of_channels", SND_CONFIG_TYPE_INTEGER, NULL, &number_of_channels, NULL},
121c72fcc34Sopenharmony_ci		{"valid_bit_depth", SND_CONFIG_TYPE_INTEGER, NULL, &valid_bit_depth, NULL},
122c72fcc34Sopenharmony_ci		{"sample_type", SND_CONFIG_TYPE_INTEGER, NULL, &sample_type, NULL},
123c72fcc34Sopenharmony_ci	};
124c72fcc34Sopenharmony_ci
125c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_tr_data[0], ARRAY_SIZE(ssp_tr_data), cfg, top,
126c72fcc34Sopenharmony_ci			      "Class.Base.tr_stop_config");
127c72fcc34Sopenharmony_ci	if (ret < 0)
128c72fcc34Sopenharmony_ci		return ret;
129c72fcc34Sopenharmony_ci
130c72fcc34Sopenharmony_ci	return ssp_tr_stop_set_params(nhlt, sampling_frequency, bit_depth, channel_map,
131c72fcc34Sopenharmony_ci				      channel_config, interleaving_style, number_of_channels,
132c72fcc34Sopenharmony_ci				      valid_bit_depth,sample_type);
133c72fcc34Sopenharmony_ci}
134c72fcc34Sopenharmony_ci
135c72fcc34Sopenharmony_cistatic int set_run_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
136c72fcc34Sopenharmony_ci{
137c72fcc34Sopenharmony_ci	long always_run;
138c72fcc34Sopenharmony_ci	long ret;
139c72fcc34Sopenharmony_ci
140c72fcc34Sopenharmony_ci	struct dai_values ssp_run_data[] = {
141c72fcc34Sopenharmony_ci		{"always_run", SND_CONFIG_TYPE_INTEGER, NULL, &always_run, NULL},
142c72fcc34Sopenharmony_ci	};
143c72fcc34Sopenharmony_ci
144c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_run_data[0], ARRAY_SIZE(ssp_run_data), cfg, top,
145c72fcc34Sopenharmony_ci			      "Class.Base.run_config");
146c72fcc34Sopenharmony_ci	if (ret < 0)
147c72fcc34Sopenharmony_ci		return ret;
148c72fcc34Sopenharmony_ci
149c72fcc34Sopenharmony_ci	return ssp_run_set_params(nhlt, always_run);
150c72fcc34Sopenharmony_ci}
151c72fcc34Sopenharmony_ci
152c72fcc34Sopenharmony_cistatic int set_node_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
153c72fcc34Sopenharmony_ci{
154c72fcc34Sopenharmony_ci	long sampling_rate;
155c72fcc34Sopenharmony_ci	long node_id;
156c72fcc34Sopenharmony_ci	long ret;
157c72fcc34Sopenharmony_ci
158c72fcc34Sopenharmony_ci	struct dai_values ssp_node_data[] = {
159c72fcc34Sopenharmony_ci		{"node_id", SND_CONFIG_TYPE_INTEGER, NULL, &node_id, NULL},
160c72fcc34Sopenharmony_ci		{"sampling_rate", SND_CONFIG_TYPE_INTEGER, NULL, &sampling_rate, NULL},
161c72fcc34Sopenharmony_ci	};
162c72fcc34Sopenharmony_ci
163c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_node_data[0], ARRAY_SIZE(ssp_node_data), cfg, top,
164c72fcc34Sopenharmony_ci			      "Class.Base.node_config");
165c72fcc34Sopenharmony_ci	if (ret < 0)
166c72fcc34Sopenharmony_ci		return ret;
167c72fcc34Sopenharmony_ci
168c72fcc34Sopenharmony_ci	return ssp_node_set_params(nhlt, node_id, sampling_rate);
169c72fcc34Sopenharmony_ci}
170c72fcc34Sopenharmony_ci
171c72fcc34Sopenharmony_cistatic int set_sync_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
172c72fcc34Sopenharmony_ci{
173c72fcc34Sopenharmony_ci	long sync_denominator;
174c72fcc34Sopenharmony_ci	long ret;
175c72fcc34Sopenharmony_ci
176c72fcc34Sopenharmony_ci	struct dai_values ssp_sync_data[] = {
177c72fcc34Sopenharmony_ci		{"sync_denominator", SND_CONFIG_TYPE_INTEGER, NULL, &sync_denominator, NULL},
178c72fcc34Sopenharmony_ci	};
179c72fcc34Sopenharmony_ci
180c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_sync_data[0], ARRAY_SIZE(ssp_sync_data), cfg, top,
181c72fcc34Sopenharmony_ci			      "Class.Base.sync_config");
182c72fcc34Sopenharmony_ci	if (ret < 0)
183c72fcc34Sopenharmony_ci		return ret;
184c72fcc34Sopenharmony_ci
185c72fcc34Sopenharmony_ci	return ssp_sync_set_params(nhlt, sync_denominator);
186c72fcc34Sopenharmony_ci}
187c72fcc34Sopenharmony_ci
188c72fcc34Sopenharmony_cistatic int set_ext_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
189c72fcc34Sopenharmony_ci{
190c72fcc34Sopenharmony_ci	long mclk_policy_override;
191c72fcc34Sopenharmony_ci	long mclk_always_running;
192c72fcc34Sopenharmony_ci	long mclk_starts_on_gtw_init;
193c72fcc34Sopenharmony_ci	long mclk_starts_on_run;
194c72fcc34Sopenharmony_ci	long mclk_starts_on_pause;
195c72fcc34Sopenharmony_ci	long mclk_stops_on_pause;
196c72fcc34Sopenharmony_ci	long mclk_stops_on_reset;
197c72fcc34Sopenharmony_ci
198c72fcc34Sopenharmony_ci	long bclk_policy_override;
199c72fcc34Sopenharmony_ci	long bclk_always_running;
200c72fcc34Sopenharmony_ci	long bclk_starts_on_gtw_init;
201c72fcc34Sopenharmony_ci	long bclk_starts_on_run;
202c72fcc34Sopenharmony_ci	long bclk_starts_on_pause;
203c72fcc34Sopenharmony_ci	long bclk_stops_on_pause;
204c72fcc34Sopenharmony_ci	long bclk_stops_on_reset;
205c72fcc34Sopenharmony_ci
206c72fcc34Sopenharmony_ci	long sync_policy_override;
207c72fcc34Sopenharmony_ci	long sync_always_running;
208c72fcc34Sopenharmony_ci	long sync_starts_on_gtw_init;
209c72fcc34Sopenharmony_ci	long sync_starts_on_run;
210c72fcc34Sopenharmony_ci	long sync_starts_on_pause;
211c72fcc34Sopenharmony_ci	long sync_stops_on_pause;
212c72fcc34Sopenharmony_ci	long sync_stops_on_reset;
213c72fcc34Sopenharmony_ci	long ret;
214c72fcc34Sopenharmony_ci
215c72fcc34Sopenharmony_ci	struct dai_values ssp_ext_data[] = {
216c72fcc34Sopenharmony_ci		{"mclk_policy_override", SND_CONFIG_TYPE_INTEGER, NULL, &mclk_policy_override, NULL},
217c72fcc34Sopenharmony_ci		{"mclk_always_running", SND_CONFIG_TYPE_INTEGER, NULL, &mclk_always_running, NULL},
218c72fcc34Sopenharmony_ci		{"mclk_starts_on_gtw_init", SND_CONFIG_TYPE_INTEGER, NULL, &mclk_starts_on_gtw_init, NULL},
219c72fcc34Sopenharmony_ci		{"mclk_starts_on_run", SND_CONFIG_TYPE_INTEGER, NULL, &mclk_starts_on_run, NULL},
220c72fcc34Sopenharmony_ci		{"mclk_starts_on_pause", SND_CONFIG_TYPE_INTEGER, NULL, &mclk_starts_on_pause, NULL},
221c72fcc34Sopenharmony_ci		{"mclk_stops_on_pause", SND_CONFIG_TYPE_INTEGER, NULL, &mclk_stops_on_pause, NULL},
222c72fcc34Sopenharmony_ci		{"mclk_stops_on_reset", SND_CONFIG_TYPE_INTEGER, NULL, &mclk_stops_on_reset, NULL},
223c72fcc34Sopenharmony_ci		{"bclk_policy_override", SND_CONFIG_TYPE_INTEGER, NULL, &bclk_policy_override, NULL},
224c72fcc34Sopenharmony_ci		{"bclk_always_running", SND_CONFIG_TYPE_INTEGER, NULL, &bclk_always_running, NULL},
225c72fcc34Sopenharmony_ci		{"bclk_starts_on_gtw_init", SND_CONFIG_TYPE_INTEGER, NULL, &bclk_starts_on_gtw_init, NULL},
226c72fcc34Sopenharmony_ci		{"bclk_starts_on_run", SND_CONFIG_TYPE_INTEGER, NULL, &bclk_starts_on_run, NULL},
227c72fcc34Sopenharmony_ci		{"bclk_starts_on_pause", SND_CONFIG_TYPE_INTEGER, NULL, &bclk_starts_on_pause, NULL},
228c72fcc34Sopenharmony_ci		{"bclk_stops_on_pause", SND_CONFIG_TYPE_INTEGER, NULL, &bclk_stops_on_pause, NULL},
229c72fcc34Sopenharmony_ci		{"bclk_stops_on_reset", SND_CONFIG_TYPE_INTEGER, NULL, &bclk_stops_on_reset, NULL},
230c72fcc34Sopenharmony_ci		{"sync_policy_override", SND_CONFIG_TYPE_INTEGER, NULL, &sync_policy_override, NULL},
231c72fcc34Sopenharmony_ci		{"sync_always_running", SND_CONFIG_TYPE_INTEGER, NULL, &sync_always_running, NULL},
232c72fcc34Sopenharmony_ci		{"sync_starts_on_gtw_init", SND_CONFIG_TYPE_INTEGER, NULL, &sync_starts_on_gtw_init, NULL},
233c72fcc34Sopenharmony_ci		{"sync_starts_on_run", SND_CONFIG_TYPE_INTEGER, NULL, &sync_starts_on_run, NULL},
234c72fcc34Sopenharmony_ci		{"sync_starts_on_pause", SND_CONFIG_TYPE_INTEGER, NULL, &sync_starts_on_pause, NULL},
235c72fcc34Sopenharmony_ci		{"sync_stops_on_pause", SND_CONFIG_TYPE_INTEGER, NULL, &sync_stops_on_pause, NULL},
236c72fcc34Sopenharmony_ci		{"sync_stops_on_reset", SND_CONFIG_TYPE_INTEGER, NULL, &sync_stops_on_reset, NULL},
237c72fcc34Sopenharmony_ci	};
238c72fcc34Sopenharmony_ci
239c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_ext_data[0], ARRAY_SIZE(ssp_ext_data), cfg, top,
240c72fcc34Sopenharmony_ci			      "Class.Base.ext_config");
241c72fcc34Sopenharmony_ci	if (ret < 0)
242c72fcc34Sopenharmony_ci		return ret;
243c72fcc34Sopenharmony_ci
244c72fcc34Sopenharmony_ci	return ssp_ext_set_params(nhlt, mclk_policy_override, mclk_always_running,
245c72fcc34Sopenharmony_ci				  mclk_starts_on_gtw_init, mclk_starts_on_run, mclk_starts_on_pause,
246c72fcc34Sopenharmony_ci				  mclk_stops_on_pause, mclk_stops_on_reset,
247c72fcc34Sopenharmony_ci				  bclk_policy_override, bclk_always_running,
248c72fcc34Sopenharmony_ci				  bclk_starts_on_gtw_init, bclk_starts_on_run, bclk_starts_on_pause,
249c72fcc34Sopenharmony_ci				  bclk_stops_on_pause, bclk_stops_on_reset,
250c72fcc34Sopenharmony_ci				  sync_policy_override, sync_always_running,
251c72fcc34Sopenharmony_ci				  sync_starts_on_gtw_init, sync_starts_on_run, sync_starts_on_pause,
252c72fcc34Sopenharmony_ci				  sync_stops_on_pause, sync_stops_on_reset);
253c72fcc34Sopenharmony_ci}
254c72fcc34Sopenharmony_ci
255c72fcc34Sopenharmony_cistatic int set_link_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
256c72fcc34Sopenharmony_ci{
257c72fcc34Sopenharmony_ci	long clock_source;
258c72fcc34Sopenharmony_ci	long ret;
259c72fcc34Sopenharmony_ci
260c72fcc34Sopenharmony_ci	struct dai_values ssp_link_data[] = {
261c72fcc34Sopenharmony_ci		{"clock_source", SND_CONFIG_TYPE_INTEGER, NULL, &clock_source, NULL},
262c72fcc34Sopenharmony_ci	};
263c72fcc34Sopenharmony_ci
264c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_link_data[0], ARRAY_SIZE(ssp_link_data), cfg, top,
265c72fcc34Sopenharmony_ci			      "Class.Base.link_config");
266c72fcc34Sopenharmony_ci	if (ret < 0)
267c72fcc34Sopenharmony_ci		return ret;
268c72fcc34Sopenharmony_ci
269c72fcc34Sopenharmony_ci	return ssp_link_set_params(nhlt, clock_source);
270c72fcc34Sopenharmony_ci}
271c72fcc34Sopenharmony_ci
272c72fcc34Sopenharmony_cistatic int set_aux_params(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
273c72fcc34Sopenharmony_ci{
274c72fcc34Sopenharmony_ci	struct aux_map {
275c72fcc34Sopenharmony_ci		const char *name;
276c72fcc34Sopenharmony_ci		int id;
277c72fcc34Sopenharmony_ci	};
278c72fcc34Sopenharmony_ci
279c72fcc34Sopenharmony_ci	struct aux_map aux_maps[] = {
280c72fcc34Sopenharmony_ci		{ "Object.Base.mn_config", SSP_MN_DIVIDER_CONTROLS },
281c72fcc34Sopenharmony_ci		{"Object.Base.clk_config", SSP_DMA_CLK_CONTROLS },
282c72fcc34Sopenharmony_ci		{"Object.Base.tr_start_config", SSP_DMA_TRANSMISSION_START },
283c72fcc34Sopenharmony_ci		{"Object.Base.tr_stop_config", SSP_DMA_TRANSMISSION_STOP },
284c72fcc34Sopenharmony_ci		{"Object.Base.run_config", SSP_DMA_ALWAYS_RUNNING_MODE} ,
285c72fcc34Sopenharmony_ci		{"Object.Base.sync_config", SSP_DMA_SYNC_DATA },
286c72fcc34Sopenharmony_ci		{"Object.Base.ext_config", SSP_DMA_CLK_CONTROLS_EXT },
287c72fcc34Sopenharmony_ci		{"Object.Base.link_config", SSP_LINK_CLK_SOURCE },
288c72fcc34Sopenharmony_ci		{"Object.Base.node_config", SSP_DMA_SYNC_NODE },
289c72fcc34Sopenharmony_ci	};
290c72fcc34Sopenharmony_ci
291c72fcc34Sopenharmony_ci	snd_config_iterator_t iter, next;
292c72fcc34Sopenharmony_ci	snd_config_t *items, *n;
293c72fcc34Sopenharmony_ci	const char *id;
294c72fcc34Sopenharmony_ci	unsigned int i;
295c72fcc34Sopenharmony_ci	int ret = 0;
296c72fcc34Sopenharmony_ci
297c72fcc34Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(aux_maps); i++) {
298c72fcc34Sopenharmony_ci		if (snd_config_search(cfg, aux_maps[i].name, &items) < 0)
299c72fcc34Sopenharmony_ci			continue;
300c72fcc34Sopenharmony_ci
301c72fcc34Sopenharmony_ci		snd_config_for_each(iter, next, items) {
302c72fcc34Sopenharmony_ci			n = snd_config_iterator_entry(iter);
303c72fcc34Sopenharmony_ci
304c72fcc34Sopenharmony_ci			if (snd_config_get_id(n, &id) < 0)
305c72fcc34Sopenharmony_ci				continue;
306c72fcc34Sopenharmony_ci
307c72fcc34Sopenharmony_ci			switch(aux_maps[i].id) {
308c72fcc34Sopenharmony_ci			case SSP_MN_DIVIDER_CONTROLS:
309c72fcc34Sopenharmony_ci				ret = set_mn_config(nhlt, n, top);
310c72fcc34Sopenharmony_ci				break;
311c72fcc34Sopenharmony_ci			case SSP_DMA_CLK_CONTROLS:
312c72fcc34Sopenharmony_ci				ret = set_clk_config(nhlt, n, top);
313c72fcc34Sopenharmony_ci				break;
314c72fcc34Sopenharmony_ci			case SSP_DMA_TRANSMISSION_START:
315c72fcc34Sopenharmony_ci				ret = set_tr_start_config(nhlt, n, top);
316c72fcc34Sopenharmony_ci				break;
317c72fcc34Sopenharmony_ci			case SSP_DMA_TRANSMISSION_STOP:
318c72fcc34Sopenharmony_ci				ret = set_tr_stop_config(nhlt, n, top);
319c72fcc34Sopenharmony_ci				break;
320c72fcc34Sopenharmony_ci			case SSP_DMA_ALWAYS_RUNNING_MODE:
321c72fcc34Sopenharmony_ci				ret = set_run_config(nhlt, n, top);
322c72fcc34Sopenharmony_ci				break;
323c72fcc34Sopenharmony_ci			case SSP_DMA_SYNC_DATA:
324c72fcc34Sopenharmony_ci				ret = set_sync_config(nhlt, n, top);
325c72fcc34Sopenharmony_ci				break;
326c72fcc34Sopenharmony_ci			case SSP_DMA_CLK_CONTROLS_EXT:
327c72fcc34Sopenharmony_ci				ret = set_ext_config(nhlt, n, top);
328c72fcc34Sopenharmony_ci				break;
329c72fcc34Sopenharmony_ci			case SSP_LINK_CLK_SOURCE:
330c72fcc34Sopenharmony_ci				ret = set_link_config(nhlt, n, top);
331c72fcc34Sopenharmony_ci				break;
332c72fcc34Sopenharmony_ci			case SSP_DMA_SYNC_NODE:
333c72fcc34Sopenharmony_ci				ret = set_node_config(nhlt, n, top);
334c72fcc34Sopenharmony_ci				break;
335c72fcc34Sopenharmony_ci			default:
336c72fcc34Sopenharmony_ci				ret = -EINVAL;
337c72fcc34Sopenharmony_ci			}
338c72fcc34Sopenharmony_ci
339c72fcc34Sopenharmony_ci			if (ret < 0)
340c72fcc34Sopenharmony_ci				return ret;
341c72fcc34Sopenharmony_ci		}
342c72fcc34Sopenharmony_ci	}
343c72fcc34Sopenharmony_ci
344c72fcc34Sopenharmony_ci	return ret;
345c72fcc34Sopenharmony_ci}
346c72fcc34Sopenharmony_ci
347c72fcc34Sopenharmony_cistatic int set_hw_config(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
348c72fcc34Sopenharmony_ci{
349c72fcc34Sopenharmony_ci	const char *format = NULL;
350c72fcc34Sopenharmony_ci	const char *mclk = NULL;
351c72fcc34Sopenharmony_ci	const char *bclk = NULL;
352c72fcc34Sopenharmony_ci	const char *bclk_invert = NULL;
353c72fcc34Sopenharmony_ci	const char *fsync = NULL;
354c72fcc34Sopenharmony_ci	const char *fsync_invert = NULL;
355c72fcc34Sopenharmony_ci	long mclk_freq = 0;
356c72fcc34Sopenharmony_ci	long bclk_freq = 0;
357c72fcc34Sopenharmony_ci	long fsync_freq = 0;
358c72fcc34Sopenharmony_ci	long tdm_slots = 0;
359c72fcc34Sopenharmony_ci	long tdm_slot_width = 0;
360c72fcc34Sopenharmony_ci	long tx_slots = 0;
361c72fcc34Sopenharmony_ci	long rx_slots = 0;
362c72fcc34Sopenharmony_ci	long ret;
363c72fcc34Sopenharmony_ci
364c72fcc34Sopenharmony_ci	struct dai_values ssp_hw_data[] = {
365c72fcc34Sopenharmony_ci		{"format", SND_CONFIG_TYPE_STRING, NULL, NULL, &format},
366c72fcc34Sopenharmony_ci		{"mclk", SND_CONFIG_TYPE_STRING, NULL, NULL, &mclk},
367c72fcc34Sopenharmony_ci		{"bclk", SND_CONFIG_TYPE_STRING, NULL, NULL, &bclk},
368c72fcc34Sopenharmony_ci		{"fsync", SND_CONFIG_TYPE_STRING, NULL, NULL, &fsync},
369c72fcc34Sopenharmony_ci		{"bclk_invert", SND_CONFIG_TYPE_STRING, NULL, NULL, &bclk_invert},
370c72fcc34Sopenharmony_ci		{"fsync_invert", SND_CONFIG_TYPE_STRING, NULL, NULL, &fsync_invert},
371c72fcc34Sopenharmony_ci		{"fsync_freq", SND_CONFIG_TYPE_INTEGER, NULL, &fsync_freq, NULL},
372c72fcc34Sopenharmony_ci		{"bclk_freq", SND_CONFIG_TYPE_INTEGER, NULL, &bclk_freq, NULL},
373c72fcc34Sopenharmony_ci		{"mclk_freq", SND_CONFIG_TYPE_INTEGER, NULL, &mclk_freq, NULL},
374c72fcc34Sopenharmony_ci		{"tdm_slots", SND_CONFIG_TYPE_INTEGER, NULL, &tdm_slots, NULL},
375c72fcc34Sopenharmony_ci		{"tdm_slot_width", SND_CONFIG_TYPE_INTEGER, NULL, &tdm_slot_width, NULL},
376c72fcc34Sopenharmony_ci		{"tx_slots", SND_CONFIG_TYPE_INTEGER, NULL, &tx_slots, NULL},
377c72fcc34Sopenharmony_ci		{"rx_slots", SND_CONFIG_TYPE_INTEGER, NULL, &rx_slots, NULL},
378c72fcc34Sopenharmony_ci	};
379c72fcc34Sopenharmony_ci
380c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_hw_data[0], ARRAY_SIZE(ssp_hw_data), cfg, top,
381c72fcc34Sopenharmony_ci			      "Class.Base.hw_config");
382c72fcc34Sopenharmony_ci	if (ret < 0)
383c72fcc34Sopenharmony_ci		return ret;
384c72fcc34Sopenharmony_ci
385c72fcc34Sopenharmony_ci	ret = set_aux_params(nhlt, cfg, top);
386c72fcc34Sopenharmony_ci	if (ret < 0)
387c72fcc34Sopenharmony_ci		return ret;
388c72fcc34Sopenharmony_ci
389c72fcc34Sopenharmony_ci	return ssp_hw_set_params(nhlt, format, mclk, bclk, bclk_invert, fsync, fsync_invert,
390c72fcc34Sopenharmony_ci				 mclk_freq, bclk_freq, fsync_freq, tdm_slots, tdm_slot_width,
391c72fcc34Sopenharmony_ci				 tx_slots, rx_slots);
392c72fcc34Sopenharmony_ci}
393c72fcc34Sopenharmony_ci
394c72fcc34Sopenharmony_cistatic int set_ssp_data(struct intel_nhlt_params *nhlt, snd_config_t *dai_cfg, snd_config_t *top)
395c72fcc34Sopenharmony_ci{
396c72fcc34Sopenharmony_ci	const char *tdm_padding_per_slot = NULL;
397c72fcc34Sopenharmony_ci	const char *direction = NULL;
398c72fcc34Sopenharmony_ci	const char *quirks = NULL;
399c72fcc34Sopenharmony_ci	long frame_pulse_width = 0;
400c72fcc34Sopenharmony_ci	long clks_control = 0;
401c72fcc34Sopenharmony_ci	long sample_bits = 0;
402c72fcc34Sopenharmony_ci	long bclk_delay = 0;
403c72fcc34Sopenharmony_ci	long version = 0;
404c72fcc34Sopenharmony_ci	long dai_index = 0;
405c72fcc34Sopenharmony_ci	long mclk_id = 0;
406c72fcc34Sopenharmony_ci	long io_clk = 0;
407c72fcc34Sopenharmony_ci	int ret;
408c72fcc34Sopenharmony_ci
409c72fcc34Sopenharmony_ci	struct dai_values ssp_data[] = {
410c72fcc34Sopenharmony_ci		{ "io_clk",  SND_CONFIG_TYPE_INTEGER, NULL, &io_clk, NULL},
411c72fcc34Sopenharmony_ci		{ "direction", SND_CONFIG_TYPE_STRING, NULL, NULL, &direction},
412c72fcc34Sopenharmony_ci		{ "quirks", SND_CONFIG_TYPE_STRING, NULL, NULL, &quirks},
413c72fcc34Sopenharmony_ci		{ "dai_index", SND_CONFIG_TYPE_INTEGER, NULL, &dai_index, NULL},
414c72fcc34Sopenharmony_ci		{ "sample_bits", SND_CONFIG_TYPE_INTEGER, NULL, &sample_bits, NULL},
415c72fcc34Sopenharmony_ci		{ "bclk_delay", SND_CONFIG_TYPE_INTEGER, NULL, &bclk_delay, NULL},
416c72fcc34Sopenharmony_ci		{ "mclk_id", SND_CONFIG_TYPE_INTEGER, NULL, &mclk_id, NULL},
417c72fcc34Sopenharmony_ci		{ "clks_control", SND_CONFIG_TYPE_INTEGER, NULL, &clks_control, NULL},
418c72fcc34Sopenharmony_ci		{ "frame_pulse_width", SND_CONFIG_TYPE_INTEGER, NULL, &frame_pulse_width, NULL},
419c72fcc34Sopenharmony_ci		{ "tdm_padding_per_slot", SND_CONFIG_TYPE_STRING, NULL, NULL,
420c72fcc34Sopenharmony_ci		  &tdm_padding_per_slot},
421c72fcc34Sopenharmony_ci		{ "version", SND_CONFIG_TYPE_INTEGER, NULL, &version, NULL},
422c72fcc34Sopenharmony_ci	};
423c72fcc34Sopenharmony_ci
424c72fcc34Sopenharmony_ci	ret = find_set_values(&ssp_data[0], ARRAY_SIZE(ssp_data), dai_cfg, top, "Class.Dai.SSP");
425c72fcc34Sopenharmony_ci	if (ret < 0)
426c72fcc34Sopenharmony_ci		return ret;
427c72fcc34Sopenharmony_ci
428c72fcc34Sopenharmony_ci	return ssp_set_params(nhlt, direction, dai_index, io_clk, bclk_delay, sample_bits, mclk_id,
429c72fcc34Sopenharmony_ci			      clks_control, frame_pulse_width, tdm_padding_per_slot, quirks,
430c72fcc34Sopenharmony_ci			      version);
431c72fcc34Sopenharmony_ci}
432c72fcc34Sopenharmony_ci
433c72fcc34Sopenharmony_ci/* init ssp parameters, should be called before parsing dais */
434c72fcc34Sopenharmony_ciint nhlt_ssp_init_params(struct intel_nhlt_params *nhlt)
435c72fcc34Sopenharmony_ci{
436c72fcc34Sopenharmony_ci	return ssp_init_params(nhlt);
437c72fcc34Sopenharmony_ci}
438c72fcc34Sopenharmony_ci
439c72fcc34Sopenharmony_ciint nhlt_ssp_get_ep_count(struct intel_nhlt_params *nhlt)
440c72fcc34Sopenharmony_ci{
441c72fcc34Sopenharmony_ci	return ssp_get_vendor_blob_count(nhlt);
442c72fcc34Sopenharmony_ci}
443c72fcc34Sopenharmony_ci
444c72fcc34Sopenharmony_ciint nhlt_ssp_get_dir(struct intel_nhlt_params *nhlt, int dai_index, uint8_t *dir)
445c72fcc34Sopenharmony_ci{
446c72fcc34Sopenharmony_ci	return ssp_get_dir(nhlt, dai_index, dir);
447c72fcc34Sopenharmony_ci}
448c72fcc34Sopenharmony_ci
449c72fcc34Sopenharmony_ciint nhlt_ssp_get_ep(struct intel_nhlt_params *nhlt, struct endpoint_descriptor **eps,
450c72fcc34Sopenharmony_ci		    int dai_index, uint8_t dir)
451c72fcc34Sopenharmony_ci{
452c72fcc34Sopenharmony_ci	struct endpoint_descriptor ep;
453c72fcc34Sopenharmony_ci	struct ssp_device_specific_config ssp_conf;
454c72fcc34Sopenharmony_ci	struct formats_config f_conf;
455c72fcc34Sopenharmony_ci	struct format_config f_conf1[8];
456c72fcc34Sopenharmony_ci	uint32_t sample_rate;
457c72fcc34Sopenharmony_ci	uint16_t channel_count;
458c72fcc34Sopenharmony_ci	uint32_t bits_per_sample;
459c72fcc34Sopenharmony_ci	uint32_t virtualbus_id;
460c72fcc34Sopenharmony_ci	uint32_t formats_count;
461c72fcc34Sopenharmony_ci	uint32_t device_type;
462c72fcc34Sopenharmony_ci	uint32_t direction = dir;
463c72fcc34Sopenharmony_ci	uint8_t *ep_target;
464c72fcc34Sopenharmony_ci	size_t blob_size;
465c72fcc34Sopenharmony_ci	int ret;
466c72fcc34Sopenharmony_ci	int i;
467c72fcc34Sopenharmony_ci
468c72fcc34Sopenharmony_ci	/*
469c72fcc34Sopenharmony_ci	 * nhlt ssp structure:
470c72fcc34Sopenharmony_ci	 *
471c72fcc34Sopenharmony_ci	 * endpoint_descriptor, sizeof(struct endpoint_descriptor)
472c72fcc34Sopenharmony_ci	 * device_specific_config (headset), sizeof(struct ssp_device_specific_config)
473c72fcc34Sopenharmony_ci	 * formats_config (formats_count), sizeof(struct formats_config)
474c72fcc34Sopenharmony_ci	 * format_config (waveex), sizeof(struct format_config)
475c72fcc34Sopenharmony_ci	 * vendor_blob sizeof(vendor_blob)
476c72fcc34Sopenharmony_ci	 */
477c72fcc34Sopenharmony_ci
478c72fcc34Sopenharmony_ci	ret = ssp_get_params(nhlt, dai_index, &virtualbus_id, &formats_count,
479c72fcc34Sopenharmony_ci			     &device_type, &direction);
480c72fcc34Sopenharmony_ci	if (ret < 0) {
481c72fcc34Sopenharmony_ci		fprintf(stderr, "nhlt_ssp_get_ep: ssp_get_params failed\n");
482c72fcc34Sopenharmony_ci		return ret;
483c72fcc34Sopenharmony_ci	}
484c72fcc34Sopenharmony_ci
485c72fcc34Sopenharmony_ci	ep.link_type = NHLT_LINK_TYPE_SSP;
486c72fcc34Sopenharmony_ci	ep.instance_id = 0;
487c72fcc34Sopenharmony_ci	ep.vendor_id = NHLT_VENDOR_ID_INTEL;
488c72fcc34Sopenharmony_ci	ep.device_id = NHLT_DEVICE_ID_INTEL_I2S_TDM;
489c72fcc34Sopenharmony_ci	ep.revision_id = 0;
490c72fcc34Sopenharmony_ci	ep.subsystem_id = 0;
491c72fcc34Sopenharmony_ci	ep.device_type = device_type;
492c72fcc34Sopenharmony_ci
493c72fcc34Sopenharmony_ci	ep.direction = direction;
494c72fcc34Sopenharmony_ci	/* ssp device index */
495c72fcc34Sopenharmony_ci	ep.virtualbus_id = virtualbus_id;
496c72fcc34Sopenharmony_ci	/* ssp config */
497c72fcc34Sopenharmony_ci	ssp_conf.config.capabilities_size = 2;
498c72fcc34Sopenharmony_ci	ssp_conf.device_config.virtual_slot = 0;
499c72fcc34Sopenharmony_ci	ssp_conf.device_config.config_type = 0;
500c72fcc34Sopenharmony_ci
501c72fcc34Sopenharmony_ci	/* formats_config */
502c72fcc34Sopenharmony_ci	f_conf.formats_count = formats_count;
503c72fcc34Sopenharmony_ci
504c72fcc34Sopenharmony_ci	for (i = 0; i < f_conf.formats_count; i++) {
505c72fcc34Sopenharmony_ci		/* fill in wave format extensible types */
506c72fcc34Sopenharmony_ci		f_conf1[i].format.wFormatTag = 0xFFFE;
507c72fcc34Sopenharmony_ci
508c72fcc34Sopenharmony_ci		ret = ssp_get_hw_params(nhlt, dai_index, i, &sample_rate, &channel_count,
509c72fcc34Sopenharmony_ci					&bits_per_sample);
510c72fcc34Sopenharmony_ci
511c72fcc34Sopenharmony_ci		if (ret < 0) {
512c72fcc34Sopenharmony_ci			fprintf(stderr, "nhlt_ssp_get_ep: ssp_get_hw_params failed\n");
513c72fcc34Sopenharmony_ci			return ret;
514c72fcc34Sopenharmony_ci		}
515c72fcc34Sopenharmony_ci
516c72fcc34Sopenharmony_ci		f_conf1[i].format.nChannels = channel_count;
517c72fcc34Sopenharmony_ci		f_conf1[i].format.nSamplesPerSec = sample_rate;
518c72fcc34Sopenharmony_ci		f_conf1[i].format.wBitsPerSample = bits_per_sample;
519c72fcc34Sopenharmony_ci		f_conf1[i].format.nBlockAlign = channel_count * bits_per_sample / 8;
520c72fcc34Sopenharmony_ci		f_conf1[i].format.nAvgBytesPerSec = sample_rate * f_conf1[i].format.nBlockAlign;
521c72fcc34Sopenharmony_ci
522c72fcc34Sopenharmony_ci		/* bytes after this value in this struct */
523c72fcc34Sopenharmony_ci		f_conf1[i].format.cbSize = 22;
524c72fcc34Sopenharmony_ci		/* actual bits in container */
525c72fcc34Sopenharmony_ci		f_conf1[i].format.wValidBitsPerSample = bits_per_sample;
526c72fcc34Sopenharmony_ci		/* channel map not used at this time */
527c72fcc34Sopenharmony_ci		f_conf1[i].format.dwChannelMask = 0;
528c72fcc34Sopenharmony_ci		/* WAVE_FORMAT_PCM guid (0x0001) ? */
529c72fcc34Sopenharmony_ci		f_conf1[i].format.SubFormat[0] = 0;
530c72fcc34Sopenharmony_ci		f_conf1[i].format.SubFormat[1] = 0;
531c72fcc34Sopenharmony_ci		f_conf1[i].format.SubFormat[2] = 0;
532c72fcc34Sopenharmony_ci		f_conf1[i].format.SubFormat[3] = 0;
533c72fcc34Sopenharmony_ci
534c72fcc34Sopenharmony_ci		ret = ssp_get_vendor_blob_size(nhlt, dai_index, i, &blob_size);
535c72fcc34Sopenharmony_ci		if (ret < 0) {
536c72fcc34Sopenharmony_ci			fprintf(stderr, "nhlt_ssp_get_ep: dmic_get_vendor_blob_size failed\n");
537c72fcc34Sopenharmony_ci			return ret;
538c72fcc34Sopenharmony_ci		}
539c72fcc34Sopenharmony_ci		f_conf1[i].vendor_blob.capabilities_size = blob_size;
540c72fcc34Sopenharmony_ci	}
541c72fcc34Sopenharmony_ci
542c72fcc34Sopenharmony_ci	ep.length = sizeof(struct endpoint_descriptor) +
543c72fcc34Sopenharmony_ci		sizeof(struct ssp_device_specific_config) +
544c72fcc34Sopenharmony_ci		sizeof(struct formats_config) +
545c72fcc34Sopenharmony_ci		sizeof(struct format_config) * f_conf.formats_count +
546c72fcc34Sopenharmony_ci		blob_size * f_conf.formats_count;
547c72fcc34Sopenharmony_ci
548c72fcc34Sopenharmony_ci	/* allocate the final variable length ep struct */
549c72fcc34Sopenharmony_ci	ep_target = calloc(ep.length, sizeof(uint8_t));
550c72fcc34Sopenharmony_ci	if (!ep_target)
551c72fcc34Sopenharmony_ci		return -ENOMEM;
552c72fcc34Sopenharmony_ci
553c72fcc34Sopenharmony_ci	*eps = (struct endpoint_descriptor *)ep_target;
554c72fcc34Sopenharmony_ci
555c72fcc34Sopenharmony_ci	/* copy all parsed sub arrays into the top level array */
556c72fcc34Sopenharmony_ci	memcpy(ep_target, &ep, sizeof(struct endpoint_descriptor));
557c72fcc34Sopenharmony_ci
558c72fcc34Sopenharmony_ci	ep_target += sizeof(struct endpoint_descriptor);
559c72fcc34Sopenharmony_ci
560c72fcc34Sopenharmony_ci	memcpy(ep_target, &ssp_conf, sizeof(struct ssp_device_specific_config));
561c72fcc34Sopenharmony_ci	ep_target += sizeof(struct ssp_device_specific_config);
562c72fcc34Sopenharmony_ci
563c72fcc34Sopenharmony_ci	memcpy(ep_target, &f_conf, sizeof(struct formats_config));
564c72fcc34Sopenharmony_ci	ep_target += sizeof(struct formats_config);
565c72fcc34Sopenharmony_ci
566c72fcc34Sopenharmony_ci	/* copy all hw configs */
567c72fcc34Sopenharmony_ci	for (i = 0; i < f_conf.formats_count; i++) {
568c72fcc34Sopenharmony_ci		memcpy(ep_target, &f_conf1[i], sizeof(struct format_config));
569c72fcc34Sopenharmony_ci		ep_target += sizeof(struct format_config);
570c72fcc34Sopenharmony_ci		ret = ssp_get_vendor_blob(nhlt, ep_target, dai_index, i);
571c72fcc34Sopenharmony_ci		if (ret < 0) {
572c72fcc34Sopenharmony_ci			fprintf(stderr, "nhlt_sso_get_ep: ssp_get_vendor_blob failed\n");
573c72fcc34Sopenharmony_ci			return ret;
574c72fcc34Sopenharmony_ci		}
575c72fcc34Sopenharmony_ci		ep_target += blob_size;
576c72fcc34Sopenharmony_ci	}
577c72fcc34Sopenharmony_ci
578c72fcc34Sopenharmony_ci	return 0;
579c72fcc34Sopenharmony_ci}
580c72fcc34Sopenharmony_ci
581c72fcc34Sopenharmony_ci/* Set ssp parameters from topology for ssp coefficient calculation.
582c72fcc34Sopenharmony_ci *
583c72fcc34Sopenharmony_ci * You can see an example of topology v2 config of ssp below. In this example the default
584c72fcc34Sopenharmony_ci * object parameters are spelled out for clarity. General parameters like sample_bits are parsed
585c72fcc34Sopenharmony_ci * with set_ssp_data and hw_config object data with set_hw_data. Ssp can have multiple hw_configs.
586c72fcc34Sopenharmony_ci * Values are saved into intermediate structs and the vendor specific blob is calculated at the end
587c72fcc34Sopenharmony_ci * of parsing with ssp_calculate.
588c72fcc34Sopenharmony_ci *
589c72fcc34Sopenharmony_ci * 	SSP."0" {
590c72fcc34Sopenharmony_ci *		id 			0
591c72fcc34Sopenharmony_ci *		direction		"duplex"
592c72fcc34Sopenharmony_ci *		name			NoCodec-0
593c72fcc34Sopenharmony_ci *		io_clk			38400000
594c72fcc34Sopenharmony_ci *		default_hw_conf_id	0
595c72fcc34Sopenharmony_ci *		sample_bits		16
596c72fcc34Sopenharmony_ci *		quirks			"lbm_mode"
597c72fcc34Sopenharmony_ci *		bclk_delay		0
598c72fcc34Sopenharmony_ci *		mclk_id 		0
599c72fcc34Sopenharmony_ci *		clks_control 		0
600c72fcc34Sopenharmony_ci *		frame_pulse_width	0
601c72fcc34Sopenharmony_ci *		tdm_padding_per_slot	false
602c72fcc34Sopenharmony_ci *
603c72fcc34Sopenharmony_ci *		Object.Base.hw_config."SSP0" {
604c72fcc34Sopenharmony_ci *			id	0
605c72fcc34Sopenharmony_ci *			mclk_freq	24576000
606c72fcc34Sopenharmony_ci *			bclk_freq	3072000
607c72fcc34Sopenharmony_ci *			tdm_slot_width	32
608c72fcc34Sopenharmony_ci *			format		"I2S"
609c72fcc34Sopenharmony_ci *			mclk		"codec_mclk_in"
610c72fcc34Sopenharmony_ci *			bclk		"codec_consumer"
611c72fcc34Sopenharmony_ci *			fsync		"codec_consumer"
612c72fcc34Sopenharmony_ci *			fsync_freq	48000
613c72fcc34Sopenharmony_ci *			tdm_slots	2
614c72fcc34Sopenharmony_ci *			tx_slots	3
615c72fcc34Sopenharmony_ci *			rx_slots	3
616c72fcc34Sopenharmony_ci *		}
617c72fcc34Sopenharmony_ci *	}
618c72fcc34Sopenharmony_ci */
619c72fcc34Sopenharmony_ciint nhlt_ssp_set_params(struct intel_nhlt_params *nhlt, snd_config_t *cfg, snd_config_t *top)
620c72fcc34Sopenharmony_ci{
621c72fcc34Sopenharmony_ci	snd_config_iterator_t i, next;
622c72fcc34Sopenharmony_ci	snd_config_t *items;
623c72fcc34Sopenharmony_ci	snd_config_t *n;
624c72fcc34Sopenharmony_ci	const char *id;
625c72fcc34Sopenharmony_ci	int ret;
626c72fcc34Sopenharmony_ci
627c72fcc34Sopenharmony_ci	ret = set_ssp_data(nhlt, cfg, top);
628c72fcc34Sopenharmony_ci	if (ret < 0)
629c72fcc34Sopenharmony_ci		return ret;
630c72fcc34Sopenharmony_ci
631c72fcc34Sopenharmony_ci	ret = snd_config_search(cfg, "Object.Base.hw_config", &items);
632c72fcc34Sopenharmony_ci	if (ret < 0)
633c72fcc34Sopenharmony_ci		return ret;
634c72fcc34Sopenharmony_ci
635c72fcc34Sopenharmony_ci	snd_config_for_each(i, next, items) {
636c72fcc34Sopenharmony_ci		n = snd_config_iterator_entry(i);
637c72fcc34Sopenharmony_ci
638c72fcc34Sopenharmony_ci		if (snd_config_get_id(n, &id) < 0)
639c72fcc34Sopenharmony_ci			continue;
640c72fcc34Sopenharmony_ci
641c72fcc34Sopenharmony_ci		ret = set_hw_config(nhlt, n, top);
642c72fcc34Sopenharmony_ci		if (ret < 0)
643c72fcc34Sopenharmony_ci			return ret;
644c72fcc34Sopenharmony_ci	}
645c72fcc34Sopenharmony_ci
646c72fcc34Sopenharmony_ci	ret = ssp_calculate(nhlt);
647c72fcc34Sopenharmony_ci
648c72fcc34Sopenharmony_ci	return ret;
649c72fcc34Sopenharmony_ci}
650