Lines Matching +full:disable +full:- +full:report +full:- +full:mask

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * da7219-aad.c - Dialog DA7219 ALSA SoC AAD Driver
24 #include "da7219-aad.h"
35 da7219->aad->jack = jack; in da7219_aad_jack_det()
36 da7219->aad->jack_inserted = false; in da7219_aad_jack_det()
38 /* Send an initial empty report */ in da7219_aad_jack_det()
41 /* Enable/Disable jack detection */ in da7219_aad_jack_det()
55 struct snd_soc_component *component = da7219_aad->component; in da7219_aad_btn_det_work()
83 dev_warn(component->dev, "Mic bias status check timed out"); in da7219_aad_btn_det_work()
85 da7219->micbias_on_event = true; in da7219_aad_btn_det_work()
91 if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) { in da7219_aad_btn_det_work()
96 da7219_aad->micbias_pulse_lvl); in da7219_aad_btn_det_work()
97 msleep(da7219_aad->micbias_pulse_time); in da7219_aad_btn_det_work()
104 da7219_aad->btn_cfg); in da7219_aad_btn_det_work()
111 struct snd_soc_component *component = da7219_aad->component; in da7219_aad_hptest_work()
117 int report = 0, ret; in da7219_aad_hptest_work() local
121 mutex_lock(&da7219->ctrl_lock); in da7219_aad_hptest_work()
122 mutex_lock(&da7219->pll_lock); in da7219_aad_hptest_work()
125 if (da7219->mclk) { in da7219_aad_hptest_work()
126 ret = clk_prepare_enable(da7219->mclk); in da7219_aad_hptest_work()
128 dev_err(component->dev, "Failed to enable mclk - %d\n", ret); in da7219_aad_hptest_work()
129 mutex_unlock(&da7219->pll_lock); in da7219_aad_hptest_work()
130 mutex_unlock(&da7219->ctrl_lock); in da7219_aad_hptest_work()
160 regcache_cache_bypass(da7219->regmap, true); in da7219_aad_hptest_work()
177 /* Disable DAC filters, EQs and soft mute */ in da7219_aad_hptest_work()
239 regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L, in da7219_aad_hptest_work()
252 report |= SND_JACK_HEADPHONE; in da7219_aad_hptest_work()
254 report |= SND_JACK_LINEOUT; in da7219_aad_hptest_work()
262 regcache_mark_dirty(da7219->regmap); in da7219_aad_hptest_work()
263 regcache_sync_region(da7219->regmap, DA7219_HP_L_CTRL, in da7219_aad_hptest_work()
266 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_CTRL, in da7219_aad_hptest_work()
268 regcache_sync_region(da7219->regmap, DA7219_DROUTING_ST_OUTFILT_1L, in da7219_aad_hptest_work()
270 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_SELECT, in da7219_aad_hptest_work()
272 regcache_sync_region(da7219->regmap, DA7219_DAC_L_CTRL, in da7219_aad_hptest_work()
274 regcache_sync_region(da7219->regmap, DA7219_DIG_ROUTING_DAC, in da7219_aad_hptest_work()
276 regcache_sync_region(da7219->regmap, DA7219_CP_CTRL, DA7219_CP_CTRL); in da7219_aad_hptest_work()
277 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS5, in da7219_aad_hptest_work()
279 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS4, in da7219_aad_hptest_work()
281 regcache_sync_region(da7219->regmap, DA7219_HP_L_GAIN, in da7219_aad_hptest_work()
283 regcache_sync_region(da7219->regmap, DA7219_DAC_L_GAIN, in da7219_aad_hptest_work()
285 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_ON_PER, in da7219_aad_hptest_work()
287 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_FREQ1_L, in da7219_aad_hptest_work()
289 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_CFG1, in da7219_aad_hptest_work()
292 regcache_cache_bypass(da7219->regmap, false); in da7219_aad_hptest_work()
294 /* Disable HPTest block */ in da7219_aad_hptest_work()
314 /* Restore PLL to previous configuration, if re-configured */ in da7219_aad_hptest_work()
320 if (da7219->mclk) in da7219_aad_hptest_work()
321 clk_disable_unprepare(da7219->mclk); in da7219_aad_hptest_work()
323 mutex_unlock(&da7219->pll_lock); in da7219_aad_hptest_work()
324 mutex_unlock(&da7219->ctrl_lock); in da7219_aad_hptest_work()
328 * Only send report if jack hasn't been removed during process, in da7219_aad_hptest_work()
331 if (da7219_aad->jack_inserted) in da7219_aad_hptest_work()
332 snd_soc_jack_report(da7219_aad->jack, report, in da7219_aad_hptest_work()
340 struct snd_soc_component *component = da7219_aad->component; in da7219_aad_jack_det_work()
353 struct snd_soc_component *component = da7219_aad->component; in da7219_aad_irq_thread()
358 int i, ret, report = 0, mask = 0; in da7219_aad_irq_thread() local
361 ret = regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, in da7219_aad_irq_thread()
364 dev_warn_ratelimited(component->dev, "Failed to read IRQ events: %d\n", ret); in da7219_aad_irq_thread()
380 delay = (da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 2); in da7219_aad_irq_thread()
381 queue_delayed_work(da7219_aad->aad_wq, in da7219_aad_irq_thread()
382 &da7219_aad->jack_det_work, in da7219_aad_irq_thread()
387 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, in da7219_aad_irq_thread()
390 dev_dbg(component->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n", in da7219_aad_irq_thread()
398 report |= SND_JACK_MECHANICAL; in da7219_aad_irq_thread()
399 mask |= SND_JACK_MECHANICAL; in da7219_aad_irq_thread()
400 da7219_aad->jack_inserted = true; in da7219_aad_irq_thread()
407 * If 4-pole, then enable button detection, else perform in da7219_aad_irq_thread()
408 * HP impedance test to determine output type to report. in da7219_aad_irq_thread()
419 cancel_delayed_work_sync(&da7219_aad->jack_det_work); in da7219_aad_irq_thread()
420 /* Disable ground switch */ in da7219_aad_irq_thread()
424 report |= SND_JACK_HEADSET; in da7219_aad_irq_thread()
425 mask |= SND_JACK_HEADSET | SND_JACK_LINEOUT; in da7219_aad_irq_thread()
426 queue_work(da7219_aad->aad_wq, &da7219_aad->btn_det_work); in da7219_aad_irq_thread()
428 queue_work(da7219_aad->aad_wq, &da7219_aad->hptest_work); in da7219_aad_irq_thread()
432 /* Button support for 4-pole jack */ in da7219_aad_irq_thread()
438 report |= SND_JACK_BTN_0 >> i; in da7219_aad_irq_thread()
439 mask |= SND_JACK_BTN_0 >> i; in da7219_aad_irq_thread()
442 snd_soc_jack_report(da7219_aad->jack, report, mask); in da7219_aad_irq_thread()
448 report &= ~(SND_JACK_BTN_0 >> i); in da7219_aad_irq_thread()
449 mask |= SND_JACK_BTN_0 >> i; in da7219_aad_irq_thread()
456 report = 0; in da7219_aad_irq_thread()
457 mask |= DA7219_AAD_REPORT_ALL_MASK; in da7219_aad_irq_thread()
458 da7219_aad->jack_inserted = false; in da7219_aad_irq_thread()
461 cancel_delayed_work_sync(&da7219_aad->jack_det_work); in da7219_aad_irq_thread()
462 cancel_work_sync(&da7219_aad->btn_det_work); in da7219_aad_irq_thread()
463 cancel_work_sync(&da7219_aad->hptest_work); in da7219_aad_irq_thread()
465 /* Un-drive headphones/lineout */ in da7219_aad_irq_thread()
475 da7219->micbias_on_event = false; in da7219_aad_irq_thread()
477 /* Disable mic bias */ in da7219_aad_irq_thread()
481 /* Disable ground switch */ in da7219_aad_irq_thread()
486 snd_soc_jack_report(da7219_aad->jack, report, mask); in da7219_aad_irq_thread()
656 dev_warn(dev, "Invalid ADC 1-bit repeat value"); in da7219_aad_fw_adc_1bit_rpt()
679 aad_pdata->irq = i2c->irq; in da7219_aad_fw_to_pdata()
681 if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl", in da7219_aad_fw_to_pdata()
683 aad_pdata->micbias_pulse_lvl = in da7219_aad_fw_to_pdata()
686 aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF; in da7219_aad_fw_to_pdata()
688 if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-time", in da7219_aad_fw_to_pdata()
690 aad_pdata->micbias_pulse_time = fw_val32; in da7219_aad_fw_to_pdata()
692 if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
693 aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(dev, fw_val32); in da7219_aad_fw_to_pdata()
695 aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS; in da7219_aad_fw_to_pdata()
697 if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
698 aad_pdata->mic_det_thr = in da7219_aad_fw_to_pdata()
701 aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_200_OHMS; in da7219_aad_fw_to_pdata()
703 if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
704 aad_pdata->jack_ins_deb = in da7219_aad_fw_to_pdata()
707 aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS; in da7219_aad_fw_to_pdata()
709 if (!fwnode_property_read_string(aad_np, "dlg,jack-ins-det-pty", &fw_str)) in da7219_aad_fw_to_pdata()
710 aad_pdata->jack_ins_det_pty = in da7219_aad_fw_to_pdata()
713 aad_pdata->jack_ins_det_pty = DA7219_AAD_JACK_INS_DET_PTY_LOW; in da7219_aad_fw_to_pdata()
715 if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str)) in da7219_aad_fw_to_pdata()
716 aad_pdata->jack_det_rate = in da7219_aad_fw_to_pdata()
719 aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS; in da7219_aad_fw_to_pdata()
721 if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
722 aad_pdata->jack_rem_deb = in da7219_aad_fw_to_pdata()
725 aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS; in da7219_aad_fw_to_pdata()
727 if (fwnode_property_read_u32(aad_np, "dlg,a-d-btn-thr", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
728 aad_pdata->a_d_btn_thr = (u8) fw_val32; in da7219_aad_fw_to_pdata()
730 aad_pdata->a_d_btn_thr = 0xA; in da7219_aad_fw_to_pdata()
732 if (fwnode_property_read_u32(aad_np, "dlg,d-b-btn-thr", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
733 aad_pdata->d_b_btn_thr = (u8) fw_val32; in da7219_aad_fw_to_pdata()
735 aad_pdata->d_b_btn_thr = 0x16; in da7219_aad_fw_to_pdata()
737 if (fwnode_property_read_u32(aad_np, "dlg,b-c-btn-thr", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
738 aad_pdata->b_c_btn_thr = (u8) fw_val32; in da7219_aad_fw_to_pdata()
740 aad_pdata->b_c_btn_thr = 0x21; in da7219_aad_fw_to_pdata()
742 if (fwnode_property_read_u32(aad_np, "dlg,c-mic-btn-thr", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
743 aad_pdata->c_mic_btn_thr = (u8) fw_val32; in da7219_aad_fw_to_pdata()
745 aad_pdata->c_mic_btn_thr = 0x3E; in da7219_aad_fw_to_pdata()
747 if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
748 aad_pdata->btn_avg = da7219_aad_fw_btn_avg(dev, fw_val32); in da7219_aad_fw_to_pdata()
750 aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2; in da7219_aad_fw_to_pdata()
752 if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0) in da7219_aad_fw_to_pdata()
753 aad_pdata->adc_1bit_rpt = in da7219_aad_fw_to_pdata()
756 aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1; in da7219_aad_fw_to_pdata()
766 struct da7219_aad_priv *da7219_aad = da7219->aad; in da7219_aad_handle_pdata()
767 struct da7219_pdata *pdata = da7219->pdata; in da7219_aad_handle_pdata()
769 if ((pdata) && (pdata->aad_pdata)) { in da7219_aad_handle_pdata()
770 struct da7219_aad_pdata *aad_pdata = pdata->aad_pdata; in da7219_aad_handle_pdata()
771 u8 cfg, mask; in da7219_aad_handle_pdata() local
773 da7219_aad->irq = aad_pdata->irq; in da7219_aad_handle_pdata()
775 switch (aad_pdata->micbias_pulse_lvl) { in da7219_aad_handle_pdata()
778 da7219_aad->micbias_pulse_lvl = in da7219_aad_handle_pdata()
779 (aad_pdata->micbias_pulse_lvl << in da7219_aad_handle_pdata()
786 da7219_aad->micbias_pulse_time = aad_pdata->micbias_pulse_time; in da7219_aad_handle_pdata()
788 switch (aad_pdata->btn_cfg) { in da7219_aad_handle_pdata()
796 da7219_aad->btn_cfg = (aad_pdata->btn_cfg << in da7219_aad_handle_pdata()
801 mask = 0; in da7219_aad_handle_pdata()
802 switch (aad_pdata->mic_det_thr) { in da7219_aad_handle_pdata()
807 cfg |= (aad_pdata->mic_det_thr << in da7219_aad_handle_pdata()
809 mask |= DA7219_MIC_DET_THRESH_MASK; in da7219_aad_handle_pdata()
811 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, mask, cfg); in da7219_aad_handle_pdata()
814 mask = 0; in da7219_aad_handle_pdata()
815 switch (aad_pdata->jack_ins_deb) { in da7219_aad_handle_pdata()
824 cfg |= (aad_pdata->jack_ins_deb << in da7219_aad_handle_pdata()
826 mask |= DA7219_JACKDET_DEBOUNCE_MASK; in da7219_aad_handle_pdata()
828 switch (aad_pdata->jack_det_rate) { in da7219_aad_handle_pdata()
833 cfg |= (aad_pdata->jack_det_rate << in da7219_aad_handle_pdata()
835 mask |= DA7219_JACK_DETECT_RATE_MASK; in da7219_aad_handle_pdata()
837 switch (aad_pdata->jack_rem_deb) { in da7219_aad_handle_pdata()
842 cfg |= (aad_pdata->jack_rem_deb << in da7219_aad_handle_pdata()
844 mask |= DA7219_JACKDET_REM_DEB_MASK; in da7219_aad_handle_pdata()
846 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_2, mask, cfg); in da7219_aad_handle_pdata()
849 aad_pdata->a_d_btn_thr); in da7219_aad_handle_pdata()
851 aad_pdata->d_b_btn_thr); in da7219_aad_handle_pdata()
853 aad_pdata->b_c_btn_thr); in da7219_aad_handle_pdata()
855 aad_pdata->c_mic_btn_thr); in da7219_aad_handle_pdata()
858 mask = 0; in da7219_aad_handle_pdata()
859 switch (aad_pdata->btn_avg) { in da7219_aad_handle_pdata()
864 cfg |= (aad_pdata->btn_avg << in da7219_aad_handle_pdata()
866 mask |= DA7219_BUTTON_AVERAGE_MASK; in da7219_aad_handle_pdata()
868 switch (aad_pdata->adc_1bit_rpt) { in da7219_aad_handle_pdata()
873 cfg |= (aad_pdata->adc_1bit_rpt << in da7219_aad_handle_pdata()
875 mask |= DA7219_ADC_1_BIT_REPEAT_MASK; in da7219_aad_handle_pdata()
877 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_7, mask, cfg); in da7219_aad_handle_pdata()
879 switch (aad_pdata->jack_ins_det_pty) { in da7219_aad_handle_pdata()
899 struct da7219_aad_priv *da7219_aad = da7219->aad; in da7219_aad_handle_gnd_switch_time()
906 da7219_aad->gnd_switch_delay = 32; in da7219_aad_handle_gnd_switch_time()
909 da7219_aad->gnd_switch_delay = 64; in da7219_aad_handle_gnd_switch_time()
912 da7219_aad->gnd_switch_delay = 128; in da7219_aad_handle_gnd_switch_time()
915 da7219_aad->gnd_switch_delay = 256; in da7219_aad_handle_gnd_switch_time()
918 da7219_aad->gnd_switch_delay = 32; in da7219_aad_handle_gnd_switch_time()
930 struct da7219_aad_priv *da7219_aad = da7219->aad; in da7219_aad_suspend()
934 disable_irq(da7219_aad->irq); in da7219_aad_suspend()
936 if (da7219_aad->jack) { in da7219_aad_suspend()
937 /* Disable jack detection during suspend */ in da7219_aad_suspend()
940 cancel_delayed_work_sync(&da7219_aad->jack_det_work); in da7219_aad_suspend()
941 /* Disable ground switch */ in da7219_aad_suspend()
945 * If we have a 4-pole jack inserted, then micbias will be in da7219_aad_suspend()
946 * enabled. We can disable micbias here, and keep a note to in da7219_aad_suspend()
947 * re-enable it on resume. If jack removal occurred during in da7219_aad_suspend()
950 if (da7219_aad->jack_inserted) { in da7219_aad_suspend()
955 da7219_aad->micbias_resume_enable = true; in da7219_aad_suspend()
964 struct da7219_aad_priv *da7219_aad = da7219->aad; in da7219_aad_resume()
967 if (da7219_aad->jack) { in da7219_aad_resume()
968 /* Re-enable micbias if previously enabled for 4-pole jack */ in da7219_aad_resume()
969 if (da7219_aad->jack_inserted && in da7219_aad_resume()
970 da7219_aad->micbias_resume_enable) { in da7219_aad_resume()
973 da7219_aad->micbias_resume_enable = false; in da7219_aad_resume()
976 /* Re-enable jack detection */ in da7219_aad_resume()
982 enable_irq(da7219_aad->irq); in da7219_aad_resume()
993 struct da7219_aad_priv *da7219_aad = da7219->aad; in da7219_aad_init()
994 u8 mask[DA7219_AAD_IRQ_REG_MAX]; in da7219_aad_init() local
997 da7219_aad->component = component; in da7219_aad_init()
1002 /* Disable button detection */ in da7219_aad_init()
1008 da7219_aad->aad_wq = create_singlethread_workqueue("da7219-aad"); in da7219_aad_init()
1009 if (!da7219_aad->aad_wq) { in da7219_aad_init()
1010 dev_err(component->dev, "Failed to create aad workqueue\n"); in da7219_aad_init()
1011 return -ENOMEM; in da7219_aad_init()
1014 INIT_DELAYED_WORK(&da7219_aad->jack_det_work, da7219_aad_jack_det_work); in da7219_aad_init()
1015 INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work); in da7219_aad_init()
1016 INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work); in da7219_aad_init()
1018 ret = request_threaded_irq(da7219_aad->irq, NULL, in da7219_aad_init()
1021 "da7219-aad", da7219_aad); in da7219_aad_init()
1023 dev_err(component->dev, "Failed to request IRQ: %d\n", ret); in da7219_aad_init()
1028 memset(mask, 0, DA7219_AAD_IRQ_REG_MAX); in da7219_aad_init()
1029 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A, in da7219_aad_init()
1030 &mask, DA7219_AAD_IRQ_REG_MAX); in da7219_aad_init()
1038 struct da7219_aad_priv *da7219_aad = da7219->aad; in da7219_aad_exit()
1039 u8 mask[DA7219_AAD_IRQ_REG_MAX]; in da7219_aad_exit() local
1041 /* Mask off AAD IRQs */ in da7219_aad_exit()
1042 memset(mask, DA7219_BYTE_MASK, DA7219_AAD_IRQ_REG_MAX); in da7219_aad_exit()
1043 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A, in da7219_aad_exit()
1044 mask, DA7219_AAD_IRQ_REG_MAX); in da7219_aad_exit()
1046 free_irq(da7219_aad->irq, da7219_aad); in da7219_aad_exit()
1048 cancel_delayed_work_sync(&da7219_aad->jack_det_work); in da7219_aad_exit()
1049 cancel_work_sync(&da7219_aad->btn_det_work); in da7219_aad_exit()
1050 cancel_work_sync(&da7219_aad->hptest_work); in da7219_aad_exit()
1051 destroy_workqueue(da7219_aad->aad_wq); in da7219_aad_exit()
1061 struct device *dev = &i2c->dev; in da7219_aad_probe()
1066 return -ENOMEM; in da7219_aad_probe()
1068 da7219->aad = da7219_aad; in da7219_aad_probe()
1071 if (da7219->pdata && !da7219->pdata->aad_pdata) in da7219_aad_probe()
1072 da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(dev); in da7219_aad_probe()