Merge remote-tracking branches 'asoc/topic/rl6231', 'asoc/topic/rt5514' and 'asoc...
authorMark Brown <broonie@kernel.org>
Fri, 5 Jan 2018 12:44:00 +0000 (12:44 +0000)
committerMark Brown <broonie@kernel.org>
Fri, 5 Jan 2018 12:44:00 +0000 (12:44 +0000)
1  2  3  4 
sound/soc/codecs/rt5514-spi.c
sound/soc/codecs/rt5514.c
sound/soc/codecs/rt5645.c

    
    static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
    {
  +     size_t period_bytes;
        u8 buf[8];
    
  +     if (!rt5514_dsp->substream)
  +             return;
  + 
  +     period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream);
        rt5514_dsp->get_size = 0;
    
        /**
    
        rt5514_dsp->buf_size = rt5514_dsp->buf_limit - rt5514_dsp->buf_base;
    
  +     if (rt5514_dsp->buf_size % period_bytes)
  +             rt5514_dsp->buf_size = (rt5514_dsp->buf_size / period_bytes) *
  +                     period_bytes;
  + 
        if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
                rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
                schedule_delayed_work(&rt5514_dsp->copy_work, 0);
@@@@@ -289,8 -289,6 -280,6 -289,6 +289,8 @@@@@ static int rt5514_spi_pcm_probe(struct 
                        dev_err(&rt5514_spi->dev,
                                "%s Failed to reguest IRQ: %d\n", __func__,
                                ret);
 +++            else
 +++                    device_init_wakeup(rt5514_dsp->dev, true);
        }
    
        return 0;
@@@@@ -381,6 -379,6 -370,7 -379,6 +381,7 @@@@@ int rt5514_spi_burst_read(unsigned int 
    
        return true;
    }
++ +EXPORT_SYMBOL_GPL(rt5514_spi_burst_read);
    
    /**
     * rt5514_spi_burst_write - Write data to SPI by rt5514 address.
@@@@@ -458,46 -456,45 -448,9 -456,45 +459,46 @@@@@ static int rt5514_spi_probe(struct spi_
                return ret;
        }
    
 - -    device_init_wakeup(&spi->dev, true);
 - -
        return 0;
    }
    
 - -    if (rt5514_dsp->substream) {
 - -            rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf));
 - -            if (buf[0] & RT5514_IRQ_STATUS_BIT)
 - -                    rt5514_schedule_copy(rt5514_dsp);
  + static int __maybe_unused rt5514_suspend(struct device *dev)
  + {
  +     int irq = to_spi_device(dev)->irq;
  + 
  +     if (device_may_wakeup(dev))
  +             enable_irq_wake(irq);
  + 
  +     return 0;
  + }
  + 
  + static int __maybe_unused rt5514_resume(struct device *dev)
  + {
  +     struct snd_soc_platform *platform = snd_soc_lookup_platform(dev);
  +     struct rt5514_dsp *rt5514_dsp =
  +             snd_soc_platform_get_drvdata(platform);
  +     int irq = to_spi_device(dev)->irq;
  +     u8 buf[8];
  + 
  +     if (device_may_wakeup(dev))
  +             disable_irq_wake(irq);
  + 
 +++    if (rt5514_dsp) {
 +++            if (rt5514_dsp->substream) {
 +++                    rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf,
 +++                            sizeof(buf));
 +++                    if (buf[0] & RT5514_IRQ_STATUS_BIT)
 +++                            rt5514_schedule_copy(rt5514_dsp);
 +++            }
  +     }
  + 
  +     return 0;
  + }
  + 
  + static const struct dev_pm_ops rt5514_pm_ops = {
  +     SET_SYSTEM_SLEEP_PM_OPS(rt5514_suspend, rt5514_resume)
  + };
  + 
    static const struct of_device_id rt5514_of_match[] = {
        { .compatible = "realtek,rt5514", },
        {},
@@@@@ -507,7 -504,7 -460,6 -504,7 +508,7 @@@@@ MODULE_DEVICE_TABLE(of, rt5514_of_match
    static struct spi_driver rt5514_spi_driver = {
        .driver = {
                .name = "rt5514",
  +             .pm = &rt5514_pm_ops,
                .of_match_table = of_match_ptr(rt5514_of_match),
        },
        .probe = rt5514_spi_probe,
@@@@@ -295,6 -295,6 -295,33 -295,6 +295,33 @@@@@ static int rt5514_dsp_voice_wake_up_get
        return 0;
    }
    
++ +static int rt5514_calibration(struct rt5514_priv *rt5514, bool on)
++ +{
++ +    if (on) {
++ +            regmap_write(rt5514->regmap, RT5514_ANA_CTRL_PLL3, 0x0000000a);
++ +            regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL, 0xf,
++ +                    0xa);
++ +            regmap_update_bits(rt5514->regmap, RT5514_PWR_ANA1, 0x301,
++ +                    0x301);
++ +            regmap_write(rt5514->regmap, RT5514_PLL3_CALIB_CTRL4,
++ +                    0x80000000 | rt5514->pll3_cal_value);
++ +            regmap_write(rt5514->regmap, RT5514_PLL3_CALIB_CTRL1,
++ +                    0x8bb80800);
++ +            regmap_update_bits(rt5514->regmap, RT5514_PLL3_CALIB_CTRL5,
++ +                    0xc0000000, 0x80000000);
++ +            regmap_update_bits(rt5514->regmap, RT5514_PLL3_CALIB_CTRL5,
++ +                    0xc0000000, 0xc0000000);
++ +    } else {
++ +            regmap_update_bits(rt5514->regmap, RT5514_PLL3_CALIB_CTRL5,
++ +                    0xc0000000, 0x40000000);
++ +            regmap_update_bits(rt5514->regmap, RT5514_PWR_ANA1, 0x301, 0);
++ +            regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL, 0xf,
++ +                    0x4);
++ +    }
++ +
++ +    return 0;
++ +}
++ +
    static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
    {
        struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
        struct snd_soc_codec *codec = rt5514->codec;
        const struct firmware *fw = NULL;
++ +    u8 buf[8];
    
        if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled)
                return 0;
                rt5514->dsp_enabled = ucontrol->value.integer.value[0];
    
                if (rt5514->dsp_enabled) {
++ +                    if (rt5514->pdata.dsp_calib_clk_name &&
++ +                            !IS_ERR(rt5514->dsp_calib_clk)) {
++ +                            if (clk_set_rate(rt5514->dsp_calib_clk,
++ +                                    rt5514->pdata.dsp_calib_clk_rate))
++ +                                    dev_err(codec->dev,
++ +                                            "Can't set rate for mclk");
++ +
++ +                            if (clk_prepare_enable(rt5514->dsp_calib_clk))
++ +                                    dev_err(codec->dev,
++ +                                            "Can't enable dsp_calib_clk");
++ +
++ +                            rt5514_calibration(rt5514, true);
++ +
++ +                            msleep(20);
++ +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
++ +                            rt5514_spi_burst_read(RT5514_PLL3_CALIB_CTRL6 |
++ +                                    RT5514_DSP_MAPPING,
++ +                                    (u8 *)&buf, sizeof(buf));
++ +#else
++ +                            dev_err(codec->dev, "There is no SPI driver for"
++ +                                    " loading the firmware\n");
++ +#endif
++ +                            rt5514->pll3_cal_value = buf[0] | buf[1] << 8 |
++ +                                    buf[2] << 16 | buf[3] << 24;
++ +
++ +                            rt5514_calibration(rt5514, false);
++ +                            clk_disable_unprepare(rt5514->dsp_calib_clk);
++ +                    }
++ +
                        rt5514_enable_dsp_prepare(rt5514);
    
                        request_firmware(&fw, RT5514_FIRMWARE1, codec->dev);
                        /* DSP run */
                        regmap_write(rt5514->i2c_regmap, 0x18002f00,
                                0x00055148);
++ +
++ +                    if (rt5514->pdata.dsp_calib_clk_name &&
++ +                            !IS_ERR(rt5514->dsp_calib_clk)) {
++ +                            msleep(20);
++ +
++ +                            regmap_write(rt5514->i2c_regmap, 0x1800211c,
++ +                                    rt5514->pll3_cal_value);
++ +                            regmap_write(rt5514->i2c_regmap, 0x18002124,
++ +                                    0x00220012);
++ +                            regmap_write(rt5514->i2c_regmap, 0x18002124,
++ +                                    0x80220042);
++ +                            regmap_write(rt5514->i2c_regmap, 0x18002124,
++ +                                    0xe0220042);
++ +                    }
                } else {
                        regmap_multi_reg_write(rt5514->i2c_regmap,
                                rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch));
@@@@@ -496,7 -496,7 -567,7 -496,7 +567,7 @@@@@ static const struct snd_soc_dapm_widge
        SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
        SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
    
 ---    SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
 +++    SND_SOC_DAPM_SUPPLY_S("DMIC CLK", 1, SND_SOC_NOPM, 0, 0,
                rt5514_set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
    
        SND_SOC_DAPM_SUPPLY("ADC CLK", RT5514_CLK_CTRL1,
@@@@@ -1024,12 -1024,12 -1095,22 -1024,12 +1095,22 @@@@@ static int rt5514_set_bias_level(struc
    static int rt5514_probe(struct snd_soc_codec *codec)
    {
        struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
++ +    struct platform_device *pdev = container_of(codec->dev,
++ +                                               struct platform_device, dev);
    
        rt5514->mclk = devm_clk_get(codec->dev, "mclk");
        if (PTR_ERR(rt5514->mclk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
    
++ +    if (rt5514->pdata.dsp_calib_clk_name) {
++ +            rt5514->dsp_calib_clk = devm_clk_get(&pdev->dev,
++ +                            rt5514->pdata.dsp_calib_clk_name);
++ +            if (PTR_ERR(rt5514->dsp_calib_clk) == -EPROBE_DEFER)
++ +                    return -EPROBE_DEFER;
++ +    }
++ +
        rt5514->codec = codec;
++ +    rt5514->pll3_cal_value = 0x0078b000;
    
        return 0;
    }
@@@@@ -1147,6 -1147,6 -1228,10 -1147,6 +1228,10 @@@@@ static int rt5514_parse_dp(struct rt551
    {
        device_property_read_u32(dev, "realtek,dmic-init-delay-ms",
                &rt5514->pdata.dmic_init_delay);
++ +    device_property_read_string(dev, "realtek,dsp-calib-clk-name",
++ +            &rt5514->pdata.dsp_calib_clk_name);
++ +    device_property_read_u32(dev, "realtek,dsp-calib-clk-rate",
++ +            &rt5514->pdata.dsp_calib_clk_rate);
    
        return 0;
    }
@@@@@ -55,8 -55,8 -55,6 -55,8 +55,8 @@@@@ MODULE_PARM_DESC(quirk, "RT5645 pdata q
    
    #define RT5645_HWEQ_NUM 57
    
  + #define TIME_TO_POWER_MS 400
  + 
    static const struct regmap_range_cfg rt5645_ranges[] = {
        {
                .name = "PR",
@@@@@ -434,7 -434,7 -432,6 -434,7 +434,7 @@@@@ struct rt5645_priv 
        int jack_type;
        bool en_button_func;
        bool hp_on;
  +     int v_id;
    };
    
    static int rt5645_reset(struct snd_soc_codec *codec)
@@@@@ -1943,6 -1943,6 -1940,6 -1943,56 +1943,56 @@@@@ static int rt5650_hp_event(struct snd_s
        return 0;
    }
    
+++ static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w,
+++             struct snd_kcontrol *k, int  event)
+++ {
+++     struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+++ 
+++     switch (event) {
+++     case SND_SOC_DAPM_PRE_PMU:
+++             snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+++                     RT5645_MICBIAS1_POW_CTRL_SEL_MASK,
+++                     RT5645_MICBIAS1_POW_CTRL_SEL_M);
+++             break;
+++ 
+++     case SND_SOC_DAPM_POST_PMD:
+++             snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+++                     RT5645_MICBIAS1_POW_CTRL_SEL_MASK,
+++                     RT5645_MICBIAS1_POW_CTRL_SEL_A);
+++             break;
+++ 
+++     default:
+++             return 0;
+++     }
+++ 
+++     return 0;
+++ }
+++ 
+++ static int rt5645_set_micbias2_event(struct snd_soc_dapm_widget *w,
+++             struct snd_kcontrol *k, int  event)
+++ {
+++     struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+++ 
+++     switch (event) {
+++     case SND_SOC_DAPM_PRE_PMU:
+++             snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+++                     RT5645_MICBIAS2_POW_CTRL_SEL_MASK,
+++                     RT5645_MICBIAS2_POW_CTRL_SEL_M);
+++             break;
+++ 
+++     case SND_SOC_DAPM_POST_PMD:
+++             snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+++                     RT5645_MICBIAS2_POW_CTRL_SEL_MASK,
+++                     RT5645_MICBIAS2_POW_CTRL_SEL_A);
+++             break;
+++ 
+++     default:
+++             return 0;
+++     }
+++ 
+++     return 0;
+++ }
+++ 
    static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("LDO2", RT5645_PWR_MIXER,
                RT5645_PWR_LDO2_BIT, 0, NULL, 0),
    
        /* Input Side */
        /* micbias */
---     SND_SOC_DAPM_MICBIAS("micbias1", RT5645_PWR_ANLG2,
---                     RT5645_PWR_MB1_BIT, 0),
---     SND_SOC_DAPM_MICBIAS("micbias2", RT5645_PWR_ANLG2,
---                     RT5645_PWR_MB2_BIT, 0),
+++     SND_SOC_DAPM_SUPPLY("micbias1", RT5645_PWR_ANLG2,
+++                     RT5645_PWR_MB1_BIT, 0, rt5645_set_micbias1_event,
+++                     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+++     SND_SOC_DAPM_SUPPLY("micbias2", RT5645_PWR_ANLG2,
+++                     RT5645_PWR_MB2_BIT, 0, rt5645_set_micbias2_event,
+++                     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
        /* Input Lines */
        SND_SOC_DAPM_INPUT("DMIC L1"),
        SND_SOC_DAPM_INPUT("DMIC R1"),
@@@@@ -2519,7 -2519,7 -2516,9 -2571,7 +2571,7 @@@@@ static const struct snd_soc_dapm_route 
        { "SPKVOL L", "Switch", "SPK MIXL" },
        { "SPKVOL R", "Switch", "SPK MIXR" },
    
  -     { "SPOL MIX", "DAC R1 Switch", "DAC R1" },
        { "SPOL MIX", "DAC L1 Switch", "DAC L1" },
  -     { "SPOL MIX", "SPKVOL R Switch", "SPKVOL R" },
        { "SPOL MIX", "SPKVOL L Switch", "SPKVOL L" },
        { "SPOR MIX", "DAC R1 Switch", "DAC R1" },
        { "SPOR MIX", "SPKVOL R Switch", "SPKVOL R" },
@@@@@ -2708,11 -2708,11 -2707,6 -2760,11 +2760,11 @@@@@ static const struct snd_soc_dapm_route 
        { "DAC R2 Mux", "IF1 DAC", "RT5645 IF1 DAC2 R Mux" },
    };
    
  + static const struct snd_soc_dapm_route rt5645_old_dapm_routes[] = {
  +     { "SPOL MIX", "DAC R1 Switch", "DAC R1" },
  +     { "SPOL MIX", "SPKVOL R Switch", "SPKVOL R" },
  + };
  + 
    static int rt5645_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
    {
@@@@@ -3346,9 -3346,9 -3340,9 -3398,9 +3398,9 @@@@@ static irqreturn_t rt5645_irq(int irq, 
        return IRQ_HANDLED;
    }
    
  --static void rt5645_btn_check_callback(unsigned long data)
  ++static void rt5645_btn_check_callback(struct timer_list *t)
    {
  --    struct rt5645_priv *rt5645 = (struct rt5645_priv *)data;
  ++    struct rt5645_priv *rt5645 = from_timer(rt5645, t, btn_check_timer);
    
        queue_delayed_work(system_power_efficient_wq,
                   &rt5645->jack_detect_work, msecs_to_jiffies(5));
@@@@@ -3369,11 -3369,11 -3363,6 -3421,11 +3421,11 @@@@@ static int rt5645_probe(struct snd_soc_
                snd_soc_dapm_add_routes(dapm,
                        rt5645_specific_dapm_routes,
                        ARRAY_SIZE(rt5645_specific_dapm_routes));
  +             if (rt5645->v_id < 3) {
  +                     snd_soc_dapm_add_routes(dapm,
  +                             rt5645_old_dapm_routes,
  +                             ARRAY_SIZE(rt5645_old_dapm_routes));
  +             }
                break;
        case CODEC_TYPE_RT5650:
                snd_soc_dapm_new_controls(dapm,
                snd_soc_dapm_sync(dapm);
        }
    
+++     if (rt5645->pdata.long_name)
+++             codec->component.card->long_name = rt5645->pdata.long_name;
+++ 
        rt5645->eq_param = devm_kzalloc(codec->dev,
                RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL);
    
@@@@@ -3570,63 -3570,63 -3559,63 -3625,74 +3625,74 @@@@@ static const struct acpi_device_id rt56
    MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match);
    #endif
    
--- static const struct rt5645_platform_data general_platform_data = {
+++ static const struct rt5645_platform_data intel_braswell_platform_data = {
        .dmic1_data_pin = RT5645_DMIC1_DISABLE,
        .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
        .jd_mode = 3,
    };
    
--- static const struct dmi_system_id dmi_platform_intel_braswell[] = {
+++ static const struct rt5645_platform_data buddy_platform_data = {
+++     .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
+++     .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
+++     .jd_mode = 3,
+++     .level_trigger_irq = true,
+++ };
+++ 
+++ static const struct rt5645_platform_data gpd_win_platform_data = {
+++     .jd_mode = 3,
+++     .inv_jd1_1 = true,
+++     .long_name = "gpd-win-pocket-rt5645",
+++     /* The GPD pocket has a diff. mic, for the win this does not matter. */
+++     .in2_diff = true,
+++ };
+++ 
+++ static const struct rt5645_platform_data asus_t100ha_platform_data = {
+++     .dmic1_data_pin = RT5645_DMIC_DATA_IN2N,
+++     .dmic2_data_pin = RT5645_DMIC2_DISABLE,
+++     .jd_mode = 3,
+++     .inv_jd1_1 = true,
+++ };
+++ 
+++ static const struct rt5645_platform_data jd_mode3_platform_data = {
+++     .jd_mode = 3,
+++ };
+++ 
+++ static const struct dmi_system_id dmi_platform_data[] = {
+++     {
+++             .ident = "Chrome Buddy",
+++             .matches = {
+++                     DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"),
+++             },
+++             .driver_data = (void *)&buddy_platform_data,
+++     },
        {
                .ident = "Intel Strago",
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Strago"),
                },
+++             .driver_data = (void *)&intel_braswell_platform_data,
        },
        {
                .ident = "Google Chrome",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
                },
+++             .driver_data = (void *)&intel_braswell_platform_data,
        },
        {
                .ident = "Google Setzer",
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"),
                },
+++             .driver_data = (void *)&intel_braswell_platform_data,
        },
        {
                .ident = "Microsoft Surface 3",
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
                },
+++             .driver_data = (void *)&intel_braswell_platform_data,
        },
---     { }
--- };
--- 
--- static const struct rt5645_platform_data buddy_platform_data = {
---     .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
---     .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
---     .jd_mode = 3,
---     .level_trigger_irq = true,
--- };
--- 
--  static const struct dmi_system_id dmi_platform_intel_broadwell[] = {
  - static struct dmi_system_id dmi_platform_intel_broadwell[] = {
---     {
---             .ident = "Chrome Buddy",
---             .matches = {
---                     DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"),
---             },
---     },
---     { }
--- };
--- 
--- static const struct rt5645_platform_data gpd_win_platform_data = {
---     .jd_mode = 3,
---     .inv_jd1_1 = true,
--- };
--- 
--- static const struct dmi_system_id dmi_platform_gpd_win[] = {
        {
                /*
                 * Match for the GPDwin which unfortunately uses somewhat
                 * the same default product_name. Also the GPDwin is the
                 * only device to have both board_ and product_name not set.
                 */
---             .ident = "GPD Win",
+++             .ident = "GPD Win / Pocket",
                .matches = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
                        DMI_MATCH(DMI_BOARD_NAME, "Default string"),
                        DMI_MATCH(DMI_BOARD_SERIAL, "Default string"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
                },
+++             .driver_data = (void *)&gpd_win_platform_data,
        },
---     {}
--- };
--- 
--  static const struct rt5645_platform_data general_platform_data2 = {
  - static struct rt5645_platform_data general_platform_data2 = {
---     .dmic1_data_pin = RT5645_DMIC_DATA_IN2N,
---     .dmic2_data_pin = RT5645_DMIC2_DISABLE,
---     .jd_mode = 3,
---     .inv_jd1_1 = true,
--- };
--- 
--  static const struct dmi_system_id dmi_platform_asus_t100ha[] = {
  - static struct dmi_system_id dmi_platform_asus_t100ha[] = {
        {
                .ident = "ASUS T100HAN",
                .matches = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
                        DMI_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
                },
+++             .driver_data = (void *)&asus_t100ha_platform_data,
        },
---     { }
--- };
--- 
--  static const struct rt5645_platform_data minix_z83_4_platform_data = {
  - static struct rt5645_platform_data minix_z83_4_platform_data = {
---     .jd_mode = 3,
--- };
--- 
--  static const struct dmi_system_id dmi_platform_minix_z83_4[] = {
  - static struct dmi_system_id dmi_platform_minix_z83_4[] = {
        {
                .ident = "MINIX Z83-4",
                .matches = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MINIX"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
                },
+++             .driver_data = (void *)&jd_mode3_platform_data,
+++     },
+++     {
+++             .ident = "Teclast X80 Pro",
+++             .matches = {
+++                     DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+++                     DMI_MATCH(DMI_PRODUCT_NAME, "X80 Pro"),
+++             },
+++             .driver_data = (void *)&jd_mode3_platform_data,
        },
        { }
    };
    
--- static bool rt5645_check_dp(struct device *dev)
--- {
---     if (device_property_present(dev, "realtek,in2-differential") ||
---             device_property_present(dev, "realtek,dmic1-data-pin") ||
---             device_property_present(dev, "realtek,dmic2-data-pin") ||
---             device_property_present(dev, "realtek,jd-mode"))
---             return true;
--- 
---     return false;
--- }
--- 
    static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev)
    {
        rt5645->pdata.in2_diff = device_property_read_bool(dev,
@@@@@ -3710,6 -3710,6 -3699,6 -3757,7 +3757,7 @@@@@ static int rt5645_i2c_probe(struct i2c_
                    const struct i2c_device_id *id)
    {
        struct rt5645_platform_data *pdata = dev_get_platdata(&i2c->dev);
+++     const struct dmi_system_id *dmi_data;
        struct rt5645_priv *rt5645;
        int ret, i;
        unsigned int val;
        rt5645->i2c = i2c;
        i2c_set_clientdata(i2c, rt5645);
    
+++     dmi_data = dmi_first_match(dmi_platform_data);
+++     if (dmi_data) {
+++             dev_info(&i2c->dev, "Detected %s platform\n", dmi_data->ident);
+++             pdata = dmi_data->driver_data;
+++     }
+++ 
        if (pdata)
                rt5645->pdata = *pdata;
---     else if (dmi_check_system(dmi_platform_intel_broadwell))
---             rt5645->pdata = buddy_platform_data;
---     else if (rt5645_check_dp(&i2c->dev))
+++     else
                rt5645_parse_dt(rt5645, &i2c->dev);
---     else if (dmi_check_system(dmi_platform_intel_braswell))
---             rt5645->pdata = general_platform_data;
---     else if (dmi_check_system(dmi_platform_gpd_win))
---             rt5645->pdata = gpd_win_platform_data;
---     else if (dmi_check_system(dmi_platform_asus_t100ha))
---             rt5645->pdata = general_platform_data2;
---     else if (dmi_check_system(dmi_platform_minix_z83_4))
---             rt5645->pdata = minix_z83_4_platform_data;
    
        if (quirk != -1) {
                rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk);
                        ret);
                return ret;
        }
  + 
  +     /*
  +      * Read after 400msec, as it is the interval required between
  +      * read and power On.
  +      */
  +     msleep(TIME_TO_POWER_MS);
        regmap_read(regmap, RT5645_VENDOR_ID2, &val);
    
        switch (val) {
    
        regmap_write(rt5645->regmap, RT5645_RESET, 0);
    
  +     regmap_read(regmap, RT5645_VENDOR_ID, &val);
  +     rt5645->v_id = val & 0xff;
  + 
 ++     regmap_write(rt5645->regmap, RT5645_AD_DA_MIXER, 0x8080);
 ++ 
        ret = regmap_register_patch(rt5645->regmap, init_list,
                                    ARRAY_SIZE(init_list));
        if (ret != 0)
                regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
                        RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
        }
  --    setup_timer(&rt5645->btn_check_timer,
  --            rt5645_btn_check_callback, (unsigned long)rt5645);
  ++    timer_setup(&rt5645->btn_check_timer, rt5645_btn_check_callback, 0);
    
        INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work);
        INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work);