Merge "audio-kernel: Fix compile with CONFIG_DEBUG_FS removed"
diff --git a/Android.mk b/Android.mk
index f5b8931..e0d3f0f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -60,3 +60,8 @@
$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers)
include $(MY_LOCAL_PATH)/asoc/codecs/wcd937x/Android.mk
endif
+
+ifeq ($(call is-board-platform-in-list, lito),true)
+$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wsa883x/Module.symvers)
+include $(MY_LOCAL_PATH)/asoc/codecs/wsa883x/Android.mk
+endif
\ No newline at end of file
diff --git a/asoc/bengal.c b/asoc/bengal.c
index 1ab7f99..ec73cc9 100644
--- a/asoc/bengal.c
+++ b/asoc/bengal.c
@@ -5030,6 +5030,33 @@
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
},
+ /* Proxy Tx BACK END DAI Link */
+ {
+ .name = LPASS_BE_PROXY_TX,
+ .stream_name = "Proxy Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.8195",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_PROXY_TX,
+ .ignore_suspend = 1,
+ },
+ /* Proxy Rx BACK END DAI Link */
+ {
+ .name = LPASS_BE_PROXY_RX,
+ .stream_name = "Proxy Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.8194",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_PROXY_RX,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
{
.name = LPASS_BE_USB_AUDIO_RX,
.stream_name = "USB Audio Playback",
diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild
index 7a2cfcd..5ab7c3b 100644
--- a/asoc/codecs/Kbuild
+++ b/asoc/codecs/Kbuild
@@ -227,6 +227,7 @@
obj-y += wcd938x/
obj-y += bolero/
obj-y += rouleur/
+ obj-y += wsa883x/
endif
# Module information used by KBuild framework
obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o
diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c
index eb7cb88..70b0126 100644
--- a/asoc/codecs/bolero/rx-macro.c
+++ b/asoc/codecs/bolero/rx-macro.c
@@ -1908,7 +1908,12 @@
0x40, 0x40);
break;
case INTERP_HPHR:
- snd_soc_component_update_bits(component,
+ if (rx_priv->is_ear_mode_on)
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_RX_CLSH_HPH_V_PA,
+ 0x3F, 0x39);
+ else
+ snd_soc_component_update_bits(component,
BOLERO_CDC_RX_CLSH_HPH_V_PA,
0x3F, 0x1C);
snd_soc_component_update_bits(component,
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index 472cdfe..121f56d 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -496,8 +496,6 @@
hpf_cut_off_freq << 5);
snd_soc_component_update_bits(component, hpf_gate_reg,
0x03, 0x02);
- /* Minimum 1 clk cycle delay is required as per HW spec */
- usleep_range(1000, 1010);
snd_soc_component_update_bits(component, hpf_gate_reg,
0x03, 0x01);
} else {
@@ -993,10 +991,6 @@
if (!is_amic_enabled(component, decimator))
snd_soc_component_update_bits(component,
hpf_gate_reg, 0x03, 0x00);
- /*
- * Minimum 1 clk cycle delay is required as per HW spec
- */
- usleep_range(1000, 1010);
snd_soc_component_update_bits(component,
hpf_gate_reg, 0x03, 0x01);
/*
diff --git a/asoc/codecs/csra66x0/csra66x0.c b/asoc/codecs/csra66x0/csra66x0.c
index e0e702f..9cdbbda 100644
--- a/asoc/codecs/csra66x0/csra66x0.c
+++ b/asoc/codecs/csra66x0/csra66x0.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
#include <linux/delay.h>
@@ -602,6 +602,25 @@
{"PGA", NULL, "DAC"},
{"SPKR", NULL, "PGA"},
};
+/*
+ * csra66x0_hw_free_mute - Update csra66x0 mute register
+ *
+ * @component - csra66x0 component
+ *
+ */
+void csra66x0_hw_free_mute(struct snd_soc_component *component)
+{
+ int val = 0;
+
+ if (component == NULL)
+ return;
+
+ val = snd_soc_component_read32(component,
+ CSRA66X0_MISC_CONTROL_STATUS_1_FA);
+ snd_soc_component_write(component, CSRA66X0_MISC_CONTROL_STATUS_1_FA,
+ val | 0x04);
+}
+EXPORT_SYMBOL(csra66x0_hw_free_mute);
static int csra66x0_wait_for_config_state(struct snd_soc_component *component)
{
diff --git a/asoc/codecs/csra66x0/csra66x0.h b/asoc/codecs/csra66x0/csra66x0.h
index 04d9ef8..2bde3cc 100644
--- a/asoc/codecs/csra66x0/csra66x0.h
+++ b/asoc/codecs/csra66x0/csra66x0.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CSRA66X0_H
@@ -226,4 +226,6 @@
#define FAULT_STATUS_TEMP 0x10
#define FAULT_STATUS_PROTECT 0x20
+
+void csra66x0_hw_free_mute(struct snd_soc_component *component);
#endif /* _CSRA66X0_H */
diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c
index 2fb954b..30ad7e3 100644
--- a/asoc/codecs/wcd937x/wcd937x.c
+++ b/asoc/codecs/wcd937x/wcd937x.c
@@ -570,7 +570,8 @@
snd_soc_component_update_bits(component,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
0x0F, 0x06);
- snd_soc_component_update_bits(component,
+ if (wcd937x->comp1_enable)
+ snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_COMP_CTL_0,
0x02, 0x02);
usleep_range(5000, 5010);
@@ -588,6 +589,10 @@
snd_soc_component_update_bits(component,
WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
0x0F, 0x01);
+ if (wcd937x->comp1_enable)
+ snd_soc_component_update_bits(component,
+ WCD937X_DIGITAL_CDC_COMP_CTL_0,
+ 0x02, 0x00);
break;
};
return 0;
@@ -1449,7 +1454,7 @@
mutex_unlock(&wcd937x->ana_tx_clk_lock);
if (wcd937x->micb_ref[micb_index] == 1) {
snd_soc_component_update_bits(component,
- WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0);
+ WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0xF0, 0xF0);
snd_soc_component_update_bits(component,
WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
snd_soc_component_update_bits(component,
diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h
index c59d5b8..f8a47fd 100644
--- a/asoc/codecs/wcd938x/internal.h
+++ b/asoc/codecs/wcd938x/internal.h
@@ -155,8 +155,8 @@
enum {
/* INTR_CTRL_INT_MASK_0 */
- WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET = 0,
- WCD938X_IRQ_MBHC_BUTTON_PRESS_DET,
+ WCD938X_IRQ_MBHC_BUTTON_PRESS_DET = 0,
+ WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET,
WCD938X_IRQ_MBHC_ELECT_INS_REM_DET,
WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
WCD938X_IRQ_MBHC_SW_DET,
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index c90bba4..abd3106 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -657,8 +657,10 @@
WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x04, 0x04);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01);
- snd_soc_component_update_bits(component,
- WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x02);
+ if (wcd938x->comp1_enable)
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_CDC_COMP_CTL_0,
+ 0x02, 0x02);
}
/* 5 msec delay as per HW requirement */
usleep_range(5000, 5010);
@@ -683,8 +685,10 @@
WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x04, 0x00);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00);
- snd_soc_component_update_bits(component,
- WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x02, 0x00);
+ if (wcd938x->comp1_enable)
+ snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_CDC_COMP_CTL_0,
+ 0x02, 0x00);
}
snd_soc_component_update_bits(component,
WCD938X_ANA_EAR_COMPANDER_CTL, 0x80, 0x00);
@@ -777,7 +781,7 @@
usleep_range(100, 110);
set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
snd_soc_component_update_bits(component,
- WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x13);
+ WCD938X_DIGITAL_PDM_WD_CTL1, 0x07, 0x03);
break;
case SND_SOC_DAPM_POST_PMU:
/*
@@ -857,7 +861,7 @@
snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
0x10, 0x00);
snd_soc_component_update_bits(component,
- WCD938X_DIGITAL_PDM_WD_CTL1, 0x17, 0x00);
+ WCD938X_DIGITAL_PDM_WD_CTL1, 0x07, 0x00);
wcd_cls_h_fsm(component, &wcd938x->clsh_info,
WCD_CLSH_EVENT_POST_PA,
WCD_CLSH_STATE_HPHR,
@@ -913,7 +917,7 @@
usleep_range(100, 110);
set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
snd_soc_component_update_bits(component,
- WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x13);
+ WCD938X_DIGITAL_PDM_WD_CTL0, 0x07, 0x03);
break;
case SND_SOC_DAPM_POST_PMU:
/*
@@ -993,7 +997,7 @@
snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
0x20, 0x00);
snd_soc_component_update_bits(component,
- WCD938X_DIGITAL_PDM_WD_CTL0, 0x17, 0x00);
+ WCD938X_DIGITAL_PDM_WD_CTL0, 0x07, 0x00);
wcd_cls_h_fsm(component, &wcd938x->clsh_info,
WCD_CLSH_EVENT_POST_PA,
WCD_CLSH_STATE_HPHL,
@@ -1026,7 +1030,7 @@
wcd938x->rx_swr_dev->dev_num,
true);
snd_soc_component_update_bits(component,
- WCD938X_DIGITAL_PDM_WD_CTL2, 0x05, 0x05);
+ WCD938X_DIGITAL_PDM_WD_CTL2, 0x01, 0x01);
break;
case SND_SOC_DAPM_POST_PMU:
/* 1 msec delay as per HW requirement */
@@ -1054,7 +1058,7 @@
/* 1 msec delay as per HW requirement */
usleep_range(1000, 1010);
snd_soc_component_update_bits(component,
- WCD938X_DIGITAL_PDM_WD_CTL2, 0x05, 0x00);
+ WCD938X_DIGITAL_PDM_WD_CTL2, 0x01, 0x00);
wcd_cls_h_fsm(component, &wcd938x->clsh_info,
WCD_CLSH_EVENT_POST_PA,
WCD_CLSH_STATE_AUX,
@@ -1098,11 +1102,11 @@
if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_PDM_WD_CTL2,
- 0x05, 0x05);
+ 0x01, 0x01);
else
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_PDM_WD_CTL0,
- 0x17, 0x13);
+ 0x07, 0x03);
if (!wcd938x->comp1_enable)
snd_soc_component_update_bits(component,
WCD938X_ANA_EAR_COMPANDER_CTL, 0x80, 0x80);
@@ -1157,11 +1161,11 @@
if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_PDM_WD_CTL2,
- 0x05, 0x00);
+ 0x01, 0x00);
else
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_PDM_WD_CTL0,
- 0x17, 0x00);
+ 0x07, 0x00);
wcd_cls_h_fsm(component, &wcd938x->clsh_info,
WCD_CLSH_EVENT_POST_PA,
WCD_CLSH_STATE_EAR,
@@ -1878,7 +1882,7 @@
wcd938x->micb_ref[micb_index]++;
if (wcd938x->micb_ref[micb_index] == 1) {
snd_soc_component_update_bits(component,
- WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0xE0, 0xE0);
+ WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0xF0, 0xF0);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10);
snd_soc_component_update_bits(component,
diff --git a/asoc/codecs/wsa883x/Android.mk b/asoc/codecs/wsa883x/Android.mk
index 66056e8..42ad517 100644
--- a/asoc/codecs/wsa883x/Android.mk
+++ b/asoc/codecs/wsa883x/Android.mk
@@ -9,7 +9,7 @@
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
-ifeq ($(call is-board-platform-in-list,lahaina),true)
+ifeq ($(call is-board-platform-in-list,lahaina lito),true)
LOCAL_PATH := $(call my-dir)
diff --git a/asoc/codecs/wsa883x/Kbuild b/asoc/codecs/wsa883x/Kbuild
index 4eb844a..ac608b4 100644
--- a/asoc/codecs/wsa883x/Kbuild
+++ b/asoc/codecs/wsa883x/Kbuild
@@ -18,6 +18,10 @@
include $(AUDIO_ROOT)/config/lahainaauto.conf
INCS += -include $(AUDIO_ROOT)/config/lahainaautoconf.h
endif
+ ifeq ($(CONFIG_ARCH_LITO), y)
+ include $(AUDIO_ROOT)/config/litoauto.conf
+ INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h
+ endif
endif
# As per target team, build is done as follows:
diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h
index 2384043..1863aac 100644
--- a/asoc/codecs/wsa883x/internal.h
+++ b/asoc/codecs/wsa883x/internal.h
@@ -1,11 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#ifndef WSA883X_INTERNAL_H
#define WSA883X_INTERNAL_H
+#include <asoc/wcd-irq.h>
#include "wsa883x.h"
#include "wsa883x-registers.h"
@@ -25,7 +26,11 @@
#define WSA883X_DRV_NAME "wsa883x-codec"
#define WSA883X_NUM_RETRY 5
-#define WSA883X_VERSION_ENTRY_SIZE 27
+#define WSA883X_VERSION_ENTRY_SIZE 32
+#define WSA883X_VARIANT_ENTRY_SIZE 32
+
+#define WSA883X_VERSION_1_0 0
+#define WSA883X_VERSION_1_1 1
enum {
G_18DB = 0,
@@ -60,12 +65,13 @@
BOLERO_WSA_EVT_PA_OFF_PRE_SSR,
BOLERO_WSA_EVT_SSR_DOWN,
BOLERO_WSA_EVT_SSR_UP,
+ BOLERO_WSA_EVT_PA_ON_POST_FSCLK,
};
struct wsa_ctrl_platform_data {
- void *handle,
+ void *handle;
int (*update_wsa_event)(void *handle, u16 event, u32 data);
- int (*register_notifier)(void *handle, struct notifer_block *nblock,
+ int (*register_notifier)(void *handle, struct notifier_block *nblock,
bool enable);
};
@@ -97,10 +103,13 @@
struct mutex res_lock;
struct snd_info_entry *entry;
struct snd_info_entry *version_entry;
+ struct snd_info_entry *variant_entry;
struct device_node *wsa_rst_np;
int pa_mute;
int curr_temp;
int variant;
+ int version;
+ u8 pa_gain;
struct irq_domain *virq;
struct wcd_irq_info irq_info;
#ifdef CONFIG_DEBUG_FS
@@ -116,8 +125,11 @@
void *handle;
int (*register_notifier)(void *handle,
struct notifier_block *nblock, bool enable);
+ struct delayed_work vbat_work;
+ struct cdc_regulator *regulator;
+ int num_supplies;
+ struct regulator_bulk_data *supplies;
+ unsigned long status_mask;
};
-static int32_t wsa883x_resource_acquire(struct snd_soc_component *component,
- bool enable);
#endif /* WSA883X_INTERNAL_H */
diff --git a/asoc/codecs/wsa883x/wsa883x-registers.h b/asoc/codecs/wsa883x/wsa883x-registers.h
index 7e518d2..6450a45 100644
--- a/asoc/codecs/wsa883x/wsa883x-registers.h
+++ b/asoc/codecs/wsa883x/wsa883x-registers.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2019-2020, The Linux Foundation. All rights reserved.
*/
#ifndef WSA883X_REGISTERS_H
@@ -15,7 +15,7 @@
RD_WR_REG,
};
-#define WSA883X_ANA_BG_TSADC_BASE (WSA883X_BASE+0x00000000)
+#define WSA883X_ANA_BG_TSADC_BASE (WSA883X_BASE+0x00000001)
#define WSA883X_REF_CTRL (WSA883X_ANA_BG_TSADC_BASE+0x0000)
#define WSA883X_TEST_CTL_0 (WSA883X_ANA_BG_TSADC_BASE+0x0001)
#define WSA883X_BIAS_0 (WSA883X_ANA_BG_TSADC_BASE+0x0002)
@@ -69,8 +69,8 @@
#define WSA883X_SPKR_DRV_LF_MASK_DCC_CTL (WSA883X_ANA_SPK_TOP_BASE+0x000F)
#define WSA883X_SPKR_DRV_LF_MISC_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0010)
#define WSA883X_SPKR_DRV_LF_REG_GAIN (WSA883X_ANA_SPK_TOP_BASE+0x0011)
-#define WSA883X_SPKR_DRV_LF_OS_CAL_CTL1 (WSA883X_ANA_SPK_TOP_BASE+0x0012)
-#define WSA883X_SPKR_DRV_LF_OS_CAL_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0013)
+#define WSA883X_SPKR_DRV_OS_CAL_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0012)
+#define WSA883X_SPKR_DRV_OS_CAL_CTL1 (WSA883X_ANA_SPK_TOP_BASE+0x0013)
#define WSA883X_SPKR_PWM_CLK_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0014)
#define WSA883X_SPKR_PDRV_HS_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0015)
#define WSA883X_SPKR_PDRV_LS_CTL (WSA883X_ANA_SPK_TOP_BASE+0x0016)
@@ -81,7 +81,7 @@
#define WSA883X_PA_STATUS1 (WSA883X_ANA_SPK_TOP_BASE+0x001B)
#define WSA883X_PA_STATUS2 (WSA883X_ANA_SPK_TOP_BASE+0x001C)
-#define WSA883X_ANA_BOOST_BASE (WSA883X_BASE+0x00000045)
+#define WSA883X_ANA_BOOST_BASE (WSA883X_BASE+0x00000043)
#define WSA883X_EN_CTRL (WSA883X_ANA_BOOST_BASE+0x0000)
#define WSA883X_CURRENT_LIMIT (WSA883X_ANA_BOOST_BASE+0x0001)
#define WSA883X_IBIAS1 (WSA883X_ANA_BOOST_BASE+0x0002)
@@ -92,34 +92,35 @@
#define WSA883X_STABILITY_CTRL2 (WSA883X_ANA_BOOST_BASE+0x0007)
#define WSA883X_PWRSTAGE_CTRL1 (WSA883X_ANA_BOOST_BASE+0x0008)
#define WSA883X_PWRSTAGE_CTRL2 (WSA883X_ANA_BOOST_BASE+0x0009)
-#define WSA883X_UVLO (WSA883X_ANA_BOOST_BASE+0x000A)
-#define WSA883X_SEQUENCE_CTRL (WSA883X_ANA_BOOST_BASE+0x000B)
+#define WSA883X_BYPASS_1 (WSA883X_ANA_BOOST_BASE+0x000A)
+#define WSA883X_BYPASS_2 (WSA883X_ANA_BOOST_BASE+0x000B)
#define WSA883X_ZX_CTRL_1 (WSA883X_ANA_BOOST_BASE+0x000C)
#define WSA883X_ZX_CTRL_2 (WSA883X_ANA_BOOST_BASE+0x000D)
#define WSA883X_MISC1 (WSA883X_ANA_BOOST_BASE+0x000E)
#define WSA883X_MISC2 (WSA883X_ANA_BOOST_BASE+0x000F)
#define WSA883X_GMAMP_SUP1 (WSA883X_ANA_BOOST_BASE+0x0010)
#define WSA883X_PWRSTAGE_CTRL3 (WSA883X_ANA_BOOST_BASE+0x0011)
-#define WSA883X_PRSTAGE_CTRL4 (WSA883X_ANA_BOOST_BASE+0x0012)
-#define WSA883X_SPARE1 (WSA883X_ANA_BOOST_BASE+0x0013)
+#define WSA883X_PWRSTAGE_CTRL4 (WSA883X_ANA_BOOST_BASE+0x0012)
+#define WSA883X_TEST1 (WSA883X_ANA_BOOST_BASE+0x0013)
+#define WSA883X_SPARE1 (WSA883X_ANA_BOOST_BASE+0x0014)
+#define WSA883X_SPARE2 (WSA883X_ANA_BOOST_BASE+0x0015)
#define WSA883X_ANA_PON_LDOL_BASE (WSA883X_BASE+0x00000059)
#define WSA883X_PON_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0000)
#define WSA883X_PON_CLT_1 (WSA883X_ANA_PON_LDOL_BASE+0x0001)
#define WSA883X_PON_CTL_2 (WSA883X_ANA_PON_LDOL_BASE+0x0002)
#define WSA883X_PON_CTL_3 (WSA883X_ANA_PON_LDOL_BASE+0x0003)
-#define WSA883X_PON_CTL_4 (WSA883X_ANA_PON_LDOL_BASE+0x0004)
-#define WSA883X_CKWD_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0005)
-#define WSA883X_CKWD_CTL_1 (WSA883X_ANA_PON_LDOL_BASE+0x0006)
-#define WSA883X_CKWD_CTL_2 (WSA883X_ANA_PON_LDOL_BASE+0x0007)
-#define WSA883X_CKSK_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0008)
+#define WSA883X_CKWD_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0004)
+#define WSA883X_CKWD_CTL_1 (WSA883X_ANA_PON_LDOL_BASE+0x0005)
+#define WSA883X_CKWD_CTL_2 (WSA883X_ANA_PON_LDOL_BASE+0x0006)
+#define WSA883X_CKSK_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0007)
+#define WSA883X_PADSW_CTL_0 (WSA883X_ANA_PON_LDOL_BASE+0x0008)
#define WSA883X_TEST_0 (WSA883X_ANA_PON_LDOL_BASE+0x0009)
#define WSA883X_TEST_1 (WSA883X_ANA_PON_LDOL_BASE+0x000A)
#define WSA883X_STATUS_0 (WSA883X_ANA_PON_LDOL_BASE+0x000B)
#define WSA883X_STATUS_1 (WSA883X_ANA_PON_LDOL_BASE+0x000C)
#define WSA883X_DIG_CTRL_BASE (WSA883X_BASE+0x00000400)
-#define WSA883X_PAGE_REGISTER (WSA883X_DIG_CTRL_BASE+0x0000)
#define WSA883X_CHIP_ID0 (WSA883X_DIG_CTRL_BASE+0x0001)
#define WSA883X_CHIP_ID1 (WSA883X_DIG_CTRL_BASE+0x0002)
#define WSA883X_CHIP_ID2 (WSA883X_DIG_CTRL_BASE+0x0003)
@@ -130,6 +131,7 @@
#define WSA883X_CDC_PATH_MODE (WSA883X_DIG_CTRL_BASE+0x0008)
#define WSA883X_CDC_CLK_CTL (WSA883X_DIG_CTRL_BASE+0x0009)
#define WSA883X_SWR_RESET_EN (WSA883X_DIG_CTRL_BASE+0x000A)
+#define WSA883X_RESET_CTL (WSA883X_DIG_CTRL_BASE+0x000B)
#define WSA883X_PA_FSM_CTL (WSA883X_DIG_CTRL_BASE+0x0010)
#define WSA883X_PA_FSM_TIMER0 (WSA883X_DIG_CTRL_BASE+0x0011)
#define WSA883X_PA_FSM_TIMER1 (WSA883X_DIG_CTRL_BASE+0x0012)
@@ -137,6 +139,7 @@
#define WSA883X_PA_FSM_ERR_COND (WSA883X_DIG_CTRL_BASE+0x0014)
#define WSA883X_PA_FSM_MSK (WSA883X_DIG_CTRL_BASE+0x0015)
#define WSA883X_PA_FSM_BYP (WSA883X_DIG_CTRL_BASE+0x0016)
+#define WSA883X_PA_FSM_DBG (WSA883X_DIG_CTRL_BASE+0x0017)
#define WSA883X_TADC_VALUE_CTL (WSA883X_DIG_CTRL_BASE+0x0020)
#define WSA883X_TEMP_DETECT_CTL (WSA883X_DIG_CTRL_BASE+0x0021)
#define WSA883X_TEMP_MSB (WSA883X_DIG_CTRL_BASE+0x0022)
@@ -208,8 +211,10 @@
#define WSA883X_WAVG_PER_2_3 (WSA883X_DIG_CTRL_BASE+0x0068)
#define WSA883X_WAVG_PER_4_5 (WSA883X_DIG_CTRL_BASE+0x0069)
#define WSA883X_WAVG_PER_6_7 (WSA883X_DIG_CTRL_BASE+0x006A)
+#define WSA883X_WAVG_STA (WSA883X_DIG_CTRL_BASE+0x006B)
#define WSA883X_DRE_CTL_0 (WSA883X_DIG_CTRL_BASE+0x006C)
#define WSA883X_DRE_CTL_1 (WSA883X_DIG_CTRL_BASE+0x006D)
+#define WSA883X_DRE_IDLE_DET_CTL (WSA883X_DIG_CTRL_BASE+0x006E)
#define WSA883X_CLSH_CTL_0 (WSA883X_DIG_CTRL_BASE+0x0070)
#define WSA883X_CLSH_CTL_1 (WSA883X_DIG_CTRL_BASE+0x0071)
#define WSA883X_CLSH_V_HD_PA (WSA883X_DIG_CTRL_BASE+0x0072)
@@ -249,26 +254,28 @@
#define WSA883X_I2C_SLAVE_CTL (WSA883X_DIG_CTRL_BASE+0x0097)
#define WSA883X_PDM_TEST_MODE (WSA883X_DIG_CTRL_BASE+0x00A0)
#define WSA883X_ATE_TEST_MODE (WSA883X_DIG_CTRL_BASE+0x00A1)
-#define WSA883X_DRE_TEST (WSA883X_DIG_CTRL_BASE+0x00A2)
#define WSA883X_DIG_DEBUG_MODE (WSA883X_DIG_CTRL_BASE+0x00A3)
#define WSA883X_DIG_DEBUG_SEL (WSA883X_DIG_CTRL_BASE+0x00A4)
#define WSA883X_DIG_DEBUG_EN (WSA883X_DIG_CTRL_BASE+0x00A5)
#define WSA883X_SWR_HM_TEST0 (WSA883X_DIG_CTRL_BASE+0x00A6)
#define WSA883X_SWR_HM_TEST1 (WSA883X_DIG_CTRL_BASE+0x00A7)
#define WSA883X_SWR_PAD_CTL (WSA883X_DIG_CTRL_BASE+0x00A8)
-#define WSA883X_TEMP_DETECT_DBG_CTL (WSA883X_DIG_CTRL_BASE+0x00A9)
-#define WSA883X_TEMP_DEBUG_MSB (WSA883X_DIG_CTRL_BASE+0x00AA)
-#define WSA883X_TEMP_DEBUG_LSB (WSA883X_DIG_CTRL_BASE+0x00AB)
+#define WSA883X_TADC_DETECT_DBG_CTL (WSA883X_DIG_CTRL_BASE+0x00A9)
+#define WSA883X_TADC_DEBUG_MSB (WSA883X_DIG_CTRL_BASE+0x00AA)
+#define WSA883X_TADC_DEBUG_LSB (WSA883X_DIG_CTRL_BASE+0x00AB)
#define WSA883X_SAMPLE_EDGE_SEL (WSA883X_DIG_CTRL_BASE+0x00AC)
-#define WSA883X_TEST_MODE_CTL (WSA883X_DIG_CTRL_BASE+0x00AD)
-#define WSA883X_IOPAD_CTL (WSA883X_DIG_CTRL_BASE+0x00AE)
-#define WSA883X_SPARE_0 (WSA883X_DIG_CTRL_BASE+0x00B0)
-#define WSA883X_SPARE_1 (WSA883X_DIG_CTRL_BASE+0x00B1)
-#define WSA883X_SPARE_2 (WSA883X_DIG_CTRL_BASE+0x00B2)
+#define WSA883X_SWR_EDGE_SEL (WSA883X_DIG_CTRL_BASE+0x00AD)
+#define WSA883X_TEST_MODE_CTL (WSA883X_DIG_CTRL_BASE+0x00AE)
+#define WSA883X_IOPAD_CTL (WSA883X_DIG_CTRL_BASE+0x00AF)
+#define WSA883X_ANA_CSR_DBG_ADD (WSA883X_DIG_CTRL_BASE+0x00B0)
+#define WSA883X_ANA_CSR_DBG_CTL (WSA883X_DIG_CTRL_BASE+0x00B1)
+#define WSA883X_SPARE_R (WSA883X_DIG_CTRL_BASE+0x00BC)
+#define WSA883X_SPARE_0 (WSA883X_DIG_CTRL_BASE+0x00BD)
+#define WSA883X_SPARE_1 (WSA883X_DIG_CTRL_BASE+0x00BE)
+#define WSA883X_SPARE_2 (WSA883X_DIG_CTRL_BASE+0x00BF)
#define WSA883X_SCODE (WSA883X_DIG_CTRL_BASE+0x00C0)
#define WSA883X_DIG_TRIM_BASE (WSA883X_BASE+0x00000500)
-#define WSA883X_PAGE_REGISTER (WSA883X_DIG_TRIM_BASE+0x0000)
#define WSA883X_OTP_REG_0 (WSA883X_DIG_TRIM_BASE+0x0080)
#define WSA883X_OTP_REG_1 (WSA883X_DIG_TRIM_BASE+0x0081)
#define WSA883X_OTP_REG_2 (WSA883X_DIG_TRIM_BASE+0x0082)
@@ -301,7 +308,10 @@
#define WSA883X_OTP_REG_29 (WSA883X_DIG_TRIM_BASE+0x009D)
#define WSA883X_OTP_REG_30 (WSA883X_DIG_TRIM_BASE+0x009E)
#define WSA883X_OTP_REG_31 (WSA883X_DIG_TRIM_BASE+0x009F)
-#define WSA883X_OTP_REG_SCODE (WSA883X_DIG_TRIM_BASE+0x00A0)
+#define WSA883X_OTP_REG_32 (WSA883X_DIG_TRIM_BASE+0x00A0)
+#define WSA883X_OTP_REG_33 (WSA883X_DIG_TRIM_BASE+0x00A1)
+#define WSA883X_OTP_REG_34 (WSA883X_DIG_TRIM_BASE+0x00A2)
+#define WSA883X_OTP_REG_35 (WSA883X_DIG_TRIM_BASE+0x00A3)
#define WSA883X_OTP_REG_63 (WSA883X_DIG_TRIM_BASE+0x00BF)
#define WSA883X_DIG_EMEM_BASE (WSA883X_BASE+0x000005C0)
diff --git a/asoc/codecs/wsa883x/wsa883x-regmap.c b/asoc/codecs/wsa883x/wsa883x-regmap.c
index 8394e9c..b55fbad 100644
--- a/asoc/codecs/wsa883x/wsa883x-regmap.c
+++ b/asoc/codecs/wsa883x/wsa883x-regmap.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2015-2016, 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016, 2019-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/regmap.h>
@@ -11,100 +11,101 @@
extern const u8 wsa883x_reg_access[WSA883X_NUM_REGISTERS];
static struct reg_default wsa883x_defaults[] = {
- {WSA883X_REF_CTRL, 0x6C},
+ {WSA883X_REF_CTRL, 0xD5},
{WSA883X_TEST_CTL_0, 0x06},
{WSA883X_BIAS_0, 0xD2},
{WSA883X_OP_CTL, 0xE0},
- {WSA883X_IREF_CTL, 0x58},
+ {WSA883X_IREF_CTL, 0x57},
{WSA883X_ISENS_CTL, 0x47},
{WSA883X_CLK_CTL, 0x87},
{WSA883X_TEST_CTL_1, 0x00},
{WSA883X_BIAS_1, 0x51},
- {WSA883X_ADC_CTL, 0x03},
+ {WSA883X_ADC_CTL, 0x01},
{WSA883X_DOUT_MSB, 0x00},
{WSA883X_DOUT_LSB, 0x00},
- {WSA883X_VBAT_SNS, 0x00},
- {WSA883X_ITRIM_CODE, 0x1F},
- {WSA883X_EN, 0x00},
+ {WSA883X_VBAT_SNS, 0x40},
+ {WSA883X_ITRIM_CODE, 0x9F},
+ {WSA883X_EN, 0x20},
{WSA883X_OVERRIDE1, 0x00},
{WSA883X_OVERRIDE2, 0x08},
{WSA883X_VSENSE1, 0xD3},
{WSA883X_ISENSE1, 0xD4},
{WSA883X_ISENSE2, 0x20},
{WSA883X_ISENSE_CAL, 0x00},
- {WSA883X_MISC, 0x00},
+ {WSA883X_MISC, 0x08},
{WSA883X_ADC_0, 0x00},
{WSA883X_ADC_1, 0x00},
- {WSA883X_ADC_2, 0x00},
- {WSA883X_ADC_3, 0x00},
- {WSA883X_ADC_4, 0x45},
- {WSA883X_ADC_5, 0x20},
- {WSA883X_ADC_6, 0x10},
- {WSA883X_ADC_7, 0x00},
+ {WSA883X_ADC_2, 0x40},
+ {WSA883X_ADC_3, 0x80},
+ {WSA883X_ADC_4, 0x25},
+ {WSA883X_ADC_5, 0x25},
+ {WSA883X_ADC_6, 0x08},
+ {WSA883X_ADC_7, 0x81},
{WSA883X_STATUS, 0x00},
- {WSA883X_DAC_CTRL_REG, 0x41},
+ {WSA883X_DAC_CTRL_REG, 0x53},
{WSA883X_DAC_EN_DEBUG_REG, 0x00},
{WSA883X_DAC_OPAMP_BIAS1_REG, 0x48},
{WSA883X_DAC_OPAMP_BIAS2_REG, 0x48},
- {WSA883X_DAC_VCM_CTRL_REG, 0x0B},
- {WSA883X_DAC_VOLTAGE_CTRL_REG, 0x05},
+ {WSA883X_DAC_VCM_CTRL_REG, 0x88},
+ {WSA883X_DAC_VOLTAGE_CTRL_REG, 0xA5},
{WSA883X_ATEST1_REG, 0x00},
{WSA883X_ATEST2_REG, 0x00},
- {WSA883X_SPKR_TOP_BIAS_REG1, 0x4A},
+ {WSA883X_SPKR_TOP_BIAS_REG1, 0x6A},
{WSA883X_SPKR_TOP_BIAS_REG2, 0x65},
{WSA883X_SPKR_TOP_BIAS_REG3, 0x55},
{WSA883X_SPKR_TOP_BIAS_REG4, 0xA9},
- {WSA883X_SPKR_CLIP_DET_REG, 0x00},
+ {WSA883X_SPKR_CLIP_DET_REG, 0x9C},
{WSA883X_SPKR_DRV_LF_BLK_EN, 0x0F},
{WSA883X_SPKR_DRV_LF_EN, 0x0A},
{WSA883X_SPKR_DRV_LF_MASK_DCC_CTL, 0x00},
- {WSA883X_SPKR_DRV_LF_MISC_CTL, 0x32},
+ {WSA883X_SPKR_DRV_LF_MISC_CTL, 0x3A},
{WSA883X_SPKR_DRV_LF_REG_GAIN, 0x00},
- {WSA883X_SPKR_DRV_LF_OS_CAL_CTL1, 0x90},
- {WSA883X_SPKR_DRV_LF_OS_CAL_CTL, 0x00},
+ {WSA883X_SPKR_DRV_OS_CAL_CTL, 0x00},
+ {WSA883X_SPKR_DRV_OS_CAL_CTL1, 0x90},
{WSA883X_SPKR_PWM_CLK_CTL, 0x00},
- {WSA883X_SPKR_PDRV_HS_CTL, 0x50},
+ {WSA883X_SPKR_PDRV_HS_CTL, 0x52},
{WSA883X_SPKR_PDRV_LS_CTL, 0x48},
- {WSA883X_SPKR_PWRSTG_DBG, 0x00},
- {WSA883X_SPKR_OCP_CTL, 0x00},
- {WSA883X_SPKR_BBM_CTL, 0x90},
+ {WSA883X_SPKR_PWRSTG_DBG, 0x08},
+ {WSA883X_SPKR_OCP_CTL, 0xE2},
+ {WSA883X_SPKR_BBM_CTL, 0x92},
{WSA883X_PA_STATUS0, 0x00},
{WSA883X_PA_STATUS1, 0x00},
- {WSA883X_PA_STATUS2, 0x00},
- {WSA883X_EN_CTRL, 0x54},
- {WSA883X_CURRENT_LIMIT, 0x90},
+ {WSA883X_PA_STATUS2, 0x80},
+ {WSA883X_EN_CTRL, 0x44},
+ {WSA883X_CURRENT_LIMIT, 0xCC},
{WSA883X_IBIAS1, 0x00},
{WSA883X_IBIAS2, 0x00},
{WSA883X_IBIAS3, 0x00},
- {WSA883X_LDO_PROG, 0x2A},
+ {WSA883X_LDO_PROG, 0x02},
{WSA883X_STABILITY_CTRL1, 0x8E},
- {WSA883X_STABILITY_CTRL2, 0x00},
- {WSA883X_PWRSTAGE_CTRL1, 0x00},
- {WSA883X_PWRSTAGE_CTRL2, 0x40},
- {WSA883X_UVLO, 0xE9},
- {WSA883X_SEQUENCE_CTRL, 0x11},
+ {WSA883X_STABILITY_CTRL2, 0x10},
+ {WSA883X_PWRSTAGE_CTRL1, 0x06},
+ {WSA883X_PWRSTAGE_CTRL2, 0x00},
+ {WSA883X_BYPASS_1, 0x19},
+ {WSA883X_BYPASS_2, 0x13},
{WSA883X_ZX_CTRL_1, 0xF0},
- {WSA883X_ZX_CTRL_2, 0x06},
- {WSA883X_MISC1, 0x02},
- {WSA883X_MISC2, 0x81},
- {WSA883X_GMAMP_SUP1, 0x84},
- {WSA883X_PWRSTAGE_CTRL3, 0x14},
- {WSA883X_PRSTAGE_CTRL4, 0x5F},
+ {WSA883X_ZX_CTRL_2, 0x04},
+ {WSA883X_MISC1, 0x06},
+ {WSA883X_MISC2, 0xA0},
+ {WSA883X_GMAMP_SUP1, 0x82},
+ {WSA883X_PWRSTAGE_CTRL3, 0x39},
+ {WSA883X_PWRSTAGE_CTRL4, 0x5F},
+ {WSA883X_TEST1, 0x00},
{WSA883X_SPARE1, 0x00},
- {WSA883X_PON_CTL_0, 0xE3},
- {WSA883X_PON_CLT_1, 0x70},
- {WSA883X_PON_CTL_2, 0x00},
- {WSA883X_PON_CTL_3, 0x00},
- {WSA883X_PON_CTL_4, 0x00},
+ {WSA883X_SPARE2, 0x00},
+ {WSA883X_PON_CTL_0, 0x10},
+ {WSA883X_PON_CLT_1, 0xE0},
+ {WSA883X_PON_CTL_2, 0x90},
+ {WSA883X_PON_CTL_3, 0x70},
{WSA883X_CKWD_CTL_0, 0x34},
- {WSA883X_CKWD_CTL_1, 0x80},
+ {WSA883X_CKWD_CTL_1, 0x0F},
{WSA883X_CKWD_CTL_2, 0x00},
- {WSA883X_CKSK_CTL_0, 0x0A},
+ {WSA883X_CKSK_CTL_0, 0x00},
+ {WSA883X_PADSW_CTL_0, 0x00},
{WSA883X_TEST_0, 0x00},
{WSA883X_TEST_1, 0x00},
{WSA883X_STATUS_0, 0x00},
{WSA883X_STATUS_1, 0x00},
- {WSA883X_PAGE_REGISTER, 0x00},
{WSA883X_CHIP_ID0, 0x00},
{WSA883X_CHIP_ID1, 0x00},
{WSA883X_CHIP_ID2, 0x02},
@@ -115,13 +116,15 @@
{WSA883X_CDC_PATH_MODE, 0x00},
{WSA883X_CDC_CLK_CTL, 0xFF},
{WSA883X_SWR_RESET_EN, 0x00},
+ {WSA883X_RESET_CTL, 0x00},
{WSA883X_PA_FSM_CTL, 0x00},
{WSA883X_PA_FSM_TIMER0, 0x80},
{WSA883X_PA_FSM_TIMER1, 0x80},
{WSA883X_PA_FSM_STA, 0x00},
{WSA883X_PA_FSM_ERR_COND, 0x00},
{WSA883X_PA_FSM_MSK, 0x00},
- {WSA883X_PA_FSM_BYP, 0x00},
+ {WSA883X_PA_FSM_BYP, 0x01},
+ {WSA883X_PA_FSM_DBG, 0x00},
{WSA883X_TADC_VALUE_CTL, 0x03},
{WSA883X_TEMP_DETECT_CTL, 0x01},
{WSA883X_TEMP_MSB, 0x00},
@@ -193,15 +196,17 @@
{WSA883X_WAVG_PER_2_3, 0x88},
{WSA883X_WAVG_PER_4_5, 0x88},
{WSA883X_WAVG_PER_6_7, 0x88},
- {WSA883X_DRE_CTL_0, 0x30},
- {WSA883X_DRE_CTL_1, 0x20},
+ {WSA883X_WAVG_STA, 0x00},
+ {WSA883X_DRE_CTL_0, 0x70},
+ {WSA883X_DRE_CTL_1, 0x08},
+ {WSA883X_DRE_IDLE_DET_CTL, 0x1F},
{WSA883X_CLSH_CTL_0, 0x37},
{WSA883X_CLSH_CTL_1, 0x81},
{WSA883X_CLSH_V_HD_PA, 0x0F},
{WSA883X_CLSH_V_PA_MIN, 0x00},
{WSA883X_CLSH_OVRD_VAL, 0x00},
{WSA883X_CLSH_HARD_MAX, 0xFF},
- {WSA883X_CLSH_SOFT_MAX, 0xFF},
+ {WSA883X_CLSH_SOFT_MAX, 0xF5},
{WSA883X_CLSH_SIG_DP, 0x00},
{WSA883X_TAGC_CTL, 0x10},
{WSA883X_TAGC_TIME, 0x20},
@@ -212,18 +217,18 @@
{WSA883X_VAGC_ATTN_LVL_1_2, 0x21},
{WSA883X_VAGC_ATTN_LVL_3, 0x03},
{WSA883X_INTR_MODE, 0x00},
- {WSA883X_INTR_MASK0, 0x1B},
- {WSA883X_INTR_MASK1, 0x03},
+ {WSA883X_INTR_MASK0, 0x90},
+ {WSA883X_INTR_MASK1, 0x00},
{WSA883X_INTR_STATUS0, 0x00},
{WSA883X_INTR_STATUS1, 0x00},
{WSA883X_INTR_CLEAR0, 0x00},
- {WSA883X_INTR_CLEAR1, 0x03},
+ {WSA883X_INTR_CLEAR1, 0x00},
{WSA883X_INTR_LEVEL0, 0x00},
- {WSA883X_INTR_LEVEL1, 0x03},
+ {WSA883X_INTR_LEVEL1, 0x00},
{WSA883X_INTR_SET0, 0x00},
- {WSA883X_INTR_SET1, 0x03},
+ {WSA883X_INTR_SET1, 0x00},
{WSA883X_INTR_TEST0, 0x00},
- {WSA883X_INTR_TEST1, 0x03},
+ {WSA883X_INTR_TEST1, 0x00},
{WSA883X_OTP_CTRL0, 0x00},
{WSA883X_OTP_CTRL1, 0x00},
{WSA883X_HDRIVE_CTL_GROUP1, 0x00},
@@ -234,25 +239,27 @@
{WSA883X_I2C_SLAVE_CTL, 0x00},
{WSA883X_PDM_TEST_MODE, 0x00},
{WSA883X_ATE_TEST_MODE, 0x00},
- {WSA883X_DRE_TEST, 0x00},
{WSA883X_DIG_DEBUG_MODE, 0x00},
{WSA883X_DIG_DEBUG_SEL, 0x00},
{WSA883X_DIG_DEBUG_EN, 0x00},
{WSA883X_SWR_HM_TEST0, 0x08},
{WSA883X_SWR_HM_TEST1, 0x00},
- {WSA883X_SWR_PAD_CTL, 0x45},
- {WSA883X_TEMP_DETECT_DBG_CTL, 0x00},
- {WSA883X_TEMP_DEBUG_MSB, 0x00},
- {WSA883X_TEMP_DEBUG_LSB, 0x00},
+ {WSA883X_SWR_PAD_CTL, 0x37},
+ {WSA883X_TADC_DETECT_DBG_CTL, 0x00},
+ {WSA883X_TADC_DEBUG_MSB, 0x00},
+ {WSA883X_TADC_DEBUG_LSB, 0x00},
{WSA883X_SAMPLE_EDGE_SEL, 0x7F},
- {WSA883X_TEST_MODE_CTL, 0x00},
+ {WSA883X_SWR_EDGE_SEL, 0x00},
+ {WSA883X_TEST_MODE_CTL, 0x04},
{WSA883X_IOPAD_CTL, 0x00},
+ {WSA883X_ANA_CSR_DBG_ADD, 0x00},
+ {WSA883X_ANA_CSR_DBG_CTL, 0x12},
+ {WSA883X_SPARE_R, 0x00},
{WSA883X_SPARE_0, 0x00},
{WSA883X_SPARE_1, 0x00},
{WSA883X_SPARE_2, 0x00},
{WSA883X_SCODE, 0x00},
- {WSA883X_PAGE_REGISTER, 0x00},
- {WSA883X_OTP_REG_0, 0x01},
+ {WSA883X_OTP_REG_0, 0x05},
{WSA883X_OTP_REG_1, 0xFF},
{WSA883X_OTP_REG_2, 0xC0},
{WSA883X_OTP_REG_3, 0xFF},
@@ -276,15 +283,18 @@
{WSA883X_OTP_REG_21, 0xFF},
{WSA883X_OTP_REG_22, 0xFF},
{WSA883X_OTP_REG_23, 0xFF},
- {WSA883X_OTP_REG_24, 0x03},
- {WSA883X_OTP_REG_25, 0x01},
+ {WSA883X_OTP_REG_24, 0x37},
+ {WSA883X_OTP_REG_25, 0x3F},
{WSA883X_OTP_REG_26, 0x03},
- {WSA883X_OTP_REG_27, 0x11},
- {WSA883X_OTP_REG_28, 0x3F},
- {WSA883X_OTP_REG_29, 0x3F},
- {WSA883X_OTP_REG_30, 0x01},
- {WSA883X_OTP_REG_31, 0x01},
- {WSA883X_OTP_REG_SCODE, 0x00},
+ {WSA883X_OTP_REG_27, 0x00},
+ {WSA883X_OTP_REG_28, 0x00},
+ {WSA883X_OTP_REG_29, 0x00},
+ {WSA883X_OTP_REG_30, 0x00},
+ {WSA883X_OTP_REG_31, 0x03},
+ {WSA883X_OTP_REG_32, 0x00},
+ {WSA883X_OTP_REG_33, 0xFF},
+ {WSA883X_OTP_REG_34, 0x00},
+ {WSA883X_OTP_REG_35, 0x00},
{WSA883X_OTP_REG_63, 0x40},
{WSA883X_EMEM_0, 0x00},
{WSA883X_EMEM_1, 0x00},
@@ -377,7 +387,7 @@
!(wsa883x_reg_access[WSA883X_REG(reg)] & WR_REG));
}
-struct regmap_config wsa881x_regmap_config = {
+struct regmap_config wsa883x_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
diff --git a/asoc/codecs/wsa883x/wsa883x-tables.c b/asoc/codecs/wsa883x/wsa883x-tables.c
index 16b0a88..c693097 100644
--- a/asoc/codecs/wsa883x/wsa883x-tables.c
+++ b/asoc/codecs/wsa883x/wsa883x-tables.c
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2020 The Linux Foundation. All rights reserved.
*/
#include <linux/regmap.h>
#include <linux/device.h>
#include "wsa883x-registers.h"
-const u8 wsa883x_reg_readable[WSA883X_NUM_REGISTERS] = {
+const u8 wsa883x_reg_access[WSA883X_NUM_REGISTERS] = {
[WSA883X_REG(WSA883X_REF_CTRL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_TEST_CTL_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_BIAS_0)] = RD_WR_REG,
@@ -57,14 +57,14 @@
[WSA883X_REG(WSA883X_SPKR_DRV_LF_MASK_DCC_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPKR_DRV_LF_MISC_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPKR_DRV_LF_REG_GAIN)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_SPKR_DRV_LF_OS_CAL_CTL1)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_SPKR_DRV_LF_OS_CAL_CTL)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_SPKR_DRV_OS_CAL_CTL)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_SPKR_DRV_OS_CAL_CTL1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPKR_PWM_CLK_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPKR_PDRV_HS_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPKR_PDRV_LS_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPKR_PWRSTG_DBG)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPKR_OCP_CTL)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_SPKR_BBM_CTL)] = RD_REG,
+ [WSA883X_REG(WSA883X_SPKR_BBM_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PA_STATUS0)] = RD_REG,
[WSA883X_REG(WSA883X_PA_STATUS1)] = RD_REG,
[WSA883X_REG(WSA883X_PA_STATUS2)] = RD_REG,
@@ -78,30 +78,31 @@
[WSA883X_REG(WSA883X_STABILITY_CTRL2)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PWRSTAGE_CTRL1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PWRSTAGE_CTRL2)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_UVLO)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_SEQUENCE_CTRL)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_BYPASS_1)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_BYPASS_2)] = RD_WR_REG,
[WSA883X_REG(WSA883X_ZX_CTRL_1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_ZX_CTRL_2)] = RD_WR_REG,
[WSA883X_REG(WSA883X_MISC1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_MISC2)] = RD_WR_REG,
[WSA883X_REG(WSA883X_GMAMP_SUP1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PWRSTAGE_CTRL3)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_PRSTAGE_CTRL4)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_PWRSTAGE_CTRL4)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_TEST1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPARE1)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_SPARE2)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PON_CTL_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PON_CLT_1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PON_CTL_2)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PON_CTL_3)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_PON_CTL_4)] = RD_WR_REG,
[WSA883X_REG(WSA883X_CKWD_CTL_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_CKWD_CTL_1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_CKWD_CTL_2)] = RD_WR_REG,
[WSA883X_REG(WSA883X_CKSK_CTL_0)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_PADSW_CTL_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_TEST_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_TEST_1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_STATUS_0)] = RD_REG,
[WSA883X_REG(WSA883X_STATUS_1)] = RD_REG,
- [WSA883X_REG(WSA883X_PAGE_REGISTER)] = RD_WR_REG,
[WSA883X_REG(WSA883X_CHIP_ID0)] = RD_REG,
[WSA883X_REG(WSA883X_CHIP_ID1)] = RD_REG,
[WSA883X_REG(WSA883X_CHIP_ID2)] = RD_REG,
@@ -112,6 +113,7 @@
[WSA883X_REG(WSA883X_CDC_PATH_MODE)] = RD_WR_REG,
[WSA883X_REG(WSA883X_CDC_CLK_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SWR_RESET_EN)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_RESET_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PA_FSM_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PA_FSM_TIMER0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PA_FSM_TIMER1)] = RD_WR_REG,
@@ -119,6 +121,7 @@
[WSA883X_REG(WSA883X_PA_FSM_ERR_COND)] = RD_REG,
[WSA883X_REG(WSA883X_PA_FSM_MSK)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PA_FSM_BYP)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_PA_FSM_DBG)] = RD_WR_REG,
[WSA883X_REG(WSA883X_TADC_VALUE_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_TEMP_DETECT_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_TEMP_MSB)] = RD_REG,
@@ -190,8 +193,10 @@
[WSA883X_REG(WSA883X_WAVG_PER_2_3)] = RD_WR_REG,
[WSA883X_REG(WSA883X_WAVG_PER_4_5)] = RD_WR_REG,
[WSA883X_REG(WSA883X_WAVG_PER_6_7)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_WAVG_STA)] = RD_REG,
[WSA883X_REG(WSA883X_DRE_CTL_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_DRE_CTL_1)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_DRE_IDLE_DET_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_CLSH_CTL_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_CLSH_CTL_1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_CLSH_V_HD_PA)] = RD_WR_REG,
@@ -231,24 +236,26 @@
[WSA883X_REG(WSA883X_I2C_SLAVE_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_PDM_TEST_MODE)] = RD_WR_REG,
[WSA883X_REG(WSA883X_ATE_TEST_MODE)] = RD_REG,
- [WSA883X_REG(WSA883X_DRE_TEST)] = RD_WR_REG,
[WSA883X_REG(WSA883X_DIG_DEBUG_MODE)] = RD_WR_REG,
[WSA883X_REG(WSA883X_DIG_DEBUG_SEL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_DIG_DEBUG_EN)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SWR_HM_TEST0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SWR_HM_TEST1)] = RD_REG,
[WSA883X_REG(WSA883X_SWR_PAD_CTL)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_TEMP_DETECT_DBG_CTL)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_TEMP_DEBUG_MSB)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_TEMP_DEBUG_LSB)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_TADC_DETECT_DBG_CTL)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_TADC_DEBUG_MSB)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_TADC_DEBUG_LSB)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SAMPLE_EDGE_SEL)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_SWR_EDGE_SEL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_TEST_MODE_CTL)] = RD_WR_REG,
[WSA883X_REG(WSA883X_IOPAD_CTL)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_ANA_CSR_DBG_ADD)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_ANA_CSR_DBG_CTL)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_SPARE_R)] = RD_REG,
[WSA883X_REG(WSA883X_SPARE_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPARE_1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SPARE_2)] = RD_WR_REG,
[WSA883X_REG(WSA883X_SCODE)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_PAGE_REGISTER)] = RD_WR_REG,
[WSA883X_REG(WSA883X_OTP_REG_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_OTP_REG_1)] = RD_WR_REG,
[WSA883X_REG(WSA883X_OTP_REG_2)] = RD_WR_REG,
@@ -280,8 +287,11 @@
[WSA883X_REG(WSA883X_OTP_REG_28)] = RD_WR_REG,
[WSA883X_REG(WSA883X_OTP_REG_29)] = RD_WR_REG,
[WSA883X_REG(WSA883X_OTP_REG_30)] = RD_WR_REG,
- [WSA883X_REG(WSA883X_OTP_REG_31)] = RD_REG,
- [WSA883X_REG(WSA883X_OTP_REG_SCODE)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_OTP_REG_31)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_OTP_REG_32)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_OTP_REG_33)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_OTP_REG_34)] = RD_WR_REG,
+ [WSA883X_REG(WSA883X_OTP_REG_35)] = RD_WR_REG,
[WSA883X_REG(WSA883X_OTP_REG_63)] = RD_WR_REG,
[WSA883X_REG(WSA883X_EMEM_0)] = RD_WR_REG,
[WSA883X_REG(WSA883X_EMEM_1)] = RD_WR_REG,
diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c
index 08f6858..9e25e53 100644
--- a/asoc/codecs/wsa883x/wsa883x.c
+++ b/asoc/codecs/wsa883x/wsa883x.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/debugfs.h>
#include <soc/soundwire.h>
@@ -25,6 +26,7 @@
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <asoc/msm-cdc-pinctrl.h>
+#include <asoc/msm-cdc-supply.h>
#include "wsa883x.h"
#include "internal.h"
@@ -34,6 +36,13 @@
#define HIGH_TEMP_THRESHOLD 45
#define TEMP_INVALID 0xFFFF
#define WSA883X_TEMP_RETRY 3
+#define WSA883X_VBAT_TIMER_SEC 2
+
+static int wsa883x_vbat_timer_sec = WSA883X_VBAT_TIMER_SEC;
+module_param(wsa883x_vbat_timer_sec, int, 0664);
+MODULE_PARM_DESC(wsa883x_vbat_timer_sec, "timer for VBAT monitor polling");
+
+#define DRV_NAME "wsa-codec"
enum {
WSA_4OHMS =4,
@@ -51,6 +60,56 @@
u8 dmeas_lsb;
};
+struct wsa_reg_mask_val {
+ u16 reg;
+ u8 mask;
+ u8 val;
+};
+
+static const struct wsa_reg_mask_val reg_init[] = {
+ {WSA883X_PA_FSM_BYP, 0x01, 0x00},
+ {WSA883X_CDC_SPK_DSM_A2_0, 0xFF, 0x0A},
+ {WSA883X_CDC_SPK_DSM_A2_1, 0x0F, 0x08},
+ {WSA883X_CDC_SPK_DSM_A3_0, 0xFF, 0xF3},
+ {WSA883X_CDC_SPK_DSM_A3_1, 0x07, 0x07},
+ {WSA883X_CDC_SPK_DSM_A4_0, 0xFF, 0x79},
+ {WSA883X_CDC_SPK_DSM_A4_1, 0x03, 0x02},
+ {WSA883X_CDC_SPK_DSM_A5_0, 0xFF, 0x0B},
+ {WSA883X_CDC_SPK_DSM_A5_1, 0x03, 0x02},
+ {WSA883X_CDC_SPK_DSM_A6_0, 0xFF, 0x8A},
+ {WSA883X_CDC_SPK_DSM_A7_0, 0xFF, 0x9B},
+ {WSA883X_CDC_SPK_DSM_C_0, 0xFF, 0x68},
+ {WSA883X_CDC_SPK_DSM_C_1, 0xFF, 0x54},
+ {WSA883X_CDC_SPK_DSM_C_2, 0xFF, 0xF2},
+ {WSA883X_CDC_SPK_DSM_C_3, 0x3F, 0x20},
+ {WSA883X_CDC_SPK_DSM_R1, 0xFF, 0x83},
+ {WSA883X_CDC_SPK_DSM_R2, 0xFF, 0x7F},
+ {WSA883X_CDC_SPK_DSM_R3, 0xFF, 0x9D},
+ {WSA883X_CDC_SPK_DSM_R4, 0xFF, 0x82},
+ {WSA883X_CDC_SPK_DSM_R5, 0xFF, 0x8B},
+ {WSA883X_CDC_SPK_DSM_R6, 0xFF, 0x9B},
+ {WSA883X_CDC_SPK_DSM_R7, 0xFF, 0x3F},
+ {WSA883X_DRE_CTL_0, 0xF0, 0x90},
+ {WSA883X_DRE_IDLE_DET_CTL, 0x10, 0x00},
+ {WSA883X_PDM_WD_CTL, 0x01, 0x01},
+ {WSA883X_CURRENT_LIMIT, 0x78, 0x40},
+ {WSA883X_DRE_CTL_0, 0x07, 0x02},
+ {WSA883X_VAGC_TIME, 0x03, 0x02},
+ {WSA883X_VAGC_CTL, 0x01, 0x01},
+ {WSA883X_TAGC_CTL, 0x0E, 0x0A},
+ {WSA883X_TAGC_TIME, 0x0C, 0x0C},
+ {WSA883X_TAGC_E2E_GAIN, 0x1F, 0x02},
+ {WSA883X_TEMP_CONFIG0, 0x07, 0x02},
+ {WSA883X_TEMP_CONFIG1, 0x07, 0x02},
+ {WSA883X_OTP_REG_1, 0xFF, 0x49},
+ {WSA883X_OTP_REG_2, 0xC0, 0x80},
+ {WSA883X_OTP_REG_3, 0xFF, 0xC9},
+ {WSA883X_OTP_REG_4, 0xC0, 0x40},
+ {WSA883X_TAGC_CTL, 0x01, 0x01},
+ {WSA883X_CKWD_CTL_0, 0x60, 0x00},
+ {WSA883X_CKWD_CTL_1, 0x1F, 0x1B},
+};
+
static int wsa883x_get_temperature(struct snd_soc_component *component,
int *temp);
enum {
@@ -59,6 +118,10 @@
};
enum {
+ SPKR_STATUS = 0,
+};
+
+enum {
WSA883X_IRQ_INT_SAF2WAR = 0,
WSA883X_IRQ_INT_WAR2SAF,
WSA883X_IRQ_INT_DISABLE,
@@ -69,6 +132,7 @@
WSA883X_IRQ_INT_INTR_PIN,
WSA883X_IRQ_INT_UVLO,
WSA883X_IRQ_INT_PA_ON_ERR,
+ WSA883X_NUM_IRQS,
};
static const struct regmap_irq wsa883x_irqs[WSA883X_NUM_IRQS] = {
@@ -174,8 +238,13 @@
if (!is_swr_slave_reg_readable(i))
continue;
swr_read(pdev, pdev->dev_num, i, ®_val, 1);
- len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i,
+ len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i,
(reg_val & 0xFF));
+ if (len < 0) {
+ pr_err("%s: fail to fill the buffer\n", __func__);
+ total = -EFAULT;
+ goto copy_err;
+ }
if ((total + len) >= count - 1)
break;
if (copy_to_user((ubuf + total), tmp_buf, len)) {
@@ -334,6 +403,14 @@
};
#endif
+static void wsa883x_regcache_sync(struct wsa883x_priv *wsa883x)
+{
+ mutex_lock(&wsa883x->res_lock);
+ regcache_mark_dirty(wsa883x->regmap);
+ regcache_sync(wsa883x->regmap);
+ mutex_unlock(&wsa883x->res_lock);
+}
+
static irqreturn_t wsa883x_saf2war_handle_irq(int irq, void *data)
{
pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
@@ -535,7 +612,17 @@
return -EINVAL;
}
- len = snprintf(buffer, sizeof(buffer), "WSA883X-SOUNDWIRE_1_0\n");
+ switch (wsa883x->version) {
+ case WSA883X_VERSION_1_0:
+ len = snprintf(buffer, sizeof(buffer), "WSA883X_1_0\n");
+ break;
+ case WSA883X_VERSION_1_1:
+ len = snprintf(buffer, sizeof(buffer), "WSA883X_1_1\n");
+ break;
+ default:
+ len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
+ break;
+ }
return simple_read_from_buffer(buf, count, &pos, buffer, len);
}
@@ -544,6 +631,41 @@
.read = wsa883x_codec_version_read,
};
+static ssize_t wsa883x_variant_read(struct snd_info_entry *entry,
+ void *file_private_data,
+ struct file *file,
+ char __user *buf, size_t count,
+ loff_t pos)
+{
+ struct wsa883x_priv *wsa883x;
+ char buffer[WSA883X_VARIANT_ENTRY_SIZE];
+ int len = 0;
+
+ wsa883x = (struct wsa883x_priv *) entry->private_data;
+ if (!wsa883x) {
+ pr_err("%s: wsa883x priv is null\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (wsa883x->variant) {
+ case WSA8830:
+ len = snprintf(buffer, sizeof(buffer), "WSA8830\n");
+ break;
+ case WSA8835:
+ len = snprintf(buffer, sizeof(buffer), "WSA8835\n");
+ break;
+ default:
+ len = snprintf(buffer, sizeof(buffer), "UNDEFINED\n");
+ break;
+ }
+
+ return simple_read_from_buffer(buf, count, &pos, buffer, len);
+}
+
+static struct snd_info_entry_ops wsa883x_variant_ops = {
+ .read = wsa883x_variant_read,
+};
+
/*
* wsa883x_codec_info_create_codec_entry - creates wsa883x module
* @codec_root: The parent directory
@@ -558,6 +680,7 @@
struct snd_soc_component *component)
{
struct snd_info_entry *version_entry;
+ struct snd_info_entry *variant_entry;
struct wsa883x_priv *wsa883x;
struct snd_soc_card *card;
char name[80];
@@ -566,11 +689,17 @@
return -EINVAL;
wsa883x = snd_soc_component_get_drvdata(component);
+ if (wsa883x->entry) {
+ dev_dbg(wsa883x->dev,
+ "%s:wsa883x module already created\n", __func__);
+ return 0;
+ }
card = component->card;
- snprintf(name, sizeof(name), "%s.%x", "wsa883x",
- (u32)wsa883x->swr_slave->addr);
- wsa883x->entry = snd_info_create_subdir(codec_root->module,
+ snprintf(name, sizeof(name), "%s.%llx", "wsa883x",
+ wsa883x->swr_slave->addr);
+
+ wsa883x->entry = snd_info_create_module_entry(codec_root->module,
(const char *)name,
codec_root);
if (!wsa883x->entry) {
@@ -579,12 +708,19 @@
return -ENOMEM;
}
+ wsa883x->entry->mode = S_IFDIR | 0555;
+ if (snd_info_register(wsa883x->entry) < 0) {
+ snd_info_free_entry(wsa883x->entry);
+ return -ENOMEM;
+ }
+
version_entry = snd_info_create_card_entry(card->snd_card,
"version",
wsa883x->entry);
if (!version_entry) {
dev_dbg(component->dev, "%s: failed to create wsa883x version entry\n",
__func__);
+ snd_info_free_entry(wsa883x->entry);
return -ENOMEM;
}
@@ -595,22 +731,40 @@
if (snd_info_register(version_entry) < 0) {
snd_info_free_entry(version_entry);
+ snd_info_free_entry(wsa883x->entry);
return -ENOMEM;
}
wsa883x->version_entry = version_entry;
+ variant_entry = snd_info_create_card_entry(card->snd_card,
+ "variant",
+ wsa883x->entry);
+ if (!variant_entry) {
+ dev_dbg(component->dev,
+ "%s: failed to create wsa883x variant entry\n",
+ __func__);
+ snd_info_free_entry(version_entry);
+ snd_info_free_entry(wsa883x->entry);
+ return -ENOMEM;
+ }
+
+ variant_entry->private_data = wsa883x;
+ variant_entry->size = WSA883X_VARIANT_ENTRY_SIZE;
+ variant_entry->content = SNDRV_INFO_CONTENT_DATA;
+ variant_entry->c.ops = &wsa883x_variant_ops;
+
+ if (snd_info_register(variant_entry) < 0) {
+ snd_info_free_entry(variant_entry);
+ snd_info_free_entry(version_entry);
+ snd_info_free_entry(wsa883x->entry);
+ return -ENOMEM;
+ }
+ wsa883x->variant_entry = variant_entry;
+
return 0;
}
EXPORT_SYMBOL(wsa883x_codec_info_create_codec_entry);
-static void wsa883x_regcache_sync(struct wsa883x_priv *wsa883x)
-{
- mutex_lock(&wsa883x->res_lock);
- regcache_mark_dirty(wsa883x->regmap);
- regcache_sync(wsa883x->regmap);
- mutex_unlock(&wsa883x->res_lock);
-}
-
static int wsa883x_get_compander(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -774,16 +928,8 @@
&port_type[0]);
break;
case SND_SOC_DAPM_POST_PMU:
- swr_slvdev_datapath_control(wsa883x->swr_slave,
- wsa883x->swr_slave->dev_num,
- true);
break;
case SND_SOC_DAPM_PRE_PMD:
- swr_slvdev_datapath_control(wsa883x->swr_slave,
- wsa883x->swr_slave->dev_num,
- false);
- break;
- case SND_SOC_DAPM_POST_PMD:
wsa883x_set_port(component, SWR_DAC_PORT,
&port_id[num_port], &num_ch[num_port],
&ch_mask[num_port], &ch_rate[num_port],
@@ -807,6 +953,15 @@
swr_disconnect_port(wsa883x->swr_slave, &port_id[0], num_port,
&ch_mask[0], &port_type[0]);
break;
+ case SND_SOC_DAPM_POST_PMD:
+ if (swr_set_device_group(wsa883x->swr_slave, SWR_GROUP_NONE))
+ dev_err(component->dev,
+ "%s: set num ch failed\n", __func__);
+
+ swr_slvdev_datapath_control(wsa883x->swr_slave,
+ wsa883x->swr_slave->dev_num,
+ false);
+ break;
default:
break;
}
@@ -819,21 +974,39 @@
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
- int min_gain, max_gain;
dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event);
switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- /* TODO Vote for Global PA */
- break;
-
case SND_SOC_DAPM_POST_PMU:
+ swr_slvdev_datapath_control(wsa883x->swr_slave,
+ wsa883x->swr_slave->dev_num,
+ true);
+ wcd_enable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
/* Force remove group */
swr_remove_from_group(wsa883x->swr_slave,
wsa883x->swr_slave->dev_num);
+ snd_soc_component_update_bits(component,
+ WSA883X_VBAT_ADC_FLT_CTL,
+ 0x0E, 0x06);
+ snd_soc_component_update_bits(component,
+ WSA883X_VBAT_ADC_FLT_CTL,
+ 0x01, 0x01);
+ schedule_delayed_work(&wsa883x->vbat_work,
+ msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000));
+ set_bit(SPKR_STATUS, &wsa883x->status_mask);
break;
- case SND_SOC_DAPM_POST_PMD:
- /* TODO Unvote for Global PA */
+ case SND_SOC_DAPM_PRE_PMD:
+ cancel_delayed_work_sync(&wsa883x->vbat_work);
+ snd_soc_component_update_bits(component,
+ WSA883X_VBAT_ADC_FLT_CTL,
+ 0x01, 0x00);
+ snd_soc_component_update_bits(component,
+ WSA883X_VBAT_ADC_FLT_CTL,
+ 0x0E, 0x00);
+ snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
+ 0x01, 0x00);
+ wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
+ clear_bit(SPKR_STATUS, &wsa883x->status_mask);
break;
}
return 0;
@@ -884,10 +1057,14 @@
static void wsa883x_codec_init(struct snd_soc_component *component)
{
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
+ int i;
if (!wsa883x)
return;
+ for (i = 0; i < ARRAY_SIZE(reg_init); i++)
+ snd_soc_component_update_bits(component, reg_init[i].reg,
+ reg_init[i].mask, reg_init[i].val);
}
static int32_t wsa883x_temp_reg_read(struct snd_soc_component *component,
@@ -929,7 +1106,6 @@
static int wsa883x_get_temperature(struct snd_soc_component *component,
int *temp)
{
- struct snd_soc_component *component;
struct wsa_temp_register reg;
int dmeas, d1, d2;
int ret = 0;
@@ -943,7 +1119,7 @@
return -EINVAL;
do {
- ret = wsa883x_temp_reg_read(component, ®)
+ ret = wsa883x_temp_reg_read(component, ®);
if (ret) {
pr_err("%s: temp read failed: %d, current temp: %d\n",
__func__, ret, wsa883x->curr_temp);
@@ -996,10 +1172,42 @@
return ret;
}
+static void wsa883x_vbat_monitor_work(struct work_struct *work)
+{
+ struct wsa883x_priv *wsa883x;
+ struct delayed_work *dwork;
+ struct snd_soc_component *component;
+ u16 val = 0, vbat_code = 0;
+ int vbat_val = 0;
+
+ dwork = to_delayed_work(work);
+ wsa883x = container_of(dwork, struct wsa883x_priv, vbat_work);
+ component = wsa883x->component;
+
+ val = snd_soc_component_read32(component, WSA883X_VBAT_DIN_MSB);
+ vbat_code = (val << 2);
+ val = (snd_soc_component_read32(component, WSA883X_VBAT_DIN_LSB)
+ & 0xC0);
+ vbat_code |= (val >> 6);
+ vbat_val = ((vbat_code * 5) / 1023);
+ dev_dbg(component->dev, "%s: instant vbat code = %d val = %d\n",
+ __func__, vbat_code, vbat_val);
+
+ val = snd_soc_component_read32(component, WSA883X_VBAT_DOUT);
+ vbat_val = ((val * 5) / 255);
+
+ dev_dbg(component->dev, "%s: low pass vbat code = %d val = %d\n",
+ __func__, val, vbat_val);
+
+ schedule_delayed_work(&wsa883x->vbat_work,
+ msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000));
+}
+
static int wsa883x_codec_probe(struct snd_soc_component *component)
{
struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
struct swr_device *dev;
+ int variant = 0, version = 0;
if (!wsa883x)
return -EINVAL;
@@ -1007,8 +1215,18 @@
dev = wsa883x->swr_slave;
wsa883x->component = component;
+
+ variant = (snd_soc_component_read32(component, WSA883X_OTP_REG_0)
+ & 0x0F);
+ wsa883x->variant = variant;
+
+ version = (snd_soc_component_read32(component, WSA883X_CHIP_ID0)
+ & 0xFF);
+ wsa883x->version = version;
+
wsa883x_codec_init(component);
wsa883x->global_pa_cnt = 0;
+ INIT_DELAYED_WORK(&wsa883x->vbat_work, wsa883x_vbat_monitor_work);
return 0;
}
@@ -1055,6 +1273,45 @@
return ret;
}
+static int wsa883x_swr_up(struct wsa883x_priv *wsa883x)
+{
+ int ret;
+
+ ret = wsa883x_gpio_ctrl(wsa883x, true);
+ if (ret)
+ dev_err(wsa883x->dev, "%s: Failed to enable gpio\n", __func__);
+
+ return ret;
+}
+
+static int wsa883x_swr_down(struct wsa883x_priv *wsa883x)
+{
+ int ret;
+
+ ret = wsa883x_gpio_ctrl(wsa883x, false);
+ if (ret)
+ dev_err(wsa883x->dev, "%s: Failed to disable gpio\n", __func__);
+
+ return ret;
+}
+
+static int wsa883x_swr_reset(struct wsa883x_priv *wsa883x)
+{
+ u8 retry = WSA883X_NUM_RETRY;
+ u8 devnum = 0;
+ struct swr_device *pdev;
+
+ pdev = wsa883x->swr_slave;
+ while (swr_get_logical_dev_num(pdev, pdev->addr, &devnum) && retry--) {
+ /* Retry after 1 msec delay */
+ usleep_range(1000, 1100);
+ }
+ pdev->dev_num = devnum;
+ wsa883x_regcache_sync(wsa883x);
+
+ return 0;
+}
+
static int wsa883x_event_notify(struct notifier_block *nb,
unsigned long val, void *ptr)
{
@@ -1067,23 +1324,70 @@
switch (event) {
case BOLERO_WSA_EVT_PA_OFF_PRE_SSR:
+ if (delayed_work_pending(&wsa883x->vbat_work))
+ cancel_delayed_work_sync(&wsa883x->vbat_work);
snd_soc_component_update_bits(wsa883x->component,
- WSA883X_SPKR_DRV_GAIN,
- 0xF0, 0xC0);
- snd_soc_component_update_bits(wsa883x->component,
- WSA883X_SPKR_DRV_EN,
- 0x80, 0x00);
+ WSA883X_PA_FSM_CTL,
+ 0x01, 0x00);
+ wsa883x_swr_down(wsa883x);
+ break;
+
+ case BOLERO_WSA_EVT_SSR_UP:
+ wsa883x_swr_up(wsa883x);
+ /* Add delay to allow enumerate */
+ usleep_range(20000, 20010);
+ wsa883x_swr_reset(wsa883x);
+ break;
+
+ case BOLERO_WSA_EVT_PA_ON_POST_FSCLK:
+ if (test_bit(SPKR_STATUS, &wsa883x->status_mask))
+ snd_soc_component_update_bits(wsa883x->component,
+ WSA883X_PA_FSM_CTL,
+ 0x01, 0x01);
break;
default:
+ dev_dbg(wsa883x->dev, "%s: unknown event %d\n",
+ __func__, event);
break;
}
return 0;
}
-static int wsa883x_swr_probe(struct swr_device *pdev)
+static int wsa883x_enable_supplies(struct device * dev,
+ struct wsa883x_priv *priv)
{
int ret = 0;
+
+ /* Parse power supplies */
+ msm_cdc_get_power_supplies(dev, &priv->regulator,
+ &priv->num_supplies);
+ if (!priv->regulator || (priv->num_supplies <= 0)) {
+ dev_err(dev, "%s: no power supplies defined\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = msm_cdc_init_supplies(dev, &priv->supplies,
+ priv->regulator, priv->num_supplies);
+ if (!priv->supplies) {
+ dev_err(dev, "%s: Cannot init wsa supplies\n",
+ __func__);
+ return ret;
+ }
+
+ ret = msm_cdc_enable_static_supplies(dev, priv->supplies,
+ priv->regulator,
+ priv->num_supplies);
+ if (ret)
+ dev_err(dev, "%s: wsa static supply enable failed!\n",
+ __func__);
+
+ return ret;
+}
+
+static int wsa883x_swr_probe(struct swr_device *pdev)
+{
+ int ret = 0, i = 0;
struct wsa883x_priv *wsa883x;
u8 devnum = 0;
bool pin_state_current = false;
@@ -1094,6 +1398,10 @@
if (!wsa883x)
return -ENOMEM;
+ ret = wsa883x_enable_supplies(&pdev->dev, wsa883x);
+ if (ret)
+ return -EINVAL;
+
wsa883x->wsa_rst_np = of_parse_phandle(pdev->dev.of_node,
"qcom,spkr-sd-n-node", 0);
if (!wsa883x->wsa_rst_np) {
@@ -1109,10 +1417,10 @@
* soundwire auto enumeration of slave devices as
* as per HW requirement.
*/
- usleep_range(5000, 5010);
+ usleep_range(20000, 20010);
ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
if (ret) {
- dev_dbg(&pdev->dev,
+ dev_err(&pdev->dev,
"%s get devnum %d for dev addr %lx failed\n",
__func__, devnum, pdev->addr);
goto dev_err;
@@ -1136,7 +1444,7 @@
wsa883x->irq_info.wcd_regmap_irq_chip = &wsa883x_regmap_irq_chip;
wsa883x->irq_info.codec_name = "WSA883X";
wsa883x->irq_info.regmap = wsa883x->regmap;
- wsa883x->irq_info.dev = dev;
+ wsa883x->irq_info.dev = &pdev->dev;
ret = wcd_irq_init(&wsa883x->irq_info, &wsa883x->virq);
if (ret) {
@@ -1157,15 +1465,23 @@
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_OCP,
"WSA OCP", wsa883x_ocp_handle_irq, NULL);
+ wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_OCP);
+
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLIP,
"WSA CLIP", wsa883x_clip_handle_irq, NULL);
+ wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLIP);
+
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD,
"WSA PDM WD", wsa883x_pdm_wd_handle_irq, NULL);
+ wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
+
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLK_WD,
"WSA CLK WD", wsa883x_clk_wd_handle_irq, NULL);
+ wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_CLK_WD);
+
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_INTR_PIN,
"WSA EXT INT", wsa883x_ext_int_handle_irq, NULL);
@@ -1176,6 +1492,8 @@
wcd_request_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR,
"WSA PA ERR", wsa883x_pa_on_err_handle_irq, NULL);
+ wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR);
+
ret = snd_soc_register_component(&pdev->dev, &soc_codec_dev_wsa883x,
NULL, 0);
if (ret) {
diff --git a/asoc/kona.c b/asoc/kona.c
index 4382689..7560fa9 100644
--- a/asoc/kona.c
+++ b/asoc/kona.c
@@ -31,6 +31,7 @@
#include "asoc/wcd-mbhc-v2.h"
#include "codecs/wcd938x/wcd938x-mbhc.h"
#include "codecs/wsa881x.h"
+#include "codecs/wsa883x/wsa883x.h"
#include "codecs/wcd938x/wcd938x.h"
#include "codecs/bolero/bolero-cdc.h"
#include <dt-bindings/sound/audio-codec-port-types.h>
@@ -7570,9 +7571,14 @@
if (!strcmp(component->name_prefix, "SpkrLeft")) {
dev_dbg(component->dev, "%s: setting left ch map to codec %s\n",
__func__, component->name);
- wsa881x_set_channel_map(component, &spkleft_ports[0],
- WSA881X_MAX_SWR_PORTS, &ch_mask[0],
- &ch_rate[0], &spkleft_port_types[0]);
+ if (strnstr(component->name, "wsa883x", sizeof(component->name)))
+ wsa883x_set_channel_map(component, &spkleft_ports[0],
+ WSA881X_MAX_SWR_PORTS, &ch_mask[0],
+ &ch_rate[0], &spkleft_port_types[0]);
+ else
+ wsa881x_set_channel_map(component, &spkleft_ports[0],
+ WSA881X_MAX_SWR_PORTS, &ch_mask[0],
+ &ch_rate[0], &spkleft_port_types[0]);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
@@ -7580,9 +7586,14 @@
} else if (!strcmp(component->name_prefix, "SpkrRight")) {
dev_dbg(component->dev, "%s: setting right ch map to codec %s\n",
__func__, component->name);
- wsa881x_set_channel_map(component, &spkright_ports[0],
- WSA881X_MAX_SWR_PORTS, &ch_mask[0],
- &ch_rate[0], &spkright_port_types[0]);
+ if (strnstr(component->name, "wsa883x", sizeof(component->name)))
+ wsa883x_set_channel_map(component, &spkright_ports[0],
+ WSA881X_MAX_SWR_PORTS, &ch_mask[0],
+ &ch_rate[0], &spkright_port_types[0]);
+ else
+ wsa881x_set_channel_map(component, &spkright_ports[0],
+ WSA881X_MAX_SWR_PORTS, &ch_mask[0],
+ &ch_rate[0], &spkright_port_types[0]);
if (dapm->component) {
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
@@ -7605,8 +7616,12 @@
}
pdata->codec_root = entry;
}
- wsa881x_codec_info_create_codec_entry(pdata->codec_root,
- component);
+ if (strnstr(component->name, "wsa883x", sizeof(component->name)))
+ wsa883x_codec_info_create_codec_entry(pdata->codec_root,
+ component);
+ else
+ wsa881x_codec_info_create_codec_entry(pdata->codec_root,
+ component);
err:
return ret;
}
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index 70e2ebf..d4fbe39 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -30222,6 +30222,50 @@
msm_aptx_dec_license_control_put),
};
+static int msm_routing_get_pll_clk_drift(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int msm_routing_put_pll_clk_drift(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u16 port_id = 0;
+ int32_t clk_drift = 0;
+ uint32_t clk_reset = 0;
+ int be_idx, ret = -EINVAL;
+
+ be_idx = ucontrol->value.integer.value[0];
+ clk_drift = ucontrol->value.integer.value[1];
+ clk_reset = ucontrol->value.integer.value[2];
+
+ if (be_idx < 0 && be_idx >= MSM_BACKEND_DAI_MAX) {
+ pr_err("%s: Invalid be id %d\n", __func__, be_idx);
+ return -EINVAL;
+ }
+
+ if (!msm_bedais[be_idx].active && !clk_reset) {
+ pr_err("%s:BE is not active %d, cannot set clock drift\n",
+ __func__, be_idx);
+ return -EINVAL;
+ }
+
+ port_id = msm_bedais[be_idx].port_id;
+ pr_debug("%s: clk drift %d be idx %d clk reset %d port id 0x%x\n",
+ __func__, clk_drift, be_idx, clk_reset, port_id);
+ ret = afe_set_pll_clk_drift(port_id, clk_drift, clk_reset);
+ if (ret < 0)
+ pr_err("%s: failed to set pll clk drift\n", __func__);
+
+ return ret;
+}
+
+static const struct snd_kcontrol_new pll_clk_drift_controls[] = {
+ SOC_SINGLE_MULTI_EXT("PLL config data", SND_SOC_NOPM, 0, 0xFFFFFFFF,
+ 0, 128, msm_routing_get_pll_clk_drift, msm_routing_put_pll_clk_drift),
+};
+
static int msm_routing_put_port_chmap_mixer(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -30522,6 +30566,9 @@
port_multi_channel_map_mixer_controls,
ARRAY_SIZE(port_multi_channel_map_mixer_controls));
+ snd_soc_add_component_controls(component, pll_clk_drift_controls,
+ ARRAY_SIZE(pll_clk_drift_controls));
+
return 0;
}
diff --git a/asoc/qcs405.c b/asoc/qcs405.c
index b76728c..241305c 100644
--- a/asoc/qcs405.c
+++ b/asoc/qcs405.c
@@ -6552,6 +6552,36 @@
return ret;
}
+static int msm_mi2s_snd_hw_free(struct snd_pcm_substream *substream)
+{
+ int i, data_format = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ int index = rtd->cpu_dai->id;
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_component *component;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ data_format = mi2s_rx_cfg[index].data_format;
+ else
+ data_format = mi2s_tx_cfg[index].data_format;
+
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+ /* Call csra mute function if data format is DSD, else return */
+ if (data_format != AFE_DSD_DATA)
+ return 0;
+
+ for (i = 0; i < card->num_aux_devs; i++) {
+ component =
+ soc_find_component(card->aux_dev[i].codec_of_node,
+ NULL);
+ csra66x0_hw_free_mute(component);
+ }
+
+ return 0;
+}
+
static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
{
int ret;
@@ -6902,6 +6932,7 @@
static struct snd_soc_ops msm_mi2s_be_ops = {
.startup = msm_mi2s_snd_startup,
+ .hw_free = msm_mi2s_snd_hw_free,
.shutdown = msm_mi2s_snd_shutdown,
};
diff --git a/config/litoauto.conf b/config/litoauto.conf
index 8dbeee0..d0030bb 100644
--- a/config/litoauto.conf
+++ b/config/litoauto.conf
@@ -3,6 +3,7 @@
CONFIG_SND_SOC_WCD9XXX_V2=m
CONFIG_SND_SOC_WCD_MBHC=m
CONFIG_SND_SOC_WSA881X=m
+CONFIG_SND_SOC_WSA883X=m
CONFIG_WCD9XXX_CODEC_CORE_V2=m
CONFIG_MSM_CDC_PINCTRL=m
CONFIG_MSM_QDSP6V2_CODECS=m
diff --git a/config/litoautoconf.h b/config/litoautoconf.h
index adf43e2..322ac73 100644
--- a/config/litoautoconf.h
+++ b/config/litoautoconf.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#define CONFIG_PINCTRL_LPI 1
@@ -7,6 +7,7 @@
#define CONFIG_SND_SOC_WCD9XXX_V2 1
#define CONFIG_SND_SOC_WCD_MBHC 1
#define CONFIG_SND_SOC_WSA881X 1
+#define CONFIG_SND_SOC_WSA883X 1
#define CONFIG_WCD9XXX_CODEC_CORE_V2 1
#define CONFIG_MSM_CDC_PINCTRL 1
#define CONFIG_MSM_QDSP6V2_CODECS 1
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 3b26c0c..2586bd5 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -174,6 +174,43 @@
uint32_t v_vali_flag;
};
+struct afe_clkinfo_per_port {
+ u16 port_id; /* AFE port ID */
+ uint32_t clk_id; /* Clock ID */
+};
+
+struct afe_clkinfo_per_port clkinfo_per_port[] = {
+ { AFE_PORT_ID_PRIMARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT},
+ { AFE_PORT_ID_SECONDARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT},
+ { AFE_PORT_ID_TERTIARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT},
+ { AFE_PORT_ID_QUATERNARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT},
+ { AFE_PORT_ID_QUINARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT},
+ { AFE_PORT_ID_SENARY_MI2S_RX, Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT},
+ { AFE_PORT_ID_PRIMARY_PCM_RX, Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT},
+ { AFE_PORT_ID_SECONDARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT},
+ { AFE_PORT_ID_TERTIARY_PCM_RX, Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT},
+ { AFE_PORT_ID_QUATERNARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT},
+ { AFE_PORT_ID_QUINARY_PCM_RX, Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT},
+ { AFE_PORT_ID_SENARY_PCM_RX, Q6AFE_LPASS_CLK_ID_SEN_PCM_IBIT},
+ { AFE_PORT_ID_PRIMARY_TDM_RX, Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT},
+ { AFE_PORT_ID_SECONDARY_TDM_RX, Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT},
+ { AFE_PORT_ID_TERTIARY_TDM_RX, Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT},
+ { AFE_PORT_ID_QUATERNARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT},
+ { AFE_PORT_ID_QUINARY_TDM_RX, Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT},
+ { AFE_PORT_ID_PRIMARY_SPDIF_RX,
+ AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE},
+ { AFE_PORT_ID_PRIMARY_SPDIF_TX,
+ AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE},
+ { AFE_PORT_ID_SECONDARY_SPDIF_RX,
+ AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE},
+ { AFE_PORT_ID_SECONDARY_SPDIF_TX,
+ AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE},
+ { AFE_PORT_ID_PRIMARY_META_MI2S_RX,
+ Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT},
+ { AFE_PORT_ID_SECONDARY_META_MI2S_RX,
+ Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT},
+};
+
static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX];
static unsigned long afe_configured_cmd;
@@ -7843,6 +7880,156 @@
}
EXPORT_SYMBOL(afe_set_lpass_clock);
+static int afe_get_port_idx(u16 port_id)
+{
+ u16 afe_port = 0;
+ int i = -EINVAL;
+
+ pr_debug("%s: port id 0x%x\n", __func__, port_id);
+
+ if ((port_id >= AFE_PORT_ID_TDM_PORT_RANGE_START) &&
+ (port_id <= AFE_PORT_ID_TDM_PORT_RANGE_END))
+ afe_port = port_id & 0xFFF0;
+ else if ((port_id == AFE_PORT_ID_PRIMARY_SPDIF_RX) ||
+ (port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) ||
+ (port_id == AFE_PORT_ID_SECONDARY_SPDIF_RX) ||
+ (port_id == AFE_PORT_ID_SECONDARY_SPDIF_TX))
+ afe_port = port_id;
+ else
+ afe_port = port_id & 0xFFFE;
+
+ for (i = 0; i < ARRAY_SIZE(clkinfo_per_port); i++) {
+ if (afe_port == clkinfo_per_port[i].port_id) {
+ pr_debug("%s: idx 0x%x port id 0x%x\n", __func__,
+ i, afe_port);
+ return i;
+ }
+ }
+
+ pr_debug("%s: cannot get idx for port id 0x%x\n", __func__,
+ afe_port);
+
+ return -EINVAL;
+}
+
+static int afe_get_clk_id(u16 port_id)
+{
+ u16 afe_port = 0;
+ uint32_t clk_id = -EINVAL;
+ int idx = 0;
+
+ idx = afe_get_port_idx(port_id);
+ if (idx < 0) {
+ pr_err("%s: cannot get clock id for port id 0x%x\n", __func__,
+ afe_port);
+ return -EINVAL;
+ }
+
+ clk_id = clkinfo_per_port[idx].clk_id;
+ pr_debug("%s: clk id 0x%x port id 0x%x\n", __func__, clk_id,
+ afe_port);
+
+ return clk_id;
+}
+
+/**
+ * afe_set_clk_id - Update clock id for AFE port
+ *
+ * @port_id: AFE port id
+ * @clk_id: CLock ID
+ *
+ * Returns 0 on success, appropriate error code otherwise
+ */
+int afe_set_clk_id(u16 port_id, uint32_t clk_id)
+{
+ u16 afe_port = 0;
+ int idx = 0;
+
+ idx = afe_get_port_idx(port_id);
+ if (idx < 0) {
+ pr_debug("%s: cannot set clock id for port id 0x%x\n", __func__,
+ afe_port);
+ return -EINVAL;
+ }
+
+ clkinfo_per_port[idx].clk_id = clk_id;
+ pr_debug("%s: updated clk id 0x%x port id 0x%x\n", __func__,
+ clkinfo_per_port[idx].clk_id, afe_port);
+
+ return 0;
+}
+EXPORT_SYMBOL(afe_set_clk_id);
+
+/**
+ * afe_set_pll_clk_drift - Set audio interface PLL clock drift
+ *
+ * @port_id: AFE port id
+ * @set_clk_drift: clk drift to adjust PLL
+ * @clk_reset: reset Interface clock to original value
+ *
+ * Returns 0 on success, appropriate error code otherwise
+ */
+int afe_set_pll_clk_drift(u16 port_id, int32_t set_clk_drift,
+ uint32_t clk_reset)
+{
+ struct afe_set_clk_drift clk_drift;
+ struct param_hdr_v3 param_hdr;
+ uint32_t clk_id;
+ int index = 0, ret = 0;
+
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ memset(&clk_drift, 0, sizeof(clk_drift));
+
+ index = q6audio_get_port_index(port_id);
+ if (index < 0 || index >= AFE_MAX_PORTS) {
+ pr_err("%s: index[%d] invalid!\n", __func__, index);
+ return -EINVAL;
+ }
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0) {
+ pr_err_ratelimited("%s: Q6 interface prepare failed %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ clk_id = afe_get_clk_id(port_id);
+ if (clk_id < 0) {
+ pr_err("%s: cannot get clk id for port id 0x%x\n",
+ __func__, port_id);
+ return -EINVAL;
+ }
+
+ if (clk_id & 0x01) {
+ pr_err("%s: cannot adjust clock drift for external clock id 0x%x\n",
+ __func__, clk_id);
+ return -EINVAL;
+ }
+
+ clk_drift.clk_drift = set_clk_drift;
+ clk_drift.clk_reset = clk_reset;
+ clk_drift.clk_id = clk_id;
+ pr_debug("%s: clk id = 0x%x clk drift = %d clk reset = %d port id 0x%x\n",
+ __func__, clk_drift.clk_id, clk_drift.clk_drift,
+ clk_drift.clk_reset, port_id);
+
+ mutex_lock(&this_afe.afe_clk_lock);
+ param_hdr.module_id = AFE_MODULE_CLOCK_SET;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CLOCK_ADJUST;
+ param_hdr.param_size = sizeof(struct afe_set_clk_drift);
+
+ ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr,
+ (u8 *) &clk_drift);
+ if (ret < 0)
+ pr_err_ratelimited("%s: AFE PLL clk drift failed with ret %d\n",
+ __func__, ret);
+
+ mutex_unlock(&this_afe.afe_clk_lock);
+ return ret;
+}
+EXPORT_SYMBOL(afe_set_pll_clk_drift);
+
/**
* afe_set_lpass_clk_cfg - Set AFE clk config
*
@@ -7929,6 +8116,10 @@
return -EINVAL;
}
+ ret = afe_set_clk_id(port_id, cfg->clk_id);
+ if (ret < 0)
+ pr_debug("%s: afe_set_clk_id fail %d\n", __func__, ret);
+
ret = afe_set_lpass_clk_cfg(index, cfg);
if (ret)
pr_err("%s: afe_set_lpass_clk_cfg_v2 failed %d\n",
diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c
index 66883ba..a77ffd3 100644
--- a/dsp/q6lsm.c
+++ b/dsp/q6lsm.c
@@ -2393,7 +2393,7 @@
lab_config_hdr.param_id = LSM_PARAM_ID_LAB_CONFIG;
lab_config_hdr.param_size = sizeof(lab_config);
lab_config.minor_version = 1;
- lab_config.wake_up_latency_ms = 250;
+ lab_config.wake_up_latency_ms = 40;
rc = q6lsm_pack_and_set_params(client, &lab_config_hdr,
(uint8_t *) &lab_config,
LSM_SESSION_CMD_SET_PARAMS);
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index 7d56a4d..5ac7751 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -11766,6 +11766,35 @@
#define AFE_MODULE_CLOCK_SET 0x0001028F
#define AFE_PARAM_ID_CLOCK_SET 0x00010290
+struct afe_set_clk_drift {
+ /*
+ * Clock ID
+ * @values
+ * - 0x100 to 0x10E
+ * - 0x200 to 0x20C
+ * - 0x500 to 0x505
+ */
+ uint32_t clk_id;
+
+ /*
+ * Clock drift (in PPB) to be set.
+ * @values
+ * - need to get values from DSP team
+ */
+ int32_t clk_drift;
+
+ /*
+ * Clock rest.
+ * @values
+ * - 1 -- Reset PLL with the original frequency
+ * - 0 -- Adjust the clock with the clk drift value
+ */
+ uint32_t clk_reset;
+} __packed;
+
+/* This param id is used to adjust audio interface PLL*/
+#define AFE_PARAM_ID_CLOCK_ADJUST 0x000102C6
+
enum afe_lpass_digital_clk_src {
Q6AFE_LPASS_DIGITAL_ROOT_INVALID,
Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR,
diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h
index 76617a9..3ff3028 100644
--- a/include/dsp/q6afe-v2.h
+++ b/include/dsp/q6afe-v2.h
@@ -487,6 +487,9 @@
void (*afe_cb_wakeup_irq)(void *handle));
int afe_get_doa_tracking_mon(u16 port_id,
struct doa_tracking_mon_param *doa_tracking_data);
+int afe_set_pll_clk_drift(u16 port_id, int32_t set_clk_drift,
+ uint32_t clk_reset);
+int afe_set_clk_id(u16 port_id, uint32_t clk_id);
enum {
AFE_LPASS_CORE_HW_BLOCK_ID_NONE,
diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h
index 35b5960..e8ba1b3 100644
--- a/include/uapi/linux/msm_audio_calibration.h
+++ b/include/uapi/linux/msm_audio_calibration.h
@@ -104,6 +104,7 @@
ADM_LSM_TOPOLOGY_CAL_TYPE,
ADM_LSM_AUDPROC_CAL_TYPE,
ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE,
+ ADM_AUDPROC_PERSISTENT_CAL_TYPE,
MAX_CAL_TYPES,
};
@@ -117,6 +118,7 @@
#define ADM_LSM_TOPOLOGY_CAL_TYPE ADM_LSM_TOPOLOGY_CAL_TYPE
#define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE
#define ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE
+#define ADM_AUDPROC_PERSISTENT_CAL_TYPE ADM_AUDPROC_PERSISTENT_CAL_TYPE
#define LSM_CAL_TYPES
#define TOPOLOGY_SPECIFIC_CHANNEL_INFO
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index b0ad17f..6358437 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -616,10 +616,10 @@
for (i = 0; i < length; i++) {
/* wait for FIFO WR command to complete to avoid overflow */
/*
- * Reduce sleep from 100us to 10us to meet KPIs
+ * Reduce sleep from 100us to 50us to meet KPIs
* This still meets the hardware spec
*/
- usleep_range(10, 12);
+ usleep_range(50, 55);
swr_master_write(swrm, reg_addr[i], val[i]);
}
mutex_unlock(&swrm->iolock);
@@ -1341,9 +1341,9 @@
dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n",
__func__, bank, master->num_port);
-
- swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00,
- SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank));
+ if (!swrm->disable_div2_clk_switch)
+ swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00,
+ SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank));
swrm_copy_data_port_config(master, bank);
}
@@ -2648,6 +2648,7 @@
swrm->state = SWR_MSTR_UP;
swrm->ipc_wakeup = false;
swrm->ipc_wakeup_triggered = false;
+ swrm->disable_div2_clk_switch = FALSE;
init_completion(&swrm->reset);
init_completion(&swrm->broadcast);
init_completion(&swrm->clk_off_complete);
@@ -2669,6 +2670,12 @@
for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++)
INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list);
+ if (of_property_read_u32(pdev->dev.of_node,
+ "qcom,disable-div2-clk-switch",
+ &swrm->disable_div2_clk_switch)) {
+ swrm->disable_div2_clk_switch = FALSE;
+ }
+
/* Register LPASS core hw vote */
lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote");
if (IS_ERR(lpass_core_hw_vote)) {
diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h
index ce0b64d..ec5bbd2 100644
--- a/soc/swr-mstr-ctrl.h
+++ b/soc/swr-mstr-ctrl.h
@@ -180,6 +180,7 @@
int hw_core_clk_en;
int aud_core_clk_en;
int clk_src;
+ u32 disable_div2_clk_switch;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_swrm_dent;
struct dentry *debugfs_peek;