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