1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. 3 4 #include <linux/module.h> 5 #include <linux/init.h> 6 #include <linux/slab.h> 7 #include <linux/device.h> 8 #include <linux/pm_runtime.h> 9 #include <linux/printk.h> 10 #include <linux/delay.h> 11 #include <linux/kernel.h> 12 #include <sound/soc.h> 13 #include <sound/jack.h> 14 #include "wcd-mbhc-v2.h" 15 16 #define HS_DETECT_PLUG_TIME_MS (3 * 1000) 17 #define MBHC_BUTTON_PRESS_THRESHOLD_MIN 250 18 #define GND_MIC_SWAP_THRESHOLD 4 19 #define WCD_FAKE_REMOVAL_MIN_PERIOD_MS 100 20 #define HPHL_CROSS_CONN_THRESHOLD 100 21 #define HS_VREF_MIN_VAL 1400 22 #define FAKE_REM_RETRY_ATTEMPTS 3 23 #define WCD_MBHC_ADC_HS_THRESHOLD_MV 1700 24 #define WCD_MBHC_ADC_HPH_THRESHOLD_MV 75 25 #define WCD_MBHC_ADC_MICBIAS_MV 1800 26 #define WCD_MBHC_FAKE_INS_RETRY 4 27 28 #define WCD_MBHC_JACK_MASK (SND_JACK_HEADSET | SND_JACK_LINEOUT | \ 29 SND_JACK_MECHANICAL) 30 31 #define WCD_MBHC_JACK_BUTTON_MASK (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \ 32 SND_JACK_BTN_2 | SND_JACK_BTN_3 | \ 33 SND_JACK_BTN_4 | SND_JACK_BTN_5) 34 35 enum wcd_mbhc_adc_mux_ctl { 36 MUX_CTL_AUTO = 0, 37 MUX_CTL_IN2P, 38 MUX_CTL_IN3P, 39 MUX_CTL_IN4P, 40 MUX_CTL_HPH_L, 41 MUX_CTL_HPH_R, 42 MUX_CTL_NONE, 43 }; 44 45 struct wcd_mbhc { 46 struct device *dev; 47 struct snd_soc_component *component; 48 struct snd_soc_jack *jack; 49 struct wcd_mbhc_config *cfg; 50 const struct wcd_mbhc_cb *mbhc_cb; 51 const struct wcd_mbhc_intr *intr_ids; 52 struct wcd_mbhc_field *fields; 53 /* Delayed work to report long button press */ 54 struct delayed_work mbhc_btn_dwork; 55 /* Work to correct accessory type */ 56 struct work_struct correct_plug_swch; 57 struct mutex lock; 58 int buttons_pressed; 59 u32 hph_status; /* track headhpone status */ 60 u8 current_plug; 61 bool is_btn_press; 62 bool in_swch_irq_handler; 63 bool hs_detect_work_stop; 64 bool is_hs_recording; 65 bool extn_cable_hph_rem; 66 bool force_linein; 67 bool impedance_detect; 68 unsigned long event_state; 69 unsigned long jiffies_atreport; 70 /* impedance of hphl and hphr */ 71 uint32_t zl, zr; 72 /* Holds type of Headset - Mono/Stereo */ 73 enum wcd_mbhc_hph_type hph_type; 74 /* Holds mbhc detection method - ADC/Legacy */ 75 int mbhc_detection_logic; 76 }; 77 78 static inline int wcd_mbhc_write_field(const struct wcd_mbhc *mbhc, 79 int field, int val) 80 { 81 if (!mbhc->fields[field].reg) 82 return 0; 83 84 return snd_soc_component_write_field(mbhc->component, 85 mbhc->fields[field].reg, 86 mbhc->fields[field].mask, val); 87 } 88 89 static inline int wcd_mbhc_read_field(const struct wcd_mbhc *mbhc, int field) 90 { 91 if (!mbhc->fields[field].reg) 92 return 0; 93 94 return snd_soc_component_read_field(mbhc->component, 95 mbhc->fields[field].reg, 96 mbhc->fields[field].mask); 97 } 98 99 static void wcd_program_hs_vref(struct wcd_mbhc *mbhc) 100 { 101 u32 reg_val = ((mbhc->cfg->v_hs_max - HS_VREF_MIN_VAL) / 100); 102 103 wcd_mbhc_write_field(mbhc, WCD_MBHC_HS_VREF, reg_val); 104 } 105 106 static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc, bool micbias) 107 { 108 struct snd_soc_component *component = mbhc->component; 109 110 mbhc->mbhc_cb->set_btn_thr(component, mbhc->cfg->btn_low, 111 mbhc->cfg->btn_high, 112 mbhc->cfg->num_btn, micbias); 113 } 114 115 static void wcd_mbhc_curr_micbias_control(const struct wcd_mbhc *mbhc, 116 const enum wcd_mbhc_cs_mb_en_flag cs_mb_en) 117 { 118 119 /* 120 * Some codecs handle micbias/pullup enablement in codec 121 * drivers itself and micbias is not needed for regular 122 * plug type detection. So if micbias_control callback function 123 * is defined, just return. 124 */ 125 if (mbhc->mbhc_cb->mbhc_micbias_control) 126 return; 127 128 switch (cs_mb_en) { 129 case WCD_MBHC_EN_CS: 130 wcd_mbhc_write_field(mbhc, WCD_MBHC_MICB_CTRL, 0); 131 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 3); 132 /* Program Button threshold registers as per CS */ 133 wcd_program_btn_threshold(mbhc, false); 134 break; 135 case WCD_MBHC_EN_MB: 136 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 0); 137 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 1); 138 /* Disable PULL_UP_EN & enable MICBIAS */ 139 wcd_mbhc_write_field(mbhc, WCD_MBHC_MICB_CTRL, 2); 140 /* Program Button threshold registers as per MICBIAS */ 141 wcd_program_btn_threshold(mbhc, true); 142 break; 143 case WCD_MBHC_EN_PULLUP: 144 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 3); 145 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 1); 146 wcd_mbhc_write_field(mbhc, WCD_MBHC_MICB_CTRL, 1); 147 /* Program Button threshold registers as per MICBIAS */ 148 wcd_program_btn_threshold(mbhc, true); 149 break; 150 case WCD_MBHC_EN_NONE: 151 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 0); 152 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 1); 153 wcd_mbhc_write_field(mbhc, WCD_MBHC_MICB_CTRL, 0); 154 break; 155 default: 156 dev_err(mbhc->dev, "%s: Invalid parameter", __func__); 157 break; 158 } 159 } 160 161 int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event) 162 { 163 164 struct snd_soc_component *component; 165 bool micbias2 = false; 166 167 if (!mbhc) 168 return 0; 169 170 component = mbhc->component; 171 172 if (mbhc->mbhc_cb->micbias_enable_status) 173 micbias2 = mbhc->mbhc_cb->micbias_enable_status(component, MIC_BIAS_2); 174 175 switch (event) { 176 /* MICBIAS usage change */ 177 case WCD_EVENT_POST_DAPM_MICBIAS_2_ON: 178 mbhc->is_hs_recording = true; 179 break; 180 case WCD_EVENT_POST_MICBIAS_2_ON: 181 /* Disable current source if micbias2 enabled */ 182 if (mbhc->mbhc_cb->mbhc_micbias_control) { 183 if (wcd_mbhc_read_field(mbhc, WCD_MBHC_FSM_EN)) 184 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 0); 185 } else { 186 mbhc->is_hs_recording = true; 187 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_MB); 188 } 189 break; 190 case WCD_EVENT_PRE_MICBIAS_2_OFF: 191 /* 192 * Before MICBIAS_2 is turned off, if FSM is enabled, 193 * make sure current source is enabled so as to detect 194 * button press/release events 195 */ 196 if (mbhc->mbhc_cb->mbhc_micbias_control/* && !mbhc->micbias_enable*/) { 197 if (wcd_mbhc_read_field(mbhc, WCD_MBHC_FSM_EN)) 198 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 3); 199 } 200 break; 201 /* MICBIAS usage change */ 202 case WCD_EVENT_POST_DAPM_MICBIAS_2_OFF: 203 mbhc->is_hs_recording = false; 204 break; 205 case WCD_EVENT_POST_MICBIAS_2_OFF: 206 if (!mbhc->mbhc_cb->mbhc_micbias_control) 207 mbhc->is_hs_recording = false; 208 209 /* Enable PULL UP if PA's are enabled */ 210 if ((test_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state)) || 211 (test_bit(WCD_MBHC_EVENT_PA_HPHR, &mbhc->event_state))) 212 /* enable pullup and cs, disable mb */ 213 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_PULLUP); 214 else 215 /* enable current source and disable mb, pullup*/ 216 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_CS); 217 218 break; 219 case WCD_EVENT_POST_HPHL_PA_OFF: 220 clear_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state); 221 222 /* check if micbias is enabled */ 223 if (micbias2) 224 /* Disable cs, pullup & enable micbias */ 225 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_MB); 226 else 227 /* Disable micbias, pullup & enable cs */ 228 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_CS); 229 break; 230 case WCD_EVENT_POST_HPHR_PA_OFF: 231 clear_bit(WCD_MBHC_EVENT_PA_HPHR, &mbhc->event_state); 232 /* check if micbias is enabled */ 233 if (micbias2) 234 /* Disable cs, pullup & enable micbias */ 235 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_MB); 236 else 237 /* Disable micbias, pullup & enable cs */ 238 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_CS); 239 break; 240 case WCD_EVENT_PRE_HPHL_PA_ON: 241 set_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state); 242 /* check if micbias is enabled */ 243 if (micbias2) 244 /* Disable cs, pullup & enable micbias */ 245 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_MB); 246 else 247 /* Disable micbias, enable pullup & cs */ 248 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_PULLUP); 249 break; 250 case WCD_EVENT_PRE_HPHR_PA_ON: 251 set_bit(WCD_MBHC_EVENT_PA_HPHR, &mbhc->event_state); 252 /* check if micbias is enabled */ 253 if (micbias2) 254 /* Disable cs, pullup & enable micbias */ 255 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_MB); 256 else 257 /* Disable micbias, enable pullup & cs */ 258 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_PULLUP); 259 break; 260 default: 261 break; 262 } 263 return 0; 264 } 265 EXPORT_SYMBOL_GPL(wcd_mbhc_event_notify); 266 267 static int wcd_cancel_btn_work(struct wcd_mbhc *mbhc) 268 { 269 return cancel_delayed_work_sync(&mbhc->mbhc_btn_dwork); 270 } 271 272 static void wcd_micbias_disable(struct wcd_mbhc *mbhc) 273 { 274 struct snd_soc_component *component = mbhc->component; 275 276 if (mbhc->mbhc_cb->mbhc_micbias_control) 277 mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, MICB_DISABLE); 278 279 if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) 280 mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(component, MIC_BIAS_2, false); 281 282 if (mbhc->mbhc_cb->set_micbias_value) { 283 mbhc->mbhc_cb->set_micbias_value(component); 284 wcd_mbhc_write_field(mbhc, WCD_MBHC_MICB_CTRL, 0); 285 } 286 } 287 288 static void wcd_mbhc_report_plug_removal(struct wcd_mbhc *mbhc, 289 enum snd_jack_types jack_type) 290 { 291 mbhc->hph_status &= ~jack_type; 292 /* 293 * cancel possibly scheduled btn work and 294 * report release if we reported button press 295 */ 296 if (!wcd_cancel_btn_work(mbhc) && mbhc->buttons_pressed) { 297 snd_soc_jack_report(mbhc->jack, 0, mbhc->buttons_pressed); 298 mbhc->buttons_pressed &= ~WCD_MBHC_JACK_BUTTON_MASK; 299 } 300 301 wcd_micbias_disable(mbhc); 302 mbhc->hph_type = WCD_MBHC_HPH_NONE; 303 mbhc->zl = mbhc->zr = 0; 304 snd_soc_jack_report(mbhc->jack, mbhc->hph_status, WCD_MBHC_JACK_MASK); 305 mbhc->current_plug = MBHC_PLUG_TYPE_NONE; 306 mbhc->force_linein = false; 307 } 308 309 static void wcd_mbhc_compute_impedance(struct wcd_mbhc *mbhc) 310 { 311 312 if (!mbhc->impedance_detect) 313 return; 314 315 if (mbhc->cfg->linein_th != 0) { 316 u8 fsm_en = wcd_mbhc_read_field(mbhc, WCD_MBHC_FSM_EN); 317 /* Set MUX_CTL to AUTO for Z-det */ 318 319 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 0); 320 wcd_mbhc_write_field(mbhc, WCD_MBHC_MUX_CTL, MUX_CTL_AUTO); 321 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 1); 322 mbhc->mbhc_cb->compute_impedance(mbhc->component, &mbhc->zl, &mbhc->zr); 323 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, fsm_en); 324 } 325 } 326 327 static void wcd_mbhc_report_plug_insertion(struct wcd_mbhc *mbhc, 328 enum snd_jack_types jack_type) 329 { 330 bool is_pa_on; 331 /* 332 * Report removal of current jack type. 333 * Headphone to headset shouldn't report headphone 334 * removal. 335 */ 336 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET && 337 jack_type == SND_JACK_HEADPHONE) 338 mbhc->hph_status &= ~SND_JACK_HEADSET; 339 340 /* Report insertion */ 341 switch (jack_type) { 342 case SND_JACK_HEADPHONE: 343 mbhc->current_plug = MBHC_PLUG_TYPE_HEADPHONE; 344 break; 345 case SND_JACK_HEADSET: 346 mbhc->current_plug = MBHC_PLUG_TYPE_HEADSET; 347 mbhc->jiffies_atreport = jiffies; 348 break; 349 case SND_JACK_LINEOUT: 350 mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; 351 break; 352 default: 353 break; 354 } 355 356 357 is_pa_on = wcd_mbhc_read_field(mbhc, WCD_MBHC_HPH_PA_EN); 358 359 if (!is_pa_on) { 360 wcd_mbhc_compute_impedance(mbhc); 361 if ((mbhc->zl > mbhc->cfg->linein_th) && 362 (mbhc->zr > mbhc->cfg->linein_th) && 363 (jack_type == SND_JACK_HEADPHONE)) { 364 jack_type = SND_JACK_LINEOUT; 365 mbhc->force_linein = true; 366 mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; 367 if (mbhc->hph_status) { 368 mbhc->hph_status &= ~(SND_JACK_HEADSET | 369 SND_JACK_LINEOUT); 370 snd_soc_jack_report(mbhc->jack, mbhc->hph_status, 371 WCD_MBHC_JACK_MASK); 372 } 373 } 374 } 375 376 /* Do not calculate impedance again for lineout 377 * as during playback pa is on and impedance values 378 * will not be correct resulting in lineout detected 379 * as headphone. 380 */ 381 if (is_pa_on && mbhc->force_linein) { 382 jack_type = SND_JACK_LINEOUT; 383 mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; 384 if (mbhc->hph_status) { 385 mbhc->hph_status &= ~(SND_JACK_HEADSET | 386 SND_JACK_LINEOUT); 387 snd_soc_jack_report(mbhc->jack, mbhc->hph_status, 388 WCD_MBHC_JACK_MASK); 389 } 390 } 391 392 mbhc->hph_status |= jack_type; 393 394 if (jack_type == SND_JACK_HEADPHONE && mbhc->mbhc_cb->mbhc_micb_ramp_control) 395 mbhc->mbhc_cb->mbhc_micb_ramp_control(mbhc->component, false); 396 397 snd_soc_jack_report(mbhc->jack, (mbhc->hph_status | SND_JACK_MECHANICAL), 398 WCD_MBHC_JACK_MASK); 399 } 400 401 static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, 402 enum snd_jack_types jack_type) 403 { 404 405 WARN_ON(!mutex_is_locked(&mbhc->lock)); 406 407 if (!insertion) /* Report removal */ 408 wcd_mbhc_report_plug_removal(mbhc, jack_type); 409 else 410 wcd_mbhc_report_plug_insertion(mbhc, jack_type); 411 412 } 413 414 static void wcd_cancel_hs_detect_plug(struct wcd_mbhc *mbhc, 415 struct work_struct *work) 416 { 417 mbhc->hs_detect_work_stop = true; 418 mutex_unlock(&mbhc->lock); 419 cancel_work_sync(work); 420 mutex_lock(&mbhc->lock); 421 } 422 423 static void wcd_mbhc_cancel_pending_work(struct wcd_mbhc *mbhc) 424 { 425 /* cancel pending button press */ 426 wcd_cancel_btn_work(mbhc); 427 /* cancel correct work function */ 428 wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); 429 } 430 431 static void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc) 432 { 433 wcd_mbhc_cancel_pending_work(mbhc); 434 /* Report extension cable */ 435 wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); 436 /* 437 * Disable HPHL trigger and MIC Schmitt triggers. 438 * Setup for insertion detection. 439 */ 440 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_rem_intr); 441 wcd_mbhc_curr_micbias_control(mbhc, WCD_MBHC_EN_NONE); 442 /* Disable HW FSM */ 443 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 0); 444 wcd_mbhc_write_field(mbhc, WCD_MBHC_ELECT_SCHMT_ISRC, 3); 445 446 /* Set the detection type appropriately */ 447 wcd_mbhc_write_field(mbhc, WCD_MBHC_ELECT_DETECTION_TYPE, 1); 448 enable_irq(mbhc->intr_ids->mbhc_hs_ins_intr); 449 } 450 451 static void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, 452 enum wcd_mbhc_plug_type plug_type) 453 { 454 if (mbhc->current_plug == plug_type) 455 return; 456 457 mutex_lock(&mbhc->lock); 458 459 switch (plug_type) { 460 case MBHC_PLUG_TYPE_HEADPHONE: 461 wcd_mbhc_report_plug(mbhc, 1, SND_JACK_HEADPHONE); 462 break; 463 case MBHC_PLUG_TYPE_HEADSET: 464 wcd_mbhc_report_plug(mbhc, 1, SND_JACK_HEADSET); 465 break; 466 case MBHC_PLUG_TYPE_HIGH_HPH: 467 wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); 468 break; 469 case MBHC_PLUG_TYPE_GND_MIC_SWAP: 470 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) 471 wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADPHONE); 472 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) 473 wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET); 474 break; 475 default: 476 WARN(1, "Unexpected current plug_type %d, plug_type %d\n", 477 mbhc->current_plug, plug_type); 478 break; 479 } 480 mutex_unlock(&mbhc->lock); 481 } 482 483 static void wcd_schedule_hs_detect_plug(struct wcd_mbhc *mbhc, 484 struct work_struct *work) 485 { 486 WARN_ON(!mutex_is_locked(&mbhc->lock)); 487 mbhc->hs_detect_work_stop = false; 488 schedule_work(work); 489 } 490 491 static void wcd_mbhc_adc_detect_plug_type(struct wcd_mbhc *mbhc) 492 { 493 struct snd_soc_component *component = mbhc->component; 494 495 WARN_ON(!mutex_is_locked(&mbhc->lock)); 496 497 if (mbhc->mbhc_cb->hph_pull_down_ctrl) 498 mbhc->mbhc_cb->hph_pull_down_ctrl(component, false); 499 500 wcd_mbhc_write_field(mbhc, WCD_MBHC_DETECTION_DONE, 0); 501 502 if (mbhc->mbhc_cb->mbhc_micbias_control) { 503 mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, 504 MICB_ENABLE); 505 wcd_schedule_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); 506 } 507 } 508 509 static irqreturn_t wcd_mbhc_mech_plug_detect_irq(int irq, void *data) 510 { 511 struct snd_soc_component *component; 512 enum snd_jack_types jack_type; 513 struct wcd_mbhc *mbhc = data; 514 bool detection_type; 515 516 component = mbhc->component; 517 mutex_lock(&mbhc->lock); 518 519 mbhc->in_swch_irq_handler = true; 520 521 wcd_mbhc_cancel_pending_work(mbhc); 522 523 detection_type = wcd_mbhc_read_field(mbhc, WCD_MBHC_MECH_DETECTION_TYPE); 524 525 /* Set the detection type appropriately */ 526 wcd_mbhc_write_field(mbhc, WCD_MBHC_MECH_DETECTION_TYPE, !detection_type); 527 528 /* Enable micbias ramp */ 529 if (mbhc->mbhc_cb->mbhc_micb_ramp_control) 530 mbhc->mbhc_cb->mbhc_micb_ramp_control(component, true); 531 532 if (detection_type) { 533 if (mbhc->current_plug != MBHC_PLUG_TYPE_NONE) 534 goto exit; 535 /* Make sure MASTER_BIAS_CTL is enabled */ 536 mbhc->mbhc_cb->mbhc_bias(component, true); 537 mbhc->is_btn_press = false; 538 wcd_mbhc_adc_detect_plug_type(mbhc); 539 } else { 540 /* Disable HW FSM */ 541 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 0); 542 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 0); 543 mbhc->extn_cable_hph_rem = false; 544 545 if (mbhc->current_plug == MBHC_PLUG_TYPE_NONE) 546 goto exit; 547 548 mbhc->is_btn_press = false; 549 switch (mbhc->current_plug) { 550 case MBHC_PLUG_TYPE_HEADPHONE: 551 jack_type = SND_JACK_HEADPHONE; 552 break; 553 case MBHC_PLUG_TYPE_HEADSET: 554 jack_type = SND_JACK_HEADSET; 555 break; 556 case MBHC_PLUG_TYPE_HIGH_HPH: 557 if (mbhc->mbhc_detection_logic == WCD_DETECTION_ADC) 558 wcd_mbhc_write_field(mbhc, WCD_MBHC_ELECT_ISRC_EN, 0); 559 jack_type = SND_JACK_LINEOUT; 560 break; 561 case MBHC_PLUG_TYPE_GND_MIC_SWAP: 562 dev_err(mbhc->dev, "Ground and Mic Swapped on plug\n"); 563 goto exit; 564 default: 565 dev_err(mbhc->dev, "Invalid current plug: %d\n", 566 mbhc->current_plug); 567 goto exit; 568 } 569 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_rem_intr); 570 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr); 571 wcd_mbhc_write_field(mbhc, WCD_MBHC_ELECT_DETECTION_TYPE, 1); 572 wcd_mbhc_write_field(mbhc, WCD_MBHC_ELECT_SCHMT_ISRC, 0); 573 wcd_mbhc_report_plug(mbhc, 0, jack_type); 574 } 575 576 exit: 577 mbhc->in_swch_irq_handler = false; 578 mutex_unlock(&mbhc->lock); 579 return IRQ_HANDLED; 580 } 581 582 static int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc) 583 { 584 int mask = 0; 585 int btn; 586 587 btn = wcd_mbhc_read_field(mbhc, WCD_MBHC_BTN_RESULT); 588 589 switch (btn) { 590 case 0: 591 mask = SND_JACK_BTN_0; 592 break; 593 case 1: 594 mask = SND_JACK_BTN_1; 595 break; 596 case 2: 597 mask = SND_JACK_BTN_2; 598 break; 599 case 3: 600 mask = SND_JACK_BTN_3; 601 break; 602 case 4: 603 mask = SND_JACK_BTN_4; 604 break; 605 case 5: 606 mask = SND_JACK_BTN_5; 607 break; 608 default: 609 break; 610 } 611 612 return mask; 613 } 614 615 static void wcd_btn_long_press_fn(struct work_struct *work) 616 { 617 struct delayed_work *dwork = to_delayed_work(work); 618 struct wcd_mbhc *mbhc = container_of(dwork, struct wcd_mbhc, mbhc_btn_dwork); 619 620 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) 621 snd_soc_jack_report(mbhc->jack, mbhc->buttons_pressed, 622 mbhc->buttons_pressed); 623 } 624 625 static irqreturn_t wcd_mbhc_btn_press_handler(int irq, void *data) 626 { 627 struct wcd_mbhc *mbhc = data; 628 int mask; 629 unsigned long msec_val; 630 631 mutex_lock(&mbhc->lock); 632 wcd_cancel_btn_work(mbhc); 633 mbhc->is_btn_press = true; 634 msec_val = jiffies_to_msecs(jiffies - mbhc->jiffies_atreport); 635 636 /* Too short, ignore button press */ 637 if (msec_val < MBHC_BUTTON_PRESS_THRESHOLD_MIN) 638 goto done; 639 640 /* If switch interrupt already kicked in, ignore button press */ 641 if (mbhc->in_swch_irq_handler) 642 goto done; 643 644 /* Plug isn't headset, ignore button press */ 645 if (mbhc->current_plug != MBHC_PLUG_TYPE_HEADSET) 646 goto done; 647 648 mask = wcd_mbhc_get_button_mask(mbhc); 649 mbhc->buttons_pressed |= mask; 650 if (schedule_delayed_work(&mbhc->mbhc_btn_dwork, msecs_to_jiffies(400)) == 0) 651 WARN(1, "Button pressed twice without release event\n"); 652 done: 653 mutex_unlock(&mbhc->lock); 654 return IRQ_HANDLED; 655 } 656 657 static irqreturn_t wcd_mbhc_btn_release_handler(int irq, void *data) 658 { 659 struct wcd_mbhc *mbhc = data; 660 int ret; 661 662 mutex_lock(&mbhc->lock); 663 if (mbhc->is_btn_press) 664 mbhc->is_btn_press = false; 665 else /* fake btn press */ 666 goto exit; 667 668 if (!(mbhc->buttons_pressed & WCD_MBHC_JACK_BUTTON_MASK)) 669 goto exit; 670 671 ret = wcd_cancel_btn_work(mbhc); 672 if (ret == 0) { /* Reporting long button release event */ 673 snd_soc_jack_report(mbhc->jack, 0, mbhc->buttons_pressed); 674 } else { 675 if (!mbhc->in_swch_irq_handler) { 676 /* Reporting btn press n Release */ 677 snd_soc_jack_report(mbhc->jack, mbhc->buttons_pressed, 678 mbhc->buttons_pressed); 679 snd_soc_jack_report(mbhc->jack, 0, mbhc->buttons_pressed); 680 } 681 } 682 mbhc->buttons_pressed &= ~WCD_MBHC_JACK_BUTTON_MASK; 683 exit: 684 mutex_unlock(&mbhc->lock); 685 686 return IRQ_HANDLED; 687 } 688 689 static irqreturn_t wcd_mbhc_hph_ocp_irq(struct wcd_mbhc *mbhc, bool hphr) 690 { 691 692 /* TODO Find a better way to report this to Userspace */ 693 dev_err(mbhc->dev, "MBHC Over Current on %s detected\n", 694 hphr ? "HPHR" : "HPHL"); 695 696 wcd_mbhc_write_field(mbhc, WCD_MBHC_OCP_FSM_EN, 0); 697 wcd_mbhc_write_field(mbhc, WCD_MBHC_OCP_FSM_EN, 1); 698 699 return IRQ_HANDLED; 700 } 701 702 static irqreturn_t wcd_mbhc_hphl_ocp_irq(int irq, void *data) 703 { 704 return wcd_mbhc_hph_ocp_irq(data, false); 705 } 706 707 static irqreturn_t wcd_mbhc_hphr_ocp_irq(int irq, void *data) 708 { 709 return wcd_mbhc_hph_ocp_irq(data, true); 710 } 711 712 static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) 713 { 714 struct snd_soc_component *component = mbhc->component; 715 int ret; 716 717 ret = pm_runtime_resume_and_get(component->dev); 718 if (ret < 0 && ret != -EACCES) { 719 dev_err_ratelimited(component->dev, 720 "pm_runtime_resume_and_get failed in %s, ret %d\n", 721 __func__, ret); 722 return ret; 723 } 724 725 mutex_lock(&mbhc->lock); 726 727 /* enable HS detection */ 728 if (mbhc->mbhc_cb->hph_pull_up_control_v2) 729 mbhc->mbhc_cb->hph_pull_up_control_v2(component, 730 HS_PULLUP_I_DEFAULT); 731 else if (mbhc->mbhc_cb->hph_pull_up_control) 732 mbhc->mbhc_cb->hph_pull_up_control(component, I_DEFAULT); 733 else 734 wcd_mbhc_write_field(mbhc, WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3); 735 736 wcd_mbhc_write_field(mbhc, WCD_MBHC_HPHL_PLUG_TYPE, mbhc->cfg->hphl_swh); 737 wcd_mbhc_write_field(mbhc, WCD_MBHC_GND_PLUG_TYPE, mbhc->cfg->gnd_swh); 738 wcd_mbhc_write_field(mbhc, WCD_MBHC_SW_HPH_LP_100K_TO_GND, 1); 739 if (mbhc->cfg->gnd_det_en && mbhc->mbhc_cb->mbhc_gnd_det_ctrl) 740 mbhc->mbhc_cb->mbhc_gnd_det_ctrl(component, true); 741 wcd_mbhc_write_field(mbhc, WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, 1); 742 743 wcd_mbhc_write_field(mbhc, WCD_MBHC_L_DET_EN, 1); 744 745 /* Insertion debounce set to 96ms */ 746 wcd_mbhc_write_field(mbhc, WCD_MBHC_INSREM_DBNC, 6); 747 748 /* Button Debounce set to 16ms */ 749 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_DBNC, 2); 750 751 /* enable bias */ 752 mbhc->mbhc_cb->mbhc_bias(component, true); 753 /* enable MBHC clock */ 754 if (mbhc->mbhc_cb->clk_setup) 755 mbhc->mbhc_cb->clk_setup(component, true); 756 757 /* program HS_VREF value */ 758 wcd_program_hs_vref(mbhc); 759 760 wcd_program_btn_threshold(mbhc, false); 761 762 mutex_unlock(&mbhc->lock); 763 764 pm_runtime_mark_last_busy(component->dev); 765 pm_runtime_put_autosuspend(component->dev); 766 767 return 0; 768 } 769 770 static int wcd_mbhc_get_micbias(struct wcd_mbhc *mbhc) 771 { 772 int micbias = 0; 773 774 if (mbhc->mbhc_cb->get_micbias_val) { 775 mbhc->mbhc_cb->get_micbias_val(mbhc->component, &micbias); 776 } else { 777 u8 vout_ctl = 0; 778 /* Read MBHC Micbias (Mic Bias2) voltage */ 779 vout_ctl = wcd_mbhc_read_field(mbhc, WCD_MBHC_MICB2_VOUT); 780 /* Formula for getting micbias from vout 781 * micbias = 1.0V + VOUT_CTL * 50mV 782 */ 783 micbias = 1000 + (vout_ctl * 50); 784 } 785 return micbias; 786 } 787 788 static int wcd_get_voltage_from_adc(u8 val, int micbias) 789 { 790 /* Formula for calculating voltage from ADC 791 * Voltage = ADC_RESULT*12.5mV*V_MICBIAS/1.8 792 */ 793 return ((val * 125 * micbias)/(WCD_MBHC_ADC_MICBIAS_MV * 10)); 794 } 795 796 static int wcd_measure_adc_continuous(struct wcd_mbhc *mbhc) 797 { 798 u8 adc_result; 799 int output_mv; 800 int retry = 3; 801 u8 adc_en; 802 803 /* Pre-requisites for ADC continuous measurement */ 804 /* Read legacy electircal detection and disable */ 805 wcd_mbhc_write_field(mbhc, WCD_MBHC_ELECT_SCHMT_ISRC, 0x00); 806 /* Set ADC to continuous measurement */ 807 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_MODE, 1); 808 /* Read ADC Enable bit to restore after adc measurement */ 809 adc_en = wcd_mbhc_read_field(mbhc, WCD_MBHC_ADC_EN); 810 /* Disable ADC_ENABLE bit */ 811 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, 0); 812 /* Disable MBHC FSM */ 813 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 0); 814 /* Set the MUX selection to IN2P */ 815 wcd_mbhc_write_field(mbhc, WCD_MBHC_MUX_CTL, MUX_CTL_IN2P); 816 /* Enable MBHC FSM */ 817 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 1); 818 /* Enable ADC_ENABLE bit */ 819 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, 1); 820 821 while (retry--) { 822 /* wait for 3 msec before reading ADC result */ 823 usleep_range(3000, 3100); 824 adc_result = wcd_mbhc_read_field(mbhc, WCD_MBHC_ADC_RESULT); 825 } 826 827 /* Restore ADC Enable */ 828 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, adc_en); 829 /* Get voltage from ADC result */ 830 output_mv = wcd_get_voltage_from_adc(adc_result, wcd_mbhc_get_micbias(mbhc)); 831 832 return output_mv; 833 } 834 835 static int wcd_measure_adc_once(struct wcd_mbhc *mbhc, int mux_ctl) 836 { 837 struct device *dev = mbhc->dev; 838 u8 adc_timeout = 0; 839 u8 adc_complete = 0; 840 u8 adc_result; 841 int retry = 6; 842 int ret; 843 int output_mv = 0; 844 u8 adc_en; 845 846 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_MODE, 0); 847 /* Read ADC Enable bit to restore after adc measurement */ 848 adc_en = wcd_mbhc_read_field(mbhc, WCD_MBHC_ADC_EN); 849 /* Trigger ADC one time measurement */ 850 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, 0); 851 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 0); 852 /* Set the appropriate MUX selection */ 853 wcd_mbhc_write_field(mbhc, WCD_MBHC_MUX_CTL, mux_ctl); 854 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 1); 855 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, 1); 856 857 while (retry--) { 858 /* wait for 600usec to get adc results */ 859 usleep_range(600, 610); 860 861 /* check for ADC Timeout */ 862 adc_timeout = wcd_mbhc_read_field(mbhc, WCD_MBHC_ADC_TIMEOUT); 863 if (adc_timeout) 864 continue; 865 866 /* Read ADC complete bit */ 867 adc_complete = wcd_mbhc_read_field(mbhc, WCD_MBHC_ADC_COMPLETE); 868 if (!adc_complete) 869 continue; 870 871 /* Read ADC result */ 872 adc_result = wcd_mbhc_read_field(mbhc, WCD_MBHC_ADC_RESULT); 873 874 /* Get voltage from ADC result */ 875 output_mv = wcd_get_voltage_from_adc(adc_result, 876 wcd_mbhc_get_micbias(mbhc)); 877 break; 878 } 879 880 /* Restore ADC Enable */ 881 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, adc_en); 882 883 if (retry <= 0) { 884 dev_err(dev, "%s: adc complete: %d, adc timeout: %d\n", 885 __func__, adc_complete, adc_timeout); 886 ret = -EINVAL; 887 } else { 888 ret = output_mv; 889 } 890 891 return ret; 892 } 893 894 /* To determine if cross connection occurred */ 895 static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) 896 { 897 u8 adc_mode, elect_ctl, adc_en, fsm_en; 898 int hphl_adc_res, hphr_adc_res; 899 bool is_cross_conn = false; 900 901 /* If PA is enabled, dont check for cross-connection */ 902 if (wcd_mbhc_read_field(mbhc, WCD_MBHC_HPH_PA_EN)) 903 return -EINVAL; 904 905 /* Read legacy electircal detection and disable */ 906 elect_ctl = wcd_mbhc_read_field(mbhc, WCD_MBHC_ELECT_SCHMT_ISRC); 907 wcd_mbhc_write_field(mbhc, WCD_MBHC_ELECT_SCHMT_ISRC, 0); 908 909 /* Read and set ADC to single measurement */ 910 adc_mode = wcd_mbhc_read_field(mbhc, WCD_MBHC_ADC_MODE); 911 /* Read ADC Enable bit to restore after adc measurement */ 912 adc_en = wcd_mbhc_read_field(mbhc, WCD_MBHC_ADC_EN); 913 /* Read FSM status */ 914 fsm_en = wcd_mbhc_read_field(mbhc, WCD_MBHC_FSM_EN); 915 916 /* Get adc result for HPH L */ 917 hphl_adc_res = wcd_measure_adc_once(mbhc, MUX_CTL_HPH_L); 918 if (hphl_adc_res < 0) 919 return hphl_adc_res; 920 921 /* Get adc result for HPH R in mV */ 922 hphr_adc_res = wcd_measure_adc_once(mbhc, MUX_CTL_HPH_R); 923 if (hphr_adc_res < 0) 924 return hphr_adc_res; 925 926 if (hphl_adc_res > HPHL_CROSS_CONN_THRESHOLD || 927 hphr_adc_res > HPHL_CROSS_CONN_THRESHOLD) 928 is_cross_conn = true; 929 930 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 0); 931 /* Set the MUX selection to Auto */ 932 wcd_mbhc_write_field(mbhc, WCD_MBHC_MUX_CTL, MUX_CTL_AUTO); 933 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, 1); 934 /* Restore ADC Enable */ 935 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, adc_en); 936 /* Restore ADC mode */ 937 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_MODE, adc_mode); 938 /* Restore FSM state */ 939 wcd_mbhc_write_field(mbhc, WCD_MBHC_FSM_EN, fsm_en); 940 /* Restore electrical detection */ 941 wcd_mbhc_write_field(mbhc, WCD_MBHC_ELECT_SCHMT_ISRC, elect_ctl); 942 943 return is_cross_conn; 944 } 945 946 static int wcd_mbhc_adc_get_hs_thres(struct wcd_mbhc *mbhc) 947 { 948 int hs_threshold, micbias_mv; 949 950 micbias_mv = wcd_mbhc_get_micbias(mbhc); 951 if (mbhc->cfg->hs_thr) { 952 if (mbhc->cfg->micb_mv == micbias_mv) 953 hs_threshold = mbhc->cfg->hs_thr; 954 else 955 hs_threshold = (mbhc->cfg->hs_thr * 956 micbias_mv) / mbhc->cfg->micb_mv; 957 } else { 958 hs_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * 959 micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV); 960 } 961 return hs_threshold; 962 } 963 964 static int wcd_mbhc_adc_get_hph_thres(struct wcd_mbhc *mbhc) 965 { 966 int hph_threshold, micbias_mv; 967 968 micbias_mv = wcd_mbhc_get_micbias(mbhc); 969 if (mbhc->cfg->hph_thr) { 970 if (mbhc->cfg->micb_mv == micbias_mv) 971 hph_threshold = mbhc->cfg->hph_thr; 972 else 973 hph_threshold = (mbhc->cfg->hph_thr * 974 micbias_mv) / mbhc->cfg->micb_mv; 975 } else { 976 hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV * 977 micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV); 978 } 979 return hph_threshold; 980 } 981 982 static void wcd_mbhc_adc_update_fsm_source(struct wcd_mbhc *mbhc, 983 enum wcd_mbhc_plug_type plug_type) 984 { 985 bool micbias2 = false; 986 987 switch (plug_type) { 988 case MBHC_PLUG_TYPE_HEADPHONE: 989 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 3); 990 break; 991 case MBHC_PLUG_TYPE_HEADSET: 992 if (mbhc->mbhc_cb->micbias_enable_status) 993 micbias2 = mbhc->mbhc_cb->micbias_enable_status(mbhc->component, 994 MIC_BIAS_2); 995 996 if (!mbhc->is_hs_recording && !micbias2) 997 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 3); 998 break; 999 default: 1000 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 0); 1001 break; 1002 1003 } 1004 } 1005 1006 static void wcd_mbhc_bcs_enable(struct wcd_mbhc *mbhc, int plug_type, bool enable) 1007 { 1008 switch (plug_type) { 1009 case MBHC_PLUG_TYPE_HEADSET: 1010 case MBHC_PLUG_TYPE_HEADPHONE: 1011 if (mbhc->mbhc_cb->bcs_enable) 1012 mbhc->mbhc_cb->bcs_enable(mbhc->component, enable); 1013 break; 1014 default: 1015 break; 1016 } 1017 } 1018 1019 static int wcd_mbhc_get_plug_from_adc(struct wcd_mbhc *mbhc, int adc_result) 1020 1021 { 1022 enum wcd_mbhc_plug_type plug_type; 1023 u32 hph_thr, hs_thr; 1024 1025 hs_thr = wcd_mbhc_adc_get_hs_thres(mbhc); 1026 hph_thr = wcd_mbhc_adc_get_hph_thres(mbhc); 1027 1028 if (adc_result < hph_thr) 1029 plug_type = MBHC_PLUG_TYPE_HEADPHONE; 1030 else if (adc_result > hs_thr) 1031 plug_type = MBHC_PLUG_TYPE_HIGH_HPH; 1032 else 1033 plug_type = MBHC_PLUG_TYPE_HEADSET; 1034 1035 return plug_type; 1036 } 1037 1038 static int wcd_mbhc_get_spl_hs_thres(struct wcd_mbhc *mbhc) 1039 { 1040 int hs_threshold, micbias_mv; 1041 1042 micbias_mv = wcd_mbhc_get_micbias(mbhc); 1043 if (mbhc->cfg->hs_thr && mbhc->cfg->micb_mv != WCD_MBHC_ADC_MICBIAS_MV) { 1044 if (mbhc->cfg->micb_mv == micbias_mv) 1045 hs_threshold = mbhc->cfg->hs_thr; 1046 else 1047 hs_threshold = (mbhc->cfg->hs_thr * micbias_mv) / mbhc->cfg->micb_mv; 1048 } else { 1049 hs_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV * micbias_mv) / 1050 WCD_MBHC_ADC_MICBIAS_MV); 1051 } 1052 return hs_threshold; 1053 } 1054 1055 static bool wcd_mbhc_check_for_spl_headset(struct wcd_mbhc *mbhc) 1056 { 1057 bool is_spl_hs = false; 1058 int output_mv, hs_threshold, hph_threshold; 1059 1060 if (!mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) 1061 return false; 1062 1063 /* Bump up MIC_BIAS2 to 2.7V */ 1064 mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, MIC_BIAS_2, true); 1065 usleep_range(10000, 10100); 1066 1067 output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); 1068 hs_threshold = wcd_mbhc_get_spl_hs_thres(mbhc); 1069 hph_threshold = wcd_mbhc_adc_get_hph_thres(mbhc); 1070 1071 if (!(output_mv > hs_threshold || output_mv < hph_threshold)) 1072 is_spl_hs = true; 1073 1074 /* Back MIC_BIAS2 to 1.8v if the type is not special headset */ 1075 if (!is_spl_hs) { 1076 mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, MIC_BIAS_2, false); 1077 /* Add 10ms delay for micbias to settle */ 1078 usleep_range(10000, 10100); 1079 } 1080 1081 return is_spl_hs; 1082 } 1083 1084 static void wcd_correct_swch_plug(struct work_struct *work) 1085 { 1086 struct wcd_mbhc *mbhc; 1087 struct snd_soc_component *component; 1088 enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID; 1089 unsigned long timeout; 1090 int pt_gnd_mic_swap_cnt = 0; 1091 int output_mv, cross_conn, hs_threshold, try = 0, micbias_mv; 1092 bool is_spl_hs = false; 1093 bool is_pa_on; 1094 int ret; 1095 1096 mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch); 1097 component = mbhc->component; 1098 1099 ret = pm_runtime_resume_and_get(component->dev); 1100 if (ret < 0 && ret != -EACCES) { 1101 dev_err_ratelimited(component->dev, 1102 "pm_runtime_resume_and_get failed in %s, ret %d\n", 1103 __func__, ret); 1104 return; 1105 } 1106 micbias_mv = wcd_mbhc_get_micbias(mbhc); 1107 hs_threshold = wcd_mbhc_adc_get_hs_thres(mbhc); 1108 1109 /* Mask ADC COMPLETE interrupt */ 1110 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr); 1111 1112 /* Check for cross connection */ 1113 do { 1114 cross_conn = wcd_check_cross_conn(mbhc); 1115 try++; 1116 } while (try < GND_MIC_SWAP_THRESHOLD); 1117 1118 if (cross_conn > 0) { 1119 plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; 1120 dev_err(mbhc->dev, "cross connection found, Plug type %d\n", 1121 plug_type); 1122 goto correct_plug_type; 1123 } 1124 1125 /* Find plug type */ 1126 output_mv = wcd_measure_adc_continuous(mbhc); 1127 plug_type = wcd_mbhc_get_plug_from_adc(mbhc, output_mv); 1128 1129 /* 1130 * Report plug type if it is either headset or headphone 1131 * else start the 3 sec loop 1132 */ 1133 switch (plug_type) { 1134 case MBHC_PLUG_TYPE_HEADPHONE: 1135 wcd_mbhc_find_plug_and_report(mbhc, plug_type); 1136 break; 1137 case MBHC_PLUG_TYPE_HEADSET: 1138 wcd_mbhc_find_plug_and_report(mbhc, plug_type); 1139 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_MODE, 0); 1140 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, 0); 1141 wcd_mbhc_write_field(mbhc, WCD_MBHC_DETECTION_DONE, 1); 1142 break; 1143 default: 1144 break; 1145 } 1146 1147 correct_plug_type: 1148 1149 /* Disable BCS slow insertion detection */ 1150 wcd_mbhc_bcs_enable(mbhc, plug_type, false); 1151 1152 timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS); 1153 1154 while (!time_after(jiffies, timeout)) { 1155 if (mbhc->hs_detect_work_stop) { 1156 wcd_micbias_disable(mbhc); 1157 goto exit; 1158 } 1159 1160 msleep(180); 1161 /* 1162 * Use ADC single mode to minimize the chance of missing out 1163 * btn press/release for HEADSET type during correct work. 1164 */ 1165 output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); 1166 plug_type = wcd_mbhc_get_plug_from_adc(mbhc, output_mv); 1167 is_pa_on = wcd_mbhc_read_field(mbhc, WCD_MBHC_HPH_PA_EN); 1168 1169 if (output_mv > hs_threshold && !is_spl_hs) { 1170 is_spl_hs = wcd_mbhc_check_for_spl_headset(mbhc); 1171 output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); 1172 1173 if (is_spl_hs) { 1174 hs_threshold *= wcd_mbhc_get_micbias(mbhc); 1175 hs_threshold /= micbias_mv; 1176 } 1177 } 1178 1179 if ((output_mv <= hs_threshold) && !is_pa_on) { 1180 /* Check for cross connection*/ 1181 cross_conn = wcd_check_cross_conn(mbhc); 1182 if (cross_conn > 0) { /* cross-connection */ 1183 pt_gnd_mic_swap_cnt++; 1184 if (pt_gnd_mic_swap_cnt < GND_MIC_SWAP_THRESHOLD) 1185 continue; 1186 else 1187 plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; 1188 } else if (!cross_conn) { /* no cross connection */ 1189 pt_gnd_mic_swap_cnt = 0; 1190 plug_type = wcd_mbhc_get_plug_from_adc(mbhc, output_mv); 1191 continue; 1192 } else if (cross_conn < 0) /* Error */ 1193 continue; 1194 1195 if (pt_gnd_mic_swap_cnt == GND_MIC_SWAP_THRESHOLD) { 1196 /* US_EU gpio present, flip switch */ 1197 if (mbhc->cfg->swap_gnd_mic) { 1198 if (mbhc->cfg->swap_gnd_mic(component, true)) 1199 continue; 1200 } 1201 } 1202 } 1203 1204 /* cable is extension cable */ 1205 if (output_mv > hs_threshold || mbhc->force_linein) 1206 plug_type = MBHC_PLUG_TYPE_HIGH_HPH; 1207 } 1208 1209 wcd_mbhc_bcs_enable(mbhc, plug_type, true); 1210 1211 if (plug_type == MBHC_PLUG_TYPE_HIGH_HPH) { 1212 if (is_spl_hs) 1213 plug_type = MBHC_PLUG_TYPE_HEADSET; 1214 else 1215 wcd_mbhc_write_field(mbhc, WCD_MBHC_ELECT_ISRC_EN, 1); 1216 } 1217 1218 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_MODE, 0); 1219 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, 0); 1220 wcd_mbhc_find_plug_and_report(mbhc, plug_type); 1221 1222 /* 1223 * Set DETECTION_DONE bit for HEADSET 1224 * so that btn press/release interrupt can be generated. 1225 * For other plug type, clear the bit. 1226 */ 1227 if (plug_type == MBHC_PLUG_TYPE_HEADSET) 1228 wcd_mbhc_write_field(mbhc, WCD_MBHC_DETECTION_DONE, 1); 1229 else 1230 wcd_mbhc_write_field(mbhc, WCD_MBHC_DETECTION_DONE, 0); 1231 1232 if (mbhc->mbhc_cb->mbhc_micbias_control) 1233 wcd_mbhc_adc_update_fsm_source(mbhc, plug_type); 1234 1235 exit: 1236 if (mbhc->mbhc_cb->mbhc_micbias_control/* && !mbhc->micbias_enable*/) 1237 mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, MICB_DISABLE); 1238 1239 /* 1240 * If plug type is corrected from special headset to headphone, 1241 * clear the micbias enable flag, set micbias back to 1.8V and 1242 * disable micbias. 1243 */ 1244 if (plug_type == MBHC_PLUG_TYPE_HEADPHONE) { 1245 wcd_micbias_disable(mbhc); 1246 /* 1247 * Enable ADC COMPLETE interrupt for HEADPHONE. 1248 * Btn release may happen after the correct work, ADC COMPLETE 1249 * interrupt needs to be captured to correct plug type. 1250 */ 1251 enable_irq(mbhc->intr_ids->mbhc_hs_ins_intr); 1252 } 1253 1254 if (mbhc->mbhc_cb->hph_pull_down_ctrl) 1255 mbhc->mbhc_cb->hph_pull_down_ctrl(component, true); 1256 1257 pm_runtime_mark_last_busy(component->dev); 1258 pm_runtime_put_autosuspend(component->dev); 1259 } 1260 1261 static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) 1262 { 1263 struct wcd_mbhc *mbhc = data; 1264 unsigned long timeout; 1265 int adc_threshold, output_mv, retry = 0; 1266 1267 mutex_lock(&mbhc->lock); 1268 timeout = jiffies + msecs_to_jiffies(WCD_FAKE_REMOVAL_MIN_PERIOD_MS); 1269 adc_threshold = wcd_mbhc_adc_get_hs_thres(mbhc); 1270 1271 do { 1272 retry++; 1273 /* 1274 * read output_mv every 10ms to look for 1275 * any change in IN2_P 1276 */ 1277 usleep_range(10000, 10100); 1278 output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P); 1279 1280 /* Check for fake removal */ 1281 if ((output_mv <= adc_threshold) && retry > FAKE_REM_RETRY_ATTEMPTS) 1282 goto exit; 1283 } while (!time_after(jiffies, timeout)); 1284 1285 /* 1286 * ADC COMPLETE and ELEC_REM interrupts are both enabled for 1287 * HEADPHONE, need to reject the ADC COMPLETE interrupt which 1288 * follows ELEC_REM one when HEADPHONE is removed. 1289 */ 1290 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) 1291 mbhc->extn_cable_hph_rem = true; 1292 1293 wcd_mbhc_write_field(mbhc, WCD_MBHC_DETECTION_DONE, 0); 1294 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_MODE, 0); 1295 wcd_mbhc_write_field(mbhc, WCD_MBHC_ADC_EN, 0); 1296 wcd_mbhc_elec_hs_report_unplug(mbhc); 1297 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_ISRC_CTL, 0); 1298 1299 exit: 1300 mutex_unlock(&mbhc->lock); 1301 return IRQ_HANDLED; 1302 } 1303 1304 static irqreturn_t wcd_mbhc_adc_hs_ins_irq(int irq, void *data) 1305 { 1306 struct wcd_mbhc *mbhc = data; 1307 u8 clamp_state; 1308 u8 clamp_retry = WCD_MBHC_FAKE_INS_RETRY; 1309 1310 /* 1311 * ADC COMPLETE and ELEC_REM interrupts are both enabled for HEADPHONE, 1312 * need to reject the ADC COMPLETE interrupt which follows ELEC_REM one 1313 * when HEADPHONE is removed. 1314 */ 1315 if (mbhc->extn_cable_hph_rem == true) { 1316 mbhc->extn_cable_hph_rem = false; 1317 return IRQ_HANDLED; 1318 } 1319 1320 do { 1321 clamp_state = wcd_mbhc_read_field(mbhc, WCD_MBHC_IN2P_CLAMP_STATE); 1322 if (clamp_state) 1323 return IRQ_HANDLED; 1324 /* 1325 * check clamp for 120ms but at 30ms chunks to leave 1326 * room for other interrupts to be processed 1327 */ 1328 usleep_range(30000, 30100); 1329 } while (--clamp_retry); 1330 1331 /* 1332 * If current plug is headphone then there is no chance to 1333 * get ADC complete interrupt, so connected cable should be 1334 * headset not headphone. 1335 */ 1336 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) { 1337 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr); 1338 wcd_mbhc_write_field(mbhc, WCD_MBHC_DETECTION_DONE, 1); 1339 wcd_mbhc_find_plug_and_report(mbhc, MBHC_PLUG_TYPE_HEADSET); 1340 return IRQ_HANDLED; 1341 } 1342 1343 return IRQ_HANDLED; 1344 } 1345 1346 int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, uint32_t *zr) 1347 { 1348 *zl = mbhc->zl; 1349 *zr = mbhc->zr; 1350 1351 if (*zl && *zr) 1352 return 0; 1353 else 1354 return -EINVAL; 1355 } 1356 EXPORT_SYMBOL(wcd_mbhc_get_impedance); 1357 1358 void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type) 1359 { 1360 mbhc->hph_type = hph_type; 1361 } 1362 EXPORT_SYMBOL(wcd_mbhc_set_hph_type); 1363 1364 int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc) 1365 { 1366 return mbhc->hph_type; 1367 } 1368 EXPORT_SYMBOL(wcd_mbhc_get_hph_type); 1369 1370 int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *cfg, 1371 struct snd_soc_jack *jack) 1372 { 1373 if (!mbhc || !cfg || !jack) 1374 return -EINVAL; 1375 1376 mbhc->cfg = cfg; 1377 mbhc->jack = jack; 1378 1379 return wcd_mbhc_initialise(mbhc); 1380 } 1381 EXPORT_SYMBOL(wcd_mbhc_start); 1382 1383 void wcd_mbhc_stop(struct wcd_mbhc *mbhc) 1384 { 1385 mbhc->current_plug = MBHC_PLUG_TYPE_NONE; 1386 mbhc->hph_status = 0; 1387 disable_irq_nosync(mbhc->intr_ids->hph_left_ocp); 1388 disable_irq_nosync(mbhc->intr_ids->hph_right_ocp); 1389 } 1390 EXPORT_SYMBOL(wcd_mbhc_stop); 1391 1392 int wcd_dt_parse_mbhc_data(struct device *dev, struct wcd_mbhc_config *cfg) 1393 { 1394 struct device_node *np = dev->of_node; 1395 int ret, i, microvolt; 1396 1397 if (of_property_read_bool(np, "qcom,hphl-jack-type-normally-closed")) 1398 cfg->hphl_swh = false; 1399 else 1400 cfg->hphl_swh = true; 1401 1402 if (of_property_read_bool(np, "qcom,ground-jack-type-normally-closed")) 1403 cfg->gnd_swh = false; 1404 else 1405 cfg->gnd_swh = true; 1406 1407 ret = of_property_read_u32(np, "qcom,mbhc-headset-vthreshold-microvolt", 1408 µvolt); 1409 if (ret) 1410 dev_dbg(dev, "missing qcom,mbhc-hs-mic-max-vthreshold--microvolt in dt node\n"); 1411 else 1412 cfg->hs_thr = microvolt/1000; 1413 1414 ret = of_property_read_u32(np, "qcom,mbhc-headphone-vthreshold-microvolt", 1415 µvolt); 1416 if (ret) 1417 dev_dbg(dev, "missing qcom,mbhc-hs-mic-min-vthreshold-microvolt entry\n"); 1418 else 1419 cfg->hph_thr = microvolt/1000; 1420 1421 ret = of_property_read_u32_array(np, 1422 "qcom,mbhc-buttons-vthreshold-microvolt", 1423 &cfg->btn_high[0], 1424 WCD_MBHC_DEF_BUTTONS); 1425 if (ret) 1426 dev_err(dev, "missing qcom,mbhc-buttons-vthreshold-microvolt entry\n"); 1427 1428 for (i = 0; i < WCD_MBHC_DEF_BUTTONS; i++) { 1429 if (ret) /* default voltage */ 1430 cfg->btn_high[i] = 500000; 1431 else 1432 /* Micro to Milli Volts */ 1433 cfg->btn_high[i] = cfg->btn_high[i]/1000; 1434 } 1435 1436 return 0; 1437 } 1438 EXPORT_SYMBOL(wcd_dt_parse_mbhc_data); 1439 1440 struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component, 1441 const struct wcd_mbhc_cb *mbhc_cb, 1442 const struct wcd_mbhc_intr *intr_ids, 1443 struct wcd_mbhc_field *fields, 1444 bool impedance_det_en) 1445 { 1446 struct device *dev = component->dev; 1447 struct wcd_mbhc *mbhc; 1448 int ret; 1449 1450 if (!intr_ids || !fields || !mbhc_cb || !mbhc_cb->mbhc_bias || !mbhc_cb->set_btn_thr) { 1451 dev_err(dev, "%s: Insufficient mbhc configuration\n", __func__); 1452 return ERR_PTR(-EINVAL); 1453 } 1454 1455 mbhc = devm_kzalloc(dev, sizeof(*mbhc), GFP_KERNEL); 1456 if (!mbhc) 1457 return ERR_PTR(-ENOMEM); 1458 1459 mbhc->component = component; 1460 mbhc->dev = dev; 1461 mbhc->intr_ids = intr_ids; 1462 mbhc->mbhc_cb = mbhc_cb; 1463 mbhc->fields = fields; 1464 mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; 1465 1466 if (mbhc_cb->compute_impedance) 1467 mbhc->impedance_detect = impedance_det_en; 1468 1469 INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd_btn_long_press_fn); 1470 1471 mutex_init(&mbhc->lock); 1472 1473 INIT_WORK(&mbhc->correct_plug_swch, wcd_correct_swch_plug); 1474 1475 ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_sw_intr, NULL, 1476 wcd_mbhc_mech_plug_detect_irq, 1477 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 1478 "mbhc sw intr", mbhc); 1479 if (ret) 1480 goto err; 1481 1482 ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_btn_press_intr, NULL, 1483 wcd_mbhc_btn_press_handler, 1484 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 1485 "Button Press detect", mbhc); 1486 if (ret) 1487 goto err; 1488 1489 ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_btn_release_intr, NULL, 1490 wcd_mbhc_btn_release_handler, 1491 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 1492 "Button Release detect", mbhc); 1493 if (ret) 1494 goto err; 1495 1496 ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_hs_ins_intr, NULL, 1497 wcd_mbhc_adc_hs_ins_irq, 1498 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 1499 "Elect Insert", mbhc); 1500 if (ret) 1501 goto err; 1502 1503 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr); 1504 1505 ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_hs_rem_intr, NULL, 1506 wcd_mbhc_adc_hs_rem_irq, 1507 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 1508 "Elect Remove", mbhc); 1509 if (ret) 1510 goto err; 1511 1512 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_rem_intr); 1513 1514 ret = devm_request_threaded_irq(dev, mbhc->intr_ids->hph_left_ocp, NULL, 1515 wcd_mbhc_hphl_ocp_irq, 1516 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 1517 "HPH_L OCP detect", mbhc); 1518 if (ret) 1519 goto err; 1520 1521 ret = devm_request_threaded_irq(dev, mbhc->intr_ids->hph_right_ocp, NULL, 1522 wcd_mbhc_hphr_ocp_irq, 1523 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 1524 "HPH_R OCP detect", mbhc); 1525 if (ret) 1526 goto err; 1527 1528 return mbhc; 1529 err: 1530 dev_err(dev, "Failed to request mbhc interrupts %d\n", ret); 1531 1532 return ERR_PTR(ret); 1533 } 1534 EXPORT_SYMBOL(wcd_mbhc_init); 1535 1536 void wcd_mbhc_deinit(struct wcd_mbhc *mbhc) 1537 { 1538 mutex_lock(&mbhc->lock); 1539 wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); 1540 mutex_unlock(&mbhc->lock); 1541 } 1542 EXPORT_SYMBOL(wcd_mbhc_deinit); 1543 1544 static int __init mbhc_init(void) 1545 { 1546 return 0; 1547 } 1548 1549 static void __exit mbhc_exit(void) 1550 { 1551 } 1552 1553 module_init(mbhc_init); 1554 module_exit(mbhc_exit); 1555 1556 MODULE_DESCRIPTION("wcd MBHC v2 module"); 1557 MODULE_LICENSE("GPL"); 1558