Commit 860bfa6d authored by Mark Brown's avatar Mark Brown

Merge series "ASoC: Mediatek: Add support for MT8192 SoC" from Jiaxin Yu <jiaxin.yu@mediatek.com>:

This series of patches adds support for Mediatek AFE for MT8192 SoC. At the same
time, the calibration function of MT6359 is completed with real machine driver.
The patch is based on broonie tree "for-next" branch.

Change since v3:
  - use normal conditional statements to improve legiblity in [v3,3/9]
  - remove mtk_i2s_hd_en_event as there's trace in the core
  - impove mt8192_i2s_enum and mt8192_adda_enum

Change since v2:
  - split the dai driver files as a separate patch
  - fix dt-bindings to GPL-2.0-only License
  - remove unnecessary preperty descriptions such as 'maxItems'

Change since v1:
  - fixed some typos related to dt-bindings in [v1,3/5] and [v1,5/5]
  - add vendor prefix to the properties, such as "mediatek,apmixedsys"
  - add a dependency description to indicate the required header files

Jiaxin Yu (9):
  ASoC: mediatek: mt6359: add the calibration functions
  ASoC: mediatek: mt8192: add platform driver
  ASoC: mediatek: mt8192: support i2s in platform driver
  ASoC: mediatek: mt8192: support adda in platform driver
  ASoC: mediatek: mt8192: support pcm in platform driver
  ASoC: mediatek: mt8192: support tdm in platform driver
  dt-bindings: mediatek: mt8192: add audio afe document
  ASoC: mediatek: mt8192: add machine driver with mt6359, rt1015 and
    rt5682
  dt-bindings: mediatek: mt8192: add mt8192-mt6358-rt1015-rt5682
    document

 .../bindings/sound/mt8192-afe-pcm.yaml        |  100 +
 .../sound/mt8192-mt6359-rt1015-rt5682.yaml    |   42 +
 sound/soc/codecs/mt6359.c                     |  110 +
 sound/soc/codecs/mt6359.h                     |    7 +
 sound/soc/mediatek/Kconfig                    |   23 +
 sound/soc/mediatek/Makefile                   |    1 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.c    |   13 +-
 sound/soc/mediatek/common/mtk-base-afe.h      |    1 +
 sound/soc/mediatek/mt8192/Makefile            |   16 +
 sound/soc/mediatek/mt8192/mt8192-afe-clk.c    |  669 ++++
 sound/soc/mediatek/mt8192/mt8192-afe-clk.h    |  244 ++
 sound/soc/mediatek/mt8192/mt8192-afe-common.h |  170 +
 .../soc/mediatek/mt8192/mt8192-afe-control.c  |  163 +
 sound/soc/mediatek/mt8192/mt8192-afe-gpio.c   |  306 ++
 sound/soc/mediatek/mt8192/mt8192-afe-gpio.h   |   19 +
 sound/soc/mediatek/mt8192/mt8192-afe-pcm.c    | 2389 +++++++++++++
 sound/soc/mediatek/mt8192/mt8192-dai-adda.c   | 1471 ++++++++
 sound/soc/mediatek/mt8192/mt8192-dai-i2s.c    | 2110 +++++++++++
 sound/soc/mediatek/mt8192/mt8192-dai-pcm.c    |  409 +++
 sound/soc/mediatek/mt8192/mt8192-dai-tdm.c    |  778 ++++
 .../mediatek/mt8192/mt8192-interconnection.h  |   65 +
 .../mt8192/mt8192-mt6359-rt1015-rt5682.c      | 1058 ++++++
 sound/soc/mediatek/mt8192/mt8192-reg.h        | 3131 +++++++++++++++++
 23 files changed, 13291 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8192-afe-pcm.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml
 create mode 100644 sound/soc/mediatek/mt8192/Makefile
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-afe-clk.c
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-afe-clk.h
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-afe-common.h
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-afe-control.c
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-afe-gpio.c
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-afe-gpio.h
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-dai-adda.c
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-dai-i2s.c
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-dai-pcm.c
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-dai-tdm.c
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-interconnection.h
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
 create mode 100644 sound/soc/mediatek/mt8192/mt8192-reg.h

--
2.18.0
parents 7e9a2387 4a232122
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mt8192-afe-pcm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek AFE PCM controller for mt8192
maintainers:
- Jiaxin Yu <jiaxin.yu@mediatek.com>
- Shane Chien <shane.chien@mediatek.com>
properties:
compatible:
const: mediatek,mt8192-audio
interrupts:
maxItems: 1
resets:
maxItems: 1
reset-names:
const: audiosys
mediatek,apmixedsys:
$ref: "/schemas/types.yaml#/definitions/phandle"
description: The phandle of the mediatek apmixedsys controller
mediatek,infracfg:
$ref: "/schemas/types.yaml#/definitions/phandle"
description: The phandle of the mediatek infracfg controller
mediatek,topckgen:
$ref: "/schemas/types.yaml#/definitions/phandle"
description: The phandle of the mediatek topckgen controller
power-domains:
maxItems: 1
clocks:
items:
- description: AFE clock
- description: ADDA DAC clock
- description: ADDA DAC pre-distortion clock
- description: audio infra sys clock
- description: audio infra 26M clock
clock-names:
items:
- const: aud_afe_clk
- const: aud_dac_clk
- const: aud_dac_predis_clk
- const: aud_infra_clk
- const: aud_infra_26m_clk
required:
- compatible
- interrupts
- resets
- reset-names
- mediatek,apmixedsys
- mediatek,infracfg
- mediatek,topckgen
- power-domains
- clocks
- clock-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/mt8192-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/power/mt8192-power.h>
#include <dt-bindings/reset-controller/mt8192-resets.h>
afe: mt8192-afe-pcm {
compatible = "mediatek,mt8192-audio";
interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>;
resets = <&watchdog MT8192_TOPRGU_AUDIO_SW_RST>;
reset-names = "audiosys";
mediatek,apmixedsys = <&apmixedsys>;
mediatek,infracfg = <&infracfg>;
mediatek,topckgen = <&topckgen>;
power-domains = <&scpsys MT8192_POWER_DOMAIN_AUDIO>;
clocks = <&audsys CLK_AUD_AFE>,
<&audsys CLK_AUD_DAC>,
<&audsys CLK_AUD_DAC_PREDIS>,
<&infracfg CLK_INFRA_AUDIO>,
<&infracfg CLK_INFRA_AUDIO_26M_B>;
clock-names = "aud_afe_clk",
"aud_dac_clk",
"aud_dac_predis_clk",
"aud_infra_clk",
"aud_infra_26m_clk";
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mt8192-mt6359-rt1015-rt5682.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek MT8192 with MT6359, RT1015 and RT5682 ASoC sound card driver
maintainers:
- Jiaxin Yu <jiaxin.yu@mediatek.com>
- Shane Chien <shane.chien@mediatek.com>
description:
This binding describes the MT8192 sound card.
properties:
compatible:
const: mediatek,mt8192_mt6359_rt1015_rt5682
mediatek,platform:
$ref: "/schemas/types.yaml#/definitions/phandle"
description: The phandle of MT8192 ASoC platform.
additionalProperties: false
required:
- compatible
- mediatek,platform
examples:
- |
sound: mt8192-sound {
compatible = "mediatek,mt8192-mt6359-rt1015-rt5682";
mediatek,platform = <&afe>;
pinctrl-names = "aud_clk_mosi_off",
"aud_clk_mosi_on";
pinctrl-0 = <&aud_clk_mosi_off>;
pinctrl-1 = <&aud_clk_mosi_on>;
};
...
......@@ -68,6 +68,38 @@ static void mt6359_reset_capture_gpio(struct mt6359_priv *priv)
0x3 << 0, 0x0);
}
/* use only when doing mtkaif calibraiton at the boot time */
static void mt6359_set_dcxo(struct mt6359_priv *priv, bool enable)
{
regmap_update_bits(priv->regmap, MT6359_DCXO_CW12,
0x1 << RG_XO_AUDIO_EN_M_SFT,
(enable ? 1 : 0) << RG_XO_AUDIO_EN_M_SFT);
}
/* use only when doing mtkaif calibraiton at the boot time */
static void mt6359_set_clksq(struct mt6359_priv *priv, bool enable)
{
/* Enable/disable CLKSQ 26MHz */
regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON23,
RG_CLKSQ_EN_MASK_SFT,
(enable ? 1 : 0) << RG_CLKSQ_EN_SFT);
}
/* use only when doing mtkaif calibraiton at the boot time */
static void mt6359_set_aud_global_bias(struct mt6359_priv *priv, bool enable)
{
regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON13,
RG_AUDGLB_PWRDN_VA32_MASK_SFT,
(enable ? 0 : 1) << RG_AUDGLB_PWRDN_VA32_SFT);
}
/* use only when doing mtkaif calibraiton at the boot time */
static void mt6359_set_topck(struct mt6359_priv *priv, bool enable)
{
regmap_update_bits(priv->regmap, MT6359_AUD_TOP_CKPDN_CON0,
0x0066, enable ? 0x0 : 0x66);
}
static void mt6359_set_decoder_clk(struct mt6359_priv *priv, bool enable)
{
regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON13,
......@@ -122,6 +154,84 @@ static void mt6359_mtkaif_tx_disable(struct mt6359_priv *priv)
0xff00, 0x3000);
}
void mt6359_set_mtkaif_protocol(struct snd_soc_component *cmpnt,
int mtkaif_protocol)
{
struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);
priv->mtkaif_protocol = mtkaif_protocol;
}
EXPORT_SYMBOL_GPL(mt6359_set_mtkaif_protocol);
void mt6359_mtkaif_calibration_enable(struct snd_soc_component *cmpnt)
{
struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);
mt6359_set_playback_gpio(priv);
mt6359_set_capture_gpio(priv);
mt6359_mtkaif_tx_enable(priv);
mt6359_set_dcxo(priv, true);
mt6359_set_aud_global_bias(priv, true);
mt6359_set_clksq(priv, true);
mt6359_set_topck(priv, true);
/* set dat_miso_loopback on */
regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,
RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT,
1 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT);
regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,
RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT,
1 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT);
regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG1,
RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_MASK_SFT,
1 << RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_SFT);
}
EXPORT_SYMBOL_GPL(mt6359_mtkaif_calibration_enable);
void mt6359_mtkaif_calibration_disable(struct snd_soc_component *cmpnt)
{
struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);
/* set dat_miso_loopback off */
regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,
RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT,
0 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT);
regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,
RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT,
0 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT);
regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG1,
RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_MASK_SFT,
0 << RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_SFT);
mt6359_set_topck(priv, false);
mt6359_set_clksq(priv, false);
mt6359_set_aud_global_bias(priv, false);
mt6359_set_dcxo(priv, false);
mt6359_mtkaif_tx_disable(priv);
mt6359_reset_playback_gpio(priv);
mt6359_reset_capture_gpio(priv);
}
EXPORT_SYMBOL_GPL(mt6359_mtkaif_calibration_disable);
void mt6359_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt,
int phase_1, int phase_2, int phase_3)
{
struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);
regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,
RG_AUD_PAD_TOP_PHASE_MODE_MASK_SFT,
phase_1 << RG_AUD_PAD_TOP_PHASE_MODE_SFT);
regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,
RG_AUD_PAD_TOP_PHASE_MODE2_MASK_SFT,
phase_2 << RG_AUD_PAD_TOP_PHASE_MODE2_SFT);
regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG1,
RG_AUD_PAD_TOP_PHASE_MODE3_MASK_SFT,
phase_3 << RG_AUD_PAD_TOP_PHASE_MODE3_SFT);
}
EXPORT_SYMBOL_GPL(mt6359_set_mtkaif_calibration_phase);
static void zcd_disable(struct mt6359_priv *priv)
{
regmap_write(priv->regmap, MT6359_ZCD_CON0, 0x0000);
......
......@@ -2637,4 +2637,11 @@ struct mt6359_priv {
(type) == MIC_TYPE_MUX_DCC_ECM_DIFF || \
(type) == MIC_TYPE_MUX_DCC_ECM_SINGLE)
void mt6359_set_mtkaif_protocol(struct snd_soc_component *cmpnt,
int mtkaif_protocol);
void mt6359_mtkaif_calibration_enable(struct snd_soc_component *cmpnt);
void mt6359_mtkaif_calibration_disable(struct snd_soc_component *cmpnt);
void mt6359_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt,
int phase_1, int phase_2, int phase_3);
#endif/* end _MT6359_H_ */
......@@ -158,3 +158,26 @@ config SND_SOC_MTK_BTCVSD
BT encoded data to/from BT firmware.
Select Y if you have such device.
If unsure select "N".
config SND_SOC_MT8192
tristate "ASoC support for Mediatek MT8192 chip"
depends on ARCH_MEDIATEK
select SND_SOC_MEDIATEK
help
This adds ASoC platform driver support for Mediatek MT8192 chip
that can be used with other codecs.
Select Y if you have such device.
If unsure select "N".
config SND_SOC_MT8192_MT6359_RT1015_RT5682
tristate "ASoC Audio driver for MT8192 with MT6359 RT1015 RT5682 codec"
depends on I2C
depends on SND_SOC_MT8192
select SND_SOC_MT6359
select SND_SOC_RT1015
select SND_SOC_RT5682_I2C
help
This adds ASoC driver for Mediatek MT8192 boards
with the MT6359 RT1015 RT5682 audio codec.
Select Y if you have such device.
If unsure select "N".
......@@ -4,3 +4,4 @@ obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
obj-$(CONFIG_SND_SOC_MT8192) += mt8192/
......@@ -542,8 +542,13 @@ int mtk_memif_set_format(struct mtk_base_afe *afe,
break;
case SNDRV_PCM_FORMAT_S32_LE:
case SNDRV_PCM_FORMAT_U32_LE:
if (afe->memif_32bit_supported) {
hd_audio = 2;
hd_align = 0;
} else {
hd_audio = 1;
hd_align = 1;
}
break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_U24_LE:
......@@ -556,10 +561,10 @@ int mtk_memif_set_format(struct mtk_base_afe *afe,
}
mtk_regmap_update_bits(afe->regmap, memif->data->hd_reg,
1, hd_audio, memif->data->hd_shift);
0x3, hd_audio, memif->data->hd_shift);
mtk_regmap_update_bits(afe->regmap, memif->data->hd_align_reg,
1, hd_align, memif->data->hd_align_mshift);
0x1, hd_align, memif->data->hd_align_mshift);
return 0;
}
......
......@@ -91,6 +91,7 @@ struct mtk_base_afe {
int memif_size;
struct mtk_base_afe_irq *irqs;
int irqs_size;
int memif_32bit_supported;
struct list_head sub_dais;
struct snd_soc_dai_driver *dai_drivers;
......
# SPDX-License-Identifier: GPL-2.0
# platform driver
snd-soc-mt8192-afe-objs := \
mt8192-afe-pcm.o \
mt8192-afe-clk.o \
mt8192-afe-gpio.o \
mt8192-dai-adda.o \
mt8192-afe-control.o \
mt8192-dai-i2s.o \
mt8192-dai-pcm.o \
mt8192-dai-tdm.o
obj-$(CONFIG_SND_SOC_MT8192) += snd-soc-mt8192-afe.o
obj-$(CONFIG_SND_SOC_MT8192_MT6359_RT1015_RT5682) += \
mt8192-mt6359-rt1015-rt5682.o
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* mt8192-afe-clk.h -- Mediatek 8192 afe clock ctrl definition
*
* Copyright (c) 2020 MediaTek Inc.
* Author: Shane Chien <shane.chien@mediatek.com>
*/
#ifndef _MT8192_AFE_CLOCK_CTRL_H_
#define _MT8192_AFE_CLOCK_CTRL_H_
#define AP_PLL_CON3 0x0014
#define APLL1_CON0 0x0318
#define APLL1_CON1 0x031c
#define APLL1_CON2 0x0320
#define APLL1_CON4 0x0328
#define APLL1_TUNER_CON0 0x0040
#define APLL2_CON0 0x032c
#define APLL2_CON1 0x0330
#define APLL2_CON2 0x0334
#define APLL2_CON4 0x033c
#define APLL2_TUNER_CON0 0x0044
#define CLK_CFG_7 0x0080
#define CLK_CFG_8 0x0090
#define CLK_CFG_11 0x00c0
#define CLK_CFG_12 0x00d0
#define CLK_CFG_13 0x00e0
#define CLK_CFG_15 0x0100
#define CLK_AUDDIV_0 0x0320
#define CLK_AUDDIV_2 0x0328
#define CLK_AUDDIV_3 0x0334
#define CLK_AUDDIV_4 0x0338
#define CKSYS_AUD_TOP_CFG 0x032c
#define CKSYS_AUD_TOP_MON 0x0330
#define PERI_BUS_DCM_CTRL 0x0074
#define MODULE_SW_CG_1_STA 0x0094
#define MODULE_SW_CG_2_STA 0x00ac
/* CLK_AUDDIV_0 */
#define APLL12_DIV0_PDN_SFT 0
#define APLL12_DIV0_PDN_MASK 0x1
#define APLL12_DIV0_PDN_MASK_SFT (0x1 << 0)
#define APLL12_DIV1_PDN_SFT 1
#define APLL12_DIV1_PDN_MASK 0x1
#define APLL12_DIV1_PDN_MASK_SFT (0x1 << 1)
#define APLL12_DIV2_PDN_SFT 2
#define APLL12_DIV2_PDN_MASK 0x1
#define APLL12_DIV2_PDN_MASK_SFT (0x1 << 2)
#define APLL12_DIV3_PDN_SFT 3
#define APLL12_DIV3_PDN_MASK 0x1
#define APLL12_DIV3_PDN_MASK_SFT (0x1 << 3)
#define APLL12_DIV4_PDN_SFT 4
#define APLL12_DIV4_PDN_MASK 0x1
#define APLL12_DIV4_PDN_MASK_SFT (0x1 << 4)
#define APLL12_DIVB_PDN_SFT 5
#define APLL12_DIVB_PDN_MASK 0x1
#define APLL12_DIVB_PDN_MASK_SFT (0x1 << 5)
#define APLL12_DIV5_PDN_SFT 6
#define APLL12_DIV5_PDN_MASK 0x1
#define APLL12_DIV5_PDN_MASK_SFT (0x1 << 6)
#define APLL12_DIV6_PDN_SFT 7
#define APLL12_DIV6_PDN_MASK 0x1
#define APLL12_DIV6_PDN_MASK_SFT (0x1 << 7)
#define APLL12_DIV7_PDN_SFT 8
#define APLL12_DIV7_PDN_MASK 0x1
#define APLL12_DIV7_PDN_MASK_SFT (0x1 << 8)
#define APLL12_DIV8_PDN_SFT 9
#define APLL12_DIV8_PDN_MASK 0x1
#define APLL12_DIV8_PDN_MASK_SFT (0x1 << 9)
#define APLL12_DIV9_PDN_SFT 10
#define APLL12_DIV9_PDN_MASK 0x1
#define APLL12_DIV9_PDN_MASK_SFT (0x1 << 10)
#define APLL_I2S0_MCK_SEL_SFT 16
#define APLL_I2S0_MCK_SEL_MASK 0x1
#define APLL_I2S0_MCK_SEL_MASK_SFT (0x1 << 16)
#define APLL_I2S1_MCK_SEL_SFT 17
#define APLL_I2S1_MCK_SEL_MASK 0x1
#define APLL_I2S1_MCK_SEL_MASK_SFT (0x1 << 17)
#define APLL_I2S2_MCK_SEL_SFT 18
#define APLL_I2S2_MCK_SEL_MASK 0x1
#define APLL_I2S2_MCK_SEL_MASK_SFT (0x1 << 18)
#define APLL_I2S3_MCK_SEL_SFT 19
#define APLL_I2S3_MCK_SEL_MASK 0x1
#define APLL_I2S3_MCK_SEL_MASK_SFT (0x1 << 19)
#define APLL_I2S4_MCK_SEL_SFT 20
#define APLL_I2S4_MCK_SEL_MASK 0x1
#define APLL_I2S4_MCK_SEL_MASK_SFT (0x1 << 20)
#define APLL_I2S5_MCK_SEL_SFT 21
#define APLL_I2S5_MCK_SEL_MASK 0x1
#define APLL_I2S5_MCK_SEL_MASK_SFT (0x1 << 21)
#define APLL_I2S6_MCK_SEL_SFT 22
#define APLL_I2S6_MCK_SEL_MASK 0x1
#define APLL_I2S6_MCK_SEL_MASK_SFT (0x1 << 22)
#define APLL_I2S7_MCK_SEL_SFT 23
#define APLL_I2S7_MCK_SEL_MASK 0x1
#define APLL_I2S7_MCK_SEL_MASK_SFT (0x1 << 23)
#define APLL_I2S8_MCK_SEL_SFT 24
#define APLL_I2S8_MCK_SEL_MASK 0x1
#define APLL_I2S8_MCK_SEL_MASK_SFT (0x1 << 24)
#define APLL_I2S9_MCK_SEL_SFT 25
#define APLL_I2S9_MCK_SEL_MASK 0x1
#define APLL_I2S9_MCK_SEL_MASK_SFT (0x1 << 25)
/* CLK_AUDDIV_2 */
#define APLL12_CK_DIV0_SFT 0
#define APLL12_CK_DIV0_MASK 0xff
#define APLL12_CK_DIV0_MASK_SFT (0xff << 0)
#define APLL12_CK_DIV1_SFT 8
#define APLL12_CK_DIV1_MASK 0xff
#define APLL12_CK_DIV1_MASK_SFT (0xff << 8)
#define APLL12_CK_DIV2_SFT 16
#define APLL12_CK_DIV2_MASK 0xff
#define APLL12_CK_DIV2_MASK_SFT (0xff << 16)
#define APLL12_CK_DIV3_SFT 24
#define APLL12_CK_DIV3_MASK 0xff
#define APLL12_CK_DIV3_MASK_SFT (0xff << 24)
/* CLK_AUDDIV_3 */
#define APLL12_CK_DIV4_SFT 0
#define APLL12_CK_DIV4_MASK 0xff
#define APLL12_CK_DIV4_MASK_SFT (0xff << 0)
#define APLL12_CK_DIVB_SFT 8
#define APLL12_CK_DIVB_MASK 0xff
#define APLL12_CK_DIVB_MASK_SFT (0xff << 8)
#define APLL12_CK_DIV5_SFT 16
#define APLL12_CK_DIV5_MASK 0xff
#define APLL12_CK_DIV5_MASK_SFT (0xff << 16)
#define APLL12_CK_DIV6_SFT 24
#define APLL12_CK_DIV6_MASK 0xff
#define APLL12_CK_DIV6_MASK_SFT (0xff << 24)
/* CLK_AUDDIV_4 */
#define APLL12_CK_DIV7_SFT 0
#define APLL12_CK_DIV7_MASK 0xff
#define APLL12_CK_DIV7_MASK_SFT (0xff << 0)
#define APLL12_CK_DIV8_SFT 8
#define APLL12_CK_DIV8_MASK 0xff
#define APLL12_CK_DIV8_MASK_SFT (0xff << 0)
#define APLL12_CK_DIV9_SFT 16
#define APLL12_CK_DIV9_MASK 0xff
#define APLL12_CK_DIV9_MASK_SFT (0xff << 0)
/* AUD_TOP_CFG */
#define AUD_TOP_CFG_SFT 0
#define AUD_TOP_CFG_MASK 0xffffffff
#define AUD_TOP_CFG_MASK_SFT (0xffffffff << 0)
/* AUD_TOP_MON */
#define AUD_TOP_MON_SFT 0
#define AUD_TOP_MON_MASK 0xffffffff
#define AUD_TOP_MON_MASK_SFT (0xffffffff << 0)
/* CLK_AUDDIV_3 */
#define APLL12_CK_DIV5_MSB_SFT 0
#define APLL12_CK_DIV5_MSB_MASK 0xf
#define APLL12_CK_DIV5_MSB_MASK_SFT (0xf << 0)
#define RESERVED0_SFT 4
#define RESERVED0_MASK 0xfffffff
#define RESERVED0_MASK_SFT (0xfffffff << 4)
/* APLL */
#define APLL1_W_NAME "APLL1"
#define APLL2_W_NAME "APLL2"
enum {
MT8192_APLL1 = 0,
MT8192_APLL2,
};
enum {
CLK_AFE = 0,
CLK_TML,
CLK_APLL22M,
CLK_APLL24M,
CLK_APLL1_TUNER,
CLK_APLL2_TUNER,
CLK_NLE,
CLK_INFRA_SYS_AUDIO,
CLK_INFRA_AUDIO_26M,
CLK_MUX_AUDIO,
CLK_MUX_AUDIOINTBUS,
CLK_TOP_MAINPLL_D4_D4,
/* apll related mux */
CLK_TOP_MUX_AUD_1,
CLK_TOP_APLL1_CK,
CLK_TOP_MUX_AUD_2,
CLK_TOP_APLL2_CK,
CLK_TOP_MUX_AUD_ENG1,
CLK_TOP_APLL1_D4,
CLK_TOP_MUX_AUD_ENG2,
CLK_TOP_APLL2_D4,
CLK_TOP_MUX_AUDIO_H,
CLK_TOP_I2S0_M_SEL,
CLK_TOP_I2S1_M_SEL,
CLK_TOP_I2S2_M_SEL,
CLK_TOP_I2S3_M_SEL,
CLK_TOP_I2S4_M_SEL,
CLK_TOP_I2S5_M_SEL,
CLK_TOP_I2S6_M_SEL,
CLK_TOP_I2S7_M_SEL,
CLK_TOP_I2S8_M_SEL,
CLK_TOP_I2S9_M_SEL,
CLK_TOP_APLL12_DIV0,
CLK_TOP_APLL12_DIV1,
CLK_TOP_APLL12_DIV2,
CLK_TOP_APLL12_DIV3,
CLK_TOP_APLL12_DIV4,
CLK_TOP_APLL12_DIVB,
CLK_TOP_APLL12_DIV5,
CLK_TOP_APLL12_DIV6,
CLK_TOP_APLL12_DIV7,
CLK_TOP_APLL12_DIV8,
CLK_TOP_APLL12_DIV9,
CLK_CLK26M,
CLK_NUM
};
struct mtk_base_afe;
int mt8192_init_clock(struct mtk_base_afe *afe);
int mt8192_afe_enable_clock(struct mtk_base_afe *afe);
void mt8192_afe_disable_clock(struct mtk_base_afe *afe);
int mt8192_apll1_enable(struct mtk_base_afe *afe);
void mt8192_apll1_disable(struct mtk_base_afe *afe);
int mt8192_apll2_enable(struct mtk_base_afe *afe);
void mt8192_apll2_disable(struct mtk_base_afe *afe);
int mt8192_get_apll_rate(struct mtk_base_afe *afe, int apll);
int mt8192_get_apll_by_rate(struct mtk_base_afe *afe, int rate);
int mt8192_get_apll_by_name(struct mtk_base_afe *afe, const char *name);
/* these will be replaced by using CCF */
int mt8192_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate);
void mt8192_mck_disable(struct mtk_base_afe *afe, int mck_id);
int mt8192_set_audio_int_bus_parent(struct mtk_base_afe *afe,
int clk_id);
#endif
/* SPDX-License-Identifier: GPL-2.0 */
/*
* mt8192-afe-common.h -- Mediatek 8192 audio driver definitions
*
* Copyright (c) 2020 MediaTek Inc.
* Author: Shane Chien <shane.chien@mediatek.com>
*/
#ifndef _MT_8192_AFE_COMMON_H_
#define _MT_8192_AFE_COMMON_H_
#include <linux/list.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include "../common/mtk-base-afe.h"
#include "mt8192-reg.h"
enum {
MT8192_MEMIF_DL1,
MT8192_MEMIF_DL12,
MT8192_MEMIF_DL2,
MT8192_MEMIF_DL3,
MT8192_MEMIF_DL4,
MT8192_MEMIF_DL5,
MT8192_MEMIF_DL6,
MT8192_MEMIF_DL7,
MT8192_MEMIF_DL8,
MT8192_MEMIF_DL9,
MT8192_MEMIF_DAI,
MT8192_MEMIF_DAI2,
MT8192_MEMIF_MOD_DAI,
MT8192_MEMIF_VUL12,
MT8192_MEMIF_VUL2,
MT8192_MEMIF_VUL3,
MT8192_MEMIF_VUL4,
MT8192_MEMIF_VUL5,
MT8192_MEMIF_VUL6,
MT8192_MEMIF_AWB,
MT8192_MEMIF_AWB2,
MT8192_MEMIF_HDMI,
MT8192_MEMIF_NUM,
MT8192_DAI_ADDA = MT8192_MEMIF_NUM,
MT8192_DAI_ADDA_CH34,
MT8192_DAI_AP_DMIC,
MT8192_DAI_AP_DMIC_CH34,
MT8192_DAI_VOW,
MT8192_DAI_CONNSYS_I2S,
MT8192_DAI_I2S_0,
MT8192_DAI_I2S_1,
MT8192_DAI_I2S_2,
MT8192_DAI_I2S_3,
MT8192_DAI_I2S_5,
MT8192_DAI_I2S_6,
MT8192_DAI_I2S_7,
MT8192_DAI_I2S_8,
MT8192_DAI_I2S_9,
MT8192_DAI_HW_GAIN_1,
MT8192_DAI_HW_GAIN_2,
MT8192_DAI_SRC_1,
MT8192_DAI_SRC_2,
MT8192_DAI_PCM_1,
MT8192_DAI_PCM_2,
MT8192_DAI_TDM,
MT8192_DAI_NUM,
};
enum {
MT8192_IRQ_0,
MT8192_IRQ_1,
MT8192_IRQ_2,
MT8192_IRQ_3,
MT8192_IRQ_4,
MT8192_IRQ_5,
MT8192_IRQ_6,
MT8192_IRQ_7,
MT8192_IRQ_8,
MT8192_IRQ_9,
MT8192_IRQ_10,
MT8192_IRQ_11,
MT8192_IRQ_12,
MT8192_IRQ_13,
MT8192_IRQ_14,
MT8192_IRQ_15,
MT8192_IRQ_16,
MT8192_IRQ_17,
MT8192_IRQ_18,
MT8192_IRQ_19,
MT8192_IRQ_20,
MT8192_IRQ_21,
MT8192_IRQ_22,
MT8192_IRQ_23,
MT8192_IRQ_24,
MT8192_IRQ_25,
MT8192_IRQ_26,
MT8192_IRQ_31, /* used only for TDM */
MT8192_IRQ_NUM,
};
enum {
MTKAIF_PROTOCOL_1 = 0,
MTKAIF_PROTOCOL_2,
MTKAIF_PROTOCOL_2_CLK_P2,
};
enum {
MTK_AFE_ADDA_DL_GAIN_MUTE = 0,
MTK_AFE_ADDA_DL_GAIN_NORMAL = 0xf74f,
/* SA suggest apply -0.3db to audio/speech path */
};
/* MCLK */
enum {
MT8192_I2S0_MCK = 0,
MT8192_I2S1_MCK,
MT8192_I2S2_MCK,
MT8192_I2S3_MCK,
MT8192_I2S4_MCK,
MT8192_I2S4_BCK,
MT8192_I2S5_MCK,
MT8192_I2S6_MCK,
MT8192_I2S7_MCK,
MT8192_I2S8_MCK,
MT8192_I2S9_MCK,
MT8192_MCK_NUM,
};
struct clk;
struct mt8192_afe_private {
struct clk **clk;
struct regmap *topckgen;
struct regmap *apmixedsys;
struct regmap *infracfg;
int stf_positive_gain_db;
int pm_runtime_bypass_reg_ctl;
/* dai */
bool dai_on[MT8192_DAI_NUM];
void *dai_priv[MT8192_DAI_NUM];
/* adda */
int mtkaif_protocol;
int mtkaif_chosen_phase[4];
int mtkaif_phase_cycle[4];
int mtkaif_calibration_num_phase;
int mtkaif_dmic;
int mtkaif_dmic_ch34;
int mtkaif_adda6_only;
/* mck */
int mck_rate[MT8192_MCK_NUM];
};
int mt8192_dai_adda_register(struct mtk_base_afe *afe);
int mt8192_dai_i2s_register(struct mtk_base_afe *afe);
int mt8192_dai_hw_gain_register(struct mtk_base_afe *afe);
int mt8192_dai_src_register(struct mtk_base_afe *afe);
int mt8192_dai_pcm_register(struct mtk_base_afe *afe);
int mt8192_dai_tdm_register(struct mtk_base_afe *afe);
unsigned int mt8192_general_rate_transform(struct device *dev,
unsigned int rate);
unsigned int mt8192_rate_transform(struct device *dev,
unsigned int rate, int aud_blk);
int mt8192_dai_set_priv(struct mtk_base_afe *afe, int id,
int priv_size, const void *priv_data);
#endif
// SPDX-License-Identifier: GPL-2.0
//
// MediaTek ALSA SoC Audio Control
//
// Copyright (c) 2020 MediaTek Inc.
// Author: Shane Chien <shane.chien@mediatek.com>
//
#include <linux/pm_runtime.h>
#include "mt8192-afe-common.h"
enum {
MTK_AFE_RATE_8K = 0,
MTK_AFE_RATE_11K = 1,
MTK_AFE_RATE_12K = 2,
MTK_AFE_RATE_384K = 3,
MTK_AFE_RATE_16K = 4,
MTK_AFE_RATE_22K = 5,
MTK_AFE_RATE_24K = 6,
MTK_AFE_RATE_352K = 7,
MTK_AFE_RATE_32K = 8,
MTK_AFE_RATE_44K = 9,
MTK_AFE_RATE_48K = 10,
MTK_AFE_RATE_88K = 11,
MTK_AFE_RATE_96K = 12,
MTK_AFE_RATE_176K = 13,
MTK_AFE_RATE_192K = 14,
MTK_AFE_RATE_260K = 15,
};
enum {
MTK_AFE_DAI_MEMIF_RATE_8K = 0,
MTK_AFE_DAI_MEMIF_RATE_16K = 1,
MTK_AFE_DAI_MEMIF_RATE_32K = 2,
MTK_AFE_DAI_MEMIF_RATE_48K = 3,
};
enum {
MTK_AFE_PCM_RATE_8K = 0,
MTK_AFE_PCM_RATE_16K = 1,
MTK_AFE_PCM_RATE_32K = 2,
MTK_AFE_PCM_RATE_48K = 3,
};
unsigned int mt8192_general_rate_transform(struct device *dev,
unsigned int rate)
{
switch (rate) {
case 8000:
return MTK_AFE_RATE_8K;
case 11025:
return MTK_AFE_RATE_11K;
case 12000:
return MTK_AFE_RATE_12K;
case 16000:
return MTK_AFE_RATE_16K;
case 22050:
return MTK_AFE_RATE_22K;
case 24000:
return MTK_AFE_RATE_24K;
case 32000:
return MTK_AFE_RATE_32K;
case 44100:
return MTK_AFE_RATE_44K;
case 48000:
return MTK_AFE_RATE_48K;
case 88200:
return MTK_AFE_RATE_88K;
case 96000:
return MTK_AFE_RATE_96K;
case 176400:
return MTK_AFE_RATE_176K;
case 192000:
return MTK_AFE_RATE_192K;
case 260000:
return MTK_AFE_RATE_260K;
case 352800:
return MTK_AFE_RATE_352K;
case 384000:
return MTK_AFE_RATE_384K;
default:
dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n",
__func__,
rate, MTK_AFE_RATE_48K);
return MTK_AFE_RATE_48K;
}
}
static unsigned int dai_memif_rate_transform(struct device *dev,
unsigned int rate)
{
switch (rate) {
case 8000:
return MTK_AFE_DAI_MEMIF_RATE_8K;
case 16000:
return MTK_AFE_DAI_MEMIF_RATE_16K;
case 32000:
return MTK_AFE_DAI_MEMIF_RATE_32K;
case 48000:
return MTK_AFE_DAI_MEMIF_RATE_48K;
default:
dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n",
__func__,
rate, MTK_AFE_DAI_MEMIF_RATE_16K);
return MTK_AFE_DAI_MEMIF_RATE_16K;
}
}
static unsigned int pcm_rate_transform(struct device *dev,
unsigned int rate)
{
switch (rate) {
case 8000:
return MTK_AFE_PCM_RATE_8K;
case 16000:
return MTK_AFE_PCM_RATE_16K;
case 32000:
return MTK_AFE_PCM_RATE_32K;
case 48000:
return MTK_AFE_PCM_RATE_48K;
default:
dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n",
__func__,
rate, MTK_AFE_PCM_RATE_32K);
return MTK_AFE_PCM_RATE_32K;
}
}
unsigned int mt8192_rate_transform(struct device *dev,
unsigned int rate, int aud_blk)
{
switch (aud_blk) {
case MT8192_MEMIF_DAI:
case MT8192_MEMIF_MOD_DAI:
return dai_memif_rate_transform(dev, rate);
case MT8192_DAI_PCM_1:
case MT8192_DAI_PCM_2:
return pcm_rate_transform(dev, rate);
default:
return mt8192_general_rate_transform(dev, rate);
}
}
int mt8192_dai_set_priv(struct mtk_base_afe *afe, int id,
int priv_size, const void *priv_data)
{
struct mt8192_afe_private *afe_priv = afe->platform_priv;
void *temp_data;
temp_data = devm_kzalloc(afe->dev,
priv_size,
GFP_KERNEL);
if (!temp_data)
return -ENOMEM;
if (priv_data)
memcpy(temp_data, priv_data, priv_size);
afe_priv->dai_priv[id] = temp_data;
return 0;
}
// SPDX-License-Identifier: GPL-2.0
//
// mt8192-afe-gpio.c -- Mediatek 8192 afe gpio ctrl
//
// Copyright (c) 2020 MediaTek Inc.
// Author: Shane Chien <shane.chien@mediatek.com>
//
#include <linux/gpio.h>
#include <linux/pinctrl/consumer.h>
#include "mt8192-afe-common.h"
#include "mt8192-afe-gpio.h"
struct pinctrl *aud_pinctrl;
enum mt8192_afe_gpio {
MT8192_AFE_GPIO_DAT_MISO_OFF,
MT8192_AFE_GPIO_DAT_MISO_ON,
MT8192_AFE_GPIO_DAT_MOSI_OFF,
MT8192_AFE_GPIO_DAT_MOSI_ON,
MT8192_AFE_GPIO_DAT_MISO_CH34_OFF,
MT8192_AFE_GPIO_DAT_MISO_CH34_ON,
MT8192_AFE_GPIO_DAT_MOSI_CH34_OFF,
MT8192_AFE_GPIO_DAT_MOSI_CH34_ON,
MT8192_AFE_GPIO_I2S0_OFF,
MT8192_AFE_GPIO_I2S0_ON,
MT8192_AFE_GPIO_I2S1_OFF,
MT8192_AFE_GPIO_I2S1_ON,
MT8192_AFE_GPIO_I2S2_OFF,
MT8192_AFE_GPIO_I2S2_ON,
MT8192_AFE_GPIO_I2S3_OFF,
MT8192_AFE_GPIO_I2S3_ON,
MT8192_AFE_GPIO_I2S5_OFF,
MT8192_AFE_GPIO_I2S5_ON,
MT8192_AFE_GPIO_I2S6_OFF,
MT8192_AFE_GPIO_I2S6_ON,
MT8192_AFE_GPIO_I2S7_OFF,
MT8192_AFE_GPIO_I2S7_ON,
MT8192_AFE_GPIO_I2S8_OFF,
MT8192_AFE_GPIO_I2S8_ON,
MT8192_AFE_GPIO_I2S9_OFF,
MT8192_AFE_GPIO_I2S9_ON,
MT8192_AFE_GPIO_VOW_DAT_OFF,
MT8192_AFE_GPIO_VOW_DAT_ON,
MT8192_AFE_GPIO_VOW_CLK_OFF,
MT8192_AFE_GPIO_VOW_CLK_ON,
MT8192_AFE_GPIO_CLK_MOSI_OFF,
MT8192_AFE_GPIO_CLK_MOSI_ON,
MT8192_AFE_GPIO_TDM_OFF,
MT8192_AFE_GPIO_TDM_ON,
MT8192_AFE_GPIO_GPIO_NUM
};
struct audio_gpio_attr {
const char *name;
bool gpio_prepare;
struct pinctrl_state *gpioctrl;
};
static struct audio_gpio_attr aud_gpios[MT8192_AFE_GPIO_GPIO_NUM] = {
[MT8192_AFE_GPIO_DAT_MISO_OFF] = {"aud_dat_miso_off", false, NULL},
[MT8192_AFE_GPIO_DAT_MISO_ON] = {"aud_dat_miso_on", false, NULL},
[MT8192_AFE_GPIO_DAT_MOSI_OFF] = {"aud_dat_mosi_off", false, NULL},
[MT8192_AFE_GPIO_DAT_MOSI_ON] = {"aud_dat_mosi_on", false, NULL},
[MT8192_AFE_GPIO_I2S0_OFF] = {"aud_gpio_i2s0_off", false, NULL},
[MT8192_AFE_GPIO_I2S0_ON] = {"aud_gpio_i2s0_on", false, NULL},
[MT8192_AFE_GPIO_I2S1_OFF] = {"aud_gpio_i2s1_off", false, NULL},
[MT8192_AFE_GPIO_I2S1_ON] = {"aud_gpio_i2s1_on", false, NULL},
[MT8192_AFE_GPIO_I2S2_OFF] = {"aud_gpio_i2s2_off", false, NULL},
[MT8192_AFE_GPIO_I2S2_ON] = {"aud_gpio_i2s2_on", false, NULL},
[MT8192_AFE_GPIO_I2S3_OFF] = {"aud_gpio_i2s3_off", false, NULL},
[MT8192_AFE_GPIO_I2S3_ON] = {"aud_gpio_i2s3_on", false, NULL},
[MT8192_AFE_GPIO_I2S5_OFF] = {"aud_gpio_i2s5_off", false, NULL},
[MT8192_AFE_GPIO_I2S5_ON] = {"aud_gpio_i2s5_on", false, NULL},
[MT8192_AFE_GPIO_I2S6_OFF] = {"aud_gpio_i2s6_off", false, NULL},
[MT8192_AFE_GPIO_I2S6_ON] = {"aud_gpio_i2s6_on", false, NULL},
[MT8192_AFE_GPIO_I2S7_OFF] = {"aud_gpio_i2s7_off", false, NULL},
[MT8192_AFE_GPIO_I2S7_ON] = {"aud_gpio_i2s7_on", false, NULL},
[MT8192_AFE_GPIO_I2S8_OFF] = {"aud_gpio_i2s8_off", false, NULL},
[MT8192_AFE_GPIO_I2S8_ON] = {"aud_gpio_i2s8_on", false, NULL},
[MT8192_AFE_GPIO_I2S9_OFF] = {"aud_gpio_i2s9_off", false, NULL},
[MT8192_AFE_GPIO_I2S9_ON] = {"aud_gpio_i2s9_on", false, NULL},
[MT8192_AFE_GPIO_TDM_OFF] = {"aud_gpio_tdm_off", false, NULL},
[MT8192_AFE_GPIO_TDM_ON] = {"aud_gpio_tdm_on", false, NULL},
[MT8192_AFE_GPIO_VOW_DAT_OFF] = {"vow_dat_miso_off", false, NULL},
[MT8192_AFE_GPIO_VOW_DAT_ON] = {"vow_dat_miso_on", false, NULL},
[MT8192_AFE_GPIO_VOW_CLK_OFF] = {"vow_clk_miso_off", false, NULL},
[MT8192_AFE_GPIO_VOW_CLK_ON] = {"vow_clk_miso_on", false, NULL},
[MT8192_AFE_GPIO_DAT_MISO_CH34_OFF] = {"aud_dat_miso_ch34_off",
false, NULL},
[MT8192_AFE_GPIO_DAT_MISO_CH34_ON] = {"aud_dat_miso_ch34_on",
false, NULL},
[MT8192_AFE_GPIO_DAT_MOSI_CH34_OFF] = {"aud_dat_mosi_ch34_off",
false, NULL},
[MT8192_AFE_GPIO_DAT_MOSI_CH34_ON] = {"aud_dat_mosi_ch34_on",
false, NULL},
[MT8192_AFE_GPIO_CLK_MOSI_OFF] = {"aud_clk_mosi_off", false, NULL},
[MT8192_AFE_GPIO_CLK_MOSI_ON] = {"aud_clk_mosi_on", false, NULL},
};
static DEFINE_MUTEX(gpio_request_mutex);
static int mt8192_afe_gpio_select(struct device *dev,
enum mt8192_afe_gpio type)
{
int ret;
if (type < 0 || type >= MT8192_AFE_GPIO_GPIO_NUM) {
dev_err(dev, "%s(), error, invalid gpio type %d\n",
__func__, type);
return -EINVAL;
}
if (!aud_gpios[type].gpio_prepare) {
dev_warn(dev, "%s(), error, gpio type %d not prepared\n",
__func__, type);
return -EIO;
}
ret = pinctrl_select_state(aud_pinctrl,
aud_gpios[type].gpioctrl);
if (ret) {
dev_dbg(dev, "%s(), error, can not set gpio type %d\n",
__func__, type);
}
return ret;
}
int mt8192_afe_gpio_init(struct device *dev)
{
int i, ret;
aud_pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(aud_pinctrl)) {
ret = PTR_ERR(aud_pinctrl);
dev_err(dev, "%s(), ret %d, cannot get aud_pinctrl!\n",
__func__, ret);
return ret;
}
for (i = 0; i < ARRAY_SIZE(aud_gpios); i++) {
aud_gpios[i].gpioctrl = pinctrl_lookup_state(aud_pinctrl,
aud_gpios[i].name);
if (IS_ERR(aud_gpios[i].gpioctrl)) {
ret = PTR_ERR(aud_gpios[i].gpioctrl);
dev_dbg(dev, "%s(), pinctrl_lookup_state %s fail, ret %d\n",
__func__, aud_gpios[i].name, ret);
} else {
aud_gpios[i].gpio_prepare = true;
}
}
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_CLK_MOSI_ON);
/* gpio status init */
mt8192_afe_gpio_request(dev, false, MT8192_DAI_ADDA, 0);
mt8192_afe_gpio_request(dev, false, MT8192_DAI_ADDA, 1);
return 0;
}
static int mt8192_afe_gpio_adda_dl(struct device *dev, bool enable)
{
if (enable) {
return mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_DAT_MOSI_ON);
} else {
return mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_DAT_MOSI_OFF);
}
}
static int mt8192_afe_gpio_adda_ul(struct device *dev, bool enable)
{
if (enable) {
return mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_DAT_MISO_ON);
} else {
return mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_DAT_MISO_OFF);
}
}
static int mt8192_afe_gpio_adda_ch34_dl(struct device *dev, bool enable)
{
if (enable) {
return mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_DAT_MOSI_CH34_ON);
} else {
return mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_DAT_MOSI_CH34_OFF);
}
}
static int mt8192_afe_gpio_adda_ch34_ul(struct device *dev, bool enable)
{
if (enable) {
return mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_DAT_MISO_CH34_ON);
} else {
return mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_DAT_MISO_CH34_OFF);
}
}
int mt8192_afe_gpio_request(struct device *dev, bool enable,
int dai, int uplink)
{
mutex_lock(&gpio_request_mutex);
switch (dai) {
case MT8192_DAI_ADDA:
if (uplink)
mt8192_afe_gpio_adda_ul(dev, enable);
else
mt8192_afe_gpio_adda_dl(dev, enable);
break;
case MT8192_DAI_ADDA_CH34:
if (uplink)
mt8192_afe_gpio_adda_ch34_ul(dev, enable);
else
mt8192_afe_gpio_adda_ch34_dl(dev, enable);
break;
case MT8192_DAI_I2S_0:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S0_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S0_OFF);
break;
case MT8192_DAI_I2S_1:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S1_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S1_OFF);
break;
case MT8192_DAI_I2S_2:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S2_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S2_OFF);
break;
case MT8192_DAI_I2S_3:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S3_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S3_OFF);
break;
case MT8192_DAI_I2S_5:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S5_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S5_OFF);
break;
case MT8192_DAI_I2S_6:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S6_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S6_OFF);
break;
case MT8192_DAI_I2S_7:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S7_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S7_OFF);
break;
case MT8192_DAI_I2S_8:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S8_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S8_OFF);
break;
case MT8192_DAI_I2S_9:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S9_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S9_OFF);
break;
case MT8192_DAI_TDM:
if (enable)
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_TDM_ON);
else
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_TDM_OFF);
break;
case MT8192_DAI_VOW:
if (enable) {
mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_VOW_CLK_ON);
mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_VOW_DAT_ON);
} else {
mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_VOW_CLK_OFF);
mt8192_afe_gpio_select(dev,
MT8192_AFE_GPIO_VOW_DAT_OFF);
}
break;
default:
mutex_unlock(&gpio_request_mutex);
dev_warn(dev, "%s(), invalid dai %d\n", __func__, dai);
return -EINVAL;
}
mutex_unlock(&gpio_request_mutex);
return 0;
}
/* SPDX-License-Identifier: GPL-2.0 */
/*
* mt8192-afe-gpio.h -- Mediatek 8192 afe gpio ctrl definition
*
* Copyright (c) 2020 MediaTek Inc.
* Author: Shane Chien <shane.chien@mediatek.com>
*/
#ifndef _MT8192_AFE_GPIO_H_
#define _MT8192_AFE_GPIO_H_
struct device;
int mt8192_afe_gpio_init(struct device *dev);
int mt8192_afe_gpio_request(struct device *dev, bool enable,
int dai, int uplink);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Mediatek MT8192 audio driver interconnection definition
*
* Copyright (c) 2020 MediaTek Inc.
* Author: Shane Chien <shane.chien@mediatek.com>
*/
#ifndef _MT8192_INTERCONNECTION_H_
#define _MT8192_INTERCONNECTION_H_
/* in port define */
#define I_I2S0_CH1 0
#define I_I2S0_CH2 1
#define I_ADDA_UL_CH1 3
#define I_ADDA_UL_CH2 4
#define I_DL1_CH1 5
#define I_DL1_CH2 6
#define I_DL2_CH1 7
#define I_DL2_CH2 8
#define I_PCM_1_CAP_CH1 9
#define I_GAIN1_OUT_CH1 10
#define I_GAIN1_OUT_CH2 11
#define I_GAIN2_OUT_CH1 12
#define I_GAIN2_OUT_CH2 13
#define I_PCM_2_CAP_CH1 14
#define I_ADDA_UL_CH3 17
#define I_ADDA_UL_CH4 18
#define I_DL12_CH1 19
#define I_DL12_CH2 20
#define I_PCM_2_CAP_CH2 21
#define I_PCM_1_CAP_CH2 22
#define I_DL3_CH1 23
#define I_DL3_CH2 24
#define I_I2S2_CH1 25
#define I_I2S2_CH2 26
#define I_I2S2_CH3 27
#define I_I2S2_CH4 28
/* in port define >= 32 */
#define I_32_OFFSET 32
#define I_CONNSYS_I2S_CH1 (34 - I_32_OFFSET)
#define I_CONNSYS_I2S_CH2 (35 - I_32_OFFSET)
#define I_SRC_1_OUT_CH1 (36 - I_32_OFFSET)
#define I_SRC_1_OUT_CH2 (37 - I_32_OFFSET)
#define I_SRC_2_OUT_CH1 (38 - I_32_OFFSET)
#define I_SRC_2_OUT_CH2 (39 - I_32_OFFSET)
#define I_DL4_CH1 (40 - I_32_OFFSET)
#define I_DL4_CH2 (41 - I_32_OFFSET)
#define I_DL5_CH1 (42 - I_32_OFFSET)
#define I_DL5_CH2 (43 - I_32_OFFSET)
#define I_DL6_CH1 (44 - I_32_OFFSET)
#define I_DL6_CH2 (45 - I_32_OFFSET)
#define I_DL7_CH1 (46 - I_32_OFFSET)
#define I_DL7_CH2 (47 - I_32_OFFSET)
#define I_DL8_CH1 (48 - I_32_OFFSET)
#define I_DL8_CH2 (49 - I_32_OFFSET)
#define I_DL9_CH1 (50 - I_32_OFFSET)
#define I_DL9_CH2 (51 - I_32_OFFSET)
#define I_I2S6_CH1 (52 - I_32_OFFSET)
#define I_I2S6_CH2 (53 - I_32_OFFSET)
#define I_I2S8_CH1 (54 - I_32_OFFSET)
#define I_I2S8_CH2 (55 - I_32_OFFSET)
#endif
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment