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

mt8173-max98090.c (5829B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * mt8173-max98090.c  --  MT8173 MAX98090 ALSA SoC machine driver
      4 *
      5 * Copyright (c) 2015 MediaTek Inc.
      6 * Author: Koro Chen <koro.chen@mediatek.com>
      7 */
      8
      9#include <linux/module.h>
     10#include <sound/soc.h>
     11#include <sound/jack.h>
     12#include <linux/gpio.h>
     13#include "../../codecs/max98090.h"
     14
     15static struct snd_soc_jack mt8173_max98090_jack;
     16
     17static struct snd_soc_jack_pin mt8173_max98090_jack_pins[] = {
     18	{
     19		.pin	= "Headphone",
     20		.mask	= SND_JACK_HEADPHONE,
     21	},
     22	{
     23		.pin	= "Headset Mic",
     24		.mask	= SND_JACK_MICROPHONE,
     25	},
     26};
     27
     28static const struct snd_soc_dapm_widget mt8173_max98090_widgets[] = {
     29	SND_SOC_DAPM_SPK("Speaker", NULL),
     30	SND_SOC_DAPM_MIC("Int Mic", NULL),
     31	SND_SOC_DAPM_HP("Headphone", NULL),
     32	SND_SOC_DAPM_MIC("Headset Mic", NULL),
     33};
     34
     35static const struct snd_soc_dapm_route mt8173_max98090_routes[] = {
     36	{"Speaker", NULL, "SPKL"},
     37	{"Speaker", NULL, "SPKR"},
     38	{"DMICL", NULL, "Int Mic"},
     39	{"Headphone", NULL, "HPL"},
     40	{"Headphone", NULL, "HPR"},
     41	{"Headset Mic", NULL, "MICBIAS"},
     42	{"IN34", NULL, "Headset Mic"},
     43};
     44
     45static const struct snd_kcontrol_new mt8173_max98090_controls[] = {
     46	SOC_DAPM_PIN_SWITCH("Speaker"),
     47	SOC_DAPM_PIN_SWITCH("Int Mic"),
     48	SOC_DAPM_PIN_SWITCH("Headphone"),
     49	SOC_DAPM_PIN_SWITCH("Headset Mic"),
     50};
     51
     52static int mt8173_max98090_hw_params(struct snd_pcm_substream *substream,
     53				     struct snd_pcm_hw_params *params)
     54{
     55	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
     56	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
     57
     58	return snd_soc_dai_set_sysclk(codec_dai, 0, params_rate(params) * 256,
     59				      SND_SOC_CLOCK_IN);
     60}
     61
     62static const struct snd_soc_ops mt8173_max98090_ops = {
     63	.hw_params = mt8173_max98090_hw_params,
     64};
     65
     66static int mt8173_max98090_init(struct snd_soc_pcm_runtime *runtime)
     67{
     68	int ret;
     69	struct snd_soc_card *card = runtime->card;
     70	struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component;
     71
     72	/* enable jack detection */
     73	ret = snd_soc_card_jack_new_pins(card, "Headphone", SND_JACK_HEADPHONE,
     74					 &mt8173_max98090_jack,
     75					 mt8173_max98090_jack_pins,
     76					 ARRAY_SIZE(mt8173_max98090_jack_pins));
     77	if (ret) {
     78		dev_err(card->dev, "Can't create a new Jack %d\n", ret);
     79		return ret;
     80	}
     81
     82	return max98090_mic_detect(component, &mt8173_max98090_jack);
     83}
     84
     85SND_SOC_DAILINK_DEFS(playback,
     86	DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
     87	DAILINK_COMP_ARRAY(COMP_DUMMY()),
     88	DAILINK_COMP_ARRAY(COMP_EMPTY()));
     89
     90SND_SOC_DAILINK_DEFS(capture,
     91	DAILINK_COMP_ARRAY(COMP_CPU("VUL")),
     92	DAILINK_COMP_ARRAY(COMP_DUMMY()),
     93	DAILINK_COMP_ARRAY(COMP_EMPTY()));
     94
     95SND_SOC_DAILINK_DEFS(hifi,
     96	DAILINK_COMP_ARRAY(COMP_CPU("I2S")),
     97	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "HiFi")),
     98	DAILINK_COMP_ARRAY(COMP_EMPTY()));
     99
    100/* Digital audio interface glue - connects codec <---> CPU */
    101static struct snd_soc_dai_link mt8173_max98090_dais[] = {
    102	/* Front End DAI links */
    103	{
    104		.name = "MAX98090 Playback",
    105		.stream_name = "MAX98090 Playback",
    106		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
    107		.dynamic = 1,
    108		.dpcm_playback = 1,
    109		SND_SOC_DAILINK_REG(playback),
    110	},
    111	{
    112		.name = "MAX98090 Capture",
    113		.stream_name = "MAX98090 Capture",
    114		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
    115		.dynamic = 1,
    116		.dpcm_capture = 1,
    117		SND_SOC_DAILINK_REG(capture),
    118	},
    119	/* Back End DAI links */
    120	{
    121		.name = "Codec",
    122		.no_pcm = 1,
    123		.init = mt8173_max98090_init,
    124		.ops = &mt8173_max98090_ops,
    125		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
    126			   SND_SOC_DAIFMT_CBS_CFS,
    127		.dpcm_playback = 1,
    128		.dpcm_capture = 1,
    129		SND_SOC_DAILINK_REG(hifi),
    130	},
    131};
    132
    133static struct snd_soc_card mt8173_max98090_card = {
    134	.name = "mt8173-max98090",
    135	.owner = THIS_MODULE,
    136	.dai_link = mt8173_max98090_dais,
    137	.num_links = ARRAY_SIZE(mt8173_max98090_dais),
    138	.controls = mt8173_max98090_controls,
    139	.num_controls = ARRAY_SIZE(mt8173_max98090_controls),
    140	.dapm_widgets = mt8173_max98090_widgets,
    141	.num_dapm_widgets = ARRAY_SIZE(mt8173_max98090_widgets),
    142	.dapm_routes = mt8173_max98090_routes,
    143	.num_dapm_routes = ARRAY_SIZE(mt8173_max98090_routes),
    144};
    145
    146static int mt8173_max98090_dev_probe(struct platform_device *pdev)
    147{
    148	struct snd_soc_card *card = &mt8173_max98090_card;
    149	struct device_node *codec_node, *platform_node;
    150	struct snd_soc_dai_link *dai_link;
    151	int ret, i;
    152
    153	platform_node = of_parse_phandle(pdev->dev.of_node,
    154					 "mediatek,platform", 0);
    155	if (!platform_node) {
    156		dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
    157		return -EINVAL;
    158	}
    159	for_each_card_prelinks(card, i, dai_link) {
    160		if (dai_link->platforms->name)
    161			continue;
    162		dai_link->platforms->of_node = platform_node;
    163	}
    164
    165	codec_node = of_parse_phandle(pdev->dev.of_node,
    166				      "mediatek,audio-codec", 0);
    167	if (!codec_node) {
    168		dev_err(&pdev->dev,
    169			"Property 'audio-codec' missing or invalid\n");
    170		ret = -EINVAL;
    171		goto put_platform_node;
    172	}
    173	for_each_card_prelinks(card, i, dai_link) {
    174		if (dai_link->codecs->name)
    175			continue;
    176		dai_link->codecs->of_node = codec_node;
    177	}
    178	card->dev = &pdev->dev;
    179
    180	ret = devm_snd_soc_register_card(&pdev->dev, card);
    181
    182	of_node_put(codec_node);
    183
    184put_platform_node:
    185	of_node_put(platform_node);
    186	return ret;
    187}
    188
    189static const struct of_device_id mt8173_max98090_dt_match[] = {
    190	{ .compatible = "mediatek,mt8173-max98090", },
    191	{ }
    192};
    193MODULE_DEVICE_TABLE(of, mt8173_max98090_dt_match);
    194
    195static struct platform_driver mt8173_max98090_driver = {
    196	.driver = {
    197		   .name = "mt8173-max98090",
    198		   .of_match_table = mt8173_max98090_dt_match,
    199		   .pm = &snd_soc_pm_ops,
    200	},
    201	.probe = mt8173_max98090_dev_probe,
    202};
    203
    204module_platform_driver(mt8173_max98090_driver);
    205
    206/* Module information */
    207MODULE_DESCRIPTION("MT8173 MAX98090 ALSA SoC machine driver");
    208MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>");
    209MODULE_LICENSE("GPL v2");
    210MODULE_ALIAS("platform:mt8173-max98090");
    211