cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mt2701-wm8960.c (4901B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * mt2701-wm8960.c  --  MT2701 WM8960 ALSA SoC machine driver
      4 *
      5 * Copyright (c) 2017 MediaTek Inc.
      6 * Author: Ryder Lee <ryder.lee@mediatek.com>
      7 */
      8
      9#include <linux/module.h>
     10#include <sound/soc.h>
     11
     12#include "mt2701-afe-common.h"
     13
     14static const struct snd_soc_dapm_widget mt2701_wm8960_widgets[] = {
     15	SND_SOC_DAPM_HP("Headphone", NULL),
     16	SND_SOC_DAPM_MIC("AMIC", NULL),
     17};
     18
     19static const struct snd_kcontrol_new mt2701_wm8960_controls[] = {
     20	SOC_DAPM_PIN_SWITCH("Headphone"),
     21	SOC_DAPM_PIN_SWITCH("AMIC"),
     22};
     23
     24static int mt2701_wm8960_be_ops_hw_params(struct snd_pcm_substream *substream,
     25					  struct snd_pcm_hw_params *params)
     26{
     27	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
     28	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
     29	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
     30	unsigned int mclk_rate;
     31	unsigned int rate = params_rate(params);
     32	unsigned int div_mclk_over_bck = rate > 192000 ? 2 : 4;
     33	unsigned int div_bck_over_lrck = 64;
     34
     35	mclk_rate = rate * div_bck_over_lrck * div_mclk_over_bck;
     36
     37	snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_rate, SND_SOC_CLOCK_OUT);
     38	snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate, SND_SOC_CLOCK_IN);
     39
     40	return 0;
     41}
     42
     43static const struct snd_soc_ops mt2701_wm8960_be_ops = {
     44	.hw_params = mt2701_wm8960_be_ops_hw_params
     45};
     46
     47SND_SOC_DAILINK_DEFS(playback,
     48	DAILINK_COMP_ARRAY(COMP_CPU("PCMO0")),
     49	DAILINK_COMP_ARRAY(COMP_DUMMY()),
     50	DAILINK_COMP_ARRAY(COMP_EMPTY()));
     51
     52SND_SOC_DAILINK_DEFS(capture,
     53	DAILINK_COMP_ARRAY(COMP_CPU("PCM0")),
     54	DAILINK_COMP_ARRAY(COMP_DUMMY()),
     55	DAILINK_COMP_ARRAY(COMP_EMPTY()));
     56
     57SND_SOC_DAILINK_DEFS(codec,
     58	DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
     59	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8960-hifi")),
     60	DAILINK_COMP_ARRAY(COMP_EMPTY()));
     61
     62static struct snd_soc_dai_link mt2701_wm8960_dai_links[] = {
     63	/* FE */
     64	{
     65		.name = "wm8960-playback",
     66		.stream_name = "wm8960-playback",
     67		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
     68			    SND_SOC_DPCM_TRIGGER_POST},
     69		.dynamic = 1,
     70		.dpcm_playback = 1,
     71		SND_SOC_DAILINK_REG(playback),
     72	},
     73	{
     74		.name = "wm8960-capture",
     75		.stream_name = "wm8960-capture",
     76		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
     77			    SND_SOC_DPCM_TRIGGER_POST},
     78		.dynamic = 1,
     79		.dpcm_capture = 1,
     80		SND_SOC_DAILINK_REG(capture),
     81	},
     82	/* BE */
     83	{
     84		.name = "wm8960-codec",
     85		.no_pcm = 1,
     86		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS
     87			| SND_SOC_DAIFMT_GATED,
     88		.ops = &mt2701_wm8960_be_ops,
     89		.dpcm_playback = 1,
     90		.dpcm_capture = 1,
     91		SND_SOC_DAILINK_REG(codec),
     92	},
     93};
     94
     95static struct snd_soc_card mt2701_wm8960_card = {
     96	.name = "mt2701-wm8960",
     97	.owner = THIS_MODULE,
     98	.dai_link = mt2701_wm8960_dai_links,
     99	.num_links = ARRAY_SIZE(mt2701_wm8960_dai_links),
    100	.controls = mt2701_wm8960_controls,
    101	.num_controls = ARRAY_SIZE(mt2701_wm8960_controls),
    102	.dapm_widgets = mt2701_wm8960_widgets,
    103	.num_dapm_widgets = ARRAY_SIZE(mt2701_wm8960_widgets),
    104};
    105
    106static int mt2701_wm8960_machine_probe(struct platform_device *pdev)
    107{
    108	struct snd_soc_card *card = &mt2701_wm8960_card;
    109	struct device_node *platform_node, *codec_node;
    110	struct snd_soc_dai_link *dai_link;
    111	int ret, i;
    112
    113	platform_node = of_parse_phandle(pdev->dev.of_node,
    114					 "mediatek,platform", 0);
    115	if (!platform_node) {
    116		dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
    117		return -EINVAL;
    118	}
    119	for_each_card_prelinks(card, i, dai_link) {
    120		if (dai_link->platforms->name)
    121			continue;
    122		dai_link->platforms->of_node = platform_node;
    123	}
    124
    125	card->dev = &pdev->dev;
    126
    127	codec_node = of_parse_phandle(pdev->dev.of_node,
    128				      "mediatek,audio-codec", 0);
    129	if (!codec_node) {
    130		dev_err(&pdev->dev,
    131			"Property 'audio-codec' missing or invalid\n");
    132		ret = -EINVAL;
    133		goto put_platform_node;
    134	}
    135	for_each_card_prelinks(card, i, dai_link) {
    136		if (dai_link->codecs->name)
    137			continue;
    138		dai_link->codecs->of_node = codec_node;
    139	}
    140
    141	ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
    142	if (ret) {
    143		dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
    144		goto put_codec_node;
    145	}
    146
    147	ret = devm_snd_soc_register_card(&pdev->dev, card);
    148	if (ret)
    149		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
    150			__func__, ret);
    151
    152put_codec_node:
    153	of_node_put(codec_node);
    154put_platform_node:
    155	of_node_put(platform_node);
    156	return ret;
    157}
    158
    159#ifdef CONFIG_OF
    160static const struct of_device_id mt2701_wm8960_machine_dt_match[] = {
    161	{.compatible = "mediatek,mt2701-wm8960-machine",},
    162	{}
    163};
    164#endif
    165
    166static struct platform_driver mt2701_wm8960_machine = {
    167	.driver = {
    168		.name = "mt2701-wm8960",
    169#ifdef CONFIG_OF
    170		.of_match_table = mt2701_wm8960_machine_dt_match,
    171#endif
    172	},
    173	.probe = mt2701_wm8960_machine_probe,
    174};
    175
    176module_platform_driver(mt2701_wm8960_machine);
    177
    178/* Module information */
    179MODULE_DESCRIPTION("MT2701 WM8960 ALSA SoC machine driver");
    180MODULE_AUTHOR("Ryder Lee <ryder.lee@mediatek.com>");
    181MODULE_LICENSE("GPL v2");
    182MODULE_ALIAS("mt2701 wm8960 soc card");
    183