dai: intel: dmic: Move definitions of nhlt structures to a new file
Definitions of a configuration blob structures were separated from the main drivers header file and moved to a dedicated file to improve code readability. Removed unnecessary nhlt_pdm_fir_coeffs structure. The nhlt_pdm_ctrl_cfg structure was extended with nhlt_pdm_ctrl_fir_cfg and fir coefficients. Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
This commit is contained in:
parent
844c78cf3a
commit
81944c5c62
3 changed files with 129 additions and 61 deletions
|
@ -133,56 +133,6 @@
|
|||
#define DMA_HANDSHAKE_DMIC_CH0 0
|
||||
#define DMA_HANDSHAKE_DMIC_CH1 1
|
||||
|
||||
/* For NHLT DMIC configuration parsing */
|
||||
#define DMIC_HW_CONTROLLERS_MAX 4
|
||||
#define DMIC_HW_FIFOS_MAX 2
|
||||
|
||||
struct nhlt_dmic_gateway_attributes {
|
||||
uint32_t dw;
|
||||
};
|
||||
|
||||
struct nhlt_dmic_ts_group {
|
||||
uint32_t ts_group[4];
|
||||
};
|
||||
|
||||
struct nhlt_dmic_clock_on_delay {
|
||||
uint32_t clock_on_delay;
|
||||
};
|
||||
|
||||
struct nhlt_dmic_channel_ctrl_mask {
|
||||
uint8_t channel_ctrl_mask;
|
||||
uint8_t clock_source;
|
||||
uint16_t rsvd;
|
||||
};
|
||||
|
||||
struct nhlt_pdm_ctrl_mask {
|
||||
uint32_t pdm_ctrl_mask;
|
||||
};
|
||||
|
||||
struct nhlt_pdm_ctrl_cfg {
|
||||
uint32_t cic_control;
|
||||
uint32_t cic_config;
|
||||
uint32_t reserved0;
|
||||
uint32_t mic_control;
|
||||
uint32_t pdm_sdw_map;
|
||||
uint32_t reuse_fir_from_pdm;
|
||||
uint32_t reserved1[2];
|
||||
};
|
||||
|
||||
struct nhlt_pdm_ctrl_fir_cfg {
|
||||
uint32_t fir_control;
|
||||
uint32_t fir_config;
|
||||
int32_t dc_offset_left;
|
||||
int32_t dc_offset_right;
|
||||
int32_t out_gain_left;
|
||||
int32_t out_gain_right;
|
||||
uint32_t reserved[2];
|
||||
};
|
||||
|
||||
struct nhlt_pdm_fir_coeffs {
|
||||
int32_t fir_coeffs[0];
|
||||
};
|
||||
|
||||
enum dai_dmic_frame_format {
|
||||
DAI_DMIC_FRAME_S16_LE = 0,
|
||||
DAI_DMIC_FRAME_S24_4LE,
|
||||
|
|
|
@ -16,6 +16,7 @@ LOG_MODULE_REGISTER(LOG_DOMAIN);
|
|||
#include <adsp_clk.h>
|
||||
#include "dmic.h"
|
||||
#include <dmic_regs.h>
|
||||
#include "dmic_nhlt.h"
|
||||
|
||||
extern struct dai_dmic_global_shared dai_dmic_global;
|
||||
|
||||
|
@ -279,8 +280,8 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
|
|||
struct nhlt_pdm_ctrl_cfg *pdm_cfg[DMIC_HW_CONTROLLERS_MAX];
|
||||
struct nhlt_pdm_ctrl_fir_cfg *fir_cfg_a[DMIC_HW_CONTROLLERS_MAX];
|
||||
struct nhlt_pdm_ctrl_fir_cfg *fir_cfg_b[DMIC_HW_CONTROLLERS_MAX];
|
||||
struct nhlt_pdm_fir_coeffs *fir_a[DMIC_HW_CONTROLLERS_MAX] = {NULL};
|
||||
struct nhlt_pdm_fir_coeffs *fir_b[DMIC_HW_CONTROLLERS_MAX];
|
||||
const uint32_t *fir_a[DMIC_HW_CONTROLLERS_MAX] = {NULL};
|
||||
const uint32_t *fir_b[DMIC_HW_CONTROLLERS_MAX];
|
||||
struct nhlt_dmic_channel_ctrl_mask *dmic_cfg;
|
||||
|
||||
uint32_t out_control[DMIC_HW_FIFOS_MAX] = {0};
|
||||
|
@ -320,7 +321,7 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
|
|||
/* Skip not used headers */
|
||||
p += sizeof(struct nhlt_dmic_gateway_attributes);
|
||||
p += sizeof(struct nhlt_dmic_ts_group);
|
||||
p += sizeof(struct nhlt_dmic_clock_on_delay);
|
||||
p += sizeof(struct nhlt_dmic_global_config);
|
||||
|
||||
/* Channel_ctlr_mask bits indicate the FIFOs enabled*/
|
||||
dmic_cfg = (struct nhlt_dmic_channel_ctrl_mask *)p;
|
||||
|
@ -512,8 +513,7 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
|
|||
}
|
||||
|
||||
/* FIR A */
|
||||
fir_cfg_a[n] = (struct nhlt_pdm_ctrl_fir_cfg *)p;
|
||||
p += sizeof(struct nhlt_pdm_ctrl_fir_cfg);
|
||||
fir_cfg_a[n] = &pdm_cfg[n]->fir_config[0];
|
||||
val = fir_cfg_a[n]->fir_config;
|
||||
fir_length = FIELD_GET(FIR_CONFIG_FIR_LENGTH, val);
|
||||
fir_length_a = fir_length + 1; /* Need for parsing */
|
||||
|
@ -583,8 +583,7 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
|
|||
}
|
||||
|
||||
/* FIR B */
|
||||
fir_cfg_b[n] = (struct nhlt_pdm_ctrl_fir_cfg *)p;
|
||||
p += sizeof(struct nhlt_pdm_ctrl_fir_cfg);
|
||||
fir_cfg_b[n] = &pdm_cfg[n]->fir_config[1];
|
||||
val = fir_cfg_b[n]->fir_config;
|
||||
fir_length = FIELD_GET(FIR_CONFIG_FIR_LENGTH, val);
|
||||
fir_length_b = fir_length + 1; /* Need for parsing */
|
||||
|
@ -642,9 +641,9 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
|
|||
/* Set up FIR coefficients RAM */
|
||||
val = pdm_cfg[n]->reuse_fir_from_pdm;
|
||||
if (val == 0) {
|
||||
fir_a[n] = (struct nhlt_pdm_fir_coeffs *)p;
|
||||
fir_a[n] = (uint32_t *)p;
|
||||
p += sizeof(int32_t) * fir_length_a;
|
||||
fir_b[n] = (struct nhlt_pdm_fir_coeffs *)p;
|
||||
fir_b[n] = (uint32_t *)p;
|
||||
p += sizeof(int32_t) * fir_length_b;
|
||||
} else {
|
||||
val--;
|
||||
|
@ -669,14 +668,14 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
|
|||
p_clkdiv, p_mcic, p_mfira, fir_length_a);
|
||||
for (i = 0; i < fir_length_a; i++)
|
||||
dai_dmic_write(dmic,
|
||||
coef_base_a[n] + (i << 2), fir_a[n]->fir_coeffs[i]);
|
||||
coef_base_a[n] + (i << 2), fir_a[n][i]);
|
||||
} else {
|
||||
LOG_INF(
|
||||
"dmic_set_config_nhlt(): clkdiv = %d, mcic = %d, mfir_b = %d, len = %d",
|
||||
p_clkdiv, p_mcic, p_mfirb, fir_length_b);
|
||||
for (i = 0; i < fir_length_b; i++)
|
||||
dai_dmic_write(dmic,
|
||||
coef_base_b[n] + (i << 2), fir_b[n]->fir_coeffs[i]);
|
||||
coef_base_b[n] + (i << 2), fir_b[n][i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
119
drivers/dai/intel/dmic/dmic_nhlt.h
Normal file
119
drivers/dai/intel/dmic/dmic_nhlt.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2023 Intel Corporation
|
||||
*
|
||||
* Author: Adrian Warecki <adrian.warecki@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_DAI_DRIVER_DMIC_NHLT_H__
|
||||
#define __INTEL_DAI_DRIVER_DMIC_NHLT_H__
|
||||
|
||||
/* For NHLT DMIC configuration parsing */
|
||||
#define DMIC_HW_CONTROLLERS_MAX 4
|
||||
#define DMIC_HW_FIFOS_MAX 2
|
||||
|
||||
struct nhlt_dmic_gateway_attributes {
|
||||
uint32_t dw;
|
||||
};
|
||||
|
||||
/* Time-slot mappings */
|
||||
struct nhlt_dmic_ts_group {
|
||||
uint32_t ts_group[4];
|
||||
};
|
||||
|
||||
/* Global configuration settings */
|
||||
struct nhlt_dmic_global_config {
|
||||
uint32_t clock_on_delay;
|
||||
};
|
||||
|
||||
/* PDM channels to be programmed using data from channel_cfg array. */
|
||||
struct nhlt_dmic_channel_ctrl_mask {
|
||||
/* i'th bit = 1 means that configuration for PDM channel # i is provided. */
|
||||
uint8_t channel_ctrl_mask;
|
||||
uint8_t clock_source;
|
||||
uint16_t rsvd;
|
||||
};
|
||||
|
||||
/* Channel configuration, see PDM HW specification for details. */
|
||||
struct nhlt_dmic_channel_config {
|
||||
uint32_t out_control;
|
||||
};
|
||||
|
||||
struct nhlt_dmic_config_blob {
|
||||
struct nhlt_dmic_gateway_attributes gtw_attributes;
|
||||
struct nhlt_dmic_ts_group time_slot;
|
||||
struct nhlt_dmic_global_config global_config;
|
||||
struct nhlt_dmic_channel_ctrl_mask ctrl_mask;
|
||||
struct nhlt_dmic_channel_config channel_config[];
|
||||
};
|
||||
|
||||
struct nhlt_pdm_ctrl_mask {
|
||||
uint32_t pdm_ctrl_mask;
|
||||
};
|
||||
|
||||
/* FIR configuration, see PDM HW specification for details.
|
||||
*
|
||||
* If there is only one PDM controller configuration passed, the other (missing) one is configured
|
||||
* by the driver just by clearing CIC_CONTROL.SOFT_RESET bit.
|
||||
*
|
||||
* The driver needs to make sure that all mics are disabled before starting to program PDM
|
||||
* controllers.
|
||||
*/
|
||||
struct nhlt_pdm_ctrl_fir_cfg {
|
||||
uint32_t fir_control;
|
||||
uint32_t fir_config;
|
||||
int32_t dc_offset_left;
|
||||
int32_t dc_offset_right;
|
||||
int32_t out_gain_left;
|
||||
int32_t out_gain_right;
|
||||
uint32_t reserved[2];
|
||||
};
|
||||
|
||||
/* PDM controller configuration, see PDM HW specification for details. */
|
||||
struct nhlt_pdm_ctrl_cfg {
|
||||
uint32_t cic_control;
|
||||
uint32_t cic_config;
|
||||
|
||||
uint32_t reserved0;
|
||||
uint32_t mic_control;
|
||||
|
||||
/* PDM SoundWire Map
|
||||
*
|
||||
* This field is used on platforms with SoundWire, otherwise ignored.
|
||||
*/
|
||||
uint32_t pdm_sdw_map;
|
||||
|
||||
/* Index of another nhlt_pdm_ctrl_cfg to be used as a source of FIR coefficients.
|
||||
*
|
||||
* The index is 1-based, value of 0 means that FIR coefficients array fir_coeffs is provided
|
||||
* by this item.
|
||||
* This is a very common case that the same FIR coefficients are used to program more than
|
||||
* one PDM controller. In this case, fir_coeffs array may be provided in a single copy
|
||||
* following nhlt_pdm_ctrl_cfg #0 and be reused by nhlt_pdm_ctrl_cfg #1 by setting
|
||||
* reuse_fir_from_pdm to 1 (1-based index).
|
||||
*/
|
||||
uint32_t reuse_fir_from_pdm;
|
||||
uint32_t reserved1[2];
|
||||
|
||||
/* FIR configurations */
|
||||
struct nhlt_pdm_ctrl_fir_cfg fir_config[2];
|
||||
|
||||
/* Array of FIR coefficients, channel A goes first, then channel B.
|
||||
*
|
||||
* Actual size of the array depends on the number of active taps of the FIR filter for
|
||||
* channel A plus the number of active taps of the FIR filter for channel B (see FIR_CONFIG)
|
||||
* as well as on the form (packed/unpacked) of values.
|
||||
*/
|
||||
uint32_t fir_coeffs[];
|
||||
};
|
||||
|
||||
/* Tag indicating that FIRs are in a packed 24-bit format.
|
||||
*
|
||||
* Size of a single coefficient is 20-bit. Coefficients may be sent in either unpacked form where
|
||||
* each value takes one DWORD (32-bits) or in packed form where the array begins with
|
||||
* (FIR_COEFFS_PACKED_TO_24_BITS) value to indicate packed form (unpacked coefficient has always
|
||||
* most significant byte set to 0) followed by array of 24-bit values (in little endian form).
|
||||
*/
|
||||
#define FIR_COEFFS_PACKED_TO_24_BITS 0xFFFFFFFF
|
||||
|
||||
#endif /* __INTEL_DAI_DRIVER_DMIC_NHLT_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue