Skip to content

Commit 2958a40

Browse files
softwareckinashif
authored andcommitted
adsp: dmic: Add source clock selection support
The dmic driver has been expanded to support different clock sources. Signed-off-by: Adrian Warecki <[email protected]>
1 parent 64b2246 commit 2958a40

File tree

3 files changed

+94
-4
lines changed

3 files changed

+94
-4
lines changed

drivers/dai/intel/dmic/dmic.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ struct nhlt_dmic_clock_on_delay {
150150
};
151151

152152
struct nhlt_dmic_channel_ctrl_mask {
153-
uint32_t channel_ctrl_mask;
153+
uint8_t channel_ctrl_mask;
154+
uint8_t clock_source;
155+
uint16_t rsvd;
154156
};
155157

156158
struct nhlt_pdm_ctrl_mask {

drivers/dai/intel/dmic/dmic_nhlt.c

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
LOG_MODULE_REGISTER(LOG_DOMAIN);
1414

1515
#include <zephyr/drivers/dai.h>
16+
#include <adsp_clk.h>
1617
#include "dmic.h"
1718
#include "dmic_regs.h"
1819

@@ -125,6 +126,68 @@ static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic,
125126

126127
return 0;
127128
}
129+
130+
131+
/*
132+
* @brief Set clock source used by device
133+
*
134+
* @param source Clock source index
135+
*/
136+
static inline void dai_dmic_clock_select_set(const struct dai_intel_dmic *dmic, uint32_t source)
137+
{
138+
uint32_t val;
139+
#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */
140+
val = sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET);
141+
val &= ~DMICLVSCTL_MLCS;
142+
val |= FIELD_PREP(DMICLVSCTL_MLCS, source);
143+
sys_write32(val, dmic->vshim_base + DMICLVSCTL_OFFSET);
144+
#else
145+
val = sys_read32(dmic->shim_base + DMICLCTL_OFFSET);
146+
val &= ~DMICLCTL_MLCS;
147+
val |= FIELD_PREP(DMICLCTL_MLCS, source);
148+
sys_write32(val, dmic->shim_base + DMICLCTL_OFFSET);
149+
#endif
150+
}
151+
152+
/*
153+
* @brief Get clock source used by device
154+
*
155+
* @return Clock source index
156+
*/
157+
static inline uint32_t dai_dmic_clock_select_get(const struct dai_intel_dmic *dmic)
158+
{
159+
uint32_t val;
160+
#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */
161+
val = sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET);
162+
return FIELD_GET(DMICLVSCTL_MLCS, val);
163+
#else
164+
val = sys_read32(dmic->shim_base + DMICLCTL_OFFSET);
165+
return FIELD_GET(DMICLCTL_MLCS, val);
166+
#endif
167+
}
168+
169+
/*
170+
* @brief Set clock source used by device
171+
*
172+
* @param source Clock source index
173+
*/
174+
static int dai_dmic_set_clock(const struct dai_intel_dmic *dmic, const uint8_t clock_source)
175+
{
176+
LOG_DBG("%s(): clock_source = %u", __func__, clock_source);
177+
178+
if (!adsp_clock_source_is_supported(clock_source)) {
179+
return -ENOTSUP;
180+
}
181+
182+
#ifndef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */
183+
if (clock_source && !(sys_read32(dmic->shim_base + DMICLCAP_OFFSET) & DMICLCAP_MLCS)) {
184+
return -ENOTSUP;
185+
}
186+
#endif
187+
188+
dai_dmic_clock_select_set(dmic, clock_source);
189+
return 0;
190+
}
128191
#else
129192
static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic,
130193
int32_t *outcontrol,
@@ -204,6 +267,11 @@ static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic,
204267

205268
return 0;
206269
}
270+
271+
static inline int dai_dmic_set_clock(const struct dai_intel_dmic *dmic, const uint8_t clock_source)
272+
{
273+
return 0;
274+
}
207275
#endif
208276

209277
int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cfg)
@@ -213,6 +281,8 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
213281
struct nhlt_pdm_ctrl_fir_cfg *fir_cfg_b[DMIC_HW_CONTROLLERS_MAX];
214282
struct nhlt_pdm_fir_coeffs *fir_a[DMIC_HW_CONTROLLERS_MAX] = {NULL};
215283
struct nhlt_pdm_fir_coeffs *fir_b[DMIC_HW_CONTROLLERS_MAX];
284+
struct nhlt_dmic_channel_ctrl_mask *dmic_cfg;
285+
216286
uint32_t out_control[DMIC_HW_FIFOS_MAX] = {0};
217287
uint32_t channel_ctrl_mask;
218288
uint32_t fir_control;
@@ -253,11 +323,17 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
253323
p += sizeof(struct nhlt_dmic_clock_on_delay);
254324

255325
/* Channel_ctlr_mask bits indicate the FIFOs enabled*/
256-
channel_ctrl_mask = ((struct nhlt_dmic_channel_ctrl_mask *)p)->channel_ctrl_mask;
326+
dmic_cfg = (struct nhlt_dmic_channel_ctrl_mask *)p;
327+
channel_ctrl_mask = dmic_cfg->channel_ctrl_mask;
257328
num_fifos = POPCOUNT(channel_ctrl_mask); /* Count set bits */
258329
p += sizeof(struct nhlt_dmic_channel_ctrl_mask);
259330
LOG_DBG("dmic_set_config_nhlt(): channel_ctrl_mask = %d", channel_ctrl_mask);
260331

332+
/* Configure clock source */
333+
ret = dai_dmic_set_clock(dmic, dmic_cfg->clock_source);
334+
if (ret)
335+
return ret;
336+
261337
/* Get OUTCONTROLx configuration */
262338
if (num_fifos < 1 || num_fifos > DMIC_HW_FIFOS_MAX) {
263339
LOG_ERR("dmic_set_config_nhlt(): illegal number of FIFOs %d", num_fifos);
@@ -623,13 +699,14 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
623699
return -EINVAL;
624700
}
625701

626-
dmic->dai_config_params.rate = CONFIG_DAI_DMIC_HW_IOCLK / rate_div;
702+
dmic->dai_config_params.rate = adsp_clock_source_frequency(dmic_cfg->clock_source) /
703+
rate_div;
627704
LOG_INF("dmic_set_config_nhlt(): rate = %d, channels = %d, format = %d",
628705
dmic->dai_config_params.rate, dmic->dai_config_params.channels,
629706
dmic->dai_config_params.format);
630707

631708
LOG_INF("dmic_set_config_nhlt(): io_clk %u, rate_div %d",
632-
CONFIG_DAI_DMIC_HW_IOCLK, rate_div);
709+
adsp_clock_source_frequency(dmic_cfg->clock_source), rate_div);
633710

634711
LOG_INF("dmic_set_config_nhlt(): enable0 %u, enable1 %u",
635712
dmic->enable[0], dmic->enable[1]);

tests/boards/intel_adsp/ssp/src/main.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,15 @@ static void *adsp_ssp_setup(void)
407407
return NULL;
408408
}
409409

410+
411+
bool adsp_clock_source_is_supported(int source)
412+
{
413+
return true;
414+
}
415+
416+
uint32_t adsp_clock_source_frequency(int source)
417+
{
418+
return 0;
419+
}
420+
410421
ZTEST_SUITE(adsp_ssp, NULL, adsp_ssp_setup, NULL, NULL, NULL);

0 commit comments

Comments
 (0)