Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform
0004  *
0005  *  Copyright (C) 2014 Intel Corp
0006  *  Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
0007  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0008  *
0009  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0010  */
0011 
0012 #include <linux/i2c.h>
0013 #include <linux/init.h>
0014 #include <linux/module.h>
0015 #include <linux/moduleparam.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/acpi.h>
0018 #include <linux/clk.h>
0019 #include <linux/device.h>
0020 #include <linux/dmi.h>
0021 #include <linux/gpio/consumer.h>
0022 #include <linux/gpio/machine.h>
0023 #include <linux/input.h>
0024 #include <linux/slab.h>
0025 #include <sound/pcm.h>
0026 #include <sound/pcm_params.h>
0027 #include <sound/soc.h>
0028 #include <sound/jack.h>
0029 #include <sound/soc-acpi.h>
0030 #include <dt-bindings/sound/rt5640.h>
0031 #include "../../codecs/rt5640.h"
0032 #include "../atom/sst-atom-controls.h"
0033 #include "../common/soc-intel-quirks.h"
0034 
0035 enum {
0036     BYT_RT5640_DMIC1_MAP,
0037     BYT_RT5640_DMIC2_MAP,
0038     BYT_RT5640_IN1_MAP,
0039     BYT_RT5640_IN3_MAP,
0040     BYT_RT5640_NO_INTERNAL_MIC_MAP,
0041 };
0042 
0043 #define RT5640_JD_SRC_EXT_GPIO          0x0f
0044 
0045 enum {
0046     BYT_RT5640_JD_SRC_GPIO1     = (RT5640_JD_SRC_GPIO1 << 4),
0047     BYT_RT5640_JD_SRC_JD1_IN4P  = (RT5640_JD_SRC_JD1_IN4P << 4),
0048     BYT_RT5640_JD_SRC_JD2_IN4N  = (RT5640_JD_SRC_JD2_IN4N << 4),
0049     BYT_RT5640_JD_SRC_GPIO2     = (RT5640_JD_SRC_GPIO2 << 4),
0050     BYT_RT5640_JD_SRC_GPIO3     = (RT5640_JD_SRC_GPIO3 << 4),
0051     BYT_RT5640_JD_SRC_GPIO4     = (RT5640_JD_SRC_GPIO4 << 4),
0052     BYT_RT5640_JD_SRC_EXT_GPIO  = (RT5640_JD_SRC_EXT_GPIO << 4)
0053 };
0054 
0055 enum {
0056     BYT_RT5640_OVCD_TH_600UA    = (6 << 8),
0057     BYT_RT5640_OVCD_TH_1500UA   = (15 << 8),
0058     BYT_RT5640_OVCD_TH_2000UA   = (20 << 8),
0059 };
0060 
0061 enum {
0062     BYT_RT5640_OVCD_SF_0P5      = (RT5640_OVCD_SF_0P5 << 13),
0063     BYT_RT5640_OVCD_SF_0P75     = (RT5640_OVCD_SF_0P75 << 13),
0064     BYT_RT5640_OVCD_SF_1P0      = (RT5640_OVCD_SF_1P0 << 13),
0065     BYT_RT5640_OVCD_SF_1P5      = (RT5640_OVCD_SF_1P5 << 13),
0066 };
0067 
0068 #define BYT_RT5640_MAP(quirk)       ((quirk) &  GENMASK(3, 0))
0069 #define BYT_RT5640_JDSRC(quirk)     (((quirk) & GENMASK(7, 4)) >> 4)
0070 #define BYT_RT5640_OVCD_TH(quirk)   (((quirk) & GENMASK(12, 8)) >> 8)
0071 #define BYT_RT5640_OVCD_SF(quirk)   (((quirk) & GENMASK(14, 13)) >> 13)
0072 #define BYT_RT5640_JD_NOT_INV       BIT(16)
0073 #define BYT_RT5640_MONO_SPEAKER     BIT(17)
0074 #define BYT_RT5640_DIFF_MIC     BIT(18) /* default is single-ended */
0075 #define BYT_RT5640_SSP2_AIF2        BIT(19) /* default is using AIF1  */
0076 #define BYT_RT5640_SSP0_AIF1        BIT(20)
0077 #define BYT_RT5640_SSP0_AIF2        BIT(21)
0078 #define BYT_RT5640_MCLK_EN      BIT(22)
0079 #define BYT_RT5640_MCLK_25MHZ       BIT(23)
0080 #define BYT_RT5640_NO_SPEAKERS      BIT(24)
0081 #define BYT_RT5640_LINEOUT      BIT(25)
0082 #define BYT_RT5640_LINEOUT_AS_HP2   BIT(26)
0083 #define BYT_RT5640_HSMIC2_ON_IN1    BIT(27)
0084 #define BYT_RT5640_JD_HP_ELITEP_1000G2  BIT(28)
0085 #define BYT_RT5640_USE_AMCR0F28     BIT(29)
0086 
0087 #define BYTCR_INPUT_DEFAULTS                \
0088     (BYT_RT5640_IN3_MAP |               \
0089      BYT_RT5640_JD_SRC_JD1_IN4P |           \
0090      BYT_RT5640_OVCD_TH_2000UA |            \
0091      BYT_RT5640_OVCD_SF_0P75 |          \
0092      BYT_RT5640_DIFF_MIC)
0093 
0094 /* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
0095 #define MAX_NO_PROPS 6
0096 
0097 struct byt_rt5640_private {
0098     struct snd_soc_jack jack;
0099     struct snd_soc_jack jack2;
0100     struct rt5640_set_jack_data jack_data;
0101     struct gpio_desc *hsmic_detect;
0102     struct clk *mclk;
0103     struct device *codec_dev;
0104 };
0105 static bool is_bytcr;
0106 
0107 static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN;
0108 static int quirk_override = -1;
0109 module_param_named(quirk, quirk_override, int, 0444);
0110 MODULE_PARM_DESC(quirk, "Board-specific quirk override");
0111 
0112 static void log_quirks(struct device *dev)
0113 {
0114     int map;
0115     bool has_mclk = false;
0116     bool has_ssp0 = false;
0117     bool has_ssp0_aif1 = false;
0118     bool has_ssp0_aif2 = false;
0119     bool has_ssp2_aif2 = false;
0120 
0121     map = BYT_RT5640_MAP(byt_rt5640_quirk);
0122     switch (map) {
0123     case BYT_RT5640_DMIC1_MAP:
0124         dev_info(dev, "quirk DMIC1_MAP enabled\n");
0125         break;
0126     case BYT_RT5640_DMIC2_MAP:
0127         dev_info(dev, "quirk DMIC2_MAP enabled\n");
0128         break;
0129     case BYT_RT5640_IN1_MAP:
0130         dev_info(dev, "quirk IN1_MAP enabled\n");
0131         break;
0132     case BYT_RT5640_IN3_MAP:
0133         dev_info(dev, "quirk IN3_MAP enabled\n");
0134         break;
0135     case BYT_RT5640_NO_INTERNAL_MIC_MAP:
0136         dev_info(dev, "quirk NO_INTERNAL_MIC_MAP enabled\n");
0137         break;
0138     default:
0139         dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
0140         break;
0141     }
0142     if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1)
0143         dev_info(dev, "quirk HSMIC2_ON_IN1 enabled\n");
0144     if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
0145         dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
0146              BYT_RT5640_JDSRC(byt_rt5640_quirk));
0147         dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
0148              BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
0149         dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
0150              BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
0151     }
0152     if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
0153         dev_info(dev, "quirk JD_NOT_INV enabled\n");
0154     if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2)
0155         dev_info(dev, "quirk JD_HP_ELITEPAD_1000G2 enabled\n");
0156     if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
0157         dev_info(dev, "quirk MONO_SPEAKER enabled\n");
0158     if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)
0159         dev_info(dev, "quirk NO_SPEAKERS enabled\n");
0160     if (byt_rt5640_quirk & BYT_RT5640_LINEOUT)
0161         dev_info(dev, "quirk LINEOUT enabled\n");
0162     if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2)
0163         dev_info(dev, "quirk LINEOUT_AS_HP2 enabled\n");
0164     if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
0165         dev_info(dev, "quirk DIFF_MIC enabled\n");
0166     if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
0167         dev_info(dev, "quirk SSP0_AIF1 enabled\n");
0168         has_ssp0 = true;
0169         has_ssp0_aif1 = true;
0170     }
0171     if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
0172         dev_info(dev, "quirk SSP0_AIF2 enabled\n");
0173         has_ssp0 = true;
0174         has_ssp0_aif2 = true;
0175     }
0176     if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
0177         dev_info(dev, "quirk SSP2_AIF2 enabled\n");
0178         has_ssp2_aif2 = true;
0179     }
0180     if (is_bytcr && !has_ssp0)
0181         dev_err(dev, "Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr\n");
0182     if (has_ssp0_aif1 && has_ssp0_aif2)
0183         dev_err(dev, "Invalid routing, SSP0 cannot be connected to both AIF1 and AIF2\n");
0184     if (has_ssp0 && has_ssp2_aif2)
0185         dev_err(dev, "Invalid routing, cannot have both SSP0 and SSP2 connected to codec\n");
0186 
0187     if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
0188         dev_info(dev, "quirk MCLK_EN enabled\n");
0189         has_mclk = true;
0190     }
0191     if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
0192         if (has_mclk)
0193             dev_info(dev, "quirk MCLK_25MHZ enabled\n");
0194         else
0195             dev_err(dev, "quirk MCLK_25MHZ enabled but quirk MCLK not selected, will be ignored\n");
0196     }
0197 }
0198 
0199 static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
0200                           int rate)
0201 {
0202     int ret;
0203 
0204     /* Configure the PLL before selecting it */
0205     if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
0206         /* use bitclock as PLL input */
0207         if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
0208             (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
0209             /* 2x16 bit slots on SSP0 */
0210             ret = snd_soc_dai_set_pll(codec_dai, 0,
0211                           RT5640_PLL1_S_BCLK1,
0212                           rate * 32, rate * 512);
0213         } else {
0214             /* 2x15 bit slots on SSP2 */
0215             ret = snd_soc_dai_set_pll(codec_dai, 0,
0216                           RT5640_PLL1_S_BCLK1,
0217                           rate * 50, rate * 512);
0218         }
0219     } else {
0220         if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
0221             ret = snd_soc_dai_set_pll(codec_dai, 0,
0222                           RT5640_PLL1_S_MCLK,
0223                           25000000, rate * 512);
0224         } else {
0225             ret = snd_soc_dai_set_pll(codec_dai, 0,
0226                           RT5640_PLL1_S_MCLK,
0227                           19200000, rate * 512);
0228         }
0229     }
0230 
0231     if (ret < 0) {
0232         dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
0233         return ret;
0234     }
0235 
0236     ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
0237                      rate * 512, SND_SOC_CLOCK_IN);
0238     if (ret < 0) {
0239         dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
0240         return ret;
0241     }
0242 
0243     return 0;
0244 }
0245 
0246 #define BYT_CODEC_DAI1  "rt5640-aif1"
0247 #define BYT_CODEC_DAI2  "rt5640-aif2"
0248 
0249 static struct snd_soc_dai *byt_rt5640_get_codec_dai(struct snd_soc_dapm_context *dapm)
0250 {
0251     struct snd_soc_card *card = dapm->card;
0252     struct snd_soc_dai *codec_dai;
0253 
0254     codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
0255     if (!codec_dai)
0256         codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
0257     if (!codec_dai)
0258         dev_err(card->dev, "Error codec dai not found\n");
0259 
0260     return codec_dai;
0261 }
0262 
0263 static int platform_clock_control(struct snd_soc_dapm_widget *w,
0264                   struct snd_kcontrol *k, int  event)
0265 {
0266     struct snd_soc_dapm_context *dapm = w->dapm;
0267     struct snd_soc_card *card = dapm->card;
0268     struct snd_soc_dai *codec_dai;
0269     struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
0270     int ret;
0271 
0272     codec_dai = byt_rt5640_get_codec_dai(dapm);
0273     if (!codec_dai)
0274         return -EIO;
0275 
0276     if (SND_SOC_DAPM_EVENT_ON(event)) {
0277         ret = clk_prepare_enable(priv->mclk);
0278         if (ret < 0) {
0279             dev_err(card->dev, "could not configure MCLK state\n");
0280             return ret;
0281         }
0282         ret = byt_rt5640_prepare_and_enable_pll1(codec_dai, 48000);
0283     } else {
0284         /*
0285          * Set codec clock source to internal clock before
0286          * turning off the platform clock. Codec needs clock
0287          * for Jack detection and button press
0288          */
0289         ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
0290                          48000 * 512,
0291                          SND_SOC_CLOCK_IN);
0292         if (!ret)
0293             clk_disable_unprepare(priv->mclk);
0294     }
0295 
0296     if (ret < 0) {
0297         dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
0298         return ret;
0299     }
0300 
0301     return 0;
0302 }
0303 
0304 static int byt_rt5640_event_lineout(struct snd_soc_dapm_widget *w,
0305             struct snd_kcontrol *k, int event)
0306 {
0307     unsigned int gpio_ctrl3_val = RT5640_GP1_PF_OUT;
0308     struct snd_soc_dai *codec_dai;
0309 
0310     if (!(byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2))
0311         return 0;
0312 
0313     /*
0314      * On devices which use line-out as a second headphones output,
0315      * the codec's GPIO1 pin is used to enable an external HP-amp.
0316      */
0317 
0318     codec_dai = byt_rt5640_get_codec_dai(w->dapm);
0319     if (!codec_dai)
0320         return -EIO;
0321 
0322     if (SND_SOC_DAPM_EVENT_ON(event))
0323         gpio_ctrl3_val |= RT5640_GP1_OUT_HI;
0324 
0325     snd_soc_component_update_bits(codec_dai->component, RT5640_GPIO_CTRL3,
0326         RT5640_GP1_PF_MASK | RT5640_GP1_OUT_MASK, gpio_ctrl3_val);
0327 
0328     return 0;
0329 }
0330 
0331 static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
0332     SND_SOC_DAPM_HP("Headphone", NULL),
0333     SND_SOC_DAPM_MIC("Headset Mic", NULL),
0334     SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
0335     SND_SOC_DAPM_MIC("Internal Mic", NULL),
0336     SND_SOC_DAPM_SPK("Speaker", NULL),
0337     SND_SOC_DAPM_LINE("Line Out", byt_rt5640_event_lineout),
0338     SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
0339                 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
0340                 SND_SOC_DAPM_POST_PMD),
0341 };
0342 
0343 static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
0344     {"Headphone", NULL, "Platform Clock"},
0345     {"Headset Mic", NULL, "Platform Clock"},
0346     {"Headset Mic", NULL, "MICBIAS1"},
0347     {"IN2P", NULL, "Headset Mic"},
0348     {"Headphone", NULL, "HPOL"},
0349     {"Headphone", NULL, "HPOR"},
0350 };
0351 
0352 static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
0353     {"Internal Mic", NULL, "Platform Clock"},
0354     {"DMIC1", NULL, "Internal Mic"},
0355 };
0356 
0357 static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
0358     {"Internal Mic", NULL, "Platform Clock"},
0359     {"DMIC2", NULL, "Internal Mic"},
0360 };
0361 
0362 static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
0363     {"Internal Mic", NULL, "Platform Clock"},
0364     {"Internal Mic", NULL, "MICBIAS1"},
0365     {"IN1P", NULL, "Internal Mic"},
0366 };
0367 
0368 static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
0369     {"Internal Mic", NULL, "Platform Clock"},
0370     {"Internal Mic", NULL, "MICBIAS1"},
0371     {"IN3P", NULL, "Internal Mic"},
0372 };
0373 
0374 static const struct snd_soc_dapm_route byt_rt5640_hsmic2_in1_map[] = {
0375     {"Headset Mic 2", NULL, "Platform Clock"},
0376     {"Headset Mic 2", NULL, "MICBIAS1"},
0377     {"IN1P", NULL, "Headset Mic 2"},
0378 };
0379 
0380 static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
0381     {"ssp2 Tx", NULL, "codec_out0"},
0382     {"ssp2 Tx", NULL, "codec_out1"},
0383     {"codec_in0", NULL, "ssp2 Rx"},
0384     {"codec_in1", NULL, "ssp2 Rx"},
0385 
0386     {"AIF1 Playback", NULL, "ssp2 Tx"},
0387     {"ssp2 Rx", NULL, "AIF1 Capture"},
0388 };
0389 
0390 static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
0391     {"ssp2 Tx", NULL, "codec_out0"},
0392     {"ssp2 Tx", NULL, "codec_out1"},
0393     {"codec_in0", NULL, "ssp2 Rx"},
0394     {"codec_in1", NULL, "ssp2 Rx"},
0395 
0396     {"AIF2 Playback", NULL, "ssp2 Tx"},
0397     {"ssp2 Rx", NULL, "AIF2 Capture"},
0398 };
0399 
0400 static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
0401     {"ssp0 Tx", NULL, "modem_out"},
0402     {"modem_in", NULL, "ssp0 Rx"},
0403 
0404     {"AIF1 Playback", NULL, "ssp0 Tx"},
0405     {"ssp0 Rx", NULL, "AIF1 Capture"},
0406 };
0407 
0408 static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
0409     {"ssp0 Tx", NULL, "modem_out"},
0410     {"modem_in", NULL, "ssp0 Rx"},
0411 
0412     {"AIF2 Playback", NULL, "ssp0 Tx"},
0413     {"ssp0 Rx", NULL, "AIF2 Capture"},
0414 };
0415 
0416 static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
0417     {"Speaker", NULL, "Platform Clock"},
0418     {"Speaker", NULL, "SPOLP"},
0419     {"Speaker", NULL, "SPOLN"},
0420     {"Speaker", NULL, "SPORP"},
0421     {"Speaker", NULL, "SPORN"},
0422 };
0423 
0424 static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
0425     {"Speaker", NULL, "Platform Clock"},
0426     {"Speaker", NULL, "SPOLP"},
0427     {"Speaker", NULL, "SPOLN"},
0428 };
0429 
0430 static const struct snd_soc_dapm_route byt_rt5640_lineout_map[] = {
0431     {"Line Out", NULL, "Platform Clock"},
0432     {"Line Out", NULL, "LOUTR"},
0433     {"Line Out", NULL, "LOUTL"},
0434 };
0435 
0436 static const struct snd_kcontrol_new byt_rt5640_controls[] = {
0437     SOC_DAPM_PIN_SWITCH("Headphone"),
0438     SOC_DAPM_PIN_SWITCH("Headset Mic"),
0439     SOC_DAPM_PIN_SWITCH("Headset Mic 2"),
0440     SOC_DAPM_PIN_SWITCH("Internal Mic"),
0441     SOC_DAPM_PIN_SWITCH("Speaker"),
0442     SOC_DAPM_PIN_SWITCH("Line Out"),
0443 };
0444 
0445 static struct snd_soc_jack_pin rt5640_pins[] = {
0446     {
0447         .pin    = "Headphone",
0448         .mask   = SND_JACK_HEADPHONE,
0449     },
0450     {
0451         .pin    = "Headset Mic",
0452         .mask   = SND_JACK_MICROPHONE,
0453     },
0454 };
0455 
0456 static struct snd_soc_jack_pin rt5640_pins2[] = {
0457     {
0458         /* The 2nd headset jack uses lineout with an external HP-amp */
0459         .pin    = "Line Out",
0460         .mask   = SND_JACK_HEADPHONE,
0461     },
0462     {
0463         .pin    = "Headset Mic 2",
0464         .mask   = SND_JACK_MICROPHONE,
0465     },
0466 };
0467 
0468 static struct snd_soc_jack_gpio rt5640_jack_gpio = {
0469     .name = "hp-detect",
0470     .report = SND_JACK_HEADSET,
0471     .invert = true,
0472     .debounce_time = 200,
0473 };
0474 
0475 static struct snd_soc_jack_gpio rt5640_jack2_gpio = {
0476     .name = "hp2-detect",
0477     .report = SND_JACK_HEADSET,
0478     .invert = true,
0479     .debounce_time = 200,
0480 };
0481 
0482 static const struct acpi_gpio_params acpi_gpio0 = { 0, 0, false };
0483 static const struct acpi_gpio_params acpi_gpio1 = { 1, 0, false };
0484 static const struct acpi_gpio_params acpi_gpio2 = { 2, 0, false };
0485 
0486 static const struct acpi_gpio_mapping byt_rt5640_hp_elitepad_1000g2_gpios[] = {
0487     { "hp-detect-gpios", &acpi_gpio0, 1, },
0488     { "headset-mic-detect-gpios", &acpi_gpio1, 1, },
0489     { "hp2-detect-gpios", &acpi_gpio2, 1, },
0490     { },
0491 };
0492 
0493 static int byt_rt5640_hp_elitepad_1000g2_jack1_check(void *data)
0494 {
0495     struct byt_rt5640_private *priv = data;
0496     int jack_status, mic_status;
0497 
0498     jack_status = gpiod_get_value_cansleep(rt5640_jack_gpio.desc);
0499     if (jack_status)
0500         return 0;
0501 
0502     mic_status = gpiod_get_value_cansleep(priv->hsmic_detect);
0503     if (mic_status)
0504         return SND_JACK_HEADPHONE;
0505     else
0506         return SND_JACK_HEADSET;
0507 }
0508 
0509 static int byt_rt5640_hp_elitepad_1000g2_jack2_check(void *data)
0510 {
0511     struct snd_soc_component *component = data;
0512     int jack_status, report;
0513 
0514     jack_status = gpiod_get_value_cansleep(rt5640_jack2_gpio.desc);
0515     if (jack_status)
0516         return 0;
0517 
0518     rt5640_enable_micbias1_for_ovcd(component);
0519     report = rt5640_detect_headset(component, rt5640_jack2_gpio.desc);
0520     rt5640_disable_micbias1_for_ovcd(component);
0521 
0522     return report;
0523 }
0524 
0525 static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
0526                     struct snd_pcm_hw_params *params)
0527 {
0528     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0529     struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
0530 
0531     return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
0532 }
0533 
0534 /* Please keep this list alphabetically sorted */
0535 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
0536     {   /* Acer Iconia Tab 8 W1-810 */
0537         .matches = {
0538             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
0539             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Iconia W1-810"),
0540         },
0541         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
0542                     BYT_RT5640_JD_SRC_JD1_IN4P |
0543                     BYT_RT5640_OVCD_TH_1500UA |
0544                     BYT_RT5640_OVCD_SF_0P75 |
0545                     BYT_RT5640_SSP0_AIF1 |
0546                     BYT_RT5640_MCLK_EN),
0547     },
0548     {   /* Acer One 10 S1002 */
0549         .matches = {
0550             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0551             DMI_MATCH(DMI_PRODUCT_NAME, "One S1002"),
0552         },
0553         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0554                     BYT_RT5640_JD_SRC_JD2_IN4N |
0555                     BYT_RT5640_OVCD_TH_2000UA |
0556                     BYT_RT5640_OVCD_SF_0P75 |
0557                     BYT_RT5640_DIFF_MIC |
0558                     BYT_RT5640_SSP0_AIF2 |
0559                     BYT_RT5640_MCLK_EN),
0560     },
0561     {
0562         .matches = {
0563             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0564             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
0565         },
0566         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
0567                     BYT_RT5640_JD_SRC_JD2_IN4N |
0568                     BYT_RT5640_OVCD_TH_2000UA |
0569                     BYT_RT5640_OVCD_SF_0P75 |
0570                     BYT_RT5640_SSP0_AIF1 |
0571                     BYT_RT5640_MCLK_EN),
0572     },
0573     {
0574         .matches = {
0575             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
0576             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"),
0577         },
0578         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0579                     BYT_RT5640_MONO_SPEAKER |
0580                     BYT_RT5640_SSP0_AIF1 |
0581                     BYT_RT5640_MCLK_EN),
0582     },
0583     {
0584         .matches = {
0585             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
0586             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 140 CESIUM"),
0587         },
0588         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0589                     BYT_RT5640_JD_SRC_JD2_IN4N |
0590                     BYT_RT5640_OVCD_TH_2000UA |
0591                     BYT_RT5640_OVCD_SF_0P75 |
0592                     BYT_RT5640_SSP0_AIF1 |
0593                     BYT_RT5640_MCLK_EN),
0594     },
0595     {
0596         .matches = {
0597             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
0598             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
0599         },
0600         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0601                     BYT_RT5640_JD_SRC_JD2_IN4N |
0602                     BYT_RT5640_OVCD_TH_2000UA |
0603                     BYT_RT5640_OVCD_SF_0P75 |
0604                     BYT_RT5640_SSP0_AIF1 |
0605                     BYT_RT5640_MCLK_EN |
0606                     BYT_RT5640_USE_AMCR0F28),
0607     },
0608     {
0609         .matches = {
0610             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
0611             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
0612         },
0613         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0614                     BYT_RT5640_JD_SRC_JD2_IN4N |
0615                     BYT_RT5640_OVCD_TH_2000UA |
0616                     BYT_RT5640_OVCD_SF_0P75 |
0617                     BYT_RT5640_MCLK_EN),
0618     },
0619     {
0620         .matches = {
0621             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
0622             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
0623         },
0624         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0625                     BYT_RT5640_JD_SRC_JD2_IN4N |
0626                     BYT_RT5640_OVCD_TH_2000UA |
0627                     BYT_RT5640_OVCD_SF_0P75 |
0628                     BYT_RT5640_MONO_SPEAKER |
0629                     BYT_RT5640_DIFF_MIC |
0630                     BYT_RT5640_SSP0_AIF2 |
0631                     BYT_RT5640_MCLK_EN),
0632     },
0633     {
0634         .matches = {
0635             DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
0636             DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
0637         },
0638         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0639                     BYT_RT5640_JD_SRC_EXT_GPIO |
0640                     BYT_RT5640_OVCD_TH_2000UA |
0641                     BYT_RT5640_OVCD_SF_0P75 |
0642                     BYT_RT5640_SSP0_AIF1 |
0643                     BYT_RT5640_MCLK_EN |
0644                     BYT_RT5640_USE_AMCR0F28),
0645     },
0646     {   /* Chuwi Vi8 (CWI506) */
0647         .matches = {
0648             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
0649             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"),
0650             /* The above are too generic, also match BIOS info */
0651             DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
0652         },
0653         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0654                     BYT_RT5640_MONO_SPEAKER |
0655                     BYT_RT5640_SSP0_AIF1 |
0656                     BYT_RT5640_MCLK_EN),
0657     },
0658     {
0659         /* Chuwi Vi10 (CWI505) */
0660         .matches = {
0661             DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
0662             DMI_MATCH(DMI_BOARD_NAME, "BYT-PF02"),
0663             DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
0664             DMI_MATCH(DMI_PRODUCT_NAME, "S165"),
0665         },
0666         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0667                     BYT_RT5640_JD_SRC_JD2_IN4N |
0668                     BYT_RT5640_OVCD_TH_2000UA |
0669                     BYT_RT5640_OVCD_SF_0P75 |
0670                     BYT_RT5640_DIFF_MIC |
0671                     BYT_RT5640_SSP0_AIF1 |
0672                     BYT_RT5640_MCLK_EN),
0673     },
0674     {
0675         /* Chuwi Hi8 (CWI509) */
0676         .matches = {
0677             DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
0678             DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"),
0679             DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
0680             DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
0681         },
0682         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0683                     BYT_RT5640_JD_SRC_JD2_IN4N |
0684                     BYT_RT5640_OVCD_TH_2000UA |
0685                     BYT_RT5640_OVCD_SF_0P75 |
0686                     BYT_RT5640_MONO_SPEAKER |
0687                     BYT_RT5640_DIFF_MIC |
0688                     BYT_RT5640_SSP0_AIF1 |
0689                     BYT_RT5640_MCLK_EN),
0690     },
0691     {
0692         .matches = {
0693             DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
0694             DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
0695         },
0696         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
0697     },
0698     {   /* Connect Tablet 9 */
0699         .matches = {
0700             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Connect"),
0701             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Tablet 9"),
0702         },
0703         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0704                     BYT_RT5640_MONO_SPEAKER |
0705                     BYT_RT5640_SSP0_AIF1 |
0706                     BYT_RT5640_MCLK_EN),
0707     },
0708     {
0709         .matches = {
0710             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0711             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
0712         },
0713         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
0714                     BYT_RT5640_JD_SRC_JD2_IN4N |
0715                     BYT_RT5640_OVCD_TH_2000UA |
0716                     BYT_RT5640_OVCD_SF_0P75 |
0717                     BYT_RT5640_MONO_SPEAKER |
0718                     BYT_RT5640_MCLK_EN),
0719     },
0720     {   /* Estar Beauty HD MID 7316R */
0721         .matches = {
0722             DMI_MATCH(DMI_SYS_VENDOR, "Estar"),
0723             DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"),
0724         },
0725         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0726                     BYT_RT5640_MONO_SPEAKER |
0727                     BYT_RT5640_SSP0_AIF1 |
0728                     BYT_RT5640_MCLK_EN),
0729     },
0730     {   /* Glavey TM800A550L */
0731         .matches = {
0732             DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
0733             DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
0734             /* Above strings are too generic, also match on BIOS version */
0735             DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"),
0736         },
0737         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0738                     BYT_RT5640_SSP0_AIF1 |
0739                     BYT_RT5640_MCLK_EN),
0740     },
0741     {
0742         .matches = {
0743             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
0744             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
0745         },
0746         .driver_data = (void *)(BYT_RT5640_DMIC2_MAP |
0747                     BYT_RT5640_MCLK_EN |
0748                     BYT_RT5640_LINEOUT |
0749                     BYT_RT5640_LINEOUT_AS_HP2 |
0750                     BYT_RT5640_HSMIC2_ON_IN1 |
0751                     BYT_RT5640_JD_HP_ELITEP_1000G2),
0752     },
0753     {   /* HP Pavilion x2 10-k0XX, 10-n0XX */
0754         .matches = {
0755             DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
0756             DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
0757         },
0758         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
0759                     BYT_RT5640_JD_SRC_JD2_IN4N |
0760                     BYT_RT5640_OVCD_TH_1500UA |
0761                     BYT_RT5640_OVCD_SF_0P75 |
0762                     BYT_RT5640_SSP0_AIF1 |
0763                     BYT_RT5640_MCLK_EN),
0764     },
0765     {   /* HP Pavilion x2 10-p0XX */
0766         .matches = {
0767             DMI_MATCH(DMI_SYS_VENDOR, "HP"),
0768             DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
0769         },
0770         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
0771                     BYT_RT5640_JD_SRC_JD1_IN4P |
0772                     BYT_RT5640_OVCD_TH_2000UA |
0773                     BYT_RT5640_OVCD_SF_0P75 |
0774                     BYT_RT5640_MCLK_EN),
0775     },
0776     {   /* HP Pro Tablet 408 */
0777         .matches = {
0778             DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
0779             DMI_MATCH(DMI_PRODUCT_NAME, "HP Pro Tablet 408"),
0780         },
0781         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
0782                     BYT_RT5640_JD_SRC_JD2_IN4N |
0783                     BYT_RT5640_OVCD_TH_1500UA |
0784                     BYT_RT5640_OVCD_SF_0P75 |
0785                     BYT_RT5640_SSP0_AIF1 |
0786                     BYT_RT5640_MCLK_EN),
0787     },
0788     {   /* HP Stream 7 */
0789         .matches = {
0790             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
0791             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 7 Tablet"),
0792         },
0793         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0794                     BYT_RT5640_MONO_SPEAKER |
0795                     BYT_RT5640_JD_NOT_INV |
0796                     BYT_RT5640_SSP0_AIF1 |
0797                     BYT_RT5640_MCLK_EN),
0798     },
0799     {   /* I.T.Works TW891 */
0800         .matches = {
0801             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
0802             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
0803             DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
0804             DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
0805         },
0806         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0807                     BYT_RT5640_MONO_SPEAKER |
0808                     BYT_RT5640_SSP0_AIF1 |
0809                     BYT_RT5640_MCLK_EN),
0810     },
0811     {   /* Lamina I8270 / T701BR.SE */
0812         .matches = {
0813             DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Lamina"),
0814             DMI_EXACT_MATCH(DMI_BOARD_NAME, "T701BR.SE"),
0815         },
0816         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0817                     BYT_RT5640_MONO_SPEAKER |
0818                     BYT_RT5640_JD_NOT_INV |
0819                     BYT_RT5640_SSP0_AIF1 |
0820                     BYT_RT5640_MCLK_EN),
0821     },
0822     {   /* Lenovo Miix 2 8 */
0823         .matches = {
0824             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0825             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "20326"),
0826             DMI_EXACT_MATCH(DMI_BOARD_NAME, "Hiking"),
0827         },
0828         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
0829                     BYT_RT5640_JD_SRC_JD2_IN4N |
0830                     BYT_RT5640_OVCD_TH_2000UA |
0831                     BYT_RT5640_OVCD_SF_0P75 |
0832                     BYT_RT5640_MONO_SPEAKER |
0833                     BYT_RT5640_MCLK_EN),
0834     },
0835     {   /* Lenovo Miix 3-830 */
0836         .matches = {
0837             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0838             DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 3-830"),
0839         },
0840         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0841                     BYT_RT5640_JD_SRC_JD2_IN4N |
0842                     BYT_RT5640_OVCD_TH_2000UA |
0843                     BYT_RT5640_OVCD_SF_0P75 |
0844                     BYT_RT5640_MONO_SPEAKER |
0845                     BYT_RT5640_DIFF_MIC |
0846                     BYT_RT5640_SSP0_AIF1 |
0847                     BYT_RT5640_MCLK_EN),
0848     },
0849     {   /* Linx Linx7 tablet */
0850         .matches = {
0851             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LINX"),
0852             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LINX7"),
0853         },
0854         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0855                     BYT_RT5640_MONO_SPEAKER |
0856                     BYT_RT5640_JD_NOT_INV |
0857                     BYT_RT5640_SSP0_AIF1 |
0858                     BYT_RT5640_MCLK_EN),
0859     },
0860     {   /* Mele PCG03 Mini PC */
0861         .matches = {
0862             DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Mini PC"),
0863             DMI_EXACT_MATCH(DMI_BOARD_NAME, "Mini PC"),
0864         },
0865         .driver_data = (void *)(BYT_RT5640_NO_INTERNAL_MIC_MAP |
0866                     BYT_RT5640_NO_SPEAKERS |
0867                     BYT_RT5640_SSP0_AIF1),
0868     },
0869     {   /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */
0870         .matches = {
0871             DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"),
0872             DMI_MATCH(DMI_PRODUCT_NAME, "Converter9"),
0873         },
0874         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0875                     BYT_RT5640_MONO_SPEAKER |
0876                     BYT_RT5640_SSP0_AIF1 |
0877                     BYT_RT5640_MCLK_EN),
0878     },
0879     {
0880         /* MPMAN MPWIN895CL */
0881         .matches = {
0882             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MPMAN"),
0883             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MPWIN8900CL"),
0884         },
0885         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0886                     BYT_RT5640_MONO_SPEAKER |
0887                     BYT_RT5640_SSP0_AIF1 |
0888                     BYT_RT5640_MCLK_EN),
0889     },
0890     {   /* MSI S100 tablet */
0891         .matches = {
0892             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
0893             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "S100"),
0894         },
0895         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0896                     BYT_RT5640_JD_SRC_JD2_IN4N |
0897                     BYT_RT5640_OVCD_TH_2000UA |
0898                     BYT_RT5640_OVCD_SF_0P75 |
0899                     BYT_RT5640_MONO_SPEAKER |
0900                     BYT_RT5640_DIFF_MIC |
0901                     BYT_RT5640_MCLK_EN),
0902     },
0903     {   /* Nuvison/TMax TM800W560 */
0904         .matches = {
0905             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TMAX"),
0906             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TM800W560L"),
0907         },
0908         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0909                     BYT_RT5640_JD_SRC_JD2_IN4N |
0910                     BYT_RT5640_OVCD_TH_2000UA |
0911                     BYT_RT5640_OVCD_SF_0P75 |
0912                     BYT_RT5640_JD_NOT_INV |
0913                     BYT_RT5640_DIFF_MIC |
0914                     BYT_RT5640_SSP0_AIF1 |
0915                     BYT_RT5640_MCLK_EN),
0916     },
0917     {   /* Onda v975w */
0918         .matches = {
0919             DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
0920             DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
0921             /* The above are too generic, also match BIOS info */
0922             DMI_EXACT_MATCH(DMI_BIOS_VERSION, "5.6.5"),
0923             DMI_EXACT_MATCH(DMI_BIOS_DATE, "07/25/2014"),
0924         },
0925         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0926                     BYT_RT5640_JD_SRC_JD2_IN4N |
0927                     BYT_RT5640_OVCD_TH_2000UA |
0928                     BYT_RT5640_OVCD_SF_0P75 |
0929                     BYT_RT5640_DIFF_MIC |
0930                     BYT_RT5640_MCLK_EN),
0931     },
0932     {   /* Pipo W4 */
0933         .matches = {
0934             DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
0935             DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
0936             /* The above are too generic, also match BIOS info */
0937             DMI_MATCH(DMI_BIOS_VERSION, "V8L_WIN32_CHIPHD"),
0938         },
0939         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
0940                     BYT_RT5640_MONO_SPEAKER |
0941                     BYT_RT5640_SSP0_AIF1 |
0942                     BYT_RT5640_MCLK_EN),
0943     },
0944     {   /* Point of View Mobii TAB-P800W (V2.0) */
0945         .matches = {
0946             DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
0947             DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
0948             /* The above are too generic, also match BIOS info */
0949             DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
0950             DMI_EXACT_MATCH(DMI_BIOS_DATE, "10/24/2014"),
0951         },
0952         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0953                     BYT_RT5640_JD_SRC_JD2_IN4N |
0954                     BYT_RT5640_OVCD_TH_2000UA |
0955                     BYT_RT5640_OVCD_SF_0P75 |
0956                     BYT_RT5640_MONO_SPEAKER |
0957                     BYT_RT5640_DIFF_MIC |
0958                     BYT_RT5640_SSP0_AIF2 |
0959                     BYT_RT5640_MCLK_EN),
0960     },
0961     {   /* Point of View Mobii TAB-P800W (V2.1) */
0962         .matches = {
0963             DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
0964             DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
0965             /* The above are too generic, also match BIOS info */
0966             DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
0967             DMI_EXACT_MATCH(DMI_BIOS_DATE, "08/22/2014"),
0968         },
0969         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0970                     BYT_RT5640_JD_SRC_JD2_IN4N |
0971                     BYT_RT5640_OVCD_TH_2000UA |
0972                     BYT_RT5640_OVCD_SF_0P75 |
0973                     BYT_RT5640_MONO_SPEAKER |
0974                     BYT_RT5640_DIFF_MIC |
0975                     BYT_RT5640_SSP0_AIF2 |
0976                     BYT_RT5640_MCLK_EN),
0977     },
0978     {   /* Point of View Mobii TAB-P1005W-232 (V2.0) */
0979         .matches = {
0980             DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "POV"),
0981             DMI_EXACT_MATCH(DMI_BOARD_NAME, "I102A"),
0982         },
0983         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0984                     BYT_RT5640_JD_SRC_JD2_IN4N |
0985                     BYT_RT5640_OVCD_TH_2000UA |
0986                     BYT_RT5640_OVCD_SF_0P75 |
0987                     BYT_RT5640_DIFF_MIC |
0988                     BYT_RT5640_SSP0_AIF1 |
0989                     BYT_RT5640_MCLK_EN),
0990     },
0991     {
0992         /* Prowise PT301 */
0993         .matches = {
0994             DMI_MATCH(DMI_SYS_VENDOR, "Prowise"),
0995             DMI_MATCH(DMI_PRODUCT_NAME, "PT301"),
0996         },
0997         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
0998                     BYT_RT5640_JD_SRC_JD2_IN4N |
0999                     BYT_RT5640_OVCD_TH_2000UA |
1000                     BYT_RT5640_OVCD_SF_0P75 |
1001                     BYT_RT5640_DIFF_MIC |
1002                     BYT_RT5640_SSP0_AIF1 |
1003                     BYT_RT5640_MCLK_EN),
1004     },
1005     {
1006         /* Teclast X89 */
1007         .matches = {
1008             DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
1009             DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
1010         },
1011         .driver_data = (void *)(BYT_RT5640_IN3_MAP |
1012                     BYT_RT5640_JD_SRC_JD1_IN4P |
1013                     BYT_RT5640_OVCD_TH_2000UA |
1014                     BYT_RT5640_OVCD_SF_1P0 |
1015                     BYT_RT5640_SSP0_AIF1 |
1016                     BYT_RT5640_MCLK_EN),
1017     },
1018     {   /* Toshiba Satellite Click Mini L9W-B */
1019         .matches = {
1020             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1021             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
1022         },
1023         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
1024                     BYT_RT5640_JD_SRC_JD2_IN4N |
1025                     BYT_RT5640_OVCD_TH_1500UA |
1026                     BYT_RT5640_OVCD_SF_0P75 |
1027                     BYT_RT5640_SSP0_AIF1 |
1028                     BYT_RT5640_MCLK_EN),
1029     },
1030     {   /* Toshiba Encore WT8-A */
1031         .matches = {
1032             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1033             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT8-A"),
1034         },
1035         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
1036                     BYT_RT5640_JD_SRC_JD2_IN4N |
1037                     BYT_RT5640_OVCD_TH_2000UA |
1038                     BYT_RT5640_OVCD_SF_0P75 |
1039                     BYT_RT5640_JD_NOT_INV |
1040                     BYT_RT5640_MCLK_EN),
1041     },
1042     {   /* Toshiba Encore WT10-A */
1043         .matches = {
1044             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1045             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT10-A-103"),
1046         },
1047         .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
1048                     BYT_RT5640_JD_SRC_JD1_IN4P |
1049                     BYT_RT5640_OVCD_TH_2000UA |
1050                     BYT_RT5640_OVCD_SF_0P75 |
1051                     BYT_RT5640_SSP0_AIF2 |
1052                     BYT_RT5640_MCLK_EN),
1053     },
1054     {   /* Voyo Winpad A15 */
1055         .matches = {
1056             DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1057             DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1058             /* Above strings are too generic, also match on BIOS date */
1059             DMI_MATCH(DMI_BIOS_DATE, "11/20/2014"),
1060         },
1061         .driver_data = (void *)(BYT_RT5640_IN1_MAP |
1062                     BYT_RT5640_JD_SRC_JD2_IN4N |
1063                     BYT_RT5640_OVCD_TH_2000UA |
1064                     BYT_RT5640_OVCD_SF_0P75 |
1065                     BYT_RT5640_DIFF_MIC |
1066                     BYT_RT5640_MCLK_EN),
1067     },
1068     {   /* Catch-all for generic Insyde tablets, must be last */
1069         .matches = {
1070             DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
1071         },
1072         .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
1073                     BYT_RT5640_MCLK_EN |
1074                     BYT_RT5640_SSP0_AIF1),
1075 
1076     },
1077     {}
1078 };
1079 
1080 /*
1081  * Note this MUST be called before snd_soc_register_card(), so that the props
1082  * are in place before the codec component driver's probe function parses them.
1083  */
1084 static int byt_rt5640_add_codec_device_props(struct device *i2c_dev,
1085                          struct byt_rt5640_private *priv)
1086 {
1087     struct property_entry props[MAX_NO_PROPS] = {};
1088     struct fwnode_handle *fwnode;
1089     int cnt = 0;
1090     int ret;
1091 
1092     switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
1093     case BYT_RT5640_DMIC1_MAP:
1094         props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic1-data-pin",
1095                           RT5640_DMIC1_DATA_PIN_IN1P);
1096         break;
1097     case BYT_RT5640_DMIC2_MAP:
1098         props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic2-data-pin",
1099                           RT5640_DMIC2_DATA_PIN_IN1N);
1100         break;
1101     case BYT_RT5640_IN1_MAP:
1102         if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
1103             props[cnt++] =
1104                 PROPERTY_ENTRY_BOOL("realtek,in1-differential");
1105         break;
1106     case BYT_RT5640_IN3_MAP:
1107         if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
1108             props[cnt++] =
1109                 PROPERTY_ENTRY_BOOL("realtek,in3-differential");
1110         break;
1111     }
1112 
1113     if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
1114         if (BYT_RT5640_JDSRC(byt_rt5640_quirk) != RT5640_JD_SRC_EXT_GPIO) {
1115             props[cnt++] = PROPERTY_ENTRY_U32(
1116                         "realtek,jack-detect-source",
1117                         BYT_RT5640_JDSRC(byt_rt5640_quirk));
1118         }
1119 
1120         props[cnt++] = PROPERTY_ENTRY_U32(
1121                     "realtek,over-current-threshold-microamp",
1122                     BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
1123 
1124         props[cnt++] = PROPERTY_ENTRY_U32(
1125                     "realtek,over-current-scale-factor",
1126                     BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
1127     }
1128 
1129     if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
1130         props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
1131 
1132     fwnode = fwnode_create_software_node(props, NULL);
1133     if (IS_ERR(fwnode)) {
1134         /* put_device() is handled in caller */
1135         return PTR_ERR(fwnode);
1136     }
1137 
1138     ret = device_add_software_node(i2c_dev, to_software_node(fwnode));
1139 
1140     fwnode_handle_put(fwnode);
1141 
1142     return ret;
1143 }
1144 
1145 /* Some Android devs specify IRQs/GPIOS in a special AMCR0F28 ACPI device */
1146 static const struct acpi_gpio_params amcr0f28_jd_gpio = { 1, 0, false };
1147 
1148 static const struct acpi_gpio_mapping amcr0f28_gpios[] = {
1149     { "rt5640-jd-gpios", &amcr0f28_jd_gpio, 1 },
1150     { }
1151 };
1152 
1153 static int byt_rt5640_get_amcr0f28_settings(struct snd_soc_card *card)
1154 {
1155     struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1156     struct rt5640_set_jack_data *data = &priv->jack_data;
1157     struct acpi_device *adev;
1158     int ret = 0;
1159 
1160     adev = acpi_dev_get_first_match_dev("AMCR0F28", "1", -1);
1161     if (!adev) {
1162         dev_err(card->dev, "error cannot find AMCR0F28 adev\n");
1163         return -ENOENT;
1164     }
1165 
1166     data->codec_irq_override = acpi_dev_gpio_irq_get(adev, 0);
1167     if (data->codec_irq_override < 0) {
1168         ret = data->codec_irq_override;
1169         dev_err(card->dev, "error %d getting codec IRQ\n", ret);
1170         goto put_adev;
1171     }
1172 
1173     if (BYT_RT5640_JDSRC(byt_rt5640_quirk) == RT5640_JD_SRC_EXT_GPIO) {
1174         acpi_dev_add_driver_gpios(adev, amcr0f28_gpios);
1175         data->jd_gpio = devm_fwnode_gpiod_get(card->dev, acpi_fwnode_handle(adev),
1176                               "rt5640-jd", GPIOD_IN, "rt5640-jd");
1177         acpi_dev_remove_driver_gpios(adev);
1178 
1179         if (IS_ERR(data->jd_gpio)) {
1180             ret = PTR_ERR(data->jd_gpio);
1181             dev_err(card->dev, "error %d getting jd GPIO\n", ret);
1182         }
1183     }
1184 
1185 put_adev:
1186     acpi_dev_put(adev);
1187     return ret;
1188 }
1189 
1190 static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
1191 {
1192     struct snd_soc_card *card = runtime->card;
1193     struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1194     struct rt5640_set_jack_data *jack_data = &priv->jack_data;
1195     struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component;
1196     const struct snd_soc_dapm_route *custom_map = NULL;
1197     int num_routes = 0;
1198     int ret;
1199 
1200     card->dapm.idle_bias_off = true;
1201     jack_data->use_platform_clock = true;
1202 
1203     /* Start with RC clk for jack-detect (we disable MCLK below) */
1204     if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
1205         snd_soc_component_update_bits(component, RT5640_GLB_CLK,
1206             RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_RCCLK);
1207 
1208     rt5640_sel_asrc_clk_src(component,
1209                 RT5640_DA_STEREO_FILTER |
1210                 RT5640_DA_MONO_L_FILTER |
1211                 RT5640_DA_MONO_R_FILTER |
1212                 RT5640_AD_STEREO_FILTER |
1213                 RT5640_AD_MONO_L_FILTER |
1214                 RT5640_AD_MONO_R_FILTER,
1215                 RT5640_CLK_SEL_ASRC);
1216 
1217     ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
1218                     ARRAY_SIZE(byt_rt5640_controls));
1219     if (ret) {
1220         dev_err(card->dev, "unable to add card controls\n");
1221         return ret;
1222     }
1223 
1224     switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
1225     case BYT_RT5640_IN1_MAP:
1226         custom_map = byt_rt5640_intmic_in1_map;
1227         num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
1228         break;
1229     case BYT_RT5640_IN3_MAP:
1230         custom_map = byt_rt5640_intmic_in3_map;
1231         num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
1232         break;
1233     case BYT_RT5640_DMIC1_MAP:
1234         custom_map = byt_rt5640_intmic_dmic1_map;
1235         num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
1236         break;
1237     case BYT_RT5640_DMIC2_MAP:
1238         custom_map = byt_rt5640_intmic_dmic2_map;
1239         num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
1240         break;
1241     }
1242 
1243     ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
1244     if (ret)
1245         return ret;
1246 
1247     if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1) {
1248         ret = snd_soc_dapm_add_routes(&card->dapm,
1249                     byt_rt5640_hsmic2_in1_map,
1250                     ARRAY_SIZE(byt_rt5640_hsmic2_in1_map));
1251         if (ret)
1252             return ret;
1253     }
1254 
1255     if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
1256         ret = snd_soc_dapm_add_routes(&card->dapm,
1257                     byt_rt5640_ssp2_aif2_map,
1258                     ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
1259     } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
1260         ret = snd_soc_dapm_add_routes(&card->dapm,
1261                     byt_rt5640_ssp0_aif1_map,
1262                     ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
1263     } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
1264         ret = snd_soc_dapm_add_routes(&card->dapm,
1265                     byt_rt5640_ssp0_aif2_map,
1266                     ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
1267     } else {
1268         ret = snd_soc_dapm_add_routes(&card->dapm,
1269                     byt_rt5640_ssp2_aif1_map,
1270                     ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
1271     }
1272     if (ret)
1273         return ret;
1274 
1275     if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
1276         ret = snd_soc_dapm_add_routes(&card->dapm,
1277                     byt_rt5640_mono_spk_map,
1278                     ARRAY_SIZE(byt_rt5640_mono_spk_map));
1279     } else if (!(byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)) {
1280         ret = snd_soc_dapm_add_routes(&card->dapm,
1281                     byt_rt5640_stereo_spk_map,
1282                     ARRAY_SIZE(byt_rt5640_stereo_spk_map));
1283     }
1284     if (ret)
1285         return ret;
1286 
1287     if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) {
1288         ret = snd_soc_dapm_add_routes(&card->dapm,
1289                     byt_rt5640_lineout_map,
1290                     ARRAY_SIZE(byt_rt5640_lineout_map));
1291         if (ret)
1292             return ret;
1293     }
1294 
1295     /*
1296      * The firmware might enable the clock at boot (this information
1297      * may or may not be reflected in the enable clock register).
1298      * To change the rate we must disable the clock first to cover
1299      * these cases. Due to common clock framework restrictions that
1300      * do not allow to disable a clock that has not been enabled,
1301      * we need to enable the clock first.
1302      */
1303     ret = clk_prepare_enable(priv->mclk);
1304     if (!ret)
1305         clk_disable_unprepare(priv->mclk);
1306 
1307     if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
1308         ret = clk_set_rate(priv->mclk, 25000000);
1309     else
1310         ret = clk_set_rate(priv->mclk, 19200000);
1311     if (ret) {
1312         dev_err(card->dev, "unable to set MCLK rate\n");
1313         return ret;
1314     }
1315 
1316     if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
1317         ret = snd_soc_card_jack_new_pins(card, "Headset",
1318                          SND_JACK_HEADSET | SND_JACK_BTN_0,
1319                          &priv->jack, rt5640_pins,
1320                          ARRAY_SIZE(rt5640_pins));
1321         if (ret) {
1322             dev_err(card->dev, "Jack creation failed %d\n", ret);
1323             return ret;
1324         }
1325         snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
1326                  KEY_PLAYPAUSE);
1327 
1328         if (byt_rt5640_quirk & BYT_RT5640_USE_AMCR0F28) {
1329             ret = byt_rt5640_get_amcr0f28_settings(card);
1330             if (ret)
1331                 return ret;
1332         }
1333 
1334         snd_soc_component_set_jack(component, &priv->jack, &priv->jack_data);
1335     }
1336 
1337     if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
1338         ret = snd_soc_card_jack_new_pins(card, "Headset",
1339                          SND_JACK_HEADSET,
1340                          &priv->jack, rt5640_pins,
1341                          ARRAY_SIZE(rt5640_pins));
1342         if (ret)
1343             return ret;
1344 
1345         ret = snd_soc_card_jack_new_pins(card, "Headset 2",
1346                          SND_JACK_HEADSET,
1347                          &priv->jack2, rt5640_pins2,
1348                          ARRAY_SIZE(rt5640_pins2));
1349         if (ret)
1350             return ret;
1351 
1352         rt5640_jack_gpio.data = priv;
1353         rt5640_jack_gpio.gpiod_dev = priv->codec_dev;
1354         rt5640_jack_gpio.jack_status_check = byt_rt5640_hp_elitepad_1000g2_jack1_check;
1355         ret = snd_soc_jack_add_gpios(&priv->jack, 1, &rt5640_jack_gpio);
1356         if (ret)
1357             return ret;
1358 
1359         rt5640_set_ovcd_params(component);
1360         rt5640_jack2_gpio.data = component;
1361         rt5640_jack2_gpio.gpiod_dev = priv->codec_dev;
1362         rt5640_jack2_gpio.jack_status_check = byt_rt5640_hp_elitepad_1000g2_jack2_check;
1363         ret = snd_soc_jack_add_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
1364         if (ret) {
1365             snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
1366             return ret;
1367         }
1368     }
1369 
1370     return 0;
1371 }
1372 
1373 static void byt_rt5640_exit(struct snd_soc_pcm_runtime *runtime)
1374 {
1375     struct snd_soc_card *card = runtime->card;
1376     struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1377 
1378     if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
1379         snd_soc_jack_free_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
1380         snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
1381     }
1382 }
1383 
1384 static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
1385                 struct snd_pcm_hw_params *params)
1386 {
1387     struct snd_interval *rate = hw_param_interval(params,
1388             SNDRV_PCM_HW_PARAM_RATE);
1389     struct snd_interval *channels = hw_param_interval(params,
1390                         SNDRV_PCM_HW_PARAM_CHANNELS);
1391     int ret, bits;
1392 
1393     /* The DSP will covert the FE rate to 48k, stereo */
1394     rate->min = rate->max = 48000;
1395     channels->min = channels->max = 2;
1396 
1397     if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
1398         (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1399         /* set SSP0 to 16-bit */
1400         params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
1401         bits = 16;
1402     } else {
1403         /* set SSP2 to 24-bit */
1404         params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
1405         bits = 24;
1406     }
1407 
1408     /*
1409      * Default mode for SSP configuration is TDM 4 slot, override config
1410      * with explicit setting to I2S 2ch. The word length is set with
1411      * dai_set_tdm_slot() since there is no other API exposed
1412      */
1413     ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0),
1414                   SND_SOC_DAIFMT_I2S     |
1415                   SND_SOC_DAIFMT_NB_NF   |
1416                   SND_SOC_DAIFMT_BP_FP);
1417     if (ret < 0) {
1418         dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
1419         return ret;
1420     }
1421 
1422     ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits);
1423     if (ret < 0) {
1424         dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
1425         return ret;
1426     }
1427 
1428     return 0;
1429 }
1430 
1431 static int byt_rt5640_aif1_startup(struct snd_pcm_substream *substream)
1432 {
1433     return snd_pcm_hw_constraint_single(substream->runtime,
1434             SNDRV_PCM_HW_PARAM_RATE, 48000);
1435 }
1436 
1437 static const struct snd_soc_ops byt_rt5640_aif1_ops = {
1438     .startup = byt_rt5640_aif1_startup,
1439 };
1440 
1441 static const struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
1442     .hw_params = byt_rt5640_aif1_hw_params,
1443 };
1444 
1445 SND_SOC_DAILINK_DEF(dummy,
1446     DAILINK_COMP_ARRAY(COMP_DUMMY()));
1447 
1448 SND_SOC_DAILINK_DEF(media,
1449     DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
1450 
1451 SND_SOC_DAILINK_DEF(deepbuffer,
1452     DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
1453 
1454 SND_SOC_DAILINK_DEF(ssp2_port,
1455     /* overwritten for ssp0 routing */
1456     DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
1457 SND_SOC_DAILINK_DEF(ssp2_codec,
1458     DAILINK_COMP_ARRAY(COMP_CODEC(
1459     /* overwritten with HID */ "i2c-10EC5640:00",
1460     /* changed w/ quirk */  "rt5640-aif1")));
1461 
1462 SND_SOC_DAILINK_DEF(platform,
1463     DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
1464 
1465 static struct snd_soc_dai_link byt_rt5640_dais[] = {
1466     [MERR_DPCM_AUDIO] = {
1467         .name = "Baytrail Audio Port",
1468         .stream_name = "Baytrail Audio",
1469         .nonatomic = true,
1470         .dynamic = 1,
1471         .dpcm_playback = 1,
1472         .dpcm_capture = 1,
1473         .ops = &byt_rt5640_aif1_ops,
1474         SND_SOC_DAILINK_REG(media, dummy, platform),
1475     },
1476     [MERR_DPCM_DEEP_BUFFER] = {
1477         .name = "Deep-Buffer Audio Port",
1478         .stream_name = "Deep-Buffer Audio",
1479         .nonatomic = true,
1480         .dynamic = 1,
1481         .dpcm_playback = 1,
1482         .ops = &byt_rt5640_aif1_ops,
1483         SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
1484     },
1485         /* back ends */
1486     {
1487         .name = "SSP2-Codec",
1488         .id = 0,
1489         .no_pcm = 1,
1490         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
1491                         | SND_SOC_DAIFMT_CBC_CFC,
1492         .be_hw_params_fixup = byt_rt5640_codec_fixup,
1493         .dpcm_playback = 1,
1494         .dpcm_capture = 1,
1495         .init = byt_rt5640_init,
1496         .exit = byt_rt5640_exit,
1497         .ops = &byt_rt5640_be_ssp2_ops,
1498         SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
1499     },
1500 };
1501 
1502 /* SoC card */
1503 static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
1504 #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
1505 static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
1506 #endif
1507 static char byt_rt5640_components[64]; /* = "cfg-spk:* cfg-mic:* ..." */
1508 
1509 static int byt_rt5640_suspend(struct snd_soc_card *card)
1510 {
1511     struct snd_soc_component *component;
1512 
1513     if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
1514         return 0;
1515 
1516     for_each_card_components(card, component) {
1517         if (!strcmp(component->name, byt_rt5640_codec_name)) {
1518             dev_dbg(component->dev, "disabling jack detect before suspend\n");
1519             snd_soc_component_set_jack(component, NULL, NULL);
1520             break;
1521         }
1522     }
1523 
1524     return 0;
1525 }
1526 
1527 static int byt_rt5640_resume(struct snd_soc_card *card)
1528 {
1529     struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1530     struct snd_soc_component *component;
1531 
1532     if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
1533         return 0;
1534 
1535     for_each_card_components(card, component) {
1536         if (!strcmp(component->name, byt_rt5640_codec_name)) {
1537             dev_dbg(component->dev, "re-enabling jack detect after resume\n");
1538             snd_soc_component_set_jack(component, &priv->jack,
1539                            &priv->jack_data);
1540             break;
1541         }
1542     }
1543 
1544     return 0;
1545 }
1546 
1547 /* use space before codec name to simplify card ID, and simplify driver name */
1548 #define SOF_CARD_NAME "bytcht rt5640" /* card name will be 'sof-bytcht rt5640' */
1549 #define SOF_DRIVER_NAME "SOF"
1550 
1551 #define CARD_NAME "bytcr-rt5640"
1552 #define DRIVER_NAME NULL /* card name will be used for driver name */
1553 
1554 static struct snd_soc_card byt_rt5640_card = {
1555     .owner = THIS_MODULE,
1556     .dai_link = byt_rt5640_dais,
1557     .num_links = ARRAY_SIZE(byt_rt5640_dais),
1558     .dapm_widgets = byt_rt5640_widgets,
1559     .num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
1560     .dapm_routes = byt_rt5640_audio_map,
1561     .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
1562     .fully_routed = true,
1563     .suspend_pre = byt_rt5640_suspend,
1564     .resume_post = byt_rt5640_resume,
1565 };
1566 
1567 struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
1568     u64 aif_value;       /* 1: AIF1, 2: AIF2 */
1569     u64 mclock_value;    /* usually 25MHz (0x17d7940), ignored */
1570 };
1571 
1572 static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
1573 {
1574     struct device *dev = &pdev->dev;
1575     static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3", "none" };
1576     struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
1577     __maybe_unused const char *spk_type;
1578     const struct dmi_system_id *dmi_id;
1579     const char *headset2_string = "";
1580     const char *lineout_string = "";
1581     struct byt_rt5640_private *priv;
1582     const char *platform_name;
1583     struct acpi_device *adev;
1584     struct device *codec_dev;
1585     bool sof_parent;
1586     int ret_val = 0;
1587     int dai_index = 0;
1588     int i, cfg_spk;
1589     int aif;
1590 
1591     is_bytcr = false;
1592     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1593     if (!priv)
1594         return -ENOMEM;
1595 
1596     /* register the soc card */
1597     byt_rt5640_card.dev = dev;
1598     snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
1599 
1600     /* fix index of codec dai */
1601     for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
1602         if (!strcmp(byt_rt5640_dais[i].codecs->name,
1603                 "i2c-10EC5640:00")) {
1604             dai_index = i;
1605             break;
1606         }
1607     }
1608 
1609     /* fixup codec name based on HID */
1610     adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
1611     if (adev) {
1612         snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
1613              "i2c-%s", acpi_dev_name(adev));
1614         put_device(&adev->dev);
1615         byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name;
1616     } else {
1617         dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
1618         return -ENXIO;
1619     }
1620 
1621     /*
1622      * swap SSP0 if bytcr is detected
1623      * (will be overridden if DMI quirk is detected)
1624      */
1625     if (soc_intel_is_byt()) {
1626         if (mach->mach_params.acpi_ipc_irq_index == 0)
1627             is_bytcr = true;
1628     }
1629 
1630     if (is_bytcr) {
1631         /*
1632          * Baytrail CR platforms may have CHAN package in BIOS, try
1633          * to find relevant routing quirk based as done on Windows
1634          * platforms. We have to read the information directly from the
1635          * BIOS, at this stage the card is not created and the links
1636          * with the codec driver/pdata are non-existent
1637          */
1638 
1639         struct acpi_chan_package chan_package = { 0 };
1640 
1641         /* format specified: 2 64-bit integers */
1642         struct acpi_buffer format = {sizeof("NN"), "NN"};
1643         struct acpi_buffer state = {0, NULL};
1644         struct snd_soc_acpi_package_context pkg_ctx;
1645         bool pkg_found = false;
1646 
1647         state.length = sizeof(chan_package);
1648         state.pointer = &chan_package;
1649 
1650         pkg_ctx.name = "CHAN";
1651         pkg_ctx.length = 2;
1652         pkg_ctx.format = &format;
1653         pkg_ctx.state = &state;
1654         pkg_ctx.data_valid = false;
1655 
1656         pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
1657                                    &pkg_ctx);
1658         if (pkg_found) {
1659             if (chan_package.aif_value == 1) {
1660                 dev_info(dev, "BIOS Routing: AIF1 connected\n");
1661                 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF1;
1662             } else  if (chan_package.aif_value == 2) {
1663                 dev_info(dev, "BIOS Routing: AIF2 connected\n");
1664                 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1665             } else {
1666                 dev_info(dev, "BIOS Routing isn't valid, ignored\n");
1667                 pkg_found = false;
1668             }
1669         }
1670 
1671         if (!pkg_found) {
1672             /* no BIOS indications, assume SSP0-AIF2 connection */
1673             byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1674         }
1675 
1676         /* change defaults for Baytrail-CR capture */
1677         byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
1678     } else {
1679         byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP |
1680                     BYT_RT5640_JD_SRC_JD2_IN4N |
1681                     BYT_RT5640_OVCD_TH_2000UA |
1682                     BYT_RT5640_OVCD_SF_0P75;
1683     }
1684 
1685     /* check quirks before creating card */
1686     dmi_id = dmi_first_match(byt_rt5640_quirk_table);
1687     if (dmi_id)
1688         byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
1689     if (quirk_override != -1) {
1690         dev_info(dev, "Overriding quirk 0x%lx => 0x%x\n",
1691              byt_rt5640_quirk, quirk_override);
1692         byt_rt5640_quirk = quirk_override;
1693     }
1694 
1695     codec_dev = acpi_get_first_physical_node(adev);
1696     if (!codec_dev)
1697         return -EPROBE_DEFER;
1698     priv->codec_dev = get_device(codec_dev);
1699 
1700     if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
1701         acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev),
1702                       byt_rt5640_hp_elitepad_1000g2_gpios);
1703 
1704         priv->hsmic_detect = devm_fwnode_gpiod_get(dev, codec_dev->fwnode,
1705                                "headset-mic-detect", GPIOD_IN,
1706                                "headset-mic-detect");
1707         if (IS_ERR(priv->hsmic_detect)) {
1708             ret_val = dev_err_probe(dev, PTR_ERR(priv->hsmic_detect),
1709                         "getting hsmic-detect GPIO\n");
1710             goto err_device;
1711         }
1712     }
1713 
1714     /* Must be called before register_card, also see declaration comment. */
1715     ret_val = byt_rt5640_add_codec_device_props(codec_dev, priv);
1716     if (ret_val)
1717         goto err_remove_gpios;
1718 
1719     log_quirks(dev);
1720 
1721     if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
1722         (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1723         byt_rt5640_dais[dai_index].codecs->dai_name = "rt5640-aif2";
1724         aif = 2;
1725     } else {
1726         aif = 1;
1727     }
1728 
1729     if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
1730         (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2))
1731         byt_rt5640_dais[dai_index].cpus->dai_name = "ssp0-port";
1732 
1733     if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
1734         priv->mclk = devm_clk_get_optional(dev, "pmc_plt_clk_3");
1735         if (IS_ERR(priv->mclk)) {
1736             ret_val = dev_err_probe(dev, PTR_ERR(priv->mclk),
1737                         "Failed to get MCLK from pmc_plt_clk_3\n");
1738             goto err;
1739         }
1740         /*
1741          * Fall back to bit clock usage when clock is not
1742          * available likely due to missing dependencies.
1743          */
1744         if (!priv->mclk)
1745             byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
1746     }
1747 
1748     if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) {
1749         cfg_spk = 0;
1750         spk_type = "none";
1751     } else if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
1752         cfg_spk = 1;
1753         spk_type = "mono";
1754     } else {
1755         cfg_spk = 2;
1756         spk_type = "stereo";
1757     }
1758 
1759     if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) {
1760         if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2)
1761             lineout_string = " cfg-hp2:lineout";
1762         else
1763             lineout_string = " cfg-lineout:2";
1764     }
1765 
1766     if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1)
1767         headset2_string = " cfg-hs2:in1";
1768 
1769     snprintf(byt_rt5640_components, sizeof(byt_rt5640_components),
1770          "cfg-spk:%d cfg-mic:%s aif:%d%s%s", cfg_spk,
1771          map_name[BYT_RT5640_MAP(byt_rt5640_quirk)], aif,
1772          lineout_string, headset2_string);
1773     byt_rt5640_card.components = byt_rt5640_components;
1774 #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
1775     snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
1776          "bytcr-rt5640-%s-spk-%s-mic", spk_type,
1777          map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
1778     byt_rt5640_card.long_name = byt_rt5640_long_name;
1779 #endif
1780 
1781     /* override platform name, if required */
1782     platform_name = mach->mach_params.platform;
1783 
1784     ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5640_card,
1785                             platform_name);
1786     if (ret_val)
1787         goto err;
1788 
1789     sof_parent = snd_soc_acpi_sof_parent(dev);
1790 
1791     /* set card and driver name */
1792     if (sof_parent) {
1793         byt_rt5640_card.name = SOF_CARD_NAME;
1794         byt_rt5640_card.driver_name = SOF_DRIVER_NAME;
1795     } else {
1796         byt_rt5640_card.name = CARD_NAME;
1797         byt_rt5640_card.driver_name = DRIVER_NAME;
1798     }
1799 
1800     /* set pm ops */
1801     if (sof_parent)
1802         dev->driver->pm = &snd_soc_pm_ops;
1803 
1804     ret_val = devm_snd_soc_register_card(dev, &byt_rt5640_card);
1805     if (ret_val) {
1806         dev_err(dev, "devm_snd_soc_register_card failed %d\n", ret_val);
1807         goto err;
1808     }
1809     platform_set_drvdata(pdev, &byt_rt5640_card);
1810     return ret_val;
1811 
1812 err:
1813     device_remove_software_node(priv->codec_dev);
1814 err_remove_gpios:
1815     if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2)
1816         acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
1817 err_device:
1818     put_device(priv->codec_dev);
1819     return ret_val;
1820 }
1821 
1822 static int snd_byt_rt5640_mc_remove(struct platform_device *pdev)
1823 {
1824     struct snd_soc_card *card = platform_get_drvdata(pdev);
1825     struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1826 
1827     if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2)
1828         acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
1829 
1830     device_remove_software_node(priv->codec_dev);
1831     put_device(priv->codec_dev);
1832     return 0;
1833 }
1834 
1835 static struct platform_driver snd_byt_rt5640_mc_driver = {
1836     .driver = {
1837         .name = "bytcr_rt5640",
1838     },
1839     .probe = snd_byt_rt5640_mc_probe,
1840     .remove = snd_byt_rt5640_mc_remove,
1841 };
1842 
1843 module_platform_driver(snd_byt_rt5640_mc_driver);
1844 
1845 MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
1846 MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
1847 MODULE_LICENSE("GPL v2");
1848 MODULE_ALIAS("platform:bytcr_rt5640");