drivers: ssp: update SSP driver to support Intel ACE30 PTL

This commit refactors the SSP driver to support the Intel ACE30 PTL
platform. The changes include:
- Adding new structures ssp_rx_dir and ssp_tx_dir to hold the TDM
slot configuration for RX and TX directions
- Adjusting the dai_ssp_set_config_blob functions to work with
the new TDM slot configuration.

Signed-off-by: Damian Nikodem <damian.nikodem@intel.com>
This commit is contained in:
Damian Nikodem 2024-06-10 20:12:39 +02:00 committed by Carles Cufí
parent 9faf111744
commit a2386efbce
6 changed files with 306 additions and 70 deletions

View file

@ -11,6 +11,9 @@
#define DAI_INTEL_I2S_TDM_MAX_SLOT_MAP_COUNT 8
#define I2SIPCMC 8
#define I2SOPCMC 8
/**< Type of the gateway. */
enum dai_intel_ipc4_connector_node_id_type {
/**< HD/A host output (-> DSP). */
@ -228,12 +231,18 @@ struct dai_intel_ipc4_ssp_config {
uint32_t ssc1;
uint32_t sscto;
uint32_t sspsp;
#ifndef CONFIG_SOC_INTEL_ACE30_PTL
uint32_t sstsa;
uint32_t ssrsa;
#endif
uint32_t ssc2;
uint32_t sspsp2;
uint32_t ssc3;
uint32_t ssioc;
#ifdef CONFIG_SOC_INTEL_ACE30_PTL
uint64_t ssmidytsa[I2SIPCMC];
uint64_t ssmodytsa[I2SOPCMC];
#endif
} __packed;
struct dai_intel_ipc4_ssp_mclk_config {

View file

@ -873,9 +873,10 @@ static void dai_ssp_pm_runtime_dis_ssp_power(struct dai_intel_ssp *dp, uint32_t
}
static void dai_ssp_program_channel_map(struct dai_intel_ssp *dp,
const struct dai_config *cfg, uint32_t ssp_index)
const struct dai_config *cfg, uint32_t ssp_index, const void *spec_config)
{
#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30_PTL)
#if defined(CONFIG_SOC_INTEL_ACE20_LNL)
ARG_UNUSED(spec_config);
uint16_t pcmsycm = cfg->link_config;
/* Set upper slot number from configuration */
pcmsycm = pcmsycm | (dp->ssp_plat_data->params.tdm_slots - 1) << 4;
@ -889,10 +890,39 @@ static void dai_ssp_program_channel_map(struct dai_intel_ssp *dp,
/* Program HDA input stream parameters */
sys_write16((pcmsycm & 0xffff), reg_add);
}
#elif defined(CONFIG_SOC_INTEL_ACE30_PTL)
const struct dai_intel_ipc4_ssp_configuration_blob *blob = spec_config;
uint64_t time_slot_map = 0;
uint16_t pcmsycm = cfg->link_config;
uint8_t slot_count = 0;
if (DAI_INTEL_SSP_IS_BIT_SET(cfg->link_config, 15)) {
time_slot_map =
blob->i2s_driver_config.i2s_config.ssmidytsa[cfg->tdm_slot_group];
slot_count = POPCOUNT(time_slot_map >> 32) + POPCOUNT(time_slot_map & 0xFFFFFFFF);
pcmsycm = cfg->link_config | (slot_count - 1) << 4;
uint32_t reg_add = dai_ip_base(dp) + 0x1000 * ssp_index +
PCMSyCM_OFFSET(cfg->tdm_slot_group);
/* Program HDA output stream parameters */
sys_write16((pcmsycm & 0xffff), reg_add);
} else {
time_slot_map =
blob->i2s_driver_config.i2s_config.ssmodytsa[cfg->tdm_slot_group];
slot_count = POPCOUNT(time_slot_map >> 32) + POPCOUNT(time_slot_map & 0xFFFFFFFF);
pcmsycm = cfg->link_config | (slot_count - 1) << 4;
uint32_t reg_add = dai_ip_base(dp) + 0x1000 * ssp_index +
PCMSyCM_OFFSET(cfg->tdm_slot_group + I2SOPCMC);
/* Program HDA input stream parameters */
sys_write16((pcmsycm & 0xffff), reg_add);
}
#else
ARG_UNUSED(dp);
ARG_UNUSED(cfg);
ARG_UNUSED(ssp_index);
ARG_UNUSED(spec_config);
#endif /* CONFIG_SOC_INTEL_ACE20_LNL */
}
@ -907,11 +937,12 @@ static void dai_ssp_empty_tx_fifo(struct dai_intel_ssp *dp)
* so wait for set TNF then for TFL zero - order matter.
*/
#ifdef CONFIG_SOC_INTEL_ACE30_PTL
ret = dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(0),
ret = dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(dp->tdm_slot_group),
SSMODyCS_TNF, SSMODyCS_TNF,
DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE);
ret |= dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(0), SSMODyCS_TFL, 0,
ret |= dai_ssp_poll_for_register_delay(dai_base(dp) + SSMODyCS(dp->tdm_slot_group),
SSMODyCS_TFL, 0,
DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE *
(DAI_INTEL_SSP_FIFO_DEPTH - 1) / 2);
#else
@ -944,8 +975,10 @@ static void ssp_empty_rx_fifo_on_start(struct dai_intel_ssp *dp)
if (sssr & SSSR_ROR) {
/* The RX FIFO is in overflow condition, empty it */
for (i = 0; i < DAI_INTEL_SSP_FIFO_DEPTH; i++)
sys_read32(dai_base(dp) + SSMIDyD(0));
for (uint32_t idx = 0; idx < I2SIPCMC; ++idx) {
for (i = 0; i < DAI_INTEL_SSP_FIFO_DEPTH; i++)
sys_read32(dai_base(dp) + SSMIDyD(idx));
}
/* Clear the overflow status */
dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR);
@ -953,14 +986,17 @@ static void ssp_empty_rx_fifo_on_start(struct dai_intel_ssp *dp)
sssr = sys_read32(dai_base(dp) + SSSR);
}
while ((sys_read32(dai_base(dp) + SSMIDyCS(0)) & SSMIDyCS_RNE) && retry--) {
uint32_t entries = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(0)));
for (uint32_t idx = 0; idx < I2SIPCMC; ++idx) {
while ((sys_read32(dai_base(dp) + SSMIDyCS(idx)) & SSMIDyCS_RNE) && retry--) {
uint32_t entries = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) +
SSMIDyCS(idx)));
/* Empty the RX FIFO (the DMA is not running at this point) */
for (i = 0; i < entries + 1; i++)
sys_read32(dai_base(dp) + SSMIDyD(0));
/* Empty the RX FIFO (the DMA is not running at this point) */
for (i = 0; i < entries + 1; i++)
sys_read32(dai_base(dp) + SSMIDyD(idx));
sssr = sys_read32(dai_base(dp) + SSSR);
sssr = sys_read32(dai_base(dp) + SSSR);
}
}
}
@ -969,41 +1005,47 @@ static void ssp_empty_rx_fifo_on_stop(struct dai_intel_ssp *dp)
struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp);
uint64_t sample_ticks = ssp_plat_data->params.fsync_rate ?
1000000 / ssp_plat_data->params.fsync_rate : 0;
uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX;
uint32_t i, sssr, ssmidycs;
uint32_t entries[2];
sssr = sys_read32(dai_base(dp) + SSSR);
entries[0] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(0)));
while ((sys_read32(dai_base(dp) + SSMIDyCS(0)) & SSMIDyCS_RNE) && retry--) {
/* Wait one sample time */
k_busy_wait(sample_ticks);
entries[1] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(0)));
sssr = sys_read32(dai_base(dp) + SSSR);
ssmidycs = sys_read32(dai_base(dp) + SSMIDyCS(0));
if (entries[0] > entries[1]) {
/*
* The DMA is reading the FIFO, check the status in the
* next loop
*/
entries[0] = entries[1];
} else if (!(ssmidycs & SSMIDyCS_RFS)) {
/*
* The DMA request is not asserted, read the FIFO
* directly, otherwise let the next loop iteration to
* check the status
*/
for (i = 0; i < entries[1] + 1; i++)
sys_read32(dai_base(dp) + SSMIDyD(0));
}
sssr = sys_read32(dai_base(dp) + SSSR);
if (ssp_is_acquired(dp->ssp_plat_data)) {
return;
}
sssr = sys_read32(dai_base(dp) + SSSR);
for (uint32_t idx = 0; idx < I2SIPCMC; ++idx) {
entries[0] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(idx)));
while ((sys_read32(dai_base(dp) + SSMIDyCS(idx)) & SSMIDyCS_RNE) && retry--) {
/* Wait one sample time */
k_busy_wait(sample_ticks);
entries[1] = SSMIDyCS_RFL_VAL(sys_read32(dai_base(dp) + SSMIDyCS(idx)));
sssr = sys_read32(dai_base(dp) + SSSR);
ssmidycs = sys_read32(dai_base(dp) + SSMIDyCS(idx));
if (entries[0] > entries[1]) {
/*
* The DMA is reading the FIFO, check the status in the
* next loop
*/
entries[0] = entries[1];
} else if (!(ssmidycs & SSMIDyCS_RFS)) {
/*
* The DMA request is not asserted, read the FIFO
* directly, otherwise let the next loop iteration to
* check the status
*/
for (i = 0; i < entries[1] + 1; i++)
sys_read32(dai_base(dp) + SSMIDyD(idx));
}
sssr = sys_read32(dai_base(dp) + SSSR);
}
}
/* Just in case clear the overflow status */
dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR);
}
@ -1688,8 +1730,13 @@ static int dai_ssp_set_config_tplg(struct dai_intel_ssp *dp, const struct dai_co
sys_write32(ssioc, dai_base(dp) + SSIOC);
sys_write32(ssto, dai_base(dp) + SSTO);
#ifdef CONFIG_SOC_INTEL_ACE30_PTL
sys_write64((uint64_t)sstsa, dai_base(dp) + SSMODyTSA(0));
sys_write64((uint64_t)ssrsa, dai_base(dp) + SSMIDyTSA(0));
for (uint32_t idx = 0; idx < I2SIPCMC; ++idx) {
sys_write64(sstsa, dai_base(dp) + SSMODyTSA(idx));
}
for (uint32_t idx = 0; idx < I2SOPCMC; ++idx) {
sys_write64(ssrsa, dai_base(dp) + SSMIDyTSA(idx));
}
#else
sys_write32(sstsa, dai_base(dp) + SSTSA);
sys_write32(ssrsa, dai_base(dp) + SSRSA);
@ -1735,6 +1782,16 @@ clk:
ssp_plat_data->clk_active |= SSP_CLK_BCLK_ES_REQ;
if (enable_sse) {
#ifdef CONFIG_SOC_INTEL_ACE30_PTL
dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group),
SSMIDyCS_RSRE, SSMIDyCS_RSRE);
dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group),
SSMODyCS_TSRE, SSMODyCS_TSRE);
#else
dai_ssp_update_bits(dp, SSCR1,
SSCR1_TSRE | SSCR1_RSRE,
SSCR1_TSRE | SSCR1_RSRE);
#endif
/* enable port */
dai_ssp_update_bits(dp, SSCR0, SSCR0_SSE, SSCR0_SSE);
@ -1758,6 +1815,19 @@ clk:
LOG_INF("hw_free stage: releasing BCLK clocks for SSP%d...",
dp->dai_index);
if (ssp_plat_data->clk_active & SSP_CLK_BCLK_ACTIVE) {
#ifdef CONFIG_SOC_INTEL_ACE30_PTL
for (uint32_t idx = 0; idx < I2SOPCMC; ++idx) {
dai_ssp_update_bits(dp, SSMODyCS(idx), SSMODyCS_TSRE, 0);
}
for (uint32_t idx = 0; idx < I2SIPCMC; ++idx) {
dai_ssp_update_bits(dp, SSMIDyCS(idx), SSMIDyCS_RSRE, 0);
}
#else
dai_ssp_update_bits(dp, SSCR1,
SSCR1_TSRE | SSCR1_RSRE,
0);
#endif
dai_ssp_update_bits(dp, SSCR0, SSCR0_SSE, 0);
LOG_INF("SSE clear for SSP%d", dp->dai_index);
}
@ -1957,17 +2027,19 @@ static int dai_ssp_set_clock_control_ver_1(struct dai_intel_ssp *dp,
static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_config *cfg,
const struct dai_intel_ipc4_ssp_config *regs)
{
uint32_t ssc0, sstsa, ssrsa;
uint32_t sscr1 = regs->ssc1;
struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp);
uint32_t sscr1 = 0;
uint32_t sstsa = 0;
uint32_t ssrsa = 0;
uint32_t ssc0 = regs->ssc0;
#ifdef CONFIG_SOC_INTEL_ACE30_PTL
sscr1 = regs->ssc1 & ~(SSCR1_RSVD21);
#else
sscr1 = regs->ssc1 & ~(SSCR1_RSRE | SSCR1_TSRE);
#endif
ssc0 = regs->ssc0;
sstsa = SSTSA_GET(regs->sstsa);
ssrsa = SSRSA_GET(regs->ssrsa);
#endif
LOG_INF("SSP%d configuration:", dp->dai_index);
#ifndef CONFIG_SOC_INTEL_ACE30_PTL
@ -1986,14 +2058,21 @@ static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_co
sys_write32(sscr1, dai_base(dp) + SSCR1);
sys_write32(regs->ssc2 | SSCR2_SFRMEN, dai_base(dp) + SSCR2); /* hardware specific flow */
sys_write32(regs->ssc2, dai_base(dp) + SSCR2);
#ifndef CONFIG_SOC_INTEL_ACE30_PTL
sys_write32(regs->ssc3, dai_base(dp) + SSCR3);
#endif
sys_write32(regs->sspsp, dai_base(dp) + SSPSP);
sys_write32(regs->sspsp2, dai_base(dp) + SSPSP2);
sys_write32(regs->ssioc, dai_base(dp) + SSIOC);
sys_write32(regs->sscto, dai_base(dp) + SSTO);
#ifdef CONFIG_SOC_INTEL_ACE30_PTL
sys_write64((uint64_t)sstsa, dai_base(dp) + SSMODyTSA(0));
sys_write64((uint64_t)ssrsa, dai_base(dp) + SSMIDyTSA(0));
for (uint32_t idx = 0; idx < I2SIPCMC; ++idx) {
sys_write64(regs->ssmidytsa[idx], dai_base(dp) + SSMIDyTSA(idx));
}
for (uint32_t idx = 0; idx < I2SOPCMC; ++idx) {
sys_write64(regs->ssmodytsa[idx], dai_base(dp) + SSMODyTSA(idx));
}
#else
sys_write32(sstsa, dai_base(dp) + SSTSA);
sys_write32(ssrsa, dai_base(dp) + SSRSA);
@ -2006,16 +2085,19 @@ static void dai_ssp_set_reg_config(struct dai_intel_ssp *dp, const struct dai_co
LOG_INF(" ssioc = 0x%08x, ssrsa = 0x%08x, sstsa = 0x%08x",
regs->ssioc, ssrsa, sstsa);
dp->ssp_plat_data->params.sample_valid_bits = SSCR0_DSIZE_GET(ssc0);
ssp_plat_data->params.sample_valid_bits = SSCR0_DSIZE_GET(ssc0);
if (ssc0 & SSCR0_EDSS) {
dp->ssp_plat_data->params.sample_valid_bits += 16;
ssp_plat_data->params.sample_valid_bits += 16;
}
dp->ssp_plat_data->params.tdm_slots = SSCR0_FRDC_GET(ssc0);
dp->ssp_plat_data->params.tx_slots = SSTSA_GET(sstsa);
dp->ssp_plat_data->params.rx_slots = SSRSA_GET(ssrsa);
dp->ssp_plat_data->params.fsync_rate = cfg->rate;
#ifdef CONFIG_SOC_INTEL_ACE30_PTL
ssp_plat_data->params.tx_slots = regs->ssmodytsa[dp->tdm_slot_group];
ssp_plat_data->params.rx_slots = regs->ssmidytsa[dp->tdm_slot_group];
#else
ssp_plat_data->params.tdm_slots = SSCR0_FRDC_GET(ssc0);
ssp_plat_data->params.tx_slots = SSTSA_GET(sstsa);
ssp_plat_data->params.rx_slots = SSRSA_GET(ssrsa);
#endif
ssp_plat_data->params.fsync_rate = cfg->rate;
dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING;
dp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING;
}
@ -2028,6 +2110,10 @@ static int dai_ssp_set_config_blob(struct dai_intel_ssp *dp, const struct dai_co
struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp);
int err;
#ifdef CONFIG_SOC_INTEL_ACE30_PTL
dp->tdm_slot_group = cfg->tdm_slot_group;
#endif
/* set config only once for playback or capture */
if (ssp_plat_data->is_initialized) {
dp->state[DAI_DIR_PLAYBACK] = DAI_STATE_PRE_RUNNING;
@ -2151,11 +2237,15 @@ static void dai_ssp_start(struct dai_intel_ssp *dp, int direction)
/* enable DMA */
#if CONFIG_SOC_INTEL_ACE30_PTL
if (direction == DAI_DIR_PLAYBACK) {
dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TSRE, SSMODyCS_TSRE);
dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TXEN, SSMODyCS_TXEN);
dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group),
SSMODyCS_TSRE, SSMODyCS_TSRE);
dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group),
SSMODyCS_TXEN, SSMODyCS_TXEN);
} else {
dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RSRE, SSMIDyCS_RSRE);
dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RXEN, SSMIDyCS_RXEN);
dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group),
SSMIDyCS_RSRE, SSMIDyCS_RSRE);
dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group),
SSMIDyCS_RXEN, SSMIDyCS_RXEN);
}
#else
if (direction == DAI_DIR_PLAYBACK) {
@ -2218,8 +2308,8 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction)
dp->state[DAI_DIR_CAPTURE] != DAI_STATE_PRE_RUNNING) {
LOG_INF("SSP%d RX", dp->dai_index);
#if CONFIG_SOC_INTEL_ACE30_PTL
dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RXEN, 0);
dai_ssp_update_bits(dp, SSMIDyCS(0), SSMIDyCS_RSRE, 0);
dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group), SSMIDyCS_RXEN, 0);
dai_ssp_update_bits(dp, SSMIDyCS(dp->tdm_slot_group), SSMIDyCS_RSRE, 0);
#else
dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, 0);
dai_ssp_update_bits(dp, SSCR1, SSCR1_RSRE, 0);
@ -2234,9 +2324,9 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction)
dp->state[DAI_DIR_PLAYBACK] != DAI_STATE_PRE_RUNNING) {
LOG_INF("SSP%d TX", dp->dai_index);
#if CONFIG_SOC_INTEL_ACE30_PTL
dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TSRE, 0);
dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group), SSMODyCS_TSRE, 0);
dai_ssp_empty_tx_fifo(dp);
dai_ssp_update_bits(dp, SSMODyCS(0), SSMODyCS_TXEN, 0);
dai_ssp_update_bits(dp, SSMODyCS(dp->tdm_slot_group), SSMODyCS_TXEN, 0);
#else
dai_ssp_update_bits(dp, SSCR1, SSCR1_TSRE, 0);
dai_ssp_empty_tx_fifo(dp);
@ -2251,7 +2341,6 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction)
dp->state[DAI_DIR_PLAYBACK] == DAI_STATE_PRE_RUNNING &&
COND_CODE_1(CONFIG_INTEL_ADSP_CAVS,
(!(ssp_plat_data->clk_active & SSP_CLK_BCLK_ES_REQ)), (true))) {
if (!ssp_is_acquired(ssp_plat_data)) {
dai_ssp_update_bits(dp, SSCR0, SSCR0_SSE, 0);
LOG_INF("%s SSE clear SSP%d", __func__, ssp_plat_data->ssp_index);
@ -2342,6 +2431,7 @@ static int dai_ssp_config_set(const struct device *dev, const struct dai_config
const void *bespoke_cfg)
{
struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data;
struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp);
int ret;
if (cfg->type == DAI_INTEL_SSP) {
@ -2349,7 +2439,8 @@ static int dai_ssp_config_set(const struct device *dev, const struct dai_config
} else {
ret = dai_ssp_set_config_blob(dp, cfg, bespoke_cfg);
}
dai_ssp_program_channel_map(dp, cfg, dp->ssp_index);
dai_ssp_program_channel_map(dp, cfg, ssp_plat_data->ssp_index, bespoke_cfg);
return ret;
}
@ -2421,6 +2512,12 @@ static int dai_ssp_remove(struct dai_intel_ssp *dp)
{
struct dai_intel_ssp_plat_data *ssp_plat_data = dai_get_plat_data(dp);
if (ssp_is_acquired(ssp_plat_data)) {
k_free(dai_get_drvdata(dp));
dai_set_drvdata(dp, NULL);
return 0;
}
dai_ssp_pm_runtime_en_ssp_clk_gating(dp, ssp_plat_data->ssp_index);
dai_ssp_mclk_disable_unprepare(dp);
@ -2502,6 +2599,7 @@ static struct dai_driver_api dai_intel_ssp_api_funcs = {
static struct dai_intel_ssp dai_intel_ssp_data_##n = { \
.dai_index = DT_INST_REG_ADDR(n), \
.ssp_index = DT_PROP(DT_INST_PARENT(n), ssp_index), \
.tdm_slot_group = 0, \
}; \
\
PM_DEVICE_DT_INST_DEFINE(n, ssp_pm_action); \

View file

@ -142,6 +142,7 @@ struct dai_intel_ssp_pdata {
struct dai_intel_ssp {
uint32_t dai_index;
uint32_t ssp_index;
uint32_t tdm_slot_group;
uint32_t state[2];
struct k_spinlock lock; /**< locking mechanism */
int sref; /**< simple ref counter, guarded by lock */

View file

@ -29,6 +29,8 @@
#define SSMODyD(y) 0x64 + 0x10*I2SIPCMC + 0x10*y
#define SSMODyTSA(y) 0x68 + 0x10*I2SIPCMC + 0x10*y
#define PCMSyCM_OFFSET(x) 0x16 + 0x4*(x)
#define OUT_FIFO SSMODyD(0)
#define IN_FIFO SSMIDyD(0)
@ -211,8 +213,6 @@
#define I2SLCTL_OFLEN BIT(4)
#define I2SLCTL_SPA(x) BIT(16 + x)
#define I2SLCTL_CPA(x) BIT(23 + x)
#define PCMS0CM_OFFSET 0x16
#define PCMS1CM_OFFSET PCMS0CM_OFFSET + 4 * I2SIPCMC
#define I2CLCTL_MLCS(x) DAI_INTEL_SSP_SET_BITS(30, 27, x)
#define SHIM_CLKCTL 0x78

View file

@ -238,6 +238,48 @@
reg = <0x0>;
status = "okay";
};
ssp01: ssp@1 {
compatible = "intel,ssp-dai";
reg = <0x1>;
status = "okay";
};
ssp02: ssp@2 {
compatible = "intel,ssp-dai";
reg = <0x2>;
status = "okay";
};
ssp03: ssp@3 {
compatible = "intel,ssp-dai";
reg = <0x3>;
status = "okay";
};
ssp04: ssp@4 {
compatible = "intel,ssp-dai";
reg = <0x4>;
status = "okay";
};
ssp05: ssp@5 {
compatible = "intel,ssp-dai";
reg = <0x5>;
status = "okay";
};
ssp06: ssp@6 {
compatible = "intel,ssp-dai";
reg = <0x6>;
status = "okay";
};
ssp07: ssp@7 {
compatible = "intel,ssp-dai";
reg = <0x7>;
status = "okay";
};
};
ssp1: ssp@29100 {
@ -260,6 +302,48 @@
reg = <0x10>;
status = "okay";
};
ssp11: ssp@11 {
compatible = "intel,ssp-dai";
reg = <0x11>;
status = "okay";
};
ssp12: ssp@12 {
compatible = "intel,ssp-dai";
reg = <0x12>;
status = "okay";
};
ssp13: ssp@13 {
compatible = "intel,ssp-dai";
reg = <0x13>;
status = "okay";
};
ssp14: ssp@14 {
compatible = "intel,ssp-dai";
reg = <0x14>;
status = "okay";
};
ssp15: ssp@15 {
compatible = "intel,ssp-dai";
reg = <0x15>;
status = "okay";
};
ssp16: ssp@16 {
compatible = "intel,ssp-dai";
reg = <0x16>;
status = "okay";
};
ssp17: ssp@17 {
compatible = "intel,ssp-dai";
reg = <0x17>;
status = "okay";
};
};
ssp2: ssp@2a100 {
@ -282,6 +366,48 @@
reg = <0x20>;
status = "okay";
};
ssp21: ssp@21 {
compatible = "intel,ssp-dai";
reg = <0x21>;
status = "okay";
};
ssp22: ssp@22 {
compatible = "intel,ssp-dai";
reg = <0x22>;
status = "okay";
};
ssp23: ssp@23 {
compatible = "intel,ssp-dai";
reg = <0x23>;
status = "okay";
};
ssp24: ssp@24 {
compatible = "intel,ssp-dai";
reg = <0x24>;
status = "okay";
};
ssp25: ssp@25 {
compatible = "intel,ssp-dai";
reg = <0x25>;
status = "okay";
};
ssp26: ssp@26 {
compatible = "intel,ssp-dai";
reg = <0x26>;
status = "okay";
};
ssp27: ssp@27 {
compatible = "intel,ssp-dai";
reg = <0x27>;
status = "okay";
};
};
mem_window0: mem_window@70200 {

View file

@ -268,6 +268,8 @@ struct dai_config {
size_t block_size;
/** DAI specific link configuration. */
uint16_t link_config;
/**< tdm slot goup number*/
uint32_t tdm_slot_group;
};
/**