From ec0ec7242828c81b68b5e8f8cb721122d9fbafa6 Mon Sep 17 00:00:00 2001 From: Jaska Uimonen Date: Tue, 2 Aug 2022 12:39:59 +0300 Subject: [PATCH] drivers: dai: intel: dmic: misc fixes and changes Fix misc issues and warnings found with sof native drivers compilation. Signed-off-by: Jaska Uimonen --- drivers/dai/intel/dmic/dmic.c | 90 ++++++++++++++++++++++++++++-- drivers/dai/intel/dmic/dmic.h | 76 ------------------------- drivers/dai/intel/dmic/dmic_nhlt.c | 17 ++++-- 3 files changed, 97 insertions(+), 86 deletions(-) diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index 26266bf0f5b..82d386bc8f0 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -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"); @@ -243,6 +319,7 @@ static int dai_dmic_probe(struct dai_intel_dmic *dmic) dai_dmic_claim_ownership(dmic); irq_enable(dmic->irq); + return 0; } @@ -314,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; @@ -530,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 */ @@ -542,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) @@ -611,7 +691,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; @@ -800,4 +880,4 @@ static int dai_dmic_initialize_device(const struct device *dev) 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) diff --git a/drivers/dai/intel/dmic/dmic.h b/drivers/dai/intel/dmic/dmic.h index 6accbd6d6d8..ce232b1724b 100644 --- a/drivers/dai/intel/dmic/dmic.h +++ b/drivers/dai/intel/dmic/dmic.h @@ -558,82 +558,6 @@ struct dai_intel_dmic { uint32_t flags; }; -/* 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 inline int32_t sat_int32(int64_t x) { if (x > INT32_MAX) diff --git a/drivers/dai/intel/dmic/dmic_nhlt.c b/drivers/dai/intel/dmic/dmic_nhlt.c index 56e2920af3b..35d05ea0589 100644 --- a/drivers/dai/intel/dmic/dmic_nhlt.c +++ b/drivers/dai/intel/dmic/dmic_nhlt.c @@ -25,7 +25,7 @@ static const uint32_t coef_base_b[4] = {PDM0_COEFFICIENT_B, PDM1_COEFFICIENT_B, PDM2_COEFFICIENT_B, PDM3_COEFFICIENT_B}; static inline void dai_dmic_write(const struct dai_intel_dmic *dmic, - uint32_t reg, uint32_t val) + uint32_t reg, uint32_t val) { sys_write32(val, dmic->reg_base + reg); } @@ -54,9 +54,9 @@ static int dai_ipm_source_to_enable(struct dai_intel_dmic *dmic, } static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic, - int32_t *outcontrol, - struct nhlt_pdm_ctrl_cfg **pdm_cfg, - struct nhlt_pdm_ctrl_fir_cfg **fir_cfg) + int32_t *outcontrol, + struct nhlt_pdm_ctrl_cfg **pdm_cfg, + struct nhlt_pdm_ctrl_fir_cfg **fir_cfg) { uint32_t outcontrol_val = outcontrol[dmic->dai_config_params.dai_index]; int num_pdm; @@ -82,7 +82,8 @@ static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic, num_pdm = OUTCONTROL0_IPM_GET(outcontrol_val); if (num_pdm > CONFIG_DAI_DMIC_HW_CONTROLLERS) { - LOG_ERR("nhlt_dmic_dai_params_get(): Illegal IPM PDM controllers count"); + LOG_ERR("nhlt_dmic_dai_params_get(): Illegal IPM PDM controllers count %d", + num_pdm); return -EINVAL; } @@ -588,5 +589,11 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf LOG_INF("dmic_set_config_nhlt(): rate = %d, channels = %d, format = %d", dmic->dai_config_params.rate, dmic->dai_config_params.channels, dmic->dai_config_params.format); + + LOG_INF("dmic_set_config_nhlt(): io_clk %u, rate_div %d", + CONFIG_DAI_DMIC_HW_IOCLK, rate_div); + + LOG_INF("dmic_set_config_nhlt(): enable0 %u, enable1 %u", + dmic->enable[0], dmic->enable[1]); return 0; }