root/sound/soc/samsung/smdk_wm8994.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smdk_hw_params
  2. smdk_wm8994_init_paiftx
  3. smdk_audio_probe

   1 // SPDX-License-Identifier: GPL-2.0+
   2 
   3 #include "../codecs/wm8994.h"
   4 #include <sound/pcm_params.h>
   5 #include <sound/soc.h>
   6 #include <linux/module.h>
   7 #include <linux/of.h>
   8 #include <linux/of_device.h>
   9 
  10  /*
  11   * Default CFG switch settings to use this driver:
  12   *     SMDKV310: CFG5-1000, CFG7-111111
  13   */
  14 
  15  /*
  16   * Configure audio route as :-
  17   * $ amixer sset 'DAC1' on,on
  18   * $ amixer sset 'Right Headphone Mux' 'DAC'
  19   * $ amixer sset 'Left Headphone Mux' 'DAC'
  20   * $ amixer sset 'DAC1R Mixer AIF1.1' on
  21   * $ amixer sset 'DAC1L Mixer AIF1.1' on
  22   * $ amixer sset 'IN2L' on
  23   * $ amixer sset 'IN2L PGA IN2LN' on
  24   * $ amixer sset 'MIXINL IN2L' on
  25   * $ amixer sset 'AIF1ADC1L Mixer ADC/DMIC' on
  26   * $ amixer sset 'IN2R' on
  27   * $ amixer sset 'IN2R PGA IN2RN' on
  28   * $ amixer sset 'MIXINR IN2R' on
  29   * $ amixer sset 'AIF1ADC1R Mixer ADC/DMIC' on
  30   */
  31 
  32 /* SMDK has a 16.934MHZ crystal attached to WM8994 */
  33 #define SMDK_WM8994_FREQ 16934000
  34 
  35 struct smdk_wm8994_data {
  36         int mclk1_rate;
  37 };
  38 
  39 /* Default SMDKs */
  40 static struct smdk_wm8994_data smdk_board_data = {
  41         .mclk1_rate = SMDK_WM8994_FREQ,
  42 };
  43 
  44 static int smdk_hw_params(struct snd_pcm_substream *substream,
  45         struct snd_pcm_hw_params *params)
  46 {
  47         struct snd_soc_pcm_runtime *rtd = substream->private_data;
  48         struct snd_soc_dai *codec_dai = rtd->codec_dai;
  49         unsigned int pll_out;
  50         int ret;
  51 
  52         /* AIF1CLK should be >=3MHz for optimal performance */
  53         if (params_width(params) == 24)
  54                 pll_out = params_rate(params) * 384;
  55         else if (params_rate(params) == 8000 || params_rate(params) == 11025)
  56                 pll_out = params_rate(params) * 512;
  57         else
  58                 pll_out = params_rate(params) * 256;
  59 
  60         ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
  61                                         SMDK_WM8994_FREQ, pll_out);
  62         if (ret < 0)
  63                 return ret;
  64 
  65         ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
  66                                         pll_out, SND_SOC_CLOCK_IN);
  67         if (ret < 0)
  68                 return ret;
  69 
  70         return 0;
  71 }
  72 
  73 /*
  74  * SMDK WM8994 DAI operations.
  75  */
  76 static struct snd_soc_ops smdk_ops = {
  77         .hw_params = smdk_hw_params,
  78 };
  79 
  80 static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd)
  81 {
  82         struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
  83 
  84         /* Other pins NC */
  85         snd_soc_dapm_nc_pin(dapm, "HPOUT2P");
  86         snd_soc_dapm_nc_pin(dapm, "HPOUT2N");
  87         snd_soc_dapm_nc_pin(dapm, "SPKOUTLN");
  88         snd_soc_dapm_nc_pin(dapm, "SPKOUTLP");
  89         snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
  90         snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
  91         snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
  92         snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
  93         snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
  94         snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
  95         snd_soc_dapm_nc_pin(dapm, "IN1LP");
  96         snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
  97         snd_soc_dapm_nc_pin(dapm, "IN1RP");
  98         snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
  99 
 100         return 0;
 101 }
 102 
 103 SND_SOC_DAILINK_DEFS(aif1,
 104         DAILINK_COMP_ARRAY(COMP_CPU("samsung-i2s.0")),
 105         DAILINK_COMP_ARRAY(COMP_CODEC("wm8994-codec", "wm8994-aif1")),
 106         DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-i2s.0")));
 107 
 108 SND_SOC_DAILINK_DEFS(fifo_tx,
 109         DAILINK_COMP_ARRAY(COMP_CPU("samsung-i2s-sec")),
 110         DAILINK_COMP_ARRAY(COMP_CODEC("wm8994-codec", "wm8994-aif1")),
 111         DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-i2s-sec")));
 112 
 113 static struct snd_soc_dai_link smdk_dai[] = {
 114         { /* Primary DAI i/f */
 115                 .name = "WM8994 AIF1",
 116                 .stream_name = "Pri_Dai",
 117                 .init = smdk_wm8994_init_paiftx,
 118                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 119                         SND_SOC_DAIFMT_CBM_CFM,
 120                 .ops = &smdk_ops,
 121                 SND_SOC_DAILINK_REG(aif1),
 122         }, { /* Sec_Fifo Playback i/f */
 123                 .name = "Sec_FIFO TX",
 124                 .stream_name = "Sec_Dai",
 125                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 126                         SND_SOC_DAIFMT_CBM_CFM,
 127                 .ops = &smdk_ops,
 128                 SND_SOC_DAILINK_REG(fifo_tx),
 129         },
 130 };
 131 
 132 static struct snd_soc_card smdk = {
 133         .name = "SMDK-I2S",
 134         .owner = THIS_MODULE,
 135         .dai_link = smdk_dai,
 136         .num_links = ARRAY_SIZE(smdk_dai),
 137 };
 138 
 139 static const struct of_device_id samsung_wm8994_of_match[] = {
 140         { .compatible = "samsung,smdk-wm8994", .data = &smdk_board_data },
 141         {},
 142 };
 143 MODULE_DEVICE_TABLE(of, samsung_wm8994_of_match);
 144 
 145 static int smdk_audio_probe(struct platform_device *pdev)
 146 {
 147         int ret;
 148         struct device_node *np = pdev->dev.of_node;
 149         struct snd_soc_card *card = &smdk;
 150         struct smdk_wm8994_data *board;
 151         const struct of_device_id *id;
 152 
 153         card->dev = &pdev->dev;
 154 
 155         board = devm_kzalloc(&pdev->dev, sizeof(*board), GFP_KERNEL);
 156         if (!board)
 157                 return -ENOMEM;
 158 
 159         if (np) {
 160                 smdk_dai[0].cpus->dai_name = NULL;
 161                 smdk_dai[0].cpus->of_node = of_parse_phandle(np,
 162                                 "samsung,i2s-controller", 0);
 163                 if (!smdk_dai[0].cpus->of_node) {
 164                         dev_err(&pdev->dev,
 165                            "Property 'samsung,i2s-controller' missing or invalid\n");
 166                         ret = -EINVAL;
 167                 }
 168 
 169                 smdk_dai[0].platforms->name = NULL;
 170                 smdk_dai[0].platforms->of_node = smdk_dai[0].cpus->of_node;
 171         }
 172 
 173         id = of_match_device(of_match_ptr(samsung_wm8994_of_match), &pdev->dev);
 174         if (id)
 175                 *board = *((struct smdk_wm8994_data *)id->data);
 176 
 177         platform_set_drvdata(pdev, board);
 178 
 179         ret = devm_snd_soc_register_card(&pdev->dev, card);
 180 
 181         if (ret)
 182                 dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret);
 183 
 184         return ret;
 185 }
 186 
 187 static struct platform_driver smdk_audio_driver = {
 188         .driver         = {
 189                 .name   = "smdk-audio-wm8994",
 190                 .of_match_table = of_match_ptr(samsung_wm8994_of_match),
 191                 .pm     = &snd_soc_pm_ops,
 192         },
 193         .probe          = smdk_audio_probe,
 194 };
 195 
 196 module_platform_driver(smdk_audio_driver);
 197 
 198 MODULE_DESCRIPTION("ALSA SoC SMDK WM8994");
 199 MODULE_LICENSE("GPL");
 200 MODULE_ALIAS("platform:smdk-audio-wm8994");

/* [<][>][^][v][top][bottom][index][help] */