#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
 #include <asm/platform_sst_audio.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
        struct clk *mclk;
 };
 
+#define BYT_CHT_ES8316_SSP0                    BIT(16)
+
+static int quirk;
+
+static int quirk_override = -1;
+module_param_named(quirk, quirk_override, int, 0444);
+MODULE_PARM_DESC(quirk, "Board-specific quirk override");
+
+static void log_quirks(struct device *dev)
+{
+       if (quirk & BYT_CHT_ES8316_SSP0)
+               dev_info(dev, "quirk SSP0 enabled");
+}
+
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
        SND_SOC_DAPM_HP("Headphone", NULL),
 
 
        {"Headphone", NULL, "HPOL"},
        {"Headphone", NULL, "HPOR"},
+};
+
+static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
+       {"Playback", NULL, "ssp0 Tx"},
+       {"ssp0 Tx", NULL, "modem_out"},
+       {"modem_in", NULL, "ssp0 Rx"},
+       {"ssp0 Rx", NULL, "Capture"},
+};
 
+static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
        {"Playback", NULL, "ssp2 Tx"},
        {"ssp2 Tx", NULL, "codec_out0"},
        {"ssp2 Tx", NULL, "codec_out1"},
 {
        struct snd_soc_card *card = runtime->card;
        struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+       const struct snd_soc_dapm_route *custom_map;
+       int num_routes;
        int ret;
 
        card->dapm.idle_bias_off = true;
 
+       if (quirk & BYT_CHT_ES8316_SSP0) {
+               custom_map = byt_cht_es8316_ssp0_map;
+               num_routes = ARRAY_SIZE(byt_cht_es8316_ssp0_map);
+       } else {
+               custom_map = byt_cht_es8316_ssp2_map;
+               num_routes = ARRAY_SIZE(byt_cht_es8316_ssp2_map);
+       }
+       ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
+       if (ret)
+               return ret;
+
        /*
         * The firmware might enable the clock at boot (this information
         * may or may not be reflected in the enable clock register).
                        SNDRV_PCM_HW_PARAM_RATE);
        struct snd_interval *channels = hw_param_interval(params,
                                                SNDRV_PCM_HW_PARAM_CHANNELS);
-       int ret;
+       int ret, bits;
 
        /* The DSP will covert the FE rate to 48k, stereo */
        rate->min = rate->max = 48000;
        channels->min = channels->max = 2;
 
-       /* set SSP2 to 24-bit */
-       params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+       if (quirk & BYT_CHT_ES8316_SSP0) {
+               /* set SSP0 to 16-bit */
+               params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
+               bits = 16;
+       } else {
+               /* set SSP2 to 24-bit */
+               params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+               bits = 24;
+       }
 
        /*
         * Default mode for SSP configuration is TDM 4 slot, override config
                return ret;
        }
 
-       ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
+       ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits);
        if (ret < 0) {
                dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
                return ret;
        .fully_routed = true,
 };
 
+static const struct x86_cpu_id baytrail_cpu_ids[] = {
+       { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT }, /* Valleyview */
+       {}
+};
+
 static char codec_name[SND_ACPI_I2C_ID_LEN];
 
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
                byt_cht_es8316_dais[dai_index].codec_name = codec_name;
        }
 
+       /* Check for BYTCR or other platform and setup quirks */
+       if (x86_match_cpu(baytrail_cpu_ids) &&
+           mach->mach_params.acpi_ipc_irq_index == 0) {
+               /* On BYTCR default to SSP0 */
+               quirk = BYT_CHT_ES8316_SSP0;
+       } else {
+               quirk = 0;
+       }
+       if (quirk_override != -1) {
+               dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
+                        quirk_override);
+               quirk = quirk_override;
+       }
+       log_quirks(dev);
+
+       if (quirk & BYT_CHT_ES8316_SSP0)
+               byt_cht_es8316_dais[dai_index].cpu_dai_name = "ssp0-port";
+
        /* get the clock */
        priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
        if (IS_ERR(priv->mclk)) {