Add audio support for the MediaTek Genio 350-evk
Merge series from Alexandre Mergnat <amergnat@baylibre.com>: This serie aim to add the following audio support for the Genio 350-evk: - Playback - 2ch Headset Jack (Earphone) - 1ch Line-out Jack (Speaker) - 8ch HDMI Tx - Capture - 1ch DMIC (On-board Digital Microphone) - 1ch AMIC (On-board Analogic Microphone) - 1ch Headset Jack (External Analogic Microphone) Of course, HDMI playback need the MT8365 display patches [1] and a DTS change documented in "mediatek,mt8365-mt6357.yaml". Applied patch: - mfd: mt6397-core: register mt6357 sound codec Test passed: - mixer-test log: [3] - pcm-test log: [4] [1]: https://lore.kernel.org/all/20231023-display-support-v1-0-5c860ed5c33b@baylibre.com/ [2]: https://lore.kernel.org/all/20240313110147.1267793-1-angelogioacchino.delregno@collabora.com/ [3]: https://pastebin.com/pc43AVrT [4]: https://pastebin.com/cCtGhDpg [5]: https://gitlab.baylibre.com/baylibre/mediatek/bsp/linux/-/commits/sound/for-next/add-i350-audio-support
This commit is contained in:
@@ -37,6 +37,24 @@ properties:
|
||||
"#interrupt-cells":
|
||||
const: 2
|
||||
|
||||
mediatek,hp-pull-down:
|
||||
description:
|
||||
Earphone driver positive output stage short to
|
||||
the audio reference ground.
|
||||
type: boolean
|
||||
|
||||
mediatek,micbias0-microvolt:
|
||||
description: Selects MIC Bias 0 output voltage.
|
||||
enum: [1700000, 1800000, 1900000, 2000000,
|
||||
2100000, 2500000, 2600000, 2700000]
|
||||
default: 1700000
|
||||
|
||||
mediatek,micbias1-microvolt:
|
||||
description: Selects MIC Bias 1 output voltage.
|
||||
enum: [1700000, 1800000, 1900000, 2000000,
|
||||
2100000, 2500000, 2600000, 2700000]
|
||||
default: 1700000
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
$ref: /schemas/regulator/mediatek,mt6357-regulator.yaml
|
||||
@@ -83,6 +101,9 @@ examples:
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
mediatek,micbias0-microvolt = <1700000>;
|
||||
mediatek,micbias1-microvolt = <1700000>;
|
||||
|
||||
regulators {
|
||||
mt6357_vproc_reg: buck-vproc {
|
||||
regulator-name = "vproc";
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mediatek,mt8365-afe.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek Audio Front End PCM controller for MT8365
|
||||
|
||||
maintainers:
|
||||
- Alexandre Mergnat <amergnat@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8365-afe-pcm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: 26M clock
|
||||
- description: mux for audio clock
|
||||
- description: audio i2s0 mck
|
||||
- description: audio i2s1 mck
|
||||
- description: audio i2s2 mck
|
||||
- description: audio i2s3 mck
|
||||
- description: engen 1 clock
|
||||
- description: engen 2 clock
|
||||
- description: audio 1 clock
|
||||
- description: audio 2 clock
|
||||
- description: mux for i2s0
|
||||
- description: mux for i2s1
|
||||
- description: mux for i2s2
|
||||
- description: mux for i2s3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: top_clk26m_clk
|
||||
- const: top_audio_sel
|
||||
- const: audio_i2s0_m
|
||||
- const: audio_i2s1_m
|
||||
- const: audio_i2s2_m
|
||||
- const: audio_i2s3_m
|
||||
- const: engen1
|
||||
- const: engen2
|
||||
- const: aud1
|
||||
- const: aud2
|
||||
- const: i2s0_m_sel
|
||||
- const: i2s1_m_sel
|
||||
- const: i2s2_m_sel
|
||||
- const: i2s3_m_sel
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
mediatek,dmic-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Indicates how many data pins are used to transmit two channels of PDM
|
||||
signal. 1 means two wires, 0 means one wire. Default value is 0.
|
||||
enum:
|
||||
- 0 # one wire
|
||||
- 1 # two wires
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- power-domains
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/mediatek,mt8365-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/power/mediatek,mt8365-power.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
audio-controller@11220000 {
|
||||
compatible = "mediatek,mt8365-afe-pcm";
|
||||
reg = <0 0x11220000 0 0x1000>;
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&clk26m>,
|
||||
<&topckgen CLK_TOP_AUDIO_SEL>,
|
||||
<&topckgen CLK_TOP_AUD_I2S0_M>,
|
||||
<&topckgen CLK_TOP_AUD_I2S1_M>,
|
||||
<&topckgen CLK_TOP_AUD_I2S2_M>,
|
||||
<&topckgen CLK_TOP_AUD_I2S3_M>,
|
||||
<&topckgen CLK_TOP_AUD_ENGEN1_SEL>,
|
||||
<&topckgen CLK_TOP_AUD_ENGEN2_SEL>,
|
||||
<&topckgen CLK_TOP_AUD_1_SEL>,
|
||||
<&topckgen CLK_TOP_AUD_2_SEL>,
|
||||
<&topckgen CLK_TOP_APLL_I2S0_SEL>,
|
||||
<&topckgen CLK_TOP_APLL_I2S1_SEL>,
|
||||
<&topckgen CLK_TOP_APLL_I2S2_SEL>,
|
||||
<&topckgen CLK_TOP_APLL_I2S3_SEL>;
|
||||
clock-names = "top_clk26m_clk",
|
||||
"top_audio_sel",
|
||||
"audio_i2s0_m",
|
||||
"audio_i2s1_m",
|
||||
"audio_i2s2_m",
|
||||
"audio_i2s3_m",
|
||||
"engen1",
|
||||
"engen2",
|
||||
"aud1",
|
||||
"aud2",
|
||||
"i2s0_m_sel",
|
||||
"i2s1_m_sel",
|
||||
"i2s2_m_sel",
|
||||
"i2s3_m_sel";
|
||||
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_LOW>;
|
||||
power-domains = <&spm MT8365_POWER_DOMAIN_AUDIO>;
|
||||
mediatek,dmic-mode = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -0,0 +1,107 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mediatek,mt8365-mt6357.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek MT8365 ASoC sound card
|
||||
|
||||
maintainers:
|
||||
- Alexandre Mergnat <amergnat@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8365-mt6357
|
||||
|
||||
pinctrl-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: default
|
||||
- const: dmic
|
||||
- const: miso_off
|
||||
- const: miso_on
|
||||
- const: mosi_off
|
||||
- const: mosi_on
|
||||
|
||||
mediatek,platform:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of MT8365 ASoC platform.
|
||||
|
||||
patternProperties:
|
||||
"^dai-link-[0-9]+$":
|
||||
type: object
|
||||
description:
|
||||
Container for dai-link level properties and CODEC sub-nodes.
|
||||
|
||||
properties:
|
||||
codec:
|
||||
type: object
|
||||
description: Holds subnode which indicates codec dai.
|
||||
|
||||
properties:
|
||||
sound-dai:
|
||||
maxItems: 1
|
||||
description: phandle of the codec DAI
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
link-name:
|
||||
description: Indicates dai-link name and PCM stream name
|
||||
enum:
|
||||
- I2S_IN_BE
|
||||
- I2S_OUT_BE
|
||||
- PCM1_BE
|
||||
- PDM1_BE
|
||||
- PDM2_BE
|
||||
- PDM3_BE
|
||||
- PDM4_BE
|
||||
- SPDIF_IN_BE
|
||||
- SPDIF_OUT_BE
|
||||
- TDM_IN_BE
|
||||
- TDM_OUT_BE
|
||||
|
||||
sound-dai:
|
||||
maxItems: 1
|
||||
description: phandle of the CPU DAI
|
||||
|
||||
required:
|
||||
- link-name
|
||||
- sound-dai
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- pinctrl-names
|
||||
- mediatek,platform
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "mediatek,mt8365-mt6357";
|
||||
pinctrl-names = "default",
|
||||
"dmic",
|
||||
"miso_off",
|
||||
"miso_on",
|
||||
"mosi_off",
|
||||
"mosi_on";
|
||||
pinctrl-0 = <&aud_default_pins>;
|
||||
pinctrl-1 = <&aud_dmic_pins>;
|
||||
pinctrl-2 = <&aud_miso_off_pins>;
|
||||
pinctrl-3 = <&aud_miso_on_pins>;
|
||||
pinctrl-4 = <&aud_mosi_off_pins>;
|
||||
pinctrl-5 = <&aud_mosi_on_pins>;
|
||||
mediatek,platform = <&afe>;
|
||||
|
||||
/* hdmi interface */
|
||||
dai-link-0 {
|
||||
link-name = "I2S_OUT_BE";
|
||||
sound-dai = <&afe>;
|
||||
|
||||
codec {
|
||||
sound-dai = <&it66121hdmitx>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,421 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek 8365 AFE clock control
|
||||
*
|
||||
* Copyright (c) 2024 MediaTek Inc.
|
||||
* Authors: Jia Zeng <jia.zeng@mediatek.com>
|
||||
* Alexandre Mergnat <amergnat@baylibre.com>
|
||||
*/
|
||||
|
||||
#include "mt8365-afe-clk.h"
|
||||
#include "mt8365-afe-common.h"
|
||||
#include "mt8365-reg.h"
|
||||
#include "../common/mtk-base-afe.h"
|
||||
#include <linux/device.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
|
||||
static const char *aud_clks[MT8365_CLK_NUM] = {
|
||||
[MT8365_CLK_TOP_AUD_SEL] = "top_audio_sel",
|
||||
[MT8365_CLK_AUD_I2S0_M] = "audio_i2s0_m",
|
||||
[MT8365_CLK_AUD_I2S1_M] = "audio_i2s1_m",
|
||||
[MT8365_CLK_AUD_I2S2_M] = "audio_i2s2_m",
|
||||
[MT8365_CLK_AUD_I2S3_M] = "audio_i2s3_m",
|
||||
[MT8365_CLK_ENGEN1] = "engen1",
|
||||
[MT8365_CLK_ENGEN2] = "engen2",
|
||||
[MT8365_CLK_AUD1] = "aud1",
|
||||
[MT8365_CLK_AUD2] = "aud2",
|
||||
[MT8365_CLK_I2S0_M_SEL] = "i2s0_m_sel",
|
||||
[MT8365_CLK_I2S1_M_SEL] = "i2s1_m_sel",
|
||||
[MT8365_CLK_I2S2_M_SEL] = "i2s2_m_sel",
|
||||
[MT8365_CLK_I2S3_M_SEL] = "i2s3_m_sel",
|
||||
[MT8365_CLK_CLK26M] = "top_clk26m_clk",
|
||||
};
|
||||
|
||||
int mt8365_afe_init_audio_clk(struct mtk_base_afe *afe)
|
||||
{
|
||||
size_t i;
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
|
||||
afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]);
|
||||
if (IS_ERR(afe_priv->clocks[i])) {
|
||||
dev_err(afe->dev, "%s devm_clk_get %s fail\n",
|
||||
__func__, aud_clks[i]);
|
||||
return PTR_ERR(afe_priv->clocks[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mt8365_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk)
|
||||
{
|
||||
if (clk)
|
||||
clk_disable_unprepare(clk);
|
||||
}
|
||||
|
||||
int mt8365_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
|
||||
unsigned int rate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (clk) {
|
||||
ret = clk_set_rate(clk, rate);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "Failed to set rate\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
|
||||
struct clk *parent)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (clk && parent) {
|
||||
ret = clk_set_parent(clk, parent);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "Failed to set parent\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int get_top_cg_reg(unsigned int cg_type)
|
||||
{
|
||||
switch (cg_type) {
|
||||
case MT8365_TOP_CG_AFE:
|
||||
case MT8365_TOP_CG_I2S_IN:
|
||||
case MT8365_TOP_CG_22M:
|
||||
case MT8365_TOP_CG_24M:
|
||||
case MT8365_TOP_CG_INTDIR_CK:
|
||||
case MT8365_TOP_CG_APLL2_TUNER:
|
||||
case MT8365_TOP_CG_APLL_TUNER:
|
||||
case MT8365_TOP_CG_SPDIF:
|
||||
case MT8365_TOP_CG_TDM_OUT:
|
||||
case MT8365_TOP_CG_TDM_IN:
|
||||
case MT8365_TOP_CG_ADC:
|
||||
case MT8365_TOP_CG_DAC:
|
||||
case MT8365_TOP_CG_DAC_PREDIS:
|
||||
case MT8365_TOP_CG_TML:
|
||||
return AUDIO_TOP_CON0;
|
||||
case MT8365_TOP_CG_I2S1_BCLK:
|
||||
case MT8365_TOP_CG_I2S2_BCLK:
|
||||
case MT8365_TOP_CG_I2S3_BCLK:
|
||||
case MT8365_TOP_CG_I2S4_BCLK:
|
||||
case MT8365_TOP_CG_DMIC0_ADC:
|
||||
case MT8365_TOP_CG_DMIC1_ADC:
|
||||
case MT8365_TOP_CG_DMIC2_ADC:
|
||||
case MT8365_TOP_CG_DMIC3_ADC:
|
||||
case MT8365_TOP_CG_CONNSYS_I2S_ASRC:
|
||||
case MT8365_TOP_CG_GENERAL1_ASRC:
|
||||
case MT8365_TOP_CG_GENERAL2_ASRC:
|
||||
case MT8365_TOP_CG_TDM_ASRC:
|
||||
return AUDIO_TOP_CON1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int get_top_cg_mask(unsigned int cg_type)
|
||||
{
|
||||
switch (cg_type) {
|
||||
case MT8365_TOP_CG_AFE:
|
||||
return AUD_TCON0_PDN_AFE;
|
||||
case MT8365_TOP_CG_I2S_IN:
|
||||
return AUD_TCON0_PDN_I2S_IN;
|
||||
case MT8365_TOP_CG_22M:
|
||||
return AUD_TCON0_PDN_22M;
|
||||
case MT8365_TOP_CG_24M:
|
||||
return AUD_TCON0_PDN_24M;
|
||||
case MT8365_TOP_CG_INTDIR_CK:
|
||||
return AUD_TCON0_PDN_INTDIR;
|
||||
case MT8365_TOP_CG_APLL2_TUNER:
|
||||
return AUD_TCON0_PDN_APLL2_TUNER;
|
||||
case MT8365_TOP_CG_APLL_TUNER:
|
||||
return AUD_TCON0_PDN_APLL_TUNER;
|
||||
case MT8365_TOP_CG_SPDIF:
|
||||
return AUD_TCON0_PDN_SPDIF;
|
||||
case MT8365_TOP_CG_TDM_OUT:
|
||||
return AUD_TCON0_PDN_TDM_OUT;
|
||||
case MT8365_TOP_CG_TDM_IN:
|
||||
return AUD_TCON0_PDN_TDM_IN;
|
||||
case MT8365_TOP_CG_ADC:
|
||||
return AUD_TCON0_PDN_ADC;
|
||||
case MT8365_TOP_CG_DAC:
|
||||
return AUD_TCON0_PDN_DAC;
|
||||
case MT8365_TOP_CG_DAC_PREDIS:
|
||||
return AUD_TCON0_PDN_DAC_PREDIS;
|
||||
case MT8365_TOP_CG_TML:
|
||||
return AUD_TCON0_PDN_TML;
|
||||
case MT8365_TOP_CG_I2S1_BCLK:
|
||||
return AUD_TCON1_PDN_I2S1_BCLK;
|
||||
case MT8365_TOP_CG_I2S2_BCLK:
|
||||
return AUD_TCON1_PDN_I2S2_BCLK;
|
||||
case MT8365_TOP_CG_I2S3_BCLK:
|
||||
return AUD_TCON1_PDN_I2S3_BCLK;
|
||||
case MT8365_TOP_CG_I2S4_BCLK:
|
||||
return AUD_TCON1_PDN_I2S4_BCLK;
|
||||
case MT8365_TOP_CG_DMIC0_ADC:
|
||||
return AUD_TCON1_PDN_DMIC0_ADC;
|
||||
case MT8365_TOP_CG_DMIC1_ADC:
|
||||
return AUD_TCON1_PDN_DMIC1_ADC;
|
||||
case MT8365_TOP_CG_DMIC2_ADC:
|
||||
return AUD_TCON1_PDN_DMIC2_ADC;
|
||||
case MT8365_TOP_CG_DMIC3_ADC:
|
||||
return AUD_TCON1_PDN_DMIC3_ADC;
|
||||
case MT8365_TOP_CG_CONNSYS_I2S_ASRC:
|
||||
return AUD_TCON1_PDN_CONNSYS_I2S_ASRC;
|
||||
case MT8365_TOP_CG_GENERAL1_ASRC:
|
||||
return AUD_TCON1_PDN_GENERAL1_ASRC;
|
||||
case MT8365_TOP_CG_GENERAL2_ASRC:
|
||||
return AUD_TCON1_PDN_GENERAL2_ASRC;
|
||||
case MT8365_TOP_CG_TDM_ASRC:
|
||||
return AUD_TCON1_PDN_TDM_ASRC;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int get_top_cg_on_val(unsigned int cg_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int get_top_cg_off_val(unsigned int cg_type)
|
||||
{
|
||||
return get_top_cg_mask(cg_type);
|
||||
}
|
||||
|
||||
int mt8365_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
unsigned int reg = get_top_cg_reg(cg_type);
|
||||
unsigned int mask = get_top_cg_mask(cg_type);
|
||||
unsigned int val = get_top_cg_on_val(cg_type);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
afe_priv->top_cg_ref_cnt[cg_type]++;
|
||||
if (afe_priv->top_cg_ref_cnt[cg_type] == 1)
|
||||
regmap_update_bits(afe->regmap, reg, mask, val);
|
||||
|
||||
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
unsigned int reg = get_top_cg_reg(cg_type);
|
||||
unsigned int mask = get_top_cg_mask(cg_type);
|
||||
unsigned int val = get_top_cg_off_val(cg_type);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
afe_priv->top_cg_ref_cnt[cg_type]--;
|
||||
if (afe_priv->top_cg_ref_cnt[cg_type] == 0)
|
||||
regmap_update_bits(afe->regmap, reg, mask, val);
|
||||
else if (afe_priv->top_cg_ref_cnt[cg_type] < 0)
|
||||
afe_priv->top_cg_ref_cnt[cg_type] = 0;
|
||||
|
||||
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_enable_main_clk(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
clk_prepare_enable(afe_priv->clocks[MT8365_CLK_TOP_AUD_SEL]);
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_AFE);
|
||||
mt8365_afe_enable_afe_on(afe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_disable_main_clk(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
mt8365_afe_disable_afe_on(afe);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_AFE);
|
||||
mt8365_afe_disable_clk(afe, afe_priv->clocks[MT8365_CLK_TOP_AUD_SEL]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_emi_clk_on(struct mtk_base_afe *afe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_emi_clk_off(struct mtk_base_afe *afe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_enable_afe_on(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
afe_priv->afe_on_ref_cnt++;
|
||||
if (afe_priv->afe_on_ref_cnt == 1)
|
||||
regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
|
||||
|
||||
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_disable_afe_on(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
afe_priv->afe_on_ref_cnt--;
|
||||
if (afe_priv->afe_on_ref_cnt == 0)
|
||||
regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x0);
|
||||
else if (afe_priv->afe_on_ref_cnt < 0)
|
||||
afe_priv->afe_on_ref_cnt = 0;
|
||||
|
||||
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_hd_engen_enable(struct mtk_base_afe *afe, bool apll1)
|
||||
{
|
||||
if (apll1)
|
||||
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
|
||||
AFE_22M_PLL_EN, AFE_22M_PLL_EN);
|
||||
else
|
||||
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
|
||||
AFE_24M_PLL_EN, AFE_24M_PLL_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_hd_engen_disable(struct mtk_base_afe *afe, bool apll1)
|
||||
{
|
||||
if (apll1)
|
||||
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
|
||||
AFE_22M_PLL_EN, ~AFE_22M_PLL_EN);
|
||||
else
|
||||
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
|
||||
AFE_24M_PLL_EN, ~AFE_24M_PLL_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_enable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
mutex_lock(&afe_priv->afe_clk_mutex);
|
||||
|
||||
afe_priv->apll_tuner_ref_cnt[apll]++;
|
||||
if (afe_priv->apll_tuner_ref_cnt[apll] != 1) {
|
||||
mutex_unlock(&afe_priv->afe_clk_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (apll == MT8365_AFE_APLL1) {
|
||||
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG,
|
||||
AFE_APLL_TUNER_CFG_MASK, 0x432);
|
||||
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG,
|
||||
AFE_APLL_TUNER_CFG_EN_MASK, 0x1);
|
||||
} else {
|
||||
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG1,
|
||||
AFE_APLL_TUNER_CFG1_MASK, 0x434);
|
||||
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG1,
|
||||
AFE_APLL_TUNER_CFG1_EN_MASK, 0x1);
|
||||
}
|
||||
|
||||
mutex_unlock(&afe_priv->afe_clk_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_disable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
mutex_lock(&afe_priv->afe_clk_mutex);
|
||||
|
||||
afe_priv->apll_tuner_ref_cnt[apll]--;
|
||||
if (afe_priv->apll_tuner_ref_cnt[apll] == 0) {
|
||||
if (apll == MT8365_AFE_APLL1)
|
||||
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG,
|
||||
AFE_APLL_TUNER_CFG_EN_MASK, 0x0);
|
||||
else
|
||||
regmap_update_bits(afe->regmap, AFE_APLL_TUNER_CFG1,
|
||||
AFE_APLL_TUNER_CFG1_EN_MASK, 0x0);
|
||||
|
||||
} else if (afe_priv->apll_tuner_ref_cnt[apll] < 0) {
|
||||
afe_priv->apll_tuner_ref_cnt[apll] = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&afe_priv->afe_clk_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_enable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
if (apll == MT8365_AFE_APLL1) {
|
||||
if (clk_prepare_enable(afe_priv->clocks[MT8365_CLK_ENGEN1])) {
|
||||
dev_info(afe->dev, "%s Failed to enable ENGEN1 clk\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_22M);
|
||||
mt8365_afe_hd_engen_enable(afe, true);
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_APLL_TUNER);
|
||||
mt8365_afe_enable_apll_tuner_cfg(afe, MT8365_AFE_APLL1);
|
||||
} else {
|
||||
if (clk_prepare_enable(afe_priv->clocks[MT8365_CLK_ENGEN2])) {
|
||||
dev_info(afe->dev, "%s Failed to enable ENGEN2 clk\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_24M);
|
||||
mt8365_afe_hd_engen_enable(afe, false);
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_APLL2_TUNER);
|
||||
mt8365_afe_enable_apll_tuner_cfg(afe, MT8365_AFE_APLL2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_disable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
if (apll == MT8365_AFE_APLL1) {
|
||||
mt8365_afe_disable_apll_tuner_cfg(afe, MT8365_AFE_APLL1);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_APLL_TUNER);
|
||||
mt8365_afe_hd_engen_disable(afe, true);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_22M);
|
||||
clk_disable_unprepare(afe_priv->clocks[MT8365_CLK_ENGEN1]);
|
||||
} else {
|
||||
mt8365_afe_disable_apll_tuner_cfg(afe, MT8365_AFE_APLL2);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_APLL2_TUNER);
|
||||
mt8365_afe_hd_engen_disable(afe, false);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_24M);
|
||||
clk_disable_unprepare(afe_priv->clocks[MT8365_CLK_ENGEN2]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* MediaTek 8365 AFE clock control definitions
|
||||
*
|
||||
* Copyright (c) 2024 MediaTek Inc.
|
||||
* Authors: Jia Zeng <jia.zeng@mediatek.com>
|
||||
* Alexandre Mergnat <amergnat@baylibre.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT8365_AFE_UTILS_H_
|
||||
#define _MT8365_AFE_UTILS_H_
|
||||
|
||||
struct mtk_base_afe;
|
||||
struct clk;
|
||||
|
||||
int mt8365_afe_init_audio_clk(struct mtk_base_afe *afe);
|
||||
void mt8365_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
|
||||
int mt8365_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk, unsigned int rate);
|
||||
int mt8365_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk, struct clk *parent);
|
||||
int mt8365_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type);
|
||||
int mt8365_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type);
|
||||
int mt8365_afe_enable_main_clk(struct mtk_base_afe *afe);
|
||||
int mt8365_afe_disable_main_clk(struct mtk_base_afe *afe);
|
||||
int mt8365_afe_emi_clk_on(struct mtk_base_afe *afe);
|
||||
int mt8365_afe_emi_clk_off(struct mtk_base_afe *afe);
|
||||
int mt8365_afe_enable_afe_on(struct mtk_base_afe *afe);
|
||||
int mt8365_afe_disable_afe_on(struct mtk_base_afe *afe);
|
||||
int mt8365_afe_enable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll);
|
||||
int mt8365_afe_disable_apll_tuner_cfg(struct mtk_base_afe *afe, unsigned int apll);
|
||||
int mt8365_afe_enable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll);
|
||||
int mt8365_afe_disable_apll_associated_cfg(struct mtk_base_afe *afe, unsigned int apll);
|
||||
#endif
|
||||
@@ -0,0 +1,449 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* MediaTek 8365 audio driver common definitions
|
||||
*
|
||||
* Copyright (c) 2024 MediaTek Inc.
|
||||
* Authors: Jia Zeng <jia.zeng@mediatek.com>
|
||||
* Alexandre Mergnat <amergnat@baylibre.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT8365_AFE_COMMON_H_
|
||||
#define _MT8365_AFE_COMMON_H_
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/asound.h>
|
||||
#include "../common/mtk-base-afe.h"
|
||||
#include "mt8365-reg.h"
|
||||
|
||||
enum {
|
||||
MT8365_AFE_MEMIF_DL1,
|
||||
MT8365_AFE_MEMIF_DL2,
|
||||
MT8365_AFE_MEMIF_TDM_OUT,
|
||||
/*
|
||||
* MT8365_AFE_MEMIF_SPDIF_OUT,
|
||||
*/
|
||||
MT8365_AFE_MEMIF_AWB,
|
||||
MT8365_AFE_MEMIF_VUL,
|
||||
MT8365_AFE_MEMIF_VUL2,
|
||||
MT8365_AFE_MEMIF_VUL3,
|
||||
MT8365_AFE_MEMIF_TDM_IN,
|
||||
/*
|
||||
* MT8365_AFE_MEMIF_SPDIF_IN,
|
||||
*/
|
||||
MT8365_AFE_MEMIF_NUM,
|
||||
MT8365_AFE_BACKEND_BASE = MT8365_AFE_MEMIF_NUM,
|
||||
MT8365_AFE_IO_TDM_OUT = MT8365_AFE_BACKEND_BASE,
|
||||
MT8365_AFE_IO_TDM_IN,
|
||||
MT8365_AFE_IO_I2S,
|
||||
MT8365_AFE_IO_2ND_I2S,
|
||||
MT8365_AFE_IO_PCM1,
|
||||
MT8365_AFE_IO_VIRTUAL_DL_SRC,
|
||||
MT8365_AFE_IO_VIRTUAL_TDM_OUT_SRC,
|
||||
MT8365_AFE_IO_VIRTUAL_FM,
|
||||
MT8365_AFE_IO_DMIC,
|
||||
MT8365_AFE_IO_INT_ADDA,
|
||||
MT8365_AFE_IO_GASRC1,
|
||||
MT8365_AFE_IO_GASRC2,
|
||||
MT8365_AFE_IO_TDM_ASRC,
|
||||
MT8365_AFE_IO_HW_GAIN1,
|
||||
MT8365_AFE_IO_HW_GAIN2,
|
||||
MT8365_AFE_BACKEND_END,
|
||||
MT8365_AFE_BACKEND_NUM = (MT8365_AFE_BACKEND_END -
|
||||
MT8365_AFE_BACKEND_BASE),
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_AFE_IRQ1,
|
||||
MT8365_AFE_IRQ2,
|
||||
MT8365_AFE_IRQ3,
|
||||
MT8365_AFE_IRQ4,
|
||||
MT8365_AFE_IRQ5,
|
||||
MT8365_AFE_IRQ6,
|
||||
MT8365_AFE_IRQ7,
|
||||
MT8365_AFE_IRQ8,
|
||||
MT8365_AFE_IRQ9,
|
||||
MT8365_AFE_IRQ10,
|
||||
MT8365_AFE_IRQ_NUM,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_TOP_CG_AFE,
|
||||
MT8365_TOP_CG_I2S_IN,
|
||||
MT8365_TOP_CG_22M,
|
||||
MT8365_TOP_CG_24M,
|
||||
MT8365_TOP_CG_INTDIR_CK,
|
||||
MT8365_TOP_CG_APLL2_TUNER,
|
||||
MT8365_TOP_CG_APLL_TUNER,
|
||||
MT8365_TOP_CG_SPDIF,
|
||||
MT8365_TOP_CG_TDM_OUT,
|
||||
MT8365_TOP_CG_TDM_IN,
|
||||
MT8365_TOP_CG_ADC,
|
||||
MT8365_TOP_CG_DAC,
|
||||
MT8365_TOP_CG_DAC_PREDIS,
|
||||
MT8365_TOP_CG_TML,
|
||||
MT8365_TOP_CG_I2S1_BCLK,
|
||||
MT8365_TOP_CG_I2S2_BCLK,
|
||||
MT8365_TOP_CG_I2S3_BCLK,
|
||||
MT8365_TOP_CG_I2S4_BCLK,
|
||||
MT8365_TOP_CG_DMIC0_ADC,
|
||||
MT8365_TOP_CG_DMIC1_ADC,
|
||||
MT8365_TOP_CG_DMIC2_ADC,
|
||||
MT8365_TOP_CG_DMIC3_ADC,
|
||||
MT8365_TOP_CG_CONNSYS_I2S_ASRC,
|
||||
MT8365_TOP_CG_GENERAL1_ASRC,
|
||||
MT8365_TOP_CG_GENERAL2_ASRC,
|
||||
MT8365_TOP_CG_TDM_ASRC,
|
||||
MT8365_TOP_CG_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_CLK_TOP_AUD_SEL,
|
||||
MT8365_CLK_AUD_I2S0_M,
|
||||
MT8365_CLK_AUD_I2S1_M,
|
||||
MT8365_CLK_AUD_I2S2_M,
|
||||
MT8365_CLK_AUD_I2S3_M,
|
||||
MT8365_CLK_ENGEN1,
|
||||
MT8365_CLK_ENGEN2,
|
||||
MT8365_CLK_AUD1,
|
||||
MT8365_CLK_AUD2,
|
||||
MT8365_CLK_I2S0_M_SEL,
|
||||
MT8365_CLK_I2S1_M_SEL,
|
||||
MT8365_CLK_I2S2_M_SEL,
|
||||
MT8365_CLK_I2S3_M_SEL,
|
||||
MT8365_CLK_CLK26M,
|
||||
MT8365_CLK_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_AFE_APLL1 = 0,
|
||||
MT8365_AFE_APLL2,
|
||||
MT8365_AFE_APLL_NUM,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_AFE_1ST_I2S = 0,
|
||||
MT8365_AFE_2ND_I2S,
|
||||
MT8365_AFE_I2S_SETS,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_AFE_I2S_SEPARATE_CLOCK = 0,
|
||||
MT8365_AFE_I2S_SHARED_CLOCK,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_AFE_TDM_OUT_I2S = 0,
|
||||
MT8365_AFE_TDM_OUT_TDM,
|
||||
MT8365_AFE_TDM_OUT_I2S_32BITS,
|
||||
};
|
||||
|
||||
enum mt8365_afe_tdm_ch_start {
|
||||
AFE_TDM_CH_START_O28_O29 = 0,
|
||||
AFE_TDM_CH_START_O30_O31,
|
||||
AFE_TDM_CH_START_O32_O33,
|
||||
AFE_TDM_CH_START_O34_O35,
|
||||
AFE_TDM_CH_ZERO,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_PCM_FORMAT_I2S = 0,
|
||||
MT8365_PCM_FORMAT_EIAJ,
|
||||
MT8365_PCM_FORMAT_PCMA,
|
||||
MT8365_PCM_FORMAT_PCMB,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_FS_8K = 0,
|
||||
MT8365_FS_11D025K,
|
||||
MT8365_FS_12K,
|
||||
MT8365_FS_384K,
|
||||
MT8365_FS_16K,
|
||||
MT8365_FS_22D05K,
|
||||
MT8365_FS_24K,
|
||||
MT8365_FS_130K,
|
||||
MT8365_FS_32K,
|
||||
MT8365_FS_44D1K,
|
||||
MT8365_FS_48K,
|
||||
MT8365_FS_88D2K,
|
||||
MT8365_FS_96K,
|
||||
MT8365_FS_176D4K,
|
||||
MT8365_FS_192K,
|
||||
};
|
||||
|
||||
enum {
|
||||
FS_8000HZ = 0, /* 0000b */
|
||||
FS_11025HZ = 1, /* 0001b */
|
||||
FS_12000HZ = 2, /* 0010b */
|
||||
FS_384000HZ = 3, /* 0011b */
|
||||
FS_16000HZ = 4, /* 0100b */
|
||||
FS_22050HZ = 5, /* 0101b */
|
||||
FS_24000HZ = 6, /* 0110b */
|
||||
FS_130000HZ = 7, /* 0111b */
|
||||
FS_32000HZ = 8, /* 1000b */
|
||||
FS_44100HZ = 9, /* 1001b */
|
||||
FS_48000HZ = 10, /* 1010b */
|
||||
FS_88200HZ = 11, /* 1011b */
|
||||
FS_96000HZ = 12, /* 1100b */
|
||||
FS_176400HZ = 13, /* 1101b */
|
||||
FS_192000HZ = 14, /* 1110b */
|
||||
FS_260000HZ = 15, /* 1111b */
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_AFE_DEBUGFS_AFE,
|
||||
MT8365_AFE_DEBUGFS_MEMIF,
|
||||
MT8365_AFE_DEBUGFS_IRQ,
|
||||
MT8365_AFE_DEBUGFS_CONN,
|
||||
MT8365_AFE_DEBUGFS_DBG,
|
||||
MT8365_AFE_DEBUGFS_NUM,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_AFE_IRQ_DIR_MCU = 0,
|
||||
MT8365_AFE_IRQ_DIR_DSP,
|
||||
MT8365_AFE_IRQ_DIR_BOTH,
|
||||
};
|
||||
|
||||
/* MCLK */
|
||||
enum {
|
||||
MT8365_I2S0_MCK = 0,
|
||||
MT8365_I2S3_MCK,
|
||||
MT8365_MCK_NUM,
|
||||
};
|
||||
|
||||
struct mt8365_fe_dai_data {
|
||||
bool use_sram;
|
||||
unsigned int sram_phy_addr;
|
||||
void __iomem *sram_vir_addr;
|
||||
unsigned int sram_size;
|
||||
};
|
||||
|
||||
struct mt8365_be_dai_data {
|
||||
bool prepared[SNDRV_PCM_STREAM_LAST + 1];
|
||||
unsigned int fmt_mode;
|
||||
};
|
||||
|
||||
#define MT8365_CLK_26M 26000000
|
||||
#define MT8365_CLK_24M 24000000
|
||||
#define MT8365_CLK_22M 22000000
|
||||
#define MT8365_CM_UPDATA_CNT_SET 8
|
||||
|
||||
enum mt8365_cm_num {
|
||||
MT8365_CM1 = 0,
|
||||
MT8365_CM2,
|
||||
MT8365_CM_NUM,
|
||||
};
|
||||
|
||||
enum mt8365_cm2_mux_in {
|
||||
MT8365_FROM_GASRC1 = 1,
|
||||
MT8365_FROM_GASRC2,
|
||||
MT8365_FROM_TDM_ASRC,
|
||||
MT8365_CM_MUX_NUM,
|
||||
};
|
||||
|
||||
enum cm2_mux_conn_in {
|
||||
GENERAL2_ASRC_OUT_LCH = 0,
|
||||
GENERAL2_ASRC_OUT_RCH = 1,
|
||||
TDM_IN_CH0 = 2,
|
||||
TDM_IN_CH1 = 3,
|
||||
TDM_IN_CH2 = 4,
|
||||
TDM_IN_CH3 = 5,
|
||||
TDM_IN_CH4 = 6,
|
||||
TDM_IN_CH5 = 7,
|
||||
TDM_IN_CH6 = 8,
|
||||
TDM_IN_CH7 = 9,
|
||||
GENERAL1_ASRC_OUT_LCH = 10,
|
||||
GENERAL1_ASRC_OUT_RCH = 11,
|
||||
TDM_OUT_ASRC_CH0 = 12,
|
||||
TDM_OUT_ASRC_CH1 = 13,
|
||||
TDM_OUT_ASRC_CH2 = 14,
|
||||
TDM_OUT_ASRC_CH3 = 15,
|
||||
TDM_OUT_ASRC_CH4 = 16,
|
||||
TDM_OUT_ASRC_CH5 = 17,
|
||||
TDM_OUT_ASRC_CH6 = 18,
|
||||
TDM_OUT_ASRC_CH7 = 19
|
||||
};
|
||||
|
||||
struct mt8365_cm_ctrl_reg {
|
||||
unsigned int con0;
|
||||
unsigned int con1;
|
||||
unsigned int con2;
|
||||
unsigned int con3;
|
||||
unsigned int con4;
|
||||
};
|
||||
|
||||
struct mt8365_control_data {
|
||||
bool bypass_cm1;
|
||||
bool bypass_cm2;
|
||||
unsigned int loopback_type;
|
||||
};
|
||||
|
||||
enum dmic_input_mode {
|
||||
DMIC_MODE_3P25M = 0,
|
||||
DMIC_MODE_1P625M,
|
||||
DMIC_MODE_812P5K,
|
||||
DMIC_MODE_406P25K,
|
||||
};
|
||||
|
||||
enum iir_mode {
|
||||
IIR_MODE0 = 0,
|
||||
IIR_MODE1,
|
||||
IIR_MODE2,
|
||||
IIR_MODE3,
|
||||
IIR_MODE4,
|
||||
IIR_MODE5,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8365_GASRC1 = 0,
|
||||
MT8365_GASRC2,
|
||||
MT8365_GASRC_NUM,
|
||||
MT8365_TDM_ASRC1 = MT8365_GASRC_NUM,
|
||||
MT8365_TDM_ASRC2,
|
||||
MT8365_TDM_ASRC3,
|
||||
MT8365_TDM_ASRC4,
|
||||
MT8365_TDM_ASRC_NUM,
|
||||
};
|
||||
|
||||
struct mt8365_gasrc_ctrl_reg {
|
||||
unsigned int con0;
|
||||
unsigned int con2;
|
||||
unsigned int con3;
|
||||
unsigned int con4;
|
||||
unsigned int con5;
|
||||
unsigned int con6;
|
||||
unsigned int con9;
|
||||
unsigned int con10;
|
||||
unsigned int con12;
|
||||
unsigned int con13;
|
||||
};
|
||||
|
||||
struct mt8365_gasrc_data {
|
||||
bool duplex;
|
||||
bool tx_mode;
|
||||
bool cali_on;
|
||||
bool tdm_asrc_out_cm2;
|
||||
bool iir_on;
|
||||
};
|
||||
|
||||
struct mt8365_afe_private {
|
||||
struct clk *clocks[MT8365_CLK_NUM];
|
||||
struct regmap *topckgen;
|
||||
struct mt8365_fe_dai_data fe_data[MT8365_AFE_MEMIF_NUM];
|
||||
struct mt8365_be_dai_data be_data[MT8365_AFE_BACKEND_NUM];
|
||||
struct mt8365_control_data ctrl_data;
|
||||
struct mt8365_gasrc_data gasrc_data[MT8365_TDM_ASRC_NUM];
|
||||
int afe_on_ref_cnt;
|
||||
int top_cg_ref_cnt[MT8365_TOP_CG_NUM];
|
||||
void __iomem *afe_sram_vir_addr;
|
||||
unsigned int afe_sram_phy_addr;
|
||||
unsigned int afe_sram_size;
|
||||
/* locks */
|
||||
spinlock_t afe_ctrl_lock;
|
||||
struct mutex afe_clk_mutex; /* Protect & sync APLL TUNER registers access*/
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs_dentry[MT8365_AFE_DEBUGFS_NUM];
|
||||
#endif
|
||||
int apll_tuner_ref_cnt[MT8365_AFE_APLL_NUM];
|
||||
unsigned int tdm_out_mode;
|
||||
unsigned int cm2_mux_input;
|
||||
|
||||
/* dai */
|
||||
bool dai_on[MT8365_AFE_BACKEND_END];
|
||||
void *dai_priv[MT8365_AFE_BACKEND_END];
|
||||
};
|
||||
|
||||
static inline u32 rx_frequency_palette(unsigned int fs)
|
||||
{
|
||||
/* *
|
||||
* A = (26M / fs) * 64
|
||||
* B = 8125 / A
|
||||
* return = DEC2HEX(B * 2^23)
|
||||
*/
|
||||
switch (fs) {
|
||||
case FS_8000HZ: return 0x050000;
|
||||
case FS_11025HZ: return 0x06E400;
|
||||
case FS_12000HZ: return 0x078000;
|
||||
case FS_16000HZ: return 0x0A0000;
|
||||
case FS_22050HZ: return 0x0DC800;
|
||||
case FS_24000HZ: return 0x0F0000;
|
||||
case FS_32000HZ: return 0x140000;
|
||||
case FS_44100HZ: return 0x1B9000;
|
||||
case FS_48000HZ: return 0x1E0000;
|
||||
case FS_88200HZ: return 0x372000;
|
||||
case FS_96000HZ: return 0x3C0000;
|
||||
case FS_176400HZ: return 0x6E4000;
|
||||
case FS_192000HZ: return 0x780000;
|
||||
default: return 0x0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline u32 AutoRstThHi(unsigned int fs)
|
||||
{
|
||||
switch (fs) {
|
||||
case FS_8000HZ: return 0x36000;
|
||||
case FS_11025HZ: return 0x27000;
|
||||
case FS_12000HZ: return 0x24000;
|
||||
case FS_16000HZ: return 0x1B000;
|
||||
case FS_22050HZ: return 0x14000;
|
||||
case FS_24000HZ: return 0x12000;
|
||||
case FS_32000HZ: return 0x0D800;
|
||||
case FS_44100HZ: return 0x09D00;
|
||||
case FS_48000HZ: return 0x08E00;
|
||||
case FS_88200HZ: return 0x04E00;
|
||||
case FS_96000HZ: return 0x04800;
|
||||
case FS_176400HZ: return 0x02700;
|
||||
case FS_192000HZ: return 0x02400;
|
||||
default: return 0x0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline u32 AutoRstThLo(unsigned int fs)
|
||||
{
|
||||
switch (fs) {
|
||||
case FS_8000HZ: return 0x30000;
|
||||
case FS_11025HZ: return 0x23000;
|
||||
case FS_12000HZ: return 0x20000;
|
||||
case FS_16000HZ: return 0x18000;
|
||||
case FS_22050HZ: return 0x11000;
|
||||
case FS_24000HZ: return 0x0FE00;
|
||||
case FS_32000HZ: return 0x0BE00;
|
||||
case FS_44100HZ: return 0x08A00;
|
||||
case FS_48000HZ: return 0x07F00;
|
||||
case FS_88200HZ: return 0x04500;
|
||||
case FS_96000HZ: return 0x04000;
|
||||
case FS_176400HZ: return 0x02300;
|
||||
case FS_192000HZ: return 0x02000;
|
||||
default: return 0x0;
|
||||
}
|
||||
}
|
||||
|
||||
bool mt8365_afe_clk_group_48k(int sample_rate);
|
||||
bool mt8365_afe_rate_supported(unsigned int rate, unsigned int id);
|
||||
bool mt8365_afe_channel_supported(unsigned int channel, unsigned int id);
|
||||
|
||||
int mt8365_dai_i2s_register(struct mtk_base_afe *afe);
|
||||
int mt8365_dai_set_priv(struct mtk_base_afe *afe,
|
||||
int id,
|
||||
int priv_size,
|
||||
const void *priv_data);
|
||||
|
||||
int mt8365_afe_fs_timing(unsigned int rate);
|
||||
|
||||
void mt8365_afe_set_i2s_out_enable(struct mtk_base_afe *afe, bool enable);
|
||||
int mt8365_afe_set_i2s_out(struct mtk_base_afe *afe, unsigned int rate, int bit_width);
|
||||
|
||||
int mt8365_dai_adda_register(struct mtk_base_afe *afe);
|
||||
int mt8365_dai_enable_adda_on(struct mtk_base_afe *afe);
|
||||
int mt8365_dai_disable_adda_on(struct mtk_base_afe *afe);
|
||||
|
||||
int mt8365_dai_dmic_register(struct mtk_base_afe *afe);
|
||||
|
||||
int mt8365_dai_pcm_register(struct mtk_base_afe *afe);
|
||||
|
||||
int mt8365_dai_tdm_register(struct mtk_base_afe *afe);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,311 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek 8365 ALSA SoC Audio DAI ADDA Control
|
||||
*
|
||||
* Copyright (c) 2024 MediaTek Inc.
|
||||
* Authors: Jia Zeng <jia.zeng@mediatek.com>
|
||||
* Alexandre Mergnat <amergnat@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include "mt8365-afe-clk.h"
|
||||
#include "mt8365-afe-common.h"
|
||||
#include "../common/mtk-dai-adda-common.h"
|
||||
|
||||
static int adda_afe_on_ref_cnt;
|
||||
|
||||
/* DAI Drivers */
|
||||
|
||||
static int mt8365_dai_set_adda_out(struct mtk_base_afe *afe, unsigned int rate)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
if (rate == 8000 || rate == 16000)
|
||||
val = AFE_ADDA_DL_VOICE_DATA;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
val |= FIELD_PREP(AFE_ADDA_DL_SAMPLING_RATE,
|
||||
mtk_adda_dl_rate_transform(afe, rate));
|
||||
val |= AFE_ADDA_DL_8X_UPSAMPLE |
|
||||
AFE_ADDA_DL_MUTE_OFF_CH1 |
|
||||
AFE_ADDA_DL_MUTE_OFF_CH2 |
|
||||
AFE_ADDA_DL_DEGRADE_GAIN;
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_PREDIS_CON0, 0xffffffff, 0);
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_PREDIS_CON1, 0xffffffff, 0);
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, 0xffffffff, val);
|
||||
/* SA suggest apply -0.3db to audio/speech path */
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON1,
|
||||
0xffffffff, 0xf74f0000);
|
||||
/* SA suggest use default value for sdm */
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON,
|
||||
0xffffffff, 0x0700701e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt8365_dai_set_adda_in(struct mtk_base_afe *afe, unsigned int rate)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = FIELD_PREP(AFE_ADDA_UL_SAMPLING_RATE,
|
||||
mtk_adda_ul_rate_transform(afe, rate));
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
|
||||
AFE_ADDA_UL_SAMPLING_RATE, val);
|
||||
/* Using Internal ADC */
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, 0x1, 0x0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_dai_enable_adda_on(struct mtk_base_afe *afe)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
adda_afe_on_ref_cnt++;
|
||||
if (adda_afe_on_ref_cnt == 1)
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0,
|
||||
AFE_ADDA_UL_DL_ADDA_AFE_ON,
|
||||
AFE_ADDA_UL_DL_ADDA_AFE_ON);
|
||||
|
||||
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_dai_disable_adda_on(struct mtk_base_afe *afe)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
adda_afe_on_ref_cnt--;
|
||||
if (adda_afe_on_ref_cnt == 0)
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0,
|
||||
AFE_ADDA_UL_DL_ADDA_AFE_ON,
|
||||
~AFE_ADDA_UL_DL_ADDA_AFE_ON);
|
||||
else if (adda_afe_on_ref_cnt < 0) {
|
||||
adda_afe_on_ref_cnt = 0;
|
||||
dev_warn(afe->dev, "Abnormal adda_on ref count. Force it to 0\n");
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt8365_dai_set_adda_out_enable(struct mtk_base_afe *afe,
|
||||
bool enable)
|
||||
{
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, 0x1, enable);
|
||||
|
||||
if (enable)
|
||||
mt8365_dai_enable_adda_on(afe);
|
||||
else
|
||||
mt8365_dai_disable_adda_on(afe);
|
||||
}
|
||||
|
||||
static void mt8365_dai_set_adda_in_enable(struct mtk_base_afe *afe, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 0x1, 0x1);
|
||||
mt8365_dai_enable_adda_on(afe);
|
||||
/* enable aud_pad_top fifo */
|
||||
regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP,
|
||||
0xffffffff, 0x31);
|
||||
} else {
|
||||
/* disable aud_pad_top fifo */
|
||||
regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP,
|
||||
0xffffffff, 0x30);
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 0x1, 0x0);
|
||||
/* de suggest disable ADDA_UL_SRC at least wait 125us */
|
||||
usleep_range(150, 300);
|
||||
mt8365_dai_disable_adda_on(afe);
|
||||
}
|
||||
}
|
||||
|
||||
static int mt8365_dai_int_adda_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
unsigned int stream = substream->stream;
|
||||
|
||||
mt8365_afe_enable_main_clk(afe);
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DAC);
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DAC_PREDIS);
|
||||
} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_ADC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt8365_dai_int_adda_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_be_dai_data *be =
|
||||
&afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE];
|
||||
unsigned int stream = substream->stream;
|
||||
|
||||
if (be->prepared[stream]) {
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
mt8365_dai_set_adda_out_enable(afe, false);
|
||||
mt8365_afe_set_i2s_out_enable(afe, false);
|
||||
} else {
|
||||
mt8365_dai_set_adda_in_enable(afe, false);
|
||||
}
|
||||
be->prepared[stream] = false;
|
||||
}
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DAC_PREDIS);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DAC);
|
||||
} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_ADC);
|
||||
}
|
||||
|
||||
mt8365_afe_disable_main_clk(afe);
|
||||
}
|
||||
|
||||
static int mt8365_dai_int_adda_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_be_dai_data *be =
|
||||
&afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE];
|
||||
unsigned int rate = substream->runtime->rate;
|
||||
int bit_width = snd_pcm_format_width(substream->runtime->format);
|
||||
int ret;
|
||||
|
||||
dev_info(afe->dev, "%s '%s' rate = %u\n", __func__,
|
||||
snd_pcm_stream_str(substream), rate);
|
||||
|
||||
if (be->prepared[substream->stream]) {
|
||||
dev_info(afe->dev, "%s '%s' prepared already\n",
|
||||
__func__, snd_pcm_stream_str(substream));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
ret = mt8365_dai_set_adda_out(afe, rate);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mt8365_afe_set_i2s_out(afe, rate, bit_width);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mt8365_dai_set_adda_out_enable(afe, true);
|
||||
mt8365_afe_set_i2s_out_enable(afe, true);
|
||||
} else {
|
||||
ret = mt8365_dai_set_adda_in(afe, rate);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mt8365_dai_set_adda_in_enable(afe, true);
|
||||
}
|
||||
be->prepared[substream->stream] = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops mt8365_afe_int_adda_ops = {
|
||||
.startup = mt8365_dai_int_adda_startup,
|
||||
.shutdown = mt8365_dai_int_adda_shutdown,
|
||||
.prepare = mt8365_dai_int_adda_prepare,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
|
||||
{
|
||||
.name = "INT ADDA",
|
||||
.id = MT8365_AFE_IO_INT_ADDA,
|
||||
.playback = {
|
||||
.stream_name = "INT ADDA Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "INT ADDA Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_32000 |
|
||||
SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &mt8365_afe_int_adda_ops,
|
||||
}
|
||||
};
|
||||
|
||||
/* DAI Controls */
|
||||
|
||||
static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = {
|
||||
SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN3,
|
||||
10, 1, 0),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = {
|
||||
SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN4,
|
||||
11, 1, 0),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new int_adda_o03_o04_enable_ctl =
|
||||
SOC_DAPM_SINGLE_VIRT("Switch", 1);
|
||||
|
||||
/* DAI widget */
|
||||
|
||||
static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
|
||||
SND_SOC_DAPM_SWITCH("INT ADDA O03_O04", SND_SOC_NOPM, 0, 0,
|
||||
&int_adda_o03_o04_enable_ctl),
|
||||
/* inter-connections */
|
||||
SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0,
|
||||
mtk_adda_dl_ch1_mix,
|
||||
ARRAY_SIZE(mtk_adda_dl_ch1_mix)),
|
||||
SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0,
|
||||
mtk_adda_dl_ch2_mix,
|
||||
ARRAY_SIZE(mtk_adda_dl_ch2_mix)),
|
||||
};
|
||||
|
||||
/* DAI route */
|
||||
|
||||
static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
|
||||
{"INT ADDA O03_O04", "Switch", "O03"},
|
||||
{"INT ADDA O03_O04", "Switch", "O04"},
|
||||
{"INT ADDA Playback", NULL, "INT ADDA O03_O04"},
|
||||
{"INT ADDA Playback", NULL, "ADDA_DL_CH1"},
|
||||
{"INT ADDA Playback", NULL, "ADDA_DL_CH2"},
|
||||
{"AIN Mux", "INT ADC", "INT ADDA Capture"},
|
||||
{"ADDA_DL_CH1", "GAIN1_OUT_CH1", "Hostless FM DL"},
|
||||
{"ADDA_DL_CH2", "GAIN1_OUT_CH2", "Hostless FM DL"},
|
||||
};
|
||||
|
||||
int mt8365_dai_adda_register(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mtk_base_afe_dai *dai;
|
||||
|
||||
dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
|
||||
if (!dai)
|
||||
return -ENOMEM;
|
||||
list_add(&dai->list, &afe->sub_dais);
|
||||
dai->dai_drivers = mtk_dai_adda_driver;
|
||||
dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
|
||||
dai->dapm_widgets = mtk_dai_adda_widgets;
|
||||
dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
|
||||
dai->dapm_routes = mtk_dai_adda_routes;
|
||||
dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek 8365 ALSA SoC Audio DAI DMIC Control
|
||||
*
|
||||
* Copyright (c) 2024 MediaTek Inc.
|
||||
* Authors: Jia Zeng <jia.zeng@mediatek.com>
|
||||
* Alexandre Mergnat <amergnat@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include "mt8365-afe-clk.h"
|
||||
#include "mt8365-afe-common.h"
|
||||
|
||||
struct mt8365_dmic_data {
|
||||
bool two_wire_mode;
|
||||
unsigned int clk_phase_sel_ch1;
|
||||
unsigned int clk_phase_sel_ch2;
|
||||
bool iir_on;
|
||||
unsigned int irr_mode;
|
||||
unsigned int dmic_mode;
|
||||
unsigned int dmic_channel;
|
||||
};
|
||||
|
||||
static int get_chan_reg(unsigned int channel)
|
||||
{
|
||||
switch (channel) {
|
||||
case 8:
|
||||
fallthrough;
|
||||
case 7:
|
||||
return AFE_DMIC3_UL_SRC_CON0;
|
||||
case 6:
|
||||
fallthrough;
|
||||
case 5:
|
||||
return AFE_DMIC2_UL_SRC_CON0;
|
||||
case 4:
|
||||
fallthrough;
|
||||
case 3:
|
||||
return AFE_DMIC1_UL_SRC_CON0;
|
||||
case 2:
|
||||
fallthrough;
|
||||
case 1:
|
||||
return AFE_DMIC0_UL_SRC_CON0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* DAI Drivers */
|
||||
|
||||
static void audio_dmic_adda_enable(struct mtk_base_afe *afe)
|
||||
{
|
||||
mt8365_dai_enable_adda_on(afe);
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0,
|
||||
AFE_ADDA_UL_DL_DMIC_CLKDIV_ON,
|
||||
AFE_ADDA_UL_DL_DMIC_CLKDIV_ON);
|
||||
}
|
||||
|
||||
static void audio_dmic_adda_disable(struct mtk_base_afe *afe)
|
||||
{
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_UL_DL_CON0,
|
||||
AFE_ADDA_UL_DL_DMIC_CLKDIV_ON,
|
||||
~AFE_ADDA_UL_DL_DMIC_CLKDIV_ON);
|
||||
mt8365_dai_disable_adda_on(afe);
|
||||
}
|
||||
|
||||
static void mt8365_dai_enable_dmic(struct mtk_base_afe *afe,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC];
|
||||
unsigned int val_mask;
|
||||
int reg = get_chan_reg(dmic_data->dmic_channel);
|
||||
|
||||
if (reg < 0)
|
||||
return;
|
||||
|
||||
/* val and mask will be always same to enable */
|
||||
val_mask = DMIC_TOP_CON_CH1_ON |
|
||||
DMIC_TOP_CON_CH2_ON |
|
||||
DMIC_TOP_CON_SRC_ON;
|
||||
|
||||
regmap_update_bits(afe->regmap, reg, val_mask, val_mask);
|
||||
}
|
||||
|
||||
static void mt8365_dai_disable_dmic(struct mtk_base_afe *afe,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC];
|
||||
unsigned int mask;
|
||||
int reg = get_chan_reg(dmic_data->dmic_channel);
|
||||
|
||||
if (reg < 0)
|
||||
return;
|
||||
|
||||
dev_dbg(afe->dev, "%s dmic_channel %d\n", __func__, dmic_data->dmic_channel);
|
||||
|
||||
mask = DMIC_TOP_CON_CH1_ON |
|
||||
DMIC_TOP_CON_CH2_ON |
|
||||
DMIC_TOP_CON_SRC_ON |
|
||||
DMIC_TOP_CON_SDM3_LEVEL_MODE;
|
||||
|
||||
/* Set all masked values to 0 */
|
||||
regmap_update_bits(afe->regmap, reg, mask, 0);
|
||||
}
|
||||
|
||||
static const struct reg_sequence mt8365_dmic_iir_coeff[] = {
|
||||
{ AFE_DMIC0_IIR_COEF_02_01, 0x00000000 },
|
||||
{ AFE_DMIC0_IIR_COEF_04_03, 0x00003FB8 },
|
||||
{ AFE_DMIC0_IIR_COEF_06_05, 0x3FB80000 },
|
||||
{ AFE_DMIC0_IIR_COEF_08_07, 0x3FB80000 },
|
||||
{ AFE_DMIC0_IIR_COEF_10_09, 0x0000C048 },
|
||||
{ AFE_DMIC1_IIR_COEF_02_01, 0x00000000 },
|
||||
{ AFE_DMIC1_IIR_COEF_04_03, 0x00003FB8 },
|
||||
{ AFE_DMIC1_IIR_COEF_06_05, 0x3FB80000 },
|
||||
{ AFE_DMIC1_IIR_COEF_08_07, 0x3FB80000 },
|
||||
{ AFE_DMIC1_IIR_COEF_10_09, 0x0000C048 },
|
||||
{ AFE_DMIC2_IIR_COEF_02_01, 0x00000000 },
|
||||
{ AFE_DMIC2_IIR_COEF_04_03, 0x00003FB8 },
|
||||
{ AFE_DMIC2_IIR_COEF_06_05, 0x3FB80000 },
|
||||
{ AFE_DMIC2_IIR_COEF_08_07, 0x3FB80000 },
|
||||
{ AFE_DMIC2_IIR_COEF_10_09, 0x0000C048 },
|
||||
{ AFE_DMIC3_IIR_COEF_02_01, 0x00000000 },
|
||||
{ AFE_DMIC3_IIR_COEF_04_03, 0x00003FB8 },
|
||||
{ AFE_DMIC3_IIR_COEF_06_05, 0x3FB80000 },
|
||||
{ AFE_DMIC3_IIR_COEF_08_07, 0x3FB80000 },
|
||||
{ AFE_DMIC3_IIR_COEF_10_09, 0x0000C048 },
|
||||
};
|
||||
|
||||
static int mt8365_dai_load_dmic_iir_coeff_table(struct mtk_base_afe *afe)
|
||||
{
|
||||
return regmap_multi_reg_write(afe->regmap,
|
||||
mt8365_dmic_iir_coeff,
|
||||
ARRAY_SIZE(mt8365_dmic_iir_coeff));
|
||||
}
|
||||
|
||||
static int mt8365_dai_configure_dmic(struct mtk_base_afe *afe,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_dmic_data *dmic_data = afe_priv->dai_priv[MT8365_AFE_IO_DMIC];
|
||||
bool two_wire_mode = dmic_data->two_wire_mode;
|
||||
unsigned int clk_phase_sel_ch1 = dmic_data->clk_phase_sel_ch1;
|
||||
unsigned int clk_phase_sel_ch2 = dmic_data->clk_phase_sel_ch2;
|
||||
unsigned int val = 0;
|
||||
unsigned int rate = dai->rate;
|
||||
int reg = get_chan_reg(dai->channels);
|
||||
|
||||
if (reg < 0)
|
||||
return -EINVAL;
|
||||
|
||||
dmic_data->dmic_channel = dai->channels;
|
||||
|
||||
val |= DMIC_TOP_CON_SDM3_LEVEL_MODE;
|
||||
|
||||
if (two_wire_mode) {
|
||||
val |= DMIC_TOP_CON_TWO_WIRE_MODE;
|
||||
} else {
|
||||
val |= FIELD_PREP(DMIC_TOP_CON_CK_PHASE_SEL_CH1,
|
||||
clk_phase_sel_ch1);
|
||||
val |= FIELD_PREP(DMIC_TOP_CON_CK_PHASE_SEL_CH2,
|
||||
clk_phase_sel_ch2);
|
||||
}
|
||||
|
||||
switch (rate) {
|
||||
case 48000:
|
||||
val |= DMIC_TOP_CON_VOICE_MODE_48K;
|
||||
break;
|
||||
case 32000:
|
||||
val |= DMIC_TOP_CON_VOICE_MODE_32K;
|
||||
break;
|
||||
case 16000:
|
||||
val |= DMIC_TOP_CON_VOICE_MODE_16K;
|
||||
break;
|
||||
case 8000:
|
||||
val |= DMIC_TOP_CON_VOICE_MODE_8K;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap_update_bits(afe->regmap, reg, DMIC_TOP_CON_CONFIG_MASK, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt8365_dai_dmic_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
mt8365_afe_enable_main_clk(afe);
|
||||
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC0_ADC);
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC1_ADC);
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC2_ADC);
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_DMIC3_ADC);
|
||||
|
||||
audio_dmic_adda_enable(afe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt8365_dai_dmic_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
mt8365_dai_disable_dmic(afe, substream, dai);
|
||||
audio_dmic_adda_disable(afe);
|
||||
/* HW Request delay 125us before CG off */
|
||||
usleep_range(125, 300);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC3_ADC);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC2_ADC);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC1_ADC);
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_DMIC0_ADC);
|
||||
|
||||
mt8365_afe_disable_main_clk(afe);
|
||||
}
|
||||
|
||||
static int mt8365_dai_dmic_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
mt8365_dai_configure_dmic(afe, substream, dai);
|
||||
mt8365_dai_enable_dmic(afe, substream, dai);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops mt8365_afe_dmic_ops = {
|
||||
.startup = mt8365_dai_dmic_startup,
|
||||
.shutdown = mt8365_dai_dmic_shutdown,
|
||||
.prepare = mt8365_dai_dmic_prepare,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver mtk_dai_dmic_driver[] = {
|
||||
{
|
||||
.name = "DMIC",
|
||||
.id = MT8365_AFE_IO_DMIC,
|
||||
.capture = {
|
||||
.stream_name = "DMIC Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 8,
|
||||
.rates = SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_32000 |
|
||||
SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &mt8365_afe_dmic_ops,
|
||||
}
|
||||
};
|
||||
|
||||
/* DAI Controls */
|
||||
|
||||
/* Values for 48kHz mode */
|
||||
static const char * const iir_mode_src[] = {
|
||||
"SW custom", "5Hz", "10Hz", "25Hz", "50Hz", "65Hz"
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(iir_mode, AFE_DMIC0_UL_SRC_CON0, 7, iir_mode_src);
|
||||
|
||||
static const struct snd_kcontrol_new mtk_dai_dmic_controls[] = {
|
||||
SOC_SINGLE("DMIC IIR Switch", AFE_DMIC0_UL_SRC_CON0, DMIC_TOP_CON_IIR_ON, 1, 0),
|
||||
SOC_ENUM("DMIC IIR Mode", iir_mode),
|
||||
};
|
||||
|
||||
/* DAI widget */
|
||||
|
||||
static const struct snd_soc_dapm_widget mtk_dai_dmic_widgets[] = {
|
||||
SND_SOC_DAPM_INPUT("DMIC In"),
|
||||
};
|
||||
|
||||
/* DAI route */
|
||||
|
||||
static const struct snd_soc_dapm_route mtk_dai_dmic_routes[] = {
|
||||
{"I14", NULL, "DMIC Capture"},
|
||||
{"I15", NULL, "DMIC Capture"},
|
||||
{"I16", NULL, "DMIC Capture"},
|
||||
{"I17", NULL, "DMIC Capture"},
|
||||
{"I18", NULL, "DMIC Capture"},
|
||||
{"I19", NULL, "DMIC Capture"},
|
||||
{"I20", NULL, "DMIC Capture"},
|
||||
{"I21", NULL, "DMIC Capture"},
|
||||
{"DMIC Capture", NULL, "DMIC In"},
|
||||
};
|
||||
|
||||
static int init_dmic_priv_data(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_dmic_data *dmic_priv;
|
||||
struct device_node *np = afe->dev->of_node;
|
||||
unsigned int temps[4];
|
||||
int ret;
|
||||
|
||||
dmic_priv = devm_kzalloc(afe->dev, sizeof(*dmic_priv), GFP_KERNEL);
|
||||
if (!dmic_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = of_property_read_u32_array(np, "mediatek,dmic-mode",
|
||||
&temps[0],
|
||||
1);
|
||||
if (ret == 0)
|
||||
dmic_priv->two_wire_mode = !!temps[0];
|
||||
|
||||
if (!dmic_priv->two_wire_mode) {
|
||||
dmic_priv->clk_phase_sel_ch1 = 0;
|
||||
dmic_priv->clk_phase_sel_ch2 = 4;
|
||||
}
|
||||
|
||||
afe_priv->dai_priv[MT8365_AFE_IO_DMIC] = dmic_priv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_dai_dmic_register(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mtk_base_afe_dai *dai;
|
||||
|
||||
dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
|
||||
if (!dai)
|
||||
return -ENOMEM;
|
||||
|
||||
list_add(&dai->list, &afe->sub_dais);
|
||||
dai->dai_drivers = mtk_dai_dmic_driver;
|
||||
dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_dmic_driver);
|
||||
dai->controls = mtk_dai_dmic_controls;
|
||||
dai->num_controls = ARRAY_SIZE(mtk_dai_dmic_controls);
|
||||
dai->dapm_widgets = mtk_dai_dmic_widgets;
|
||||
dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_dmic_widgets);
|
||||
dai->dapm_routes = mtk_dai_dmic_routes;
|
||||
dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_dmic_routes);
|
||||
return init_dmic_priv_data(afe);
|
||||
}
|
||||
@@ -0,0 +1,850 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek 8365 ALSA SoC Audio DAI I2S Control
|
||||
*
|
||||
* Copyright (c) 2024 MediaTek Inc.
|
||||
* Authors: Jia Zeng <jia.zeng@mediatek.com>
|
||||
* Alexandre Mergnat <amergnat@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include "mt8365-afe-clk.h"
|
||||
#include "mt8365-afe-common.h"
|
||||
|
||||
#define IIR_RATIOVER 9
|
||||
#define IIR_INV_COEF 10
|
||||
#define IIR_NO_NEED 11
|
||||
|
||||
struct mtk_afe_i2s_priv {
|
||||
bool adda_link;
|
||||
int i2s_out_on_ref_cnt;
|
||||
int id;
|
||||
int low_jitter_en;
|
||||
int mclk_id;
|
||||
int share_i2s_id;
|
||||
unsigned int clk_id_in;
|
||||
unsigned int clk_id_in_m_sel;
|
||||
unsigned int clk_id_out;
|
||||
unsigned int clk_id_out_m_sel;
|
||||
unsigned int clk_in_mult;
|
||||
unsigned int clk_out_mult;
|
||||
unsigned int config_val_in;
|
||||
unsigned int config_val_out;
|
||||
unsigned int dynamic_bck;
|
||||
unsigned int reg_off_in;
|
||||
unsigned int reg_off_out;
|
||||
};
|
||||
|
||||
/* This enum is merely for mtk_afe_i2s_priv declare */
|
||||
enum {
|
||||
DAI_I2S0 = 0,
|
||||
DAI_I2S3,
|
||||
DAI_I2S_NUM,
|
||||
};
|
||||
|
||||
static const struct mtk_afe_i2s_priv mt8365_i2s_priv[DAI_I2S_NUM] = {
|
||||
[DAI_I2S0] = {
|
||||
.id = MT8365_AFE_IO_I2S,
|
||||
.mclk_id = MT8365_I2S0_MCK,
|
||||
.share_i2s_id = -1,
|
||||
.clk_id_in = MT8365_CLK_AUD_I2S2_M,
|
||||
.clk_id_out = MT8365_CLK_AUD_I2S1_M,
|
||||
.clk_id_in_m_sel = MT8365_CLK_I2S2_M_SEL,
|
||||
.clk_id_out_m_sel = MT8365_CLK_I2S1_M_SEL,
|
||||
.clk_in_mult = 256,
|
||||
.clk_out_mult = 256,
|
||||
.adda_link = true,
|
||||
.config_val_out = AFE_I2S_CON1_I2S2_TO_PAD,
|
||||
.reg_off_in = AFE_I2S_CON2,
|
||||
.reg_off_out = AFE_I2S_CON1,
|
||||
},
|
||||
[DAI_I2S3] = {
|
||||
.id = MT8365_AFE_IO_2ND_I2S,
|
||||
.mclk_id = MT8365_I2S3_MCK,
|
||||
.share_i2s_id = -1,
|
||||
.clk_id_in = MT8365_CLK_AUD_I2S0_M,
|
||||
.clk_id_out = MT8365_CLK_AUD_I2S3_M,
|
||||
.clk_id_in_m_sel = MT8365_CLK_I2S0_M_SEL,
|
||||
.clk_id_out_m_sel = MT8365_CLK_I2S3_M_SEL,
|
||||
.clk_in_mult = 256,
|
||||
.clk_out_mult = 256,
|
||||
.adda_link = false,
|
||||
.config_val_in = AFE_I2S_CON_FROM_IO_MUX,
|
||||
.reg_off_in = AFE_I2S_CON,
|
||||
.reg_off_out = AFE_I2S_CON3,
|
||||
},
|
||||
};
|
||||
|
||||
static const u32 *get_iir_coef(unsigned int input_fs,
|
||||
unsigned int output_fs, unsigned int *count)
|
||||
{
|
||||
static const u32 IIR_COEF_48_TO_44p1[30] = {
|
||||
0x061fb0, 0x0bd256, 0x061fb0, 0xe3a3e6, 0xf0a300, 0x000003,
|
||||
0x0e416d, 0x1bb577, 0x0e416d, 0xe59178, 0xf23637, 0x000003,
|
||||
0x0c7d72, 0x189060, 0x0c7d72, 0xe96f09, 0xf505b2, 0x000003,
|
||||
0x126054, 0x249143, 0x126054, 0xe1fc0c, 0xf4b20a, 0x000002,
|
||||
0x000000, 0x323c85, 0x323c85, 0xf76d4e, 0x000000, 0x000002,
|
||||
};
|
||||
|
||||
static const u32 IIR_COEF_44p1_TO_32[42] = {
|
||||
0x0a6074, 0x0d237a, 0x0a6074, 0xdd8d6c, 0xe0b3f6, 0x000002,
|
||||
0x0e41f8, 0x128d48, 0x0e41f8, 0xefc14e, 0xf12d7a, 0x000003,
|
||||
0x0cfa60, 0x11e89c, 0x0cfa60, 0xf1b09e, 0xf27205, 0x000003,
|
||||
0x15b69c, 0x20e7e4, 0x15b69c, 0xea799a, 0xe9314a, 0x000002,
|
||||
0x0f79e2, 0x1a7064, 0x0f79e2, 0xf65e4a, 0xf03d8e, 0x000002,
|
||||
0x10c34f, 0x1ffe4b, 0x10c34f, 0x0bbecb, 0xf2bc4b, 0x000001,
|
||||
0x000000, 0x23b063, 0x23b063, 0x07335f, 0x000000, 0x000002,
|
||||
};
|
||||
|
||||
static const u32 IIR_COEF_48_TO_32[42] = {
|
||||
0x0a2a9b, 0x0a2f05, 0x0a2a9b, 0xe73873, 0xe0c525, 0x000002,
|
||||
0x0dd4ad, 0x0e765a, 0x0dd4ad, 0xf49808, 0xf14844, 0x000003,
|
||||
0x18a8cd, 0x1c40d0, 0x18a8cd, 0xed2aab, 0xe542ec, 0x000002,
|
||||
0x13e044, 0x1a47c4, 0x13e044, 0xf44aed, 0xe9acc7, 0x000002,
|
||||
0x1abd9c, 0x2a5429, 0x1abd9c, 0xff3441, 0xe0fc5f, 0x000001,
|
||||
0x0d86db, 0x193e2e, 0x0d86db, 0x1a6f15, 0xf14507, 0x000001,
|
||||
0x000000, 0x1f820c, 0x1f820c, 0x0a1b1f, 0x000000, 0x000002,
|
||||
};
|
||||
|
||||
static const u32 IIR_COEF_32_TO_16[48] = {
|
||||
0x122893, 0xffadd4, 0x122893, 0x0bc205, 0xc0ee1c, 0x000001,
|
||||
0x1bab8a, 0x00750d, 0x1bab8a, 0x06a983, 0xe18a5c, 0x000002,
|
||||
0x18f68e, 0x02706f, 0x18f68e, 0x0886a9, 0xe31bcb, 0x000002,
|
||||
0x149c05, 0x054487, 0x149c05, 0x0bec31, 0xe5973e, 0x000002,
|
||||
0x0ea303, 0x07f24a, 0x0ea303, 0x115ff9, 0xe967b6, 0x000002,
|
||||
0x0823fd, 0x085531, 0x0823fd, 0x18d5b4, 0xee8d21, 0x000002,
|
||||
0x06888e, 0x0acbbb, 0x06888e, 0x40b55c, 0xe76dce, 0x000001,
|
||||
0x000000, 0x2d31a9, 0x2d31a9, 0x23ba4f, 0x000000, 0x000001,
|
||||
};
|
||||
|
||||
static const u32 IIR_COEF_96_TO_44p1[48] = {
|
||||
0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002,
|
||||
0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002,
|
||||
0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002,
|
||||
0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002,
|
||||
0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002,
|
||||
0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002,
|
||||
0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001,
|
||||
0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001,
|
||||
};
|
||||
|
||||
static const u32 IIR_COEF_44p1_TO_16[48] = {
|
||||
0x0998fb, 0xf7f925, 0x0998fb, 0x1e54a0, 0xe06605, 0x000002,
|
||||
0x0d828e, 0xf50f97, 0x0d828e, 0x0f41b5, 0xf0a999, 0x000003,
|
||||
0x17ebeb, 0xee30d8, 0x17ebeb, 0x1f48ca, 0xe2ae88, 0x000002,
|
||||
0x12fab5, 0xf46ddc, 0x12fab5, 0x20cc51, 0xe4d068, 0x000002,
|
||||
0x0c7ac6, 0xfbd00e, 0x0c7ac6, 0x2337da, 0xe8028c, 0x000002,
|
||||
0x060ddc, 0x015b3e, 0x060ddc, 0x266754, 0xec21b6, 0x000002,
|
||||
0x0407b5, 0x04f827, 0x0407b5, 0x52e3d0, 0xe0149f, 0x000001,
|
||||
0x000000, 0x1f9521, 0x1f9521, 0x2ac116, 0x000000, 0x000001,
|
||||
};
|
||||
|
||||
static const u32 IIR_COEF_48_TO_16[48] = {
|
||||
0x0955ff, 0xf6544a, 0x0955ff, 0x2474e5, 0xe062e6, 0x000002,
|
||||
0x0d4180, 0xf297f4, 0x0d4180, 0x12415b, 0xf0a3b0, 0x000003,
|
||||
0x0ba079, 0xf4f0b0, 0x0ba079, 0x1285d3, 0xf1488b, 0x000003,
|
||||
0x12247c, 0xf1033c, 0x12247c, 0x2625be, 0xe48e0d, 0x000002,
|
||||
0x0b98e0, 0xf96d1a, 0x0b98e0, 0x27e79c, 0xe7798a, 0x000002,
|
||||
0x055e3b, 0xffed09, 0x055e3b, 0x2a2e2d, 0xeb2854, 0x000002,
|
||||
0x01a934, 0x01ca03, 0x01a934, 0x2c4fea, 0xee93ab, 0x000002,
|
||||
0x000000, 0x1c46c5, 0x1c46c5, 0x2d37dc, 0x000000, 0x000001,
|
||||
};
|
||||
|
||||
static const u32 IIR_COEF_96_TO_16[48] = {
|
||||
0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002,
|
||||
0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003,
|
||||
0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003,
|
||||
0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003,
|
||||
0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002,
|
||||
0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002,
|
||||
0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002,
|
||||
0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001,
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const u32 *coef;
|
||||
unsigned int cnt;
|
||||
} iir_coef_tbl_list[8] = {
|
||||
/* 0: 0.9188 */
|
||||
{ IIR_COEF_48_TO_44p1, ARRAY_SIZE(IIR_COEF_48_TO_44p1) },
|
||||
/* 1: 0.7256 */
|
||||
{ IIR_COEF_44p1_TO_32, ARRAY_SIZE(IIR_COEF_44p1_TO_32) },
|
||||
/* 2: 0.6667 */
|
||||
{ IIR_COEF_48_TO_32, ARRAY_SIZE(IIR_COEF_48_TO_32) },
|
||||
/* 3: 0.5 */
|
||||
{ IIR_COEF_32_TO_16, ARRAY_SIZE(IIR_COEF_32_TO_16) },
|
||||
/* 4: 0.4594 */
|
||||
{ IIR_COEF_96_TO_44p1, ARRAY_SIZE(IIR_COEF_96_TO_44p1) },
|
||||
/* 5: 0.3628 */
|
||||
{ IIR_COEF_44p1_TO_16, ARRAY_SIZE(IIR_COEF_44p1_TO_16) },
|
||||
/* 6: 0.3333 */
|
||||
{ IIR_COEF_48_TO_16, ARRAY_SIZE(IIR_COEF_48_TO_16) },
|
||||
/* 7: 0.1667 */
|
||||
{ IIR_COEF_96_TO_16, ARRAY_SIZE(IIR_COEF_96_TO_16) },
|
||||
};
|
||||
|
||||
static const u32 freq_new_index[16] = {
|
||||
0, 1, 2, 99, 3, 4, 5, 99, 6, 7, 8, 9, 10, 11, 12, 99
|
||||
};
|
||||
|
||||
static const u32 iir_coef_tbl_matrix[13][13] = {
|
||||
{/*0*/
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*1*/
|
||||
1, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*2*/
|
||||
2, 0, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*3*/
|
||||
3, IIR_INV_COEF, IIR_INV_COEF, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*4*/
|
||||
5, 3, IIR_INV_COEF, 2, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*5*/
|
||||
6, 4, 3, 2, 0, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*6*/
|
||||
IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, 3, IIR_INV_COEF,
|
||||
IIR_INV_COEF, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*7*/
|
||||
IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, 5, 3,
|
||||
IIR_INV_COEF, 1, IIR_NO_NEED, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*8*/
|
||||
7, IIR_INV_COEF, IIR_INV_COEF, 6, 4, 3, 2, 0, IIR_NO_NEED,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*9*/
|
||||
IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF,
|
||||
IIR_INV_COEF, IIR_INV_COEF, 5, 3, IIR_INV_COEF,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*10*/
|
||||
IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, 7, IIR_INV_COEF,
|
||||
IIR_INV_COEF, 6, 4, 3, 0,
|
||||
IIR_NO_NEED, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{ /*11*/
|
||||
IIR_RATIOVER, IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF,
|
||||
IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF, IIR_INV_COEF,
|
||||
IIR_INV_COEF, 3, IIR_INV_COEF, IIR_NO_NEED, IIR_NO_NEED
|
||||
},
|
||||
{/*12*/
|
||||
IIR_RATIOVER, IIR_RATIOVER, IIR_INV_COEF, IIR_INV_COEF,
|
||||
IIR_INV_COEF, IIR_INV_COEF, 7, IIR_INV_COEF,
|
||||
IIR_INV_COEF, 4, 3, 0, IIR_NO_NEED
|
||||
},
|
||||
};
|
||||
|
||||
const u32 *coef = NULL;
|
||||
unsigned int cnt = 0;
|
||||
u32 i = freq_new_index[input_fs];
|
||||
u32 j = freq_new_index[output_fs];
|
||||
|
||||
if (i < 13 && j < 13) {
|
||||
u32 k = iir_coef_tbl_matrix[i][j];
|
||||
|
||||
if (k >= IIR_NO_NEED) {
|
||||
} else if (k == IIR_RATIOVER) {
|
||||
} else if (k == IIR_INV_COEF) {
|
||||
} else {
|
||||
coef = iir_coef_tbl_list[k].coef;
|
||||
cnt = iir_coef_tbl_list[k].cnt;
|
||||
}
|
||||
}
|
||||
*count = cnt;
|
||||
return coef;
|
||||
}
|
||||
|
||||
static int mt8365_dai_set_config(struct mtk_base_afe *afe,
|
||||
struct mtk_afe_i2s_priv *i2s_data,
|
||||
bool is_input, unsigned int rate,
|
||||
int bit_width)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_be_dai_data *be =
|
||||
&afe_priv->be_data[i2s_data->id - MT8365_AFE_BACKEND_BASE];
|
||||
unsigned int val, reg_off;
|
||||
int fs = mt8365_afe_fs_timing(rate);
|
||||
|
||||
if (fs < 0)
|
||||
return -EINVAL;
|
||||
|
||||
val = AFE_I2S_CON_LOW_JITTER_CLK | AFE_I2S_CON_FORMAT_I2S;
|
||||
val |= FIELD_PREP(AFE_I2S_CON_RATE_MASK, fs);
|
||||
|
||||
if (is_input) {
|
||||
reg_off = i2s_data->reg_off_in;
|
||||
if (i2s_data->adda_link)
|
||||
val |= i2s_data->config_val_in;
|
||||
} else {
|
||||
reg_off = i2s_data->reg_off_out;
|
||||
val |= i2s_data->config_val_in;
|
||||
}
|
||||
|
||||
/* 1:bck=32lrck(16bit) or bck=64lrck(32bit) 0:fix bck=64lrck */
|
||||
if (i2s_data->dynamic_bck) {
|
||||
if (bit_width > 16)
|
||||
val |= AFE_I2S_CON_WLEN_32BIT;
|
||||
else
|
||||
val &= ~(u32)AFE_I2S_CON_WLEN_32BIT;
|
||||
} else {
|
||||
val |= AFE_I2S_CON_WLEN_32BIT;
|
||||
}
|
||||
|
||||
if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) ==
|
||||
SND_SOC_DAIFMT_CBM_CFM) {
|
||||
val |= AFE_I2S_CON_SRC_SLAVE;
|
||||
val &= ~(u32)AFE_I2S_CON_FROM_IO_MUX;//from consys
|
||||
}
|
||||
|
||||
regmap_update_bits(afe->regmap, reg_off, ~(u32)AFE_I2S_CON_EN, val);
|
||||
|
||||
if (i2s_data->adda_link && is_input)
|
||||
regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, 0x1, 0x1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_afe_set_i2s_out(struct mtk_base_afe *afe,
|
||||
unsigned int rate, int bit_width)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mtk_afe_i2s_priv *i2s_data =
|
||||
afe_priv->dai_priv[MT8365_AFE_IO_I2S];
|
||||
|
||||
return mt8365_dai_set_config(afe, i2s_data, false, rate, bit_width);
|
||||
}
|
||||
|
||||
static int mt8365_afe_set_2nd_i2s_asrc(struct mtk_base_afe *afe,
|
||||
unsigned int rate_in,
|
||||
unsigned int rate_out,
|
||||
unsigned int width,
|
||||
unsigned int mono,
|
||||
int o16bit, int tracking)
|
||||
{
|
||||
int ifs, ofs = 0;
|
||||
unsigned int val = 0;
|
||||
unsigned int mask = 0;
|
||||
const u32 *coef;
|
||||
u32 iir_stage;
|
||||
unsigned int coef_count = 0;
|
||||
|
||||
ifs = mt8365_afe_fs_timing(rate_in);
|
||||
|
||||
if (ifs < 0)
|
||||
return -EINVAL;
|
||||
|
||||
ofs = mt8365_afe_fs_timing(rate_out);
|
||||
|
||||
if (ofs < 0)
|
||||
return -EINVAL;
|
||||
|
||||
val = FIELD_PREP(O16BIT, o16bit) | FIELD_PREP(IS_MONO, mono);
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2,
|
||||
O16BIT | IS_MONO, val);
|
||||
|
||||
coef = get_iir_coef(ifs, ofs, &coef_count);
|
||||
iir_stage = ((u32)coef_count / 6) - 1;
|
||||
|
||||
if (coef) {
|
||||
unsigned int i;
|
||||
|
||||
/* CPU control IIR coeff SRAM */
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,
|
||||
COEFF_SRAM_CTRL, COEFF_SRAM_CTRL);
|
||||
|
||||
/* set to 0, IIR coeff SRAM addr */
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON13,
|
||||
0xffffffff, 0x0);
|
||||
|
||||
for (i = 0; i < coef_count; ++i)
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON12,
|
||||
0xffffffff, coef[i]);
|
||||
|
||||
/* disable IIR coeff SRAM access */
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,
|
||||
COEFF_SRAM_CTRL,
|
||||
(unsigned long)~COEFF_SRAM_CTRL);
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2,
|
||||
CLR_IIR_HISTORY | IIR_EN | IIR_STAGE_MASK,
|
||||
CLR_IIR_HISTORY | IIR_EN |
|
||||
FIELD_PREP(IIR_STAGE_MASK, iir_stage));
|
||||
} else {
|
||||
/* disable IIR */
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2,
|
||||
IIR_EN, (unsigned long)~IIR_EN);
|
||||
}
|
||||
|
||||
/* CON3 setting (RX OFS) */
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON3,
|
||||
0x00FFFFFF, rx_frequency_palette(ofs));
|
||||
/* CON4 setting (RX IFS) */
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON4,
|
||||
0x00FFFFFF, rx_frequency_palette(ifs));
|
||||
|
||||
/* CON5 setting */
|
||||
if (tracking) {
|
||||
val = CALI_64_CYCLE |
|
||||
CALI_AUTORST |
|
||||
AUTO_TUNE_FREQ5 |
|
||||
COMP_FREQ_RES |
|
||||
CALI_BP_DGL |
|
||||
CALI_AUTO_RESTART |
|
||||
CALI_USE_FREQ_OUT |
|
||||
CALI_SEL_01;
|
||||
|
||||
mask = CALI_CYCLE_MASK |
|
||||
CALI_AUTORST |
|
||||
AUTO_TUNE_FREQ5 |
|
||||
COMP_FREQ_RES |
|
||||
CALI_SEL_MASK |
|
||||
CALI_BP_DGL |
|
||||
AUTO_TUNE_FREQ4 |
|
||||
CALI_AUTO_RESTART |
|
||||
CALI_USE_FREQ_OUT |
|
||||
CALI_ON;
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5,
|
||||
mask, val);
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5,
|
||||
CALI_ON, CALI_ON);
|
||||
} else {
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5,
|
||||
0xffffffff, 0x0);
|
||||
}
|
||||
/* CON6 setting fix 8125 */
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON6,
|
||||
0x0000ffff, 0x1FBD);
|
||||
/* CON9 setting (RX IFS) */
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON9,
|
||||
0x000fffff, AutoRstThHi(ifs));
|
||||
/* CON10 setting (RX IFS) */
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON10,
|
||||
0x000fffff, AutoRstThLo(ifs));
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,
|
||||
CHSET_STR_CLR, CHSET_STR_CLR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt8365_afe_set_2nd_i2s_asrc_enable(struct mtk_base_afe *afe,
|
||||
bool enable)
|
||||
{
|
||||
if (enable)
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,
|
||||
ASM_ON, ASM_ON);
|
||||
else
|
||||
regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,
|
||||
ASM_ON, (unsigned long)~ASM_ON);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mt8365_afe_set_i2s_out_enable(struct mtk_base_afe *afe, bool enable)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mtk_afe_i2s_priv *i2s_data;
|
||||
|
||||
for (i = 0; i < DAI_I2S_NUM; i++) {
|
||||
if (mt8365_i2s_priv[i].adda_link)
|
||||
i2s_data = afe_priv->dai_priv[mt8365_i2s_priv[i].id];
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
|
||||
|
||||
if (enable) {
|
||||
i2s_data->i2s_out_on_ref_cnt++;
|
||||
if (i2s_data->i2s_out_on_ref_cnt == 1)
|
||||
regmap_update_bits(afe->regmap, AFE_I2S_CON1,
|
||||
0x1, enable);
|
||||
} else {
|
||||
i2s_data->i2s_out_on_ref_cnt--;
|
||||
if (i2s_data->i2s_out_on_ref_cnt == 0)
|
||||
regmap_update_bits(afe->regmap, AFE_I2S_CON1,
|
||||
0x1, enable);
|
||||
else if (i2s_data->i2s_out_on_ref_cnt < 0)
|
||||
i2s_data->i2s_out_on_ref_cnt = 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
|
||||
}
|
||||
|
||||
static void mt8365_dai_set_enable(struct mtk_base_afe *afe,
|
||||
struct mtk_afe_i2s_priv *i2s_data,
|
||||
bool is_input, bool enable)
|
||||
{
|
||||
unsigned int reg_off;
|
||||
|
||||
if (is_input) {
|
||||
reg_off = i2s_data->reg_off_in;
|
||||
} else {
|
||||
if (i2s_data->adda_link) {
|
||||
mt8365_afe_set_i2s_out_enable(afe, enable);
|
||||
return;
|
||||
}
|
||||
reg_off = i2s_data->reg_off_out;
|
||||
}
|
||||
regmap_update_bits(afe->regmap, reg_off,
|
||||
0x1, enable);
|
||||
}
|
||||
|
||||
static int mt8365_dai_i2s_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id];
|
||||
struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE];
|
||||
bool i2s_in_slave =
|
||||
(substream->stream == SNDRV_PCM_STREAM_CAPTURE) &&
|
||||
((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) ==
|
||||
SND_SOC_DAIFMT_CBM_CFM);
|
||||
|
||||
mt8365_afe_enable_main_clk(afe);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
clk_prepare_enable(afe_priv->clocks[i2s_data->clk_id_out]);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && !i2s_in_slave)
|
||||
clk_prepare_enable(afe_priv->clocks[i2s_data->clk_id_in]);
|
||||
|
||||
if (i2s_in_slave)
|
||||
mt8365_afe_enable_top_cg(afe, MT8365_TOP_CG_I2S_IN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt8365_dai_i2s_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id];
|
||||
struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE];
|
||||
bool reset_i2s_out_change = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
|
||||
bool reset_i2s_in_change = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
|
||||
bool i2s_in_slave =
|
||||
(substream->stream == SNDRV_PCM_STREAM_CAPTURE) &&
|
||||
((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) ==
|
||||
SND_SOC_DAIFMT_CBM_CFM);
|
||||
|
||||
if (be->prepared[substream->stream]) {
|
||||
if (reset_i2s_out_change)
|
||||
mt8365_dai_set_enable(afe, i2s_data, false, false);
|
||||
|
||||
if (reset_i2s_in_change)
|
||||
mt8365_dai_set_enable(afe, i2s_data, true, false);
|
||||
|
||||
if (substream->runtime->rate % 8000)
|
||||
mt8365_afe_disable_apll_associated_cfg(afe, MT8365_AFE_APLL1);
|
||||
else
|
||||
mt8365_afe_disable_apll_associated_cfg(afe, MT8365_AFE_APLL2);
|
||||
|
||||
if (reset_i2s_out_change)
|
||||
be->prepared[SNDRV_PCM_STREAM_PLAYBACK] = false;
|
||||
|
||||
if (reset_i2s_in_change)
|
||||
be->prepared[SNDRV_PCM_STREAM_CAPTURE] = false;
|
||||
}
|
||||
|
||||
if (reset_i2s_out_change)
|
||||
mt8365_afe_disable_clk(afe,
|
||||
afe_priv->clocks[i2s_data->clk_id_out]);
|
||||
|
||||
if (reset_i2s_in_change && !i2s_in_slave)
|
||||
mt8365_afe_disable_clk(afe,
|
||||
afe_priv->clocks[i2s_data->clk_id_in]);
|
||||
|
||||
if (i2s_in_slave)
|
||||
mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_I2S_IN);
|
||||
|
||||
mt8365_afe_disable_main_clk(afe);
|
||||
}
|
||||
|
||||
static int mt8365_dai_i2s_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mtk_afe_i2s_priv *i2s_data = afe_priv->dai_priv[dai->id];
|
||||
struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE];
|
||||
bool apply_i2s_out_change = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
|
||||
bool apply_i2s_in_change = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
|
||||
unsigned int rate = substream->runtime->rate;
|
||||
int bit_width = snd_pcm_format_width(substream->runtime->format);
|
||||
int ret;
|
||||
|
||||
if (be->prepared[substream->stream]) {
|
||||
dev_info(afe->dev, "%s '%s' prepared already\n",
|
||||
__func__, snd_pcm_stream_str(substream));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (apply_i2s_out_change) {
|
||||
ret = mt8365_dai_set_config(afe, i2s_data, false, rate, bit_width);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (apply_i2s_in_change) {
|
||||
if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK)
|
||||
== SND_SOC_DAIFMT_CBM_CFM) {
|
||||
ret = mt8365_afe_set_2nd_i2s_asrc(afe, 32000, rate,
|
||||
(unsigned int)bit_width,
|
||||
0, 0, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ret = mt8365_dai_set_config(afe, i2s_data, true, rate, bit_width);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rate % 8000)
|
||||
mt8365_afe_enable_apll_associated_cfg(afe, MT8365_AFE_APLL1);
|
||||
else
|
||||
mt8365_afe_enable_apll_associated_cfg(afe, MT8365_AFE_APLL2);
|
||||
|
||||
if (apply_i2s_out_change) {
|
||||
mt8365_afe_set_clk_parent(afe,
|
||||
afe_priv->clocks[i2s_data->clk_id_out_m_sel],
|
||||
((rate % 8000) ?
|
||||
afe_priv->clocks[MT8365_CLK_AUD1] :
|
||||
afe_priv->clocks[MT8365_CLK_AUD2]));
|
||||
|
||||
mt8365_afe_set_clk_rate(afe,
|
||||
afe_priv->clocks[i2s_data->clk_id_out],
|
||||
rate * i2s_data->clk_out_mult);
|
||||
|
||||
mt8365_dai_set_enable(afe, i2s_data, false, true);
|
||||
be->prepared[SNDRV_PCM_STREAM_PLAYBACK] = true;
|
||||
}
|
||||
|
||||
if (apply_i2s_in_change) {
|
||||
mt8365_afe_set_clk_parent(afe,
|
||||
afe_priv->clocks[i2s_data->clk_id_in_m_sel],
|
||||
((rate % 8000) ?
|
||||
afe_priv->clocks[MT8365_CLK_AUD1] :
|
||||
afe_priv->clocks[MT8365_CLK_AUD2]));
|
||||
|
||||
mt8365_afe_set_clk_rate(afe,
|
||||
afe_priv->clocks[i2s_data->clk_id_in],
|
||||
rate * i2s_data->clk_in_mult);
|
||||
|
||||
mt8365_dai_set_enable(afe, i2s_data, true, true);
|
||||
|
||||
if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK)
|
||||
== SND_SOC_DAIFMT_CBM_CFM)
|
||||
mt8365_afe_set_2nd_i2s_asrc_enable(afe, true);
|
||||
|
||||
be->prepared[SNDRV_PCM_STREAM_CAPTURE] = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt8365_afe_2nd_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
unsigned int width_val = params_width(params) > 16 ?
|
||||
(AFE_CONN_24BIT_O00 | AFE_CONN_24BIT_O01) : 0;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
regmap_update_bits(afe->regmap, AFE_CONN_24BIT,
|
||||
AFE_CONN_24BIT_O00 | AFE_CONN_24BIT_O01, width_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt8365_afe_2nd_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_be_dai_data *be = &afe_priv->be_data[dai->id - MT8365_AFE_BACKEND_BASE];
|
||||
|
||||
be->fmt_mode = 0;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
be->fmt_mode |= SND_SOC_DAIFMT_I2S;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
be->fmt_mode |= SND_SOC_DAIFMT_LEFT_J;
|
||||
break;
|
||||
default:
|
||||
dev_err(afe->dev, "invalid audio format for 2nd i2s!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) &&
|
||||
((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_IF) &&
|
||||
((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_IB_NF) &&
|
||||
((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_IB_IF)) {
|
||||
dev_err(afe->dev, "invalid audio format for 2nd i2s!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
be->fmt_mode |= (fmt & SND_SOC_DAIFMT_INV_MASK);
|
||||
|
||||
if (((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM))
|
||||
be->fmt_mode |= (fmt & SND_SOC_DAIFMT_MASTER_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops mt8365_afe_i2s_ops = {
|
||||
.startup = mt8365_dai_i2s_startup,
|
||||
.shutdown = mt8365_dai_i2s_shutdown,
|
||||
.prepare = mt8365_dai_i2s_prepare,
|
||||
};
|
||||
|
||||
static const struct snd_soc_dai_ops mt8365_afe_2nd_i2s_ops = {
|
||||
.startup = mt8365_dai_i2s_startup,
|
||||
.shutdown = mt8365_dai_i2s_shutdown,
|
||||
.hw_params = mt8365_afe_2nd_i2s_hw_params,
|
||||
.prepare = mt8365_dai_i2s_prepare,
|
||||
.set_fmt = mt8365_afe_2nd_i2s_set_fmt,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {
|
||||
{
|
||||
.name = "I2S",
|
||||
.id = MT8365_AFE_IO_I2S,
|
||||
.playback = {
|
||||
.stream_name = "I2S Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "I2S Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &mt8365_afe_i2s_ops,
|
||||
}, {
|
||||
.name = "2ND I2S",
|
||||
.id = MT8365_AFE_IO_2ND_I2S,
|
||||
.playback = {
|
||||
.stream_name = "2ND I2S Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "2ND I2S Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &mt8365_afe_2nd_i2s_ops,
|
||||
}
|
||||
};
|
||||
|
||||
/* low jitter control */
|
||||
static const char * const mt8365_i2s_hd_str[] = {
|
||||
"Normal", "Low_Jitter"
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(mt8365_i2s_enum, mt8365_i2s_hd_str);
|
||||
|
||||
static const char * const fmi2sin_text[] = {
|
||||
"OPEN", "FM_2ND_I2S_IN"
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_VIRT_DECL(fmi2sin_enum, fmi2sin_text);
|
||||
|
||||
static const struct snd_kcontrol_new fmi2sin_mux =
|
||||
SOC_DAPM_ENUM("FM 2ND I2S Source", fmi2sin_enum);
|
||||
|
||||
static const struct snd_kcontrol_new i2s_o03_o04_enable_ctl =
|
||||
SOC_DAPM_SINGLE_VIRT("Switch", 1);
|
||||
|
||||
static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {
|
||||
SND_SOC_DAPM_SWITCH("I2S O03_O04", SND_SOC_NOPM, 0, 0,
|
||||
&i2s_o03_o04_enable_ctl),
|
||||
SND_SOC_DAPM_MUX("FM 2ND I2S Mux", SND_SOC_NOPM, 0, 0, &fmi2sin_mux),
|
||||
SND_SOC_DAPM_INPUT("2ND I2S In"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {
|
||||
{"I2S O03_O04", "Switch", "O03"},
|
||||
{"I2S O03_O04", "Switch", "O04"},
|
||||
{"I2S Playback", NULL, "I2S O03_O04"},
|
||||
{"2ND I2S Playback", NULL, "O00"},
|
||||
{"2ND I2S Playback", NULL, "O01"},
|
||||
{"2ND I2S Capture", NULL, "2ND I2S In"},
|
||||
{"FM 2ND I2S Mux", "FM_2ND_I2S_IN", "2ND I2S Capture"},
|
||||
};
|
||||
|
||||
static int mt8365_dai_i2s_set_priv(struct mtk_base_afe *afe)
|
||||
{
|
||||
int i, ret;
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
for (i = 0; i < DAI_I2S_NUM; i++) {
|
||||
ret = mt8365_dai_set_priv(afe, mt8365_i2s_priv[i].id,
|
||||
sizeof(*afe_priv),
|
||||
&mt8365_i2s_priv[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_dai_i2s_register(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mtk_base_afe_dai *dai;
|
||||
|
||||
dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
|
||||
if (!dai)
|
||||
return -ENOMEM;
|
||||
|
||||
list_add(&dai->list, &afe->sub_dais);
|
||||
|
||||
dai->dai_drivers = mtk_dai_i2s_driver;
|
||||
dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);
|
||||
dai->dapm_widgets = mtk_dai_i2s_widgets;
|
||||
dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);
|
||||
dai->dapm_routes = mtk_dai_i2s_routes;
|
||||
dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);
|
||||
|
||||
/* set all dai i2s private data */
|
||||
return mt8365_dai_i2s_set_priv(afe);
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek 8365 ALSA SoC Audio DAI PCM Control
|
||||
*
|
||||
* Copyright (c) 2024 MediaTek Inc.
|
||||
* Authors: Jia Zeng <jia.zeng@mediatek.com>
|
||||
* Alexandre Mergnat <amergnat@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include "mt8365-afe-clk.h"
|
||||
#include "mt8365-afe-common.h"
|
||||
|
||||
struct mt8365_pcm_intf_data {
|
||||
bool slave_mode;
|
||||
bool lrck_inv;
|
||||
bool bck_inv;
|
||||
unsigned int format;
|
||||
};
|
||||
|
||||
/* DAI Drivers */
|
||||
|
||||
static void mt8365_dai_enable_pcm1(struct mtk_base_afe *afe)
|
||||
{
|
||||
regmap_update_bits(afe->regmap, PCM_INTF_CON1,
|
||||
PCM_INTF_CON1_EN, PCM_INTF_CON1_EN);
|
||||
}
|
||||
|
||||
static void mt8365_dai_disable_pcm1(struct mtk_base_afe *afe)
|
||||
{
|
||||
regmap_update_bits(afe->regmap, PCM_INTF_CON1,
|
||||
PCM_INTF_CON1_EN, 0x0);
|
||||
}
|
||||
|
||||
static int mt8365_dai_configure_pcm1(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_pcm_intf_data *pcm_priv = afe_priv->dai_priv[MT8365_AFE_IO_PCM1];
|
||||
bool slave_mode = pcm_priv->slave_mode;
|
||||
bool lrck_inv = pcm_priv->lrck_inv;
|
||||
bool bck_inv = pcm_priv->bck_inv;
|
||||
unsigned int fmt = pcm_priv->format;
|
||||
unsigned int bit_width = dai->sample_bits;
|
||||
unsigned int val = 0;
|
||||
|
||||
if (!slave_mode) {
|
||||
val |= PCM_INTF_CON1_MASTER_MODE |
|
||||
PCM_INTF_CON1_BYPASS_ASRC;
|
||||
|
||||
if (lrck_inv)
|
||||
val |= PCM_INTF_CON1_SYNC_OUT_INV;
|
||||
if (bck_inv)
|
||||
val |= PCM_INTF_CON1_BCLK_OUT_INV;
|
||||
} else {
|
||||
val |= PCM_INTF_CON1_SLAVE_MODE;
|
||||
|
||||
if (lrck_inv)
|
||||
val |= PCM_INTF_CON1_SYNC_IN_INV;
|
||||
if (bck_inv)
|
||||
val |= PCM_INTF_CON1_BCLK_IN_INV;
|
||||
|
||||
/* TODO: add asrc setting */
|
||||
}
|
||||
|
||||
val |= FIELD_PREP(PCM_INTF_CON1_FORMAT_MASK, fmt);
|
||||
|
||||
if (fmt == MT8365_PCM_FORMAT_PCMA ||
|
||||
fmt == MT8365_PCM_FORMAT_PCMB)
|
||||
val |= PCM_INTF_CON1_SYNC_LEN(1);
|
||||
else
|
||||
val |= PCM_INTF_CON1_SYNC_LEN(bit_width);
|
||||
|
||||
switch (substream->runtime->rate) {
|
||||
case 48000:
|
||||
val |= PCM_INTF_CON1_FS_48K;
|
||||
break;
|
||||
case 32000:
|
||||
val |= PCM_INTF_CON1_FS_32K;
|
||||
break;
|
||||
case 16000:
|
||||
val |= PCM_INTF_CON1_FS_16K;
|
||||
break;
|
||||
case 8000:
|
||||
val |= PCM_INTF_CON1_FS_8K;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bit_width > 16)
|
||||
val |= PCM_INTF_CON1_24BIT | PCM_INTF_CON1_64BCK;
|
||||
else
|
||||
val |= PCM_INTF_CON1_16BIT | PCM_INTF_CON1_32BCK;
|
||||
|
||||
val |= PCM_INTF_CON1_EXT_MODEM;
|
||||
|
||||
regmap_update_bits(afe->regmap, PCM_INTF_CON1,
|
||||
PCM_INTF_CON1_CONFIG_MASK, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt8365_dai_pcm1_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (snd_soc_dai_active(dai))
|
||||
return 0;
|
||||
|
||||
mt8365_afe_enable_main_clk(afe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt8365_dai_pcm1_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (snd_soc_dai_active(dai))
|
||||
return;
|
||||
|
||||
mt8365_dai_disable_pcm1(afe);
|
||||
mt8365_afe_disable_main_clk(afe);
|
||||
}
|
||||
|
||||
static int mt8365_dai_pcm1_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
int ret;
|
||||
|
||||
if ((snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK) +
|
||||
snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE)) > 1) {
|
||||
dev_info(afe->dev, "%s '%s' active(%u-%u) already\n",
|
||||
__func__, snd_pcm_stream_str(substream),
|
||||
snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK),
|
||||
snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = mt8365_dai_configure_pcm1(substream, dai);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mt8365_dai_enable_pcm1(afe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt8365_dai_pcm1_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_pcm_intf_data *pcm_priv = afe_priv->dai_priv[MT8365_AFE_IO_PCM1];
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
pcm_priv->format = MT8365_PCM_FORMAT_I2S;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
case SND_SOC_DAIFMT_NB_NF:
|
||||
pcm_priv->bck_inv = false;
|
||||
pcm_priv->lrck_inv = false;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_NB_IF:
|
||||
pcm_priv->bck_inv = false;
|
||||
pcm_priv->lrck_inv = true;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_NF:
|
||||
pcm_priv->bck_inv = true;
|
||||
pcm_priv->lrck_inv = false;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_IF:
|
||||
pcm_priv->bck_inv = true;
|
||||
pcm_priv->lrck_inv = true;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
pcm_priv->slave_mode = true;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
pcm_priv->slave_mode = false;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops mt8365_dai_pcm1_ops = {
|
||||
.startup = mt8365_dai_pcm1_startup,
|
||||
.shutdown = mt8365_dai_pcm1_shutdown,
|
||||
.prepare = mt8365_dai_pcm1_prepare,
|
||||
.set_fmt = mt8365_dai_pcm1_set_fmt,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
|
||||
{
|
||||
.name = "PCM1",
|
||||
.id = MT8365_AFE_IO_PCM1,
|
||||
.playback = {
|
||||
.stream_name = "PCM1 Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000 |
|
||||
SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_32000 |
|
||||
SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "PCM1 Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000 |
|
||||
SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_32000 |
|
||||
SNDRV_PCM_RATE_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &mt8365_dai_pcm1_ops,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
}
|
||||
};
|
||||
|
||||
/* DAI widget */
|
||||
|
||||
static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
|
||||
SND_SOC_DAPM_OUTPUT("PCM1 Out"),
|
||||
SND_SOC_DAPM_INPUT("PCM1 In"),
|
||||
};
|
||||
|
||||
/* DAI route */
|
||||
|
||||
static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
|
||||
{"PCM1 Playback", NULL, "O07"},
|
||||
{"PCM1 Playback", NULL, "O08"},
|
||||
{"PCM1 Out", NULL, "PCM1 Playback"},
|
||||
|
||||
{"I09", NULL, "PCM1 Capture"},
|
||||
{"I22", NULL, "PCM1 Capture"},
|
||||
{"PCM1 Capture", NULL, "PCM1 In"},
|
||||
};
|
||||
|
||||
static int init_pcmif_priv_data(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8365_afe_private *afe_priv = afe->platform_priv;
|
||||
struct mt8365_pcm_intf_data *pcmif_priv;
|
||||
|
||||
pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mt8365_pcm_intf_data),
|
||||
GFP_KERNEL);
|
||||
if (!pcmif_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
afe_priv->dai_priv[MT8365_AFE_IO_PCM1] = pcmif_priv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt8365_dai_pcm_register(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mtk_base_afe_dai *dai;
|
||||
|
||||
dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
|
||||
if (!dai)
|
||||
return -ENOMEM;
|
||||
|
||||
list_add(&dai->list, &afe->sub_dais);
|
||||
dai->dai_drivers = mtk_dai_pcm_driver;
|
||||
dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
|
||||
dai->dapm_widgets = mtk_dai_pcm_widgets;
|
||||
dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
|
||||
dai->dapm_routes = mtk_dai_pcm_routes;
|
||||
dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
|
||||
return init_pcmif_priv_data(afe);
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek MT8365 Sound Card driver
|
||||
*
|
||||
* Copyright (c) 2024 MediaTek Inc.
|
||||
* Authors: Nicolas Belin <nbelin@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include "mt8365-afe-common.h"
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include "../common/mtk-soc-card.h"
|
||||
#include "../common/mtk-soundcard-driver.h"
|
||||
|
||||
enum pinctrl_pin_state {
|
||||
PIN_STATE_DEFAULT,
|
||||
PIN_STATE_DMIC,
|
||||
PIN_STATE_MISO_OFF,
|
||||
PIN_STATE_MISO_ON,
|
||||
PIN_STATE_MOSI_OFF,
|
||||
PIN_STATE_MOSI_ON,
|
||||
PIN_STATE_MAX
|
||||
};
|
||||
|
||||
static const char * const mt8365_mt6357_pin_str[PIN_STATE_MAX] = {
|
||||
"default",
|
||||
"dmic",
|
||||
"miso_off",
|
||||
"miso_on",
|
||||
"mosi_off",
|
||||
"mosi_on",
|
||||
};
|
||||
|
||||
struct mt8365_mt6357_priv {
|
||||
struct pinctrl *pinctrl;
|
||||
struct pinctrl_state *pin_states[PIN_STATE_MAX];
|
||||
};
|
||||
|
||||
enum {
|
||||
/* FE */
|
||||
DAI_LINK_DL1_PLAYBACK = 0,
|
||||
DAI_LINK_DL2_PLAYBACK,
|
||||
DAI_LINK_AWB_CAPTURE,
|
||||
DAI_LINK_VUL_CAPTURE,
|
||||
/* BE */
|
||||
DAI_LINK_2ND_I2S_INTF,
|
||||
DAI_LINK_DMIC,
|
||||
DAI_LINK_INT_ADDA,
|
||||
DAI_LINK_NUM
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget mt8365_mt6357_widgets[] = {
|
||||
SND_SOC_DAPM_OUTPUT("HDMI Out"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route mt8365_mt6357_routes[] = {
|
||||
{"HDMI Out", NULL, "2ND I2S Playback"},
|
||||
{"DMIC In", NULL, "MICBIAS0"},
|
||||
};
|
||||
|
||||
static int mt8365_mt6357_int_adda_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct mt8365_mt6357_priv *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||
int ret = 0;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
if (IS_ERR(priv->pin_states[PIN_STATE_MOSI_ON]))
|
||||
return ret;
|
||||
|
||||
ret = pinctrl_select_state(priv->pinctrl,
|
||||
priv->pin_states[PIN_STATE_MOSI_ON]);
|
||||
if (ret)
|
||||
dev_err(rtd->card->dev, "%s failed to select state %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
if (IS_ERR(priv->pin_states[PIN_STATE_MISO_ON]))
|
||||
return ret;
|
||||
|
||||
ret = pinctrl_select_state(priv->pinctrl,
|
||||
priv->pin_states[PIN_STATE_MISO_ON]);
|
||||
if (ret)
|
||||
dev_err(rtd->card->dev, "%s failed to select state %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt8365_mt6357_int_adda_shutdown(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct mt8365_mt6357_priv *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||
int ret = 0;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
if (IS_ERR(priv->pin_states[PIN_STATE_MOSI_OFF]))
|
||||
return;
|
||||
|
||||
ret = pinctrl_select_state(priv->pinctrl,
|
||||
priv->pin_states[PIN_STATE_MOSI_OFF]);
|
||||
if (ret)
|
||||
dev_err(rtd->card->dev, "%s failed to select state %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
if (IS_ERR(priv->pin_states[PIN_STATE_MISO_OFF]))
|
||||
return;
|
||||
|
||||
ret = pinctrl_select_state(priv->pinctrl,
|
||||
priv->pin_states[PIN_STATE_MISO_OFF]);
|
||||
if (ret)
|
||||
dev_err(rtd->card->dev, "%s failed to select state %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops mt8365_mt6357_int_adda_ops = {
|
||||
.startup = mt8365_mt6357_int_adda_startup,
|
||||
.shutdown = mt8365_mt6357_int_adda_shutdown,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(playback1,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
SND_SOC_DAILINK_DEFS(playback2,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
SND_SOC_DAILINK_DEFS(awb_capture,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("AWB")),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
SND_SOC_DAILINK_DEFS(vul,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("VUL")),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(i2s3,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("2ND I2S")),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
SND_SOC_DAILINK_DEFS(dmic,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("DMIC")),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
SND_SOC_DAILINK_DEFS(primary_codec,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("INT ADDA")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("mt6357-sound", "mt6357-snd-codec-aif1")),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
|
||||
/* Digital audio interface glue - connects codec <---> CPU */
|
||||
static struct snd_soc_dai_link mt8365_mt6357_dais[] = {
|
||||
/* Front End DAI links */
|
||||
[DAI_LINK_DL1_PLAYBACK] = {
|
||||
.name = "DL1_FE",
|
||||
.stream_name = "MultiMedia1_PLayback",
|
||||
.id = DAI_LINK_DL1_PLAYBACK,
|
||||
.trigger = {
|
||||
SND_SOC_DPCM_TRIGGER_POST,
|
||||
SND_SOC_DPCM_TRIGGER_POST
|
||||
},
|
||||
.dynamic = 1,
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_merged_rate = 1,
|
||||
SND_SOC_DAILINK_REG(playback1),
|
||||
},
|
||||
[DAI_LINK_DL2_PLAYBACK] = {
|
||||
.name = "DL2_FE",
|
||||
.stream_name = "MultiMedia2_PLayback",
|
||||
.id = DAI_LINK_DL2_PLAYBACK,
|
||||
.trigger = {
|
||||
SND_SOC_DPCM_TRIGGER_POST,
|
||||
SND_SOC_DPCM_TRIGGER_POST
|
||||
},
|
||||
.dynamic = 1,
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_merged_rate = 1,
|
||||
SND_SOC_DAILINK_REG(playback2),
|
||||
},
|
||||
[DAI_LINK_AWB_CAPTURE] = {
|
||||
.name = "AWB_FE",
|
||||
.stream_name = "DL1_AWB_Record",
|
||||
.id = DAI_LINK_AWB_CAPTURE,
|
||||
.trigger = {
|
||||
SND_SOC_DPCM_TRIGGER_POST,
|
||||
SND_SOC_DPCM_TRIGGER_POST
|
||||
},
|
||||
.dynamic = 1,
|
||||
.dpcm_capture = 1,
|
||||
.dpcm_merged_rate = 1,
|
||||
SND_SOC_DAILINK_REG(awb_capture),
|
||||
},
|
||||
[DAI_LINK_VUL_CAPTURE] = {
|
||||
.name = "VUL_FE",
|
||||
.stream_name = "MultiMedia1_Capture",
|
||||
.id = DAI_LINK_VUL_CAPTURE,
|
||||
.trigger = {
|
||||
SND_SOC_DPCM_TRIGGER_POST,
|
||||
SND_SOC_DPCM_TRIGGER_POST
|
||||
},
|
||||
.dynamic = 1,
|
||||
.dpcm_capture = 1,
|
||||
.dpcm_merged_rate = 1,
|
||||
SND_SOC_DAILINK_REG(vul),
|
||||
},
|
||||
/* Back End DAI links */
|
||||
[DAI_LINK_2ND_I2S_INTF] = {
|
||||
.name = "I2S_OUT_BE",
|
||||
.no_pcm = 1,
|
||||
.id = DAI_LINK_2ND_I2S_INTF,
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_capture = 1,
|
||||
SND_SOC_DAILINK_REG(i2s3),
|
||||
},
|
||||
[DAI_LINK_DMIC] = {
|
||||
.name = "DMIC_BE",
|
||||
.no_pcm = 1,
|
||||
.id = DAI_LINK_DMIC,
|
||||
.dpcm_capture = 1,
|
||||
SND_SOC_DAILINK_REG(dmic),
|
||||
},
|
||||
[DAI_LINK_INT_ADDA] = {
|
||||
.name = "MTK_Codec",
|
||||
.no_pcm = 1,
|
||||
.id = DAI_LINK_INT_ADDA,
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_capture = 1,
|
||||
.ops = &mt8365_mt6357_int_adda_ops,
|
||||
SND_SOC_DAILINK_REG(primary_codec),
|
||||
},
|
||||
};
|
||||
|
||||
static int mt8365_mt6357_gpio_probe(struct snd_soc_card *card)
|
||||
{
|
||||
struct mt8365_mt6357_priv *priv = snd_soc_card_get_drvdata(card);
|
||||
int ret, i;
|
||||
|
||||
priv->pinctrl = devm_pinctrl_get(card->dev);
|
||||
if (IS_ERR(priv->pinctrl)) {
|
||||
ret = PTR_ERR(priv->pinctrl);
|
||||
return dev_err_probe(card->dev, ret,
|
||||
"Failed to get pinctrl\n");
|
||||
}
|
||||
|
||||
for (i = PIN_STATE_DEFAULT ; i < PIN_STATE_MAX ; i++) {
|
||||
priv->pin_states[i] = pinctrl_lookup_state(priv->pinctrl,
|
||||
mt8365_mt6357_pin_str[i]);
|
||||
if (IS_ERR(priv->pin_states[i])) {
|
||||
ret = PTR_ERR(priv->pin_states[i]);
|
||||
dev_warn(card->dev, "No pin state for %s\n",
|
||||
mt8365_mt6357_pin_str[i]);
|
||||
} else {
|
||||
ret = pinctrl_select_state(priv->pinctrl,
|
||||
priv->pin_states[i]);
|
||||
if (ret) {
|
||||
dev_err_probe(card->dev, ret,
|
||||
"Failed to select pin state %s\n",
|
||||
mt8365_mt6357_pin_str[i]);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_card mt8365_mt6357_soc_card = {
|
||||
.name = "mt8365-evk",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = mt8365_mt6357_dais,
|
||||
.num_links = ARRAY_SIZE(mt8365_mt6357_dais),
|
||||
.dapm_widgets = mt8365_mt6357_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(mt8365_mt6357_widgets),
|
||||
.dapm_routes = mt8365_mt6357_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(mt8365_mt6357_routes),
|
||||
};
|
||||
|
||||
static int mt8365_mt6357_dev_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)
|
||||
{
|
||||
struct mtk_platform_card_data *card_data = soc_card_data->card_data;
|
||||
struct snd_soc_card *card = card_data->card;
|
||||
struct device *dev = card->dev;
|
||||
struct device_node *platform_node;
|
||||
struct mt8365_mt6357_priv *mach_priv;
|
||||
int i, ret;
|
||||
|
||||
card->dev = dev;
|
||||
ret = parse_dai_link_info(card);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
mach_priv = devm_kzalloc(dev, sizeof(*mach_priv),
|
||||
GFP_KERNEL);
|
||||
if (!mach_priv)
|
||||
return -ENOMEM;
|
||||
soc_card_data->mach_priv = mach_priv;
|
||||
snd_soc_card_set_drvdata(card, soc_card_data);
|
||||
mt8365_mt6357_gpio_probe(card);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
clean_card_reference(card);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct mtk_soundcard_pdata mt8365_mt6357_card = {
|
||||
.card_name = "mt8365-mt6357",
|
||||
.card_data = &(struct mtk_platform_card_data) {
|
||||
.card = &mt8365_mt6357_soc_card,
|
||||
},
|
||||
.soc_probe = mt8365_mt6357_dev_probe
|
||||
};
|
||||
|
||||
static const struct of_device_id mt8365_mt6357_dt_match[] = {
|
||||
{ .compatible = "mediatek,mt8365-mt6357", .data = &mt8365_mt6357_card },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mt8365_mt6357_dt_match);
|
||||
|
||||
static struct platform_driver mt8365_mt6357_driver = {
|
||||
.driver = {
|
||||
.name = "mt8365_mt6357",
|
||||
.of_match_table = mt8365_mt6357_dt_match,
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = mtk_soundcard_common_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(mt8365_mt6357_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_DESCRIPTION("MT8365 EVK SoC machine driver");
|
||||
MODULE_AUTHOR("Nicolas Belin <nbelin@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform: mt8365_mt6357");
|
||||
@@ -0,0 +1,991 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* MediaTek 8365 audio driver reg definition
|
||||
*
|
||||
* Copyright (c) 2024 MediaTek Inc.
|
||||
* Authors: Jia Zeng <jia.zeng@mediatek.com>
|
||||
* Alexandre Mergnat <amergnat@baylibre.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT8365_REG_H_
|
||||
#define _MT8365_REG_H_
|
||||
|
||||
#define AUDIO_TOP_CON0 (0x0000)
|
||||
#define AUDIO_TOP_CON1 (0x0004)
|
||||
#define AUDIO_TOP_CON2 (0x0008)
|
||||
#define AUDIO_TOP_CON3 (0x000c)
|
||||
|
||||
#define AFE_DAC_CON0 (0x0010)
|
||||
#define AFE_DAC_CON1 (0x0014)
|
||||
#define AFE_I2S_CON (0x0018)
|
||||
#define AFE_CONN0 (0x0020)
|
||||
#define AFE_CONN1 (0x0024)
|
||||
#define AFE_CONN2 (0x0028)
|
||||
#define AFE_CONN3 (0x002c)
|
||||
#define AFE_CONN4 (0x0030)
|
||||
#define AFE_I2S_CON1 (0x0034)
|
||||
#define AFE_I2S_CON2 (0x0038)
|
||||
#define AFE_MRGIF_CON (0x003c)
|
||||
#define AFE_DL1_BASE (0x0040)
|
||||
#define AFE_DL1_CUR (0x0044)
|
||||
#define AFE_DL1_END (0x0048)
|
||||
#define AFE_I2S_CON3 (0x004c)
|
||||
#define AFE_DL2_BASE (0x0050)
|
||||
#define AFE_DL2_CUR (0x0054)
|
||||
#define AFE_DL2_END (0x0058)
|
||||
#define AFE_CONN5 (0x005c)
|
||||
#define AFE_AWB_BASE (0x0070)
|
||||
#define AFE_AWB_END (0x0078)
|
||||
#define AFE_AWB_CUR (0x007c)
|
||||
#define AFE_VUL_BASE (0x0080)
|
||||
#define AFE_VUL_END (0x0088)
|
||||
#define AFE_VUL_CUR (0x008c)
|
||||
#define AFE_CONN6 (0x00bc)
|
||||
#define AFE_MEMIF_MSB (0x00cc)
|
||||
#define AFE_MEMIF_MON0 (0x00d0)
|
||||
#define AFE_MEMIF_MON1 (0x00d4)
|
||||
#define AFE_MEMIF_MON2 (0x00d8)
|
||||
#define AFE_MEMIF_MON3 (0x00dc)
|
||||
#define AFE_MEMIF_MON4 (0x00e0)
|
||||
#define AFE_MEMIF_MON5 (0x00e4)
|
||||
#define AFE_MEMIF_MON6 (0x00e8)
|
||||
#define AFE_MEMIF_MON7 (0x00ec)
|
||||
#define AFE_MEMIF_MON8 (0x00f0)
|
||||
#define AFE_MEMIF_MON9 (0x00f4)
|
||||
#define AFE_MEMIF_MON10 (0x00f8)
|
||||
#define AFE_MEMIF_MON11 (0x00fc)
|
||||
#define AFE_ADDA_DL_SRC2_CON0 (0x0108)
|
||||
#define AFE_ADDA_DL_SRC2_CON1 (0x010c)
|
||||
#define AFE_ADDA_UL_SRC_CON0 (0x0114)
|
||||
#define AFE_ADDA_UL_SRC_CON1 (0x0118)
|
||||
#define AFE_ADDA_TOP_CON0 (0x0120)
|
||||
#define AFE_ADDA_UL_DL_CON0 (0x0124)
|
||||
#define AFE_ADDA_SRC_DEBUG (0x012c)
|
||||
#define AFE_ADDA_SRC_DEBUG_MON0 (0x0130)
|
||||
#define AFE_ADDA_SRC_DEBUG_MON1 (0x0134)
|
||||
#define AFE_ADDA_UL_SRC_MON0 (0x0148)
|
||||
#define AFE_ADDA_UL_SRC_MON1 (0x014c)
|
||||
#define AFE_SRAM_BOUND (0x0170)
|
||||
#define AFE_SECURE_CON (0x0174)
|
||||
#define AFE_SECURE_CONN0 (0x0178)
|
||||
#define AFE_SIDETONE_DEBUG (0x01d0)
|
||||
#define AFE_SIDETONE_MON (0x01d4)
|
||||
#define AFE_SIDETONE_CON0 (0x01e0)
|
||||
#define AFE_SIDETONE_COEFF (0x01e4)
|
||||
#define AFE_SIDETONE_CON1 (0x01e8)
|
||||
#define AFE_SIDETONE_GAIN (0x01ec)
|
||||
#define AFE_SGEN_CON0 (0x01f0)
|
||||
#define AFE_SINEGEN_CON_TDM (0x01f8)
|
||||
#define AFE_SINEGEN_CON_TDM_IN (0x01fc)
|
||||
#define AFE_TOP_CON0 (0x0200)
|
||||
#define AFE_BUS_CFG (0x0240)
|
||||
#define AFE_BUS_MON0 (0x0244)
|
||||
#define AFE_ADDA_PREDIS_CON0 (0x0260)
|
||||
#define AFE_ADDA_PREDIS_CON1 (0x0264)
|
||||
#define AFE_CONN_MON0 (0x0280)
|
||||
#define AFE_CONN_MON1 (0x0284)
|
||||
#define AFE_CONN_MON2 (0x0288)
|
||||
#define AFE_CONN_MON3 (0x028c)
|
||||
#define AFE_ADDA_IIR_COEF_02_01 (0x0290)
|
||||
#define AFE_ADDA_IIR_COEF_04_03 (0x0294)
|
||||
#define AFE_ADDA_IIR_COEF_06_05 (0x0298)
|
||||
#define AFE_ADDA_IIR_COEF_08_07 (0x029c)
|
||||
#define AFE_ADDA_IIR_COEF_10_09 (0x02a0)
|
||||
#define AFE_VUL_D2_BASE (0x0350)
|
||||
#define AFE_VUL_D2_END (0x0358)
|
||||
#define AFE_VUL_D2_CUR (0x035c)
|
||||
#define AFE_HDMI_OUT_CON0 (0x0370)
|
||||
#define AFE_HDMI_OUT_BASE (0x0374)
|
||||
#define AFE_HDMI_OUT_CUR (0x0378)
|
||||
#define AFE_HDMI_OUT_END (0x037c)
|
||||
#define AFE_SPDIF_OUT_CON0 (0x0380)
|
||||
#define AFE_SPDIF_OUT_BASE (0x0384)
|
||||
#define AFE_SPDIF_OUT_CUR (0x0388)
|
||||
#define AFE_SPDIF_OUT_END (0x038c)
|
||||
#define AFE_HDMI_CONN0 (0x0390)
|
||||
#define AFE_HDMI_CONN1 (0x0398)
|
||||
#define AFE_CONN_TDMIN_CON (0x039c)
|
||||
#define AFE_IRQ_MCU_CON (0x03a0)
|
||||
#define AFE_IRQ_MCU_STATUS (0x03a4)
|
||||
#define AFE_IRQ_MCU_CLR (0x03a8)
|
||||
#define AFE_IRQ_MCU_CNT1 (0x03ac)
|
||||
#define AFE_IRQ_MCU_CNT2 (0x03b0)
|
||||
#define AFE_IRQ_MCU_EN (0x03b4)
|
||||
#define AFE_IRQ_MCU_MON2 (0x03b8)
|
||||
#define AFE_IRQ_MCU_CNT5 (0x03bc)
|
||||
#define AFE_IRQ1_MCU_CNT_MON (0x03c0)
|
||||
#define AFE_IRQ2_MCU_CNT_MON (0x03c4)
|
||||
#define AFE_IRQ1_MCU_EN_CNT_MON (0x03c8)
|
||||
#define AFE_IRQ5_MCU_CNT_MON (0x03cc)
|
||||
#define AFE_MEMIF_MINLEN (0x03d0)
|
||||
#define AFE_MEMIF_MAXLEN (0x03d4)
|
||||
#define AFE_MEMIF_PBUF_SIZE (0x03d8)
|
||||
#define AFE_IRQ_MCU_CNT7 (0x03dc)
|
||||
#define AFE_IRQ7_MCU_CNT_MON (0x03e0)
|
||||
#define AFE_MEMIF_PBUF2_SIZE (0x03ec)
|
||||
#define AFE_APLL_TUNER_CFG (0x03f0)
|
||||
#define AFE_APLL_TUNER_CFG1 (0x03f4)
|
||||
#define AFE_IRQ_MCU_CON2 (0x03f8)
|
||||
#define IRQ13_MCU_CNT (0x0408)
|
||||
#define IRQ13_MCU_CNT_MON (0x040c)
|
||||
#define AFE_GAIN1_CON0 (0x0410)
|
||||
#define AFE_GAIN1_CON1 (0x0414)
|
||||
#define AFE_GAIN1_CON2 (0x0418)
|
||||
#define AFE_GAIN1_CON3 (0x041c)
|
||||
#define AFE_GAIN2_CON0 (0x0428)
|
||||
#define AFE_GAIN2_CON1 (0x042c)
|
||||
#define AFE_GAIN2_CON2 (0x0430)
|
||||
#define AFE_GAIN2_CON3 (0x0434)
|
||||
#define AFE_GAIN2_CUR (0x043c)
|
||||
#define AFE_CONN11 (0x0448)
|
||||
#define AFE_CONN12 (0x044c)
|
||||
#define AFE_CONN13 (0x0450)
|
||||
#define AFE_CONN14 (0x0454)
|
||||
#define AFE_CONN15 (0x0458)
|
||||
#define AFE_CONN16 (0x045c)
|
||||
#define AFE_CONN7 (0x0460)
|
||||
#define AFE_CONN8 (0x0464)
|
||||
#define AFE_CONN9 (0x0468)
|
||||
#define AFE_CONN10 (0x046c)
|
||||
#define AFE_CONN21 (0x0470)
|
||||
#define AFE_CONN22 (0x0474)
|
||||
#define AFE_CONN23 (0x0478)
|
||||
#define AFE_CONN24 (0x047c)
|
||||
#define AFE_IEC_CFG (0x0480)
|
||||
#define AFE_IEC_NSNUM (0x0484)
|
||||
#define AFE_IEC_BURST_INFO (0x0488)
|
||||
#define AFE_IEC_BURST_LEN (0x048c)
|
||||
#define AFE_IEC_NSADR (0x0490)
|
||||
#define AFE_CONN_RS (0x0494)
|
||||
#define AFE_CONN_DI (0x0498)
|
||||
#define AFE_IEC_CHL_STAT0 (0x04a0)
|
||||
#define AFE_IEC_CHL_STAT1 (0x04a4)
|
||||
#define AFE_IEC_CHR_STAT0 (0x04a8)
|
||||
#define AFE_IEC_CHR_STAT1 (0x04ac)
|
||||
#define AFE_CONN25 (0x04b0)
|
||||
#define AFE_CONN26 (0x04b4)
|
||||
#define FPGA_CFG2 (0x04b8)
|
||||
#define FPGA_CFG3 (0x04bc)
|
||||
#define FPGA_CFG0 (0x04c0)
|
||||
#define FPGA_CFG1 (0x04c4)
|
||||
#define AFE_SRAM_DELSEL_CON0 (0x04f0)
|
||||
#define AFE_SRAM_DELSEL_CON1 (0x04f4)
|
||||
#define AFE_SRAM_DELSEL_CON2 (0x04f8)
|
||||
#define FPGA_CFG4 (0x04fc)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON0 (0x0500)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON1 (0x0504)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON2 (0x0508)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON3 (0x050c)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON4 (0x0510)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON5 (0x0514)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON6 (0x0518)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON7 (0x051c)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON8 (0x0520)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON9 (0x0524)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON10 (0x0528)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON12 (0x0530)
|
||||
#define AFE_TDM_GASRC4_ASRC_2CH_CON13 (0x0534)
|
||||
#define PCM_INTF_CON2 (0x0538)
|
||||
#define PCM2_INTF_CON (0x053c)
|
||||
#define AFE_APB_MON (0x0540)
|
||||
#define AFE_CONN34 (0x0544)
|
||||
#define AFE_TDM_CON1 (0x0548)
|
||||
#define AFE_TDM_CON2 (0x054c)
|
||||
#define PCM_INTF_CON1 (0x0550)
|
||||
#define AFE_SECURE_MASK_CONN47_1 (0x0554)
|
||||
#define AFE_SECURE_MASK_CONN48_1 (0x0558)
|
||||
#define AFE_SECURE_MASK_CONN49_1 (0x055c)
|
||||
#define AFE_SECURE_MASK_CONN50_1 (0x0560)
|
||||
#define AFE_SECURE_MASK_CONN51_1 (0x0564)
|
||||
#define AFE_SECURE_MASK_CONN52_1 (0x0568)
|
||||
#define AFE_SECURE_MASK_CONN53_1 (0x056c)
|
||||
#define AFE_SE_SECURE_CON (0x0570)
|
||||
#define AFE_TDM_IN_CON1 (0x0588)
|
||||
#define AFE_TDM_IN_CON2 (0x058c)
|
||||
#define AFE_TDM_IN_MON1 (0x0590)
|
||||
#define AFE_TDM_IN_MON2 (0x0594)
|
||||
#define AFE_TDM_IN_MON3 (0x0598)
|
||||
#define AFE_DMIC0_UL_SRC_CON0 (0x05b4)
|
||||
#define AFE_DMIC0_UL_SRC_CON1 (0x05b8)
|
||||
#define AFE_DMIC0_SRC_DEBUG (0x05bc)
|
||||
#define AFE_DMIC0_SRC_DEBUG_MON0 (0x05c0)
|
||||
#define AFE_DMIC0_UL_SRC_MON0 (0x05c8)
|
||||
#define AFE_DMIC0_UL_SRC_MON1 (0x05cc)
|
||||
#define AFE_DMIC0_IIR_COEF_02_01 (0x05d0)
|
||||
#define AFE_DMIC0_IIR_COEF_04_03 (0x05d4)
|
||||
#define AFE_DMIC0_IIR_COEF_06_05 (0x05d8)
|
||||
#define AFE_DMIC0_IIR_COEF_08_07 (0x05dc)
|
||||
#define AFE_DMIC0_IIR_COEF_10_09 (0x05e0)
|
||||
#define AFE_DMIC1_UL_SRC_CON0 (0x0620)
|
||||
#define AFE_DMIC1_UL_SRC_CON1 (0x0624)
|
||||
#define AFE_DMIC1_SRC_DEBUG (0x0628)
|
||||
#define AFE_DMIC1_SRC_DEBUG_MON0 (0x062c)
|
||||
#define AFE_DMIC1_UL_SRC_MON0 (0x0634)
|
||||
#define AFE_DMIC1_UL_SRC_MON1 (0x0638)
|
||||
#define AFE_DMIC1_IIR_COEF_02_01 (0x063c)
|
||||
#define AFE_DMIC1_IIR_COEF_04_03 (0x0640)
|
||||
#define AFE_DMIC1_IIR_COEF_06_05 (0x0644)
|
||||
#define AFE_DMIC1_IIR_COEF_08_07 (0x0648)
|
||||
#define AFE_DMIC1_IIR_COEF_10_09 (0x064c)
|
||||
#define AFE_SECURE_MASK_CONN39_1 (0x068c)
|
||||
#define AFE_SECURE_MASK_CONN40_1 (0x0690)
|
||||
#define AFE_SECURE_MASK_CONN41_1 (0x0694)
|
||||
#define AFE_SECURE_MASK_CONN42_1 (0x0698)
|
||||
#define AFE_SECURE_MASK_CONN43_1 (0x069c)
|
||||
#define AFE_SECURE_MASK_CONN44_1 (0x06a0)
|
||||
#define AFE_SECURE_MASK_CONN45_1 (0x06a4)
|
||||
#define AFE_SECURE_MASK_CONN46_1 (0x06a8)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON0 (0x06c0)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON1 (0x06c4)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON2 (0x06c8)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON3 (0x06cc)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON4 (0x06d0)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON5 (0x06d4)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON6 (0x06d8)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON7 (0x06dc)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON8 (0x06e0)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON9 (0x06e4)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON10 (0x06e8)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON12 (0x06f0)
|
||||
#define AFE_TDM_GASRC1_ASRC_2CH_CON13 (0x06f4)
|
||||
#define AFE_TDM_ASRC_CON0 (0x06f8)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON0 (0x0700)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON1 (0x0704)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON2 (0x0708)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON3 (0x070c)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON4 (0x0710)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON5 (0x0714)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON6 (0x0718)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON7 (0x071c)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON8 (0x0720)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON9 (0x0724)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON10 (0x0728)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON12 (0x0730)
|
||||
#define AFE_TDM_GASRC2_ASRC_2CH_CON13 (0x0734)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON0 (0x0740)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON1 (0x0744)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON2 (0x0748)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON3 (0x074c)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON4 (0x0750)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON5 (0x0754)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON6 (0x0758)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON7 (0x075c)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON8 (0x0760)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON9 (0x0764)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON10 (0x0768)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON12 (0x0770)
|
||||
#define AFE_TDM_GASRC3_ASRC_2CH_CON13 (0x0774)
|
||||
#define AFE_DMIC2_UL_SRC_CON0 (0x0780)
|
||||
#define AFE_DMIC2_UL_SRC_CON1 (0x0784)
|
||||
#define AFE_DMIC2_SRC_DEBUG (0x0788)
|
||||
#define AFE_DMIC2_SRC_DEBUG_MON0 (0x078c)
|
||||
#define AFE_DMIC2_UL_SRC_MON0 (0x0794)
|
||||
#define AFE_DMIC2_UL_SRC_MON1 (0x0798)
|
||||
#define AFE_DMIC2_IIR_COEF_02_01 (0x079c)
|
||||
#define AFE_DMIC2_IIR_COEF_04_03 (0x07a0)
|
||||
#define AFE_DMIC2_IIR_COEF_06_05 (0x07a4)
|
||||
#define AFE_DMIC2_IIR_COEF_08_07 (0x07a8)
|
||||
#define AFE_DMIC2_IIR_COEF_10_09 (0x07ac)
|
||||
#define AFE_DMIC3_UL_SRC_CON0 (0x07ec)
|
||||
#define AFE_DMIC3_UL_SRC_CON1 (0x07f0)
|
||||
#define AFE_DMIC3_SRC_DEBUG (0x07f4)
|
||||
#define AFE_DMIC3_SRC_DEBUG_MON0 (0x07f8)
|
||||
#define AFE_DMIC3_UL_SRC_MON0 (0x0800)
|
||||
#define AFE_DMIC3_UL_SRC_MON1 (0x0804)
|
||||
#define AFE_DMIC3_IIR_COEF_02_01 (0x0808)
|
||||
#define AFE_DMIC3_IIR_COEF_04_03 (0x080c)
|
||||
#define AFE_DMIC3_IIR_COEF_06_05 (0x0810)
|
||||
#define AFE_DMIC3_IIR_COEF_08_07 (0x0814)
|
||||
#define AFE_DMIC3_IIR_COEF_10_09 (0x0818)
|
||||
#define AFE_SECURE_MASK_CONN25_1 (0x0858)
|
||||
#define AFE_SECURE_MASK_CONN26_1 (0x085c)
|
||||
#define AFE_SECURE_MASK_CONN27_1 (0x0860)
|
||||
#define AFE_SECURE_MASK_CONN28_1 (0x0864)
|
||||
#define AFE_SECURE_MASK_CONN29_1 (0x0868)
|
||||
#define AFE_SECURE_MASK_CONN30_1 (0x086c)
|
||||
#define AFE_SECURE_MASK_CONN31_1 (0x0870)
|
||||
#define AFE_SECURE_MASK_CONN32_1 (0x0874)
|
||||
#define AFE_SECURE_MASK_CONN33_1 (0x0878)
|
||||
#define AFE_SECURE_MASK_CONN34_1 (0x087c)
|
||||
#define AFE_SECURE_MASK_CONN35_1 (0x0880)
|
||||
#define AFE_SECURE_MASK_CONN36_1 (0x0884)
|
||||
#define AFE_SECURE_MASK_CONN37_1 (0x0888)
|
||||
#define AFE_SECURE_MASK_CONN38_1 (0x088c)
|
||||
#define AFE_IRQ_MCU_SCP_EN (0x0890)
|
||||
#define AFE_IRQ_MCU_DSP_EN (0x0894)
|
||||
#define AFE_IRQ3_MCU_CNT_MON (0x0898)
|
||||
#define AFE_IRQ4_MCU_CNT_MON (0x089c)
|
||||
#define AFE_IRQ8_MCU_CNT_MON (0x08a0)
|
||||
#define AFE_IRQ_MCU_CNT3 (0x08a4)
|
||||
#define AFE_IRQ_MCU_CNT4 (0x08a8)
|
||||
#define AFE_IRQ_MCU_CNT8 (0x08ac)
|
||||
#define AFE_IRQ_MCU_CNT11 (0x08b0)
|
||||
#define AFE_IRQ_MCU_CNT12 (0x08b4)
|
||||
#define AFE_IRQ11_MCU_CNT_MON (0x08b8)
|
||||
#define AFE_IRQ12_MCU_CNT_MON (0x08bc)
|
||||
#define AFE_VUL3_BASE (0x08c0)
|
||||
#define AFE_VUL3_CUR (0x08c4)
|
||||
#define AFE_VUL3_END (0x08c8)
|
||||
#define AFE_VUL3_BASE_MSB (0x08d0)
|
||||
#define AFE_VUL3_END_MSB (0x08d4)
|
||||
#define AFE_IRQ10_MCU_CNT_MON (0x08d8)
|
||||
#define AFE_IRQ_MCU_CNT10 (0x08dc)
|
||||
#define AFE_IRQ_ACC1_CNT (0x08e0)
|
||||
#define AFE_IRQ_ACC2_CNT (0x08e4)
|
||||
#define AFE_IRQ_ACC1_CNT_MON1 (0x08e8)
|
||||
#define AFE_IRQ_ACC2_CNT_MON (0x08ec)
|
||||
#define AFE_TSF_CON (0x08f0)
|
||||
#define AFE_TSF_MON (0x08f4)
|
||||
#define AFE_IRQ_ACC1_CNT_MON2 (0x08f8)
|
||||
#define AFE_SPDIFIN_CFG0 (0x0900)
|
||||
#define AFE_SPDIFIN_CFG1 (0x0904)
|
||||
#define AFE_SPDIFIN_CHSTS1 (0x0908)
|
||||
#define AFE_SPDIFIN_CHSTS2 (0x090c)
|
||||
#define AFE_SPDIFIN_CHSTS3 (0x0910)
|
||||
#define AFE_SPDIFIN_CHSTS4 (0x0914)
|
||||
#define AFE_SPDIFIN_CHSTS5 (0x0918)
|
||||
#define AFE_SPDIFIN_CHSTS6 (0x091c)
|
||||
#define AFE_SPDIFIN_DEBUG1 (0x0920)
|
||||
#define AFE_SPDIFIN_DEBUG2 (0x0924)
|
||||
#define AFE_SPDIFIN_DEBUG3 (0x0928)
|
||||
#define AFE_SPDIFIN_DEBUG4 (0x092c)
|
||||
#define AFE_SPDIFIN_EC (0x0930)
|
||||
#define AFE_SPDIFIN_CKLOCK_CFG (0x0934)
|
||||
#define AFE_SPDIFIN_BR (0x093c)
|
||||
#define AFE_SPDIFIN_BR_DBG1 (0x0940)
|
||||
#define AFE_SPDIFIN_INT_EXT (0x0948)
|
||||
#define AFE_SPDIFIN_INT_EXT2 (0x094c)
|
||||
#define SPDIFIN_FREQ_INFO (0x0950)
|
||||
#define SPDIFIN_FREQ_INFO_2 (0x0954)
|
||||
#define SPDIFIN_FREQ_INFO_3 (0x0958)
|
||||
#define SPDIFIN_FREQ_STATUS (0x095c)
|
||||
#define SPDIFIN_USERCODE1 (0x0960)
|
||||
#define SPDIFIN_USERCODE2 (0x0964)
|
||||
#define SPDIFIN_USERCODE3 (0x0968)
|
||||
#define SPDIFIN_USERCODE4 (0x096c)
|
||||
#define SPDIFIN_USERCODE5 (0x0970)
|
||||
#define SPDIFIN_USERCODE6 (0x0974)
|
||||
#define SPDIFIN_USERCODE7 (0x0978)
|
||||
#define SPDIFIN_USERCODE8 (0x097c)
|
||||
#define SPDIFIN_USERCODE9 (0x0980)
|
||||
#define SPDIFIN_USERCODE10 (0x0984)
|
||||
#define SPDIFIN_USERCODE11 (0x0988)
|
||||
#define SPDIFIN_USERCODE12 (0x098c)
|
||||
#define SPDIFIN_MEMIF_CON0 (0x0990)
|
||||
#define SPDIFIN_BASE_ADR (0x0994)
|
||||
#define SPDIFIN_END_ADR (0x0998)
|
||||
#define SPDIFIN_APLL_TUNER_CFG (0x09a0)
|
||||
#define SPDIFIN_APLL_TUNER_CFG1 (0x09a4)
|
||||
#define SPDIFIN_APLL2_TUNER_CFG (0x09a8)
|
||||
#define SPDIFIN_APLL2_TUNER_CFG1 (0x09ac)
|
||||
#define SPDIFIN_TYPE_DET (0x09b0)
|
||||
#define MPHONE_MULTI_CON0 (0x09b4)
|
||||
#define SPDIFIN_CUR_ADR (0x09b8)
|
||||
#define AFE_SINEGEN_CON_SPDIFIN (0x09bc)
|
||||
#define AFE_HDMI_IN_2CH_CON0 (0x09c0)
|
||||
#define AFE_HDMI_IN_2CH_BASE (0x09c4)
|
||||
#define AFE_HDMI_IN_2CH_END (0x09c8)
|
||||
#define AFE_HDMI_IN_2CH_CUR (0x09cc)
|
||||
#define AFE_MEMIF_BUF_MON0 (0x09d0)
|
||||
#define AFE_MEMIF_BUF_MON1 (0x09d4)
|
||||
#define AFE_MEMIF_BUF_MON2 (0x09d8)
|
||||
#define AFE_MEMIF_BUF_MON3 (0x09dc)
|
||||
#define AFE_MEMIF_BUF_MON6 (0x09e8)
|
||||
#define AFE_MEMIF_BUF_MON7 (0x09ec)
|
||||
#define AFE_MEMIF_BUF_MON8 (0x09f0)
|
||||
#define AFE_MEMIF_BUF_MON10 (0x09f8)
|
||||
#define AFE_MEMIF_BUF_MON11 (0x09fc)
|
||||
#define SYSTOP_STC_CONFIG (0x0a00)
|
||||
#define AUDIO_STC_STATUS (0x0a04)
|
||||
#define SYSTOP_W_STC_H (0x0a08)
|
||||
#define SYSTOP_W_STC_L (0x0a0c)
|
||||
#define SYSTOP_R_STC_H (0x0a10)
|
||||
#define SYSTOP_R_STC_L (0x0a14)
|
||||
#define AUDIO_W_STC_H (0x0a18)
|
||||
#define AUDIO_W_STC_L (0x0a1c)
|
||||
#define AUDIO_R_STC_H (0x0a20)
|
||||
#define AUDIO_R_STC_L (0x0a24)
|
||||
#define SYSTOP_W_STC2_H (0x0a28)
|
||||
#define SYSTOP_W_STC2_L (0x0a2c)
|
||||
#define SYSTOP_R_STC2_H (0x0a30)
|
||||
#define SYSTOP_R_STC2_L (0x0a34)
|
||||
#define AUDIO_W_STC2_H (0x0a38)
|
||||
#define AUDIO_W_STC2_L (0x0a3c)
|
||||
#define AUDIO_R_STC2_H (0x0a40)
|
||||
#define AUDIO_R_STC2_L (0x0a44)
|
||||
|
||||
#define AFE_CONN17 (0x0a48)
|
||||
#define AFE_CONN18 (0x0a4c)
|
||||
#define AFE_CONN19 (0x0a50)
|
||||
#define AFE_CONN20 (0x0a54)
|
||||
#define AFE_CONN27 (0x0a58)
|
||||
#define AFE_CONN28 (0x0a5c)
|
||||
#define AFE_CONN29 (0x0a60)
|
||||
#define AFE_CONN30 (0x0a64)
|
||||
#define AFE_CONN31 (0x0a68)
|
||||
#define AFE_CONN32 (0x0a6c)
|
||||
#define AFE_CONN33 (0x0a70)
|
||||
#define AFE_CONN35 (0x0a74)
|
||||
#define AFE_CONN36 (0x0a78)
|
||||
#define AFE_CONN37 (0x0a7c)
|
||||
#define AFE_CONN38 (0x0a80)
|
||||
#define AFE_CONN39 (0x0a84)
|
||||
#define AFE_CONN40 (0x0a88)
|
||||
#define AFE_CONN41 (0x0a8c)
|
||||
#define AFE_CONN42 (0x0a90)
|
||||
#define AFE_CONN44 (0x0a94)
|
||||
#define AFE_CONN45 (0x0a98)
|
||||
#define AFE_CONN46 (0x0a9c)
|
||||
#define AFE_CONN47 (0x0aa0)
|
||||
#define AFE_CONN_24BIT (0x0aa4)
|
||||
#define AFE_CONN0_1 (0x0aa8)
|
||||
#define AFE_CONN1_1 (0x0aac)
|
||||
#define AFE_CONN2_1 (0x0ab0)
|
||||
#define AFE_CONN3_1 (0x0ab4)
|
||||
#define AFE_CONN4_1 (0x0ab8)
|
||||
#define AFE_CONN5_1 (0x0abc)
|
||||
#define AFE_CONN6_1 (0x0ac0)
|
||||
#define AFE_CONN7_1 (0x0ac4)
|
||||
#define AFE_CONN8_1 (0x0ac8)
|
||||
#define AFE_CONN9_1 (0x0acc)
|
||||
#define AFE_CONN10_1 (0x0ad0)
|
||||
#define AFE_CONN11_1 (0x0ad4)
|
||||
#define AFE_CONN12_1 (0x0ad8)
|
||||
#define AFE_CONN13_1 (0x0adc)
|
||||
#define AFE_CONN14_1 (0x0ae0)
|
||||
#define AFE_CONN15_1 (0x0ae4)
|
||||
#define AFE_CONN16_1 (0x0ae8)
|
||||
#define AFE_CONN17_1 (0x0aec)
|
||||
#define AFE_CONN18_1 (0x0af0)
|
||||
#define AFE_CONN19_1 (0x0af4)
|
||||
#define AFE_CONN43 (0x0af8)
|
||||
#define AFE_CONN43_1 (0x0afc)
|
||||
#define AFE_CONN21_1 (0x0b00)
|
||||
#define AFE_CONN22_1 (0x0b04)
|
||||
#define AFE_CONN23_1 (0x0b08)
|
||||
#define AFE_CONN24_1 (0x0b0c)
|
||||
#define AFE_CONN25_1 (0x0b10)
|
||||
#define AFE_CONN26_1 (0x0b14)
|
||||
#define AFE_CONN27_1 (0x0b18)
|
||||
#define AFE_CONN28_1 (0x0b1c)
|
||||
#define AFE_CONN29_1 (0x0b20)
|
||||
#define AFE_CONN30_1 (0x0b24)
|
||||
#define AFE_CONN31_1 (0x0b28)
|
||||
#define AFE_CONN32_1 (0x0b2c)
|
||||
#define AFE_CONN33_1 (0x0b30)
|
||||
#define AFE_CONN34_1 (0x0b34)
|
||||
#define AFE_CONN35_1 (0x0b38)
|
||||
#define AFE_CONN36_1 (0x0b3c)
|
||||
#define AFE_CONN37_1 (0x0b40)
|
||||
#define AFE_CONN38_1 (0x0b44)
|
||||
#define AFE_CONN39_1 (0x0b48)
|
||||
#define AFE_CONN40_1 (0x0b4c)
|
||||
#define AFE_CONN41_1 (0x0b50)
|
||||
#define AFE_CONN42_1 (0x0b54)
|
||||
#define AFE_CONN44_1 (0x0b58)
|
||||
#define AFE_CONN45_1 (0x0b5c)
|
||||
#define AFE_CONN46_1 (0x0b60)
|
||||
#define AFE_CONN47_1 (0x0b64)
|
||||
#define AFE_CONN_RS_1 (0x0b68)
|
||||
#define AFE_CONN_DI_1 (0x0b6c)
|
||||
#define AFE_CONN_24BIT_1 (0x0b70)
|
||||
#define AFE_GAIN1_CUR (0x0b78)
|
||||
#define AFE_CONN20_1 (0x0b7c)
|
||||
#define AFE_DL1_BASE_MSB (0x0b80)
|
||||
#define AFE_DL1_END_MSB (0x0b84)
|
||||
#define AFE_DL2_BASE_MSB (0x0b88)
|
||||
#define AFE_DL2_END_MSB (0x0b8c)
|
||||
#define AFE_AWB_BASE_MSB (0x0b90)
|
||||
#define AFE_AWB_END_MSB (0x0b94)
|
||||
#define AFE_VUL_BASE_MSB (0x0ba0)
|
||||
#define AFE_VUL_END_MSB (0x0ba4)
|
||||
#define AFE_VUL_D2_BASE_MSB (0x0ba8)
|
||||
#define AFE_VUL_D2_END_MSB (0x0bac)
|
||||
#define AFE_HDMI_OUT_BASE_MSB (0x0bb8)
|
||||
#define AFE_HDMI_OUT_END_MSB (0x0bbc)
|
||||
#define AFE_HDMI_IN_2CH_BASE_MSB (0x0bc0)
|
||||
#define AFE_HDMI_IN_2CH_END_MSB (0x0bc4)
|
||||
#define AFE_SPDIF_OUT_BASE_MSB (0x0bc8)
|
||||
#define AFE_SPDIF_OUT_END_MSB (0x0bcc)
|
||||
#define SPDIFIN_BASE_MSB (0x0bd0)
|
||||
#define SPDIFIN_END_MSB (0x0bd4)
|
||||
#define AFE_DL1_CUR_MSB (0x0bd8)
|
||||
#define AFE_DL2_CUR_MSB (0x0bdc)
|
||||
#define AFE_AWB_CUR_MSB (0x0be8)
|
||||
#define AFE_VUL_CUR_MSB (0x0bf8)
|
||||
#define AFE_VUL_D2_CUR_MSB (0x0c04)
|
||||
#define AFE_HDMI_OUT_CUR_MSB (0x0c0c)
|
||||
#define AFE_HDMI_IN_2CH_CUR_MSB (0x0c10)
|
||||
#define AFE_SPDIF_OUT_CUR_MSB (0x0c14)
|
||||
#define SPDIFIN_CUR_MSB (0x0c18)
|
||||
#define AFE_CONN_REG (0x0c20)
|
||||
#define AFE_SECURE_MASK_CONN14_1 (0x0c24)
|
||||
#define AFE_SECURE_MASK_CONN15_1 (0x0c28)
|
||||
#define AFE_SECURE_MASK_CONN16_1 (0x0c2c)
|
||||
#define AFE_SECURE_MASK_CONN17_1 (0x0c30)
|
||||
#define AFE_SECURE_MASK_CONN18_1 (0x0c34)
|
||||
#define AFE_SECURE_MASK_CONN19_1 (0x0c38)
|
||||
#define AFE_SECURE_MASK_CONN20_1 (0x0c3c)
|
||||
#define AFE_SECURE_MASK_CONN21_1 (0x0c40)
|
||||
#define AFE_SECURE_MASK_CONN22_1 (0x0c44)
|
||||
#define AFE_SECURE_MASK_CONN23_1 (0x0c48)
|
||||
#define AFE_SECURE_MASK_CONN24_1 (0x0c4c)
|
||||
#define AFE_ADDA_DL_SDM_DCCOMP_CON (0x0c50)
|
||||
#define AFE_ADDA_DL_SDM_TEST (0x0c54)
|
||||
#define AFE_ADDA_DL_DC_COMP_CFG0 (0x0c58)
|
||||
#define AFE_ADDA_DL_DC_COMP_CFG1 (0x0c5c)
|
||||
#define AFE_ADDA_DL_SDM_FIFO_MON (0x0c60)
|
||||
#define AFE_ADDA_DL_SRC_LCH_MON (0x0c64)
|
||||
#define AFE_ADDA_DL_SRC_RCH_MON (0x0c68)
|
||||
#define AFE_ADDA_DL_SDM_OUT_MON (0x0c6c)
|
||||
#define AFE_ADDA_DL_SDM_DITHER_CON (0x0c70)
|
||||
|
||||
#define AFE_VUL3_CUR_MSB (0x0c78)
|
||||
#define AFE_ASRC_2CH_CON0 (0x0c80)
|
||||
#define AFE_ASRC_2CH_CON1 (0x0c84)
|
||||
#define AFE_ASRC_2CH_CON2 (0x0c88)
|
||||
#define AFE_ASRC_2CH_CON3 (0x0c8c)
|
||||
#define AFE_ASRC_2CH_CON4 (0x0c90)
|
||||
#define AFE_ASRC_2CH_CON5 (0x0c94)
|
||||
#define AFE_ASRC_2CH_CON6 (0x0c98)
|
||||
#define AFE_ASRC_2CH_CON7 (0x0c9c)
|
||||
#define AFE_ASRC_2CH_CON8 (0x0ca0)
|
||||
#define AFE_ASRC_2CH_CON9 (0x0ca4)
|
||||
#define AFE_ASRC_2CH_CON10 (0x0ca8)
|
||||
#define AFE_ASRC_2CH_CON12 (0x0cb0)
|
||||
#define AFE_ASRC_2CH_CON13 (0x0cb4)
|
||||
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON0 (0x0cc0)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON1 (0x0cc4)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON2 (0x0cc8)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON3 (0x0ccc)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON4 (0x0cd0)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON5 (0x0cd4)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON6 (0x0cd8)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON7 (0x0cdc)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON8 (0x0ce0)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON9 (0x0ce4)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON10 (0x0ce8)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON12 (0x0cf0)
|
||||
#define AFE_PCM_TX_ASRC_2CH_CON13 (0x0cf4)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON0 (0x0d00)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON1 (0x0d04)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON2 (0x0d08)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON3 (0x0d0c)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON4 (0x0d10)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON5 (0x0d14)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON6 (0x0d18)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON7 (0x0d1c)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON8 (0x0d20)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON9 (0x0d24)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON10 (0x0d28)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON12 (0x0d30)
|
||||
#define AFE_PCM_RX_ASRC_2CH_CON13 (0x0d34)
|
||||
|
||||
#define AFE_ADDA_PREDIS_CON2 (0x0d40)
|
||||
#define AFE_ADDA_PREDIS_CON3 (0x0d44)
|
||||
#define AFE_SECURE_MASK_CONN4_1 (0x0d48)
|
||||
#define AFE_SECURE_MASK_CONN5_1 (0x0d4c)
|
||||
#define AFE_SECURE_MASK_CONN6_1 (0x0d50)
|
||||
#define AFE_SECURE_MASK_CONN7_1 (0x0d54)
|
||||
#define AFE_SECURE_MASK_CONN8_1 (0x0d58)
|
||||
#define AFE_SECURE_MASK_CONN9_1 (0x0d5c)
|
||||
#define AFE_SECURE_MASK_CONN10_1 (0x0d60)
|
||||
#define AFE_SECURE_MASK_CONN11_1 (0x0d64)
|
||||
#define AFE_SECURE_MASK_CONN12_1 (0x0d68)
|
||||
#define AFE_SECURE_MASK_CONN13_1 (0x0d6c)
|
||||
#define AFE_MEMIF_MON12 (0x0d70)
|
||||
#define AFE_MEMIF_MON13 (0x0d74)
|
||||
#define AFE_MEMIF_MON14 (0x0d78)
|
||||
#define AFE_MEMIF_MON15 (0x0d7c)
|
||||
#define AFE_SECURE_MASK_CONN42 (0x0dbc)
|
||||
#define AFE_SECURE_MASK_CONN43 (0x0dc0)
|
||||
#define AFE_SECURE_MASK_CONN44 (0x0dc4)
|
||||
#define AFE_SECURE_MASK_CONN45 (0x0dc8)
|
||||
#define AFE_SECURE_MASK_CONN46 (0x0dcc)
|
||||
#define AFE_HD_ENGEN_ENABLE (0x0dd0)
|
||||
#define AFE_SECURE_MASK_CONN47 (0x0dd4)
|
||||
#define AFE_SECURE_MASK_CONN48 (0x0dd8)
|
||||
#define AFE_SECURE_MASK_CONN49 (0x0ddc)
|
||||
#define AFE_SECURE_MASK_CONN50 (0x0de0)
|
||||
#define AFE_SECURE_MASK_CONN51 (0x0de4)
|
||||
#define AFE_SECURE_MASK_CONN52 (0x0de8)
|
||||
#define AFE_SECURE_MASK_CONN53 (0x0dec)
|
||||
#define AFE_SECURE_MASK_CONN0_1 (0x0df0)
|
||||
#define AFE_SECURE_MASK_CONN1_1 (0x0df4)
|
||||
#define AFE_SECURE_MASK_CONN2_1 (0x0df8)
|
||||
#define AFE_SECURE_MASK_CONN3_1 (0x0dfc)
|
||||
|
||||
#define AFE_ADDA_MTKAIF_CFG0 (0x0e00)
|
||||
#define AFE_ADDA_MTKAIF_SYNCWORD_CFG (0x0e14)
|
||||
#define AFE_ADDA_MTKAIF_RX_CFG0 (0x0e20)
|
||||
#define AFE_ADDA_MTKAIF_RX_CFG1 (0x0e24)
|
||||
#define AFE_ADDA_MTKAIF_RX_CFG2 (0x0e28)
|
||||
#define AFE_ADDA_MTKAIF_MON0 (0x0e34)
|
||||
#define AFE_ADDA_MTKAIF_MON1 (0x0e38)
|
||||
#define AFE_AUD_PAD_TOP (0x0e40)
|
||||
|
||||
#define AFE_CM1_CON4 (0x0e48)
|
||||
#define AFE_CM2_CON4 (0x0e4c)
|
||||
#define AFE_CM1_CON0 (0x0e50)
|
||||
#define AFE_CM1_CON1 (0x0e54)
|
||||
#define AFE_CM1_CON2 (0x0e58)
|
||||
#define AFE_CM1_CON3 (0x0e5c)
|
||||
#define AFE_CM2_CON0 (0x0e60)
|
||||
#define AFE_CM2_CON1 (0x0e64)
|
||||
#define AFE_CM2_CON2 (0x0e68)
|
||||
#define AFE_CM2_CON3 (0x0e6c)
|
||||
#define AFE_CM2_CONN0 (0x0e70)
|
||||
#define AFE_CM2_CONN1 (0x0e74)
|
||||
#define AFE_CM2_CONN2 (0x0e78)
|
||||
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON0 (0x0e80)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON1 (0x0e84)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON2 (0x0e88)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON3 (0x0e8c)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON4 (0x0e90)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON5 (0x0e94)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON6 (0x0e98)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON7 (0x0e9c)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON8 (0x0ea0)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON9 (0x0ea4)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON10 (0x0ea8)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON12 (0x0eb0)
|
||||
#define AFE_GENERAL1_ASRC_2CH_CON13 (0x0eb4)
|
||||
#define GENERAL_ASRC_MODE (0x0eb8)
|
||||
#define GENERAL_ASRC_EN_ON (0x0ebc)
|
||||
|
||||
#define AFE_CONN48 (0x0ec0)
|
||||
#define AFE_CONN49 (0x0ec4)
|
||||
#define AFE_CONN50 (0x0ec8)
|
||||
#define AFE_CONN51 (0x0ecc)
|
||||
#define AFE_CONN52 (0x0ed0)
|
||||
#define AFE_CONN53 (0x0ed4)
|
||||
#define AFE_CONN48_1 (0x0ee0)
|
||||
#define AFE_CONN49_1 (0x0ee4)
|
||||
#define AFE_CONN50_1 (0x0ee8)
|
||||
#define AFE_CONN51_1 (0x0eec)
|
||||
#define AFE_CONN52_1 (0x0ef0)
|
||||
#define AFE_CONN53_1 (0x0ef4)
|
||||
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON0 (0x0f00)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON1 (0x0f04)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON2 (0x0f08)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON3 (0x0f0c)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON4 (0x0f10)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON5 (0x0f14)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON6 (0x0f18)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON7 (0x0f1c)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON8 (0x0f20)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON9 (0x0f24)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON10 (0x0f28)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON12 (0x0f30)
|
||||
#define AFE_GENERAL2_ASRC_2CH_CON13 (0x0f34)
|
||||
|
||||
#define AFE_SECURE_MASK_CONN28 (0x0f48)
|
||||
#define AFE_SECURE_MASK_CONN29 (0x0f4c)
|
||||
#define AFE_SECURE_MASK_CONN30 (0x0f50)
|
||||
#define AFE_SECURE_MASK_CONN31 (0x0f54)
|
||||
#define AFE_SECURE_MASK_CONN32 (0x0f58)
|
||||
#define AFE_SECURE_MASK_CONN33 (0x0f5c)
|
||||
#define AFE_SECURE_MASK_CONN34 (0x0f60)
|
||||
#define AFE_SECURE_MASK_CONN35 (0x0f64)
|
||||
#define AFE_SECURE_MASK_CONN36 (0x0f68)
|
||||
#define AFE_SECURE_MASK_CONN37 (0x0f6c)
|
||||
#define AFE_SECURE_MASK_CONN38 (0x0f70)
|
||||
#define AFE_SECURE_MASK_CONN39 (0x0f74)
|
||||
#define AFE_SECURE_MASK_CONN40 (0x0f78)
|
||||
#define AFE_SECURE_MASK_CONN41 (0x0f7c)
|
||||
#define AFE_SIDEBAND0 (0x0f80)
|
||||
#define AFE_SIDEBAND1 (0x0f84)
|
||||
#define AFE_SECURE_SIDEBAND0 (0x0f88)
|
||||
#define AFE_SECURE_SIDEBAND1 (0x0f8c)
|
||||
#define AFE_SECURE_MASK_CONN0 (0x0f90)
|
||||
#define AFE_SECURE_MASK_CONN1 (0x0f94)
|
||||
#define AFE_SECURE_MASK_CONN2 (0x0f98)
|
||||
#define AFE_SECURE_MASK_CONN3 (0x0f9c)
|
||||
#define AFE_SECURE_MASK_CONN4 (0x0fa0)
|
||||
#define AFE_SECURE_MASK_CONN5 (0x0fa4)
|
||||
#define AFE_SECURE_MASK_CONN6 (0x0fa8)
|
||||
#define AFE_SECURE_MASK_CONN7 (0x0fac)
|
||||
#define AFE_SECURE_MASK_CONN8 (0x0fb0)
|
||||
#define AFE_SECURE_MASK_CONN9 (0x0fb4)
|
||||
#define AFE_SECURE_MASK_CONN10 (0x0fb8)
|
||||
#define AFE_SECURE_MASK_CONN11 (0x0fbc)
|
||||
#define AFE_SECURE_MASK_CONN12 (0x0fc0)
|
||||
#define AFE_SECURE_MASK_CONN13 (0x0fc4)
|
||||
#define AFE_SECURE_MASK_CONN14 (0x0fc8)
|
||||
#define AFE_SECURE_MASK_CONN15 (0x0fcc)
|
||||
#define AFE_SECURE_MASK_CONN16 (0x0fd0)
|
||||
#define AFE_SECURE_MASK_CONN17 (0x0fd4)
|
||||
#define AFE_SECURE_MASK_CONN18 (0x0fd8)
|
||||
#define AFE_SECURE_MASK_CONN19 (0x0fdc)
|
||||
#define AFE_SECURE_MASK_CONN20 (0x0fe0)
|
||||
#define AFE_SECURE_MASK_CONN21 (0x0fe4)
|
||||
#define AFE_SECURE_MASK_CONN22 (0x0fe8)
|
||||
#define AFE_SECURE_MASK_CONN23 (0x0fec)
|
||||
#define AFE_SECURE_MASK_CONN24 (0x0ff0)
|
||||
#define AFE_SECURE_MASK_CONN25 (0x0ff4)
|
||||
#define AFE_SECURE_MASK_CONN26 (0x0ff8)
|
||||
#define AFE_SECURE_MASK_CONN27 (0x0ffc)
|
||||
|
||||
#define MAX_REGISTER AFE_SECURE_MASK_CONN27
|
||||
|
||||
#define AFE_IRQ_STATUS_BITS 0x3ff
|
||||
|
||||
/* AUDIO_TOP_CON0 (0x0000) */
|
||||
#define AUD_TCON0_PDN_TML BIT(27)
|
||||
#define AUD_TCON0_PDN_DAC_PREDIS BIT(26)
|
||||
#define AUD_TCON0_PDN_DAC BIT(25)
|
||||
#define AUD_TCON0_PDN_ADC BIT(24)
|
||||
#define AUD_TCON0_PDN_TDM_IN BIT(23)
|
||||
#define AUD_TCON0_PDN_TDM_OUT BIT(22)
|
||||
#define AUD_TCON0_PDN_SPDIF BIT(21)
|
||||
#define AUD_TCON0_PDN_APLL_TUNER BIT(19)
|
||||
#define AUD_TCON0_PDN_APLL2_TUNER BIT(18)
|
||||
#define AUD_TCON0_PDN_INTDIR BIT(15)
|
||||
#define AUD_TCON0_PDN_24M BIT(9)
|
||||
#define AUD_TCON0_PDN_22M BIT(8)
|
||||
#define AUD_TCON0_PDN_I2S_IN BIT(6)
|
||||
#define AUD_TCON0_PDN_AFE BIT(2)
|
||||
|
||||
/* AUDIO_TOP_CON1 (0x0004) */
|
||||
#define AUD_TCON1_PDN_TDM_ASRC BIT(15)
|
||||
#define AUD_TCON1_PDN_GENERAL2_ASRC BIT(14)
|
||||
#define AUD_TCON1_PDN_GENERAL1_ASRC BIT(13)
|
||||
#define AUD_TCON1_PDN_CONNSYS_I2S_ASRC BIT(12)
|
||||
#define AUD_TCON1_PDN_DMIC3_ADC BIT(11)
|
||||
#define AUD_TCON1_PDN_DMIC2_ADC BIT(10)
|
||||
#define AUD_TCON1_PDN_DMIC1_ADC BIT(9)
|
||||
#define AUD_TCON1_PDN_DMIC0_ADC BIT(8)
|
||||
#define AUD_TCON1_PDN_I2S4_BCLK BIT(7)
|
||||
#define AUD_TCON1_PDN_I2S3_BCLK BIT(6)
|
||||
#define AUD_TCON1_PDN_I2S2_BCLK BIT(5)
|
||||
#define AUD_TCON1_PDN_I2S1_BCLK BIT(4)
|
||||
|
||||
/* AUDIO_TOP_CON3 (0x000C) */
|
||||
#define AUD_TCON3_HDMI_BCK_INV BIT(3)
|
||||
|
||||
/* AFE_I2S_CON (0x0018) */
|
||||
#define AFE_I2S_CON_PHASE_SHIFT_FIX BIT(31)
|
||||
#define AFE_I2S_CON_FROM_IO_MUX BIT(28)
|
||||
#define AFE_I2S_CON_LOW_JITTER_CLK BIT(12)
|
||||
#define AFE_I2S_CON_RATE_MASK GENMASK(11, 8)
|
||||
#define AFE_I2S_CON_FORMAT_I2S BIT(3)
|
||||
#define AFE_I2S_CON_SRC_SLAVE BIT(2)
|
||||
|
||||
/* AFE_ASRC_2CH_CON0 */
|
||||
#define ONE_HEART BIT(31)
|
||||
#define CHSET_STR_CLR BIT(4)
|
||||
#define COEFF_SRAM_CTRL BIT(1)
|
||||
#define ASM_ON BIT(0)
|
||||
|
||||
/* CON2 */
|
||||
#define O16BIT BIT(19)
|
||||
#define CLR_IIR_HISTORY BIT(17)
|
||||
#define IS_MONO BIT(16)
|
||||
#define IIR_EN BIT(11)
|
||||
#define IIR_STAGE_MASK GENMASK(10, 8)
|
||||
|
||||
/* CON5 */
|
||||
#define CALI_CYCLE_MASK GENMASK(31, 16)
|
||||
#define CALI_64_CYCLE FIELD_PREP(CALI_CYCLE_MASK, 0x3F)
|
||||
#define CALI_96_CYCLE FIELD_PREP(CALI_CYCLE_MASK, 0x5F)
|
||||
#define CALI_441_CYCLE FIELD_PREP(CALI_CYCLE_MASK, 0x1B8)
|
||||
|
||||
#define CALI_AUTORST BIT(15)
|
||||
#define AUTO_TUNE_FREQ5 BIT(12)
|
||||
#define COMP_FREQ_RES BIT(11)
|
||||
|
||||
#define CALI_SEL_MASK GENMASK(9, 8)
|
||||
#define CALI_SEL_00 FIELD_PREP(CALI_SEL_MASK, 0)
|
||||
#define CALI_SEL_01 FIELD_PREP(CALI_SEL_MASK, 1)
|
||||
|
||||
#define CALI_BP_DGL BIT(7) /* Bypass the deglitch circuit */
|
||||
#define AUTO_TUNE_FREQ4 BIT(3)
|
||||
#define CALI_AUTO_RESTART BIT(2)
|
||||
#define CALI_USE_FREQ_OUT BIT(1)
|
||||
#define CALI_ON BIT(0)
|
||||
|
||||
#define AFE_I2S_CON_WLEN_32BIT BIT(1)
|
||||
#define AFE_I2S_CON_EN BIT(0)
|
||||
|
||||
#define AFE_CONN3_I03_O03_S BIT(3)
|
||||
#define AFE_CONN4_I04_O04_S BIT(4)
|
||||
#define AFE_CONN4_I03_O04_S BIT(3)
|
||||
|
||||
/* AFE_I2S_CON1 (0x0034) */
|
||||
#define AFE_I2S_CON1_I2S2_TO_PAD BIT(18)
|
||||
#define AFE_I2S_CON1_TDMOUT_TO_PAD (0 << 18)
|
||||
#define AFE_I2S_CON1_RATE GENMASK(11, 8)
|
||||
#define AFE_I2S_CON1_FORMAT_I2S BIT(3)
|
||||
#define AFE_I2S_CON1_WLEN_32BIT BIT(1)
|
||||
#define AFE_I2S_CON1_EN BIT(0)
|
||||
|
||||
/* AFE_I2S_CON2 (0x0038) */
|
||||
#define AFE_I2S_CON2_LOW_JITTER_CLK BIT(12)
|
||||
#define AFE_I2S_CON2_RATE GENMASK(11, 8)
|
||||
#define AFE_I2S_CON2_FORMAT_I2S BIT(3)
|
||||
#define AFE_I2S_CON2_WLEN_32BIT BIT(1)
|
||||
#define AFE_I2S_CON2_EN BIT(0)
|
||||
|
||||
/* AFE_I2S_CON3 (0x004C) */
|
||||
#define AFE_I2S_CON3_LOW_JITTER_CLK BIT(12)
|
||||
#define AFE_I2S_CON3_RATE GENMASK(11, 8)
|
||||
#define AFE_I2S_CON3_FORMAT_I2S BIT(3)
|
||||
#define AFE_I2S_CON3_WLEN_32BIT BIT(1)
|
||||
#define AFE_I2S_CON3_EN BIT(0)
|
||||
|
||||
/* AFE_ADDA_DL_SRC2_CON0 (0x0108) */
|
||||
#define AFE_ADDA_DL_SAMPLING_RATE GENMASK(31, 28)
|
||||
#define AFE_ADDA_DL_8X_UPSAMPLE GENMASK(25, 24)
|
||||
#define AFE_ADDA_DL_MUTE_OFF_CH1 BIT(12)
|
||||
#define AFE_ADDA_DL_MUTE_OFF_CH2 BIT(11)
|
||||
#define AFE_ADDA_DL_VOICE_DATA BIT(5)
|
||||
#define AFE_ADDA_DL_DEGRADE_GAIN BIT(1)
|
||||
|
||||
/* AFE_ADDA_UL_SRC_CON0 (0x0114) */
|
||||
#define AFE_ADDA_UL_SAMPLING_RATE GENMASK(19, 17)
|
||||
|
||||
/* AFE_ADDA_UL_DL_CON0 */
|
||||
#define AFE_ADDA_UL_DL_ADDA_AFE_ON BIT(0)
|
||||
#define AFE_ADDA_UL_DL_DMIC_CLKDIV_ON BIT(1)
|
||||
|
||||
/* AFE_APLL_TUNER_CFG (0x03f0) */
|
||||
#define AFE_APLL_TUNER_CFG_MASK GENMASK(15, 1)
|
||||
#define AFE_APLL_TUNER_CFG_EN_MASK BIT(0)
|
||||
|
||||
/* AFE_APLL_TUNER_CFG1 (0x03f4) */
|
||||
#define AFE_APLL_TUNER_CFG1_MASK GENMASK(15, 1)
|
||||
#define AFE_APLL_TUNER_CFG1_EN_MASK BIT(0)
|
||||
|
||||
/* PCM_INTF_CON1 (0x0550) */
|
||||
#define PCM_INTF_CON1_EXT_MODEM BIT(17)
|
||||
#define PCM_INTF_CON1_16BIT (0 << 16)
|
||||
#define PCM_INTF_CON1_24BIT BIT(16)
|
||||
#define PCM_INTF_CON1_32BCK (0 << 14)
|
||||
#define PCM_INTF_CON1_64BCK BIT(14)
|
||||
#define PCM_INTF_CON1_MASTER_MODE (0 << 5)
|
||||
#define PCM_INTF_CON1_SLAVE_MODE BIT(5)
|
||||
#define PCM_INTF_CON1_FS_MASK GENMASK(4, 3)
|
||||
#define PCM_INTF_CON1_FS_8K FIELD_PREP(PCM_INTF_CON1_FS_MASK, 0)
|
||||
#define PCM_INTF_CON1_FS_16K FIELD_PREP(PCM_INTF_CON1_FS_MASK, 1)
|
||||
#define PCM_INTF_CON1_FS_32K FIELD_PREP(PCM_INTF_CON1_FS_MASK, 2)
|
||||
#define PCM_INTF_CON1_FS_48K FIELD_PREP(PCM_INTF_CON1_FS_MASK, 3)
|
||||
#define PCM_INTF_CON1_SYNC_LEN_MASK GENMASK(13, 9)
|
||||
#define PCM_INTF_CON1_SYNC_LEN(x) FIELD_PREP(PCM_INTF_CON1_SYNC_LEN_MASK, ((x) - 1))
|
||||
#define PCM_INTF_CON1_FORMAT_MASK GENMASK(2, 1)
|
||||
#define PCM_INTF_CON1_SYNC_OUT_INV BIT(23)
|
||||
#define PCM_INTF_CON1_BCLK_OUT_INV BIT(22)
|
||||
#define PCM_INTF_CON1_SYNC_IN_INV BIT(21)
|
||||
#define PCM_INTF_CON1_BCLK_IN_INV BIT(20)
|
||||
#define PCM_INTF_CON1_BYPASS_ASRC BIT(6)
|
||||
#define PCM_INTF_CON1_EN BIT(0)
|
||||
#define PCM_INTF_CON1_CONFIG_MASK (0xf3fffe)
|
||||
|
||||
/* AFE_DMIC0_UL_SRC_CON0 (0x05b4)
|
||||
* AFE_DMIC1_UL_SRC_CON0 (0x0620)
|
||||
* AFE_DMIC2_UL_SRC_CON0 (0x0780)
|
||||
* AFE_DMIC3_UL_SRC_CON0 (0x07ec)
|
||||
*/
|
||||
#define DMIC_TOP_CON_CK_PHASE_SEL_CH1 GENMASK(29, 27)
|
||||
#define DMIC_TOP_CON_CK_PHASE_SEL_CH2 GENMASK(26, 24)
|
||||
#define DMIC_TOP_CON_TWO_WIRE_MODE BIT(23)
|
||||
#define DMIC_TOP_CON_CH2_ON BIT(22)
|
||||
#define DMIC_TOP_CON_CH1_ON BIT(21)
|
||||
#define DMIC_TOP_CON_VOICE_MODE_MASK GENMASK(19, 17)
|
||||
#define DMIC_TOP_CON_VOICE_MODE_8K FIELD_PREP(DMIC_TOP_CON_VOICE_MODE_MASK, 0)
|
||||
#define DMIC_TOP_CON_VOICE_MODE_16K FIELD_PREP(DMIC_TOP_CON_VOICE_MODE_MASK, 1)
|
||||
#define DMIC_TOP_CON_VOICE_MODE_32K FIELD_PREP(DMIC_TOP_CON_VOICE_MODE_MASK, 2)
|
||||
#define DMIC_TOP_CON_VOICE_MODE_48K FIELD_PREP(DMIC_TOP_CON_VOICE_MODE_MASK, 3)
|
||||
#define DMIC_TOP_CON_LOW_POWER_MODE_MASK GENMASK(15, 14)
|
||||
#define DMIC_TOP_CON_LOW_POWER_MODE(x) FIELD_PREP(DMIC_TOP_CON_LOW_POWER_MODE_MASK, (x))
|
||||
#define DMIC_TOP_CON_IIR_ON BIT(10)
|
||||
#define DMIC_TOP_CON_IIR_MODE GENMASK(9, 7)
|
||||
#define DMIC_TOP_CON_INPUT_MODE BIT(5)
|
||||
#define DMIC_TOP_CON_SDM3_LEVEL_MODE BIT(1)
|
||||
#define DMIC_TOP_CON_SRC_ON BIT(0)
|
||||
#define DMIC_TOP_CON_SDM3_DE_SELECT (0 << 1)
|
||||
#define DMIC_TOP_CON_CONFIG_MASK (0x3f8ed7a6)
|
||||
|
||||
/* AFE_CONN_24BIT (0x0AA4) */
|
||||
#define AFE_CONN_24BIT_O10 BIT(10)
|
||||
#define AFE_CONN_24BIT_O09 BIT(9)
|
||||
#define AFE_CONN_24BIT_O06 BIT(6)
|
||||
#define AFE_CONN_24BIT_O05 BIT(5)
|
||||
#define AFE_CONN_24BIT_O04 BIT(4)
|
||||
#define AFE_CONN_24BIT_O03 BIT(3)
|
||||
#define AFE_CONN_24BIT_O02 BIT(2)
|
||||
#define AFE_CONN_24BIT_O01 BIT(1)
|
||||
#define AFE_CONN_24BIT_O00 BIT(0)
|
||||
|
||||
/* AFE_HD_ENGEN_ENABLE */
|
||||
#define AFE_22M_PLL_EN BIT(0)
|
||||
#define AFE_24M_PLL_EN BIT(1)
|
||||
|
||||
/* AFE_GAIN1_CON0 (0x0410) */
|
||||
#define AFE_GAIN1_CON0_EN_MASK GENMASK(0, 0)
|
||||
#define AFE_GAIN1_CON0_MODE_MASK GENMASK(7, 4)
|
||||
#define AFE_GAIN1_CON0_SAMPLE_PER_STEP_MASK GENMASK(15, 8)
|
||||
|
||||
/* AFE_GAIN1_CON1 (0x0414) */
|
||||
#define AFE_GAIN1_CON1_MASK GENMASK(19, 0)
|
||||
|
||||
/* AFE_GAIN1_CUR (0x0B78) */
|
||||
#define AFE_GAIN1_CUR_MASK GENMASK(19, 0)
|
||||
|
||||
/* AFE_CM1_CON0 (0x0e50) */
|
||||
/* AFE_CM2_CON0 (0x0e60) */
|
||||
#define CM_AFE_CM_CH_NUM_MASK GENMASK(3, 0)
|
||||
#define CM_AFE_CM_CH_NUM(x) FIELD_PREP(CM_AFE_CM_CH_NUM_MASK, ((x) - 1))
|
||||
#define CM_AFE_CM_ON BIT(4)
|
||||
#define CM_AFE_CM_START_DATA_MASK GENMASK(11, 8)
|
||||
|
||||
#define CM_AFE_CM1_VUL_SEL BIT(12)
|
||||
#define CM_AFE_CM1_IN_MODE_MASK GENMASK(19, 16)
|
||||
#define CM_AFE_CM2_TDM_SEL BIT(12)
|
||||
#define CM_AFE_CM2_CLK_SEL BIT(13)
|
||||
#define CM_AFE_CM2_GASRC1_OUT_SEL BIT(17)
|
||||
#define CM_AFE_CM2_GASRC2_OUT_SEL BIT(16)
|
||||
|
||||
/* AFE_CM2_CONN* */
|
||||
#define CM2_AFE_CM2_CONN_CFG1(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG1_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG1_MASK GENMASK(4, 0)
|
||||
#define CM2_AFE_CM2_CONN_CFG2(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG2_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG2_MASK GENMASK(9, 5)
|
||||
#define CM2_AFE_CM2_CONN_CFG3(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG3_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG3_MASK GENMASK(14, 10)
|
||||
#define CM2_AFE_CM2_CONN_CFG4(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG4_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG4_MASK GENMASK(19, 15)
|
||||
#define CM2_AFE_CM2_CONN_CFG5(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG5_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG5_MASK GENMASK(24, 20)
|
||||
#define CM2_AFE_CM2_CONN_CFG6(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG6_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG6_MASK GENMASK(29, 25)
|
||||
#define CM2_AFE_CM2_CONN_CFG7(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG7_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG7_MASK GENMASK(4, 0)
|
||||
#define CM2_AFE_CM2_CONN_CFG8(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG8_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG8_MASK GENMASK(9, 5)
|
||||
#define CM2_AFE_CM2_CONN_CFG9(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG9_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG9_MASK GENMASK(14, 10)
|
||||
#define CM2_AFE_CM2_CONN_CFG10(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG10_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG10_MASK GENMASK(19, 15)
|
||||
#define CM2_AFE_CM2_CONN_CFG11(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG11_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG11_MASK GENMASK(24, 20)
|
||||
#define CM2_AFE_CM2_CONN_CFG12(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG12_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG12_MASK GENMASK(29, 25)
|
||||
#define CM2_AFE_CM2_CONN_CFG13(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG13_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG13_MASK GENMASK(4, 0)
|
||||
#define CM2_AFE_CM2_CONN_CFG14(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG14_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG14_MASK GENMASK(9, 5)
|
||||
#define CM2_AFE_CM2_CONN_CFG15(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG15_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG15_MASK GENMASK(14, 10)
|
||||
#define CM2_AFE_CM2_CONN_CFG16(x) FIELD_PREP(CM2_AFE_CM2_CONN_CFG16_MASK, (x))
|
||||
#define CM2_AFE_CM2_CONN_CFG16_MASK GENMASK(19, 15)
|
||||
|
||||
/* AFE_CM1_CON* */
|
||||
#define CM_AFE_CM_UPDATE_CNT1_MASK GENMASK(15, 0)
|
||||
#define CM_AFE_CM_UPDATE_CNT1(x) FIELD_PREP(CM_AFE_CM_UPDATE_CNT1_MASK, (x))
|
||||
#define CM_AFE_CM_UPDATE_CNT2_MASK GENMASK(31, 16)
|
||||
#define CM_AFE_CM_UPDATE_CNT2(x) FIELD_PREP(CM_AFE_CM_UPDATE_CNT2_MASK, (x))
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user