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