| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * wm8400.c -- WM8400 ALSA Soc Audio driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2008-11 Wolfson Microelectronics PLC. |
|---|
| 5 | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 8 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 9 | | - * Free Software Foundation; either version 2 of the License, or (at your |
|---|
| 10 | | - * option) any later version. |
|---|
| 11 | | - * |
|---|
| 12 | 7 | */ |
|---|
| 13 | 8 | |
|---|
| 14 | 9 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 72 | 67 | wm8400_reset_codec_reg_cache(wm8400->wm8400); |
|---|
| 73 | 68 | } |
|---|
| 74 | 69 | |
|---|
| 75 | | -static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0); |
|---|
| 76 | | - |
|---|
| 77 | 70 | static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0); |
|---|
| 78 | 71 | |
|---|
| 79 | 72 | static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -2100, 0, 0); |
|---|
| 80 | 73 | |
|---|
| 81 | 74 | static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0); |
|---|
| 82 | | - |
|---|
| 83 | | -static const DECLARE_TLV_DB_SCALE(out_omix_tlv, -600, 0, 0); |
|---|
| 84 | 75 | |
|---|
| 85 | 76 | static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0); |
|---|
| 86 | 77 | |
|---|
| .. | .. |
|---|
| 103 | 94 | return ret; |
|---|
| 104 | 95 | |
|---|
| 105 | 96 | /* now hit the volume update bits (always bit 8) */ |
|---|
| 106 | | - val = snd_soc_component_read32(component, reg); |
|---|
| 97 | + val = snd_soc_component_read(component, reg); |
|---|
| 107 | 98 | return snd_soc_component_write(component, reg, val | 0x0100); |
|---|
| 108 | 99 | } |
|---|
| 109 | 100 | |
|---|
| .. | .. |
|---|
| 333 | 324 | |
|---|
| 334 | 325 | switch (reg_shift) { |
|---|
| 335 | 326 | case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) : |
|---|
| 336 | | - reg = snd_soc_component_read32(component, WM8400_OUTPUT_MIXER1); |
|---|
| 327 | + reg = snd_soc_component_read(component, WM8400_OUTPUT_MIXER1); |
|---|
| 337 | 328 | if (reg & WM8400_LDLO) { |
|---|
| 338 | 329 | printk(KERN_WARNING |
|---|
| 339 | 330 | "Cannot set as Output Mixer 1 LDLO Set\n"); |
|---|
| .. | .. |
|---|
| 341 | 332 | } |
|---|
| 342 | 333 | break; |
|---|
| 343 | 334 | case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8): |
|---|
| 344 | | - reg = snd_soc_component_read32(component, WM8400_OUTPUT_MIXER2); |
|---|
| 335 | + reg = snd_soc_component_read(component, WM8400_OUTPUT_MIXER2); |
|---|
| 345 | 336 | if (reg & WM8400_RDRO) { |
|---|
| 346 | 337 | printk(KERN_WARNING |
|---|
| 347 | 338 | "Cannot set as Output Mixer 2 RDRO Set\n"); |
|---|
| .. | .. |
|---|
| 349 | 340 | } |
|---|
| 350 | 341 | break; |
|---|
| 351 | 342 | case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8): |
|---|
| 352 | | - reg = snd_soc_component_read32(component, WM8400_SPEAKER_MIXER); |
|---|
| 343 | + reg = snd_soc_component_read(component, WM8400_SPEAKER_MIXER); |
|---|
| 353 | 344 | if (reg & WM8400_LDSPK) { |
|---|
| 354 | 345 | printk(KERN_WARNING |
|---|
| 355 | 346 | "Cannot set as Speaker Mixer LDSPK Set\n"); |
|---|
| .. | .. |
|---|
| 357 | 348 | } |
|---|
| 358 | 349 | break; |
|---|
| 359 | 350 | case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8): |
|---|
| 360 | | - reg = snd_soc_component_read32(component, WM8400_SPEAKER_MIXER); |
|---|
| 351 | + reg = snd_soc_component_read(component, WM8400_SPEAKER_MIXER); |
|---|
| 361 | 352 | if (reg & WM8400_RDSPK) { |
|---|
| 362 | 353 | printk(KERN_WARNING |
|---|
| 363 | 354 | "Cannot set as Speaker Mixer RDSPK Set\n"); |
|---|
| .. | .. |
|---|
| 443 | 434 | |
|---|
| 444 | 435 | static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = |
|---|
| 445 | 436 | SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); |
|---|
| 446 | | - |
|---|
| 447 | | -/* RXVOICE */ |
|---|
| 448 | | -static const struct snd_kcontrol_new wm8400_dapm_rxvoice_controls[] = { |
|---|
| 449 | | -SOC_DAPM_SINGLE_TLV("LIN4/RXN", WM8400_INPUT_MIXER5, WM8400_LR4BVOL_SHIFT, |
|---|
| 450 | | - WM8400_LR4BVOL_MASK, 0, in_mix_tlv), |
|---|
| 451 | | -SOC_DAPM_SINGLE_TLV("RIN4/RXP", WM8400_INPUT_MIXER6, WM8400_RL4BVOL_SHIFT, |
|---|
| 452 | | - WM8400_RL4BVOL_MASK, 0, in_mix_tlv), |
|---|
| 453 | | -}; |
|---|
| 454 | 437 | |
|---|
| 455 | 438 | /* LOMIX */ |
|---|
| 456 | 439 | static const struct snd_kcontrol_new wm8400_dapm_lomix_controls[] = { |
|---|
| .. | .. |
|---|
| 962 | 945 | wm8400->fll_in = freq_in; |
|---|
| 963 | 946 | |
|---|
| 964 | 947 | /* We *must* disable the FLL before any changes */ |
|---|
| 965 | | - reg = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_2); |
|---|
| 948 | + reg = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_2); |
|---|
| 966 | 949 | reg &= ~WM8400_FLL_ENA; |
|---|
| 967 | 950 | snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_2, reg); |
|---|
| 968 | 951 | |
|---|
| 969 | | - reg = snd_soc_component_read32(component, WM8400_FLL_CONTROL_1); |
|---|
| 952 | + reg = snd_soc_component_read(component, WM8400_FLL_CONTROL_1); |
|---|
| 970 | 953 | reg &= ~WM8400_FLL_OSC_ENA; |
|---|
| 971 | 954 | snd_soc_component_write(component, WM8400_FLL_CONTROL_1, reg); |
|---|
| 972 | 955 | |
|---|
| .. | .. |
|---|
| 981 | 964 | snd_soc_component_write(component, WM8400_FLL_CONTROL_2, factors.k); |
|---|
| 982 | 965 | snd_soc_component_write(component, WM8400_FLL_CONTROL_3, factors.n); |
|---|
| 983 | 966 | |
|---|
| 984 | | - reg = snd_soc_component_read32(component, WM8400_FLL_CONTROL_4); |
|---|
| 967 | + reg = snd_soc_component_read(component, WM8400_FLL_CONTROL_4); |
|---|
| 985 | 968 | reg &= ~WM8400_FLL_OUTDIV_MASK; |
|---|
| 986 | 969 | reg |= factors.outdiv; |
|---|
| 987 | 970 | snd_soc_component_write(component, WM8400_FLL_CONTROL_4, reg); |
|---|
| .. | .. |
|---|
| 998 | 981 | struct snd_soc_component *component = codec_dai->component; |
|---|
| 999 | 982 | u16 audio1, audio3; |
|---|
| 1000 | 983 | |
|---|
| 1001 | | - audio1 = snd_soc_component_read32(component, WM8400_AUDIO_INTERFACE_1); |
|---|
| 1002 | | - audio3 = snd_soc_component_read32(component, WM8400_AUDIO_INTERFACE_3); |
|---|
| 984 | + audio1 = snd_soc_component_read(component, WM8400_AUDIO_INTERFACE_1); |
|---|
| 985 | + audio3 = snd_soc_component_read(component, WM8400_AUDIO_INTERFACE_3); |
|---|
| 1003 | 986 | |
|---|
| 1004 | 987 | /* set master/slave audio interface */ |
|---|
| 1005 | 988 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
|---|
| .. | .. |
|---|
| 1053 | 1036 | |
|---|
| 1054 | 1037 | switch (div_id) { |
|---|
| 1055 | 1038 | case WM8400_MCLK_DIV: |
|---|
| 1056 | | - reg = snd_soc_component_read32(component, WM8400_CLOCKING_2) & |
|---|
| 1039 | + reg = snd_soc_component_read(component, WM8400_CLOCKING_2) & |
|---|
| 1057 | 1040 | ~WM8400_MCLK_DIV_MASK; |
|---|
| 1058 | 1041 | snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div); |
|---|
| 1059 | 1042 | break; |
|---|
| 1060 | 1043 | case WM8400_DACCLK_DIV: |
|---|
| 1061 | | - reg = snd_soc_component_read32(component, WM8400_CLOCKING_2) & |
|---|
| 1044 | + reg = snd_soc_component_read(component, WM8400_CLOCKING_2) & |
|---|
| 1062 | 1045 | ~WM8400_DAC_CLKDIV_MASK; |
|---|
| 1063 | 1046 | snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div); |
|---|
| 1064 | 1047 | break; |
|---|
| 1065 | 1048 | case WM8400_ADCCLK_DIV: |
|---|
| 1066 | | - reg = snd_soc_component_read32(component, WM8400_CLOCKING_2) & |
|---|
| 1049 | + reg = snd_soc_component_read(component, WM8400_CLOCKING_2) & |
|---|
| 1067 | 1050 | ~WM8400_ADC_CLKDIV_MASK; |
|---|
| 1068 | 1051 | snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div); |
|---|
| 1069 | 1052 | break; |
|---|
| 1070 | 1053 | case WM8400_BCLK_DIV: |
|---|
| 1071 | | - reg = snd_soc_component_read32(component, WM8400_CLOCKING_1) & |
|---|
| 1054 | + reg = snd_soc_component_read(component, WM8400_CLOCKING_1) & |
|---|
| 1072 | 1055 | ~WM8400_BCLK_DIV_MASK; |
|---|
| 1073 | 1056 | snd_soc_component_write(component, WM8400_CLOCKING_1, reg | div); |
|---|
| 1074 | 1057 | break; |
|---|
| .. | .. |
|---|
| 1087 | 1070 | struct snd_soc_dai *dai) |
|---|
| 1088 | 1071 | { |
|---|
| 1089 | 1072 | struct snd_soc_component *component = dai->component; |
|---|
| 1090 | | - u16 audio1 = snd_soc_component_read32(component, WM8400_AUDIO_INTERFACE_1); |
|---|
| 1073 | + u16 audio1 = snd_soc_component_read(component, WM8400_AUDIO_INTERFACE_1); |
|---|
| 1091 | 1074 | |
|---|
| 1092 | 1075 | audio1 &= ~WM8400_AIF_WL_MASK; |
|---|
| 1093 | 1076 | /* bit size */ |
|---|
| .. | .. |
|---|
| 1109 | 1092 | return 0; |
|---|
| 1110 | 1093 | } |
|---|
| 1111 | 1094 | |
|---|
| 1112 | | -static int wm8400_mute(struct snd_soc_dai *dai, int mute) |
|---|
| 1095 | +static int wm8400_mute(struct snd_soc_dai *dai, int mute, int direction) |
|---|
| 1113 | 1096 | { |
|---|
| 1114 | 1097 | struct snd_soc_component *component = dai->component; |
|---|
| 1115 | | - u16 val = snd_soc_component_read32(component, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE; |
|---|
| 1098 | + u16 val = snd_soc_component_read(component, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE; |
|---|
| 1116 | 1099 | |
|---|
| 1117 | 1100 | if (mute) |
|---|
| 1118 | 1101 | snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); |
|---|
| .. | .. |
|---|
| 1136 | 1119 | |
|---|
| 1137 | 1120 | case SND_SOC_BIAS_PREPARE: |
|---|
| 1138 | 1121 | /* VMID=2*50k */ |
|---|
| 1139 | | - val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1) & |
|---|
| 1122 | + val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1) & |
|---|
| 1140 | 1123 | ~WM8400_VMID_MODE_MASK; |
|---|
| 1141 | 1124 | snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x2); |
|---|
| 1142 | 1125 | break; |
|---|
| .. | .. |
|---|
| 1162 | 1145 | msleep(50); |
|---|
| 1163 | 1146 | |
|---|
| 1164 | 1147 | /* Enable VREF & VMID at 2x50k */ |
|---|
| 1165 | | - val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1); |
|---|
| 1148 | + val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1); |
|---|
| 1166 | 1149 | val |= 0x2 | WM8400_VREF_ENA; |
|---|
| 1167 | 1150 | snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val); |
|---|
| 1168 | 1151 | |
|---|
| .. | .. |
|---|
| 1176 | 1159 | } |
|---|
| 1177 | 1160 | |
|---|
| 1178 | 1161 | /* VMID=2*300k */ |
|---|
| 1179 | | - val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1) & |
|---|
| 1162 | + val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1) & |
|---|
| 1180 | 1163 | ~WM8400_VMID_MODE_MASK; |
|---|
| 1181 | 1164 | snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x4); |
|---|
| 1182 | 1165 | break; |
|---|
| .. | .. |
|---|
| 1192 | 1175 | WM8400_BUFIOEN); |
|---|
| 1193 | 1176 | |
|---|
| 1194 | 1177 | /* mute DAC */ |
|---|
| 1195 | | - val = snd_soc_component_read32(component, WM8400_DAC_CTRL); |
|---|
| 1178 | + val = snd_soc_component_read(component, WM8400_DAC_CTRL); |
|---|
| 1196 | 1179 | snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); |
|---|
| 1197 | 1180 | |
|---|
| 1198 | 1181 | /* Enable any disabled outputs */ |
|---|
| 1199 | | - val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1); |
|---|
| 1182 | + val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1); |
|---|
| 1200 | 1183 | val |= WM8400_SPK_ENA | WM8400_OUT3_ENA | |
|---|
| 1201 | 1184 | WM8400_OUT4_ENA | WM8400_LOUT_ENA | |
|---|
| 1202 | 1185 | WM8400_ROUT_ENA; |
|---|
| .. | .. |
|---|
| 1239 | 1222 | |
|---|
| 1240 | 1223 | static const struct snd_soc_dai_ops wm8400_dai_ops = { |
|---|
| 1241 | 1224 | .hw_params = wm8400_hw_params, |
|---|
| 1242 | | - .digital_mute = wm8400_mute, |
|---|
| 1225 | + .mute_stream = wm8400_mute, |
|---|
| 1243 | 1226 | .set_fmt = wm8400_set_dai_fmt, |
|---|
| 1244 | 1227 | .set_clkdiv = wm8400_set_dai_clkdiv, |
|---|
| 1245 | 1228 | .set_sysclk = wm8400_set_dai_sysclk, |
|---|
| 1246 | 1229 | .set_pll = wm8400_set_dai_pll, |
|---|
| 1230 | + .no_capture_mute = 1, |
|---|
| 1247 | 1231 | }; |
|---|
| 1248 | 1232 | |
|---|
| 1249 | 1233 | /* |
|---|
| .. | .. |
|---|
| 1298 | 1282 | |
|---|
| 1299 | 1283 | wm8400_component_reset(component); |
|---|
| 1300 | 1284 | |
|---|
| 1301 | | - reg = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1); |
|---|
| 1285 | + reg = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1); |
|---|
| 1302 | 1286 | snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA); |
|---|
| 1303 | 1287 | |
|---|
| 1304 | 1288 | /* Latch volume update bits */ |
|---|
| 1305 | | - reg = snd_soc_component_read32(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME); |
|---|
| 1289 | + reg = snd_soc_component_read(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME); |
|---|
| 1306 | 1290 | snd_soc_component_write(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME, |
|---|
| 1307 | 1291 | reg & WM8400_IPVU); |
|---|
| 1308 | | - reg = snd_soc_component_read32(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME); |
|---|
| 1292 | + reg = snd_soc_component_read(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME); |
|---|
| 1309 | 1293 | snd_soc_component_write(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, |
|---|
| 1310 | 1294 | reg & WM8400_IPVU); |
|---|
| 1311 | 1295 | |
|---|
| .. | .. |
|---|
| 1319 | 1303 | { |
|---|
| 1320 | 1304 | u16 reg; |
|---|
| 1321 | 1305 | |
|---|
| 1322 | | - reg = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1); |
|---|
| 1306 | + reg = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1); |
|---|
| 1323 | 1307 | snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, |
|---|
| 1324 | 1308 | reg & (~WM8400_CODEC_ENA)); |
|---|
| 1325 | 1309 | } |
|---|