1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. 3 // Copyright (c) 2025, Linaro Ltd 4 5 #include <linux/component.h> 6 #include <linux/delay.h> 7 #include <linux/device.h> 8 #include <linux/kernel.h> 9 #include <linux/module.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/pm_runtime.h> 13 #include <linux/regmap.h> 14 #include <linux/regulator/consumer.h> 15 #include <linux/slab.h> 16 #include <sound/jack.h> 17 #include <sound/pcm.h> 18 #include <sound/pcm_params.h> 19 #include <sound/soc.h> 20 #include <sound/soc-dapm.h> 21 #include <sound/tlv.h> 22 23 #include "pm4125.h" 24 #include "wcd-mbhc-v2.h" 25 26 #define WCD_MBHC_HS_V_MAX 1600 27 #define PM4125_MBHC_MAX_BUTTONS 8 28 29 #define PM4125_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 30 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ 31 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ 32 SNDRV_PCM_RATE_384000) 33 34 /* Fractional Rates */ 35 #define PM4125_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ 36 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800) 37 38 #define PM4125_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ 39 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 40 41 /* Registers in SPMI addr space */ 42 #define PM4125_CODEC_RESET_REG 0xF3DB 43 #define PM4125_CODEC_OFF 0x1 44 #define PM4125_CODEC_ON 0x0 45 #define PM4125_CODEC_FOUNDRY_ID_REG 0x7 46 47 enum { 48 HPH_COMP_DELAY, 49 HPH_PA_DELAY, 50 AMIC2_BCS_ENABLE, 51 }; 52 53 enum { 54 AIF1_PB = 0, 55 AIF1_CAP, 56 NUM_CODEC_DAIS, 57 }; 58 59 struct pm4125_priv { 60 struct sdw_slave *tx_sdw_dev; 61 struct pm4125_sdw_priv *sdw_priv[NUM_CODEC_DAIS]; 62 struct device *txdev; 63 struct device *rxdev; 64 struct device_node *rxnode; 65 struct device_node *txnode; 66 struct regmap *regmap; 67 struct regmap *spmi_regmap; 68 /* mbhc module */ 69 struct wcd_mbhc *wcd_mbhc; 70 struct wcd_mbhc_config mbhc_cfg; 71 struct wcd_mbhc_intr intr_ids; 72 struct wcd_common common; 73 struct irq_domain *virq; 74 const struct regmap_irq_chip *chip_desc; 75 struct regmap_irq_chip_data *irq_chip; 76 struct snd_soc_jack *jack; 77 unsigned long status_mask; 78 s32 micb_ref[PM4125_MAX_MICBIAS]; 79 s32 pullup_ref[PM4125_MAX_MICBIAS]; 80 81 int hphr_pdm_wd_int; 82 int hphl_pdm_wd_int; 83 bool comp1_enable; 84 bool comp2_enable; 85 86 atomic_t gloal_mbias_cnt; 87 }; 88 89 static const char * const pm4125_power_supplies[] = { 90 "vdd-io", "vdd-cp", "vdd-mic-bias", "vdd-pa-vpos", 91 }; 92 93 static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); 94 static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); 95 96 static const struct wcd_mbhc_field pm4125_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = { 97 WCD_MBHC_FIELD(WCD_MBHC_L_DET_EN, PM4125_ANA_MBHC_MECH, 0x80), 98 WCD_MBHC_FIELD(WCD_MBHC_GND_DET_EN, PM4125_ANA_MBHC_MECH, 0x40), 99 WCD_MBHC_FIELD(WCD_MBHC_MECH_DETECTION_TYPE, PM4125_ANA_MBHC_MECH, 0x20), 100 WCD_MBHC_FIELD(WCD_MBHC_MIC_CLAMP_CTL, PM4125_ANA_MBHC_PLUG_DETECT_CTL, 0x30), 101 WCD_MBHC_FIELD(WCD_MBHC_ELECT_DETECTION_TYPE, PM4125_ANA_MBHC_ELECT, 0x08), 102 WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, PM4125_ANA_MBHC_PLUG_DETECT_CTL, 0x1F), 103 WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, PM4125_ANA_MBHC_MECH, 0x04), 104 WCD_MBHC_FIELD(WCD_MBHC_HPHL_PLUG_TYPE, PM4125_ANA_MBHC_MECH, 0x10), 105 WCD_MBHC_FIELD(WCD_MBHC_GND_PLUG_TYPE, PM4125_ANA_MBHC_MECH, 0x08), 106 WCD_MBHC_FIELD(WCD_MBHC_SW_HPH_LP_100K_TO_GND, PM4125_ANA_MBHC_MECH, 0x01), 107 WCD_MBHC_FIELD(WCD_MBHC_ELECT_SCHMT_ISRC, PM4125_ANA_MBHC_ELECT, 0x06), 108 WCD_MBHC_FIELD(WCD_MBHC_FSM_EN, PM4125_ANA_MBHC_ELECT, 0x80), 109 WCD_MBHC_FIELD(WCD_MBHC_INSREM_DBNC, PM4125_ANA_MBHC_PLUG_DETECT_CTL, 0x0F), 110 WCD_MBHC_FIELD(WCD_MBHC_BTN_DBNC, PM4125_ANA_MBHC_CTL_1, 0x03), 111 WCD_MBHC_FIELD(WCD_MBHC_HS_VREF, PM4125_ANA_MBHC_CTL_2, 0x03), 112 WCD_MBHC_FIELD(WCD_MBHC_HS_COMP_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x08), 113 WCD_MBHC_FIELD(WCD_MBHC_IN2P_CLAMP_STATE, PM4125_ANA_MBHC_RESULT_3, 0x10), 114 WCD_MBHC_FIELD(WCD_MBHC_MIC_SCHMT_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x20), 115 WCD_MBHC_FIELD(WCD_MBHC_HPHL_SCHMT_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x80), 116 WCD_MBHC_FIELD(WCD_MBHC_HPHR_SCHMT_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x40), 117 WCD_MBHC_FIELD(WCD_MBHC_BTN_RESULT, PM4125_ANA_MBHC_RESULT_3, 0x07), 118 WCD_MBHC_FIELD(WCD_MBHC_BTN_ISRC_CTL, PM4125_ANA_MBHC_ELECT, 0x70), 119 WCD_MBHC_FIELD(WCD_MBHC_ELECT_RESULT, PM4125_ANA_MBHC_RESULT_3, 0xFF), 120 WCD_MBHC_FIELD(WCD_MBHC_MICB_CTRL, PM4125_ANA_MICBIAS_MICB_1_2_EN, 0xC0), 121 WCD_MBHC_FIELD(WCD_MBHC_HPHR_PA_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0x40), 122 WCD_MBHC_FIELD(WCD_MBHC_HPHL_PA_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0x80), 123 WCD_MBHC_FIELD(WCD_MBHC_HPH_PA_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0xC0), 124 WCD_MBHC_FIELD(WCD_MBHC_SWCH_LEVEL_REMOVE, PM4125_ANA_MBHC_RESULT_3, 0x10), 125 WCD_MBHC_FIELD(WCD_MBHC_FSM_STATUS, PM4125_ANA_MBHC_FSM_STATUS, 0x01), 126 WCD_MBHC_FIELD(WCD_MBHC_MUX_CTL, PM4125_ANA_MBHC_CTL_2, 0x70), 127 WCD_MBHC_FIELD(WCD_MBHC_MOISTURE_STATUS, PM4125_ANA_MBHC_FSM_STATUS, 0x20), 128 WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_DET_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0x01), 129 WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_DET_EN, PM4125_ANA_HPHPA_CNP_CTL_2, 0x01), 130 WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_STATUS, PM4125_DIG_SWR_INTR_STATUS_0, 0x80), 131 WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_STATUS, PM4125_DIG_SWR_INTR_STATUS_0, 0x20), 132 WCD_MBHC_FIELD(WCD_MBHC_ADC_EN, PM4125_ANA_MBHC_CTL_1, 0x08), 133 WCD_MBHC_FIELD(WCD_MBHC_ADC_COMPLETE, PM4125_ANA_MBHC_FSM_STATUS, 0x40), 134 WCD_MBHC_FIELD(WCD_MBHC_ADC_TIMEOUT, PM4125_ANA_MBHC_FSM_STATUS, 0x80), 135 WCD_MBHC_FIELD(WCD_MBHC_ADC_RESULT, PM4125_ANA_MBHC_ADC_RESULT, 0xFF), 136 WCD_MBHC_FIELD(WCD_MBHC_MICB2_VOUT, PM4125_ANA_MICBIAS_LDO_1_SETTING, 0x3F), 137 WCD_MBHC_FIELD(WCD_MBHC_ADC_MODE, PM4125_ANA_MBHC_CTL_1, 0x10), 138 WCD_MBHC_FIELD(WCD_MBHC_DETECTION_DONE, PM4125_ANA_MBHC_CTL_1, 0x04), 139 WCD_MBHC_FIELD(WCD_MBHC_ELECT_ISRC_EN, PM4125_ANA_MBHC_ZDET, 0x02), 140 }; 141 142 static const struct regmap_irq pm4125_irqs[PM4125_NUM_IRQS] = { 143 REGMAP_IRQ_REG(PM4125_IRQ_MBHC_BUTTON_PRESS_DET, 0, BIT(0)), 144 REGMAP_IRQ_REG(PM4125_IRQ_MBHC_BUTTON_RELEASE_DET, 0, BIT(1)), 145 REGMAP_IRQ_REG(PM4125_IRQ_MBHC_ELECT_INS_REM_DET, 0, BIT(2)), 146 REGMAP_IRQ_REG(PM4125_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, BIT(3)), 147 REGMAP_IRQ_REG(PM4125_IRQ_MBHC_SW_DET, 0, BIT(4)), 148 REGMAP_IRQ_REG(PM4125_IRQ_HPHR_OCP_INT, 0, BIT(5)), 149 REGMAP_IRQ_REG(PM4125_IRQ_HPHR_CNP_INT, 0, BIT(6)), 150 REGMAP_IRQ_REG(PM4125_IRQ_HPHL_OCP_INT, 0, BIT(7)), 151 REGMAP_IRQ_REG(PM4125_IRQ_HPHL_CNP_INT, 1, BIT(0)), 152 REGMAP_IRQ_REG(PM4125_IRQ_EAR_CNP_INT, 1, BIT(1)), 153 REGMAP_IRQ_REG(PM4125_IRQ_EAR_SCD_INT, 1, BIT(2)), 154 REGMAP_IRQ_REG(PM4125_IRQ_AUX_CNP_INT, 1, BIT(3)), 155 REGMAP_IRQ_REG(PM4125_IRQ_AUX_SCD_INT, 1, BIT(4)), 156 REGMAP_IRQ_REG(PM4125_IRQ_HPHL_PDM_WD_INT, 1, BIT(5)), 157 REGMAP_IRQ_REG(PM4125_IRQ_HPHR_PDM_WD_INT, 1, BIT(6)), 158 REGMAP_IRQ_REG(PM4125_IRQ_AUX_PDM_WD_INT, 1, BIT(7)), 159 REGMAP_IRQ_REG(PM4125_IRQ_LDORT_SCD_INT, 2, BIT(0)), 160 REGMAP_IRQ_REG(PM4125_IRQ_MBHC_MOISTURE_INT, 2, BIT(1)), 161 REGMAP_IRQ_REG(PM4125_IRQ_HPHL_SURGE_DET_INT, 2, BIT(2)), 162 REGMAP_IRQ_REG(PM4125_IRQ_HPHR_SURGE_DET_INT, 2, BIT(3)), 163 }; 164 165 static int pm4125_handle_post_irq(void *data) 166 { 167 struct pm4125_priv *pm4125 = (struct pm4125_priv *)data; 168 169 regmap_write(pm4125->regmap, PM4125_DIG_SWR_INTR_CLEAR_0, 0); 170 regmap_write(pm4125->regmap, PM4125_DIG_SWR_INTR_CLEAR_1, 0); 171 regmap_write(pm4125->regmap, PM4125_DIG_SWR_INTR_CLEAR_2, 0); 172 173 return IRQ_HANDLED; 174 } 175 176 static const u32 pm4125_config_regs[] = { 177 PM4125_DIG_SWR_INTR_LEVEL_0, 178 }; 179 180 static const struct regmap_irq_chip pm4125_regmap_irq_chip = { 181 .name = "pm4125", 182 .irqs = pm4125_irqs, 183 .num_irqs = ARRAY_SIZE(pm4125_irqs), 184 .num_regs = 3, 185 .status_base = PM4125_DIG_SWR_INTR_STATUS_0, 186 .mask_base = PM4125_DIG_SWR_INTR_MASK_0, 187 .ack_base = PM4125_DIG_SWR_INTR_CLEAR_0, 188 .use_ack = 1, 189 .clear_ack = 1, 190 .config_base = pm4125_config_regs, 191 .num_config_bases = ARRAY_SIZE(pm4125_config_regs), 192 .num_config_regs = 1, 193 .runtime_pm = true, 194 .handle_post_irq = pm4125_handle_post_irq, 195 }; 196 197 static void pm4125_reset(struct pm4125_priv *pm4125) 198 { 199 regmap_write(pm4125->spmi_regmap, PM4125_CODEC_RESET_REG, PM4125_CODEC_OFF); 200 usleep_range(20, 30); 201 regmap_write(pm4125->spmi_regmap, PM4125_CODEC_RESET_REG, PM4125_CODEC_ON); 202 usleep_range(5000, 5010); 203 } 204 205 static void pm4125_io_init(struct regmap *regmap) 206 { 207 /* Disable HPH OCP */ 208 regmap_update_bits(regmap, PM4125_ANA_HPHPA_CNP_CTL_2, 209 PM4125_ANA_HPHPA_CNP_OCP_EN_L_MASK | PM4125_ANA_HPHPA_CNP_OCP_EN_R_MASK, 210 PM4125_ANA_HPHPA_CNP_OCP_DISABLE); 211 212 /* Enable surge protection */ 213 regmap_update_bits(regmap, PM4125_ANA_SURGE_EN, PM4125_ANA_SURGE_PROTECTION_HPHL_MASK, 214 FIELD_PREP(PM4125_ANA_SURGE_PROTECTION_HPHL_MASK, 215 PM4125_ANA_SURGE_PROTECTION_ENABLE)); 216 regmap_update_bits(regmap, PM4125_ANA_SURGE_EN, PM4125_ANA_SURGE_PROTECTION_HPHR_MASK, 217 FIELD_PREP(PM4125_ANA_SURGE_PROTECTION_HPHR_MASK, 218 PM4125_ANA_SURGE_PROTECTION_ENABLE)); 219 220 /* Disable mic bias 2 pull down */ 221 regmap_update_bits(regmap, PM4125_ANA_MICBIAS_MICB_1_2_EN, 222 PM4125_ANA_MICBIAS_MICB2_PULL_DN_MASK, 223 FIELD_PREP(PM4125_ANA_MICBIAS_MICB2_PULL_DN_MASK, 224 PM4125_ANA_MICBIAS_MICB_PULL_DISABLE)); 225 } 226 227 static int pm4125_global_mbias_disable(struct snd_soc_component *component) 228 { 229 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 230 231 if (atomic_dec_and_test(&pm4125->gloal_mbias_cnt)) { 232 233 snd_soc_component_write_field(component, PM4125_ANA_MBIAS_EN, 234 PM4125_ANA_MBIAS_EN_V2I_MASK, 235 PM4125_ANA_MBIAS_EN_DISABLE); 236 snd_soc_component_write_field(component, PM4125_ANA_MBIAS_EN, 237 PM4125_ANA_MBIAS_EN_GLOBAL_MASK, 238 PM4125_ANA_MBIAS_EN_DISABLE); 239 } 240 241 return 0; 242 } 243 244 static int pm4125_global_mbias_enable(struct snd_soc_component *component) 245 { 246 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 247 248 if (atomic_inc_return(&pm4125->gloal_mbias_cnt) == 1) { 249 snd_soc_component_write_field(component, PM4125_ANA_MBIAS_EN, 250 PM4125_ANA_MBIAS_EN_GLOBAL_MASK, 251 PM4125_ANA_MBIAS_EN_ENABLE); 252 snd_soc_component_write_field(component, PM4125_ANA_MBIAS_EN, 253 PM4125_ANA_MBIAS_EN_V2I_MASK, 254 PM4125_ANA_MBIAS_EN_ENABLE); 255 usleep_range(1000, 1100); 256 } 257 258 return 0; 259 } 260 261 static int pm4125_rx_clk_enable(struct snd_soc_component *component) 262 { 263 pm4125_global_mbias_enable(component); 264 265 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 266 PM4125_DIG_SWR_ANA_RX_CLK_EN_MASK, 267 PM4125_DIG_SWR_RX_CLK_ENABLE); 268 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 269 PM4125_DIG_SWR_ANA_RX_DIV2_CLK_EN_MASK, 270 PM4125_DIG_SWR_RX_CLK_ENABLE); 271 usleep_range(5000, 5100); 272 273 snd_soc_component_write_field(component, PM4125_ANA_HPHPA_FSM_CLK, 274 PM4125_ANA_HPHPA_FSM_DIV_RATIO_MASK, 275 PM4125_ANA_HPHPA_FSM_DIV_RATIO_68); 276 snd_soc_component_write_field(component, PM4125_ANA_HPHPA_FSM_CLK, 277 PM4125_ANA_HPHPA_FSM_CLK_DIV_EN_MASK, 278 PM4125_ANA_HPHPA_FSM_CLK_DIV_ENABLE); 279 snd_soc_component_update_bits(component, PM4125_ANA_NCP_VCTRL, 0x07, 0x06); 280 snd_soc_component_write_field(component, PM4125_ANA_NCP_EN, 281 PM4125_ANA_NCP_ENABLE_MASK, 282 PM4125_ANA_NCP_ENABLE); 283 usleep_range(500, 510); 284 285 return 0; 286 } 287 288 static int pm4125_rx_clk_disable(struct snd_soc_component *component) 289 { 290 291 snd_soc_component_write_field(component, PM4125_ANA_HPHPA_FSM_CLK, 292 PM4125_ANA_HPHPA_FSM_CLK_DIV_EN_MASK, 293 PM4125_ANA_HPHPA_FSM_CLK_DIV_DISABLE); 294 snd_soc_component_write_field(component, PM4125_ANA_HPHPA_FSM_CLK, 295 PM4125_ANA_HPHPA_FSM_DIV_RATIO_MASK, 296 0x00); 297 snd_soc_component_write_field(component, PM4125_ANA_NCP_EN, 298 PM4125_ANA_NCP_ENABLE_MASK, 299 PM4125_ANA_NCP_DISABLE); 300 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 301 PM4125_DIG_SWR_ANA_RX_DIV2_CLK_EN_MASK, 302 PM4125_DIG_SWR_RX_CLK_DISABLE); 303 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 304 PM4125_DIG_SWR_ANA_RX_CLK_EN_MASK, 305 PM4125_DIG_SWR_RX_CLK_DISABLE); 306 307 pm4125_global_mbias_disable(component); 308 309 return 0; 310 } 311 312 313 static int pm4125_codec_enable_rxclk(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 314 int event) 315 { 316 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 317 318 switch (event) { 319 case SND_SOC_DAPM_PRE_PMU: 320 pm4125_rx_clk_enable(component); 321 break; 322 case SND_SOC_DAPM_POST_PMD: 323 pm4125_rx_clk_disable(component); 324 break; 325 } 326 327 return 0; 328 } 329 330 static int pm4125_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 331 struct snd_kcontrol *kcontrol, int event) 332 { 333 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 334 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 335 336 switch (event) { 337 case SND_SOC_DAPM_PRE_PMU: 338 snd_soc_component_write_field(component, PM4125_ANA_HPHPA_CNP_CTL_1, 339 PM4125_ANA_HPHPA_CNP_CTL_1_EN_MASK, 340 PM4125_ANA_HPHPA_CNP_CTL_1_EN); 341 snd_soc_component_write_field(component, PM4125_SWR_HPHPA_HD2, 342 PM4125_SWR_HPHPA_HD2_LEFT_MASK, 343 PM4125_SWR_HPHPA_HD2_ENABLE); 344 break; 345 case SND_SOC_DAPM_POST_PMU: 346 if (pm4125->comp1_enable) { 347 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0, 348 PM4125_DIG_SWR_COMP_HPHL_EN_MASK, 349 PM4125_DIG_SWR_COMP_ENABLE); 350 351 if (pm4125->comp2_enable) 352 snd_soc_component_write_field(component, 353 PM4125_DIG_SWR_CDC_COMP_CTL_0, 354 PM4125_DIG_SWR_COMP_HPHR_EN_MASK, 355 PM4125_DIG_SWR_COMP_ENABLE); 356 /* 357 * 5ms sleep is required after COMP is enabled as per 358 * HW requirement 359 */ 360 usleep_range(5000, 5100); 361 } else { 362 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0, 363 PM4125_DIG_SWR_COMP_HPHL_EN_MASK, 364 PM4125_DIG_SWR_COMP_DISABLE); 365 } 366 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX0_CTL, 367 PM4125_DIG_SWR_DSM_DITHER_EN_MASK, 368 PM4125_DIG_SWR_DSM_DITHER_DISABLE); 369 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL, 370 PM4125_DIG_SWR_RX0_EN_MASK, 371 PM4125_DIG_SWR_RX_INPUT_ENABLE); 372 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 373 PM4125_DIG_SWR_RX0_CLK_EN_MASK, 374 PM4125_DIG_SWR_RX_CLK_ENABLE); 375 break; 376 case SND_SOC_DAPM_POST_PMD: 377 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 378 PM4125_DIG_SWR_RX0_CLK_EN_MASK, 379 PM4125_DIG_SWR_RX_CLK_DISABLE); 380 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL, 381 PM4125_DIG_SWR_RX0_EN_MASK, 382 PM4125_DIG_SWR_RX_INPUT_DISABLE); 383 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX0_CTL, 384 PM4125_DIG_SWR_DSM_DITHER_EN_MASK, 385 PM4125_DIG_SWR_DSM_DITHER_ENABLE); 386 if (pm4125->comp1_enable) 387 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0, 388 PM4125_DIG_SWR_COMP_HPHL_EN_MASK, 389 PM4125_DIG_SWR_COMP_DISABLE); 390 break; 391 } 392 393 return 0; 394 } 395 396 static int pm4125_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 397 struct snd_kcontrol *kcontrol, int event) 398 { 399 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 400 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 401 402 switch (event) { 403 case SND_SOC_DAPM_PRE_PMU: 404 snd_soc_component_write_field(component, PM4125_ANA_HPHPA_CNP_CTL_1, 405 PM4125_ANA_HPHPA_CNP_CTL_1_EN_MASK, 406 PM4125_ANA_HPHPA_CNP_CTL_1_EN); 407 snd_soc_component_write_field(component, PM4125_SWR_HPHPA_HD2, 408 PM4125_SWR_HPHPA_HD2_RIGHT_MASK, 409 PM4125_SWR_HPHPA_HD2_ENABLE); 410 break; 411 case SND_SOC_DAPM_POST_PMU: 412 if (pm4125->comp2_enable) { 413 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0, 414 PM4125_DIG_SWR_COMP_HPHR_EN_MASK, 415 PM4125_DIG_SWR_COMP_ENABLE); 416 if (pm4125->comp1_enable) 417 snd_soc_component_write_field(component, 418 PM4125_DIG_SWR_CDC_COMP_CTL_0, 419 PM4125_DIG_SWR_COMP_HPHL_EN_MASK, 420 PM4125_DIG_SWR_COMP_ENABLE); 421 /* 422 * 5ms sleep is required after COMP is enabled 423 * as per HW requirement 424 */ 425 usleep_range(5000, 5100); 426 } else { 427 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0, 428 PM4125_DIG_SWR_COMP_HPHR_EN_MASK, 429 PM4125_DIG_SWR_COMP_DISABLE); 430 } 431 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX1_CTL, 432 PM4125_DIG_SWR_DSM_DITHER_EN_MASK, 433 PM4125_DIG_SWR_DSM_DITHER_DISABLE); 434 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL, 435 PM4125_DIG_SWR_RX1_EN_MASK, 436 PM4125_DIG_SWR_RX_INPUT_ENABLE); 437 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 438 PM4125_DIG_SWR_RX1_CLK_EN_MASK, 439 PM4125_DIG_SWR_RX_CLK_ENABLE); 440 break; 441 case SND_SOC_DAPM_POST_PMD: 442 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 443 PM4125_DIG_SWR_RX1_CLK_EN_MASK, 444 PM4125_DIG_SWR_RX_CLK_DISABLE); 445 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL, 446 PM4125_DIG_SWR_RX1_EN_MASK, 447 PM4125_DIG_SWR_RX_INPUT_DISABLE); 448 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX1_CTL, 449 PM4125_DIG_SWR_DSM_DITHER_EN_MASK, 450 PM4125_DIG_SWR_DSM_DITHER_ENABLE); 451 if (pm4125->comp2_enable) 452 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_COMP_CTL_0, 453 PM4125_DIG_SWR_COMP_HPHR_EN_MASK, 454 PM4125_DIG_SWR_COMP_DISABLE); 455 break; 456 } 457 458 return 0; 459 } 460 461 static int pm4125_codec_ear_lo_dac_event(struct snd_soc_dapm_widget *w, 462 struct snd_kcontrol *kcontrol, int event) 463 { 464 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 465 466 switch (event) { 467 case SND_SOC_DAPM_PRE_PMU: 468 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX0_CTL, 469 PM4125_DIG_SWR_DSM_DITHER_EN_MASK, 470 PM4125_DIG_SWR_DSM_DITHER_DISABLE); 471 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 472 PM4125_DIG_SWR_RX0_CLK_EN_MASK, 473 PM4125_DIG_SWR_RX_CLK_ENABLE); 474 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL, 475 PM4125_DIG_SWR_RX0_EN_MASK, 476 PM4125_DIG_SWR_RX_INPUT_ENABLE); 477 break; 478 case SND_SOC_DAPM_POST_PMD: 479 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_CLK_CTL, 480 PM4125_DIG_SWR_RX0_CLK_EN_MASK, 481 PM4125_DIG_SWR_RX_CLK_DISABLE); 482 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX_GAIN_CTL, 483 PM4125_DIG_SWR_RX0_EN_MASK, 484 PM4125_DIG_SWR_RX_INPUT_DISABLE); 485 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_RX0_CTL, 486 PM4125_DIG_SWR_DSM_DITHER_EN_MASK, 487 PM4125_DIG_SWR_DSM_DITHER_ENABLE); 488 break; 489 } 490 491 return 0; 492 } 493 494 495 static int pm4125_codec_enable_hphl_wdt_irq(struct snd_soc_dapm_widget *w, 496 struct snd_kcontrol *kcontrol, int event) 497 { 498 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 499 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 500 501 switch (event) { 502 case SND_SOC_DAPM_POST_PMU: 503 usleep_range(5000, 5100); 504 enable_irq(pm4125->hphl_pdm_wd_int); 505 break; 506 case SND_SOC_DAPM_PRE_PMD: 507 disable_irq_nosync(pm4125->hphl_pdm_wd_int); 508 break; 509 } 510 511 return 0; 512 } 513 514 static int pm4125_codec_enable_hphr_wdt_irq(struct snd_soc_dapm_widget *w, 515 struct snd_kcontrol *kcontrol, int event) 516 { 517 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 518 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 519 520 switch (event) { 521 case SND_SOC_DAPM_POST_PMU: 522 usleep_range(5000, 5100); 523 enable_irq(pm4125->hphr_pdm_wd_int); 524 break; 525 case SND_SOC_DAPM_PRE_PMD: 526 disable_irq_nosync(pm4125->hphr_pdm_wd_int); 527 break; 528 } 529 530 return 0; 531 } 532 533 static int pm4125_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, 534 struct snd_kcontrol *kcontrol, int event) 535 { 536 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 537 538 switch (event) { 539 case SND_SOC_DAPM_PRE_PMU: 540 usleep_range(200, 210); 541 snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL1, 542 PM4125_WDT_ENABLE_MASK, 543 (PM4125_WDT_ENABLE_RX1_M | PM4125_WDT_ENABLE_RX1_L)); 544 break; 545 case SND_SOC_DAPM_POST_PMD: 546 usleep_range(5000, 5100); 547 snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL1, 548 PM4125_WDT_ENABLE_MASK, 0x00); 549 break; 550 } 551 552 return 0; 553 } 554 555 static int pm4125_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, 556 struct snd_kcontrol *kcontrol, int event) 557 { 558 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 559 560 switch (event) { 561 case SND_SOC_DAPM_PRE_PMU: 562 usleep_range(200, 210); 563 snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0, 564 PM4125_WDT_ENABLE_MASK, 565 (PM4125_WDT_ENABLE_RX0_M | PM4125_WDT_ENABLE_RX0_L)); 566 break; 567 case SND_SOC_DAPM_POST_PMD: 568 usleep_range(5000, 5100); 569 snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0, 570 PM4125_WDT_ENABLE_MASK, 0x00); 571 break; 572 } 573 574 return 0; 575 } 576 577 static int pm4125_codec_enable_lo_pa(struct snd_soc_dapm_widget *w, 578 struct snd_kcontrol *kcontrol, int event) 579 { 580 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 581 582 switch (event) { 583 case SND_SOC_DAPM_PRE_PMU: 584 snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_5, 0x04, 0x00); 585 usleep_range(1000, 1010); 586 snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_4, 0x0F, 0x0F); 587 usleep_range(1000, 1010); 588 snd_soc_component_write_field(component, PM4125_ANA_COMBOPA_CTL, 589 PM4125_ANA_COMBO_PA_SELECT_MASK, 590 PM4125_ANA_COMBO_PA_SELECT_LO); 591 snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0, 592 PM4125_WDT_ENABLE_MASK, 593 (PM4125_WDT_ENABLE_RX0_M | PM4125_WDT_ENABLE_RX0_L)); 594 break; 595 case SND_SOC_DAPM_POST_PMU: 596 usleep_range(5000, 5010); 597 snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_4, 0x0F, 0x04); 598 break; 599 case SND_SOC_DAPM_POST_PMD: 600 usleep_range(2000, 2010); 601 snd_soc_component_write_field(component, PM4125_ANA_COMBOPA_CTL, 602 PM4125_ANA_COMBO_PA_SELECT_MASK, 603 PM4125_ANA_COMBO_PA_SELECT_EAR); 604 usleep_range(5000, 5100); 605 snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0, 606 PM4125_WDT_ENABLE_MASK, 0x00); 607 break; 608 } 609 610 return 0; 611 } 612 613 static int pm4125_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, 614 struct snd_kcontrol *kcontrol, int event) 615 { 616 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 617 618 switch (event) { 619 case SND_SOC_DAPM_PRE_PMU: 620 snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_5, 0x04, 0x00); 621 usleep_range(1000, 1010); 622 snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_4, 0x0F, 0x0F); 623 usleep_range(1000, 1010); 624 snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL, 625 PM4125_ANA_COMBO_PA_SELECT_MASK, 626 PM4125_ANA_COMBO_PA_SELECT_EAR); 627 snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0, 628 PM4125_WDT_ENABLE_MASK, 629 (PM4125_WDT_ENABLE_RX0_M | PM4125_WDT_ENABLE_RX0_L)); 630 break; 631 case SND_SOC_DAPM_POST_PMU: 632 usleep_range(5000, 5010); 633 snd_soc_component_update_bits(component, PM4125_ANA_COMBOPA_CTL_4, 0x0F, 0x04); 634 break; 635 case SND_SOC_DAPM_POST_PMD: 636 usleep_range(5000, 5010); 637 snd_soc_component_write_field(component, PM4125_DIG_SWR_PDM_WD_CTL0, 638 PM4125_WDT_ENABLE_MASK, 0x00); 639 break; 640 } 641 642 return 0; 643 } 644 645 static int pm4125_codec_enable_adc(struct snd_soc_dapm_widget *w, 646 struct snd_kcontrol *kcontrol, int event) 647 { 648 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 649 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 650 651 switch (event) { 652 case SND_SOC_DAPM_PRE_PMU: 653 /* Enable BCS for Headset mic */ 654 if (w->shift == 1 && 655 !(snd_soc_component_read(component, PM4125_ANA_TX_AMIC2) & 0x10)) { 656 set_bit(AMIC2_BCS_ENABLE, &pm4125->status_mask); 657 } 658 pm4125_global_mbias_enable(component); 659 if (w->shift) 660 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1, 661 PM4125_DIG_SWR_TX_ANA_TXD1_MODE_MASK, 662 PM4125_DIG_SWR_TXD_MODE_NORMAL); 663 else 664 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1, 665 PM4125_DIG_SWR_TX_ANA_TXD0_MODE_MASK, 666 PM4125_DIG_SWR_TXD_MODE_NORMAL); 667 break; 668 case SND_SOC_DAPM_POST_PMD: 669 if (w->shift == 1 && test_bit(AMIC2_BCS_ENABLE, &pm4125->status_mask)) 670 clear_bit(AMIC2_BCS_ENABLE, &pm4125->status_mask); 671 672 if (w->shift) 673 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1, 674 PM4125_DIG_SWR_TX_ANA_TXD1_MODE_MASK, 675 0x00); 676 else 677 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_TX_ANA_MODE_0_1, 678 PM4125_DIG_SWR_TX_ANA_TXD0_MODE_MASK, 679 0x00); 680 pm4125_global_mbias_disable(component); 681 break; 682 } 683 684 return 0; 685 } 686 687 static int pm4125_codec_enable_dmic(struct snd_soc_dapm_widget *w, 688 struct snd_kcontrol *kcontrol, int event) 689 { 690 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 691 u16 dmic_clk_reg = w->reg; 692 693 switch (event) { 694 case SND_SOC_DAPM_PRE_PMU: 695 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_AMIC_CTL, 696 PM4125_DIG_SWR_AMIC_SELECT_MASK, 697 PM4125_DIG_SWR_AMIC_SELECT_DMIC1); 698 snd_soc_component_update_bits(component, dmic_clk_reg, 699 PM4125_DIG_SWR_DMIC1_CLK_EN_MASK, 700 PM4125_DIG_SWR_DMIC1_CLK_ENABLE); 701 break; 702 case SND_SOC_DAPM_POST_PMD: 703 snd_soc_component_update_bits(component, dmic_clk_reg, 704 PM4125_DIG_SWR_DMIC1_CLK_EN_MASK, 705 PM4125_DIG_SWR_DMIC1_CLK_DISABLE); 706 snd_soc_component_write_field(component, PM4125_DIG_SWR_CDC_AMIC_CTL, 707 PM4125_DIG_SWR_AMIC_SELECT_MASK, 708 PM4125_DIG_SWR_AMIC_SELECT_AMIC3); 709 break; 710 } 711 712 return 0; 713 } 714 715 static int pm4125_micbias_control(struct snd_soc_component *component, int micb_num, int req, 716 bool is_dapm) 717 { 718 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 719 int micb_index = micb_num - 1; 720 u16 micb_reg; 721 u8 pullup_mask = 0, enable_mask = 0; 722 723 if ((micb_index < 0) || (micb_index > PM4125_MAX_MICBIAS - 1)) { 724 dev_err(component->dev, "%s: Invalid micbias index, micb_ind:%d\n", 725 __func__, micb_index); 726 return -EINVAL; 727 } 728 switch (micb_num) { 729 case MIC_BIAS_1: 730 micb_reg = PM4125_ANA_MICBIAS_MICB_1_2_EN; 731 pullup_mask = PM4125_ANA_MICBIAS_MICB1_PULL_UP_MASK; 732 enable_mask = 0x40; 733 break; 734 case MIC_BIAS_2: 735 micb_reg = PM4125_ANA_MICBIAS_MICB_1_2_EN; 736 pullup_mask = PM4125_ANA_MICBIAS_MICB2_PULL_UP_MASK; 737 enable_mask = 0x04; 738 break; 739 case MIC_BIAS_3: 740 micb_reg = PM4125_ANA_MICBIAS_MICB_3_EN; 741 pullup_mask = 0x02; 742 break; 743 default: 744 dev_err(component->dev, "%s: Invalid micbias number: %d\n", 745 __func__, micb_num); 746 return -EINVAL; 747 } 748 749 switch (req) { 750 case MICB_PULLUP_ENABLE: 751 pm4125->pullup_ref[micb_index]++; 752 if ((pm4125->pullup_ref[micb_index] == 1) && 753 (pm4125->micb_ref[micb_index] == 0)) 754 snd_soc_component_update_bits(component, micb_reg, 755 pullup_mask, pullup_mask); 756 break; 757 case MICB_PULLUP_DISABLE: 758 if (pm4125->pullup_ref[micb_index] > 0) 759 pm4125->pullup_ref[micb_index]--; 760 if ((pm4125->pullup_ref[micb_index] == 0) && 761 (pm4125->micb_ref[micb_index] == 0)) 762 snd_soc_component_update_bits(component, micb_reg, 763 pullup_mask, 0x00); 764 break; 765 case MICB_ENABLE: 766 pm4125->micb_ref[micb_index]++; 767 if (pm4125->micb_ref[micb_index] == 1) { 768 pm4125_global_mbias_enable(component); 769 snd_soc_component_update_bits(component, micb_reg, 770 enable_mask, enable_mask); 771 } 772 break; 773 case MICB_DISABLE: 774 if (pm4125->micb_ref[micb_index] > 0) 775 pm4125->micb_ref[micb_index]--; 776 if ((pm4125->micb_ref[micb_index] == 0) && 777 (pm4125->pullup_ref[micb_index] > 0)) { 778 snd_soc_component_update_bits(component, micb_reg, 779 pullup_mask, pullup_mask); 780 snd_soc_component_update_bits(component, micb_reg, 781 enable_mask, 0x00); 782 pm4125_global_mbias_disable(component); 783 } else if ((pm4125->micb_ref[micb_index] == 0) && 784 (pm4125->pullup_ref[micb_index] == 0)) { 785 snd_soc_component_update_bits(component, micb_reg, 786 enable_mask, 0x00); 787 pm4125_global_mbias_disable(component); 788 } 789 break; 790 } 791 792 return 0; 793 } 794 795 static int pm4125_codec_enable_micbias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 796 int event) 797 { 798 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 799 int micb_num = w->shift; 800 801 switch (event) { 802 case SND_SOC_DAPM_PRE_PMU: 803 if (micb_num == MIC_BIAS_3) 804 pm4125_micbias_control(component, micb_num, MICB_PULLUP_ENABLE, true); 805 else 806 pm4125_micbias_control(component, micb_num, MICB_ENABLE, true); 807 break; 808 case SND_SOC_DAPM_POST_PMU: 809 usleep_range(1000, 1100); 810 break; 811 case SND_SOC_DAPM_POST_PMD: 812 if (micb_num == MIC_BIAS_3) 813 pm4125_micbias_control(component, micb_num, MICB_PULLUP_DISABLE, true); 814 else 815 pm4125_micbias_control(component, micb_num, MICB_DISABLE, true); 816 break; 817 } 818 819 return 0; 820 } 821 822 static int pm4125_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w, 823 struct snd_kcontrol *kcontrol, int event) 824 { 825 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 826 int micb_num = w->shift; 827 828 switch (event) { 829 case SND_SOC_DAPM_PRE_PMU: 830 pm4125_micbias_control(component, micb_num, MICB_PULLUP_ENABLE, true); 831 break; 832 case SND_SOC_DAPM_POST_PMU: 833 usleep_range(1000, 1100); 834 break; 835 case SND_SOC_DAPM_POST_PMD: 836 pm4125_micbias_control(component, micb_num, MICB_PULLUP_DISABLE, true); 837 break; 838 } 839 840 return 0; 841 } 842 843 static int pm4125_connect_port(struct pm4125_sdw_priv *sdw_priv, u8 port_idx, u8 ch_id, bool enable) 844 { 845 struct sdw_port_config *port_config = &sdw_priv->port_config[port_idx - 1]; 846 const struct wcd_sdw_ch_info *ch_info = &sdw_priv->ch_info[ch_id]; 847 struct sdw_slave *sdev = sdw_priv->sdev; 848 u8 port_num = ch_info->port_num; 849 u8 ch_mask = ch_info->ch_mask; 850 u8 mstr_port_num, mstr_ch_mask; 851 852 port_config->num = port_num; 853 854 mstr_port_num = sdev->m_port_map[port_num]; 855 mstr_ch_mask = ch_info->master_ch_mask; 856 857 if (enable) { 858 port_config->ch_mask |= ch_mask; 859 sdw_priv->master_channel_map[mstr_port_num] |= mstr_ch_mask; 860 } else { 861 port_config->ch_mask &= ~ch_mask; 862 sdw_priv->master_channel_map[mstr_port_num] &= ~mstr_ch_mask; 863 } 864 865 return 0; 866 } 867 868 static int pm4125_get_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 869 { 870 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 871 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 872 struct soc_mixer_control *mc; 873 bool hphr; 874 875 mc = (struct soc_mixer_control *)(kcontrol->private_value); 876 hphr = mc->shift; 877 878 ucontrol->value.integer.value[0] = hphr ? pm4125->comp2_enable : pm4125->comp1_enable; 879 return 0; 880 } 881 882 static int pm4125_set_compander(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 883 { 884 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 885 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 886 struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[AIF1_PB]; 887 int value = ucontrol->value.integer.value[0]; 888 struct soc_mixer_control *mc; 889 int portidx; 890 bool hphr; 891 892 mc = (struct soc_mixer_control *)(kcontrol->private_value); 893 hphr = mc->shift; 894 895 if (hphr) { 896 if (value == pm4125->comp2_enable) 897 return 0; 898 899 pm4125->comp2_enable = value; 900 } else { 901 if (value == pm4125->comp1_enable) 902 return 0; 903 904 pm4125->comp1_enable = value; 905 } 906 907 portidx = sdw_priv->ch_info[mc->reg].port_num; 908 909 pm4125_connect_port(sdw_priv, portidx, mc->reg, value ? true : false); 910 911 return 1; 912 } 913 914 static int pm4125_get_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 915 { 916 struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; 917 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 918 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(comp); 919 struct pm4125_sdw_priv *sdw_priv; 920 int dai_id = mixer->shift; 921 int ch_idx = mixer->reg; 922 int portidx; 923 924 sdw_priv = pm4125->sdw_priv[dai_id]; 925 portidx = sdw_priv->ch_info[ch_idx].port_num; 926 927 ucontrol->value.integer.value[0] = sdw_priv->port_enable[portidx]; 928 929 return 0; 930 } 931 932 static int pm4125_set_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 933 { 934 struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; 935 struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol); 936 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(comp); 937 struct pm4125_sdw_priv *sdw_priv; 938 int dai_id = mixer->shift; 939 int ch_idx = mixer->reg; 940 int portidx; 941 bool enable; 942 943 sdw_priv = pm4125->sdw_priv[dai_id]; 944 945 portidx = sdw_priv->ch_info[ch_idx].port_num; 946 947 enable = ucontrol->value.integer.value[0]; 948 949 if (enable == sdw_priv->port_enable[portidx]) { 950 pm4125_connect_port(sdw_priv, portidx, ch_idx, enable); 951 return 0; 952 } 953 954 sdw_priv->port_enable[portidx] = enable; 955 pm4125_connect_port(sdw_priv, portidx, ch_idx, enable); 956 957 return 1; 958 } 959 960 static void pm4125_mbhc_bias_control(struct snd_soc_component *component, bool enable) 961 { 962 snd_soc_component_write_field(component, PM4125_ANA_MBHC_ELECT, 963 PM4125_ANA_MBHC_ELECT_BIAS_EN_MASK, 964 enable ? PM4125_ANA_MBHC_ELECT_BIAS_ENABLE : 965 PM4125_ANA_MBHC_ELECT_BIAS_DISABLE); 966 } 967 968 static void pm4125_mbhc_program_btn_thr(struct snd_soc_component *component, 969 int *btn_low, int *btn_high, 970 int num_btn, bool is_micbias) 971 { 972 int i, vth; 973 974 if (num_btn > WCD_MBHC_DEF_BUTTONS) { 975 dev_err(component->dev, "%s: invalid number of buttons: %d\n", 976 __func__, num_btn); 977 return; 978 } 979 980 for (i = 0; i < num_btn; i++) { 981 vth = ((btn_high[i] * 2) / 25) & 0x3F; 982 snd_soc_component_write_field(component, PM4125_ANA_MBHC_BTN0_ZDET_VREF1 + i, 983 PM4125_ANA_MBHC_BTN0_THRESHOLD_MASK, vth << 2); 984 } 985 } 986 987 static const struct wcd_mbhc_cb mbhc_cb = { 988 .mbhc_bias = pm4125_mbhc_bias_control, 989 .set_btn_thr = pm4125_mbhc_program_btn_thr, 990 }; 991 992 static int pm4125_mbhc_init(struct snd_soc_component *component) 993 { 994 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 995 struct wcd_mbhc_intr *intr_ids = &pm4125->intr_ids; 996 997 intr_ids->mbhc_sw_intr = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_MBHC_SW_DET); 998 999 intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(pm4125->irq_chip, 1000 PM4125_IRQ_MBHC_BUTTON_PRESS_DET); 1001 1002 intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(pm4125->irq_chip, 1003 PM4125_IRQ_MBHC_BUTTON_RELEASE_DET); 1004 1005 intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(pm4125->irq_chip, 1006 PM4125_IRQ_MBHC_ELECT_INS_REM_LEG_DET); 1007 1008 intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(pm4125->irq_chip, 1009 PM4125_IRQ_MBHC_ELECT_INS_REM_DET); 1010 1011 intr_ids->hph_left_ocp = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_HPHL_OCP_INT); 1012 1013 intr_ids->hph_right_ocp = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_HPHR_OCP_INT); 1014 1015 pm4125->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, pm4125_mbhc_fields, false); 1016 if (IS_ERR(pm4125->wcd_mbhc)) 1017 return PTR_ERR(pm4125->wcd_mbhc); 1018 1019 return 0; 1020 } 1021 1022 static void pm4125_mbhc_deinit(struct snd_soc_component *component) 1023 { 1024 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 1025 1026 wcd_mbhc_deinit(pm4125->wcd_mbhc); 1027 } 1028 1029 static const struct snd_kcontrol_new pm4125_snd_controls[] = { 1030 SOC_SINGLE_EXT("HPHL_COMP Switch", PM4125_COMP_L, 0, 1, 0, 1031 pm4125_get_compander, pm4125_set_compander), 1032 SOC_SINGLE_EXT("HPHR_COMP Switch", PM4125_COMP_R, 1, 1, 0, 1033 pm4125_get_compander, pm4125_set_compander), 1034 1035 SOC_SINGLE_TLV("HPHL Volume", PM4125_ANA_HPHPA_L_GAIN, 0, 20, 1, 1036 line_gain), 1037 SOC_SINGLE_TLV("HPHR Volume", PM4125_ANA_HPHPA_R_GAIN, 0, 20, 1, 1038 line_gain), 1039 SOC_SINGLE_TLV("ADC1 Volume", PM4125_ANA_TX_AMIC1, 0, 8, 0, 1040 analog_gain), 1041 SOC_SINGLE_TLV("ADC2 Volume", PM4125_ANA_TX_AMIC2, 0, 8, 0, 1042 analog_gain), 1043 1044 SOC_SINGLE_EXT("HPHL Switch", PM4125_HPH_L, 0, 1, 0, 1045 pm4125_get_swr_port, pm4125_set_swr_port), 1046 SOC_SINGLE_EXT("HPHR Switch", PM4125_HPH_R, 0, 1, 0, 1047 pm4125_get_swr_port, pm4125_set_swr_port), 1048 1049 SOC_SINGLE_EXT("ADC1 Switch", PM4125_ADC1, 1, 1, 0, 1050 pm4125_get_swr_port, pm4125_set_swr_port), 1051 SOC_SINGLE_EXT("ADC2 Switch", PM4125_ADC2, 1, 1, 0, 1052 pm4125_get_swr_port, pm4125_set_swr_port), 1053 }; 1054 1055 static const struct snd_kcontrol_new adc1_switch[] = { 1056 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1057 }; 1058 1059 static const struct snd_kcontrol_new adc2_switch[] = { 1060 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1061 }; 1062 1063 static const struct snd_kcontrol_new dmic1_switch[] = { 1064 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1065 }; 1066 1067 static const struct snd_kcontrol_new dmic2_switch[] = { 1068 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1069 }; 1070 1071 static const struct snd_kcontrol_new ear_rdac_switch[] = { 1072 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1073 }; 1074 1075 static const struct snd_kcontrol_new lo_rdac_switch[] = { 1076 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1077 }; 1078 1079 static const struct snd_kcontrol_new hphl_rdac_switch[] = { 1080 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1081 }; 1082 1083 static const struct snd_kcontrol_new hphr_rdac_switch[] = { 1084 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1085 }; 1086 1087 static const char * const adc2_mux_text[] = { 1088 "INP2", "INP3" 1089 }; 1090 1091 static const struct soc_enum adc2_enum = SOC_ENUM_SINGLE(PM4125_ANA_TX_AMIC2, 4, 1092 ARRAY_SIZE(adc2_mux_text), adc2_mux_text); 1093 1094 static const struct snd_kcontrol_new tx_adc2_mux = SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum); 1095 1096 static const struct snd_soc_dapm_widget pm4125_dapm_widgets[] = { 1097 /* Input widgets */ 1098 SND_SOC_DAPM_INPUT("AMIC1"), 1099 SND_SOC_DAPM_INPUT("AMIC2"), 1100 SND_SOC_DAPM_INPUT("AMIC3"), 1101 SND_SOC_DAPM_INPUT("IN1_HPHL"), 1102 SND_SOC_DAPM_INPUT("IN2_HPHR"), 1103 1104 /* TX widgets */ 1105 SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0, pm4125_codec_enable_adc, 1106 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1107 SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0, pm4125_codec_enable_adc, 1108 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1109 1110 SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux), 1111 1112 /* TX mixers */ 1113 SND_SOC_DAPM_MIXER("ADC1_MIXER", SND_SOC_NOPM, 0, 0, adc1_switch, ARRAY_SIZE(adc1_switch)), 1114 SND_SOC_DAPM_MIXER("ADC2_MIXER", SND_SOC_NOPM, 1, 0, adc2_switch, ARRAY_SIZE(adc2_switch)), 1115 1116 /* MIC_BIAS widgets */ 1117 SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0, pm4125_codec_enable_micbias, 1118 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1119 SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0, pm4125_codec_enable_micbias, 1120 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1121 SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0, pm4125_codec_enable_micbias, 1122 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1123 1124 SND_SOC_DAPM_SUPPLY("PA_VPOS", SND_SOC_NOPM, 0, 0, NULL, 0), 1125 1126 /* RX widgets */ 1127 SND_SOC_DAPM_PGA_E("EAR PGA", PM4125_ANA_COMBOPA_CTL, 7, 0, NULL, 0, 1128 pm4125_codec_enable_ear_pa, 1129 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 1130 SND_SOC_DAPM_POST_PMD), 1131 SND_SOC_DAPM_PGA_E("LO PGA", PM4125_ANA_COMBOPA_CTL, 7, 0, NULL, 0, 1132 pm4125_codec_enable_lo_pa, 1133 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 1134 SND_SOC_DAPM_POST_PMD), 1135 SND_SOC_DAPM_PGA_E("HPHL PGA", PM4125_ANA_HPHPA_CNP_CTL_2, 7, 0, NULL, 0, 1136 pm4125_codec_enable_hphl_pa, 1137 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1138 SND_SOC_DAPM_PGA_E("HPHR PGA", PM4125_ANA_HPHPA_CNP_CTL_2, 6, 0, NULL, 0, 1139 pm4125_codec_enable_hphr_pa, 1140 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1141 1142 SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0, pm4125_codec_hphl_dac_event, 1143 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 1144 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 1145 SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0, pm4125_codec_hphr_dac_event, 1146 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 1147 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 1148 SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0, pm4125_codec_ear_lo_dac_event, 1149 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 1150 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 1151 1152 1153 SND_SOC_DAPM_SUPPLY("HPHL_WDT_IRQ", SND_SOC_NOPM, 0, 0, pm4125_codec_enable_hphl_wdt_irq, 1154 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1155 SND_SOC_DAPM_SUPPLY("HPHR_WDT_IRQ", SND_SOC_NOPM, 0, 0, pm4125_codec_enable_hphr_wdt_irq, 1156 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1157 SND_SOC_DAPM_SUPPLY("RXCLK", SND_SOC_NOPM, 0, 0, pm4125_codec_enable_rxclk, 1158 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1159 SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), 1160 SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), 1161 1162 /* RX mixer widgets */ 1163 SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0, ear_rdac_switch, 1164 ARRAY_SIZE(ear_rdac_switch)), 1165 SND_SOC_DAPM_MIXER("LO_RDAC", SND_SOC_NOPM, 0, 0, lo_rdac_switch, 1166 ARRAY_SIZE(lo_rdac_switch)), 1167 SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0, hphl_rdac_switch, 1168 ARRAY_SIZE(hphl_rdac_switch)), 1169 SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0, hphr_rdac_switch, 1170 ARRAY_SIZE(hphr_rdac_switch)), 1171 1172 /* TX output widgets */ 1173 SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"), 1174 SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"), 1175 1176 /* RX output widgets */ 1177 SND_SOC_DAPM_OUTPUT("EAR"), 1178 SND_SOC_DAPM_OUTPUT("LO"), 1179 SND_SOC_DAPM_OUTPUT("HPHL"), 1180 SND_SOC_DAPM_OUTPUT("HPHR"), 1181 1182 /* MIC_BIAS pull up widgets */ 1183 SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0, 1184 pm4125_codec_enable_micbias_pullup, 1185 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1186 SND_SOC_DAPM_SUPPLY("VA MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0, 1187 pm4125_codec_enable_micbias_pullup, 1188 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1189 SND_SOC_DAPM_SUPPLY("VA MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0, 1190 pm4125_codec_enable_micbias_pullup, 1191 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1192 1193 /* TX widgets */ 1194 SND_SOC_DAPM_ADC_E("DMIC1", NULL, PM4125_DIG_SWR_CDC_DMIC1_CTL, 0, 0, 1195 pm4125_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1196 SND_SOC_DAPM_ADC_E("DMIC2", NULL, PM4125_DIG_SWR_CDC_DMIC1_CTL, 1, 0, 1197 pm4125_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1198 1199 /* TX mixer widgets */ 1200 SND_SOC_DAPM_MIXER("DMIC1_MIXER", SND_SOC_NOPM, 0, 0, dmic1_switch, 1201 ARRAY_SIZE(dmic1_switch)), 1202 SND_SOC_DAPM_MIXER("DMIC2_MIXER", SND_SOC_NOPM, 1, 0, dmic2_switch, 1203 ARRAY_SIZE(dmic2_switch)), 1204 1205 /* Output widgets */ 1206 SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"), 1207 SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"), 1208 }; 1209 1210 static const struct snd_soc_dapm_route pm4125_audio_map[] = { 1211 { "ADC1_OUTPUT", NULL, "ADC1_MIXER" }, 1212 { "ADC1_MIXER", "Switch", "ADC1" }, 1213 { "ADC1", NULL, "AMIC1" }, 1214 1215 { "ADC2_OUTPUT", NULL, "ADC2_MIXER" }, 1216 { "ADC2_MIXER", "Switch", "ADC2" }, 1217 { "ADC2", NULL, "ADC2 MUX" }, 1218 { "ADC2 MUX", "INP3", "AMIC3" }, 1219 { "ADC2 MUX", "INP2", "AMIC2" }, 1220 1221 { "IN1_HPHL", NULL, "PA_VPOS" }, 1222 { "RX1", NULL, "IN1_HPHL" }, 1223 { "RX1", NULL, "RXCLK" }, 1224 { "RX1", NULL, "HPHL_WDT_IRQ" }, 1225 { "RDAC1", NULL, "RX1" }, 1226 { "HPHL_RDAC", "Switch", "RDAC1" }, 1227 { "HPHL PGA", NULL, "HPHL_RDAC" }, 1228 { "HPHL", NULL, "HPHL PGA" }, 1229 1230 { "IN2_HPHR", NULL, "PA_VPOS" }, 1231 { "RX2", NULL, "IN2_HPHR" }, 1232 { "RX2", NULL, "RXCLK" }, 1233 { "RX2", NULL, "HPHR_WDT_IRQ" }, 1234 { "RDAC2", NULL, "RX2" }, 1235 { "HPHR_RDAC", "Switch", "RDAC2" }, 1236 { "HPHR PGA", NULL, "HPHR_RDAC" }, 1237 { "HPHR", NULL, "HPHR PGA" }, 1238 1239 { "RDAC3", NULL, "RX1" }, 1240 { "EAR_RDAC", "Switch", "RDAC3" }, 1241 { "EAR PGA", NULL, "EAR_RDAC" }, 1242 { "EAR", NULL, "EAR PGA" }, 1243 1244 { "LO_RDAC", "Switch", "RDAC3" }, 1245 { "LO PGA", NULL, "LO_RDAC" }, 1246 { "LO", NULL, "LO PGA" }, 1247 1248 { "DMIC1_OUTPUT", NULL, "DMIC1_MIXER" }, 1249 { "DMIC1_MIXER", "Switch", "DMIC1" }, 1250 1251 { "DMIC2_OUTPUT", NULL, "DMIC2_MIXER" }, 1252 { "DMIC2_MIXER", "Switch", "DMIC2" }, 1253 }; 1254 1255 static int pm4125_set_micbias_data(struct device *dev, struct pm4125_priv *pm4125) 1256 { 1257 regmap_update_bits(pm4125->regmap, PM4125_ANA_MICBIAS_LDO_1_SETTING, 1258 PM4125_ANA_MICBIAS_MICB_OUT_VAL_MASK, pm4125->common.micb_vout[0]); 1259 return 0; 1260 } 1261 1262 static irqreturn_t pm4125_wd_handle_irq(int irq, void *data) 1263 { 1264 /* 1265 * HPHR/HPHL Watchdog interrupt threaded handler 1266 * Watchdog interrupts are expected to be enabled when switching on the HPHL/R 1267 * in order to make sure the interrupts are acked by the regmap_irq handler 1268 * io allow PDM sync. We could leave those interrupts masked but we would 1269 * not haveany valid way to enable/disable them without violating irq layers. 1270 * 1271 * The HPHR/HPHL Watchdog interrupts are handled by regmap_irq, so requesting 1272 * a threaded handler is the safest way to be able to ack those interrupts 1273 * without colliding with the regmap_irq setup. 1274 */ 1275 return IRQ_HANDLED; 1276 } 1277 1278 static const struct irq_chip pm4125_codec_irq_chip = { 1279 .name = "pm4125_codec", 1280 }; 1281 1282 static int pm4125_codec_irq_chip_map(struct irq_domain *irqd, unsigned int virq, 1283 irq_hw_number_t hw) 1284 { 1285 irq_set_chip_and_handler(virq, &pm4125_codec_irq_chip, handle_simple_irq); 1286 irq_set_nested_thread(virq, 1); 1287 irq_set_noprobe(virq); 1288 1289 return 0; 1290 } 1291 1292 static const struct irq_domain_ops pm4125_domain_ops = { 1293 .map = pm4125_codec_irq_chip_map, 1294 }; 1295 1296 static int pm4125_irq_init(struct pm4125_priv *pm4125, struct device *dev) 1297 { 1298 pm4125->virq = irq_domain_add_linear(NULL, 1, &pm4125_domain_ops, NULL); 1299 if (!(pm4125->virq)) { 1300 dev_err(dev, "%s: Failed to add IRQ domain\n", __func__); 1301 return -EINVAL; 1302 } 1303 1304 return devm_regmap_add_irq_chip(dev, pm4125->regmap, irq_create_mapping(pm4125->virq, 0), 1305 IRQF_ONESHOT, 0, pm4125->chip_desc, 1306 &pm4125->irq_chip); 1307 } 1308 1309 static int pm4125_soc_codec_probe(struct snd_soc_component *component) 1310 { 1311 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 1312 struct sdw_slave *tx_sdw_dev = pm4125->tx_sdw_dev; 1313 struct device *dev = component->dev; 1314 unsigned long time_left; 1315 int i, ret; 1316 1317 time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete, 1318 msecs_to_jiffies(5000)); 1319 if (!time_left) { 1320 dev_err(dev, "soundwire device init timeout\n"); 1321 return -ETIMEDOUT; 1322 } 1323 1324 snd_soc_component_init_regmap(component, pm4125->regmap); 1325 ret = pm_runtime_resume_and_get(dev); 1326 if (ret < 0) 1327 return ret; 1328 1329 pm4125_io_init(pm4125->regmap); 1330 1331 /* Set all interrupts as edge triggered */ 1332 for (i = 0; i < pm4125_regmap_irq_chip.num_regs; i++) 1333 regmap_write(pm4125->regmap, (PM4125_DIG_SWR_INTR_LEVEL_0 + i), 0); 1334 1335 pm_runtime_put(dev); 1336 1337 pm4125->hphr_pdm_wd_int = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_HPHR_PDM_WD_INT); 1338 pm4125->hphl_pdm_wd_int = regmap_irq_get_virq(pm4125->irq_chip, PM4125_IRQ_HPHL_PDM_WD_INT); 1339 1340 /* Request for watchdog interrupts */ 1341 ret = devm_request_threaded_irq(dev, pm4125->hphr_pdm_wd_int, NULL, pm4125_wd_handle_irq, 1342 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 1343 "HPHR PDM WDOG INT", pm4125); 1344 if (ret) 1345 dev_err(dev, "Failed to request HPHR wdt interrupt: %d\n", ret); 1346 1347 ret = devm_request_threaded_irq(dev, pm4125->hphl_pdm_wd_int, NULL, pm4125_wd_handle_irq, 1348 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 1349 "HPHL PDM WDOG INT", pm4125); 1350 if (ret) 1351 dev_err(dev, "Failed to request HPHL wdt interrupt: %d\n", ret); 1352 1353 disable_irq_nosync(pm4125->hphr_pdm_wd_int); 1354 disable_irq_nosync(pm4125->hphl_pdm_wd_int); 1355 1356 ret = pm4125_mbhc_init(component); 1357 if (ret) 1358 dev_err(component->dev, "mbhc initialization failed\n"); 1359 1360 return ret; 1361 } 1362 1363 static void pm4125_soc_codec_remove(struct snd_soc_component *component) 1364 { 1365 struct pm4125_priv *pm4125 = snd_soc_component_get_drvdata(component); 1366 1367 pm4125_mbhc_deinit(component); 1368 free_irq(pm4125->hphl_pdm_wd_int, pm4125); 1369 free_irq(pm4125->hphr_pdm_wd_int, pm4125); 1370 } 1371 1372 static int pm4125_codec_set_jack(struct snd_soc_component *comp, struct snd_soc_jack *jack, 1373 void *data) 1374 { 1375 struct pm4125_priv *pm4125 = dev_get_drvdata(comp->dev); 1376 int ret = 0; 1377 1378 if (jack) 1379 ret = wcd_mbhc_start(pm4125->wcd_mbhc, &pm4125->mbhc_cfg, jack); 1380 else 1381 wcd_mbhc_stop(pm4125->wcd_mbhc); 1382 1383 return ret; 1384 } 1385 1386 static const struct snd_soc_component_driver soc_codec_dev_pm4125 = { 1387 .name = "pm4125_codec", 1388 .probe = pm4125_soc_codec_probe, 1389 .remove = pm4125_soc_codec_remove, 1390 .controls = pm4125_snd_controls, 1391 .num_controls = ARRAY_SIZE(pm4125_snd_controls), 1392 .dapm_widgets = pm4125_dapm_widgets, 1393 .num_dapm_widgets = ARRAY_SIZE(pm4125_dapm_widgets), 1394 .dapm_routes = pm4125_audio_map, 1395 .num_dapm_routes = ARRAY_SIZE(pm4125_audio_map), 1396 .set_jack = pm4125_codec_set_jack, 1397 .endianness = 1, 1398 }; 1399 1400 static int pm4125_codec_hw_params(struct snd_pcm_substream *substream, 1401 struct snd_pcm_hw_params *params, 1402 struct snd_soc_dai *dai) 1403 { 1404 struct pm4125_priv *pm4125 = dev_get_drvdata(dai->dev); 1405 struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[dai->id]; 1406 1407 return pm4125_sdw_hw_params(sdw_priv, substream, params, dai); 1408 } 1409 1410 static int pm4125_codec_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) 1411 { 1412 struct pm4125_priv *pm4125 = dev_get_drvdata(dai->dev); 1413 struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[dai->id]; 1414 1415 return sdw_stream_remove_slave(sdw_priv->sdev, sdw_priv->sruntime); 1416 } 1417 1418 static int pm4125_codec_set_sdw_stream(struct snd_soc_dai *dai, void *stream, int direction) 1419 { 1420 struct pm4125_priv *pm4125 = dev_get_drvdata(dai->dev); 1421 struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[dai->id]; 1422 1423 sdw_priv->sruntime = stream; 1424 1425 return 0; 1426 } 1427 1428 static int pm4125_get_channel_map(const struct snd_soc_dai *dai, 1429 unsigned int *tx_num, unsigned int *tx_slot, 1430 unsigned int *rx_num, unsigned int *rx_slot) 1431 { 1432 struct pm4125_priv *pm4125 = dev_get_drvdata(dai->dev); 1433 struct pm4125_sdw_priv *sdw_priv = pm4125->sdw_priv[dai->id]; 1434 int i; 1435 1436 switch (dai->id) { 1437 case AIF1_PB: 1438 if (!rx_slot || !rx_num) { 1439 dev_err(dai->dev, "Invalid rx_slot %p or rx_num %p\n", rx_slot, rx_num); 1440 return -EINVAL; 1441 } 1442 1443 for (i = 0; i < SDW_MAX_PORTS; i++) 1444 rx_slot[i] = sdw_priv->master_channel_map[i]; 1445 1446 *rx_num = i; 1447 break; 1448 case AIF1_CAP: 1449 if (!tx_slot || !tx_num) { 1450 dev_err(dai->dev, "Invalid tx_slot %p or tx_num %p\n", tx_slot, tx_num); 1451 return -EINVAL; 1452 } 1453 1454 for (i = 0; i < SDW_MAX_PORTS; i++) 1455 tx_slot[i] = sdw_priv->master_channel_map[i]; 1456 1457 *tx_num = i; 1458 break; 1459 default: 1460 break; 1461 } 1462 1463 return 0; 1464 } 1465 1466 static const struct snd_soc_dai_ops pm4125_sdw_dai_ops = { 1467 .hw_params = pm4125_codec_hw_params, 1468 .hw_free = pm4125_codec_free, 1469 .set_stream = pm4125_codec_set_sdw_stream, 1470 .get_channel_map = pm4125_get_channel_map, 1471 }; 1472 1473 static struct snd_soc_dai_driver pm4125_dais[] = { 1474 [0] = { 1475 .name = "pm4125-sdw-rx", 1476 .playback = { 1477 .stream_name = "PM4125 AIF Playback", 1478 .rates = PM4125_RATES | PM4125_FRAC_RATES, 1479 .formats = PM4125_FORMATS, 1480 .rate_min = 8000, 1481 .rate_max = 384000, 1482 .channels_min = 1, 1483 .channels_max = 4, 1484 }, 1485 .ops = &pm4125_sdw_dai_ops, 1486 }, 1487 [1] = { 1488 .name = "pm4125-sdw-tx", 1489 .capture = { 1490 .stream_name = "PM4125 AIF Capture", 1491 .rates = PM4125_RATES, 1492 .formats = PM4125_FORMATS, 1493 .rate_min = 8000, 1494 .rate_max = 192000, 1495 .channels_min = 1, 1496 .channels_max = 4, 1497 }, 1498 .ops = &pm4125_sdw_dai_ops, 1499 }, 1500 }; 1501 1502 static int pm4125_bind(struct device *dev) 1503 { 1504 struct pm4125_priv *pm4125 = dev_get_drvdata(dev); 1505 struct device_link *devlink; 1506 int ret; 1507 1508 /* Initialize device pointers to NULL for safe cleanup */ 1509 pm4125->rxdev = NULL; 1510 pm4125->txdev = NULL; 1511 1512 /* Give the soundwire subdevices some more time to settle */ 1513 usleep_range(15000, 15010); 1514 1515 ret = component_bind_all(dev, pm4125); 1516 if (ret) { 1517 dev_err(dev, "Slave bind failed, ret = %d\n", ret); 1518 return ret; 1519 } 1520 1521 pm4125->rxdev = of_sdw_find_device_by_node(pm4125->rxnode); 1522 if (!pm4125->rxdev) { 1523 dev_err(dev, "could not find rxslave with matching of node\n"); 1524 ret = -EINVAL; 1525 goto error_unbind_all; 1526 } 1527 1528 pm4125->sdw_priv[AIF1_PB] = dev_get_drvdata(pm4125->rxdev); 1529 pm4125->sdw_priv[AIF1_PB]->pm4125 = pm4125; 1530 1531 pm4125->txdev = of_sdw_find_device_by_node(pm4125->txnode); 1532 if (!pm4125->txdev) { 1533 dev_err(dev, "could not find txslave with matching of node\n"); 1534 ret = -EINVAL; 1535 goto error_put_rx; 1536 } 1537 1538 pm4125->sdw_priv[AIF1_CAP] = dev_get_drvdata(pm4125->txdev); 1539 pm4125->sdw_priv[AIF1_CAP]->pm4125 = pm4125; 1540 1541 pm4125->tx_sdw_dev = dev_to_sdw_dev(pm4125->txdev); 1542 if (!pm4125->tx_sdw_dev) { 1543 dev_err(dev, "could not get txslave with matching of dev\n"); 1544 ret = -EINVAL; 1545 goto error_put_tx; 1546 } 1547 1548 /* 1549 * As TX is the main CSR reg interface, which should not be suspended first. 1550 * expicilty add the dependency link 1551 */ 1552 devlink = device_link_add(pm4125->rxdev, pm4125->txdev, 1553 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); 1554 if (!devlink) { 1555 dev_err(dev, "Could not devlink TX and RX\n"); 1556 ret = -EINVAL; 1557 goto error_put_tx; 1558 } 1559 1560 devlink = device_link_add(dev, pm4125->txdev, 1561 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); 1562 if (!devlink) { 1563 dev_err(dev, "Could not devlink PM4125 and TX\n"); 1564 ret = -EINVAL; 1565 goto link_remove_rx_tx; 1566 } 1567 1568 devlink = device_link_add(dev, pm4125->rxdev, 1569 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); 1570 if (!devlink) { 1571 dev_err(dev, "Could not devlink PM4125 and RX\n"); 1572 ret = -EINVAL; 1573 goto link_remove_dev_tx; 1574 } 1575 1576 pm4125->regmap = pm4125->sdw_priv[AIF1_CAP]->regmap; 1577 if (!pm4125->regmap) { 1578 dev_err(dev, "could not get TX device regmap\n"); 1579 ret = -EINVAL; 1580 goto link_remove_dev_rx; 1581 } 1582 1583 ret = pm4125_irq_init(pm4125, dev); 1584 if (ret) { 1585 dev_err(dev, "IRQ init failed: %d\n", ret); 1586 goto link_remove_dev_rx; 1587 } 1588 1589 pm4125->sdw_priv[AIF1_PB]->slave_irq = pm4125->virq; 1590 pm4125->sdw_priv[AIF1_CAP]->slave_irq = pm4125->virq; 1591 1592 pm4125_set_micbias_data(dev, pm4125); 1593 1594 ret = snd_soc_register_component(dev, &soc_codec_dev_pm4125, 1595 pm4125_dais, ARRAY_SIZE(pm4125_dais)); 1596 if (!ret) 1597 return ret; 1598 1599 dev_err(dev, "Codec registration failed\n"); 1600 1601 link_remove_dev_rx: 1602 device_link_remove(dev, pm4125->rxdev); 1603 link_remove_dev_tx: 1604 device_link_remove(dev, pm4125->txdev); 1605 link_remove_rx_tx: 1606 device_link_remove(pm4125->rxdev, pm4125->txdev); 1607 error_put_tx: 1608 put_device(pm4125->txdev); 1609 error_put_rx: 1610 put_device(pm4125->rxdev); 1611 error_unbind_all: 1612 component_unbind_all(dev, pm4125); 1613 return ret; 1614 } 1615 1616 static void pm4125_unbind(struct device *dev) 1617 { 1618 struct pm4125_priv *pm4125 = dev_get_drvdata(dev); 1619 1620 snd_soc_unregister_component(dev); 1621 devm_regmap_del_irq_chip(dev, irq_find_mapping(pm4125->virq, 0), 1622 pm4125->irq_chip); 1623 device_link_remove(dev, pm4125->txdev); 1624 device_link_remove(dev, pm4125->rxdev); 1625 device_link_remove(pm4125->rxdev, pm4125->txdev); 1626 1627 /* Release device references acquired in bind */ 1628 if (pm4125->txdev) 1629 put_device(pm4125->txdev); 1630 if (pm4125->rxdev) 1631 put_device(pm4125->rxdev); 1632 1633 component_unbind_all(dev, pm4125); 1634 } 1635 1636 static const struct component_master_ops pm4125_comp_ops = { 1637 .bind = pm4125_bind, 1638 .unbind = pm4125_unbind, 1639 }; 1640 1641 static int pm4125_add_slave_components(struct pm4125_priv *pm4125, struct device *dev, 1642 struct component_match **matchptr) 1643 { 1644 struct device_node *np = dev->of_node; 1645 1646 pm4125->rxnode = of_parse_phandle(np, "qcom,rx-device", 0); 1647 if (!pm4125->rxnode) 1648 return dev_err_probe(dev, -ENODEV, "Couldn't parse phandle to qcom,rx-device\n"); 1649 component_match_add_release(dev, matchptr, component_release_of, component_compare_of, 1650 pm4125->rxnode); 1651 1652 pm4125->txnode = of_parse_phandle(np, "qcom,tx-device", 0); 1653 if (!pm4125->txnode) 1654 return dev_err_probe(dev, -ENODEV, "Couldn't parse phandle to qcom,tx-device\n"); 1655 component_match_add_release(dev, matchptr, component_release_of, component_compare_of, 1656 pm4125->txnode); 1657 1658 return 0; 1659 } 1660 1661 static int pm4125_probe(struct platform_device *pdev) 1662 { 1663 struct component_match *match = NULL; 1664 struct device *dev = &pdev->dev; 1665 struct regmap_irq_chip *chip_desc; 1666 struct pm4125_priv *pm4125; 1667 struct wcd_mbhc_config *cfg; 1668 int ret; 1669 1670 pm4125 = devm_kzalloc(dev, sizeof(*pm4125), GFP_KERNEL); 1671 if (!pm4125) 1672 return -ENOMEM; 1673 1674 dev_set_drvdata(dev, pm4125); 1675 1676 chip_desc = devm_kmemdup(dev, &pm4125_regmap_irq_chip, 1677 sizeof(pm4125_regmap_irq_chip), 1678 GFP_KERNEL); 1679 if (!chip_desc) 1680 return -ENOMEM; 1681 chip_desc->irq_drv_data = pm4125; 1682 pm4125->chip_desc = chip_desc; 1683 1684 ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(pm4125_power_supplies), 1685 pm4125_power_supplies); 1686 if (ret) 1687 return dev_err_probe(dev, ret, "Failed to get and enable supplies\n"); 1688 1689 pm4125->spmi_regmap = dev_get_regmap(pdev->dev.parent, NULL); 1690 if (!pm4125->spmi_regmap) 1691 return -ENXIO; 1692 1693 pm4125_reset(pm4125); 1694 1695 pm4125->common.dev = dev; 1696 pm4125->common.max_bias = 3; 1697 ret = wcd_dt_parse_micbias_info(&pm4125->common); 1698 if (ret) 1699 return dev_err_probe(dev, ret, "Failed to get micbias\n"); 1700 1701 atomic_set(&pm4125->gloal_mbias_cnt, 0); 1702 1703 cfg = &pm4125->mbhc_cfg; 1704 cfg->mbhc_micbias = MIC_BIAS_2; 1705 cfg->anc_micbias = MIC_BIAS_2; 1706 cfg->v_hs_max = WCD_MBHC_HS_V_MAX; 1707 cfg->num_btn = PM4125_MBHC_MAX_BUTTONS; 1708 cfg->micb_mv = pm4125->common.micb_mv[1]; 1709 cfg->linein_th = 5000; 1710 cfg->hs_thr = 1700; 1711 cfg->hph_thr = 50; 1712 1713 wcd_dt_parse_mbhc_data(dev, &pm4125->mbhc_cfg); 1714 1715 ret = pm4125_add_slave_components(pm4125, dev, &match); 1716 if (ret) 1717 return ret; 1718 1719 ret = component_master_add_with_match(dev, &pm4125_comp_ops, match); 1720 if (ret) 1721 return ret; 1722 1723 pm_runtime_set_autosuspend_delay(dev, 1000); 1724 pm_runtime_use_autosuspend(dev); 1725 pm_runtime_set_active(dev); 1726 pm_runtime_enable(dev); 1727 pm_runtime_idle(dev); 1728 1729 return 0; 1730 } 1731 1732 static void pm4125_remove(struct platform_device *pdev) 1733 { 1734 struct device *dev = &pdev->dev; 1735 1736 component_master_del(&pdev->dev, &pm4125_comp_ops); 1737 1738 pm_runtime_disable(dev); 1739 pm_runtime_set_suspended(dev); 1740 pm_runtime_dont_use_autosuspend(dev); 1741 } 1742 1743 static const struct of_device_id pm4125_of_match[] = { 1744 { .compatible = "qcom,pm4125-codec" }, 1745 { } 1746 }; 1747 MODULE_DEVICE_TABLE(of, pm4125_of_match); 1748 1749 static struct platform_driver pm4125_codec_driver = { 1750 .probe = pm4125_probe, 1751 .remove = pm4125_remove, 1752 .driver = { 1753 .name = "pm4125_codec", 1754 .of_match_table = pm4125_of_match, 1755 .suppress_bind_attrs = true, 1756 }, 1757 }; 1758 1759 module_platform_driver(pm4125_codec_driver); 1760 MODULE_DESCRIPTION("PM4125 audio codec driver"); 1761 MODULE_LICENSE("GPL"); 1762