summaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt5682.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/rt5682.c')
-rw-r--r--sound/soc/codecs/rt5682.c86
1 files changed, 58 insertions, 28 deletions
diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c
index 8a3052874c29..34cfaf8f6f34 100644
--- a/sound/soc/codecs/rt5682.c
+++ b/sound/soc/codecs/rt5682.c
@@ -67,7 +67,8 @@ struct rt5682_priv {
};
static const struct reg_sequence patch_list[] = {
- {0x01c1, 0x1000},
+ {RT5682_HP_IMP_SENS_CTRL_19, 0x1000},
+ {RT5682_DAC_ADC_DIG_VOL1, 0xa020},
};
static const struct reg_default rt5682_reg[] = {
@@ -749,7 +750,6 @@ static bool rt5682_readable_register(struct device *dev, unsigned int reg)
}
}
-static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -2250, 150, 0);
static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0);
static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0);
static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
@@ -1108,10 +1108,6 @@ static void rt5682_jack_detect_handler(struct work_struct *work)
}
static const struct snd_kcontrol_new rt5682_snd_controls[] = {
- /* Headphone Output Volume */
- SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5682_HPL_GAIN,
- RT5682_HPR_GAIN, RT5682_G_HP_SFT, 15, 1, hp_vol_tlv),
-
/* DAC Digital Volume */
SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5682_DAC1_DIG_VOL,
RT5682_L_VOL_SFT + 1, RT5682_R_VOL_SFT + 1, 86, 0, dac_vol_tlv),
@@ -1437,6 +1433,28 @@ static const struct snd_kcontrol_new hpor_switch =
SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5682_HP_CTRL_1,
RT5682_R_MUTE_SFT, 1, 1);
+static int rt5682_charge_pump_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component =
+ snd_soc_dapm_to_component(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_component_update_bits(component,
+ RT5682_HP_CHARGE_PUMP_1, RT5682_PM_HP_MASK, RT5682_PM_HP_HV);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_component_update_bits(component,
+ RT5682_HP_CHARGE_PUMP_1, RT5682_PM_HP_MASK, RT5682_PM_HP_LV);
+ break;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -1449,10 +1467,10 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
RT5682_HP_LOGIC_CTRL_2, 0x0012);
snd_soc_component_write(component,
RT5682_HP_CTRL_2, 0x6000);
- snd_soc_component_update_bits(component, RT5682_STO_NG2_CTRL_1,
- RT5682_NG2_EN_MASK, RT5682_NG2_EN);
snd_soc_component_update_bits(component,
RT5682_DEPOP_1, 0x60, 0x60);
+ snd_soc_component_update_bits(component,
+ RT5682_DAC_ADC_DIG_VOL1, 0x00c0, 0x0080);
break;
case SND_SOC_DAPM_POST_PMD:
@@ -1460,6 +1478,8 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
RT5682_DEPOP_1, 0x60, 0x0);
snd_soc_component_write(component,
RT5682_HP_CTRL_2, 0x0000);
+ snd_soc_component_update_bits(component,
+ RT5682_DAC_ADC_DIG_VOL1, 0x00c0, 0x0000);
break;
default:
@@ -1723,7 +1743,8 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("HP Amp R", RT5682_PWR_ANLG_1,
RT5682_PWR_HA_R_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, RT5682_DEPOP_1,
- RT5682_PUMP_EN_SFT, 0, NULL, 0),
+ RT5682_PUMP_EN_SFT, 0, rt5682_charge_pump_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY_S("Capless", 2, RT5682_DEPOP_1,
RT5682_CAPLESS_EN_SFT, 0, NULL, 0),
@@ -1884,6 +1905,7 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = {
{"HP Amp", NULL, "Charge Pump"},
{"HP Amp", NULL, "CLKDET SYS"},
{"HP Amp", NULL, "CBJ Power"},
+ {"HP Amp", NULL, "Vref1"},
{"HP Amp", NULL, "Vref2"},
{"HPOL Playback", "Switch", "HP Amp"},
{"HPOR Playback", "Switch", "HP Amp"},
@@ -2452,30 +2474,23 @@ static void rt5682_calibrate(struct rt5682_priv *rt5682)
mutex_lock(&rt5682->calibrate_mutex);
rt5682_reset(rt5682->regmap);
- regmap_write(rt5682->regmap, RT5682_PWR_ANLG_1, 0xa2bf);
+ regmap_write(rt5682->regmap, RT5682_PWR_ANLG_1, 0xa2af);
usleep_range(15000, 20000);
- regmap_write(rt5682->regmap, RT5682_PWR_ANLG_1, 0xf2bf);
- regmap_write(rt5682->regmap, RT5682_MICBIAS_2, 0x0380);
- regmap_write(rt5682->regmap, RT5682_PWR_DIG_1, 0x8001);
- regmap_write(rt5682->regmap, RT5682_TEST_MODE_CTRL_1, 0x0000);
- regmap_write(rt5682->regmap, RT5682_STO1_DAC_MIXER, 0x2080);
- regmap_write(rt5682->regmap, RT5682_STO1_ADC_MIXER, 0x4040);
- regmap_write(rt5682->regmap, RT5682_DEPOP_1, 0x0069);
+ regmap_write(rt5682->regmap, RT5682_PWR_ANLG_1, 0xf2af);
+ regmap_write(rt5682->regmap, RT5682_MICBIAS_2, 0x0300);
+ regmap_write(rt5682->regmap, RT5682_GLB_CLK, 0x8000);
+ regmap_write(rt5682->regmap, RT5682_PWR_DIG_1, 0x0100);
+ regmap_write(rt5682->regmap, RT5682_HP_IMP_SENS_CTRL_19, 0x3800);
regmap_write(rt5682->regmap, RT5682_CHOP_DAC, 0x3000);
- regmap_write(rt5682->regmap, RT5682_HP_CTRL_2, 0x6000);
- regmap_write(rt5682->regmap, RT5682_HP_CHARGE_PUMP_1, 0x0f26);
- regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x7f05);
+ regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x7005);
regmap_write(rt5682->regmap, RT5682_STO1_ADC_MIXER, 0x686c);
regmap_write(rt5682->regmap, RT5682_CAL_REC, 0x0d0d);
- regmap_write(rt5682->regmap, RT5682_HP_CALIB_CTRL_9, 0x000f);
- regmap_write(rt5682->regmap, RT5682_PWR_DIG_1, 0x8d01);
regmap_write(rt5682->regmap, RT5682_HP_CALIB_CTRL_2, 0x0321);
regmap_write(rt5682->regmap, RT5682_HP_LOGIC_CTRL_2, 0x0004);
regmap_write(rt5682->regmap, RT5682_HP_CALIB_CTRL_1, 0x7c00);
regmap_write(rt5682->regmap, RT5682_HP_CALIB_CTRL_3, 0x06a1);
regmap_write(rt5682->regmap, RT5682_A_DAC1_MUX, 0x0311);
- regmap_write(rt5682->regmap, RT5682_RESET_HPF_CTRL, 0x0000);
- regmap_write(rt5682->regmap, RT5682_ADC_STO1_HP_CTRL_1, 0x3320);
+ regmap_write(rt5682->regmap, RT5682_HP_CALIB_CTRL_1, 0x7c00);
regmap_write(rt5682->regmap, RT5682_HP_CALIB_CTRL_1, 0xfc00);
@@ -2491,8 +2506,12 @@ static void rt5682_calibrate(struct rt5682_priv *rt5682)
pr_err("HP Calibration Failure\n");
/* restore settings */
- regmap_write(rt5682->regmap, RT5682_STO1_ADC_MIXER, 0xc0c4);
+ regmap_write(rt5682->regmap, RT5682_PWR_ANLG_1, 0x02af);
+ regmap_write(rt5682->regmap, RT5682_MICBIAS_2, 0x0080);
+ regmap_write(rt5682->regmap, RT5682_GLB_CLK, 0x0000);
regmap_write(rt5682->regmap, RT5682_PWR_DIG_1, 0x0000);
+ regmap_write(rt5682->regmap, RT5682_CHOP_DAC, 0x2000);
+ regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x2005);
mutex_unlock(&rt5682->calibrate_mutex);
@@ -2566,7 +2585,7 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
rt5682_calibrate(rt5682);
- ret = regmap_register_patch(rt5682->regmap, patch_list,
+ ret = regmap_multi_reg_write(rt5682->regmap, patch_list,
ARRAY_SIZE(patch_list));
if (ret != 0)
dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
@@ -2620,6 +2639,10 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
RT5682_GP4_PIN_MASK | RT5682_GP5_PIN_MASK,
RT5682_GP4_PIN_ADCDAT1 | RT5682_GP5_PIN_DACDAT1);
regmap_write(rt5682->regmap, RT5682_TEST_MODE_CTRL_1, 0x0000);
+ regmap_update_bits(rt5682->regmap, RT5682_BIAS_CUR_CTRL_8,
+ RT5682_HPA_CP_BIAS_CTRL_MASK, RT5682_HPA_CP_BIAS_3UA);
+ regmap_update_bits(rt5682->regmap, RT5682_CHARGE_PUMP_1,
+ RT5682_CP_CLK_HP_MASK, RT5682_CP_CLK_HP_300KHZ);
INIT_DELAYED_WORK(&rt5682->jack_detect_work,
rt5682_jack_detect_handler);
@@ -2637,11 +2660,17 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
}
- return devm_snd_soc_register_component(&i2c->dev,
- &soc_component_dev_rt5682,
+ return snd_soc_register_component(&i2c->dev, &soc_component_dev_rt5682,
rt5682_dai, ARRAY_SIZE(rt5682_dai));
}
+static int rt5682_i2c_remove(struct i2c_client *i2c)
+{
+ snd_soc_unregister_component(&i2c->dev);
+
+ return 0;
+}
+
static void rt5682_i2c_shutdown(struct i2c_client *client)
{
struct rt5682_priv *rt5682 = i2c_get_clientdata(client);
@@ -2672,6 +2701,7 @@ static struct i2c_driver rt5682_i2c_driver = {
.acpi_match_table = ACPI_PTR(rt5682_acpi_match),
},
.probe = rt5682_i2c_probe,
+ .remove = rt5682_i2c_remove,
.shutdown = rt5682_i2c_shutdown,
.id_table = rt5682_i2c_id,
};