diff options
author | Mark Brown <broonie@kernel.org> | 2017-04-30 09:15:43 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-04-30 09:15:43 -0400 |
commit | cce9b271e5e05ba43ce9332652ef309b9e44c87a (patch) | |
tree | 6df46e772a83aafd8f84638ee1be0eb4011c4d46 | |
parent | 245e302a4d17d70f223882f6fbd2c4cb35059ca9 (diff) | |
parent | 97c415a6f6c34b8c3a71b0e6058c89c49bb8285f (diff) |
Merge remote-tracking branch 'asoc/topic/rt5665' into asoc-next
-rw-r--r-- | include/sound/soc.h | 5 | ||||
-rw-r--r-- | sound/soc/codecs/rt5665.c | 222 | ||||
-rw-r--r-- | sound/soc/codecs/rt5665.h | 2 | ||||
-rw-r--r-- | sound/soc/soc-jack.c | 48 |
4 files changed, 195 insertions, 82 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index 786765fc630b..5170fd81e1fd 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -434,6 +434,8 @@ int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
434 | int source, unsigned int freq, int dir); | 434 | int source, unsigned int freq, int dir); |
435 | int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, | 435 | int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, |
436 | unsigned int freq_in, unsigned int freq_out); | 436 | unsigned int freq_in, unsigned int freq_out); |
437 | int snd_soc_codec_set_jack(struct snd_soc_codec *codec, | ||
438 | struct snd_soc_jack *jack, void *data); | ||
437 | 439 | ||
438 | int snd_soc_register_card(struct snd_soc_card *card); | 440 | int snd_soc_register_card(struct snd_soc_card *card); |
439 | int snd_soc_unregister_card(struct snd_soc_card *card); | 441 | int snd_soc_unregister_card(struct snd_soc_card *card); |
@@ -729,6 +731,7 @@ struct snd_soc_jack_gpio { | |||
729 | /* private: */ | 731 | /* private: */ |
730 | struct snd_soc_jack *jack; | 732 | struct snd_soc_jack *jack; |
731 | struct delayed_work work; | 733 | struct delayed_work work; |
734 | struct notifier_block pm_notifier; | ||
732 | struct gpio_desc *desc; | 735 | struct gpio_desc *desc; |
733 | 736 | ||
734 | void *data; | 737 | void *data; |
@@ -920,6 +923,8 @@ struct snd_soc_codec_driver { | |||
920 | int clk_id, int source, unsigned int freq, int dir); | 923 | int clk_id, int source, unsigned int freq, int dir); |
921 | int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source, | 924 | int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source, |
922 | unsigned int freq_in, unsigned int freq_out); | 925 | unsigned int freq_in, unsigned int freq_out); |
926 | int (*set_jack)(struct snd_soc_codec *codec, | ||
927 | struct snd_soc_jack *jack, void *data); | ||
923 | 928 | ||
924 | /* codec IO */ | 929 | /* codec IO */ |
925 | struct regmap *(*get_regmap)(struct device *); | 930 | struct regmap *(*get_regmap)(struct device *); |
diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 476135ec5726..8cd22307f5b6 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c | |||
@@ -1139,7 +1139,8 @@ static void rt5665_enable_push_button_irq(struct snd_soc_codec *codec, | |||
1139 | bool enable) | 1139 | bool enable) |
1140 | { | 1140 | { |
1141 | if (enable) { | 1141 | if (enable) { |
1142 | snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x000b); | 1142 | snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x0003); |
1143 | snd_soc_update_bits(codec, RT5665_SAR_IL_CMD_9, 0x1, 0x1); | ||
1143 | snd_soc_write(codec, RT5665_IL_CMD_1, 0x0048); | 1144 | snd_soc_write(codec, RT5665_IL_CMD_1, 0x0048); |
1144 | snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2, | 1145 | snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2, |
1145 | RT5665_4BTN_IL_MASK | RT5665_4BTN_IL_RST_MASK, | 1146 | RT5665_4BTN_IL_MASK | RT5665_4BTN_IL_RST_MASK, |
@@ -1192,10 +1193,13 @@ static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert) | |||
1192 | } | 1193 | } |
1193 | 1194 | ||
1194 | regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1, | 1195 | regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1, |
1195 | 0x180, 0x180); | 1196 | 0x1a0, 0x120); |
1196 | regmap_write(rt5665->regmap, RT5665_EJD_CTRL_3, 0x3424); | 1197 | regmap_write(rt5665->regmap, RT5665_EJD_CTRL_3, 0x3424); |
1198 | regmap_write(rt5665->regmap, RT5665_IL_CMD_1, 0x0048); | ||
1197 | regmap_write(rt5665->regmap, RT5665_SAR_IL_CMD_1, 0xa291); | 1199 | regmap_write(rt5665->regmap, RT5665_SAR_IL_CMD_1, 0xa291); |
1198 | 1200 | ||
1201 | usleep_range(10000, 15000); | ||
1202 | |||
1199 | rt5665->sar_adc_value = snd_soc_read(rt5665->codec, | 1203 | rt5665->sar_adc_value = snd_soc_read(rt5665->codec, |
1200 | RT5665_SAR_IL_CMD_4) & 0x7ff; | 1204 | RT5665_SAR_IL_CMD_4) & 0x7ff; |
1201 | 1205 | ||
@@ -1256,8 +1260,8 @@ static void rt5665_jd_check_handler(struct work_struct *work) | |||
1256 | } | 1260 | } |
1257 | } | 1261 | } |
1258 | 1262 | ||
1259 | int rt5665_set_jack_detect(struct snd_soc_codec *codec, | 1263 | static int rt5665_set_jack_detect(struct snd_soc_codec *codec, |
1260 | struct snd_soc_jack *hs_jack) | 1264 | struct snd_soc_jack *hs_jack, void *data) |
1261 | { | 1265 | { |
1262 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); | 1266 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); |
1263 | 1267 | ||
@@ -1284,7 +1288,6 @@ int rt5665_set_jack_detect(struct snd_soc_codec *codec, | |||
1284 | 1288 | ||
1285 | return 0; | 1289 | return 0; |
1286 | } | 1290 | } |
1287 | EXPORT_SYMBOL_GPL(rt5665_set_jack_detect); | ||
1288 | 1291 | ||
1289 | static void rt5665_jack_detect_handler(struct work_struct *work) | 1292 | static void rt5665_jack_detect_handler(struct work_struct *work) |
1290 | { | 1293 | { |
@@ -2600,6 +2603,55 @@ static int rt5655_set_verf(struct snd_soc_dapm_widget *w, | |||
2600 | return 0; | 2603 | return 0; |
2601 | } | 2604 | } |
2602 | 2605 | ||
2606 | static int rt5665_i2s_pin_event(struct snd_soc_dapm_widget *w, | ||
2607 | struct snd_kcontrol *kcontrol, int event) | ||
2608 | { | ||
2609 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
2610 | unsigned int val1, val2, mask1, mask2 = 0; | ||
2611 | |||
2612 | switch (w->shift) { | ||
2613 | case RT5665_PWR_I2S2_1_BIT: | ||
2614 | mask1 = RT5665_GP2_PIN_MASK | RT5665_GP3_PIN_MASK | | ||
2615 | RT5665_GP4_PIN_MASK | RT5665_GP5_PIN_MASK; | ||
2616 | val1 = RT5665_GP2_PIN_BCLK2 | RT5665_GP3_PIN_LRCK2 | | ||
2617 | RT5665_GP4_PIN_DACDAT2_1 | RT5665_GP5_PIN_ADCDAT2_1; | ||
2618 | break; | ||
2619 | case RT5665_PWR_I2S2_2_BIT: | ||
2620 | mask1 = RT5665_GP2_PIN_MASK | RT5665_GP3_PIN_MASK | | ||
2621 | RT5665_GP8_PIN_MASK; | ||
2622 | val1 = RT5665_GP2_PIN_BCLK2 | RT5665_GP3_PIN_LRCK2 | | ||
2623 | RT5665_GP8_PIN_DACDAT2_2; | ||
2624 | mask2 = RT5665_GP9_PIN_MASK; | ||
2625 | val2 = RT5665_GP9_PIN_ADCDAT2_2; | ||
2626 | break; | ||
2627 | case RT5665_PWR_I2S3_BIT: | ||
2628 | mask1 = RT5665_GP6_PIN_MASK | RT5665_GP7_PIN_MASK | | ||
2629 | RT5665_GP8_PIN_MASK; | ||
2630 | val1 = RT5665_GP6_PIN_BCLK3 | RT5665_GP7_PIN_LRCK3 | | ||
2631 | RT5665_GP8_PIN_DACDAT3; | ||
2632 | mask2 = RT5665_GP9_PIN_MASK; | ||
2633 | val2 = RT5665_GP9_PIN_ADCDAT3; | ||
2634 | break; | ||
2635 | } | ||
2636 | switch (event) { | ||
2637 | case SND_SOC_DAPM_PRE_PMU: | ||
2638 | snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1, mask1, val1); | ||
2639 | if (mask2) | ||
2640 | snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2, | ||
2641 | mask2, val2); | ||
2642 | break; | ||
2643 | case SND_SOC_DAPM_POST_PMD: | ||
2644 | snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1, mask1, 0); | ||
2645 | if (mask2) | ||
2646 | snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2, | ||
2647 | mask2, 0); | ||
2648 | break; | ||
2649 | default: | ||
2650 | return 0; | ||
2651 | } | ||
2652 | |||
2653 | return 0; | ||
2654 | } | ||
2603 | 2655 | ||
2604 | static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = { | 2656 | static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = { |
2605 | SND_SOC_DAPM_SUPPLY("LDO2", RT5665_PWR_ANLG_3, RT5665_PWR_LDO2_BIT, 0, | 2657 | SND_SOC_DAPM_SUPPLY("LDO2", RT5665_PWR_ANLG_3, RT5665_PWR_LDO2_BIT, 0, |
@@ -2852,11 +2904,14 @@ static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = { | |||
2852 | SND_SOC_DAPM_SUPPLY("I2S1_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S1_2_BIT, | 2904 | SND_SOC_DAPM_SUPPLY("I2S1_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S1_2_BIT, |
2853 | 0, NULL, 0), | 2905 | 0, NULL, 0), |
2854 | SND_SOC_DAPM_SUPPLY("I2S2_1", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_1_BIT, | 2906 | SND_SOC_DAPM_SUPPLY("I2S2_1", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_1_BIT, |
2855 | 0, NULL, 0), | 2907 | 0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU | |
2908 | SND_SOC_DAPM_POST_PMD), | ||
2856 | SND_SOC_DAPM_SUPPLY("I2S2_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_2_BIT, | 2909 | SND_SOC_DAPM_SUPPLY("I2S2_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_2_BIT, |
2857 | 0, NULL, 0), | 2910 | 0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU | |
2911 | SND_SOC_DAPM_POST_PMD), | ||
2858 | SND_SOC_DAPM_SUPPLY("I2S3", RT5665_PWR_DIG_1, RT5665_PWR_I2S3_BIT, | 2912 | SND_SOC_DAPM_SUPPLY("I2S3", RT5665_PWR_DIG_1, RT5665_PWR_I2S3_BIT, |
2859 | 0, NULL, 0), | 2913 | 0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU | |
2914 | SND_SOC_DAPM_POST_PMD), | ||
2860 | SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0), | 2915 | SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0), |
2861 | SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0), | 2916 | SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0), |
2862 | SND_SOC_DAPM_PGA("IF1 DAC3", SND_SOC_NOPM, 0, 0, NULL, 0), | 2917 | SND_SOC_DAPM_PGA("IF1 DAC3", SND_SOC_NOPM, 0, 0, NULL, 0), |
@@ -3963,12 +4018,68 @@ static const struct snd_soc_dapm_route rt5665_dapm_routes[] = { | |||
3963 | {"PDMR", NULL, "PDM R Playback"}, | 4018 | {"PDMR", NULL, "PDM R Playback"}, |
3964 | }; | 4019 | }; |
3965 | 4020 | ||
4021 | static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | ||
4022 | unsigned int rx_mask, int slots, int slot_width) | ||
4023 | { | ||
4024 | struct snd_soc_codec *codec = dai->codec; | ||
4025 | unsigned int val = 0; | ||
4026 | |||
4027 | if (rx_mask || tx_mask) | ||
4028 | val |= RT5665_I2S1_MODE_TDM; | ||
4029 | |||
4030 | switch (slots) { | ||
4031 | case 4: | ||
4032 | val |= RT5665_TDM_IN_CH_4; | ||
4033 | val |= RT5665_TDM_OUT_CH_4; | ||
4034 | break; | ||
4035 | case 6: | ||
4036 | val |= RT5665_TDM_IN_CH_6; | ||
4037 | val |= RT5665_TDM_OUT_CH_6; | ||
4038 | break; | ||
4039 | case 8: | ||
4040 | val |= RT5665_TDM_IN_CH_8; | ||
4041 | val |= RT5665_TDM_OUT_CH_8; | ||
4042 | break; | ||
4043 | case 2: | ||
4044 | break; | ||
4045 | default: | ||
4046 | return -EINVAL; | ||
4047 | } | ||
4048 | |||
4049 | switch (slot_width) { | ||
4050 | case 20: | ||
4051 | val |= RT5665_TDM_IN_LEN_20; | ||
4052 | val |= RT5665_TDM_OUT_LEN_20; | ||
4053 | break; | ||
4054 | case 24: | ||
4055 | val |= RT5665_TDM_IN_LEN_24; | ||
4056 | val |= RT5665_TDM_OUT_LEN_24; | ||
4057 | break; | ||
4058 | case 32: | ||
4059 | val |= RT5665_TDM_IN_LEN_32; | ||
4060 | val |= RT5665_TDM_OUT_LEN_32; | ||
4061 | break; | ||
4062 | case 16: | ||
4063 | break; | ||
4064 | default: | ||
4065 | return -EINVAL; | ||
4066 | } | ||
4067 | |||
4068 | snd_soc_update_bits(codec, RT5665_TDM_CTRL_1, | ||
4069 | RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK | | ||
4070 | RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK | | ||
4071 | RT5665_TDM_OUT_LEN_MASK, val); | ||
4072 | |||
4073 | return 0; | ||
4074 | } | ||
4075 | |||
4076 | |||
3966 | static int rt5665_hw_params(struct snd_pcm_substream *substream, | 4077 | static int rt5665_hw_params(struct snd_pcm_substream *substream, |
3967 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 4078 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
3968 | { | 4079 | { |
3969 | struct snd_soc_codec *codec = dai->codec; | 4080 | struct snd_soc_codec *codec = dai->codec; |
3970 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); | 4081 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); |
3971 | unsigned int val_len = 0, val_clk, mask_clk, val_bits = 0x0100; | 4082 | unsigned int val_len = 0, val_clk, reg_clk, mask_clk, val_bits = 0x0100; |
3972 | int pre_div, frame_size; | 4083 | int pre_div, frame_size; |
3973 | 4084 | ||
3974 | rt5665->lrck[dai->id] = params_rate(params); | 4085 | rt5665->lrck[dai->id] = params_rate(params); |
@@ -4009,6 +4120,10 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, | |||
4009 | switch (dai->id) { | 4120 | switch (dai->id) { |
4010 | case RT5665_AIF1_1: | 4121 | case RT5665_AIF1_1: |
4011 | case RT5665_AIF1_2: | 4122 | case RT5665_AIF1_2: |
4123 | if (params_channels(params) > 2) | ||
4124 | rt5665_set_tdm_slot(dai, 0xf, 0xf, | ||
4125 | params_channels(params), params_width(params)); | ||
4126 | reg_clk = RT5665_ADDA_CLK_1; | ||
4012 | mask_clk = RT5665_I2S_PD1_MASK; | 4127 | mask_clk = RT5665_I2S_PD1_MASK; |
4013 | val_clk = pre_div << RT5665_I2S_PD1_SFT; | 4128 | val_clk = pre_div << RT5665_I2S_PD1_SFT; |
4014 | snd_soc_update_bits(codec, RT5665_I2S1_SDP, | 4129 | snd_soc_update_bits(codec, RT5665_I2S1_SDP, |
@@ -4016,12 +4131,14 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, | |||
4016 | break; | 4131 | break; |
4017 | case RT5665_AIF2_1: | 4132 | case RT5665_AIF2_1: |
4018 | case RT5665_AIF2_2: | 4133 | case RT5665_AIF2_2: |
4134 | reg_clk = RT5665_ADDA_CLK_2; | ||
4019 | mask_clk = RT5665_I2S_PD2_MASK; | 4135 | mask_clk = RT5665_I2S_PD2_MASK; |
4020 | val_clk = pre_div << RT5665_I2S_PD2_SFT; | 4136 | val_clk = pre_div << RT5665_I2S_PD2_SFT; |
4021 | snd_soc_update_bits(codec, RT5665_I2S2_SDP, | 4137 | snd_soc_update_bits(codec, RT5665_I2S2_SDP, |
4022 | RT5665_I2S_DL_MASK, val_len); | 4138 | RT5665_I2S_DL_MASK, val_len); |
4023 | break; | 4139 | break; |
4024 | case RT5665_AIF3: | 4140 | case RT5665_AIF3: |
4141 | reg_clk = RT5665_ADDA_CLK_2; | ||
4025 | mask_clk = RT5665_I2S_PD3_MASK; | 4142 | mask_clk = RT5665_I2S_PD3_MASK; |
4026 | val_clk = pre_div << RT5665_I2S_PD3_SFT; | 4143 | val_clk = pre_div << RT5665_I2S_PD3_SFT; |
4027 | snd_soc_update_bits(codec, RT5665_I2S3_SDP, | 4144 | snd_soc_update_bits(codec, RT5665_I2S3_SDP, |
@@ -4032,7 +4149,7 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, | |||
4032 | return -EINVAL; | 4149 | return -EINVAL; |
4033 | } | 4150 | } |
4034 | 4151 | ||
4035 | snd_soc_update_bits(codec, RT5665_ADDA_CLK_1, mask_clk, val_clk); | 4152 | snd_soc_update_bits(codec, reg_clk, mask_clk, val_clk); |
4036 | snd_soc_update_bits(codec, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits); | 4153 | snd_soc_update_bits(codec, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits); |
4037 | 4154 | ||
4038 | switch (rt5665->lrck[dai->id]) { | 4155 | switch (rt5665->lrck[dai->id]) { |
@@ -4125,10 +4242,9 @@ static int rt5665_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
4125 | return 0; | 4242 | return 0; |
4126 | } | 4243 | } |
4127 | 4244 | ||
4128 | static int rt5665_set_dai_sysclk(struct snd_soc_dai *dai, | 4245 | static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, |
4129 | int clk_id, unsigned int freq, int dir) | 4246 | int source, unsigned int freq, int dir) |
4130 | { | 4247 | { |
4131 | struct snd_soc_codec *codec = dai->codec; | ||
4132 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); | 4248 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); |
4133 | unsigned int reg_val = 0; | 4249 | unsigned int reg_val = 0; |
4134 | 4250 | ||
@@ -4154,20 +4270,20 @@ static int rt5665_set_dai_sysclk(struct snd_soc_dai *dai, | |||
4154 | rt5665->sysclk = freq; | 4270 | rt5665->sysclk = freq; |
4155 | rt5665->sysclk_src = clk_id; | 4271 | rt5665->sysclk_src = clk_id; |
4156 | 4272 | ||
4157 | dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); | 4273 | dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); |
4158 | 4274 | ||
4159 | return 0; | 4275 | return 0; |
4160 | } | 4276 | } |
4161 | 4277 | ||
4162 | static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source, | 4278 | static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id, |
4163 | unsigned int freq_in, unsigned int freq_out) | 4279 | int source, unsigned int freq_in, |
4280 | unsigned int freq_out) | ||
4164 | { | 4281 | { |
4165 | struct snd_soc_codec *codec = dai->codec; | ||
4166 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); | 4282 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); |
4167 | struct rl6231_pll_code pll_code; | 4283 | struct rl6231_pll_code pll_code; |
4168 | int ret; | 4284 | int ret; |
4169 | 4285 | ||
4170 | if (Source == rt5665->pll_src && freq_in == rt5665->pll_in && | 4286 | if (source == rt5665->pll_src && freq_in == rt5665->pll_in && |
4171 | freq_out == rt5665->pll_out) | 4287 | freq_out == rt5665->pll_out) |
4172 | return 0; | 4288 | return 0; |
4173 | 4289 | ||
@@ -4181,7 +4297,7 @@ static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source, | |||
4181 | return 0; | 4297 | return 0; |
4182 | } | 4298 | } |
4183 | 4299 | ||
4184 | switch (Source) { | 4300 | switch (source) { |
4185 | case RT5665_PLL1_S_MCLK: | 4301 | case RT5665_PLL1_S_MCLK: |
4186 | snd_soc_update_bits(codec, RT5665_GLB_CLK, | 4302 | snd_soc_update_bits(codec, RT5665_GLB_CLK, |
4187 | RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_MCLK); | 4303 | RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_MCLK); |
@@ -4199,7 +4315,7 @@ static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source, | |||
4199 | RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK3); | 4315 | RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK3); |
4200 | break; | 4316 | break; |
4201 | default: | 4317 | default: |
4202 | dev_err(codec->dev, "Unknown PLL Source %d\n", Source); | 4318 | dev_err(codec->dev, "Unknown PLL Source %d\n", source); |
4203 | return -EINVAL; | 4319 | return -EINVAL; |
4204 | } | 4320 | } |
4205 | 4321 | ||
@@ -4221,62 +4337,7 @@ static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source, | |||
4221 | 4337 | ||
4222 | rt5665->pll_in = freq_in; | 4338 | rt5665->pll_in = freq_in; |
4223 | rt5665->pll_out = freq_out; | 4339 | rt5665->pll_out = freq_out; |
4224 | rt5665->pll_src = Source; | 4340 | rt5665->pll_src = source; |
4225 | |||
4226 | return 0; | ||
4227 | } | ||
4228 | |||
4229 | static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | ||
4230 | unsigned int rx_mask, int slots, int slot_width) | ||
4231 | { | ||
4232 | struct snd_soc_codec *codec = dai->codec; | ||
4233 | unsigned int val = 0; | ||
4234 | |||
4235 | if (rx_mask || tx_mask) | ||
4236 | val |= RT5665_I2S1_MODE_TDM; | ||
4237 | |||
4238 | switch (slots) { | ||
4239 | case 4: | ||
4240 | val |= RT5665_TDM_IN_CH_4; | ||
4241 | val |= RT5665_TDM_OUT_CH_4; | ||
4242 | break; | ||
4243 | case 6: | ||
4244 | val |= RT5665_TDM_IN_CH_6; | ||
4245 | val |= RT5665_TDM_OUT_CH_6; | ||
4246 | break; | ||
4247 | case 8: | ||
4248 | val |= RT5665_TDM_IN_CH_8; | ||
4249 | val |= RT5665_TDM_OUT_CH_8; | ||
4250 | break; | ||
4251 | case 2: | ||
4252 | break; | ||
4253 | default: | ||
4254 | return -EINVAL; | ||
4255 | } | ||
4256 | |||
4257 | switch (slot_width) { | ||
4258 | case 20: | ||
4259 | val |= RT5665_TDM_IN_LEN_20; | ||
4260 | val |= RT5665_TDM_OUT_LEN_20; | ||
4261 | break; | ||
4262 | case 24: | ||
4263 | val |= RT5665_TDM_IN_LEN_24; | ||
4264 | val |= RT5665_TDM_OUT_LEN_24; | ||
4265 | break; | ||
4266 | case 32: | ||
4267 | val |= RT5665_TDM_IN_LEN_32; | ||
4268 | val |= RT5665_TDM_OUT_LEN_32; | ||
4269 | break; | ||
4270 | case 16: | ||
4271 | break; | ||
4272 | default: | ||
4273 | return -EINVAL; | ||
4274 | } | ||
4275 | |||
4276 | snd_soc_update_bits(codec, RT5665_TDM_CTRL_1, | ||
4277 | RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK | | ||
4278 | RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK | | ||
4279 | RT5665_TDM_OUT_LEN_MASK, val); | ||
4280 | 4341 | ||
4281 | return 0; | 4342 | return 0; |
4282 | } | 4343 | } |
@@ -4393,9 +4454,7 @@ static int rt5665_resume(struct snd_soc_codec *codec) | |||
4393 | static const struct snd_soc_dai_ops rt5665_aif_dai_ops = { | 4454 | static const struct snd_soc_dai_ops rt5665_aif_dai_ops = { |
4394 | .hw_params = rt5665_hw_params, | 4455 | .hw_params = rt5665_hw_params, |
4395 | .set_fmt = rt5665_set_dai_fmt, | 4456 | .set_fmt = rt5665_set_dai_fmt, |
4396 | .set_sysclk = rt5665_set_dai_sysclk, | ||
4397 | .set_tdm_slot = rt5665_set_tdm_slot, | 4457 | .set_tdm_slot = rt5665_set_tdm_slot, |
4398 | .set_pll = rt5665_set_dai_pll, | ||
4399 | .set_bclk_ratio = rt5665_set_bclk_ratio, | 4458 | .set_bclk_ratio = rt5665_set_bclk_ratio, |
4400 | }; | 4459 | }; |
4401 | 4460 | ||
@@ -4504,7 +4563,10 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5665 = { | |||
4504 | .num_dapm_widgets = ARRAY_SIZE(rt5665_dapm_widgets), | 4563 | .num_dapm_widgets = ARRAY_SIZE(rt5665_dapm_widgets), |
4505 | .dapm_routes = rt5665_dapm_routes, | 4564 | .dapm_routes = rt5665_dapm_routes, |
4506 | .num_dapm_routes = ARRAY_SIZE(rt5665_dapm_routes), | 4565 | .num_dapm_routes = ARRAY_SIZE(rt5665_dapm_routes), |
4507 | } | 4566 | }, |
4567 | .set_sysclk = rt5665_set_codec_sysclk, | ||
4568 | .set_pll = rt5665_set_codec_pll, | ||
4569 | .set_jack = rt5665_set_jack_detect, | ||
4508 | }; | 4570 | }; |
4509 | 4571 | ||
4510 | 4572 | ||
@@ -4783,7 +4845,7 @@ static int rt5665_i2c_probe(struct i2c_client *i2c, | |||
4783 | 4845 | ||
4784 | regmap_write(rt5665->regmap, RT5665_HP_LOGIC_CTRL_2, 0x0002); | 4846 | regmap_write(rt5665->regmap, RT5665_HP_LOGIC_CTRL_2, 0x0002); |
4785 | regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1, | 4847 | regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1, |
4786 | 0xf000 | RT5665_VREF_POW_MASK, 0xd000 | RT5665_VREF_POW_REG); | 4848 | 0xf000 | RT5665_VREF_POW_MASK, 0xe000 | RT5665_VREF_POW_REG); |
4787 | /* Work around for pow_pump */ | 4849 | /* Work around for pow_pump */ |
4788 | regmap_update_bits(rt5665->regmap, RT5665_STO1_DAC_SIL_DET, | 4850 | regmap_update_bits(rt5665->regmap, RT5665_STO1_DAC_SIL_DET, |
4789 | RT5665_DEB_STO_DAC_MASK, RT5665_DEB_80_MS); | 4851 | RT5665_DEB_STO_DAC_MASK, RT5665_DEB_80_MS); |
diff --git a/sound/soc/codecs/rt5665.h b/sound/soc/codecs/rt5665.h index a30f5e6d0628..1db5c6a62a8e 100644 --- a/sound/soc/codecs/rt5665.h +++ b/sound/soc/codecs/rt5665.h | |||
@@ -1984,7 +1984,5 @@ enum { | |||
1984 | 1984 | ||
1985 | int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec, | 1985 | int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec, |
1986 | unsigned int filter_mask, unsigned int clk_src); | 1986 | unsigned int filter_mask, unsigned int clk_src); |
1987 | int rt5665_set_jack_detect(struct snd_soc_codec *codec, | ||
1988 | struct snd_soc_jack *hs_jack); | ||
1989 | 1987 | ||
1990 | #endif /* __RT5665_H__ */ | 1988 | #endif /* __RT5665_H__ */ |
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index fbaa1bb41102..7daf21fee355 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
@@ -19,9 +19,28 @@ | |||
19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/export.h> | 21 | #include <linux/export.h> |
22 | #include <linux/suspend.h> | ||
22 | #include <trace/events/asoc.h> | 23 | #include <trace/events/asoc.h> |
23 | 24 | ||
24 | /** | 25 | /** |
26 | * snd_soc_codec_set_jack - configure codec jack. | ||
27 | * @codec: CODEC | ||
28 | * @jack: structure to use for the jack | ||
29 | * @data: can be used if codec driver need extra data for configuring jack | ||
30 | * | ||
31 | * Configures and enables jack detection function. | ||
32 | */ | ||
33 | int snd_soc_codec_set_jack(struct snd_soc_codec *codec, | ||
34 | struct snd_soc_jack *jack, void *data) | ||
35 | { | ||
36 | if (codec->driver->set_jack) | ||
37 | return codec->driver->set_jack(codec, jack, data); | ||
38 | else | ||
39 | return -EINVAL; | ||
40 | } | ||
41 | EXPORT_SYMBOL_GPL(snd_soc_codec_set_jack); | ||
42 | |||
43 | /** | ||
25 | * snd_soc_card_jack_new - Create a new jack | 44 | * snd_soc_card_jack_new - Create a new jack |
26 | * @card: ASoC card | 45 | * @card: ASoC card |
27 | * @id: an identifying string for this jack | 46 | * @id: an identifying string for this jack |
@@ -293,6 +312,27 @@ static void gpio_work(struct work_struct *work) | |||
293 | snd_soc_jack_gpio_detect(gpio); | 312 | snd_soc_jack_gpio_detect(gpio); |
294 | } | 313 | } |
295 | 314 | ||
315 | static int snd_soc_jack_pm_notifier(struct notifier_block *nb, | ||
316 | unsigned long action, void *data) | ||
317 | { | ||
318 | struct snd_soc_jack_gpio *gpio = | ||
319 | container_of(nb, struct snd_soc_jack_gpio, pm_notifier); | ||
320 | |||
321 | switch (action) { | ||
322 | case PM_POST_SUSPEND: | ||
323 | case PM_POST_HIBERNATION: | ||
324 | case PM_POST_RESTORE: | ||
325 | /* | ||
326 | * Use workqueue so we do not have to care about running | ||
327 | * concurrently with work triggered by the interrupt handler. | ||
328 | */ | ||
329 | queue_delayed_work(system_power_efficient_wq, &gpio->work, 0); | ||
330 | break; | ||
331 | } | ||
332 | |||
333 | return NOTIFY_DONE; | ||
334 | } | ||
335 | |||
296 | /** | 336 | /** |
297 | * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack | 337 | * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack |
298 | * | 338 | * |
@@ -369,6 +409,13 @@ got_gpio: | |||
369 | i, ret); | 409 | i, ret); |
370 | } | 410 | } |
371 | 411 | ||
412 | /* | ||
413 | * Register PM notifier so we do not miss state transitions | ||
414 | * happening while system is asleep. | ||
415 | */ | ||
416 | gpios[i].pm_notifier.notifier_call = snd_soc_jack_pm_notifier; | ||
417 | register_pm_notifier(&gpios[i].pm_notifier); | ||
418 | |||
372 | /* Expose GPIO value over sysfs for diagnostic purposes */ | 419 | /* Expose GPIO value over sysfs for diagnostic purposes */ |
373 | gpiod_export(gpios[i].desc, false); | 420 | gpiod_export(gpios[i].desc, false); |
374 | 421 | ||
@@ -428,6 +475,7 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, | |||
428 | 475 | ||
429 | for (i = 0; i < count; i++) { | 476 | for (i = 0; i < count; i++) { |
430 | gpiod_unexport(gpios[i].desc); | 477 | gpiod_unexport(gpios[i].desc); |
478 | unregister_pm_notifier(&gpios[i].pm_notifier); | ||
431 | free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); | 479 | free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); |
432 | cancel_delayed_work_sync(&gpios[i].work); | 480 | cancel_delayed_work_sync(&gpios[i].work); |
433 | gpiod_put(gpios[i].desc); | 481 | gpiod_put(gpios[i].desc); |