ASoC: mt8188: add new board support
Merge series from Trevor Wu <trevor.wu@mediatek.com>: In the series, we extend the capability of mt8188-mt6359 driver. The following changes are included. 1. Divide ADDA BE dai into two dais for SOF. 2. Register hdmi/dp jack pins. 3. dai_fmt can be configured from device tree. 4. Add some I2S codecs support. In addition, new compatible string "mediatek,mt8188-nau8825" is included for a new board support.
This commit is contained in:
commit
c7e076de2d
|
@ -11,7 +11,9 @@ maintainers:
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
const: mediatek,mt8188-mt6359-evb
|
enum:
|
||||||
|
- mediatek,mt8188-mt6359-evb
|
||||||
|
- mediatek,mt8188-nau8825
|
||||||
|
|
||||||
model:
|
model:
|
||||||
$ref: /schemas/types.yaml#/definitions/string
|
$ref: /schemas/types.yaml#/definitions/string
|
||||||
|
@ -42,7 +44,6 @@ patternProperties:
|
||||||
we are going to update parameters in this node.
|
we are going to update parameters in this node.
|
||||||
items:
|
items:
|
||||||
enum:
|
enum:
|
||||||
- ADDA_BE
|
|
||||||
- DPTX_BE
|
- DPTX_BE
|
||||||
- ETDM1_IN_BE
|
- ETDM1_IN_BE
|
||||||
- ETDM2_IN_BE
|
- ETDM2_IN_BE
|
||||||
|
@ -62,11 +63,28 @@ patternProperties:
|
||||||
required:
|
required:
|
||||||
- sound-dai
|
- sound-dai
|
||||||
|
|
||||||
|
dai-format:
|
||||||
|
description: audio format.
|
||||||
|
items:
|
||||||
|
enum:
|
||||||
|
- i2s
|
||||||
|
- right_j
|
||||||
|
- left_j
|
||||||
|
- dsp_a
|
||||||
|
- dsp_b
|
||||||
|
|
||||||
|
mediatek,clk-provider:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/string
|
||||||
|
description: Indicates dai-link clock master.
|
||||||
|
items:
|
||||||
|
enum:
|
||||||
|
- cpu
|
||||||
|
- codec
|
||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- link-name
|
- link-name
|
||||||
- codec
|
|
||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
|
@ -87,7 +105,8 @@ examples:
|
||||||
"AIN1", "Headset Mic";
|
"AIN1", "Headset Mic";
|
||||||
dai-link-0 {
|
dai-link-0 {
|
||||||
link-name = "ETDM3_OUT_BE";
|
link-name = "ETDM3_OUT_BE";
|
||||||
|
dai-format = "i2s";
|
||||||
|
mediatek,clk-provider = "cpu";
|
||||||
codec {
|
codec {
|
||||||
sound-dai = <&hdmi0>;
|
sound-dai = <&hdmi0>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -225,6 +225,10 @@ config SND_SOC_MT8188_MT6359
|
||||||
depends on SND_SOC_MT8188 && MTK_PMIC_WRAP
|
depends on SND_SOC_MT8188 && MTK_PMIC_WRAP
|
||||||
select SND_SOC_MT6359
|
select SND_SOC_MT6359
|
||||||
select SND_SOC_HDMI_CODEC
|
select SND_SOC_HDMI_CODEC
|
||||||
|
select SND_SOC_DMIC
|
||||||
|
select SND_SOC_MAX98390
|
||||||
|
select SND_SOC_NAU8315
|
||||||
|
select SND_SOC_NAU8825
|
||||||
help
|
help
|
||||||
This adds support for ASoC machine driver for MediaTek MT8188
|
This adds support for ASoC machine driver for MediaTek MT8188
|
||||||
boards with the MT6359 and other I2S audio codecs.
|
boards with the MT6359 and other I2S audio codecs.
|
||||||
|
|
|
@ -21,8 +21,10 @@ static int set_card_codec_info(struct snd_soc_card *card,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
codec_node = of_get_child_by_name(sub_node, "codec");
|
codec_node = of_get_child_by_name(sub_node, "codec");
|
||||||
if (!codec_node)
|
if (!codec_node) {
|
||||||
return -EINVAL;
|
dev_dbg(dev, "%s no specified codec\n", dai_link->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* set card codec info */
|
/* set card codec info */
|
||||||
ret = snd_soc_of_get_dai_link_codecs(dev, codec_node, dai_link);
|
ret = snd_soc_of_get_dai_link_codecs(dev, codec_node, dai_link);
|
||||||
|
@ -36,6 +38,47 @@ static int set_card_codec_info(struct snd_soc_card *card,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_dailink_daifmt(struct snd_soc_card *card,
|
||||||
|
struct device_node *sub_node,
|
||||||
|
struct snd_soc_dai_link *dai_link)
|
||||||
|
{
|
||||||
|
unsigned int daifmt;
|
||||||
|
const char *str;
|
||||||
|
int ret;
|
||||||
|
struct {
|
||||||
|
char *name;
|
||||||
|
unsigned int val;
|
||||||
|
} of_clk_table[] = {
|
||||||
|
{ "cpu", SND_SOC_DAIFMT_CBC_CFC },
|
||||||
|
{ "codec", SND_SOC_DAIFMT_CBP_CFP },
|
||||||
|
};
|
||||||
|
|
||||||
|
daifmt = snd_soc_daifmt_parse_format(sub_node, NULL);
|
||||||
|
if (daifmt) {
|
||||||
|
dai_link->dai_fmt &= SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
|
||||||
|
dai_link->dai_fmt |= daifmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check "mediatek,clk-provider = xxx"
|
||||||
|
* SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK area
|
||||||
|
*/
|
||||||
|
ret = of_property_read_string(sub_node, "mediatek,clk-provider", &str);
|
||||||
|
if (ret == 0) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(of_clk_table); i++) {
|
||||||
|
if (strcmp(str, of_clk_table[i].name) == 0) {
|
||||||
|
dai_link->dai_fmt &= ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
|
||||||
|
dai_link->dai_fmt |= of_clk_table[i].val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int parse_dai_link_info(struct snd_soc_card *card)
|
int parse_dai_link_info(struct snd_soc_card *card)
|
||||||
{
|
{
|
||||||
struct device *dev = card->dev;
|
struct device *dev = card->dev;
|
||||||
|
@ -67,6 +110,12 @@ int parse_dai_link_info(struct snd_soc_card *card)
|
||||||
of_node_put(sub_node);
|
of_node_put(sub_node);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = set_dailink_daifmt(card, sub_node, dai_link);
|
||||||
|
if (ret < 0) {
|
||||||
|
of_node_put(sub_node);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -39,7 +39,7 @@ enum {
|
||||||
MT8188_AFE_MEMIF_END,
|
MT8188_AFE_MEMIF_END,
|
||||||
MT8188_AFE_MEMIF_NUM = (MT8188_AFE_MEMIF_END - MT8188_AFE_MEMIF_START),
|
MT8188_AFE_MEMIF_NUM = (MT8188_AFE_MEMIF_END - MT8188_AFE_MEMIF_START),
|
||||||
MT8188_AFE_IO_START = MT8188_AFE_MEMIF_END,
|
MT8188_AFE_IO_START = MT8188_AFE_MEMIF_END,
|
||||||
MT8188_AFE_IO_ADDA = MT8188_AFE_IO_START,
|
MT8188_AFE_IO_DL_SRC = MT8188_AFE_IO_START,
|
||||||
MT8188_AFE_IO_DMIC_IN,
|
MT8188_AFE_IO_DMIC_IN,
|
||||||
MT8188_AFE_IO_DPTX,
|
MT8188_AFE_IO_DPTX,
|
||||||
MT8188_AFE_IO_ETDM_START,
|
MT8188_AFE_IO_ETDM_START,
|
||||||
|
@ -52,6 +52,7 @@ enum {
|
||||||
MT8188_AFE_IO_ETDM_NUM =
|
MT8188_AFE_IO_ETDM_NUM =
|
||||||
(MT8188_AFE_IO_ETDM_END - MT8188_AFE_IO_ETDM_START),
|
(MT8188_AFE_IO_ETDM_END - MT8188_AFE_IO_ETDM_START),
|
||||||
MT8188_AFE_IO_PCM = MT8188_AFE_IO_ETDM_END,
|
MT8188_AFE_IO_PCM = MT8188_AFE_IO_ETDM_END,
|
||||||
|
MT8188_AFE_IO_UL_SRC,
|
||||||
MT8188_AFE_IO_END,
|
MT8188_AFE_IO_END,
|
||||||
MT8188_AFE_IO_NUM = (MT8188_AFE_IO_END - MT8188_AFE_IO_START),
|
MT8188_AFE_IO_NUM = (MT8188_AFE_IO_END - MT8188_AFE_IO_START),
|
||||||
MT8188_DAI_END = MT8188_AFE_IO_END,
|
MT8188_DAI_END = MT8188_AFE_IO_END,
|
||||||
|
|
|
@ -53,8 +53,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mtk_dai_adda_priv {
|
struct mtk_dai_adda_priv {
|
||||||
unsigned int dl_rate;
|
bool hires_required;
|
||||||
unsigned int ul_rate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
|
static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
|
||||||
|
@ -241,42 +240,35 @@ static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source,
|
static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
struct mt8188_afe_private *afe_priv = afe->platform_priv;
|
||||||
|
|
||||||
|
if (strstr(name, "aud_adc_hires"))
|
||||||
|
return afe_priv->dai_priv[MT8188_AFE_IO_UL_SRC];
|
||||||
|
else if (strstr(name, "aud_dac_hires"))
|
||||||
|
return afe_priv->dai_priv[MT8188_AFE_IO_DL_SRC];
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,
|
||||||
struct snd_soc_dapm_widget *sink)
|
struct snd_soc_dapm_widget *sink)
|
||||||
{
|
{
|
||||||
struct snd_soc_dapm_widget *w = source;
|
struct snd_soc_dapm_widget *w = source;
|
||||||
struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
|
struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
|
||||||
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
|
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
|
||||||
struct mt8188_afe_private *afe_priv = afe->platform_priv;
|
|
||||||
struct mtk_dai_adda_priv *adda_priv;
|
struct mtk_dai_adda_priv *adda_priv;
|
||||||
|
|
||||||
adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA];
|
adda_priv = get_adda_priv_by_name(afe, w->name);
|
||||||
|
|
||||||
if (!adda_priv) {
|
if (!adda_priv) {
|
||||||
dev_err(afe->dev, "%s adda_priv == NULL", __func__);
|
dev_dbg(afe->dev, "adda_priv == NULL");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!(adda_priv->ul_rate > ADDA_HIRES_THRES);
|
return (adda_priv->hires_required) ? 1 : 0;
|
||||||
}
|
|
||||||
|
|
||||||
static int mtk_afe_dac_hires_connect(struct snd_soc_dapm_widget *source,
|
|
||||||
struct snd_soc_dapm_widget *sink)
|
|
||||||
{
|
|
||||||
struct snd_soc_dapm_widget *w = source;
|
|
||||||
struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
|
|
||||||
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
|
|
||||||
struct mt8188_afe_private *afe_priv = afe->platform_priv;
|
|
||||||
struct mtk_dai_adda_priv *adda_priv;
|
|
||||||
|
|
||||||
adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA];
|
|
||||||
|
|
||||||
if (!adda_priv) {
|
|
||||||
dev_err(afe->dev, "%s adda_priv == NULL", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !!(adda_priv->dl_rate > ADDA_HIRES_THRES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
|
static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
|
||||||
|
@ -361,7 +353,7 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
|
||||||
{"ADDA Capture", NULL, "ADDA Capture Enable"},
|
{"ADDA Capture", NULL, "ADDA Capture Enable"},
|
||||||
{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
|
{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
|
||||||
{"ADDA Capture", NULL, "aud_adc"},
|
{"ADDA Capture", NULL, "aud_adc"},
|
||||||
{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adc_hires_connect},
|
{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},
|
||||||
|
|
||||||
{"I168", NULL, "ADDA Capture"},
|
{"I168", NULL, "ADDA Capture"},
|
||||||
{"I169", NULL, "ADDA Capture"},
|
{"I169", NULL, "ADDA Capture"},
|
||||||
|
@ -369,7 +361,7 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
|
||||||
{"ADDA Playback", NULL, "ADDA Enable"},
|
{"ADDA Playback", NULL, "ADDA Enable"},
|
||||||
{"ADDA Playback", NULL, "ADDA Playback Enable"},
|
{"ADDA Playback", NULL, "ADDA Playback Enable"},
|
||||||
{"ADDA Playback", NULL, "aud_dac"},
|
{"ADDA Playback", NULL, "aud_dac"},
|
||||||
{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_dac_hires_connect},
|
{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},
|
||||||
|
|
||||||
{"DL_GAIN", NULL, "O176"},
|
{"DL_GAIN", NULL, "O176"},
|
||||||
{"DL_GAIN", NULL, "O177"},
|
{"DL_GAIN", NULL, "O177"},
|
||||||
|
@ -503,13 +495,12 @@ static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
|
||||||
dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %u\n",
|
dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %u\n",
|
||||||
__func__, id, substream->stream, rate);
|
__func__, id, substream->stream, rate);
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
adda_priv->hires_required = (rate > ADDA_HIRES_THRES);
|
||||||
adda_priv->dl_rate = rate;
|
|
||||||
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||||
ret = mtk_dai_da_configure(afe, rate, id);
|
ret = mtk_dai_da_configure(afe, rate, id);
|
||||||
} else {
|
else
|
||||||
adda_priv->ul_rate = rate;
|
|
||||||
ret = mtk_dai_ad_configure(afe, rate, id);
|
ret = mtk_dai_ad_configure(afe, rate, id);
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -536,8 +527,8 @@ static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
|
||||||
|
|
||||||
static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
|
static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
|
||||||
{
|
{
|
||||||
.name = "ADDA",
|
.name = "DL_SRC",
|
||||||
.id = MT8188_AFE_IO_ADDA,
|
.id = MT8188_AFE_IO_DL_SRC,
|
||||||
.playback = {
|
.playback = {
|
||||||
.stream_name = "ADDA Playback",
|
.stream_name = "ADDA Playback",
|
||||||
.channels_min = 1,
|
.channels_min = 1,
|
||||||
|
@ -545,6 +536,11 @@ static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
|
||||||
.rates = MTK_ADDA_PLAYBACK_RATES,
|
.rates = MTK_ADDA_PLAYBACK_RATES,
|
||||||
.formats = MTK_ADDA_FORMATS,
|
.formats = MTK_ADDA_FORMATS,
|
||||||
},
|
},
|
||||||
|
.ops = &mtk_dai_adda_ops,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "UL_SRC",
|
||||||
|
.id = MT8188_AFE_IO_UL_SRC,
|
||||||
.capture = {
|
.capture = {
|
||||||
.stream_name = "ADDA Capture",
|
.stream_name = "ADDA Capture",
|
||||||
.channels_min = 1,
|
.channels_min = 1,
|
||||||
|
@ -560,13 +556,18 @@ static int init_adda_priv_data(struct mtk_base_afe *afe)
|
||||||
{
|
{
|
||||||
struct mt8188_afe_private *afe_priv = afe->platform_priv;
|
struct mt8188_afe_private *afe_priv = afe->platform_priv;
|
||||||
struct mtk_dai_adda_priv *adda_priv;
|
struct mtk_dai_adda_priv *adda_priv;
|
||||||
|
int adda_dai_list[] = {MT8188_AFE_IO_DL_SRC, MT8188_AFE_IO_UL_SRC};
|
||||||
|
int i;
|
||||||
|
|
||||||
adda_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_adda_priv),
|
for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {
|
||||||
|
adda_priv = devm_kzalloc(afe->dev,
|
||||||
|
sizeof(struct mtk_dai_adda_priv),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!adda_priv)
|
if (!adda_priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
afe_priv->dai_priv[MT8188_AFE_IO_ADDA] = adda_priv;
|
afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* Author: Trevor Wu <trevor.wu@mediatek.com>
|
* Author: Trevor Wu <trevor.wu@mediatek.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
|
@ -13,10 +14,27 @@
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
#include "mt8188-afe-common.h"
|
#include "mt8188-afe-common.h"
|
||||||
|
#include "../../codecs/nau8825.h"
|
||||||
#include "../../codecs/mt6359.h"
|
#include "../../codecs/mt6359.h"
|
||||||
#include "../common/mtk-afe-platform-driver.h"
|
#include "../common/mtk-afe-platform-driver.h"
|
||||||
#include "../common/mtk-soundcard-driver.h"
|
#include "../common/mtk-soundcard-driver.h"
|
||||||
|
|
||||||
|
#define NAU8825_HS_PRESENT BIT(0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maxim MAX98390
|
||||||
|
*/
|
||||||
|
#define MAX98390_CODEC_DAI "max98390-aif1"
|
||||||
|
#define MAX98390_DEV0_NAME "max98390.0-0038" /* rear right */
|
||||||
|
#define MAX98390_DEV1_NAME "max98390.0-0039" /* rear left */
|
||||||
|
#define MAX98390_DEV2_NAME "max98390.0-003a" /* front right */
|
||||||
|
#define MAX98390_DEV3_NAME "max98390.0-003b" /* front left */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nau88l25
|
||||||
|
*/
|
||||||
|
#define NAU8825_CODEC_DAI "nau8825-hifi"
|
||||||
|
|
||||||
/* FE */
|
/* FE */
|
||||||
SND_SOC_DAILINK_DEFS(playback2,
|
SND_SOC_DAILINK_DEFS(playback2,
|
||||||
DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
|
DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
|
||||||
|
@ -99,8 +117,8 @@ SND_SOC_DAILINK_DEFS(capture10,
|
||||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||||
|
|
||||||
/* BE */
|
/* BE */
|
||||||
SND_SOC_DAILINK_DEFS(adda,
|
SND_SOC_DAILINK_DEFS(dl_src,
|
||||||
DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
|
DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")),
|
||||||
DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
|
DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
|
||||||
"mt6359-snd-codec-aif1")),
|
"mt6359-snd-codec-aif1")),
|
||||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||||
|
@ -140,9 +158,44 @@ SND_SOC_DAILINK_DEFS(pcm1,
|
||||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||||
|
|
||||||
|
SND_SOC_DAILINK_DEFS(ul_src,
|
||||||
|
DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC")),
|
||||||
|
DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
|
||||||
|
"mt6359-snd-codec-aif1"),
|
||||||
|
COMP_CODEC("dmic-codec",
|
||||||
|
"dmic-hifi")),
|
||||||
|
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||||
|
|
||||||
struct mt8188_mt6359_priv {
|
struct mt8188_mt6359_priv {
|
||||||
struct snd_soc_jack dp_jack;
|
struct snd_soc_jack dp_jack;
|
||||||
struct snd_soc_jack hdmi_jack;
|
struct snd_soc_jack hdmi_jack;
|
||||||
|
struct snd_soc_jack headset_jack;
|
||||||
|
void *private_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct snd_soc_jack_pin mt8188_hdmi_jack_pins[] = {
|
||||||
|
{
|
||||||
|
.pin = "HDMI",
|
||||||
|
.mask = SND_JACK_LINEOUT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct snd_soc_jack_pin mt8188_dp_jack_pins[] = {
|
||||||
|
{
|
||||||
|
.pin = "DP",
|
||||||
|
.mask = SND_JACK_LINEOUT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct snd_soc_jack_pin nau8825_jack_pins[] = {
|
||||||
|
{
|
||||||
|
.pin = "Headphone Jack",
|
||||||
|
.mask = SND_JACK_HEADPHONE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.pin = "Headset Mic",
|
||||||
|
.mask = SND_JACK_MICROPHONE,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mt8188_card_data {
|
struct mt8188_card_data {
|
||||||
|
@ -150,9 +203,39 @@ struct mt8188_card_data {
|
||||||
unsigned long quirk;
|
unsigned long quirk;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new mt8188_dumb_spk_controls[] = {
|
||||||
|
SOC_DAPM_PIN_SWITCH("Ext Spk"),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_widget mt8188_dumb_spk_widgets[] = {
|
||||||
|
SND_SOC_DAPM_SPK("Ext Spk", NULL),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new mt8188_dual_spk_controls[] = {
|
||||||
|
SOC_DAPM_PIN_SWITCH("Left Spk"),
|
||||||
|
SOC_DAPM_PIN_SWITCH("Right Spk"),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_widget mt8188_dual_spk_widgets[] = {
|
||||||
|
SND_SOC_DAPM_SPK("Left Spk", NULL),
|
||||||
|
SND_SOC_DAPM_SPK("Right Spk", NULL),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new mt8188_rear_spk_controls[] = {
|
||||||
|
SOC_DAPM_PIN_SWITCH("Rear Left Spk"),
|
||||||
|
SOC_DAPM_PIN_SWITCH("Rear Right Spk"),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_widget mt8188_rear_spk_widgets[] = {
|
||||||
|
SND_SOC_DAPM_SPK("Rear Left Spk", NULL),
|
||||||
|
SND_SOC_DAPM_SPK("Rear Right Spk", NULL),
|
||||||
|
};
|
||||||
|
|
||||||
static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = {
|
static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = {
|
||||||
SND_SOC_DAPM_HP("Headphone", NULL),
|
SND_SOC_DAPM_HP("Headphone", NULL),
|
||||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||||
|
SND_SOC_DAPM_SINK("HDMI"),
|
||||||
|
SND_SOC_DAPM_SINK("DP"),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new mt8188_mt6359_controls[] = {
|
static const struct snd_kcontrol_new mt8188_mt6359_controls[] = {
|
||||||
|
@ -160,6 +243,14 @@ static const struct snd_kcontrol_new mt8188_mt6359_controls[] = {
|
||||||
SOC_DAPM_PIN_SWITCH("Headset Mic"),
|
SOC_DAPM_PIN_SWITCH("Headset Mic"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_widget mt8188_nau8825_widgets[] = {
|
||||||
|
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new mt8188_nau8825_controls[] = {
|
||||||
|
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
|
||||||
|
};
|
||||||
|
|
||||||
#define CKSYS_AUD_TOP_CFG 0x032c
|
#define CKSYS_AUD_TOP_CFG 0x032c
|
||||||
#define CKSYS_AUD_TOP_MON 0x0330
|
#define CKSYS_AUD_TOP_MON 0x0330
|
||||||
|
|
||||||
|
@ -345,7 +436,7 @@ enum {
|
||||||
DAI_LINK_UL8_FE,
|
DAI_LINK_UL8_FE,
|
||||||
DAI_LINK_UL9_FE,
|
DAI_LINK_UL9_FE,
|
||||||
DAI_LINK_UL10_FE,
|
DAI_LINK_UL10_FE,
|
||||||
DAI_LINK_ADDA_BE,
|
DAI_LINK_DL_SRC_BE,
|
||||||
DAI_LINK_DPTX_BE,
|
DAI_LINK_DPTX_BE,
|
||||||
DAI_LINK_ETDM1_IN_BE,
|
DAI_LINK_ETDM1_IN_BE,
|
||||||
DAI_LINK_ETDM2_IN_BE,
|
DAI_LINK_ETDM2_IN_BE,
|
||||||
|
@ -353,6 +444,7 @@ enum {
|
||||||
DAI_LINK_ETDM2_OUT_BE,
|
DAI_LINK_ETDM2_OUT_BE,
|
||||||
DAI_LINK_ETDM3_OUT_BE,
|
DAI_LINK_ETDM3_OUT_BE,
|
||||||
DAI_LINK_PCM1_BE,
|
DAI_LINK_PCM1_BE,
|
||||||
|
DAI_LINK_UL_SRC_BE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mt8188_dptx_hw_params(struct snd_pcm_substream *substream,
|
static int mt8188_dptx_hw_params(struct snd_pcm_substream *substream,
|
||||||
|
@ -389,8 +481,10 @@ static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
|
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
|
ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack",
|
||||||
&priv->hdmi_jack);
|
SND_JACK_LINEOUT, &priv->hdmi_jack,
|
||||||
|
mt8188_hdmi_jack_pins,
|
||||||
|
ARRAY_SIZE(mt8188_hdmi_jack_pins));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_info(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);
|
dev_info(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -410,8 +504,9 @@ static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
|
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT,
|
ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT,
|
||||||
&priv->dp_jack);
|
&priv->dp_jack, mt8188_dp_jack_pins,
|
||||||
|
ARRAY_SIZE(mt8188_dp_jack_pins));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_info(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);
|
dev_info(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -425,6 +520,189 @@ static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mt8188_dumb_amp_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
|
{
|
||||||
|
struct snd_soc_card *card = rtd->card;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dumb_spk_widgets,
|
||||||
|
ARRAY_SIZE(mt8188_dumb_spk_widgets));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_soc_add_card_controls(card, mt8188_dumb_spk_controls,
|
||||||
|
ARRAY_SIZE(mt8188_dumb_spk_controls));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt8188_max98390_hw_params(struct snd_pcm_substream *substream,
|
||||||
|
struct snd_pcm_hw_params *params)
|
||||||
|
{
|
||||||
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
|
unsigned int bit_width = params_width(params);
|
||||||
|
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||||
|
struct snd_soc_dai *codec_dai;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0xf, 4, bit_width);
|
||||||
|
|
||||||
|
for_each_rtd_codec_dais(rtd, i, codec_dai) {
|
||||||
|
if (!strcmp(codec_dai->component->name, MAX98390_DEV0_NAME))
|
||||||
|
snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x3, 4, bit_width);
|
||||||
|
|
||||||
|
if (!strcmp(codec_dai->component->name, MAX98390_DEV1_NAME))
|
||||||
|
snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x3, 4, bit_width);
|
||||||
|
|
||||||
|
if (!strcmp(codec_dai->component->name, MAX98390_DEV2_NAME))
|
||||||
|
snd_soc_dai_set_tdm_slot(codec_dai, 0x2, 0x3, 4, bit_width);
|
||||||
|
|
||||||
|
if (!strcmp(codec_dai->component->name, MAX98390_DEV3_NAME))
|
||||||
|
snd_soc_dai_set_tdm_slot(codec_dai, 0x1, 0x3, 4, bit_width);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct snd_soc_ops mt8188_max98390_ops = {
|
||||||
|
.hw_params = mt8188_max98390_hw_params,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
|
{
|
||||||
|
struct snd_soc_card *card = rtd->card;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* add regular speakers dapm route */
|
||||||
|
ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dual_spk_widgets,
|
||||||
|
ARRAY_SIZE(mt8188_dual_spk_widgets));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "unable to add Left/Right Speaker widget, ret %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_soc_add_card_controls(card, mt8188_dual_spk_controls,
|
||||||
|
ARRAY_SIZE(mt8188_dual_spk_controls));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "unable to add Left/Right card controls, ret %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtd->dai_link->num_codecs <= 2)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* add widgets/controls/dapm for rear speakers */
|
||||||
|
ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_rear_spk_widgets,
|
||||||
|
ARRAY_SIZE(mt8188_rear_spk_widgets));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "unable to add Rear Speaker widget, ret %d\n", ret);
|
||||||
|
/* Don't need to add routes if widget addition failed */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_soc_add_card_controls(card, mt8188_rear_spk_controls,
|
||||||
|
ARRAY_SIZE(mt8188_rear_spk_controls));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "unable to add Rear card controls, ret %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt8188_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
|
{
|
||||||
|
struct snd_soc_card *card = rtd->card;
|
||||||
|
struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(card);
|
||||||
|
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
|
||||||
|
struct snd_soc_jack *jack = &priv->headset_jack;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_nau8825_widgets,
|
||||||
|
ARRAY_SIZE(mt8188_nau8825_widgets));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_soc_add_card_controls(card, mt8188_nau8825_controls,
|
||||||
|
ARRAY_SIZE(mt8188_nau8825_controls));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
|
||||||
|
SND_JACK_HEADSET | SND_JACK_BTN_0 |
|
||||||
|
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
|
||||||
|
SND_JACK_BTN_3,
|
||||||
|
jack,
|
||||||
|
nau8825_jack_pins,
|
||||||
|
ARRAY_SIZE(nau8825_jack_pins));
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
|
||||||
|
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
|
||||||
|
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
|
||||||
|
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
|
||||||
|
ret = snd_soc_component_set_jack(component, jack, NULL);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mt8188_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd)
|
||||||
|
{
|
||||||
|
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
|
||||||
|
|
||||||
|
snd_soc_component_set_jack(component, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt8188_nau8825_hw_params(struct snd_pcm_substream *substream,
|
||||||
|
struct snd_pcm_hw_params *params)
|
||||||
|
{
|
||||||
|
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||||
|
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||||
|
unsigned int rate = params_rate(params);
|
||||||
|
unsigned int bit_width = params_width(params);
|
||||||
|
int clk_freq, ret;
|
||||||
|
|
||||||
|
clk_freq = rate * 2 * bit_width;
|
||||||
|
|
||||||
|
/* Configure clock for codec */
|
||||||
|
ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0,
|
||||||
|
SND_SOC_CLOCK_IN);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure pll for codec */
|
||||||
|
ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq,
|
||||||
|
params_rate(params) * 256);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct snd_soc_ops mt8188_nau8825_ops = {
|
||||||
|
.hw_params = mt8188_nau8825_hw_params,
|
||||||
|
};
|
||||||
static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {
|
static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {
|
||||||
/* FE */
|
/* FE */
|
||||||
[DAI_LINK_DL2_FE] = {
|
[DAI_LINK_DL2_FE] = {
|
||||||
|
@ -604,13 +882,11 @@ static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {
|
||||||
SND_SOC_DAILINK_REG(capture10),
|
SND_SOC_DAILINK_REG(capture10),
|
||||||
},
|
},
|
||||||
/* BE */
|
/* BE */
|
||||||
[DAI_LINK_ADDA_BE] = {
|
[DAI_LINK_DL_SRC_BE] = {
|
||||||
.name = "ADDA_BE",
|
.name = "DL_SRC_BE",
|
||||||
.no_pcm = 1,
|
.no_pcm = 1,
|
||||||
.dpcm_playback = 1,
|
.dpcm_playback = 1,
|
||||||
.dpcm_capture = 1,
|
SND_SOC_DAILINK_REG(dl_src),
|
||||||
.init = mt8188_mt6359_init,
|
|
||||||
SND_SOC_DAILINK_REG(adda),
|
|
||||||
},
|
},
|
||||||
[DAI_LINK_DPTX_BE] = {
|
[DAI_LINK_DPTX_BE] = {
|
||||||
.name = "DPTX_BE",
|
.name = "DPTX_BE",
|
||||||
|
@ -676,8 +952,48 @@ static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {
|
||||||
.dpcm_capture = 1,
|
.dpcm_capture = 1,
|
||||||
SND_SOC_DAILINK_REG(pcm1),
|
SND_SOC_DAILINK_REG(pcm1),
|
||||||
},
|
},
|
||||||
|
[DAI_LINK_UL_SRC_BE] = {
|
||||||
|
.name = "UL_SRC_BE",
|
||||||
|
.no_pcm = 1,
|
||||||
|
.dpcm_capture = 1,
|
||||||
|
SND_SOC_DAILINK_REG(ul_src),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
|
||||||
|
{
|
||||||
|
struct snd_ctl_elem_id sid;
|
||||||
|
|
||||||
|
memset(&sid, 0, sizeof(sid));
|
||||||
|
strcpy(sid.name, name);
|
||||||
|
sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||||
|
return snd_ctl_find_id(card, &sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mt8188_fixup_controls(struct snd_soc_card *card)
|
||||||
|
{
|
||||||
|
struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(card);
|
||||||
|
struct mt8188_card_data *card_data = (struct mt8188_card_data *)priv->private_data;
|
||||||
|
struct snd_kcontrol *kctl;
|
||||||
|
|
||||||
|
if (card_data->quirk & NAU8825_HS_PRESENT) {
|
||||||
|
struct snd_soc_dapm_widget *w, *next_w;
|
||||||
|
|
||||||
|
for_each_card_widgets_safe(card, w, next_w) {
|
||||||
|
if (strcmp(w->name, "Headphone"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snd_soc_dapm_free_widget(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
kctl = ctl_find(card->snd_card, "Headphone Switch");
|
||||||
|
if (kctl)
|
||||||
|
snd_ctl_remove(card->snd_card, kctl);
|
||||||
|
else
|
||||||
|
dev_warn(card->dev, "Cannot find ctl : Headphone Switch\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct snd_soc_card mt8188_mt6359_soc_card = {
|
static struct snd_soc_card mt8188_mt6359_soc_card = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.dai_link = mt8188_mt6359_dai_links,
|
.dai_link = mt8188_mt6359_dai_links,
|
||||||
|
@ -686,6 +1002,7 @@ static struct snd_soc_card mt8188_mt6359_soc_card = {
|
||||||
.num_dapm_widgets = ARRAY_SIZE(mt8188_mt6359_widgets),
|
.num_dapm_widgets = ARRAY_SIZE(mt8188_mt6359_widgets),
|
||||||
.controls = mt8188_mt6359_controls,
|
.controls = mt8188_mt6359_controls,
|
||||||
.num_controls = ARRAY_SIZE(mt8188_mt6359_controls),
|
.num_controls = ARRAY_SIZE(mt8188_mt6359_controls),
|
||||||
|
.fixup_controls = mt8188_fixup_controls,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
|
static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
|
||||||
|
@ -695,6 +1012,10 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
|
||||||
struct mt8188_mt6359_priv *priv;
|
struct mt8188_mt6359_priv *priv;
|
||||||
struct mt8188_card_data *card_data;
|
struct mt8188_card_data *card_data;
|
||||||
struct snd_soc_dai_link *dai_link;
|
struct snd_soc_dai_link *dai_link;
|
||||||
|
bool init_mt6359 = false;
|
||||||
|
bool init_nau8825 = false;
|
||||||
|
bool init_max98390 = false;
|
||||||
|
bool init_dumb = false;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
card_data = (struct mt8188_card_data *)of_device_get_match_data(&pdev->dev);
|
card_data = (struct mt8188_card_data *)of_device_get_match_data(&pdev->dev);
|
||||||
|
@ -739,9 +1060,41 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
|
||||||
} else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
|
} else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
|
||||||
if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
||||||
dai_link->init = mt8188_hdmi_codec_init;
|
dai_link->init = mt8188_hdmi_codec_init;
|
||||||
|
} else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 ||
|
||||||
|
strcmp(dai_link->name, "UL_SRC_BE") == 0) {
|
||||||
|
if (!init_mt6359) {
|
||||||
|
dai_link->init = mt8188_mt6359_init;
|
||||||
|
init_mt6359 = true;
|
||||||
|
}
|
||||||
|
} else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0 ||
|
||||||
|
strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 ||
|
||||||
|
strcmp(dai_link->name, "ETDM1_IN_BE") == 0 ||
|
||||||
|
strcmp(dai_link->name, "ETDM2_IN_BE") == 0) {
|
||||||
|
if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) {
|
||||||
|
dai_link->ops = &mt8188_max98390_ops;
|
||||||
|
if (!init_max98390) {
|
||||||
|
dai_link->init = mt8188_max98390_codec_init;
|
||||||
|
init_max98390 = true;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) {
|
||||||
|
dai_link->ops = &mt8188_nau8825_ops;
|
||||||
|
if (!init_nau8825) {
|
||||||
|
dai_link->init = mt8188_nau8825_codec_init;
|
||||||
|
dai_link->exit = mt8188_nau8825_codec_exit;
|
||||||
|
init_nau8825 = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) {
|
||||||
|
if (!init_dumb) {
|
||||||
|
dai_link->init = mt8188_dumb_amp_init;
|
||||||
|
init_dumb = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->private_data = card_data;
|
||||||
snd_soc_card_set_drvdata(card, priv);
|
snd_soc_card_set_drvdata(card, priv);
|
||||||
|
|
||||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||||
|
@ -758,11 +1111,20 @@ static struct mt8188_card_data mt8188_evb_card = {
|
||||||
.name = "mt8188_mt6359",
|
.name = "mt8188_mt6359",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct mt8188_card_data mt8188_nau8825_card = {
|
||||||
|
.name = "mt8188_nau8825",
|
||||||
|
.quirk = NAU8825_HS_PRESENT,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id mt8188_mt6359_dt_match[] = {
|
static const struct of_device_id mt8188_mt6359_dt_match[] = {
|
||||||
{
|
{
|
||||||
.compatible = "mediatek,mt8188-mt6359-evb",
|
.compatible = "mediatek,mt8188-mt6359-evb",
|
||||||
.data = &mt8188_evb_card,
|
.data = &mt8188_evb_card,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.compatible = "mediatek,mt8188-nau8825",
|
||||||
|
.data = &mt8188_nau8825_card,
|
||||||
|
},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, mt8188_mt6359_dt_match);
|
MODULE_DEVICE_TABLE(of, mt8188_mt6359_dt_match);
|
||||||
|
|
|
@ -2216,6 +2216,16 @@ static void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
|
||||||
&dapm_widget_power_fops);
|
&dapm_widget_power_fops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dapm_debugfs_free_widget(struct snd_soc_dapm_widget *w)
|
||||||
|
{
|
||||||
|
struct snd_soc_dapm_context *dapm = w->dapm;
|
||||||
|
|
||||||
|
if (!dapm->debugfs_dapm || !w->name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
debugfs_lookup_and_remove(w->name, dapm->debugfs_dapm);
|
||||||
|
}
|
||||||
|
|
||||||
static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
|
static void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
|
||||||
{
|
{
|
||||||
debugfs_remove_recursive(dapm->debugfs_dapm);
|
debugfs_remove_recursive(dapm->debugfs_dapm);
|
||||||
|
@ -2232,6 +2242,10 @@ static inline void dapm_debugfs_add_widget(struct snd_soc_dapm_widget *w)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void dapm_debugfs_free_widget(struct snd_soc_dapm_widget *w)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
|
static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -2495,6 +2509,8 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w)
|
||||||
dapm_free_path(p);
|
dapm_free_path(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dapm_debugfs_free_widget(w);
|
||||||
|
|
||||||
kfree(w->kcontrols);
|
kfree(w->kcontrols);
|
||||||
kfree_const(w->name);
|
kfree_const(w->name);
|
||||||
kfree_const(w->sname);
|
kfree_const(w->sname);
|
||||||
|
|
Loading…
Reference in New Issue