Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: codecs: add support for WCD939x Codec

Merge series from Neil Armstrong <neil.armstrong@linaro.org>:

Add the main WCD9390/WCD9395 Audio Codec driver to support:
- 4 ADC inputs for up to 5 Analog Microphones
- 4 DMIC inputs for up to 8 Digital Microphones
- 4 Microphone BIAS
- Stereo Headphone output
- Mono EAR output
- MBHC engine for Headset Detection

This adds:
- bindings
- MBHC changes to support Type-C muc
- Soundwire Slave driver
- Code driver

The USB Mux subsystem support will be submitted separately
since it's a functionally separate subsystem connected over
I2C with it's own reset signal.

+6597 -95
+1 -80
Documentation/devicetree/bindings/sound/qcom,wcd938x.yaml
··· 15 15 16 16 allOf: 17 17 - $ref: dai-common.yaml# 18 + - $ref: qcom,wcd93xx-common.yaml# 18 19 19 20 properties: 20 21 compatible: ··· 23 22 - qcom,wcd9380-codec 24 23 - qcom,wcd9385-codec 25 24 26 - reset-gpios: 27 - description: GPIO spec for reset line to use 28 - maxItems: 1 29 - 30 25 us-euro-gpios: 31 26 description: GPIO spec for swapping gnd and mic segments 32 27 maxItems: 1 33 28 34 - vdd-buck-supply: 35 - description: A reference to the 1.8V buck supply 36 - 37 - vdd-rxtx-supply: 38 - description: A reference to the 1.8V rx supply 39 - 40 - vdd-io-supply: 41 - description: A reference to the 1.8V I/O supply 42 - 43 - vdd-mic-bias-supply: 44 - description: A reference to the 3.8V mic bias supply 45 - 46 - qcom,tx-device: 47 - $ref: /schemas/types.yaml#/definitions/phandle-array 48 - description: A reference to Soundwire tx device phandle 49 - 50 - qcom,rx-device: 51 - $ref: /schemas/types.yaml#/definitions/phandle-array 52 - description: A reference to Soundwire rx device phandle 53 - 54 - qcom,micbias1-microvolt: 55 - description: micbias1 voltage 56 - minimum: 1800000 57 - maximum: 2850000 58 - 59 - qcom,micbias2-microvolt: 60 - description: micbias2 voltage 61 - minimum: 1800000 62 - maximum: 2850000 63 - 64 - qcom,micbias3-microvolt: 65 - description: micbias3 voltage 66 - minimum: 1800000 67 - maximum: 2850000 68 - 69 - qcom,micbias4-microvolt: 70 - description: micbias4 voltage 71 - minimum: 1800000 72 - maximum: 2850000 73 - 74 - qcom,hphl-jack-type-normally-closed: 75 - description: Indicates that HPHL jack switch type is normally closed 76 - type: boolean 77 - 78 - qcom,ground-jack-type-normally-closed: 79 - description: Indicates that Headset Ground switch type is normally closed 80 - type: boolean 81 - 82 - qcom,mbhc-headset-vthreshold-microvolt: 83 - description: Voltage threshold value for headset detection 84 - minimum: 0 85 - maximum: 2850000 86 - 87 - qcom,mbhc-headphone-vthreshold-microvolt: 88 - description: Voltage threshold value for headphone detection 89 - minimum: 0 90 - maximum: 2850000 91 - 92 - qcom,mbhc-buttons-vthreshold-microvolt: 93 - description: 94 - Array of 8 Voltage threshold values corresponding to headset 95 - button0 - button7 96 - minItems: 8 97 - maxItems: 8 98 - 99 - '#sound-dai-cells': 100 - const: 1 101 - 102 29 required: 103 30 - compatible 104 - - reset-gpios 105 - - qcom,tx-device 106 - - qcom,rx-device 107 - - qcom,micbias1-microvolt 108 - - qcom,micbias2-microvolt 109 - - qcom,micbias3-microvolt 110 - - qcom,micbias4-microvolt 111 - - "#sound-dai-cells" 112 31 113 32 unevaluatedProperties: false 114 33
+69
Documentation/devicetree/bindings/sound/qcom,wcd939x-sdw.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/qcom,wcd939x-sdw.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm SoundWire devices on WCD9390/WCD9395 8 + 9 + maintainers: 10 + - Srinivas Kandagatla <srinivas.kandagatla@linaro.org> 11 + 12 + description: | 13 + Qualcomm WCD9390/WCD9395 Codec is a standalone Hi-Fi audio codec IC. 14 + It has RX and TX Soundwire devices. This bindings is for the devices. 15 + 16 + properties: 17 + compatible: 18 + const: sdw20217010e00 19 + 20 + reg: 21 + maxItems: 1 22 + 23 + qcom,tx-port-mapping: 24 + description: | 25 + Specifies static port mapping between device and host tx ports. 26 + In the order of the device port index. 27 + $ref: /schemas/types.yaml#/definitions/uint32-array 28 + minItems: 4 29 + maxItems: 4 30 + 31 + qcom,rx-port-mapping: 32 + description: | 33 + Specifies static port mapping between device and host rx ports. 34 + In the order of device port index. 35 + $ref: /schemas/types.yaml#/definitions/uint32-array 36 + minItems: 6 37 + maxItems: 6 38 + 39 + required: 40 + - compatible 41 + - reg 42 + 43 + additionalProperties: false 44 + 45 + examples: 46 + - | 47 + soundwire@3210000 { 48 + #address-cells = <2>; 49 + #size-cells = <0>; 50 + reg = <0x03210000 0x2000>; 51 + wcd938x_rx: codec@0,4 { 52 + compatible = "sdw20217010e00"; 53 + reg = <0 4>; 54 + qcom,rx-port-mapping = <1 2 3 4 5 6>; 55 + }; 56 + }; 57 + 58 + soundwire@3230000 { 59 + #address-cells = <2>; 60 + #size-cells = <0>; 61 + reg = <0x03230000 0x2000>; 62 + wcd938x_tx: codec@0,3 { 63 + compatible = "sdw20217010e00"; 64 + reg = <0 3>; 65 + qcom,tx-port-mapping = <2 3 4 5>; 66 + }; 67 + }; 68 + 69 + ...
+96
Documentation/devicetree/bindings/sound/qcom,wcd939x.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/qcom,wcd939x.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm WCD9380/WCD9385 Audio Codec 8 + 9 + maintainers: 10 + - Srinivas Kandagatla <srinivas.kandagatla@linaro.org> 11 + 12 + description: | 13 + Qualcomm WCD9390/WCD9395 Codec is a standalone Hi-Fi audio codec IC. 14 + It has RX and TX Soundwire devices. 15 + The WCD9390/WCD9395 IC has a functionally separate USB-C Mux subsystem 16 + accessible over an I2C interface. 17 + The Audio Headphone and Microphone data path between the Codec and the USB-C Mux 18 + subsystems are external to the IC, thus requiring DT port-endpoint graph description 19 + to handle USB-C altmode & orientation switching for Audio Accessory Mode. 20 + 21 + allOf: 22 + - $ref: dai-common.yaml# 23 + - $ref: qcom,wcd93xx-common.yaml# 24 + 25 + properties: 26 + compatible: 27 + oneOf: 28 + - const: qcom,wcd9390-codec 29 + - items: 30 + - const: qcom,wcd9395-codec 31 + - const: qcom,wcd9390-codec 32 + 33 + mode-switch: 34 + description: Flag the port as possible handler of altmode switching 35 + type: boolean 36 + 37 + orientation-switch: 38 + description: Flag the port as possible handler of orientation switching 39 + type: boolean 40 + 41 + port: 42 + $ref: /schemas/graph.yaml#/properties/port 43 + description: 44 + A port node to link the WCD939x Codec node to USB MUX subsystems for the 45 + purpose of handling altmode muxing and orientation switching to detect and 46 + enable Audio Accessory Mode. 47 + 48 + required: 49 + - compatible 50 + 51 + unevaluatedProperties: false 52 + 53 + examples: 54 + - | 55 + #include <dt-bindings/interrupt-controller/irq.h> 56 + codec { 57 + compatible = "qcom,wcd9390-codec"; 58 + reset-gpios = <&tlmm 32 IRQ_TYPE_NONE>; 59 + #sound-dai-cells = <1>; 60 + qcom,tx-device = <&wcd939x_tx>; 61 + qcom,rx-device = <&wcd939x_rx>; 62 + qcom,micbias1-microvolt = <1800000>; 63 + qcom,micbias2-microvolt = <1800000>; 64 + qcom,micbias3-microvolt = <1800000>; 65 + qcom,micbias4-microvolt = <1800000>; 66 + qcom,hphl-jack-type-normally-closed; 67 + qcom,ground-jack-type-normally-closed; 68 + qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000 500000 500000 500000>; 69 + qcom,mbhc-headphone-vthreshold-microvolt = <50000>; 70 + }; 71 + 72 + /* ... */ 73 + 74 + soundwire@3210000 { 75 + #address-cells = <2>; 76 + #size-cells = <0>; 77 + reg = <0x03210000 0x2000>; 78 + wcd939x_rx: codec@0,4 { 79 + compatible = "sdw20217010e00"; 80 + reg = <0 4>; 81 + qcom,rx-port-mapping = <1 2 3 4 5 6>; 82 + }; 83 + }; 84 + 85 + soundwire@3230000 { 86 + #address-cells = <2>; 87 + #size-cells = <0>; 88 + reg = <0x03230000 0x2000>; 89 + wcd938x_tx: codec@0,3 { 90 + compatible = "sdw20217010e00"; 91 + reg = <0 3>; 92 + qcom,tx-port-mapping = <2 3 4 5>; 93 + }; 94 + }; 95 + 96 + ...
+95
Documentation/devicetree/bindings/sound/qcom,wcd93xx-common.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/sound/qcom,wcd93xx-common.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Common properties for Qualcomm WCD93xx Audio Codec 8 + 9 + maintainers: 10 + - Srinivas Kandagatla <srinivas.kandagatla@linaro.org> 11 + 12 + properties: 13 + reset-gpios: 14 + description: GPIO spec for reset line to use 15 + maxItems: 1 16 + 17 + vdd-buck-supply: 18 + description: A reference to the 1.8V buck supply 19 + 20 + vdd-rxtx-supply: 21 + description: A reference to the 1.8V rx supply 22 + 23 + vdd-io-supply: 24 + description: A reference to the 1.8V I/O supply 25 + 26 + vdd-mic-bias-supply: 27 + description: A reference to the 3.8V mic bias supply 28 + 29 + qcom,tx-device: 30 + $ref: /schemas/types.yaml#/definitions/phandle-array 31 + description: A reference to Soundwire tx device phandle 32 + 33 + qcom,rx-device: 34 + $ref: /schemas/types.yaml#/definitions/phandle-array 35 + description: A reference to Soundwire rx device phandle 36 + 37 + qcom,micbias1-microvolt: 38 + description: micbias1 voltage 39 + minimum: 1800000 40 + maximum: 2850000 41 + 42 + qcom,micbias2-microvolt: 43 + description: micbias2 voltage 44 + minimum: 1800000 45 + maximum: 2850000 46 + 47 + qcom,micbias3-microvolt: 48 + description: micbias3 voltage 49 + minimum: 1800000 50 + maximum: 2850000 51 + 52 + qcom,micbias4-microvolt: 53 + description: micbias4 voltage 54 + minimum: 1800000 55 + maximum: 2850000 56 + 57 + qcom,hphl-jack-type-normally-closed: 58 + description: Indicates that HPHL jack switch type is normally closed 59 + type: boolean 60 + 61 + qcom,ground-jack-type-normally-closed: 62 + description: Indicates that Headset Ground switch type is normally closed 63 + type: boolean 64 + 65 + qcom,mbhc-headset-vthreshold-microvolt: 66 + description: Voltage threshold value for headset detection 67 + minimum: 0 68 + maximum: 2850000 69 + 70 + qcom,mbhc-headphone-vthreshold-microvolt: 71 + description: Voltage threshold value for headphone detection 72 + minimum: 0 73 + maximum: 2850000 74 + 75 + qcom,mbhc-buttons-vthreshold-microvolt: 76 + description: 77 + Array of 8 Voltage threshold values corresponding to headset 78 + button0 - button7 79 + minItems: 8 80 + maxItems: 8 81 + 82 + '#sound-dai-cells': 83 + const: 1 84 + 85 + required: 86 + - reset-gpios 87 + - qcom,tx-device 88 + - qcom,rx-device 89 + - qcom,micbias1-microvolt 90 + - qcom,micbias2-microvolt 91 + - qcom,micbias3-microvolt 92 + - qcom,micbias4-microvolt 93 + - "#sound-dai-cells" 94 + 95 + additionalProperties: true
+19
sound/soc/codecs/Kconfig
··· 276 276 imply SND_SOC_WCD9335 277 277 imply SND_SOC_WCD934X 278 278 imply SND_SOC_WCD938X_SDW 279 + imply SND_SOC_WCD939X_SDW 279 280 imply SND_SOC_LPASS_MACRO_COMMON 280 281 imply SND_SOC_LPASS_RX_MACRO 281 282 imply SND_SOC_LPASS_TX_MACRO ··· 2059 2058 help 2060 2059 The WCD9380/9385 is a audio codec IC Integrated in 2061 2060 Qualcomm SoCs like SM8250. 2061 + 2062 + config SND_SOC_WCD939X 2063 + depends on SND_SOC_WCD939X_SDW 2064 + tristate 2065 + depends on SOUNDWIRE || !SOUNDWIRE 2066 + depends on TYPEC || !TYPEC 2067 + select SND_SOC_WCD_CLASSH 2068 + 2069 + config SND_SOC_WCD939X_SDW 2070 + tristate "WCD9390/WCD9395 Codec - SDW" 2071 + select SND_SOC_WCD939X 2072 + select SND_SOC_WCD_MBHC 2073 + select REGMAP_IRQ 2074 + depends on SOUNDWIRE 2075 + select REGMAP_SOUNDWIRE 2076 + help 2077 + The WCD9390/9395 is a audio codec IC Integrated in 2078 + Qualcomm SoCs like SM8650. 2062 2079 2063 2080 config SND_SOC_WL1273 2064 2081 tristate
+7
sound/soc/codecs/Makefile
··· 313 313 snd-soc-wcd934x-objs := wcd934x.o 314 314 snd-soc-wcd938x-objs := wcd938x.o 315 315 snd-soc-wcd938x-sdw-objs := wcd938x-sdw.o 316 + snd-soc-wcd939x-objs := wcd939x.o 317 + snd-soc-wcd939x-sdw-objs := wcd939x-sdw.o 316 318 snd-soc-wl1273-objs := wl1273.o 317 319 snd-soc-wm-adsp-objs := wm_adsp.o 318 320 snd-soc-wm0010-objs := wm0010.o ··· 704 702 ifdef CONFIG_SND_SOC_WCD938X_SDW 705 703 # avoid link failure by forcing sdw code built-in when needed 706 704 obj-$(CONFIG_SND_SOC_WCD938X) += snd-soc-wcd938x-sdw.o 705 + endif 706 + obj-$(CONFIG_SND_SOC_WCD939X) += snd-soc-wcd939x.o 707 + ifdef CONFIG_SND_SOC_WCD939X_SDW 708 + # avoid link failure by forcing sdw code built-in when needed 709 + obj-$(CONFIG_SND_SOC_WCD939X) += snd-soc-wcd939x-sdw.o 707 710 endif 708 711 obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o 709 712 obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o
+1
sound/soc/codecs/wcd-clsh-v2.h
··· 47 47 /* New CLSH after this */ 48 48 WCD937X = 2, 49 49 WCD938X = 3, 50 + WCD939X = 4, 50 51 }; 51 52 struct wcd_clsh_ctrl; 52 53
+80 -15
sound/soc/codecs/wcd-mbhc-v2.c
··· 16 16 #define HS_DETECT_PLUG_TIME_MS (3 * 1000) 17 17 #define MBHC_BUTTON_PRESS_THRESHOLD_MIN 250 18 18 #define GND_MIC_SWAP_THRESHOLD 4 19 + #define GND_MIC_USBC_SWAP_THRESHOLD 2 19 20 #define WCD_FAKE_REMOVAL_MIN_PERIOD_MS 100 20 21 #define HPHL_CROSS_CONN_THRESHOLD 100 21 22 #define HS_VREF_MIN_VAL 1400 ··· 53 52 struct wcd_mbhc_field *fields; 54 53 /* Delayed work to report long button press */ 55 54 struct delayed_work mbhc_btn_dwork; 55 + /* Work to handle plug report */ 56 + struct work_struct mbhc_plug_detect_work; 56 57 /* Work to correct accessory type */ 57 58 struct work_struct correct_plug_swch; 58 59 struct mutex lock; 59 60 int buttons_pressed; 60 61 u32 hph_status; /* track headhpone status */ 61 62 u8 current_plug; 63 + unsigned int swap_thr; 62 64 bool is_btn_press; 63 65 bool in_swch_irq_handler; 64 66 bool hs_detect_work_stop; ··· 510 506 } 511 507 } 512 508 513 - static irqreturn_t wcd_mbhc_mech_plug_detect_irq(int irq, void *data) 509 + static void mbhc_plug_detect_fn(struct work_struct *work) 514 510 { 515 - struct snd_soc_component *component; 511 + struct wcd_mbhc *mbhc = container_of(work, struct wcd_mbhc, mbhc_plug_detect_work); 512 + struct snd_soc_component *component = mbhc->component; 516 513 enum snd_jack_types jack_type; 517 - struct wcd_mbhc *mbhc = data; 518 514 bool detection_type; 519 515 520 - component = mbhc->component; 521 516 mutex_lock(&mbhc->lock); 522 517 523 518 mbhc->in_swch_irq_handler = true; ··· 579 576 exit: 580 577 mbhc->in_swch_irq_handler = false; 581 578 mutex_unlock(&mbhc->lock); 579 + } 580 + 581 + static irqreturn_t wcd_mbhc_mech_plug_detect_irq(int irq, void *data) 582 + { 583 + struct wcd_mbhc *mbhc = data; 584 + 585 + if (!mbhc->cfg->typec_analog_mux) 586 + schedule_work(&mbhc->mbhc_plug_detect_work); 587 + 582 588 return IRQ_HANDLED; 583 589 } 590 + 591 + int wcd_mbhc_typec_report_unplug(struct wcd_mbhc *mbhc) 592 + { 593 + 594 + if (!mbhc || !mbhc->cfg->typec_analog_mux) 595 + return -EINVAL; 596 + 597 + if (mbhc->mbhc_cb->clk_setup) 598 + mbhc->mbhc_cb->clk_setup(mbhc->component, false); 599 + 600 + wcd_mbhc_write_field(mbhc, WCD_MBHC_L_DET_EN, 0); 601 + wcd_mbhc_write_field(mbhc, WCD_MBHC_MECH_DETECTION_TYPE, 0); 602 + 603 + schedule_work(&mbhc->mbhc_plug_detect_work); 604 + 605 + return 0; 606 + } 607 + EXPORT_SYMBOL_GPL(wcd_mbhc_typec_report_unplug); 608 + 609 + int wcd_mbhc_typec_report_plug(struct wcd_mbhc *mbhc) 610 + { 611 + if (!mbhc || !mbhc->cfg->typec_analog_mux) 612 + return -EINVAL; 613 + 614 + if (mbhc->mbhc_cb->clk_setup) 615 + mbhc->mbhc_cb->clk_setup(mbhc->component, true); 616 + wcd_mbhc_write_field(mbhc, WCD_MBHC_L_DET_EN, 1); 617 + 618 + schedule_work(&mbhc->mbhc_plug_detect_work); 619 + 620 + return 0; 621 + } 622 + EXPORT_SYMBOL_GPL(wcd_mbhc_typec_report_plug); 584 623 585 624 static int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc) 586 625 { ··· 770 725 771 726 mutex_lock(&mbhc->lock); 772 727 773 - /* enable HS detection */ 728 + if (mbhc->cfg->typec_analog_mux) 729 + mbhc->swap_thr = GND_MIC_USBC_SWAP_THRESHOLD; 730 + else 731 + mbhc->swap_thr = GND_MIC_SWAP_THRESHOLD; 732 + 733 + /* setup HS detection */ 774 734 if (mbhc->mbhc_cb->hph_pull_up_control_v2) 775 735 mbhc->mbhc_cb->hph_pull_up_control_v2(component, 776 - HS_PULLUP_I_DEFAULT); 736 + mbhc->cfg->typec_analog_mux ? 737 + HS_PULLUP_I_OFF : HS_PULLUP_I_DEFAULT); 777 738 else if (mbhc->mbhc_cb->hph_pull_up_control) 778 - mbhc->mbhc_cb->hph_pull_up_control(component, I_DEFAULT); 739 + mbhc->mbhc_cb->hph_pull_up_control(component, 740 + mbhc->cfg->typec_analog_mux ? 741 + I_OFF : I_DEFAULT); 779 742 else 780 - wcd_mbhc_write_field(mbhc, WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3); 743 + wcd_mbhc_write_field(mbhc, WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 744 + mbhc->cfg->typec_analog_mux ? 0 : 3); 781 745 782 746 wcd_mbhc_write_field(mbhc, WCD_MBHC_HPHL_PLUG_TYPE, mbhc->cfg->hphl_swh); 783 747 wcd_mbhc_write_field(mbhc, WCD_MBHC_GND_PLUG_TYPE, mbhc->cfg->gnd_swh); ··· 795 741 mbhc->mbhc_cb->mbhc_gnd_det_ctrl(component, true); 796 742 wcd_mbhc_write_field(mbhc, WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, 1); 797 743 798 - wcd_mbhc_write_field(mbhc, WCD_MBHC_L_DET_EN, 1); 744 + /* Plug detect is triggered manually if analog goes through USBCC */ 745 + if (mbhc->cfg->typec_analog_mux) 746 + wcd_mbhc_write_field(mbhc, WCD_MBHC_L_DET_EN, 0); 747 + else 748 + wcd_mbhc_write_field(mbhc, WCD_MBHC_L_DET_EN, 1); 799 749 800 - /* Insertion debounce set to 96ms */ 801 - wcd_mbhc_write_field(mbhc, WCD_MBHC_INSREM_DBNC, 6); 750 + if (mbhc->cfg->typec_analog_mux) 751 + /* Insertion debounce set to 48ms */ 752 + wcd_mbhc_write_field(mbhc, WCD_MBHC_INSREM_DBNC, 4); 753 + else 754 + /* Insertion debounce set to 96ms */ 755 + wcd_mbhc_write_field(mbhc, WCD_MBHC_INSREM_DBNC, 6); 802 756 803 757 /* Button Debounce set to 16ms */ 804 758 wcd_mbhc_write_field(mbhc, WCD_MBHC_BTN_DBNC, 2); ··· 815 753 mbhc->mbhc_cb->mbhc_bias(component, true); 816 754 /* enable MBHC clock */ 817 755 if (mbhc->mbhc_cb->clk_setup) 818 - mbhc->mbhc_cb->clk_setup(component, true); 756 + mbhc->mbhc_cb->clk_setup(component, 757 + mbhc->cfg->typec_analog_mux ? false : true); 819 758 820 759 /* program HS_VREF value */ 821 760 wcd_program_hs_vref(mbhc); ··· 1178 1115 do { 1179 1116 cross_conn = wcd_check_cross_conn(mbhc); 1180 1117 try++; 1181 - } while (try < GND_MIC_SWAP_THRESHOLD); 1118 + } while (try < mbhc->swap_thr); 1182 1119 1183 1120 if (cross_conn > 0) { 1184 1121 plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; ··· 1246 1183 cross_conn = wcd_check_cross_conn(mbhc); 1247 1184 if (cross_conn > 0) { /* cross-connection */ 1248 1185 pt_gnd_mic_swap_cnt++; 1249 - if (pt_gnd_mic_swap_cnt < GND_MIC_SWAP_THRESHOLD) 1186 + if (pt_gnd_mic_swap_cnt < mbhc->swap_thr) 1250 1187 continue; 1251 1188 else 1252 1189 plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; ··· 1257 1194 } else /* Error if (cross_conn < 0) */ 1258 1195 continue; 1259 1196 1260 - if (pt_gnd_mic_swap_cnt == GND_MIC_SWAP_THRESHOLD) { 1197 + if (pt_gnd_mic_swap_cnt == mbhc->swap_thr) { 1261 1198 /* US_EU gpio present, flip switch */ 1262 1199 if (mbhc->cfg->swap_gnd_mic) { 1263 1200 if (mbhc->cfg->swap_gnd_mic(component, true)) ··· 1536 1473 mutex_init(&mbhc->lock); 1537 1474 1538 1475 INIT_WORK(&mbhc->correct_plug_swch, wcd_correct_swch_plug); 1476 + INIT_WORK(&mbhc->mbhc_plug_detect_work, mbhc_plug_detect_fn); 1539 1477 1540 1478 ret = request_threaded_irq(mbhc->intr_ids->mbhc_sw_intr, NULL, 1541 1479 wcd_mbhc_mech_plug_detect_irq, ··· 1626 1562 1627 1563 mutex_lock(&mbhc->lock); 1628 1564 wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); 1565 + cancel_work_sync(&mbhc->mbhc_plug_detect_work); 1629 1566 mutex_unlock(&mbhc->lock); 1630 1567 1631 1568 kfree(mbhc);
+3
sound/soc/codecs/wcd-mbhc-v2.h
··· 193 193 int v_hs_max; 194 194 int num_btn; 195 195 bool mono_stero_detection; 196 + bool typec_analog_mux; 196 197 bool (*swap_gnd_mic)(struct snd_soc_component *component, bool active); 197 198 bool hs_ext_micbias; 198 199 bool gnd_det_en; ··· 274 273 void wcd_mbhc_stop(struct wcd_mbhc *mbhc); 275 274 void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type); 276 275 int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc); 276 + int wcd_mbhc_typec_report_plug(struct wcd_mbhc *mbhc); 277 + int wcd_mbhc_typec_report_unplug(struct wcd_mbhc *mbhc); 277 278 struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component, 278 279 const struct wcd_mbhc_cb *mbhc_cb, 279 280 const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
+1551
sound/soc/codecs/wcd939x-sdw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2023, Linaro Limited 4 + */ 5 + 6 + #include <linux/module.h> 7 + #include <linux/slab.h> 8 + #include <linux/platform_device.h> 9 + #include <linux/device.h> 10 + #include <linux/kernel.h> 11 + #include <linux/component.h> 12 + #include <linux/pm_runtime.h> 13 + #include <linux/irq.h> 14 + #include <linux/irqdomain.h> 15 + #include <linux/of.h> 16 + #include <linux/soundwire/sdw.h> 17 + #include <linux/soundwire/sdw_type.h> 18 + #include <linux/soundwire/sdw_registers.h> 19 + #include <linux/regmap.h> 20 + #include <sound/soc.h> 21 + #include <sound/soc-dapm.h> 22 + #include "wcd939x.h" 23 + 24 + #define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (0xE0 + 0x10 * (m)) 25 + 26 + static struct wcd939x_sdw_ch_info wcd939x_sdw_rx_ch_info[] = { 27 + WCD_SDW_CH(WCD939X_HPH_L, WCD939X_HPH_PORT, BIT(0)), 28 + WCD_SDW_CH(WCD939X_HPH_R, WCD939X_HPH_PORT, BIT(1)), 29 + WCD_SDW_CH(WCD939X_CLSH, WCD939X_CLSH_PORT, BIT(0)), 30 + WCD_SDW_CH(WCD939X_COMP_L, WCD939X_COMP_PORT, BIT(0)), 31 + WCD_SDW_CH(WCD939X_COMP_R, WCD939X_COMP_PORT, BIT(1)), 32 + WCD_SDW_CH(WCD939X_LO, WCD939X_LO_PORT, BIT(0)), 33 + WCD_SDW_CH(WCD939X_DSD_L, WCD939X_DSD_PORT, BIT(0)), 34 + WCD_SDW_CH(WCD939X_DSD_R, WCD939X_DSD_PORT, BIT(1)), 35 + WCD_SDW_CH(WCD939X_HIFI_PCM_L, WCD939X_HIFI_PCM_PORT, BIT(0)), 36 + WCD_SDW_CH(WCD939X_HIFI_PCM_R, WCD939X_HIFI_PCM_PORT, BIT(1)), 37 + }; 38 + 39 + static struct wcd939x_sdw_ch_info wcd939x_sdw_tx_ch_info[] = { 40 + WCD_SDW_CH(WCD939X_ADC1, WCD939X_ADC_1_4_PORT, BIT(0)), 41 + WCD_SDW_CH(WCD939X_ADC2, WCD939X_ADC_1_4_PORT, BIT(1)), 42 + WCD_SDW_CH(WCD939X_ADC3, WCD939X_ADC_1_4_PORT, BIT(2)), 43 + WCD_SDW_CH(WCD939X_ADC4, WCD939X_ADC_1_4_PORT, BIT(3)), 44 + WCD_SDW_CH(WCD939X_DMIC0, WCD939X_DMIC_0_3_MBHC_PORT, BIT(0)), 45 + WCD_SDW_CH(WCD939X_DMIC1, WCD939X_DMIC_0_3_MBHC_PORT, BIT(1)), 46 + WCD_SDW_CH(WCD939X_MBHC, WCD939X_DMIC_0_3_MBHC_PORT, BIT(2)), 47 + WCD_SDW_CH(WCD939X_DMIC2, WCD939X_DMIC_0_3_MBHC_PORT, BIT(2)), 48 + WCD_SDW_CH(WCD939X_DMIC3, WCD939X_DMIC_0_3_MBHC_PORT, BIT(3)), 49 + WCD_SDW_CH(WCD939X_DMIC4, WCD939X_DMIC_3_7_PORT, BIT(0)), 50 + WCD_SDW_CH(WCD939X_DMIC5, WCD939X_DMIC_3_7_PORT, BIT(1)), 51 + WCD_SDW_CH(WCD939X_DMIC6, WCD939X_DMIC_3_7_PORT, BIT(2)), 52 + WCD_SDW_CH(WCD939X_DMIC7, WCD939X_DMIC_3_7_PORT, BIT(3)), 53 + }; 54 + 55 + static struct sdw_dpn_prop wcd939x_rx_dpn_prop[WCD939X_MAX_RX_SWR_PORTS] = { 56 + { 57 + .num = WCD939X_HPH_PORT, 58 + .type = SDW_DPN_SIMPLE, 59 + .min_ch = 1, 60 + .max_ch = 2, 61 + .simple_ch_prep_sm = true, 62 + }, 63 + { 64 + .num = WCD939X_CLSH_PORT, 65 + .type = SDW_DPN_SIMPLE, 66 + .min_ch = 1, 67 + .max_ch = 1, 68 + .simple_ch_prep_sm = true, 69 + }, 70 + { 71 + .num = WCD939X_COMP_PORT, 72 + .type = SDW_DPN_SIMPLE, 73 + .min_ch = 1, 74 + .max_ch = 2, 75 + .simple_ch_prep_sm = true, 76 + }, 77 + { 78 + .num = WCD939X_LO_PORT, 79 + .type = SDW_DPN_SIMPLE, 80 + .min_ch = 1, 81 + .max_ch = 1, 82 + .simple_ch_prep_sm = true, 83 + }, 84 + { 85 + .num = WCD939X_DSD_PORT, 86 + .type = SDW_DPN_SIMPLE, 87 + .min_ch = 1, 88 + .max_ch = 2, 89 + .simple_ch_prep_sm = true, 90 + }, 91 + { 92 + .num = WCD939X_HIFI_PCM_PORT, 93 + .type = SDW_DPN_SIMPLE, 94 + .min_ch = 1, 95 + .max_ch = 2, 96 + .simple_ch_prep_sm = true, 97 + } 98 + }; 99 + 100 + static struct sdw_dpn_prop wcd939x_tx_dpn_prop[WCD939X_MAX_TX_SWR_PORTS] = { 101 + { 102 + .num = WCD939X_ADC_1_4_PORT, 103 + .type = SDW_DPN_SIMPLE, 104 + .min_ch = 1, 105 + .max_ch = 4, 106 + .simple_ch_prep_sm = true, 107 + }, 108 + { 109 + .num = WCD939X_ADC_DMIC_1_2_PORT, 110 + .type = SDW_DPN_SIMPLE, 111 + .min_ch = 1, 112 + .max_ch = 4, 113 + .simple_ch_prep_sm = true, 114 + }, 115 + { 116 + .num = WCD939X_DMIC_0_3_MBHC_PORT, 117 + .type = SDW_DPN_SIMPLE, 118 + .min_ch = 1, 119 + .max_ch = 4, 120 + .simple_ch_prep_sm = true, 121 + }, 122 + { 123 + .num = WCD939X_DMIC_3_7_PORT, 124 + .type = SDW_DPN_SIMPLE, 125 + .min_ch = 1, 126 + .max_ch = 4, 127 + .simple_ch_prep_sm = true, 128 + } 129 + }; 130 + 131 + struct device *wcd939x_sdw_device_get(struct device_node *np) 132 + { 133 + return bus_find_device_by_of_node(&sdw_bus_type, np); 134 + } 135 + EXPORT_SYMBOL_GPL(wcd939x_sdw_device_get); 136 + 137 + unsigned int wcd939x_swr_get_current_bank(struct sdw_slave *sdev) 138 + { 139 + return FIELD_GET(SDW_SCP_STAT_CURR_BANK, 140 + sdw_read(sdev, SDW_SCP_CTRL)); 141 + } 142 + EXPORT_SYMBOL_GPL(wcd939x_swr_get_current_bank); 143 + 144 + int wcd939x_sdw_hw_params(struct wcd939x_sdw_priv *wcd, 145 + struct snd_pcm_substream *substream, 146 + struct snd_pcm_hw_params *params, 147 + struct snd_soc_dai *dai) 148 + { 149 + struct sdw_port_config port_config[WCD939X_MAX_SWR_PORTS]; 150 + unsigned long ch_mask; 151 + int i, j; 152 + 153 + wcd->sconfig.ch_count = 1; 154 + wcd->active_ports = 0; 155 + for (i = 0; i < WCD939X_MAX_SWR_PORTS; i++) { 156 + ch_mask = wcd->port_config[i].ch_mask; 157 + 158 + if (!ch_mask) 159 + continue; 160 + 161 + for_each_set_bit(j, &ch_mask, 4) 162 + wcd->sconfig.ch_count++; 163 + 164 + port_config[wcd->active_ports] = wcd->port_config[i]; 165 + wcd->active_ports++; 166 + } 167 + 168 + wcd->sconfig.bps = 1; 169 + wcd->sconfig.frame_rate = params_rate(params); 170 + if (wcd->is_tx) 171 + wcd->sconfig.direction = SDW_DATA_DIR_TX; 172 + else 173 + wcd->sconfig.direction = SDW_DATA_DIR_RX; 174 + 175 + wcd->sconfig.type = SDW_STREAM_PCM; 176 + 177 + return sdw_stream_add_slave(wcd->sdev, &wcd->sconfig, &port_config[0], 178 + wcd->active_ports, wcd->sruntime); 179 + } 180 + EXPORT_SYMBOL_GPL(wcd939x_sdw_hw_params); 181 + 182 + int wcd939x_sdw_free(struct wcd939x_sdw_priv *wcd, 183 + struct snd_pcm_substream *substream, 184 + struct snd_soc_dai *dai) 185 + { 186 + sdw_stream_remove_slave(wcd->sdev, wcd->sruntime); 187 + 188 + return 0; 189 + } 190 + EXPORT_SYMBOL_GPL(wcd939x_sdw_free); 191 + 192 + int wcd939x_sdw_set_sdw_stream(struct wcd939x_sdw_priv *wcd, 193 + struct snd_soc_dai *dai, void *stream, 194 + int direction) 195 + { 196 + wcd->sruntime = stream; 197 + 198 + return 0; 199 + } 200 + EXPORT_SYMBOL_GPL(wcd939x_sdw_set_sdw_stream); 201 + 202 + struct regmap *wcd939x_swr_get_regmap(struct wcd939x_sdw_priv *wcd) 203 + { 204 + if (wcd->regmap) 205 + return wcd->regmap; 206 + 207 + return ERR_PTR(-EINVAL); 208 + } 209 + EXPORT_SYMBOL_GPL(wcd939x_swr_get_regmap); 210 + 211 + static int wcd9390_update_status(struct sdw_slave *slave, 212 + enum sdw_slave_status status) 213 + { 214 + struct wcd939x_sdw_priv *wcd = dev_get_drvdata(&slave->dev); 215 + 216 + if (wcd->regmap && status == SDW_SLAVE_ATTACHED) { 217 + /* Write out any cached changes that happened between probe and attach */ 218 + regcache_cache_only(wcd->regmap, false); 219 + return regcache_sync(wcd->regmap); 220 + } 221 + 222 + return 0; 223 + } 224 + 225 + static int wcd9390_bus_config(struct sdw_slave *slave, 226 + struct sdw_bus_params *params) 227 + { 228 + sdw_write(slave, SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(params->next_bank), 229 + 0x01); 230 + 231 + return 0; 232 + } 233 + 234 + /* 235 + * Handle Soundwire out-of-band interrupt event by triggering 236 + * the first irq of the slave_irq irq domain, which then will 237 + * be handled by the regmap_irq threaded irq. 238 + * Looping is to ensure no interrupts were missed in the process. 239 + */ 240 + static int wcd9390_interrupt_callback(struct sdw_slave *slave, 241 + struct sdw_slave_intr_status *status) 242 + { 243 + struct wcd939x_sdw_priv *wcd = dev_get_drvdata(&slave->dev); 244 + struct irq_domain *slave_irq = wcd->slave_irq; 245 + u32 sts1, sts2, sts3; 246 + 247 + do { 248 + handle_nested_irq(irq_find_mapping(slave_irq, 0)); 249 + regmap_read(wcd->regmap, WCD939X_DIGITAL_INTR_STATUS_0, &sts1); 250 + regmap_read(wcd->regmap, WCD939X_DIGITAL_INTR_STATUS_1, &sts2); 251 + regmap_read(wcd->regmap, WCD939X_DIGITAL_INTR_STATUS_2, &sts3); 252 + 253 + } while (sts1 || sts2 || sts3); 254 + 255 + return IRQ_HANDLED; 256 + } 257 + 258 + static const struct reg_default wcd939x_defaults[] = { 259 + /* Default values except for Read-Only & Volatile registers */ 260 + { WCD939X_ANA_PAGE, 0x00 }, 261 + { WCD939X_ANA_BIAS, 0x00 }, 262 + { WCD939X_ANA_RX_SUPPLIES, 0x00 }, 263 + { WCD939X_ANA_HPH, 0x0c }, 264 + { WCD939X_ANA_EAR, 0x00 }, 265 + { WCD939X_ANA_EAR_COMPANDER_CTL, 0x02 }, 266 + { WCD939X_ANA_TX_CH1, 0x20 }, 267 + { WCD939X_ANA_TX_CH2, 0x00 }, 268 + { WCD939X_ANA_TX_CH3, 0x20 }, 269 + { WCD939X_ANA_TX_CH4, 0x00 }, 270 + { WCD939X_ANA_MICB1_MICB2_DSP_EN_LOGIC, 0x00 }, 271 + { WCD939X_ANA_MICB3_DSP_EN_LOGIC, 0x00 }, 272 + { WCD939X_ANA_MBHC_MECH, 0x39 }, 273 + { WCD939X_ANA_MBHC_ELECT, 0x08 }, 274 + { WCD939X_ANA_MBHC_ZDET, 0x00 }, 275 + { WCD939X_ANA_MBHC_BTN0, 0x00 }, 276 + { WCD939X_ANA_MBHC_BTN1, 0x10 }, 277 + { WCD939X_ANA_MBHC_BTN2, 0x20 }, 278 + { WCD939X_ANA_MBHC_BTN3, 0x30 }, 279 + { WCD939X_ANA_MBHC_BTN4, 0x40 }, 280 + { WCD939X_ANA_MBHC_BTN5, 0x50 }, 281 + { WCD939X_ANA_MBHC_BTN6, 0x60 }, 282 + { WCD939X_ANA_MBHC_BTN7, 0x70 }, 283 + { WCD939X_ANA_MICB1, 0x10 }, 284 + { WCD939X_ANA_MICB2, 0x10 }, 285 + { WCD939X_ANA_MICB2_RAMP, 0x00 }, 286 + { WCD939X_ANA_MICB3, 0x00 }, 287 + { WCD939X_ANA_MICB4, 0x00 }, 288 + { WCD939X_BIAS_CTL, 0x2a }, 289 + { WCD939X_BIAS_VBG_FINE_ADJ, 0x55 }, 290 + { WCD939X_LDOL_VDDCX_ADJUST, 0x01 }, 291 + { WCD939X_LDOL_DISABLE_LDOL, 0x00 }, 292 + { WCD939X_MBHC_CTL_CLK, 0x00 }, 293 + { WCD939X_MBHC_CTL_ANA, 0x00 }, 294 + { WCD939X_MBHC_ZDET_VNEG_CTL, 0x00 }, 295 + { WCD939X_MBHC_ZDET_BIAS_CTL, 0x46 }, 296 + { WCD939X_MBHC_CTL_BCS, 0x00 }, 297 + { WCD939X_MBHC_TEST_CTL, 0x00 }, 298 + { WCD939X_LDOH_MODE, 0x2b }, 299 + { WCD939X_LDOH_BIAS, 0x68 }, 300 + { WCD939X_LDOH_STB_LOADS, 0x00 }, 301 + { WCD939X_LDOH_SLOWRAMP, 0x50 }, 302 + { WCD939X_MICB1_TEST_CTL_1, 0x1a }, 303 + { WCD939X_MICB1_TEST_CTL_2, 0x00 }, 304 + { WCD939X_MICB1_TEST_CTL_3, 0xa4 }, 305 + { WCD939X_MICB2_TEST_CTL_1, 0x1a }, 306 + { WCD939X_MICB2_TEST_CTL_2, 0x00 }, 307 + { WCD939X_MICB2_TEST_CTL_3, 0x24 }, 308 + { WCD939X_MICB3_TEST_CTL_1, 0x9a }, 309 + { WCD939X_MICB3_TEST_CTL_2, 0x80 }, 310 + { WCD939X_MICB3_TEST_CTL_3, 0x24 }, 311 + { WCD939X_MICB4_TEST_CTL_1, 0x1a }, 312 + { WCD939X_MICB4_TEST_CTL_2, 0x80 }, 313 + { WCD939X_MICB4_TEST_CTL_3, 0x24 }, 314 + { WCD939X_TX_COM_ADC_VCM, 0x39 }, 315 + { WCD939X_TX_COM_BIAS_ATEST, 0xe0 }, 316 + { WCD939X_TX_COM_SPARE1, 0x00 }, 317 + { WCD939X_TX_COM_SPARE2, 0x00 }, 318 + { WCD939X_TX_COM_TXFE_DIV_CTL, 0x22 }, 319 + { WCD939X_TX_COM_TXFE_DIV_START, 0x00 }, 320 + { WCD939X_TX_COM_SPARE3, 0x00 }, 321 + { WCD939X_TX_COM_SPARE4, 0x00 }, 322 + { WCD939X_TX_1_2_TEST_EN, 0xcc }, 323 + { WCD939X_TX_1_2_ADC_IB, 0xe9 }, 324 + { WCD939X_TX_1_2_ATEST_REFCTL, 0x0b }, 325 + { WCD939X_TX_1_2_TEST_CTL, 0x38 }, 326 + { WCD939X_TX_1_2_TEST_BLK_EN1, 0xff }, 327 + { WCD939X_TX_1_2_TXFE1_CLKDIV, 0x00 }, 328 + { WCD939X_TX_3_4_TEST_EN, 0xcc }, 329 + { WCD939X_TX_3_4_ADC_IB, 0xe9 }, 330 + { WCD939X_TX_3_4_ATEST_REFCTL, 0x0b }, 331 + { WCD939X_TX_3_4_TEST_CTL, 0x38 }, 332 + { WCD939X_TX_3_4_TEST_BLK_EN3, 0xff }, 333 + { WCD939X_TX_3_4_TXFE3_CLKDIV, 0x00 }, 334 + { WCD939X_TX_3_4_TEST_BLK_EN2, 0xfb }, 335 + { WCD939X_TX_3_4_TXFE2_CLKDIV, 0x00 }, 336 + { WCD939X_TX_3_4_SPARE1, 0x00 }, 337 + { WCD939X_TX_3_4_TEST_BLK_EN4, 0xfb }, 338 + { WCD939X_TX_3_4_TXFE4_CLKDIV, 0x00 }, 339 + { WCD939X_TX_3_4_SPARE2, 0x00 }, 340 + { WCD939X_CLASSH_MODE_1, 0x40 }, 341 + { WCD939X_CLASSH_MODE_2, 0x3a }, 342 + { WCD939X_CLASSH_MODE_3, 0xf0 }, 343 + { WCD939X_CLASSH_CTRL_VCL_1, 0x7c }, 344 + { WCD939X_CLASSH_CTRL_VCL_2, 0x82 }, 345 + { WCD939X_CLASSH_CTRL_CCL_1, 0x31 }, 346 + { WCD939X_CLASSH_CTRL_CCL_2, 0x80 }, 347 + { WCD939X_CLASSH_CTRL_CCL_3, 0x80 }, 348 + { WCD939X_CLASSH_CTRL_CCL_4, 0x51 }, 349 + { WCD939X_CLASSH_CTRL_CCL_5, 0x00 }, 350 + { WCD939X_CLASSH_BUCK_TMUX_A_D, 0x00 }, 351 + { WCD939X_CLASSH_BUCK_SW_DRV_CNTL, 0x77 }, 352 + { WCD939X_CLASSH_SPARE, 0x80 }, 353 + { WCD939X_FLYBACK_EN, 0x4e }, 354 + { WCD939X_FLYBACK_VNEG_CTRL_1, 0x0b }, 355 + { WCD939X_FLYBACK_VNEG_CTRL_2, 0x45 }, 356 + { WCD939X_FLYBACK_VNEG_CTRL_3, 0x14 }, 357 + { WCD939X_FLYBACK_VNEG_CTRL_4, 0xdb }, 358 + { WCD939X_FLYBACK_VNEG_CTRL_5, 0x83 }, 359 + { WCD939X_FLYBACK_VNEG_CTRL_6, 0x98 }, 360 + { WCD939X_FLYBACK_VNEG_CTRL_7, 0xa9 }, 361 + { WCD939X_FLYBACK_VNEG_CTRL_8, 0x68 }, 362 + { WCD939X_FLYBACK_VNEG_CTRL_9, 0x66 }, 363 + { WCD939X_FLYBACK_VNEGDAC_CTRL_1, 0xed }, 364 + { WCD939X_FLYBACK_VNEGDAC_CTRL_2, 0xf8 }, 365 + { WCD939X_FLYBACK_VNEGDAC_CTRL_3, 0xa6 }, 366 + { WCD939X_FLYBACK_CTRL_1, 0x65 }, 367 + { WCD939X_FLYBACK_TEST_CTL, 0x02 }, 368 + { WCD939X_RX_AUX_SW_CTL, 0x00 }, 369 + { WCD939X_RX_PA_AUX_IN_CONN, 0x01 }, 370 + { WCD939X_RX_TIMER_DIV, 0x32 }, 371 + { WCD939X_RX_OCP_CTL, 0x1f }, 372 + { WCD939X_RX_OCP_COUNT, 0x77 }, 373 + { WCD939X_RX_BIAS_EAR_DAC, 0xa0 }, 374 + { WCD939X_RX_BIAS_EAR_AMP, 0xaa }, 375 + { WCD939X_RX_BIAS_HPH_LDO, 0xa9 }, 376 + { WCD939X_RX_BIAS_HPH_PA, 0xaa }, 377 + { WCD939X_RX_BIAS_HPH_RDACBUFF_CNP2, 0xca }, 378 + { WCD939X_RX_BIAS_HPH_RDAC_LDO, 0x88 }, 379 + { WCD939X_RX_BIAS_HPH_CNP1, 0x82 }, 380 + { WCD939X_RX_BIAS_HPH_LOWPOWER, 0x82 }, 381 + { WCD939X_RX_BIAS_AUX_DAC, 0xa0 }, 382 + { WCD939X_RX_BIAS_AUX_AMP, 0xaa }, 383 + { WCD939X_RX_BIAS_VNEGDAC_BLEEDER, 0x50 }, 384 + { WCD939X_RX_BIAS_MISC, 0x00 }, 385 + { WCD939X_RX_BIAS_BUCK_RST, 0x08 }, 386 + { WCD939X_RX_BIAS_BUCK_VREF_ERRAMP, 0x44 }, 387 + { WCD939X_RX_BIAS_FLYB_ERRAMP, 0x40 }, 388 + { WCD939X_RX_BIAS_FLYB_BUFF, 0xaa }, 389 + { WCD939X_RX_BIAS_FLYB_MID_RST, 0x14 }, 390 + { WCD939X_HPH_CNP_EN, 0x80 }, 391 + { WCD939X_HPH_CNP_WG_CTL, 0x9a }, 392 + { WCD939X_HPH_CNP_WG_TIME, 0x14 }, 393 + { WCD939X_HPH_OCP_CTL, 0x28 }, 394 + { WCD939X_HPH_AUTO_CHOP, 0x56 }, 395 + { WCD939X_HPH_CHOP_CTL, 0x83 }, 396 + { WCD939X_HPH_PA_CTL1, 0x46 }, 397 + { WCD939X_HPH_PA_CTL2, 0x50 }, 398 + { WCD939X_HPH_L_EN, 0x80 }, 399 + { WCD939X_HPH_L_TEST, 0xe0 }, 400 + { WCD939X_HPH_L_ATEST, 0x50 }, 401 + { WCD939X_HPH_R_EN, 0x80 }, 402 + { WCD939X_HPH_R_TEST, 0xe0 }, 403 + { WCD939X_HPH_R_ATEST, 0x50 }, 404 + { WCD939X_HPH_RDAC_CLK_CTL1, 0x80 }, 405 + { WCD939X_HPH_RDAC_CLK_CTL2, 0x0b }, 406 + { WCD939X_HPH_RDAC_LDO_CTL, 0x33 }, 407 + { WCD939X_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00 }, 408 + { WCD939X_HPH_REFBUFF_UHQA_CTL, 0x00 }, 409 + { WCD939X_HPH_REFBUFF_LP_CTL, 0x8e }, 410 + { WCD939X_HPH_L_DAC_CTL, 0x20 }, 411 + { WCD939X_HPH_R_DAC_CTL, 0x20 }, 412 + { WCD939X_HPH_SURGE_COMP_SEL, 0x55 }, 413 + { WCD939X_HPH_SURGE_EN, 0x19 }, 414 + { WCD939X_HPH_SURGE_MISC1, 0xa0 }, 415 + { WCD939X_EAR_EN, 0x22 }, 416 + { WCD939X_EAR_PA_CON, 0x44 }, 417 + { WCD939X_EAR_SP_CON, 0xdb }, 418 + { WCD939X_EAR_DAC_CON, 0x80 }, 419 + { WCD939X_EAR_CNP_FSM_CON, 0xb2 }, 420 + { WCD939X_EAR_TEST_CTL, 0x00 }, 421 + { WCD939X_FLYBACK_NEW_CTRL_2, 0x00 }, 422 + { WCD939X_FLYBACK_NEW_CTRL_3, 0x00 }, 423 + { WCD939X_FLYBACK_NEW_CTRL_4, 0x44 }, 424 + { WCD939X_ANA_NEW_PAGE, 0x00 }, 425 + { WCD939X_HPH_NEW_ANA_HPH2, 0x00 }, 426 + { WCD939X_HPH_NEW_ANA_HPH3, 0x00 }, 427 + { WCD939X_SLEEP_CTL, 0x18 }, 428 + { WCD939X_SLEEP_WATCHDOG_CTL, 0x00 }, 429 + { WCD939X_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00 }, 430 + { WCD939X_MBHC_NEW_CTL_1, 0x02 }, 431 + { WCD939X_MBHC_NEW_CTL_2, 0x05 }, 432 + { WCD939X_MBHC_NEW_PLUG_DETECT_CTL, 0xe9 }, 433 + { WCD939X_MBHC_NEW_ZDET_ANA_CTL, 0x0f }, 434 + { WCD939X_MBHC_NEW_ZDET_RAMP_CTL, 0x00 }, 435 + { WCD939X_TX_NEW_CH12_MUX, 0x11 }, 436 + { WCD939X_TX_NEW_CH34_MUX, 0x23 }, 437 + { WCD939X_DIE_CRACK_DET_EN, 0x00 }, 438 + { WCD939X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x00 }, 439 + { WCD939X_HPH_NEW_INT_PA_GAIN_CTL_L, 0x00 }, 440 + { WCD939X_HPH_NEW_INT_RDAC_VREF_CTL, 0x08 }, 441 + { WCD939X_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00 }, 442 + { WCD939X_HPH_NEW_INT_PA_GAIN_CTL_R, 0x00 }, 443 + { WCD939X_HPH_NEW_INT_PA_MISC1, 0x32 }, 444 + { WCD939X_HPH_NEW_INT_PA_MISC2, 0x00 }, 445 + { WCD939X_HPH_NEW_INT_PA_RDAC_MISC, 0x00 }, 446 + { WCD939X_HPH_NEW_INT_TIMER1, 0xfe }, 447 + { WCD939X_HPH_NEW_INT_TIMER2, 0x02 }, 448 + { WCD939X_HPH_NEW_INT_TIMER3, 0x4e }, 449 + { WCD939X_HPH_NEW_INT_TIMER4, 0x54 }, 450 + { WCD939X_HPH_NEW_INT_PA_RDAC_MISC2, 0x0b }, 451 + { WCD939X_HPH_NEW_INT_PA_RDAC_MISC3, 0x00 }, 452 + { WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0xa0 }, 453 + { WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0xa0 }, 454 + { WCD939X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x64 }, 455 + { WCD939X_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01 }, 456 + { WCD939X_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11 }, 457 + { WCD939X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL, 0x57 }, 458 + { WCD939X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x01 }, 459 + { WCD939X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x00 }, 460 + { WCD939X_MBHC_NEW_INT_ZDET_CLK_AND_MOISTURE_CTL_NEW, 0x47 }, 461 + { WCD939X_EAR_INT_NEW_CHOPPER_CON, 0xa8 }, 462 + { WCD939X_EAR_INT_NEW_CNP_VCM_CON1, 0x42 }, 463 + { WCD939X_EAR_INT_NEW_CNP_VCM_CON2, 0x22 }, 464 + { WCD939X_EAR_INT_NEW_DYNAMIC_BIAS, 0x00 }, 465 + { WCD939X_SLEEP_INT_WATCHDOG_CTL_1, 0x0a }, 466 + { WCD939X_SLEEP_INT_WATCHDOG_CTL_2, 0x0a }, 467 + { WCD939X_DIE_CRACK_INT_DET_INT1, 0x02 }, 468 + { WCD939X_DIE_CRACK_INT_DET_INT2, 0x60 }, 469 + { WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_L2, 0xff }, 470 + { WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_L1, 0x7f }, 471 + { WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_L0, 0x3f }, 472 + { WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_ULP1P2M, 0x1f }, 473 + { WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_ULP0P6M, 0x0f }, 474 + { WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG1_L2L1, 0xd7 }, 475 + { WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG1_L0, 0xc8 }, 476 + { WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG1_ULP, 0xc6 }, 477 + { WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_L2L1, 0x95 }, 478 + { WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_L0, 0x6a }, 479 + { WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_ULP, 0x05 }, 480 + { WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2CASC_L2L1L0, 0xa5 }, 481 + { WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2CASC_ULP, 0x13 }, 482 + { WCD939X_TX_COM_NEW_INT_ADC_SCBIAS_L2L1, 0x88 }, 483 + { WCD939X_TX_COM_NEW_INT_ADC_SCBIAS_L0ULP, 0x42 }, 484 + { WCD939X_TX_COM_NEW_INT_ADC_INT_L2, 0xff }, 485 + { WCD939X_TX_COM_NEW_INT_ADC_INT_L1, 0x64 }, 486 + { WCD939X_TX_COM_NEW_INT_ADC_INT_L0, 0x64 }, 487 + { WCD939X_TX_COM_NEW_INT_ADC_INT_ULP, 0x77 }, 488 + { WCD939X_DIGITAL_PAGE, 0x00 }, 489 + { WCD939X_DIGITAL_SWR_TX_CLK_RATE, 0x00 }, 490 + { WCD939X_DIGITAL_CDC_RST_CTL, 0x03 }, 491 + { WCD939X_DIGITAL_TOP_CLK_CFG, 0x00 }, 492 + { WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 0x00 }, 493 + { WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 0xf0 }, 494 + { WCD939X_DIGITAL_SWR_RST_EN, 0x00 }, 495 + { WCD939X_DIGITAL_CDC_PATH_MODE, 0x55 }, 496 + { WCD939X_DIGITAL_CDC_RX_RST, 0x00 }, 497 + { WCD939X_DIGITAL_CDC_RX0_CTL, 0xfc }, 498 + { WCD939X_DIGITAL_CDC_RX1_CTL, 0xfc }, 499 + { WCD939X_DIGITAL_CDC_RX2_CTL, 0xfc }, 500 + { WCD939X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0x00 }, 501 + { WCD939X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0x00 }, 502 + { WCD939X_DIGITAL_CDC_COMP_CTL_0, 0x00 }, 503 + { WCD939X_DIGITAL_CDC_ANA_TX_CLK_CTL, 0x1e }, 504 + { WCD939X_DIGITAL_CDC_HPH_DSM_A1_0, 0x00 }, 505 + { WCD939X_DIGITAL_CDC_HPH_DSM_A1_1, 0x01 }, 506 + { WCD939X_DIGITAL_CDC_HPH_DSM_A2_0, 0x63 }, 507 + { WCD939X_DIGITAL_CDC_HPH_DSM_A2_1, 0x04 }, 508 + { WCD939X_DIGITAL_CDC_HPH_DSM_A3_0, 0xac }, 509 + { WCD939X_DIGITAL_CDC_HPH_DSM_A3_1, 0x04 }, 510 + { WCD939X_DIGITAL_CDC_HPH_DSM_A4_0, 0x1a }, 511 + { WCD939X_DIGITAL_CDC_HPH_DSM_A4_1, 0x03 }, 512 + { WCD939X_DIGITAL_CDC_HPH_DSM_A5_0, 0xbc }, 513 + { WCD939X_DIGITAL_CDC_HPH_DSM_A5_1, 0x02 }, 514 + { WCD939X_DIGITAL_CDC_HPH_DSM_A6_0, 0xc7 }, 515 + { WCD939X_DIGITAL_CDC_HPH_DSM_A7_0, 0xf8 }, 516 + { WCD939X_DIGITAL_CDC_HPH_DSM_C_0, 0x47 }, 517 + { WCD939X_DIGITAL_CDC_HPH_DSM_C_1, 0x43 }, 518 + { WCD939X_DIGITAL_CDC_HPH_DSM_C_2, 0xb1 }, 519 + { WCD939X_DIGITAL_CDC_HPH_DSM_C_3, 0x17 }, 520 + { WCD939X_DIGITAL_CDC_HPH_DSM_R1, 0x4d }, 521 + { WCD939X_DIGITAL_CDC_HPH_DSM_R2, 0x29 }, 522 + { WCD939X_DIGITAL_CDC_HPH_DSM_R3, 0x34 }, 523 + { WCD939X_DIGITAL_CDC_HPH_DSM_R4, 0x59 }, 524 + { WCD939X_DIGITAL_CDC_HPH_DSM_R5, 0x66 }, 525 + { WCD939X_DIGITAL_CDC_HPH_DSM_R6, 0x87 }, 526 + { WCD939X_DIGITAL_CDC_HPH_DSM_R7, 0x64 }, 527 + { WCD939X_DIGITAL_CDC_EAR_DSM_A1_0, 0x00 }, 528 + { WCD939X_DIGITAL_CDC_EAR_DSM_A1_1, 0x01 }, 529 + { WCD939X_DIGITAL_CDC_EAR_DSM_A2_0, 0x96 }, 530 + { WCD939X_DIGITAL_CDC_EAR_DSM_A2_1, 0x09 }, 531 + { WCD939X_DIGITAL_CDC_EAR_DSM_A3_0, 0xab }, 532 + { WCD939X_DIGITAL_CDC_EAR_DSM_A3_1, 0x05 }, 533 + { WCD939X_DIGITAL_CDC_EAR_DSM_A4_0, 0x1c }, 534 + { WCD939X_DIGITAL_CDC_EAR_DSM_A4_1, 0x02 }, 535 + { WCD939X_DIGITAL_CDC_EAR_DSM_A5_0, 0x17 }, 536 + { WCD939X_DIGITAL_CDC_EAR_DSM_A5_1, 0x02 }, 537 + { WCD939X_DIGITAL_CDC_EAR_DSM_A6_0, 0xaa }, 538 + { WCD939X_DIGITAL_CDC_EAR_DSM_A7_0, 0xe3 }, 539 + { WCD939X_DIGITAL_CDC_EAR_DSM_C_0, 0x69 }, 540 + { WCD939X_DIGITAL_CDC_EAR_DSM_C_1, 0x54 }, 541 + { WCD939X_DIGITAL_CDC_EAR_DSM_C_2, 0x02 }, 542 + { WCD939X_DIGITAL_CDC_EAR_DSM_C_3, 0x15 }, 543 + { WCD939X_DIGITAL_CDC_EAR_DSM_R1, 0xa4 }, 544 + { WCD939X_DIGITAL_CDC_EAR_DSM_R2, 0xb5 }, 545 + { WCD939X_DIGITAL_CDC_EAR_DSM_R3, 0x86 }, 546 + { WCD939X_DIGITAL_CDC_EAR_DSM_R4, 0x85 }, 547 + { WCD939X_DIGITAL_CDC_EAR_DSM_R5, 0xaa }, 548 + { WCD939X_DIGITAL_CDC_EAR_DSM_R6, 0xe2 }, 549 + { WCD939X_DIGITAL_CDC_EAR_DSM_R7, 0x62 }, 550 + { WCD939X_DIGITAL_CDC_HPH_GAIN_RX_0, 0x55 }, 551 + { WCD939X_DIGITAL_CDC_HPH_GAIN_RX_1, 0xa9 }, 552 + { WCD939X_DIGITAL_CDC_HPH_GAIN_DSD_0, 0x3d }, 553 + { WCD939X_DIGITAL_CDC_HPH_GAIN_DSD_1, 0x2e }, 554 + { WCD939X_DIGITAL_CDC_HPH_GAIN_DSD_2, 0x01 }, 555 + { WCD939X_DIGITAL_CDC_EAR_GAIN_DSD_0, 0x00 }, 556 + { WCD939X_DIGITAL_CDC_EAR_GAIN_DSD_1, 0xfc }, 557 + { WCD939X_DIGITAL_CDC_EAR_GAIN_DSD_2, 0x01 }, 558 + { WCD939X_DIGITAL_CDC_HPH_GAIN_CTL, 0x00 }, 559 + { WCD939X_DIGITAL_CDC_EAR_GAIN_CTL, 0x00 }, 560 + { WCD939X_DIGITAL_CDC_EAR_PATH_CTL, 0x00 }, 561 + { WCD939X_DIGITAL_CDC_SWR_CLH, 0x00 }, 562 + { WCD939X_DIGITAL_SWR_CLH_BYP, 0x00 }, 563 + { WCD939X_DIGITAL_CDC_TX0_CTL, 0x68 }, 564 + { WCD939X_DIGITAL_CDC_TX1_CTL, 0x68 }, 565 + { WCD939X_DIGITAL_CDC_TX2_CTL, 0x68 }, 566 + { WCD939X_DIGITAL_CDC_TX_RST, 0x00 }, 567 + { WCD939X_DIGITAL_CDC_REQ_CTL, 0x01 }, 568 + { WCD939X_DIGITAL_CDC_RST, 0x00 }, 569 + { WCD939X_DIGITAL_CDC_AMIC_CTL, 0x0f }, 570 + { WCD939X_DIGITAL_CDC_DMIC_CTL, 0x04 }, 571 + { WCD939X_DIGITAL_CDC_DMIC1_CTL, 0x01 }, 572 + { WCD939X_DIGITAL_CDC_DMIC2_CTL, 0x01 }, 573 + { WCD939X_DIGITAL_CDC_DMIC3_CTL, 0x01 }, 574 + { WCD939X_DIGITAL_CDC_DMIC4_CTL, 0x01 }, 575 + { WCD939X_DIGITAL_EFUSE_PRG_CTL, 0x00 }, 576 + { WCD939X_DIGITAL_EFUSE_CTL, 0x2b }, 577 + { WCD939X_DIGITAL_CDC_DMIC_RATE_1_2, 0x11 }, 578 + { WCD939X_DIGITAL_CDC_DMIC_RATE_3_4, 0x11 }, 579 + { WCD939X_DIGITAL_PDM_WD_CTL0, 0x00 }, 580 + { WCD939X_DIGITAL_PDM_WD_CTL1, 0x00 }, 581 + { WCD939X_DIGITAL_PDM_WD_CTL2, 0x00 }, 582 + { WCD939X_DIGITAL_INTR_MODE, 0x00 }, 583 + { WCD939X_DIGITAL_INTR_MASK_0, 0xff }, 584 + { WCD939X_DIGITAL_INTR_MASK_1, 0xe7 }, 585 + { WCD939X_DIGITAL_INTR_MASK_2, 0x0e }, 586 + { WCD939X_DIGITAL_INTR_CLEAR_0, 0x00 }, 587 + { WCD939X_DIGITAL_INTR_CLEAR_1, 0x00 }, 588 + { WCD939X_DIGITAL_INTR_CLEAR_2, 0x00 }, 589 + { WCD939X_DIGITAL_INTR_LEVEL_0, 0x00 }, 590 + { WCD939X_DIGITAL_INTR_LEVEL_1, 0x00 }, 591 + { WCD939X_DIGITAL_INTR_LEVEL_2, 0x00 }, 592 + { WCD939X_DIGITAL_INTR_SET_0, 0x00 }, 593 + { WCD939X_DIGITAL_INTR_SET_1, 0x00 }, 594 + { WCD939X_DIGITAL_INTR_SET_2, 0x00 }, 595 + { WCD939X_DIGITAL_INTR_TEST_0, 0x00 }, 596 + { WCD939X_DIGITAL_INTR_TEST_1, 0x00 }, 597 + { WCD939X_DIGITAL_INTR_TEST_2, 0x00 }, 598 + { WCD939X_DIGITAL_TX_MODE_DBG_EN, 0x00 }, 599 + { WCD939X_DIGITAL_TX_MODE_DBG_0_1, 0x00 }, 600 + { WCD939X_DIGITAL_TX_MODE_DBG_2_3, 0x00 }, 601 + { WCD939X_DIGITAL_LB_IN_SEL_CTL, 0x00 }, 602 + { WCD939X_DIGITAL_LOOP_BACK_MODE, 0x00 }, 603 + { WCD939X_DIGITAL_SWR_DAC_TEST, 0x00 }, 604 + { WCD939X_DIGITAL_SWR_HM_TEST_RX_0, 0x40 }, 605 + { WCD939X_DIGITAL_SWR_HM_TEST_TX_0, 0x40 }, 606 + { WCD939X_DIGITAL_SWR_HM_TEST_RX_1, 0x00 }, 607 + { WCD939X_DIGITAL_SWR_HM_TEST_TX_1, 0x00 }, 608 + { WCD939X_DIGITAL_SWR_HM_TEST_TX_2, 0x00 }, 609 + { WCD939X_DIGITAL_PAD_CTL_SWR_0, 0x8f }, 610 + { WCD939X_DIGITAL_PAD_CTL_SWR_1, 0x06 }, 611 + { WCD939X_DIGITAL_I2C_CTL, 0x00 }, 612 + { WCD939X_DIGITAL_CDC_TX_TANGGU_SW_MODE, 0x00 }, 613 + { WCD939X_DIGITAL_EFUSE_TEST_CTL_0, 0x00 }, 614 + { WCD939X_DIGITAL_EFUSE_TEST_CTL_1, 0x00 }, 615 + { WCD939X_DIGITAL_PAD_CTL_PDM_RX0, 0xf1 }, 616 + { WCD939X_DIGITAL_PAD_CTL_PDM_RX1, 0xf1 }, 617 + { WCD939X_DIGITAL_PAD_CTL_PDM_TX0, 0xf1 }, 618 + { WCD939X_DIGITAL_PAD_CTL_PDM_TX1, 0xf1 }, 619 + { WCD939X_DIGITAL_PAD_CTL_PDM_TX2, 0xf1 }, 620 + { WCD939X_DIGITAL_PAD_INP_DIS_0, 0x00 }, 621 + { WCD939X_DIGITAL_PAD_INP_DIS_1, 0x00 }, 622 + { WCD939X_DIGITAL_DRIVE_STRENGTH_0, 0x00 }, 623 + { WCD939X_DIGITAL_DRIVE_STRENGTH_1, 0x00 }, 624 + { WCD939X_DIGITAL_DRIVE_STRENGTH_2, 0x00 }, 625 + { WCD939X_DIGITAL_RX_DATA_EDGE_CTL, 0x1f }, 626 + { WCD939X_DIGITAL_TX_DATA_EDGE_CTL, 0x80 }, 627 + { WCD939X_DIGITAL_GPIO_MODE, 0x00 }, 628 + { WCD939X_DIGITAL_PIN_CTL_OE, 0x00 }, 629 + { WCD939X_DIGITAL_PIN_CTL_DATA_0, 0x00 }, 630 + { WCD939X_DIGITAL_PIN_CTL_DATA_1, 0x00 }, 631 + { WCD939X_DIGITAL_DIG_DEBUG_CTL, 0x00 }, 632 + { WCD939X_DIGITAL_DIG_DEBUG_EN, 0x00 }, 633 + { WCD939X_DIGITAL_ANA_CSR_DBG_ADD, 0x00 }, 634 + { WCD939X_DIGITAL_ANA_CSR_DBG_CTL, 0x48 }, 635 + { WCD939X_DIGITAL_SSP_DBG, 0x00 }, 636 + { WCD939X_DIGITAL_SPARE_0, 0x00 }, 637 + { WCD939X_DIGITAL_SPARE_1, 0x00 }, 638 + { WCD939X_DIGITAL_SPARE_2, 0x00 }, 639 + { WCD939X_DIGITAL_TX_REQ_FB_CTL_0, 0x88 }, 640 + { WCD939X_DIGITAL_TX_REQ_FB_CTL_1, 0x88 }, 641 + { WCD939X_DIGITAL_TX_REQ_FB_CTL_2, 0x88 }, 642 + { WCD939X_DIGITAL_TX_REQ_FB_CTL_3, 0x88 }, 643 + { WCD939X_DIGITAL_TX_REQ_FB_CTL_4, 0x88 }, 644 + { WCD939X_DIGITAL_DEM_BYPASS_DATA0, 0x55 }, 645 + { WCD939X_DIGITAL_DEM_BYPASS_DATA1, 0x55 }, 646 + { WCD939X_DIGITAL_DEM_BYPASS_DATA2, 0x55 }, 647 + { WCD939X_DIGITAL_DEM_BYPASS_DATA3, 0x01 }, 648 + { WCD939X_DIGITAL_DEM_SECOND_ORDER, 0x03 }, 649 + { WCD939X_DIGITAL_DSM_CTRL, 0x00 }, 650 + { WCD939X_DIGITAL_DSM_0_STATIC_DATA_0, 0x00 }, 651 + { WCD939X_DIGITAL_DSM_0_STATIC_DATA_1, 0x00 }, 652 + { WCD939X_DIGITAL_DSM_0_STATIC_DATA_2, 0x00 }, 653 + { WCD939X_DIGITAL_DSM_0_STATIC_DATA_3, 0x00 }, 654 + { WCD939X_DIGITAL_DSM_1_STATIC_DATA_0, 0x00 }, 655 + { WCD939X_DIGITAL_DSM_1_STATIC_DATA_1, 0x00 }, 656 + { WCD939X_DIGITAL_DSM_1_STATIC_DATA_2, 0x00 }, 657 + { WCD939X_DIGITAL_DSM_1_STATIC_DATA_3, 0x00 }, 658 + { WCD939X_RX_TOP_PAGE, 0x00 }, 659 + { WCD939X_RX_TOP_TOP_CFG0, 0x00 }, 660 + { WCD939X_RX_TOP_HPHL_COMP_WR_LSB, 0x00 }, 661 + { WCD939X_RX_TOP_HPHL_COMP_WR_MSB, 0x00 }, 662 + { WCD939X_RX_TOP_HPHL_COMP_LUT, 0x00 }, 663 + { WCD939X_RX_TOP_HPHR_COMP_WR_LSB, 0x00 }, 664 + { WCD939X_RX_TOP_HPHR_COMP_WR_MSB, 0x00 }, 665 + { WCD939X_RX_TOP_HPHR_COMP_LUT, 0x00 }, 666 + { WCD939X_RX_TOP_DSD0_DEBUG_CFG1, 0x05 }, 667 + { WCD939X_RX_TOP_DSD0_DEBUG_CFG2, 0x08 }, 668 + { WCD939X_RX_TOP_DSD0_DEBUG_CFG3, 0x00 }, 669 + { WCD939X_RX_TOP_DSD0_DEBUG_CFG4, 0x00 }, 670 + { WCD939X_RX_TOP_DSD1_DEBUG_CFG1, 0x03 }, 671 + { WCD939X_RX_TOP_DSD1_DEBUG_CFG2, 0x08 }, 672 + { WCD939X_RX_TOP_DSD1_DEBUG_CFG3, 0x00 }, 673 + { WCD939X_RX_TOP_DSD1_DEBUG_CFG4, 0x00 }, 674 + { WCD939X_RX_TOP_HPHL_PATH_CFG0, 0x00 }, 675 + { WCD939X_RX_TOP_HPHL_PATH_CFG1, 0x00 }, 676 + { WCD939X_RX_TOP_HPHR_PATH_CFG0, 0x00 }, 677 + { WCD939X_RX_TOP_HPHR_PATH_CFG1, 0x00 }, 678 + { WCD939X_RX_TOP_PATH_CFG2, 0x00 }, 679 + { WCD939X_RX_TOP_HPHL_PATH_SEC0, 0x00 }, 680 + { WCD939X_RX_TOP_HPHL_PATH_SEC1, 0x00 }, 681 + { WCD939X_RX_TOP_HPHL_PATH_SEC2, 0x00 }, 682 + { WCD939X_RX_TOP_HPHL_PATH_SEC3, 0x00 }, 683 + { WCD939X_RX_TOP_HPHR_PATH_SEC0, 0x00 }, 684 + { WCD939X_RX_TOP_HPHR_PATH_SEC1, 0x00 }, 685 + { WCD939X_RX_TOP_HPHR_PATH_SEC2, 0x00 }, 686 + { WCD939X_RX_TOP_HPHR_PATH_SEC3, 0x00 }, 687 + { WCD939X_RX_TOP_PATH_SEC4, 0x00 }, 688 + { WCD939X_RX_TOP_PATH_SEC5, 0x00 }, 689 + { WCD939X_COMPANDER_HPHL_CTL0, 0x60 }, 690 + { WCD939X_COMPANDER_HPHL_CTL1, 0xdb }, 691 + { WCD939X_COMPANDER_HPHL_CTL2, 0xff }, 692 + { WCD939X_COMPANDER_HPHL_CTL3, 0x35 }, 693 + { WCD939X_COMPANDER_HPHL_CTL4, 0xff }, 694 + { WCD939X_COMPANDER_HPHL_CTL5, 0x00 }, 695 + { WCD939X_COMPANDER_HPHL_CTL7, 0x08 }, 696 + { WCD939X_COMPANDER_HPHL_CTL8, 0x00 }, 697 + { WCD939X_COMPANDER_HPHL_CTL9, 0x00 }, 698 + { WCD939X_COMPANDER_HPHL_CTL10, 0x06 }, 699 + { WCD939X_COMPANDER_HPHL_CTL11, 0x12 }, 700 + { WCD939X_COMPANDER_HPHL_CTL12, 0x1e }, 701 + { WCD939X_COMPANDER_HPHL_CTL13, 0x2a }, 702 + { WCD939X_COMPANDER_HPHL_CTL14, 0x36 }, 703 + { WCD939X_COMPANDER_HPHL_CTL15, 0x3c }, 704 + { WCD939X_COMPANDER_HPHL_CTL16, 0xc4 }, 705 + { WCD939X_COMPANDER_HPHL_CTL17, 0x00 }, 706 + { WCD939X_COMPANDER_HPHL_CTL18, 0x0c }, 707 + { WCD939X_COMPANDER_HPHL_CTL19, 0x16 }, 708 + { WCD939X_R_CTL0, 0x60 }, 709 + { WCD939X_R_CTL1, 0xdb }, 710 + { WCD939X_R_CTL2, 0xff }, 711 + { WCD939X_R_CTL3, 0x35 }, 712 + { WCD939X_R_CTL4, 0xff }, 713 + { WCD939X_R_CTL5, 0x00 }, 714 + { WCD939X_R_CTL7, 0x08 }, 715 + { WCD939X_R_CTL8, 0x00 }, 716 + { WCD939X_R_CTL9, 0x00 }, 717 + { WCD939X_R_CTL10, 0x06 }, 718 + { WCD939X_R_CTL11, 0x12 }, 719 + { WCD939X_R_CTL12, 0x1e }, 720 + { WCD939X_R_CTL13, 0x2a }, 721 + { WCD939X_R_CTL14, 0x36 }, 722 + { WCD939X_R_CTL15, 0x3c }, 723 + { WCD939X_R_CTL16, 0xc4 }, 724 + { WCD939X_R_CTL17, 0x00 }, 725 + { WCD939X_R_CTL18, 0x0c }, 726 + { WCD939X_R_CTL19, 0x16 }, 727 + { WCD939X_E_PATH_CTL, 0x00 }, 728 + { WCD939X_E_CFG0, 0x07 }, 729 + { WCD939X_E_CFG1, 0x3c }, 730 + { WCD939X_E_CFG2, 0x00 }, 731 + { WCD939X_E_CFG3, 0x00 }, 732 + { WCD939X_DSD_HPHL_PATH_CTL, 0x00 }, 733 + { WCD939X_DSD_HPHL_CFG0, 0x00 }, 734 + { WCD939X_DSD_HPHL_CFG1, 0x00 }, 735 + { WCD939X_DSD_HPHL_CFG2, 0x22 }, 736 + { WCD939X_DSD_HPHL_CFG3, 0x00 }, 737 + { WCD939X_DSD_HPHL_CFG4, 0x1a }, 738 + { WCD939X_DSD_HPHL_CFG5, 0x00 }, 739 + { WCD939X_DSD_HPHR_PATH_CTL, 0x00 }, 740 + { WCD939X_DSD_HPHR_CFG0, 0x00 }, 741 + { WCD939X_DSD_HPHR_CFG1, 0x00 }, 742 + { WCD939X_DSD_HPHR_CFG2, 0x22 }, 743 + { WCD939X_DSD_HPHR_CFG3, 0x00 }, 744 + { WCD939X_DSD_HPHR_CFG4, 0x1a }, 745 + { WCD939X_DSD_HPHR_CFG5, 0x00 }, 746 + }; 747 + 748 + static bool wcd939x_rdwr_register(struct device *dev, unsigned int reg) 749 + { 750 + switch (reg) { 751 + case WCD939X_ANA_PAGE: 752 + case WCD939X_ANA_BIAS: 753 + case WCD939X_ANA_RX_SUPPLIES: 754 + case WCD939X_ANA_HPH: 755 + case WCD939X_ANA_EAR: 756 + case WCD939X_ANA_EAR_COMPANDER_CTL: 757 + case WCD939X_ANA_TX_CH1: 758 + case WCD939X_ANA_TX_CH2: 759 + case WCD939X_ANA_TX_CH3: 760 + case WCD939X_ANA_TX_CH4: 761 + case WCD939X_ANA_MICB1_MICB2_DSP_EN_LOGIC: 762 + case WCD939X_ANA_MICB3_DSP_EN_LOGIC: 763 + case WCD939X_ANA_MBHC_MECH: 764 + case WCD939X_ANA_MBHC_ELECT: 765 + case WCD939X_ANA_MBHC_ZDET: 766 + case WCD939X_ANA_MBHC_BTN0: 767 + case WCD939X_ANA_MBHC_BTN1: 768 + case WCD939X_ANA_MBHC_BTN2: 769 + case WCD939X_ANA_MBHC_BTN3: 770 + case WCD939X_ANA_MBHC_BTN4: 771 + case WCD939X_ANA_MBHC_BTN5: 772 + case WCD939X_ANA_MBHC_BTN6: 773 + case WCD939X_ANA_MBHC_BTN7: 774 + case WCD939X_ANA_MICB1: 775 + case WCD939X_ANA_MICB2: 776 + case WCD939X_ANA_MICB2_RAMP: 777 + case WCD939X_ANA_MICB3: 778 + case WCD939X_ANA_MICB4: 779 + case WCD939X_BIAS_CTL: 780 + case WCD939X_BIAS_VBG_FINE_ADJ: 781 + case WCD939X_LDOL_VDDCX_ADJUST: 782 + case WCD939X_LDOL_DISABLE_LDOL: 783 + case WCD939X_MBHC_CTL_CLK: 784 + case WCD939X_MBHC_CTL_ANA: 785 + case WCD939X_MBHC_ZDET_VNEG_CTL: 786 + case WCD939X_MBHC_ZDET_BIAS_CTL: 787 + case WCD939X_MBHC_CTL_BCS: 788 + case WCD939X_MBHC_TEST_CTL: 789 + case WCD939X_LDOH_MODE: 790 + case WCD939X_LDOH_BIAS: 791 + case WCD939X_LDOH_STB_LOADS: 792 + case WCD939X_LDOH_SLOWRAMP: 793 + case WCD939X_MICB1_TEST_CTL_1: 794 + case WCD939X_MICB1_TEST_CTL_2: 795 + case WCD939X_MICB1_TEST_CTL_3: 796 + case WCD939X_MICB2_TEST_CTL_1: 797 + case WCD939X_MICB2_TEST_CTL_2: 798 + case WCD939X_MICB2_TEST_CTL_3: 799 + case WCD939X_MICB3_TEST_CTL_1: 800 + case WCD939X_MICB3_TEST_CTL_2: 801 + case WCD939X_MICB3_TEST_CTL_3: 802 + case WCD939X_MICB4_TEST_CTL_1: 803 + case WCD939X_MICB4_TEST_CTL_2: 804 + case WCD939X_MICB4_TEST_CTL_3: 805 + case WCD939X_TX_COM_ADC_VCM: 806 + case WCD939X_TX_COM_BIAS_ATEST: 807 + case WCD939X_TX_COM_SPARE1: 808 + case WCD939X_TX_COM_SPARE2: 809 + case WCD939X_TX_COM_TXFE_DIV_CTL: 810 + case WCD939X_TX_COM_TXFE_DIV_START: 811 + case WCD939X_TX_COM_SPARE3: 812 + case WCD939X_TX_COM_SPARE4: 813 + case WCD939X_TX_1_2_TEST_EN: 814 + case WCD939X_TX_1_2_ADC_IB: 815 + case WCD939X_TX_1_2_ATEST_REFCTL: 816 + case WCD939X_TX_1_2_TEST_CTL: 817 + case WCD939X_TX_1_2_TEST_BLK_EN1: 818 + case WCD939X_TX_1_2_TXFE1_CLKDIV: 819 + case WCD939X_TX_3_4_TEST_EN: 820 + case WCD939X_TX_3_4_ADC_IB: 821 + case WCD939X_TX_3_4_ATEST_REFCTL: 822 + case WCD939X_TX_3_4_TEST_CTL: 823 + case WCD939X_TX_3_4_TEST_BLK_EN3: 824 + case WCD939X_TX_3_4_TXFE3_CLKDIV: 825 + case WCD939X_TX_3_4_TEST_BLK_EN2: 826 + case WCD939X_TX_3_4_TXFE2_CLKDIV: 827 + case WCD939X_TX_3_4_SPARE1: 828 + case WCD939X_TX_3_4_TEST_BLK_EN4: 829 + case WCD939X_TX_3_4_TXFE4_CLKDIV: 830 + case WCD939X_TX_3_4_SPARE2: 831 + case WCD939X_CLASSH_MODE_1: 832 + case WCD939X_CLASSH_MODE_2: 833 + case WCD939X_CLASSH_MODE_3: 834 + case WCD939X_CLASSH_CTRL_VCL_1: 835 + case WCD939X_CLASSH_CTRL_VCL_2: 836 + case WCD939X_CLASSH_CTRL_CCL_1: 837 + case WCD939X_CLASSH_CTRL_CCL_2: 838 + case WCD939X_CLASSH_CTRL_CCL_3: 839 + case WCD939X_CLASSH_CTRL_CCL_4: 840 + case WCD939X_CLASSH_CTRL_CCL_5: 841 + case WCD939X_CLASSH_BUCK_TMUX_A_D: 842 + case WCD939X_CLASSH_BUCK_SW_DRV_CNTL: 843 + case WCD939X_CLASSH_SPARE: 844 + case WCD939X_FLYBACK_EN: 845 + case WCD939X_FLYBACK_VNEG_CTRL_1: 846 + case WCD939X_FLYBACK_VNEG_CTRL_2: 847 + case WCD939X_FLYBACK_VNEG_CTRL_3: 848 + case WCD939X_FLYBACK_VNEG_CTRL_4: 849 + case WCD939X_FLYBACK_VNEG_CTRL_5: 850 + case WCD939X_FLYBACK_VNEG_CTRL_6: 851 + case WCD939X_FLYBACK_VNEG_CTRL_7: 852 + case WCD939X_FLYBACK_VNEG_CTRL_8: 853 + case WCD939X_FLYBACK_VNEG_CTRL_9: 854 + case WCD939X_FLYBACK_VNEGDAC_CTRL_1: 855 + case WCD939X_FLYBACK_VNEGDAC_CTRL_2: 856 + case WCD939X_FLYBACK_VNEGDAC_CTRL_3: 857 + case WCD939X_FLYBACK_CTRL_1: 858 + case WCD939X_FLYBACK_TEST_CTL: 859 + case WCD939X_RX_AUX_SW_CTL: 860 + case WCD939X_RX_PA_AUX_IN_CONN: 861 + case WCD939X_RX_TIMER_DIV: 862 + case WCD939X_RX_OCP_CTL: 863 + case WCD939X_RX_OCP_COUNT: 864 + case WCD939X_RX_BIAS_EAR_DAC: 865 + case WCD939X_RX_BIAS_EAR_AMP: 866 + case WCD939X_RX_BIAS_HPH_LDO: 867 + case WCD939X_RX_BIAS_HPH_PA: 868 + case WCD939X_RX_BIAS_HPH_RDACBUFF_CNP2: 869 + case WCD939X_RX_BIAS_HPH_RDAC_LDO: 870 + case WCD939X_RX_BIAS_HPH_CNP1: 871 + case WCD939X_RX_BIAS_HPH_LOWPOWER: 872 + case WCD939X_RX_BIAS_AUX_DAC: 873 + case WCD939X_RX_BIAS_AUX_AMP: 874 + case WCD939X_RX_BIAS_VNEGDAC_BLEEDER: 875 + case WCD939X_RX_BIAS_MISC: 876 + case WCD939X_RX_BIAS_BUCK_RST: 877 + case WCD939X_RX_BIAS_BUCK_VREF_ERRAMP: 878 + case WCD939X_RX_BIAS_FLYB_ERRAMP: 879 + case WCD939X_RX_BIAS_FLYB_BUFF: 880 + case WCD939X_RX_BIAS_FLYB_MID_RST: 881 + case WCD939X_HPH_CNP_EN: 882 + case WCD939X_HPH_CNP_WG_CTL: 883 + case WCD939X_HPH_CNP_WG_TIME: 884 + case WCD939X_HPH_OCP_CTL: 885 + case WCD939X_HPH_AUTO_CHOP: 886 + case WCD939X_HPH_CHOP_CTL: 887 + case WCD939X_HPH_PA_CTL1: 888 + case WCD939X_HPH_PA_CTL2: 889 + case WCD939X_HPH_L_EN: 890 + case WCD939X_HPH_L_TEST: 891 + case WCD939X_HPH_L_ATEST: 892 + case WCD939X_HPH_R_EN: 893 + case WCD939X_HPH_R_TEST: 894 + case WCD939X_HPH_R_ATEST: 895 + case WCD939X_HPH_RDAC_CLK_CTL1: 896 + case WCD939X_HPH_RDAC_CLK_CTL2: 897 + case WCD939X_HPH_RDAC_LDO_CTL: 898 + case WCD939X_HPH_RDAC_CHOP_CLK_LP_CTL: 899 + case WCD939X_HPH_REFBUFF_UHQA_CTL: 900 + case WCD939X_HPH_REFBUFF_LP_CTL: 901 + case WCD939X_HPH_L_DAC_CTL: 902 + case WCD939X_HPH_R_DAC_CTL: 903 + case WCD939X_HPH_SURGE_COMP_SEL: 904 + case WCD939X_HPH_SURGE_EN: 905 + case WCD939X_HPH_SURGE_MISC1: 906 + case WCD939X_EAR_EN: 907 + case WCD939X_EAR_PA_CON: 908 + case WCD939X_EAR_SP_CON: 909 + case WCD939X_EAR_DAC_CON: 910 + case WCD939X_EAR_CNP_FSM_CON: 911 + case WCD939X_EAR_TEST_CTL: 912 + case WCD939X_FLYBACK_NEW_CTRL_2: 913 + case WCD939X_FLYBACK_NEW_CTRL_3: 914 + case WCD939X_FLYBACK_NEW_CTRL_4: 915 + case WCD939X_ANA_NEW_PAGE: 916 + case WCD939X_HPH_NEW_ANA_HPH2: 917 + case WCD939X_HPH_NEW_ANA_HPH3: 918 + case WCD939X_SLEEP_CTL: 919 + case WCD939X_SLEEP_WATCHDOG_CTL: 920 + case WCD939X_MBHC_NEW_ELECT_REM_CLAMP_CTL: 921 + case WCD939X_MBHC_NEW_CTL_1: 922 + case WCD939X_MBHC_NEW_CTL_2: 923 + case WCD939X_MBHC_NEW_PLUG_DETECT_CTL: 924 + case WCD939X_MBHC_NEW_ZDET_ANA_CTL: 925 + case WCD939X_MBHC_NEW_ZDET_RAMP_CTL: 926 + case WCD939X_TX_NEW_CH12_MUX: 927 + case WCD939X_TX_NEW_CH34_MUX: 928 + case WCD939X_DIE_CRACK_DET_EN: 929 + case WCD939X_HPH_NEW_INT_RDAC_GAIN_CTL: 930 + case WCD939X_HPH_NEW_INT_PA_GAIN_CTL_L: 931 + case WCD939X_HPH_NEW_INT_RDAC_VREF_CTL: 932 + case WCD939X_HPH_NEW_INT_RDAC_OVERRIDE_CTL: 933 + case WCD939X_HPH_NEW_INT_PA_GAIN_CTL_R: 934 + case WCD939X_HPH_NEW_INT_PA_MISC1: 935 + case WCD939X_HPH_NEW_INT_PA_MISC2: 936 + case WCD939X_HPH_NEW_INT_PA_RDAC_MISC: 937 + case WCD939X_HPH_NEW_INT_TIMER1: 938 + case WCD939X_HPH_NEW_INT_TIMER2: 939 + case WCD939X_HPH_NEW_INT_TIMER3: 940 + case WCD939X_HPH_NEW_INT_TIMER4: 941 + case WCD939X_HPH_NEW_INT_PA_RDAC_MISC2: 942 + case WCD939X_HPH_NEW_INT_PA_RDAC_MISC3: 943 + case WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_L: 944 + case WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_R: 945 + case WCD939X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI: 946 + case WCD939X_RX_NEW_INT_HPH_RDAC_BIAS_ULP: 947 + case WCD939X_RX_NEW_INT_HPH_RDAC_LDO_LP: 948 + case WCD939X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL: 949 + case WCD939X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL: 950 + case WCD939X_MBHC_NEW_INT_MECH_DET_CURRENT: 951 + case WCD939X_MBHC_NEW_INT_ZDET_CLK_AND_MOISTURE_CTL_NEW: 952 + case WCD939X_EAR_INT_NEW_CHOPPER_CON: 953 + case WCD939X_EAR_INT_NEW_CNP_VCM_CON1: 954 + case WCD939X_EAR_INT_NEW_CNP_VCM_CON2: 955 + case WCD939X_EAR_INT_NEW_DYNAMIC_BIAS: 956 + case WCD939X_SLEEP_INT_WATCHDOG_CTL_1: 957 + case WCD939X_SLEEP_INT_WATCHDOG_CTL_2: 958 + case WCD939X_DIE_CRACK_INT_DET_INT1: 959 + case WCD939X_DIE_CRACK_INT_DET_INT2: 960 + case WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_L2: 961 + case WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_L1: 962 + case WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_L0: 963 + case WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_ULP1P2M: 964 + case WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_ULP0P6M: 965 + case WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG1_L2L1: 966 + case WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG1_L0: 967 + case WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG1_ULP: 968 + case WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_L2L1: 969 + case WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_L0: 970 + case WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_ULP: 971 + case WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2CASC_L2L1L0: 972 + case WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2CASC_ULP: 973 + case WCD939X_TX_COM_NEW_INT_ADC_SCBIAS_L2L1: 974 + case WCD939X_TX_COM_NEW_INT_ADC_SCBIAS_L0ULP: 975 + case WCD939X_TX_COM_NEW_INT_ADC_INT_L2: 976 + case WCD939X_TX_COM_NEW_INT_ADC_INT_L1: 977 + case WCD939X_TX_COM_NEW_INT_ADC_INT_L0: 978 + case WCD939X_TX_COM_NEW_INT_ADC_INT_ULP: 979 + case WCD939X_DIGITAL_PAGE: 980 + case WCD939X_DIGITAL_SWR_TX_CLK_RATE: 981 + case WCD939X_DIGITAL_CDC_RST_CTL: 982 + case WCD939X_DIGITAL_TOP_CLK_CFG: 983 + case WCD939X_DIGITAL_CDC_ANA_CLK_CTL: 984 + case WCD939X_DIGITAL_CDC_DIG_CLK_CTL: 985 + case WCD939X_DIGITAL_SWR_RST_EN: 986 + case WCD939X_DIGITAL_CDC_PATH_MODE: 987 + case WCD939X_DIGITAL_CDC_RX_RST: 988 + case WCD939X_DIGITAL_CDC_RX0_CTL: 989 + case WCD939X_DIGITAL_CDC_RX1_CTL: 990 + case WCD939X_DIGITAL_CDC_RX2_CTL: 991 + case WCD939X_DIGITAL_CDC_TX_ANA_MODE_0_1: 992 + case WCD939X_DIGITAL_CDC_TX_ANA_MODE_2_3: 993 + case WCD939X_DIGITAL_CDC_COMP_CTL_0: 994 + case WCD939X_DIGITAL_CDC_ANA_TX_CLK_CTL: 995 + case WCD939X_DIGITAL_CDC_HPH_DSM_A1_0: 996 + case WCD939X_DIGITAL_CDC_HPH_DSM_A1_1: 997 + case WCD939X_DIGITAL_CDC_HPH_DSM_A2_0: 998 + case WCD939X_DIGITAL_CDC_HPH_DSM_A2_1: 999 + case WCD939X_DIGITAL_CDC_HPH_DSM_A3_0: 1000 + case WCD939X_DIGITAL_CDC_HPH_DSM_A3_1: 1001 + case WCD939X_DIGITAL_CDC_HPH_DSM_A4_0: 1002 + case WCD939X_DIGITAL_CDC_HPH_DSM_A4_1: 1003 + case WCD939X_DIGITAL_CDC_HPH_DSM_A5_0: 1004 + case WCD939X_DIGITAL_CDC_HPH_DSM_A5_1: 1005 + case WCD939X_DIGITAL_CDC_HPH_DSM_A6_0: 1006 + case WCD939X_DIGITAL_CDC_HPH_DSM_A7_0: 1007 + case WCD939X_DIGITAL_CDC_HPH_DSM_C_0: 1008 + case WCD939X_DIGITAL_CDC_HPH_DSM_C_1: 1009 + case WCD939X_DIGITAL_CDC_HPH_DSM_C_2: 1010 + case WCD939X_DIGITAL_CDC_HPH_DSM_C_3: 1011 + case WCD939X_DIGITAL_CDC_HPH_DSM_R1: 1012 + case WCD939X_DIGITAL_CDC_HPH_DSM_R2: 1013 + case WCD939X_DIGITAL_CDC_HPH_DSM_R3: 1014 + case WCD939X_DIGITAL_CDC_HPH_DSM_R4: 1015 + case WCD939X_DIGITAL_CDC_HPH_DSM_R5: 1016 + case WCD939X_DIGITAL_CDC_HPH_DSM_R6: 1017 + case WCD939X_DIGITAL_CDC_HPH_DSM_R7: 1018 + case WCD939X_DIGITAL_CDC_EAR_DSM_A1_0: 1019 + case WCD939X_DIGITAL_CDC_EAR_DSM_A1_1: 1020 + case WCD939X_DIGITAL_CDC_EAR_DSM_A2_0: 1021 + case WCD939X_DIGITAL_CDC_EAR_DSM_A2_1: 1022 + case WCD939X_DIGITAL_CDC_EAR_DSM_A3_0: 1023 + case WCD939X_DIGITAL_CDC_EAR_DSM_A3_1: 1024 + case WCD939X_DIGITAL_CDC_EAR_DSM_A4_0: 1025 + case WCD939X_DIGITAL_CDC_EAR_DSM_A4_1: 1026 + case WCD939X_DIGITAL_CDC_EAR_DSM_A5_0: 1027 + case WCD939X_DIGITAL_CDC_EAR_DSM_A5_1: 1028 + case WCD939X_DIGITAL_CDC_EAR_DSM_A6_0: 1029 + case WCD939X_DIGITAL_CDC_EAR_DSM_A7_0: 1030 + case WCD939X_DIGITAL_CDC_EAR_DSM_C_0: 1031 + case WCD939X_DIGITAL_CDC_EAR_DSM_C_1: 1032 + case WCD939X_DIGITAL_CDC_EAR_DSM_C_2: 1033 + case WCD939X_DIGITAL_CDC_EAR_DSM_C_3: 1034 + case WCD939X_DIGITAL_CDC_EAR_DSM_R1: 1035 + case WCD939X_DIGITAL_CDC_EAR_DSM_R2: 1036 + case WCD939X_DIGITAL_CDC_EAR_DSM_R3: 1037 + case WCD939X_DIGITAL_CDC_EAR_DSM_R4: 1038 + case WCD939X_DIGITAL_CDC_EAR_DSM_R5: 1039 + case WCD939X_DIGITAL_CDC_EAR_DSM_R6: 1040 + case WCD939X_DIGITAL_CDC_EAR_DSM_R7: 1041 + case WCD939X_DIGITAL_CDC_HPH_GAIN_RX_0: 1042 + case WCD939X_DIGITAL_CDC_HPH_GAIN_RX_1: 1043 + case WCD939X_DIGITAL_CDC_HPH_GAIN_DSD_0: 1044 + case WCD939X_DIGITAL_CDC_HPH_GAIN_DSD_1: 1045 + case WCD939X_DIGITAL_CDC_HPH_GAIN_DSD_2: 1046 + case WCD939X_DIGITAL_CDC_EAR_GAIN_DSD_0: 1047 + case WCD939X_DIGITAL_CDC_EAR_GAIN_DSD_1: 1048 + case WCD939X_DIGITAL_CDC_EAR_GAIN_DSD_2: 1049 + case WCD939X_DIGITAL_CDC_HPH_GAIN_CTL: 1050 + case WCD939X_DIGITAL_CDC_EAR_GAIN_CTL: 1051 + case WCD939X_DIGITAL_CDC_EAR_PATH_CTL: 1052 + case WCD939X_DIGITAL_CDC_SWR_CLH: 1053 + case WCD939X_DIGITAL_SWR_CLH_BYP: 1054 + case WCD939X_DIGITAL_CDC_TX0_CTL: 1055 + case WCD939X_DIGITAL_CDC_TX1_CTL: 1056 + case WCD939X_DIGITAL_CDC_TX2_CTL: 1057 + case WCD939X_DIGITAL_CDC_TX_RST: 1058 + case WCD939X_DIGITAL_CDC_REQ_CTL: 1059 + case WCD939X_DIGITAL_CDC_RST: 1060 + case WCD939X_DIGITAL_CDC_AMIC_CTL: 1061 + case WCD939X_DIGITAL_CDC_DMIC_CTL: 1062 + case WCD939X_DIGITAL_CDC_DMIC1_CTL: 1063 + case WCD939X_DIGITAL_CDC_DMIC2_CTL: 1064 + case WCD939X_DIGITAL_CDC_DMIC3_CTL: 1065 + case WCD939X_DIGITAL_CDC_DMIC4_CTL: 1066 + case WCD939X_DIGITAL_EFUSE_PRG_CTL: 1067 + case WCD939X_DIGITAL_EFUSE_CTL: 1068 + case WCD939X_DIGITAL_CDC_DMIC_RATE_1_2: 1069 + case WCD939X_DIGITAL_CDC_DMIC_RATE_3_4: 1070 + case WCD939X_DIGITAL_PDM_WD_CTL0: 1071 + case WCD939X_DIGITAL_PDM_WD_CTL1: 1072 + case WCD939X_DIGITAL_PDM_WD_CTL2: 1073 + case WCD939X_DIGITAL_INTR_MODE: 1074 + case WCD939X_DIGITAL_INTR_MASK_0: 1075 + case WCD939X_DIGITAL_INTR_MASK_1: 1076 + case WCD939X_DIGITAL_INTR_MASK_2: 1077 + case WCD939X_DIGITAL_INTR_CLEAR_0: 1078 + case WCD939X_DIGITAL_INTR_CLEAR_1: 1079 + case WCD939X_DIGITAL_INTR_CLEAR_2: 1080 + case WCD939X_DIGITAL_INTR_LEVEL_0: 1081 + case WCD939X_DIGITAL_INTR_LEVEL_1: 1082 + case WCD939X_DIGITAL_INTR_LEVEL_2: 1083 + case WCD939X_DIGITAL_INTR_SET_0: 1084 + case WCD939X_DIGITAL_INTR_SET_1: 1085 + case WCD939X_DIGITAL_INTR_SET_2: 1086 + case WCD939X_DIGITAL_INTR_TEST_0: 1087 + case WCD939X_DIGITAL_INTR_TEST_1: 1088 + case WCD939X_DIGITAL_INTR_TEST_2: 1089 + case WCD939X_DIGITAL_TX_MODE_DBG_EN: 1090 + case WCD939X_DIGITAL_TX_MODE_DBG_0_1: 1091 + case WCD939X_DIGITAL_TX_MODE_DBG_2_3: 1092 + case WCD939X_DIGITAL_LB_IN_SEL_CTL: 1093 + case WCD939X_DIGITAL_LOOP_BACK_MODE: 1094 + case WCD939X_DIGITAL_SWR_DAC_TEST: 1095 + case WCD939X_DIGITAL_SWR_HM_TEST_RX_0: 1096 + case WCD939X_DIGITAL_SWR_HM_TEST_TX_0: 1097 + case WCD939X_DIGITAL_SWR_HM_TEST_RX_1: 1098 + case WCD939X_DIGITAL_SWR_HM_TEST_TX_1: 1099 + case WCD939X_DIGITAL_SWR_HM_TEST_TX_2: 1100 + case WCD939X_DIGITAL_PAD_CTL_SWR_0: 1101 + case WCD939X_DIGITAL_PAD_CTL_SWR_1: 1102 + case WCD939X_DIGITAL_I2C_CTL: 1103 + case WCD939X_DIGITAL_CDC_TX_TANGGU_SW_MODE: 1104 + case WCD939X_DIGITAL_EFUSE_TEST_CTL_0: 1105 + case WCD939X_DIGITAL_EFUSE_TEST_CTL_1: 1106 + case WCD939X_DIGITAL_PAD_CTL_PDM_RX0: 1107 + case WCD939X_DIGITAL_PAD_CTL_PDM_RX1: 1108 + case WCD939X_DIGITAL_PAD_CTL_PDM_TX0: 1109 + case WCD939X_DIGITAL_PAD_CTL_PDM_TX1: 1110 + case WCD939X_DIGITAL_PAD_CTL_PDM_TX2: 1111 + case WCD939X_DIGITAL_PAD_INP_DIS_0: 1112 + case WCD939X_DIGITAL_PAD_INP_DIS_1: 1113 + case WCD939X_DIGITAL_DRIVE_STRENGTH_0: 1114 + case WCD939X_DIGITAL_DRIVE_STRENGTH_1: 1115 + case WCD939X_DIGITAL_DRIVE_STRENGTH_2: 1116 + case WCD939X_DIGITAL_RX_DATA_EDGE_CTL: 1117 + case WCD939X_DIGITAL_TX_DATA_EDGE_CTL: 1118 + case WCD939X_DIGITAL_GPIO_MODE: 1119 + case WCD939X_DIGITAL_PIN_CTL_OE: 1120 + case WCD939X_DIGITAL_PIN_CTL_DATA_0: 1121 + case WCD939X_DIGITAL_PIN_CTL_DATA_1: 1122 + case WCD939X_DIGITAL_DIG_DEBUG_CTL: 1123 + case WCD939X_DIGITAL_DIG_DEBUG_EN: 1124 + case WCD939X_DIGITAL_ANA_CSR_DBG_ADD: 1125 + case WCD939X_DIGITAL_ANA_CSR_DBG_CTL: 1126 + case WCD939X_DIGITAL_SSP_DBG: 1127 + case WCD939X_DIGITAL_SPARE_0: 1128 + case WCD939X_DIGITAL_SPARE_1: 1129 + case WCD939X_DIGITAL_SPARE_2: 1130 + case WCD939X_DIGITAL_TX_REQ_FB_CTL_0: 1131 + case WCD939X_DIGITAL_TX_REQ_FB_CTL_1: 1132 + case WCD939X_DIGITAL_TX_REQ_FB_CTL_2: 1133 + case WCD939X_DIGITAL_TX_REQ_FB_CTL_3: 1134 + case WCD939X_DIGITAL_TX_REQ_FB_CTL_4: 1135 + case WCD939X_DIGITAL_DEM_BYPASS_DATA0: 1136 + case WCD939X_DIGITAL_DEM_BYPASS_DATA1: 1137 + case WCD939X_DIGITAL_DEM_BYPASS_DATA2: 1138 + case WCD939X_DIGITAL_DEM_BYPASS_DATA3: 1139 + case WCD939X_DIGITAL_DEM_SECOND_ORDER: 1140 + case WCD939X_DIGITAL_DSM_CTRL: 1141 + case WCD939X_DIGITAL_DSM_0_STATIC_DATA_0: 1142 + case WCD939X_DIGITAL_DSM_0_STATIC_DATA_1: 1143 + case WCD939X_DIGITAL_DSM_0_STATIC_DATA_2: 1144 + case WCD939X_DIGITAL_DSM_0_STATIC_DATA_3: 1145 + case WCD939X_DIGITAL_DSM_1_STATIC_DATA_0: 1146 + case WCD939X_DIGITAL_DSM_1_STATIC_DATA_1: 1147 + case WCD939X_DIGITAL_DSM_1_STATIC_DATA_2: 1148 + case WCD939X_DIGITAL_DSM_1_STATIC_DATA_3: 1149 + case WCD939X_RX_TOP_PAGE: 1150 + case WCD939X_RX_TOP_TOP_CFG0: 1151 + case WCD939X_RX_TOP_HPHL_COMP_WR_LSB: 1152 + case WCD939X_RX_TOP_HPHL_COMP_WR_MSB: 1153 + case WCD939X_RX_TOP_HPHL_COMP_LUT: 1154 + case WCD939X_RX_TOP_HPHR_COMP_WR_LSB: 1155 + case WCD939X_RX_TOP_HPHR_COMP_WR_MSB: 1156 + case WCD939X_RX_TOP_HPHR_COMP_LUT: 1157 + case WCD939X_RX_TOP_DSD0_DEBUG_CFG1: 1158 + case WCD939X_RX_TOP_DSD0_DEBUG_CFG2: 1159 + case WCD939X_RX_TOP_DSD0_DEBUG_CFG3: 1160 + case WCD939X_RX_TOP_DSD0_DEBUG_CFG4: 1161 + case WCD939X_RX_TOP_DSD1_DEBUG_CFG1: 1162 + case WCD939X_RX_TOP_DSD1_DEBUG_CFG2: 1163 + case WCD939X_RX_TOP_DSD1_DEBUG_CFG3: 1164 + case WCD939X_RX_TOP_DSD1_DEBUG_CFG4: 1165 + case WCD939X_RX_TOP_HPHL_PATH_CFG0: 1166 + case WCD939X_RX_TOP_HPHL_PATH_CFG1: 1167 + case WCD939X_RX_TOP_HPHR_PATH_CFG0: 1168 + case WCD939X_RX_TOP_HPHR_PATH_CFG1: 1169 + case WCD939X_RX_TOP_PATH_CFG2: 1170 + case WCD939X_RX_TOP_HPHL_PATH_SEC0: 1171 + case WCD939X_RX_TOP_HPHL_PATH_SEC1: 1172 + case WCD939X_RX_TOP_HPHL_PATH_SEC2: 1173 + case WCD939X_RX_TOP_HPHL_PATH_SEC3: 1174 + case WCD939X_RX_TOP_HPHR_PATH_SEC0: 1175 + case WCD939X_RX_TOP_HPHR_PATH_SEC1: 1176 + case WCD939X_RX_TOP_HPHR_PATH_SEC2: 1177 + case WCD939X_RX_TOP_HPHR_PATH_SEC3: 1178 + case WCD939X_RX_TOP_PATH_SEC4: 1179 + case WCD939X_RX_TOP_PATH_SEC5: 1180 + case WCD939X_COMPANDER_HPHL_CTL0: 1181 + case WCD939X_COMPANDER_HPHL_CTL1: 1182 + case WCD939X_COMPANDER_HPHL_CTL2: 1183 + case WCD939X_COMPANDER_HPHL_CTL3: 1184 + case WCD939X_COMPANDER_HPHL_CTL4: 1185 + case WCD939X_COMPANDER_HPHL_CTL5: 1186 + case WCD939X_COMPANDER_HPHL_CTL7: 1187 + case WCD939X_COMPANDER_HPHL_CTL8: 1188 + case WCD939X_COMPANDER_HPHL_CTL9: 1189 + case WCD939X_COMPANDER_HPHL_CTL10: 1190 + case WCD939X_COMPANDER_HPHL_CTL11: 1191 + case WCD939X_COMPANDER_HPHL_CTL12: 1192 + case WCD939X_COMPANDER_HPHL_CTL13: 1193 + case WCD939X_COMPANDER_HPHL_CTL14: 1194 + case WCD939X_COMPANDER_HPHL_CTL15: 1195 + case WCD939X_COMPANDER_HPHL_CTL16: 1196 + case WCD939X_COMPANDER_HPHL_CTL17: 1197 + case WCD939X_COMPANDER_HPHL_CTL18: 1198 + case WCD939X_COMPANDER_HPHL_CTL19: 1199 + case WCD939X_R_CTL0: 1200 + case WCD939X_R_CTL1: 1201 + case WCD939X_R_CTL2: 1202 + case WCD939X_R_CTL3: 1203 + case WCD939X_R_CTL4: 1204 + case WCD939X_R_CTL5: 1205 + case WCD939X_R_CTL7: 1206 + case WCD939X_R_CTL8: 1207 + case WCD939X_R_CTL9: 1208 + case WCD939X_R_CTL10: 1209 + case WCD939X_R_CTL11: 1210 + case WCD939X_R_CTL12: 1211 + case WCD939X_R_CTL13: 1212 + case WCD939X_R_CTL14: 1213 + case WCD939X_R_CTL15: 1214 + case WCD939X_R_CTL16: 1215 + case WCD939X_R_CTL17: 1216 + case WCD939X_R_CTL18: 1217 + case WCD939X_R_CTL19: 1218 + case WCD939X_E_PATH_CTL: 1219 + case WCD939X_E_CFG0: 1220 + case WCD939X_E_CFG1: 1221 + case WCD939X_E_CFG2: 1222 + case WCD939X_E_CFG3: 1223 + case WCD939X_DSD_HPHL_PATH_CTL: 1224 + case WCD939X_DSD_HPHL_CFG0: 1225 + case WCD939X_DSD_HPHL_CFG1: 1226 + case WCD939X_DSD_HPHL_CFG2: 1227 + case WCD939X_DSD_HPHL_CFG3: 1228 + case WCD939X_DSD_HPHL_CFG4: 1229 + case WCD939X_DSD_HPHL_CFG5: 1230 + case WCD939X_DSD_HPHR_PATH_CTL: 1231 + case WCD939X_DSD_HPHR_CFG0: 1232 + case WCD939X_DSD_HPHR_CFG1: 1233 + case WCD939X_DSD_HPHR_CFG2: 1234 + case WCD939X_DSD_HPHR_CFG3: 1235 + case WCD939X_DSD_HPHR_CFG4: 1236 + case WCD939X_DSD_HPHR_CFG5: 1237 + return true; 1238 + } 1239 + 1240 + return false; 1241 + } 1242 + 1243 + static bool wcd939x_readable_register(struct device *dev, unsigned int reg) 1244 + { 1245 + /* Read-Only Registers */ 1246 + switch (reg) { 1247 + case WCD939X_ANA_MBHC_RESULT_1: 1248 + case WCD939X_ANA_MBHC_RESULT_2: 1249 + case WCD939X_ANA_MBHC_RESULT_3: 1250 + case WCD939X_MBHC_MOISTURE_DET_FSM_STATUS: 1251 + case WCD939X_TX_1_2_SAR2_ERR: 1252 + case WCD939X_TX_1_2_SAR1_ERR: 1253 + case WCD939X_TX_3_4_SAR4_ERR: 1254 + case WCD939X_TX_3_4_SAR3_ERR: 1255 + case WCD939X_HPH_L_STATUS: 1256 + case WCD939X_HPH_R_STATUS: 1257 + case WCD939X_HPH_SURGE_STATUS: 1258 + case WCD939X_EAR_STATUS_REG_1: 1259 + case WCD939X_EAR_STATUS_REG_2: 1260 + case WCD939X_MBHC_NEW_FSM_STATUS: 1261 + case WCD939X_MBHC_NEW_ADC_RESULT: 1262 + case WCD939X_DIE_CRACK_DET_OUT: 1263 + case WCD939X_DIGITAL_CHIP_ID0: 1264 + case WCD939X_DIGITAL_CHIP_ID1: 1265 + case WCD939X_DIGITAL_CHIP_ID2: 1266 + case WCD939X_DIGITAL_CHIP_ID3: 1267 + case WCD939X_DIGITAL_INTR_STATUS_0: 1268 + case WCD939X_DIGITAL_INTR_STATUS_1: 1269 + case WCD939X_DIGITAL_INTR_STATUS_2: 1270 + case WCD939X_DIGITAL_SWR_HM_TEST_0: 1271 + case WCD939X_DIGITAL_SWR_HM_TEST_1: 1272 + case WCD939X_DIGITAL_EFUSE_T_DATA_0: 1273 + case WCD939X_DIGITAL_EFUSE_T_DATA_1: 1274 + case WCD939X_DIGITAL_PIN_STATUS_0: 1275 + case WCD939X_DIGITAL_PIN_STATUS_1: 1276 + case WCD939X_DIGITAL_MODE_STATUS_0: 1277 + case WCD939X_DIGITAL_MODE_STATUS_1: 1278 + case WCD939X_DIGITAL_EFUSE_REG_0: 1279 + case WCD939X_DIGITAL_EFUSE_REG_1: 1280 + case WCD939X_DIGITAL_EFUSE_REG_2: 1281 + case WCD939X_DIGITAL_EFUSE_REG_3: 1282 + case WCD939X_DIGITAL_EFUSE_REG_4: 1283 + case WCD939X_DIGITAL_EFUSE_REG_5: 1284 + case WCD939X_DIGITAL_EFUSE_REG_6: 1285 + case WCD939X_DIGITAL_EFUSE_REG_7: 1286 + case WCD939X_DIGITAL_EFUSE_REG_8: 1287 + case WCD939X_DIGITAL_EFUSE_REG_9: 1288 + case WCD939X_DIGITAL_EFUSE_REG_10: 1289 + case WCD939X_DIGITAL_EFUSE_REG_11: 1290 + case WCD939X_DIGITAL_EFUSE_REG_12: 1291 + case WCD939X_DIGITAL_EFUSE_REG_13: 1292 + case WCD939X_DIGITAL_EFUSE_REG_14: 1293 + case WCD939X_DIGITAL_EFUSE_REG_15: 1294 + case WCD939X_DIGITAL_EFUSE_REG_16: 1295 + case WCD939X_DIGITAL_EFUSE_REG_17: 1296 + case WCD939X_DIGITAL_EFUSE_REG_18: 1297 + case WCD939X_DIGITAL_EFUSE_REG_19: 1298 + case WCD939X_DIGITAL_EFUSE_REG_20: 1299 + case WCD939X_DIGITAL_EFUSE_REG_21: 1300 + case WCD939X_DIGITAL_EFUSE_REG_22: 1301 + case WCD939X_DIGITAL_EFUSE_REG_23: 1302 + case WCD939X_DIGITAL_EFUSE_REG_24: 1303 + case WCD939X_DIGITAL_EFUSE_REG_25: 1304 + case WCD939X_DIGITAL_EFUSE_REG_26: 1305 + case WCD939X_DIGITAL_EFUSE_REG_27: 1306 + case WCD939X_DIGITAL_EFUSE_REG_28: 1307 + case WCD939X_DIGITAL_EFUSE_REG_29: 1308 + case WCD939X_DIGITAL_EFUSE_REG_30: 1309 + case WCD939X_DIGITAL_EFUSE_REG_31: 1310 + case WCD939X_RX_TOP_HPHL_COMP_RD_LSB: 1311 + case WCD939X_RX_TOP_HPHL_COMP_RD_MSB: 1312 + case WCD939X_RX_TOP_HPHR_COMP_RD_LSB: 1313 + case WCD939X_RX_TOP_HPHR_COMP_RD_MSB: 1314 + case WCD939X_RX_TOP_DSD0_DEBUG_CFG5: 1315 + case WCD939X_RX_TOP_DSD0_DEBUG_CFG6: 1316 + case WCD939X_RX_TOP_DSD1_DEBUG_CFG5: 1317 + case WCD939X_RX_TOP_DSD1_DEBUG_CFG6: 1318 + case WCD939X_COMPANDER_HPHL_CTL6: 1319 + case WCD939X_R_CTL6: 1320 + return true; 1321 + } 1322 + 1323 + return wcd939x_rdwr_register(dev, reg); 1324 + } 1325 + 1326 + static bool wcd939x_volatile_register(struct device *dev, unsigned int reg) 1327 + { 1328 + switch (reg) { 1329 + case WCD939X_ANA_MBHC_RESULT_1: 1330 + case WCD939X_ANA_MBHC_RESULT_2: 1331 + case WCD939X_ANA_MBHC_RESULT_3: 1332 + case WCD939X_MBHC_MOISTURE_DET_FSM_STATUS: 1333 + case WCD939X_TX_1_2_SAR2_ERR: 1334 + case WCD939X_TX_1_2_SAR1_ERR: 1335 + case WCD939X_TX_3_4_SAR4_ERR: 1336 + case WCD939X_TX_3_4_SAR3_ERR: 1337 + case WCD939X_HPH_L_STATUS: 1338 + case WCD939X_HPH_R_STATUS: 1339 + case WCD939X_HPH_SURGE_STATUS: 1340 + case WCD939X_EAR_STATUS_REG_1: 1341 + case WCD939X_EAR_STATUS_REG_2: 1342 + case WCD939X_MBHC_NEW_FSM_STATUS: 1343 + case WCD939X_MBHC_NEW_ADC_RESULT: 1344 + case WCD939X_DIE_CRACK_DET_OUT: 1345 + case WCD939X_DIGITAL_INTR_STATUS_0: 1346 + case WCD939X_DIGITAL_INTR_STATUS_1: 1347 + case WCD939X_DIGITAL_INTR_STATUS_2: 1348 + case WCD939X_DIGITAL_SWR_HM_TEST_0: 1349 + case WCD939X_DIGITAL_SWR_HM_TEST_1: 1350 + case WCD939X_DIGITAL_PIN_STATUS_0: 1351 + case WCD939X_DIGITAL_PIN_STATUS_1: 1352 + case WCD939X_DIGITAL_MODE_STATUS_0: 1353 + case WCD939X_DIGITAL_MODE_STATUS_1: 1354 + case WCD939X_RX_TOP_HPHL_COMP_RD_LSB: 1355 + case WCD939X_RX_TOP_HPHL_COMP_RD_MSB: 1356 + case WCD939X_RX_TOP_HPHR_COMP_RD_LSB: 1357 + case WCD939X_RX_TOP_HPHR_COMP_RD_MSB: 1358 + case WCD939X_RX_TOP_DSD0_DEBUG_CFG5: 1359 + case WCD939X_RX_TOP_DSD0_DEBUG_CFG6: 1360 + case WCD939X_RX_TOP_DSD1_DEBUG_CFG5: 1361 + case WCD939X_RX_TOP_DSD1_DEBUG_CFG6: 1362 + case WCD939X_COMPANDER_HPHL_CTL6: 1363 + case WCD939X_R_CTL6: 1364 + return true; 1365 + } 1366 + return false; 1367 + } 1368 + 1369 + static bool wcd939x_writeable_register(struct device *dev, unsigned int reg) 1370 + { 1371 + return wcd939x_rdwr_register(dev, reg); 1372 + } 1373 + 1374 + static const struct regmap_config wcd939x_regmap_config = { 1375 + .name = "wcd939x_csr", 1376 + .reg_bits = 32, 1377 + .val_bits = 8, 1378 + .cache_type = REGCACHE_MAPLE, 1379 + .reg_defaults = wcd939x_defaults, 1380 + .num_reg_defaults = ARRAY_SIZE(wcd939x_defaults), 1381 + .max_register = WCD939X_MAX_REGISTER, 1382 + .readable_reg = wcd939x_readable_register, 1383 + .writeable_reg = wcd939x_writeable_register, 1384 + .volatile_reg = wcd939x_volatile_register, 1385 + }; 1386 + 1387 + static const struct sdw_slave_ops wcd9390_slave_ops = { 1388 + .update_status = wcd9390_update_status, 1389 + .interrupt_callback = wcd9390_interrupt_callback, 1390 + .bus_config = wcd9390_bus_config, 1391 + }; 1392 + 1393 + static int wcd939x_sdw_component_bind(struct device *dev, struct device *master, 1394 + void *data) 1395 + { 1396 + pm_runtime_set_autosuspend_delay(dev, 3000); 1397 + pm_runtime_use_autosuspend(dev); 1398 + pm_runtime_mark_last_busy(dev); 1399 + pm_runtime_set_active(dev); 1400 + pm_runtime_enable(dev); 1401 + 1402 + return 0; 1403 + } 1404 + 1405 + static void wcd939x_sdw_component_unbind(struct device *dev, 1406 + struct device *master, void *data) 1407 + { 1408 + pm_runtime_disable(dev); 1409 + pm_runtime_set_suspended(dev); 1410 + pm_runtime_dont_use_autosuspend(dev); 1411 + } 1412 + 1413 + static const struct component_ops wcd939x_sdw_component_ops = { 1414 + .bind = wcd939x_sdw_component_bind, 1415 + .unbind = wcd939x_sdw_component_unbind, 1416 + }; 1417 + 1418 + static int wcd9390_probe(struct sdw_slave *pdev, const struct sdw_device_id *id) 1419 + { 1420 + struct device *dev = &pdev->dev; 1421 + struct wcd939x_sdw_priv *wcd; 1422 + int ret; 1423 + 1424 + wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL); 1425 + if (!wcd) 1426 + return -ENOMEM; 1427 + 1428 + /* 1429 + * Port map index starts with 0, however the data port for this codec 1430 + * are from index 1 1431 + */ 1432 + if (of_property_read_bool(dev->of_node, "qcom,tx-port-mapping")) { 1433 + wcd->is_tx = true; 1434 + ret = of_property_read_u32_array(dev->of_node, 1435 + "qcom,tx-port-mapping", 1436 + &pdev->m_port_map[1], 1437 + WCD939X_MAX_TX_SWR_PORTS); 1438 + } else { 1439 + ret = of_property_read_u32_array(dev->of_node, 1440 + "qcom,rx-port-mapping", 1441 + &pdev->m_port_map[1], 1442 + WCD939X_MAX_RX_SWR_PORTS); 1443 + } 1444 + 1445 + if (ret < 0) 1446 + dev_info(dev, "Static Port mapping not specified\n"); 1447 + 1448 + wcd->sdev = pdev; 1449 + dev_set_drvdata(dev, wcd); 1450 + 1451 + pdev->prop.scp_int1_mask = SDW_SCP_INT1_IMPL_DEF | 1452 + SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; 1453 + pdev->prop.lane_control_support = true; 1454 + pdev->prop.simple_clk_stop_capable = true; 1455 + if (wcd->is_tx) { 1456 + pdev->prop.source_ports = GENMASK(WCD939X_MAX_TX_SWR_PORTS, 0); 1457 + pdev->prop.src_dpn_prop = wcd939x_tx_dpn_prop; 1458 + wcd->ch_info = &wcd939x_sdw_tx_ch_info[0]; 1459 + pdev->prop.wake_capable = true; 1460 + } else { 1461 + pdev->prop.sink_ports = GENMASK(WCD939X_MAX_RX_SWR_PORTS, 0); 1462 + pdev->prop.sink_dpn_prop = wcd939x_rx_dpn_prop; 1463 + wcd->ch_info = &wcd939x_sdw_rx_ch_info[0]; 1464 + } 1465 + 1466 + if (wcd->is_tx) { 1467 + /* 1468 + * Do not use devres here since devres_release_group() could 1469 + * be called by component_unbind() id the aggregate device 1470 + * fails to bind. 1471 + */ 1472 + wcd->regmap = regmap_init_sdw(pdev, &wcd939x_regmap_config); 1473 + if (IS_ERR(wcd->regmap)) 1474 + return dev_err_probe(dev, PTR_ERR(wcd->regmap), 1475 + "Regmap init failed\n"); 1476 + 1477 + /* Start in cache-only until device is enumerated */ 1478 + regcache_cache_only(wcd->regmap, true); 1479 + } 1480 + 1481 + ret = component_add(dev, &wcd939x_sdw_component_ops); 1482 + if (ret) 1483 + return ret; 1484 + 1485 + /* Set suspended until aggregate device is bind */ 1486 + pm_runtime_set_suspended(dev); 1487 + 1488 + return 0; 1489 + } 1490 + 1491 + static int wcd9390_remove(struct sdw_slave *pdev) 1492 + { 1493 + struct device *dev = &pdev->dev; 1494 + struct wcd939x_sdw_priv *wcd = dev_get_drvdata(dev); 1495 + 1496 + component_del(dev, &wcd939x_sdw_component_ops); 1497 + 1498 + if (wcd->regmap) 1499 + regmap_exit(wcd->regmap); 1500 + 1501 + return 0; 1502 + } 1503 + 1504 + static const struct sdw_device_id wcd9390_slave_id[] = { 1505 + SDW_SLAVE_ENTRY(0x0217, 0x10e, 0), /* WCD9390 & WCD9390 RX/TX Device ID */ 1506 + {}, 1507 + }; 1508 + MODULE_DEVICE_TABLE(sdw, wcd9390_slave_id); 1509 + 1510 + static int __maybe_unused wcd939x_sdw_runtime_suspend(struct device *dev) 1511 + { 1512 + struct wcd939x_sdw_priv *wcd = dev_get_drvdata(dev); 1513 + 1514 + if (wcd->regmap) { 1515 + regcache_cache_only(wcd->regmap, true); 1516 + regcache_mark_dirty(wcd->regmap); 1517 + } 1518 + 1519 + return 0; 1520 + } 1521 + 1522 + static int __maybe_unused wcd939x_sdw_runtime_resume(struct device *dev) 1523 + { 1524 + struct wcd939x_sdw_priv *wcd = dev_get_drvdata(dev); 1525 + 1526 + if (wcd->regmap) { 1527 + regcache_cache_only(wcd->regmap, false); 1528 + regcache_sync(wcd->regmap); 1529 + } 1530 + 1531 + return 0; 1532 + } 1533 + 1534 + static const struct dev_pm_ops wcd939x_sdw_pm_ops = { 1535 + SET_RUNTIME_PM_OPS(wcd939x_sdw_runtime_suspend, wcd939x_sdw_runtime_resume, NULL) 1536 + }; 1537 + 1538 + static struct sdw_driver wcd9390_codec_driver = { 1539 + .probe = wcd9390_probe, 1540 + .remove = wcd9390_remove, 1541 + .ops = &wcd9390_slave_ops, 1542 + .id_table = wcd9390_slave_id, 1543 + .driver = { 1544 + .name = "wcd9390-codec", 1545 + .pm = &wcd939x_sdw_pm_ops, 1546 + } 1547 + }; 1548 + module_sdw_driver(wcd9390_codec_driver); 1549 + 1550 + MODULE_DESCRIPTION("WCD939X SDW codec driver"); 1551 + MODULE_LICENSE("GPL");
+3686
sound/soc/codecs/wcd939x.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) 2023, Linaro Limited 6 + */ 7 + 8 + #include <linux/module.h> 9 + #include <linux/slab.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/device.h> 12 + #include <linux/delay.h> 13 + #include <linux/gpio/consumer.h> 14 + #include <linux/kernel.h> 15 + #include <linux/pm_runtime.h> 16 + #include <linux/component.h> 17 + #include <sound/tlv.h> 18 + #include <linux/of_gpio.h> 19 + #include <linux/of_graph.h> 20 + #include <linux/of.h> 21 + #include <sound/jack.h> 22 + #include <sound/pcm.h> 23 + #include <sound/pcm_params.h> 24 + #include <linux/regmap.h> 25 + #include <sound/soc.h> 26 + #include <sound/soc-dapm.h> 27 + #include <linux/regulator/consumer.h> 28 + #include <linux/usb/typec_mux.h> 29 + #include <linux/usb/typec_altmode.h> 30 + 31 + #include "wcd-clsh-v2.h" 32 + #include "wcd-mbhc-v2.h" 33 + #include "wcd939x.h" 34 + 35 + #define WCD939X_MAX_MICBIAS (4) 36 + #define WCD939X_MAX_SUPPLY (4) 37 + #define WCD939X_MBHC_MAX_BUTTONS (8) 38 + #define TX_ADC_MAX (4) 39 + #define WCD_MBHC_HS_V_MAX 1600 40 + 41 + enum { 42 + WCD939X_VERSION_1_0 = 0, 43 + WCD939X_VERSION_1_1, 44 + WCD939X_VERSION_2_0, 45 + }; 46 + 47 + #define WCD939X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 48 + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ 49 + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ 50 + SNDRV_PCM_RATE_384000) 51 + /* Fractional Rates */ 52 + #define WCD939X_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ 53 + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800) 54 + #define WCD939X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 55 + SNDRV_PCM_FMTBIT_S24_LE |\ 56 + SNDRV_PCM_FMTBIT_S24_3LE |\ 57 + SNDRV_PCM_FMTBIT_S32_LE) 58 + 59 + /* Convert from vout ctl to micbias voltage in mV */ 60 + #define WCD_VOUT_CTL_TO_MICB(v) (1000 + (v) * 50) 61 + #define SWR_CLK_RATE_0P6MHZ (600000) 62 + #define SWR_CLK_RATE_1P2MHZ (1200000) 63 + #define SWR_CLK_RATE_2P4MHZ (2400000) 64 + #define SWR_CLK_RATE_4P8MHZ (4800000) 65 + #define SWR_CLK_RATE_9P6MHZ (9600000) 66 + #define SWR_CLK_RATE_11P2896MHZ (1128960) 67 + 68 + #define ADC_MODE_VAL_HIFI 0x01 69 + #define ADC_MODE_VAL_LO_HIF 0x02 70 + #define ADC_MODE_VAL_NORMAL 0x03 71 + #define ADC_MODE_VAL_LP 0x05 72 + #define ADC_MODE_VAL_ULP1 0x09 73 + #define ADC_MODE_VAL_ULP2 0x0B 74 + 75 + /* Z value defined in milliohm */ 76 + #define WCD939X_ZDET_VAL_32 (32000) 77 + #define WCD939X_ZDET_VAL_400 (400000) 78 + #define WCD939X_ZDET_VAL_1200 (1200000) 79 + #define WCD939X_ZDET_VAL_100K (100000000) 80 + 81 + /* Z floating defined in ohms */ 82 + #define WCD939X_ZDET_FLOATING_IMPEDANCE (0x0FFFFFFE) 83 + #define WCD939X_ZDET_NUM_MEASUREMENTS (900) 84 + #define WCD939X_MBHC_GET_C1(c) (((c) & 0xC000) >> 14) 85 + #define WCD939X_MBHC_GET_X1(x) ((x) & 0x3FFF) 86 + 87 + /* Z value compared in milliOhm */ 88 + #define WCD939X_MBHC_IS_SECOND_RAMP_REQUIRED(z) false 89 + #define WCD939X_ANA_MBHC_ZDET_CONST (1018 * 1024) 90 + 91 + enum { 92 + WCD9390 = 0, 93 + WCD9395 = 5, 94 + }; 95 + 96 + enum { 97 + /* INTR_CTRL_INT_MASK_0 */ 98 + WCD939X_IRQ_MBHC_BUTTON_PRESS_DET = 0, 99 + WCD939X_IRQ_MBHC_BUTTON_RELEASE_DET, 100 + WCD939X_IRQ_MBHC_ELECT_INS_REM_DET, 101 + WCD939X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 102 + WCD939X_IRQ_MBHC_SW_DET, 103 + WCD939X_IRQ_HPHR_OCP_INT, 104 + WCD939X_IRQ_HPHR_CNP_INT, 105 + WCD939X_IRQ_HPHL_OCP_INT, 106 + 107 + /* INTR_CTRL_INT_MASK_1 */ 108 + WCD939X_IRQ_HPHL_CNP_INT, 109 + WCD939X_IRQ_EAR_CNP_INT, 110 + WCD939X_IRQ_EAR_SCD_INT, 111 + WCD939X_IRQ_HPHL_PDM_WD_INT, 112 + WCD939X_IRQ_HPHR_PDM_WD_INT, 113 + WCD939X_IRQ_EAR_PDM_WD_INT, 114 + 115 + /* INTR_CTRL_INT_MASK_2 */ 116 + WCD939X_IRQ_MBHC_MOISTURE_INT, 117 + WCD939X_IRQ_HPHL_SURGE_DET_INT, 118 + WCD939X_IRQ_HPHR_SURGE_DET_INT, 119 + WCD939X_NUM_IRQS, 120 + }; 121 + 122 + enum { 123 + MICB_BIAS_DISABLE = 0, 124 + MICB_BIAS_ENABLE, 125 + MICB_BIAS_PULL_UP, 126 + MICB_BIAS_PULL_DOWN, 127 + }; 128 + 129 + enum { 130 + WCD_ADC1 = 0, 131 + WCD_ADC2, 132 + WCD_ADC3, 133 + WCD_ADC4, 134 + HPH_PA_DELAY, 135 + }; 136 + 137 + enum { 138 + ADC_MODE_INVALID = 0, 139 + ADC_MODE_HIFI, 140 + ADC_MODE_LO_HIF, 141 + ADC_MODE_NORMAL, 142 + ADC_MODE_LP, 143 + ADC_MODE_ULP1, 144 + ADC_MODE_ULP2, 145 + }; 146 + 147 + enum { 148 + AIF1_PB = 0, 149 + AIF1_CAP, 150 + NUM_CODEC_DAIS, 151 + }; 152 + 153 + static u8 tx_mode_bit[] = { 154 + [ADC_MODE_INVALID] = 0x00, 155 + [ADC_MODE_HIFI] = 0x01, 156 + [ADC_MODE_LO_HIF] = 0x02, 157 + [ADC_MODE_NORMAL] = 0x04, 158 + [ADC_MODE_LP] = 0x08, 159 + [ADC_MODE_ULP1] = 0x10, 160 + [ADC_MODE_ULP2] = 0x20, 161 + }; 162 + 163 + struct zdet_param { 164 + u16 ldo_ctl; 165 + u16 noff; 166 + u16 nshift; 167 + u16 btn5; 168 + u16 btn6; 169 + u16 btn7; 170 + }; 171 + 172 + struct wcd939x_priv { 173 + struct sdw_slave *tx_sdw_dev; 174 + struct wcd939x_sdw_priv *sdw_priv[NUM_CODEC_DAIS]; 175 + struct device *txdev; 176 + struct device *rxdev; 177 + struct device_node *rxnode, *txnode; 178 + struct regmap *regmap; 179 + struct snd_soc_component *component; 180 + /* micb setup lock */ 181 + struct mutex micb_lock; 182 + /* typec handling */ 183 + bool typec_analog_mux; 184 + #if IS_ENABLED(CONFIG_TYPEC) 185 + struct typec_mux_dev *typec_mux; 186 + struct typec_switch_dev *typec_sw; 187 + enum typec_orientation typec_orientation; 188 + unsigned long typec_mode; 189 + struct typec_switch *typec_switch; 190 + #endif /* CONFIG_TYPEC */ 191 + /* mbhc module */ 192 + struct wcd_mbhc *wcd_mbhc; 193 + struct wcd_mbhc_config mbhc_cfg; 194 + struct wcd_mbhc_intr intr_ids; 195 + struct wcd_clsh_ctrl *clsh_info; 196 + struct irq_domain *virq; 197 + struct regmap_irq_chip *wcd_regmap_irq_chip; 198 + struct regmap_irq_chip_data *irq_chip; 199 + struct regulator_bulk_data supplies[WCD939X_MAX_SUPPLY]; 200 + struct snd_soc_jack *jack; 201 + unsigned long status_mask; 202 + s32 micb_ref[WCD939X_MAX_MICBIAS]; 203 + s32 pullup_ref[WCD939X_MAX_MICBIAS]; 204 + u32 hph_mode; 205 + u32 tx_mode[TX_ADC_MAX]; 206 + int variant; 207 + int reset_gpio; 208 + u32 micb1_mv; 209 + u32 micb2_mv; 210 + u32 micb3_mv; 211 + u32 micb4_mv; 212 + int hphr_pdm_wd_int; 213 + int hphl_pdm_wd_int; 214 + int ear_pdm_wd_int; 215 + bool comp1_enable; 216 + bool comp2_enable; 217 + bool ldoh; 218 + }; 219 + 220 + static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); 221 + static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); 222 + static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); 223 + 224 + static struct wcd_mbhc_field wcd_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = { 225 + WCD_MBHC_FIELD(WCD_MBHC_L_DET_EN, WCD939X_ANA_MBHC_MECH, 0x80), 226 + WCD_MBHC_FIELD(WCD_MBHC_GND_DET_EN, WCD939X_ANA_MBHC_MECH, 0x40), 227 + WCD_MBHC_FIELD(WCD_MBHC_MECH_DETECTION_TYPE, WCD939X_ANA_MBHC_MECH, 0x20), 228 + WCD_MBHC_FIELD(WCD_MBHC_MIC_CLAMP_CTL, WCD939X_MBHC_NEW_PLUG_DETECT_CTL, 0x30), 229 + WCD_MBHC_FIELD(WCD_MBHC_ELECT_DETECTION_TYPE, WCD939X_ANA_MBHC_ELECT, 0x08), 230 + WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, WCD939X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F), 231 + WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, WCD939X_ANA_MBHC_MECH, 0x04), 232 + WCD_MBHC_FIELD(WCD_MBHC_HPHL_PLUG_TYPE, WCD939X_ANA_MBHC_MECH, 0x10), 233 + WCD_MBHC_FIELD(WCD_MBHC_GND_PLUG_TYPE, WCD939X_ANA_MBHC_MECH, 0x08), 234 + WCD_MBHC_FIELD(WCD_MBHC_SW_HPH_LP_100K_TO_GND, WCD939X_ANA_MBHC_MECH, 0x01), 235 + WCD_MBHC_FIELD(WCD_MBHC_ELECT_SCHMT_ISRC, WCD939X_ANA_MBHC_ELECT, 0x06), 236 + WCD_MBHC_FIELD(WCD_MBHC_FSM_EN, WCD939X_ANA_MBHC_ELECT, 0x80), 237 + WCD_MBHC_FIELD(WCD_MBHC_INSREM_DBNC, WCD939X_MBHC_NEW_PLUG_DETECT_CTL, 0x0F), 238 + WCD_MBHC_FIELD(WCD_MBHC_BTN_DBNC, WCD939X_MBHC_NEW_CTL_1, 0x03), 239 + WCD_MBHC_FIELD(WCD_MBHC_HS_VREF, WCD939X_MBHC_NEW_CTL_2, 0x03), 240 + WCD_MBHC_FIELD(WCD_MBHC_HS_COMP_RESULT, WCD939X_ANA_MBHC_RESULT_3, 0x08), 241 + WCD_MBHC_FIELD(WCD_MBHC_IN2P_CLAMP_STATE, WCD939X_ANA_MBHC_RESULT_3, 0x10), 242 + WCD_MBHC_FIELD(WCD_MBHC_MIC_SCHMT_RESULT, WCD939X_ANA_MBHC_RESULT_3, 0x20), 243 + WCD_MBHC_FIELD(WCD_MBHC_HPHL_SCHMT_RESULT, WCD939X_ANA_MBHC_RESULT_3, 0x80), 244 + WCD_MBHC_FIELD(WCD_MBHC_HPHR_SCHMT_RESULT, WCD939X_ANA_MBHC_RESULT_3, 0x40), 245 + WCD_MBHC_FIELD(WCD_MBHC_OCP_FSM_EN, WCD939X_HPH_OCP_CTL, 0x10), 246 + WCD_MBHC_FIELD(WCD_MBHC_BTN_RESULT, WCD939X_ANA_MBHC_RESULT_3, 0x07), 247 + WCD_MBHC_FIELD(WCD_MBHC_BTN_ISRC_CTL, WCD939X_ANA_MBHC_ELECT, 0x70), 248 + WCD_MBHC_FIELD(WCD_MBHC_ELECT_RESULT, WCD939X_ANA_MBHC_RESULT_3, 0xFF), 249 + WCD_MBHC_FIELD(WCD_MBHC_MICB_CTRL, WCD939X_ANA_MICB2, 0xC0), 250 + WCD_MBHC_FIELD(WCD_MBHC_HPH_CNP_WG_TIME, WCD939X_HPH_CNP_WG_TIME, 0xFF), 251 + WCD_MBHC_FIELD(WCD_MBHC_HPHR_PA_EN, WCD939X_ANA_HPH, 0x40), 252 + WCD_MBHC_FIELD(WCD_MBHC_HPHL_PA_EN, WCD939X_ANA_HPH, 0x80), 253 + WCD_MBHC_FIELD(WCD_MBHC_HPH_PA_EN, WCD939X_ANA_HPH, 0xC0), 254 + WCD_MBHC_FIELD(WCD_MBHC_SWCH_LEVEL_REMOVE, WCD939X_ANA_MBHC_RESULT_3, 0x10), 255 + WCD_MBHC_FIELD(WCD_MBHC_ANC_DET_EN, WCD939X_MBHC_CTL_BCS, 0x02), 256 + WCD_MBHC_FIELD(WCD_MBHC_FSM_STATUS, WCD939X_MBHC_NEW_FSM_STATUS, 0x01), 257 + WCD_MBHC_FIELD(WCD_MBHC_MUX_CTL, WCD939X_MBHC_NEW_CTL_2, 0x70), 258 + WCD_MBHC_FIELD(WCD_MBHC_MOISTURE_STATUS, WCD939X_MBHC_NEW_FSM_STATUS, 0x20), 259 + WCD_MBHC_FIELD(WCD_MBHC_HPHR_GND, WCD939X_HPH_PA_CTL2, 0x40), 260 + WCD_MBHC_FIELD(WCD_MBHC_HPHL_GND, WCD939X_HPH_PA_CTL2, 0x10), 261 + WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_DET_EN, WCD939X_HPH_L_TEST, 0x01), 262 + WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_DET_EN, WCD939X_HPH_R_TEST, 0x01), 263 + WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_STATUS, WCD939X_DIGITAL_INTR_STATUS_0, 0x80), 264 + WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_STATUS, WCD939X_DIGITAL_INTR_STATUS_0, 0x20), 265 + WCD_MBHC_FIELD(WCD_MBHC_ADC_EN, WCD939X_MBHC_NEW_CTL_1, 0x08), 266 + WCD_MBHC_FIELD(WCD_MBHC_ADC_COMPLETE, WCD939X_MBHC_NEW_FSM_STATUS, 0x40), 267 + WCD_MBHC_FIELD(WCD_MBHC_ADC_TIMEOUT, WCD939X_MBHC_NEW_FSM_STATUS, 0x80), 268 + WCD_MBHC_FIELD(WCD_MBHC_ADC_RESULT, WCD939X_MBHC_NEW_ADC_RESULT, 0xFF), 269 + WCD_MBHC_FIELD(WCD_MBHC_MICB2_VOUT, WCD939X_ANA_MICB2, 0x3F), 270 + WCD_MBHC_FIELD(WCD_MBHC_ADC_MODE, WCD939X_MBHC_NEW_CTL_1, 0x10), 271 + WCD_MBHC_FIELD(WCD_MBHC_DETECTION_DONE, WCD939X_MBHC_NEW_CTL_1, 0x04), 272 + WCD_MBHC_FIELD(WCD_MBHC_ELECT_ISRC_EN, WCD939X_ANA_MBHC_ZDET, 0x02), 273 + }; 274 + 275 + static const struct regmap_irq wcd939x_irqs[WCD939X_NUM_IRQS] = { 276 + REGMAP_IRQ_REG(WCD939X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01), 277 + REGMAP_IRQ_REG(WCD939X_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x02), 278 + REGMAP_IRQ_REG(WCD939X_IRQ_MBHC_ELECT_INS_REM_DET, 0, 0x04), 279 + REGMAP_IRQ_REG(WCD939X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, 0x08), 280 + REGMAP_IRQ_REG(WCD939X_IRQ_MBHC_SW_DET, 0, 0x10), 281 + REGMAP_IRQ_REG(WCD939X_IRQ_HPHR_OCP_INT, 0, 0x20), 282 + REGMAP_IRQ_REG(WCD939X_IRQ_HPHR_CNP_INT, 0, 0x40), 283 + REGMAP_IRQ_REG(WCD939X_IRQ_HPHL_OCP_INT, 0, 0x80), 284 + REGMAP_IRQ_REG(WCD939X_IRQ_HPHL_CNP_INT, 1, 0x01), 285 + REGMAP_IRQ_REG(WCD939X_IRQ_EAR_CNP_INT, 1, 0x02), 286 + REGMAP_IRQ_REG(WCD939X_IRQ_EAR_SCD_INT, 1, 0x04), 287 + REGMAP_IRQ_REG(WCD939X_IRQ_HPHL_PDM_WD_INT, 1, 0x20), 288 + REGMAP_IRQ_REG(WCD939X_IRQ_HPHR_PDM_WD_INT, 1, 0x40), 289 + REGMAP_IRQ_REG(WCD939X_IRQ_EAR_PDM_WD_INT, 1, 0x80), 290 + REGMAP_IRQ_REG(WCD939X_IRQ_MBHC_MOISTURE_INT, 2, 0x02), 291 + REGMAP_IRQ_REG(WCD939X_IRQ_HPHL_SURGE_DET_INT, 2, 0x04), 292 + REGMAP_IRQ_REG(WCD939X_IRQ_HPHR_SURGE_DET_INT, 2, 0x08), 293 + }; 294 + 295 + static struct regmap_irq_chip wcd939x_regmap_irq_chip = { 296 + .name = "wcd939x", 297 + .irqs = wcd939x_irqs, 298 + .num_irqs = ARRAY_SIZE(wcd939x_irqs), 299 + .num_regs = 3, 300 + .status_base = WCD939X_DIGITAL_INTR_STATUS_0, 301 + .mask_base = WCD939X_DIGITAL_INTR_MASK_0, 302 + .ack_base = WCD939X_DIGITAL_INTR_CLEAR_0, 303 + .use_ack = 1, 304 + .runtime_pm = true, 305 + .irq_drv_data = NULL, 306 + }; 307 + 308 + static int wcd939x_get_clk_rate(int mode) 309 + { 310 + int rate; 311 + 312 + switch (mode) { 313 + case ADC_MODE_ULP2: 314 + rate = SWR_CLK_RATE_0P6MHZ; 315 + break; 316 + case ADC_MODE_ULP1: 317 + rate = SWR_CLK_RATE_1P2MHZ; 318 + break; 319 + case ADC_MODE_LP: 320 + rate = SWR_CLK_RATE_4P8MHZ; 321 + break; 322 + case ADC_MODE_NORMAL: 323 + case ADC_MODE_LO_HIF: 324 + case ADC_MODE_HIFI: 325 + case ADC_MODE_INVALID: 326 + default: 327 + rate = SWR_CLK_RATE_9P6MHZ; 328 + break; 329 + } 330 + 331 + return rate; 332 + } 333 + 334 + static int wcd939x_set_swr_clk_rate(struct snd_soc_component *component, int rate, int bank) 335 + { 336 + u8 mask = (bank ? 0xF0 : 0x0F); 337 + u8 val = 0; 338 + 339 + switch (rate) { 340 + case SWR_CLK_RATE_0P6MHZ: 341 + val = 6; 342 + break; 343 + case SWR_CLK_RATE_1P2MHZ: 344 + val = 5; 345 + break; 346 + case SWR_CLK_RATE_2P4MHZ: 347 + val = 3; 348 + break; 349 + case SWR_CLK_RATE_4P8MHZ: 350 + val = 1; 351 + break; 352 + case SWR_CLK_RATE_9P6MHZ: 353 + default: 354 + val = 0; 355 + break; 356 + } 357 + 358 + snd_soc_component_write_field(component, WCD939X_DIGITAL_SWR_TX_CLK_RATE, mask, val); 359 + 360 + return 0; 361 + } 362 + 363 + static int wcd939x_io_init(struct snd_soc_component *component) 364 + { 365 + snd_soc_component_write_field(component, WCD939X_ANA_BIAS, 366 + WCD939X_BIAS_ANALOG_BIAS_EN, true); 367 + snd_soc_component_write_field(component, WCD939X_ANA_BIAS, 368 + WCD939X_BIAS_PRECHRG_EN, true); 369 + 370 + /* 10 msec delay as per HW requirement */ 371 + usleep_range(10000, 10010); 372 + snd_soc_component_write_field(component, WCD939X_ANA_BIAS, 373 + WCD939X_BIAS_PRECHRG_EN, false); 374 + 375 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_L, 376 + WCD939X_RDAC_HD2_CTL_L_HD2_RES_DIV_CTL_L, 0x15); 377 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_R, 378 + WCD939X_RDAC_HD2_CTL_R_HD2_RES_DIV_CTL_R, 0x15); 379 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_DMIC_CTL, 380 + WCD939X_CDC_DMIC_CTL_CLK_SCALE_EN, true); 381 + 382 + snd_soc_component_write_field(component, WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2CASC_ULP, 383 + WCD939X_FE_ICTRL_STG2CASC_ULP_ICTRL_SCBIAS_ULP0P6M, 1); 384 + snd_soc_component_write_field(component, WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2CASC_ULP, 385 + WCD939X_FE_ICTRL_STG2CASC_ULP_VALUE, 4); 386 + 387 + snd_soc_component_write_field(component, WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_ULP, 388 + WCD939X_FE_ICTRL_STG2MAIN_ULP_VALUE, 8); 389 + 390 + snd_soc_component_write_field(component, WCD939X_MICB1_TEST_CTL_1, 391 + WCD939X_TEST_CTL_1_NOISE_FILT_RES_VAL, 7); 392 + snd_soc_component_write_field(component, WCD939X_MICB2_TEST_CTL_1, 393 + WCD939X_TEST_CTL_1_NOISE_FILT_RES_VAL, 7); 394 + snd_soc_component_write_field(component, WCD939X_MICB3_TEST_CTL_1, 395 + WCD939X_TEST_CTL_1_NOISE_FILT_RES_VAL, 7); 396 + snd_soc_component_write_field(component, WCD939X_MICB4_TEST_CTL_1, 397 + WCD939X_TEST_CTL_1_NOISE_FILT_RES_VAL, 7); 398 + snd_soc_component_write_field(component, WCD939X_TX_3_4_TEST_BLK_EN2, 399 + WCD939X_TEST_BLK_EN2_TXFE2_MBHC_CLKRST_EN, false); 400 + 401 + snd_soc_component_write_field(component, WCD939X_HPH_SURGE_EN, 402 + WCD939X_EN_EN_SURGE_PROTECTION_HPHL, false); 403 + snd_soc_component_write_field(component, WCD939X_HPH_SURGE_EN, 404 + WCD939X_EN_EN_SURGE_PROTECTION_HPHR, false); 405 + 406 + snd_soc_component_write_field(component, WCD939X_HPH_OCP_CTL, 407 + WCD939X_OCP_CTL_OCP_FSM_EN, true); 408 + snd_soc_component_write_field(component, WCD939X_HPH_OCP_CTL, 409 + WCD939X_OCP_CTL_SCD_OP_EN, true); 410 + 411 + snd_soc_component_write(component, WCD939X_E_CFG0, 412 + WCD939X_CFG0_IDLE_STEREO | 413 + WCD939X_CFG0_AUTO_DISABLE_ANC); 414 + 415 + return 0; 416 + } 417 + 418 + static int wcd939x_sdw_connect_port(struct wcd939x_sdw_ch_info *ch_info, 419 + struct sdw_port_config *port_config, 420 + u8 enable) 421 + { 422 + u8 ch_mask, port_num; 423 + 424 + port_num = ch_info->port_num; 425 + ch_mask = ch_info->ch_mask; 426 + 427 + port_config->num = port_num; 428 + 429 + if (enable) 430 + port_config->ch_mask |= ch_mask; 431 + else 432 + port_config->ch_mask &= ~ch_mask; 433 + 434 + return 0; 435 + } 436 + 437 + static int wcd939x_connect_port(struct wcd939x_sdw_priv *wcd, u8 port_num, u8 ch_id, u8 enable) 438 + { 439 + return wcd939x_sdw_connect_port(&wcd->ch_info[ch_id], 440 + &wcd->port_config[port_num - 1], 441 + enable); 442 + } 443 + 444 + static int wcd939x_codec_enable_rxclk(struct snd_soc_dapm_widget *w, 445 + struct snd_kcontrol *kcontrol, 446 + int event) 447 + { 448 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 449 + 450 + switch (event) { 451 + case SND_SOC_DAPM_PRE_PMU: 452 + snd_soc_component_write_field(component, WCD939X_ANA_RX_SUPPLIES, 453 + WCD939X_RX_SUPPLIES_RX_BIAS_ENABLE, true); 454 + 455 + /* Analog path clock controls */ 456 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 457 + WCD939X_CDC_ANA_CLK_CTL_ANA_RX_CLK_EN, true); 458 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 459 + WCD939X_CDC_ANA_CLK_CTL_ANA_RX_DIV2_CLK_EN, 460 + true); 461 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 462 + WCD939X_CDC_ANA_CLK_CTL_ANA_RX_DIV4_CLK_EN, 463 + true); 464 + 465 + /* Digital path clock controls */ 466 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 467 + WCD939X_CDC_DIG_CLK_CTL_RXD0_CLK_EN, true); 468 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 469 + WCD939X_CDC_DIG_CLK_CTL_RXD1_CLK_EN, true); 470 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 471 + WCD939X_CDC_DIG_CLK_CTL_RXD2_CLK_EN, true); 472 + break; 473 + case SND_SOC_DAPM_POST_PMD: 474 + snd_soc_component_write_field(component, WCD939X_ANA_RX_SUPPLIES, 475 + WCD939X_RX_SUPPLIES_VNEG_EN, false); 476 + snd_soc_component_write_field(component, WCD939X_ANA_RX_SUPPLIES, 477 + WCD939X_RX_SUPPLIES_VPOS_EN, false); 478 + 479 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 480 + WCD939X_CDC_DIG_CLK_CTL_RXD2_CLK_EN, false); 481 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 482 + WCD939X_CDC_DIG_CLK_CTL_RXD1_CLK_EN, false); 483 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 484 + WCD939X_CDC_DIG_CLK_CTL_RXD0_CLK_EN, false); 485 + 486 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 487 + WCD939X_CDC_ANA_CLK_CTL_ANA_RX_DIV4_CLK_EN, 488 + false); 489 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 490 + WCD939X_CDC_ANA_CLK_CTL_ANA_RX_DIV2_CLK_EN, 491 + false); 492 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 493 + WCD939X_CDC_ANA_CLK_CTL_ANA_RX_CLK_EN, false); 494 + 495 + snd_soc_component_write_field(component, WCD939X_ANA_RX_SUPPLIES, 496 + WCD939X_RX_SUPPLIES_RX_BIAS_ENABLE, false); 497 + 498 + break; 499 + } 500 + 501 + return 0; 502 + } 503 + 504 + static int wcd939x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 505 + struct snd_kcontrol *kcontrol, 506 + int event) 507 + { 508 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 509 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 510 + 511 + switch (event) { 512 + case SND_SOC_DAPM_PRE_PMU: 513 + snd_soc_component_write_field(component, WCD939X_HPH_RDAC_CLK_CTL1, 514 + WCD939X_RDAC_CLK_CTL1_OPAMP_CHOP_CLK_EN, 515 + false); 516 + 517 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_HPH_GAIN_CTL, 518 + WCD939X_CDC_HPH_GAIN_CTL_HPHL_RX_EN, true); 519 + break; 520 + case SND_SOC_DAPM_POST_PMU: 521 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_L, 522 + WCD939X_RDAC_HD2_CTL_L_HD2_RES_DIV_CTL_L, 0x1d); 523 + if (wcd939x->comp1_enable) { 524 + snd_soc_component_write_field(component, 525 + WCD939X_DIGITAL_CDC_COMP_CTL_0, 526 + WCD939X_CDC_COMP_CTL_0_HPHL_COMP_EN, 527 + true); 528 + /* 5msec compander delay as per HW requirement */ 529 + if (!wcd939x->comp2_enable || 530 + snd_soc_component_read_field(component, 531 + WCD939X_DIGITAL_CDC_COMP_CTL_0, 532 + WCD939X_CDC_COMP_CTL_0_HPHR_COMP_EN)) 533 + usleep_range(5000, 5010); 534 + 535 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_TIMER1, 536 + WCD939X_TIMER1_AUTOCHOP_TIMER_CTL_EN, 537 + false); 538 + } else { 539 + snd_soc_component_write_field(component, 540 + WCD939X_DIGITAL_CDC_COMP_CTL_0, 541 + WCD939X_CDC_COMP_CTL_0_HPHL_COMP_EN, 542 + false); 543 + snd_soc_component_write_field(component, WCD939X_HPH_L_EN, 544 + WCD939X_L_EN_GAIN_SOURCE_SEL, true); 545 + } 546 + break; 547 + case SND_SOC_DAPM_POST_PMD: 548 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_L, 549 + WCD939X_RDAC_HD2_CTL_L_HD2_RES_DIV_CTL_L, 1); 550 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_HPH_GAIN_CTL, 551 + WCD939X_CDC_HPH_GAIN_CTL_HPHL_RX_EN, false); 552 + break; 553 + } 554 + 555 + return 0; 556 + } 557 + 558 + static int wcd939x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 559 + struct snd_kcontrol *kcontrol, 560 + int event) 561 + { 562 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 563 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 564 + 565 + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, 566 + w->name, event); 567 + 568 + switch (event) { 569 + case SND_SOC_DAPM_PRE_PMU: 570 + snd_soc_component_write_field(component, WCD939X_HPH_RDAC_CLK_CTL1, 571 + WCD939X_RDAC_CLK_CTL1_OPAMP_CHOP_CLK_EN, 572 + false); 573 + 574 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_HPH_GAIN_CTL, 575 + WCD939X_CDC_HPH_GAIN_CTL_HPHR_RX_EN, true); 576 + break; 577 + case SND_SOC_DAPM_POST_PMU: 578 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_R, 579 + WCD939X_RDAC_HD2_CTL_R_HD2_RES_DIV_CTL_R, 0x1d); 580 + if (wcd939x->comp2_enable) { 581 + snd_soc_component_write_field(component, 582 + WCD939X_DIGITAL_CDC_COMP_CTL_0, 583 + WCD939X_CDC_COMP_CTL_0_HPHR_COMP_EN, 584 + true); 585 + /* 5msec compander delay as per HW requirement */ 586 + if (!wcd939x->comp1_enable || 587 + snd_soc_component_read_field(component, 588 + WCD939X_DIGITAL_CDC_COMP_CTL_0, 589 + WCD939X_CDC_COMP_CTL_0_HPHL_COMP_EN)) 590 + usleep_range(5000, 5010); 591 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_TIMER1, 592 + WCD939X_TIMER1_AUTOCHOP_TIMER_CTL_EN, 593 + false); 594 + } else { 595 + snd_soc_component_write_field(component, 596 + WCD939X_DIGITAL_CDC_COMP_CTL_0, 597 + WCD939X_CDC_COMP_CTL_0_HPHR_COMP_EN, 598 + false); 599 + snd_soc_component_write_field(component, WCD939X_HPH_R_EN, 600 + WCD939X_R_EN_GAIN_SOURCE_SEL, true); 601 + } 602 + break; 603 + case SND_SOC_DAPM_POST_PMD: 604 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_R, 605 + WCD939X_RDAC_HD2_CTL_R_HD2_RES_DIV_CTL_R, 1); 606 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_HPH_GAIN_CTL, 607 + WCD939X_CDC_HPH_GAIN_CTL_HPHR_RX_EN, false); 608 + break; 609 + } 610 + 611 + return 0; 612 + } 613 + 614 + static int wcd939x_codec_ear_dac_event(struct snd_soc_dapm_widget *w, 615 + struct snd_kcontrol *kcontrol, 616 + int event) 617 + { 618 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 619 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 620 + 621 + switch (event) { 622 + case SND_SOC_DAPM_PRE_PMU: 623 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_EAR_GAIN_CTL, 624 + WCD939X_CDC_EAR_GAIN_CTL_EAR_EN, true); 625 + 626 + snd_soc_component_write_field(component, WCD939X_EAR_DAC_CON, 627 + WCD939X_DAC_CON_DAC_SAMPLE_EDGE_SEL, false); 628 + 629 + /* 5 msec delay as per HW requirement */ 630 + usleep_range(5000, 5010); 631 + wcd_clsh_ctrl_set_state(wcd939x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, 632 + WCD_CLSH_STATE_EAR, CLS_AB_HIFI); 633 + 634 + snd_soc_component_write_field(component, WCD939X_FLYBACK_VNEG_CTRL_4, 635 + WCD939X_VNEG_CTRL_4_ILIM_SEL, 0xd); 636 + break; 637 + case SND_SOC_DAPM_POST_PMD: 638 + snd_soc_component_write_field(component, WCD939X_EAR_DAC_CON, 639 + WCD939X_DAC_CON_DAC_SAMPLE_EDGE_SEL, true); 640 + break; 641 + } 642 + 643 + return 0; 644 + } 645 + 646 + static int wcd939x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, 647 + struct snd_kcontrol *kcontrol, 648 + int event) 649 + { 650 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 651 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 652 + int hph_mode = wcd939x->hph_mode; 653 + 654 + switch (event) { 655 + case SND_SOC_DAPM_PRE_PMU: 656 + if (wcd939x->ldoh) 657 + snd_soc_component_write_field(component, WCD939X_LDOH_MODE, 658 + WCD939X_MODE_LDOH_EN, true); 659 + 660 + wcd_clsh_ctrl_set_state(wcd939x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, 661 + WCD_CLSH_STATE_HPHR, hph_mode); 662 + wcd_clsh_set_hph_mode(wcd939x->clsh_info, CLS_H_HIFI); 663 + 664 + if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI || hph_mode == CLS_H_ULP) 665 + snd_soc_component_write_field(component, 666 + WCD939X_HPH_REFBUFF_LP_CTL, 667 + WCD939X_REFBUFF_LP_CTL_PREREF_FILT_BYPASS, true); 668 + if (hph_mode == CLS_H_LOHIFI) 669 + snd_soc_component_write_field(component, WCD939X_ANA_HPH, 670 + WCD939X_HPH_PWR_LEVEL, 0); 671 + 672 + snd_soc_component_write_field(component, WCD939X_FLYBACK_VNEG_CTRL_4, 673 + WCD939X_VNEG_CTRL_4_ILIM_SEL, 0xd); 674 + snd_soc_component_write_field(component, WCD939X_ANA_HPH, 675 + WCD939X_HPH_HPHR_REF_ENABLE, true); 676 + 677 + if (snd_soc_component_read_field(component, WCD939X_ANA_HPH, 678 + WCD939X_HPH_HPHL_REF_ENABLE)) 679 + usleep_range(2500, 2600); /* 2.5msec delay as per HW requirement */ 680 + 681 + set_bit(HPH_PA_DELAY, &wcd939x->status_mask); 682 + snd_soc_component_write_field(component, WCD939X_DIGITAL_PDM_WD_CTL1, 683 + WCD939X_PDM_WD_CTL1_PDM_WD_EN, 3); 684 + break; 685 + case SND_SOC_DAPM_POST_PMU: 686 + /* 687 + * 7ms sleep is required if compander is enabled as per 688 + * HW requirement. If compander is disabled, then 689 + * 20ms delay is required. 690 + */ 691 + if (test_bit(HPH_PA_DELAY, &wcd939x->status_mask)) { 692 + if (!wcd939x->comp2_enable) 693 + usleep_range(20000, 20100); 694 + else 695 + usleep_range(7000, 7100); 696 + 697 + if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI || 698 + hph_mode == CLS_H_ULP) 699 + snd_soc_component_write_field(component, 700 + WCD939X_HPH_REFBUFF_LP_CTL, 701 + WCD939X_REFBUFF_LP_CTL_PREREF_FILT_BYPASS, 702 + false); 703 + clear_bit(HPH_PA_DELAY, &wcd939x->status_mask); 704 + } 705 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_TIMER1, 706 + WCD939X_TIMER1_AUTOCHOP_TIMER_CTL_EN, true); 707 + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI || 708 + hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI) 709 + snd_soc_component_write_field(component, WCD939X_ANA_RX_SUPPLIES, 710 + WCD939X_RX_SUPPLIES_REGULATOR_MODE, 711 + true); 712 + 713 + enable_irq(wcd939x->hphr_pdm_wd_int); 714 + break; 715 + case SND_SOC_DAPM_PRE_PMD: 716 + disable_irq_nosync(wcd939x->hphr_pdm_wd_int); 717 + /* 718 + * 7ms sleep is required if compander is enabled as per 719 + * HW requirement. If compander is disabled, then 720 + * 20ms delay is required. 721 + */ 722 + if (!wcd939x->comp2_enable) 723 + usleep_range(20000, 20100); 724 + else 725 + usleep_range(7000, 7100); 726 + 727 + snd_soc_component_write_field(component, WCD939X_ANA_HPH, 728 + WCD939X_HPH_HPHR_ENABLE, false); 729 + 730 + wcd_mbhc_event_notify(wcd939x->wcd_mbhc, 731 + WCD_EVENT_PRE_HPHR_PA_OFF); 732 + set_bit(HPH_PA_DELAY, &wcd939x->status_mask); 733 + break; 734 + case SND_SOC_DAPM_POST_PMD: 735 + /* 736 + * 7ms sleep is required if compander is enabled as per 737 + * HW requirement. If compander is disabled, then 738 + * 20ms delay is required. 739 + */ 740 + if (test_bit(HPH_PA_DELAY, &wcd939x->status_mask)) { 741 + if (!wcd939x->comp2_enable) 742 + usleep_range(20000, 20100); 743 + else 744 + usleep_range(7000, 7100); 745 + clear_bit(HPH_PA_DELAY, &wcd939x->status_mask); 746 + } 747 + wcd_mbhc_event_notify(wcd939x->wcd_mbhc, 748 + WCD_EVENT_POST_HPHR_PA_OFF); 749 + 750 + snd_soc_component_write_field(component, WCD939X_ANA_HPH, 751 + WCD939X_HPH_HPHR_REF_ENABLE, false); 752 + snd_soc_component_write_field(component, WCD939X_DIGITAL_PDM_WD_CTL1, 753 + WCD939X_PDM_WD_CTL1_PDM_WD_EN, 0); 754 + 755 + wcd_clsh_ctrl_set_state(wcd939x->clsh_info, WCD_CLSH_EVENT_POST_PA, 756 + WCD_CLSH_STATE_HPHR, hph_mode); 757 + if (wcd939x->ldoh) 758 + snd_soc_component_write_field(component, WCD939X_LDOH_MODE, 759 + WCD939X_MODE_LDOH_EN, false); 760 + break; 761 + } 762 + 763 + return 0; 764 + } 765 + 766 + static int wcd939x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, 767 + struct snd_kcontrol *kcontrol, 768 + int event) 769 + { 770 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 771 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 772 + int hph_mode = wcd939x->hph_mode; 773 + 774 + dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__, 775 + w->name, event); 776 + 777 + switch (event) { 778 + case SND_SOC_DAPM_PRE_PMU: 779 + if (wcd939x->ldoh) 780 + snd_soc_component_write_field(component, WCD939X_LDOH_MODE, 781 + WCD939X_MODE_LDOH_EN, true); 782 + wcd_clsh_ctrl_set_state(wcd939x->clsh_info, WCD_CLSH_EVENT_PRE_DAC, 783 + WCD_CLSH_STATE_HPHL, hph_mode); 784 + wcd_clsh_set_hph_mode(wcd939x->clsh_info, CLS_H_HIFI); 785 + 786 + if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI || hph_mode == CLS_H_ULP) 787 + snd_soc_component_write_field(component, 788 + WCD939X_HPH_REFBUFF_LP_CTL, 789 + WCD939X_REFBUFF_LP_CTL_PREREF_FILT_BYPASS, 790 + true); 791 + if (hph_mode == CLS_H_LOHIFI) 792 + snd_soc_component_write_field(component, WCD939X_ANA_HPH, 793 + WCD939X_HPH_PWR_LEVEL, 0); 794 + 795 + snd_soc_component_write_field(component, WCD939X_FLYBACK_VNEG_CTRL_4, 796 + WCD939X_VNEG_CTRL_4_ILIM_SEL, 0xd); 797 + snd_soc_component_write_field(component, WCD939X_ANA_HPH, 798 + WCD939X_HPH_HPHL_REF_ENABLE, true); 799 + 800 + if (snd_soc_component_read_field(component, WCD939X_ANA_HPH, 801 + WCD939X_HPH_HPHR_REF_ENABLE)) 802 + usleep_range(2500, 2600); /* 2.5msec delay as per HW requirement */ 803 + 804 + set_bit(HPH_PA_DELAY, &wcd939x->status_mask); 805 + snd_soc_component_write_field(component, WCD939X_DIGITAL_PDM_WD_CTL0, 806 + WCD939X_PDM_WD_CTL0_PDM_WD_EN, 3); 807 + break; 808 + case SND_SOC_DAPM_POST_PMU: 809 + /* 810 + * 7ms sleep is required if compander is enabled as per 811 + * HW requirement. If compander is disabled, then 812 + * 20ms delay is required. 813 + */ 814 + if (test_bit(HPH_PA_DELAY, &wcd939x->status_mask)) { 815 + if (!wcd939x->comp1_enable) 816 + usleep_range(20000, 20100); 817 + else 818 + usleep_range(7000, 7100); 819 + if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI || 820 + hph_mode == CLS_H_ULP) 821 + snd_soc_component_write_field(component, 822 + WCD939X_HPH_REFBUFF_LP_CTL, 823 + WCD939X_REFBUFF_LP_CTL_PREREF_FILT_BYPASS, 824 + false); 825 + clear_bit(HPH_PA_DELAY, &wcd939x->status_mask); 826 + } 827 + snd_soc_component_write_field(component, WCD939X_HPH_NEW_INT_TIMER1, 828 + WCD939X_TIMER1_AUTOCHOP_TIMER_CTL_EN, true); 829 + if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI || 830 + hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI) 831 + snd_soc_component_write_field(component, WCD939X_ANA_RX_SUPPLIES, 832 + WCD939X_RX_SUPPLIES_REGULATOR_MODE, 833 + true); 834 + enable_irq(wcd939x->hphl_pdm_wd_int); 835 + break; 836 + case SND_SOC_DAPM_PRE_PMD: 837 + disable_irq_nosync(wcd939x->hphl_pdm_wd_int); 838 + /* 839 + * 7ms sleep is required if compander is enabled as per 840 + * HW requirement. If compander is disabled, then 841 + * 20ms delay is required. 842 + */ 843 + if (!wcd939x->comp1_enable) 844 + usleep_range(20000, 20100); 845 + else 846 + usleep_range(7000, 7100); 847 + 848 + snd_soc_component_write_field(component, WCD939X_ANA_HPH, 849 + WCD939X_HPH_HPHL_ENABLE, false); 850 + 851 + wcd_mbhc_event_notify(wcd939x->wcd_mbhc, WCD_EVENT_PRE_HPHL_PA_OFF); 852 + set_bit(HPH_PA_DELAY, &wcd939x->status_mask); 853 + break; 854 + case SND_SOC_DAPM_POST_PMD: 855 + /* 856 + * 7ms sleep is required if compander is enabled as per 857 + * HW requirement. If compander is disabled, then 858 + * 20ms delay is required. 859 + */ 860 + if (test_bit(HPH_PA_DELAY, &wcd939x->status_mask)) { 861 + if (!wcd939x->comp1_enable) 862 + usleep_range(21000, 21100); 863 + else 864 + usleep_range(7000, 7100); 865 + clear_bit(HPH_PA_DELAY, &wcd939x->status_mask); 866 + } 867 + wcd_mbhc_event_notify(wcd939x->wcd_mbhc, 868 + WCD_EVENT_POST_HPHL_PA_OFF); 869 + snd_soc_component_write_field(component, WCD939X_ANA_HPH, 870 + WCD939X_HPH_HPHL_REF_ENABLE, false); 871 + snd_soc_component_write_field(component, WCD939X_DIGITAL_PDM_WD_CTL0, 872 + WCD939X_PDM_WD_CTL0_PDM_WD_EN, 0); 873 + wcd_clsh_ctrl_set_state(wcd939x->clsh_info, WCD_CLSH_EVENT_POST_PA, 874 + WCD_CLSH_STATE_HPHL, hph_mode); 875 + if (wcd939x->ldoh) 876 + snd_soc_component_write_field(component, WCD939X_LDOH_MODE, 877 + WCD939X_MODE_LDOH_EN, false); 878 + break; 879 + } 880 + 881 + return 0; 882 + } 883 + 884 + static int wcd939x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, 885 + struct snd_kcontrol *kcontrol, int event) 886 + { 887 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 888 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 889 + 890 + switch (event) { 891 + case SND_SOC_DAPM_PRE_PMU: 892 + /* Enable watchdog interrupt for HPHL */ 893 + snd_soc_component_write_field(component, WCD939X_DIGITAL_PDM_WD_CTL0, 894 + WCD939X_PDM_WD_CTL0_PDM_WD_EN, 3); 895 + /* For EAR, use CLASS_AB regulator mode */ 896 + snd_soc_component_write_field(component, WCD939X_ANA_RX_SUPPLIES, 897 + WCD939X_RX_SUPPLIES_REGULATOR_MODE, true); 898 + snd_soc_component_write_field(component, WCD939X_ANA_EAR_COMPANDER_CTL, 899 + WCD939X_EAR_COMPANDER_CTL_GAIN_OVRD_REG, true); 900 + break; 901 + case SND_SOC_DAPM_POST_PMU: 902 + /* 6 msec delay as per HW requirement */ 903 + usleep_range(6000, 6010); 904 + enable_irq(wcd939x->ear_pdm_wd_int); 905 + break; 906 + case SND_SOC_DAPM_PRE_PMD: 907 + disable_irq_nosync(wcd939x->ear_pdm_wd_int); 908 + break; 909 + case SND_SOC_DAPM_POST_PMD: 910 + snd_soc_component_write_field(component, WCD939X_ANA_EAR_COMPANDER_CTL, 911 + WCD939X_EAR_COMPANDER_CTL_GAIN_OVRD_REG, 912 + false); 913 + /* 7 msec delay as per HW requirement */ 914 + usleep_range(7000, 7010); 915 + snd_soc_component_write_field(component, WCD939X_DIGITAL_PDM_WD_CTL0, 916 + WCD939X_PDM_WD_CTL0_PDM_WD_EN, 0); 917 + wcd_clsh_ctrl_set_state(wcd939x->clsh_info, WCD_CLSH_EVENT_POST_PA, 918 + WCD_CLSH_STATE_EAR, CLS_AB_HIFI); 919 + break; 920 + } 921 + 922 + return 0; 923 + } 924 + 925 + /* TX Controls */ 926 + 927 + static int wcd939x_codec_enable_dmic(struct snd_soc_dapm_widget *w, 928 + struct snd_kcontrol *kcontrol, 929 + int event) 930 + { 931 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 932 + u16 dmic_clk_reg, dmic_clk_en_reg; 933 + u8 dmic_clk_en_mask; 934 + u8 dmic_ctl_mask; 935 + u8 dmic_clk_mask; 936 + 937 + switch (w->shift) { 938 + case 0: 939 + case 1: 940 + dmic_clk_reg = WCD939X_DIGITAL_CDC_DMIC_RATE_1_2; 941 + dmic_clk_en_reg = WCD939X_DIGITAL_CDC_DMIC1_CTL; 942 + dmic_clk_en_mask = WCD939X_CDC_DMIC1_CTL_DMIC_CLK_EN; 943 + dmic_clk_mask = WCD939X_CDC_DMIC_RATE_1_2_DMIC1_RATE; 944 + dmic_ctl_mask = WCD939X_CDC_AMIC_CTL_AMIC1_IN_SEL; 945 + break; 946 + case 2: 947 + case 3: 948 + dmic_clk_reg = WCD939X_DIGITAL_CDC_DMIC_RATE_1_2; 949 + dmic_clk_en_reg = WCD939X_DIGITAL_CDC_DMIC2_CTL; 950 + dmic_clk_en_mask = WCD939X_CDC_DMIC2_CTL_DMIC_CLK_EN; 951 + dmic_clk_mask = WCD939X_CDC_DMIC_RATE_1_2_DMIC2_RATE; 952 + dmic_ctl_mask = WCD939X_CDC_AMIC_CTL_AMIC3_IN_SEL; 953 + break; 954 + case 4: 955 + case 5: 956 + dmic_clk_reg = WCD939X_DIGITAL_CDC_DMIC_RATE_3_4; 957 + dmic_clk_en_reg = WCD939X_DIGITAL_CDC_DMIC3_CTL; 958 + dmic_clk_en_mask = WCD939X_CDC_DMIC3_CTL_DMIC_CLK_EN; 959 + dmic_clk_mask = WCD939X_CDC_DMIC_RATE_3_4_DMIC3_RATE; 960 + dmic_ctl_mask = WCD939X_CDC_AMIC_CTL_AMIC4_IN_SEL; 961 + break; 962 + case 6: 963 + case 7: 964 + dmic_clk_reg = WCD939X_DIGITAL_CDC_DMIC_RATE_3_4; 965 + dmic_clk_en_reg = WCD939X_DIGITAL_CDC_DMIC4_CTL; 966 + dmic_clk_en_mask = WCD939X_CDC_DMIC4_CTL_DMIC_CLK_EN; 967 + dmic_clk_mask = WCD939X_CDC_DMIC_RATE_3_4_DMIC4_RATE; 968 + dmic_ctl_mask = WCD939X_CDC_AMIC_CTL_AMIC5_IN_SEL; 969 + break; 970 + default: 971 + dev_err(component->dev, "%s: Invalid DMIC Selection\n", __func__); 972 + return -EINVAL; 973 + }; 974 + 975 + switch (event) { 976 + case SND_SOC_DAPM_PRE_PMU: 977 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_AMIC_CTL, 978 + dmic_ctl_mask, false); 979 + /* 250us sleep as per HW requirement */ 980 + usleep_range(250, 260); 981 + if (w->shift == 2) 982 + snd_soc_component_write_field(component, 983 + WCD939X_DIGITAL_CDC_DMIC2_CTL, 984 + WCD939X_CDC_DMIC2_CTL_DMIC_LEFT_EN, 985 + true); 986 + /* Setting DMIC clock rate to 2.4MHz */ 987 + snd_soc_component_write_field(component, dmic_clk_reg, 988 + dmic_clk_mask, 3); 989 + snd_soc_component_write_field(component, dmic_clk_en_reg, 990 + dmic_clk_en_mask, true); 991 + /* enable clock scaling */ 992 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_DMIC_CTL, 993 + WCD939X_CDC_DMIC_CTL_CLK_SCALE_EN, true); 994 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_DMIC_CTL, 995 + WCD939X_CDC_DMIC_CTL_DMIC_DIV_BAK_EN, true); 996 + break; 997 + case SND_SOC_DAPM_POST_PMD: 998 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_AMIC_CTL, 999 + dmic_ctl_mask, 1); 1000 + if (w->shift == 2) 1001 + snd_soc_component_write_field(component, 1002 + WCD939X_DIGITAL_CDC_DMIC2_CTL, 1003 + WCD939X_CDC_DMIC2_CTL_DMIC_LEFT_EN, 1004 + false); 1005 + snd_soc_component_write_field(component, dmic_clk_en_reg, 1006 + dmic_clk_en_mask, 0); 1007 + break; 1008 + } 1009 + return 0; 1010 + } 1011 + 1012 + static int wcd939x_tx_swr_ctrl(struct snd_soc_dapm_widget *w, 1013 + struct snd_kcontrol *kcontrol, int event) 1014 + { 1015 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1016 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1017 + int bank; 1018 + int rate; 1019 + 1020 + bank = wcd939x_swr_get_current_bank(wcd939x->sdw_priv[AIF1_CAP]->sdev); 1021 + 1022 + switch (event) { 1023 + case SND_SOC_DAPM_PRE_PMU: 1024 + if (strnstr(w->name, "ADC", sizeof("ADC"))) { 1025 + int mode = 0; 1026 + 1027 + if (test_bit(WCD_ADC1, &wcd939x->status_mask)) 1028 + mode |= tx_mode_bit[wcd939x->tx_mode[WCD_ADC1]]; 1029 + if (test_bit(WCD_ADC2, &wcd939x->status_mask)) 1030 + mode |= tx_mode_bit[wcd939x->tx_mode[WCD_ADC2]]; 1031 + if (test_bit(WCD_ADC3, &wcd939x->status_mask)) 1032 + mode |= tx_mode_bit[wcd939x->tx_mode[WCD_ADC3]]; 1033 + if (test_bit(WCD_ADC4, &wcd939x->status_mask)) 1034 + mode |= tx_mode_bit[wcd939x->tx_mode[WCD_ADC4]]; 1035 + 1036 + if (mode) 1037 + rate = wcd939x_get_clk_rate(ffs(mode) - 1); 1038 + else 1039 + rate = wcd939x_get_clk_rate(ADC_MODE_INVALID); 1040 + wcd939x_set_swr_clk_rate(component, rate, bank); 1041 + wcd939x_set_swr_clk_rate(component, rate, !bank); 1042 + } 1043 + break; 1044 + case SND_SOC_DAPM_POST_PMD: 1045 + if (strnstr(w->name, "ADC", sizeof("ADC"))) { 1046 + rate = wcd939x_get_clk_rate(ADC_MODE_INVALID); 1047 + wcd939x_set_swr_clk_rate(component, rate, !bank); 1048 + wcd939x_set_swr_clk_rate(component, rate, bank); 1049 + } 1050 + break; 1051 + } 1052 + 1053 + return 0; 1054 + } 1055 + 1056 + static int wcd939x_get_adc_mode(int val) 1057 + { 1058 + int ret = 0; 1059 + 1060 + switch (val) { 1061 + case ADC_MODE_INVALID: 1062 + ret = ADC_MODE_VAL_NORMAL; 1063 + break; 1064 + case ADC_MODE_HIFI: 1065 + ret = ADC_MODE_VAL_HIFI; 1066 + break; 1067 + case ADC_MODE_LO_HIF: 1068 + ret = ADC_MODE_VAL_LO_HIF; 1069 + break; 1070 + case ADC_MODE_NORMAL: 1071 + ret = ADC_MODE_VAL_NORMAL; 1072 + break; 1073 + case ADC_MODE_LP: 1074 + ret = ADC_MODE_VAL_LP; 1075 + break; 1076 + case ADC_MODE_ULP1: 1077 + ret = ADC_MODE_VAL_ULP1; 1078 + break; 1079 + case ADC_MODE_ULP2: 1080 + ret = ADC_MODE_VAL_ULP2; 1081 + break; 1082 + default: 1083 + ret = -EINVAL; 1084 + break; 1085 + } 1086 + return ret; 1087 + } 1088 + 1089 + static int wcd939x_codec_enable_adc(struct snd_soc_dapm_widget *w, 1090 + struct snd_kcontrol *kcontrol, int event) 1091 + { 1092 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1093 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1094 + 1095 + switch (event) { 1096 + case SND_SOC_DAPM_PRE_PMU: 1097 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 1098 + WCD939X_CDC_ANA_CLK_CTL_ANA_TX_CLK_EN, true); 1099 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 1100 + WCD939X_CDC_ANA_CLK_CTL_ANA_TX_DIV2_CLK_EN, 1101 + true); 1102 + set_bit(w->shift, &wcd939x->status_mask); 1103 + break; 1104 + case SND_SOC_DAPM_POST_PMD: 1105 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 1106 + WCD939X_CDC_ANA_CLK_CTL_ANA_TX_DIV2_CLK_EN, 1107 + false); 1108 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 1109 + WCD939X_CDC_ANA_CLK_CTL_ANA_TX_CLK_EN, 1110 + false); 1111 + clear_bit(w->shift, &wcd939x->status_mask); 1112 + break; 1113 + } 1114 + 1115 + return 0; 1116 + } 1117 + 1118 + static void wcd939x_tx_channel_config(struct snd_soc_component *component, 1119 + int channel, bool init) 1120 + { 1121 + int reg, mask; 1122 + 1123 + switch (channel) { 1124 + case 0: 1125 + reg = WCD939X_ANA_TX_CH2; 1126 + mask = WCD939X_TX_CH2_HPF1_INIT; 1127 + break; 1128 + case 1: 1129 + reg = WCD939X_ANA_TX_CH2; 1130 + mask = WCD939X_TX_CH2_HPF2_INIT; 1131 + break; 1132 + case 2: 1133 + reg = WCD939X_ANA_TX_CH4; 1134 + mask = WCD939X_TX_CH4_HPF3_INIT; 1135 + break; 1136 + case 3: 1137 + reg = WCD939X_ANA_TX_CH4; 1138 + mask = WCD939X_TX_CH4_HPF4_INIT; 1139 + break; 1140 + default: 1141 + return; 1142 + } 1143 + 1144 + snd_soc_component_write_field(component, reg, mask, init); 1145 + } 1146 + 1147 + static int wcd939x_adc_enable_req(struct snd_soc_dapm_widget *w, 1148 + struct snd_kcontrol *kcontrol, int event) 1149 + { 1150 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1151 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1152 + int mode; 1153 + 1154 + switch (event) { 1155 + case SND_SOC_DAPM_PRE_PMU: 1156 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_REQ_CTL, 1157 + WCD939X_CDC_REQ_CTL_FS_RATE_4P8, true); 1158 + snd_soc_component_write_field(component, WCD939X_DIGITAL_CDC_REQ_CTL, 1159 + WCD939X_CDC_REQ_CTL_NO_NOTCH, false); 1160 + 1161 + wcd939x_tx_channel_config(component, w->shift, true); 1162 + mode = wcd939x_get_adc_mode(wcd939x->tx_mode[w->shift]); 1163 + if (mode < 0) { 1164 + dev_info(component->dev, "Invalid ADC mode\n"); 1165 + return -EINVAL; 1166 + } 1167 + 1168 + switch (w->shift) { 1169 + case 0: 1170 + snd_soc_component_write_field(component, 1171 + WCD939X_DIGITAL_CDC_TX_ANA_MODE_0_1, 1172 + WCD939X_CDC_TX_ANA_MODE_0_1_TXD0_MODE, 1173 + mode); 1174 + snd_soc_component_write_field(component, 1175 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1176 + WCD939X_CDC_DIG_CLK_CTL_TXD0_CLK_EN, 1177 + true); 1178 + break; 1179 + case 1: 1180 + snd_soc_component_write_field(component, 1181 + WCD939X_DIGITAL_CDC_TX_ANA_MODE_0_1, 1182 + WCD939X_CDC_TX_ANA_MODE_0_1_TXD1_MODE, 1183 + mode); 1184 + snd_soc_component_write_field(component, 1185 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1186 + WCD939X_CDC_DIG_CLK_CTL_TXD1_CLK_EN, 1187 + true); 1188 + break; 1189 + case 2: 1190 + snd_soc_component_write_field(component, 1191 + WCD939X_DIGITAL_CDC_TX_ANA_MODE_2_3, 1192 + WCD939X_CDC_TX_ANA_MODE_2_3_TXD2_MODE, 1193 + mode); 1194 + snd_soc_component_write_field(component, 1195 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1196 + WCD939X_CDC_DIG_CLK_CTL_TXD2_CLK_EN, 1197 + true); 1198 + break; 1199 + case 3: 1200 + snd_soc_component_write_field(component, 1201 + WCD939X_DIGITAL_CDC_TX_ANA_MODE_2_3, 1202 + WCD939X_CDC_TX_ANA_MODE_2_3_TXD3_MODE, 1203 + mode); 1204 + snd_soc_component_write_field(component, 1205 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1206 + WCD939X_CDC_DIG_CLK_CTL_TXD3_CLK_EN, 1207 + true); 1208 + break; 1209 + default: 1210 + break; 1211 + } 1212 + 1213 + wcd939x_tx_channel_config(component, w->shift, false); 1214 + break; 1215 + case SND_SOC_DAPM_POST_PMD: 1216 + switch (w->shift) { 1217 + case 0: 1218 + snd_soc_component_write_field(component, 1219 + WCD939X_DIGITAL_CDC_TX_ANA_MODE_0_1, 1220 + WCD939X_CDC_TX_ANA_MODE_0_1_TXD0_MODE, 1221 + false); 1222 + snd_soc_component_write_field(component, 1223 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1224 + WCD939X_CDC_DIG_CLK_CTL_TXD0_CLK_EN, 1225 + false); 1226 + break; 1227 + case 1: 1228 + snd_soc_component_write_field(component, 1229 + WCD939X_DIGITAL_CDC_TX_ANA_MODE_0_1, 1230 + WCD939X_CDC_TX_ANA_MODE_0_1_TXD1_MODE, 1231 + false); 1232 + snd_soc_component_write_field(component, 1233 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1234 + WCD939X_CDC_DIG_CLK_CTL_TXD1_CLK_EN, 1235 + false); 1236 + break; 1237 + case 2: 1238 + snd_soc_component_write_field(component, 1239 + WCD939X_DIGITAL_CDC_TX_ANA_MODE_2_3, 1240 + WCD939X_CDC_TX_ANA_MODE_2_3_TXD2_MODE, 1241 + false); 1242 + snd_soc_component_write_field(component, 1243 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1244 + WCD939X_CDC_DIG_CLK_CTL_TXD2_CLK_EN, 1245 + false); 1246 + break; 1247 + case 3: 1248 + snd_soc_component_write_field(component, 1249 + WCD939X_DIGITAL_CDC_TX_ANA_MODE_2_3, 1250 + WCD939X_CDC_TX_ANA_MODE_2_3_TXD3_MODE, 1251 + false); 1252 + snd_soc_component_write_field(component, 1253 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1254 + WCD939X_CDC_DIG_CLK_CTL_TXD3_CLK_EN, 1255 + false); 1256 + break; 1257 + default: 1258 + break; 1259 + } 1260 + break; 1261 + } 1262 + 1263 + return 0; 1264 + } 1265 + 1266 + static int wcd939x_micbias_control(struct snd_soc_component *component, 1267 + int micb_num, int req, bool is_dapm) 1268 + { 1269 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1270 + int micb_index = micb_num - 1; 1271 + u16 micb_field; 1272 + u16 micb_reg; 1273 + 1274 + switch (micb_num) { 1275 + case MIC_BIAS_1: 1276 + micb_reg = WCD939X_ANA_MICB1; 1277 + micb_field = WCD939X_MICB1_ENABLE; 1278 + break; 1279 + case MIC_BIAS_2: 1280 + micb_reg = WCD939X_ANA_MICB2; 1281 + micb_field = WCD939X_MICB2_ENABLE; 1282 + break; 1283 + case MIC_BIAS_3: 1284 + micb_reg = WCD939X_ANA_MICB3; 1285 + micb_field = WCD939X_MICB3_ENABLE; 1286 + break; 1287 + case MIC_BIAS_4: 1288 + micb_reg = WCD939X_ANA_MICB4; 1289 + micb_field = WCD939X_MICB4_ENABLE; 1290 + break; 1291 + default: 1292 + dev_err(component->dev, "%s: Invalid micbias number: %d\n", 1293 + __func__, micb_num); 1294 + return -EINVAL; 1295 + }; 1296 + 1297 + switch (req) { 1298 + case MICB_PULLUP_ENABLE: 1299 + wcd939x->pullup_ref[micb_index]++; 1300 + if (wcd939x->pullup_ref[micb_index] == 1 && 1301 + wcd939x->micb_ref[micb_index] == 0) 1302 + snd_soc_component_write_field(component, micb_reg, 1303 + micb_field, MICB_BIAS_PULL_UP); 1304 + break; 1305 + case MICB_PULLUP_DISABLE: 1306 + if (wcd939x->pullup_ref[micb_index] > 0) 1307 + wcd939x->pullup_ref[micb_index]--; 1308 + if (wcd939x->pullup_ref[micb_index] == 0 && 1309 + wcd939x->micb_ref[micb_index] == 0) 1310 + snd_soc_component_write_field(component, micb_reg, 1311 + micb_field, MICB_BIAS_DISABLE); 1312 + break; 1313 + case MICB_ENABLE: 1314 + wcd939x->micb_ref[micb_index]++; 1315 + if (wcd939x->micb_ref[micb_index] == 1) { 1316 + snd_soc_component_write_field(component, 1317 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1318 + WCD939X_CDC_DIG_CLK_CTL_TXD3_CLK_EN, true); 1319 + snd_soc_component_write_field(component, 1320 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1321 + WCD939X_CDC_DIG_CLK_CTL_TXD2_CLK_EN, true); 1322 + snd_soc_component_write_field(component, 1323 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1324 + WCD939X_CDC_DIG_CLK_CTL_TXD1_CLK_EN, true); 1325 + snd_soc_component_write_field(component, 1326 + WCD939X_DIGITAL_CDC_DIG_CLK_CTL, 1327 + WCD939X_CDC_DIG_CLK_CTL_TXD0_CLK_EN, true); 1328 + snd_soc_component_write_field(component, 1329 + WCD939X_DIGITAL_CDC_ANA_CLK_CTL, 1330 + WCD939X_CDC_ANA_CLK_CTL_ANA_TX_DIV2_CLK_EN, 1331 + true); 1332 + snd_soc_component_write_field(component, 1333 + WCD939X_DIGITAL_CDC_ANA_TX_CLK_CTL, 1334 + WCD939X_CDC_ANA_TX_CLK_CTL_ANA_TXSCBIAS_CLK_EN, 1335 + true); 1336 + snd_soc_component_write_field(component, 1337 + WCD939X_MICB1_TEST_CTL_2, 1338 + WCD939X_TEST_CTL_2_IBIAS_LDO_DRIVER, true); 1339 + snd_soc_component_write_field(component, 1340 + WCD939X_MICB2_TEST_CTL_2, 1341 + WCD939X_TEST_CTL_2_IBIAS_LDO_DRIVER, true); 1342 + snd_soc_component_write_field(component, 1343 + WCD939X_MICB3_TEST_CTL_2, 1344 + WCD939X_TEST_CTL_2_IBIAS_LDO_DRIVER, true); 1345 + snd_soc_component_write_field(component, 1346 + WCD939X_MICB4_TEST_CTL_2, 1347 + WCD939X_TEST_CTL_2_IBIAS_LDO_DRIVER, true); 1348 + snd_soc_component_write_field(component, micb_reg, micb_field, 1349 + MICB_BIAS_ENABLE); 1350 + if (micb_num == MIC_BIAS_2) 1351 + wcd_mbhc_event_notify(wcd939x->wcd_mbhc, 1352 + WCD_EVENT_POST_MICBIAS_2_ON); 1353 + } 1354 + if (micb_num == MIC_BIAS_2 && is_dapm) 1355 + wcd_mbhc_event_notify(wcd939x->wcd_mbhc, 1356 + WCD_EVENT_POST_DAPM_MICBIAS_2_ON); 1357 + break; 1358 + case MICB_DISABLE: 1359 + if (wcd939x->micb_ref[micb_index] > 0) 1360 + wcd939x->micb_ref[micb_index]--; 1361 + 1362 + if (wcd939x->micb_ref[micb_index] == 0 && 1363 + wcd939x->pullup_ref[micb_index] > 0) 1364 + snd_soc_component_write_field(component, micb_reg, 1365 + micb_field, MICB_BIAS_PULL_UP); 1366 + else if (wcd939x->micb_ref[micb_index] == 0 && 1367 + wcd939x->pullup_ref[micb_index] == 0) { 1368 + if (micb_num == MIC_BIAS_2) 1369 + wcd_mbhc_event_notify(wcd939x->wcd_mbhc, 1370 + WCD_EVENT_PRE_MICBIAS_2_OFF); 1371 + 1372 + snd_soc_component_write_field(component, micb_reg, 1373 + micb_field, MICB_BIAS_DISABLE); 1374 + if (micb_num == MIC_BIAS_2) 1375 + wcd_mbhc_event_notify(wcd939x->wcd_mbhc, 1376 + WCD_EVENT_POST_MICBIAS_2_OFF); 1377 + } 1378 + if (is_dapm && micb_num == MIC_BIAS_2) 1379 + wcd_mbhc_event_notify(wcd939x->wcd_mbhc, 1380 + WCD_EVENT_POST_DAPM_MICBIAS_2_OFF); 1381 + break; 1382 + } 1383 + 1384 + return 0; 1385 + } 1386 + 1387 + static int wcd939x_codec_enable_micbias(struct snd_soc_dapm_widget *w, 1388 + struct snd_kcontrol *kcontrol, 1389 + int event) 1390 + { 1391 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1392 + int micb_num = w->shift; 1393 + 1394 + switch (event) { 1395 + case SND_SOC_DAPM_PRE_PMU: 1396 + wcd939x_micbias_control(component, micb_num, MICB_ENABLE, true); 1397 + break; 1398 + case SND_SOC_DAPM_POST_PMU: 1399 + /* 1 msec delay as per HW requirement */ 1400 + usleep_range(1000, 1100); 1401 + break; 1402 + case SND_SOC_DAPM_POST_PMD: 1403 + wcd939x_micbias_control(component, micb_num, MICB_DISABLE, true); 1404 + break; 1405 + } 1406 + 1407 + return 0; 1408 + } 1409 + 1410 + static int wcd939x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w, 1411 + struct snd_kcontrol *kcontrol, 1412 + int event) 1413 + { 1414 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1415 + int micb_num = w->shift; 1416 + 1417 + switch (event) { 1418 + case SND_SOC_DAPM_PRE_PMU: 1419 + wcd939x_micbias_control(component, micb_num, 1420 + MICB_PULLUP_ENABLE, true); 1421 + break; 1422 + case SND_SOC_DAPM_POST_PMU: 1423 + /* 1 msec delay as per HW requirement */ 1424 + usleep_range(1000, 1100); 1425 + break; 1426 + case SND_SOC_DAPM_POST_PMD: 1427 + wcd939x_micbias_control(component, micb_num, 1428 + MICB_PULLUP_DISABLE, true); 1429 + break; 1430 + } 1431 + 1432 + return 0; 1433 + } 1434 + 1435 + static int wcd939x_tx_mode_get(struct snd_kcontrol *kcontrol, 1436 + struct snd_ctl_elem_value *ucontrol) 1437 + { 1438 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 1439 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1440 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1441 + int path = e->shift_l; 1442 + 1443 + ucontrol->value.enumerated.item[0] = wcd939x->tx_mode[path]; 1444 + 1445 + return 0; 1446 + } 1447 + 1448 + static int wcd939x_tx_mode_put(struct snd_kcontrol *kcontrol, 1449 + struct snd_ctl_elem_value *ucontrol) 1450 + { 1451 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 1452 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1453 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1454 + int path = e->shift_l; 1455 + 1456 + if (wcd939x->tx_mode[path] == ucontrol->value.enumerated.item[0]) 1457 + return 0; 1458 + 1459 + wcd939x->tx_mode[path] = ucontrol->value.enumerated.item[0]; 1460 + 1461 + return 1; 1462 + } 1463 + 1464 + /* RX Controls */ 1465 + 1466 + static int wcd939x_rx_hph_mode_get(struct snd_kcontrol *kcontrol, 1467 + struct snd_ctl_elem_value *ucontrol) 1468 + { 1469 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 1470 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1471 + 1472 + ucontrol->value.integer.value[0] = wcd939x->hph_mode; 1473 + 1474 + return 0; 1475 + } 1476 + 1477 + static int wcd939x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, 1478 + struct snd_ctl_elem_value *ucontrol) 1479 + { 1480 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 1481 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1482 + u32 mode_val; 1483 + 1484 + mode_val = ucontrol->value.enumerated.item[0]; 1485 + 1486 + if (mode_val == wcd939x->hph_mode) 1487 + return 0; 1488 + 1489 + if (wcd939x->variant == WCD9390) { 1490 + switch (mode_val) { 1491 + case CLS_H_NORMAL: 1492 + case CLS_H_LP: 1493 + case CLS_AB: 1494 + case CLS_H_LOHIFI: 1495 + case CLS_H_ULP: 1496 + case CLS_AB_LP: 1497 + case CLS_AB_LOHIFI: 1498 + wcd939x->hph_mode = mode_val; 1499 + return 1; 1500 + } 1501 + } else { 1502 + switch (mode_val) { 1503 + case CLS_H_NORMAL: 1504 + case CLS_H_HIFI: 1505 + case CLS_H_LP: 1506 + case CLS_AB: 1507 + case CLS_H_LOHIFI: 1508 + case CLS_H_ULP: 1509 + case CLS_AB_HIFI: 1510 + case CLS_AB_LP: 1511 + case CLS_AB_LOHIFI: 1512 + wcd939x->hph_mode = mode_val; 1513 + return 1; 1514 + } 1515 + } 1516 + 1517 + dev_dbg(component->dev, "%s: Invalid HPH Mode\n", __func__); 1518 + return -EINVAL; 1519 + } 1520 + 1521 + static int wcd939x_get_compander(struct snd_kcontrol *kcontrol, 1522 + struct snd_ctl_elem_value *ucontrol) 1523 + { 1524 + struct soc_mixer_control *mc = (struct soc_mixer_control *)(kcontrol->private_value); 1525 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 1526 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1527 + 1528 + if (mc->shift) 1529 + ucontrol->value.integer.value[0] = wcd939x->comp2_enable ? 1 : 0; 1530 + else 1531 + ucontrol->value.integer.value[0] = wcd939x->comp1_enable ? 1 : 0; 1532 + 1533 + return 0; 1534 + } 1535 + 1536 + static int wcd939x_set_compander(struct snd_kcontrol *kcontrol, 1537 + struct snd_ctl_elem_value *ucontrol) 1538 + { 1539 + struct soc_mixer_control *mc = (struct soc_mixer_control *)(kcontrol->private_value); 1540 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 1541 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1542 + struct wcd939x_sdw_priv *wcd = wcd939x->sdw_priv[AIF1_PB]; 1543 + bool value = !!ucontrol->value.integer.value[0]; 1544 + int portidx = wcd->ch_info[mc->reg].port_num; 1545 + 1546 + if (mc->shift) 1547 + wcd939x->comp2_enable = value; 1548 + else 1549 + wcd939x->comp1_enable = value; 1550 + 1551 + if (value) 1552 + wcd939x_connect_port(wcd, portidx, mc->reg, true); 1553 + else 1554 + wcd939x_connect_port(wcd, portidx, mc->reg, false); 1555 + 1556 + return 1; 1557 + } 1558 + 1559 + static int wcd939x_ldoh_get(struct snd_kcontrol *kcontrol, 1560 + struct snd_ctl_elem_value *ucontrol) 1561 + { 1562 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 1563 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1564 + 1565 + ucontrol->value.integer.value[0] = wcd939x->ldoh ? 1 : 0; 1566 + 1567 + return 0; 1568 + } 1569 + 1570 + static int wcd939x_ldoh_put(struct snd_kcontrol *kcontrol, 1571 + struct snd_ctl_elem_value *ucontrol) 1572 + { 1573 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 1574 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1575 + 1576 + if (wcd939x->ldoh == !!ucontrol->value.integer.value[0]) 1577 + return 0; 1578 + 1579 + wcd939x->ldoh = !!ucontrol->value.integer.value[0]; 1580 + 1581 + return 1; 1582 + } 1583 + 1584 + static const char * const tx_mode_mux_text_wcd9390[] = { 1585 + "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP", 1586 + }; 1587 + 1588 + static const struct soc_enum tx0_mode_mux_enum_wcd9390 = 1589 + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(tx_mode_mux_text_wcd9390), 1590 + tx_mode_mux_text_wcd9390); 1591 + 1592 + static const struct soc_enum tx1_mode_mux_enum_wcd9390 = 1593 + SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(tx_mode_mux_text_wcd9390), 1594 + tx_mode_mux_text_wcd9390); 1595 + 1596 + static const struct soc_enum tx2_mode_mux_enum_wcd9390 = 1597 + SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(tx_mode_mux_text_wcd9390), 1598 + tx_mode_mux_text_wcd9390); 1599 + 1600 + static const struct soc_enum tx3_mode_mux_enum_wcd9390 = 1601 + SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(tx_mode_mux_text_wcd9390), 1602 + tx_mode_mux_text_wcd9390); 1603 + 1604 + static const char * const tx_mode_mux_text[] = { 1605 + "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP", 1606 + "ADC_ULP1", "ADC_ULP2", 1607 + }; 1608 + 1609 + static const struct soc_enum tx0_mode_mux_enum = 1610 + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(tx_mode_mux_text), 1611 + tx_mode_mux_text); 1612 + 1613 + static const struct soc_enum tx1_mode_mux_enum = 1614 + SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(tx_mode_mux_text), 1615 + tx_mode_mux_text); 1616 + 1617 + static const struct soc_enum tx2_mode_mux_enum = 1618 + SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(tx_mode_mux_text), 1619 + tx_mode_mux_text); 1620 + 1621 + static const struct soc_enum tx3_mode_mux_enum = 1622 + SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(tx_mode_mux_text), 1623 + tx_mode_mux_text); 1624 + 1625 + static const char * const rx_hph_mode_mux_text_wcd9390[] = { 1626 + "CLS_H_NORMAL", "CLS_H_INVALID_1", "CLS_H_LP", "CLS_AB", 1627 + "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_H_INVALID_2", "CLS_AB_LP", 1628 + "CLS_AB_LOHIFI", 1629 + }; 1630 + 1631 + static const struct soc_enum rx_hph_mode_mux_enum_wcd9390 = 1632 + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text_wcd9390), 1633 + rx_hph_mode_mux_text_wcd9390); 1634 + 1635 + static const char * const rx_hph_mode_mux_text[] = { 1636 + "CLS_H_NORMAL", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI", 1637 + "CLS_H_ULP", "CLS_AB_HIFI", "CLS_AB_LP", "CLS_AB_LOHIFI", 1638 + }; 1639 + 1640 + static const struct soc_enum rx_hph_mode_mux_enum = 1641 + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), 1642 + rx_hph_mode_mux_text); 1643 + 1644 + static const struct snd_kcontrol_new wcd9390_snd_controls[] = { 1645 + SOC_SINGLE_TLV("EAR_PA Volume", WCD939X_ANA_EAR_COMPANDER_CTL, 1646 + 2, 0x10, 0, ear_pa_gain), 1647 + 1648 + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum_wcd9390, 1649 + wcd939x_rx_hph_mode_get, wcd939x_rx_hph_mode_put), 1650 + 1651 + SOC_ENUM_EXT("TX0 MODE", tx0_mode_mux_enum_wcd9390, 1652 + wcd939x_tx_mode_get, wcd939x_tx_mode_put), 1653 + SOC_ENUM_EXT("TX1 MODE", tx1_mode_mux_enum_wcd9390, 1654 + wcd939x_tx_mode_get, wcd939x_tx_mode_put), 1655 + SOC_ENUM_EXT("TX2 MODE", tx2_mode_mux_enum_wcd9390, 1656 + wcd939x_tx_mode_get, wcd939x_tx_mode_put), 1657 + SOC_ENUM_EXT("TX3 MODE", tx3_mode_mux_enum_wcd9390, 1658 + wcd939x_tx_mode_get, wcd939x_tx_mode_put), 1659 + }; 1660 + 1661 + static const struct snd_kcontrol_new wcd9395_snd_controls[] = { 1662 + SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, 1663 + wcd939x_rx_hph_mode_get, wcd939x_rx_hph_mode_put), 1664 + 1665 + SOC_ENUM_EXT("TX0 MODE", tx0_mode_mux_enum, 1666 + wcd939x_tx_mode_get, wcd939x_tx_mode_put), 1667 + SOC_ENUM_EXT("TX1 MODE", tx1_mode_mux_enum, 1668 + wcd939x_tx_mode_get, wcd939x_tx_mode_put), 1669 + SOC_ENUM_EXT("TX2 MODE", tx2_mode_mux_enum, 1670 + wcd939x_tx_mode_get, wcd939x_tx_mode_put), 1671 + SOC_ENUM_EXT("TX3 MODE", tx3_mode_mux_enum, 1672 + wcd939x_tx_mode_get, wcd939x_tx_mode_put), 1673 + }; 1674 + 1675 + static const struct snd_kcontrol_new adc1_switch[] = { 1676 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1677 + }; 1678 + 1679 + static const struct snd_kcontrol_new adc2_switch[] = { 1680 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1681 + }; 1682 + 1683 + static const struct snd_kcontrol_new adc3_switch[] = { 1684 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1685 + }; 1686 + 1687 + static const struct snd_kcontrol_new adc4_switch[] = { 1688 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1689 + }; 1690 + 1691 + static const struct snd_kcontrol_new dmic1_switch[] = { 1692 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1693 + }; 1694 + 1695 + static const struct snd_kcontrol_new dmic2_switch[] = { 1696 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1697 + }; 1698 + 1699 + static const struct snd_kcontrol_new dmic3_switch[] = { 1700 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1701 + }; 1702 + 1703 + static const struct snd_kcontrol_new dmic4_switch[] = { 1704 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1705 + }; 1706 + 1707 + static const struct snd_kcontrol_new dmic5_switch[] = { 1708 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1709 + }; 1710 + 1711 + static const struct snd_kcontrol_new dmic6_switch[] = { 1712 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1713 + }; 1714 + 1715 + static const struct snd_kcontrol_new dmic7_switch[] = { 1716 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1717 + }; 1718 + 1719 + static const struct snd_kcontrol_new dmic8_switch[] = { 1720 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1721 + }; 1722 + 1723 + static const struct snd_kcontrol_new ear_rdac_switch[] = { 1724 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1725 + }; 1726 + 1727 + static const struct snd_kcontrol_new hphl_rdac_switch[] = { 1728 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1729 + }; 1730 + 1731 + static const struct snd_kcontrol_new hphr_rdac_switch[] = { 1732 + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0) 1733 + }; 1734 + 1735 + static const char * const adc1_mux_text[] = { 1736 + "CH1_AMIC_DISABLE", "CH1_AMIC1", "CH1_AMIC2", "CH1_AMIC3", "CH1_AMIC4", "CH1_AMIC5" 1737 + }; 1738 + 1739 + static const struct soc_enum adc1_enum = 1740 + SOC_ENUM_SINGLE(WCD939X_TX_NEW_CH12_MUX, 0, 1741 + ARRAY_SIZE(adc1_mux_text), adc1_mux_text); 1742 + 1743 + static const struct snd_kcontrol_new tx_adc1_mux = 1744 + SOC_DAPM_ENUM("ADC1 MUX Mux", adc1_enum); 1745 + 1746 + static const char * const adc2_mux_text[] = { 1747 + "CH2_AMIC_DISABLE", "CH2_AMIC1", "CH2_AMIC2", "CH2_AMIC3", "CH2_AMIC4", "CH2_AMIC5" 1748 + }; 1749 + 1750 + static const struct soc_enum adc2_enum = 1751 + SOC_ENUM_SINGLE(WCD939X_TX_NEW_CH12_MUX, 3, 1752 + ARRAY_SIZE(adc2_mux_text), adc2_mux_text); 1753 + 1754 + static const struct snd_kcontrol_new tx_adc2_mux = 1755 + SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum); 1756 + 1757 + static const char * const adc3_mux_text[] = { 1758 + "CH3_AMIC_DISABLE", "CH3_AMIC1", "CH3_AMIC3", "CH3_AMIC4", "CH3_AMIC5" 1759 + }; 1760 + 1761 + static const struct soc_enum adc3_enum = 1762 + SOC_ENUM_SINGLE(WCD939X_TX_NEW_CH34_MUX, 0, 1763 + ARRAY_SIZE(adc3_mux_text), adc3_mux_text); 1764 + 1765 + static const struct snd_kcontrol_new tx_adc3_mux = 1766 + SOC_DAPM_ENUM("ADC3 MUX Mux", adc3_enum); 1767 + 1768 + static const char * const adc4_mux_text[] = { 1769 + "CH4_AMIC_DISABLE", "CH4_AMIC1", "CH4_AMIC3", "CH4_AMIC4", "CH4_AMIC5" 1770 + }; 1771 + 1772 + static const struct soc_enum adc4_enum = 1773 + SOC_ENUM_SINGLE(WCD939X_TX_NEW_CH34_MUX, 3, 1774 + ARRAY_SIZE(adc4_mux_text), adc4_mux_text); 1775 + 1776 + static const struct snd_kcontrol_new tx_adc4_mux = 1777 + SOC_DAPM_ENUM("ADC4 MUX Mux", adc4_enum); 1778 + 1779 + static const char * const rdac3_mux_text[] = { 1780 + "RX3", "RX1" 1781 + }; 1782 + 1783 + static const struct soc_enum rdac3_enum = 1784 + SOC_ENUM_SINGLE(WCD939X_DIGITAL_CDC_EAR_PATH_CTL, 0, 1785 + ARRAY_SIZE(rdac3_mux_text), rdac3_mux_text); 1786 + 1787 + static const struct snd_kcontrol_new rx_rdac3_mux = 1788 + SOC_DAPM_ENUM("RDAC3_MUX Mux", rdac3_enum); 1789 + 1790 + static int wcd939x_get_swr_port(struct snd_kcontrol *kcontrol, 1791 + struct snd_ctl_elem_value *ucontrol) 1792 + { 1793 + struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; 1794 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 1795 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(comp); 1796 + struct wcd939x_sdw_priv *wcd = wcd939x->sdw_priv[mixer->shift]; 1797 + unsigned int portidx = wcd->ch_info[mixer->reg].port_num; 1798 + 1799 + ucontrol->value.integer.value[0] = wcd->port_enable[portidx] ? 1 : 0; 1800 + 1801 + return 0; 1802 + } 1803 + 1804 + static const char *version_to_str(u32 version) 1805 + { 1806 + switch (version) { 1807 + case WCD939X_VERSION_1_0: 1808 + return __stringify(WCD939X_1_0); 1809 + case WCD939X_VERSION_1_1: 1810 + return __stringify(WCD939X_1_1); 1811 + case WCD939X_VERSION_2_0: 1812 + return __stringify(WCD939X_2_0); 1813 + } 1814 + return NULL; 1815 + } 1816 + 1817 + static int wcd939x_set_swr_port(struct snd_kcontrol *kcontrol, 1818 + struct snd_ctl_elem_value *ucontrol) 1819 + { 1820 + struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; 1821 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 1822 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(comp); 1823 + struct wcd939x_sdw_priv *wcd = wcd939x->sdw_priv[mixer->shift]; 1824 + unsigned int portidx = wcd->ch_info[mixer->reg].port_num; 1825 + 1826 + wcd->port_enable[portidx] = !!ucontrol->value.integer.value[0]; 1827 + 1828 + wcd939x_connect_port(wcd, portidx, mixer->reg, wcd->port_enable[portidx]); 1829 + 1830 + return 1; 1831 + } 1832 + 1833 + /* MBHC Related */ 1834 + 1835 + static void wcd939x_mbhc_clk_setup(struct snd_soc_component *component, 1836 + bool enable) 1837 + { 1838 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_CTL_1, 1839 + WCD939X_CTL_1_RCO_EN, enable); 1840 + } 1841 + 1842 + static void wcd939x_mbhc_mbhc_bias_control(struct snd_soc_component *component, 1843 + bool enable) 1844 + { 1845 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_ELECT, 1846 + WCD939X_MBHC_ELECT_BIAS_EN, enable); 1847 + } 1848 + 1849 + static void wcd939x_mbhc_program_btn_thr(struct snd_soc_component *component, 1850 + int *btn_low, int *btn_high, 1851 + int num_btn, bool is_micbias) 1852 + { 1853 + int i, vth; 1854 + 1855 + if (num_btn > WCD_MBHC_DEF_BUTTONS) { 1856 + dev_err(component->dev, "%s: invalid number of buttons: %d\n", 1857 + __func__, num_btn); 1858 + return; 1859 + } 1860 + 1861 + for (i = 0; i < num_btn; i++) { 1862 + vth = (btn_high[i] * 2) / 25; 1863 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_BTN0 + i, 1864 + WCD939X_MBHC_BTN0_VTH, vth); 1865 + dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n", 1866 + __func__, i, btn_high[i], vth); 1867 + } 1868 + } 1869 + 1870 + static bool wcd939x_mbhc_micb_en_status(struct snd_soc_component *component, int micb_num) 1871 + { 1872 + 1873 + if (micb_num == MIC_BIAS_2) { 1874 + u8 val; 1875 + 1876 + val = FIELD_GET(WCD939X_MICB2_ENABLE, 1877 + snd_soc_component_read(component, WCD939X_ANA_MICB2)); 1878 + if (val == MICB_BIAS_ENABLE) 1879 + return true; 1880 + } 1881 + 1882 + return false; 1883 + } 1884 + 1885 + static void wcd939x_mbhc_hph_l_pull_up_control(struct snd_soc_component *component, 1886 + int pull_up_cur) 1887 + { 1888 + /* Default pull up current to 2uA */ 1889 + if (pull_up_cur > HS_PULLUP_I_OFF || 1890 + pull_up_cur < HS_PULLUP_I_3P0_UA || 1891 + pull_up_cur == HS_PULLUP_I_DEFAULT) 1892 + pull_up_cur = HS_PULLUP_I_2P0_UA; 1893 + 1894 + dev_dbg(component->dev, "%s: HS pull up current:%d\n", 1895 + __func__, pull_up_cur); 1896 + 1897 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_INT_MECH_DET_CURRENT, 1898 + WCD939X_MECH_DET_CURRENT_HSDET_PULLUP_CTL, pull_up_cur); 1899 + } 1900 + 1901 + static int wcd939x_mbhc_request_micbias(struct snd_soc_component *component, 1902 + int micb_num, int req) 1903 + { 1904 + return wcd939x_micbias_control(component, micb_num, req, false); 1905 + } 1906 + 1907 + static void wcd939x_mbhc_micb_ramp_control(struct snd_soc_component *component, 1908 + bool enable) 1909 + { 1910 + if (enable) { 1911 + snd_soc_component_write_field(component, WCD939X_ANA_MICB2_RAMP, 1912 + WCD939X_MICB2_RAMP_SHIFT_CTL, 3); 1913 + snd_soc_component_write_field(component, WCD939X_ANA_MICB2_RAMP, 1914 + WCD939X_MICB2_RAMP_RAMP_ENABLE, true); 1915 + } else { 1916 + snd_soc_component_write_field(component, WCD939X_ANA_MICB2_RAMP, 1917 + WCD939X_MICB2_RAMP_RAMP_ENABLE, false); 1918 + snd_soc_component_write_field(component, WCD939X_ANA_MICB2_RAMP, 1919 + WCD939X_MICB2_RAMP_SHIFT_CTL, 0); 1920 + } 1921 + } 1922 + 1923 + static int wcd939x_get_micb_vout_ctl_val(u32 micb_mv) 1924 + { 1925 + /* min micbias voltage is 1V and maximum is 2.85V */ 1926 + if (micb_mv < 1000 || micb_mv > 2850) { 1927 + pr_err("%s: unsupported micbias voltage\n", __func__); 1928 + return -EINVAL; 1929 + } 1930 + 1931 + return (micb_mv - 1000) / 50; 1932 + } 1933 + 1934 + static int wcd939x_mbhc_micb_adjust_voltage(struct snd_soc_component *component, 1935 + int req_volt, int micb_num) 1936 + { 1937 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 1938 + unsigned int micb_en_field, micb_vout_ctl_field; 1939 + unsigned int micb_reg, cur_vout_ctl, micb_en; 1940 + int req_vout_ctl; 1941 + int ret = 0; 1942 + 1943 + switch (micb_num) { 1944 + case MIC_BIAS_1: 1945 + micb_reg = WCD939X_ANA_MICB1; 1946 + micb_en_field = WCD939X_MICB1_ENABLE; 1947 + micb_vout_ctl_field = WCD939X_MICB1_VOUT_CTL; 1948 + break; 1949 + case MIC_BIAS_2: 1950 + micb_reg = WCD939X_ANA_MICB2; 1951 + micb_en_field = WCD939X_MICB2_ENABLE; 1952 + micb_vout_ctl_field = WCD939X_MICB2_VOUT_CTL; 1953 + break; 1954 + case MIC_BIAS_3: 1955 + micb_reg = WCD939X_ANA_MICB3; 1956 + micb_en_field = WCD939X_MICB3_ENABLE; 1957 + micb_vout_ctl_field = WCD939X_MICB1_VOUT_CTL; 1958 + break; 1959 + case MIC_BIAS_4: 1960 + micb_reg = WCD939X_ANA_MICB4; 1961 + micb_en_field = WCD939X_MICB4_ENABLE; 1962 + micb_vout_ctl_field = WCD939X_MICB2_VOUT_CTL; 1963 + break; 1964 + default: 1965 + return -EINVAL; 1966 + } 1967 + mutex_lock(&wcd939x->micb_lock); 1968 + 1969 + /* 1970 + * If requested micbias voltage is same as current micbias 1971 + * voltage, then just return. Otherwise, adjust voltage as 1972 + * per requested value. If micbias is already enabled, then 1973 + * to avoid slow micbias ramp-up or down enable pull-up 1974 + * momentarily, change the micbias value and then re-enable 1975 + * micbias. 1976 + */ 1977 + micb_en = snd_soc_component_read_field(component, micb_reg, 1978 + micb_en_field); 1979 + cur_vout_ctl = snd_soc_component_read_field(component, micb_reg, 1980 + micb_vout_ctl_field); 1981 + 1982 + req_vout_ctl = wcd939x_get_micb_vout_ctl_val(req_volt); 1983 + if (req_vout_ctl < 0) { 1984 + ret = req_vout_ctl; 1985 + goto exit; 1986 + } 1987 + 1988 + if (cur_vout_ctl == req_vout_ctl) { 1989 + ret = 0; 1990 + goto exit; 1991 + } 1992 + 1993 + dev_dbg(component->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n", 1994 + __func__, micb_num, WCD_VOUT_CTL_TO_MICB(cur_vout_ctl), 1995 + req_volt, micb_en); 1996 + 1997 + if (micb_en == MICB_BIAS_ENABLE) 1998 + snd_soc_component_write_field(component, micb_reg, 1999 + micb_en_field, MICB_BIAS_PULL_DOWN); 2000 + 2001 + snd_soc_component_write_field(component, micb_reg, 2002 + micb_vout_ctl_field, req_vout_ctl); 2003 + 2004 + if (micb_en == MICB_BIAS_ENABLE) { 2005 + snd_soc_component_write_field(component, micb_reg, 2006 + micb_en_field, MICB_BIAS_ENABLE); 2007 + /* 2008 + * Add 2ms delay as per HW requirement after enabling 2009 + * micbias 2010 + */ 2011 + usleep_range(2000, 2100); 2012 + } 2013 + 2014 + exit: 2015 + mutex_unlock(&wcd939x->micb_lock); 2016 + return ret; 2017 + } 2018 + 2019 + static int wcd939x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *component, 2020 + int micb_num, bool req_en) 2021 + { 2022 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 2023 + int micb_mv; 2024 + 2025 + if (micb_num != MIC_BIAS_2) 2026 + return -EINVAL; 2027 + /* 2028 + * If device tree micbias level is already above the minimum 2029 + * voltage needed to detect threshold microphone, then do 2030 + * not change the micbias, just return. 2031 + */ 2032 + if (wcd939x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV) 2033 + return 0; 2034 + 2035 + micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd939x->micb2_mv; 2036 + 2037 + return wcd939x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2); 2038 + } 2039 + 2040 + /* Selected by WCD939X_MBHC_GET_C1() */ 2041 + static const s16 wcd939x_wcd_mbhc_d1_a[4] = { 2042 + 0, 30, 30, 6 2043 + }; 2044 + 2045 + /* Selected by zdet_param.noff */ 2046 + static const int wcd939x_mbhc_mincode_param[] = { 2047 + 3277, 1639, 820, 410, 205, 103, 52, 26 2048 + }; 2049 + 2050 + static const struct zdet_param wcd939x_mbhc_zdet_param = { 2051 + .ldo_ctl = 4, 2052 + .noff = 0, 2053 + .nshift = 6, 2054 + .btn5 = 0x18, 2055 + .btn6 = 0x60, 2056 + .btn7 = 0x78, 2057 + }; 2058 + 2059 + static void wcd939x_mbhc_get_result_params(struct snd_soc_component *component, 2060 + int32_t *zdet) 2061 + { 2062 + const struct zdet_param *zdet_param = &wcd939x_mbhc_zdet_param; 2063 + s32 x1, d1, denom; 2064 + int val; 2065 + s16 c1; 2066 + int i; 2067 + 2068 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_ZDET, 2069 + WCD939X_MBHC_ZDET_ZDET_CHG_EN, true); 2070 + for (i = 0; i < WCD939X_ZDET_NUM_MEASUREMENTS; i++) { 2071 + val = snd_soc_component_read_field(component, WCD939X_ANA_MBHC_RESULT_2, 2072 + WCD939X_MBHC_RESULT_2_Z_RESULT_MSB); 2073 + if (val & BIT(7)) 2074 + break; 2075 + } 2076 + val = val << 8; 2077 + val |= snd_soc_component_read_field(component, WCD939X_ANA_MBHC_RESULT_1, 2078 + WCD939X_MBHC_RESULT_1_Z_RESULT_LSB); 2079 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_ZDET, 2080 + WCD939X_MBHC_ZDET_ZDET_CHG_EN, false); 2081 + x1 = WCD939X_MBHC_GET_X1(val); 2082 + c1 = WCD939X_MBHC_GET_C1(val); 2083 + 2084 + /* If ramp is not complete, give additional 5ms */ 2085 + if (c1 < 2 && x1) 2086 + mdelay(5); 2087 + 2088 + if (!c1 || !x1) { 2089 + dev_dbg(component->dev, 2090 + "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n", 2091 + __func__, c1, x1); 2092 + goto ramp_down; 2093 + } 2094 + 2095 + d1 = wcd939x_wcd_mbhc_d1_a[c1]; 2096 + denom = (x1 * d1) - (1 << (14 - zdet_param->noff)); 2097 + if (denom > 0) 2098 + *zdet = (WCD939X_ANA_MBHC_ZDET_CONST * 1000) / denom; 2099 + else if (x1 < wcd939x_mbhc_mincode_param[zdet_param->noff]) 2100 + *zdet = WCD939X_ZDET_FLOATING_IMPEDANCE; 2101 + 2102 + dev_dbg(component->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n", 2103 + __func__, d1, c1, x1, *zdet); 2104 + ramp_down: 2105 + i = 0; 2106 + while (x1) { 2107 + val = snd_soc_component_read_field(component, WCD939X_ANA_MBHC_RESULT_1, 2108 + WCD939X_MBHC_RESULT_1_Z_RESULT_LSB) << 8; 2109 + val |= snd_soc_component_read_field(component, WCD939X_ANA_MBHC_RESULT_2, 2110 + WCD939X_MBHC_RESULT_2_Z_RESULT_MSB); 2111 + x1 = WCD939X_MBHC_GET_X1(val); 2112 + i++; 2113 + if (i == WCD939X_ZDET_NUM_MEASUREMENTS) 2114 + break; 2115 + } 2116 + } 2117 + 2118 + static void wcd939x_mbhc_zdet_ramp(struct snd_soc_component *component, 2119 + s32 *zl, int32_t *zr) 2120 + { 2121 + const struct zdet_param *zdet_param = &wcd939x_mbhc_zdet_param; 2122 + s32 zdet = 0; 2123 + 2124 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_ZDET_ANA_CTL, 2125 + WCD939X_ZDET_ANA_CTL_MAXV_CTL, zdet_param->ldo_ctl); 2126 + snd_soc_component_update_bits(component, WCD939X_ANA_MBHC_BTN5, WCD939X_MBHC_BTN5_VTH, 2127 + zdet_param->btn5); 2128 + snd_soc_component_update_bits(component, WCD939X_ANA_MBHC_BTN6, WCD939X_MBHC_BTN6_VTH, 2129 + zdet_param->btn6); 2130 + snd_soc_component_update_bits(component, WCD939X_ANA_MBHC_BTN7, WCD939X_MBHC_BTN7_VTH, 2131 + zdet_param->btn7); 2132 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_ZDET_ANA_CTL, 2133 + WCD939X_ZDET_ANA_CTL_RANGE_CTL, zdet_param->noff); 2134 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_ZDET_RAMP_CTL, 2135 + WCD939X_ZDET_RAMP_CTL_TIME_CTL, zdet_param->nshift); 2136 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_ZDET_RAMP_CTL, 2137 + WCD939X_ZDET_RAMP_CTL_ACC1_MIN_CTL, 6); /*acc1_min_63 */ 2138 + 2139 + if (!zl) 2140 + goto z_right; 2141 + 2142 + /* Start impedance measurement for HPH_L */ 2143 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_ZDET, 2144 + WCD939X_MBHC_ZDET_ZDET_L_MEAS_EN, true); 2145 + dev_dbg(component->dev, "%s: ramp for HPH_L, noff = %d\n", 2146 + __func__, zdet_param->noff); 2147 + wcd939x_mbhc_get_result_params(component, &zdet); 2148 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_ZDET, 2149 + WCD939X_MBHC_ZDET_ZDET_L_MEAS_EN, false); 2150 + 2151 + *zl = zdet; 2152 + 2153 + z_right: 2154 + if (!zr) 2155 + return; 2156 + 2157 + /* Start impedance measurement for HPH_R */ 2158 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_ZDET, 2159 + WCD939X_MBHC_ZDET_ZDET_R_MEAS_EN, true); 2160 + dev_dbg(component->dev, "%s: ramp for HPH_R, noff = %d\n", 2161 + __func__, zdet_param->noff); 2162 + wcd939x_mbhc_get_result_params(component, &zdet); 2163 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_ZDET, 2164 + WCD939X_MBHC_ZDET_ZDET_R_MEAS_EN, false); 2165 + 2166 + *zr = zdet; 2167 + } 2168 + 2169 + static void wcd939x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component, 2170 + s32 *z_val, int flag_l_r) 2171 + { 2172 + int q1_cal; 2173 + s16 q1; 2174 + 2175 + q1 = snd_soc_component_read(component, WCD939X_DIGITAL_EFUSE_REG_21 + flag_l_r); 2176 + if (q1 & BIT(7)) 2177 + q1_cal = (10000 - ((q1 & GENMASK(6, 0)) * 10)); 2178 + else 2179 + q1_cal = (10000 + (q1 * 10)); 2180 + 2181 + if (q1_cal > 0) 2182 + *z_val = ((*z_val) * 10000) / q1_cal; 2183 + } 2184 + 2185 + static void wcd939x_wcd_mbhc_calc_impedance(struct snd_soc_component *component, 2186 + u32 *zl, uint32_t *zr) 2187 + { 2188 + struct wcd939x_priv *wcd939x = dev_get_drvdata(component->dev); 2189 + unsigned int reg0, reg1, reg2, reg3, reg4; 2190 + int z_mono, z_diff1, z_diff2; 2191 + bool is_fsm_disable = false; 2192 + s32 z1l, z1r, z1ls; 2193 + 2194 + reg0 = snd_soc_component_read(component, WCD939X_ANA_MBHC_BTN5); 2195 + reg1 = snd_soc_component_read(component, WCD939X_ANA_MBHC_BTN6); 2196 + reg2 = snd_soc_component_read(component, WCD939X_ANA_MBHC_BTN7); 2197 + reg3 = snd_soc_component_read(component, WCD939X_MBHC_CTL_CLK); 2198 + reg4 = snd_soc_component_read(component, WCD939X_MBHC_NEW_ZDET_ANA_CTL); 2199 + 2200 + if (snd_soc_component_read_field(component, WCD939X_ANA_MBHC_ELECT, 2201 + WCD939X_MBHC_ELECT_FSM_EN)) { 2202 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_ELECT, 2203 + WCD939X_MBHC_ELECT_FSM_EN, false); 2204 + is_fsm_disable = true; 2205 + } 2206 + 2207 + /* For NO-jack, disable L_DET_EN before Z-det measurements */ 2208 + if (wcd939x->mbhc_cfg.hphl_swh) 2209 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_MECH, 2210 + WCD939X_MBHC_MECH_L_DET_EN, false); 2211 + 2212 + /* Turn off 100k pull down on HPHL */ 2213 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_MECH, 2214 + WCD939X_MBHC_MECH_SW_HPH_L_P_100K_TO_GND, 2215 + false); 2216 + 2217 + /* 2218 + * Disable surge protection before impedance detection. 2219 + * This is done to give correct value for high impedance. 2220 + */ 2221 + snd_soc_component_write_field(component, WCD939X_HPH_SURGE_EN, 2222 + WCD939X_EN_EN_SURGE_PROTECTION_HPHR, false); 2223 + snd_soc_component_write_field(component, WCD939X_HPH_SURGE_EN, 2224 + WCD939X_EN_EN_SURGE_PROTECTION_HPHL, false); 2225 + 2226 + /* 1ms delay needed after disable surge protection */ 2227 + usleep_range(1000, 1010); 2228 + 2229 + /* First get impedance on Left */ 2230 + wcd939x_mbhc_zdet_ramp(component, &z1l, NULL); 2231 + if (z1l == WCD939X_ZDET_FLOATING_IMPEDANCE || z1l > WCD939X_ZDET_VAL_100K) { 2232 + *zl = WCD939X_ZDET_FLOATING_IMPEDANCE; 2233 + } else { 2234 + *zl = z1l / 1000; 2235 + wcd939x_wcd_mbhc_qfuse_cal(component, zl, 0); 2236 + } 2237 + dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n", 2238 + __func__, *zl); 2239 + 2240 + /* Start of right impedance ramp and calculation */ 2241 + wcd939x_mbhc_zdet_ramp(component, NULL, &z1r); 2242 + if (z1r == WCD939X_ZDET_FLOATING_IMPEDANCE || z1r > WCD939X_ZDET_VAL_100K) { 2243 + *zr = WCD939X_ZDET_FLOATING_IMPEDANCE; 2244 + } else { 2245 + *zr = z1r / 1000; 2246 + wcd939x_wcd_mbhc_qfuse_cal(component, zr, 1); 2247 + } 2248 + dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n", 2249 + __func__, *zr); 2250 + 2251 + /* Mono/stereo detection */ 2252 + if (*zl == WCD939X_ZDET_FLOATING_IMPEDANCE && 2253 + *zr == WCD939X_ZDET_FLOATING_IMPEDANCE) { 2254 + dev_dbg(component->dev, 2255 + "%s: plug type is invalid or extension cable\n", 2256 + __func__); 2257 + goto zdet_complete; 2258 + } 2259 + 2260 + if (*zl == WCD939X_ZDET_FLOATING_IMPEDANCE || 2261 + *zr == WCD939X_ZDET_FLOATING_IMPEDANCE || 2262 + (*zl < WCD_MONO_HS_MIN_THR && *zr > WCD_MONO_HS_MIN_THR) || 2263 + (*zl > WCD_MONO_HS_MIN_THR && *zr < WCD_MONO_HS_MIN_THR)) { 2264 + dev_dbg(component->dev, 2265 + "%s: Mono plug type with one ch floating or shorted to GND\n", 2266 + __func__); 2267 + wcd_mbhc_set_hph_type(wcd939x->wcd_mbhc, WCD_MBHC_HPH_MONO); 2268 + goto zdet_complete; 2269 + } 2270 + 2271 + snd_soc_component_write_field(component, WCD939X_HPH_R_ATEST, 2272 + WCD939X_R_ATEST_HPH_GND_OVR, true); 2273 + snd_soc_component_write_field(component, WCD939X_HPH_PA_CTL2, 2274 + WCD939X_PA_CTL2_HPHPA_GND_R, true); 2275 + wcd939x_mbhc_zdet_ramp(component, &z1ls, NULL); 2276 + snd_soc_component_write_field(component, WCD939X_HPH_PA_CTL2, 2277 + WCD939X_PA_CTL2_HPHPA_GND_R, false); 2278 + snd_soc_component_write_field(component, WCD939X_HPH_R_ATEST, 2279 + WCD939X_R_ATEST_HPH_GND_OVR, false); 2280 + 2281 + z1ls /= 1000; 2282 + wcd939x_wcd_mbhc_qfuse_cal(component, &z1ls, 0); 2283 + 2284 + /* Parallel of left Z and 9 ohm pull down resistor */ 2285 + z_mono = (*zl * 9) / (*zl + 9); 2286 + z_diff1 = z1ls > z_mono ? z1ls - z_mono : z_mono - z1ls; 2287 + z_diff2 = *zl > z1ls ? *zl - z1ls : z1ls - *zl; 2288 + if ((z_diff1 * (*zl + z1ls)) > (z_diff2 * (z1ls + z_mono))) { 2289 + dev_dbg(component->dev, "%s: stereo plug type detected\n", 2290 + __func__); 2291 + wcd_mbhc_set_hph_type(wcd939x->wcd_mbhc, WCD_MBHC_HPH_STEREO); 2292 + } else { 2293 + dev_dbg(component->dev, "%s: MONO plug type detected\n", 2294 + __func__); 2295 + wcd_mbhc_set_hph_type(wcd939x->wcd_mbhc, WCD_MBHC_HPH_MONO); 2296 + } 2297 + 2298 + /* Enable surge protection again after impedance detection */ 2299 + snd_soc_component_write_field(component, WCD939X_HPH_SURGE_EN, 2300 + WCD939X_EN_EN_SURGE_PROTECTION_HPHR, true); 2301 + snd_soc_component_write_field(component, WCD939X_HPH_SURGE_EN, 2302 + WCD939X_EN_EN_SURGE_PROTECTION_HPHL, true); 2303 + 2304 + zdet_complete: 2305 + snd_soc_component_write(component, WCD939X_ANA_MBHC_BTN5, reg0); 2306 + snd_soc_component_write(component, WCD939X_ANA_MBHC_BTN6, reg1); 2307 + snd_soc_component_write(component, WCD939X_ANA_MBHC_BTN7, reg2); 2308 + 2309 + /* Turn on 100k pull down on HPHL */ 2310 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_MECH, 2311 + WCD939X_MBHC_MECH_SW_HPH_L_P_100K_TO_GND, true); 2312 + 2313 + /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ 2314 + if (wcd939x->mbhc_cfg.hphl_swh) 2315 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_MECH, 2316 + WCD939X_MBHC_MECH_L_DET_EN, true); 2317 + 2318 + snd_soc_component_write(component, WCD939X_MBHC_NEW_ZDET_ANA_CTL, reg4); 2319 + snd_soc_component_write(component, WCD939X_MBHC_CTL_CLK, reg3); 2320 + 2321 + if (is_fsm_disable) 2322 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_ELECT, 2323 + WCD939X_MBHC_ELECT_FSM_EN, true); 2324 + } 2325 + 2326 + static void wcd939x_mbhc_gnd_det_ctrl(struct snd_soc_component *component, 2327 + bool enable) 2328 + { 2329 + if (enable) { 2330 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_MECH, 2331 + WCD939X_MBHC_MECH_MECH_HS_G_PULLUP_COMP_EN, 2332 + true); 2333 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_MECH, 2334 + WCD939X_MBHC_MECH_GND_DET_EN, true); 2335 + } else { 2336 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_MECH, 2337 + WCD939X_MBHC_MECH_GND_DET_EN, false); 2338 + snd_soc_component_write_field(component, WCD939X_ANA_MBHC_MECH, 2339 + WCD939X_MBHC_MECH_MECH_HS_G_PULLUP_COMP_EN, 2340 + false); 2341 + } 2342 + } 2343 + 2344 + static void wcd939x_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component, 2345 + bool enable) 2346 + { 2347 + snd_soc_component_write_field(component, WCD939X_HPH_PA_CTL2, 2348 + WCD939X_PA_CTL2_HPHPA_GND_R, enable); 2349 + snd_soc_component_write_field(component, WCD939X_HPH_PA_CTL2, 2350 + WCD939X_PA_CTL2_HPHPA_GND_L, enable); 2351 + } 2352 + 2353 + static void wcd939x_mbhc_moisture_config(struct snd_soc_component *component) 2354 + { 2355 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 2356 + 2357 + if (wcd939x->mbhc_cfg.moist_rref == R_OFF || wcd939x->typec_analog_mux) { 2358 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_CTL_2, 2359 + WCD939X_CTL_2_M_RTH_CTL, R_OFF); 2360 + return; 2361 + } 2362 + 2363 + /* Do not enable moisture detection if jack type is NC */ 2364 + if (!wcd939x->mbhc_cfg.hphl_swh) { 2365 + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", 2366 + __func__); 2367 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_CTL_2, 2368 + WCD939X_CTL_2_M_RTH_CTL, R_OFF); 2369 + return; 2370 + } 2371 + 2372 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_CTL_2, 2373 + WCD939X_CTL_2_M_RTH_CTL, wcd939x->mbhc_cfg.moist_rref); 2374 + } 2375 + 2376 + static void wcd939x_mbhc_moisture_detect_en(struct snd_soc_component *component, bool enable) 2377 + { 2378 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 2379 + 2380 + if (enable) 2381 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_CTL_2, 2382 + WCD939X_CTL_2_M_RTH_CTL, 2383 + wcd939x->mbhc_cfg.moist_rref); 2384 + else 2385 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_CTL_2, 2386 + WCD939X_CTL_2_M_RTH_CTL, R_OFF); 2387 + } 2388 + 2389 + static bool wcd939x_mbhc_get_moisture_status(struct snd_soc_component *component) 2390 + { 2391 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 2392 + bool ret = false; 2393 + 2394 + if (wcd939x->mbhc_cfg.moist_rref == R_OFF || wcd939x->typec_analog_mux) { 2395 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_CTL_2, 2396 + WCD939X_CTL_2_M_RTH_CTL, R_OFF); 2397 + goto done; 2398 + } 2399 + 2400 + /* Do not enable moisture detection if jack type is NC */ 2401 + if (!wcd939x->mbhc_cfg.hphl_swh) { 2402 + dev_dbg(component->dev, "%s: disable moisture detection for NC\n", 2403 + __func__); 2404 + snd_soc_component_write_field(component, WCD939X_MBHC_NEW_CTL_2, 2405 + WCD939X_CTL_2_M_RTH_CTL, R_OFF); 2406 + goto done; 2407 + } 2408 + 2409 + /* 2410 + * If moisture_en is already enabled, then skip to plug type 2411 + * detection. 2412 + */ 2413 + if (snd_soc_component_read_field(component, WCD939X_MBHC_NEW_CTL_2, 2414 + WCD939X_CTL_2_M_RTH_CTL)) 2415 + goto done; 2416 + 2417 + wcd939x_mbhc_moisture_detect_en(component, true); 2418 + 2419 + /* Read moisture comparator status, invert of status bit */ 2420 + ret = !snd_soc_component_read_field(component, WCD939X_MBHC_NEW_FSM_STATUS, 2421 + WCD939X_FSM_STATUS_HS_M_COMP_STATUS); 2422 + done: 2423 + return ret; 2424 + } 2425 + 2426 + static void wcd939x_mbhc_moisture_polling_ctrl(struct snd_soc_component *component, 2427 + bool enable) 2428 + { 2429 + snd_soc_component_write_field(component, 2430 + WCD939X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 2431 + WCD939X_MOISTURE_DET_POLLING_CTRL_MOIST_EN_POLLING, 2432 + enable); 2433 + } 2434 + 2435 + static const struct wcd_mbhc_cb mbhc_cb = { 2436 + .clk_setup = wcd939x_mbhc_clk_setup, 2437 + .mbhc_bias = wcd939x_mbhc_mbhc_bias_control, 2438 + .set_btn_thr = wcd939x_mbhc_program_btn_thr, 2439 + .micbias_enable_status = wcd939x_mbhc_micb_en_status, 2440 + .hph_pull_up_control_v2 = wcd939x_mbhc_hph_l_pull_up_control, 2441 + .mbhc_micbias_control = wcd939x_mbhc_request_micbias, 2442 + .mbhc_micb_ramp_control = wcd939x_mbhc_micb_ramp_control, 2443 + .mbhc_micb_ctrl_thr_mic = wcd939x_mbhc_micb_ctrl_threshold_mic, 2444 + .compute_impedance = wcd939x_wcd_mbhc_calc_impedance, 2445 + .mbhc_gnd_det_ctrl = wcd939x_mbhc_gnd_det_ctrl, 2446 + .hph_pull_down_ctrl = wcd939x_mbhc_hph_pull_down_ctrl, 2447 + .mbhc_moisture_config = wcd939x_mbhc_moisture_config, 2448 + .mbhc_get_moisture_status = wcd939x_mbhc_get_moisture_status, 2449 + .mbhc_moisture_polling_ctrl = wcd939x_mbhc_moisture_polling_ctrl, 2450 + .mbhc_moisture_detect_en = wcd939x_mbhc_moisture_detect_en, 2451 + }; 2452 + 2453 + static int wcd939x_get_hph_type(struct snd_kcontrol *kcontrol, 2454 + struct snd_ctl_elem_value *ucontrol) 2455 + { 2456 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2457 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 2458 + 2459 + ucontrol->value.integer.value[0] = wcd_mbhc_get_hph_type(wcd939x->wcd_mbhc); 2460 + 2461 + return 0; 2462 + } 2463 + 2464 + static int wcd939x_hph_impedance_get(struct snd_kcontrol *kcontrol, 2465 + struct snd_ctl_elem_value *ucontrol) 2466 + { 2467 + struct soc_mixer_control *mc = (struct soc_mixer_control *)(kcontrol->private_value); 2468 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2469 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 2470 + bool hphr = mc->shift; 2471 + u32 zl, zr; 2472 + 2473 + wcd_mbhc_get_impedance(wcd939x->wcd_mbhc, &zl, &zr); 2474 + dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr); 2475 + ucontrol->value.integer.value[0] = hphr ? zr : zl; 2476 + 2477 + return 0; 2478 + } 2479 + 2480 + static const struct snd_kcontrol_new hph_type_detect_controls[] = { 2481 + SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0, 2482 + wcd939x_get_hph_type, NULL), 2483 + }; 2484 + 2485 + static const struct snd_kcontrol_new impedance_detect_controls[] = { 2486 + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0, 2487 + wcd939x_hph_impedance_get, NULL), 2488 + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0, 2489 + wcd939x_hph_impedance_get, NULL), 2490 + }; 2491 + 2492 + static int wcd939x_mbhc_init(struct snd_soc_component *component) 2493 + { 2494 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 2495 + struct wcd_mbhc_intr *intr_ids = &wcd939x->intr_ids; 2496 + 2497 + intr_ids->mbhc_sw_intr = regmap_irq_get_virq(wcd939x->irq_chip, 2498 + WCD939X_IRQ_MBHC_SW_DET); 2499 + intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(wcd939x->irq_chip, 2500 + WCD939X_IRQ_MBHC_BUTTON_PRESS_DET); 2501 + intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(wcd939x->irq_chip, 2502 + WCD939X_IRQ_MBHC_BUTTON_RELEASE_DET); 2503 + intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(wcd939x->irq_chip, 2504 + WCD939X_IRQ_MBHC_ELECT_INS_REM_LEG_DET); 2505 + intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(wcd939x->irq_chip, 2506 + WCD939X_IRQ_MBHC_ELECT_INS_REM_DET); 2507 + intr_ids->hph_left_ocp = regmap_irq_get_virq(wcd939x->irq_chip, 2508 + WCD939X_IRQ_HPHL_OCP_INT); 2509 + intr_ids->hph_right_ocp = regmap_irq_get_virq(wcd939x->irq_chip, 2510 + WCD939X_IRQ_HPHR_OCP_INT); 2511 + 2512 + wcd939x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true); 2513 + if (IS_ERR(wcd939x->wcd_mbhc)) 2514 + return PTR_ERR(wcd939x->wcd_mbhc); 2515 + 2516 + snd_soc_add_component_controls(component, impedance_detect_controls, 2517 + ARRAY_SIZE(impedance_detect_controls)); 2518 + snd_soc_add_component_controls(component, hph_type_detect_controls, 2519 + ARRAY_SIZE(hph_type_detect_controls)); 2520 + 2521 + return 0; 2522 + } 2523 + 2524 + static void wcd939x_mbhc_deinit(struct snd_soc_component *component) 2525 + { 2526 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 2527 + 2528 + wcd_mbhc_deinit(wcd939x->wcd_mbhc); 2529 + } 2530 + 2531 + /* END MBHC */ 2532 + 2533 + static const struct snd_kcontrol_new wcd939x_snd_controls[] = { 2534 + /* RX Path */ 2535 + SOC_SINGLE_EXT("HPHL_COMP Switch", WCD939X_COMP_L, 0, 1, 0, 2536 + wcd939x_get_compander, wcd939x_set_compander), 2537 + SOC_SINGLE_EXT("HPHR_COMP Switch", WCD939X_COMP_R, 1, 1, 0, 2538 + wcd939x_get_compander, wcd939x_set_compander), 2539 + SOC_SINGLE_EXT("HPHL Switch", WCD939X_HPH_L, 0, 1, 0, 2540 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2541 + SOC_SINGLE_EXT("HPHR Switch", WCD939X_HPH_R, 0, 1, 0, 2542 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2543 + SOC_SINGLE_EXT("CLSH Switch", WCD939X_CLSH, 0, 1, 0, 2544 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2545 + SOC_SINGLE_EXT("LO Switch", WCD939X_LO, 0, 1, 0, 2546 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2547 + SOC_SINGLE_EXT("DSD_L Switch", WCD939X_DSD_L, 0, 1, 0, 2548 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2549 + SOC_SINGLE_EXT("DSD_R Switch", WCD939X_DSD_R, 0, 1, 0, 2550 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2551 + SOC_SINGLE_TLV("HPHL Volume", WCD939X_HPH_L_EN, 0, 20, 1, line_gain), 2552 + SOC_SINGLE_TLV("HPHR Volume", WCD939X_HPH_R_EN, 0, 20, 1, line_gain), 2553 + SOC_SINGLE_EXT("LDOH Enable Switch", SND_SOC_NOPM, 0, 1, 0, 2554 + wcd939x_ldoh_get, wcd939x_ldoh_put), 2555 + 2556 + /* TX Path */ 2557 + SOC_SINGLE_EXT("ADC1 Switch", WCD939X_ADC1, 1, 1, 0, 2558 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2559 + SOC_SINGLE_EXT("ADC2 Switch", WCD939X_ADC2, 1, 1, 0, 2560 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2561 + SOC_SINGLE_EXT("ADC3 Switch", WCD939X_ADC3, 1, 1, 0, 2562 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2563 + SOC_SINGLE_EXT("ADC4 Switch", WCD939X_ADC4, 1, 1, 0, 2564 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2565 + SOC_SINGLE_EXT("DMIC0 Switch", WCD939X_DMIC0, 1, 1, 0, 2566 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2567 + SOC_SINGLE_EXT("DMIC1 Switch", WCD939X_DMIC1, 1, 1, 0, 2568 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2569 + SOC_SINGLE_EXT("MBHC Switch", WCD939X_MBHC, 1, 1, 0, 2570 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2571 + SOC_SINGLE_EXT("DMIC2 Switch", WCD939X_DMIC2, 1, 1, 0, 2572 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2573 + SOC_SINGLE_EXT("DMIC3 Switch", WCD939X_DMIC3, 1, 1, 0, 2574 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2575 + SOC_SINGLE_EXT("DMIC4 Switch", WCD939X_DMIC4, 1, 1, 0, 2576 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2577 + SOC_SINGLE_EXT("DMIC5 Switch", WCD939X_DMIC5, 1, 1, 0, 2578 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2579 + SOC_SINGLE_EXT("DMIC6 Switch", WCD939X_DMIC6, 1, 1, 0, 2580 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2581 + SOC_SINGLE_EXT("DMIC7 Switch", WCD939X_DMIC7, 1, 1, 0, 2582 + wcd939x_get_swr_port, wcd939x_set_swr_port), 2583 + SOC_SINGLE_TLV("ADC1 Volume", WCD939X_ANA_TX_CH1, 0, 20, 0, 2584 + analog_gain), 2585 + SOC_SINGLE_TLV("ADC2 Volume", WCD939X_ANA_TX_CH2, 0, 20, 0, 2586 + analog_gain), 2587 + SOC_SINGLE_TLV("ADC3 Volume", WCD939X_ANA_TX_CH3, 0, 20, 0, 2588 + analog_gain), 2589 + SOC_SINGLE_TLV("ADC4 Volume", WCD939X_ANA_TX_CH4, 0, 20, 0, 2590 + analog_gain), 2591 + }; 2592 + 2593 + static const struct snd_soc_dapm_widget wcd939x_dapm_widgets[] = { 2594 + /*input widgets*/ 2595 + SND_SOC_DAPM_INPUT("AMIC1"), 2596 + SND_SOC_DAPM_INPUT("AMIC2"), 2597 + SND_SOC_DAPM_INPUT("AMIC3"), 2598 + SND_SOC_DAPM_INPUT("AMIC4"), 2599 + SND_SOC_DAPM_INPUT("AMIC5"), 2600 + 2601 + SND_SOC_DAPM_MIC("Analog Mic1", NULL), 2602 + SND_SOC_DAPM_MIC("Analog Mic2", NULL), 2603 + SND_SOC_DAPM_MIC("Analog Mic3", NULL), 2604 + SND_SOC_DAPM_MIC("Analog Mic4", NULL), 2605 + SND_SOC_DAPM_MIC("Analog Mic5", NULL), 2606 + 2607 + /* TX widgets */ 2608 + SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0, 2609 + wcd939x_codec_enable_adc, 2610 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2611 + SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0, 2612 + wcd939x_codec_enable_adc, 2613 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2614 + SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 2, 0, 2615 + wcd939x_codec_enable_adc, 2616 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2617 + SND_SOC_DAPM_ADC_E("ADC4", NULL, SND_SOC_NOPM, 3, 0, 2618 + wcd939x_codec_enable_adc, 2619 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2620 + SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, 2621 + wcd939x_codec_enable_dmic, 2622 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2623 + SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 1, 0, 2624 + wcd939x_codec_enable_dmic, 2625 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2626 + SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 2, 0, 2627 + wcd939x_codec_enable_dmic, 2628 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2629 + SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 3, 0, 2630 + wcd939x_codec_enable_dmic, 2631 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2632 + SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 4, 0, 2633 + wcd939x_codec_enable_dmic, 2634 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2635 + SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 5, 0, 2636 + wcd939x_codec_enable_dmic, 2637 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2638 + SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 6, 0, 2639 + wcd939x_codec_enable_dmic, 2640 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2641 + SND_SOC_DAPM_ADC_E("DMIC8", NULL, SND_SOC_NOPM, 7, 0, 2642 + wcd939x_codec_enable_dmic, 2643 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2644 + 2645 + SND_SOC_DAPM_MIXER_E("ADC1 REQ", SND_SOC_NOPM, 0, 0, NULL, 0, 2646 + wcd939x_adc_enable_req, 2647 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2648 + SND_SOC_DAPM_MIXER_E("ADC2 REQ", SND_SOC_NOPM, 1, 0, NULL, 0, 2649 + wcd939x_adc_enable_req, 2650 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2651 + SND_SOC_DAPM_MIXER_E("ADC3 REQ", SND_SOC_NOPM, 2, 0, NULL, 0, 2652 + wcd939x_adc_enable_req, 2653 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2654 + SND_SOC_DAPM_MIXER_E("ADC4 REQ", SND_SOC_NOPM, 3, 0, NULL, 0, 2655 + wcd939x_adc_enable_req, 2656 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2657 + 2658 + SND_SOC_DAPM_MUX("ADC1 MUX", SND_SOC_NOPM, 0, 0, &tx_adc1_mux), 2659 + SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux), 2660 + SND_SOC_DAPM_MUX("ADC3 MUX", SND_SOC_NOPM, 0, 0, &tx_adc3_mux), 2661 + SND_SOC_DAPM_MUX("ADC4 MUX", SND_SOC_NOPM, 0, 0, &tx_adc4_mux), 2662 + 2663 + /* tx mixers */ 2664 + SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, 2665 + adc1_switch, ARRAY_SIZE(adc1_switch), wcd939x_tx_swr_ctrl, 2666 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2667 + SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 0, 0, 2668 + adc2_switch, ARRAY_SIZE(adc2_switch), wcd939x_tx_swr_ctrl, 2669 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2670 + SND_SOC_DAPM_MIXER_E("ADC3_MIXER", SND_SOC_NOPM, 0, 0, 2671 + adc3_switch, ARRAY_SIZE(adc3_switch), wcd939x_tx_swr_ctrl, 2672 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2673 + SND_SOC_DAPM_MIXER_E("ADC4_MIXER", SND_SOC_NOPM, 0, 0, 2674 + adc4_switch, ARRAY_SIZE(adc4_switch), wcd939x_tx_swr_ctrl, 2675 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2676 + SND_SOC_DAPM_MIXER_E("DMIC1_MIXER", SND_SOC_NOPM, 0, 0, 2677 + dmic1_switch, ARRAY_SIZE(dmic1_switch), wcd939x_tx_swr_ctrl, 2678 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2679 + SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 0, 0, 2680 + dmic2_switch, ARRAY_SIZE(dmic2_switch), wcd939x_tx_swr_ctrl, 2681 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2682 + SND_SOC_DAPM_MIXER_E("DMIC3_MIXER", SND_SOC_NOPM, 0, 0, 2683 + dmic3_switch, ARRAY_SIZE(dmic3_switch), wcd939x_tx_swr_ctrl, 2684 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2685 + SND_SOC_DAPM_MIXER_E("DMIC4_MIXER", SND_SOC_NOPM, 0, 0, 2686 + dmic4_switch, ARRAY_SIZE(dmic4_switch), wcd939x_tx_swr_ctrl, 2687 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2688 + SND_SOC_DAPM_MIXER_E("DMIC5_MIXER", SND_SOC_NOPM, 0, 0, 2689 + dmic5_switch, ARRAY_SIZE(dmic5_switch), wcd939x_tx_swr_ctrl, 2690 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2691 + SND_SOC_DAPM_MIXER_E("DMIC6_MIXER", SND_SOC_NOPM, 0, 0, 2692 + dmic6_switch, ARRAY_SIZE(dmic6_switch), wcd939x_tx_swr_ctrl, 2693 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2694 + SND_SOC_DAPM_MIXER_E("DMIC7_MIXER", SND_SOC_NOPM, 0, 0, 2695 + dmic7_switch, ARRAY_SIZE(dmic7_switch), wcd939x_tx_swr_ctrl, 2696 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2697 + SND_SOC_DAPM_MIXER_E("DMIC8_MIXER", SND_SOC_NOPM, 0, 0, 2698 + dmic8_switch, ARRAY_SIZE(dmic8_switch), wcd939x_tx_swr_ctrl, 2699 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2700 + 2701 + /* micbias widgets */ 2702 + SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0, 2703 + wcd939x_codec_enable_micbias, 2704 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2705 + SND_SOC_DAPM_POST_PMD), 2706 + SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0, 2707 + wcd939x_codec_enable_micbias, 2708 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2709 + SND_SOC_DAPM_POST_PMD), 2710 + SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0, 2711 + wcd939x_codec_enable_micbias, 2712 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2713 + SND_SOC_DAPM_POST_PMD), 2714 + SND_SOC_DAPM_SUPPLY("MIC BIAS4", SND_SOC_NOPM, MIC_BIAS_4, 0, 2715 + wcd939x_codec_enable_micbias, 2716 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2717 + SND_SOC_DAPM_POST_PMD), 2718 + 2719 + /* micbias pull up widgets */ 2720 + SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0, 2721 + wcd939x_codec_enable_micbias_pullup, 2722 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2723 + SND_SOC_DAPM_POST_PMD), 2724 + SND_SOC_DAPM_SUPPLY("VA MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0, 2725 + wcd939x_codec_enable_micbias_pullup, 2726 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2727 + SND_SOC_DAPM_POST_PMD), 2728 + SND_SOC_DAPM_SUPPLY("VA MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0, 2729 + wcd939x_codec_enable_micbias_pullup, 2730 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2731 + SND_SOC_DAPM_POST_PMD), 2732 + SND_SOC_DAPM_SUPPLY("VA MIC BIAS4", SND_SOC_NOPM, MIC_BIAS_4, 0, 2733 + wcd939x_codec_enable_micbias_pullup, 2734 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2735 + SND_SOC_DAPM_POST_PMD), 2736 + 2737 + /* output widgets tx */ 2738 + SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"), 2739 + SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"), 2740 + SND_SOC_DAPM_OUTPUT("ADC3_OUTPUT"), 2741 + SND_SOC_DAPM_OUTPUT("ADC4_OUTPUT"), 2742 + SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"), 2743 + SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"), 2744 + SND_SOC_DAPM_OUTPUT("DMIC3_OUTPUT"), 2745 + SND_SOC_DAPM_OUTPUT("DMIC4_OUTPUT"), 2746 + SND_SOC_DAPM_OUTPUT("DMIC5_OUTPUT"), 2747 + SND_SOC_DAPM_OUTPUT("DMIC6_OUTPUT"), 2748 + SND_SOC_DAPM_OUTPUT("DMIC7_OUTPUT"), 2749 + SND_SOC_DAPM_OUTPUT("DMIC8_OUTPUT"), 2750 + 2751 + SND_SOC_DAPM_INPUT("IN1_HPHL"), 2752 + SND_SOC_DAPM_INPUT("IN2_HPHR"), 2753 + SND_SOC_DAPM_INPUT("IN3_EAR"), 2754 + 2755 + /* rx widgets */ 2756 + SND_SOC_DAPM_PGA_E("EAR PGA", WCD939X_ANA_EAR, 7, 0, NULL, 0, 2757 + wcd939x_codec_enable_ear_pa, 2758 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2759 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 2760 + SND_SOC_DAPM_PGA_E("HPHL PGA", WCD939X_ANA_HPH, 7, 0, NULL, 0, 2761 + wcd939x_codec_enable_hphl_pa, 2762 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2763 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 2764 + SND_SOC_DAPM_PGA_E("HPHR PGA", WCD939X_ANA_HPH, 6, 0, NULL, 0, 2765 + wcd939x_codec_enable_hphr_pa, 2766 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2767 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 2768 + 2769 + SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0, 2770 + wcd939x_codec_hphl_dac_event, 2771 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2772 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 2773 + SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0, 2774 + wcd939x_codec_hphr_dac_event, 2775 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2776 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 2777 + SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0, 2778 + wcd939x_codec_ear_dac_event, 2779 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2780 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 2781 + 2782 + SND_SOC_DAPM_MUX("RDAC3_MUX", SND_SOC_NOPM, 0, 0, &rx_rdac3_mux), 2783 + 2784 + SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0, NULL, 0), 2785 + SND_SOC_DAPM_SUPPLY("RXCLK", SND_SOC_NOPM, 0, 0, 2786 + wcd939x_codec_enable_rxclk, 2787 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2788 + SND_SOC_DAPM_POST_PMD), 2789 + 2790 + SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0, NULL, 0), 2791 + 2792 + SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), 2793 + SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), 2794 + SND_SOC_DAPM_MIXER_E("RX3", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), 2795 + 2796 + /* rx mixer widgets */ 2797 + SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0, 2798 + ear_rdac_switch, ARRAY_SIZE(ear_rdac_switch)), 2799 + SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0, 2800 + hphl_rdac_switch, ARRAY_SIZE(hphl_rdac_switch)), 2801 + SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0, 2802 + hphr_rdac_switch, ARRAY_SIZE(hphr_rdac_switch)), 2803 + 2804 + /* output widgets rx */ 2805 + SND_SOC_DAPM_OUTPUT("EAR"), 2806 + SND_SOC_DAPM_OUTPUT("HPHL"), 2807 + SND_SOC_DAPM_OUTPUT("HPHR"), 2808 + }; 2809 + 2810 + static const struct snd_soc_dapm_route wcd939x_audio_map[] = { 2811 + /* TX Path */ 2812 + {"ADC1_OUTPUT", NULL, "ADC1_MIXER"}, 2813 + {"ADC1_MIXER", "Switch", "ADC1 REQ"}, 2814 + {"ADC1 REQ", NULL, "ADC1"}, 2815 + {"ADC1", NULL, "ADC1 MUX"}, 2816 + {"ADC1 MUX", "CH1_AMIC1", "AMIC1"}, 2817 + {"ADC1 MUX", "CH1_AMIC2", "AMIC2"}, 2818 + {"ADC1 MUX", "CH1_AMIC3", "AMIC3"}, 2819 + {"ADC1 MUX", "CH1_AMIC4", "AMIC4"}, 2820 + {"ADC1 MUX", "CH1_AMIC5", "AMIC5"}, 2821 + 2822 + {"ADC2_OUTPUT", NULL, "ADC2_MIXER"}, 2823 + {"ADC2_MIXER", "Switch", "ADC2 REQ"}, 2824 + {"ADC2 REQ", NULL, "ADC2"}, 2825 + {"ADC2", NULL, "ADC2 MUX"}, 2826 + {"ADC2 MUX", "CH2_AMIC1", "AMIC1"}, 2827 + {"ADC2 MUX", "CH2_AMIC2", "AMIC2"}, 2828 + {"ADC2 MUX", "CH2_AMIC3", "AMIC3"}, 2829 + {"ADC2 MUX", "CH2_AMIC4", "AMIC4"}, 2830 + {"ADC2 MUX", "CH2_AMIC5", "AMIC5"}, 2831 + 2832 + {"ADC3_OUTPUT", NULL, "ADC3_MIXER"}, 2833 + {"ADC3_MIXER", "Switch", "ADC3 REQ"}, 2834 + {"ADC3 REQ", NULL, "ADC3"}, 2835 + {"ADC3", NULL, "ADC3 MUX"}, 2836 + {"ADC3 MUX", "CH3_AMIC1", "AMIC1"}, 2837 + {"ADC3 MUX", "CH3_AMIC3", "AMIC3"}, 2838 + {"ADC3 MUX", "CH3_AMIC4", "AMIC4"}, 2839 + {"ADC3 MUX", "CH3_AMIC5", "AMIC5"}, 2840 + 2841 + {"ADC4_OUTPUT", NULL, "ADC4_MIXER"}, 2842 + {"ADC4_MIXER", "Switch", "ADC4 REQ"}, 2843 + {"ADC4 REQ", NULL, "ADC4"}, 2844 + {"ADC4", NULL, "ADC4 MUX"}, 2845 + {"ADC4 MUX", "CH4_AMIC1", "AMIC1"}, 2846 + {"ADC4 MUX", "CH4_AMIC3", "AMIC3"}, 2847 + {"ADC4 MUX", "CH4_AMIC4", "AMIC4"}, 2848 + {"ADC4 MUX", "CH4_AMIC5", "AMIC5"}, 2849 + 2850 + {"DMIC1_OUTPUT", NULL, "DMIC1_MIXER"}, 2851 + {"DMIC1_MIXER", "Switch", "DMIC1"}, 2852 + 2853 + {"DMIC2_OUTPUT", NULL, "DMIC2_MIXER"}, 2854 + {"DMIC2_MIXER", "Switch", "DMIC2"}, 2855 + 2856 + {"DMIC3_OUTPUT", NULL, "DMIC3_MIXER"}, 2857 + {"DMIC3_MIXER", "Switch", "DMIC3"}, 2858 + 2859 + {"DMIC4_OUTPUT", NULL, "DMIC4_MIXER"}, 2860 + {"DMIC4_MIXER", "Switch", "DMIC4"}, 2861 + 2862 + {"DMIC5_OUTPUT", NULL, "DMIC5_MIXER"}, 2863 + {"DMIC5_MIXER", "Switch", "DMIC5"}, 2864 + 2865 + {"DMIC6_OUTPUT", NULL, "DMIC6_MIXER"}, 2866 + {"DMIC6_MIXER", "Switch", "DMIC6"}, 2867 + 2868 + {"DMIC7_OUTPUT", NULL, "DMIC7_MIXER"}, 2869 + {"DMIC7_MIXER", "Switch", "DMIC7"}, 2870 + 2871 + {"DMIC8_OUTPUT", NULL, "DMIC8_MIXER"}, 2872 + {"DMIC8_MIXER", "Switch", "DMIC8"}, 2873 + 2874 + /* RX Path */ 2875 + {"IN1_HPHL", NULL, "VDD_BUCK"}, 2876 + {"IN1_HPHL", NULL, "CLS_H_PORT"}, 2877 + 2878 + {"RX1", NULL, "IN1_HPHL"}, 2879 + {"RX1", NULL, "RXCLK"}, 2880 + {"RDAC1", NULL, "RX1"}, 2881 + {"HPHL_RDAC", "Switch", "RDAC1"}, 2882 + {"HPHL PGA", NULL, "HPHL_RDAC"}, 2883 + {"HPHL", NULL, "HPHL PGA"}, 2884 + 2885 + {"IN2_HPHR", NULL, "VDD_BUCK"}, 2886 + {"IN2_HPHR", NULL, "CLS_H_PORT"}, 2887 + {"RX2", NULL, "IN2_HPHR"}, 2888 + {"RDAC2", NULL, "RX2"}, 2889 + {"RX2", NULL, "RXCLK"}, 2890 + {"HPHR_RDAC", "Switch", "RDAC2"}, 2891 + {"HPHR PGA", NULL, "HPHR_RDAC"}, 2892 + {"HPHR", NULL, "HPHR PGA"}, 2893 + 2894 + {"IN3_EAR", NULL, "VDD_BUCK"}, 2895 + {"RX3", NULL, "IN3_EAR"}, 2896 + {"RX3", NULL, "RXCLK"}, 2897 + 2898 + {"RDAC3_MUX", "RX3", "RX3"}, 2899 + {"RDAC3_MUX", "RX1", "RX1"}, 2900 + {"RDAC3", NULL, "RDAC3_MUX"}, 2901 + {"EAR_RDAC", "Switch", "RDAC3"}, 2902 + {"EAR PGA", NULL, "EAR_RDAC"}, 2903 + {"EAR", NULL, "EAR PGA"}, 2904 + }; 2905 + 2906 + static int wcd939x_set_micbias_data(struct wcd939x_priv *wcd939x) 2907 + { 2908 + int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4; 2909 + 2910 + /* set micbias voltage */ 2911 + vout_ctl_1 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb1_mv); 2912 + vout_ctl_2 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb2_mv); 2913 + vout_ctl_3 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb3_mv); 2914 + vout_ctl_4 = wcd939x_get_micb_vout_ctl_val(wcd939x->micb4_mv); 2915 + if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || vout_ctl_4 < 0) 2916 + return -EINVAL; 2917 + 2918 + regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB1, 2919 + WCD939X_MICB1_VOUT_CTL, vout_ctl_1); 2920 + regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB2, 2921 + WCD939X_MICB2_VOUT_CTL, vout_ctl_2); 2922 + regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB3, 2923 + WCD939X_MICB3_VOUT_CTL, vout_ctl_3); 2924 + regmap_update_bits(wcd939x->regmap, WCD939X_ANA_MICB4, 2925 + WCD939X_MICB4_VOUT_CTL, vout_ctl_4); 2926 + 2927 + return 0; 2928 + } 2929 + 2930 + static irqreturn_t wcd939x_wd_handle_irq(int irq, void *data) 2931 + { 2932 + /* 2933 + * HPHR/HPHL/EAR Watchdog interrupt threaded handler 2934 + * 2935 + * Watchdog interrupts are expected to be enabled when switching 2936 + * on the HPHL/R and EAR RX PGA in order to make sure the interrupts 2937 + * are acked by the regmap_irq handler to allow PDM sync. 2938 + * We could leave those interrupts masked but we would not have 2939 + * any valid way to enable/disable them without violating irq layers. 2940 + * 2941 + * The HPHR/HPHL/EAR Watchdog interrupts are handled 2942 + * by regmap_irq, so requesting a threaded handler is the 2943 + * safest way to be able to ack those interrupts without 2944 + * colliding with the regmap_irq setup. 2945 + */ 2946 + 2947 + return IRQ_HANDLED; 2948 + } 2949 + 2950 + /* 2951 + * Setup a virtual interrupt domain to hook regmap_irq 2952 + * The root domain will have a single interrupt which mapping 2953 + * will trigger the regmap_irq handler. 2954 + * 2955 + * root: 2956 + * wcd_irq_chip 2957 + * [0] wcd939x_regmap_irq_chip 2958 + * [0] MBHC_BUTTON_PRESS_DET 2959 + * [1] MBHC_BUTTON_RELEASE_DET 2960 + * ... 2961 + * [16] HPHR_SURGE_DET_INT 2962 + * 2963 + * Interrupt trigger: 2964 + * soundwire_interrupt_callback() 2965 + * \-handle_nested_irq(0) 2966 + * \- regmap_irq_thread() 2967 + * \- handle_nested_irq(i) 2968 + */ 2969 + static struct irq_chip wcd_irq_chip = { 2970 + .name = "WCD939x", 2971 + }; 2972 + 2973 + static int wcd_irq_chip_map(struct irq_domain *irqd, unsigned int virq, 2974 + irq_hw_number_t hw) 2975 + { 2976 + irq_set_chip_and_handler(virq, &wcd_irq_chip, handle_simple_irq); 2977 + irq_set_nested_thread(virq, 1); 2978 + irq_set_noprobe(virq); 2979 + 2980 + return 0; 2981 + } 2982 + 2983 + static const struct irq_domain_ops wcd_domain_ops = { 2984 + .map = wcd_irq_chip_map, 2985 + }; 2986 + 2987 + static int wcd939x_irq_init(struct wcd939x_priv *wcd, struct device *dev) 2988 + { 2989 + wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL); 2990 + if (!(wcd->virq)) { 2991 + dev_err(dev, "%s: Failed to add IRQ domain\n", __func__); 2992 + return -EINVAL; 2993 + } 2994 + 2995 + return devm_regmap_add_irq_chip(dev, wcd->regmap, 2996 + irq_create_mapping(wcd->virq, 0), 2997 + IRQF_ONESHOT, 0, &wcd939x_regmap_irq_chip, 2998 + &wcd->irq_chip); 2999 + } 3000 + 3001 + static int wcd939x_soc_codec_probe(struct snd_soc_component *component) 3002 + { 3003 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 3004 + struct sdw_slave *tx_sdw_dev = wcd939x->tx_sdw_dev; 3005 + struct device *dev = component->dev; 3006 + unsigned long time_left; 3007 + int ret, i; 3008 + 3009 + time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete, 3010 + msecs_to_jiffies(2000)); 3011 + if (!time_left) { 3012 + dev_err(dev, "soundwire device init timeout\n"); 3013 + return -ETIMEDOUT; 3014 + } 3015 + 3016 + snd_soc_component_init_regmap(component, wcd939x->regmap); 3017 + 3018 + ret = pm_runtime_resume_and_get(dev); 3019 + if (ret < 0) 3020 + return ret; 3021 + 3022 + wcd939x->variant = snd_soc_component_read_field(component, 3023 + WCD939X_DIGITAL_EFUSE_REG_0, 3024 + WCD939X_EFUSE_REG_0_WCD939X_ID); 3025 + 3026 + wcd939x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD939X); 3027 + if (IS_ERR(wcd939x->clsh_info)) { 3028 + pm_runtime_put(dev); 3029 + return PTR_ERR(wcd939x->clsh_info); 3030 + } 3031 + 3032 + wcd939x_io_init(component); 3033 + 3034 + /* Set all interrupts as edge triggered */ 3035 + for (i = 0; i < wcd939x_regmap_irq_chip.num_regs; i++) 3036 + regmap_write(wcd939x->regmap, 3037 + (WCD939X_DIGITAL_INTR_LEVEL_0 + i), 0); 3038 + 3039 + pm_runtime_put(dev); 3040 + 3041 + /* Request for watchdog interrupt */ 3042 + wcd939x->hphr_pdm_wd_int = regmap_irq_get_virq(wcd939x->irq_chip, 3043 + WCD939X_IRQ_HPHR_PDM_WD_INT); 3044 + wcd939x->hphl_pdm_wd_int = regmap_irq_get_virq(wcd939x->irq_chip, 3045 + WCD939X_IRQ_HPHL_PDM_WD_INT); 3046 + wcd939x->ear_pdm_wd_int = regmap_irq_get_virq(wcd939x->irq_chip, 3047 + WCD939X_IRQ_EAR_PDM_WD_INT); 3048 + 3049 + ret = request_threaded_irq(wcd939x->hphr_pdm_wd_int, NULL, wcd939x_wd_handle_irq, 3050 + IRQF_ONESHOT | IRQF_TRIGGER_RISING, 3051 + "HPHR PDM WD INT", wcd939x); 3052 + if (ret) { 3053 + dev_err(dev, "Failed to request HPHR WD interrupt (%d)\n", ret); 3054 + goto err_free_clsh_ctrl; 3055 + } 3056 + 3057 + ret = request_threaded_irq(wcd939x->hphl_pdm_wd_int, NULL, wcd939x_wd_handle_irq, 3058 + IRQF_ONESHOT | IRQF_TRIGGER_RISING, 3059 + "HPHL PDM WD INT", wcd939x); 3060 + if (ret) { 3061 + dev_err(dev, "Failed to request HPHL WD interrupt (%d)\n", ret); 3062 + goto err_free_hphr_pdm_wd_int; 3063 + } 3064 + 3065 + ret = request_threaded_irq(wcd939x->ear_pdm_wd_int, NULL, wcd939x_wd_handle_irq, 3066 + IRQF_ONESHOT | IRQF_TRIGGER_RISING, 3067 + "AUX PDM WD INT", wcd939x); 3068 + if (ret) { 3069 + dev_err(dev, "Failed to request Aux WD interrupt (%d)\n", ret); 3070 + goto err_free_hphl_pdm_wd_int; 3071 + } 3072 + 3073 + /* Disable watchdog interrupt for HPH and AUX */ 3074 + disable_irq_nosync(wcd939x->hphr_pdm_wd_int); 3075 + disable_irq_nosync(wcd939x->hphl_pdm_wd_int); 3076 + disable_irq_nosync(wcd939x->ear_pdm_wd_int); 3077 + 3078 + switch (wcd939x->variant) { 3079 + case WCD9390: 3080 + ret = snd_soc_add_component_controls(component, wcd9390_snd_controls, 3081 + ARRAY_SIZE(wcd9390_snd_controls)); 3082 + if (ret < 0) { 3083 + dev_err(component->dev, 3084 + "%s: Failed to add snd ctrls for variant: %d\n", 3085 + __func__, wcd939x->variant); 3086 + goto err_free_ear_pdm_wd_int; 3087 + } 3088 + break; 3089 + case WCD9395: 3090 + ret = snd_soc_add_component_controls(component, wcd9395_snd_controls, 3091 + ARRAY_SIZE(wcd9395_snd_controls)); 3092 + if (ret < 0) { 3093 + dev_err(component->dev, 3094 + "%s: Failed to add snd ctrls for variant: %d\n", 3095 + __func__, wcd939x->variant); 3096 + goto err_free_ear_pdm_wd_int; 3097 + } 3098 + break; 3099 + default: 3100 + break; 3101 + } 3102 + 3103 + ret = wcd939x_mbhc_init(component); 3104 + if (ret) { 3105 + dev_err(component->dev, "mbhc initialization failed\n"); 3106 + goto err_free_ear_pdm_wd_int; 3107 + } 3108 + 3109 + return 0; 3110 + 3111 + err_free_ear_pdm_wd_int: 3112 + free_irq(wcd939x->ear_pdm_wd_int, wcd939x); 3113 + err_free_hphl_pdm_wd_int: 3114 + free_irq(wcd939x->hphl_pdm_wd_int, wcd939x); 3115 + err_free_hphr_pdm_wd_int: 3116 + free_irq(wcd939x->hphr_pdm_wd_int, wcd939x); 3117 + err_free_clsh_ctrl: 3118 + wcd_clsh_ctrl_free(wcd939x->clsh_info); 3119 + 3120 + return ret; 3121 + } 3122 + 3123 + static void wcd939x_soc_codec_remove(struct snd_soc_component *component) 3124 + { 3125 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 3126 + 3127 + wcd939x_mbhc_deinit(component); 3128 + 3129 + free_irq(wcd939x->ear_pdm_wd_int, wcd939x); 3130 + free_irq(wcd939x->hphl_pdm_wd_int, wcd939x); 3131 + free_irq(wcd939x->hphr_pdm_wd_int, wcd939x); 3132 + 3133 + wcd_clsh_ctrl_free(wcd939x->clsh_info); 3134 + } 3135 + 3136 + static int wcd939x_codec_set_jack(struct snd_soc_component *comp, 3137 + struct snd_soc_jack *jack, void *data) 3138 + { 3139 + struct wcd939x_priv *wcd = dev_get_drvdata(comp->dev); 3140 + 3141 + if (jack) 3142 + return wcd_mbhc_start(wcd->wcd_mbhc, &wcd->mbhc_cfg, jack); 3143 + 3144 + wcd_mbhc_stop(wcd->wcd_mbhc); 3145 + 3146 + return 0; 3147 + } 3148 + 3149 + static const struct snd_soc_component_driver soc_codec_dev_wcd939x = { 3150 + .name = "wcd939x_codec", 3151 + .probe = wcd939x_soc_codec_probe, 3152 + .remove = wcd939x_soc_codec_remove, 3153 + .controls = wcd939x_snd_controls, 3154 + .num_controls = ARRAY_SIZE(wcd939x_snd_controls), 3155 + .dapm_widgets = wcd939x_dapm_widgets, 3156 + .num_dapm_widgets = ARRAY_SIZE(wcd939x_dapm_widgets), 3157 + .dapm_routes = wcd939x_audio_map, 3158 + .num_dapm_routes = ARRAY_SIZE(wcd939x_audio_map), 3159 + .set_jack = wcd939x_codec_set_jack, 3160 + .endianness = 1, 3161 + }; 3162 + 3163 + #if IS_ENABLED(CONFIG_TYPEC) 3164 + /* Get USB-C plug orientation to provide swap event for MBHC */ 3165 + static int wcd939x_typec_switch_set(struct typec_switch_dev *sw, 3166 + enum typec_orientation orientation) 3167 + { 3168 + struct wcd939x_priv *wcd939x = typec_switch_get_drvdata(sw); 3169 + 3170 + wcd939x->typec_orientation = orientation; 3171 + 3172 + return 0; 3173 + } 3174 + 3175 + static int wcd939x_typec_mux_set(struct typec_mux_dev *mux, 3176 + struct typec_mux_state *state) 3177 + { 3178 + struct wcd939x_priv *wcd939x = typec_mux_get_drvdata(mux); 3179 + unsigned int previous_mode = wcd939x->typec_mode; 3180 + 3181 + if (!wcd939x->wcd_mbhc) 3182 + return -EINVAL; 3183 + 3184 + if (wcd939x->typec_mode != state->mode) { 3185 + wcd939x->typec_mode = state->mode; 3186 + 3187 + if (wcd939x->typec_mode == TYPEC_MODE_AUDIO) 3188 + return wcd_mbhc_typec_report_plug(wcd939x->wcd_mbhc); 3189 + else if (previous_mode == TYPEC_MODE_AUDIO) 3190 + return wcd_mbhc_typec_report_unplug(wcd939x->wcd_mbhc); 3191 + } 3192 + 3193 + return 0; 3194 + } 3195 + #endif /* CONFIG_TYPEC */ 3196 + 3197 + static void wcd939x_dt_parse_micbias_info(struct device *dev, struct wcd939x_priv *wcd) 3198 + { 3199 + struct device_node *np = dev->of_node; 3200 + u32 prop_val = 0; 3201 + int rc = 0; 3202 + 3203 + rc = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val); 3204 + if (!rc) 3205 + wcd->micb1_mv = prop_val / 1000; 3206 + else 3207 + dev_info(dev, "%s: Micbias1 DT property not found\n", __func__); 3208 + 3209 + rc = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val); 3210 + if (!rc) 3211 + wcd->micb2_mv = prop_val / 1000; 3212 + else 3213 + dev_info(dev, "%s: Micbias2 DT property not found\n", __func__); 3214 + 3215 + rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val); 3216 + if (!rc) 3217 + wcd->micb3_mv = prop_val / 1000; 3218 + else 3219 + dev_info(dev, "%s: Micbias3 DT property not found\n", __func__); 3220 + 3221 + rc = of_property_read_u32(np, "qcom,micbias4-microvolt", &prop_val); 3222 + if (!rc) 3223 + wcd->micb4_mv = prop_val / 1000; 3224 + else 3225 + dev_info(dev, "%s: Micbias4 DT property not found\n", __func__); 3226 + } 3227 + 3228 + #if IS_ENABLED(CONFIG_TYPEC) 3229 + static bool wcd939x_swap_gnd_mic(struct snd_soc_component *component, bool active) 3230 + { 3231 + struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component); 3232 + 3233 + if (!wcd939x->typec_analog_mux || !wcd939x->typec_switch) 3234 + return false; 3235 + 3236 + /* Report inversion via Type Switch of USBSS */ 3237 + typec_switch_set(wcd939x->typec_switch, 3238 + wcd939x->typec_orientation == TYPEC_ORIENTATION_REVERSE ? 3239 + TYPEC_ORIENTATION_NORMAL : TYPEC_ORIENTATION_REVERSE); 3240 + 3241 + return true; 3242 + } 3243 + #endif /* CONFIG_TYPEC */ 3244 + 3245 + static int wcd939x_populate_dt_data(struct wcd939x_priv *wcd939x, struct device *dev) 3246 + { 3247 + struct wcd_mbhc_config *cfg = &wcd939x->mbhc_cfg; 3248 + #if IS_ENABLED(CONFIG_TYPEC) 3249 + struct device_node *np; 3250 + #endif /* CONFIG_TYPEC */ 3251 + int ret; 3252 + 3253 + wcd939x->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpios", 0); 3254 + if (wcd939x->reset_gpio < 0) 3255 + return dev_err_probe(dev, wcd939x->reset_gpio, 3256 + "Failed to get reset gpio\n"); 3257 + 3258 + wcd939x->supplies[0].supply = "vdd-rxtx"; 3259 + wcd939x->supplies[1].supply = "vdd-io"; 3260 + wcd939x->supplies[2].supply = "vdd-buck"; 3261 + wcd939x->supplies[3].supply = "vdd-mic-bias"; 3262 + 3263 + ret = regulator_bulk_get(dev, WCD939X_MAX_SUPPLY, wcd939x->supplies); 3264 + if (ret) 3265 + return dev_err_probe(dev, ret, "Failed to get supplies\n"); 3266 + 3267 + ret = regulator_bulk_enable(WCD939X_MAX_SUPPLY, wcd939x->supplies); 3268 + if (ret) { 3269 + regulator_bulk_free(WCD939X_MAX_SUPPLY, wcd939x->supplies); 3270 + return dev_err_probe(dev, ret, "Failed to enable supplies\n"); 3271 + } 3272 + 3273 + wcd939x_dt_parse_micbias_info(dev, wcd939x); 3274 + 3275 + cfg->mbhc_micbias = MIC_BIAS_2; 3276 + cfg->anc_micbias = MIC_BIAS_2; 3277 + cfg->v_hs_max = WCD_MBHC_HS_V_MAX; 3278 + cfg->num_btn = WCD939X_MBHC_MAX_BUTTONS; 3279 + cfg->micb_mv = wcd939x->micb2_mv; 3280 + cfg->linein_th = 5000; 3281 + cfg->hs_thr = 1700; 3282 + cfg->hph_thr = 50; 3283 + 3284 + wcd_dt_parse_mbhc_data(dev, cfg); 3285 + 3286 + #if IS_ENABLED(CONFIG_TYPEC) 3287 + /* 3288 + * Is node has a port and a valid remote endpoint 3289 + * consider HP lines are connected to the USBSS part 3290 + */ 3291 + np = of_graph_get_remote_node(dev->of_node, 0, 0); 3292 + if (np) { 3293 + wcd939x->typec_analog_mux = true; 3294 + cfg->typec_analog_mux = true; 3295 + cfg->swap_gnd_mic = wcd939x_swap_gnd_mic; 3296 + } 3297 + #endif /* CONFIG_TYPEC */ 3298 + 3299 + return 0; 3300 + } 3301 + 3302 + static int wcd939x_reset(struct wcd939x_priv *wcd939x) 3303 + { 3304 + gpio_direction_output(wcd939x->reset_gpio, 0); 3305 + /* 20us sleep required after pulling the reset gpio to LOW */ 3306 + usleep_range(20, 30); 3307 + gpio_set_value(wcd939x->reset_gpio, 1); 3308 + /* 20us sleep required after pulling the reset gpio to HIGH */ 3309 + usleep_range(20, 30); 3310 + 3311 + return 0; 3312 + } 3313 + 3314 + static int wcd939x_codec_hw_params(struct snd_pcm_substream *substream, 3315 + struct snd_pcm_hw_params *params, 3316 + struct snd_soc_dai *dai) 3317 + { 3318 + struct wcd939x_priv *wcd939x = dev_get_drvdata(dai->dev); 3319 + struct wcd939x_sdw_priv *wcd = wcd939x->sdw_priv[dai->id]; 3320 + 3321 + return wcd939x_sdw_hw_params(wcd, substream, params, dai); 3322 + } 3323 + 3324 + static int wcd939x_codec_free(struct snd_pcm_substream *substream, 3325 + struct snd_soc_dai *dai) 3326 + { 3327 + struct wcd939x_priv *wcd939x = dev_get_drvdata(dai->dev); 3328 + struct wcd939x_sdw_priv *wcd = wcd939x->sdw_priv[dai->id]; 3329 + 3330 + return wcd939x_sdw_free(wcd, substream, dai); 3331 + } 3332 + 3333 + static int wcd939x_codec_set_sdw_stream(struct snd_soc_dai *dai, 3334 + void *stream, int direction) 3335 + { 3336 + struct wcd939x_priv *wcd939x = dev_get_drvdata(dai->dev); 3337 + struct wcd939x_sdw_priv *wcd = wcd939x->sdw_priv[dai->id]; 3338 + 3339 + return wcd939x_sdw_set_sdw_stream(wcd, dai, stream, direction); 3340 + } 3341 + 3342 + static const struct snd_soc_dai_ops wcd939x_sdw_dai_ops = { 3343 + .hw_params = wcd939x_codec_hw_params, 3344 + .hw_free = wcd939x_codec_free, 3345 + .set_stream = wcd939x_codec_set_sdw_stream, 3346 + }; 3347 + 3348 + static struct snd_soc_dai_driver wcd939x_dais[] = { 3349 + [0] = { 3350 + .name = "wcd939x-sdw-rx", 3351 + .playback = { 3352 + .stream_name = "WCD AIF1 Playback", 3353 + .rates = WCD939X_RATES_MASK | WCD939X_FRAC_RATES_MASK, 3354 + .formats = WCD939X_FORMATS, 3355 + .rate_max = 384000, 3356 + .rate_min = 8000, 3357 + .channels_min = 1, 3358 + .channels_max = 2, 3359 + }, 3360 + .ops = &wcd939x_sdw_dai_ops, 3361 + }, 3362 + [1] = { 3363 + .name = "wcd939x-sdw-tx", 3364 + .capture = { 3365 + .stream_name = "WCD AIF1 Capture", 3366 + .rates = WCD939X_RATES_MASK | WCD939X_FRAC_RATES_MASK, 3367 + .formats = WCD939X_FORMATS, 3368 + .rate_min = 8000, 3369 + .rate_max = 384000, 3370 + .channels_min = 1, 3371 + .channels_max = 4, 3372 + }, 3373 + .ops = &wcd939x_sdw_dai_ops, 3374 + }, 3375 + }; 3376 + 3377 + static int wcd939x_bind(struct device *dev) 3378 + { 3379 + struct wcd939x_priv *wcd939x = dev_get_drvdata(dev); 3380 + unsigned int version, id1, status1; 3381 + int ret; 3382 + 3383 + #if IS_ENABLED(CONFIG_TYPEC) 3384 + /* 3385 + * Get USBSS type-c switch to send gnd/mic swap events 3386 + * typec_switch is fetched now to avoid a probe deadlock since 3387 + * the USBSS depends on the typec_mux register in wcd939x_probe() 3388 + */ 3389 + if (wcd939x->typec_analog_mux) { 3390 + wcd939x->typec_switch = fwnode_typec_switch_get(dev->fwnode); 3391 + if (IS_ERR(wcd939x->typec_switch)) 3392 + return dev_err_probe(dev, PTR_ERR(wcd939x->typec_switch), 3393 + "failed to acquire orientation-switch\n"); 3394 + } 3395 + #endif /* CONFIG_TYPEC */ 3396 + 3397 + ret = component_bind_all(dev, wcd939x); 3398 + if (ret) { 3399 + dev_err(dev, "%s: Slave bind failed, ret = %d\n", 3400 + __func__, ret); 3401 + goto err_put_typec_switch; 3402 + } 3403 + 3404 + wcd939x->rxdev = wcd939x_sdw_device_get(wcd939x->rxnode); 3405 + if (!wcd939x->rxdev) { 3406 + dev_err(dev, "could not find slave with matching of node\n"); 3407 + ret = -EINVAL; 3408 + goto err_unbind; 3409 + } 3410 + wcd939x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd939x->rxdev); 3411 + wcd939x->sdw_priv[AIF1_PB]->wcd939x = wcd939x; 3412 + 3413 + wcd939x->txdev = wcd939x_sdw_device_get(wcd939x->txnode); 3414 + if (!wcd939x->txdev) { 3415 + dev_err(dev, "could not find txslave with matching of node\n"); 3416 + ret = -EINVAL; 3417 + goto err_put_rxdev; 3418 + } 3419 + wcd939x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd939x->txdev); 3420 + wcd939x->sdw_priv[AIF1_CAP]->wcd939x = wcd939x; 3421 + wcd939x->tx_sdw_dev = dev_to_sdw_dev(wcd939x->txdev); 3422 + 3423 + /* 3424 + * As TX is main CSR reg interface, which should not be suspended first. 3425 + * explicitly add the dependency link 3426 + */ 3427 + if (!device_link_add(wcd939x->rxdev, wcd939x->txdev, DL_FLAG_STATELESS | 3428 + DL_FLAG_PM_RUNTIME)) { 3429 + dev_err(dev, "could not devlink tx and rx\n"); 3430 + ret = -EINVAL; 3431 + goto err_put_txdev; 3432 + } 3433 + 3434 + if (!device_link_add(dev, wcd939x->txdev, DL_FLAG_STATELESS | 3435 + DL_FLAG_PM_RUNTIME)) { 3436 + dev_err(dev, "could not devlink wcd and tx\n"); 3437 + ret = -EINVAL; 3438 + goto err_remove_rxtx_link; 3439 + } 3440 + 3441 + if (!device_link_add(dev, wcd939x->rxdev, DL_FLAG_STATELESS | 3442 + DL_FLAG_PM_RUNTIME)) { 3443 + dev_err(dev, "could not devlink wcd and rx\n"); 3444 + ret = -EINVAL; 3445 + goto err_remove_tx_link; 3446 + } 3447 + 3448 + /* Get regmap from TX SoundWire device */ 3449 + wcd939x->regmap = wcd939x_swr_get_regmap(wcd939x->sdw_priv[AIF1_CAP]); 3450 + if (IS_ERR(wcd939x->regmap)) { 3451 + dev_err(dev, "could not get TX device regmap\n"); 3452 + ret = PTR_ERR(wcd939x->regmap); 3453 + goto err_remove_rx_link; 3454 + } 3455 + 3456 + ret = wcd939x_irq_init(wcd939x, dev); 3457 + if (ret) { 3458 + dev_err(dev, "%s: IRQ init failed: %d\n", __func__, ret); 3459 + goto err_remove_rx_link; 3460 + } 3461 + 3462 + wcd939x->sdw_priv[AIF1_PB]->slave_irq = wcd939x->virq; 3463 + wcd939x->sdw_priv[AIF1_CAP]->slave_irq = wcd939x->virq; 3464 + 3465 + ret = wcd939x_set_micbias_data(wcd939x); 3466 + if (ret < 0) { 3467 + dev_err(dev, "%s: bad micbias pdata\n", __func__); 3468 + goto err_remove_rx_link; 3469 + } 3470 + 3471 + /* Check WCD9395 version */ 3472 + regmap_read(wcd939x->regmap, WCD939X_DIGITAL_CHIP_ID1, &id1); 3473 + regmap_read(wcd939x->regmap, WCD939X_EAR_STATUS_REG_1, &status1); 3474 + 3475 + if (id1 == 0) 3476 + version = ((status1 & 0x3) ? WCD939X_VERSION_1_1 : WCD939X_VERSION_1_0); 3477 + else 3478 + version = WCD939X_VERSION_2_0; 3479 + 3480 + dev_dbg(dev, "wcd939x version: %s\n", version_to_str(version)); 3481 + 3482 + ret = snd_soc_register_component(dev, &soc_codec_dev_wcd939x, 3483 + wcd939x_dais, ARRAY_SIZE(wcd939x_dais)); 3484 + if (ret) { 3485 + dev_err(dev, "%s: Codec registration failed\n", 3486 + __func__); 3487 + goto err_remove_rx_link; 3488 + } 3489 + 3490 + return 0; 3491 + 3492 + err_remove_rx_link: 3493 + device_link_remove(dev, wcd939x->rxdev); 3494 + err_remove_tx_link: 3495 + device_link_remove(dev, wcd939x->txdev); 3496 + err_remove_rxtx_link: 3497 + device_link_remove(wcd939x->rxdev, wcd939x->txdev); 3498 + err_put_txdev: 3499 + put_device(wcd939x->txdev); 3500 + err_put_rxdev: 3501 + put_device(wcd939x->rxdev); 3502 + err_unbind: 3503 + component_unbind_all(dev, wcd939x); 3504 + err_put_typec_switch: 3505 + #if IS_ENABLED(CONFIG_TYPEC) 3506 + if (wcd939x->typec_analog_mux) 3507 + typec_switch_put(wcd939x->typec_switch); 3508 + #endif /* CONFIG_TYPEC */ 3509 + 3510 + return ret; 3511 + } 3512 + 3513 + static void wcd939x_unbind(struct device *dev) 3514 + { 3515 + struct wcd939x_priv *wcd939x = dev_get_drvdata(dev); 3516 + 3517 + snd_soc_unregister_component(dev); 3518 + device_link_remove(dev, wcd939x->txdev); 3519 + device_link_remove(dev, wcd939x->rxdev); 3520 + device_link_remove(wcd939x->rxdev, wcd939x->txdev); 3521 + put_device(wcd939x->txdev); 3522 + put_device(wcd939x->rxdev); 3523 + component_unbind_all(dev, wcd939x); 3524 + } 3525 + 3526 + static const struct component_master_ops wcd939x_comp_ops = { 3527 + .bind = wcd939x_bind, 3528 + .unbind = wcd939x_unbind, 3529 + }; 3530 + 3531 + static int wcd939x_add_slave_components(struct wcd939x_priv *wcd939x, 3532 + struct device *dev, 3533 + struct component_match **matchptr) 3534 + { 3535 + struct device_node *np = dev->of_node; 3536 + 3537 + wcd939x->rxnode = of_parse_phandle(np, "qcom,rx-device", 0); 3538 + if (!wcd939x->rxnode) { 3539 + dev_err(dev, "%s: Rx-device node not defined\n", __func__); 3540 + return -ENODEV; 3541 + } 3542 + 3543 + of_node_get(wcd939x->rxnode); 3544 + component_match_add_release(dev, matchptr, component_release_of, 3545 + component_compare_of, wcd939x->rxnode); 3546 + 3547 + wcd939x->txnode = of_parse_phandle(np, "qcom,tx-device", 0); 3548 + if (!wcd939x->txnode) { 3549 + dev_err(dev, "%s: Tx-device node not defined\n", __func__); 3550 + return -ENODEV; 3551 + } 3552 + of_node_get(wcd939x->txnode); 3553 + component_match_add_release(dev, matchptr, component_release_of, 3554 + component_compare_of, wcd939x->txnode); 3555 + return 0; 3556 + } 3557 + 3558 + static int wcd939x_probe(struct platform_device *pdev) 3559 + { 3560 + struct component_match *match = NULL; 3561 + struct wcd939x_priv *wcd939x = NULL; 3562 + struct device *dev = &pdev->dev; 3563 + int ret; 3564 + 3565 + wcd939x = devm_kzalloc(dev, sizeof(struct wcd939x_priv), 3566 + GFP_KERNEL); 3567 + if (!wcd939x) 3568 + return -ENOMEM; 3569 + 3570 + dev_set_drvdata(dev, wcd939x); 3571 + mutex_init(&wcd939x->micb_lock); 3572 + 3573 + ret = wcd939x_populate_dt_data(wcd939x, dev); 3574 + if (ret) { 3575 + dev_err(dev, "%s: Fail to obtain platform data\n", __func__); 3576 + return -EINVAL; 3577 + } 3578 + 3579 + #if IS_ENABLED(CONFIG_TYPEC) 3580 + /* 3581 + * Is USBSS is used to mux analog lines, 3582 + * register a typec mux/switch to get typec events 3583 + */ 3584 + if (wcd939x->typec_analog_mux) { 3585 + struct typec_mux_desc mux_desc = { 3586 + .drvdata = wcd939x, 3587 + .fwnode = dev_fwnode(dev), 3588 + .set = wcd939x_typec_mux_set, 3589 + }; 3590 + struct typec_switch_desc sw_desc = { 3591 + .drvdata = wcd939x, 3592 + .fwnode = dev_fwnode(dev), 3593 + .set = wcd939x_typec_switch_set, 3594 + }; 3595 + 3596 + wcd939x->typec_mux = typec_mux_register(dev, &mux_desc); 3597 + if (IS_ERR(wcd939x->typec_mux)) { 3598 + ret = dev_err_probe(dev, PTR_ERR(wcd939x->typec_mux), 3599 + "failed to register typec mux\n"); 3600 + goto err_disable_regulators; 3601 + } 3602 + 3603 + wcd939x->typec_sw = typec_switch_register(dev, &sw_desc); 3604 + if (IS_ERR(wcd939x->typec_sw)) { 3605 + ret = dev_err_probe(dev, PTR_ERR(wcd939x->typec_sw), 3606 + "failed to register typec switch\n"); 3607 + goto err_unregister_typec_mux; 3608 + } 3609 + } 3610 + #endif /* CONFIG_TYPEC */ 3611 + 3612 + ret = wcd939x_add_slave_components(wcd939x, dev, &match); 3613 + if (ret) 3614 + goto err_unregister_typec_switch; 3615 + 3616 + wcd939x_reset(wcd939x); 3617 + 3618 + ret = component_master_add_with_match(dev, &wcd939x_comp_ops, match); 3619 + if (ret) 3620 + goto err_disable_regulators; 3621 + 3622 + pm_runtime_set_autosuspend_delay(dev, 1000); 3623 + pm_runtime_use_autosuspend(dev); 3624 + pm_runtime_mark_last_busy(dev); 3625 + pm_runtime_set_active(dev); 3626 + pm_runtime_enable(dev); 3627 + pm_runtime_idle(dev); 3628 + 3629 + return 0; 3630 + 3631 + #if IS_ENABLED(CONFIG_TYPEC) 3632 + err_unregister_typec_mux: 3633 + if (wcd939x->typec_analog_mux) 3634 + typec_mux_unregister(wcd939x->typec_mux); 3635 + #endif /* CONFIG_TYPEC */ 3636 + 3637 + err_unregister_typec_switch: 3638 + #if IS_ENABLED(CONFIG_TYPEC) 3639 + if (wcd939x->typec_analog_mux) 3640 + typec_switch_unregister(wcd939x->typec_sw); 3641 + #endif /* CONFIG_TYPEC */ 3642 + 3643 + err_disable_regulators: 3644 + regulator_bulk_disable(WCD939X_MAX_SUPPLY, wcd939x->supplies); 3645 + regulator_bulk_free(WCD939X_MAX_SUPPLY, wcd939x->supplies); 3646 + 3647 + return ret; 3648 + } 3649 + 3650 + static void wcd939x_remove(struct platform_device *pdev) 3651 + { 3652 + struct device *dev = &pdev->dev; 3653 + struct wcd939x_priv *wcd939x = dev_get_drvdata(dev); 3654 + 3655 + component_master_del(dev, &wcd939x_comp_ops); 3656 + 3657 + pm_runtime_disable(dev); 3658 + pm_runtime_set_suspended(dev); 3659 + pm_runtime_dont_use_autosuspend(dev); 3660 + 3661 + regulator_bulk_disable(WCD939X_MAX_SUPPLY, wcd939x->supplies); 3662 + regulator_bulk_free(WCD939X_MAX_SUPPLY, wcd939x->supplies); 3663 + } 3664 + 3665 + #if defined(CONFIG_OF) 3666 + static const struct of_device_id wcd939x_dt_match[] = { 3667 + { .compatible = "qcom,wcd9390-codec" }, 3668 + { .compatible = "qcom,wcd9395-codec" }, 3669 + {} 3670 + }; 3671 + MODULE_DEVICE_TABLE(of, wcd939x_dt_match); 3672 + #endif 3673 + 3674 + static struct platform_driver wcd939x_codec_driver = { 3675 + .probe = wcd939x_probe, 3676 + .remove_new = wcd939x_remove, 3677 + .driver = { 3678 + .name = "wcd939x_codec", 3679 + .of_match_table = of_match_ptr(wcd939x_dt_match), 3680 + .suppress_bind_attrs = true, 3681 + }, 3682 + }; 3683 + 3684 + module_platform_driver(wcd939x_codec_driver); 3685 + MODULE_DESCRIPTION("WCD939X Codec driver"); 3686 + MODULE_LICENSE("GPL");
+989
sound/soc/codecs/wcd939x.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 5 + */ 6 + 7 + #ifndef __WCD939X_H__ 8 + #define __WCD939X_H__ 9 + #include <linux/soundwire/sdw.h> 10 + #include <linux/soundwire/sdw_type.h> 11 + 12 + #define WCD939X_BASE (0x3000) 13 + #define WCD939X_ANA_PAGE (0x3000) 14 + #define WCD939X_ANA_BIAS (0x3001) 15 + #define WCD939X_BIAS_ANALOG_BIAS_EN BIT(7) 16 + #define WCD939X_BIAS_PRECHRG_EN BIT(6) 17 + #define WCD939X_BIAS_PRECHRG_CTL_MODE BIT(5) 18 + #define WCD939X_ANA_RX_SUPPLIES (0x3008) 19 + #define WCD939X_RX_SUPPLIES_VPOS_EN BIT(7) 20 + #define WCD939X_RX_SUPPLIES_VNEG_EN BIT(6) 21 + #define WCD939X_RX_SUPPLIES_VPOS_PWR_LVL BIT(3) 22 + #define WCD939X_RX_SUPPLIES_VNEG_PWR_LVL BIT(2) 23 + #define WCD939X_RX_SUPPLIES_REGULATOR_MODE BIT(1) 24 + #define WCD939X_RX_SUPPLIES_RX_BIAS_ENABLE BIT(0) 25 + #define WCD939X_ANA_HPH (0x3009) 26 + #define WCD939X_HPH_HPHL_ENABLE BIT(7) 27 + #define WCD939X_HPH_HPHR_ENABLE BIT(6) 28 + #define WCD939X_HPH_HPHL_REF_ENABLE BIT(5) 29 + #define WCD939X_HPH_HPHR_REF_ENABLE BIT(4) 30 + #define WCD939X_HPH_PWR_LEVEL GENMASK(3, 2) 31 + #define WCD939X_ANA_EAR (0x300a) 32 + #define WCD939X_ANA_EAR_COMPANDER_CTL (0x300b) 33 + #define WCD939X_EAR_COMPANDER_CTL_GAIN_OVRD_REG BIT(7) 34 + #define WCD939X_EAR_COMPANDER_CTL_EAR_GAIN GENMASK(6, 2) 35 + #define WCD939X_EAR_COMPANDER_CTL_COMP_DFF_BYP BIT(1) 36 + #define WCD939X_EAR_COMPANDER_CTL_COMP_DFF_CLK_EDGE BIT(0) 37 + #define WCD939X_ANA_TX_CH1 (0x300e) 38 + #define WCD939X_ANA_TX_CH2 (0x300f) 39 + #define WCD939X_TX_CH2_ENABLE BIT(7) 40 + #define WCD939X_TX_CH2_HPF1_INIT BIT(6) 41 + #define WCD939X_TX_CH2_HPF2_INIT BIT(5) 42 + #define WCD939X_TX_CH2_GAIN GENMASK(4, 0) 43 + #define WCD939X_ANA_TX_CH3 (0x3010) 44 + #define WCD939X_ANA_TX_CH4 (0x3011) 45 + #define WCD939X_TX_CH4_ENABLE BIT(7) 46 + #define WCD939X_TX_CH4_HPF3_INIT BIT(6) 47 + #define WCD939X_TX_CH4_HPF4_INIT BIT(5) 48 + #define WCD939X_TX_CH4_GAIN GENMASK(4, 0) 49 + #define WCD939X_ANA_MICB1_MICB2_DSP_EN_LOGIC (0x3012) 50 + #define WCD939X_ANA_MICB3_DSP_EN_LOGIC (0x3013) 51 + #define WCD939X_ANA_MBHC_MECH (0x3014) 52 + #define WCD939X_MBHC_MECH_L_DET_EN BIT(7) 53 + #define WCD939X_MBHC_MECH_GND_DET_EN BIT(6) 54 + #define WCD939X_MBHC_MECH_MECH_DETECT_TYPE BIT(5) 55 + #define WCD939X_MBHC_MECH_HPHL_PLUG_TYPE BIT(4) 56 + #define WCD939X_MBHC_MECH_GND_PLUG_TYPE BIT(3) 57 + #define WCD939X_MBHC_MECH_MECH_HS_L_PULLUP_COMP_EN BIT(2) 58 + #define WCD939X_MBHC_MECH_MECH_HS_G_PULLUP_COMP_EN BIT(1) 59 + #define WCD939X_MBHC_MECH_SW_HPH_L_P_100K_TO_GND BIT(0) 60 + #define WCD939X_ANA_MBHC_ELECT (0x3015) 61 + #define WCD939X_MBHC_ELECT_FSM_EN BIT(7) 62 + #define WCD939X_MBHC_ELECT_BTNDET_ISRC_CTL GENMASK(6, 4) 63 + #define WCD939X_MBHC_ELECT_ELECT_DET_TYPE BIT(3) 64 + #define WCD939X_MBHC_ELECT_ELECT_SCHMT_ISRC_CTL GENMASK(2, 1) 65 + #define WCD939X_MBHC_ELECT_BIAS_EN BIT(0) 66 + #define WCD939X_ANA_MBHC_ZDET (0x3016) 67 + #define WCD939X_MBHC_ZDET_ZDET_L_MEAS_EN BIT(7) 68 + #define WCD939X_MBHC_ZDET_ZDET_R_MEAS_EN BIT(6) 69 + #define WCD939X_MBHC_ZDET_ZDET_CHG_EN BIT(5) 70 + #define WCD939X_MBHC_ZDET_ZDET_ILEAK_COMP_EN BIT(4) 71 + #define WCD939X_MBHC_ZDET_ELECT_ISRC_EN BIT(1) 72 + #define WCD939X_ANA_MBHC_RESULT_1 (0x3017) 73 + #define WCD939X_MBHC_RESULT_1_Z_RESULT_LSB GENMASK(7, 0) 74 + #define WCD939X_ANA_MBHC_RESULT_2 (0x3018) 75 + #define WCD939X_MBHC_RESULT_2_Z_RESULT_MSB GENMASK(7, 0) 76 + #define WCD939X_ANA_MBHC_RESULT_3 (0x3019) 77 + #define WCD939X_ANA_MBHC_BTN0 (0x301a) 78 + #define WCD939X_MBHC_BTN0_VTH GENMASK(7, 2) 79 + #define WCD939X_ANA_MBHC_BTN1 (0x301b) 80 + #define WCD939X_MBHC_BTN1_VTH GENMASK(7, 2) 81 + #define WCD939X_ANA_MBHC_BTN2 (0x301c) 82 + #define WCD939X_MBHC_BTN2_VTH GENMASK(7, 2) 83 + #define WCD939X_ANA_MBHC_BTN3 (0x301d) 84 + #define WCD939X_MBHC_BTN3_VTH GENMASK(7, 2) 85 + #define WCD939X_ANA_MBHC_BTN4 (0x301e) 86 + #define WCD939X_MBHC_BTN4_VTH GENMASK(7, 2) 87 + #define WCD939X_ANA_MBHC_BTN5 (0x301f) 88 + #define WCD939X_MBHC_BTN5_VTH GENMASK(7, 2) 89 + #define WCD939X_ANA_MBHC_BTN6 (0x3020) 90 + #define WCD939X_MBHC_BTN6_VTH GENMASK(7, 2) 91 + #define WCD939X_ANA_MBHC_BTN7 (0x3021) 92 + #define WCD939X_MBHC_BTN7_VTH GENMASK(7, 2) 93 + #define WCD939X_ANA_MICB1 (0x3022) 94 + #define WCD939X_MICB1_ENABLE GENMASK(7, 6) 95 + #define WCD939X_MICB1_VOUT_CTL GENMASK(5, 0) 96 + #define WCD939X_ANA_MICB2 (0x3023) 97 + #define WCD939X_MICB2_ENABLE GENMASK(7, 6) 98 + #define WCD939X_MICB2_VOUT_CTL GENMASK(5, 0) 99 + #define WCD939X_ANA_MICB2_RAMP (0x3024) 100 + #define WCD939X_MICB2_RAMP_RAMP_ENABLE BIT(7) 101 + #define WCD939X_MICB2_RAMP_MB2_IN2P_SHORT_ENABLE BIT(6) 102 + #define WCD939X_MICB2_RAMP_ALLSW_OVRD_ENABLE BIT(5) 103 + #define WCD939X_MICB2_RAMP_SHIFT_CTL GENMASK(4, 2) 104 + #define WCD939X_MICB2_RAMP_USB_MGDET_MICB2_RAMP GENMASK(1, 0) 105 + #define WCD939X_ANA_MICB3 (0x3025) 106 + #define WCD939X_MICB3_ENABLE GENMASK(7, 6) 107 + #define WCD939X_MICB3_VOUT_CTL GENMASK(5, 0) 108 + #define WCD939X_ANA_MICB4 (0x3026) 109 + #define WCD939X_MICB4_ENABLE GENMASK(7, 6) 110 + #define WCD939X_MICB4_VOUT_CTL GENMASK(5, 0) 111 + #define WCD939X_BIAS_CTL (0x3028) 112 + #define WCD939X_BIAS_VBG_FINE_ADJ (0x3029) 113 + #define WCD939X_LDOL_VDDCX_ADJUST (0x3040) 114 + #define WCD939X_LDOL_DISABLE_LDOL (0x3041) 115 + #define WCD939X_MBHC_CTL_CLK (0x3056) 116 + #define WCD939X_MBHC_CTL_ANA (0x3057) 117 + #define WCD939X_MBHC_ZDET_VNEG_CTL (0x3058) 118 + #define WCD939X_MBHC_ZDET_BIAS_CTL (0x3059) 119 + #define WCD939X_MBHC_CTL_BCS (0x305a) 120 + #define WCD939X_MBHC_MOISTURE_DET_FSM_STATUS (0x305b) 121 + #define WCD939X_MBHC_TEST_CTL (0x305c) 122 + #define WCD939X_LDOH_MODE (0x3067) 123 + #define WCD939X_MODE_LDOH_EN BIT(7) 124 + #define WCD939X_MODE_PWRDN_STATE BIT(6) 125 + #define WCD939X_MODE_SLOWRAMP_EN BIT(5) 126 + #define WCD939X_MODE_VOUT_ADJUST GENMASK(4, 3) 127 + #define WCD939X_MODE_VOUT_COARSE_ADJ GENMASK(2, 0) 128 + #define WCD939X_LDOH_BIAS (0x3068) 129 + #define WCD939X_LDOH_STB_LOADS (0x3069) 130 + #define WCD939X_LDOH_SLOWRAMP (0x306a) 131 + #define WCD939X_MICB1_TEST_CTL_1 (0x306b) 132 + #define WCD939X_TEST_CTL_1_NOISE_FILT_RES_VAL GENMASK(7, 5) 133 + #define WCD939X_TEST_CTL_1_EN_VREFGEN BIT(4) 134 + #define WCD939X_TEST_CTL_1_EN_LDO BIT(3) 135 + #define WCD939X_TEST_CTL_1_LDO_BLEEDER_I_CTRL GENMASK(2, 0) 136 + #define WCD939X_MICB1_TEST_CTL_2 (0x306c) 137 + #define WCD939X_TEST_CTL_2_IBIAS_VREFGEN GENMASK(7, 6) 138 + #define WCD939X_TEST_CTL_2_INRUSH_CURRENT_FIX_DIS BIT(5) 139 + #define WCD939X_TEST_CTL_2_IBIAS_LDO_DRIVER GENMASK(2, 0) 140 + #define WCD939X_MICB1_TEST_CTL_3 (0x306d) 141 + #define WCD939X_TEST_CTL_3_CFILT_REF_EN BIT(7) 142 + #define WCD939X_TEST_CTL_3_RZ_LDO_VAL GENMASK(6, 4) 143 + #define WCD939X_TEST_CTL_3_IBIAS_LDO_STG3 GENMASK(3, 2) 144 + #define WCD939X_TEST_CTL_3_ATEST_CTRL GENMASK(1, 0) 145 + #define WCD939X_MICB2_TEST_CTL_1 (0x306e) 146 + #define WCD939X_MICB2_TEST_CTL_2 (0x306f) 147 + #define WCD939X_MICB2_TEST_CTL_3 (0x3070) 148 + #define WCD939X_MICB3_TEST_CTL_1 (0x3071) 149 + #define WCD939X_MICB3_TEST_CTL_2 (0x3072) 150 + #define WCD939X_MICB3_TEST_CTL_3 (0x3073) 151 + #define WCD939X_MICB4_TEST_CTL_1 (0x3074) 152 + #define WCD939X_MICB4_TEST_CTL_2 (0x3075) 153 + #define WCD939X_MICB4_TEST_CTL_3 (0x3076) 154 + #define WCD939X_TX_COM_ADC_VCM (0x3077) 155 + #define WCD939X_TX_COM_BIAS_ATEST (0x3078) 156 + #define WCD939X_TX_COM_SPARE1 (0x3079) 157 + #define WCD939X_TX_COM_SPARE2 (0x307a) 158 + #define WCD939X_TX_COM_TXFE_DIV_CTL (0x307b) 159 + #define WCD939X_TX_COM_TXFE_DIV_START (0x307c) 160 + #define WCD939X_TX_COM_SPARE3 (0x307d) 161 + #define WCD939X_TX_COM_SPARE4 (0x307e) 162 + #define WCD939X_TX_1_2_TEST_EN (0x307f) 163 + #define WCD939X_TX_1_2_ADC_IB (0x3080) 164 + #define WCD939X_TX_1_2_ATEST_REFCTL (0x3081) 165 + #define WCD939X_TX_1_2_TEST_CTL (0x3082) 166 + #define WCD939X_TX_1_2_TEST_BLK_EN1 (0x3083) 167 + #define WCD939X_TX_1_2_TXFE1_CLKDIV (0x3084) 168 + #define WCD939X_TX_1_2_SAR2_ERR (0x3085) 169 + #define WCD939X_TX_1_2_SAR1_ERR (0x3086) 170 + #define WCD939X_TX_3_4_TEST_EN (0x3087) 171 + #define WCD939X_TX_3_4_ADC_IB (0x3088) 172 + #define WCD939X_TX_3_4_ATEST_REFCTL (0x3089) 173 + #define WCD939X_TX_3_4_TEST_CTL (0x308a) 174 + #define WCD939X_TX_3_4_TEST_BLK_EN3 (0x308b) 175 + #define WCD939X_TX_3_4_TXFE3_CLKDIV (0x308c) 176 + #define WCD939X_TX_3_4_SAR4_ERR (0x308d) 177 + #define WCD939X_TX_3_4_SAR3_ERR (0x308e) 178 + #define WCD939X_TX_3_4_TEST_BLK_EN2 (0x308f) 179 + #define WCD939X_TEST_BLK_EN2_ADC2_INT1_EN BIT(7) 180 + #define WCD939X_TEST_BLK_EN2_ADC2_INT2_EN BIT(6) 181 + #define WCD939X_TEST_BLK_EN2_ADC2_SAR_EN BIT(5) 182 + #define WCD939X_TEST_BLK_EN2_ADC2_CMGEN_EN BIT(4) 183 + #define WCD939X_TEST_BLK_EN2_ADC2_CLKGEN_EN BIT(3) 184 + #define WCD939X_TEST_BLK_EN2_ADC12_VREF_NONL2 GENMASK(2, 1) 185 + #define WCD939X_TEST_BLK_EN2_TXFE2_MBHC_CLKRST_EN BIT(0) 186 + #define WCD939X_TX_3_4_TXFE2_CLKDIV (0x3090) 187 + #define WCD939X_TX_3_4_SPARE1 (0x3091) 188 + #define WCD939X_TX_3_4_TEST_BLK_EN4 (0x3092) 189 + #define WCD939X_TX_3_4_TXFE4_CLKDIV (0x3093) 190 + #define WCD939X_TX_3_4_SPARE2 (0x3094) 191 + #define WCD939X_CLASSH_MODE_1 (0x3097) 192 + #define WCD939X_CLASSH_MODE_2 (0x3098) 193 + #define WCD939X_CLASSH_MODE_3 (0x3099) 194 + #define WCD939X_CLASSH_CTRL_VCL_1 (0x309a) 195 + #define WCD939X_CLASSH_CTRL_VCL_2 (0x309b) 196 + #define WCD939X_CLASSH_CTRL_CCL_1 (0x309c) 197 + #define WCD939X_CLASSH_CTRL_CCL_2 (0x309d) 198 + #define WCD939X_CLASSH_CTRL_CCL_3 (0x309e) 199 + #define WCD939X_CLASSH_CTRL_CCL_4 (0x309f) 200 + #define WCD939X_CLASSH_CTRL_CCL_5 (0x30a0) 201 + #define WCD939X_CLASSH_BUCK_TMUX_A_D (0x30a1) 202 + #define WCD939X_CLASSH_BUCK_SW_DRV_CNTL (0x30a2) 203 + #define WCD939X_CLASSH_SPARE (0x30a3) 204 + #define WCD939X_FLYBACK_EN (0x30a4) 205 + #define WCD939X_FLYBACK_VNEG_CTRL_1 (0x30a5) 206 + #define WCD939X_FLYBACK_VNEG_CTRL_2 (0x30a6) 207 + #define WCD939X_FLYBACK_VNEG_CTRL_3 (0x30a7) 208 + #define WCD939X_FLYBACK_VNEG_CTRL_4 (0x30a8) 209 + #define WCD939X_VNEG_CTRL_4_ILIM_SEL GENMASK(7, 4) 210 + #define WCD939X_VNEG_CTRL_4_PW_BUF_POS GENMASK(3, 2) 211 + #define WCD939X_VNEG_CTRL_4_PW_BUF_NEG GENMASK(1, 0) 212 + #define WCD939X_FLYBACK_VNEG_CTRL_5 (0x30a9) 213 + #define WCD939X_FLYBACK_VNEG_CTRL_6 (0x30aa) 214 + #define WCD939X_FLYBACK_VNEG_CTRL_7 (0x30ab) 215 + #define WCD939X_FLYBACK_VNEG_CTRL_8 (0x30ac) 216 + #define WCD939X_FLYBACK_VNEG_CTRL_9 (0x30ad) 217 + #define WCD939X_FLYBACK_VNEGDAC_CTRL_1 (0x30ae) 218 + #define WCD939X_FLYBACK_VNEGDAC_CTRL_2 (0x30af) 219 + #define WCD939X_FLYBACK_VNEGDAC_CTRL_3 (0x30b0) 220 + #define WCD939X_FLYBACK_CTRL_1 (0x30b1) 221 + #define WCD939X_FLYBACK_TEST_CTL (0x30b2) 222 + #define WCD939X_RX_AUX_SW_CTL (0x30b3) 223 + #define WCD939X_RX_PA_AUX_IN_CONN (0x30b4) 224 + #define WCD939X_RX_TIMER_DIV (0x30b5) 225 + #define WCD939X_RX_OCP_CTL (0x30b6) 226 + #define WCD939X_RX_OCP_COUNT (0x30b7) 227 + #define WCD939X_RX_BIAS_EAR_DAC (0x30b8) 228 + #define WCD939X_RX_BIAS_EAR_AMP (0x30b9) 229 + #define WCD939X_RX_BIAS_HPH_LDO (0x30ba) 230 + #define WCD939X_RX_BIAS_HPH_PA (0x30bb) 231 + #define WCD939X_RX_BIAS_HPH_RDACBUFF_CNP2 (0x30bc) 232 + #define WCD939X_RX_BIAS_HPH_RDAC_LDO (0x30bd) 233 + #define WCD939X_RX_BIAS_HPH_CNP1 (0x30be) 234 + #define WCD939X_RX_BIAS_HPH_LOWPOWER (0x30bf) 235 + #define WCD939X_RX_BIAS_AUX_DAC (0x30c0) 236 + #define WCD939X_RX_BIAS_AUX_AMP (0x30c1) 237 + #define WCD939X_RX_BIAS_VNEGDAC_BLEEDER (0x30c2) 238 + #define WCD939X_RX_BIAS_MISC (0x30c3) 239 + #define WCD939X_RX_BIAS_BUCK_RST (0x30c4) 240 + #define WCD939X_RX_BIAS_BUCK_VREF_ERRAMP (0x30c5) 241 + #define WCD939X_RX_BIAS_FLYB_ERRAMP (0x30c6) 242 + #define WCD939X_RX_BIAS_FLYB_BUFF (0x30c7) 243 + #define WCD939X_RX_BIAS_FLYB_MID_RST (0x30c8) 244 + #define WCD939X_HPH_L_STATUS (0x30c9) 245 + #define WCD939X_HPH_R_STATUS (0x30ca) 246 + #define WCD939X_HPH_CNP_EN (0x30cb) 247 + #define WCD939X_HPH_CNP_WG_CTL (0x30cc) 248 + #define WCD939X_HPH_CNP_WG_TIME (0x30cd) 249 + #define WCD939X_HPH_OCP_CTL (0x30ce) 250 + #define WCD939X_OCP_CTL_OCP_CURR_LIMIT GENMASK(7, 5) 251 + #define WCD939X_OCP_CTL_OCP_FSM_EN BIT(4) 252 + #define WCD939X_OCP_CTL_SPARE_BITS BIT(3) 253 + #define WCD939X_OCP_CTL_SCD_OP_EN BIT(1) 254 + #define WCD939X_HPH_AUTO_CHOP (0x30cf) 255 + #define WCD939X_HPH_CHOP_CTL (0x30d0) 256 + #define WCD939X_HPH_PA_CTL1 (0x30d1) 257 + #define WCD939X_HPH_PA_CTL2 (0x30d2) 258 + #define WCD939X_PA_CTL2_HPHPA_GND_R BIT(6) 259 + #define WCD939X_PA_CTL2_HPHPA_GND_L BIT(4) 260 + #define WCD939X_PA_CTL2_GM3_CASCODE_CTL_NORMAL GENMASK(1, 0) 261 + #define WCD939X_HPH_L_EN (0x30d3) 262 + #define WCD939X_L_EN_CONST_SEL_L GENMASK(7, 6) 263 + #define WCD939X_L_EN_GAIN_SOURCE_SEL BIT(5) 264 + #define WCD939X_L_EN_SPARE_BITS GENMASK(4, 0) 265 + #define WCD939X_HPH_L_TEST (0x30d4) 266 + #define WCD939X_HPH_L_ATEST (0x30d5) 267 + #define WCD939X_HPH_R_EN (0x30d6) 268 + #define WCD939X_R_EN_CONST_SEL_R GENMASK(7, 6) 269 + #define WCD939X_R_EN_GAIN_SOURCE_SEL BIT(5) 270 + #define WCD939X_R_EN_SPARE_BITS GENMASK(4, 0) 271 + #define WCD939X_HPH_R_TEST (0x30d7) 272 + #define WCD939X_HPH_R_ATEST (0x30d8) 273 + #define WCD939X_R_ATEST_DACR_REF_ATEST1_CONN BIT(7) 274 + #define WCD939X_R_ATEST_LDO1_R_ATEST2_CONN BIT(6) 275 + #define WCD939X_R_ATEST_LDO_R_ATEST2_CAL BIT(5) 276 + #define WCD939X_R_ATEST_LDO2_R_ATEST2_CONN BIT(4) 277 + #define WCD939X_R_ATEST_LDO_1P65V_ATEST1_CONN BIT(3) 278 + #define WCD939X_R_ATEST_HPH_GND_OVR BIT(1) 279 + #define WCD939X_HPH_RDAC_CLK_CTL1 (0x30d9) 280 + #define WCD939X_RDAC_CLK_CTL1_OPAMP_CHOP_CLK_EN BIT(7) 281 + #define WCD939X_RDAC_CLK_CTL1_OPAMP_CHOP_CLK_DIV_CTRL GENMASK(6, 4) 282 + #define WCD939X_RDAC_CLK_CTL1_SPARE_BITS GENMASK(3, 0) 283 + #define WCD939X_HPH_RDAC_CLK_CTL2 (0x30da) 284 + #define WCD939X_HPH_RDAC_LDO_CTL (0x30db) 285 + #define WCD939X_HPH_RDAC_CHOP_CLK_LP_CTL (0x30dc) 286 + #define WCD939X_HPH_REFBUFF_UHQA_CTL (0x30dd) 287 + #define WCD939X_REFBUFF_UHQA_CTL_SPARE_BITS GENMASK(7, 6) 288 + #define WCD939X_REFBUFF_UHQA_CTL_HPH_VNEGREG2_COMP_CTL_OV BIT(5) 289 + #define WCD939X_REFBUFF_UHQA_CTL_REFBUFN_RBIAS_ADJUST BIT(4) 290 + #define WCD939X_REFBUFF_UHQA_CTL_REFBUFP_IOUT_CTL GENMASK(3, 2) 291 + #define WCD939X_REFBUFF_UHQA_CTL_REFBUFN_IOUT_CTL GENMASK(1, 0) 292 + #define WCD939X_HPH_REFBUFF_LP_CTL (0x30de) 293 + #define WCD939X_REFBUFF_LP_CTL_HPH_VNEGREG2_CURR_COMP GENMASK(7, 6) 294 + #define WCD939X_REFBUFF_LP_CTL_SPARE_BITS GENMASK(5, 4) 295 + #define WCD939X_REFBUFF_LP_CTL_EN_PREREF_FILT_STARTUP_CLKDIV BIT(3) 296 + #define WCD939X_REFBUFF_LP_CTL_PREREF_FILT_STARTUP_CLKDIV_CTL GENMASK(2, 1) 297 + #define WCD939X_REFBUFF_LP_CTL_PREREF_FILT_BYPASS BIT(0) 298 + #define WCD939X_HPH_L_DAC_CTL (0x30df) 299 + #define WCD939X_HPH_R_DAC_CTL (0x30e0) 300 + #define WCD939X_HPH_SURGE_COMP_SEL (0x30e1) 301 + #define WCD939X_HPH_SURGE_EN (0x30e2) 302 + #define WCD939X_EN_EN_SURGE_PROTECTION_HPHL BIT(7) 303 + #define WCD939X_EN_EN_SURGE_PROTECTION_HPHR BIT(6) 304 + #define WCD939X_EN_SEL_SURGE_COMP_IQ GENMASK(5, 4) 305 + #define WCD939X_EN_SURGE_VOLT_MODE_SHUTOFF_EN BIT(3) 306 + #define WCD939X_EN_LATCH_INTR_OP_STG_HIZ_EN BIT(2) 307 + #define WCD939X_EN_SURGE_LATCH_REG_RESET BIT(1) 308 + #define WCD939X_EN_SWTICH_VN_VNDAC_NSURGE_EN BIT(0) 309 + #define WCD939X_HPH_SURGE_MISC1 (0x30e3) 310 + #define WCD939X_HPH_SURGE_STATUS (0x30e4) 311 + #define WCD939X_EAR_EN (0x30e9) 312 + #define WCD939X_EAR_PA_CON (0x30ea) 313 + #define WCD939X_EAR_SP_CON (0x30eb) 314 + #define WCD939X_EAR_DAC_CON (0x30ec) 315 + #define WCD939X_DAC_CON_DAC_SAMPLE_EDGE_SEL BIT(7) 316 + #define WCD939X_DAC_CON_REF_DBG_EN BIT(6) 317 + #define WCD939X_DAC_CON_REF_DBG_GAIN GENMASK(5, 3) 318 + #define WCD939X_DAC_CON_GAIN_DAC GENMASK(2, 1) 319 + #define WCD939X_DAC_CON_INV_DATA BIT(0) 320 + #define WCD939X_EAR_CNP_FSM_CON (0x30ed) 321 + #define WCD939X_EAR_TEST_CTL (0x30ee) 322 + #define WCD939X_EAR_STATUS_REG_1 (0x30ef) 323 + #define WCD939X_EAR_STATUS_REG_2 (0x30f0) 324 + #define WCD939X_FLYBACK_NEW_CTRL_2 (0x30f6) 325 + #define WCD939X_FLYBACK_NEW_CTRL_3 (0x30f7) 326 + #define WCD939X_FLYBACK_NEW_CTRL_4 (0x30f8) 327 + #define WCD939X_ANA_NEW_PAGE (0x3100) 328 + #define WCD939X_HPH_NEW_ANA_HPH2 (0x3101) 329 + #define WCD939X_HPH_NEW_ANA_HPH3 (0x3102) 330 + #define WCD939X_SLEEP_CTL (0x3103) 331 + #define WCD939X_SLEEP_WATCHDOG_CTL (0x3104) 332 + #define WCD939X_MBHC_NEW_ELECT_REM_CLAMP_CTL (0x311f) 333 + #define WCD939X_MBHC_NEW_CTL_1 (0x3120) 334 + #define WCD939X_CTL_1_RCO_EN BIT(7) 335 + #define WCD939X_CTL_1_ADC_MODE BIT(4) 336 + #define WCD939X_CTL_1_ADC_ENABLE BIT(3) 337 + #define WCD939X_CTL_1_DETECTION_DONE BIT(2) 338 + #define WCD939X_CTL_1_BTN_DBNC_CTL GENMASK(1, 0) 339 + #define WCD939X_MBHC_NEW_CTL_2 (0x3121) 340 + #define WCD939X_CTL_2_MUX_CTL GENMASK(6, 4) 341 + #define WCD939X_CTL_2_M_RTH_CTL GENMASK(3, 2) 342 + #define WCD939X_CTL_2_HS_VREF_CTL GENMASK(1, 0) 343 + #define WCD939X_MBHC_NEW_PLUG_DETECT_CTL (0x3122) 344 + #define WCD939X_MBHC_NEW_ZDET_ANA_CTL (0x3123) 345 + #define WCD939X_ZDET_ANA_CTL_AVERAGING_EN BIT(7) 346 + #define WCD939X_ZDET_ANA_CTL_MAXV_CTL GENMASK(6, 4) 347 + #define WCD939X_ZDET_ANA_CTL_RANGE_CTL GENMASK(3, 0) 348 + #define WCD939X_MBHC_NEW_ZDET_RAMP_CTL (0x3124) 349 + #define WCD939X_ZDET_RAMP_CTL_ACC1_MIN_CTL GENMASK(6, 4) 350 + #define WCD939X_ZDET_RAMP_CTL_TIME_CTL GENMASK(3, 0) 351 + #define WCD939X_MBHC_NEW_FSM_STATUS (0x3125) 352 + #define WCD939X_FSM_STATUS_ADC_TIMEOUT BIT(7) 353 + #define WCD939X_FSM_STATUS_ADC_COMPLETE BIT(6) 354 + #define WCD939X_FSM_STATUS_HS_M_COMP_STATUS BIT(5) 355 + #define WCD939X_FSM_STATUS_FAST_PRESS_FLAG_STATUS BIT(4) 356 + #define WCD939X_FSM_STATUS_FAST_REMOVAL_FLAG_STATUS BIT(3) 357 + #define WCD939X_FSM_STATUS_REMOVAL_FLAG_STATUS BIT(2) 358 + #define WCD939X_FSM_STATUS_ELECT_REM_RT_STATUS BIT(1) 359 + #define WCD939X_FSM_STATUS_BTN_STATUS BIT(0) 360 + #define WCD939X_MBHC_NEW_ADC_RESULT (0x3126) 361 + #define WCD939X_ADC_RESULT_VALUE GENMASK(7, 0) 362 + #define WCD939X_TX_NEW_CH12_MUX (0x3127) 363 + #define WCD939X_TX_NEW_CH34_MUX (0x3128) 364 + #define WCD939X_DIE_CRACK_DET_EN (0x312c) 365 + #define WCD939X_DIE_CRACK_DET_OUT (0x312d) 366 + #define WCD939X_HPH_NEW_INT_RDAC_GAIN_CTL (0x3132) 367 + #define WCD939X_HPH_NEW_INT_PA_GAIN_CTL_L (0x3133) 368 + #define WCD939X_PA_GAIN_CTL_L_EN_HPHPA_2VPK BIT(7) 369 + #define WCD939X_PA_GAIN_CTL_L_RX_SUPPLY_LEVEL BIT(6) 370 + #define WCD939X_PA_GAIN_CTL_L_DAC_DR_BOOST BIT(5) 371 + #define WCD939X_PA_GAIN_CTL_L_VALUE GENMASK(4, 0) 372 + #define WCD939X_HPH_NEW_INT_RDAC_VREF_CTL (0x3134) 373 + #define WCD939X_HPH_NEW_INT_RDAC_OVERRIDE_CTL (0x3135) 374 + #define WCD939X_HPH_NEW_INT_PA_GAIN_CTL_R (0x3136) 375 + #define WCD939X_PA_GAIN_CTL_R_D_RCO_CLK_EN BIT(7) 376 + #define WCD939X_PA_GAIN_CTL_R_SPARE_BITS GENMASK(6, 5) 377 + #define WCD939X_PA_GAIN_CTL_R_VALUE GENMASK(4, 0) 378 + #define WCD939X_HPH_NEW_INT_PA_MISC1 (0x3137) 379 + #define WCD939X_HPH_NEW_INT_PA_MISC2 (0x3138) 380 + #define WCD939X_HPH_NEW_INT_PA_RDAC_MISC (0x3139) 381 + #define WCD939X_HPH_NEW_INT_TIMER1 (0x313a) 382 + #define WCD939X_TIMER1_CURR_IDIV_CTL_CMPDR_OFF GENMASK(7, 5) 383 + #define WCD939X_TIMER1_CURR_IDIV_CTL_AUTOCHOP GENMASK(4, 2) 384 + #define WCD939X_TIMER1_AUTOCHOP_TIMER_CTL_EN BIT(1) 385 + #define WCD939X_HPH_NEW_INT_TIMER2 (0x313b) 386 + #define WCD939X_HPH_NEW_INT_TIMER3 (0x313c) 387 + #define WCD939X_HPH_NEW_INT_TIMER4 (0x313d) 388 + #define WCD939X_HPH_NEW_INT_PA_RDAC_MISC2 (0x313e) 389 + #define WCD939X_HPH_NEW_INT_PA_RDAC_MISC3 (0x313f) 390 + #define WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_L (0x3140) 391 + #define WCD939X_RDAC_HD2_CTL_L_EN_HD2_RES_DIV_L BIT(7) 392 + #define WCD939X_RDAC_HD2_CTL_L_HD2_RES_DIV_PULLGND_L BIT(6) 393 + #define WCD939X_RDAC_HD2_CTL_L_HD2_RES_DIV_CTL_L GENMASK(5, 0) 394 + #define WCD939X_HPH_NEW_INT_RDAC_HD2_CTL_R (0x3141) 395 + #define WCD939X_RDAC_HD2_CTL_R_EN_HD2_RES_DIV_R BIT(7) 396 + #define WCD939X_RDAC_HD2_CTL_R_HD2_RES_DIV_PULLGND_L BIT(6) 397 + #define WCD939X_RDAC_HD2_CTL_R_HD2_RES_DIV_CTL_R GENMASK(5, 0) 398 + #define WCD939X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI (0x3145) 399 + #define WCD939X_RX_NEW_INT_HPH_RDAC_BIAS_ULP (0x3146) 400 + #define WCD939X_RX_NEW_INT_HPH_RDAC_LDO_LP (0x3147) 401 + #define WCD939X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL (0x31af) 402 + #define WCD939X_MOISTURE_DET_DC_CTRL_ONCOUNT GENMASK(6, 5) 403 + #define WCD939X_MOISTURE_DET_DC_CTRL_OFFCOUNT GENMASK(4, 0) 404 + #define WCD939X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL (0x31b0) 405 + #define WCD939X_MOISTURE_DET_POLLING_CTRL_HPHL_PA_EN BIT(6) 406 + #define WCD939X_MOISTURE_DET_POLLING_CTRL_DTEST_EN GENMASK(5, 4) 407 + #define WCD939X_MOISTURE_DET_POLLING_CTRL_MOIST_OVRD_POLLING BIT(3) 408 + #define WCD939X_MOISTURE_DET_POLLING_CTRL_MOIST_EN_POLLING BIT(2) 409 + #define WCD939X_MOISTURE_DET_POLLING_CTRL_MOIST_DBNC_TIME GENMASK(1, 0) 410 + #define WCD939X_MBHC_NEW_INT_MECH_DET_CURRENT (0x31b1) 411 + #define WCD939X_MECH_DET_CURRENT_HSDET_PULLUP_CTL GENMASK(4, 0) 412 + #define WCD939X_MBHC_NEW_INT_ZDET_CLK_AND_MOISTURE_CTL_NEW (0x31b2) 413 + #define WCD939X_EAR_INT_NEW_CHOPPER_CON (0x31b7) 414 + #define WCD939X_EAR_INT_NEW_CNP_VCM_CON1 (0x31b8) 415 + #define WCD939X_EAR_INT_NEW_CNP_VCM_CON2 (0x31b9) 416 + #define WCD939X_EAR_INT_NEW_DYNAMIC_BIAS (0x31ba) 417 + #define WCD939X_SLEEP_INT_WATCHDOG_CTL_1 (0x31d0) 418 + #define WCD939X_SLEEP_INT_WATCHDOG_CTL_2 (0x31d1) 419 + #define WCD939X_DIE_CRACK_INT_DET_INT1 (0x31d3) 420 + #define WCD939X_DIE_CRACK_INT_DET_INT2 (0x31d4) 421 + #define WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_L2 (0x31d5) 422 + #define WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_L1 (0x31d6) 423 + #define WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_L0 (0x31d7) 424 + #define WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_ULP1P2M (0x31d8) 425 + #define WCD939X_TX_COM_NEW_INT_FE_DIVSTOP_ULP0P6M (0x31d9) 426 + #define WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG1_L2L1 (0x31da) 427 + #define WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG1_L0 (0x31db) 428 + #define WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG1_ULP (0x31dc) 429 + #define WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_L2L1 (0x31dd) 430 + #define WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_L0 (0x31de) 431 + #define WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2MAIN_ULP (0x31df) 432 + #define WCD939X_FE_ICTRL_STG2MAIN_ULP_VALUE GENMASK(4, 0) 433 + #define WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2CASC_L2L1L0 (0x31e0) 434 + #define WCD939X_TX_COM_NEW_INT_FE_ICTRL_STG2CASC_ULP (0x31e1) 435 + #define WCD939X_FE_ICTRL_STG2CASC_ULP_ICTRL_SCBIAS_ULP0P6M GENMASK(7, 4) 436 + #define WCD939X_FE_ICTRL_STG2CASC_ULP_VALUE GENMASK(3, 0) 437 + #define WCD939X_TX_COM_NEW_INT_ADC_SCBIAS_L2L1 (0x31e2) 438 + #define WCD939X_TX_COM_NEW_INT_ADC_SCBIAS_L0ULP (0x31e3) 439 + #define WCD939X_TX_COM_NEW_INT_ADC_INT_L2 (0x31e4) 440 + #define WCD939X_TX_COM_NEW_INT_ADC_INT_L1 (0x31e5) 441 + #define WCD939X_TX_COM_NEW_INT_ADC_INT_L0 (0x31e6) 442 + #define WCD939X_TX_COM_NEW_INT_ADC_INT_ULP (0x31e7) 443 + #define WCD939X_DIGITAL_PAGE (0x3400) 444 + #define WCD939X_DIGITAL_CHIP_ID0 (0x3401) 445 + #define WCD939X_DIGITAL_CHIP_ID1 (0x3402) 446 + #define WCD939X_DIGITAL_CHIP_ID2 (0x3403) 447 + #define WCD939X_DIGITAL_CHIP_ID3 (0x3404) 448 + #define WCD939X_DIGITAL_SWR_TX_CLK_RATE (0x3405) 449 + #define WCD939X_DIGITAL_CDC_RST_CTL (0x3406) 450 + #define WCD939X_DIGITAL_TOP_CLK_CFG (0x3407) 451 + #define WCD939X_DIGITAL_CDC_ANA_CLK_CTL (0x3408) 452 + #define WCD939X_CDC_ANA_CLK_CTL_ANA_TX_DIV4_CLK_EN BIT(5) 453 + #define WCD939X_CDC_ANA_CLK_CTL_ANA_TX_DIV2_CLK_EN BIT(4) 454 + #define WCD939X_CDC_ANA_CLK_CTL_ANA_TX_CLK_EN BIT(3) 455 + #define WCD939X_CDC_ANA_CLK_CTL_ANA_RX_DIV4_CLK_EN BIT(2) 456 + #define WCD939X_CDC_ANA_CLK_CTL_ANA_RX_DIV2_CLK_EN BIT(1) 457 + #define WCD939X_CDC_ANA_CLK_CTL_ANA_RX_CLK_EN BIT(0) 458 + #define WCD939X_CDC_ANA_CLK_CTL_ANA_TX_DIV2_CLK_EN BIT(4) 459 + #define WCD939X_DIGITAL_CDC_DIG_CLK_CTL (0x3409) 460 + #define WCD939X_CDC_DIG_CLK_CTL_TXD3_CLK_EN BIT(7) 461 + #define WCD939X_CDC_DIG_CLK_CTL_TXD2_CLK_EN BIT(6) 462 + #define WCD939X_CDC_DIG_CLK_CTL_TXD1_CLK_EN BIT(5) 463 + #define WCD939X_CDC_DIG_CLK_CTL_TXD0_CLK_EN BIT(4) 464 + #define WCD939X_CDC_DIG_CLK_CTL_RXD2_CLK_EN BIT(2) 465 + #define WCD939X_CDC_DIG_CLK_CTL_RXD1_CLK_EN BIT(1) 466 + #define WCD939X_CDC_DIG_CLK_CTL_RXD0_CLK_EN BIT(0) 467 + #define WCD939X_DIGITAL_SWR_RST_EN (0x340a) 468 + #define WCD939X_DIGITAL_CDC_PATH_MODE (0x340b) 469 + #define WCD939X_DIGITAL_CDC_RX_RST (0x340c) 470 + #define WCD939X_DIGITAL_CDC_RX0_CTL (0x340d) 471 + #define WCD939X_DIGITAL_CDC_RX1_CTL (0x340e) 472 + #define WCD939X_DIGITAL_CDC_RX2_CTL (0x340f) 473 + #define WCD939X_DIGITAL_CDC_TX_ANA_MODE_0_1 (0x3410) 474 + #define WCD939X_CDC_TX_ANA_MODE_0_1_TXD1_MODE GENMASK(7, 4) 475 + #define WCD939X_CDC_TX_ANA_MODE_0_1_TXD0_MODE GENMASK(3, 0) 476 + #define WCD939X_DIGITAL_CDC_TX_ANA_MODE_2_3 (0x3411) 477 + #define WCD939X_CDC_TX_ANA_MODE_2_3_TXD3_MODE GENMASK(7, 4) 478 + #define WCD939X_CDC_TX_ANA_MODE_2_3_TXD2_MODE GENMASK(3, 0) 479 + #define WCD939X_DIGITAL_CDC_COMP_CTL_0 (0x3414) 480 + #define WCD939X_CDC_COMP_CTL_0_HPHL_COMP_EN BIT(1) 481 + #define WCD939X_CDC_COMP_CTL_0_HPHR_COMP_EN BIT(0) 482 + #define WCD939X_DIGITAL_CDC_ANA_TX_CLK_CTL (0x3417) 483 + #define WCD939X_CDC_ANA_TX_CLK_CTL_ANA_MBHC_1P2M_CLK_EN BIT(5) 484 + #define WCD939X_CDC_ANA_TX_CLK_CTL_ANA_TX3_ADC_CLK_EN BIT(4) 485 + #define WCD939X_CDC_ANA_TX_CLK_CTL_ANA_TX2_ADC_CLK_EN BIT(3) 486 + #define WCD939X_CDC_ANA_TX_CLK_CTL_ANA_TX1_ADC_CLK_EN BIT(2) 487 + #define WCD939X_CDC_ANA_TX_CLK_CTL_ANA_TX0_ADC_CLK_EN BIT(1) 488 + #define WCD939X_CDC_ANA_TX_CLK_CTL_ANA_TXSCBIAS_CLK_EN BIT(0) 489 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A1_0 (0x3418) 490 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A1_1 (0x3419) 491 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A2_0 (0x341a) 492 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A2_1 (0x341b) 493 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A3_0 (0x341c) 494 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A3_1 (0x341d) 495 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A4_0 (0x341e) 496 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A4_1 (0x341f) 497 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A5_0 (0x3420) 498 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A5_1 (0x3421) 499 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A6_0 (0x3422) 500 + #define WCD939X_DIGITAL_CDC_HPH_DSM_A7_0 (0x3423) 501 + #define WCD939X_DIGITAL_CDC_HPH_DSM_C_0 (0x3424) 502 + #define WCD939X_DIGITAL_CDC_HPH_DSM_C_1 (0x3425) 503 + #define WCD939X_DIGITAL_CDC_HPH_DSM_C_2 (0x3426) 504 + #define WCD939X_DIGITAL_CDC_HPH_DSM_C_3 (0x3427) 505 + #define WCD939X_DIGITAL_CDC_HPH_DSM_R1 (0x3428) 506 + #define WCD939X_DIGITAL_CDC_HPH_DSM_R2 (0x3429) 507 + #define WCD939X_DIGITAL_CDC_HPH_DSM_R3 (0x342a) 508 + #define WCD939X_DIGITAL_CDC_HPH_DSM_R4 (0x342b) 509 + #define WCD939X_DIGITAL_CDC_HPH_DSM_R5 (0x342c) 510 + #define WCD939X_DIGITAL_CDC_HPH_DSM_R6 (0x342d) 511 + #define WCD939X_DIGITAL_CDC_HPH_DSM_R7 (0x342e) 512 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A1_0 (0x342f) 513 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A1_1 (0x3430) 514 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A2_0 (0x3431) 515 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A2_1 (0x3432) 516 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A3_0 (0x3433) 517 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A3_1 (0x3434) 518 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A4_0 (0x3435) 519 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A4_1 (0x3436) 520 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A5_0 (0x3437) 521 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A5_1 (0x3438) 522 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A6_0 (0x3439) 523 + #define WCD939X_DIGITAL_CDC_EAR_DSM_A7_0 (0x343a) 524 + #define WCD939X_DIGITAL_CDC_EAR_DSM_C_0 (0x343b) 525 + #define WCD939X_DIGITAL_CDC_EAR_DSM_C_1 (0x343c) 526 + #define WCD939X_DIGITAL_CDC_EAR_DSM_C_2 (0x343d) 527 + #define WCD939X_DIGITAL_CDC_EAR_DSM_C_3 (0x343e) 528 + #define WCD939X_DIGITAL_CDC_EAR_DSM_R1 (0x343f) 529 + #define WCD939X_DIGITAL_CDC_EAR_DSM_R2 (0x3440) 530 + #define WCD939X_DIGITAL_CDC_EAR_DSM_R3 (0x3441) 531 + #define WCD939X_DIGITAL_CDC_EAR_DSM_R4 (0x3442) 532 + #define WCD939X_DIGITAL_CDC_EAR_DSM_R5 (0x3443) 533 + #define WCD939X_DIGITAL_CDC_EAR_DSM_R6 (0x3444) 534 + #define WCD939X_DIGITAL_CDC_EAR_DSM_R7 (0x3445) 535 + #define WCD939X_DIGITAL_CDC_HPH_GAIN_RX_0 (0x3446) 536 + #define WCD939X_DIGITAL_CDC_HPH_GAIN_RX_1 (0x3447) 537 + #define WCD939X_DIGITAL_CDC_HPH_GAIN_DSD_0 (0x3448) 538 + #define WCD939X_DIGITAL_CDC_HPH_GAIN_DSD_1 (0x3449) 539 + #define WCD939X_DIGITAL_CDC_HPH_GAIN_DSD_2 (0x344a) 540 + #define WCD939X_DIGITAL_CDC_EAR_GAIN_DSD_0 (0x344b) 541 + #define WCD939X_DIGITAL_CDC_EAR_GAIN_DSD_1 (0x344c) 542 + #define WCD939X_DIGITAL_CDC_EAR_GAIN_DSD_2 (0x344d) 543 + #define WCD939X_DIGITAL_CDC_HPH_GAIN_CTL (0x344e) 544 + #define WCD939X_CDC_HPH_GAIN_CTL_HPH_STEREO_EN BIT(4) 545 + #define WCD939X_CDC_HPH_GAIN_CTL_HPHR_RX_EN BIT(3) 546 + #define WCD939X_CDC_HPH_GAIN_CTL_HPHL_RX_EN BIT(2) 547 + #define WCD939X_CDC_HPH_GAIN_CTL_HPHR_DSD_EN BIT(1) 548 + #define WCD939X_CDC_HPH_GAIN_CTL_HPHL_DSD_EN BIT(0) 549 + #define WCD939X_DIGITAL_CDC_EAR_GAIN_CTL (0x344f) 550 + #define WCD939X_CDC_EAR_GAIN_CTL_EAR_EN BIT(0) 551 + #define WCD939X_DIGITAL_CDC_EAR_PATH_CTL (0x3450) 552 + #define WCD939X_DIGITAL_CDC_SWR_CLH (0x3451) 553 + #define WCD939X_CDC_SWR_CLH_CLH_CTL GENMASK(7, 0) 554 + #define WCD939X_DIGITAL_SWR_CLH_BYP (0x3452) 555 + #define WCD939X_DIGITAL_CDC_TX0_CTL (0x3453) 556 + #define WCD939X_DIGITAL_CDC_TX1_CTL (0x3454) 557 + #define WCD939X_DIGITAL_CDC_TX2_CTL (0x3455) 558 + #define WCD939X_DIGITAL_CDC_TX_RST (0x3456) 559 + #define WCD939X_DIGITAL_CDC_REQ_CTL (0x3457) 560 + #define WCD939X_CDC_REQ_CTL_TX3_WIDE_BAND BIT(5) 561 + #define WCD939X_CDC_REQ_CTL_TX2_WIDE_BAND BIT(4) 562 + #define WCD939X_CDC_REQ_CTL_TX1_WIDE_BAND BIT(3) 563 + #define WCD939X_CDC_REQ_CTL_TX0_WIDE_BAND BIT(2) 564 + #define WCD939X_CDC_REQ_CTL_FS_RATE_4P8 BIT(1) 565 + #define WCD939X_CDC_REQ_CTL_NO_NOTCH BIT(0) 566 + #define WCD939X_DIGITAL_CDC_RST (0x3458) 567 + #define WCD939X_DIGITAL_CDC_AMIC_CTL (0x345a) 568 + #define WCD939X_CDC_AMIC_CTL_AMIC5_IN_SEL BIT(3) 569 + #define WCD939X_CDC_AMIC_CTL_AMIC4_IN_SEL BIT(2) 570 + #define WCD939X_CDC_AMIC_CTL_AMIC3_IN_SEL BIT(1) 571 + #define WCD939X_CDC_AMIC_CTL_AMIC1_IN_SEL BIT(0) 572 + #define WCD939X_DIGITAL_CDC_DMIC_CTL (0x345b) 573 + #define WCD939X_CDC_DMIC_CTL_DMIC_LEGACY_SW_MODE BIT(3) 574 + #define WCD939X_CDC_DMIC_CTL_DMIC_DIV_BAK_EN BIT(2) 575 + #define WCD939X_CDC_DMIC_CTL_CLK_SCALE_EN BIT(1) 576 + #define WCD939X_CDC_DMIC_CTL_SOFT_RESET BIT(0) 577 + #define WCD939X_DIGITAL_CDC_DMIC1_CTL (0x345c) 578 + #define WCD939X_CDC_DMIC1_CTL_DMIC_CLK_SCALE_SEL GENMASK(6, 4) 579 + #define WCD939X_CDC_DMIC1_CTL_DMIC_CLK_EN BIT(3) 580 + #define WCD939X_CDC_DMIC1_CTL_DMIC_CLK_SEL GENMASK(2, 0) 581 + #define WCD939X_DIGITAL_CDC_DMIC2_CTL (0x345d) 582 + #define WCD939X_CDC_DMIC2_CTL_DMIC_LEFT_EN BIT(7) 583 + #define WCD939X_CDC_DMIC2_CTL_DMIC_CLK_SCALE_SEL GENMASK(6, 4) 584 + #define WCD939X_CDC_DMIC2_CTL_DMIC_CLK_EN BIT(3) 585 + #define WCD939X_CDC_DMIC2_CTL_DMIC_CLK_SEL GENMASK(2, 0) 586 + #define WCD939X_DIGITAL_CDC_DMIC3_CTL (0x345e) 587 + #define WCD939X_CDC_DMIC3_CTL_DMIC_CLK_SCALE_SEL GENMASK(6, 4) 588 + #define WCD939X_CDC_DMIC3_CTL_DMIC_CLK_EN BIT(3) 589 + #define WCD939X_CDC_DMIC3_CTL_DMIC_CLK_SEL GENMASK(2, 0) 590 + #define WCD939X_DIGITAL_CDC_DMIC4_CTL (0x345f) 591 + #define WCD939X_CDC_DMIC4_CTL_DMIC_CLK_SCALE_SEL GENMASK(6, 4) 592 + #define WCD939X_CDC_DMIC4_CTL_DMIC_CLK_EN BIT(3) 593 + #define WCD939X_CDC_DMIC4_CTL_DMIC_CLK_SEL GENMASK(2, 0) 594 + #define WCD939X_DIGITAL_EFUSE_PRG_CTL (0x3460) 595 + #define WCD939X_DIGITAL_EFUSE_CTL (0x3461) 596 + #define WCD939X_DIGITAL_CDC_DMIC_RATE_1_2 (0x3462) 597 + #define WCD939X_CDC_DMIC_RATE_1_2_DMIC2_RATE GENMASK(7, 4) 598 + #define WCD939X_CDC_DMIC_RATE_1_2_DMIC1_RATE GENMASK(3, 0) 599 + #define WCD939X_DIGITAL_CDC_DMIC_RATE_3_4 (0x3463) 600 + #define WCD939X_CDC_DMIC_RATE_3_4_DMIC4_RATE GENMASK(7, 4) 601 + #define WCD939X_CDC_DMIC_RATE_3_4_DMIC3_RATE GENMASK(3, 0) 602 + #define WCD939X_DIGITAL_PDM_WD_CTL0 (0x3465) 603 + #define WCD939X_PDM_WD_CTL0_HOLD_OFF BIT(4) 604 + #define WCD939X_PDM_WD_CTL0_TIME_OUT_SEL BIT(3) 605 + #define WCD939X_PDM_WD_CTL0_PDM_WD_EN GENMASK(2, 0) 606 + #define WCD939X_DIGITAL_PDM_WD_CTL1 (0x3466) 607 + #define WCD939X_PDM_WD_CTL1_HOLD_OFF BIT(4) 608 + #define WCD939X_PDM_WD_CTL1_TIME_OUT_SEL BIT(3) 609 + #define WCD939X_PDM_WD_CTL1_PDM_WD_EN GENMASK(2, 0) 610 + #define WCD939X_DIGITAL_PDM_WD_CTL2 (0x3467) 611 + #define WCD939X_DIGITAL_INTR_MODE (0x346a) 612 + #define WCD939X_DIGITAL_INTR_MASK_0 (0x346b) 613 + #define WCD939X_DIGITAL_INTR_MASK_1 (0x346c) 614 + #define WCD939X_DIGITAL_INTR_MASK_2 (0x346d) 615 + #define WCD939X_DIGITAL_INTR_STATUS_0 (0x346e) 616 + #define WCD939X_DIGITAL_INTR_STATUS_1 (0x346f) 617 + #define WCD939X_DIGITAL_INTR_STATUS_2 (0x3470) 618 + #define WCD939X_DIGITAL_INTR_CLEAR_0 (0x3471) 619 + #define WCD939X_DIGITAL_INTR_CLEAR_1 (0x3472) 620 + #define WCD939X_DIGITAL_INTR_CLEAR_2 (0x3473) 621 + #define WCD939X_DIGITAL_INTR_LEVEL_0 (0x3474) 622 + #define WCD939X_DIGITAL_INTR_LEVEL_1 (0x3475) 623 + #define WCD939X_DIGITAL_INTR_LEVEL_2 (0x3476) 624 + #define WCD939X_DIGITAL_INTR_SET_0 (0x3477) 625 + #define WCD939X_DIGITAL_INTR_SET_1 (0x3478) 626 + #define WCD939X_DIGITAL_INTR_SET_2 (0x3479) 627 + #define WCD939X_DIGITAL_INTR_TEST_0 (0x347a) 628 + #define WCD939X_DIGITAL_INTR_TEST_1 (0x347b) 629 + #define WCD939X_DIGITAL_INTR_TEST_2 (0x347c) 630 + #define WCD939X_DIGITAL_TX_MODE_DBG_EN (0x347f) 631 + #define WCD939X_DIGITAL_TX_MODE_DBG_0_1 (0x3480) 632 + #define WCD939X_DIGITAL_TX_MODE_DBG_2_3 (0x3481) 633 + #define WCD939X_DIGITAL_LB_IN_SEL_CTL (0x3482) 634 + #define WCD939X_DIGITAL_LOOP_BACK_MODE (0x3483) 635 + #define WCD939X_DIGITAL_SWR_DAC_TEST (0x3484) 636 + #define WCD939X_DIGITAL_SWR_HM_TEST_RX_0 (0x3485) 637 + #define WCD939X_DIGITAL_SWR_HM_TEST_TX_0 (0x3486) 638 + #define WCD939X_DIGITAL_SWR_HM_TEST_RX_1 (0x3487) 639 + #define WCD939X_DIGITAL_SWR_HM_TEST_TX_1 (0x3488) 640 + #define WCD939X_DIGITAL_SWR_HM_TEST_TX_2 (0x3489) 641 + #define WCD939X_DIGITAL_SWR_HM_TEST_0 (0x348a) 642 + #define WCD939X_DIGITAL_SWR_HM_TEST_1 (0x348b) 643 + #define WCD939X_DIGITAL_PAD_CTL_SWR_0 (0x348c) 644 + #define WCD939X_DIGITAL_PAD_CTL_SWR_1 (0x348d) 645 + #define WCD939X_DIGITAL_I2C_CTL (0x348e) 646 + #define WCD939X_DIGITAL_CDC_TX_TANGGU_SW_MODE (0x348f) 647 + #define WCD939X_DIGITAL_EFUSE_TEST_CTL_0 (0x3490) 648 + #define WCD939X_DIGITAL_EFUSE_TEST_CTL_1 (0x3491) 649 + #define WCD939X_DIGITAL_EFUSE_T_DATA_0 (0x3492) 650 + #define WCD939X_DIGITAL_EFUSE_T_DATA_1 (0x3493) 651 + #define WCD939X_DIGITAL_PAD_CTL_PDM_RX0 (0x3494) 652 + #define WCD939X_DIGITAL_PAD_CTL_PDM_RX1 (0x3495) 653 + #define WCD939X_DIGITAL_PAD_CTL_PDM_TX0 (0x3496) 654 + #define WCD939X_DIGITAL_PAD_CTL_PDM_TX1 (0x3497) 655 + #define WCD939X_DIGITAL_PAD_CTL_PDM_TX2 (0x3498) 656 + #define WCD939X_DIGITAL_PAD_INP_DIS_0 (0x3499) 657 + #define WCD939X_DIGITAL_PAD_INP_DIS_1 (0x349a) 658 + #define WCD939X_DIGITAL_DRIVE_STRENGTH_0 (0x349b) 659 + #define WCD939X_DIGITAL_DRIVE_STRENGTH_1 (0x349c) 660 + #define WCD939X_DIGITAL_DRIVE_STRENGTH_2 (0x349d) 661 + #define WCD939X_DIGITAL_RX_DATA_EDGE_CTL (0x349e) 662 + #define WCD939X_DIGITAL_TX_DATA_EDGE_CTL (0x349f) 663 + #define WCD939X_DIGITAL_GPIO_MODE (0x34a0) 664 + #define WCD939X_DIGITAL_PIN_CTL_OE (0x34a1) 665 + #define WCD939X_DIGITAL_PIN_CTL_DATA_0 (0x34a2) 666 + #define WCD939X_DIGITAL_PIN_CTL_DATA_1 (0x34a3) 667 + #define WCD939X_DIGITAL_PIN_STATUS_0 (0x34a4) 668 + #define WCD939X_DIGITAL_PIN_STATUS_1 (0x34a5) 669 + #define WCD939X_DIGITAL_DIG_DEBUG_CTL (0x34a6) 670 + #define WCD939X_DIGITAL_DIG_DEBUG_EN (0x34a7) 671 + #define WCD939X_DIGITAL_ANA_CSR_DBG_ADD (0x34a8) 672 + #define WCD939X_DIGITAL_ANA_CSR_DBG_CTL (0x34a9) 673 + #define WCD939X_DIGITAL_SSP_DBG (0x34aa) 674 + #define WCD939X_DIGITAL_MODE_STATUS_0 (0x34ab) 675 + #define WCD939X_DIGITAL_MODE_STATUS_1 (0x34ac) 676 + #define WCD939X_DIGITAL_SPARE_0 (0x34ad) 677 + #define WCD939X_DIGITAL_SPARE_1 (0x34ae) 678 + #define WCD939X_DIGITAL_SPARE_2 (0x34af) 679 + #define WCD939X_DIGITAL_EFUSE_REG_0 (0x34b0) 680 + #define WCD939X_EFUSE_REG_0_WCD939X_ID GENMASK(4, 1) 681 + #define WCD939X_EFUSE_REG_0_EFUSE_BLOWN BIT(0) 682 + #define WCD939X_DIGITAL_EFUSE_REG_1 (0x34b1) 683 + #define WCD939X_DIGITAL_EFUSE_REG_2 (0x34b2) 684 + #define WCD939X_DIGITAL_EFUSE_REG_3 (0x34b3) 685 + #define WCD939X_DIGITAL_EFUSE_REG_4 (0x34b4) 686 + #define WCD939X_DIGITAL_EFUSE_REG_5 (0x34b5) 687 + #define WCD939X_DIGITAL_EFUSE_REG_6 (0x34b6) 688 + #define WCD939X_DIGITAL_EFUSE_REG_7 (0x34b7) 689 + #define WCD939X_DIGITAL_EFUSE_REG_8 (0x34b8) 690 + #define WCD939X_DIGITAL_EFUSE_REG_9 (0x34b9) 691 + #define WCD939X_DIGITAL_EFUSE_REG_10 (0x34ba) 692 + #define WCD939X_DIGITAL_EFUSE_REG_11 (0x34bb) 693 + #define WCD939X_DIGITAL_EFUSE_REG_12 (0x34bc) 694 + #define WCD939X_DIGITAL_EFUSE_REG_13 (0x34bd) 695 + #define WCD939X_DIGITAL_EFUSE_REG_14 (0x34be) 696 + #define WCD939X_DIGITAL_EFUSE_REG_15 (0x34bf) 697 + #define WCD939X_DIGITAL_EFUSE_REG_16 (0x34c0) 698 + #define WCD939X_DIGITAL_EFUSE_REG_17 (0x34c1) 699 + #define WCD939X_DIGITAL_EFUSE_REG_18 (0x34c2) 700 + #define WCD939X_DIGITAL_EFUSE_REG_19 (0x34c3) 701 + #define WCD939X_DIGITAL_EFUSE_REG_20 (0x34c4) 702 + #define WCD939X_DIGITAL_EFUSE_REG_21 (0x34c5) 703 + #define WCD939X_DIGITAL_EFUSE_REG_22 (0x34c6) 704 + #define WCD939X_DIGITAL_EFUSE_REG_23 (0x34c7) 705 + #define WCD939X_DIGITAL_EFUSE_REG_24 (0x34c8) 706 + #define WCD939X_DIGITAL_EFUSE_REG_25 (0x34c9) 707 + #define WCD939X_DIGITAL_EFUSE_REG_26 (0x34ca) 708 + #define WCD939X_DIGITAL_EFUSE_REG_27 (0x34cb) 709 + #define WCD939X_DIGITAL_EFUSE_REG_28 (0x34cc) 710 + #define WCD939X_DIGITAL_EFUSE_REG_29 (0x34cd) 711 + #define WCD939X_DIGITAL_EFUSE_REG_30 (0x34ce) 712 + #define WCD939X_DIGITAL_EFUSE_REG_31 (0x34cf) 713 + #define WCD939X_DIGITAL_TX_REQ_FB_CTL_0 (0x34d0) 714 + #define WCD939X_DIGITAL_TX_REQ_FB_CTL_1 (0x34d1) 715 + #define WCD939X_DIGITAL_TX_REQ_FB_CTL_2 (0x34d2) 716 + #define WCD939X_DIGITAL_TX_REQ_FB_CTL_3 (0x34d3) 717 + #define WCD939X_DIGITAL_TX_REQ_FB_CTL_4 (0x34d4) 718 + #define WCD939X_DIGITAL_DEM_BYPASS_DATA0 (0x34d5) 719 + #define WCD939X_DIGITAL_DEM_BYPASS_DATA1 (0x34d6) 720 + #define WCD939X_DIGITAL_DEM_BYPASS_DATA2 (0x34d7) 721 + #define WCD939X_DIGITAL_DEM_BYPASS_DATA3 (0x34d8) 722 + #define WCD939X_DIGITAL_DEM_SECOND_ORDER (0x34d9) 723 + #define WCD939X_DIGITAL_DSM_CTRL (0x34da) 724 + #define WCD939X_DIGITAL_DSM_0_STATIC_DATA_0 (0x34db) 725 + #define WCD939X_DIGITAL_DSM_0_STATIC_DATA_1 (0x34dc) 726 + #define WCD939X_DIGITAL_DSM_0_STATIC_DATA_2 (0x34dd) 727 + #define WCD939X_DIGITAL_DSM_0_STATIC_DATA_3 (0x34de) 728 + #define WCD939X_DIGITAL_DSM_1_STATIC_DATA_0 (0x34df) 729 + #define WCD939X_DIGITAL_DSM_1_STATIC_DATA_1 (0x34e0) 730 + #define WCD939X_DIGITAL_DSM_1_STATIC_DATA_2 (0x34e1) 731 + #define WCD939X_DIGITAL_DSM_1_STATIC_DATA_3 (0x34e2) 732 + #define WCD939X_RX_TOP_PAGE (0x3500) 733 + #define WCD939X_RX_TOP_TOP_CFG0 (0x3501) 734 + #define WCD939X_TOP_CFG0_HPH_DAC_RATE_SEL BIT(1) 735 + #define WCD939X_TOP_CFG0_PGA_UPDATE BIT(0) 736 + #define WCD939X_RX_TOP_HPHL_COMP_WR_LSB (0x3502) 737 + #define WCD939X_RX_TOP_HPHL_COMP_WR_MSB (0x3503) 738 + #define WCD939X_RX_TOP_HPHL_COMP_LUT (0x3504) 739 + #define WCD939X_RX_TOP_HPHL_COMP_RD_LSB (0x3505) 740 + #define WCD939X_RX_TOP_HPHL_COMP_RD_MSB (0x3506) 741 + #define WCD939X_RX_TOP_HPHR_COMP_WR_LSB (0x3507) 742 + #define WCD939X_RX_TOP_HPHR_COMP_WR_MSB (0x3508) 743 + #define WCD939X_RX_TOP_HPHR_COMP_LUT (0x3509) 744 + #define WCD939X_RX_TOP_HPHR_COMP_RD_LSB (0x350a) 745 + #define WCD939X_RX_TOP_HPHR_COMP_RD_MSB (0x350b) 746 + #define WCD939X_RX_TOP_DSD0_DEBUG_CFG1 (0x350c) 747 + #define WCD939X_RX_TOP_DSD0_DEBUG_CFG2 (0x350d) 748 + #define WCD939X_RX_TOP_DSD0_DEBUG_CFG3 (0x350e) 749 + #define WCD939X_RX_TOP_DSD0_DEBUG_CFG4 (0x350f) 750 + #define WCD939X_RX_TOP_DSD0_DEBUG_CFG5 (0x3510) 751 + #define WCD939X_RX_TOP_DSD0_DEBUG_CFG6 (0x3511) 752 + #define WCD939X_RX_TOP_DSD1_DEBUG_CFG1 (0x3512) 753 + #define WCD939X_RX_TOP_DSD1_DEBUG_CFG2 (0x3513) 754 + #define WCD939X_RX_TOP_DSD1_DEBUG_CFG3 (0x3514) 755 + #define WCD939X_RX_TOP_DSD1_DEBUG_CFG4 (0x3515) 756 + #define WCD939X_RX_TOP_DSD1_DEBUG_CFG5 (0x3516) 757 + #define WCD939X_RX_TOP_DSD1_DEBUG_CFG6 (0x3517) 758 + #define WCD939X_RX_TOP_HPHL_PATH_CFG0 (0x351c) 759 + #define WCD939X_HPHL_PATH_CFG0_INT_EN BIT(1) 760 + #define WCD939X_HPHL_PATH_CFG0_DLY_ZN_EN BIT(0) 761 + #define WCD939X_RX_TOP_HPHL_PATH_CFG1 (0x351d) 762 + #define WCD939X_HPHL_PATH_CFG1_DSM_SOFT_RST BIT(5) 763 + #define WCD939X_HPHL_PATH_CFG1_INT_SOFT_RST BIT(4) 764 + #define WCD939X_HPHL_PATH_CFG1_FMT_CONV BIT(3) 765 + #define WCD939X_HPHL_PATH_CFG1_IDLE_OVRD_EN BIT(2) 766 + #define WCD939X_HPHL_PATH_CFG1_RX_DC_DROOP_COEFF_SEL GENMASK(1, 0) 767 + #define WCD939X_RX_TOP_HPHR_PATH_CFG0 (0x351e) 768 + #define WCD939X_HPHR_PATH_CFG0_INT_EN BIT(2) 769 + #define WCD939X_HPHR_PATH_CFG0_DLY_ZN_EN BIT(1) 770 + #define WCD939X_RX_TOP_HPHR_PATH_CFG1 (0x351f) 771 + #define WCD939X_HPHR_PATH_CFG1_DSM_SOFT_RST BIT(5) 772 + #define WCD939X_HPHR_PATH_CFG1_INT_SOFT_RST BIT(4) 773 + #define WCD939X_HPHR_PATH_CFG1_FMT_CONV BIT(3) 774 + #define WCD939X_HPHR_PATH_CFG1_IDLE_OVRD_EN BIT(2) 775 + #define WCD939X_HPHR_PATH_CFG1_RX_DC_DROOP_COEFF_SEL GENMASK(1, 0) 776 + #define WCD939X_RX_TOP_PATH_CFG2 (0x3520) 777 + #define WCD939X_RX_TOP_HPHL_PATH_SEC0 (0x3521) 778 + #define WCD939X_RX_TOP_HPHL_PATH_SEC1 (0x3522) 779 + #define WCD939X_RX_TOP_HPHL_PATH_SEC2 (0x3523) 780 + #define WCD939X_RX_TOP_HPHL_PATH_SEC3 (0x3524) 781 + #define WCD939X_RX_TOP_HPHR_PATH_SEC0 (0x3525) 782 + #define WCD939X_RX_TOP_HPHR_PATH_SEC1 (0x3526) 783 + #define WCD939X_RX_TOP_HPHR_PATH_SEC2 (0x3527) 784 + #define WCD939X_RX_TOP_HPHR_PATH_SEC3 (0x3528) 785 + #define WCD939X_RX_TOP_PATH_SEC4 (0x3529) 786 + #define WCD939X_RX_TOP_PATH_SEC5 (0x352a) 787 + #define WCD939X_COMPANDER_HPHL_CTL0 (0x3540) 788 + #define WCD939X_COMPANDER_HPHL_CTL1 (0x3541) 789 + #define WCD939X_COMPANDER_HPHL_CTL2 (0x3542) 790 + #define WCD939X_COMPANDER_HPHL_CTL3 (0x3543) 791 + #define WCD939X_COMPANDER_HPHL_CTL4 (0x3544) 792 + #define WCD939X_COMPANDER_HPHL_CTL5 (0x3545) 793 + #define WCD939X_COMPANDER_HPHL_CTL6 (0x3546) 794 + #define WCD939X_COMPANDER_HPHL_CTL7 (0x3547) 795 + #define WCD939X_COMPANDER_HPHL_CTL8 (0x3548) 796 + #define WCD939X_COMPANDER_HPHL_CTL9 (0x3549) 797 + #define WCD939X_COMPANDER_HPHL_CTL10 (0x354a) 798 + #define WCD939X_COMPANDER_HPHL_CTL11 (0x354b) 799 + #define WCD939X_COMPANDER_HPHL_CTL12 (0x354c) 800 + #define WCD939X_COMPANDER_HPHL_CTL13 (0x354d) 801 + #define WCD939X_COMPANDER_HPHL_CTL14 (0x354e) 802 + #define WCD939X_COMPANDER_HPHL_CTL15 (0x354f) 803 + #define WCD939X_COMPANDER_HPHL_CTL16 (0x3550) 804 + #define WCD939X_COMPANDER_HPHL_CTL17 (0x3551) 805 + #define WCD939X_COMPANDER_HPHL_CTL18 (0x3552) 806 + #define WCD939X_COMPANDER_HPHL_CTL19 (0x3553) 807 + #define WCD939X_R_CTL0 (0x3560) 808 + #define WCD939X_R_CTL1 (0x3561) 809 + #define WCD939X_R_CTL2 (0x3562) 810 + #define WCD939X_R_CTL3 (0x3563) 811 + #define WCD939X_R_CTL4 (0x3564) 812 + #define WCD939X_R_CTL5 (0x3565) 813 + #define WCD939X_R_CTL6 (0x3566) 814 + #define WCD939X_R_CTL7 (0x3567) 815 + #define WCD939X_R_CTL8 (0x3568) 816 + #define WCD939X_R_CTL9 (0x3569) 817 + #define WCD939X_R_CTL10 (0x356a) 818 + #define WCD939X_R_CTL11 (0x356b) 819 + #define WCD939X_R_CTL12 (0x356c) 820 + #define WCD939X_R_CTL13 (0x356d) 821 + #define WCD939X_R_CTL14 (0x356e) 822 + #define WCD939X_R_CTL15 (0x356f) 823 + #define WCD939X_R_CTL16 (0x3570) 824 + #define WCD939X_R_CTL17 (0x3571) 825 + #define WCD939X_R_CTL18 (0x3572) 826 + #define WCD939X_R_CTL19 (0x3573) 827 + #define WCD939X_E_PATH_CTL (0x3580) 828 + #define WCD939X_E_CFG0 (0x3581) 829 + #define WCD939X_CFG0_AUTO_DISABLE_ANC BIT(2) 830 + #define WCD939X_CFG0_AUTO_DISABLE_DSD BIT(1) 831 + #define WCD939X_CFG0_IDLE_STEREO BIT(0) 832 + #define WCD939X_E_CFG1 (0x3582) 833 + #define WCD939X_E_CFG2 (0x3583) 834 + #define WCD939X_E_CFG3 (0x3584) 835 + #define WCD939X_DSD_HPHL_PATH_CTL (0x3590) 836 + #define WCD939X_DSD_HPHL_CFG0 (0x3591) 837 + #define WCD939X_DSD_HPHL_CFG1 (0x3592) 838 + #define WCD939X_DSD_HPHL_CFG2 (0x3593) 839 + #define WCD939X_DSD_HPHL_CFG3 (0x3594) 840 + #define WCD939X_DSD_HPHL_CFG4 (0x3595) 841 + #define WCD939X_DSD_HPHL_CFG5 (0x3596) 842 + #define WCD939X_DSD_HPHR_PATH_CTL (0x35a0) 843 + #define WCD939X_DSD_HPHR_CFG0 (0x35a1) 844 + #define WCD939X_DSD_HPHR_CFG1 (0x35a2) 845 + #define WCD939X_DSD_HPHR_CFG2 (0x35a3) 846 + #define WCD939X_DSD_HPHR_CFG3 (0x35a4) 847 + #define WCD939X_DSD_HPHR_CFG4 (0x35a5) 848 + #define WCD939X_DSD_HPHR_CFG5 (0x35a6) 849 + #define WCD939X_MAX_REGISTER (WCD939X_DSD_HPHR_CFG5) 850 + 851 + #define WCD939X_MAX_SWR_PORTS (6) 852 + #define WCD939X_MAX_RX_SWR_PORTS (6) 853 + #define WCD939X_MAX_TX_SWR_PORTS (4) 854 + #define WCD939X_MAX_SWR_CH_IDS (15) 855 + 856 + struct wcd939x_sdw_ch_info { 857 + int port_num; 858 + unsigned int ch_mask; 859 + }; 860 + 861 + #define WCD_SDW_CH(id, pn, cmask) \ 862 + [id] = { \ 863 + .port_num = pn, \ 864 + .ch_mask = cmask, \ 865 + } 866 + 867 + enum wcd939x_tx_sdw_ports { 868 + WCD939X_ADC_1_4_PORT = 1, 869 + WCD939X_ADC_DMIC_1_2_PORT, 870 + WCD939X_DMIC_0_3_MBHC_PORT, 871 + WCD939X_DMIC_3_7_PORT, 872 + }; 873 + 874 + enum wcd939x_tx_sdw_channels { 875 + WCD939X_ADC1, 876 + WCD939X_ADC2, 877 + WCD939X_ADC3, 878 + WCD939X_ADC4, 879 + WCD939X_DMIC0, 880 + WCD939X_DMIC1, 881 + WCD939X_MBHC, 882 + WCD939X_DMIC2, 883 + WCD939X_DMIC3, 884 + WCD939X_DMIC4, 885 + WCD939X_DMIC5, 886 + WCD939X_DMIC6, 887 + WCD939X_DMIC7, 888 + }; 889 + 890 + enum wcd939x_rx_sdw_ports { 891 + WCD939X_HPH_PORT = 1, 892 + WCD939X_CLSH_PORT, 893 + WCD939X_COMP_PORT, 894 + WCD939X_LO_PORT, 895 + WCD939X_DSD_PORT, 896 + WCD939X_HIFI_PCM_PORT, 897 + }; 898 + 899 + enum wcd939x_rx_sdw_channels { 900 + WCD939X_HPH_L, 901 + WCD939X_HPH_R, 902 + WCD939X_CLSH, 903 + WCD939X_COMP_L, 904 + WCD939X_COMP_R, 905 + WCD939X_LO, 906 + WCD939X_DSD_L, 907 + WCD939X_DSD_R, 908 + WCD939X_HIFI_PCM_L, 909 + WCD939X_HIFI_PCM_R, 910 + }; 911 + 912 + enum { 913 + WCD939X_SDW_DIR_RX, 914 + WCD939X_SDW_DIR_TX, 915 + }; 916 + 917 + struct wcd939x_priv; 918 + struct wcd939x_sdw_priv { 919 + struct sdw_slave *sdev; 920 + struct sdw_stream_config sconfig; 921 + struct sdw_stream_runtime *sruntime; 922 + struct sdw_port_config port_config[WCD939X_MAX_SWR_PORTS]; 923 + struct wcd939x_sdw_ch_info *ch_info; 924 + bool port_enable[WCD939X_MAX_SWR_CH_IDS]; 925 + int active_ports; 926 + int num_ports; 927 + bool is_tx; 928 + struct wcd939x_priv *wcd939x; 929 + struct irq_domain *slave_irq; 930 + struct regmap *regmap; 931 + }; 932 + 933 + #if IS_ENABLED(CONFIG_SND_SOC_WCD939X_SDW) 934 + int wcd939x_sdw_free(struct wcd939x_sdw_priv *wcd, 935 + struct snd_pcm_substream *substream, 936 + struct snd_soc_dai *dai); 937 + int wcd939x_sdw_set_sdw_stream(struct wcd939x_sdw_priv *wcd, 938 + struct snd_soc_dai *dai, 939 + void *stream, int direction); 940 + int wcd939x_sdw_hw_params(struct wcd939x_sdw_priv *wcd, 941 + struct snd_pcm_substream *substream, 942 + struct snd_pcm_hw_params *params, 943 + struct snd_soc_dai *dai); 944 + 945 + struct device *wcd939x_sdw_device_get(struct device_node *np); 946 + unsigned int wcd939x_swr_get_current_bank(struct sdw_slave *sdev); 947 + 948 + struct regmap *wcd939x_swr_get_regmap(struct wcd939x_sdw_priv *wcd); 949 + #else 950 + 951 + static inline int wcd939x_sdw_free(struct wcd939x_sdw_priv *wcd, 952 + struct snd_pcm_substream *substream, 953 + struct snd_soc_dai *dai) 954 + { 955 + return -EOPNOTSUPP; 956 + } 957 + 958 + static inline int wcd939x_sdw_set_sdw_stream(struct wcd939x_sdw_priv *wcd, 959 + struct snd_soc_dai *dai, 960 + void *stream, int direction) 961 + { 962 + return -EOPNOTSUPP; 963 + } 964 + 965 + static inline int wcd939x_sdw_hw_params(struct wcd939x_sdw_priv *wcd, 966 + struct snd_pcm_substream *substream, 967 + struct snd_pcm_hw_params *params, 968 + struct snd_soc_dai *dai) 969 + { 970 + return -EOPNOTSUPP; 971 + } 972 + 973 + static inline struct device *wcd939x_sdw_device_get(struct device_node *np) 974 + { 975 + return NULL; 976 + } 977 + 978 + static inline unsigned int wcd939x_swr_get_current_bank(struct sdw_slave *sdev) 979 + { 980 + return 0; 981 + } 982 + 983 + struct regmap *wcd939x_swr_get_regmap(struct wcd939x_sdw_priv *wcd) 984 + { 985 + return PTR_ERR(-EINVAL); 986 + } 987 + #endif /* CONFIG_SND_SOC_WCD939X_SDW */ 988 + 989 + #endif /* __WCD939X_H__ */