Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-linus
authorMark Brown <broonie@kernel.org>
Tue, 5 Jan 2016 23:07:33 +0000 (23:07 +0000)
committerMark Brown <broonie@kernel.org>
Tue, 5 Jan 2016 23:07:33 +0000 (23:07 +0000)
1  2 
sound/soc/codecs/rt5645.c

@@@ -245,7 -245,7 +245,7 @@@ struct rt5645_priv 
        struct snd_soc_jack *hp_jack;
        struct snd_soc_jack *mic_jack;
        struct snd_soc_jack *btn_jack;
 -      struct delayed_work jack_detect_work;
 +      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;
  
@@@ -565,33 -565,12 +565,33 @@@ static int rt5645_hweq_put(struct snd_k
        .put = rt5645_hweq_put \
  }
  
 +static int rt5645_spk_put_volsw(struct snd_kcontrol *kcontrol,
 +              struct snd_ctl_elem_value *ucontrol)
 +{
 +      struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 +      struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 +      int ret;
 +
 +      cancel_delayed_work_sync(&rt5645->rcclock_work);
 +
 +      regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
 +              RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU);
 +
 +      ret = snd_soc_put_volsw(kcontrol, ucontrol);
 +
 +      queue_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work,
 +              msecs_to_jiffies(200));
 +
 +      return ret;
 +}
 +
  static const struct snd_kcontrol_new rt5645_snd_controls[] = {
        /* Speaker Output Volume */
        SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL,
                RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1),
 -      SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL,
 -              RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv),
 +      SOC_DOUBLE_EXT_TLV("Speaker Playback Volume", RT5645_SPK_VOL,
 +              RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, snd_soc_get_volsw,
 +              rt5645_spk_put_volsw, out_vol_tlv),
  
        /* ClassD modulator Speaker Gain Ratio */
        SOC_SINGLE_TLV("Speaker ClassD Playback Volume", RT5645_SPO_CLSD_RATIO,
@@@ -1519,7 -1498,7 +1519,7 @@@ static void hp_amp_power(struct snd_soc
                                regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                        RT5645_MAMP_INT_REG2, 0xfc00);
                                snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
 -                              msleep(40);
 +                              msleep(70);
                                rt5645->hp_on = true;
                        } else {
                                /* depop parameters */
@@@ -1667,9 -1646,13 +1667,13 @@@ static int rt5645_spk_event(struct snd_
                        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 |
@@@ -3143,15 -3126,6 +3147,15 @@@ static void rt5645_jack_detect_work(str
                                SND_JACK_BTN_2 | SND_JACK_BTN_3);
  }
  
 +static void rt5645_rcclock_work(struct work_struct *work)
 +{
 +      struct rt5645_priv *rt5645 =
 +              container_of(work, struct rt5645_priv, rcclock_work.work);
 +
 +      regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
 +              RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PD);
 +}
 +
  static irqreturn_t rt5645_irq(int irq, void *data)
  {
        struct rt5645_priv *rt5645 = data;
@@@ -3378,27 -3352,6 +3382,27 @@@ static const struct dmi_system_id dmi_p
                        DMI_MATCH(DMI_PRODUCT_NAME, "Reks"),
                },
        },
 +      {
 +              .ident = "Google Edgar",
 +              .callback = strago_quirk_cb,
 +              .matches = {
 +                      DMI_MATCH(DMI_PRODUCT_NAME, "Edgar"),
 +              },
 +      },
 +      {
 +              .ident = "Google Wizpig",
 +              .callback = strago_quirk_cb,
 +              .matches = {
 +                      DMI_MATCH(DMI_PRODUCT_NAME, "Wizpig"),
 +              },
 +      },
 +      {
 +              .ident = "Google Terra",
 +              .callback = strago_quirk_cb,
 +              .matches = {
 +                      DMI_MATCH(DMI_PRODUCT_NAME, "Terra"),
 +              },
 +      },
        { }
  };
  
@@@ -3638,7 -3591,6 +3642,7 @@@ static int rt5645_i2c_probe(struct i2c_
        }
  
        INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work);
 +      INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work);
  
        if (rt5645->i2c->irq) {
                ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq,
@@@ -3673,7 -3625,6 +3677,7 @@@ static int rt5645_i2c_remove(struct i2c
                free_irq(i2c->irq, rt5645);
  
        cancel_delayed_work_sync(&rt5645->jack_detect_work);
 +      cancel_delayed_work_sync(&rt5645->rcclock_work);
  
        snd_soc_unregister_codec(&i2c->dev);
        regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);