Commit cb2b0d7c authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/rt5563', 'asoc/topic/rt5616',...

Merge remote-tracking branches 'asoc/topic/rt5563', 'asoc/topic/rt5616', 'asoc/topic/rt5645', 'asoc/topic/rt5659' and 'asoc/topic/rt5663' into asoc-next
...@@ -12,6 +12,14 @@ Required properties: ...@@ -12,6 +12,14 @@ Required properties:
Optional properties: Optional properties:
- "realtek,dc_offset_l_manual"
- "realtek,dc_offset_r_manual"
- "realtek,dc_offset_l_manual_mic"
- "realtek,dc_offset_r_manual_mic"
Based on the different PCB layout, add the manual offset value to
compensate the DC offset for each L and R channel, and they are different
between headphone and headset.
Pins on the device (for linking into audio routes) for RT5663: Pins on the device (for linking into audio routes) for RT5663:
* IN1P * IN1P
......
/*
* linux/sound/rt5663.h -- Platform data for RT5663
*
* Copyright 2017 Realtek Semiconductor Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __LINUX_SND_RT5663_H
#define __LINUX_SND_RT5663_H
struct rt5663_platform_data {
unsigned int dc_offset_l_manual;
unsigned int dc_offset_r_manual;
unsigned int dc_offset_l_manual_mic;
unsigned int dc_offset_r_manual_mic;
};
#endif
...@@ -3559,7 +3559,7 @@ static const struct acpi_device_id rt5645_acpi_match[] = { ...@@ -3559,7 +3559,7 @@ static const struct acpi_device_id rt5645_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match);
#endif #endif
static struct rt5645_platform_data general_platform_data = { static const struct rt5645_platform_data general_platform_data = {
.dmic1_data_pin = RT5645_DMIC1_DISABLE, .dmic1_data_pin = RT5645_DMIC1_DISABLE,
.dmic2_data_pin = RT5645_DMIC_DATA_IN2P, .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
.jd_mode = 3, .jd_mode = 3,
...@@ -3593,7 +3593,7 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = { ...@@ -3593,7 +3593,7 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
{ } { }
}; };
static struct rt5645_platform_data buddy_platform_data = { static const struct rt5645_platform_data buddy_platform_data = {
.dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
.dmic2_data_pin = RT5645_DMIC_DATA_IN2P, .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
.jd_mode = 3, .jd_mode = 3,
...@@ -3610,7 +3610,7 @@ static struct dmi_system_id dmi_platform_intel_broadwell[] = { ...@@ -3610,7 +3610,7 @@ static struct dmi_system_id dmi_platform_intel_broadwell[] = {
{ } { }
}; };
static struct rt5645_platform_data gpd_win_platform_data = { static const struct rt5645_platform_data gpd_win_platform_data = {
.jd_mode = 3, .jd_mode = 3,
.inv_jd1_1 = true, .inv_jd1_1 = true,
}; };
...@@ -3637,6 +3637,39 @@ static const struct dmi_system_id dmi_platform_gpd_win[] = { ...@@ -3637,6 +3637,39 @@ static const struct dmi_system_id dmi_platform_gpd_win[] = {
{} {}
}; };
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 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"),
},
},
{ }
};
static struct rt5645_platform_data minix_z83_4_platform_data = {
.jd_mode = 3,
};
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"),
},
},
{ }
};
static bool rt5645_check_dp(struct device *dev) static bool rt5645_check_dp(struct device *dev)
{ {
if (device_property_present(dev, "realtek,in2-differential") || if (device_property_present(dev, "realtek,in2-differential") ||
...@@ -3689,6 +3722,10 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, ...@@ -3689,6 +3722,10 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
rt5645->pdata = general_platform_data; rt5645->pdata = general_platform_data;
else if (dmi_check_system(dmi_platform_gpd_win)) else if (dmi_check_system(dmi_platform_gpd_win))
rt5645->pdata = gpd_win_platform_data; 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) { if (quirk != -1) {
rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk);
......
...@@ -4222,7 +4222,7 @@ MODULE_DEVICE_TABLE(of, rt5659_of_match); ...@@ -4222,7 +4222,7 @@ MODULE_DEVICE_TABLE(of, rt5659_of_match);
#endif #endif
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static struct acpi_device_id rt5659_acpi_match[] = { static const struct acpi_device_id rt5659_acpi_match[] = {
{ "10EC5658", 0, }, { "10EC5658", 0, },
{ "10EC5659", 0, }, { "10EC5659", 0, },
{ }, { },
......
...@@ -40,6 +40,7 @@ enum { ...@@ -40,6 +40,7 @@ enum {
struct rt5663_priv { struct rt5663_priv {
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
struct rt5663_platform_data pdata;
struct regmap *regmap; struct regmap *regmap;
struct delayed_work jack_detect_work; struct delayed_work jack_detect_work;
struct snd_soc_jack *hs_jack; struct snd_soc_jack *hs_jack;
...@@ -57,6 +58,11 @@ struct rt5663_priv { ...@@ -57,6 +58,11 @@ struct rt5663_priv {
int jack_type; int jack_type;
}; };
static const struct reg_sequence rt5663_patch_list[] = {
{ 0x002a, 0x8020 },
{ 0x0086, 0x0028 },
};
static const struct reg_default rt5663_v2_reg[] = { static const struct reg_default rt5663_v2_reg[] = {
{ 0x0000, 0x0000 }, { 0x0000, 0x0000 },
{ 0x0001, 0xc8c8 }, { 0x0001, 0xc8c8 },
...@@ -476,7 +482,7 @@ static const struct reg_default rt5663_reg[] = { ...@@ -476,7 +482,7 @@ static const struct reg_default rt5663_reg[] = {
{ 0x0023, 0x0039 }, { 0x0023, 0x0039 },
{ 0x0026, 0xc0c0 }, { 0x0026, 0xc0c0 },
{ 0x0029, 0x8080 }, { 0x0029, 0x8080 },
{ 0x002a, 0xa0a0 }, { 0x002a, 0x8020 },
{ 0x002c, 0x000c }, { 0x002c, 0x000c },
{ 0x002d, 0x0000 }, { 0x002d, 0x0000 },
{ 0x0040, 0x0808 }, { 0x0040, 0x0808 },
...@@ -504,7 +510,7 @@ static const struct reg_default rt5663_reg[] = { ...@@ -504,7 +510,7 @@ static const struct reg_default rt5663_reg[] = {
{ 0x0082, 0x0000 }, { 0x0082, 0x0000 },
{ 0x0083, 0x0000 }, { 0x0083, 0x0000 },
{ 0x0084, 0x0000 }, { 0x0084, 0x0000 },
{ 0x0086, 0x0008 }, { 0x0086, 0x0028 },
{ 0x0087, 0x0000 }, { 0x0087, 0x0000 },
{ 0x008a, 0x0000 }, { 0x008a, 0x0000 },
{ 0x008b, 0x0000 }, { 0x008b, 0x0000 },
...@@ -1508,7 +1514,7 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert) ...@@ -1508,7 +1514,7 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert)
static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
{ {
struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; int val, i = 0;
dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert); dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert);
...@@ -1543,25 +1549,68 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) ...@@ -1543,25 +1549,68 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN); RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN);
snd_soc_update_bits(codec, RT5663_IRQ_1, snd_soc_update_bits(codec, RT5663_IRQ_1,
RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN); RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN);
while (i < 5) {
msleep(sleep_time[i]); while (true) {
val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & regmap_read(rt5663->regmap, RT5663_INT_ST_2, &val);
0x0003; if (!(val & 0x80))
dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n", usleep_range(10000, 10005);
__func__, val, sleep_time[i]); else
i++; break;
if (val == 0x1 || val == 0x2 || val == 0x3)
if (i > 200)
break; break;
i++;
} }
val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & 0x0003;
dev_dbg(codec->dev, "%s val = %d\n", __func__, val); dev_dbg(codec->dev, "%s val = %d\n", __func__, val);
snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
RT5663_OSW_HP_L_MASK | RT5663_OSW_HP_R_MASK,
RT5663_OSW_HP_L_EN | RT5663_OSW_HP_R_EN);
switch (val) { switch (val) {
case 1: case 1:
case 2: case 2:
rt5663->jack_type = SND_JACK_HEADSET; rt5663->jack_type = SND_JACK_HEADSET;
rt5663_enable_push_button_irq(codec, true); rt5663_enable_push_button_irq(codec, true);
if (rt5663->pdata.dc_offset_l_manual_mic) {
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2,
rt5663->pdata.dc_offset_l_manual_mic >>
16);
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_3,
rt5663->pdata.dc_offset_l_manual_mic &
0xffff);
}
if (rt5663->pdata.dc_offset_r_manual_mic) {
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_5,
rt5663->pdata.dc_offset_r_manual_mic >>
16);
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_6,
rt5663->pdata.dc_offset_r_manual_mic &
0xffff);
}
break; break;
default: default:
rt5663->jack_type = SND_JACK_HEADPHONE; rt5663->jack_type = SND_JACK_HEADPHONE;
if (rt5663->pdata.dc_offset_l_manual) {
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2,
rt5663->pdata.dc_offset_l_manual >> 16);
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_3,
rt5663->pdata.dc_offset_l_manual &
0xffff);
}
if (rt5663->pdata.dc_offset_r_manual) {
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_5,
rt5663->pdata.dc_offset_r_manual >> 16);
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_6,
rt5663->pdata.dc_offset_r_manual &
0xffff);
}
break; break;
} }
} else { } else {
...@@ -1656,6 +1705,9 @@ static void rt5663_jack_detect_work(struct work_struct *work) ...@@ -1656,6 +1705,9 @@ static void rt5663_jack_detect_work(struct work_struct *work)
default: default:
dev_err(codec->dev, "Unknown CODEC Version\n"); dev_err(codec->dev, "Unknown CODEC Version\n");
} }
/* Delay the jack insert report to avoid pop noise */
msleep(30);
} else { } else {
/* jack is already in, report button event */ /* jack is already in, report button event */
report = SND_JACK_HEADSET; report = SND_JACK_HEADSET;
...@@ -1953,13 +2005,9 @@ static const struct snd_kcontrol_new rt5663_adda_r_mix[] = { ...@@ -1953,13 +2005,9 @@ static const struct snd_kcontrol_new rt5663_adda_r_mix[] = {
static const struct snd_kcontrol_new rt5663_sto1_dac_l_mix[] = { static const struct snd_kcontrol_new rt5663_sto1_dac_l_mix[] = {
SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER,
RT5663_M_DAC_L1_STO_L_SHIFT, 1, 1), RT5663_M_DAC_L1_STO_L_SHIFT, 1, 1),
SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER,
RT5663_M_DAC_R1_STO_L_SHIFT, 1, 1),
}; };
static const struct snd_kcontrol_new rt5663_sto1_dac_r_mix[] = { static const struct snd_kcontrol_new rt5663_sto1_dac_r_mix[] = {
SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER,
RT5663_M_DAC_L1_STO_R_SHIFT, 1, 1),
SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER,
RT5663_M_DAC_R1_STO_R_SHIFT, 1, 1), RT5663_M_DAC_R1_STO_R_SHIFT, 1, 1),
}; };
...@@ -2024,10 +2072,6 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, ...@@ -2024,10 +2072,6 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
RT5663_HP_SIG_SRC1_SILENCE); RT5663_HP_SIG_SRC1_SILENCE);
} else { } else {
snd_soc_write(codec, RT5663_DEPOP_2, 0x3003); snd_soc_write(codec, RT5663_DEPOP_2, 0x3003);
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b,
0x000b);
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030,
0x0030);
snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS); RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS);
snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371); snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371);
...@@ -2036,6 +2080,8 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, ...@@ -2036,6 +2080,8 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766); snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766);
snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa); snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa);
snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777); snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777);
snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000,
0x8000);
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000,
0x3000); 0x3000);
} }
...@@ -2050,9 +2096,36 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, ...@@ -2050,9 +2096,36 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0); snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0);
snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN); RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN);
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0); }
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, break;
0x000b);
default:
return 0;
}
return 0;
}
static int rt5663_charge_pump_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (rt5663->codec_ver == CODEC_VER_0) {
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030,
0x0030);
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003,
0x0003);
}
break;
case SND_SOC_DAPM_POST_PMD:
if (rt5663->codec_ver == CODEC_VER_0) {
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0);
snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0);
} }
break; break;
...@@ -2182,6 +2255,9 @@ static const struct snd_soc_dapm_widget rt5663_dapm_widgets[] = { ...@@ -2182,6 +2255,9 @@ static const struct snd_soc_dapm_widget rt5663_dapm_widgets[] = {
SND_SOC_DAPM_DAC("DAC R", NULL, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_DAC("DAC R", NULL, SND_SOC_NOPM, 0, 0),
/* Headphone*/ /* Headphone*/
SND_SOC_DAPM_SUPPLY("HP Charge Pump", SND_SOC_NOPM, 0, 0,
rt5663_charge_pump_event, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5663_hp_event, SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5663_hp_event,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
...@@ -2330,14 +2406,13 @@ static const struct snd_soc_dapm_route rt5663_dapm_routes[] = { ...@@ -2330,14 +2406,13 @@ static const struct snd_soc_dapm_route rt5663_dapm_routes[] = {
{ "DAC R1", NULL, "ADDA MIXR" }, { "DAC R1", NULL, "ADDA MIXR" },
{ "STO1 DAC MIXL", "DAC L Switch", "DAC L1" }, { "STO1 DAC MIXL", "DAC L Switch", "DAC L1" },
{ "STO1 DAC MIXL", "DAC R Switch", "DAC R1" },
{ "STO1 DAC MIXL", NULL, "STO1 DAC L Power" }, { "STO1 DAC MIXL", NULL, "STO1 DAC L Power" },
{ "STO1 DAC MIXL", NULL, "STO1 DAC Filter" }, { "STO1 DAC MIXL", NULL, "STO1 DAC Filter" },
{ "STO1 DAC MIXR", "DAC R Switch", "DAC R1" }, { "STO1 DAC MIXR", "DAC R Switch", "DAC R1" },
{ "STO1 DAC MIXR", "DAC L Switch", "DAC L1" },
{ "STO1 DAC MIXR", NULL, "STO1 DAC R Power" }, { "STO1 DAC MIXR", NULL, "STO1 DAC R Power" },
{ "STO1 DAC MIXR", NULL, "STO1 DAC Filter" }, { "STO1 DAC MIXR", NULL, "STO1 DAC Filter" },
{ "HP Amp", NULL, "HP Charge Pump" },
{ "HP Amp", NULL, "DAC L" }, { "HP Amp", NULL, "DAC L" },
{ "HP Amp", NULL, "DAC R" }, { "HP Amp", NULL, "DAC R" },
}; };
...@@ -2956,7 +3031,7 @@ MODULE_DEVICE_TABLE(of, rt5663_of_match); ...@@ -2956,7 +3031,7 @@ MODULE_DEVICE_TABLE(of, rt5663_of_match);
#endif #endif
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static struct acpi_device_id rt5663_acpi_match[] = { static const struct acpi_device_id rt5663_acpi_match[] = {
{ "10EC5663", 0}, { "10EC5663", 0},
{}, {},
}; };
...@@ -2986,47 +3061,93 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) ...@@ -2986,47 +3061,93 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663)
{ {
int value, count; int value, count;
regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0280); regmap_write(rt5663->regmap, RT5663_RESET, 0x0000);
msleep(20);
regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_4, 0x00a1);
regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0380);
regmap_write(rt5663->regmap, RT5663_GLB_CLK, 0x8000); regmap_write(rt5663->regmap, RT5663_GLB_CLK, 0x8000);
regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001); regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1000);
regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032); regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032);
regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa2be); regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x000c);
msleep(20); regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x0324);
regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf2be); regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001);
regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400); regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa23b);
regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000); msleep(30);
regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b); regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf23b);
regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8); regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8000);
regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0003); regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x0008);
regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c);
regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1111);
regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_1, 0xffff); regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_1, 0xffff);
regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_2, 0xffff); regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_2, 0xffff);
regmap_write(rt5663->regmap, RT5663_CBJ_1, 0x8c10);
regmap_write(rt5663->regmap, RT5663_IL_CMD_2, 0x00c1);
regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb880);
regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4110);
regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4118);
count = 0;
while (true) {
regmap_read(rt5663->regmap, RT5663_INT_ST_2, &value);
if (!(value & 0x80))
usleep_range(10000, 10005);
else
break;
if (++count > 200)
break;
}
regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x0000);
regmap_write(rt5663->regmap, RT5663_DEPOP_2, 0x3003); regmap_write(rt5663->regmap, RT5663_DEPOP_2, 0x3003);
regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0038);
regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b); regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b);
regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400);
regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8);
regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8003);
regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c);
regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32); regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32);
regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_2, 0x1371);
regmap_write(rt5663->regmap, RT5663_DACREF_LDO, 0x3b0b); regmap_write(rt5663->regmap, RT5663_DACREF_LDO, 0x3b0b);
regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x2080); msleep(40);
regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x0000);
regmap_write(rt5663->regmap, RT5663_BYPASS_STO_DAC, 0x000c); regmap_write(rt5663->regmap, RT5663_BYPASS_STO_DAC, 0x000c);
regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xabba); regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xafaa);
regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_1, 0x2224); regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_1, 0x2224);
regmap_write(rt5663->regmap, RT5663_HP_OUT_EN, 0x8088); regmap_write(rt5663->regmap, RT5663_HP_OUT_EN, 0x8088);
regmap_write(rt5663->regmap, RT5663_STO_DRE_9, 0x0017); regmap_write(rt5663->regmap, RT5663_STO_DRE_9, 0x0017);
regmap_write(rt5663->regmap, RT5663_STO_DRE_10, 0x0017); regmap_write(rt5663->regmap, RT5663_STO_DRE_10, 0x0017);
regmap_write(rt5663->regmap, RT5663_STO1_ADC_MIXER, 0x4040); regmap_write(rt5663->regmap, RT5663_STO1_ADC_MIXER, 0x4040);
regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000);
regmap_write(rt5663->regmap, RT5663_RECMIX, 0x0005); regmap_write(rt5663->regmap, RT5663_RECMIX, 0x0005);
regmap_write(rt5663->regmap, RT5663_ADDA_RST, 0xc000); regmap_write(rt5663->regmap, RT5663_ADDA_RST, 0xc000);
regmap_write(rt5663->regmap, RT5663_STO1_HPF_ADJ1, 0x3320); regmap_write(rt5663->regmap, RT5663_STO1_HPF_ADJ1, 0x3320);
regmap_write(rt5663->regmap, RT5663_HP_CALIB_2, 0x00c9); regmap_write(rt5663->regmap, RT5663_HP_CALIB_2, 0x00c9);
regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x004c); regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x004c);
regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x7766); regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x1111);
regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4702); regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4402);
msleep(200); regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x3311);
regmap_write(rt5663->regmap, RT5663_HP_CALIB_1, 0x0069); regmap_write(rt5663->regmap, RT5663_HP_CALIB_1, 0x0069);
regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06c2); regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06ce);
regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x7b00); regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6800);
regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xfb00); regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x1100);
regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0057);
regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe800);
count = 0;
while (true) {
regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value);
if (value & 0x8000)
usleep_range(10000, 10005);
else
break;
if (count > 200)
return;
count++;
}
regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6200);
regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0059);
regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe200);
count = 0; count = 0;
while (true) { while (true) {
regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value); regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value);
...@@ -3039,11 +3160,39 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) ...@@ -3039,11 +3160,39 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663)
return; return;
count++; count++;
} }
regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb8e0);
usleep_range(10000, 10005);
regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0x003b);
usleep_range(10000, 10005);
regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x0000);
usleep_range(10000, 10005);
regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x000b);
usleep_range(10000, 10005);
regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0008);
usleep_range(10000, 10005);
regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0000);
usleep_range(10000, 10005);
}
static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev)
{
device_property_read_u32(dev, "realtek,dc_offset_l_manual",
&rt5663->pdata.dc_offset_l_manual);
device_property_read_u32(dev, "realtek,dc_offset_r_manual",
&rt5663->pdata.dc_offset_r_manual);
device_property_read_u32(dev, "realtek,dc_offset_l_manual_mic",
&rt5663->pdata.dc_offset_l_manual_mic);
device_property_read_u32(dev, "realtek,dc_offset_r_manual_mic",
&rt5663->pdata.dc_offset_r_manual_mic);
return 0;
} }
static int rt5663_i2c_probe(struct i2c_client *i2c, static int rt5663_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct rt5663_priv *rt5663; struct rt5663_priv *rt5663;
int ret; int ret;
unsigned int val; unsigned int val;
...@@ -3057,6 +3206,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, ...@@ -3057,6 +3206,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, rt5663); i2c_set_clientdata(i2c, rt5663);
if (pdata)
rt5663->pdata = *pdata;
else
rt5663_parse_dp(rt5663, &i2c->dev);
regmap = devm_regmap_init_i2c(i2c, &temp_regmap); regmap = devm_regmap_init_i2c(i2c, &temp_regmap);
if (IS_ERR(regmap)) { if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap); ret = PTR_ERR(regmap);
...@@ -3105,6 +3259,20 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, ...@@ -3105,6 +3259,20 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
regmap_write(rt5663->regmap, RT5663_RESET, 0); regmap_write(rt5663->regmap, RT5663_RESET, 0);
dev_dbg(&i2c->dev, "calibrate done\n"); dev_dbg(&i2c->dev, "calibrate done\n");
switch (rt5663->codec_ver) {
case CODEC_VER_1:
break;
case CODEC_VER_0:
ret = regmap_register_patch(rt5663->regmap, rt5663_patch_list,
ARRAY_SIZE(rt5663_patch_list));
if (ret != 0)
dev_warn(&i2c->dev,
"Failed to apply regmap patch: %d\n", ret);
break;
default:
dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__);
}
/* GPIO1 as IRQ */ /* GPIO1 as IRQ */
regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, RT5663_GP1_PIN_MASK, regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, RT5663_GP1_PIN_MASK,
RT5663_GP1_PIN_IRQ); RT5663_GP1_PIN_IRQ);
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#ifndef __RT5663_H__ #ifndef __RT5663_H__
#define __RT5663_H__ #define __RT5663_H__
#include <sound/rt5663.h>
/* Info */ /* Info */
#define RT5663_RESET 0x0000 #define RT5663_RESET 0x0000
#define RT5663_VENDOR_ID 0x00fd #define RT5663_VENDOR_ID 0x00fd
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment