Path: blob/master/sound/soc/mediatek/mt7986/mt7986-wm8960.c
26488 views
// SPDX-License-Identifier: GPL-2.01/*2* mt7986-wm8960.c -- MT7986-WM8960 ALSA SoC machine driver3*4* Copyright (c) 2023 MediaTek Inc.5* Authors: Vic Wu <[email protected]>6* Maso Huang <[email protected]>7*/89#include <linux/module.h>10#include <sound/soc.h>1112#include "mt7986-afe-common.h"1314static const struct snd_soc_dapm_widget mt7986_wm8960_widgets[] = {15SND_SOC_DAPM_HP("Headphone", NULL),16SND_SOC_DAPM_MIC("AMIC", NULL),17};1819static const struct snd_kcontrol_new mt7986_wm8960_controls[] = {20SOC_DAPM_PIN_SWITCH("Headphone"),21SOC_DAPM_PIN_SWITCH("AMIC"),22};2324SND_SOC_DAILINK_DEFS(playback,25DAILINK_COMP_ARRAY(COMP_CPU("DL1")),26DAILINK_COMP_ARRAY(COMP_DUMMY()),27DAILINK_COMP_ARRAY(COMP_EMPTY()));2829SND_SOC_DAILINK_DEFS(capture,30DAILINK_COMP_ARRAY(COMP_CPU("UL1")),31DAILINK_COMP_ARRAY(COMP_DUMMY()),32DAILINK_COMP_ARRAY(COMP_EMPTY()));3334SND_SOC_DAILINK_DEFS(codec,35DAILINK_COMP_ARRAY(COMP_CPU("ETDM")),36DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8960-hifi")),37DAILINK_COMP_ARRAY(COMP_EMPTY()));3839static struct snd_soc_dai_link mt7986_wm8960_dai_links[] = {40/* FE */41{42.name = "wm8960-playback",43.stream_name = "wm8960-playback",44.trigger = {SND_SOC_DPCM_TRIGGER_POST,45SND_SOC_DPCM_TRIGGER_POST},46.dynamic = 1,47.playback_only = 1,48SND_SOC_DAILINK_REG(playback),49},50{51.name = "wm8960-capture",52.stream_name = "wm8960-capture",53.trigger = {SND_SOC_DPCM_TRIGGER_POST,54SND_SOC_DPCM_TRIGGER_POST},55.dynamic = 1,56.capture_only = 1,57SND_SOC_DAILINK_REG(capture),58},59/* BE */60{61.name = "wm8960-codec",62.no_pcm = 1,63.dai_fmt = SND_SOC_DAIFMT_I2S |64SND_SOC_DAIFMT_NB_NF |65SND_SOC_DAIFMT_CBC_CFC |66SND_SOC_DAIFMT_GATED,67SND_SOC_DAILINK_REG(codec),68},69};7071static struct snd_soc_card mt7986_wm8960_card = {72.name = "mt7986-wm8960",73.owner = THIS_MODULE,74.dai_link = mt7986_wm8960_dai_links,75.num_links = ARRAY_SIZE(mt7986_wm8960_dai_links),76.controls = mt7986_wm8960_controls,77.num_controls = ARRAY_SIZE(mt7986_wm8960_controls),78.dapm_widgets = mt7986_wm8960_widgets,79.num_dapm_widgets = ARRAY_SIZE(mt7986_wm8960_widgets),80};8182static int mt7986_wm8960_machine_probe(struct platform_device *pdev)83{84struct snd_soc_card *card = &mt7986_wm8960_card;85struct snd_soc_dai_link *dai_link;86struct device_node *platform, *codec;87struct device_node *platform_dai_node, *codec_dai_node;88int ret, i;8990card->dev = &pdev->dev;9192platform = of_get_child_by_name(pdev->dev.of_node, "platform");9394if (platform) {95platform_dai_node = of_parse_phandle(platform, "sound-dai", 0);96of_node_put(platform);9798if (!platform_dai_node) {99dev_err(&pdev->dev, "Failed to parse platform/sound-dai property\n");100return -EINVAL;101}102} else {103dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");104return -EINVAL;105}106107for_each_card_prelinks(card, i, dai_link) {108if (dai_link->platforms->name)109continue;110dai_link->platforms->of_node = platform_dai_node;111}112113codec = of_get_child_by_name(pdev->dev.of_node, "codec");114115if (codec) {116codec_dai_node = of_parse_phandle(codec, "sound-dai", 0);117of_node_put(codec);118119if (!codec_dai_node) {120of_node_put(platform_dai_node);121dev_err(&pdev->dev, "Failed to parse codec/sound-dai property\n");122return -EINVAL;123}124} else {125of_node_put(platform_dai_node);126dev_err(&pdev->dev, "Property 'codec' missing or invalid\n");127return -EINVAL;128}129130for_each_card_prelinks(card, i, dai_link) {131if (dai_link->codecs->name)132continue;133dai_link->codecs->of_node = codec_dai_node;134}135136ret = snd_soc_of_parse_audio_routing(card, "audio-routing");137if (ret) {138dev_err(&pdev->dev, "Failed to parse audio-routing: %d\n", ret);139goto err_of_node_put;140}141142ret = devm_snd_soc_register_card(&pdev->dev, card);143if (ret) {144dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__);145goto err_of_node_put;146}147148err_of_node_put:149of_node_put(platform_dai_node);150of_node_put(codec_dai_node);151return ret;152}153154static const struct of_device_id mt7986_wm8960_machine_dt_match[] = {155{.compatible = "mediatek,mt7986-wm8960-sound"},156{ /* sentinel */ }157};158MODULE_DEVICE_TABLE(of, mt7986_wm8960_machine_dt_match);159160static struct platform_driver mt7986_wm8960_machine = {161.driver = {162.name = "mt7986-wm8960",163.of_match_table = mt7986_wm8960_machine_dt_match,164},165.probe = mt7986_wm8960_machine_probe,166};167168module_platform_driver(mt7986_wm8960_machine);169170/* Module information */171MODULE_DESCRIPTION("MT7986 WM8960 ALSA SoC machine driver");172MODULE_AUTHOR("Vic Wu <[email protected]>");173MODULE_LICENSE("GPL");174MODULE_ALIAS("mt7986 wm8960 soc card");175176177