Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Nicolas Belin | 1445 | 99.59% | 1 | 33.33% |
Kuninori Morimoto | 5 | 0.34% | 1 | 33.33% |
Muhammad Usama Anjum | 1 | 0.07% | 1 | 33.33% |
Total | 1451 | 3 |
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
// 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, .playback_only = 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, .playback_only = 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, .capture_only = 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, .capture_only = 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, SND_SOC_DAILINK_REG(i2s3), }, [DAI_LINK_DMIC] = { .name = "DMIC_BE", .no_pcm = 1, .id = DAI_LINK_DMIC, .capture_only = 1, SND_SOC_DAILINK_REG(dmic), }, [DAI_LINK_INT_ADDA] = { .name = "MTK_Codec", .no_pcm = 1, .id = DAI_LINK_INT_ADDA, .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])) { dev_info(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 mt8365_mt6357_priv *mach_priv; int 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");
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1