|
@@ -23,6 +23,20 @@
|
|
|
|
|
|
#define MCLK_FOR_CODECS 12288000
|
|
#define MCLK_FOR_CODECS 12288000
|
|
|
|
|
|
|
|
+enum mt8173_rt5650_mclk {
|
|
|
|
+ MT8173_RT5650_MCLK_EXTERNAL = 0,
|
|
|
|
+ MT8173_RT5650_MCLK_INTERNAL,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+struct mt8173_rt5650_platform_data {
|
|
|
|
+ enum mt8173_rt5650_mclk pll_from;
|
|
|
|
+ /* 0 = external oscillator; 1 = internal source from mt8173 */
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct mt8173_rt5650_platform_data mt8173_rt5650_priv = {
|
|
|
|
+ .pll_from = MT8173_RT5650_MCLK_EXTERNAL,
|
|
|
|
+};
|
|
|
|
+
|
|
static const struct snd_soc_dapm_widget mt8173_rt5650_widgets[] = {
|
|
static const struct snd_soc_dapm_widget mt8173_rt5650_widgets[] = {
|
|
SND_SOC_DAPM_SPK("Speaker", NULL),
|
|
SND_SOC_DAPM_SPK("Speaker", NULL),
|
|
SND_SOC_DAPM_MIC("Int Mic", NULL),
|
|
SND_SOC_DAPM_MIC("Int Mic", NULL),
|
|
@@ -54,13 +68,29 @@ static int mt8173_rt5650_hw_params(struct snd_pcm_substream *substream,
|
|
struct snd_pcm_hw_params *params)
|
|
struct snd_pcm_hw_params *params)
|
|
{
|
|
{
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
|
+ unsigned int mclk_clock;
|
|
int i, ret;
|
|
int i, ret;
|
|
|
|
|
|
|
|
+ switch (mt8173_rt5650_priv.pll_from) {
|
|
|
|
+ case MT8173_RT5650_MCLK_EXTERNAL:
|
|
|
|
+ /* mclk = 12.288M */
|
|
|
|
+ mclk_clock = MCLK_FOR_CODECS;
|
|
|
|
+ break;
|
|
|
|
+ case MT8173_RT5650_MCLK_INTERNAL:
|
|
|
|
+ /* mclk = sampling rate*256 */
|
|
|
|
+ mclk_clock = params_rate(params) * 256;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ /* mclk = 12.288M */
|
|
|
|
+ mclk_clock = MCLK_FOR_CODECS;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
for (i = 0; i < rtd->num_codecs; i++) {
|
|
for (i = 0; i < rtd->num_codecs; i++) {
|
|
struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
|
|
struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
|
|
|
|
|
|
- /* pll from mclk 12.288M */
|
|
|
|
- ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS,
|
|
|
|
|
|
+ /* pll from mclk */
|
|
|
|
+ ret = snd_soc_dai_set_pll(codec_dai, 0, 0, mclk_clock,
|
|
params_rate(params) * 512);
|
|
params_rate(params) * 512);
|
|
if (ret)
|
|
if (ret)
|
|
return ret;
|
|
return ret;
|
|
@@ -243,6 +273,17 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
|
|
mt8173_rt5650_codecs[1].dai_name = codec_capture_dai;
|
|
mt8173_rt5650_codecs[1].dai_name = codec_capture_dai;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (device_property_present(&pdev->dev, "mediatek,mclk")) {
|
|
|
|
+ ret = device_property_read_u32(&pdev->dev,
|
|
|
|
+ "mediatek,mclk",
|
|
|
|
+ &mt8173_rt5650_priv.pll_from);
|
|
|
|
+ if (ret) {
|
|
|
|
+ dev_err(&pdev->dev,
|
|
|
|
+ "%s snd_soc_register_card fail %d\n",
|
|
|
|
+ __func__, ret);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
card->dev = &pdev->dev;
|
|
card->dev = &pdev->dev;
|
|
platform_set_drvdata(pdev, card);
|
|
platform_set_drvdata(pdev, card);
|
|
|
|
|