ASoC: Intel: kbl_rt5663_max98927: Map BTN_0 to KEY_PLAYPAUSE
[linux-2.6-block.git] / sound / soc / intel / boards / kbl_rt5663_max98927.c
index 7f76074207063a5da6ad8c9874002646d42c88c1..94a34db4f8c05a32409142b6477c3af287a304d3 100644 (file)
@@ -17,6 +17,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/input.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <sound/core.h>
@@ -208,6 +209,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
        int ret;
        struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card);
        struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_jack *jack;
 
        /*
         * Headset buttons map to the google Reference headset.
@@ -221,6 +223,13 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
                dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
                return ret;
        }
+
+       jack = &ctx->kabylake_headset;
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
        rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
        return ret;
 }
@@ -341,13 +350,28 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
        struct snd_interval *channels = hw_param_interval(params,
                        SNDRV_PCM_HW_PARAM_CHANNELS);
        struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+       struct snd_soc_dpcm *dpcm = container_of(
+                       params, struct snd_soc_dpcm, hw_params);
+       struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link;
+       struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link;
 
-       /* The ADSP will convert the FE rate to 48k, stereo */
-       rate->min = rate->max = 48000;
-       channels->min = channels->max = 2;
-       /* set SSP1 to 24 bit */
-       snd_mask_none(fmt);
-       snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
+       /*
+        * The ADSP will convert the FE rate to 48k, stereo, 24 bit
+        */
+       if (!strcmp(fe_dai_link->name, "Kbl Audio Port") ||
+           !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
+           !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
+               rate->min = rate->max = 48000;
+               channels->min = channels->max = 2;
+               snd_mask_none(fmt);
+               snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
+       }
+       /*
+        * The speaker on the SSP0 supports S16_LE and not S24_LE.
+        * thus changing the mask here
+        */
+       if (!strcmp(be_dai_link->name, "SSP0-Codec"))
+               snd_mask_set(fmt, SNDRV_PCM_FORMAT_S16_LE);
 
        return 0;
 }
@@ -390,6 +414,43 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
        return 0;
 }
 
+static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
+                                       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       int ret = 0, j;
+
+       for (j = 0; j < rtd->num_codecs; j++) {
+               struct snd_soc_dai *codec_dai = rtd->codec_dais[j];
+
+               if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) {
+                       /*
+                        * Use channel 4 and 5 for the first amp
+                        */
+                       ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16);
+                       if (ret < 0) {
+                               dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
+                               return ret;
+                       }
+               }
+               if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) {
+                       /*
+                        * Use channel 6 and 7 for the second amp
+                        */
+                       ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16);
+                       if (ret < 0) {
+                               dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
+                               return ret;
+                       }
+               }
+       }
+       return ret;
+}
+
+static struct snd_soc_ops kabylake_ssp0_ops = {
+       .hw_params = kabylake_ssp0_hw_params,
+};
+
 static unsigned int channels_dmic[] = {
        2, 4,
 };
@@ -593,12 +654,13 @@ static struct snd_soc_dai_link kabylake_dais[] = {
                .no_pcm = 1,
                .codecs = max98927_codec_components,
                .num_codecs = ARRAY_SIZE(max98927_codec_components),
-               .dai_fmt = SND_SOC_DAIFMT_I2S |
+               .dai_fmt = SND_SOC_DAIFMT_DSP_B |
                        SND_SOC_DAIFMT_NB_NF |
                        SND_SOC_DAIFMT_CBS_CFS,
                .ignore_pmdown_time = 1,
                .be_hw_params_fixup = kabylake_ssp_fixup,
                .dpcm_playback = 1,
+               .ops = &kabylake_ssp0_ops,
        },
        {
                /* SSP1 - Codec */