| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * wm8994.c -- WM8994 ALSA SoC Audio driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2009-12 Wolfson Microelectronics plc |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 10 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 11 | | - * published by the Free Software Foundation. |
|---|
| 12 | 8 | */ |
|---|
| 13 | 9 | |
|---|
| 14 | 10 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 47 | 43 | #define WM8994_NUM_DRC 3 |
|---|
| 48 | 44 | #define WM8994_NUM_EQ 3 |
|---|
| 49 | 45 | |
|---|
| 50 | | -static struct { |
|---|
| 46 | +struct wm8994_reg_mask { |
|---|
| 51 | 47 | unsigned int reg; |
|---|
| 52 | 48 | unsigned int mask; |
|---|
| 53 | | -} wm8994_vu_bits[] = { |
|---|
| 49 | +}; |
|---|
| 50 | + |
|---|
| 51 | +static struct wm8994_reg_mask wm8994_vu_bits[] = { |
|---|
| 54 | 52 | { WM8994_LEFT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU }, |
|---|
| 55 | 53 | { WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU }, |
|---|
| 56 | 54 | { WM8994_LEFT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU }, |
|---|
| .. | .. |
|---|
| 64 | 62 | |
|---|
| 65 | 63 | { WM8994_AIF1_DAC1_LEFT_VOLUME, WM8994_AIF1DAC1_VU }, |
|---|
| 66 | 64 | { WM8994_AIF1_DAC1_RIGHT_VOLUME, WM8994_AIF1DAC1_VU }, |
|---|
| 67 | | - { WM8994_AIF1_DAC2_LEFT_VOLUME, WM8994_AIF1DAC2_VU }, |
|---|
| 68 | | - { WM8994_AIF1_DAC2_RIGHT_VOLUME, WM8994_AIF1DAC2_VU }, |
|---|
| 69 | 65 | { WM8994_AIF2_DAC_LEFT_VOLUME, WM8994_AIF2DAC_VU }, |
|---|
| 70 | 66 | { WM8994_AIF2_DAC_RIGHT_VOLUME, WM8994_AIF2DAC_VU }, |
|---|
| 71 | 67 | { WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1ADC1_VU }, |
|---|
| 72 | 68 | { WM8994_AIF1_ADC1_RIGHT_VOLUME, WM8994_AIF1ADC1_VU }, |
|---|
| 73 | | - { WM8994_AIF1_ADC2_LEFT_VOLUME, WM8994_AIF1ADC2_VU }, |
|---|
| 74 | | - { WM8994_AIF1_ADC2_RIGHT_VOLUME, WM8994_AIF1ADC2_VU }, |
|---|
| 75 | 69 | { WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2ADC_VU }, |
|---|
| 76 | 70 | { WM8994_AIF2_ADC_RIGHT_VOLUME, WM8994_AIF1ADC2_VU }, |
|---|
| 77 | 71 | { WM8994_DAC1_LEFT_VOLUME, WM8994_DAC1_VU }, |
|---|
| 78 | 72 | { WM8994_DAC1_RIGHT_VOLUME, WM8994_DAC1_VU }, |
|---|
| 79 | 73 | { WM8994_DAC2_LEFT_VOLUME, WM8994_DAC2_VU }, |
|---|
| 80 | 74 | { WM8994_DAC2_RIGHT_VOLUME, WM8994_DAC2_VU }, |
|---|
| 75 | +}; |
|---|
| 76 | + |
|---|
| 77 | +/* VU bitfields for ADC2, DAC2 not available on WM1811 */ |
|---|
| 78 | +static struct wm8994_reg_mask wm8994_adc2_dac2_vu_bits[] = { |
|---|
| 79 | + { WM8994_AIF1_DAC2_LEFT_VOLUME, WM8994_AIF1DAC2_VU }, |
|---|
| 80 | + { WM8994_AIF1_DAC2_RIGHT_VOLUME, WM8994_AIF1DAC2_VU }, |
|---|
| 81 | + { WM8994_AIF1_ADC2_LEFT_VOLUME, WM8994_AIF1ADC2_VU }, |
|---|
| 82 | + { WM8994_AIF1_ADC2_RIGHT_VOLUME, WM8994_AIF1ADC2_VU }, |
|---|
| 81 | 83 | }; |
|---|
| 82 | 84 | |
|---|
| 83 | 85 | static int wm8994_drc_base[] = { |
|---|
| .. | .. |
|---|
| 117 | 119 | |
|---|
| 118 | 120 | idle = !wm8994->jack_mic; |
|---|
| 119 | 121 | |
|---|
| 120 | | - sysclk = snd_soc_component_read32(component, WM8994_CLOCKING_1); |
|---|
| 122 | + sysclk = snd_soc_component_read(component, WM8994_CLOCKING_1); |
|---|
| 121 | 123 | if (sysclk & WM8994_SYSCLK_SRC) |
|---|
| 122 | 124 | sysclk = wm8994->aifclk[1]; |
|---|
| 123 | 125 | else |
|---|
| .. | .. |
|---|
| 171 | 173 | |
|---|
| 172 | 174 | switch (wm8994->sysclk[aif]) { |
|---|
| 173 | 175 | case WM8994_SYSCLK_MCLK1: |
|---|
| 174 | | - rate = wm8994->mclk[0]; |
|---|
| 176 | + rate = wm8994->mclk_rate[0]; |
|---|
| 175 | 177 | break; |
|---|
| 176 | 178 | |
|---|
| 177 | 179 | case WM8994_SYSCLK_MCLK2: |
|---|
| 178 | 180 | reg1 |= 0x8; |
|---|
| 179 | | - rate = wm8994->mclk[1]; |
|---|
| 181 | + rate = wm8994->mclk_rate[1]; |
|---|
| 180 | 182 | break; |
|---|
| 181 | 183 | |
|---|
| 182 | 184 | case WM8994_SYSCLK_FLL1: |
|---|
| .. | .. |
|---|
| 251 | 253 | struct snd_soc_dapm_widget *sink) |
|---|
| 252 | 254 | { |
|---|
| 253 | 255 | struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm); |
|---|
| 254 | | - int reg = snd_soc_component_read32(component, WM8994_CLOCKING_1); |
|---|
| 256 | + int reg = snd_soc_component_read(component, WM8994_CLOCKING_1); |
|---|
| 255 | 257 | const char *clk; |
|---|
| 256 | 258 | |
|---|
| 257 | 259 | /* Check what we're currently using for CLK_SYS */ |
|---|
| .. | .. |
|---|
| 289 | 291 | static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0); |
|---|
| 290 | 292 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); |
|---|
| 291 | 293 | static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0); |
|---|
| 292 | | -static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0); |
|---|
| 293 | 294 | |
|---|
| 294 | 295 | #define WM8994_DRC_SWITCH(xname, reg, shift) \ |
|---|
| 295 | 296 | SOC_SINGLE_EXT(xname, reg, shift, 1, 0, \ |
|---|
| .. | .. |
|---|
| 310 | 311 | else |
|---|
| 311 | 312 | mask = WM8994_AIF1DAC1_DRC_ENA_MASK; |
|---|
| 312 | 313 | |
|---|
| 313 | | - ret = snd_soc_component_read32(component, mc->reg); |
|---|
| 314 | + ret = snd_soc_component_read(component, mc->reg); |
|---|
| 314 | 315 | if (ret < 0) |
|---|
| 315 | 316 | return ret; |
|---|
| 316 | 317 | if (ret & mask) |
|---|
| .. | .. |
|---|
| 329 | 330 | int save, i; |
|---|
| 330 | 331 | |
|---|
| 331 | 332 | /* Save any enables; the configuration should clear them. */ |
|---|
| 332 | | - save = snd_soc_component_read32(component, base); |
|---|
| 333 | + save = snd_soc_component_read(component, base); |
|---|
| 333 | 334 | save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA | |
|---|
| 334 | 335 | WM8994_AIF1ADC1R_DRC_ENA; |
|---|
| 335 | 336 | |
|---|
| .. | .. |
|---|
| 439 | 440 | /* The EQ will be disabled while reconfiguring it, remember the |
|---|
| 440 | 441 | * current configuration. |
|---|
| 441 | 442 | */ |
|---|
| 442 | | - save = snd_soc_component_read32(component, base); |
|---|
| 443 | + save = snd_soc_component_read(component, base); |
|---|
| 443 | 444 | save &= WM8994_AIF1DAC1_EQ_ENA; |
|---|
| 444 | 445 | |
|---|
| 445 | 446 | for (i = 0; i < WM8994_EQ_REGS; i++) |
|---|
| .. | .. |
|---|
| 737 | 738 | 7, 1, ng_tlv), |
|---|
| 738 | 739 | }; |
|---|
| 739 | 740 | |
|---|
| 740 | | -static const struct snd_kcontrol_new wm1811_snd_controls[] = { |
|---|
| 741 | | -SOC_SINGLE_TLV("MIXINL IN1LP Boost Volume", WM8994_INPUT_MIXER_1, 7, 1, 0, |
|---|
| 742 | | - mixin_boost_tlv), |
|---|
| 743 | | -SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0, |
|---|
| 744 | | - mixin_boost_tlv), |
|---|
| 745 | | -}; |
|---|
| 746 | | - |
|---|
| 747 | 741 | /* We run all mode setting through a function to enforce audio mode */ |
|---|
| 748 | 742 | static void wm1811_jackdet_set_mode(struct snd_soc_component *component, u16 mode) |
|---|
| 749 | 743 | { |
|---|
| .. | .. |
|---|
| 865 | 859 | switch (wm8994->vmid_mode) { |
|---|
| 866 | 860 | default: |
|---|
| 867 | 861 | WARN_ON(NULL == "Invalid VMID mode"); |
|---|
| 868 | | - /* fall through */ |
|---|
| 862 | + fallthrough; |
|---|
| 869 | 863 | case WM8994_VMID_NORMAL: |
|---|
| 870 | 864 | /* Startup bias, VMID ramp & buffer */ |
|---|
| 871 | 865 | snd_soc_component_update_bits(component, WM8994_ANTIPOP_2, |
|---|
| .. | .. |
|---|
| 1010 | 1004 | int reg, reg_r; |
|---|
| 1011 | 1005 | |
|---|
| 1012 | 1006 | /* We also need the same AIF source for L/R and only one path */ |
|---|
| 1013 | | - reg = snd_soc_component_read32(component, WM8994_DAC1_LEFT_MIXER_ROUTING); |
|---|
| 1007 | + reg = snd_soc_component_read(component, WM8994_DAC1_LEFT_MIXER_ROUTING); |
|---|
| 1014 | 1008 | switch (reg) { |
|---|
| 1015 | 1009 | case WM8994_AIF2DACL_TO_DAC1L: |
|---|
| 1016 | 1010 | dev_vdbg(component->dev, "Class W source AIF2DAC\n"); |
|---|
| .. | .. |
|---|
| 1029 | 1023 | return false; |
|---|
| 1030 | 1024 | } |
|---|
| 1031 | 1025 | |
|---|
| 1032 | | - reg_r = snd_soc_component_read32(component, WM8994_DAC1_RIGHT_MIXER_ROUTING); |
|---|
| 1026 | + reg_r = snd_soc_component_read(component, WM8994_DAC1_RIGHT_MIXER_ROUTING); |
|---|
| 1033 | 1027 | if (reg_r != reg) { |
|---|
| 1034 | 1028 | dev_vdbg(component->dev, "Left and right DAC mixers different\n"); |
|---|
| 1035 | 1029 | return false; |
|---|
| .. | .. |
|---|
| 1042 | 1036 | return true; |
|---|
| 1043 | 1037 | } |
|---|
| 1044 | 1038 | |
|---|
| 1039 | +static void wm8994_update_vu_bits(struct snd_soc_component *component) |
|---|
| 1040 | +{ |
|---|
| 1041 | + struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); |
|---|
| 1042 | + struct wm8994 *control = wm8994->wm8994; |
|---|
| 1043 | + int i; |
|---|
| 1044 | + |
|---|
| 1045 | + for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++) |
|---|
| 1046 | + snd_soc_component_write(component, wm8994_vu_bits[i].reg, |
|---|
| 1047 | + snd_soc_component_read(component, |
|---|
| 1048 | + wm8994_vu_bits[i].reg)); |
|---|
| 1049 | + if (control->type == WM1811) |
|---|
| 1050 | + return; |
|---|
| 1051 | + |
|---|
| 1052 | + for (i = 0; i < ARRAY_SIZE(wm8994_adc2_dac2_vu_bits); i++) |
|---|
| 1053 | + snd_soc_component_write(component, |
|---|
| 1054 | + wm8994_adc2_dac2_vu_bits[i].reg, |
|---|
| 1055 | + snd_soc_component_read(component, |
|---|
| 1056 | + wm8994_adc2_dac2_vu_bits[i].reg)); |
|---|
| 1057 | +} |
|---|
| 1058 | + |
|---|
| 1059 | +static int aif_mclk_set(struct snd_soc_component *component, int aif, bool enable) |
|---|
| 1060 | +{ |
|---|
| 1061 | + struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); |
|---|
| 1062 | + unsigned int offset, val, clk_idx; |
|---|
| 1063 | + int ret; |
|---|
| 1064 | + |
|---|
| 1065 | + if (aif) |
|---|
| 1066 | + offset = 4; |
|---|
| 1067 | + else |
|---|
| 1068 | + offset = 0; |
|---|
| 1069 | + |
|---|
| 1070 | + val = snd_soc_component_read(component, WM8994_AIF1_CLOCKING_1 + offset); |
|---|
| 1071 | + val &= WM8994_AIF1CLK_SRC_MASK; |
|---|
| 1072 | + |
|---|
| 1073 | + switch (val) { |
|---|
| 1074 | + case 0: |
|---|
| 1075 | + clk_idx = WM8994_MCLK1; |
|---|
| 1076 | + break; |
|---|
| 1077 | + case 1: |
|---|
| 1078 | + clk_idx = WM8994_MCLK2; |
|---|
| 1079 | + break; |
|---|
| 1080 | + default: |
|---|
| 1081 | + return 0; |
|---|
| 1082 | + } |
|---|
| 1083 | + |
|---|
| 1084 | + if (enable) { |
|---|
| 1085 | + ret = clk_prepare_enable(wm8994->mclk[clk_idx].clk); |
|---|
| 1086 | + if (ret < 0) { |
|---|
| 1087 | + dev_err(component->dev, "Failed to enable MCLK%d\n", |
|---|
| 1088 | + clk_idx); |
|---|
| 1089 | + return ret; |
|---|
| 1090 | + } |
|---|
| 1091 | + } else { |
|---|
| 1092 | + clk_disable_unprepare(wm8994->mclk[clk_idx].clk); |
|---|
| 1093 | + } |
|---|
| 1094 | + |
|---|
| 1095 | + return 0; |
|---|
| 1096 | +} |
|---|
| 1097 | + |
|---|
| 1045 | 1098 | static int aif1clk_ev(struct snd_soc_dapm_widget *w, |
|---|
| 1046 | 1099 | struct snd_kcontrol *kcontrol, int event) |
|---|
| 1047 | 1100 | { |
|---|
| .. | .. |
|---|
| 1049 | 1102 | struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); |
|---|
| 1050 | 1103 | struct wm8994 *control = wm8994->wm8994; |
|---|
| 1051 | 1104 | int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; |
|---|
| 1052 | | - int i; |
|---|
| 1105 | + int ret; |
|---|
| 1053 | 1106 | int dac; |
|---|
| 1054 | 1107 | int adc; |
|---|
| 1055 | 1108 | int val; |
|---|
| .. | .. |
|---|
| 1065 | 1118 | |
|---|
| 1066 | 1119 | switch (event) { |
|---|
| 1067 | 1120 | case SND_SOC_DAPM_PRE_PMU: |
|---|
| 1121 | + ret = aif_mclk_set(component, 0, true); |
|---|
| 1122 | + if (ret < 0) |
|---|
| 1123 | + return ret; |
|---|
| 1124 | + |
|---|
| 1068 | 1125 | /* Don't enable timeslot 2 if not in use */ |
|---|
| 1069 | 1126 | if (wm8994->channels[0] <= 2) |
|---|
| 1070 | 1127 | mask &= ~(WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA); |
|---|
| 1071 | 1128 | |
|---|
| 1072 | | - val = snd_soc_component_read32(component, WM8994_AIF1_CONTROL_1); |
|---|
| 1129 | + val = snd_soc_component_read(component, WM8994_AIF1_CONTROL_1); |
|---|
| 1073 | 1130 | if ((val & WM8994_AIF1ADCL_SRC) && |
|---|
| 1074 | 1131 | (val & WM8994_AIF1ADCR_SRC)) |
|---|
| 1075 | 1132 | adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA; |
|---|
| .. | .. |
|---|
| 1080 | 1137 | adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA | |
|---|
| 1081 | 1138 | WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA; |
|---|
| 1082 | 1139 | |
|---|
| 1083 | | - val = snd_soc_component_read32(component, WM8994_AIF1_CONTROL_2); |
|---|
| 1140 | + val = snd_soc_component_read(component, WM8994_AIF1_CONTROL_2); |
|---|
| 1084 | 1141 | if ((val & WM8994_AIF1DACL_SRC) && |
|---|
| 1085 | 1142 | (val & WM8994_AIF1DACR_SRC)) |
|---|
| 1086 | 1143 | dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA; |
|---|
| .. | .. |
|---|
| 1113 | 1170 | break; |
|---|
| 1114 | 1171 | |
|---|
| 1115 | 1172 | case SND_SOC_DAPM_POST_PMU: |
|---|
| 1116 | | - for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++) |
|---|
| 1117 | | - snd_soc_component_write(component, wm8994_vu_bits[i].reg, |
|---|
| 1118 | | - snd_soc_component_read32(component, |
|---|
| 1119 | | - wm8994_vu_bits[i].reg)); |
|---|
| 1173 | + wm8994_update_vu_bits(component); |
|---|
| 1120 | 1174 | break; |
|---|
| 1121 | 1175 | |
|---|
| 1122 | 1176 | case SND_SOC_DAPM_PRE_PMD: |
|---|
| .. | .. |
|---|
| 1126 | 1180 | snd_soc_component_update_bits(component, WM8994_POWER_MANAGEMENT_4, |
|---|
| 1127 | 1181 | mask, 0); |
|---|
| 1128 | 1182 | |
|---|
| 1129 | | - val = snd_soc_component_read32(component, WM8994_CLOCKING_1); |
|---|
| 1183 | + val = snd_soc_component_read(component, WM8994_CLOCKING_1); |
|---|
| 1130 | 1184 | if (val & WM8994_AIF2DSPCLK_ENA) |
|---|
| 1131 | 1185 | val = WM8994_SYSDSPCLK_ENA; |
|---|
| 1132 | 1186 | else |
|---|
| .. | .. |
|---|
| 1137 | 1191 | break; |
|---|
| 1138 | 1192 | } |
|---|
| 1139 | 1193 | |
|---|
| 1194 | + switch (event) { |
|---|
| 1195 | + case SND_SOC_DAPM_POST_PMD: |
|---|
| 1196 | + aif_mclk_set(component, 0, false); |
|---|
| 1197 | + break; |
|---|
| 1198 | + } |
|---|
| 1199 | + |
|---|
| 1140 | 1200 | return 0; |
|---|
| 1141 | 1201 | } |
|---|
| 1142 | 1202 | |
|---|
| .. | .. |
|---|
| 1144 | 1204 | struct snd_kcontrol *kcontrol, int event) |
|---|
| 1145 | 1205 | { |
|---|
| 1146 | 1206 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
|---|
| 1147 | | - int i; |
|---|
| 1207 | + int ret; |
|---|
| 1148 | 1208 | int dac; |
|---|
| 1149 | 1209 | int adc; |
|---|
| 1150 | 1210 | int val; |
|---|
| 1151 | 1211 | |
|---|
| 1152 | 1212 | switch (event) { |
|---|
| 1153 | 1213 | case SND_SOC_DAPM_PRE_PMU: |
|---|
| 1154 | | - val = snd_soc_component_read32(component, WM8994_AIF2_CONTROL_1); |
|---|
| 1214 | + ret = aif_mclk_set(component, 1, true); |
|---|
| 1215 | + if (ret < 0) |
|---|
| 1216 | + return ret; |
|---|
| 1217 | + |
|---|
| 1218 | + val = snd_soc_component_read(component, WM8994_AIF2_CONTROL_1); |
|---|
| 1155 | 1219 | if ((val & WM8994_AIF2ADCL_SRC) && |
|---|
| 1156 | 1220 | (val & WM8994_AIF2ADCR_SRC)) |
|---|
| 1157 | 1221 | adc = WM8994_AIF2ADCR_ENA; |
|---|
| .. | .. |
|---|
| 1162 | 1226 | adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA; |
|---|
| 1163 | 1227 | |
|---|
| 1164 | 1228 | |
|---|
| 1165 | | - val = snd_soc_component_read32(component, WM8994_AIF2_CONTROL_2); |
|---|
| 1229 | + val = snd_soc_component_read(component, WM8994_AIF2_CONTROL_2); |
|---|
| 1166 | 1230 | if ((val & WM8994_AIF2DACL_SRC) && |
|---|
| 1167 | 1231 | (val & WM8994_AIF2DACR_SRC)) |
|---|
| 1168 | 1232 | dac = WM8994_AIF2DACR_ENA; |
|---|
| .. | .. |
|---|
| 1196 | 1260 | break; |
|---|
| 1197 | 1261 | |
|---|
| 1198 | 1262 | case SND_SOC_DAPM_POST_PMU: |
|---|
| 1199 | | - for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++) |
|---|
| 1200 | | - snd_soc_component_write(component, wm8994_vu_bits[i].reg, |
|---|
| 1201 | | - snd_soc_component_read32(component, |
|---|
| 1202 | | - wm8994_vu_bits[i].reg)); |
|---|
| 1263 | + wm8994_update_vu_bits(component); |
|---|
| 1203 | 1264 | break; |
|---|
| 1204 | 1265 | |
|---|
| 1205 | 1266 | case SND_SOC_DAPM_PRE_PMD: |
|---|
| .. | .. |
|---|
| 1211 | 1272 | WM8994_AIF2ADCL_ENA | |
|---|
| 1212 | 1273 | WM8994_AIF2ADCR_ENA, 0); |
|---|
| 1213 | 1274 | |
|---|
| 1214 | | - val = snd_soc_component_read32(component, WM8994_CLOCKING_1); |
|---|
| 1275 | + val = snd_soc_component_read(component, WM8994_CLOCKING_1); |
|---|
| 1215 | 1276 | if (val & WM8994_AIF1DSPCLK_ENA) |
|---|
| 1216 | 1277 | val = WM8994_SYSDSPCLK_ENA; |
|---|
| 1217 | 1278 | else |
|---|
| .. | .. |
|---|
| 1219 | 1280 | snd_soc_component_update_bits(component, WM8994_CLOCKING_1, |
|---|
| 1220 | 1281 | WM8994_SYSDSPCLK_ENA | |
|---|
| 1221 | 1282 | WM8994_AIF2DSPCLK_ENA, val); |
|---|
| 1283 | + break; |
|---|
| 1284 | + } |
|---|
| 1285 | + |
|---|
| 1286 | + switch (event) { |
|---|
| 1287 | + case SND_SOC_DAPM_POST_PMD: |
|---|
| 1288 | + aif_mclk_set(component, 1, false); |
|---|
| 1222 | 1289 | break; |
|---|
| 1223 | 1290 | } |
|---|
| 1224 | 1291 | |
|---|
| .. | .. |
|---|
| 1382 | 1449 | { |
|---|
| 1383 | 1450 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
|---|
| 1384 | 1451 | dev_dbg(component->dev, "SRC status: %x\n", |
|---|
| 1385 | | - snd_soc_component_read32(component, |
|---|
| 1452 | + snd_soc_component_read(component, |
|---|
| 1386 | 1453 | WM8994_RATE_STATUS)); |
|---|
| 1387 | 1454 | return 0; |
|---|
| 1388 | 1455 | } |
|---|
| .. | .. |
|---|
| 1627 | 1694 | static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { |
|---|
| 1628 | 1695 | SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev, |
|---|
| 1629 | 1696 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
|---|
| 1630 | | - SND_SOC_DAPM_PRE_PMD), |
|---|
| 1697 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), |
|---|
| 1631 | 1698 | SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev, |
|---|
| 1632 | 1699 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | |
|---|
| 1633 | | - SND_SOC_DAPM_PRE_PMD), |
|---|
| 1700 | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), |
|---|
| 1634 | 1701 | SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0), |
|---|
| 1635 | 1702 | SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0, |
|---|
| 1636 | 1703 | left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), |
|---|
| .. | .. |
|---|
| 2145 | 2212 | u16 reg, clk1, aif_reg, aif_src; |
|---|
| 2146 | 2213 | unsigned long timeout; |
|---|
| 2147 | 2214 | bool was_enabled; |
|---|
| 2215 | + struct clk *mclk; |
|---|
| 2148 | 2216 | |
|---|
| 2149 | 2217 | switch (id) { |
|---|
| 2150 | 2218 | case WM8994_FLL1: |
|---|
| .. | .. |
|---|
| 2161 | 2229 | return -EINVAL; |
|---|
| 2162 | 2230 | } |
|---|
| 2163 | 2231 | |
|---|
| 2164 | | - reg = snd_soc_component_read32(component, WM8994_FLL1_CONTROL_1 + reg_offset); |
|---|
| 2232 | + reg = snd_soc_component_read(component, WM8994_FLL1_CONTROL_1 + reg_offset); |
|---|
| 2165 | 2233 | was_enabled = reg & WM8994_FLL1_ENA; |
|---|
| 2166 | 2234 | |
|---|
| 2167 | 2235 | switch (src) { |
|---|
| .. | .. |
|---|
| 2202 | 2270 | return ret; |
|---|
| 2203 | 2271 | |
|---|
| 2204 | 2272 | /* Make sure that we're not providing SYSCLK right now */ |
|---|
| 2205 | | - clk1 = snd_soc_component_read32(component, WM8994_CLOCKING_1); |
|---|
| 2273 | + clk1 = snd_soc_component_read(component, WM8994_CLOCKING_1); |
|---|
| 2206 | 2274 | if (clk1 & WM8994_SYSCLK_SRC) |
|---|
| 2207 | 2275 | aif_reg = WM8994_AIF2_CLOCKING_1; |
|---|
| 2208 | 2276 | else |
|---|
| 2209 | 2277 | aif_reg = WM8994_AIF1_CLOCKING_1; |
|---|
| 2210 | | - reg = snd_soc_component_read32(component, aif_reg); |
|---|
| 2278 | + reg = snd_soc_component_read(component, aif_reg); |
|---|
| 2211 | 2279 | |
|---|
| 2212 | 2280 | if ((reg & WM8994_AIF1CLK_ENA) && |
|---|
| 2213 | 2281 | (reg & WM8994_AIF1CLK_SRC_MASK) == aif_src) { |
|---|
| .. | .. |
|---|
| 2219 | 2287 | /* We always need to disable the FLL while reconfiguring */ |
|---|
| 2220 | 2288 | snd_soc_component_update_bits(component, WM8994_FLL1_CONTROL_1 + reg_offset, |
|---|
| 2221 | 2289 | WM8994_FLL1_ENA, 0); |
|---|
| 2290 | + |
|---|
| 2291 | + /* Disable MCLK if needed before we possibly change to new clock parent */ |
|---|
| 2292 | + if (was_enabled) { |
|---|
| 2293 | + reg = snd_soc_component_read(component, WM8994_FLL1_CONTROL_5 |
|---|
| 2294 | + + reg_offset); |
|---|
| 2295 | + reg = ((reg & WM8994_FLL1_REFCLK_SRC_MASK) |
|---|
| 2296 | + >> WM8994_FLL1_REFCLK_SRC_SHIFT) + 1; |
|---|
| 2297 | + |
|---|
| 2298 | + switch (reg) { |
|---|
| 2299 | + case WM8994_FLL_SRC_MCLK1: |
|---|
| 2300 | + mclk = wm8994->mclk[WM8994_MCLK1].clk; |
|---|
| 2301 | + break; |
|---|
| 2302 | + case WM8994_FLL_SRC_MCLK2: |
|---|
| 2303 | + mclk = wm8994->mclk[WM8994_MCLK2].clk; |
|---|
| 2304 | + break; |
|---|
| 2305 | + default: |
|---|
| 2306 | + mclk = NULL; |
|---|
| 2307 | + } |
|---|
| 2308 | + |
|---|
| 2309 | + clk_disable_unprepare(mclk); |
|---|
| 2310 | + } |
|---|
| 2222 | 2311 | |
|---|
| 2223 | 2312 | if (wm8994->fll_byp && src == WM8994_FLL_SRC_BCLK && |
|---|
| 2224 | 2313 | freq_in == freq_out && freq_out) { |
|---|
| .. | .. |
|---|
| 2264 | 2353 | /* Clear any pending completion from a previous failure */ |
|---|
| 2265 | 2354 | try_wait_for_completion(&wm8994->fll_locked[id]); |
|---|
| 2266 | 2355 | |
|---|
| 2356 | + switch (src) { |
|---|
| 2357 | + case WM8994_FLL_SRC_MCLK1: |
|---|
| 2358 | + mclk = wm8994->mclk[WM8994_MCLK1].clk; |
|---|
| 2359 | + break; |
|---|
| 2360 | + case WM8994_FLL_SRC_MCLK2: |
|---|
| 2361 | + mclk = wm8994->mclk[WM8994_MCLK2].clk; |
|---|
| 2362 | + break; |
|---|
| 2363 | + default: |
|---|
| 2364 | + mclk = NULL; |
|---|
| 2365 | + } |
|---|
| 2366 | + |
|---|
| 2267 | 2367 | /* Enable (with fractional mode if required) */ |
|---|
| 2268 | 2368 | if (freq_out) { |
|---|
| 2369 | + ret = clk_prepare_enable(mclk); |
|---|
| 2370 | + if (ret < 0) { |
|---|
| 2371 | + dev_err(component->dev, "Failed to enable MCLK for FLL%d\n", |
|---|
| 2372 | + id + 1); |
|---|
| 2373 | + return ret; |
|---|
| 2374 | + } |
|---|
| 2375 | + |
|---|
| 2269 | 2376 | /* Enable VMID if we need it */ |
|---|
| 2270 | 2377 | if (!was_enabled) { |
|---|
| 2378 | + |
|---|
| 2271 | 2379 | active_reference(component); |
|---|
| 2272 | 2380 | |
|---|
| 2273 | 2381 | switch (control->type) { |
|---|
| .. | .. |
|---|
| 2335 | 2443 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { |
|---|
| 2336 | 2444 | dev_dbg(component->dev, "Configuring AIFs for 128fs\n"); |
|---|
| 2337 | 2445 | |
|---|
| 2338 | | - wm8994->aifdiv[0] = snd_soc_component_read32(component, WM8994_AIF1_RATE) |
|---|
| 2446 | + wm8994->aifdiv[0] = snd_soc_component_read(component, WM8994_AIF1_RATE) |
|---|
| 2339 | 2447 | & WM8994_AIF1CLK_RATE_MASK; |
|---|
| 2340 | | - wm8994->aifdiv[1] = snd_soc_component_read32(component, WM8994_AIF2_RATE) |
|---|
| 2448 | + wm8994->aifdiv[1] = snd_soc_component_read(component, WM8994_AIF2_RATE) |
|---|
| 2341 | 2449 | & WM8994_AIF1CLK_RATE_MASK; |
|---|
| 2342 | 2450 | |
|---|
| 2343 | 2451 | snd_soc_component_update_bits(component, WM8994_AIF1_RATE, |
|---|
| .. | .. |
|---|
| 2376 | 2484 | return _wm8994_set_fll(dai->component, id, src, freq_in, freq_out); |
|---|
| 2377 | 2485 | } |
|---|
| 2378 | 2486 | |
|---|
| 2487 | +static int wm8994_set_mclk_rate(struct wm8994_priv *wm8994, unsigned int id, |
|---|
| 2488 | + unsigned int *freq) |
|---|
| 2489 | +{ |
|---|
| 2490 | + int ret; |
|---|
| 2491 | + |
|---|
| 2492 | + if (!wm8994->mclk[id].clk || *freq == wm8994->mclk_rate[id]) |
|---|
| 2493 | + return 0; |
|---|
| 2494 | + |
|---|
| 2495 | + ret = clk_set_rate(wm8994->mclk[id].clk, *freq); |
|---|
| 2496 | + if (ret < 0) |
|---|
| 2497 | + return ret; |
|---|
| 2498 | + |
|---|
| 2499 | + *freq = clk_get_rate(wm8994->mclk[id].clk); |
|---|
| 2500 | + |
|---|
| 2501 | + return 0; |
|---|
| 2502 | +} |
|---|
| 2503 | + |
|---|
| 2379 | 2504 | static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, |
|---|
| 2380 | 2505 | int clk_id, unsigned int freq, int dir) |
|---|
| 2381 | 2506 | { |
|---|
| 2382 | 2507 | struct snd_soc_component *component = dai->component; |
|---|
| 2383 | 2508 | struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); |
|---|
| 2384 | | - int i; |
|---|
| 2509 | + int ret, i; |
|---|
| 2385 | 2510 | |
|---|
| 2386 | 2511 | switch (dai->id) { |
|---|
| 2387 | 2512 | case 1: |
|---|
| .. | .. |
|---|
| 2396 | 2521 | switch (clk_id) { |
|---|
| 2397 | 2522 | case WM8994_SYSCLK_MCLK1: |
|---|
| 2398 | 2523 | wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1; |
|---|
| 2399 | | - wm8994->mclk[0] = freq; |
|---|
| 2524 | + |
|---|
| 2525 | + ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq); |
|---|
| 2526 | + if (ret < 0) |
|---|
| 2527 | + return ret; |
|---|
| 2528 | + |
|---|
| 2529 | + wm8994->mclk_rate[0] = freq; |
|---|
| 2400 | 2530 | dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n", |
|---|
| 2401 | 2531 | dai->id, freq); |
|---|
| 2402 | 2532 | break; |
|---|
| .. | .. |
|---|
| 2404 | 2534 | case WM8994_SYSCLK_MCLK2: |
|---|
| 2405 | 2535 | /* TODO: Set GPIO AF */ |
|---|
| 2406 | 2536 | wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2; |
|---|
| 2407 | | - wm8994->mclk[1] = freq; |
|---|
| 2537 | + |
|---|
| 2538 | + ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq); |
|---|
| 2539 | + if (ret < 0) |
|---|
| 2540 | + return ret; |
|---|
| 2541 | + |
|---|
| 2542 | + wm8994->mclk_rate[1] = freq; |
|---|
| 2408 | 2543 | dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n", |
|---|
| 2409 | 2544 | dai->id, freq); |
|---|
| 2410 | 2545 | break; |
|---|
| .. | .. |
|---|
| 2452 | 2587 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { |
|---|
| 2453 | 2588 | dev_dbg(component->dev, "Configuring AIFs for 128fs\n"); |
|---|
| 2454 | 2589 | |
|---|
| 2455 | | - wm8994->aifdiv[0] = snd_soc_component_read32(component, WM8994_AIF1_RATE) |
|---|
| 2590 | + wm8994->aifdiv[0] = snd_soc_component_read(component, WM8994_AIF1_RATE) |
|---|
| 2456 | 2591 | & WM8994_AIF1CLK_RATE_MASK; |
|---|
| 2457 | | - wm8994->aifdiv[1] = snd_soc_component_read32(component, WM8994_AIF2_RATE) |
|---|
| 2592 | + wm8994->aifdiv[1] = snd_soc_component_read(component, WM8994_AIF2_RATE) |
|---|
| 2458 | 2593 | & WM8994_AIF1CLK_RATE_MASK; |
|---|
| 2459 | 2594 | |
|---|
| 2460 | 2595 | snd_soc_component_update_bits(component, WM8994_AIF1_RATE, |
|---|
| .. | .. |
|---|
| 2661 | 2796 | case SND_SOC_DAIFMT_DSP_B: |
|---|
| 2662 | 2797 | aif1 |= WM8994_AIF1_LRCLK_INV; |
|---|
| 2663 | 2798 | lrclk |= WM8958_AIF1_LRCLK_INV; |
|---|
| 2664 | | - /* fall through */ |
|---|
| 2799 | + fallthrough; |
|---|
| 2665 | 2800 | case SND_SOC_DAIFMT_DSP_A: |
|---|
| 2666 | 2801 | aif1 |= 0x18; |
|---|
| 2667 | 2802 | break; |
|---|
| .. | .. |
|---|
| 2876 | 3011 | dai->id, wm8994->aifclk[id], bclk_rate); |
|---|
| 2877 | 3012 | |
|---|
| 2878 | 3013 | if (wm8994->channels[id] == 1 && |
|---|
| 2879 | | - (snd_soc_component_read32(component, aif1_reg) & 0x18) == 0x18) |
|---|
| 3014 | + (snd_soc_component_read(component, aif1_reg) & 0x18) == 0x18) |
|---|
| 2880 | 3015 | aif2 |= WM8994_AIF1_MONO; |
|---|
| 2881 | 3016 | |
|---|
| 2882 | 3017 | if (wm8994->aifclk[id] == 0) { |
|---|
| .. | .. |
|---|
| 2995 | 3130 | return snd_soc_component_update_bits(component, aif1_reg, WM8994_AIF1_WL_MASK, aif1); |
|---|
| 2996 | 3131 | } |
|---|
| 2997 | 3132 | |
|---|
| 2998 | | -static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) |
|---|
| 3133 | +static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute, |
|---|
| 3134 | + int direction) |
|---|
| 2999 | 3135 | { |
|---|
| 3000 | 3136 | struct snd_soc_component *component = codec_dai->component; |
|---|
| 3001 | 3137 | int mute_reg; |
|---|
| .. | .. |
|---|
| 3072 | 3208 | .set_sysclk = wm8994_set_dai_sysclk, |
|---|
| 3073 | 3209 | .set_fmt = wm8994_set_dai_fmt, |
|---|
| 3074 | 3210 | .hw_params = wm8994_hw_params, |
|---|
| 3075 | | - .digital_mute = wm8994_aif_mute, |
|---|
| 3211 | + .mute_stream = wm8994_aif_mute, |
|---|
| 3076 | 3212 | .set_pll = wm8994_set_fll, |
|---|
| 3077 | 3213 | .set_tristate = wm8994_set_tristate, |
|---|
| 3214 | + .no_capture_mute = 1, |
|---|
| 3078 | 3215 | }; |
|---|
| 3079 | 3216 | |
|---|
| 3080 | 3217 | static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = { |
|---|
| 3081 | 3218 | .set_sysclk = wm8994_set_dai_sysclk, |
|---|
| 3082 | 3219 | .set_fmt = wm8994_set_dai_fmt, |
|---|
| 3083 | 3220 | .hw_params = wm8994_hw_params, |
|---|
| 3084 | | - .digital_mute = wm8994_aif_mute, |
|---|
| 3221 | + .mute_stream = wm8994_aif_mute, |
|---|
| 3085 | 3222 | .set_pll = wm8994_set_fll, |
|---|
| 3086 | 3223 | .set_tristate = wm8994_set_tristate, |
|---|
| 3224 | + .no_capture_mute = 1, |
|---|
| 3087 | 3225 | }; |
|---|
| 3088 | 3226 | |
|---|
| 3089 | 3227 | static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = { |
|---|
| .. | .. |
|---|
| 3684 | 3822 | |
|---|
| 3685 | 3823 | mutex_lock(&wm8994->accdet_lock); |
|---|
| 3686 | 3824 | |
|---|
| 3687 | | - reg = snd_soc_component_read32(component, WM1811_JACKDET_CTRL); |
|---|
| 3825 | + reg = snd_soc_component_read(component, WM1811_JACKDET_CTRL); |
|---|
| 3688 | 3826 | if (reg < 0) { |
|---|
| 3689 | 3827 | dev_err(component->dev, "Failed to read jack status: %d\n", reg); |
|---|
| 3690 | 3828 | mutex_unlock(&wm8994->accdet_lock); |
|---|
| .. | .. |
|---|
| 3766 | 3904 | * |
|---|
| 3767 | 3905 | * @component: WM8958 component |
|---|
| 3768 | 3906 | * @jack: jack to report detection events on |
|---|
| 3907 | + * @det_cb: detection callback |
|---|
| 3908 | + * @det_cb_data: data for detection callback |
|---|
| 3909 | + * @id_cb: mic id callback |
|---|
| 3910 | + * @id_cb_data: data for mic id callback |
|---|
| 3769 | 3911 | * |
|---|
| 3770 | 3912 | * Enable microphone detection functionality for the WM8958. By |
|---|
| 3771 | 3913 | * default simple detection which supports the detection of up to 6 |
|---|
| .. | .. |
|---|
| 3899 | 4041 | * with an update of the MICDET status; if so it will have |
|---|
| 3900 | 4042 | * stopped detection and we can ignore this interrupt. |
|---|
| 3901 | 4043 | */ |
|---|
| 3902 | | - if (!(snd_soc_component_read32(component, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) |
|---|
| 4044 | + if (!(snd_soc_component_read(component, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) |
|---|
| 3903 | 4045 | return IRQ_HANDLED; |
|---|
| 3904 | 4046 | |
|---|
| 3905 | 4047 | cancel_delayed_work_sync(&wm8994->mic_complete_work); |
|---|
| .. | .. |
|---|
| 3912 | 4054 | */ |
|---|
| 3913 | 4055 | count = 10; |
|---|
| 3914 | 4056 | do { |
|---|
| 3915 | | - reg = snd_soc_component_read32(component, WM8958_MIC_DETECT_3); |
|---|
| 4057 | + reg = snd_soc_component_read(component, WM8958_MIC_DETECT_3); |
|---|
| 3916 | 4058 | if (reg < 0) { |
|---|
| 3917 | 4059 | dev_err(component->dev, |
|---|
| 3918 | 4060 | "Failed to read mic detect status: %d\n", |
|---|
| .. | .. |
|---|
| 3941 | 4083 | |
|---|
| 3942 | 4084 | /* Avoid a transient report when the accessory is being removed */ |
|---|
| 3943 | 4085 | if (wm8994->jackdet) { |
|---|
| 3944 | | - ret = snd_soc_component_read32(component, WM1811_JACKDET_CTRL); |
|---|
| 4086 | + ret = snd_soc_component_read(component, WM1811_JACKDET_CTRL); |
|---|
| 3945 | 4087 | if (ret < 0) { |
|---|
| 3946 | 4088 | dev_err(component->dev, "Failed to read jack status: %d\n", |
|---|
| 3947 | 4089 | ret); |
|---|
| .. | .. |
|---|
| 4234 | 4376 | wm8994_vu_bits[i].mask, |
|---|
| 4235 | 4377 | wm8994_vu_bits[i].mask); |
|---|
| 4236 | 4378 | |
|---|
| 4379 | + if (control->type != WM1811) { |
|---|
| 4380 | + for (i = 0; i < ARRAY_SIZE(wm8994_adc2_dac2_vu_bits); i++) |
|---|
| 4381 | + snd_soc_component_update_bits(component, |
|---|
| 4382 | + wm8994_adc2_dac2_vu_bits[i].reg, |
|---|
| 4383 | + wm8994_adc2_dac2_vu_bits[i].mask, |
|---|
| 4384 | + wm8994_adc2_dac2_vu_bits[i].mask); |
|---|
| 4385 | + } |
|---|
| 4386 | + |
|---|
| 4237 | 4387 | /* Set the low bit of the 3D stereo depth so TLV matches */ |
|---|
| 4238 | 4388 | snd_soc_component_update_bits(component, WM8994_AIF1_DAC1_FILTERS_2, |
|---|
| 4239 | 4389 | 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT, |
|---|
| .. | .. |
|---|
| 4470 | 4620 | static int wm8994_probe(struct platform_device *pdev) |
|---|
| 4471 | 4621 | { |
|---|
| 4472 | 4622 | struct wm8994_priv *wm8994; |
|---|
| 4623 | + int ret; |
|---|
| 4473 | 4624 | |
|---|
| 4474 | 4625 | wm8994 = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_priv), |
|---|
| 4475 | 4626 | GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 4481 | 4632 | |
|---|
| 4482 | 4633 | wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); |
|---|
| 4483 | 4634 | |
|---|
| 4635 | + wm8994->mclk[WM8994_MCLK1].id = "MCLK1"; |
|---|
| 4636 | + wm8994->mclk[WM8994_MCLK2].id = "MCLK2"; |
|---|
| 4637 | + |
|---|
| 4638 | + ret = devm_clk_bulk_get_optional(pdev->dev.parent, ARRAY_SIZE(wm8994->mclk), |
|---|
| 4639 | + wm8994->mclk); |
|---|
| 4640 | + if (ret < 0) { |
|---|
| 4641 | + dev_err(&pdev->dev, "Failed to get clocks: %d\n", ret); |
|---|
| 4642 | + return ret; |
|---|
| 4643 | + } |
|---|
| 4644 | + |
|---|
| 4484 | 4645 | pm_runtime_enable(&pdev->dev); |
|---|
| 4485 | 4646 | pm_runtime_idle(&pdev->dev); |
|---|
| 4486 | 4647 | |
|---|
| 4487 | | - return devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_wm8994, |
|---|
| 4648 | + ret = devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_wm8994, |
|---|
| 4488 | 4649 | wm8994_dai, ARRAY_SIZE(wm8994_dai)); |
|---|
| 4650 | + if (ret < 0) |
|---|
| 4651 | + pm_runtime_disable(&pdev->dev); |
|---|
| 4652 | + |
|---|
| 4653 | + return ret; |
|---|
| 4489 | 4654 | } |
|---|
| 4490 | 4655 | |
|---|
| 4491 | 4656 | static int wm8994_remove(struct platform_device *pdev) |
|---|