1138 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2// Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.3 4#include <linux/component.h>5#include <linux/device.h>6#include <linux/irq.h>7#include <linux/irqdomain.h>8#include <linux/kernel.h>9#include <linux/module.h>10#include <linux/of.h>11#include <linux/platform_device.h>12#include <linux/pm_runtime.h>13#include <linux/regmap.h>14#include <linux/slab.h>15#include <linux/soundwire/sdw.h>16#include <linux/soundwire/sdw_registers.h>17#include <linux/soundwire/sdw_type.h>18#include <sound/soc-dapm.h>19#include <sound/soc.h>20#include "wcd937x.h"21 22static const struct wcd937x_sdw_ch_info wcd937x_sdw_rx_ch_info[] = {23 WCD_SDW_CH(WCD937X_HPH_L, WCD937X_HPH_PORT, BIT(0)),24 WCD_SDW_CH(WCD937X_HPH_R, WCD937X_HPH_PORT, BIT(1)),25 WCD_SDW_CH(WCD937X_CLSH, WCD937X_CLSH_PORT, BIT(0)),26 WCD_SDW_CH(WCD937X_COMP_L, WCD937X_COMP_PORT, BIT(0)),27 WCD_SDW_CH(WCD937X_COMP_R, WCD937X_COMP_PORT, BIT(1)),28 WCD_SDW_CH(WCD937X_LO, WCD937X_LO_PORT, BIT(0)),29 WCD_SDW_CH(WCD937X_DSD_L, WCD937X_DSD_PORT, BIT(0)),30 WCD_SDW_CH(WCD937X_DSD_R, WCD937X_DSD_PORT, BIT(1)),31};32 33static const struct wcd937x_sdw_ch_info wcd937x_sdw_tx_ch_info[] = {34 WCD_SDW_CH(WCD937X_ADC1, WCD937X_ADC_1_PORT, BIT(0)),35 WCD_SDW_CH(WCD937X_ADC2, WCD937X_ADC_2_3_PORT, BIT(0)),36 WCD_SDW_CH(WCD937X_ADC3, WCD937X_ADC_2_3_PORT, BIT(0)),37 WCD_SDW_CH(WCD937X_DMIC0, WCD937X_DMIC_0_3_MBHC_PORT, BIT(0)),38 WCD_SDW_CH(WCD937X_DMIC1, WCD937X_DMIC_0_3_MBHC_PORT, BIT(1)),39 WCD_SDW_CH(WCD937X_MBHC, WCD937X_DMIC_0_3_MBHC_PORT, BIT(2)),40 WCD_SDW_CH(WCD937X_DMIC2, WCD937X_DMIC_0_3_MBHC_PORT, BIT(2)),41 WCD_SDW_CH(WCD937X_DMIC3, WCD937X_DMIC_0_3_MBHC_PORT, BIT(3)),42 WCD_SDW_CH(WCD937X_DMIC4, WCD937X_DMIC_4_6_PORT, BIT(0)),43 WCD_SDW_CH(WCD937X_DMIC5, WCD937X_DMIC_4_6_PORT, BIT(1)),44 WCD_SDW_CH(WCD937X_DMIC6, WCD937X_DMIC_4_6_PORT, BIT(2)),45};46 47static struct sdw_dpn_prop wcd937x_dpn_prop[WCD937X_MAX_SWR_PORTS] = {48 {49 .num = 1,50 .type = SDW_DPN_SIMPLE,51 .min_ch = 1,52 .max_ch = 8,53 .simple_ch_prep_sm = true,54 }, {55 .num = 2,56 .type = SDW_DPN_SIMPLE,57 .min_ch = 1,58 .max_ch = 4,59 .simple_ch_prep_sm = true,60 }, {61 .num = 3,62 .type = SDW_DPN_SIMPLE,63 .min_ch = 1,64 .max_ch = 4,65 .simple_ch_prep_sm = true,66 }, {67 .num = 4,68 .type = SDW_DPN_SIMPLE,69 .min_ch = 1,70 .max_ch = 4,71 .simple_ch_prep_sm = true,72 }, {73 .num = 5,74 .type = SDW_DPN_SIMPLE,75 .min_ch = 1,76 .max_ch = 4,77 .simple_ch_prep_sm = true,78 }79};80 81struct device *wcd937x_sdw_device_get(struct device_node *np)82{83 return bus_find_device_by_of_node(&sdw_bus_type, np);84}85EXPORT_SYMBOL_GPL(wcd937x_sdw_device_get);86 87int wcd937x_sdw_hw_params(struct wcd937x_sdw_priv *wcd,88 struct snd_pcm_substream *substream,89 struct snd_pcm_hw_params *params,90 struct snd_soc_dai *dai)91{92 struct sdw_port_config port_config[WCD937X_MAX_SWR_PORTS];93 unsigned long ch_mask;94 int i, j;95 96 wcd->sconfig.ch_count = 1;97 wcd->active_ports = 0;98 for (i = 0; i < WCD937X_MAX_SWR_PORTS; i++) {99 ch_mask = wcd->port_config[i].ch_mask;100 if (!ch_mask)101 continue;102 103 for_each_set_bit(j, &ch_mask, 4)104 wcd->sconfig.ch_count++;105 106 port_config[wcd->active_ports] = wcd->port_config[i];107 wcd->active_ports++;108 }109 110 wcd->sconfig.bps = 1;111 wcd->sconfig.frame_rate = params_rate(params);112 wcd->sconfig.direction = wcd->is_tx ? SDW_DATA_DIR_TX : SDW_DATA_DIR_RX;113 wcd->sconfig.type = SDW_STREAM_PCM;114 115 return sdw_stream_add_slave(wcd->sdev, &wcd->sconfig,116 &port_config[0], wcd->active_ports,117 wcd->sruntime);118}119EXPORT_SYMBOL_GPL(wcd937x_sdw_hw_params);120 121static int wcd9370_update_status(struct sdw_slave *slave, enum sdw_slave_status status)122{123 struct wcd937x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);124 125 if (wcd->regmap && status == SDW_SLAVE_ATTACHED) {126 /* Write out any cached changes that happened between probe and attach */127 regcache_cache_only(wcd->regmap, false);128 return regcache_sync(wcd->regmap);129 }130 131 return 0;132}133 134/*135 * Handle Soundwire out-of-band interrupt event by triggering136 * the first irq of the slave_irq irq domain, which then will137 * be handled by the regmap_irq threaded irq.138 * Looping is to ensure no interrupts were missed in the process.139 */140static int wcd9370_interrupt_callback(struct sdw_slave *slave,141 struct sdw_slave_intr_status *status)142{143 struct wcd937x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);144 struct irq_domain *slave_irq = wcd->slave_irq;145 u32 sts1, sts2, sts3;146 147 do {148 handle_nested_irq(irq_find_mapping(slave_irq, 0));149 regmap_read(wcd->regmap, WCD937X_DIGITAL_INTR_STATUS_0, &sts1);150 regmap_read(wcd->regmap, WCD937X_DIGITAL_INTR_STATUS_1, &sts2);151 regmap_read(wcd->regmap, WCD937X_DIGITAL_INTR_STATUS_2, &sts3);152 153 } while (sts1 || sts2 || sts3);154 155 return IRQ_HANDLED;156}157 158static const struct reg_default wcd937x_defaults[] = {159 /* Default values except for Read-Only & Volatile registers */160 { WCD937X_ANA_BIAS, 0x00 },161 { WCD937X_ANA_RX_SUPPLIES, 0x00 },162 { WCD937X_ANA_HPH, 0x0c },163 { WCD937X_ANA_EAR, 0x00 },164 { WCD937X_ANA_EAR_COMPANDER_CTL, 0x02 },165 { WCD937X_ANA_TX_CH1, 0x20 },166 { WCD937X_ANA_TX_CH2, 0x00 },167 { WCD937X_ANA_TX_CH3, 0x20 },168 { WCD937X_ANA_TX_CH3_HPF, 0x00 },169 { WCD937X_ANA_MICB1_MICB2_DSP_EN_LOGIC, 0x00 },170 { WCD937X_ANA_MICB3_DSP_EN_LOGIC, 0x00 },171 { WCD937X_ANA_MBHC_MECH, 0x39 },172 { WCD937X_ANA_MBHC_ELECT, 0x08 },173 { WCD937X_ANA_MBHC_ZDET, 0x00 },174 { WCD937X_ANA_MBHC_BTN0, 0x00 },175 { WCD937X_ANA_MBHC_BTN1, 0x10 },176 { WCD937X_ANA_MBHC_BTN2, 0x20 },177 { WCD937X_ANA_MBHC_BTN3, 0x30 },178 { WCD937X_ANA_MBHC_BTN4, 0x40 },179 { WCD937X_ANA_MBHC_BTN5, 0x50 },180 { WCD937X_ANA_MBHC_BTN6, 0x60 },181 { WCD937X_ANA_MBHC_BTN7, 0x70 },182 { WCD937X_ANA_MICB1, 0x10 },183 { WCD937X_ANA_MICB2, 0x10 },184 { WCD937X_ANA_MICB2_RAMP, 0x00 },185 { WCD937X_ANA_MICB3, 0x10 },186 { WCD937X_BIAS_CTL, 0x2a },187 { WCD937X_BIAS_VBG_FINE_ADJ, 0x55 },188 { WCD937X_LDOL_VDDCX_ADJUST, 0x01 },189 { WCD937X_LDOL_DISABLE_LDOL, 0x00 },190 { WCD937X_MBHC_CTL_CLK, 0x00 },191 { WCD937X_MBHC_CTL_ANA, 0x00 },192 { WCD937X_MBHC_CTL_SPARE_1, 0x00 },193 { WCD937X_MBHC_CTL_SPARE_2, 0x00 },194 { WCD937X_MBHC_CTL_BCS, 0x00 },195 { WCD937X_MBHC_TEST_CTL, 0x00 },196 { WCD937X_LDOH_MODE, 0x2b },197 { WCD937X_LDOH_BIAS, 0x68 },198 { WCD937X_LDOH_STB_LOADS, 0x00 },199 { WCD937X_LDOH_SLOWRAMP, 0x50 },200 { WCD937X_MICB1_TEST_CTL_1, 0x1a },201 { WCD937X_MICB1_TEST_CTL_2, 0x18 },202 { WCD937X_MICB1_TEST_CTL_3, 0xa4 },203 { WCD937X_MICB2_TEST_CTL_1, 0x1a },204 { WCD937X_MICB2_TEST_CTL_2, 0x18 },205 { WCD937X_MICB2_TEST_CTL_3, 0xa4 },206 { WCD937X_MICB3_TEST_CTL_1, 0x1a },207 { WCD937X_MICB3_TEST_CTL_2, 0x18 },208 { WCD937X_MICB3_TEST_CTL_3, 0xa4 },209 { WCD937X_TX_COM_ADC_VCM, 0x39 },210 { WCD937X_TX_COM_BIAS_ATEST, 0xc0 },211 { WCD937X_TX_COM_ADC_INT1_IB, 0x6f },212 { WCD937X_TX_COM_ADC_INT2_IB, 0x4f },213 { WCD937X_TX_COM_TXFE_DIV_CTL, 0x2e },214 { WCD937X_TX_COM_TXFE_DIV_START, 0x00 },215 { WCD937X_TX_COM_TXFE_DIV_STOP_9P6M, 0xc7 },216 { WCD937X_TX_COM_TXFE_DIV_STOP_12P288M, 0xff },217 { WCD937X_TX_1_2_TEST_EN, 0xcc },218 { WCD937X_TX_1_2_ADC_IB, 0x09 },219 { WCD937X_TX_1_2_ATEST_REFCTL, 0x0a },220 { WCD937X_TX_1_2_TEST_CTL, 0x38 },221 { WCD937X_TX_1_2_TEST_BLK_EN, 0xff },222 { WCD937X_TX_1_2_TXFE_CLKDIV, 0x00 },223 { WCD937X_TX_3_TEST_EN, 0xcc },224 { WCD937X_TX_3_ADC_IB, 0x09 },225 { WCD937X_TX_3_ATEST_REFCTL, 0x0a },226 { WCD937X_TX_3_TEST_CTL, 0x38 },227 { WCD937X_TX_3_TEST_BLK_EN, 0xff },228 { WCD937X_TX_3_TXFE_CLKDIV, 0x00 },229 { WCD937X_TX_3_SPARE_MONO, 0x00 },230 { WCD937X_CLASSH_MODE_1, 0x40 },231 { WCD937X_CLASSH_MODE_2, 0x3a },232 { WCD937X_CLASSH_MODE_3, 0x00 },233 { WCD937X_CLASSH_CTRL_VCL_1, 0x70 },234 { WCD937X_CLASSH_CTRL_VCL_2, 0x82 },235 { WCD937X_CLASSH_CTRL_CCL_1, 0x31 },236 { WCD937X_CLASSH_CTRL_CCL_2, 0x80 },237 { WCD937X_CLASSH_CTRL_CCL_3, 0x80 },238 { WCD937X_CLASSH_CTRL_CCL_4, 0x51 },239 { WCD937X_CLASSH_CTRL_CCL_5, 0x00 },240 { WCD937X_CLASSH_BUCK_TMUX_A_D, 0x00 },241 { WCD937X_CLASSH_BUCK_SW_DRV_CNTL, 0x77 },242 { WCD937X_CLASSH_SPARE, 0x00 },243 { WCD937X_FLYBACK_EN, 0x4e },244 { WCD937X_FLYBACK_VNEG_CTRL_1, 0x0b },245 { WCD937X_FLYBACK_VNEG_CTRL_2, 0x45 },246 { WCD937X_FLYBACK_VNEG_CTRL_3, 0x74 },247 { WCD937X_FLYBACK_VNEG_CTRL_4, 0x7f },248 { WCD937X_FLYBACK_VNEG_CTRL_5, 0x83 },249 { WCD937X_FLYBACK_VNEG_CTRL_6, 0x98 },250 { WCD937X_FLYBACK_VNEG_CTRL_7, 0xa9 },251 { WCD937X_FLYBACK_VNEG_CTRL_8, 0x68 },252 { WCD937X_FLYBACK_VNEG_CTRL_9, 0x64 },253 { WCD937X_FLYBACK_VNEGDAC_CTRL_1, 0xed },254 { WCD937X_FLYBACK_VNEGDAC_CTRL_2, 0xf0 },255 { WCD937X_FLYBACK_VNEGDAC_CTRL_3, 0xa6 },256 { WCD937X_FLYBACK_CTRL_1, 0x65 },257 { WCD937X_FLYBACK_TEST_CTL, 0x00 },258 { WCD937X_RX_AUX_SW_CTL, 0x00 },259 { WCD937X_RX_PA_AUX_IN_CONN, 0x00 },260 { WCD937X_RX_TIMER_DIV, 0x32 },261 { WCD937X_RX_OCP_CTL, 0x1f },262 { WCD937X_RX_OCP_COUNT, 0x77 },263 { WCD937X_RX_BIAS_EAR_DAC, 0xa0 },264 { WCD937X_RX_BIAS_EAR_AMP, 0xaa },265 { WCD937X_RX_BIAS_HPH_LDO, 0xa9 },266 { WCD937X_RX_BIAS_HPH_PA, 0xaa },267 { WCD937X_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8a },268 { WCD937X_RX_BIAS_HPH_RDAC_LDO, 0x88 },269 { WCD937X_RX_BIAS_HPH_CNP1, 0x82 },270 { WCD937X_RX_BIAS_HPH_LOWPOWER, 0x82 },271 { WCD937X_RX_BIAS_AUX_DAC, 0xa0 },272 { WCD937X_RX_BIAS_AUX_AMP, 0xaa },273 { WCD937X_RX_BIAS_VNEGDAC_BLEEDER, 0x50 },274 { WCD937X_RX_BIAS_MISC, 0x00 },275 { WCD937X_RX_BIAS_BUCK_RST, 0x08 },276 { WCD937X_RX_BIAS_BUCK_VREF_ERRAMP, 0x44 },277 { WCD937X_RX_BIAS_FLYB_ERRAMP, 0x40 },278 { WCD937X_RX_BIAS_FLYB_BUFF, 0xaa },279 { WCD937X_RX_BIAS_FLYB_MID_RST, 0x14 },280 { WCD937X_HPH_CNP_EN, 0x80 },281 { WCD937X_HPH_CNP_WG_CTL, 0x9a },282 { WCD937X_HPH_CNP_WG_TIME, 0x14 },283 { WCD937X_HPH_OCP_CTL, 0x28 },284 { WCD937X_HPH_AUTO_CHOP, 0x16 },285 { WCD937X_HPH_CHOP_CTL, 0x83 },286 { WCD937X_HPH_PA_CTL1, 0x46 },287 { WCD937X_HPH_PA_CTL2, 0x50 },288 { WCD937X_HPH_L_EN, 0x80 },289 { WCD937X_HPH_L_TEST, 0xe0 },290 { WCD937X_HPH_L_ATEST, 0x50 },291 { WCD937X_HPH_R_EN, 0x80 },292 { WCD937X_HPH_R_TEST, 0xe0 },293 { WCD937X_HPH_R_ATEST, 0x54 },294 { WCD937X_HPH_RDAC_CLK_CTL1, 0x99 },295 { WCD937X_HPH_RDAC_CLK_CTL2, 0x9b },296 { WCD937X_HPH_RDAC_LDO_CTL, 0x33 },297 { WCD937X_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00 },298 { WCD937X_HPH_REFBUFF_UHQA_CTL, 0xa8 },299 { WCD937X_HPH_REFBUFF_LP_CTL, 0x0e },300 { WCD937X_HPH_L_DAC_CTL, 0x20 },301 { WCD937X_HPH_R_DAC_CTL, 0x20 },302 { WCD937X_HPH_SURGE_HPHLR_SURGE_COMP_SEL, 0x55 },303 { WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0x19 },304 { WCD937X_HPH_SURGE_HPHLR_SURGE_MISC1, 0xa0 },305 { WCD937X_EAR_EAR_EN_REG, 0x22 },306 { WCD937X_EAR_EAR_PA_CON, 0x44 },307 { WCD937X_EAR_EAR_SP_CON, 0xdb },308 { WCD937X_EAR_EAR_DAC_CON, 0x80 },309 { WCD937X_EAR_EAR_CNP_FSM_CON, 0xb2 },310 { WCD937X_EAR_TEST_CTL, 0x00 },311 { WCD937X_ANA_NEW_PAGE_REGISTER, 0x00 },312 { WCD937X_HPH_NEW_ANA_HPH2, 0x00 },313 { WCD937X_HPH_NEW_ANA_HPH3, 0x00 },314 { WCD937X_SLEEP_CTL, 0x16 },315 { WCD937X_SLEEP_WATCHDOG_CTL, 0x00 },316 { WCD937X_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00 },317 { WCD937X_MBHC_NEW_CTL_1, 0x02 },318 { WCD937X_MBHC_NEW_CTL_2, 0x05 },319 { WCD937X_MBHC_NEW_PLUG_DETECT_CTL, 0xe9 },320 { WCD937X_MBHC_NEW_ZDET_ANA_CTL, 0x0f },321 { WCD937X_MBHC_NEW_ZDET_RAMP_CTL, 0x00 },322 { WCD937X_TX_NEW_TX_CH2_SEL, 0x00 },323 { WCD937X_AUX_AUXPA, 0x00 },324 { WCD937X_LDORXTX_MODE, 0x0c },325 { WCD937X_LDORXTX_CONFIG, 0x10 },326 { WCD937X_DIE_CRACK_DIE_CRK_DET_EN, 0x00 },327 { WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40 },328 { WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x81 },329 { WCD937X_HPH_NEW_INT_RDAC_VREF_CTL, 0x10 },330 { WCD937X_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00 },331 { WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x81 },332 { WCD937X_HPH_NEW_INT_PA_MISC1, 0x22 },333 { WCD937X_HPH_NEW_INT_PA_MISC2, 0x00 },334 { WCD937X_HPH_NEW_INT_PA_RDAC_MISC, 0x00 },335 { WCD937X_HPH_NEW_INT_HPH_TIMER1, 0xfe },336 { WCD937X_HPH_NEW_INT_HPH_TIMER2, 0x02 },337 { WCD937X_HPH_NEW_INT_HPH_TIMER3, 0x4e },338 { WCD937X_HPH_NEW_INT_HPH_TIMER4, 0x54 },339 { WCD937X_HPH_NEW_INT_PA_RDAC_MISC2, 0x00 },340 { WCD937X_HPH_NEW_INT_PA_RDAC_MISC3, 0x00 },341 { WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x62 },342 { WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01 },343 { WCD937X_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11 },344 { WCD937X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL, 0x57 },345 { WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x01 },346 { WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x00 },347 { WCD937X_MBHC_NEW_INT_SPARE_2, 0x00 },348 { WCD937X_EAR_INT_NEW_EAR_CHOPPER_CON, 0xa8 },349 { WCD937X_EAR_INT_NEW_CNP_VCM_CON1, 0x42 },350 { WCD937X_EAR_INT_NEW_CNP_VCM_CON2, 0x22 },351 { WCD937X_EAR_INT_NEW_EAR_DYNAMIC_BIAS, 0x00 },352 { WCD937X_AUX_INT_EN_REG, 0x00 },353 { WCD937X_AUX_INT_PA_CTRL, 0x06 },354 { WCD937X_AUX_INT_SP_CTRL, 0xd2 },355 { WCD937X_AUX_INT_DAC_CTRL, 0x80 },356 { WCD937X_AUX_INT_CLK_CTRL, 0x50 },357 { WCD937X_AUX_INT_TEST_CTRL, 0x00 },358 { WCD937X_AUX_INT_STATUS_REG, 0x00 },359 { WCD937X_AUX_INT_MISC, 0x00 },360 { WCD937X_LDORXTX_INT_BIAS, 0x6e },361 { WCD937X_LDORXTX_INT_STB_LOADS_DTEST, 0x50 },362 { WCD937X_LDORXTX_INT_TEST0, 0x1c },363 { WCD937X_LDORXTX_INT_STARTUP_TIMER, 0xff },364 { WCD937X_LDORXTX_INT_TEST1, 0x1f },365 { WCD937X_LDORXTX_INT_STATUS, 0x00 },366 { WCD937X_SLEEP_INT_WATCHDOG_CTL_1, 0x0a },367 { WCD937X_SLEEP_INT_WATCHDOG_CTL_2, 0x0a },368 { WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1, 0x02 },369 { WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2, 0x60 },370 { WCD937X_DIGITAL_PAGE_REGISTER, 0x00 },371 { WCD937X_DIGITAL_CDC_RST_CTL, 0x03 },372 { WCD937X_DIGITAL_TOP_CLK_CFG, 0x00 },373 { WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x00 },374 { WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x00 },375 { WCD937X_DIGITAL_SWR_RST_EN, 0x00 },376 { WCD937X_DIGITAL_CDC_PATH_MODE, 0x55 },377 { WCD937X_DIGITAL_CDC_RX_RST, 0x00 },378 { WCD937X_DIGITAL_CDC_RX0_CTL, 0xfc },379 { WCD937X_DIGITAL_CDC_RX1_CTL, 0xfc },380 { WCD937X_DIGITAL_CDC_RX2_CTL, 0xfc },381 { WCD937X_DIGITAL_DEM_BYPASS_DATA0, 0x55 },382 { WCD937X_DIGITAL_DEM_BYPASS_DATA1, 0x55 },383 { WCD937X_DIGITAL_DEM_BYPASS_DATA2, 0x55 },384 { WCD937X_DIGITAL_DEM_BYPASS_DATA3, 0x01 },385 { WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x00 },386 { WCD937X_DIGITAL_CDC_RX_DELAY_CTL, 0x66 },387 { WCD937X_DIGITAL_CDC_HPH_DSM_A1_0, 0x00 },388 { WCD937X_DIGITAL_CDC_HPH_DSM_A1_1, 0x01 },389 { WCD937X_DIGITAL_CDC_HPH_DSM_A2_0, 0x63 },390 { WCD937X_DIGITAL_CDC_HPH_DSM_A2_1, 0x04 },391 { WCD937X_DIGITAL_CDC_HPH_DSM_A3_0, 0xac },392 { WCD937X_DIGITAL_CDC_HPH_DSM_A3_1, 0x04 },393 { WCD937X_DIGITAL_CDC_HPH_DSM_A4_0, 0x1a },394 { WCD937X_DIGITAL_CDC_HPH_DSM_A4_1, 0x03 },395 { WCD937X_DIGITAL_CDC_HPH_DSM_A5_0, 0xbc },396 { WCD937X_DIGITAL_CDC_HPH_DSM_A5_1, 0x02 },397 { WCD937X_DIGITAL_CDC_HPH_DSM_A6_0, 0xc7 },398 { WCD937X_DIGITAL_CDC_HPH_DSM_A7_0, 0xf8 },399 { WCD937X_DIGITAL_CDC_HPH_DSM_C_0, 0x47 },400 { WCD937X_DIGITAL_CDC_HPH_DSM_C_1, 0x43 },401 { WCD937X_DIGITAL_CDC_HPH_DSM_C_2, 0xb1 },402 { WCD937X_DIGITAL_CDC_HPH_DSM_C_3, 0x17 },403 { WCD937X_DIGITAL_CDC_HPH_DSM_R1, 0x4b },404 { WCD937X_DIGITAL_CDC_HPH_DSM_R2, 0x26 },405 { WCD937X_DIGITAL_CDC_HPH_DSM_R3, 0x32 },406 { WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x57 },407 { WCD937X_DIGITAL_CDC_HPH_DSM_R5, 0x63 },408 { WCD937X_DIGITAL_CDC_HPH_DSM_R6, 0x7c },409 { WCD937X_DIGITAL_CDC_HPH_DSM_R7, 0x57 },410 { WCD937X_DIGITAL_CDC_AUX_DSM_A1_0, 0x00 },411 { WCD937X_DIGITAL_CDC_AUX_DSM_A1_1, 0x01 },412 { WCD937X_DIGITAL_CDC_AUX_DSM_A2_0, 0x96 },413 { WCD937X_DIGITAL_CDC_AUX_DSM_A2_1, 0x09 },414 { WCD937X_DIGITAL_CDC_AUX_DSM_A3_0, 0xab },415 { WCD937X_DIGITAL_CDC_AUX_DSM_A3_1, 0x05 },416 { WCD937X_DIGITAL_CDC_AUX_DSM_A4_0, 0x1c },417 { WCD937X_DIGITAL_CDC_AUX_DSM_A4_1, 0x02 },418 { WCD937X_DIGITAL_CDC_AUX_DSM_A5_0, 0x17 },419 { WCD937X_DIGITAL_CDC_AUX_DSM_A5_1, 0x02 },420 { WCD937X_DIGITAL_CDC_AUX_DSM_A6_0, 0xaa },421 { WCD937X_DIGITAL_CDC_AUX_DSM_A7_0, 0xe3 },422 { WCD937X_DIGITAL_CDC_AUX_DSM_C_0, 0x69 },423 { WCD937X_DIGITAL_CDC_AUX_DSM_C_1, 0x54 },424 { WCD937X_DIGITAL_CDC_AUX_DSM_C_2, 0x02 },425 { WCD937X_DIGITAL_CDC_AUX_DSM_C_3, 0x15 },426 { WCD937X_DIGITAL_CDC_AUX_DSM_R1, 0xa4 },427 { WCD937X_DIGITAL_CDC_AUX_DSM_R2, 0xb5 },428 { WCD937X_DIGITAL_CDC_AUX_DSM_R3, 0x86 },429 { WCD937X_DIGITAL_CDC_AUX_DSM_R4, 0x85 },430 { WCD937X_DIGITAL_CDC_AUX_DSM_R5, 0xaa },431 { WCD937X_DIGITAL_CDC_AUX_DSM_R6, 0xe2 },432 { WCD937X_DIGITAL_CDC_AUX_DSM_R7, 0x62 },433 { WCD937X_DIGITAL_CDC_HPH_GAIN_RX_0, 0x55 },434 { WCD937X_DIGITAL_CDC_HPH_GAIN_RX_1, 0xa9 },435 { WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_0, 0x3d },436 { WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_1, 0x2e },437 { WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_2, 0x01 },438 { WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_0, 0x00 },439 { WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_1, 0xfc },440 { WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_2, 0x01 },441 { WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, 0x00 },442 { WCD937X_DIGITAL_CDC_AUX_GAIN_CTL, 0x00 },443 { WCD937X_DIGITAL_CDC_EAR_PATH_CTL, 0x00 },444 { WCD937X_DIGITAL_CDC_SWR_CLH, 0x00 },445 { WCD937X_DIGITAL_SWR_CLH_BYP, 0x00 },446 { WCD937X_DIGITAL_CDC_TX0_CTL, 0x68 },447 { WCD937X_DIGITAL_CDC_TX1_CTL, 0x68 },448 { WCD937X_DIGITAL_CDC_TX2_CTL, 0x68 },449 { WCD937X_DIGITAL_CDC_TX_RST, 0x00 },450 { WCD937X_DIGITAL_CDC_REQ_CTL, 0x01 },451 { WCD937X_DIGITAL_CDC_AMIC_CTL, 0x07 },452 { WCD937X_DIGITAL_CDC_DMIC_CTL, 0x00 },453 { WCD937X_DIGITAL_CDC_DMIC1_CTL, 0x01 },454 { WCD937X_DIGITAL_CDC_DMIC2_CTL, 0x01 },455 { WCD937X_DIGITAL_CDC_DMIC3_CTL, 0x01 },456 { WCD937X_DIGITAL_EFUSE_CTL, 0x2b },457 { WCD937X_DIGITAL_EFUSE_PRG_CTL, 0x00 },458 { WCD937X_DIGITAL_EFUSE_TEST_CTL_0, 0x00 },459 { WCD937X_DIGITAL_EFUSE_TEST_CTL_1, 0x00 },460 { WCD937X_DIGITAL_PDM_WD_CTL0, 0x00 },461 { WCD937X_DIGITAL_PDM_WD_CTL1, 0x00 },462 { WCD937X_DIGITAL_PDM_WD_CTL2, 0x00 },463 { WCD937X_DIGITAL_INTR_MODE, 0x00 },464 { WCD937X_DIGITAL_INTR_MASK_0, 0xff },465 { WCD937X_DIGITAL_INTR_MASK_1, 0xff },466 { WCD937X_DIGITAL_INTR_MASK_2, 0x0f },467 { WCD937X_DIGITAL_INTR_CLEAR_0, 0x00 },468 { WCD937X_DIGITAL_INTR_CLEAR_1, 0x00 },469 { WCD937X_DIGITAL_INTR_CLEAR_2, 0x00 },470 { WCD937X_DIGITAL_INTR_LEVEL_0, 0x00 },471 { WCD937X_DIGITAL_INTR_LEVEL_1, 0x00 },472 { WCD937X_DIGITAL_INTR_LEVEL_2, 0x00 },473 { WCD937X_DIGITAL_INTR_SET_0, 0x00 },474 { WCD937X_DIGITAL_INTR_SET_1, 0x00 },475 { WCD937X_DIGITAL_INTR_SET_2, 0x00 },476 { WCD937X_DIGITAL_INTR_TEST_0, 0x00 },477 { WCD937X_DIGITAL_INTR_TEST_1, 0x00 },478 { WCD937X_DIGITAL_INTR_TEST_2, 0x00 },479 { WCD937X_DIGITAL_CDC_CONN_RX0_CTL, 0x00 },480 { WCD937X_DIGITAL_CDC_CONN_RX1_CTL, 0x00 },481 { WCD937X_DIGITAL_CDC_CONN_RX2_CTL, 0x00 },482 { WCD937X_DIGITAL_CDC_CONN_TX_CTL, 0x00 },483 { WCD937X_DIGITAL_LOOP_BACK_MODE, 0x00 },484 { WCD937X_DIGITAL_SWR_DAC_TEST, 0x00 },485 { WCD937X_DIGITAL_SWR_HM_TEST_RX_0, 0x40 },486 { WCD937X_DIGITAL_SWR_HM_TEST_TX_0, 0x40 },487 { WCD937X_DIGITAL_SWR_HM_TEST_RX_1, 0x00 },488 { WCD937X_DIGITAL_SWR_HM_TEST_TX_1, 0x00 },489 { WCD937X_DIGITAL_PAD_CTL_PDM_RX0, 0xf1 },490 { WCD937X_DIGITAL_PAD_CTL_PDM_RX1, 0xf1 },491 { WCD937X_DIGITAL_PAD_CTL_PDM_TX0, 0xf1 },492 { WCD937X_DIGITAL_PAD_CTL_PDM_TX1, 0xf1 },493 { WCD937X_DIGITAL_PAD_INP_DIS_0, 0x00 },494 { WCD937X_DIGITAL_PAD_INP_DIS_1, 0x00 },495 { WCD937X_DIGITAL_DRIVE_STRENGTH_0, 0x00 },496 { WCD937X_DIGITAL_DRIVE_STRENGTH_1, 0x00 },497 { WCD937X_DIGITAL_DRIVE_STRENGTH_2, 0x00 },498 { WCD937X_DIGITAL_RX_DATA_EDGE_CTL, 0x1f },499 { WCD937X_DIGITAL_TX_DATA_EDGE_CTL, 0x10 },500 { WCD937X_DIGITAL_GPIO_MODE, 0x00 },501 { WCD937X_DIGITAL_PIN_CTL_OE, 0x00 },502 { WCD937X_DIGITAL_PIN_CTL_DATA_0, 0x00 },503 { WCD937X_DIGITAL_PIN_CTL_DATA_1, 0x00 },504 { WCD937X_DIGITAL_DIG_DEBUG_CTL, 0x00 },505 { WCD937X_DIGITAL_DIG_DEBUG_EN, 0x00 },506 { WCD937X_DIGITAL_ANA_CSR_DBG_ADD, 0x00 },507 { WCD937X_DIGITAL_ANA_CSR_DBG_CTL, 0x48 },508 { WCD937X_DIGITAL_SSP_DBG, 0x00 },509 { WCD937X_DIGITAL_SPARE_0, 0x00 },510 { WCD937X_DIGITAL_SPARE_1, 0x00 },511 { WCD937X_DIGITAL_SPARE_2, 0x00 },512};513 514static bool wcd937x_rdwr_register(struct device *dev, unsigned int reg)515{516 switch (reg) {517 case WCD937X_ANA_BIAS:518 case WCD937X_ANA_RX_SUPPLIES:519 case WCD937X_ANA_HPH:520 case WCD937X_ANA_EAR:521 case WCD937X_ANA_EAR_COMPANDER_CTL:522 case WCD937X_ANA_TX_CH1:523 case WCD937X_ANA_TX_CH2:524 case WCD937X_ANA_TX_CH3:525 case WCD937X_ANA_TX_CH3_HPF:526 case WCD937X_ANA_MICB1_MICB2_DSP_EN_LOGIC:527 case WCD937X_ANA_MICB3_DSP_EN_LOGIC:528 case WCD937X_ANA_MBHC_MECH:529 case WCD937X_ANA_MBHC_ELECT:530 case WCD937X_ANA_MBHC_ZDET:531 case WCD937X_ANA_MBHC_BTN0:532 case WCD937X_ANA_MBHC_BTN1:533 case WCD937X_ANA_MBHC_BTN2:534 case WCD937X_ANA_MBHC_BTN3:535 case WCD937X_ANA_MBHC_BTN4:536 case WCD937X_ANA_MBHC_BTN5:537 case WCD937X_ANA_MBHC_BTN6:538 case WCD937X_ANA_MBHC_BTN7:539 case WCD937X_ANA_MICB1:540 case WCD937X_ANA_MICB2:541 case WCD937X_ANA_MICB2_RAMP:542 case WCD937X_ANA_MICB3:543 case WCD937X_BIAS_CTL:544 case WCD937X_BIAS_VBG_FINE_ADJ:545 case WCD937X_LDOL_VDDCX_ADJUST:546 case WCD937X_LDOL_DISABLE_LDOL:547 case WCD937X_MBHC_CTL_CLK:548 case WCD937X_MBHC_CTL_ANA:549 case WCD937X_MBHC_CTL_SPARE_1:550 case WCD937X_MBHC_CTL_SPARE_2:551 case WCD937X_MBHC_CTL_BCS:552 case WCD937X_MBHC_TEST_CTL:553 case WCD937X_LDOH_MODE:554 case WCD937X_LDOH_BIAS:555 case WCD937X_LDOH_STB_LOADS:556 case WCD937X_LDOH_SLOWRAMP:557 case WCD937X_MICB1_TEST_CTL_1:558 case WCD937X_MICB1_TEST_CTL_2:559 case WCD937X_MICB1_TEST_CTL_3:560 case WCD937X_MICB2_TEST_CTL_1:561 case WCD937X_MICB2_TEST_CTL_2:562 case WCD937X_MICB2_TEST_CTL_3:563 case WCD937X_MICB3_TEST_CTL_1:564 case WCD937X_MICB3_TEST_CTL_2:565 case WCD937X_MICB3_TEST_CTL_3:566 case WCD937X_TX_COM_ADC_VCM:567 case WCD937X_TX_COM_BIAS_ATEST:568 case WCD937X_TX_COM_ADC_INT1_IB:569 case WCD937X_TX_COM_ADC_INT2_IB:570 case WCD937X_TX_COM_TXFE_DIV_CTL:571 case WCD937X_TX_COM_TXFE_DIV_START:572 case WCD937X_TX_COM_TXFE_DIV_STOP_9P6M:573 case WCD937X_TX_COM_TXFE_DIV_STOP_12P288M:574 case WCD937X_TX_1_2_TEST_EN:575 case WCD937X_TX_1_2_ADC_IB:576 case WCD937X_TX_1_2_ATEST_REFCTL:577 case WCD937X_TX_1_2_TEST_CTL:578 case WCD937X_TX_1_2_TEST_BLK_EN:579 case WCD937X_TX_1_2_TXFE_CLKDIV:580 case WCD937X_TX_3_TEST_EN:581 case WCD937X_TX_3_ADC_IB:582 case WCD937X_TX_3_ATEST_REFCTL:583 case WCD937X_TX_3_TEST_CTL:584 case WCD937X_TX_3_TEST_BLK_EN:585 case WCD937X_TX_3_TXFE_CLKDIV:586 case WCD937X_CLASSH_MODE_1:587 case WCD937X_CLASSH_MODE_2:588 case WCD937X_CLASSH_MODE_3:589 case WCD937X_CLASSH_CTRL_VCL_1:590 case WCD937X_CLASSH_CTRL_VCL_2:591 case WCD937X_CLASSH_CTRL_CCL_1:592 case WCD937X_CLASSH_CTRL_CCL_2:593 case WCD937X_CLASSH_CTRL_CCL_3:594 case WCD937X_CLASSH_CTRL_CCL_4:595 case WCD937X_CLASSH_CTRL_CCL_5:596 case WCD937X_CLASSH_BUCK_TMUX_A_D:597 case WCD937X_CLASSH_BUCK_SW_DRV_CNTL:598 case WCD937X_CLASSH_SPARE:599 case WCD937X_FLYBACK_EN:600 case WCD937X_FLYBACK_VNEG_CTRL_1:601 case WCD937X_FLYBACK_VNEG_CTRL_2:602 case WCD937X_FLYBACK_VNEG_CTRL_3:603 case WCD937X_FLYBACK_VNEG_CTRL_4:604 case WCD937X_FLYBACK_VNEG_CTRL_5:605 case WCD937X_FLYBACK_VNEG_CTRL_6:606 case WCD937X_FLYBACK_VNEG_CTRL_7:607 case WCD937X_FLYBACK_VNEG_CTRL_8:608 case WCD937X_FLYBACK_VNEG_CTRL_9:609 case WCD937X_FLYBACK_VNEGDAC_CTRL_1:610 case WCD937X_FLYBACK_VNEGDAC_CTRL_2:611 case WCD937X_FLYBACK_VNEGDAC_CTRL_3:612 case WCD937X_FLYBACK_CTRL_1:613 case WCD937X_FLYBACK_TEST_CTL:614 case WCD937X_RX_AUX_SW_CTL:615 case WCD937X_RX_PA_AUX_IN_CONN:616 case WCD937X_RX_TIMER_DIV:617 case WCD937X_RX_OCP_CTL:618 case WCD937X_RX_OCP_COUNT:619 case WCD937X_RX_BIAS_EAR_DAC:620 case WCD937X_RX_BIAS_EAR_AMP:621 case WCD937X_RX_BIAS_HPH_LDO:622 case WCD937X_RX_BIAS_HPH_PA:623 case WCD937X_RX_BIAS_HPH_RDACBUFF_CNP2:624 case WCD937X_RX_BIAS_HPH_RDAC_LDO:625 case WCD937X_RX_BIAS_HPH_CNP1:626 case WCD937X_RX_BIAS_HPH_LOWPOWER:627 case WCD937X_RX_BIAS_AUX_DAC:628 case WCD937X_RX_BIAS_AUX_AMP:629 case WCD937X_RX_BIAS_VNEGDAC_BLEEDER:630 case WCD937X_RX_BIAS_MISC:631 case WCD937X_RX_BIAS_BUCK_RST:632 case WCD937X_RX_BIAS_BUCK_VREF_ERRAMP:633 case WCD937X_RX_BIAS_FLYB_ERRAMP:634 case WCD937X_RX_BIAS_FLYB_BUFF:635 case WCD937X_RX_BIAS_FLYB_MID_RST:636 case WCD937X_HPH_CNP_EN:637 case WCD937X_HPH_CNP_WG_CTL:638 case WCD937X_HPH_CNP_WG_TIME:639 case WCD937X_HPH_OCP_CTL:640 case WCD937X_HPH_AUTO_CHOP:641 case WCD937X_HPH_CHOP_CTL:642 case WCD937X_HPH_PA_CTL1:643 case WCD937X_HPH_PA_CTL2:644 case WCD937X_HPH_L_EN:645 case WCD937X_HPH_L_TEST:646 case WCD937X_HPH_L_ATEST:647 case WCD937X_HPH_R_EN:648 case WCD937X_HPH_R_TEST:649 case WCD937X_HPH_R_ATEST:650 case WCD937X_HPH_RDAC_CLK_CTL1:651 case WCD937X_HPH_RDAC_CLK_CTL2:652 case WCD937X_HPH_RDAC_LDO_CTL:653 case WCD937X_HPH_RDAC_CHOP_CLK_LP_CTL:654 case WCD937X_HPH_REFBUFF_UHQA_CTL:655 case WCD937X_HPH_REFBUFF_LP_CTL:656 case WCD937X_HPH_L_DAC_CTL:657 case WCD937X_HPH_R_DAC_CTL:658 case WCD937X_HPH_SURGE_HPHLR_SURGE_COMP_SEL:659 case WCD937X_HPH_SURGE_HPHLR_SURGE_EN:660 case WCD937X_HPH_SURGE_HPHLR_SURGE_MISC1:661 case WCD937X_EAR_EAR_EN_REG:662 case WCD937X_EAR_EAR_PA_CON:663 case WCD937X_EAR_EAR_SP_CON:664 case WCD937X_EAR_EAR_DAC_CON:665 case WCD937X_EAR_EAR_CNP_FSM_CON:666 case WCD937X_EAR_TEST_CTL:667 case WCD937X_HPH_NEW_ANA_HPH2:668 case WCD937X_HPH_NEW_ANA_HPH3:669 case WCD937X_SLEEP_CTL:670 case WCD937X_SLEEP_WATCHDOG_CTL:671 case WCD937X_MBHC_NEW_ELECT_REM_CLAMP_CTL:672 case WCD937X_MBHC_NEW_CTL_1:673 case WCD937X_MBHC_NEW_CTL_2:674 case WCD937X_MBHC_NEW_PLUG_DETECT_CTL:675 case WCD937X_MBHC_NEW_ZDET_ANA_CTL:676 case WCD937X_MBHC_NEW_ZDET_RAMP_CTL:677 case WCD937X_TX_NEW_TX_CH2_SEL:678 case WCD937X_AUX_AUXPA:679 case WCD937X_LDORXTX_MODE:680 case WCD937X_LDORXTX_CONFIG:681 case WCD937X_DIE_CRACK_DIE_CRK_DET_EN:682 case WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL:683 case WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L:684 case WCD937X_HPH_NEW_INT_RDAC_VREF_CTL:685 case WCD937X_HPH_NEW_INT_RDAC_OVERRIDE_CTL:686 case WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R:687 case WCD937X_HPH_NEW_INT_PA_MISC1:688 case WCD937X_HPH_NEW_INT_PA_MISC2:689 case WCD937X_HPH_NEW_INT_PA_RDAC_MISC:690 case WCD937X_HPH_NEW_INT_HPH_TIMER1:691 case WCD937X_HPH_NEW_INT_HPH_TIMER2:692 case WCD937X_HPH_NEW_INT_HPH_TIMER3:693 case WCD937X_HPH_NEW_INT_HPH_TIMER4:694 case WCD937X_HPH_NEW_INT_PA_RDAC_MISC2:695 case WCD937X_HPH_NEW_INT_PA_RDAC_MISC3:696 case WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI:697 case WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_ULP:698 case WCD937X_RX_NEW_INT_HPH_RDAC_LDO_LP:699 case WCD937X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL:700 case WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL:701 case WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT:702 case WCD937X_MBHC_NEW_INT_SPARE_2:703 case WCD937X_EAR_INT_NEW_EAR_CHOPPER_CON:704 case WCD937X_EAR_INT_NEW_CNP_VCM_CON1:705 case WCD937X_EAR_INT_NEW_CNP_VCM_CON2:706 case WCD937X_EAR_INT_NEW_EAR_DYNAMIC_BIAS:707 case WCD937X_AUX_INT_EN_REG:708 case WCD937X_AUX_INT_PA_CTRL:709 case WCD937X_AUX_INT_SP_CTRL:710 case WCD937X_AUX_INT_DAC_CTRL:711 case WCD937X_AUX_INT_CLK_CTRL:712 case WCD937X_AUX_INT_TEST_CTRL:713 case WCD937X_AUX_INT_MISC:714 case WCD937X_LDORXTX_INT_BIAS:715 case WCD937X_LDORXTX_INT_STB_LOADS_DTEST:716 case WCD937X_LDORXTX_INT_TEST0:717 case WCD937X_LDORXTX_INT_STARTUP_TIMER:718 case WCD937X_LDORXTX_INT_TEST1:719 case WCD937X_SLEEP_INT_WATCHDOG_CTL_1:720 case WCD937X_SLEEP_INT_WATCHDOG_CTL_2:721 case WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1:722 case WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2:723 case WCD937X_DIGITAL_CDC_RST_CTL:724 case WCD937X_DIGITAL_TOP_CLK_CFG:725 case WCD937X_DIGITAL_CDC_ANA_CLK_CTL:726 case WCD937X_DIGITAL_CDC_DIG_CLK_CTL:727 case WCD937X_DIGITAL_SWR_RST_EN:728 case WCD937X_DIGITAL_CDC_PATH_MODE:729 case WCD937X_DIGITAL_CDC_RX_RST:730 case WCD937X_DIGITAL_CDC_RX0_CTL:731 case WCD937X_DIGITAL_CDC_RX1_CTL:732 case WCD937X_DIGITAL_CDC_RX2_CTL:733 case WCD937X_DIGITAL_DEM_BYPASS_DATA0:734 case WCD937X_DIGITAL_DEM_BYPASS_DATA1:735 case WCD937X_DIGITAL_DEM_BYPASS_DATA2:736 case WCD937X_DIGITAL_DEM_BYPASS_DATA3:737 case WCD937X_DIGITAL_CDC_COMP_CTL_0:738 case WCD937X_DIGITAL_CDC_RX_DELAY_CTL:739 case WCD937X_DIGITAL_CDC_HPH_DSM_A1_0:740 case WCD937X_DIGITAL_CDC_HPH_DSM_A1_1:741 case WCD937X_DIGITAL_CDC_HPH_DSM_A2_0:742 case WCD937X_DIGITAL_CDC_HPH_DSM_A2_1:743 case WCD937X_DIGITAL_CDC_HPH_DSM_A3_0:744 case WCD937X_DIGITAL_CDC_HPH_DSM_A3_1:745 case WCD937X_DIGITAL_CDC_HPH_DSM_A4_0:746 case WCD937X_DIGITAL_CDC_HPH_DSM_A4_1:747 case WCD937X_DIGITAL_CDC_HPH_DSM_A5_0:748 case WCD937X_DIGITAL_CDC_HPH_DSM_A5_1:749 case WCD937X_DIGITAL_CDC_HPH_DSM_A6_0:750 case WCD937X_DIGITAL_CDC_HPH_DSM_A7_0:751 case WCD937X_DIGITAL_CDC_HPH_DSM_C_0:752 case WCD937X_DIGITAL_CDC_HPH_DSM_C_1:753 case WCD937X_DIGITAL_CDC_HPH_DSM_C_2:754 case WCD937X_DIGITAL_CDC_HPH_DSM_C_3:755 case WCD937X_DIGITAL_CDC_HPH_DSM_R1:756 case WCD937X_DIGITAL_CDC_HPH_DSM_R2:757 case WCD937X_DIGITAL_CDC_HPH_DSM_R3:758 case WCD937X_DIGITAL_CDC_HPH_DSM_R4:759 case WCD937X_DIGITAL_CDC_HPH_DSM_R5:760 case WCD937X_DIGITAL_CDC_HPH_DSM_R6:761 case WCD937X_DIGITAL_CDC_HPH_DSM_R7:762 case WCD937X_DIGITAL_CDC_AUX_DSM_A1_0:763 case WCD937X_DIGITAL_CDC_AUX_DSM_A1_1:764 case WCD937X_DIGITAL_CDC_AUX_DSM_A2_0:765 case WCD937X_DIGITAL_CDC_AUX_DSM_A2_1:766 case WCD937X_DIGITAL_CDC_AUX_DSM_A3_0:767 case WCD937X_DIGITAL_CDC_AUX_DSM_A3_1:768 case WCD937X_DIGITAL_CDC_AUX_DSM_A4_0:769 case WCD937X_DIGITAL_CDC_AUX_DSM_A4_1:770 case WCD937X_DIGITAL_CDC_AUX_DSM_A5_0:771 case WCD937X_DIGITAL_CDC_AUX_DSM_A5_1:772 case WCD937X_DIGITAL_CDC_AUX_DSM_A6_0:773 case WCD937X_DIGITAL_CDC_AUX_DSM_A7_0:774 case WCD937X_DIGITAL_CDC_AUX_DSM_C_0:775 case WCD937X_DIGITAL_CDC_AUX_DSM_C_1:776 case WCD937X_DIGITAL_CDC_AUX_DSM_C_2:777 case WCD937X_DIGITAL_CDC_AUX_DSM_C_3:778 case WCD937X_DIGITAL_CDC_AUX_DSM_R1:779 case WCD937X_DIGITAL_CDC_AUX_DSM_R2:780 case WCD937X_DIGITAL_CDC_AUX_DSM_R3:781 case WCD937X_DIGITAL_CDC_AUX_DSM_R4:782 case WCD937X_DIGITAL_CDC_AUX_DSM_R5:783 case WCD937X_DIGITAL_CDC_AUX_DSM_R6:784 case WCD937X_DIGITAL_CDC_AUX_DSM_R7:785 case WCD937X_DIGITAL_CDC_HPH_GAIN_RX_0:786 case WCD937X_DIGITAL_CDC_HPH_GAIN_RX_1:787 case WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_0:788 case WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_1:789 case WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_2:790 case WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_0:791 case WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_1:792 case WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_2:793 case WCD937X_DIGITAL_CDC_HPH_GAIN_CTL:794 case WCD937X_DIGITAL_CDC_AUX_GAIN_CTL:795 case WCD937X_DIGITAL_CDC_EAR_PATH_CTL:796 case WCD937X_DIGITAL_CDC_SWR_CLH:797 case WCD937X_DIGITAL_SWR_CLH_BYP:798 case WCD937X_DIGITAL_CDC_TX0_CTL:799 case WCD937X_DIGITAL_CDC_TX1_CTL:800 case WCD937X_DIGITAL_CDC_TX2_CTL:801 case WCD937X_DIGITAL_CDC_TX_RST:802 case WCD937X_DIGITAL_CDC_REQ_CTL:803 case WCD937X_DIGITAL_CDC_AMIC_CTL:804 case WCD937X_DIGITAL_CDC_DMIC_CTL:805 case WCD937X_DIGITAL_CDC_DMIC1_CTL:806 case WCD937X_DIGITAL_CDC_DMIC2_CTL:807 case WCD937X_DIGITAL_CDC_DMIC3_CTL:808 case WCD937X_DIGITAL_EFUSE_CTL:809 case WCD937X_DIGITAL_EFUSE_PRG_CTL:810 case WCD937X_DIGITAL_EFUSE_TEST_CTL_0:811 case WCD937X_DIGITAL_EFUSE_TEST_CTL_1:812 case WCD937X_DIGITAL_PDM_WD_CTL0:813 case WCD937X_DIGITAL_PDM_WD_CTL1:814 case WCD937X_DIGITAL_PDM_WD_CTL2:815 case WCD937X_DIGITAL_INTR_MODE:816 case WCD937X_DIGITAL_INTR_MASK_0:817 case WCD937X_DIGITAL_INTR_MASK_1:818 case WCD937X_DIGITAL_INTR_MASK_2:819 case WCD937X_DIGITAL_INTR_CLEAR_0:820 case WCD937X_DIGITAL_INTR_CLEAR_1:821 case WCD937X_DIGITAL_INTR_CLEAR_2:822 case WCD937X_DIGITAL_INTR_LEVEL_0:823 case WCD937X_DIGITAL_INTR_LEVEL_1:824 case WCD937X_DIGITAL_INTR_LEVEL_2:825 case WCD937X_DIGITAL_INTR_SET_0:826 case WCD937X_DIGITAL_INTR_SET_1:827 case WCD937X_DIGITAL_INTR_SET_2:828 case WCD937X_DIGITAL_INTR_TEST_0:829 case WCD937X_DIGITAL_INTR_TEST_1:830 case WCD937X_DIGITAL_INTR_TEST_2:831 case WCD937X_DIGITAL_CDC_CONN_RX0_CTL:832 case WCD937X_DIGITAL_CDC_CONN_RX1_CTL:833 case WCD937X_DIGITAL_CDC_CONN_RX2_CTL:834 case WCD937X_DIGITAL_CDC_CONN_TX_CTL:835 case WCD937X_DIGITAL_LOOP_BACK_MODE:836 case WCD937X_DIGITAL_SWR_DAC_TEST:837 case WCD937X_DIGITAL_SWR_HM_TEST_RX_0:838 case WCD937X_DIGITAL_SWR_HM_TEST_TX_0:839 case WCD937X_DIGITAL_SWR_HM_TEST_RX_1:840 case WCD937X_DIGITAL_SWR_HM_TEST_TX_1:841 case WCD937X_DIGITAL_SWR_HM_TEST:842 case WCD937X_DIGITAL_PAD_CTL_PDM_RX0:843 case WCD937X_DIGITAL_PAD_CTL_PDM_RX1:844 case WCD937X_DIGITAL_PAD_CTL_PDM_TX0:845 case WCD937X_DIGITAL_PAD_CTL_PDM_TX1:846 case WCD937X_DIGITAL_PAD_INP_DIS_0:847 case WCD937X_DIGITAL_PAD_INP_DIS_1:848 case WCD937X_DIGITAL_DRIVE_STRENGTH_0:849 case WCD937X_DIGITAL_DRIVE_STRENGTH_1:850 case WCD937X_DIGITAL_DRIVE_STRENGTH_2:851 case WCD937X_DIGITAL_RX_DATA_EDGE_CTL:852 case WCD937X_DIGITAL_TX_DATA_EDGE_CTL:853 case WCD937X_DIGITAL_GPIO_MODE:854 case WCD937X_DIGITAL_PIN_CTL_OE:855 case WCD937X_DIGITAL_PIN_CTL_DATA_0:856 case WCD937X_DIGITAL_PIN_CTL_DATA_1:857 case WCD937X_DIGITAL_PIN_STATUS_0:858 case WCD937X_DIGITAL_PIN_STATUS_1:859 case WCD937X_DIGITAL_DIG_DEBUG_CTL:860 case WCD937X_DIGITAL_DIG_DEBUG_EN:861 case WCD937X_DIGITAL_ANA_CSR_DBG_ADD:862 case WCD937X_DIGITAL_ANA_CSR_DBG_CTL:863 case WCD937X_DIGITAL_SSP_DBG:864 case WCD937X_DIGITAL_MODE_STATUS_0:865 case WCD937X_DIGITAL_MODE_STATUS_1:866 case WCD937X_DIGITAL_SPARE_0:867 case WCD937X_DIGITAL_SPARE_1:868 case WCD937X_DIGITAL_SPARE_2:869 return true;870 }871 872 return false;873}874 875static bool wcd937x_readable_register(struct device *dev, unsigned int reg)876{877 switch (reg) {878 case WCD937X_ANA_MBHC_RESULT_1:879 case WCD937X_ANA_MBHC_RESULT_2:880 case WCD937X_ANA_MBHC_RESULT_3:881 case WCD937X_MBHC_MOISTURE_DET_FSM_STATUS:882 case WCD937X_TX_1_2_SAR2_ERR:883 case WCD937X_TX_1_2_SAR1_ERR:884 case WCD937X_TX_3_SPARE_MONO:885 case WCD937X_TX_3_SAR1_ERR:886 case WCD937X_HPH_L_STATUS:887 case WCD937X_HPH_R_STATUS:888 case WCD937X_HPH_SURGE_HPHLR_SURGE_STATUS:889 case WCD937X_EAR_STATUS_REG_1:890 case WCD937X_EAR_STATUS_REG_2:891 case WCD937X_MBHC_NEW_FSM_STATUS:892 case WCD937X_MBHC_NEW_ADC_RESULT:893 case WCD937X_DIE_CRACK_DIE_CRK_DET_OUT:894 case WCD937X_AUX_INT_STATUS_REG:895 case WCD937X_LDORXTX_INT_STATUS:896 case WCD937X_DIGITAL_CHIP_ID0:897 case WCD937X_DIGITAL_CHIP_ID1:898 case WCD937X_DIGITAL_CHIP_ID2:899 case WCD937X_DIGITAL_CHIP_ID3:900 case WCD937X_DIGITAL_EFUSE_T_DATA_0:901 case WCD937X_DIGITAL_EFUSE_T_DATA_1:902 case WCD937X_DIGITAL_INTR_STATUS_0:903 case WCD937X_DIGITAL_INTR_STATUS_1:904 case WCD937X_DIGITAL_INTR_STATUS_2:905 case WCD937X_DIGITAL_EFUSE_REG_0:906 case WCD937X_DIGITAL_EFUSE_REG_1:907 case WCD937X_DIGITAL_EFUSE_REG_2:908 case WCD937X_DIGITAL_EFUSE_REG_3:909 case WCD937X_DIGITAL_EFUSE_REG_4:910 case WCD937X_DIGITAL_EFUSE_REG_5:911 case WCD937X_DIGITAL_EFUSE_REG_6:912 case WCD937X_DIGITAL_EFUSE_REG_7:913 case WCD937X_DIGITAL_EFUSE_REG_8:914 case WCD937X_DIGITAL_EFUSE_REG_9:915 case WCD937X_DIGITAL_EFUSE_REG_10:916 case WCD937X_DIGITAL_EFUSE_REG_11:917 case WCD937X_DIGITAL_EFUSE_REG_12:918 case WCD937X_DIGITAL_EFUSE_REG_13:919 case WCD937X_DIGITAL_EFUSE_REG_14:920 case WCD937X_DIGITAL_EFUSE_REG_15:921 case WCD937X_DIGITAL_EFUSE_REG_16:922 case WCD937X_DIGITAL_EFUSE_REG_17:923 case WCD937X_DIGITAL_EFUSE_REG_18:924 case WCD937X_DIGITAL_EFUSE_REG_19:925 case WCD937X_DIGITAL_EFUSE_REG_20:926 case WCD937X_DIGITAL_EFUSE_REG_21:927 case WCD937X_DIGITAL_EFUSE_REG_22:928 case WCD937X_DIGITAL_EFUSE_REG_23:929 case WCD937X_DIGITAL_EFUSE_REG_24:930 case WCD937X_DIGITAL_EFUSE_REG_25:931 case WCD937X_DIGITAL_EFUSE_REG_26:932 case WCD937X_DIGITAL_EFUSE_REG_27:933 case WCD937X_DIGITAL_EFUSE_REG_28:934 case WCD937X_DIGITAL_EFUSE_REG_29:935 case WCD937X_DIGITAL_EFUSE_REG_30:936 case WCD937X_DIGITAL_EFUSE_REG_31:937 return true;938 }939 940 return wcd937x_rdwr_register(dev, reg);941}942 943static bool wcd937x_volatile_register(struct device *dev, unsigned int reg)944{945 switch (reg) {946 case WCD937X_ANA_MBHC_RESULT_1:947 case WCD937X_ANA_MBHC_RESULT_2:948 case WCD937X_ANA_MBHC_RESULT_3:949 case WCD937X_MBHC_MOISTURE_DET_FSM_STATUS:950 case WCD937X_TX_1_2_SAR1_ERR:951 case WCD937X_TX_1_2_SAR2_ERR:952 case WCD937X_TX_3_SAR1_ERR:953 case WCD937X_HPH_L_STATUS:954 case WCD937X_HPH_R_STATUS:955 case WCD937X_HPH_SURGE_HPHLR_SURGE_STATUS:956 case WCD937X_EAR_STATUS_REG_1:957 case WCD937X_EAR_STATUS_REG_2:958 case WCD937X_MBHC_NEW_FSM_STATUS:959 case WCD937X_MBHC_NEW_ADC_RESULT:960 case WCD937X_DIE_CRACK_DIE_CRK_DET_OUT:961 case WCD937X_DIGITAL_INTR_STATUS_0:962 case WCD937X_DIGITAL_INTR_STATUS_1:963 case WCD937X_DIGITAL_INTR_STATUS_2:964 case WCD937X_DIGITAL_SWR_HM_TEST:965 case WCD937X_DIGITAL_PIN_STATUS_0:966 case WCD937X_DIGITAL_PIN_STATUS_1:967 case WCD937X_DIGITAL_MODE_STATUS_0:968 case WCD937X_DIGITAL_MODE_STATUS_1:969 return true;970 }971 return false;972}973 974static const struct regmap_config wcd937x_regmap_config = {975 .name = "wcd937x_csr",976 .reg_bits = 32,977 .val_bits = 8,978 .cache_type = REGCACHE_MAPLE,979 .reg_defaults = wcd937x_defaults,980 .num_reg_defaults = ARRAY_SIZE(wcd937x_defaults),981 .max_register = WCD937X_MAX_REGISTER,982 .readable_reg = wcd937x_readable_register,983 .writeable_reg = wcd937x_rdwr_register,984 .volatile_reg = wcd937x_volatile_register,985};986 987static const struct sdw_slave_ops wcd9370_slave_ops = {988 .update_status = wcd9370_update_status,989 .interrupt_callback = wcd9370_interrupt_callback,990};991 992static int wcd937x_sdw_component_bind(struct device *dev,993 struct device *master, void *data)994{995 pm_runtime_set_autosuspend_delay(dev, 3000);996 pm_runtime_use_autosuspend(dev);997 pm_runtime_mark_last_busy(dev);998 pm_runtime_set_active(dev);999 pm_runtime_enable(dev);1000 1001 return 0;1002}1003 1004static void wcd937x_sdw_component_unbind(struct device *dev,1005 struct device *master, void *data)1006{1007 pm_runtime_disable(dev);1008 pm_runtime_set_suspended(dev);1009 pm_runtime_dont_use_autosuspend(dev);1010}1011 1012static const struct component_ops wcd937x_sdw_component_ops = {1013 .bind = wcd937x_sdw_component_bind,1014 .unbind = wcd937x_sdw_component_unbind,1015};1016 1017static int wcd9370_probe(struct sdw_slave *pdev,1018 const struct sdw_device_id *id)1019{1020 struct device *dev = &pdev->dev;1021 struct wcd937x_sdw_priv *wcd;1022 int ret;1023 1024 wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);1025 if (!wcd)1026 return -ENOMEM;1027 1028 /* Port map index starts at 0, however the data port for this codec start at index 1 */1029 if (of_property_read_bool(dev->of_node, "qcom,tx-port-mapping")) {1030 wcd->is_tx = true;1031 ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping",1032 &pdev->m_port_map[1],1033 WCD937X_MAX_TX_SWR_PORTS);1034 } else {1035 ret = of_property_read_u32_array(dev->of_node, "qcom,rx-port-mapping",1036 &pdev->m_port_map[1],1037 WCD937X_MAX_SWR_PORTS);1038 }1039 if (ret < 0)1040 dev_info(dev, "Error getting static port mapping for %s (%d)\n",1041 wcd->is_tx ? "TX" : "RX", ret);1042 1043 wcd->sdev = pdev;1044 dev_set_drvdata(dev, wcd);1045 1046 pdev->prop.scp_int1_mask = SDW_SCP_INT1_IMPL_DEF |1047 SDW_SCP_INT1_BUS_CLASH |1048 SDW_SCP_INT1_PARITY;1049 pdev->prop.lane_control_support = true;1050 pdev->prop.simple_clk_stop_capable = true;1051 if (wcd->is_tx) {1052 pdev->prop.source_ports = GENMASK(WCD937X_MAX_TX_SWR_PORTS - 1, 0);1053 pdev->prop.src_dpn_prop = wcd937x_dpn_prop;1054 wcd->ch_info = &wcd937x_sdw_tx_ch_info[0];1055 pdev->prop.wake_capable = true;1056 1057 wcd->regmap = devm_regmap_init_sdw(pdev, &wcd937x_regmap_config);1058 if (IS_ERR(wcd->regmap))1059 return dev_err_probe(dev, PTR_ERR(wcd->regmap),1060 "Regmap init failed\n");1061 1062 /* Start in cache-only until device is enumerated */1063 regcache_cache_only(wcd->regmap, true);1064 } else {1065 pdev->prop.sink_ports = GENMASK(WCD937X_MAX_SWR_PORTS - 1, 0);1066 pdev->prop.sink_dpn_prop = wcd937x_dpn_prop;1067 wcd->ch_info = &wcd937x_sdw_rx_ch_info[0];1068 }1069 1070 1071 ret = component_add(dev, &wcd937x_sdw_component_ops);1072 if (ret)1073 return ret;1074 1075 /* Set suspended until aggregate device is bind */1076 pm_runtime_set_suspended(dev);1077 1078 return 0;1079}1080 1081static int wcd9370_remove(struct sdw_slave *pdev)1082{1083 struct device *dev = &pdev->dev;1084 1085 component_del(dev, &wcd937x_sdw_component_ops);1086 1087 return 0;1088}1089 1090static const struct sdw_device_id wcd9370_slave_id[] = {1091 SDW_SLAVE_ENTRY(0x0217, 0x10a, 0), /* WCD9370 RX/TX Device ID */1092 { },1093};1094MODULE_DEVICE_TABLE(sdw, wcd9370_slave_id);1095 1096static int __maybe_unused wcd937x_sdw_runtime_suspend(struct device *dev)1097{1098 struct wcd937x_sdw_priv *wcd = dev_get_drvdata(dev);1099 1100 if (wcd->regmap) {1101 regcache_cache_only(wcd->regmap, true);1102 regcache_mark_dirty(wcd->regmap);1103 }1104 1105 return 0;1106}1107 1108static int __maybe_unused wcd937x_sdw_runtime_resume(struct device *dev)1109{1110 struct wcd937x_sdw_priv *wcd = dev_get_drvdata(dev);1111 1112 if (wcd->regmap) {1113 regcache_cache_only(wcd->regmap, false);1114 regcache_sync(wcd->regmap);1115 }1116 1117 return 0;1118}1119 1120static const struct dev_pm_ops wcd937x_sdw_pm_ops = {1121 SET_RUNTIME_PM_OPS(wcd937x_sdw_runtime_suspend, wcd937x_sdw_runtime_resume, NULL)1122};1123 1124static struct sdw_driver wcd9370_codec_driver = {1125 .probe = wcd9370_probe,1126 .remove = wcd9370_remove,1127 .ops = &wcd9370_slave_ops,1128 .id_table = wcd9370_slave_id,1129 .driver = {1130 .name = "wcd9370-codec",1131 .pm = &wcd937x_sdw_pm_ops,1132 }1133};1134module_sdw_driver(wcd9370_codec_driver);1135 1136MODULE_DESCRIPTION("WCD937X SDW codec driver");1137MODULE_LICENSE("GPL");1138