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