Merge remote-tracking branch 'asoc/topic/rt5665' into asoc-next
authorMark Brown <broonie@kernel.org>
Sun, 30 Apr 2017 13:15:43 +0000 (22:15 +0900)
committerMark Brown <broonie@kernel.org>
Sun, 30 Apr 2017 13:15:43 +0000 (22:15 +0900)
1  2 
include/sound/soc.h
sound/soc/codecs/rt5665.c
sound/soc/codecs/rt5665.h

diff --combined include/sound/soc.h
index 786765fc630bd440596afa38bed9e4dde1bd3e76,5bbb3a6767c344658962f14efe2f284877228beb..5170fd81e1fd0886c465225b72748c44792240d5
@@@ -434,6 -434,8 +434,8 @@@ int snd_soc_codec_set_sysclk(struct snd
                             int source, unsigned int freq, int dir);
  int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
                          unsigned int freq_in, unsigned int freq_out);
+ int snd_soc_codec_set_jack(struct snd_soc_codec *codec,
+                          struct snd_soc_jack *jack, void *data);
  
  int snd_soc_register_card(struct snd_soc_card *card);
  int snd_soc_unregister_card(struct snd_soc_card *card);
@@@ -497,15 -499,7 +499,15 @@@ void snd_soc_runtime_deactivate(struct 
  int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
        unsigned int dai_fmt);
  
 +#ifdef CONFIG_DMI
  int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour);
 +#else
 +static inline int snd_soc_set_dmi_name(struct snd_soc_card *card,
 +                                     const char *flavour)
 +{
 +      return 0;
 +}
 +#endif
  
  /* Utility functions to get clock rates from various things */
  int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
@@@ -729,6 -723,7 +731,7 @@@ struct snd_soc_jack_gpio 
        /* private: */
        struct snd_soc_jack *jack;
        struct delayed_work work;
+       struct notifier_block pm_notifier;
        struct gpio_desc *desc;
  
        void *data;
@@@ -820,6 -815,7 +823,6 @@@ struct snd_soc_component 
  
        unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
        unsigned int registered_as_component:1;
 -      unsigned int auxiliary:1; /* for auxiliary component of the card */
        unsigned int suspended:1; /* is in suspend PM state */
  
        struct list_head list;
@@@ -920,6 -916,8 +923,8 @@@ struct snd_soc_codec_driver 
                          int clk_id, int source, unsigned int freq, int dir);
        int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
                unsigned int freq_in, unsigned int freq_out);
+       int (*set_jack)(struct snd_soc_codec *codec,
+                       struct snd_soc_jack *jack,  void *data);
  
        /* codec IO */
        struct regmap *(*get_regmap)(struct device *);
index 476135ec57268cf6863e9792d5fb027c6383e190,4c5f08551e05b8734ea96710959217b5c869a7e9..8cd22307f5b6e6ab40e82399a19086977817b440
@@@ -1139,7 -1139,8 +1139,8 @@@ static void rt5665_enable_push_button_i
        bool enable)
  {
        if (enable) {
-               snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x000b);
+               snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x0003);
+               snd_soc_update_bits(codec, RT5665_SAR_IL_CMD_9, 0x1, 0x1);
                snd_soc_write(codec, RT5665_IL_CMD_1, 0x0048);
                snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2,
                                RT5665_4BTN_IL_MASK | RT5665_4BTN_IL_RST_MASK,
@@@ -1192,10 -1193,13 +1193,13 @@@ static int rt5665_headset_detect(struc
                }
  
                regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1,
-                       0x180, 0x180);
+                       0x1a0, 0x120);
                regmap_write(rt5665->regmap, RT5665_EJD_CTRL_3, 0x3424);
+               regmap_write(rt5665->regmap, RT5665_IL_CMD_1, 0x0048);
                regmap_write(rt5665->regmap, RT5665_SAR_IL_CMD_1, 0xa291);
  
+               usleep_range(10000, 15000);
                rt5665->sar_adc_value = snd_soc_read(rt5665->codec,
                        RT5665_SAR_IL_CMD_4) & 0x7ff;
  
@@@ -1256,8 -1260,8 +1260,8 @@@ static void rt5665_jd_check_handler(str
        }
  }
  
- int rt5665_set_jack_detect(struct snd_soc_codec *codec,
-       struct snd_soc_jack *hs_jack)
static int rt5665_set_jack_detect(struct snd_soc_codec *codec,
+       struct snd_soc_jack *hs_jack, void *data)
  {
        struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
  
  
        return 0;
  }
- EXPORT_SYMBOL_GPL(rt5665_set_jack_detect);
  
  static void rt5665_jack_detect_handler(struct work_struct *work)
  {
@@@ -2252,7 -2255,7 +2255,7 @@@ static const char * const rt5665_if2_1_
  
  static const SOC_ENUM_SINGLE_DECL(
        rt5665_if2_1_adc_in_enum, RT5665_DIG_INF2_DATA,
 -      RT5665_IF3_ADC_IN_SFT, rt5665_if2_1_adc_in_src);
 +      RT5665_IF2_1_ADC_IN_SFT, rt5665_if2_1_adc_in_src);
  
  static const struct snd_kcontrol_new rt5665_if2_1_adc_in_mux =
        SOC_DAPM_ENUM("IF2_1 ADC IN Source", rt5665_if2_1_adc_in_enum);
@@@ -2600,6 -2603,55 +2603,55 @@@ static int rt5655_set_verf(struct snd_s
        return 0;
  }
  
+ static int rt5665_i2s_pin_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);
+       unsigned int val1, val2, mask1, mask2 = 0;
+       switch (w->shift) {
+       case RT5665_PWR_I2S2_1_BIT:
+               mask1 = RT5665_GP2_PIN_MASK | RT5665_GP3_PIN_MASK |
+                       RT5665_GP4_PIN_MASK | RT5665_GP5_PIN_MASK;
+               val1 = RT5665_GP2_PIN_BCLK2 | RT5665_GP3_PIN_LRCK2 |
+                       RT5665_GP4_PIN_DACDAT2_1 | RT5665_GP5_PIN_ADCDAT2_1;
+               break;
+       case RT5665_PWR_I2S2_2_BIT:
+               mask1 = RT5665_GP2_PIN_MASK | RT5665_GP3_PIN_MASK |
+                       RT5665_GP8_PIN_MASK;
+               val1 = RT5665_GP2_PIN_BCLK2 | RT5665_GP3_PIN_LRCK2 |
+                       RT5665_GP8_PIN_DACDAT2_2;
+               mask2 = RT5665_GP9_PIN_MASK;
+               val2 = RT5665_GP9_PIN_ADCDAT2_2;
+               break;
+       case RT5665_PWR_I2S3_BIT:
+               mask1 = RT5665_GP6_PIN_MASK | RT5665_GP7_PIN_MASK |
+                       RT5665_GP8_PIN_MASK;
+               val1 = RT5665_GP6_PIN_BCLK3 | RT5665_GP7_PIN_LRCK3 |
+                       RT5665_GP8_PIN_DACDAT3;
+               mask2 = RT5665_GP9_PIN_MASK;
+               val2 = RT5665_GP9_PIN_ADCDAT3;
+               break;
+       }
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1, mask1, val1);
+               if (mask2)
+                       snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
+                                           mask2, val2);
+               break;
+       case SND_SOC_DAPM_POST_PMD:
+               snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1, mask1, 0);
+               if (mask2)
+                       snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
+                                           mask2, 0);
+               break;
+       default:
+               return 0;
+       }
+       return 0;
+ }
  
  static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("LDO2", RT5665_PWR_ANLG_3, RT5665_PWR_LDO2_BIT, 0,
        SND_SOC_DAPM_SUPPLY("I2S1_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S1_2_BIT,
                0, NULL, 0),
        SND_SOC_DAPM_SUPPLY("I2S2_1", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_1_BIT,
-               0, NULL, 0),
+               0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU |
+               SND_SOC_DAPM_POST_PMD),
        SND_SOC_DAPM_SUPPLY("I2S2_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_2_BIT,
-               0, NULL, 0),
+               0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU |
+               SND_SOC_DAPM_POST_PMD),
        SND_SOC_DAPM_SUPPLY("I2S3", RT5665_PWR_DIG_1, RT5665_PWR_I2S3_BIT,
-               0, NULL, 0),
+               0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU |
+               SND_SOC_DAPM_POST_PMD),
        SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
        SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
        SND_SOC_DAPM_PGA("IF1 DAC3", SND_SOC_NOPM, 0, 0, NULL, 0),
@@@ -3963,12 -4018,68 +4018,68 @@@ static const struct snd_soc_dapm_route 
        {"PDMR", NULL, "PDM R Playback"},
  };
  
+ static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+                       unsigned int rx_mask, int slots, int slot_width)
+ {
+       struct snd_soc_codec *codec = dai->codec;
+       unsigned int val = 0;
+       if (rx_mask || tx_mask)
+               val |= RT5665_I2S1_MODE_TDM;
+       switch (slots) {
+       case 4:
+               val |= RT5665_TDM_IN_CH_4;
+               val |= RT5665_TDM_OUT_CH_4;
+               break;
+       case 6:
+               val |= RT5665_TDM_IN_CH_6;
+               val |= RT5665_TDM_OUT_CH_6;
+               break;
+       case 8:
+               val |= RT5665_TDM_IN_CH_8;
+               val |= RT5665_TDM_OUT_CH_8;
+               break;
+       case 2:
+               break;
+       default:
+               return -EINVAL;
+       }
+       switch (slot_width) {
+       case 20:
+               val |= RT5665_TDM_IN_LEN_20;
+               val |= RT5665_TDM_OUT_LEN_20;
+               break;
+       case 24:
+               val |= RT5665_TDM_IN_LEN_24;
+               val |= RT5665_TDM_OUT_LEN_24;
+               break;
+       case 32:
+               val |= RT5665_TDM_IN_LEN_32;
+               val |= RT5665_TDM_OUT_LEN_32;
+               break;
+       case 16:
+               break;
+       default:
+               return -EINVAL;
+       }
+       snd_soc_update_bits(codec, RT5665_TDM_CTRL_1,
+               RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK |
+               RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK |
+               RT5665_TDM_OUT_LEN_MASK, val);
+       return 0;
+ }
  static int rt5665_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
  {
        struct snd_soc_codec *codec = dai->codec;
        struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
-       unsigned int val_len = 0, val_clk, mask_clk, val_bits = 0x0100;
+       unsigned int val_len = 0, val_clk, reg_clk, mask_clk, val_bits = 0x0100;
        int pre_div, frame_size;
  
        rt5665->lrck[dai->id] = params_rate(params);
        switch (dai->id) {
        case RT5665_AIF1_1:
        case RT5665_AIF1_2:
+               if (params_channels(params) > 2)
+                       rt5665_set_tdm_slot(dai, 0xf, 0xf,
+                               params_channels(params), params_width(params));
+               reg_clk = RT5665_ADDA_CLK_1;
                mask_clk = RT5665_I2S_PD1_MASK;
                val_clk = pre_div << RT5665_I2S_PD1_SFT;
                snd_soc_update_bits(codec, RT5665_I2S1_SDP,
                break;
        case RT5665_AIF2_1:
        case RT5665_AIF2_2:
+               reg_clk = RT5665_ADDA_CLK_2;
                mask_clk = RT5665_I2S_PD2_MASK;
                val_clk = pre_div << RT5665_I2S_PD2_SFT;
                snd_soc_update_bits(codec, RT5665_I2S2_SDP,
                        RT5665_I2S_DL_MASK, val_len);
                break;
        case RT5665_AIF3:
+               reg_clk = RT5665_ADDA_CLK_2;
                mask_clk = RT5665_I2S_PD3_MASK;
                val_clk = pre_div << RT5665_I2S_PD3_SFT;
                snd_soc_update_bits(codec, RT5665_I2S3_SDP,
                return -EINVAL;
        }
  
-       snd_soc_update_bits(codec, RT5665_ADDA_CLK_1, mask_clk, val_clk);
+       snd_soc_update_bits(codec, reg_clk, mask_clk, val_clk);
        snd_soc_update_bits(codec, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits);
  
        switch (rt5665->lrck[dai->id]) {
@@@ -4125,10 -4242,9 +4242,9 @@@ static int rt5665_set_dai_fmt(struct sn
        return 0;
  }
  
- static int rt5665_set_dai_sysclk(struct snd_soc_dai *dai,
-               int clk_id, unsigned int freq, int dir)
+ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
+                                  int source, unsigned int freq, int dir)
  {
-       struct snd_soc_codec *codec = dai->codec;
        struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
        unsigned int reg_val = 0;
  
        rt5665->sysclk = freq;
        rt5665->sysclk_src = clk_id;
  
-       dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
+       dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
  
        return 0;
  }
  
- static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
-                       unsigned int freq_in, unsigned int freq_out)
+ static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
+                               int source, unsigned int freq_in,
+                               unsigned int freq_out)
  {
-       struct snd_soc_codec *codec = dai->codec;
        struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
        struct rl6231_pll_code pll_code;
        int ret;
  
-       if (Source == rt5665->pll_src && freq_in == rt5665->pll_in &&
+       if (source == rt5665->pll_src && freq_in == rt5665->pll_in &&
            freq_out == rt5665->pll_out)
                return 0;
  
                return 0;
        }
  
-       switch (Source) {
+       switch (source) {
        case RT5665_PLL1_S_MCLK:
                snd_soc_update_bits(codec, RT5665_GLB_CLK,
                        RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_MCLK);
                                RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK3);
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL Source %d\n", Source);
+               dev_err(codec->dev, "Unknown PLL Source %d\n", source);
                return -EINVAL;
        }
  
  
        rt5665->pll_in = freq_in;
        rt5665->pll_out = freq_out;
-       rt5665->pll_src = Source;
-       return 0;
- }
- static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
-                       unsigned int rx_mask, int slots, int slot_width)
- {
-       struct snd_soc_codec *codec = dai->codec;
-       unsigned int val = 0;
-       if (rx_mask || tx_mask)
-               val |= RT5665_I2S1_MODE_TDM;
-       switch (slots) {
-       case 4:
-               val |= RT5665_TDM_IN_CH_4;
-               val |= RT5665_TDM_OUT_CH_4;
-               break;
-       case 6:
-               val |= RT5665_TDM_IN_CH_6;
-               val |= RT5665_TDM_OUT_CH_6;
-               break;
-       case 8:
-               val |= RT5665_TDM_IN_CH_8;
-               val |= RT5665_TDM_OUT_CH_8;
-               break;
-       case 2:
-               break;
-       default:
-               return -EINVAL;
-       }
-       switch (slot_width) {
-       case 20:
-               val |= RT5665_TDM_IN_LEN_20;
-               val |= RT5665_TDM_OUT_LEN_20;
-               break;
-       case 24:
-               val |= RT5665_TDM_IN_LEN_24;
-               val |= RT5665_TDM_OUT_LEN_24;
-               break;
-       case 32:
-               val |= RT5665_TDM_IN_LEN_32;
-               val |= RT5665_TDM_OUT_LEN_32;
-               break;
-       case 16:
-               break;
-       default:
-               return -EINVAL;
-       }
-       snd_soc_update_bits(codec, RT5665_TDM_CTRL_1,
-               RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK |
-               RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK |
-               RT5665_TDM_OUT_LEN_MASK, val);
+       rt5665->pll_src = source;
  
        return 0;
  }
@@@ -4393,9 -4454,7 +4454,7 @@@ static int rt5665_resume(struct snd_soc
  static const struct snd_soc_dai_ops rt5665_aif_dai_ops = {
        .hw_params = rt5665_hw_params,
        .set_fmt = rt5665_set_dai_fmt,
-       .set_sysclk = rt5665_set_dai_sysclk,
        .set_tdm_slot = rt5665_set_tdm_slot,
-       .set_pll = rt5665_set_dai_pll,
        .set_bclk_ratio = rt5665_set_bclk_ratio,
  };
  
@@@ -4504,7 -4563,10 +4563,10 @@@ static struct snd_soc_codec_driver soc_
                .num_dapm_widgets = ARRAY_SIZE(rt5665_dapm_widgets),
                .dapm_routes = rt5665_dapm_routes,
                .num_dapm_routes = ARRAY_SIZE(rt5665_dapm_routes),
-       }
+       },
+       .set_sysclk = rt5665_set_codec_sysclk,
+       .set_pll = rt5665_set_codec_pll,
+       .set_jack = rt5665_set_jack_detect,
  };
  
  
@@@ -4783,7 -4845,7 +4845,7 @@@ static int rt5665_i2c_probe(struct i2c_
  
        regmap_write(rt5665->regmap, RT5665_HP_LOGIC_CTRL_2, 0x0002);
        regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1,
-               0xf000 | RT5665_VREF_POW_MASK, 0xd000 | RT5665_VREF_POW_REG);
+               0xf000 | RT5665_VREF_POW_MASK, 0xe000 | RT5665_VREF_POW_REG);
        /* Work around for pow_pump */
        regmap_update_bits(rt5665->regmap, RT5665_STO1_DAC_SIL_DET,
                RT5665_DEB_STO_DAC_MASK, RT5665_DEB_80_MS);
index a30f5e6d062882724230e2bf2f2d1157ee823a9b,d153bba90963a54dfdb6d9aedf100868382b2893..1db5c6a62a8e0c872e24fc6474031cbdfb72ab80
  #define RT5665_HP_DRIVER_MASK                 (0x3 << 2)
  #define RT5665_HP_DRIVER_1X                   (0x0 << 2)
  #define RT5665_HP_DRIVER_3X                   (0x1 << 2)
 -#define RT5665_HP_DRIVER_5X                   (0x2 << 2)
 +#define RT5665_HP_DRIVER_5X                   (0x3 << 2)
  #define RT5665_LDO1_DVO_MASK                  (0x3)
  #define RT5665_LDO1_DVO_09                    (0x0)
  #define RT5665_LDO1_DVO_10                    (0x1)
@@@ -1984,7 -1984,5 +1984,5 @@@ enum 
  
  int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec,
                unsigned int filter_mask, unsigned int clk_src);
- int rt5665_set_jack_detect(struct snd_soc_codec *codec,
-       struct snd_soc_jack *hs_jack);
  
  #endif /* __RT5665_H__ */