linux/sound/soc/intel/boards/bytcr_rt5640.c
<<
>>
Prefs
   1/*
   2 *  byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform
   3 *
   4 *  Copyright (C) 2014 Intel Corp
   5 *  Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
   6 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   7 *
   8 *  This program is free software; you can redistribute it and/or modify
   9 *  it under the terms of the GNU General Public License as published by
  10 *  the Free Software Foundation; version 2 of the License.
  11 *
  12 *  This program is distributed in the hope that it will be useful, but
  13 *  WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 *  General Public License for more details.
  16 *
  17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  18 */
  19
  20#include <linux/i2c.h>
  21#include <linux/init.h>
  22#include <linux/module.h>
  23#include <linux/moduleparam.h>
  24#include <linux/platform_device.h>
  25#include <linux/acpi.h>
  26#include <linux/clk.h>
  27#include <linux/device.h>
  28#include <linux/dmi.h>
  29#include <linux/input.h>
  30#include <linux/slab.h>
  31#include <asm/cpu_device_id.h>
  32#include <asm/platform_sst_audio.h>
  33#include <sound/pcm.h>
  34#include <sound/pcm_params.h>
  35#include <sound/soc.h>
  36#include <sound/jack.h>
  37#include <sound/soc-acpi.h>
  38#include <dt-bindings/sound/rt5640.h>
  39#include "../../codecs/rt5640.h"
  40#include "../atom/sst-atom-controls.h"
  41#include "../common/sst-dsp.h"
  42
  43enum {
  44        BYT_RT5640_DMIC1_MAP,
  45        BYT_RT5640_DMIC2_MAP,
  46        BYT_RT5640_IN1_MAP,
  47        BYT_RT5640_IN3_MAP,
  48};
  49
  50enum {
  51        BYT_RT5640_JD_SRC_GPIO1         = (RT5640_JD_SRC_GPIO1 << 4),
  52        BYT_RT5640_JD_SRC_JD1_IN4P      = (RT5640_JD_SRC_JD1_IN4P << 4),
  53        BYT_RT5640_JD_SRC_JD2_IN4N      = (RT5640_JD_SRC_JD2_IN4N << 4),
  54        BYT_RT5640_JD_SRC_GPIO2         = (RT5640_JD_SRC_GPIO2 << 4),
  55        BYT_RT5640_JD_SRC_GPIO3         = (RT5640_JD_SRC_GPIO3 << 4),
  56        BYT_RT5640_JD_SRC_GPIO4         = (RT5640_JD_SRC_GPIO4 << 4),
  57};
  58
  59enum {
  60        BYT_RT5640_OVCD_TH_600UA        = (6 << 8),
  61        BYT_RT5640_OVCD_TH_1500UA       = (15 << 8),
  62        BYT_RT5640_OVCD_TH_2000UA       = (20 << 8),
  63};
  64
  65enum {
  66        BYT_RT5640_OVCD_SF_0P5          = (RT5640_OVCD_SF_0P5 << 13),
  67        BYT_RT5640_OVCD_SF_0P75         = (RT5640_OVCD_SF_0P75 << 13),
  68        BYT_RT5640_OVCD_SF_1P0          = (RT5640_OVCD_SF_1P0 << 13),
  69        BYT_RT5640_OVCD_SF_1P5          = (RT5640_OVCD_SF_1P5 << 13),
  70};
  71
  72#define BYT_RT5640_MAP(quirk)           ((quirk) &  GENMASK(3, 0))
  73#define BYT_RT5640_JDSRC(quirk)         (((quirk) & GENMASK(7, 4)) >> 4)
  74#define BYT_RT5640_OVCD_TH(quirk)       (((quirk) & GENMASK(12, 8)) >> 8)
  75#define BYT_RT5640_OVCD_SF(quirk)       (((quirk) & GENMASK(14, 13)) >> 13)
  76#define BYT_RT5640_JD_NOT_INV           BIT(16)
  77#define BYT_RT5640_MONO_SPEAKER         BIT(17)
  78#define BYT_RT5640_DIFF_MIC             BIT(18) /* default is single-ended */
  79#define BYT_RT5640_SSP2_AIF2            BIT(19) /* default is using AIF1  */
  80#define BYT_RT5640_SSP0_AIF1            BIT(20)
  81#define BYT_RT5640_SSP0_AIF2            BIT(21)
  82#define BYT_RT5640_MCLK_EN              BIT(22)
  83#define BYT_RT5640_MCLK_25MHZ           BIT(23)
  84
  85#define BYTCR_INPUT_DEFAULTS                            \
  86        (BYT_RT5640_IN3_MAP |                           \
  87         BYT_RT5640_JD_SRC_JD1_IN4P |                   \
  88         BYT_RT5640_OVCD_TH_2000UA |                    \
  89         BYT_RT5640_OVCD_SF_0P75 |                      \
  90         BYT_RT5640_DIFF_MIC)
  91
  92/* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
  93#define MAX_NO_PROPS 6
  94
  95struct byt_rt5640_private {
  96        struct snd_soc_jack jack;
  97        struct clk *mclk;
  98};
  99static bool is_bytcr;
 100
 101static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN;
 102static unsigned int quirk_override;
 103module_param_named(quirk, quirk_override, uint, 0444);
 104MODULE_PARM_DESC(quirk, "Board-specific quirk override");
 105
 106static void log_quirks(struct device *dev)
 107{
 108        int map;
 109        bool has_mclk = false;
 110        bool has_ssp0 = false;
 111        bool has_ssp0_aif1 = false;
 112        bool has_ssp0_aif2 = false;
 113        bool has_ssp2_aif2 = false;
 114
 115        map = BYT_RT5640_MAP(byt_rt5640_quirk);
 116        switch (map) {
 117        case BYT_RT5640_DMIC1_MAP:
 118                dev_info(dev, "quirk DMIC1_MAP enabled\n");
 119                break;
 120        case BYT_RT5640_DMIC2_MAP:
 121                dev_info(dev, "quirk DMIC2_MAP enabled\n");
 122                break;
 123        case BYT_RT5640_IN1_MAP:
 124                dev_info(dev, "quirk IN1_MAP enabled\n");
 125                break;
 126        case BYT_RT5640_IN3_MAP:
 127                dev_info(dev, "quirk IN3_MAP enabled\n");
 128                break;
 129        default:
 130                dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
 131                break;
 132        }
 133        if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
 134                dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
 135                         BYT_RT5640_JDSRC(byt_rt5640_quirk));
 136                dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
 137                         BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
 138                dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
 139                         BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
 140        }
 141        if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
 142                dev_info(dev, "quirk JD_NOT_INV enabled\n");
 143        if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
 144                dev_info(dev, "quirk MONO_SPEAKER enabled\n");
 145        if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
 146                dev_info(dev, "quirk DIFF_MIC enabled\n");
 147        if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
 148                dev_info(dev, "quirk SSP0_AIF1 enabled\n");
 149                has_ssp0 = true;
 150                has_ssp0_aif1 = true;
 151        }
 152        if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
 153                dev_info(dev, "quirk SSP0_AIF2 enabled\n");
 154                has_ssp0 = true;
 155                has_ssp0_aif2 = true;
 156        }
 157        if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
 158                dev_info(dev, "quirk SSP2_AIF2 enabled\n");
 159                has_ssp2_aif2 = true;
 160        }
 161        if (is_bytcr && !has_ssp0)
 162                dev_err(dev, "Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr\n");
 163        if (has_ssp0_aif1 && has_ssp0_aif2)
 164                dev_err(dev, "Invalid routing, SSP0 cannot be connected to both AIF1 and AIF2\n");
 165        if (has_ssp0 && has_ssp2_aif2)
 166                dev_err(dev, "Invalid routing, cannot have both SSP0 and SSP2 connected to codec\n");
 167
 168        if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
 169                dev_info(dev, "quirk MCLK_EN enabled\n");
 170                has_mclk = true;
 171        }
 172        if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
 173                if (has_mclk)
 174                        dev_info(dev, "quirk MCLK_25MHZ enabled\n");
 175                else
 176                        dev_err(dev, "quirk MCLK_25MHZ enabled but quirk MCLK not selected, will be ignored\n");
 177        }
 178}
 179
 180static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
 181                                              int rate)
 182{
 183        int ret;
 184
 185        /* Configure the PLL before selecting it */
 186        if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
 187                /* use bitclock as PLL input */
 188                if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
 189                    (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
 190                        /* 2x16 bit slots on SSP0 */
 191                        ret = snd_soc_dai_set_pll(codec_dai, 0,
 192                                                  RT5640_PLL1_S_BCLK1,
 193                                                  rate * 32, rate * 512);
 194                } else {
 195                        /* 2x15 bit slots on SSP2 */
 196                        ret = snd_soc_dai_set_pll(codec_dai, 0,
 197                                                  RT5640_PLL1_S_BCLK1,
 198                                                  rate * 50, rate * 512);
 199                }
 200        } else {
 201                if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
 202                        ret = snd_soc_dai_set_pll(codec_dai, 0,
 203                                                  RT5640_PLL1_S_MCLK,
 204                                                  25000000, rate * 512);
 205                } else {
 206                        ret = snd_soc_dai_set_pll(codec_dai, 0,
 207                                                  RT5640_PLL1_S_MCLK,
 208                                                  19200000, rate * 512);
 209                }
 210        }
 211
 212        if (ret < 0) {
 213                dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
 214                return ret;
 215        }
 216
 217        ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
 218                                     rate * 512, SND_SOC_CLOCK_IN);
 219        if (ret < 0) {
 220                dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
 221                return ret;
 222        }
 223
 224        return 0;
 225}
 226
 227#define BYT_CODEC_DAI1  "rt5640-aif1"
 228#define BYT_CODEC_DAI2  "rt5640-aif2"
 229
 230static int platform_clock_control(struct snd_soc_dapm_widget *w,
 231                                  struct snd_kcontrol *k, int  event)
 232{
 233        struct snd_soc_dapm_context *dapm = w->dapm;
 234        struct snd_soc_card *card = dapm->card;
 235        struct snd_soc_dai *codec_dai;
 236        struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
 237        int ret;
 238
 239        codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
 240        if (!codec_dai)
 241                codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
 242
 243        if (!codec_dai) {
 244                dev_err(card->dev,
 245                        "Codec dai not found; Unable to set platform clock\n");
 246                return -EIO;
 247        }
 248
 249        if (SND_SOC_DAPM_EVENT_ON(event)) {
 250                if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
 251                        ret = clk_prepare_enable(priv->mclk);
 252                        if (ret < 0) {
 253                                dev_err(card->dev,
 254                                        "could not configure MCLK state\n");
 255                                return ret;
 256                        }
 257                }
 258                ret = byt_rt5640_prepare_and_enable_pll1(codec_dai, 48000);
 259        } else {
 260                /*
 261                 * Set codec clock source to internal clock before
 262                 * turning off the platform clock. Codec needs clock
 263                 * for Jack detection and button press
 264                 */
 265                ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
 266                                             48000 * 512,
 267                                             SND_SOC_CLOCK_IN);
 268                if (!ret) {
 269                        if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
 270                                clk_disable_unprepare(priv->mclk);
 271                }
 272        }
 273
 274        if (ret < 0) {
 275                dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
 276                return ret;
 277        }
 278
 279        return 0;
 280}
 281
 282static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
 283        SND_SOC_DAPM_HP("Headphone", NULL),
 284        SND_SOC_DAPM_MIC("Headset Mic", NULL),
 285        SND_SOC_DAPM_MIC("Internal Mic", NULL),
 286        SND_SOC_DAPM_SPK("Speaker", NULL),
 287        SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
 288                            platform_clock_control, SND_SOC_DAPM_PRE_PMU |
 289                            SND_SOC_DAPM_POST_PMD),
 290
 291};
 292
 293static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
 294        {"Headphone", NULL, "Platform Clock"},
 295        {"Headset Mic", NULL, "Platform Clock"},
 296        {"Internal Mic", NULL, "Platform Clock"},
 297        {"Speaker", NULL, "Platform Clock"},
 298
 299        {"Headset Mic", NULL, "MICBIAS1"},
 300        {"IN2P", NULL, "Headset Mic"},
 301        {"Headphone", NULL, "HPOL"},
 302        {"Headphone", NULL, "HPOR"},
 303};
 304
 305static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
 306        {"DMIC1", NULL, "Internal Mic"},
 307};
 308
 309static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
 310        {"DMIC2", NULL, "Internal Mic"},
 311};
 312
 313static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
 314        {"Internal Mic", NULL, "MICBIAS1"},
 315        {"IN1P", NULL, "Internal Mic"},
 316};
 317
 318static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
 319        {"Internal Mic", NULL, "MICBIAS1"},
 320        {"IN3P", NULL, "Internal Mic"},
 321};
 322
 323static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
 324        {"ssp2 Tx", NULL, "codec_out0"},
 325        {"ssp2 Tx", NULL, "codec_out1"},
 326        {"codec_in0", NULL, "ssp2 Rx"},
 327        {"codec_in1", NULL, "ssp2 Rx"},
 328
 329        {"AIF1 Playback", NULL, "ssp2 Tx"},
 330        {"ssp2 Rx", NULL, "AIF1 Capture"},
 331};
 332
 333static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
 334        {"ssp2 Tx", NULL, "codec_out0"},
 335        {"ssp2 Tx", NULL, "codec_out1"},
 336        {"codec_in0", NULL, "ssp2 Rx"},
 337        {"codec_in1", NULL, "ssp2 Rx"},
 338
 339        {"AIF2 Playback", NULL, "ssp2 Tx"},
 340        {"ssp2 Rx", NULL, "AIF2 Capture"},
 341};
 342
 343static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
 344        {"ssp0 Tx", NULL, "modem_out"},
 345        {"modem_in", NULL, "ssp0 Rx"},
 346
 347        {"AIF1 Playback", NULL, "ssp0 Tx"},
 348        {"ssp0 Rx", NULL, "AIF1 Capture"},
 349};
 350
 351static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
 352        {"ssp0 Tx", NULL, "modem_out"},
 353        {"modem_in", NULL, "ssp0 Rx"},
 354
 355        {"AIF2 Playback", NULL, "ssp0 Tx"},
 356        {"ssp0 Rx", NULL, "AIF2 Capture"},
 357};
 358
 359static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
 360        {"Speaker", NULL, "SPOLP"},
 361        {"Speaker", NULL, "SPOLN"},
 362        {"Speaker", NULL, "SPORP"},
 363        {"Speaker", NULL, "SPORN"},
 364};
 365
 366static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
 367        {"Speaker", NULL, "SPOLP"},
 368        {"Speaker", NULL, "SPOLN"},
 369};
 370
 371static const struct snd_kcontrol_new byt_rt5640_controls[] = {
 372        SOC_DAPM_PIN_SWITCH("Headphone"),
 373        SOC_DAPM_PIN_SWITCH("Headset Mic"),
 374        SOC_DAPM_PIN_SWITCH("Internal Mic"),
 375        SOC_DAPM_PIN_SWITCH("Speaker"),
 376};
 377
 378static struct snd_soc_jack_pin rt5640_pins[] = {
 379        {
 380                .pin    = "Headphone",
 381                .mask   = SND_JACK_HEADPHONE,
 382        },
 383        {
 384                .pin    = "Headset Mic",
 385                .mask   = SND_JACK_MICROPHONE,
 386        },
 387};
 388
 389static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
 390                                        struct snd_pcm_hw_params *params)
 391{
 392        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 393        struct snd_soc_dai *dai = rtd->codec_dai;
 394
 395        return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
 396}
 397
 398/* Please keep this list alphabetically sorted */
 399static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 400        {       /* Acer Iconia Tab 8 W1-810 */
 401                .matches = {
 402                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
 403                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Iconia W1-810"),
 404                },
 405                .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
 406                                        BYT_RT5640_JD_SRC_JD1_IN4P |
 407                                        BYT_RT5640_OVCD_TH_2000UA |
 408                                        BYT_RT5640_OVCD_SF_0P75 |
 409                                        BYT_RT5640_SSP0_AIF1 |
 410                                        BYT_RT5640_MCLK_EN),
 411        },
 412        {
 413                .matches = {
 414                        DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 415                        DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
 416                },
 417                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
 418                                                 BYT_RT5640_MCLK_EN |
 419                                                 BYT_RT5640_SSP0_AIF1),
 420
 421        },
 422        {
 423                .matches = {
 424                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
 425                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"),
 426                },
 427                .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
 428                                        BYT_RT5640_MONO_SPEAKER |
 429                                        BYT_RT5640_SSP0_AIF1 |
 430                                        BYT_RT5640_MCLK_EN),
 431        },
 432        {
 433                .matches = {
 434                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 435                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
 436                },
 437                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
 438                                        BYT_RT5640_JD_SRC_JD2_IN4N |
 439                                        BYT_RT5640_OVCD_TH_2000UA |
 440                                        BYT_RT5640_OVCD_SF_0P75 |
 441                                        BYT_RT5640_MCLK_EN),
 442        },
 443        {
 444                .matches = {
 445                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 446                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
 447                },
 448                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
 449                                        BYT_RT5640_MONO_SPEAKER |
 450                                        BYT_RT5640_DIFF_MIC |
 451                                        BYT_RT5640_SSP0_AIF2 |
 452                                        BYT_RT5640_MCLK_EN),
 453        },
 454        {       /* Chuwi Vi8 (CWI506) */
 455                .matches = {
 456                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
 457                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"),
 458                        /* The above are too generic, also match BIOS info */
 459                        DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
 460                },
 461                .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
 462                                        BYT_RT5640_MONO_SPEAKER |
 463                                        BYT_RT5640_SSP0_AIF1 |
 464                                        BYT_RT5640_MCLK_EN),
 465        },
 466        {
 467                .matches = {
 468                        DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
 469                        DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
 470                },
 471                .driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
 472        },
 473        {
 474                .matches = {
 475                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 476                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
 477                },
 478                .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
 479                                        BYT_RT5640_JD_SRC_JD2_IN4N |
 480                                        BYT_RT5640_OVCD_TH_2000UA |
 481                                        BYT_RT5640_OVCD_SF_0P75 |
 482                                        BYT_RT5640_MONO_SPEAKER |
 483                                        BYT_RT5640_MCLK_EN),
 484        },
 485        {
 486                .matches = {
 487                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 488                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
 489                },
 490                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
 491                                        BYT_RT5640_MCLK_EN),
 492        },
 493        {       /* HP Pavilion x2 10-n000nd */
 494                .matches = {
 495                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 496                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
 497                },
 498                .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
 499                                        BYT_RT5640_JD_SRC_JD2_IN4N |
 500                                        BYT_RT5640_OVCD_TH_1500UA |
 501                                        BYT_RT5640_OVCD_SF_0P75 |
 502                                        BYT_RT5640_SSP0_AIF1 |
 503                                        BYT_RT5640_MCLK_EN),
 504        },
 505        {       /* HP Stream 7 */
 506                .matches = {
 507                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 508                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 7 Tablet"),
 509                },
 510                .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
 511                                        BYT_RT5640_MONO_SPEAKER |
 512                                        BYT_RT5640_JD_NOT_INV |
 513                                        BYT_RT5640_SSP0_AIF1 |
 514                                        BYT_RT5640_MCLK_EN),
 515        },
 516        {       /* I.T.Works TW891 */
 517                .matches = {
 518                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
 519                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
 520                        DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
 521                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
 522                },
 523                .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
 524                                        BYT_RT5640_MONO_SPEAKER |
 525                                        BYT_RT5640_SSP0_AIF1 |
 526                                        BYT_RT5640_MCLK_EN),
 527        },
 528        {       /* Lamina I8270 / T701BR.SE */
 529                .matches = {
 530                        DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Lamina"),
 531                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "T701BR.SE"),
 532                },
 533                .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
 534                                        BYT_RT5640_MONO_SPEAKER |
 535                                        BYT_RT5640_JD_NOT_INV |
 536                                        BYT_RT5640_SSP0_AIF1 |
 537                                        BYT_RT5640_MCLK_EN),
 538        },
 539        {       /* MSI S100 tablet */
 540                .matches = {
 541                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
 542                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "S100"),
 543                },
 544                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
 545                                        BYT_RT5640_JD_SRC_JD2_IN4N |
 546                                        BYT_RT5640_OVCD_TH_2000UA |
 547                                        BYT_RT5640_OVCD_SF_0P75 |
 548                                        BYT_RT5640_MONO_SPEAKER |
 549                                        BYT_RT5640_DIFF_MIC |
 550                                        BYT_RT5640_MCLK_EN),
 551        },
 552        {       /* Pipo W4 */
 553                .matches = {
 554                        DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
 555                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
 556                        /* The above are too generic, also match BIOS info */
 557                        DMI_MATCH(DMI_BIOS_VERSION, "V8L_WIN32_CHIPHD"),
 558                },
 559                .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
 560                                        BYT_RT5640_MONO_SPEAKER |
 561                                        BYT_RT5640_SSP0_AIF1 |
 562                                        BYT_RT5640_MCLK_EN),
 563        },
 564        {       /* Point of View Mobii TAB-P800W (V2.0) */
 565                .matches = {
 566                        DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
 567                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
 568                        /* The above are too generic, also match BIOS info */
 569                        DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
 570                        DMI_EXACT_MATCH(DMI_BIOS_DATE, "10/24/2014"),
 571                },
 572                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
 573                                        BYT_RT5640_JD_SRC_JD2_IN4N |
 574                                        BYT_RT5640_OVCD_TH_2000UA |
 575                                        BYT_RT5640_OVCD_SF_0P75 |
 576                                        BYT_RT5640_MONO_SPEAKER |
 577                                        BYT_RT5640_DIFF_MIC |
 578                                        BYT_RT5640_SSP0_AIF2 |
 579                                        BYT_RT5640_MCLK_EN),
 580        },
 581        {       /* Point of View Mobii TAB-P800W (V2.1) */
 582                .matches = {
 583                        DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
 584                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
 585                        /* The above are too generic, also match BIOS info */
 586                        DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
 587                        DMI_EXACT_MATCH(DMI_BIOS_DATE, "08/22/2014"),
 588                },
 589                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
 590                                        BYT_RT5640_JD_SRC_JD2_IN4N |
 591                                        BYT_RT5640_OVCD_TH_2000UA |
 592                                        BYT_RT5640_OVCD_SF_0P75 |
 593                                        BYT_RT5640_MONO_SPEAKER |
 594                                        BYT_RT5640_DIFF_MIC |
 595                                        BYT_RT5640_SSP0_AIF2 |
 596                                        BYT_RT5640_MCLK_EN),
 597        },
 598        {
 599                .matches = {
 600                        DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
 601                        DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
 602                },
 603                .driver_data = (void *)(BYT_RT5640_IN3_MAP |
 604                                        BYT_RT5640_MCLK_EN |
 605                                        BYT_RT5640_SSP0_AIF1),
 606        },
 607        {       /* Toshiba Satellite Click Mini L9W-B */
 608                .matches = {
 609                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 610                        DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
 611                },
 612                .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
 613                                        BYT_RT5640_JD_SRC_JD2_IN4N |
 614                                        BYT_RT5640_OVCD_TH_1500UA |
 615                                        BYT_RT5640_OVCD_SF_0P75 |
 616                                        BYT_RT5640_SSP0_AIF1 |
 617                                        BYT_RT5640_MCLK_EN),
 618        },
 619        {       /* Catch-all for generic Insyde tablets, must be last */
 620                .matches = {
 621                        DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
 622                },
 623                .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
 624                                        BYT_RT5640_MCLK_EN |
 625                                        BYT_RT5640_SSP0_AIF1),
 626
 627        },
 628        {}
 629};
 630
 631/*
 632 * Note this MUST be called before snd_soc_register_card(), so that the props
 633 * are in place before the codec component driver's probe function parses them.
 634 */
 635static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
 636{
 637        struct property_entry props[MAX_NO_PROPS] = {};
 638        struct device *i2c_dev;
 639        int ret, cnt = 0;
 640
 641        i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
 642        if (!i2c_dev)
 643                return -EPROBE_DEFER;
 644
 645        switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
 646        case BYT_RT5640_DMIC1_MAP:
 647                props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic1-data-pin",
 648                                                  RT5640_DMIC1_DATA_PIN_IN1P);
 649                break;
 650        case BYT_RT5640_DMIC2_MAP:
 651                props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic2-data-pin",
 652                                                  RT5640_DMIC2_DATA_PIN_IN1N);
 653                break;
 654        case BYT_RT5640_IN1_MAP:
 655                if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
 656                        props[cnt++] =
 657                                PROPERTY_ENTRY_BOOL("realtek,in1-differential");
 658                break;
 659        case BYT_RT5640_IN3_MAP:
 660                if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
 661                        props[cnt++] =
 662                                PROPERTY_ENTRY_BOOL("realtek,in3-differential");
 663                break;
 664        }
 665
 666        if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
 667                props[cnt++] = PROPERTY_ENTRY_U32(
 668                                    "realtek,jack-detect-source",
 669                                    BYT_RT5640_JDSRC(byt_rt5640_quirk));
 670
 671                props[cnt++] = PROPERTY_ENTRY_U32(
 672                                    "realtek,over-current-threshold-microamp",
 673                                    BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
 674
 675                props[cnt++] = PROPERTY_ENTRY_U32(
 676                                    "realtek,over-current-scale-factor",
 677                                    BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
 678        }
 679
 680        if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
 681                props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
 682
 683        ret = device_add_properties(i2c_dev, props);
 684        put_device(i2c_dev);
 685
 686        return ret;
 687}
 688
 689static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 690{
 691        struct snd_soc_card *card = runtime->card;
 692        struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
 693        struct snd_soc_component *component = runtime->codec_dai->component;
 694        const struct snd_soc_dapm_route *custom_map;
 695        int num_routes;
 696        int ret;
 697
 698        card->dapm.idle_bias_off = true;
 699
 700        /* Start with RC clk for jack-detect (we disable MCLK below) */
 701        if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
 702                snd_soc_component_update_bits(component, RT5640_GLB_CLK,
 703                        RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_RCCLK);
 704
 705        rt5640_sel_asrc_clk_src(component,
 706                                RT5640_DA_STEREO_FILTER |
 707                                RT5640_DA_MONO_L_FILTER |
 708                                RT5640_DA_MONO_R_FILTER |
 709                                RT5640_AD_STEREO_FILTER |
 710                                RT5640_AD_MONO_L_FILTER |
 711                                RT5640_AD_MONO_R_FILTER,
 712                                RT5640_CLK_SEL_ASRC);
 713
 714        ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
 715                                        ARRAY_SIZE(byt_rt5640_controls));
 716        if (ret) {
 717                dev_err(card->dev, "unable to add card controls\n");
 718                return ret;
 719        }
 720
 721        switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
 722        case BYT_RT5640_IN1_MAP:
 723                custom_map = byt_rt5640_intmic_in1_map;
 724                num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
 725                break;
 726        case BYT_RT5640_IN3_MAP:
 727                custom_map = byt_rt5640_intmic_in3_map;
 728                num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
 729                break;
 730        case BYT_RT5640_DMIC2_MAP:
 731                custom_map = byt_rt5640_intmic_dmic2_map;
 732                num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
 733                break;
 734        default:
 735                custom_map = byt_rt5640_intmic_dmic1_map;
 736                num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
 737        }
 738
 739        ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
 740        if (ret)
 741                return ret;
 742
 743        if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
 744                ret = snd_soc_dapm_add_routes(&card->dapm,
 745                                        byt_rt5640_ssp2_aif2_map,
 746                                        ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
 747        } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
 748                ret = snd_soc_dapm_add_routes(&card->dapm,
 749                                        byt_rt5640_ssp0_aif1_map,
 750                                        ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
 751        } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
 752                ret = snd_soc_dapm_add_routes(&card->dapm,
 753                                        byt_rt5640_ssp0_aif2_map,
 754                                        ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
 755        } else {
 756                ret = snd_soc_dapm_add_routes(&card->dapm,
 757                                        byt_rt5640_ssp2_aif1_map,
 758                                        ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
 759        }
 760        if (ret)
 761                return ret;
 762
 763        if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
 764                ret = snd_soc_dapm_add_routes(&card->dapm,
 765                                        byt_rt5640_mono_spk_map,
 766                                        ARRAY_SIZE(byt_rt5640_mono_spk_map));
 767        } else {
 768                ret = snd_soc_dapm_add_routes(&card->dapm,
 769                                        byt_rt5640_stereo_spk_map,
 770                                        ARRAY_SIZE(byt_rt5640_stereo_spk_map));
 771        }
 772        if (ret)
 773                return ret;
 774
 775        snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
 776        snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
 777
 778        if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
 779                /*
 780                 * The firmware might enable the clock at
 781                 * boot (this information may or may not
 782                 * be reflected in the enable clock register).
 783                 * To change the rate we must disable the clock
 784                 * first to cover these cases. Due to common
 785                 * clock framework restrictions that do not allow
 786                 * to disable a clock that has not been enabled,
 787                 * we need to enable the clock first.
 788                 */
 789                ret = clk_prepare_enable(priv->mclk);
 790                if (!ret)
 791                        clk_disable_unprepare(priv->mclk);
 792
 793                if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
 794                        ret = clk_set_rate(priv->mclk, 25000000);
 795                else
 796                        ret = clk_set_rate(priv->mclk, 19200000);
 797
 798                if (ret) {
 799                        dev_err(card->dev, "unable to set MCLK rate\n");
 800                        return ret;
 801                }
 802        }
 803
 804        if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
 805                ret = snd_soc_card_jack_new(card, "Headset",
 806                                            SND_JACK_HEADSET | SND_JACK_BTN_0,
 807                                            &priv->jack, rt5640_pins,
 808                                            ARRAY_SIZE(rt5640_pins));
 809                if (ret) {
 810                        dev_err(card->dev, "Jack creation failed %d\n", ret);
 811                        return ret;
 812                }
 813                snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
 814                                 KEY_PLAYPAUSE);
 815                snd_soc_component_set_jack(component, &priv->jack, NULL);
 816        }
 817
 818        return 0;
 819}
 820
 821static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
 822        .formats = SNDRV_PCM_FMTBIT_S24_LE,
 823        .rate_min = 48000,
 824        .rate_max = 48000,
 825        .channels_min = 2,
 826        .channels_max = 2,
 827};
 828
 829static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
 830                            struct snd_pcm_hw_params *params)
 831{
 832        struct snd_interval *rate = hw_param_interval(params,
 833                        SNDRV_PCM_HW_PARAM_RATE);
 834        struct snd_interval *channels = hw_param_interval(params,
 835                                                SNDRV_PCM_HW_PARAM_CHANNELS);
 836        int ret;
 837
 838        /* The DSP will covert the FE rate to 48k, stereo */
 839        rate->min = rate->max = 48000;
 840        channels->min = channels->max = 2;
 841
 842        if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
 843                (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
 844
 845                /* set SSP0 to 16-bit */
 846                params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
 847
 848                /*
 849                 * Default mode for SSP configuration is TDM 4 slot, override config
 850                 * with explicit setting to I2S 2ch 16-bit. The word length is set with
 851                 * dai_set_tdm_slot() since there is no other API exposed
 852                 */
 853                ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
 854                                        SND_SOC_DAIFMT_I2S     |
 855                                        SND_SOC_DAIFMT_NB_NF   |
 856                                        SND_SOC_DAIFMT_CBS_CFS
 857                        );
 858                if (ret < 0) {
 859                        dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
 860                        return ret;
 861                }
 862
 863                ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
 864                if (ret < 0) {
 865                        dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
 866                        return ret;
 867                }
 868
 869        } else {
 870
 871                /* set SSP2 to 24-bit */
 872                params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
 873
 874                /*
 875                 * Default mode for SSP configuration is TDM 4 slot, override config
 876                 * with explicit setting to I2S 2ch 24-bit. The word length is set with
 877                 * dai_set_tdm_slot() since there is no other API exposed
 878                 */
 879                ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
 880                                        SND_SOC_DAIFMT_I2S     |
 881                                        SND_SOC_DAIFMT_NB_NF   |
 882                                        SND_SOC_DAIFMT_CBS_CFS
 883                        );
 884                if (ret < 0) {
 885                        dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
 886                        return ret;
 887                }
 888
 889                ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
 890                if (ret < 0) {
 891                        dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
 892                        return ret;
 893                }
 894        }
 895        return 0;
 896}
 897
 898static int byt_rt5640_aif1_startup(struct snd_pcm_substream *substream)
 899{
 900        return snd_pcm_hw_constraint_single(substream->runtime,
 901                        SNDRV_PCM_HW_PARAM_RATE, 48000);
 902}
 903
 904static const struct snd_soc_ops byt_rt5640_aif1_ops = {
 905        .startup = byt_rt5640_aif1_startup,
 906};
 907
 908static const struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
 909        .hw_params = byt_rt5640_aif1_hw_params,
 910};
 911
 912static struct snd_soc_dai_link byt_rt5640_dais[] = {
 913        [MERR_DPCM_AUDIO] = {
 914                .name = "Baytrail Audio Port",
 915                .stream_name = "Baytrail Audio",
 916                .cpu_dai_name = "media-cpu-dai",
 917                .codec_dai_name = "snd-soc-dummy-dai",
 918                .codec_name = "snd-soc-dummy",
 919                .platform_name = "sst-mfld-platform",
 920                .nonatomic = true,
 921                .dynamic = 1,
 922                .dpcm_playback = 1,
 923                .dpcm_capture = 1,
 924                .ops = &byt_rt5640_aif1_ops,
 925        },
 926        [MERR_DPCM_DEEP_BUFFER] = {
 927                .name = "Deep-Buffer Audio Port",
 928                .stream_name = "Deep-Buffer Audio",
 929                .cpu_dai_name = "deepbuffer-cpu-dai",
 930                .codec_dai_name = "snd-soc-dummy-dai",
 931                .codec_name = "snd-soc-dummy",
 932                .platform_name = "sst-mfld-platform",
 933                .nonatomic = true,
 934                .dynamic = 1,
 935                .dpcm_playback = 1,
 936                .ops = &byt_rt5640_aif1_ops,
 937        },
 938                /* back ends */
 939        {
 940                .name = "SSP2-Codec",
 941                .id = 0,
 942                .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
 943                .platform_name = "sst-mfld-platform",
 944                .no_pcm = 1,
 945                .codec_dai_name = "rt5640-aif1", /* changed w/ quirk */
 946                .codec_name = "i2c-10EC5640:00", /* overwritten with HID */
 947                .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 948                                                | SND_SOC_DAIFMT_CBS_CFS,
 949                .be_hw_params_fixup = byt_rt5640_codec_fixup,
 950                .ignore_suspend = 1,
 951                .nonatomic = true,
 952                .dpcm_playback = 1,
 953                .dpcm_capture = 1,
 954                .init = byt_rt5640_init,
 955                .ops = &byt_rt5640_be_ssp2_ops,
 956        },
 957};
 958
 959/* SoC card */
 960static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
 961static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
 962static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
 963static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
 964
 965static int byt_rt5640_suspend(struct snd_soc_card *card)
 966{
 967        struct snd_soc_component *component;
 968
 969        if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
 970                return 0;
 971
 972        list_for_each_entry(component, &card->component_dev_list, card_list) {
 973                if (!strcmp(component->name, byt_rt5640_codec_name)) {
 974                        dev_dbg(component->dev, "disabling jack detect before suspend\n");
 975                        snd_soc_component_set_jack(component, NULL, NULL);
 976                        break;
 977                }
 978        }
 979
 980        return 0;
 981}
 982
 983static int byt_rt5640_resume(struct snd_soc_card *card)
 984{
 985        struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
 986        struct snd_soc_component *component;
 987
 988        if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
 989                return 0;
 990
 991        list_for_each_entry(component, &card->component_dev_list, card_list) {
 992                if (!strcmp(component->name, byt_rt5640_codec_name)) {
 993                        dev_dbg(component->dev, "re-enabling jack detect after resume\n");
 994                        snd_soc_component_set_jack(component, &priv->jack, NULL);
 995                        break;
 996                }
 997        }
 998
 999        return 0;
1000}
1001
1002static struct snd_soc_card byt_rt5640_card = {
1003        .name = "bytcr-rt5640",
1004        .owner = THIS_MODULE,
1005        .dai_link = byt_rt5640_dais,
1006        .num_links = ARRAY_SIZE(byt_rt5640_dais),
1007        .dapm_widgets = byt_rt5640_widgets,
1008        .num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
1009        .dapm_routes = byt_rt5640_audio_map,
1010        .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
1011        .fully_routed = true,
1012        .suspend_pre = byt_rt5640_suspend,
1013        .resume_post = byt_rt5640_resume,
1014};
1015
1016static bool is_valleyview(void)
1017{
1018        static const struct x86_cpu_id cpu_ids[] = {
1019                { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
1020                {}
1021        };
1022
1023        if (!x86_match_cpu(cpu_ids))
1024                return false;
1025        return true;
1026}
1027
1028struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
1029        u64 aif_value;       /* 1: AIF1, 2: AIF2 */
1030        u64 mclock_value;    /* usually 25MHz (0x17d7940), ignored */
1031};
1032
1033static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
1034{
1035        const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
1036        const struct dmi_system_id *dmi_id;
1037        struct byt_rt5640_private *priv;
1038        struct snd_soc_acpi_mach *mach;
1039        const char *i2c_name = NULL;
1040        int ret_val = 0;
1041        int dai_index = 0;
1042        int i;
1043
1044        is_bytcr = false;
1045        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1046        if (!priv)
1047                return -ENOMEM;
1048
1049        /* register the soc card */
1050        byt_rt5640_card.dev = &pdev->dev;
1051        mach = byt_rt5640_card.dev->platform_data;
1052        snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
1053
1054        /* fix index of codec dai */
1055        for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
1056                if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) {
1057                        dai_index = i;
1058                        break;
1059                }
1060        }
1061
1062        /* fixup codec name based on HID */
1063        i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
1064        if (i2c_name) {
1065                snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
1066                        "%s%s", "i2c-", i2c_name);
1067
1068                byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
1069        }
1070
1071        /*
1072         * swap SSP0 if bytcr is detected
1073         * (will be overridden if DMI quirk is detected)
1074         */
1075        if (is_valleyview()) {
1076                struct sst_platform_info *p_info = mach->pdata;
1077                const struct sst_res_info *res_info = p_info->res_info;
1078
1079                if (res_info->acpi_ipc_irq_index == 0)
1080                        is_bytcr = true;
1081        }
1082
1083        if (is_bytcr) {
1084                /*
1085                 * Baytrail CR platforms may have CHAN package in BIOS, try
1086                 * to find relevant routing quirk based as done on Windows
1087                 * platforms. We have to read the information directly from the
1088                 * BIOS, at this stage the card is not created and the links
1089                 * with the codec driver/pdata are non-existent
1090                 */
1091
1092                struct acpi_chan_package chan_package;
1093
1094                /* format specified: 2 64-bit integers */
1095                struct acpi_buffer format = {sizeof("NN"), "NN"};
1096                struct acpi_buffer state = {0, NULL};
1097                struct snd_soc_acpi_package_context pkg_ctx;
1098                bool pkg_found = false;
1099
1100                state.length = sizeof(chan_package);
1101                state.pointer = &chan_package;
1102
1103                pkg_ctx.name = "CHAN";
1104                pkg_ctx.length = 2;
1105                pkg_ctx.format = &format;
1106                pkg_ctx.state = &state;
1107                pkg_ctx.data_valid = false;
1108
1109                pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
1110                                                               &pkg_ctx);
1111                if (pkg_found) {
1112                        if (chan_package.aif_value == 1) {
1113                                dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
1114                                byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF1;
1115                        } else  if (chan_package.aif_value == 2) {
1116                                dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
1117                                byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1118                        } else {
1119                                dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
1120                                pkg_found = false;
1121                        }
1122                }
1123
1124                if (!pkg_found) {
1125                        /* no BIOS indications, assume SSP0-AIF2 connection */
1126                        byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1127                }
1128
1129                /* change defaults for Baytrail-CR capture */
1130                byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
1131        } else {
1132                byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP |
1133                                    BYT_RT5640_JD_SRC_JD2_IN4N |
1134                                    BYT_RT5640_OVCD_TH_2000UA |
1135                                    BYT_RT5640_OVCD_SF_0P75;
1136        }
1137
1138        /* check quirks before creating card */
1139        dmi_id = dmi_first_match(byt_rt5640_quirk_table);
1140        if (dmi_id)
1141                byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
1142        if (quirk_override) {
1143                dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
1144                         (unsigned int)byt_rt5640_quirk, quirk_override);
1145                byt_rt5640_quirk = quirk_override;
1146        }
1147
1148        /* Must be called before register_card, also see declaration comment. */
1149        ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name);
1150        if (ret_val)
1151                return ret_val;
1152
1153        log_quirks(&pdev->dev);
1154
1155        if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
1156            (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1157
1158                /* fixup codec aif name */
1159                snprintf(byt_rt5640_codec_aif_name,
1160                        sizeof(byt_rt5640_codec_aif_name),
1161                        "%s", "rt5640-aif2");
1162
1163                byt_rt5640_dais[dai_index].codec_dai_name =
1164                        byt_rt5640_codec_aif_name;
1165        }
1166
1167        if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
1168            (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1169
1170                /* fixup cpu dai name name */
1171                snprintf(byt_rt5640_cpu_dai_name,
1172                        sizeof(byt_rt5640_cpu_dai_name),
1173                        "%s", "ssp0-port");
1174
1175                byt_rt5640_dais[dai_index].cpu_dai_name =
1176                        byt_rt5640_cpu_dai_name;
1177        }
1178
1179        if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
1180                priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
1181                if (IS_ERR(priv->mclk)) {
1182                        ret_val = PTR_ERR(priv->mclk);
1183
1184                        dev_err(&pdev->dev,
1185                                "Failed to get MCLK from pmc_plt_clk_3: %d\n",
1186                                ret_val);
1187
1188                        /*
1189                         * Fall back to bit clock usage for -ENOENT (clock not
1190                         * available likely due to missing dependencies), bail
1191                         * for all other errors, including -EPROBE_DEFER
1192                         */
1193                        if (ret_val != -ENOENT)
1194                                return ret_val;
1195                        byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
1196                }
1197        }
1198
1199        snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
1200                 "bytcr-rt5640-%s-spk-%s-mic",
1201                 (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
1202                        "mono" : "stereo",
1203                 map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
1204        byt_rt5640_card.long_name = byt_rt5640_long_name;
1205
1206        ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
1207
1208        if (ret_val) {
1209                dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
1210                        ret_val);
1211                return ret_val;
1212        }
1213        platform_set_drvdata(pdev, &byt_rt5640_card);
1214        return ret_val;
1215}
1216
1217static struct platform_driver snd_byt_rt5640_mc_driver = {
1218        .driver = {
1219                .name = "bytcr_rt5640",
1220        },
1221        .probe = snd_byt_rt5640_mc_probe,
1222};
1223
1224module_platform_driver(snd_byt_rt5640_mc_driver);
1225
1226MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
1227MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
1228MODULE_LICENSE("GPL v2");
1229MODULE_ALIAS("platform:bytcr_rt5640");
1230