1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * da7219-aad.c - Dialog DA7219 ALSA SoC AAD Driver 4 * 5 * Copyright (c) 2015 Dialog Semiconductor Ltd. 6 * 7 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/clk.h> 13 #include <linux/i2c.h> 14 #include <linux/property.h> 15 #include <linux/pm_wakeirq.h> 16 #include <linux/slab.h> 17 #include <linux/delay.h> 18 #include <linux/workqueue.h> 19 #include <sound/soc.h> 20 #include <sound/jack.h> 21 #include <sound/da7219.h> 22 23 #include "da7219.h" 24 #include "da7219-aad.h" 25 26 27 /* 28 * Detection control 29 */ 30 31 void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack) 32 { 33 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 34 35 da7219->aad->jack = jack; 36 da7219->aad->jack_inserted = false; 37 38 /* Send an initial empty report */ 39 snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK); 40 41 /* Enable/Disable jack detection */ 42 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, 43 DA7219_ACCDET_EN_MASK, 44 (jack ? DA7219_ACCDET_EN_MASK : 0)); 45 } 46 EXPORT_SYMBOL_GPL(da7219_aad_jack_det); 47 48 /* 49 * Button/HPTest work 50 */ 51 52 static void da7219_aad_btn_det_work(struct work_struct *work) 53 { 54 struct da7219_aad_priv *da7219_aad = 55 container_of(work, struct da7219_aad_priv, btn_det_work); 56 struct snd_soc_component *component = da7219_aad->component; 57 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 58 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 59 u8 statusa, micbias_ctrl; 60 bool micbias_up = false; 61 int retries = 0; 62 63 /* Drive headphones/lineout */ 64 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, 65 DA7219_HP_L_AMP_OE_MASK, 66 DA7219_HP_L_AMP_OE_MASK); 67 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, 68 DA7219_HP_R_AMP_OE_MASK, 69 DA7219_HP_R_AMP_OE_MASK); 70 71 /* Make sure mic bias is up */ 72 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); 73 snd_soc_dapm_sync(dapm); 74 75 do { 76 statusa = snd_soc_component_read(component, DA7219_ACCDET_STATUS_A); 77 if (statusa & DA7219_MICBIAS_UP_STS_MASK) 78 micbias_up = true; 79 else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES) 80 msleep(DA7219_AAD_MICBIAS_CHK_DELAY); 81 } while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES)); 82 83 if (retries >= DA7219_AAD_MICBIAS_CHK_RETRIES) 84 dev_warn(component->dev, "Mic bias status check timed out"); 85 86 da7219->micbias_on_event = true; 87 88 /* 89 * Mic bias pulse required to enable mic, must be done before enabling 90 * button detection to prevent erroneous button readings. 91 */ 92 if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) { 93 /* Pulse higher level voltage */ 94 micbias_ctrl = snd_soc_component_read(component, DA7219_MICBIAS_CTRL); 95 snd_soc_component_update_bits(component, DA7219_MICBIAS_CTRL, 96 DA7219_MICBIAS1_LEVEL_MASK, 97 da7219_aad->micbias_pulse_lvl); 98 msleep(da7219_aad->micbias_pulse_time); 99 snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_ctrl); 100 101 } 102 103 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, 104 DA7219_BUTTON_CONFIG_MASK, 105 da7219_aad->btn_cfg); 106 } 107 108 static void da7219_aad_hptest_work(struct work_struct *work) 109 { 110 struct da7219_aad_priv *da7219_aad = 111 container_of(work, struct da7219_aad_priv, hptest_work); 112 struct snd_soc_component *component = da7219_aad->component; 113 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 114 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 115 116 __le16 tonegen_freq_hptest; 117 u8 pll_srm_sts, pll_ctrl, gain_ramp_ctrl, accdet_cfg8; 118 int report = 0, ret = 0; 119 120 /* Lock DAPM, Kcontrols affected by this test and the PLL */ 121 snd_soc_dapm_mutex_lock(dapm); 122 mutex_lock(&da7219->ctrl_lock); 123 mutex_lock(&da7219->pll_lock); 124 125 /* Ensure MCLK is available for HP test procedure */ 126 if (da7219->mclk) { 127 ret = clk_prepare_enable(da7219->mclk); 128 if (ret) { 129 dev_err(component->dev, "Failed to enable mclk - %d\n", ret); 130 mutex_unlock(&da7219->pll_lock); 131 mutex_unlock(&da7219->ctrl_lock); 132 snd_soc_dapm_mutex_unlock(dapm); 133 return; 134 } 135 } 136 137 /* 138 * If MCLK not present, then we're using the internal oscillator and 139 * require different frequency settings to achieve the same result. 140 * 141 * If MCLK is present, but PLL is not enabled then we enable it here to 142 * ensure a consistent detection procedure. 143 */ 144 pll_srm_sts = snd_soc_component_read(component, DA7219_PLL_SRM_STS); 145 if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) { 146 tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ); 147 148 pll_ctrl = snd_soc_component_read(component, DA7219_PLL_CTRL); 149 if ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS) 150 da7219_set_pll(component, DA7219_SYSCLK_PLL, 151 DA7219_PLL_FREQ_OUT_98304); 152 } else { 153 tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC); 154 } 155 156 /* Ensure gain ramping at fastest rate */ 157 gain_ramp_ctrl = snd_soc_component_read(component, DA7219_GAIN_RAMP_CTRL); 158 snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8); 159 160 /* Bypass cache so it saves current settings */ 161 regcache_cache_bypass(da7219->regmap, true); 162 163 /* Make sure Tone Generator is disabled */ 164 snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0); 165 166 /* Enable HPTest block, 1KOhms check */ 167 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8, 168 DA7219_HPTEST_EN_MASK | DA7219_HPTEST_RES_SEL_MASK, 169 DA7219_HPTEST_EN_MASK | 170 DA7219_HPTEST_RES_SEL_1KOHMS); 171 172 /* Set gains to 0db */ 173 snd_soc_component_write(component, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB); 174 snd_soc_component_write(component, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB); 175 snd_soc_component_write(component, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB); 176 snd_soc_component_write(component, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB); 177 178 /* Disable DAC filters, EQs and soft mute */ 179 snd_soc_component_update_bits(component, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK, 180 0); 181 snd_soc_component_update_bits(component, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK, 182 0); 183 snd_soc_component_update_bits(component, DA7219_DAC_FILTERS5, 184 DA7219_DAC_SOFTMUTE_EN_MASK, 0); 185 186 /* Enable HP left & right paths */ 187 snd_soc_component_update_bits(component, DA7219_CP_CTRL, DA7219_CP_EN_MASK, 188 DA7219_CP_EN_MASK); 189 snd_soc_component_update_bits(component, DA7219_DIG_ROUTING_DAC, 190 DA7219_DAC_L_SRC_MASK | DA7219_DAC_R_SRC_MASK, 191 DA7219_DAC_L_SRC_TONEGEN | 192 DA7219_DAC_R_SRC_TONEGEN); 193 snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL, 194 DA7219_DAC_L_EN_MASK | DA7219_DAC_L_MUTE_EN_MASK, 195 DA7219_DAC_L_EN_MASK); 196 snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL, 197 DA7219_DAC_R_EN_MASK | DA7219_DAC_R_MUTE_EN_MASK, 198 DA7219_DAC_R_EN_MASK); 199 snd_soc_component_update_bits(component, DA7219_MIXOUT_L_SELECT, 200 DA7219_MIXOUT_L_MIX_SELECT_MASK, 201 DA7219_MIXOUT_L_MIX_SELECT_MASK); 202 snd_soc_component_update_bits(component, DA7219_MIXOUT_R_SELECT, 203 DA7219_MIXOUT_R_MIX_SELECT_MASK, 204 DA7219_MIXOUT_R_MIX_SELECT_MASK); 205 snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1L, 206 DA7219_OUTFILT_ST_1L_SRC_MASK, 207 DA7219_DMIX_ST_SRC_OUTFILT1L); 208 snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1R, 209 DA7219_OUTFILT_ST_1R_SRC_MASK, 210 DA7219_DMIX_ST_SRC_OUTFILT1R); 211 snd_soc_component_update_bits(component, DA7219_MIXOUT_L_CTRL, 212 DA7219_MIXOUT_L_AMP_EN_MASK, 213 DA7219_MIXOUT_L_AMP_EN_MASK); 214 snd_soc_component_update_bits(component, DA7219_MIXOUT_R_CTRL, 215 DA7219_MIXOUT_R_AMP_EN_MASK, 216 DA7219_MIXOUT_R_AMP_EN_MASK); 217 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, 218 DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK, 219 DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK); 220 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, 221 DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK, 222 DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK); 223 msleep(DA7219_SETTLING_DELAY); 224 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, 225 DA7219_HP_L_AMP_MUTE_EN_MASK | 226 DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, 0); 227 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, 228 DA7219_HP_R_AMP_MUTE_EN_MASK | 229 DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, 0); 230 231 /* 232 * If we're running from the internal oscillator then give audio paths 233 * time to settle before running test. 234 */ 235 if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK)) 236 msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY); 237 238 /* Configure & start Tone Generator */ 239 snd_soc_component_write(component, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK); 240 regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L, 241 &tonegen_freq_hptest, sizeof(tonegen_freq_hptest)); 242 snd_soc_component_update_bits(component, DA7219_TONE_GEN_CFG2, 243 DA7219_SWG_SEL_MASK | DA7219_TONE_GEN_GAIN_MASK, 244 DA7219_SWG_SEL_SRAMP | 245 DA7219_TONE_GEN_GAIN_MINUS_15DB); 246 snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK); 247 248 msleep(DA7219_AAD_HPTEST_PERIOD); 249 250 /* Grab comparator reading */ 251 accdet_cfg8 = snd_soc_component_read(component, DA7219_ACCDET_CONFIG_8); 252 if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK) 253 report |= SND_JACK_HEADPHONE; 254 else 255 report |= SND_JACK_LINEOUT; 256 257 /* Stop tone generator */ 258 snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0); 259 260 msleep(DA7219_AAD_HPTEST_PERIOD); 261 262 /* Restore original settings from cache */ 263 regcache_mark_dirty(da7219->regmap); 264 regcache_sync_region(da7219->regmap, DA7219_HP_L_CTRL, 265 DA7219_HP_R_CTRL); 266 msleep(DA7219_SETTLING_DELAY); 267 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_CTRL, 268 DA7219_MIXOUT_R_CTRL); 269 regcache_sync_region(da7219->regmap, DA7219_DROUTING_ST_OUTFILT_1L, 270 DA7219_DROUTING_ST_OUTFILT_1R); 271 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_SELECT, 272 DA7219_MIXOUT_R_SELECT); 273 regcache_sync_region(da7219->regmap, DA7219_DAC_L_CTRL, 274 DA7219_DAC_R_CTRL); 275 regcache_sync_region(da7219->regmap, DA7219_DIG_ROUTING_DAC, 276 DA7219_DIG_ROUTING_DAC); 277 regcache_sync_region(da7219->regmap, DA7219_CP_CTRL, DA7219_CP_CTRL); 278 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS5, 279 DA7219_DAC_FILTERS5); 280 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS4, 281 DA7219_DAC_FILTERS1); 282 regcache_sync_region(da7219->regmap, DA7219_HP_L_GAIN, 283 DA7219_HP_R_GAIN); 284 regcache_sync_region(da7219->regmap, DA7219_DAC_L_GAIN, 285 DA7219_DAC_R_GAIN); 286 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_ON_PER, 287 DA7219_TONE_GEN_ON_PER); 288 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_FREQ1_L, 289 DA7219_TONE_GEN_FREQ1_U); 290 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_CFG1, 291 DA7219_TONE_GEN_CFG2); 292 293 regcache_cache_bypass(da7219->regmap, false); 294 295 /* Disable HPTest block */ 296 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8, 297 DA7219_HPTEST_EN_MASK, 0); 298 299 /* 300 * If we're running from the internal oscillator then give audio paths 301 * time to settle before allowing headphones to be driven as required. 302 */ 303 if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK)) 304 msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY); 305 306 /* Restore gain ramping rate */ 307 snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl); 308 309 /* Drive Headphones/lineout */ 310 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK, 311 DA7219_HP_L_AMP_OE_MASK); 312 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK, 313 DA7219_HP_R_AMP_OE_MASK); 314 315 /* Restore PLL to previous configuration, if re-configured */ 316 if ((pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) && 317 ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS)) 318 da7219_set_pll(component, DA7219_SYSCLK_MCLK, 0); 319 320 /* Remove MCLK, if previously enabled */ 321 if (da7219->mclk) 322 clk_disable_unprepare(da7219->mclk); 323 324 mutex_unlock(&da7219->pll_lock); 325 mutex_unlock(&da7219->ctrl_lock); 326 snd_soc_dapm_mutex_unlock(dapm); 327 328 /* 329 * Only send report if jack hasn't been removed during process, 330 * otherwise it's invalid and we drop it. 331 */ 332 if (da7219_aad->jack_inserted) 333 snd_soc_jack_report(da7219_aad->jack, report, 334 SND_JACK_HEADSET | SND_JACK_LINEOUT); 335 } 336 337 338 /* 339 * IRQ 340 */ 341 342 static irqreturn_t da7219_aad_irq_thread(int irq, void *data) 343 { 344 struct da7219_aad_priv *da7219_aad = data; 345 struct snd_soc_component *component = da7219_aad->component; 346 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 347 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 348 u8 events[DA7219_AAD_IRQ_REG_MAX]; 349 u8 statusa; 350 int i, report = 0, mask = 0; 351 352 /* Read current IRQ events */ 353 regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, 354 events, DA7219_AAD_IRQ_REG_MAX); 355 356 if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B]) 357 return IRQ_NONE; 358 359 /* Read status register for jack insertion & type status */ 360 statusa = snd_soc_component_read(component, DA7219_ACCDET_STATUS_A); 361 362 /* Clear events */ 363 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, 364 events, DA7219_AAD_IRQ_REG_MAX); 365 366 dev_dbg(component->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n", 367 events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B], 368 statusa); 369 370 if (statusa & DA7219_JACK_INSERTION_STS_MASK) { 371 /* Jack Insertion */ 372 if (events[DA7219_AAD_IRQ_REG_A] & 373 DA7219_E_JACK_INSERTED_MASK) { 374 report |= SND_JACK_MECHANICAL; 375 mask |= SND_JACK_MECHANICAL; 376 da7219_aad->jack_inserted = true; 377 } 378 379 /* Jack type detection */ 380 if (events[DA7219_AAD_IRQ_REG_A] & 381 DA7219_E_JACK_DETECT_COMPLETE_MASK) { 382 /* 383 * If 4-pole, then enable button detection, else perform 384 * HP impedance test to determine output type to report. 385 * 386 * We schedule work here as the tasks themselves can 387 * take time to complete, and in particular for hptest 388 * we want to be able to check if the jack was removed 389 * during the procedure as this will invalidate the 390 * result. By doing this as work, the IRQ thread can 391 * handle a removal, and we can check at the end of 392 * hptest if we have a valid result or not. 393 */ 394 if (statusa & DA7219_JACK_TYPE_STS_MASK) { 395 report |= SND_JACK_HEADSET; 396 mask |= SND_JACK_HEADSET | SND_JACK_LINEOUT; 397 schedule_work(&da7219_aad->btn_det_work); 398 } else { 399 schedule_work(&da7219_aad->hptest_work); 400 } 401 } 402 403 /* Button support for 4-pole jack */ 404 if (statusa & DA7219_JACK_TYPE_STS_MASK) { 405 for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) { 406 /* Button Press */ 407 if (events[DA7219_AAD_IRQ_REG_B] & 408 (DA7219_E_BUTTON_A_PRESSED_MASK << i)) { 409 report |= SND_JACK_BTN_0 >> i; 410 mask |= SND_JACK_BTN_0 >> i; 411 } 412 } 413 snd_soc_jack_report(da7219_aad->jack, report, mask); 414 415 for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) { 416 /* Button Release */ 417 if (events[DA7219_AAD_IRQ_REG_B] & 418 (DA7219_E_BUTTON_A_RELEASED_MASK >> i)) { 419 report &= ~(SND_JACK_BTN_0 >> i); 420 mask |= SND_JACK_BTN_0 >> i; 421 } 422 } 423 } 424 } else { 425 /* Jack removal */ 426 if (events[DA7219_AAD_IRQ_REG_A] & DA7219_E_JACK_REMOVED_MASK) { 427 report = 0; 428 mask |= DA7219_AAD_REPORT_ALL_MASK; 429 da7219_aad->jack_inserted = false; 430 431 /* Un-drive headphones/lineout */ 432 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, 433 DA7219_HP_R_AMP_OE_MASK, 0); 434 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, 435 DA7219_HP_L_AMP_OE_MASK, 0); 436 437 /* Ensure button detection disabled */ 438 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, 439 DA7219_BUTTON_CONFIG_MASK, 0); 440 441 da7219->micbias_on_event = false; 442 443 /* Disable mic bias */ 444 snd_soc_dapm_disable_pin(dapm, "Mic Bias"); 445 snd_soc_dapm_sync(dapm); 446 447 /* Cancel any pending work */ 448 cancel_work_sync(&da7219_aad->btn_det_work); 449 cancel_work_sync(&da7219_aad->hptest_work); 450 } 451 } 452 453 snd_soc_jack_report(da7219_aad->jack, report, mask); 454 455 return IRQ_HANDLED; 456 } 457 458 /* 459 * DT/ACPI to pdata conversion 460 */ 461 462 static enum da7219_aad_micbias_pulse_lvl 463 da7219_aad_fw_micbias_pulse_lvl(struct device *dev, u32 val) 464 { 465 switch (val) { 466 case 2800: 467 return DA7219_AAD_MICBIAS_PULSE_LVL_2_8V; 468 case 2900: 469 return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V; 470 default: 471 dev_warn(dev, "Invalid micbias pulse level"); 472 return DA7219_AAD_MICBIAS_PULSE_LVL_OFF; 473 } 474 } 475 476 static enum da7219_aad_btn_cfg 477 da7219_aad_fw_btn_cfg(struct device *dev, u32 val) 478 { 479 switch (val) { 480 case 2: 481 return DA7219_AAD_BTN_CFG_2MS; 482 case 5: 483 return DA7219_AAD_BTN_CFG_5MS; 484 case 10: 485 return DA7219_AAD_BTN_CFG_10MS; 486 case 50: 487 return DA7219_AAD_BTN_CFG_50MS; 488 case 100: 489 return DA7219_AAD_BTN_CFG_100MS; 490 case 200: 491 return DA7219_AAD_BTN_CFG_200MS; 492 case 500: 493 return DA7219_AAD_BTN_CFG_500MS; 494 default: 495 dev_warn(dev, "Invalid button config"); 496 return DA7219_AAD_BTN_CFG_10MS; 497 } 498 } 499 500 static enum da7219_aad_mic_det_thr 501 da7219_aad_fw_mic_det_thr(struct device *dev, u32 val) 502 { 503 switch (val) { 504 case 200: 505 return DA7219_AAD_MIC_DET_THR_200_OHMS; 506 case 500: 507 return DA7219_AAD_MIC_DET_THR_500_OHMS; 508 case 750: 509 return DA7219_AAD_MIC_DET_THR_750_OHMS; 510 case 1000: 511 return DA7219_AAD_MIC_DET_THR_1000_OHMS; 512 default: 513 dev_warn(dev, "Invalid mic detect threshold"); 514 return DA7219_AAD_MIC_DET_THR_500_OHMS; 515 } 516 } 517 518 static enum da7219_aad_jack_ins_deb 519 da7219_aad_fw_jack_ins_deb(struct device *dev, u32 val) 520 { 521 switch (val) { 522 case 5: 523 return DA7219_AAD_JACK_INS_DEB_5MS; 524 case 10: 525 return DA7219_AAD_JACK_INS_DEB_10MS; 526 case 20: 527 return DA7219_AAD_JACK_INS_DEB_20MS; 528 case 50: 529 return DA7219_AAD_JACK_INS_DEB_50MS; 530 case 100: 531 return DA7219_AAD_JACK_INS_DEB_100MS; 532 case 200: 533 return DA7219_AAD_JACK_INS_DEB_200MS; 534 case 500: 535 return DA7219_AAD_JACK_INS_DEB_500MS; 536 case 1000: 537 return DA7219_AAD_JACK_INS_DEB_1S; 538 default: 539 dev_warn(dev, "Invalid jack insert debounce"); 540 return DA7219_AAD_JACK_INS_DEB_20MS; 541 } 542 } 543 544 static enum da7219_aad_jack_det_rate 545 da7219_aad_fw_jack_det_rate(struct device *dev, const char *str) 546 { 547 if (!strcmp(str, "32ms_64ms")) { 548 return DA7219_AAD_JACK_DET_RATE_32_64MS; 549 } else if (!strcmp(str, "64ms_128ms")) { 550 return DA7219_AAD_JACK_DET_RATE_64_128MS; 551 } else if (!strcmp(str, "128ms_256ms")) { 552 return DA7219_AAD_JACK_DET_RATE_128_256MS; 553 } else if (!strcmp(str, "256ms_512ms")) { 554 return DA7219_AAD_JACK_DET_RATE_256_512MS; 555 } else { 556 dev_warn(dev, "Invalid jack detect rate"); 557 return DA7219_AAD_JACK_DET_RATE_256_512MS; 558 } 559 } 560 561 static enum da7219_aad_jack_rem_deb 562 da7219_aad_fw_jack_rem_deb(struct device *dev, u32 val) 563 { 564 switch (val) { 565 case 1: 566 return DA7219_AAD_JACK_REM_DEB_1MS; 567 case 5: 568 return DA7219_AAD_JACK_REM_DEB_5MS; 569 case 10: 570 return DA7219_AAD_JACK_REM_DEB_10MS; 571 case 20: 572 return DA7219_AAD_JACK_REM_DEB_20MS; 573 default: 574 dev_warn(dev, "Invalid jack removal debounce"); 575 return DA7219_AAD_JACK_REM_DEB_1MS; 576 } 577 } 578 579 static enum da7219_aad_btn_avg 580 da7219_aad_fw_btn_avg(struct device *dev, u32 val) 581 { 582 switch (val) { 583 case 1: 584 return DA7219_AAD_BTN_AVG_1; 585 case 2: 586 return DA7219_AAD_BTN_AVG_2; 587 case 4: 588 return DA7219_AAD_BTN_AVG_4; 589 case 8: 590 return DA7219_AAD_BTN_AVG_8; 591 default: 592 dev_warn(dev, "Invalid button average value"); 593 return DA7219_AAD_BTN_AVG_2; 594 } 595 } 596 597 static enum da7219_aad_adc_1bit_rpt 598 da7219_aad_fw_adc_1bit_rpt(struct device *dev, u32 val) 599 { 600 switch (val) { 601 case 1: 602 return DA7219_AAD_ADC_1BIT_RPT_1; 603 case 2: 604 return DA7219_AAD_ADC_1BIT_RPT_2; 605 case 4: 606 return DA7219_AAD_ADC_1BIT_RPT_4; 607 case 8: 608 return DA7219_AAD_ADC_1BIT_RPT_8; 609 default: 610 dev_warn(dev, "Invalid ADC 1-bit repeat value"); 611 return DA7219_AAD_ADC_1BIT_RPT_1; 612 } 613 } 614 615 static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev) 616 { 617 struct i2c_client *i2c = to_i2c_client(dev); 618 struct fwnode_handle *aad_np; 619 struct da7219_aad_pdata *aad_pdata; 620 const char *fw_str; 621 u32 fw_val32; 622 623 aad_np = device_get_named_child_node(dev, "da7219_aad"); 624 if (!aad_np) 625 return NULL; 626 627 aad_pdata = devm_kzalloc(dev, sizeof(*aad_pdata), GFP_KERNEL); 628 if (!aad_pdata) 629 return NULL; 630 631 aad_pdata->irq = i2c->irq; 632 633 if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl", 634 &fw_val32) >= 0) 635 aad_pdata->micbias_pulse_lvl = 636 da7219_aad_fw_micbias_pulse_lvl(dev, fw_val32); 637 else 638 aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF; 639 640 if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-time", 641 &fw_val32) >= 0) 642 aad_pdata->micbias_pulse_time = fw_val32; 643 644 if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0) 645 aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(dev, fw_val32); 646 else 647 aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS; 648 649 if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0) 650 aad_pdata->mic_det_thr = 651 da7219_aad_fw_mic_det_thr(dev, fw_val32); 652 else 653 aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS; 654 655 if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0) 656 aad_pdata->jack_ins_deb = 657 da7219_aad_fw_jack_ins_deb(dev, fw_val32); 658 else 659 aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS; 660 661 if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str)) 662 aad_pdata->jack_det_rate = 663 da7219_aad_fw_jack_det_rate(dev, fw_str); 664 else 665 aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS; 666 667 if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0) 668 aad_pdata->jack_rem_deb = 669 da7219_aad_fw_jack_rem_deb(dev, fw_val32); 670 else 671 aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS; 672 673 if (fwnode_property_read_u32(aad_np, "dlg,a-d-btn-thr", &fw_val32) >= 0) 674 aad_pdata->a_d_btn_thr = (u8) fw_val32; 675 else 676 aad_pdata->a_d_btn_thr = 0xA; 677 678 if (fwnode_property_read_u32(aad_np, "dlg,d-b-btn-thr", &fw_val32) >= 0) 679 aad_pdata->d_b_btn_thr = (u8) fw_val32; 680 else 681 aad_pdata->d_b_btn_thr = 0x16; 682 683 if (fwnode_property_read_u32(aad_np, "dlg,b-c-btn-thr", &fw_val32) >= 0) 684 aad_pdata->b_c_btn_thr = (u8) fw_val32; 685 else 686 aad_pdata->b_c_btn_thr = 0x21; 687 688 if (fwnode_property_read_u32(aad_np, "dlg,c-mic-btn-thr", &fw_val32) >= 0) 689 aad_pdata->c_mic_btn_thr = (u8) fw_val32; 690 else 691 aad_pdata->c_mic_btn_thr = 0x3E; 692 693 if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0) 694 aad_pdata->btn_avg = da7219_aad_fw_btn_avg(dev, fw_val32); 695 else 696 aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2; 697 698 if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0) 699 aad_pdata->adc_1bit_rpt = 700 da7219_aad_fw_adc_1bit_rpt(dev, fw_val32); 701 else 702 aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1; 703 704 return aad_pdata; 705 } 706 707 static void da7219_aad_handle_pdata(struct snd_soc_component *component) 708 { 709 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 710 struct da7219_aad_priv *da7219_aad = da7219->aad; 711 struct da7219_pdata *pdata = da7219->pdata; 712 713 if ((pdata) && (pdata->aad_pdata)) { 714 struct da7219_aad_pdata *aad_pdata = pdata->aad_pdata; 715 u8 cfg, mask; 716 717 da7219_aad->irq = aad_pdata->irq; 718 719 switch (aad_pdata->micbias_pulse_lvl) { 720 case DA7219_AAD_MICBIAS_PULSE_LVL_2_8V: 721 case DA7219_AAD_MICBIAS_PULSE_LVL_2_9V: 722 da7219_aad->micbias_pulse_lvl = 723 (aad_pdata->micbias_pulse_lvl << 724 DA7219_MICBIAS1_LEVEL_SHIFT); 725 break; 726 default: 727 break; 728 } 729 730 da7219_aad->micbias_pulse_time = aad_pdata->micbias_pulse_time; 731 732 switch (aad_pdata->btn_cfg) { 733 case DA7219_AAD_BTN_CFG_2MS: 734 case DA7219_AAD_BTN_CFG_5MS: 735 case DA7219_AAD_BTN_CFG_10MS: 736 case DA7219_AAD_BTN_CFG_50MS: 737 case DA7219_AAD_BTN_CFG_100MS: 738 case DA7219_AAD_BTN_CFG_200MS: 739 case DA7219_AAD_BTN_CFG_500MS: 740 da7219_aad->btn_cfg = (aad_pdata->btn_cfg << 741 DA7219_BUTTON_CONFIG_SHIFT); 742 } 743 744 cfg = 0; 745 mask = 0; 746 switch (aad_pdata->mic_det_thr) { 747 case DA7219_AAD_MIC_DET_THR_200_OHMS: 748 case DA7219_AAD_MIC_DET_THR_500_OHMS: 749 case DA7219_AAD_MIC_DET_THR_750_OHMS: 750 case DA7219_AAD_MIC_DET_THR_1000_OHMS: 751 cfg |= (aad_pdata->mic_det_thr << 752 DA7219_MIC_DET_THRESH_SHIFT); 753 mask |= DA7219_MIC_DET_THRESH_MASK; 754 } 755 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, mask, cfg); 756 757 cfg = 0; 758 mask = 0; 759 switch (aad_pdata->jack_ins_deb) { 760 case DA7219_AAD_JACK_INS_DEB_5MS: 761 case DA7219_AAD_JACK_INS_DEB_10MS: 762 case DA7219_AAD_JACK_INS_DEB_20MS: 763 case DA7219_AAD_JACK_INS_DEB_50MS: 764 case DA7219_AAD_JACK_INS_DEB_100MS: 765 case DA7219_AAD_JACK_INS_DEB_200MS: 766 case DA7219_AAD_JACK_INS_DEB_500MS: 767 case DA7219_AAD_JACK_INS_DEB_1S: 768 cfg |= (aad_pdata->jack_ins_deb << 769 DA7219_JACKDET_DEBOUNCE_SHIFT); 770 mask |= DA7219_JACKDET_DEBOUNCE_MASK; 771 } 772 switch (aad_pdata->jack_det_rate) { 773 case DA7219_AAD_JACK_DET_RATE_32_64MS: 774 case DA7219_AAD_JACK_DET_RATE_64_128MS: 775 case DA7219_AAD_JACK_DET_RATE_128_256MS: 776 case DA7219_AAD_JACK_DET_RATE_256_512MS: 777 cfg |= (aad_pdata->jack_det_rate << 778 DA7219_JACK_DETECT_RATE_SHIFT); 779 mask |= DA7219_JACK_DETECT_RATE_MASK; 780 } 781 switch (aad_pdata->jack_rem_deb) { 782 case DA7219_AAD_JACK_REM_DEB_1MS: 783 case DA7219_AAD_JACK_REM_DEB_5MS: 784 case DA7219_AAD_JACK_REM_DEB_10MS: 785 case DA7219_AAD_JACK_REM_DEB_20MS: 786 cfg |= (aad_pdata->jack_rem_deb << 787 DA7219_JACKDET_REM_DEB_SHIFT); 788 mask |= DA7219_JACKDET_REM_DEB_MASK; 789 } 790 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_2, mask, cfg); 791 792 snd_soc_component_write(component, DA7219_ACCDET_CONFIG_3, 793 aad_pdata->a_d_btn_thr); 794 snd_soc_component_write(component, DA7219_ACCDET_CONFIG_4, 795 aad_pdata->d_b_btn_thr); 796 snd_soc_component_write(component, DA7219_ACCDET_CONFIG_5, 797 aad_pdata->b_c_btn_thr); 798 snd_soc_component_write(component, DA7219_ACCDET_CONFIG_6, 799 aad_pdata->c_mic_btn_thr); 800 801 cfg = 0; 802 mask = 0; 803 switch (aad_pdata->btn_avg) { 804 case DA7219_AAD_BTN_AVG_1: 805 case DA7219_AAD_BTN_AVG_2: 806 case DA7219_AAD_BTN_AVG_4: 807 case DA7219_AAD_BTN_AVG_8: 808 cfg |= (aad_pdata->btn_avg << 809 DA7219_BUTTON_AVERAGE_SHIFT); 810 mask |= DA7219_BUTTON_AVERAGE_MASK; 811 } 812 switch (aad_pdata->adc_1bit_rpt) { 813 case DA7219_AAD_ADC_1BIT_RPT_1: 814 case DA7219_AAD_ADC_1BIT_RPT_2: 815 case DA7219_AAD_ADC_1BIT_RPT_4: 816 case DA7219_AAD_ADC_1BIT_RPT_8: 817 cfg |= (aad_pdata->adc_1bit_rpt << 818 DA7219_ADC_1_BIT_REPEAT_SHIFT); 819 mask |= DA7219_ADC_1_BIT_REPEAT_MASK; 820 } 821 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_7, mask, cfg); 822 } 823 } 824 825 826 /* 827 * Suspend/Resume 828 */ 829 830 void da7219_aad_suspend(struct snd_soc_component *component) 831 { 832 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 833 struct da7219_aad_priv *da7219_aad = da7219->aad; 834 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 835 u8 micbias_ctrl; 836 837 if (da7219_aad->jack) { 838 /* Disable jack detection during suspend */ 839 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, 840 DA7219_ACCDET_EN_MASK, 0); 841 842 /* 843 * If we have a 4-pole jack inserted, then micbias will be 844 * enabled. We can disable micbias here, and keep a note to 845 * re-enable it on resume. If jack removal occurred during 846 * suspend then this will be dealt with through the IRQ handler. 847 */ 848 if (da7219_aad->jack_inserted) { 849 micbias_ctrl = snd_soc_component_read(component, DA7219_MICBIAS_CTRL); 850 if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) { 851 snd_soc_dapm_disable_pin(dapm, "Mic Bias"); 852 snd_soc_dapm_sync(dapm); 853 da7219_aad->micbias_resume_enable = true; 854 } 855 } 856 } 857 } 858 859 void da7219_aad_resume(struct snd_soc_component *component) 860 { 861 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 862 struct da7219_aad_priv *da7219_aad = da7219->aad; 863 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 864 865 if (da7219_aad->jack) { 866 /* Re-enable micbias if previously enabled for 4-pole jack */ 867 if (da7219_aad->jack_inserted && 868 da7219_aad->micbias_resume_enable) { 869 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); 870 snd_soc_dapm_sync(dapm); 871 da7219_aad->micbias_resume_enable = false; 872 } 873 874 /* Re-enable jack detection */ 875 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, 876 DA7219_ACCDET_EN_MASK, 877 DA7219_ACCDET_EN_MASK); 878 } 879 } 880 881 882 /* 883 * Init/Exit 884 */ 885 886 int da7219_aad_init(struct snd_soc_component *component) 887 { 888 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 889 struct da7219_aad_priv *da7219_aad = da7219->aad; 890 u8 mask[DA7219_AAD_IRQ_REG_MAX]; 891 int ret; 892 893 da7219_aad->component = component; 894 895 /* Handle any DT/ACPI/platform data */ 896 da7219_aad_handle_pdata(component); 897 898 /* Disable button detection */ 899 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, 900 DA7219_BUTTON_CONFIG_MASK, 0); 901 902 INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work); 903 INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work); 904 905 ret = request_threaded_irq(da7219_aad->irq, NULL, 906 da7219_aad_irq_thread, 907 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 908 "da7219-aad", da7219_aad); 909 if (ret) { 910 dev_err(component->dev, "Failed to request IRQ: %d\n", ret); 911 return ret; 912 } 913 914 /* Unmask AAD IRQs */ 915 memset(mask, 0, DA7219_AAD_IRQ_REG_MAX); 916 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A, 917 &mask, DA7219_AAD_IRQ_REG_MAX); 918 919 return 0; 920 } 921 EXPORT_SYMBOL_GPL(da7219_aad_init); 922 923 void da7219_aad_exit(struct snd_soc_component *component) 924 { 925 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); 926 struct da7219_aad_priv *da7219_aad = da7219->aad; 927 u8 mask[DA7219_AAD_IRQ_REG_MAX]; 928 929 /* Mask off AAD IRQs */ 930 memset(mask, DA7219_BYTE_MASK, DA7219_AAD_IRQ_REG_MAX); 931 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A, 932 mask, DA7219_AAD_IRQ_REG_MAX); 933 934 free_irq(da7219_aad->irq, da7219_aad); 935 936 cancel_work_sync(&da7219_aad->btn_det_work); 937 cancel_work_sync(&da7219_aad->hptest_work); 938 } 939 EXPORT_SYMBOL_GPL(da7219_aad_exit); 940 941 /* 942 * AAD related I2C probe handling 943 */ 944 945 int da7219_aad_probe(struct i2c_client *i2c) 946 { 947 struct da7219_priv *da7219 = i2c_get_clientdata(i2c); 948 struct device *dev = &i2c->dev; 949 struct da7219_aad_priv *da7219_aad; 950 951 da7219_aad = devm_kzalloc(dev, sizeof(*da7219_aad), GFP_KERNEL); 952 if (!da7219_aad) 953 return -ENOMEM; 954 955 da7219->aad = da7219_aad; 956 957 /* Retrieve any DT/ACPI/platform data */ 958 if (da7219->pdata && !da7219->pdata->aad_pdata) 959 da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(dev); 960 961 return 0; 962 } 963 EXPORT_SYMBOL_GPL(da7219_aad_probe); 964 965 MODULE_DESCRIPTION("ASoC DA7219 AAD Driver"); 966 MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>"); 967 MODULE_LICENSE("GPL"); 968