1491 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.4 */5 6#include <linux/bitops.h>7#include <linux/device.h>8#include <linux/gpio/consumer.h>9#include <linux/init.h>10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/pm_runtime.h>13#include <linux/printk.h>14#include <linux/regmap.h>15#include <linux/regulator/consumer.h>16#include <linux/slab.h>17#include <linux/soundwire/sdw.h>18#include <linux/soundwire/sdw_registers.h>19#include <linux/soundwire/sdw_type.h>20#include <sound/pcm.h>21#include <sound/pcm_params.h>22#include <sound/soc-dapm.h>23#include <sound/soc.h>24#include <sound/tlv.h>25 26#define WSA883X_BASE 0x300027#define WSA883X_ANA_BG_TSADC_BASE (WSA883X_BASE + 0x00000001)28#define WSA883X_REF_CTRL (WSA883X_ANA_BG_TSADC_BASE + 0x0000)29#define WSA883X_TEST_CTL_0 (WSA883X_ANA_BG_TSADC_BASE + 0x0001)30#define WSA883X_BIAS_0 (WSA883X_ANA_BG_TSADC_BASE + 0x0002)31#define WSA883X_OP_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0003)32#define WSA883X_IREF_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0004)33#define WSA883X_ISENS_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0005)34#define WSA883X_CLK_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0006)35#define WSA883X_TEST_CTL_1 (WSA883X_ANA_BG_TSADC_BASE + 0x0007)36#define WSA883X_BIAS_1 (WSA883X_ANA_BG_TSADC_BASE + 0x0008)37#define WSA883X_ADC_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0009)38#define WSA883X_DOUT_MSB (WSA883X_ANA_BG_TSADC_BASE + 0x000A)39#define WSA883X_DOUT_LSB (WSA883X_ANA_BG_TSADC_BASE + 0x000B)40#define WSA883X_VBAT_SNS (WSA883X_ANA_BG_TSADC_BASE + 0x000C)41#define WSA883X_ITRIM_CODE (WSA883X_ANA_BG_TSADC_BASE + 0x000D)42 43#define WSA883X_ANA_IVSENSE_BASE (WSA883X_BASE + 0x0000000F)44#define WSA883X_EN (WSA883X_ANA_IVSENSE_BASE + 0x0000)45#define WSA883X_OVERRIDE1 (WSA883X_ANA_IVSENSE_BASE + 0x0001)46#define WSA883X_OVERRIDE2 (WSA883X_ANA_IVSENSE_BASE + 0x0002)47#define WSA883X_VSENSE1 (WSA883X_ANA_IVSENSE_BASE + 0x0003)48#define WSA883X_ISENSE1 (WSA883X_ANA_IVSENSE_BASE + 0x0004)49#define WSA883X_ISENSE2 (WSA883X_ANA_IVSENSE_BASE + 0x0005)50#define WSA883X_ISENSE_CAL (WSA883X_ANA_IVSENSE_BASE + 0x0006)51#define WSA883X_MISC (WSA883X_ANA_IVSENSE_BASE + 0x0007)52#define WSA883X_ADC_0 (WSA883X_ANA_IVSENSE_BASE + 0x0008)53#define WSA883X_ADC_1 (WSA883X_ANA_IVSENSE_BASE + 0x0009)54#define WSA883X_ADC_2 (WSA883X_ANA_IVSENSE_BASE + 0x000A)55#define WSA883X_ADC_3 (WSA883X_ANA_IVSENSE_BASE + 0x000B)56#define WSA883X_ADC_4 (WSA883X_ANA_IVSENSE_BASE + 0x000C)57#define WSA883X_ADC_5 (WSA883X_ANA_IVSENSE_BASE + 0x000D)58#define WSA883X_ADC_6 (WSA883X_ANA_IVSENSE_BASE + 0x000E)59#define WSA883X_ADC_7 (WSA883X_ANA_IVSENSE_BASE + 0x000F)60#define WSA883X_STATUS (WSA883X_ANA_IVSENSE_BASE + 0x0010)61 62#define WSA883X_ANA_SPK_TOP_BASE (WSA883X_BASE + 0x00000025)63#define WSA883X_DAC_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0000)64#define WSA883X_DAC_EN_DEBUG_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0001)65#define WSA883X_DAC_OPAMP_BIAS1_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0002)66#define WSA883X_DAC_OPAMP_BIAS2_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0003)67#define WSA883X_DAC_VCM_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0004)68#define WSA883X_DAC_VOLTAGE_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0005)69#define WSA883X_ATEST1_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0006)70#define WSA883X_ATEST2_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0007)71#define WSA883X_SPKR_TOP_BIAS_REG1 (WSA883X_ANA_SPK_TOP_BASE + 0x0008)72#define WSA883X_SPKR_TOP_BIAS_REG2 (WSA883X_ANA_SPK_TOP_BASE + 0x0009)73#define WSA883X_SPKR_TOP_BIAS_REG3 (WSA883X_ANA_SPK_TOP_BASE + 0x000A)74#define WSA883X_SPKR_TOP_BIAS_REG4 (WSA883X_ANA_SPK_TOP_BASE + 0x000B)75#define WSA883X_SPKR_CLIP_DET_REG (WSA883X_ANA_SPK_TOP_BASE + 0x000C)76#define WSA883X_SPKR_DRV_LF_BLK_EN (WSA883X_ANA_SPK_TOP_BASE + 0x000D)77#define WSA883X_SPKR_DRV_LF_EN (WSA883X_ANA_SPK_TOP_BASE + 0x000E)78#define WSA883X_SPKR_DRV_LF_MASK_DCC_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x000F)79#define WSA883X_SPKR_DRV_LF_MISC_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0010)80#define WSA883X_SPKR_DRV_LF_REG_GAIN (WSA883X_ANA_SPK_TOP_BASE + 0x0011)81#define WSA883X_SPKR_DRV_OS_CAL_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0012)82#define WSA883X_SPKR_DRV_OS_CAL_CTL1 (WSA883X_ANA_SPK_TOP_BASE + 0x0013)83#define WSA883X_SPKR_PWM_CLK_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0014)84#define WSA883X_SPKR_PWM_FREQ_SEL_MASK BIT(3)85#define WSA883X_SPKR_PWM_FREQ_F300KHZ 086#define WSA883X_SPKR_PWM_FREQ_F600KHZ 187#define WSA883X_SPKR_PDRV_HS_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0015)88#define WSA883X_SPKR_PDRV_LS_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0016)89#define WSA883X_SPKR_PWRSTG_DBG (WSA883X_ANA_SPK_TOP_BASE + 0x0017)90#define WSA883X_SPKR_OCP_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0018)91#define WSA883X_SPKR_BBM_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0019)92#define WSA883X_PA_STATUS0 (WSA883X_ANA_SPK_TOP_BASE + 0x001A)93#define WSA883X_PA_STATUS1 (WSA883X_ANA_SPK_TOP_BASE + 0x001B)94#define WSA883X_PA_STATUS2 (WSA883X_ANA_SPK_TOP_BASE + 0x001C)95 96#define WSA883X_ANA_BOOST_BASE (WSA883X_BASE + 0x00000043)97#define WSA883X_EN_CTRL (WSA883X_ANA_BOOST_BASE + 0x0000)98#define WSA883X_CURRENT_LIMIT (WSA883X_ANA_BOOST_BASE + 0x0001)99#define WSA883X_IBIAS1 (WSA883X_ANA_BOOST_BASE + 0x0002)100#define WSA883X_IBIAS2 (WSA883X_ANA_BOOST_BASE + 0x0003)101#define WSA883X_IBIAS3 (WSA883X_ANA_BOOST_BASE + 0x0004)102#define WSA883X_LDO_PROG (WSA883X_ANA_BOOST_BASE + 0x0005)103#define WSA883X_STABILITY_CTRL1 (WSA883X_ANA_BOOST_BASE + 0x0006)104#define WSA883X_STABILITY_CTRL2 (WSA883X_ANA_BOOST_BASE + 0x0007)105#define WSA883X_PWRSTAGE_CTRL1 (WSA883X_ANA_BOOST_BASE + 0x0008)106#define WSA883X_PWRSTAGE_CTRL2 (WSA883X_ANA_BOOST_BASE + 0x0009)107#define WSA883X_BYPASS_1 (WSA883X_ANA_BOOST_BASE + 0x000A)108#define WSA883X_BYPASS_2 (WSA883X_ANA_BOOST_BASE + 0x000B)109#define WSA883X_ZX_CTRL_1 (WSA883X_ANA_BOOST_BASE + 0x000C)110#define WSA883X_ZX_CTRL_2 (WSA883X_ANA_BOOST_BASE + 0x000D)111#define WSA883X_MISC1 (WSA883X_ANA_BOOST_BASE + 0x000E)112#define WSA883X_MISC2 (WSA883X_ANA_BOOST_BASE + 0x000F)113#define WSA883X_GMAMP_SUP1 (WSA883X_ANA_BOOST_BASE + 0x0010)114#define WSA883X_PWRSTAGE_CTRL3 (WSA883X_ANA_BOOST_BASE + 0x0011)115#define WSA883X_PWRSTAGE_CTRL4 (WSA883X_ANA_BOOST_BASE + 0x0012)116#define WSA883X_TEST1 (WSA883X_ANA_BOOST_BASE + 0x0013)117#define WSA883X_SPARE1 (WSA883X_ANA_BOOST_BASE + 0x0014)118#define WSA883X_SPARE2 (WSA883X_ANA_BOOST_BASE + 0x0015)119 120#define WSA883X_ANA_PON_LDOL_BASE (WSA883X_BASE + 0x00000059)121#define WSA883X_PON_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0000)122#define WSA883X_PON_CLT_1 (WSA883X_ANA_PON_LDOL_BASE + 0x0001)123#define WSA883X_PON_CTL_2 (WSA883X_ANA_PON_LDOL_BASE + 0x0002)124#define WSA883X_PON_CTL_3 (WSA883X_ANA_PON_LDOL_BASE + 0x0003)125#define WSA883X_CKWD_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0004)126#define WSA883X_CKWD_CTL_1 (WSA883X_ANA_PON_LDOL_BASE + 0x0005)127#define WSA883X_CKWD_CTL_2 (WSA883X_ANA_PON_LDOL_BASE + 0x0006)128#define WSA883X_CKSK_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0007)129#define WSA883X_PADSW_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0008)130#define WSA883X_TEST_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0009)131#define WSA883X_TEST_1 (WSA883X_ANA_PON_LDOL_BASE + 0x000A)132#define WSA883X_STATUS_0 (WSA883X_ANA_PON_LDOL_BASE + 0x000B)133#define WSA883X_STATUS_1 (WSA883X_ANA_PON_LDOL_BASE + 0x000C)134 135#define WSA883X_DIG_CTRL_BASE (WSA883X_BASE + 0x00000400)136#define WSA883X_CHIP_ID0 (WSA883X_DIG_CTRL_BASE + 0x0001)137#define WSA883X_CHIP_ID1 (WSA883X_DIG_CTRL_BASE + 0x0002)138#define WSA883X_CHIP_ID2 (WSA883X_DIG_CTRL_BASE + 0x0003)139#define WSA883X_CHIP_ID3 (WSA883X_DIG_CTRL_BASE + 0x0004)140#define WSA883X_BUS_ID (WSA883X_DIG_CTRL_BASE + 0x0005)141#define WSA883X_CDC_RST_CTL (WSA883X_DIG_CTRL_BASE + 0x0006)142#define WSA883X_TOP_CLK_CFG (WSA883X_DIG_CTRL_BASE + 0x0007)143#define WSA883X_CDC_PATH_MODE (WSA883X_DIG_CTRL_BASE + 0x0008)144#define WSA883X_RXD_MODE_MASK BIT(1)145#define WSA883X_RXD_MODE_NORMAL 0146#define WSA883X_RXD_MODE_HIFI 1147#define WSA883X_CDC_CLK_CTL (WSA883X_DIG_CTRL_BASE + 0x0009)148#define WSA883X_SWR_RESET_EN (WSA883X_DIG_CTRL_BASE + 0x000A)149#define WSA883X_RESET_CTL (WSA883X_DIG_CTRL_BASE + 0x000B)150#define WSA883X_PA_FSM_CTL (WSA883X_DIG_CTRL_BASE + 0x0010)151#define WSA883X_GLOBAL_PA_EN_MASK BIT(0)152#define WSA883X_GLOBAL_PA_ENABLE 1153#define WSA883X_PA_FSM_TIMER0 (WSA883X_DIG_CTRL_BASE + 0x0011)154#define WSA883X_PA_FSM_TIMER1 (WSA883X_DIG_CTRL_BASE + 0x0012)155#define WSA883X_PA_FSM_STA (WSA883X_DIG_CTRL_BASE + 0x0013)156#define WSA883X_PA_FSM_ERR_COND (WSA883X_DIG_CTRL_BASE + 0x0014)157#define WSA883X_PA_FSM_MSK (WSA883X_DIG_CTRL_BASE + 0x0015)158#define WSA883X_PA_FSM_BYP (WSA883X_DIG_CTRL_BASE + 0x0016)159#define WSA883X_PA_FSM_DBG (WSA883X_DIG_CTRL_BASE + 0x0017)160#define WSA883X_TADC_VALUE_CTL (WSA883X_DIG_CTRL_BASE + 0x0020)161#define WSA883X_TEMP_DETECT_CTL (WSA883X_DIG_CTRL_BASE + 0x0021)162#define WSA883X_TEMP_MSB (WSA883X_DIG_CTRL_BASE + 0x0022)163#define WSA883X_TEMP_LSB (WSA883X_DIG_CTRL_BASE + 0x0023)164#define WSA883X_TEMP_CONFIG0 (WSA883X_DIG_CTRL_BASE + 0x0024)165#define WSA883X_TEMP_CONFIG1 (WSA883X_DIG_CTRL_BASE + 0x0025)166#define WSA883X_VBAT_ADC_FLT_CTL (WSA883X_DIG_CTRL_BASE + 0x0026)167#define WSA883X_VBAT_ADC_FLT_EN_MASK BIT(0)168#define WSA883X_VBAT_ADC_COEF_SEL_MASK GENMASK(3, 1)169#define WSA883X_VBAT_ADC_COEF_F_1DIV2 0x0170#define WSA883X_VBAT_ADC_COEF_F_1DIV16 0x3171#define WSA883X_VBAT_DIN_MSB (WSA883X_DIG_CTRL_BASE + 0x0027)172#define WSA883X_VBAT_DIN_LSB (WSA883X_DIG_CTRL_BASE + 0x0028)173#define WSA883X_VBAT_DOUT (WSA883X_DIG_CTRL_BASE + 0x0029)174#define WSA883X_SDM_PDM9_LSB (WSA883X_DIG_CTRL_BASE + 0x002A)175#define WSA883X_SDM_PDM9_MSB (WSA883X_DIG_CTRL_BASE + 0x002B)176#define WSA883X_CDC_RX_CTL (WSA883X_DIG_CTRL_BASE + 0x0030)177#define WSA883X_CDC_SPK_DSM_A1_0 (WSA883X_DIG_CTRL_BASE + 0x0031)178#define WSA883X_CDC_SPK_DSM_A1_1 (WSA883X_DIG_CTRL_BASE + 0x0032)179#define WSA883X_CDC_SPK_DSM_A2_0 (WSA883X_DIG_CTRL_BASE + 0x0033)180#define WSA883X_CDC_SPK_DSM_A2_1 (WSA883X_DIG_CTRL_BASE + 0x0034)181#define WSA883X_CDC_SPK_DSM_A3_0 (WSA883X_DIG_CTRL_BASE + 0x0035)182#define WSA883X_CDC_SPK_DSM_A3_1 (WSA883X_DIG_CTRL_BASE + 0x0036)183#define WSA883X_CDC_SPK_DSM_A4_0 (WSA883X_DIG_CTRL_BASE + 0x0037)184#define WSA883X_CDC_SPK_DSM_A4_1 (WSA883X_DIG_CTRL_BASE + 0x0038)185#define WSA883X_CDC_SPK_DSM_A5_0 (WSA883X_DIG_CTRL_BASE + 0x0039)186#define WSA883X_CDC_SPK_DSM_A5_1 (WSA883X_DIG_CTRL_BASE + 0x003A)187#define WSA883X_CDC_SPK_DSM_A6_0 (WSA883X_DIG_CTRL_BASE + 0x003B)188#define WSA883X_CDC_SPK_DSM_A7_0 (WSA883X_DIG_CTRL_BASE + 0x003C)189#define WSA883X_CDC_SPK_DSM_C_0 (WSA883X_DIG_CTRL_BASE + 0x003D)190#define WSA883X_CDC_SPK_DSM_C_1 (WSA883X_DIG_CTRL_BASE + 0x003E)191#define WSA883X_CDC_SPK_DSM_C_2 (WSA883X_DIG_CTRL_BASE + 0x003F)192#define WSA883X_CDC_SPK_DSM_C_3 (WSA883X_DIG_CTRL_BASE + 0x0040)193#define WSA883X_CDC_SPK_DSM_R1 (WSA883X_DIG_CTRL_BASE + 0x0041)194#define WSA883X_CDC_SPK_DSM_R2 (WSA883X_DIG_CTRL_BASE + 0x0042)195#define WSA883X_CDC_SPK_DSM_R3 (WSA883X_DIG_CTRL_BASE + 0x0043)196#define WSA883X_CDC_SPK_DSM_R4 (WSA883X_DIG_CTRL_BASE + 0x0044)197#define WSA883X_CDC_SPK_DSM_R5 (WSA883X_DIG_CTRL_BASE + 0x0045)198#define WSA883X_CDC_SPK_DSM_R6 (WSA883X_DIG_CTRL_BASE + 0x0046)199#define WSA883X_CDC_SPK_DSM_R7 (WSA883X_DIG_CTRL_BASE + 0x0047)200#define WSA883X_CDC_SPK_GAIN_PDM_0 (WSA883X_DIG_CTRL_BASE + 0x0048)201#define WSA883X_CDC_SPK_GAIN_PDM_1 (WSA883X_DIG_CTRL_BASE + 0x0049)202#define WSA883X_CDC_SPK_GAIN_PDM_2 (WSA883X_DIG_CTRL_BASE + 0x004A)203#define WSA883X_PDM_WD_CTL (WSA883X_DIG_CTRL_BASE + 0x004B)204#define WSA883X_PDM_EN_MASK BIT(0)205#define WSA883X_PDM_ENABLE BIT(0)206#define WSA883X_DEM_BYPASS_DATA0 (WSA883X_DIG_CTRL_BASE + 0x004C)207#define WSA883X_DEM_BYPASS_DATA1 (WSA883X_DIG_CTRL_BASE + 0x004D)208#define WSA883X_DEM_BYPASS_DATA2 (WSA883X_DIG_CTRL_BASE + 0x004E)209#define WSA883X_DEM_BYPASS_DATA3 (WSA883X_DIG_CTRL_BASE + 0x004F)210#define WSA883X_WAVG_CTL (WSA883X_DIG_CTRL_BASE + 0x0050)211#define WSA883X_WAVG_LRA_PER_0 (WSA883X_DIG_CTRL_BASE + 0x0051)212#define WSA883X_WAVG_LRA_PER_1 (WSA883X_DIG_CTRL_BASE + 0x0052)213#define WSA883X_WAVG_DELTA_THETA_0 (WSA883X_DIG_CTRL_BASE + 0x0053)214#define WSA883X_WAVG_DELTA_THETA_1 (WSA883X_DIG_CTRL_BASE + 0x0054)215#define WSA883X_WAVG_DIRECT_AMP_0 (WSA883X_DIG_CTRL_BASE + 0x0055)216#define WSA883X_WAVG_DIRECT_AMP_1 (WSA883X_DIG_CTRL_BASE + 0x0056)217#define WSA883X_WAVG_PTRN_AMP0_0 (WSA883X_DIG_CTRL_BASE + 0x0057)218#define WSA883X_WAVG_PTRN_AMP0_1 (WSA883X_DIG_CTRL_BASE + 0x0058)219#define WSA883X_WAVG_PTRN_AMP1_0 (WSA883X_DIG_CTRL_BASE + 0x0059)220#define WSA883X_WAVG_PTRN_AMP1_1 (WSA883X_DIG_CTRL_BASE + 0x005A)221#define WSA883X_WAVG_PTRN_AMP2_0 (WSA883X_DIG_CTRL_BASE + 0x005B)222#define WSA883X_WAVG_PTRN_AMP2_1 (WSA883X_DIG_CTRL_BASE + 0x005C)223#define WSA883X_WAVG_PTRN_AMP3_0 (WSA883X_DIG_CTRL_BASE + 0x005D)224#define WSA883X_WAVG_PTRN_AMP3_1 (WSA883X_DIG_CTRL_BASE + 0x005E)225#define WSA883X_WAVG_PTRN_AMP4_0 (WSA883X_DIG_CTRL_BASE + 0x005F)226#define WSA883X_WAVG_PTRN_AMP4_1 (WSA883X_DIG_CTRL_BASE + 0x0060)227#define WSA883X_WAVG_PTRN_AMP5_0 (WSA883X_DIG_CTRL_BASE + 0x0061)228#define WSA883X_WAVG_PTRN_AMP5_1 (WSA883X_DIG_CTRL_BASE + 0x0062)229#define WSA883X_WAVG_PTRN_AMP6_0 (WSA883X_DIG_CTRL_BASE + 0x0063)230#define WSA883X_WAVG_PTRN_AMP6_1 (WSA883X_DIG_CTRL_BASE + 0x0064)231#define WSA883X_WAVG_PTRN_AMP7_0 (WSA883X_DIG_CTRL_BASE + 0x0065)232#define WSA883X_WAVG_PTRN_AMP7_1 (WSA883X_DIG_CTRL_BASE + 0x0066)233#define WSA883X_WAVG_PER_0_1 (WSA883X_DIG_CTRL_BASE + 0x0067)234#define WSA883X_WAVG_PER_2_3 (WSA883X_DIG_CTRL_BASE + 0x0068)235#define WSA883X_WAVG_PER_4_5 (WSA883X_DIG_CTRL_BASE + 0x0069)236#define WSA883X_WAVG_PER_6_7 (WSA883X_DIG_CTRL_BASE + 0x006A)237#define WSA883X_WAVG_STA (WSA883X_DIG_CTRL_BASE + 0x006B)238#define WSA883X_DRE_CTL_0 (WSA883X_DIG_CTRL_BASE + 0x006C)239#define WSA883X_DRE_OFFSET_MASK GENMASK(2, 0)240#define WSA883X_DRE_PROG_DELAY_MASK GENMASK(7, 4)241#define WSA883X_DRE_CTL_1 (WSA883X_DIG_CTRL_BASE + 0x006D)242#define WSA883X_DRE_GAIN_EN_MASK BIT(0)243#define WSA883X_DRE_GAIN_FROM_CSR 1244#define WSA883X_DRE_IDLE_DET_CTL (WSA883X_DIG_CTRL_BASE + 0x006E)245#define WSA883X_CLSH_CTL_0 (WSA883X_DIG_CTRL_BASE + 0x0070)246#define WSA883X_CLSH_CTL_1 (WSA883X_DIG_CTRL_BASE + 0x0071)247#define WSA883X_CLSH_V_HD_PA (WSA883X_DIG_CTRL_BASE + 0x0072)248#define WSA883X_CLSH_V_PA_MIN (WSA883X_DIG_CTRL_BASE + 0x0073)249#define WSA883X_CLSH_OVRD_VAL (WSA883X_DIG_CTRL_BASE + 0x0074)250#define WSA883X_CLSH_HARD_MAX (WSA883X_DIG_CTRL_BASE + 0x0075)251#define WSA883X_CLSH_SOFT_MAX (WSA883X_DIG_CTRL_BASE + 0x0076)252#define WSA883X_CLSH_SIG_DP (WSA883X_DIG_CTRL_BASE + 0x0077)253#define WSA883X_TAGC_CTL (WSA883X_DIG_CTRL_BASE + 0x0078)254#define WSA883X_TAGC_TIME (WSA883X_DIG_CTRL_BASE + 0x0079)255#define WSA883X_TAGC_E2E_GAIN (WSA883X_DIG_CTRL_BASE + 0x007A)256#define WSA883X_TAGC_FORCE_VAL (WSA883X_DIG_CTRL_BASE + 0x007B)257#define WSA883X_VAGC_CTL (WSA883X_DIG_CTRL_BASE + 0x007C)258#define WSA883X_VAGC_TIME (WSA883X_DIG_CTRL_BASE + 0x007D)259#define WSA883X_VAGC_ATTN_LVL_1_2 (WSA883X_DIG_CTRL_BASE + 0x007E)260#define WSA883X_VAGC_ATTN_LVL_3 (WSA883X_DIG_CTRL_BASE + 0x007F)261#define WSA883X_INTR_MODE (WSA883X_DIG_CTRL_BASE + 0x0080)262#define WSA883X_INTR_MASK0 (WSA883X_DIG_CTRL_BASE + 0x0081)263#define WSA883X_INTR_MASK1 (WSA883X_DIG_CTRL_BASE + 0x0082)264#define WSA883X_INTR_STATUS0 (WSA883X_DIG_CTRL_BASE + 0x0083)265#define WSA883X_INTR_STATUS1 (WSA883X_DIG_CTRL_BASE + 0x0084)266#define WSA883X_INTR_CLEAR0 (WSA883X_DIG_CTRL_BASE + 0x0085)267#define WSA883X_INTR_CLEAR1 (WSA883X_DIG_CTRL_BASE + 0x0086)268#define WSA883X_INTR_LEVEL0 (WSA883X_DIG_CTRL_BASE + 0x0087)269#define WSA883X_INTR_LEVEL1 (WSA883X_DIG_CTRL_BASE + 0x0088)270#define WSA883X_INTR_SET0 (WSA883X_DIG_CTRL_BASE + 0x0089)271#define WSA883X_INTR_SET1 (WSA883X_DIG_CTRL_BASE + 0x008A)272#define WSA883X_INTR_TEST0 (WSA883X_DIG_CTRL_BASE + 0x008B)273#define WSA883X_INTR_TEST1 (WSA883X_DIG_CTRL_BASE + 0x008C)274#define WSA883X_OTP_CTRL0 (WSA883X_DIG_CTRL_BASE + 0x0090)275#define WSA883X_OTP_CTRL1 (WSA883X_DIG_CTRL_BASE + 0x0091)276#define WSA883X_HDRIVE_CTL_GROUP1 (WSA883X_DIG_CTRL_BASE + 0x0092)277#define WSA883X_PIN_CTL (WSA883X_DIG_CTRL_BASE + 0x0093)278#define WSA883X_PIN_CTL_OE (WSA883X_DIG_CTRL_BASE + 0x0094)279#define WSA883X_PIN_WDATA_IOPAD (WSA883X_DIG_CTRL_BASE + 0x0095)280#define WSA883X_PIN_STATUS (WSA883X_DIG_CTRL_BASE + 0x0096)281#define WSA883X_I2C_SLAVE_CTL (WSA883X_DIG_CTRL_BASE + 0x0097)282#define WSA883X_PDM_TEST_MODE (WSA883X_DIG_CTRL_BASE + 0x00A0)283#define WSA883X_ATE_TEST_MODE (WSA883X_DIG_CTRL_BASE + 0x00A1)284#define WSA883X_DIG_DEBUG_MODE (WSA883X_DIG_CTRL_BASE + 0x00A3)285#define WSA883X_DIG_DEBUG_SEL (WSA883X_DIG_CTRL_BASE + 0x00A4)286#define WSA883X_DIG_DEBUG_EN (WSA883X_DIG_CTRL_BASE + 0x00A5)287#define WSA883X_SWR_HM_TEST0 (WSA883X_DIG_CTRL_BASE + 0x00A6)288#define WSA883X_SWR_HM_TEST1 (WSA883X_DIG_CTRL_BASE + 0x00A7)289#define WSA883X_SWR_PAD_CTL (WSA883X_DIG_CTRL_BASE + 0x00A8)290#define WSA883X_TADC_DETECT_DBG_CTL (WSA883X_DIG_CTRL_BASE + 0x00A9)291#define WSA883X_TADC_DEBUG_MSB (WSA883X_DIG_CTRL_BASE + 0x00AA)292#define WSA883X_TADC_DEBUG_LSB (WSA883X_DIG_CTRL_BASE + 0x00AB)293#define WSA883X_SAMPLE_EDGE_SEL (WSA883X_DIG_CTRL_BASE + 0x00AC)294#define WSA883X_SWR_EDGE_SEL (WSA883X_DIG_CTRL_BASE + 0x00AD)295#define WSA883X_TEST_MODE_CTL (WSA883X_DIG_CTRL_BASE + 0x00AE)296#define WSA883X_IOPAD_CTL (WSA883X_DIG_CTRL_BASE + 0x00AF)297#define WSA883X_ANA_CSR_DBG_ADD (WSA883X_DIG_CTRL_BASE + 0x00B0)298#define WSA883X_ANA_CSR_DBG_CTL (WSA883X_DIG_CTRL_BASE + 0x00B1)299#define WSA883X_SPARE_R (WSA883X_DIG_CTRL_BASE + 0x00BC)300#define WSA883X_SPARE_0 (WSA883X_DIG_CTRL_BASE + 0x00BD)301#define WSA883X_SPARE_1 (WSA883X_DIG_CTRL_BASE + 0x00BE)302#define WSA883X_SPARE_2 (WSA883X_DIG_CTRL_BASE + 0x00BF)303#define WSA883X_SCODE (WSA883X_DIG_CTRL_BASE + 0x00C0)304 305#define WSA883X_DIG_TRIM_BASE (WSA883X_BASE + 0x00000500)306#define WSA883X_OTP_REG_0 (WSA883X_DIG_TRIM_BASE + 0x0080)307#define WSA883X_ID_MASK GENMASK(3, 0)308#define WSA883X_OTP_REG_1 (WSA883X_DIG_TRIM_BASE + 0x0081)309#define WSA883X_OTP_REG_2 (WSA883X_DIG_TRIM_BASE + 0x0082)310#define WSA883X_OTP_REG_3 (WSA883X_DIG_TRIM_BASE + 0x0083)311#define WSA883X_OTP_REG_4 (WSA883X_DIG_TRIM_BASE + 0x0084)312#define WSA883X_OTP_REG_5 (WSA883X_DIG_TRIM_BASE + 0x0085)313#define WSA883X_OTP_REG_6 (WSA883X_DIG_TRIM_BASE + 0x0086)314#define WSA883X_OTP_REG_7 (WSA883X_DIG_TRIM_BASE + 0x0087)315#define WSA883X_OTP_REG_8 (WSA883X_DIG_TRIM_BASE + 0x0088)316#define WSA883X_OTP_REG_9 (WSA883X_DIG_TRIM_BASE + 0x0089)317#define WSA883X_OTP_REG_10 (WSA883X_DIG_TRIM_BASE + 0x008A)318#define WSA883X_OTP_REG_11 (WSA883X_DIG_TRIM_BASE + 0x008B)319#define WSA883X_OTP_REG_12 (WSA883X_DIG_TRIM_BASE + 0x008C)320#define WSA883X_OTP_REG_13 (WSA883X_DIG_TRIM_BASE + 0x008D)321#define WSA883X_OTP_REG_14 (WSA883X_DIG_TRIM_BASE + 0x008E)322#define WSA883X_OTP_REG_15 (WSA883X_DIG_TRIM_BASE + 0x008F)323#define WSA883X_OTP_REG_16 (WSA883X_DIG_TRIM_BASE + 0x0090)324#define WSA883X_OTP_REG_17 (WSA883X_DIG_TRIM_BASE + 0x0091)325#define WSA883X_OTP_REG_18 (WSA883X_DIG_TRIM_BASE + 0x0092)326#define WSA883X_OTP_REG_19 (WSA883X_DIG_TRIM_BASE + 0x0093)327#define WSA883X_OTP_REG_20 (WSA883X_DIG_TRIM_BASE + 0x0094)328#define WSA883X_OTP_REG_21 (WSA883X_DIG_TRIM_BASE + 0x0095)329#define WSA883X_OTP_REG_22 (WSA883X_DIG_TRIM_BASE + 0x0096)330#define WSA883X_OTP_REG_23 (WSA883X_DIG_TRIM_BASE + 0x0097)331#define WSA883X_OTP_REG_24 (WSA883X_DIG_TRIM_BASE + 0x0098)332#define WSA883X_OTP_REG_25 (WSA883X_DIG_TRIM_BASE + 0x0099)333#define WSA883X_OTP_REG_26 (WSA883X_DIG_TRIM_BASE + 0x009A)334#define WSA883X_OTP_REG_27 (WSA883X_DIG_TRIM_BASE + 0x009B)335#define WSA883X_OTP_REG_28 (WSA883X_DIG_TRIM_BASE + 0x009C)336#define WSA883X_OTP_REG_29 (WSA883X_DIG_TRIM_BASE + 0x009D)337#define WSA883X_OTP_REG_30 (WSA883X_DIG_TRIM_BASE + 0x009E)338#define WSA883X_OTP_REG_31 (WSA883X_DIG_TRIM_BASE + 0x009F)339#define WSA883X_OTP_REG_32 (WSA883X_DIG_TRIM_BASE + 0x00A0)340#define WSA883X_OTP_REG_33 (WSA883X_DIG_TRIM_BASE + 0x00A1)341#define WSA883X_OTP_REG_34 (WSA883X_DIG_TRIM_BASE + 0x00A2)342#define WSA883X_OTP_REG_35 (WSA883X_DIG_TRIM_BASE + 0x00A3)343#define WSA883X_OTP_REG_63 (WSA883X_DIG_TRIM_BASE + 0x00BF)344 345#define WSA883X_DIG_EMEM_BASE (WSA883X_BASE + 0x000005C0)346#define WSA883X_EMEM_0 (WSA883X_DIG_EMEM_BASE + 0x0000)347#define WSA883X_EMEM_1 (WSA883X_DIG_EMEM_BASE + 0x0001)348#define WSA883X_EMEM_2 (WSA883X_DIG_EMEM_BASE + 0x0002)349#define WSA883X_EMEM_3 (WSA883X_DIG_EMEM_BASE + 0x0003)350#define WSA883X_EMEM_4 (WSA883X_DIG_EMEM_BASE + 0x0004)351#define WSA883X_EMEM_5 (WSA883X_DIG_EMEM_BASE + 0x0005)352#define WSA883X_EMEM_6 (WSA883X_DIG_EMEM_BASE + 0x0006)353#define WSA883X_EMEM_7 (WSA883X_DIG_EMEM_BASE + 0x0007)354#define WSA883X_EMEM_8 (WSA883X_DIG_EMEM_BASE + 0x0008)355#define WSA883X_EMEM_9 (WSA883X_DIG_EMEM_BASE + 0x0009)356#define WSA883X_EMEM_10 (WSA883X_DIG_EMEM_BASE + 0x000A)357#define WSA883X_EMEM_11 (WSA883X_DIG_EMEM_BASE + 0x000B)358#define WSA883X_EMEM_12 (WSA883X_DIG_EMEM_BASE + 0x000C)359#define WSA883X_EMEM_13 (WSA883X_DIG_EMEM_BASE + 0x000D)360#define WSA883X_EMEM_14 (WSA883X_DIG_EMEM_BASE + 0x000E)361#define WSA883X_EMEM_15 (WSA883X_DIG_EMEM_BASE + 0x000F)362#define WSA883X_EMEM_16 (WSA883X_DIG_EMEM_BASE + 0x0010)363#define WSA883X_EMEM_17 (WSA883X_DIG_EMEM_BASE + 0x0011)364#define WSA883X_EMEM_18 (WSA883X_DIG_EMEM_BASE + 0x0012)365#define WSA883X_EMEM_19 (WSA883X_DIG_EMEM_BASE + 0x0013)366#define WSA883X_EMEM_20 (WSA883X_DIG_EMEM_BASE + 0x0014)367#define WSA883X_EMEM_21 (WSA883X_DIG_EMEM_BASE + 0x0015)368#define WSA883X_EMEM_22 (WSA883X_DIG_EMEM_BASE + 0x0016)369#define WSA883X_EMEM_23 (WSA883X_DIG_EMEM_BASE + 0x0017)370#define WSA883X_EMEM_24 (WSA883X_DIG_EMEM_BASE + 0x0018)371#define WSA883X_EMEM_25 (WSA883X_DIG_EMEM_BASE + 0x0019)372#define WSA883X_EMEM_26 (WSA883X_DIG_EMEM_BASE + 0x001A)373#define WSA883X_EMEM_27 (WSA883X_DIG_EMEM_BASE + 0x001B)374#define WSA883X_EMEM_28 (WSA883X_DIG_EMEM_BASE + 0x001C)375#define WSA883X_EMEM_29 (WSA883X_DIG_EMEM_BASE + 0x001D)376#define WSA883X_EMEM_30 (WSA883X_DIG_EMEM_BASE + 0x001E)377#define WSA883X_EMEM_31 (WSA883X_DIG_EMEM_BASE + 0x001F)378#define WSA883X_EMEM_32 (WSA883X_DIG_EMEM_BASE + 0x0020)379#define WSA883X_EMEM_33 (WSA883X_DIG_EMEM_BASE + 0x0021)380#define WSA883X_EMEM_34 (WSA883X_DIG_EMEM_BASE + 0x0022)381#define WSA883X_EMEM_35 (WSA883X_DIG_EMEM_BASE + 0x0023)382#define WSA883X_EMEM_36 (WSA883X_DIG_EMEM_BASE + 0x0024)383#define WSA883X_EMEM_37 (WSA883X_DIG_EMEM_BASE + 0x0025)384#define WSA883X_EMEM_38 (WSA883X_DIG_EMEM_BASE + 0x0026)385#define WSA883X_EMEM_39 (WSA883X_DIG_EMEM_BASE + 0x0027)386#define WSA883X_EMEM_40 (WSA883X_DIG_EMEM_BASE + 0x0028)387#define WSA883X_EMEM_41 (WSA883X_DIG_EMEM_BASE + 0x0029)388#define WSA883X_EMEM_42 (WSA883X_DIG_EMEM_BASE + 0x002A)389#define WSA883X_EMEM_43 (WSA883X_DIG_EMEM_BASE + 0x002B)390#define WSA883X_EMEM_44 (WSA883X_DIG_EMEM_BASE + 0x002C)391#define WSA883X_EMEM_45 (WSA883X_DIG_EMEM_BASE + 0x002D)392#define WSA883X_EMEM_46 (WSA883X_DIG_EMEM_BASE + 0x002E)393#define WSA883X_EMEM_47 (WSA883X_DIG_EMEM_BASE + 0x002F)394#define WSA883X_EMEM_48 (WSA883X_DIG_EMEM_BASE + 0x0030)395#define WSA883X_EMEM_49 (WSA883X_DIG_EMEM_BASE + 0x0031)396#define WSA883X_EMEM_50 (WSA883X_DIG_EMEM_BASE + 0x0032)397#define WSA883X_EMEM_51 (WSA883X_DIG_EMEM_BASE + 0x0033)398#define WSA883X_EMEM_52 (WSA883X_DIG_EMEM_BASE + 0x0034)399#define WSA883X_EMEM_53 (WSA883X_DIG_EMEM_BASE + 0x0035)400#define WSA883X_EMEM_54 (WSA883X_DIG_EMEM_BASE + 0x0036)401#define WSA883X_EMEM_55 (WSA883X_DIG_EMEM_BASE + 0x0037)402#define WSA883X_EMEM_56 (WSA883X_DIG_EMEM_BASE + 0x0038)403#define WSA883X_EMEM_57 (WSA883X_DIG_EMEM_BASE + 0x0039)404#define WSA883X_EMEM_58 (WSA883X_DIG_EMEM_BASE + 0x003A)405#define WSA883X_EMEM_59 (WSA883X_DIG_EMEM_BASE + 0x003B)406#define WSA883X_EMEM_60 (WSA883X_DIG_EMEM_BASE + 0x003C)407#define WSA883X_EMEM_61 (WSA883X_DIG_EMEM_BASE + 0x003D)408#define WSA883X_EMEM_62 (WSA883X_DIG_EMEM_BASE + 0x003E)409#define WSA883X_EMEM_63 (WSA883X_DIG_EMEM_BASE + 0x003F)410 411#define WSA883X_NUM_REGISTERS (WSA883X_EMEM_63 + 1)412#define WSA883X_MAX_REGISTER (WSA883X_NUM_REGISTERS - 1)413 414#define WSA883X_VERSION_1_0 0415#define WSA883X_VERSION_1_1 1416 417#define WSA883X_MAX_SWR_PORTS 4418#define WSA883X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\419 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\420 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\421 SNDRV_PCM_RATE_384000)422/* Fractional Rates */423#define WSA883X_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\424 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)425 426#define WSA883X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\427 SNDRV_PCM_FMTBIT_S24_LE |\428 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)429 430struct wsa883x_priv {431 struct regmap *regmap;432 struct device *dev;433 struct regulator *vdd;434 struct sdw_slave *slave;435 struct sdw_stream_config sconfig;436 struct sdw_stream_runtime *sruntime;437 struct sdw_port_config port_config[WSA883X_MAX_SWR_PORTS];438 struct gpio_desc *sd_n;439 bool port_prepared[WSA883X_MAX_SWR_PORTS];440 bool port_enable[WSA883X_MAX_SWR_PORTS];441 int active_ports;442 int dev_mode;443 int comp_offset;444};445 446enum {447 WSA8830 = 0,448 WSA8835,449 WSA8832,450 WSA8835_V2 = 5,451};452 453enum {454 COMP_OFFSET0,455 COMP_OFFSET1,456 COMP_OFFSET2,457 COMP_OFFSET3,458 COMP_OFFSET4,459};460 461enum wsa_port_ids {462 WSA883X_PORT_DAC,463 WSA883X_PORT_COMP,464 WSA883X_PORT_BOOST,465 WSA883X_PORT_VISENSE,466};467 468static const char * const wsa_dev_mode_text[] = {469 "Speaker", "Receiver", "Ultrasound"470};471 472enum {473 SPEAKER,474 RECEIVER,475 ULTRASOUND,476};477 478static const struct soc_enum wsa_dev_mode_enum =479 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_dev_mode_text), wsa_dev_mode_text);480 481/* 4 ports */482static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA883X_MAX_SWR_PORTS] = {483 [WSA883X_PORT_DAC] = {484 .num = WSA883X_PORT_DAC + 1,485 .type = SDW_DPN_SIMPLE,486 .min_ch = 1,487 .max_ch = 1,488 .simple_ch_prep_sm = true,489 .read_only_wordlength = true,490 },491 [WSA883X_PORT_COMP] = {492 .num = WSA883X_PORT_COMP + 1,493 .type = SDW_DPN_SIMPLE,494 .min_ch = 1,495 .max_ch = 1,496 .simple_ch_prep_sm = true,497 .read_only_wordlength = true,498 },499 [WSA883X_PORT_BOOST] = {500 .num = WSA883X_PORT_BOOST + 1,501 .type = SDW_DPN_SIMPLE,502 .min_ch = 1,503 .max_ch = 1,504 .simple_ch_prep_sm = true,505 .read_only_wordlength = true,506 },507 [WSA883X_PORT_VISENSE] = {508 .num = WSA883X_PORT_VISENSE + 1,509 .type = SDW_DPN_SIMPLE,510 .min_ch = 1,511 .max_ch = 1,512 .simple_ch_prep_sm = true,513 .read_only_wordlength = true,514 }515};516 517static const struct sdw_port_config wsa883x_pconfig[WSA883X_MAX_SWR_PORTS] = {518 [WSA883X_PORT_DAC] = {519 .num = WSA883X_PORT_DAC + 1,520 .ch_mask = 0x1,521 },522 [WSA883X_PORT_COMP] = {523 .num = WSA883X_PORT_COMP + 1,524 .ch_mask = 0xf,525 },526 [WSA883X_PORT_BOOST] = {527 .num = WSA883X_PORT_BOOST + 1,528 .ch_mask = 0x3,529 },530 [WSA883X_PORT_VISENSE] = {531 .num = WSA883X_PORT_VISENSE + 1,532 .ch_mask = 0x3,533 },534};535 536static struct reg_default wsa883x_defaults[] = {537 { WSA883X_REF_CTRL, 0xD5 },538 { WSA883X_TEST_CTL_0, 0x06 },539 { WSA883X_BIAS_0, 0xD2 },540 { WSA883X_OP_CTL, 0xE0 },541 { WSA883X_IREF_CTL, 0x57 },542 { WSA883X_ISENS_CTL, 0x47 },543 { WSA883X_CLK_CTL, 0x87 },544 { WSA883X_TEST_CTL_1, 0x00 },545 { WSA883X_BIAS_1, 0x51 },546 { WSA883X_ADC_CTL, 0x01 },547 { WSA883X_DOUT_MSB, 0x00 },548 { WSA883X_DOUT_LSB, 0x00 },549 { WSA883X_VBAT_SNS, 0x40 },550 { WSA883X_ITRIM_CODE, 0x9F },551 { WSA883X_EN, 0x20 },552 { WSA883X_OVERRIDE1, 0x00 },553 { WSA883X_OVERRIDE2, 0x08 },554 { WSA883X_VSENSE1, 0xD3 },555 { WSA883X_ISENSE1, 0xD4 },556 { WSA883X_ISENSE2, 0x20 },557 { WSA883X_ISENSE_CAL, 0x00 },558 { WSA883X_MISC, 0x08 },559 { WSA883X_ADC_0, 0x00 },560 { WSA883X_ADC_1, 0x00 },561 { WSA883X_ADC_2, 0x40 },562 { WSA883X_ADC_3, 0x80 },563 { WSA883X_ADC_4, 0x25 },564 { WSA883X_ADC_5, 0x25 },565 { WSA883X_ADC_6, 0x08 },566 { WSA883X_ADC_7, 0x81 },567 { WSA883X_STATUS, 0x00 },568 { WSA883X_DAC_CTRL_REG, 0x53 },569 { WSA883X_DAC_EN_DEBUG_REG, 0x00 },570 { WSA883X_DAC_OPAMP_BIAS1_REG, 0x48 },571 { WSA883X_DAC_OPAMP_BIAS2_REG, 0x48 },572 { WSA883X_DAC_VCM_CTRL_REG, 0x88 },573 { WSA883X_DAC_VOLTAGE_CTRL_REG, 0xA5 },574 { WSA883X_ATEST1_REG, 0x00 },575 { WSA883X_ATEST2_REG, 0x00 },576 { WSA883X_SPKR_TOP_BIAS_REG1, 0x6A },577 { WSA883X_SPKR_TOP_BIAS_REG2, 0x65 },578 { WSA883X_SPKR_TOP_BIAS_REG3, 0x55 },579 { WSA883X_SPKR_TOP_BIAS_REG4, 0xA9 },580 { WSA883X_SPKR_CLIP_DET_REG, 0x9C },581 { WSA883X_SPKR_DRV_LF_BLK_EN, 0x0F },582 { WSA883X_SPKR_DRV_LF_EN, 0x0A },583 { WSA883X_SPKR_DRV_LF_MASK_DCC_CTL, 0x00 },584 { WSA883X_SPKR_DRV_LF_MISC_CTL, 0x3A },585 { WSA883X_SPKR_DRV_LF_REG_GAIN, 0x00 },586 { WSA883X_SPKR_DRV_OS_CAL_CTL, 0x00 },587 { WSA883X_SPKR_DRV_OS_CAL_CTL1, 0x90 },588 { WSA883X_SPKR_PWM_CLK_CTL, 0x00 },589 { WSA883X_SPKR_PDRV_HS_CTL, 0x52 },590 { WSA883X_SPKR_PDRV_LS_CTL, 0x48 },591 { WSA883X_SPKR_PWRSTG_DBG, 0x08 },592 { WSA883X_SPKR_OCP_CTL, 0xE2 },593 { WSA883X_SPKR_BBM_CTL, 0x92 },594 { WSA883X_PA_STATUS0, 0x00 },595 { WSA883X_PA_STATUS1, 0x00 },596 { WSA883X_PA_STATUS2, 0x80 },597 { WSA883X_EN_CTRL, 0x44 },598 { WSA883X_CURRENT_LIMIT, 0xCC },599 { WSA883X_IBIAS1, 0x00 },600 { WSA883X_IBIAS2, 0x00 },601 { WSA883X_IBIAS3, 0x00 },602 { WSA883X_LDO_PROG, 0x02 },603 { WSA883X_STABILITY_CTRL1, 0x8E },604 { WSA883X_STABILITY_CTRL2, 0x10 },605 { WSA883X_PWRSTAGE_CTRL1, 0x06 },606 { WSA883X_PWRSTAGE_CTRL2, 0x00 },607 { WSA883X_BYPASS_1, 0x19 },608 { WSA883X_BYPASS_2, 0x13 },609 { WSA883X_ZX_CTRL_1, 0xF0 },610 { WSA883X_ZX_CTRL_2, 0x04 },611 { WSA883X_MISC1, 0x06 },612 { WSA883X_MISC2, 0xA0 },613 { WSA883X_GMAMP_SUP1, 0x82 },614 { WSA883X_PWRSTAGE_CTRL3, 0x39 },615 { WSA883X_PWRSTAGE_CTRL4, 0x5F },616 { WSA883X_TEST1, 0x00 },617 { WSA883X_SPARE1, 0x00 },618 { WSA883X_SPARE2, 0x00 },619 { WSA883X_PON_CTL_0, 0x10 },620 { WSA883X_PON_CLT_1, 0xE0 },621 { WSA883X_PON_CTL_2, 0x90 },622 { WSA883X_PON_CTL_3, 0x70 },623 { WSA883X_CKWD_CTL_0, 0x34 },624 { WSA883X_CKWD_CTL_1, 0x0F },625 { WSA883X_CKWD_CTL_2, 0x00 },626 { WSA883X_CKSK_CTL_0, 0x00 },627 { WSA883X_PADSW_CTL_0, 0x00 },628 { WSA883X_TEST_0, 0x00 },629 { WSA883X_TEST_1, 0x00 },630 { WSA883X_STATUS_0, 0x00 },631 { WSA883X_STATUS_1, 0x00 },632 { WSA883X_CHIP_ID0, 0x00 },633 { WSA883X_CHIP_ID1, 0x00 },634 { WSA883X_CHIP_ID2, 0x02 },635 { WSA883X_CHIP_ID3, 0x02 },636 { WSA883X_BUS_ID, 0x00 },637 { WSA883X_CDC_RST_CTL, 0x01 },638 { WSA883X_TOP_CLK_CFG, 0x00 },639 { WSA883X_CDC_PATH_MODE, 0x00 },640 { WSA883X_CDC_CLK_CTL, 0xFF },641 { WSA883X_SWR_RESET_EN, 0x00 },642 { WSA883X_RESET_CTL, 0x00 },643 { WSA883X_PA_FSM_CTL, 0x00 },644 { WSA883X_PA_FSM_TIMER0, 0x80 },645 { WSA883X_PA_FSM_TIMER1, 0x80 },646 { WSA883X_PA_FSM_STA, 0x00 },647 { WSA883X_PA_FSM_ERR_COND, 0x00 },648 { WSA883X_PA_FSM_MSK, 0x00 },649 { WSA883X_PA_FSM_BYP, 0x01 },650 { WSA883X_PA_FSM_DBG, 0x00 },651 { WSA883X_TADC_VALUE_CTL, 0x03 },652 { WSA883X_TEMP_DETECT_CTL, 0x01 },653 { WSA883X_TEMP_MSB, 0x00 },654 { WSA883X_TEMP_LSB, 0x00 },655 { WSA883X_TEMP_CONFIG0, 0x00 },656 { WSA883X_TEMP_CONFIG1, 0x00 },657 { WSA883X_VBAT_ADC_FLT_CTL, 0x00 },658 { WSA883X_VBAT_DIN_MSB, 0x00 },659 { WSA883X_VBAT_DIN_LSB, 0x00 },660 { WSA883X_VBAT_DOUT, 0x00 },661 { WSA883X_SDM_PDM9_LSB, 0x00 },662 { WSA883X_SDM_PDM9_MSB, 0x00 },663 { WSA883X_CDC_RX_CTL, 0xFE },664 { WSA883X_CDC_SPK_DSM_A1_0, 0x00 },665 { WSA883X_CDC_SPK_DSM_A1_1, 0x01 },666 { WSA883X_CDC_SPK_DSM_A2_0, 0x96 },667 { WSA883X_CDC_SPK_DSM_A2_1, 0x09 },668 { WSA883X_CDC_SPK_DSM_A3_0, 0xAB },669 { WSA883X_CDC_SPK_DSM_A3_1, 0x05 },670 { WSA883X_CDC_SPK_DSM_A4_0, 0x1C },671 { WSA883X_CDC_SPK_DSM_A4_1, 0x02 },672 { WSA883X_CDC_SPK_DSM_A5_0, 0x17 },673 { WSA883X_CDC_SPK_DSM_A5_1, 0x02 },674 { WSA883X_CDC_SPK_DSM_A6_0, 0xAA },675 { WSA883X_CDC_SPK_DSM_A7_0, 0xE3 },676 { WSA883X_CDC_SPK_DSM_C_0, 0x69 },677 { WSA883X_CDC_SPK_DSM_C_1, 0x54 },678 { WSA883X_CDC_SPK_DSM_C_2, 0x02 },679 { WSA883X_CDC_SPK_DSM_C_3, 0x15 },680 { WSA883X_CDC_SPK_DSM_R1, 0xA4 },681 { WSA883X_CDC_SPK_DSM_R2, 0xB5 },682 { WSA883X_CDC_SPK_DSM_R3, 0x86 },683 { WSA883X_CDC_SPK_DSM_R4, 0x85 },684 { WSA883X_CDC_SPK_DSM_R5, 0xAA },685 { WSA883X_CDC_SPK_DSM_R6, 0xE2 },686 { WSA883X_CDC_SPK_DSM_R7, 0x62 },687 { WSA883X_CDC_SPK_GAIN_PDM_0, 0x00 },688 { WSA883X_CDC_SPK_GAIN_PDM_1, 0xFC },689 { WSA883X_CDC_SPK_GAIN_PDM_2, 0x05 },690 { WSA883X_PDM_WD_CTL, 0x00 },691 { WSA883X_DEM_BYPASS_DATA0, 0x00 },692 { WSA883X_DEM_BYPASS_DATA1, 0x00 },693 { WSA883X_DEM_BYPASS_DATA2, 0x00 },694 { WSA883X_DEM_BYPASS_DATA3, 0x00 },695 { WSA883X_WAVG_CTL, 0x06 },696 { WSA883X_WAVG_LRA_PER_0, 0xD1 },697 { WSA883X_WAVG_LRA_PER_1, 0x00 },698 { WSA883X_WAVG_DELTA_THETA_0, 0xE6 },699 { WSA883X_WAVG_DELTA_THETA_1, 0x04 },700 { WSA883X_WAVG_DIRECT_AMP_0, 0x50 },701 { WSA883X_WAVG_DIRECT_AMP_1, 0x00 },702 { WSA883X_WAVG_PTRN_AMP0_0, 0x50 },703 { WSA883X_WAVG_PTRN_AMP0_1, 0x00 },704 { WSA883X_WAVG_PTRN_AMP1_0, 0x50 },705 { WSA883X_WAVG_PTRN_AMP1_1, 0x00 },706 { WSA883X_WAVG_PTRN_AMP2_0, 0x50 },707 { WSA883X_WAVG_PTRN_AMP2_1, 0x00 },708 { WSA883X_WAVG_PTRN_AMP3_0, 0x50 },709 { WSA883X_WAVG_PTRN_AMP3_1, 0x00 },710 { WSA883X_WAVG_PTRN_AMP4_0, 0x50 },711 { WSA883X_WAVG_PTRN_AMP4_1, 0x00 },712 { WSA883X_WAVG_PTRN_AMP5_0, 0x50 },713 { WSA883X_WAVG_PTRN_AMP5_1, 0x00 },714 { WSA883X_WAVG_PTRN_AMP6_0, 0x50 },715 { WSA883X_WAVG_PTRN_AMP6_1, 0x00 },716 { WSA883X_WAVG_PTRN_AMP7_0, 0x50 },717 { WSA883X_WAVG_PTRN_AMP7_1, 0x00 },718 { WSA883X_WAVG_PER_0_1, 0x88 },719 { WSA883X_WAVG_PER_2_3, 0x88 },720 { WSA883X_WAVG_PER_4_5, 0x88 },721 { WSA883X_WAVG_PER_6_7, 0x88 },722 { WSA883X_WAVG_STA, 0x00 },723 { WSA883X_DRE_CTL_0, 0x70 },724 { WSA883X_DRE_CTL_1, 0x08 },725 { WSA883X_DRE_IDLE_DET_CTL, 0x1F },726 { WSA883X_CLSH_CTL_0, 0x37 },727 { WSA883X_CLSH_CTL_1, 0x81 },728 { WSA883X_CLSH_V_HD_PA, 0x0F },729 { WSA883X_CLSH_V_PA_MIN, 0x00 },730 { WSA883X_CLSH_OVRD_VAL, 0x00 },731 { WSA883X_CLSH_HARD_MAX, 0xFF },732 { WSA883X_CLSH_SOFT_MAX, 0xF5 },733 { WSA883X_CLSH_SIG_DP, 0x00 },734 { WSA883X_TAGC_CTL, 0x10 },735 { WSA883X_TAGC_TIME, 0x20 },736 { WSA883X_TAGC_E2E_GAIN, 0x02 },737 { WSA883X_TAGC_FORCE_VAL, 0x00 },738 { WSA883X_VAGC_CTL, 0x00 },739 { WSA883X_VAGC_TIME, 0x08 },740 { WSA883X_VAGC_ATTN_LVL_1_2, 0x21 },741 { WSA883X_VAGC_ATTN_LVL_3, 0x03 },742 { WSA883X_INTR_MODE, 0x00 },743 { WSA883X_INTR_MASK0, 0x90 },744 { WSA883X_INTR_MASK1, 0x00 },745 { WSA883X_INTR_STATUS0, 0x00 },746 { WSA883X_INTR_STATUS1, 0x00 },747 { WSA883X_INTR_CLEAR0, 0x00 },748 { WSA883X_INTR_CLEAR1, 0x00 },749 { WSA883X_INTR_LEVEL0, 0x00 },750 { WSA883X_INTR_LEVEL1, 0x00 },751 { WSA883X_INTR_SET0, 0x00 },752 { WSA883X_INTR_SET1, 0x00 },753 { WSA883X_INTR_TEST0, 0x00 },754 { WSA883X_INTR_TEST1, 0x00 },755 { WSA883X_OTP_CTRL0, 0x00 },756 { WSA883X_OTP_CTRL1, 0x00 },757 { WSA883X_HDRIVE_CTL_GROUP1, 0x00 },758 { WSA883X_PIN_CTL, 0x04 },759 { WSA883X_PIN_CTL_OE, 0x00 },760 { WSA883X_PIN_WDATA_IOPAD, 0x00 },761 { WSA883X_PIN_STATUS, 0x00 },762 { WSA883X_I2C_SLAVE_CTL, 0x00 },763 { WSA883X_PDM_TEST_MODE, 0x00 },764 { WSA883X_ATE_TEST_MODE, 0x00 },765 { WSA883X_DIG_DEBUG_MODE, 0x00 },766 { WSA883X_DIG_DEBUG_SEL, 0x00 },767 { WSA883X_DIG_DEBUG_EN, 0x00 },768 { WSA883X_SWR_HM_TEST0, 0x08 },769 { WSA883X_SWR_HM_TEST1, 0x00 },770 { WSA883X_SWR_PAD_CTL, 0x37 },771 { WSA883X_TADC_DETECT_DBG_CTL, 0x00 },772 { WSA883X_TADC_DEBUG_MSB, 0x00 },773 { WSA883X_TADC_DEBUG_LSB, 0x00 },774 { WSA883X_SAMPLE_EDGE_SEL, 0x7F },775 { WSA883X_SWR_EDGE_SEL, 0x00 },776 { WSA883X_TEST_MODE_CTL, 0x04 },777 { WSA883X_IOPAD_CTL, 0x00 },778 { WSA883X_ANA_CSR_DBG_ADD, 0x00 },779 { WSA883X_ANA_CSR_DBG_CTL, 0x12 },780 { WSA883X_SPARE_R, 0x00 },781 { WSA883X_SPARE_0, 0x00 },782 { WSA883X_SPARE_1, 0x00 },783 { WSA883X_SPARE_2, 0x00 },784 { WSA883X_SCODE, 0x00 },785 { WSA883X_OTP_REG_0, 0x05 },786 { WSA883X_OTP_REG_1, 0xFF },787 { WSA883X_OTP_REG_2, 0xC0 },788 { WSA883X_OTP_REG_3, 0xFF },789 { WSA883X_OTP_REG_4, 0xC0 },790 { WSA883X_OTP_REG_5, 0xFF },791 { WSA883X_OTP_REG_6, 0xFF },792 { WSA883X_OTP_REG_7, 0xFF },793 { WSA883X_OTP_REG_8, 0xFF },794 { WSA883X_OTP_REG_9, 0xFF },795 { WSA883X_OTP_REG_10, 0xFF },796 { WSA883X_OTP_REG_11, 0xFF },797 { WSA883X_OTP_REG_12, 0xFF },798 { WSA883X_OTP_REG_13, 0xFF },799 { WSA883X_OTP_REG_14, 0xFF },800 { WSA883X_OTP_REG_15, 0xFF },801 { WSA883X_OTP_REG_16, 0xFF },802 { WSA883X_OTP_REG_17, 0xFF },803 { WSA883X_OTP_REG_18, 0xFF },804 { WSA883X_OTP_REG_19, 0xFF },805 { WSA883X_OTP_REG_20, 0xFF },806 { WSA883X_OTP_REG_21, 0xFF },807 { WSA883X_OTP_REG_22, 0xFF },808 { WSA883X_OTP_REG_23, 0xFF },809 { WSA883X_OTP_REG_24, 0x37 },810 { WSA883X_OTP_REG_25, 0x3F },811 { WSA883X_OTP_REG_26, 0x03 },812 { WSA883X_OTP_REG_27, 0x00 },813 { WSA883X_OTP_REG_28, 0x00 },814 { WSA883X_OTP_REG_29, 0x00 },815 { WSA883X_OTP_REG_30, 0x00 },816 { WSA883X_OTP_REG_31, 0x03 },817 { WSA883X_OTP_REG_32, 0x00 },818 { WSA883X_OTP_REG_33, 0xFF },819 { WSA883X_OTP_REG_34, 0x00 },820 { WSA883X_OTP_REG_35, 0x00 },821 { WSA883X_OTP_REG_63, 0x40 },822 { WSA883X_EMEM_0, 0x00 },823 { WSA883X_EMEM_1, 0x00 },824 { WSA883X_EMEM_2, 0x00 },825 { WSA883X_EMEM_3, 0x00 },826 { WSA883X_EMEM_4, 0x00 },827 { WSA883X_EMEM_5, 0x00 },828 { WSA883X_EMEM_6, 0x00 },829 { WSA883X_EMEM_7, 0x00 },830 { WSA883X_EMEM_8, 0x00 },831 { WSA883X_EMEM_9, 0x00 },832 { WSA883X_EMEM_10, 0x00 },833 { WSA883X_EMEM_11, 0x00 },834 { WSA883X_EMEM_12, 0x00 },835 { WSA883X_EMEM_13, 0x00 },836 { WSA883X_EMEM_14, 0x00 },837 { WSA883X_EMEM_15, 0x00 },838 { WSA883X_EMEM_16, 0x00 },839 { WSA883X_EMEM_17, 0x00 },840 { WSA883X_EMEM_18, 0x00 },841 { WSA883X_EMEM_19, 0x00 },842 { WSA883X_EMEM_20, 0x00 },843 { WSA883X_EMEM_21, 0x00 },844 { WSA883X_EMEM_22, 0x00 },845 { WSA883X_EMEM_23, 0x00 },846 { WSA883X_EMEM_24, 0x00 },847 { WSA883X_EMEM_25, 0x00 },848 { WSA883X_EMEM_26, 0x00 },849 { WSA883X_EMEM_27, 0x00 },850 { WSA883X_EMEM_28, 0x00 },851 { WSA883X_EMEM_29, 0x00 },852 { WSA883X_EMEM_30, 0x00 },853 { WSA883X_EMEM_31, 0x00 },854 { WSA883X_EMEM_32, 0x00 },855 { WSA883X_EMEM_33, 0x00 },856 { WSA883X_EMEM_34, 0x00 },857 { WSA883X_EMEM_35, 0x00 },858 { WSA883X_EMEM_36, 0x00 },859 { WSA883X_EMEM_37, 0x00 },860 { WSA883X_EMEM_38, 0x00 },861 { WSA883X_EMEM_39, 0x00 },862 { WSA883X_EMEM_40, 0x00 },863 { WSA883X_EMEM_41, 0x00 },864 { WSA883X_EMEM_42, 0x00 },865 { WSA883X_EMEM_43, 0x00 },866 { WSA883X_EMEM_44, 0x00 },867 { WSA883X_EMEM_45, 0x00 },868 { WSA883X_EMEM_46, 0x00 },869 { WSA883X_EMEM_47, 0x00 },870 { WSA883X_EMEM_48, 0x00 },871 { WSA883X_EMEM_49, 0x00 },872 { WSA883X_EMEM_50, 0x00 },873 { WSA883X_EMEM_51, 0x00 },874 { WSA883X_EMEM_52, 0x00 },875 { WSA883X_EMEM_53, 0x00 },876 { WSA883X_EMEM_54, 0x00 },877 { WSA883X_EMEM_55, 0x00 },878 { WSA883X_EMEM_56, 0x00 },879 { WSA883X_EMEM_57, 0x00 },880 { WSA883X_EMEM_58, 0x00 },881 { WSA883X_EMEM_59, 0x00 },882 { WSA883X_EMEM_60, 0x00 },883 { WSA883X_EMEM_61, 0x00 },884 { WSA883X_EMEM_62, 0x00 },885 { WSA883X_EMEM_63, 0x00 },886};887 888static bool wsa883x_readonly_register(struct device *dev, unsigned int reg)889{890 switch (reg) {891 case WSA883X_DOUT_MSB:892 case WSA883X_DOUT_LSB:893 case WSA883X_STATUS:894 case WSA883X_PA_STATUS0:895 case WSA883X_PA_STATUS1:896 case WSA883X_PA_STATUS2:897 case WSA883X_STATUS_0:898 case WSA883X_STATUS_1:899 case WSA883X_CHIP_ID0:900 case WSA883X_CHIP_ID1:901 case WSA883X_CHIP_ID2:902 case WSA883X_CHIP_ID3:903 case WSA883X_BUS_ID:904 case WSA883X_PA_FSM_STA:905 case WSA883X_PA_FSM_ERR_COND:906 case WSA883X_TEMP_MSB:907 case WSA883X_TEMP_LSB:908 case WSA883X_VBAT_DIN_MSB:909 case WSA883X_VBAT_DIN_LSB:910 case WSA883X_VBAT_DOUT:911 case WSA883X_SDM_PDM9_LSB:912 case WSA883X_SDM_PDM9_MSB:913 case WSA883X_WAVG_STA:914 case WSA883X_INTR_STATUS0:915 case WSA883X_INTR_STATUS1:916 case WSA883X_OTP_CTRL1:917 case WSA883X_PIN_STATUS:918 case WSA883X_ATE_TEST_MODE:919 case WSA883X_SWR_HM_TEST1:920 case WSA883X_SPARE_R:921 case WSA883X_OTP_REG_0:922 return true;923 }924 return false;925}926 927static bool wsa883x_writeable_register(struct device *dev, unsigned int reg)928{929 return !wsa883x_readonly_register(dev, reg);930}931 932static bool wsa883x_volatile_register(struct device *dev, unsigned int reg)933{934 return wsa883x_readonly_register(dev, reg);935}936 937static const struct regmap_config wsa883x_regmap_config = {938 .reg_bits = 32,939 .val_bits = 8,940 .cache_type = REGCACHE_MAPLE,941 .reg_defaults = wsa883x_defaults,942 .max_register = WSA883X_MAX_REGISTER,943 .num_reg_defaults = ARRAY_SIZE(wsa883x_defaults),944 .volatile_reg = wsa883x_volatile_register,945 .writeable_reg = wsa883x_writeable_register,946 .reg_format_endian = REGMAP_ENDIAN_NATIVE,947 .val_format_endian = REGMAP_ENDIAN_NATIVE,948 .use_single_read = true,949};950 951static const struct reg_sequence reg_init[] = {952 {WSA883X_PA_FSM_BYP, 0x00},953 {WSA883X_ADC_6, 0x02},954 {WSA883X_CDC_SPK_DSM_A2_0, 0x0A},955 {WSA883X_CDC_SPK_DSM_A2_1, 0x08},956 {WSA883X_CDC_SPK_DSM_A3_0, 0xF3},957 {WSA883X_CDC_SPK_DSM_A3_1, 0x07},958 {WSA883X_CDC_SPK_DSM_A4_0, 0x79},959 {WSA883X_CDC_SPK_DSM_A4_1, 0x02},960 {WSA883X_CDC_SPK_DSM_A5_0, 0x0B},961 {WSA883X_CDC_SPK_DSM_A5_1, 0x02},962 {WSA883X_CDC_SPK_DSM_A6_0, 0x8A},963 {WSA883X_CDC_SPK_DSM_A7_0, 0x9B},964 {WSA883X_CDC_SPK_DSM_C_0, 0x68},965 {WSA883X_CDC_SPK_DSM_C_1, 0x54},966 {WSA883X_CDC_SPK_DSM_C_2, 0xF2},967 {WSA883X_CDC_SPK_DSM_C_3, 0x20},968 {WSA883X_CDC_SPK_DSM_R1, 0x83},969 {WSA883X_CDC_SPK_DSM_R2, 0x7F},970 {WSA883X_CDC_SPK_DSM_R3, 0x9D},971 {WSA883X_CDC_SPK_DSM_R4, 0x82},972 {WSA883X_CDC_SPK_DSM_R5, 0x8B},973 {WSA883X_CDC_SPK_DSM_R6, 0x9B},974 {WSA883X_CDC_SPK_DSM_R7, 0x3F},975 {WSA883X_VBAT_SNS, 0x20},976 {WSA883X_DRE_CTL_0, 0x92},977 {WSA883X_DRE_IDLE_DET_CTL, 0x0F},978 {WSA883X_CURRENT_LIMIT, 0xC4},979 {WSA883X_VAGC_TIME, 0x0F},980 {WSA883X_VAGC_ATTN_LVL_1_2, 0x00},981 {WSA883X_VAGC_ATTN_LVL_3, 0x01},982 {WSA883X_VAGC_CTL, 0x01},983 {WSA883X_TAGC_CTL, 0x1A},984 {WSA883X_TAGC_TIME, 0x2C},985 {WSA883X_TEMP_CONFIG0, 0x02},986 {WSA883X_TEMP_CONFIG1, 0x02},987 {WSA883X_OTP_REG_1, 0x49},988 {WSA883X_OTP_REG_2, 0x80},989 {WSA883X_OTP_REG_3, 0xC9},990 {WSA883X_OTP_REG_4, 0x40},991 {WSA883X_TAGC_CTL, 0x1B},992 {WSA883X_ADC_2, 0x00},993 {WSA883X_ADC_7, 0x85},994 {WSA883X_ADC_7, 0x87},995 {WSA883X_CKWD_CTL_0, 0x14},996 {WSA883X_CKWD_CTL_1, 0x1B},997 {WSA883X_GMAMP_SUP1, 0xE2},998};999 1000static int wsa883x_init(struct wsa883x_priv *wsa883x)1001{1002 struct regmap *regmap = wsa883x->regmap;1003 int variant, version, ret;1004 1005 ret = regmap_read(regmap, WSA883X_OTP_REG_0, &variant);1006 if (ret)1007 return ret;1008 variant = variant & WSA883X_ID_MASK;1009 1010 ret = regmap_read(regmap, WSA883X_CHIP_ID0, &version);1011 if (ret)1012 return ret;1013 1014 switch (variant) {1015 case WSA8830:1016 dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n",1017 version);1018 break;1019 case WSA8835:1020 dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n",1021 version);1022 break;1023 case WSA8832:1024 dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n",1025 version);1026 break;1027 case WSA8835_V2:1028 dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n",1029 version);1030 break;1031 default:1032 break;1033 }1034 1035 wsa883x->comp_offset = COMP_OFFSET2;1036 1037 /* Initial settings */1038 regmap_multi_reg_write(regmap, reg_init, ARRAY_SIZE(reg_init));1039 1040 if (variant == WSA8830 || variant == WSA8832) {1041 wsa883x->comp_offset = COMP_OFFSET3;1042 regmap_update_bits(regmap, WSA883X_DRE_CTL_0,1043 WSA883X_DRE_OFFSET_MASK,1044 wsa883x->comp_offset);1045 }1046 1047 return 0;1048}1049 1050static int wsa883x_update_status(struct sdw_slave *slave,1051 enum sdw_slave_status status)1052{1053 struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev);1054 1055 if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)1056 return wsa883x_init(wsa883x);1057 1058 return 0;1059}1060 1061static int wsa883x_port_prep(struct sdw_slave *slave,1062 struct sdw_prepare_ch *prepare_ch,1063 enum sdw_port_prep_ops state)1064{1065 struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev);1066 1067 if (state == SDW_OPS_PORT_POST_PREP)1068 wsa883x->port_prepared[prepare_ch->num - 1] = true;1069 else1070 wsa883x->port_prepared[prepare_ch->num - 1] = false;1071 1072 return 0;1073}1074 1075static const struct sdw_slave_ops wsa883x_slave_ops = {1076 .update_status = wsa883x_update_status,1077 .port_prep = wsa883x_port_prep,1078};1079 1080static int wsa_dev_mode_get(struct snd_kcontrol *kcontrol,1081 struct snd_ctl_elem_value *ucontrol)1082{1083 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1084 struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);1085 1086 ucontrol->value.enumerated.item[0] = wsa883x->dev_mode;1087 1088 return 0;1089}1090 1091static int wsa_dev_mode_put(struct snd_kcontrol *kcontrol,1092 struct snd_ctl_elem_value *ucontrol)1093{1094 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1095 struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);1096 1097 if (wsa883x->dev_mode == ucontrol->value.enumerated.item[0])1098 return 0;1099 1100 wsa883x->dev_mode = ucontrol->value.enumerated.item[0];1101 1102 return 1;1103}1104 1105static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(pa_gain,1106 0, 14, TLV_DB_SCALE_ITEM(-300, 0, 0),1107 15, 29, TLV_DB_SCALE_ITEM(-300, 150, 0),1108 30, 31, TLV_DB_SCALE_ITEM(1800, 0, 0),1109);1110 1111static int wsa883x_get_swr_port(struct snd_kcontrol *kcontrol,1112 struct snd_ctl_elem_value *ucontrol)1113{1114 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);1115 struct wsa883x_priv *data = snd_soc_component_get_drvdata(comp);1116 struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;1117 int portidx = mixer->reg;1118 1119 ucontrol->value.integer.value[0] = data->port_enable[portidx];1120 1121 return 0;1122}1123 1124static int wsa883x_set_swr_port(struct snd_kcontrol *kcontrol,1125 struct snd_ctl_elem_value *ucontrol)1126{1127 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);1128 struct wsa883x_priv *data = snd_soc_component_get_drvdata(comp);1129 struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;1130 int portidx = mixer->reg;1131 1132 if (ucontrol->value.integer.value[0]) {1133 if (data->port_enable[portidx])1134 return 0;1135 1136 data->port_enable[portidx] = true;1137 } else {1138 if (!data->port_enable[portidx])1139 return 0;1140 1141 data->port_enable[portidx] = false;1142 }1143 1144 return 1;1145}1146 1147static int wsa883x_get_comp_offset(struct snd_kcontrol *kcontrol,1148 struct snd_ctl_elem_value *ucontrol)1149{1150 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1151 struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);1152 1153 ucontrol->value.integer.value[0] = wsa883x->comp_offset;1154 1155 return 0;1156}1157 1158static int wsa883x_set_comp_offset(struct snd_kcontrol *kcontrol,1159 struct snd_ctl_elem_value *ucontrol)1160{1161 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1162 struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);1163 1164 if (wsa883x->comp_offset == ucontrol->value.integer.value[0])1165 return 0;1166 1167 wsa883x->comp_offset = ucontrol->value.integer.value[0];1168 1169 return 1;1170}1171 1172static int wsa883x_codec_probe(struct snd_soc_component *comp)1173{1174 struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(comp);1175 1176 snd_soc_component_init_regmap(comp, wsa883x->regmap);1177 1178 return 0;1179}1180 1181static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w,1182 struct snd_kcontrol *kcontrol, int event)1183{1184 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1185 struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);1186 1187 switch (event) {1188 case SND_SOC_DAPM_POST_PMU:1189 switch (wsa883x->dev_mode) {1190 case RECEIVER:1191 snd_soc_component_write_field(component, WSA883X_CDC_PATH_MODE,1192 WSA883X_RXD_MODE_MASK,1193 WSA883X_RXD_MODE_HIFI);1194 snd_soc_component_write_field(component, WSA883X_SPKR_PWM_CLK_CTL,1195 WSA883X_SPKR_PWM_FREQ_SEL_MASK,1196 WSA883X_SPKR_PWM_FREQ_F600KHZ);1197 snd_soc_component_write_field(component, WSA883X_DRE_CTL_0,1198 WSA883X_DRE_PROG_DELAY_MASK, 0x0);1199 break;1200 case SPEAKER:1201 snd_soc_component_write_field(component, WSA883X_CDC_PATH_MODE,1202 WSA883X_RXD_MODE_MASK,1203 WSA883X_RXD_MODE_NORMAL);1204 snd_soc_component_write_field(component, WSA883X_SPKR_PWM_CLK_CTL,1205 WSA883X_SPKR_PWM_FREQ_SEL_MASK,1206 WSA883X_SPKR_PWM_FREQ_F300KHZ);1207 snd_soc_component_write_field(component, WSA883X_DRE_CTL_0,1208 WSA883X_DRE_PROG_DELAY_MASK, 0x9);1209 break;1210 default:1211 break;1212 }1213 1214 if (wsa883x->port_enable[WSA883X_PORT_COMP])1215 snd_soc_component_write_field(component, WSA883X_DRE_CTL_0,1216 WSA883X_DRE_OFFSET_MASK,1217 wsa883x->comp_offset);1218 snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL,1219 WSA883X_VBAT_ADC_COEF_SEL_MASK,1220 WSA883X_VBAT_ADC_COEF_F_1DIV16);1221 snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL,1222 WSA883X_VBAT_ADC_FLT_EN_MASK, 0x1);1223 snd_soc_component_write_field(component, WSA883X_PDM_WD_CTL,1224 WSA883X_PDM_EN_MASK,1225 WSA883X_PDM_ENABLE);1226 1227 break;1228 case SND_SOC_DAPM_PRE_PMD:1229 snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL,1230 WSA883X_VBAT_ADC_FLT_EN_MASK, 0x0);1231 snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL,1232 WSA883X_VBAT_ADC_COEF_SEL_MASK,1233 WSA883X_VBAT_ADC_COEF_F_1DIV2);1234 snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL,1235 WSA883X_GLOBAL_PA_EN_MASK, 0);1236 snd_soc_component_write_field(component, WSA883X_PDM_WD_CTL,1237 WSA883X_PDM_EN_MASK, 0);1238 break;1239 }1240 return 0;1241}1242 1243static const struct snd_soc_dapm_widget wsa883x_dapm_widgets[] = {1244 SND_SOC_DAPM_INPUT("IN"),1245 SND_SOC_DAPM_SPK("SPKR", wsa883x_spkr_event),1246};1247 1248static const struct snd_kcontrol_new wsa883x_snd_controls[] = {1249 SOC_SINGLE_RANGE_TLV("PA Volume", WSA883X_DRE_CTL_1, 1,1250 0x0, 0x1f, 1, pa_gain),1251 SOC_ENUM_EXT("WSA MODE", wsa_dev_mode_enum,1252 wsa_dev_mode_get, wsa_dev_mode_put),1253 SOC_SINGLE_EXT("COMP Offset", SND_SOC_NOPM, 0, 4, 0,1254 wsa883x_get_comp_offset, wsa883x_set_comp_offset),1255 SOC_SINGLE_EXT("DAC Switch", WSA883X_PORT_DAC, 0, 1, 0,1256 wsa883x_get_swr_port, wsa883x_set_swr_port),1257 SOC_SINGLE_EXT("COMP Switch", WSA883X_PORT_COMP, 0, 1, 0,1258 wsa883x_get_swr_port, wsa883x_set_swr_port),1259 SOC_SINGLE_EXT("BOOST Switch", WSA883X_PORT_BOOST, 0, 1, 0,1260 wsa883x_get_swr_port, wsa883x_set_swr_port),1261 SOC_SINGLE_EXT("VISENSE Switch", WSA883X_PORT_VISENSE, 0, 1, 0,1262 wsa883x_get_swr_port, wsa883x_set_swr_port),1263};1264 1265static const struct snd_soc_dapm_route wsa883x_audio_map[] = {1266 {"SPKR", NULL, "IN"},1267};1268 1269static const struct snd_soc_component_driver wsa883x_component_drv = {1270 .name = "WSA883x",1271 .probe = wsa883x_codec_probe,1272 .controls = wsa883x_snd_controls,1273 .num_controls = ARRAY_SIZE(wsa883x_snd_controls),1274 .dapm_widgets = wsa883x_dapm_widgets,1275 .num_dapm_widgets = ARRAY_SIZE(wsa883x_dapm_widgets),1276 .dapm_routes = wsa883x_audio_map,1277 .num_dapm_routes = ARRAY_SIZE(wsa883x_audio_map),1278};1279 1280static int wsa883x_hw_params(struct snd_pcm_substream *substream,1281 struct snd_pcm_hw_params *params,1282 struct snd_soc_dai *dai)1283{1284 struct wsa883x_priv *wsa883x = dev_get_drvdata(dai->dev);1285 int i;1286 1287 wsa883x->active_ports = 0;1288 for (i = 0; i < WSA883X_MAX_SWR_PORTS; i++) {1289 if (!wsa883x->port_enable[i])1290 continue;1291 1292 wsa883x->port_config[wsa883x->active_ports] = wsa883x_pconfig[i];1293 wsa883x->active_ports++;1294 }1295 1296 wsa883x->sconfig.frame_rate = params_rate(params);1297 1298 return sdw_stream_add_slave(wsa883x->slave, &wsa883x->sconfig,1299 wsa883x->port_config, wsa883x->active_ports,1300 wsa883x->sruntime);1301}1302 1303static int wsa883x_hw_free(struct snd_pcm_substream *substream,1304 struct snd_soc_dai *dai)1305{1306 struct wsa883x_priv *wsa883x = dev_get_drvdata(dai->dev);1307 1308 sdw_stream_remove_slave(wsa883x->slave, wsa883x->sruntime);1309 1310 return 0;1311}1312 1313static int wsa883x_set_sdw_stream(struct snd_soc_dai *dai,1314 void *stream, int direction)1315{1316 struct wsa883x_priv *wsa883x = dev_get_drvdata(dai->dev);1317 1318 wsa883x->sruntime = stream;1319 1320 return 0;1321}1322 1323static int wsa883x_digital_mute(struct snd_soc_dai *dai, int mute, int stream)1324{1325 struct snd_soc_component *component = dai->component;1326 1327 if (mute) {1328 snd_soc_component_write_field(component, WSA883X_DRE_CTL_1,1329 WSA883X_DRE_GAIN_EN_MASK, 0);1330 snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL,1331 WSA883X_GLOBAL_PA_EN_MASK, 0);1332 1333 } else {1334 snd_soc_component_write_field(component, WSA883X_DRE_CTL_1,1335 WSA883X_DRE_GAIN_EN_MASK,1336 WSA883X_DRE_GAIN_FROM_CSR);1337 snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL,1338 WSA883X_GLOBAL_PA_EN_MASK,1339 WSA883X_GLOBAL_PA_ENABLE);1340 1341 }1342 1343 return 0;1344}1345 1346static const struct snd_soc_dai_ops wsa883x_dai_ops = {1347 .hw_params = wsa883x_hw_params,1348 .hw_free = wsa883x_hw_free,1349 .mute_stream = wsa883x_digital_mute,1350 .set_stream = wsa883x_set_sdw_stream,1351 .mute_unmute_on_trigger = true,1352};1353 1354static struct snd_soc_dai_driver wsa883x_dais[] = {1355 {1356 .name = "SPKR",1357 .playback = {1358 .stream_name = "SPKR Playback",1359 .rates = WSA883X_RATES | WSA883X_FRAC_RATES,1360 .formats = WSA883X_FORMATS,1361 .rate_min = 8000,1362 .rate_max = 352800,1363 .channels_min = 1,1364 .channels_max = 1,1365 },1366 .ops = &wsa883x_dai_ops,1367 },1368};1369 1370static int wsa883x_probe(struct sdw_slave *pdev,1371 const struct sdw_device_id *id)1372{1373 struct wsa883x_priv *wsa883x;1374 struct device *dev = &pdev->dev;1375 int ret;1376 1377 wsa883x = devm_kzalloc(dev, sizeof(*wsa883x), GFP_KERNEL);1378 if (!wsa883x)1379 return -ENOMEM;1380 1381 wsa883x->vdd = devm_regulator_get(dev, "vdd");1382 if (IS_ERR(wsa883x->vdd))1383 return dev_err_probe(dev, PTR_ERR(wsa883x->vdd),1384 "No vdd regulator found\n");1385 1386 ret = regulator_enable(wsa883x->vdd);1387 if (ret)1388 return dev_err_probe(dev, ret, "Failed to enable vdd regulator\n");1389 1390 wsa883x->sd_n = devm_gpiod_get_optional(dev, "powerdown",1391 GPIOD_FLAGS_BIT_NONEXCLUSIVE | GPIOD_OUT_HIGH);1392 if (IS_ERR(wsa883x->sd_n)) {1393 ret = dev_err_probe(dev, PTR_ERR(wsa883x->sd_n),1394 "Shutdown Control GPIO not found\n");1395 goto err;1396 }1397 1398 dev_set_drvdata(dev, wsa883x);1399 wsa883x->slave = pdev;1400 wsa883x->dev = dev;1401 wsa883x->sconfig.ch_count = 1;1402 wsa883x->sconfig.bps = 1;1403 wsa883x->sconfig.direction = SDW_DATA_DIR_RX;1404 wsa883x->sconfig.type = SDW_STREAM_PDM;1405 1406 /**1407 * Port map index starts with 0, however the data port for this codec1408 * are from index 11409 */1410 if (of_property_read_u32_array(dev->of_node, "qcom,port-mapping", &pdev->m_port_map[1],1411 WSA883X_MAX_SWR_PORTS))1412 dev_dbg(dev, "Static Port mapping not specified\n");1413 1414 pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS - 1, 0);1415 pdev->prop.simple_clk_stop_capable = true;1416 pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;1417 pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;1418 gpiod_direction_output(wsa883x->sd_n, 0);1419 1420 wsa883x->regmap = devm_regmap_init_sdw(pdev, &wsa883x_regmap_config);1421 if (IS_ERR(wsa883x->regmap)) {1422 gpiod_direction_output(wsa883x->sd_n, 1);1423 ret = dev_err_probe(dev, PTR_ERR(wsa883x->regmap),1424 "regmap_init failed\n");1425 goto err;1426 }1427 pm_runtime_set_autosuspend_delay(dev, 3000);1428 pm_runtime_use_autosuspend(dev);1429 pm_runtime_mark_last_busy(dev);1430 pm_runtime_set_active(dev);1431 pm_runtime_enable(dev);1432 1433 ret = devm_snd_soc_register_component(dev,1434 &wsa883x_component_drv,1435 wsa883x_dais,1436 ARRAY_SIZE(wsa883x_dais));1437err:1438 if (ret)1439 regulator_disable(wsa883x->vdd);1440 1441 return ret;1442 1443}1444 1445static int __maybe_unused wsa883x_runtime_suspend(struct device *dev)1446{1447 struct regmap *regmap = dev_get_regmap(dev, NULL);1448 1449 regcache_cache_only(regmap, true);1450 regcache_mark_dirty(regmap);1451 1452 return 0;1453}1454 1455static int __maybe_unused wsa883x_runtime_resume(struct device *dev)1456{1457 struct regmap *regmap = dev_get_regmap(dev, NULL);1458 1459 regcache_cache_only(regmap, false);1460 regcache_sync(regmap);1461 1462 return 0;1463}1464 1465static const struct dev_pm_ops wsa883x_pm_ops = {1466 SET_RUNTIME_PM_OPS(wsa883x_runtime_suspend, wsa883x_runtime_resume, NULL)1467};1468 1469static const struct sdw_device_id wsa883x_swr_id[] = {1470 SDW_SLAVE_ENTRY(0x0217, 0x0202, 0),1471 {},1472};1473 1474MODULE_DEVICE_TABLE(sdw, wsa883x_swr_id);1475 1476static struct sdw_driver wsa883x_codec_driver = {1477 .driver = {1478 .name = "wsa883x-codec",1479 .pm = &wsa883x_pm_ops,1480 .suppress_bind_attrs = true,1481 },1482 .probe = wsa883x_probe,1483 .ops = &wsa883x_slave_ops,1484 .id_table = wsa883x_swr_id,1485};1486 1487module_sdw_driver(wsa883x_codec_driver);1488 1489MODULE_DESCRIPTION("WSA883x codec driver");1490MODULE_LICENSE("GPL");1491