summaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt5645.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/rt5645.c')
-rw-r--r--sound/soc/codecs/rt5645.c51
1 files changed, 41 insertions, 10 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 3e8d66661b7e..7af5e7380d61 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -64,7 +64,6 @@ static const struct reg_sequence init_list[] = {
{RT5645_PR_BASE + 0x21, 0x4040},
{RT5645_PR_BASE + 0x23, 0x0004},
};
-#define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list)
static const struct reg_sequence rt5650_init_list[] = {
{0xf6, 0x0100},
@@ -405,6 +404,7 @@ struct rt5645_priv {
struct delayed_work jack_detect_work, rcclock_work;
struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
struct rt5645_eq_param_s *eq_param;
+ struct timer_list btn_check_timer;
int codec_type;
int sysclk;
@@ -776,7 +776,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
/* IN1/IN2 Control */
SOC_SINGLE_TLV("IN1 Boost", RT5645_IN1_CTRL1,
- RT5645_BST_SFT1, 8, 0, bst_tlv),
+ RT5645_BST_SFT1, 12, 0, bst_tlv),
SOC_SINGLE_TLV("IN2 Boost", RT5645_IN2_CTRL,
RT5645_BST_SFT2, 8, 0, bst_tlv),
@@ -1674,7 +1674,7 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
regmap_write(rt5645->regmap, RT5645_PR_BASE +
RT5645_MAMP_INT_REG2, 0xfc00);
snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
- msleep(70);
+ msleep(90);
rt5645->hp_on = true;
} else {
/* depop parameters */
@@ -1822,9 +1822,13 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
RT5645_PWR_CLS_D_L,
RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
RT5645_PWR_CLS_D_L);
+ snd_soc_update_bits(codec, RT5645_GEN_CTRL3,
+ RT5645_DET_CLK_MASK, RT5645_DET_CLK_MODE1);
break;
case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5645_GEN_CTRL3,
+ RT5645_DET_CLK_MASK, RT5645_DET_CLK_DIS);
snd_soc_write(codec, RT5645_EQ_CTRL2, 0);
snd_soc_update_bits(codec, RT5645_PWR_DIG1,
RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
@@ -3025,13 +3029,18 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
RT5645_PWR_BG | RT5645_PWR_VREF2,
RT5645_PWR_VREF1 | RT5645_PWR_MB |
RT5645_PWR_BG | RT5645_PWR_VREF2);
+ mdelay(10);
snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
RT5645_PWR_FV1 | RT5645_PWR_FV2,
RT5645_PWR_FV1 | RT5645_PWR_FV2);
- if (rt5645->en_button_func &&
- snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
- queue_delayed_work(system_power_efficient_wq,
- &rt5645->jack_detect_work, msecs_to_jiffies(0));
+ if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+ snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
+ msleep(40);
+ if (rt5645->en_button_func)
+ queue_delayed_work(system_power_efficient_wq,
+ &rt5645->jack_detect_work,
+ msecs_to_jiffies(0));
+ }
break;
case SND_SOC_BIAS_OFF:
@@ -3062,6 +3071,7 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
snd_soc_dapm_force_enable_pin(dapm, "ADC R power");
snd_soc_dapm_sync(dapm);
+ snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD1, 0x3, 0x3);
snd_soc_update_bits(codec,
RT5645_INT_IRQ_ST, 0x8, 0x8);
snd_soc_update_bits(codec,
@@ -3130,7 +3140,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
}
if (rt5645->pdata.jd_invert)
regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
- RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
+ RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR);
} else { /* jack out */
rt5645->jack_type = 0;
@@ -3151,7 +3161,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
snd_soc_dapm_sync(dapm);
if (rt5645->pdata.jd_invert)
regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
- RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR);
+ RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
}
return rt5645->jack_type;
@@ -3275,6 +3285,12 @@ static void rt5645_jack_detect_work(struct work_struct *work)
}
if (btn_type == 0)/* button release */
report = rt5645->jack_type;
+ else {
+ if (rt5645->pdata.jd_invert) {
+ mod_timer(&rt5645->btn_check_timer,
+ msecs_to_jiffies(100));
+ }
+ }
break;
/* jack out */
@@ -3317,6 +3333,14 @@ static irqreturn_t rt5645_irq(int irq, void *data)
return IRQ_HANDLED;
}
+static void rt5645_btn_check_callback(unsigned long data)
+{
+ struct rt5645_priv *rt5645 = (struct rt5645_priv *)data;
+
+ queue_delayed_work(system_power_efficient_wq,
+ &rt5645->jack_detect_work, msecs_to_jiffies(5));
+}
+
static int rt5645_probe(struct snd_soc_codec *codec)
{
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
@@ -3506,7 +3530,7 @@ static const struct i2c_device_id rt5645_i2c_id[] = {
MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
#ifdef CONFIG_ACPI
-static struct acpi_device_id rt5645_acpi_match[] = {
+static const struct acpi_device_id rt5645_acpi_match[] = {
{ "10EC5645", 0 },
{ "10EC5650", 0 },
{},
@@ -3783,6 +3807,13 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
}
}
+ if (rt5645->pdata.jd_invert) {
+ 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);
+ }
+
INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work);
INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work);