drivers: dai: intel: dmic: misc fixes and changes

Fix misc issues and warnings found with sof native drivers compilation.

Signed-off-by: Jaska Uimonen <jaska.uimonen@linux.intel.com>
This commit is contained in:
Jaska Uimonen 2022-08-02 12:39:59 +03:00 committed by Carles Cufí
commit ec0ec72428
3 changed files with 97 additions and 86 deletions

View file

@ -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); 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, static void dai_dmic_update_bits(const struct dai_intel_dmic *dmic,
uint32_t reg, uint32_t mask, uint32_t val) 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 */ /* Trace OUTSTAT0 register */
val0 = dai_dmic_read(dmic, OUTSTAT0); val0 = dai_dmic_read(dmic, OUTSTAT0);
val1 = dai_dmic_read(dmic, OUTSTAT1); 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) { if (val0 & OUTSTAT0_ROR_BIT) {
LOG_ERR("dmic_irq_handler(): full fifo A or PDM overrun"); 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); dai_dmic_claim_ownership(dmic);
irq_enable(dmic->irq); irq_enable(dmic->irq);
return 0; 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, 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 */ /* Read DMIC timestamp registers */
uint32_t tsctrl = TS_DMIC_LOCAL_TSCTRL; 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++) { for (i = 0; i < CONFIG_DAI_DMIC_HW_CONTROLLERS; i++) {
dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL, dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL,
CIC_CONTROL_SOFT_RESET_BIT, 0); 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 */ /* Set bit dai->index */
@ -542,7 +622,7 @@ static void dai_dmic_start(struct dai_intel_dmic *dmic)
dmic_sync_trigger(dmic); dmic_sync_trigger(dmic);
LOG_INF("dmic_start(), dmic_active_fifos_mask = 0x%x", 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) 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, 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; 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, \ CONFIG_DAI_INIT_PRIORITY, \
&dai_dmic_ops); &dai_dmic_ops);
DT_INST_FOREACH_STATUS_OKAY(DAI_INTEL_DMIC_DEVICE_INIT); DT_INST_FOREACH_STATUS_OKAY(DAI_INTEL_DMIC_DEVICE_INIT)

View file

@ -558,82 +558,6 @@ struct dai_intel_dmic {
uint32_t flags; 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) static inline int32_t sat_int32(int64_t x)
{ {
if (x > INT32_MAX) if (x > INT32_MAX)

View file

@ -25,7 +25,7 @@ static const uint32_t coef_base_b[4] = {PDM0_COEFFICIENT_B, PDM1_COEFFICIENT_B,
PDM2_COEFFICIENT_B, PDM3_COEFFICIENT_B}; PDM2_COEFFICIENT_B, PDM3_COEFFICIENT_B};
static inline void dai_dmic_write(const struct dai_intel_dmic *dmic, 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); 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, static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic,
int32_t *outcontrol, int32_t *outcontrol,
struct nhlt_pdm_ctrl_cfg **pdm_cfg, struct nhlt_pdm_ctrl_cfg **pdm_cfg,
struct nhlt_pdm_ctrl_fir_cfg **fir_cfg) struct nhlt_pdm_ctrl_fir_cfg **fir_cfg)
{ {
uint32_t outcontrol_val = outcontrol[dmic->dai_config_params.dai_index]; uint32_t outcontrol_val = outcontrol[dmic->dai_config_params.dai_index];
int num_pdm; 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); num_pdm = OUTCONTROL0_IPM_GET(outcontrol_val);
if (num_pdm > CONFIG_DAI_DMIC_HW_CONTROLLERS) { 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; 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", 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.rate, dmic->dai_config_params.channels,
dmic->dai_config_params.format); 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; return 0;
} }