Merge tag 'mips_fixes_5.1_3' of git://git.kernel.org/pub/scm/linux/kernel/git/mips...
[linux-2.6-microblaze.git] / sound / soc / intel / boards / cht_bsw_rt5645.c
1 /*
2  *  cht-bsw-rt5645.c - ASoc Machine driver for Intel Cherryview-based platforms
3  *                     Cherrytrail and Braswell, with RT5645 codec.
4  *
5  *  Copyright (C) 2015 Intel Corp
6  *  Author: Fang, Yang A <yang.a.fang@intel.com>
7  *              N,Harshapriya <harshapriya.n@intel.com>
8  *  This file is modified from cht_bsw_rt5672.c
9  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; version 2 of the License.
14  *
15  *  This program is distributed in the hope that it will be useful, but
16  *  WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  General Public License for more details.
19  *
20  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21  */
22
23 #include <linux/module.h>
24 #include <linux/platform_device.h>
25 #include <linux/acpi.h>
26 #include <linux/clk.h>
27 #include <linux/dmi.h>
28 #include <linux/slab.h>
29 #include <asm/cpu_device_id.h>
30 #include <sound/pcm.h>
31 #include <sound/pcm_params.h>
32 #include <sound/soc.h>
33 #include <sound/jack.h>
34 #include <sound/soc-acpi.h>
35 #include "../../codecs/rt5645.h"
36 #include "../atom/sst-atom-controls.h"
37
38 #define CHT_PLAT_CLK_3_HZ       19200000
39 #define CHT_CODEC_DAI1  "rt5645-aif1"
40 #define CHT_CODEC_DAI2  "rt5645-aif2"
41
42 struct cht_acpi_card {
43         char *codec_id;
44         int codec_type;
45         struct snd_soc_card *soc_card;
46 };
47
48 struct cht_mc_private {
49         struct snd_soc_jack jack;
50         struct cht_acpi_card *acpi_card;
51         char codec_name[SND_ACPI_I2C_ID_LEN];
52         struct clk *mclk;
53 };
54
55 #define CHT_RT5645_MAP(quirk)   ((quirk) & GENMASK(7, 0))
56 #define CHT_RT5645_SSP2_AIF2     BIT(16) /* default is using AIF1  */
57 #define CHT_RT5645_SSP0_AIF1     BIT(17)
58 #define CHT_RT5645_SSP0_AIF2     BIT(18)
59
60 static unsigned long cht_rt5645_quirk = 0;
61
62 static void log_quirks(struct device *dev)
63 {
64         if (cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2)
65                 dev_info(dev, "quirk SSP2_AIF2 enabled");
66         if (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF1)
67                 dev_info(dev, "quirk SSP0_AIF1 enabled");
68         if (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)
69                 dev_info(dev, "quirk SSP0_AIF2 enabled");
70 }
71
72 static int platform_clock_control(struct snd_soc_dapm_widget *w,
73                 struct snd_kcontrol *k, int  event)
74 {
75         struct snd_soc_dapm_context *dapm = w->dapm;
76         struct snd_soc_card *card = dapm->card;
77         struct snd_soc_dai *codec_dai;
78         struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
79         int ret;
80
81         codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI1);
82         if (!codec_dai)
83                 codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI2);
84
85         if (!codec_dai) {
86                 dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
87                 return -EIO;
88         }
89
90         if (SND_SOC_DAPM_EVENT_ON(event)) {
91                 ret = clk_prepare_enable(ctx->mclk);
92                 if (ret < 0) {
93                         dev_err(card->dev,
94                                 "could not configure MCLK state");
95                         return ret;
96                 }
97         } else {
98                 /* Set codec sysclk source to its internal clock because codec PLL will
99                  * be off when idle and MCLK will also be off when codec is
100                  * runtime suspended. Codec needs clock for jack detection and button
101                  * press. MCLK is turned off with clock framework or ACPI.
102                  */
103                 ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK,
104                                         48000 * 512, SND_SOC_CLOCK_IN);
105                 if (ret < 0) {
106                         dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
107                         return ret;
108                 }
109
110                 clk_disable_unprepare(ctx->mclk);
111         }
112
113         return 0;
114 }
115
116 static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
117         SND_SOC_DAPM_HP("Headphone", NULL),
118         SND_SOC_DAPM_MIC("Headset Mic", NULL),
119         SND_SOC_DAPM_MIC("Int Mic", NULL),
120         SND_SOC_DAPM_MIC("Int Analog Mic", NULL),
121         SND_SOC_DAPM_SPK("Ext Spk", NULL),
122         SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
123                         platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
124 };
125
126 static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = {
127         {"IN1P", NULL, "Headset Mic"},
128         {"IN1N", NULL, "Headset Mic"},
129         {"DMIC L1", NULL, "Int Mic"},
130         {"DMIC R1", NULL, "Int Mic"},
131         {"IN2P", NULL, "Int Analog Mic"},
132         {"IN2N", NULL, "Int Analog Mic"},
133         {"Headphone", NULL, "HPOL"},
134         {"Headphone", NULL, "HPOR"},
135         {"Ext Spk", NULL, "SPOL"},
136         {"Ext Spk", NULL, "SPOR"},
137         {"Headphone", NULL, "Platform Clock"},
138         {"Headset Mic", NULL, "Platform Clock"},
139         {"Int Mic", NULL, "Platform Clock"},
140         {"Int Analog Mic", NULL, "Platform Clock"},
141         {"Int Analog Mic", NULL, "micbias1"},
142         {"Int Analog Mic", NULL, "micbias2"},
143         {"Ext Spk", NULL, "Platform Clock"},
144 };
145
146 static const struct snd_soc_dapm_route cht_rt5650_audio_map[] = {
147         {"IN1P", NULL, "Headset Mic"},
148         {"IN1N", NULL, "Headset Mic"},
149         {"DMIC L2", NULL, "Int Mic"},
150         {"DMIC R2", NULL, "Int Mic"},
151         {"Headphone", NULL, "HPOL"},
152         {"Headphone", NULL, "HPOR"},
153         {"Ext Spk", NULL, "SPOL"},
154         {"Ext Spk", NULL, "SPOR"},
155         {"Headphone", NULL, "Platform Clock"},
156         {"Headset Mic", NULL, "Platform Clock"},
157         {"Int Mic", NULL, "Platform Clock"},
158         {"Ext Spk", NULL, "Platform Clock"},
159 };
160
161 static const struct snd_soc_dapm_route cht_rt5645_ssp2_aif1_map[] = {
162         {"AIF1 Playback", NULL, "ssp2 Tx"},
163         {"ssp2 Tx", NULL, "codec_out0"},
164         {"ssp2 Tx", NULL, "codec_out1"},
165         {"codec_in0", NULL, "ssp2 Rx" },
166         {"codec_in1", NULL, "ssp2 Rx" },
167         {"ssp2 Rx", NULL, "AIF1 Capture"},
168 };
169
170 static const struct snd_soc_dapm_route cht_rt5645_ssp2_aif2_map[] = {
171         {"AIF2 Playback", NULL, "ssp2 Tx"},
172         {"ssp2 Tx", NULL, "codec_out0"},
173         {"ssp2 Tx", NULL, "codec_out1"},
174         {"codec_in0", NULL, "ssp2 Rx" },
175         {"codec_in1", NULL, "ssp2 Rx" },
176         {"ssp2 Rx", NULL, "AIF2 Capture"},
177 };
178
179 static const struct snd_soc_dapm_route cht_rt5645_ssp0_aif1_map[] = {
180         {"AIF1 Playback", NULL, "ssp0 Tx"},
181         {"ssp0 Tx", NULL, "modem_out"},
182         {"modem_in", NULL, "ssp0 Rx" },
183         {"ssp0 Rx", NULL, "AIF1 Capture"},
184 };
185
186 static const struct snd_soc_dapm_route cht_rt5645_ssp0_aif2_map[] = {
187         {"AIF2 Playback", NULL, "ssp0 Tx"},
188         {"ssp0 Tx", NULL, "modem_out"},
189         {"modem_in", NULL, "ssp0 Rx" },
190         {"ssp0 Rx", NULL, "AIF2 Capture"},
191 };
192
193 static const struct snd_kcontrol_new cht_mc_controls[] = {
194         SOC_DAPM_PIN_SWITCH("Headphone"),
195         SOC_DAPM_PIN_SWITCH("Headset Mic"),
196         SOC_DAPM_PIN_SWITCH("Int Mic"),
197         SOC_DAPM_PIN_SWITCH("Int Analog Mic"),
198         SOC_DAPM_PIN_SWITCH("Ext Spk"),
199 };
200
201 static struct snd_soc_jack_pin cht_bsw_jack_pins[] = {
202         {
203                 .pin    = "Headphone",
204                 .mask   = SND_JACK_HEADPHONE,
205         },
206         {
207                 .pin    = "Headset Mic",
208                 .mask   = SND_JACK_MICROPHONE,
209         },
210 };
211
212 static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
213                              struct snd_pcm_hw_params *params)
214 {
215         struct snd_soc_pcm_runtime *rtd = substream->private_data;
216         struct snd_soc_dai *codec_dai = rtd->codec_dai;
217         int ret;
218
219         /* set codec PLL source to the 19.2MHz platform clock (MCLK) */
220         ret = snd_soc_dai_set_pll(codec_dai, 0, RT5645_PLL1_S_MCLK,
221                                   CHT_PLAT_CLK_3_HZ, params_rate(params) * 512);
222         if (ret < 0) {
223                 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
224                 return ret;
225         }
226
227         ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_PLL1,
228                                 params_rate(params) * 512, SND_SOC_CLOCK_IN);
229         if (ret < 0) {
230                 dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
231                 return ret;
232         }
233
234         return 0;
235 }
236
237 /* uncomment when we have a real quirk
238 static int cht_rt5645_quirk_cb(const struct dmi_system_id *id)
239 {
240         cht_rt5645_quirk = (unsigned long)id->driver_data;
241         return 1;
242 }
243 */
244
245 static const struct dmi_system_id cht_rt5645_quirk_table[] = {
246         {
247         },
248 };
249
250 static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
251 {
252         struct snd_soc_card *card = runtime->card;
253         struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
254         struct snd_soc_component *component = runtime->codec_dai->component;
255         int jack_type;
256         int ret;
257
258         if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) ||
259             (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
260                 /* Select clk_i2s2_asrc as ASRC clock source */
261                 rt5645_sel_asrc_clk_src(component,
262                                         RT5645_DA_STEREO_FILTER |
263                                         RT5645_DA_MONO_L_FILTER |
264                                         RT5645_DA_MONO_R_FILTER |
265                                         RT5645_AD_STEREO_FILTER,
266                                         RT5645_CLK_SEL_I2S2_ASRC);
267         } else {
268                 /* Select clk_i2s1_asrc as ASRC clock source */
269                 rt5645_sel_asrc_clk_src(component,
270                                         RT5645_DA_STEREO_FILTER |
271                                         RT5645_DA_MONO_L_FILTER |
272                                         RT5645_DA_MONO_R_FILTER |
273                                         RT5645_AD_STEREO_FILTER,
274                                         RT5645_CLK_SEL_I2S1_ASRC);
275         }
276
277         if (cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) {
278                 ret = snd_soc_dapm_add_routes(&card->dapm,
279                                         cht_rt5645_ssp2_aif2_map,
280                                         ARRAY_SIZE(cht_rt5645_ssp2_aif2_map));
281         } else if (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF1) {
282                 ret = snd_soc_dapm_add_routes(&card->dapm,
283                                         cht_rt5645_ssp0_aif1_map,
284                                         ARRAY_SIZE(cht_rt5645_ssp0_aif1_map));
285         } else if (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2) {
286                 ret = snd_soc_dapm_add_routes(&card->dapm,
287                                         cht_rt5645_ssp0_aif2_map,
288                                         ARRAY_SIZE(cht_rt5645_ssp0_aif2_map));
289         } else {
290                 ret = snd_soc_dapm_add_routes(&card->dapm,
291                                         cht_rt5645_ssp2_aif1_map,
292                                         ARRAY_SIZE(cht_rt5645_ssp2_aif1_map));
293         }
294         if (ret)
295                 return ret;
296
297         if (ctx->acpi_card->codec_type == CODEC_TYPE_RT5650)
298                 jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
299                                         SND_JACK_BTN_0 | SND_JACK_BTN_1 |
300                                         SND_JACK_BTN_2 | SND_JACK_BTN_3;
301         else
302                 jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE;
303
304         ret = snd_soc_card_jack_new(runtime->card, "Headset",
305                                     jack_type, &ctx->jack,
306                                     cht_bsw_jack_pins, ARRAY_SIZE(cht_bsw_jack_pins));
307         if (ret) {
308                 dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);
309                 return ret;
310         }
311
312         rt5645_set_jack_detect(component, &ctx->jack, &ctx->jack, &ctx->jack);
313
314
315         /*
316          * The firmware might enable the clock at
317          * boot (this information may or may not
318          * be reflected in the enable clock register).
319          * To change the rate we must disable the clock
320          * first to cover these cases. Due to common
321          * clock framework restrictions that do not allow
322          * to disable a clock that has not been enabled,
323          * we need to enable the clock first.
324          */
325         ret = clk_prepare_enable(ctx->mclk);
326         if (!ret)
327                 clk_disable_unprepare(ctx->mclk);
328
329         ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ);
330
331         if (ret)
332                 dev_err(runtime->dev, "unable to set MCLK rate\n");
333
334         return ret;
335 }
336
337 static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
338                             struct snd_pcm_hw_params *params)
339 {
340         int ret;
341         struct snd_interval *rate = hw_param_interval(params,
342                         SNDRV_PCM_HW_PARAM_RATE);
343         struct snd_interval *channels = hw_param_interval(params,
344                                                 SNDRV_PCM_HW_PARAM_CHANNELS);
345
346         /* The DSP will covert the FE rate to 48k, stereo, 24bits */
347         rate->min = rate->max = 48000;
348         channels->min = channels->max = 2;
349
350         if ((cht_rt5645_quirk & CHT_RT5645_SSP0_AIF1) ||
351                 (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
352
353                 /* set SSP0 to 16-bit */
354                 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
355
356                 /*
357                  * Default mode for SSP configuration is TDM 4 slot, override config
358                  * with explicit setting to I2S 2ch 16-bit. The word length is set with
359                  * dai_set_tdm_slot() since there is no other API exposed
360                  */
361                 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
362                                         SND_SOC_DAIFMT_I2S     |
363                                         SND_SOC_DAIFMT_NB_NF   |
364                                         SND_SOC_DAIFMT_CBS_CFS
365                         );
366                 if (ret < 0) {
367                         dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
368                         return ret;
369                 }
370
371                 ret = snd_soc_dai_set_fmt(rtd->codec_dai,
372                                         SND_SOC_DAIFMT_I2S     |
373                                         SND_SOC_DAIFMT_NB_NF   |
374                                         SND_SOC_DAIFMT_CBS_CFS
375                         );
376                 if (ret < 0) {
377                         dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
378                         return ret;
379                 }
380
381                 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
382                 if (ret < 0) {
383                         dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
384                         return ret;
385                 }
386
387         } else {
388
389                 /* set SSP2 to 24-bit */
390                 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
391
392                 /*
393                  * Default mode for SSP configuration is TDM 4 slot
394                  */
395                 ret = snd_soc_dai_set_fmt(rtd->codec_dai,
396                                         SND_SOC_DAIFMT_DSP_B |
397                                         SND_SOC_DAIFMT_IB_NF |
398                                         SND_SOC_DAIFMT_CBS_CFS);
399                 if (ret < 0) {
400                         dev_err(rtd->dev, "can't set format to TDM %d\n", ret);
401                         return ret;
402                 }
403
404                 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
405                 ret = snd_soc_dai_set_tdm_slot(rtd->codec_dai, 0xF, 0xF, 4, 24);
406                 if (ret < 0) {
407                         dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret);
408                         return ret;
409                 }
410         }
411         return 0;
412 }
413
414 static int cht_aif1_startup(struct snd_pcm_substream *substream)
415 {
416         return snd_pcm_hw_constraint_single(substream->runtime,
417                         SNDRV_PCM_HW_PARAM_RATE, 48000);
418 }
419
420 static const struct snd_soc_ops cht_aif1_ops = {
421         .startup = cht_aif1_startup,
422 };
423
424 static const struct snd_soc_ops cht_be_ssp2_ops = {
425         .hw_params = cht_aif1_hw_params,
426 };
427
428 static struct snd_soc_dai_link cht_dailink[] = {
429         [MERR_DPCM_AUDIO] = {
430                 .name = "Audio Port",
431                 .stream_name = "Audio",
432                 .cpu_dai_name = "media-cpu-dai",
433                 .codec_dai_name = "snd-soc-dummy-dai",
434                 .codec_name = "snd-soc-dummy",
435                 .platform_name = "sst-mfld-platform",
436                 .nonatomic = true,
437                 .dynamic = 1,
438                 .dpcm_playback = 1,
439                 .dpcm_capture = 1,
440                 .ops = &cht_aif1_ops,
441         },
442         [MERR_DPCM_DEEP_BUFFER] = {
443                 .name = "Deep-Buffer Audio Port",
444                 .stream_name = "Deep-Buffer Audio",
445                 .cpu_dai_name = "deepbuffer-cpu-dai",
446                 .codec_dai_name = "snd-soc-dummy-dai",
447                 .codec_name = "snd-soc-dummy",
448                 .platform_name = "sst-mfld-platform",
449                 .nonatomic = true,
450                 .dynamic = 1,
451                 .dpcm_playback = 1,
452                 .ops = &cht_aif1_ops,
453         },
454         /* CODEC<->CODEC link */
455         /* back ends */
456         {
457                 .name = "SSP2-Codec",
458                 .id = 0,
459                 .cpu_dai_name = "ssp2-port",
460                 .platform_name = "sst-mfld-platform",
461                 .no_pcm = 1,
462                 .codec_dai_name = "rt5645-aif1",
463                 .codec_name = "i2c-10EC5645:00",
464                 .init = cht_codec_init,
465                 .be_hw_params_fixup = cht_codec_fixup,
466                 .nonatomic = true,
467                 .dpcm_playback = 1,
468                 .dpcm_capture = 1,
469                 .ops = &cht_be_ssp2_ops,
470         },
471 };
472
473 /* SoC card */
474 static struct snd_soc_card snd_soc_card_chtrt5645 = {
475         .name = "chtrt5645",
476         .owner = THIS_MODULE,
477         .dai_link = cht_dailink,
478         .num_links = ARRAY_SIZE(cht_dailink),
479         .dapm_widgets = cht_dapm_widgets,
480         .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
481         .dapm_routes = cht_rt5645_audio_map,
482         .num_dapm_routes = ARRAY_SIZE(cht_rt5645_audio_map),
483         .controls = cht_mc_controls,
484         .num_controls = ARRAY_SIZE(cht_mc_controls),
485 };
486
487 static struct snd_soc_card snd_soc_card_chtrt5650 = {
488         .name = "chtrt5650",
489         .owner = THIS_MODULE,
490         .dai_link = cht_dailink,
491         .num_links = ARRAY_SIZE(cht_dailink),
492         .dapm_widgets = cht_dapm_widgets,
493         .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
494         .dapm_routes = cht_rt5650_audio_map,
495         .num_dapm_routes = ARRAY_SIZE(cht_rt5650_audio_map),
496         .controls = cht_mc_controls,
497         .num_controls = ARRAY_SIZE(cht_mc_controls),
498 };
499
500 static struct cht_acpi_card snd_soc_cards[] = {
501         {"10EC5640", CODEC_TYPE_RT5645, &snd_soc_card_chtrt5645},
502         {"10EC5645", CODEC_TYPE_RT5645, &snd_soc_card_chtrt5645},
503         {"10EC5648", CODEC_TYPE_RT5645, &snd_soc_card_chtrt5645},
504         {"10EC3270", CODEC_TYPE_RT5645, &snd_soc_card_chtrt5645},
505         {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650},
506 };
507
508 static char cht_rt5645_codec_name[SND_ACPI_I2C_ID_LEN];
509 static char cht_rt5645_codec_aif_name[12]; /*  = "rt5645-aif[1|2]" */
510 static char cht_rt5645_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
511
512 static bool is_valleyview(void)
513 {
514         static const struct x86_cpu_id cpu_ids[] = {
515                 { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
516                 {}
517         };
518
519         if (!x86_match_cpu(cpu_ids))
520                 return false;
521         return true;
522 }
523
524 struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
525         u64 aif_value;       /* 1: AIF1, 2: AIF2 */
526         u64 mclock_value;    /* usually 25MHz (0x17d7940), ignored */
527 };
528
529 static int snd_cht_mc_probe(struct platform_device *pdev)
530 {
531         struct snd_soc_card *card = snd_soc_cards[0].soc_card;
532         struct snd_soc_acpi_mach *mach;
533         const char *platform_name;
534         struct cht_mc_private *drv;
535         const char *i2c_name = NULL;
536         bool found = false;
537         bool is_bytcr = false;
538         int dai_index = 0;
539         int ret_val = 0;
540         int i;
541
542         drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
543         if (!drv)
544                 return -ENOMEM;
545
546         mach = (&pdev->dev)->platform_data;
547
548         for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) {
549                 if (acpi_dev_found(snd_soc_cards[i].codec_id) &&
550                         (!strncmp(snd_soc_cards[i].codec_id, mach->id, 8))) {
551                         dev_dbg(&pdev->dev,
552                                 "found codec %s\n", snd_soc_cards[i].codec_id);
553                         card = snd_soc_cards[i].soc_card;
554                         drv->acpi_card = &snd_soc_cards[i];
555                         found = true;
556                         break;
557                 }
558         }
559
560         if (!found) {
561                 dev_err(&pdev->dev, "No matching HID found in supported list\n");
562                 return -ENODEV;
563         }
564
565         card->dev = &pdev->dev;
566         sprintf(drv->codec_name, "i2c-%s:00", drv->acpi_card->codec_id);
567
568         /* set correct codec name */
569         for (i = 0; i < ARRAY_SIZE(cht_dailink); i++)
570                 if (!strcmp(card->dai_link[i].codec_name, "i2c-10EC5645:00")) {
571                         card->dai_link[i].codec_name = drv->codec_name;
572                         dai_index = i;
573                 }
574
575         /* fixup codec name based on HID */
576         i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
577         if (i2c_name) {
578                 snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name),
579                         "%s%s", "i2c-", i2c_name);
580                 cht_dailink[dai_index].codec_name = cht_rt5645_codec_name;
581         }
582
583         /*
584          * swap SSP0 if bytcr is detected
585          * (will be overridden if DMI quirk is detected)
586          */
587         if (is_valleyview()) {
588                 if (mach->mach_params.acpi_ipc_irq_index == 0)
589                         is_bytcr = true;
590         }
591
592         if (is_bytcr) {
593                 /*
594                  * Baytrail CR platforms may have CHAN package in BIOS, try
595                  * to find relevant routing quirk based as done on Windows
596                  * platforms. We have to read the information directly from the
597                  * BIOS, at this stage the card is not created and the links
598                  * with the codec driver/pdata are non-existent
599                  */
600
601                 struct acpi_chan_package chan_package;
602
603                 /* format specified: 2 64-bit integers */
604                 struct acpi_buffer format = {sizeof("NN"), "NN"};
605                 struct acpi_buffer state = {0, NULL};
606                 struct snd_soc_acpi_package_context pkg_ctx;
607                 bool pkg_found = false;
608
609                 state.length = sizeof(chan_package);
610                 state.pointer = &chan_package;
611
612                 pkg_ctx.name = "CHAN";
613                 pkg_ctx.length = 2;
614                 pkg_ctx.format = &format;
615                 pkg_ctx.state = &state;
616                 pkg_ctx.data_valid = false;
617
618                 pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
619                                                                &pkg_ctx);
620                 if (pkg_found) {
621                         if (chan_package.aif_value == 1) {
622                                 dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
623                                 cht_rt5645_quirk |= CHT_RT5645_SSP0_AIF1;
624                         } else  if (chan_package.aif_value == 2) {
625                                 dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
626                                 cht_rt5645_quirk |= CHT_RT5645_SSP0_AIF2;
627                         } else {
628                                 dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
629                                 pkg_found = false;
630                         }
631                 }
632
633                 if (!pkg_found) {
634                         /* no BIOS indications, assume SSP0-AIF2 connection */
635                         cht_rt5645_quirk |= CHT_RT5645_SSP0_AIF2;
636                 }
637         }
638
639         /* check quirks before creating card */
640         dmi_check_system(cht_rt5645_quirk_table);
641         log_quirks(&pdev->dev);
642
643         if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) ||
644                 (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
645
646                 /* fixup codec aif name */
647                 snprintf(cht_rt5645_codec_aif_name,
648                         sizeof(cht_rt5645_codec_aif_name),
649                         "%s", "rt5645-aif2");
650
651                 cht_dailink[dai_index].codec_dai_name =
652                         cht_rt5645_codec_aif_name;
653         }
654
655         if ((cht_rt5645_quirk & CHT_RT5645_SSP0_AIF1) ||
656                 (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
657
658                 /* fixup cpu dai name name */
659                 snprintf(cht_rt5645_cpu_dai_name,
660                         sizeof(cht_rt5645_cpu_dai_name),
661                         "%s", "ssp0-port");
662
663                 cht_dailink[dai_index].cpu_dai_name =
664                         cht_rt5645_cpu_dai_name;
665         }
666
667         /* override plaform name, if required */
668         platform_name = mach->mach_params.platform;
669
670         ret_val = snd_soc_fixup_dai_links_platform_name(card,
671                                                         platform_name);
672         if (ret_val)
673                 return ret_val;
674
675         drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
676         if (IS_ERR(drv->mclk)) {
677                 dev_err(&pdev->dev,
678                         "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
679                         PTR_ERR(drv->mclk));
680                 return PTR_ERR(drv->mclk);
681         }
682
683         snd_soc_card_set_drvdata(card, drv);
684         ret_val = devm_snd_soc_register_card(&pdev->dev, card);
685         if (ret_val) {
686                 dev_err(&pdev->dev,
687                         "snd_soc_register_card failed %d\n", ret_val);
688                 return ret_val;
689         }
690         platform_set_drvdata(pdev, card);
691         return ret_val;
692 }
693
694 static struct platform_driver snd_cht_mc_driver = {
695         .driver = {
696                 .name = "cht-bsw-rt5645",
697         },
698         .probe = snd_cht_mc_probe,
699 };
700
701 module_platform_driver(snd_cht_mc_driver)
702
703 MODULE_DESCRIPTION("ASoC Intel(R) Braswell Machine driver");
704 MODULE_AUTHOR("Fang, Yang A,N,Harshapriya");
705 MODULE_LICENSE("GPL v2");
706 MODULE_ALIAS("platform:cht-bsw-rt5645");