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