Lines Matching +full:sampling +full:- +full:frequencies
4 * SPDX-License-Identifier: Apache-2.0
22 #define dai_set_drvdata(dai, data) (dai->priv_data = data)
23 #define dai_get_drvdata(dai) dai->priv_data
24 #define dai_get_plat_data(dai) dai->ssp_plat_data
25 #define dai_get_mn(dai) dai->ssp_plat_data->mn_inst
26 #define dai_get_ftable(dai) dai->ssp_plat_data->ftable
27 #define dai_get_fsources(dai) dai->ssp_plat_data->fsources
28 #define dai_mn_base(dai) dai->ssp_plat_data->mn_inst->base
29 #define dai_base(dai) dai->ssp_plat_data->base
30 #define dai_ip_base(dai) dai->ssp_plat_data->ip_base
31 #define dai_shim_base(dai) dai->ssp_plat_data->shim_base
32 #define dai_hdamlssp_base(dai) dai->ssp_plat_data->hdamlssp_base
33 #define dai_i2svss_base(dai) dai->ssp_plat_data->i2svss_base
140 * gcd(a, b) = gcd(-a, -b) = gcd(-a, b) = gcd(a, -b) in dai_ssp_gcd()
143 a = -a; in dai_ssp_gcd()
147 b = -b; in dai_ssp_gcd()
168 * then set b = b - a, which is also even in dai_ssp_gcd()
176 b = b - a; in dai_ssp_gcd()
196 for (i = 0; i < ARRAY_SIZE(mp->mclk_sources_ref); i++) { in dai_ssp_is_mclk_source_in_use()
197 if (mp->mclk_sources_ref[i] > 0) { in dai_ssp_is_mclk_source_in_use()
219 int clk_index = -1; in dai_ssp_setup_initial_mclk_source()
227 ret = -EINVAL; in dai_ssp_setup_initial_mclk_source()
241 ret = -EINVAL; in dai_ssp_setup_initial_mclk_source()
245 mp->mclk_source_clock = clk_index; in dai_ssp_setup_initial_mclk_source()
252 /* clear source mclk clock - bits 17-16 */ in dai_ssp_setup_initial_mclk_source()
260 mp->mclk_sources_ref[mclk_id]++; in dai_ssp_setup_initial_mclk_source()
279 LOG_INF("MCLK %d, source = %d", mclk_rate, mp->mclk_source_clock); in dai_ssp_check_current_mclk_source()
281 if (ft[mp->mclk_source_clock].freq % mclk_rate != 0) { in dai_ssp_check_current_mclk_source()
283 mclk_rate, mp->mclk_source_clock); in dai_ssp_check_current_mclk_source()
284 ret = -EINVAL; in dai_ssp_check_current_mclk_source()
288 if (mp->mclk_sources_ref[mclk_id] > 0) { in dai_ssp_check_current_mclk_source()
289 if (mp->mclk_rate[mclk_id] != mclk_rate) { in dai_ssp_check_current_mclk_source()
291 mclk_id, mclk_rate, mp->mclk_rate[mclk_id]); in dai_ssp_check_current_mclk_source()
292 return -EINVAL; in dai_ssp_check_current_mclk_source()
295 mp->mclk_sources_ref[mclk_id]++; in dai_ssp_check_current_mclk_source()
303 mp->mclk_sources_ref[mclk_id]++; in dai_ssp_check_current_mclk_source()
325 mdivr = mdivr_val - 2; /* 1/n */ in dai_ssp_set_mclk_divider()
329 return -EINVAL; in dai_ssp_set_mclk_divider()
346 return -EINVAL; in dai_ssp_mn_set_mclk()
349 key = k_spin_lock(&mp->lock); in dai_ssp_mn_set_mclk()
361 LOG_INF("mclk_rate %d, mclk_source_clock %d", mclk_rate, mp->mclk_source_clock); in dai_ssp_mn_set_mclk()
363 ret = dai_ssp_set_mclk_divider(dp, mclk_id, ft[mp->mclk_source_clock].freq / mclk_rate); in dai_ssp_mn_set_mclk()
365 mp->mclk_rate[mclk_id] = mclk_rate; in dai_ssp_mn_set_mclk()
369 k_spin_unlock(&mp->lock, key); in dai_ssp_mn_set_mclk()
388 key = k_spin_lock(&mp->lock); in dai_ssp_mn_release_mclk()
390 mp->mclk_sources_ref[mclk_id]--; in dai_ssp_mn_release_mclk()
393 if (!mp->mclk_sources_ref[mclk_id]) { in dai_ssp_mn_release_mclk()
404 /* clear source mclk clock - bits 17-16 */ in dai_ssp_mn_release_mclk()
409 mp->mclk_source_clock = 0; in dai_ssp_mn_release_mclk()
411 k_spin_unlock(&mp->lock, key); in dai_ssp_mn_release_mclk()
416 * \brief Finds valid M/(N * SCR) values for given frequencies.
447 --scr_div; in dai_ssp_find_mn()
455 scr_div -= 2; in dai_ssp_find_mn()
485 * \return index of suitable clock if could find it, -EINVAL otherwise.
496 if (dai_ssp_find_mn(ft[mp->mclk_source_clock].freq, bclk, scr_div, m, n)) { in dai_ssp_find_bclk_source()
497 return mp->mclk_source_clock; in dai_ssp_find_bclk_source()
501 ft[mp->mclk_source_clock].freq); in dai_ssp_find_bclk_source()
519 return -EINVAL; in dai_ssp_find_bclk_source()
524 * \return the index in ssp_freq if could find it, -EINVAL otherwise.
538 return -EINVAL; in dai_ssp_find_clk_ssp_index()
552 for (i = 0; i < ARRAY_SIZE(mp->bclk_sources); i++) { in dai_ssp_is_bclk_source_in_use()
553 if (mp->bclk_sources[i] == clk_src) { in dai_ssp_is_bclk_source_in_use()
582 return -EINVAL; in dai_ssp_setup_initial_bclk_mn_source()
585 mp->bclk_source_mn_clock = clk_index; in dai_ssp_setup_initial_bclk_mn_source()
589 /* clear source bclk clock - 21-20 bits */ in dai_ssp_setup_initial_bclk_mn_source()
624 mp->bclk_source_mn_clock = clk_index; in dai_ssp_reset_bclk_mn_source()
644 if (dai_ssp_find_mn(ft[mp->bclk_source_mn_clock].freq, bclk, scr_div, m, n)) { in dai_ssp_setup_current_bclk_mn_source()
649 bclk, mp->bclk_source_mn_clock); in dai_ssp_setup_current_bclk_mn_source()
650 ret = -EINVAL; in dai_ssp_setup_current_bclk_mn_source()
674 key = k_spin_lock(&mp->lock); in dai_ssp_mn_set_bclk()
676 mp->bclk_sources[dai_index] = MN_BCLK_SOURCE_NONE; in dai_ssp_mn_set_bclk()
681 mp->bclk_sources[dai_index] = MN_BCLK_SOURCE_XTAL; in dai_ssp_mn_set_bclk()
695 mp->bclk_sources[dai_index] = MN_BCLK_SOURCE_MN; in dai_ssp_mn_set_bclk()
705 k_spin_unlock(&mp->lock, key); in dai_ssp_mn_set_bclk()
716 key = k_spin_lock(&mp->lock); in dai_ssp_mn_release_bclk()
717 mp->bclk_sources[ssp_index] = MN_BCLK_SOURCE_NONE; in dai_ssp_mn_release_bclk()
725 k_spin_unlock(&mp->lock, key); in dai_ssp_mn_release_bclk()
733 key = k_spin_lock(&mp->lock); in dai_ssp_mn_reset_bclk_divider()
738 k_spin_unlock(&mp->lock, key); in dai_ssp_mn_reset_bclk_divider()
747 return -EIO; in dai_ssp_poll_for_register_delay()
762 SHIM_CLKCTL_I2SEFDCGB(ssp_index - in dai_ssp_pm_runtime_dis_ssp_clk_gating()
780 SHIM_CLKCTL_I2SEFDCGB(ssp_index - in dai_ssp_pm_runtime_en_ssp_clk_gating()
863 uint16_t pcmsycm = cfg->link_config; in dai_ssp_program_channel_map()
865 pcmsycm = pcmsycm | (dp->ssp_plat_data->params.tdm_slots - 1) << 4; in dai_ssp_program_channel_map()
867 if (DAI_INTEL_SSP_IS_BIT_SET(cfg->link_config, 15)) { in dai_ssp_program_channel_map()
880 uint16_t pcmsycm = cfg->link_config; in dai_ssp_program_channel_map()
883 if (DAI_INTEL_SSP_IS_BIT_SET(cfg->link_config, 15)) { in dai_ssp_program_channel_map()
884 if (blob30->version == SSP_BLOB_VER_3_0) { in dai_ssp_program_channel_map()
886 blob30->i2s_ssp_config.ssmidytsa[cfg->tdm_slot_group]; in dai_ssp_program_channel_map()
889 blob->i2s_driver_config.i2s_config.ssmidytsa[cfg->tdm_slot_group]; in dai_ssp_program_channel_map()
892 pcmsycm = cfg->link_config | (slot_count - 1) << 4; in dai_ssp_program_channel_map()
894 PCMSyCM_OFFSET(cfg->tdm_slot_group); in dai_ssp_program_channel_map()
900 if (blob30->version == SSP_BLOB_VER_3_0) { in dai_ssp_program_channel_map()
902 blob30->i2s_ssp_config.ssmodytsa[cfg->tdm_slot_group]; in dai_ssp_program_channel_map()
905 blob->i2s_driver_config.i2s_config.ssmodytsa[cfg->tdm_slot_group]; in dai_ssp_program_channel_map()
908 pcmsycm = cfg->link_config | (slot_count - 1) << 4; in dai_ssp_program_channel_map()
910 PCMSyCM_OFFSET(cfg->tdm_slot_group + I2SOPCMC); in dai_ssp_program_channel_map()
931 * so wait for set TNF then for TFL zero - order matter. in dai_ssp_empty_tx_fifo()
934 ret = dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(dp->tdm_slot_group), in dai_ssp_empty_tx_fifo()
938 ret |= dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(dp->tdm_slot_group), in dai_ssp_empty_tx_fifo()
941 (DAI_INTEL_SSP_FIFO_DEPTH - 1) / 2); in dai_ssp_empty_tx_fifo()
947 (DAI_INTEL_SSP_FIFO_DEPTH - 1) / 2); in dai_ssp_empty_tx_fifo()
980 /* Re-read the SSSR register */ in ssp_empty_rx_fifo_on_start()
985 while ((sys_read32(dai_base(dp) + SSMIDyCS(idx)) & SSMIDyCS_RNE) && retry--) { in ssp_empty_rx_fifo_on_start()
1002 uint64_t sample_ticks = ssp_plat_data->params.fsync_rate ? in ssp_empty_rx_fifo_on_stop()
1003 1000000 / ssp_plat_data->params.fsync_rate : 0; in ssp_empty_rx_fifo_on_stop()
1010 entries[0] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(dp->tdm_slot_group))); in ssp_empty_rx_fifo_on_stop()
1012 while ((sys_read32(dai_base(dp) + SSMIDyCS(dp->tdm_slot_group)) & in ssp_empty_rx_fifo_on_stop()
1013 SSMIDyCS_RNE) && retry--) { in ssp_empty_rx_fifo_on_stop()
1018 SSMIDyCS(dp->tdm_slot_group))); in ssp_empty_rx_fifo_on_stop()
1020 ssmidycs = sys_read32(dai_base(dp) + SSMIDyCS(dp->tdm_slot_group)); in ssp_empty_rx_fifo_on_stop()
1035 sys_read32(dai_base(dp) + SSMIDyD(dp->tdm_slot_group)); in ssp_empty_rx_fifo_on_stop()
1061 /* Re-read the SSSR register */ in ssp_empty_rx_fifo_on_start()
1065 while ((sssr & SSSR_RNE) && retry--) { in ssp_empty_rx_fifo_on_start()
1080 uint64_t sample_ticks = ssp_plat_data->params.fsync_rate ? in ssp_empty_rx_fifo_on_stop()
1081 1000000 / ssp_plat_data->params.fsync_rate : 0; in ssp_empty_rx_fifo_on_stop()
1089 while ((sssr & SSSR_RNE) && retry--) { in ssp_empty_rx_fifo_on_stop()
1127 if (ssp_plat_data->clk_active & SSP_CLK_MCLK_ACTIVE) { in dai_ssp_mclk_prepare_enable()
1132 ret = dai_ssp_mn_set_mclk(dp, ssp_plat_data->params.mclk_id, in dai_ssp_mclk_prepare_enable()
1133 ssp_plat_data->params.mclk_rate); in dai_ssp_mclk_prepare_enable()
1135 LOG_ERR("invalid mclk_rate = %d for mclk_id = %d", ssp_plat_data->params.mclk_rate, in dai_ssp_mclk_prepare_enable()
1136 ssp_plat_data->params.mclk_id); in dai_ssp_mclk_prepare_enable()
1138 ssp_plat_data->clk_active |= SSP_CLK_MCLK_ACTIVE; in dai_ssp_mclk_prepare_enable()
1148 if (!(ssp_plat_data->clk_active & SSP_CLK_MCLK_ACTIVE)) { in dai_ssp_mclk_disable_unprepare()
1152 dai_ssp_mn_release_mclk(dp, ssp_plat_data->params.mclk_id); in dai_ssp_mclk_disable_unprepare()
1154 ssp_plat_data->clk_active &= ~SSP_CLK_MCLK_ACTIVE; in dai_ssp_mclk_disable_unprepare()
1167 if (ssp_plat_data->clk_active & SSP_CLK_BCLK_ACTIVE) { in dai_ssp_bclk_prepare_enable()
1176 ret = dai_ssp_mn_set_bclk(dp, dp->dai_index, ssp_plat_data->params.bclk_rate, in dai_ssp_bclk_prepare_enable()
1180 ssp_plat_data->params.bclk_rate, dp->dai_index); in dai_ssp_bclk_prepare_enable()
1184 if (ft[DAI_INTEL_SSP_DEFAULT_IDX].freq % ssp_plat_data->params.bclk_rate != 0) { in dai_ssp_bclk_prepare_enable()
1186 ssp_plat_data->params.bclk_rate, dp->dai_index); in dai_ssp_bclk_prepare_enable()
1187 ret = -EINVAL; in dai_ssp_bclk_prepare_enable()
1191 mdiv = ft[DAI_INTEL_SSP_DEFAULT_IDX].freq / ssp_plat_data->params.bclk_rate; in dai_ssp_bclk_prepare_enable()
1201 mdiv -= 1; in dai_ssp_bclk_prepare_enable()
1206 ret = -EINVAL; in dai_ssp_bclk_prepare_enable()
1219 ssp_plat_data->clk_active |= SSP_CLK_BCLK_ACTIVE; in dai_ssp_bclk_prepare_enable()
1229 if (!(ssp_plat_data->clk_active & SSP_CLK_BCLK_ACTIVE)) { in dai_ssp_bclk_disable_unprepare()
1233 dai_ssp_mn_release_bclk(dp, ssp_plat_data->ssp_index); in dai_ssp_bclk_disable_unprepare()
1235 ssp_plat_data->clk_active &= ~SSP_CLK_BCLK_ACTIVE; in dai_ssp_bclk_disable_unprepare()
1240 LOG_INF("dai index: %u", dp->dai_index); in dai_ssp_log_ssp_data()
1241 LOG_INF("plat_data base: %u", dp->ssp_plat_data->base); in dai_ssp_log_ssp_data()
1242 LOG_INF("plat_data irq: %u", dp->ssp_plat_data->irq); in dai_ssp_log_ssp_data()
1244 dp->ssp_plat_data->fifo[DAI_DIR_PLAYBACK].offset); in dai_ssp_log_ssp_data()
1246 dp->ssp_plat_data->fifo[DAI_DIR_PLAYBACK].handshake); in dai_ssp_log_ssp_data()
1248 dp->ssp_plat_data->fifo[DAI_DIR_CAPTURE].offset); in dai_ssp_log_ssp_data()
1250 dp->ssp_plat_data->fifo[DAI_DIR_CAPTURE].handshake); in dai_ssp_log_ssp_data()
1291 key = k_spin_lock(&dp->lock); in dai_ssp_set_config_tplg()
1294 if (dp->state[DAI_DIR_PLAYBACK] > DAI_STATE_READY || in dai_ssp_set_config_tplg()
1295 dp->state[DAI_DIR_CAPTURE] > DAI_STATE_READY) { in dai_ssp_set_config_tplg()
1296 if (!memcmp(&ssp_plat_data->params, bespoke_cfg, in dai_ssp_set_config_tplg()
1302 if (ssp_plat_data->clk_active & in dai_ssp_set_config_tplg()
1311 LOG_INF("SSP%d", dp->dai_index); in dai_ssp_set_config_tplg()
1333 ssp->config = *config; in dai_ssp_set_config_tplg()
1334 memcpy(&ssp_plat_data->params, bespoke_cfg, sizeof(struct dai_intel_ipc3_ssp_params)); in dai_ssp_set_config_tplg()
1346 sstsa = SSTSA_SSTSA(ssp_plat_data->params.tx_slots); in dai_ssp_set_config_tplg()
1349 ssrsa = SSRSA_SSRSA(ssp_plat_data->params.rx_slots); in dai_ssp_set_config_tplg()
1351 switch (config->format & DAI_INTEL_IPC3_SSP_FMT_CLOCK_PROVIDER_MASK) { in dai_ssp_set_config_tplg()
1371 ret = -EINVAL; in dai_ssp_set_config_tplg()
1376 switch (config->format & DAI_INTEL_IPC3_SSP_FMT_INV_MASK) { in dai_ssp_set_config_tplg()
1391 ret = -EINVAL; in dai_ssp_set_config_tplg()
1396 if (ssp_plat_data->params.clks_control & DAI_INTEL_IPC3_SSP_CLKCTRL_BCLK_IDLE_HIGH) { in dai_ssp_set_config_tplg()
1408 /* Receiver Time-out Interrupt Disabled/Enabled */ in dai_ssp_set_config_tplg()
1409 sscr1 |= (ssp_plat_data->params.quirks & DAI_INTEL_IPC3_SSP_QUIRK_TINTE) ? in dai_ssp_set_config_tplg()
1413 sscr1 |= (ssp_plat_data->params.quirks & DAI_INTEL_IPC3_SSP_QUIRK_PINTE) ? in dai_ssp_set_config_tplg()
1419 sscr1 |= (ssp_plat_data->params.quirks & DAI_INTEL_IPC3_SSP_QUIRK_LBM) ? in dai_ssp_set_config_tplg()
1422 if (ssp_plat_data->params.quirks & DAI_INTEL_IPC3_SSP_QUIRK_LBM) { in dai_ssp_set_config_tplg()
1431 sscr2 |= (ssp_plat_data->params.quirks & DAI_INTEL_IPC3_SSP_QUIRK_SMTATF) ? in dai_ssp_set_config_tplg()
1437 sscr2 |= (ssp_plat_data->params.quirks & DAI_INTEL_IPC3_SSP_QUIRK_MMRATF) ? in dai_ssp_set_config_tplg()
1441 * de-assertion before starting the second channel in dai_ssp_set_config_tplg()
1443 sscr2 |= (ssp_plat_data->params.quirks & DAI_INTEL_IPC3_SSP_QUIRK_PSPSTWFDFD) ? in dai_ssp_set_config_tplg()
1449 sscr2 |= (ssp_plat_data->params.quirks & DAI_INTEL_IPC3_SSP_QUIRK_PSPSRWFDFD) ? in dai_ssp_set_config_tplg()
1452 if (!ssp_plat_data->params.mclk_rate || in dai_ssp_set_config_tplg()
1453 ssp_plat_data->params.mclk_rate > ft[DAI_INTEL_SSP_MAX_FREQ_INDEX].freq) { in dai_ssp_set_config_tplg()
1454 LOG_ERR("invalid MCLK = %d Hz (valid < %d)", ssp_plat_data->params.mclk_rate, in dai_ssp_set_config_tplg()
1456 ret = -EINVAL; in dai_ssp_set_config_tplg()
1460 if (!ssp_plat_data->params.bclk_rate || in dai_ssp_set_config_tplg()
1461 ssp_plat_data->params.bclk_rate > ssp_plat_data->params.mclk_rate) { in dai_ssp_set_config_tplg()
1462 LOG_ERR("BCLK %d Hz = 0 or > MCLK %d Hz", ssp_plat_data->params.bclk_rate, in dai_ssp_set_config_tplg()
1463 ssp_plat_data->params.mclk_rate); in dai_ssp_set_config_tplg()
1464 ret = -EINVAL; in dai_ssp_set_config_tplg()
1468 /* calc frame width based on BCLK and rate - must be divisible */ in dai_ssp_set_config_tplg()
1469 if (ssp_plat_data->params.bclk_rate % ssp_plat_data->params.fsync_rate) { in dai_ssp_set_config_tplg()
1470 LOG_ERR("BCLK %d is not divisible by rate %d", ssp_plat_data->params.bclk_rate, in dai_ssp_set_config_tplg()
1471 ssp_plat_data->params.fsync_rate); in dai_ssp_set_config_tplg()
1472 ret = -EINVAL; in dai_ssp_set_config_tplg()
1477 bdiv = ssp_plat_data->params.bclk_rate / ssp_plat_data->params.fsync_rate; in dai_ssp_set_config_tplg()
1478 if (bdiv < ssp_plat_data->params.tdm_slot_width * ssp_plat_data->params.tdm_slots) { in dai_ssp_set_config_tplg()
1480 ssp_plat_data->params.tdm_slot_width * ssp_plat_data->params.tdm_slots); in dai_ssp_set_config_tplg()
1481 ret = -EINVAL; in dai_ssp_set_config_tplg()
1486 if (ssp_plat_data->params.tdm_slot_width > 38) { in dai_ssp_set_config_tplg()
1487 LOG_ERR("tdm_slot_width %d > 38", ssp_plat_data->params.tdm_slot_width); in dai_ssp_set_config_tplg()
1488 ret = -EINVAL; in dai_ssp_set_config_tplg()
1492 bdiv_min = ssp_plat_data->params.tdm_slots * in dai_ssp_set_config_tplg()
1493 (ssp_plat_data->params.tdm_per_slot_padding_flag ? in dai_ssp_set_config_tplg()
1494 ssp_plat_data->params.tdm_slot_width : ssp_plat_data->params.sample_valid_bits); in dai_ssp_set_config_tplg()
1497 ret = -EINVAL; in dai_ssp_set_config_tplg()
1501 frame_end_padding = bdiv - bdiv_min; in dai_ssp_set_config_tplg()
1504 ret = -EINVAL; in dai_ssp_set_config_tplg()
1509 switch (config->format & DAI_INTEL_IPC3_SSP_FMT_FORMAT_MASK) { in dai_ssp_set_config_tplg()
1514 sscr0 |= SSCR0_FRDC(ssp_plat_data->params.tdm_slots); in dai_ssp_set_config_tplg()
1518 ret = -EINVAL; in dai_ssp_set_config_tplg()
1527 * non-inverted(inverted_frame=0) -- active low(SFRMP=0), in dai_ssp_set_config_tplg()
1528 * inverted(inverted_frame=1) -- rising/active high(SFRMP=1), in dai_ssp_set_config_tplg()
1539 ret = -EINVAL; in dai_ssp_set_config_tplg()
1548 ret = -EINVAL; in dai_ssp_set_config_tplg()
1562 sscr0 |= SSCR0_FRDC(ssp_plat_data->params.tdm_slots); in dai_ssp_set_config_tplg()
1569 ret = -EINVAL; in dai_ssp_set_config_tplg()
1578 * non-inverted(inverted_frame=0) -- active high(SFRMP=1), in dai_ssp_set_config_tplg()
1579 * inverted(inverted_frame=1) -- falling/active low(SFRMP=0), in dai_ssp_set_config_tplg()
1590 ret = -EINVAL; in dai_ssp_set_config_tplg()
1599 ret = -EINVAL; in dai_ssp_set_config_tplg()
1618 sscr0 |= SSCR0_MOD | SSCR0_FRDC(ssp_plat_data->params.tdm_slots); in dai_ssp_set_config_tplg()
1623 if (cfs && ssp_plat_data->params.frame_pulse_width > 0 && in dai_ssp_set_config_tplg()
1624 ssp_plat_data->params.frame_pulse_width <= in dai_ssp_set_config_tplg()
1626 frame_len = ssp_plat_data->params.frame_pulse_width; in dai_ssp_set_config_tplg()
1630 if (ssp_plat_data->params.frame_pulse_width > in dai_ssp_set_config_tplg()
1633 ret = -EINVAL; in dai_ssp_set_config_tplg()
1638 * non-inverted(inverted_frame=0) -- active high(SFRMP=1), in dai_ssp_set_config_tplg()
1639 * inverted(inverted_frame=1) -- falling/active low(SFRMP=0), in dai_ssp_set_config_tplg()
1644 active_tx_slots = POPCOUNT(ssp_plat_data->params.tx_slots); in dai_ssp_set_config_tplg()
1645 active_rx_slots = POPCOUNT(ssp_plat_data->params.rx_slots); in dai_ssp_set_config_tplg()
1652 if (ssp_plat_data->params.tdm_per_slot_padding_flag) { in dai_ssp_set_config_tplg()
1653 frame_end_padding = bdiv - ssp_plat_data->params.tdm_slots * in dai_ssp_set_config_tplg()
1654 ssp_plat_data->params.tdm_slot_width; in dai_ssp_set_config_tplg()
1656 slot_end_padding = ssp_plat_data->params.tdm_slot_width - in dai_ssp_set_config_tplg()
1657 ssp_plat_data->params.sample_valid_bits; in dai_ssp_set_config_tplg()
1663 ret = -EINVAL; in dai_ssp_set_config_tplg()
1676 LOG_ERR("invalid format 0x%04x", config->format); in dai_ssp_set_config_tplg()
1677 ret = -EINVAL; in dai_ssp_set_config_tplg()
1687 data_size = ssp_plat_data->params.sample_valid_bits; in dai_ssp_set_config_tplg()
1690 sscr0 |= (SSCR0_EDSS | SSCR0_DSIZE(data_size - 16)); in dai_ssp_set_config_tplg()
1696 switch (ssp_plat_data->params.sample_valid_bits) { in dai_ssp_set_config_tplg()
1707 LOG_ERR("sample_valid_bits %d", ssp_plat_data->params.sample_valid_bits); in dai_ssp_set_config_tplg()
1708 ret = -EINVAL; in dai_ssp_set_config_tplg()
1712 tft = MIN(DAI_INTEL_SSP_FIFO_DEPTH - DAI_INTEL_SSP_FIFO_WATERMARK, in dai_ssp_set_config_tplg()
1714 rft = MIN(DAI_INTEL_SSP_FIFO_DEPTH - DAI_INTEL_SSP_FIFO_WATERMARK, in dai_ssp_set_config_tplg()
1748 dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING; in dai_ssp_set_config_tplg()
1749 dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; in dai_ssp_set_config_tplg()
1752 switch (config->options & DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_CMD_MASK) { in dai_ssp_set_config_tplg()
1754 if (ssp_plat_data->params.clks_control & DAI_INTEL_IPC3_SSP_CLKCTRL_MCLK_ES) { in dai_ssp_set_config_tplg()
1760 ssp_plat_data->clk_active |= SSP_CLK_MCLK_ES_REQ; in dai_ssp_set_config_tplg()
1763 dp->dai_index); in dai_ssp_set_config_tplg()
1766 if (ssp_plat_data->params.clks_control & DAI_INTEL_IPC3_SSP_CLKCTRL_BCLK_ES) { in dai_ssp_set_config_tplg()
1769 if (!(ssp_plat_data->clk_active & SSP_CLK_BCLK_ACTIVE)) { in dai_ssp_set_config_tplg()
1778 ssp_plat_data->clk_active |= SSP_CLK_BCLK_ES_REQ; in dai_ssp_set_config_tplg()
1783 dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group), in dai_ssp_set_config_tplg()
1785 dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group), in dai_ssp_set_config_tplg()
1791 LOG_INF("SSE set for SSP%d", ssp_plat_data->ssp_index); in dai_ssp_set_config_tplg()
1795 ssp_plat_data->ssp_index); in dai_ssp_set_config_tplg()
1800 if (dp->state[DAI_DIR_CAPTURE] != DAI_STATE_PRE_RUNNING || in dai_ssp_set_config_tplg()
1801 dp->state[DAI_DIR_PLAYBACK] != DAI_STATE_PRE_RUNNING) { in dai_ssp_set_config_tplg()
1803 dp->dai_index); in dai_ssp_set_config_tplg()
1807 if (ssp_plat_data->params.clks_control & DAI_INTEL_IPC3_SSP_CLKCTRL_BCLK_ES) { in dai_ssp_set_config_tplg()
1809 dp->dai_index); in dai_ssp_set_config_tplg()
1810 if (ssp_plat_data->clk_active & SSP_CLK_BCLK_ACTIVE) { in dai_ssp_set_config_tplg()
1822 LOG_INF("SSE clear for SSP%d", dp->dai_index); in dai_ssp_set_config_tplg()
1825 ssp_plat_data->clk_active &= ~SSP_CLK_BCLK_ES_REQ; in dai_ssp_set_config_tplg()
1827 if (ssp_plat_data->params.clks_control & DAI_INTEL_IPC3_SSP_CLKCTRL_MCLK_ES) { in dai_ssp_set_config_tplg()
1829 dp->dai_index); in dai_ssp_set_config_tplg()
1831 ssp_plat_data->clk_active &= ~SSP_CLK_MCLK_ES_REQ; in dai_ssp_set_config_tplg()
1839 k_spin_unlock(&dp->lock, key); in dai_ssp_set_config_tplg()
1849 switch (aux_tlv->type) { in dai_ssp_check_aux_data()
1864 sync = (struct ssp_intel_sync_ctl *)&aux_tlv->val; in dai_ssp_check_aux_data()
1865 size += sync->count * sizeof(struct ssp_intel_node_ctl); in dai_ssp_check_aux_data()
1878 LOG_ERR("undefined aux data type %u", aux_tlv->type); in dai_ssp_check_aux_data()
1879 return -EINVAL; in dai_ssp_check_aux_data()
1883 size_left = aux_len - parsed_len - sizeof(struct ssp_intel_aux_tlv); in dai_ssp_check_aux_data()
1884 if (size > size_left || size != aux_tlv->size) { in dai_ssp_check_aux_data()
1886 size_left, aux_tlv->size); in dai_ssp_check_aux_data()
1887 return -EINVAL; in dai_ssp_check_aux_data()
1895 * TLV (Type-Length-Value) entries. It ensures that only specific types
1905 switch (aux_tlv->type) { in dai_ssp_check_dma_control()
1915 LOG_ERR("incorect config type %u", aux_tlv->type); in dai_ssp_check_dma_control()
1916 return -EINVAL; in dai_ssp_check_dma_control()
1919 hop = aux_tlv->size + sizeof(struct ssp_intel_aux_tlv); in dai_ssp_check_dma_control()
1947 return -EINVAL; in dai_ssp_parse_tlv()
1949 switch (aux_tlv->type) { in dai_ssp_parse_tlv()
1951 mn = (struct ssp_intel_mn_ctl *)&aux_tlv->val; in dai_ssp_parse_tlv()
1952 LOG_INF("mn div_m %u, div_n %u", mn->div_m, mn->div_n); in dai_ssp_parse_tlv()
1955 clk = (struct ssp_intel_clk_ctl *)&aux_tlv->val; in dai_ssp_parse_tlv()
1956 LOG_INF("clk start %u, stop %u", clk->start, clk->stop); in dai_ssp_parse_tlv()
1960 tr = (struct ssp_intel_tr_ctl *)&aux_tlv->val; in dai_ssp_parse_tlv()
1961 LOG_INF("tr sampling frequency %u, bit_depth %u, channel_map %u,", in dai_ssp_parse_tlv()
1962 tr->sampling_frequency, tr->bit_depth, tr->channel_map); in dai_ssp_parse_tlv()
1964 tr->channel_config, tr->interleaving_style, tr->format); in dai_ssp_parse_tlv()
1967 run = (struct ssp_intel_run_ctl *)&aux_tlv->val; in dai_ssp_parse_tlv()
1968 LOG_INF("run enabled %u", run->enabled); in dai_ssp_parse_tlv()
1971 sync = (struct ssp_intel_sync_ctl *)&aux_tlv->val; in dai_ssp_parse_tlv()
1973 sync->sync_denominator, sync->count); in dai_ssp_parse_tlv()
1976 for (j = 0; j < sync->count; j++) { in dai_ssp_parse_tlv()
1978 node->node_id, node->sampling_rate); in dai_ssp_parse_tlv()
1983 ext = (struct ssp_intel_ext_ctl *)&aux_tlv->val; in dai_ssp_parse_tlv()
1984 LOG_INF("ext ext_data %u", ext->ext_data); in dai_ssp_parse_tlv()
1988 link = (struct ssp_intel_link_ctl *)&aux_tlv->val; in dai_ssp_parse_tlv()
1992 I2CLCTL_MLCS(link->clock_source), dai_ip_base(dp) + in dai_ssp_parse_tlv()
1995 ssp->link_clock = link->clock_source; in dai_ssp_parse_tlv()
1998 I2CLCTL_MLCS(link->clock_source), in dai_ssp_parse_tlv()
2001 LOG_INF("link clock_source %u", link->clock_source); in dai_ssp_parse_tlv()
2005 LOG_ERR("undefined aux data type %u", aux_tlv->type); in dai_ssp_parse_tlv()
2006 return -EINVAL; in dai_ssp_parse_tlv()
2009 hop = aux_tlv->size + sizeof(struct ssp_intel_aux_tlv); in dai_ssp_parse_tlv()
2023 if (blob15->version == SSP_BLOB_VER_1_5) { in dai_ssp_parse_aux_data()
2024 cfg_len = blob15->size; in dai_ssp_parse_aux_data()
2026 blob15->i2s_mclk_control.mdivrcnt * sizeof(uint32_t); in dai_ssp_parse_aux_data()
2027 aux_len = cfg_len - pre_aux_len; in dai_ssp_parse_aux_data()
2029 } else if (blob30->version == SSP_BLOB_VER_3_0) { in dai_ssp_parse_aux_data()
2030 cfg_len = blob30->size; in dai_ssp_parse_aux_data()
2032 blob30->i2s_mclk_control.mdivrcnt * sizeof(uint32_t); in dai_ssp_parse_aux_data()
2033 aux_len = cfg_len - pre_aux_len; in dai_ssp_parse_aux_data()
2037 return -EINVAL; in dai_ssp_parse_aux_data()
2051 if (cc->mdivrcnt != 1) { in dai_ssp_set_clock_control_ver_1_5()
2052 LOG_ERR("bad clock divider count %u", cc->mdivrcnt); in dai_ssp_set_clock_control_ver_1_5()
2053 return -EINVAL; in dai_ssp_set_clock_control_ver_1_5()
2059 dai_ssp_mn_set_mclk_blob(dp, cc->mdivctlr, cc->mdivr[0]); in dai_ssp_set_clock_control_ver_1_5()
2070 dai_ssp_mn_set_mclk_blob(dp, cc->mdivc, cc->mdivr); in dai_ssp_set_clock_control_ver_1()
2082 uint32_t ssc0 = regs->ssc0; in dai_ssp_set_reg_config()
2083 sscr1 = regs->ssc1 & ~(SSCR1_RSVD21); in dai_ssp_set_reg_config()
2085 LOG_INF("SSP%d configuration:", dp->dai_index); in dai_ssp_set_reg_config()
2088 sys_write32(regs->ssc2 & ~SSCR2_SFRMEN, dai_base(dp) + SSCR2); /* hardware specific flow */ in dai_ssp_set_reg_config()
2090 sys_write32(regs->ssc2 | SSCR2_SFRMEN, dai_base(dp) + SSCR2); /* hardware specific flow */ in dai_ssp_set_reg_config()
2091 sys_write32(regs->ssc2, dai_base(dp) + SSCR2); in dai_ssp_set_reg_config()
2092 sys_write32(regs->sspsp, dai_base(dp) + SSPSP); in dai_ssp_set_reg_config()
2093 sys_write32(regs->sspsp2, dai_base(dp) + SSPSP2); in dai_ssp_set_reg_config()
2094 sys_write32(regs->ssioc, dai_base(dp) + SSIOC); in dai_ssp_set_reg_config()
2095 sys_write32(regs->sscto, dai_base(dp) + SSTO); in dai_ssp_set_reg_config()
2098 sys_write64(regs->ssmidytsa[idx], dai_base(dp) + SSMIDyTSA(idx)); in dai_ssp_set_reg_config()
2102 sys_write64(regs->ssmodytsa[idx], dai_base(dp) + SSMODyTSA(idx)); in dai_ssp_set_reg_config()
2106 ssc0, sscr1, regs->sscto, regs->sspsp); in dai_ssp_set_reg_config()
2108 regs->ssc2, regs->sspsp2, regs->ssc3); in dai_ssp_set_reg_config()
2109 LOG_INF(" ssioc = 0x%08x", regs->ssioc); in dai_ssp_set_reg_config()
2111 ssp_plat_data->params.sample_valid_bits = SSCR0_DSIZE_GET(ssc0); in dai_ssp_set_reg_config()
2113 ssp_plat_data->params.sample_valid_bits += 16; in dai_ssp_set_reg_config()
2116 ssp_plat_data->params.tx_slots = regs->ssmodytsa[dp->tdm_slot_group]; in dai_ssp_set_reg_config()
2117 ssp_plat_data->params.rx_slots = regs->ssmidytsa[dp->tdm_slot_group]; in dai_ssp_set_reg_config()
2119 ssp_plat_data->params.fsync_rate = cfg->rate; in dai_ssp_set_reg_config()
2120 dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING; in dai_ssp_set_reg_config()
2121 dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; in dai_ssp_set_reg_config()
2132 uint32_t ssc0 = regs->ssc0; in dai_ssp_set_reg_config()
2134 sscr1 = regs->ssc1 & ~(SSCR1_RSRE | SSCR1_TSRE); in dai_ssp_set_reg_config()
2135 sstsa = SSTSA_GET(regs->sstsa); in dai_ssp_set_reg_config()
2136 ssrsa = SSRSA_GET(regs->ssrsa); in dai_ssp_set_reg_config()
2138 LOG_INF("SSP%d configuration:", dp->dai_index); in dai_ssp_set_reg_config()
2140 if (regs->sstsa & SSTSA_TXEN || regs->ssrsa & SSRSA_RXEN || in dai_ssp_set_reg_config()
2141 regs->ssc1 & (SSCR1_RSRE | SSCR1_TSRE)) { in dai_ssp_set_reg_config()
2143 regs->sstsa & SSTSA_TXEN ? "SSTSA:TXEN " : "", in dai_ssp_set_reg_config()
2144 regs->ssrsa & SSRSA_RXEN ? "SSRSA:RXEN " : "", in dai_ssp_set_reg_config()
2145 regs->ssc1 & SSCR1_TSRE ? "SSCR1:TSRE " : "", in dai_ssp_set_reg_config()
2146 regs->ssc1 & SSCR1_RSRE ? "SSCR1:RSRE " : ""); in dai_ssp_set_reg_config()
2150 sys_write32(regs->ssc2 & ~SSCR2_SFRMEN, dai_base(dp) + SSCR2); /* hardware specific flow */ in dai_ssp_set_reg_config()
2152 sys_write32(regs->ssc2 | SSCR2_SFRMEN, dai_base(dp) + SSCR2); /* hardware specific flow */ in dai_ssp_set_reg_config()
2153 sys_write32(regs->ssc2, dai_base(dp) + SSCR2); in dai_ssp_set_reg_config()
2154 sys_write32(regs->ssc3, dai_base(dp) + SSCR3); in dai_ssp_set_reg_config()
2155 sys_write32(regs->sspsp, dai_base(dp) + SSPSP); in dai_ssp_set_reg_config()
2156 sys_write32(regs->sspsp2, dai_base(dp) + SSPSP2); in dai_ssp_set_reg_config()
2157 sys_write32(regs->ssioc, dai_base(dp) + SSIOC); in dai_ssp_set_reg_config()
2158 sys_write32(regs->sscto, dai_base(dp) + SSTO); in dai_ssp_set_reg_config()
2163 ssc0, sscr1, regs->sscto, regs->sspsp); in dai_ssp_set_reg_config()
2165 regs->ssc2, regs->sspsp2, regs->ssc3); in dai_ssp_set_reg_config()
2167 regs->ssioc, ssrsa, sstsa); in dai_ssp_set_reg_config()
2169 ssp_plat_data->params.sample_valid_bits = SSCR0_DSIZE_GET(ssc0); in dai_ssp_set_reg_config()
2171 ssp_plat_data->params.sample_valid_bits += 16; in dai_ssp_set_reg_config()
2174 ssp_plat_data->params.tdm_slots = SSCR0_FRDC_GET(ssc0); in dai_ssp_set_reg_config()
2175 ssp_plat_data->params.tx_slots = SSTSA_GET(sstsa); in dai_ssp_set_reg_config()
2176 ssp_plat_data->params.rx_slots = SSRSA_GET(ssrsa); in dai_ssp_set_reg_config()
2177 ssp_plat_data->params.fsync_rate = cfg->rate; in dai_ssp_set_reg_config()
2178 dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING; in dai_ssp_set_reg_config()
2179 dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; in dai_ssp_set_reg_config()
2193 dp->tdm_slot_group = cfg->tdm_slot_group; in dai_ssp_set_config_blob()
2197 if (ssp_plat_data->is_initialized) { in dai_ssp_set_config_blob()
2198 dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING; in dai_ssp_set_config_blob()
2199 dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; in dai_ssp_set_config_blob()
2203 if (blob15->version == SSP_BLOB_VER_1_5) { in dai_ssp_set_config_blob()
2208 dai_ssp_set_reg_config(dp, cfg, (void *)&blob15->i2s_ssp_config); in dai_ssp_set_config_blob()
2209 err = dai_ssp_set_clock_control_ver_1_5(dp, &blob15->i2s_mclk_control); in dai_ssp_set_config_blob()
2213 } else if (blob30->version == SSP_BLOB_VER_3_0) { in dai_ssp_set_config_blob()
2218 dai_ssp_set_reg_config(dp, cfg, (void *)&blob30->i2s_ssp_config); in dai_ssp_set_config_blob()
2219 err = dai_ssp_set_clock_control_ver_1_5(dp, &blob30->i2s_mclk_control); in dai_ssp_set_config_blob()
2224 dai_ssp_set_reg_config(dp, cfg, (void *)&blob->i2s_driver_config.i2s_config); in dai_ssp_set_config_blob()
2225 err = dai_ssp_set_clock_control_ver_1(dp, &blob->i2s_driver_config.mclk_config); in dai_ssp_set_config_blob()
2231 ssp_plat_data->clk_active |= SSP_CLK_MCLK_ES_REQ; in dai_ssp_set_config_blob()
2235 ssp_plat_data->clk_active |= SSP_CLK_BCLK_ES_REQ; in dai_ssp_set_config_blob()
2236 ssp_plat_data->is_initialized = true; in dai_ssp_set_config_blob()
2255 if (!(ssp_plat_data->clk_active & SSP_CLK_MCLK_ES_REQ)) { in dai_ssp_pre_start()
2263 if (!(ssp_plat_data->clk_active & SSP_CLK_BCLK_ES_REQ)) { in dai_ssp_pre_start()
2280 if (dp->state[DAI_DIR_PLAYBACK] != DAI_STATE_RUNNING && in dai_ssp_post_stop()
2281 dp->state[DAI_DIR_CAPTURE] != DAI_STATE_RUNNING) { in dai_ssp_post_stop()
2282 if (!(ssp_plat_data->clk_active & SSP_CLK_BCLK_ES_REQ)) { in dai_ssp_post_stop()
2283 LOG_INF("releasing BCLK clocks for SSP%d...", dp->dai_index); in dai_ssp_post_stop()
2286 if (!(ssp_plat_data->clk_active & SSP_CLK_MCLK_ES_REQ)) { in dai_ssp_post_stop()
2287 LOG_INF("releasing MCLK clocks for SSP%d...", dp->dai_index); in dai_ssp_post_stop()
2298 key = k_spin_lock(&dp->lock); in dai_ssp_early_start()
2302 LOG_INF("SSP%d RX", dp->dai_index); in dai_ssp_early_start()
2305 LOG_INF("SSP%d TX", dp->dai_index); in dai_ssp_early_start()
2311 if (!(ssp_plat_data->clk_active & SSP_CLK_BCLK_ES_REQ)) { in dai_ssp_early_start()
2313 LOG_INF("SSP%d: set SSE", dp->dai_index); in dai_ssp_early_start()
2317 k_spin_unlock(&dp->lock, key); in dai_ssp_early_start()
2326 key = k_spin_lock(&dp->lock); in dai_ssp_start()
2332 dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group), in dai_ssp_start()
2334 dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group), in dai_ssp_start()
2337 dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group), in dai_ssp_start()
2339 dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group), in dai_ssp_start()
2344 LOG_INF("SSP%d TX", dp->dai_index); in dai_ssp_start()
2348 LOG_INF("SSP%d RX", dp->dai_index); in dai_ssp_start()
2354 dp->state[direction] = DAI_STATE_RUNNING; in dai_ssp_start()
2361 switch (ssp->config.format & DAI_INTEL_IPC3_SSP_FMT_CLOCK_PROVIDER_MASK) { in dai_ssp_start()
2365 /* delay for all SSP consumed clocks atm - see above */ in dai_ssp_start()
2371 k_spin_unlock(&dp->lock, key); in dai_ssp_start()
2380 key = k_spin_lock(&dp->lock); in dai_ssp_stop()
2387 switch (ssp->config.format & DAI_INTEL_IPC3_SSP_FMT_CLOCK_PROVIDER_MASK) { in dai_ssp_stop()
2391 /* delay for all SSP consumed clocks atm - see above */ in dai_ssp_stop()
2398 dp->state[DAI_DIR_CAPTURE] != DAI_STATE_PRE_RUNNING) { in dai_ssp_stop()
2399 LOG_INF("SSP%d RX", dp->dai_index); in dai_ssp_stop()
2402 dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group), SSMIDyCS_RXEN, 0); in dai_ssp_stop()
2403 dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group), SSMIDyCS_RSRE, 0); in dai_ssp_stop()
2409 dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; in dai_ssp_stop()
2414 dp->state[DAI_DIR_PLAYBACK] != DAI_STATE_PRE_RUNNING) { in dai_ssp_stop()
2415 LOG_INF("SSP%d TX", dp->dai_index); in dai_ssp_stop()
2418 dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group), SSMODyCS_TSRE, 0); in dai_ssp_stop()
2420 dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group), SSMODyCS_TXEN, 0); in dai_ssp_stop()
2426 dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING; in dai_ssp_stop()
2429 k_spin_unlock(&dp->lock, key); in dai_ssp_stop()
2435 LOG_INF("SSP%d RX", dp->dai_index); in dai_ssp_pause()
2437 LOG_INF("SSP%d TX", dp->dai_index); in dai_ssp_pause()
2440 dp->state[direction] = DAI_STATE_PAUSED; in dai_ssp_pause()
2446 struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data; in dai_ssp_trigger()
2449 LOG_DBG("SSP%d: cmd %d", dp->dai_index, cmd); in dai_ssp_trigger()
2453 if (dp->state[array_index] == DAI_STATE_PAUSED || in dai_ssp_trigger()
2454 dp->state[array_index] == DAI_STATE_PRE_RUNNING) { in dai_ssp_trigger()
2476 struct dai_config *params = (struct dai_config *)dev->config; in dai_ssp_config_get()
2477 struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data; in dai_ssp_config_get()
2482 return -EINVAL; in dai_ssp_config_get()
2490 params->rate = ssp_plat_data->params.fsync_rate; in dai_ssp_config_get()
2493 params->channels = POPCOUNT(ssp_plat_data->params.tx_slots); in dai_ssp_config_get()
2495 params->channels = POPCOUNT(ssp_plat_data->params.rx_slots); in dai_ssp_config_get()
2498 params->word_size = ssp_plat_data->params.sample_valid_bits; in dai_ssp_config_get()
2508 struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data; in dai_ssp_config_set()
2512 if (cfg->type == DAI_INTEL_SSP) { in dai_ssp_config_set()
2517 dai_ssp_program_channel_map(dp, cfg, ssp_plat_data->ssp_index, bespoke_cfg); in dai_ssp_config_set()
2525 struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data; in dai_ssp_get_properties()
2528 struct dai_properties *prop = &ssp->props; in dai_ssp_get_properties()
2531 prop->fifo_address = ssp_plat_data->fifo[array_index].offset; in dai_ssp_get_properties()
2532 prop->dma_hs_id = ssp_plat_data->fifo[array_index].handshake; in dai_ssp_get_properties()
2534 if (ssp_plat_data->clk_active & SSP_CLK_BCLK_ACTIVE) { in dai_ssp_get_properties()
2535 prop->reg_init_delay = 0; in dai_ssp_get_properties()
2537 prop->reg_init_delay = ssp_plat_data->params.bclk_delay; in dai_ssp_get_properties()
2540 LOG_INF("SSP%u: fifo %u, handshake %u, init delay %u", dp->dai_index, prop->fifo_address, in dai_ssp_get_properties()
2541 prop->dma_hs_id, prop->reg_init_delay); in dai_ssp_get_properties()
2550 ssp->acquire_count++; in ssp_acquire_ip()
2552 if (ssp->acquire_count == 1) { in ssp_acquire_ip()
2554 dai_ssp_pm_runtime_en_ssp_power(dp, ssp->ssp_index); in ssp_acquire_ip()
2557 dai_ssp_pm_runtime_dis_ssp_clk_gating(dp, ssp->ssp_index); in ssp_acquire_ip()
2563 I2CLCTL_MLCS(ssp->link_clock), in ssp_acquire_ip()
2573 if (ssp->acquire_count == 0) { in ssp_release_ip()
2577 --ssp->acquire_count; in ssp_release_ip()
2579 if (ssp->acquire_count == 0) { in ssp_release_ip()
2581 if (dp->state[DAI_DIR_CAPTURE] == DAI_STATE_PRE_RUNNING && in ssp_release_ip()
2582 dp->state[DAI_DIR_PLAYBACK] == DAI_STATE_PRE_RUNNING && in ssp_release_ip()
2584 (!(ssp->clk_active & SSP_CLK_BCLK_ES_REQ)), (true))) { in ssp_release_ip()
2586 LOG_INF("%s SSE clear SSP%d", __func__, ssp->ssp_index); in ssp_release_ip()
2599 dai_ssp_pm_runtime_en_ssp_clk_gating(dp, ssp->ssp_index); in ssp_release_ip()
2605 dai_ssp_pm_runtime_dis_ssp_power(dp, ssp->ssp_index); in ssp_release_ip()
2606 ssp->is_initialized = false; in ssp_release_ip()
2616 return -EEXIST; /* already created */ in dai_ssp_probe()
2622 LOG_ERR("SSP%d: alloc failed", ssp_plat_data->ssp_index); in dai_ssp_probe()
2623 return -ENOMEM; in dai_ssp_probe()
2627 dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_READY; in dai_ssp_probe()
2628 dp->state[DAI_DIR_CAPTURE] = DAI_STATE_READY; in dai_ssp_probe()
2631 /* Reset M/N, power-gating functions need it */ in dai_ssp_probe()
2632 dai_ssp_mn_reset_bclk_divider(dp, ssp_plat_data->ssp_index); in dai_ssp_probe()
2652 struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data; in ssp_pm_action()
2666 return -ENOTSUP; in ssp_pm_action()
2674 struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data; in dai_intel_ssp_init_device()
2676 dp->ssp_plat_data = ssp_get_device_instance(dp->ssp_index); in dai_intel_ssp_init_device()
2691 struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data; in dai_ssp_dma_control_set()
2694 dp->dai_index, (uint32_t)bespoke_cfg, size); in dai_ssp_dma_control_set()
2696 return -EINVAL; in dai_ssp_dma_control_set()
2699 if (dp->state[DAI_DIR_PLAYBACK] != DAI_STATE_READY || in dai_ssp_dma_control_set()
2700 dp->state[DAI_DIR_CAPTURE] != DAI_STATE_READY) { in dai_ssp_dma_control_set()
2701 return -EIO; in dai_ssp_dma_control_set()
2705 return -EINVAL; in dai_ssp_dma_control_set()