Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * linux/sound/soc/pxa/brownstone.c
0004  *
0005  * Copyright (C) 2011 Marvell International Ltd.
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <sound/core.h>
0010 #include <sound/pcm.h>
0011 #include <sound/soc.h>
0012 #include <sound/jack.h>
0013 
0014 #include "../codecs/wm8994.h"
0015 #include "mmp-sspa.h"
0016 
0017 static const struct snd_kcontrol_new brownstone_dapm_control[] = {
0018     SOC_DAPM_PIN_SWITCH("Ext Spk"),
0019 };
0020 
0021 static const struct snd_soc_dapm_widget brownstone_dapm_widgets[] = {
0022     SND_SOC_DAPM_SPK("Ext Spk", NULL),
0023     SND_SOC_DAPM_HP("Headset Stereophone", NULL),
0024     SND_SOC_DAPM_MIC("Headset Mic", NULL),
0025     SND_SOC_DAPM_MIC("Main Mic", NULL),
0026 };
0027 
0028 static const struct snd_soc_dapm_route brownstone_audio_map[] = {
0029     {"Ext Spk", NULL, "SPKOUTLP"},
0030     {"Ext Spk", NULL, "SPKOUTLN"},
0031     {"Ext Spk", NULL, "SPKOUTRP"},
0032     {"Ext Spk", NULL, "SPKOUTRN"},
0033 
0034     {"Headset Stereophone", NULL, "HPOUT1L"},
0035     {"Headset Stereophone", NULL, "HPOUT1R"},
0036 
0037     {"IN1RN", NULL, "Headset Mic"},
0038 
0039     {"DMIC1DAT", NULL, "MICBIAS1"},
0040     {"MICBIAS1", NULL, "Main Mic"},
0041 };
0042 
0043 static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
0044                        struct snd_pcm_hw_params *params)
0045 {
0046     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0047     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0048     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0049     int freq_out, sspa_mclk, sysclk;
0050 
0051     if (params_rate(params) > 11025) {
0052         freq_out  = params_rate(params) * 512;
0053         sysclk    = params_rate(params) * 256;
0054         sspa_mclk = params_rate(params) * 64;
0055     } else {
0056         freq_out  = params_rate(params) * 1024;
0057         sysclk    = params_rate(params) * 512;
0058         sspa_mclk = params_rate(params) * 64;
0059     }
0060 
0061     snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);
0062     snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);
0063     snd_soc_dai_set_pll(cpu_dai, MMP_SSPA_CLK, 0, freq_out, sspa_mclk);
0064 
0065     /* set wm8994 sysclk */
0066     snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, sysclk, 0);
0067 
0068     return 0;
0069 }
0070 
0071 /* machine stream operations */
0072 static const struct snd_soc_ops brownstone_ops = {
0073     .hw_params = brownstone_wm8994_hw_params,
0074 };
0075 
0076 SND_SOC_DAILINK_DEFS(wm8994,
0077     DAILINK_COMP_ARRAY(COMP_CPU("mmp-sspa-dai.0")),
0078     DAILINK_COMP_ARRAY(COMP_CODEC("wm8994-codec", "wm8994-aif1")),
0079     DAILINK_COMP_ARRAY(COMP_PLATFORM("mmp-pcm-audio")));
0080 
0081 static struct snd_soc_dai_link brownstone_wm8994_dai[] = {
0082 {
0083     .name       = "WM8994",
0084     .stream_name    = "WM8994 HiFi",
0085     .dai_fmt    = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
0086                 SND_SOC_DAIFMT_CBS_CFS,
0087     .ops        = &brownstone_ops,
0088     SND_SOC_DAILINK_REG(wm8994),
0089 },
0090 };
0091 
0092 /* audio machine driver */
0093 static struct snd_soc_card brownstone = {
0094     .name         = "brownstone",
0095     .owner        = THIS_MODULE,
0096     .dai_link     = brownstone_wm8994_dai,
0097     .num_links    = ARRAY_SIZE(brownstone_wm8994_dai),
0098 
0099     .controls = brownstone_dapm_control,
0100     .num_controls = ARRAY_SIZE(brownstone_dapm_control),
0101     .dapm_widgets = brownstone_dapm_widgets,
0102     .num_dapm_widgets = ARRAY_SIZE(brownstone_dapm_widgets),
0103     .dapm_routes = brownstone_audio_map,
0104     .num_dapm_routes = ARRAY_SIZE(brownstone_audio_map),
0105     .fully_routed = true,
0106 };
0107 
0108 static int brownstone_probe(struct platform_device *pdev)
0109 {
0110     int ret;
0111 
0112     brownstone.dev = &pdev->dev;
0113     ret = devm_snd_soc_register_card(&pdev->dev, &brownstone);
0114     if (ret)
0115         dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
0116                 ret);
0117     return ret;
0118 }
0119 
0120 static struct platform_driver mmp_driver = {
0121     .driver     = {
0122         .name   = "brownstone-audio",
0123         .pm     = &snd_soc_pm_ops,
0124     },
0125     .probe      = brownstone_probe,
0126 };
0127 
0128 module_platform_driver(mmp_driver);
0129 
0130 MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
0131 MODULE_DESCRIPTION("ALSA SoC Brownstone");
0132 MODULE_LICENSE("GPL");
0133 MODULE_ALIAS("platform:brownstone-audio");