-
Notifications
You must be signed in to change notification settings - Fork 8.4k
Dai intel dmic additions #48949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dai intel dmic additions #48949
Changes from all commits
6a52ede
333ff93
02407d3
a63b80f
850e1ca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # Copyright (c) 2022 Intel Corporation | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| # Suppress "unique_unit_address_if_enabled" to handle the following overlaps: | ||
| # - dmic0: dmic0@10000 & dmic1: dmic1@10000 | ||
| list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # Copyright (c) 2022 Intel Corporation | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| # Suppress "unique_unit_address_if_enabled" to handle the following overlaps: | ||
| # - dmic0: dmic0@10000 & dmic1: dmic1@10000 | ||
| list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # Copyright (c) 2022 Intel Corporation | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| # Suppress "unique_unit_address_if_enabled" to handle the following overlaps: | ||
| # - dmic0: dmic0@10000 & dmic1: dmic1@10000 | ||
| list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,82 @@ struct dai_dmic_global_shared dai_dmic_global; | |
|
|
||
| int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *spec_config); | ||
|
|
||
| /* Exponent function for small values of x. This function calculates | ||
| * fairly accurately exponent for x in range -2.0 .. +2.0. The iteration | ||
| * uses first 11 terms of Taylor series approximation for exponent | ||
| * function. With the current scaling the numerator just remains under | ||
| * 64 bits with the 11 terms. | ||
| * | ||
| * See https://en.wikipedia.org/wiki/Exponential_function#Computation | ||
| * | ||
| * The input is Q3.29 | ||
| * The output is Q9.23 | ||
| */ | ||
| static int32_t exp_small_fixed(int32_t x) | ||
| { | ||
| int64_t p; | ||
| int64_t num = Q_SHIFT_RND(x, 29, 23); | ||
| int32_t y = (int32_t)num; | ||
| int32_t den = 1; | ||
| int32_t inc; | ||
| int k; | ||
|
|
||
| /* Numerator is x^k, denominator is k! */ | ||
| for (k = 2; k < 12; k++) { | ||
| p = num * x; /* Q9.23 x Q3.29 -> Q12.52 */ | ||
| num = Q_SHIFT_RND(p, 52, 23); | ||
| den = den * k; | ||
| inc = (int32_t)(num / den); | ||
| y += inc; | ||
| } | ||
|
|
||
| return y + ONE_Q23; | ||
| } | ||
|
|
||
| static int32_t exp_fixed(int32_t x) | ||
| { | ||
| int32_t xs; | ||
| int32_t y; | ||
| int32_t z; | ||
| int i; | ||
| int n = 0; | ||
|
|
||
| if (x < Q_CONVERT_FLOAT(-11.5, 27)) | ||
| return 0; | ||
|
|
||
| if (x > Q_CONVERT_FLOAT(7.6245, 27)) | ||
| return INT32_MAX; | ||
|
|
||
| /* x is Q5.27 */ | ||
| xs = x; | ||
| while (xs >= TWO_Q27 || xs <= MINUS_TWO_Q27) { | ||
| xs >>= 1; | ||
| n++; | ||
| } | ||
|
|
||
| /* exp_small_fixed() input is Q3.29, while x1 is Q5.27 | ||
| * exp_small_fixed() output is Q9.23, while z is Q12.20 | ||
| */ | ||
| z = Q_SHIFT_RND(exp_small_fixed(Q_SHIFT_LEFT(xs, 27, 29)), 23, 20); | ||
| y = ONE_Q20; | ||
| for (i = 0; i < (1 << n); i++) | ||
| y = (int32_t)Q_MULTSR_32X32((int64_t)y, z, 20, 20, 20); | ||
|
|
||
| return y; | ||
| } | ||
|
|
||
| static int32_t db2lin_fixed(int32_t db) | ||
| { | ||
| int32_t arg; | ||
|
|
||
| if (db < Q_CONVERT_FLOAT(-100.0, 24)) | ||
| return 0; | ||
|
|
||
| /* Q8.24 x Q5.27, result needs to be Q5.27 */ | ||
| arg = (int32_t)Q_MULTSR_32X32((int64_t)db, LOG10_DIV20_Q27, 24, 27, 27); | ||
| return exp_fixed(arg); | ||
| } | ||
|
|
||
| static void dai_dmic_update_bits(const struct dai_intel_dmic *dmic, | ||
| uint32_t reg, uint32_t mask, uint32_t val) | ||
| { | ||
|
|
@@ -157,7 +233,7 @@ static void dai_dmic_irq_handler(const void *data) | |
| /* Trace OUTSTAT0 register */ | ||
| val0 = dai_dmic_read(dmic, OUTSTAT0); | ||
| val1 = dai_dmic_read(dmic, OUTSTAT1); | ||
| LOG_INF("dmic_irq_handler(), OUTSTAT0 = 0x%x, OUTSTAT1 = 0x%x", val0, val1); | ||
| LOG_DBG("dmic_irq_handler(), OUTSTAT0 = 0x%x, OUTSTAT1 = 0x%x", val0, val1); | ||
|
|
||
| if (val0 & OUTSTAT0_ROR_BIT) { | ||
| LOG_ERR("dmic_irq_handler(): full fifo A or PDM overrun"); | ||
|
|
@@ -174,30 +250,53 @@ static void dai_dmic_irq_handler(const void *data) | |
|
|
||
| static inline void dai_dmic_dis_clk_gating(const struct dai_intel_dmic *dmic) | ||
| { | ||
| #ifdef CONFIG_SOC_SERIES_INTEL_CAVS_V15 | ||
|
||
| uint32_t shim_reg; | ||
|
|
||
| shim_reg = sys_read32(SHIM_CLKCTL) | SHIM_CLKCTL_DMICFDCGB; | ||
|
|
||
| sys_write32(shim_reg, SHIM_CLKCTL); | ||
|
|
||
| LOG_INF("dis-dmic-clk-gating CLKCTL %08x", shim_reg); | ||
| #else | ||
| /* Disable DMIC clock gating */ | ||
| sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) | DMIC_DCGD), | ||
| dmic->shim_base + DMICLCTL_OFFSET); | ||
| #endif | ||
| } | ||
|
|
||
| static inline void dai_dmic_en_clk_gating(const struct dai_intel_dmic *dmic) | ||
| { | ||
| #ifdef CONFIG_SOC_SERIES_INTEL_CAVS_V15 | ||
| uint32_t shim_reg; | ||
|
|
||
| shim_reg = sys_read32(SHIM_CLKCTL) & ~SHIM_CLKCTL_DMICFDCGB; | ||
|
|
||
| sys_write32(shim_reg, SHIM_CLKCTL); | ||
|
|
||
| LOG_INF("en-dmic-clk-gating CLKCTL %08x", shim_reg); | ||
| #else | ||
| /* Enable DMIC clock gating */ | ||
| sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) & ~DMIC_DCGD), | ||
| dmic->shim_base + DMICLCTL_OFFSET); | ||
| #endif | ||
| } | ||
|
|
||
| static inline void dai_dmic_en_power(const struct dai_intel_dmic *dmic) | ||
| { | ||
| #ifndef CONFIG_SOC_SERIES_INTEL_CAVS_V15 | ||
| /* Enable DMIC power */ | ||
| sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) | DMICLCTL_SPA), | ||
| dmic->shim_base + DMICLCTL_OFFSET); | ||
|
|
||
| #endif | ||
| } | ||
| static inline void dai_dmic_dis_power(const struct dai_intel_dmic *dmic) | ||
| { | ||
| #ifndef CONFIG_SOC_SERIES_INTEL_CAVS_V15 | ||
| /* Disable DMIC power */ | ||
| sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) & (~DMICLCTL_SPA)), | ||
| dmic->shim_base + DMICLCTL_OFFSET); | ||
| #endif | ||
| } | ||
|
|
||
| static int dai_dmic_probe(struct dai_intel_dmic *dmic) | ||
|
|
@@ -220,6 +319,7 @@ static int dai_dmic_probe(struct dai_intel_dmic *dmic) | |
| dai_dmic_claim_ownership(dmic); | ||
|
|
||
| irq_enable(dmic->irq); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
|
|
@@ -291,7 +391,7 @@ static int dai_timestamp_dmic_stop(const struct device *dev, struct dai_ts_cfg * | |
| } | ||
|
|
||
| static int dai_timestamp_dmic_get(const struct device *dev, struct dai_ts_cfg *cfg, | ||
| struct dai_ts_data *tsd) | ||
| struct dai_ts_data *tsd) | ||
| { | ||
| /* Read DMIC timestamp registers */ | ||
| uint32_t tsctrl = TS_DMIC_LOCAL_TSCTRL; | ||
|
|
@@ -507,6 +607,9 @@ static void dai_dmic_start(struct dai_intel_dmic *dmic) | |
| for (i = 0; i < CONFIG_DAI_DMIC_HW_CONTROLLERS; i++) { | ||
| dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL, | ||
| CIC_CONTROL_SOFT_RESET_BIT, 0); | ||
|
|
||
| LOG_INF("dmic_start(), cic 0x%08x", | ||
| dai_dmic_read(dmic, base[i] + CIC_CONTROL)); | ||
| } | ||
|
|
||
| /* Set bit dai->index */ | ||
|
|
@@ -519,7 +622,7 @@ static void dai_dmic_start(struct dai_intel_dmic *dmic) | |
| dmic_sync_trigger(dmic); | ||
|
|
||
| LOG_INF("dmic_start(), dmic_active_fifos_mask = 0x%x", | ||
| dai_dmic_global.active_fifos_mask); | ||
| dai_dmic_global.active_fifos_mask); | ||
| } | ||
|
|
||
| static void dai_dmic_stop(struct dai_intel_dmic *dmic, bool stop_is_pause) | ||
|
|
@@ -587,7 +690,7 @@ const struct dai_properties *dai_dmic_get_properties(const struct device *dev, | |
| } | ||
|
|
||
| static int dai_dmic_trigger(const struct device *dev, enum dai_dir dir, | ||
| enum dai_trigger_cmd cmd) | ||
| enum dai_trigger_cmd cmd) | ||
| { | ||
| struct dai_intel_dmic *dmic = (struct dai_intel_dmic *)dev->data; | ||
|
|
||
|
|
@@ -757,12 +860,12 @@ static int dai_dmic_initialize_device(const struct device *dev) | |
| .dai_index = n \ | ||
| }, \ | ||
| .reg_base = DT_INST_REG_ADDR_BY_IDX(n, 0), \ | ||
| .shim_base = DT_INST_PROP_BY_IDX(n, shim, 0), \ | ||
| .shim_base = DT_INST_PROP(n, shim), \ | ||
| .irq = DT_INST_IRQN(n), \ | ||
| .fifo = \ | ||
| { \ | ||
| .offset = DT_INST_REG_ADDR_BY_IDX(n, 0) \ | ||
| + OUTDATA##n, \ | ||
| + DT_INST_PROP(n, fifo), \ | ||
| .handshake = DMA_HANDSHAKE_DMIC_CH##n \ | ||
| }, \ | ||
| }; \ | ||
|
|
@@ -773,7 +876,7 @@ static int dai_dmic_initialize_device(const struct device *dev) | |
| &dai_intel_dmic_data_##n, \ | ||
| &dai_intel_dmic_properties_##n, \ | ||
| POST_KERNEL, \ | ||
| CONFIG_DAI_INIT_PRIORITY, \ | ||
| CONFIG_DAI_INIT_PRIORITY, \ | ||
| &dai_dmic_ops); | ||
|
|
||
| DT_INST_FOREACH_STATUS_OKAY(DAI_INTEL_DMIC_DEVICE_INIT); | ||
| DT_INST_FOREACH_STATUS_OKAY(DAI_INTEL_DMIC_DEVICE_INIT) | ||
Uh oh!
There was an error while loading. Please reload this page.