0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <sound/soc.h>
0008 #include <sound/pcm.h>
0009 #include <sound/pcm_params.h>
0010
0011 #include "../codecs/wm8994.h"
0012 #include "pcm.h"
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #define SMDK_WM8994_FREQ 16934400
0042
0043 static int smdk_wm8994_pcm_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 unsigned long mclk_freq;
0050 int rfs, ret;
0051
0052 switch(params_rate(params)) {
0053 case 8000:
0054 rfs = 512;
0055 break;
0056 default:
0057 dev_err(cpu_dai->dev, "%s:%d Sampling Rate %u not supported!\n",
0058 __func__, __LINE__, params_rate(params));
0059 return -EINVAL;
0060 }
0061
0062 mclk_freq = params_rate(params) * rfs;
0063
0064 ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
0065 mclk_freq, SND_SOC_CLOCK_IN);
0066 if (ret < 0)
0067 return ret;
0068
0069 ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
0070 SMDK_WM8994_FREQ, mclk_freq);
0071 if (ret < 0)
0072 return ret;
0073
0074
0075 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX,
0076 mclk_freq, SND_SOC_CLOCK_IN);
0077 if (ret < 0)
0078 return ret;
0079
0080
0081 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs);
0082 if (ret < 0)
0083 return ret;
0084
0085 return 0;
0086 }
0087
0088 static const struct snd_soc_ops smdk_wm8994_pcm_ops = {
0089 .hw_params = smdk_wm8994_pcm_hw_params,
0090 };
0091
0092 SND_SOC_DAILINK_DEFS(paif_pcm,
0093 DAILINK_COMP_ARRAY(COMP_CPU("samsung-pcm.0")),
0094 DAILINK_COMP_ARRAY(COMP_CODEC("wm8994-codec", "wm8994-aif1")),
0095 DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-pcm.0")));
0096
0097 static struct snd_soc_dai_link smdk_dai[] = {
0098 {
0099 .name = "WM8994 PAIF PCM",
0100 .stream_name = "Primary PCM",
0101 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF |
0102 SND_SOC_DAIFMT_CBS_CFS,
0103 .ops = &smdk_wm8994_pcm_ops,
0104 SND_SOC_DAILINK_REG(paif_pcm),
0105 },
0106 };
0107
0108 static struct snd_soc_card smdk_pcm = {
0109 .name = "SMDK-PCM",
0110 .owner = THIS_MODULE,
0111 .dai_link = smdk_dai,
0112 .num_links = 1,
0113 };
0114
0115 static int snd_smdk_probe(struct platform_device *pdev)
0116 {
0117 int ret = 0;
0118
0119 smdk_pcm.dev = &pdev->dev;
0120 ret = devm_snd_soc_register_card(&pdev->dev, &smdk_pcm);
0121 if (ret)
0122 dev_err_probe(&pdev->dev, ret, "snd_soc_register_card failed\n");
0123
0124 return ret;
0125 }
0126
0127 static struct platform_driver snd_smdk_driver = {
0128 .driver = {
0129 .name = "samsung-smdk-pcm",
0130 },
0131 .probe = snd_smdk_probe,
0132 };
0133
0134 module_platform_driver(snd_smdk_driver);
0135
0136 MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
0137 MODULE_DESCRIPTION("ALSA SoC SMDK WM8994 for PCM");
0138 MODULE_LICENSE("GPL");