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:
parent
88941a1f71
commit
ec0ec72428
3 changed files with 97 additions and 86 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue