brintos

brintos / linux-shallow public Read only

0
0
Text · 51.6 KiB · c781da4 Raw
1747 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2// Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.3 4#include <linux/clk.h>5#include <linux/clk-provider.h>6#include <linux/init.h>7#include <linux/io.h>8#include <linux/module.h>9#include <linux/of_clk.h>10#include <linux/of_platform.h>11#include <linux/platform_device.h>12#include <linux/pm_runtime.h>13#include <linux/regmap.h>14#include <linux/regulator/consumer.h>15#include <sound/soc.h>16#include <sound/soc-dapm.h>17#include <sound/tlv.h>18 19#include "lpass-macro-common.h"20 21/* VA macro registers */22#define CDC_VA_CLK_RST_CTRL_MCLK_CONTROL	(0x0000)23#define CDC_VA_MCLK_CONTROL_EN			BIT(0)24#define CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL	(0x0004)25#define CDC_VA_FS_CONTROL_EN			BIT(0)26#define CDC_VA_FS_COUNTER_CLR			BIT(1)27#define CDC_VA_CLK_RST_CTRL_SWR_CONTROL		(0x0008)28#define CDC_VA_SWR_RESET_MASK		BIT(1)29#define CDC_VA_SWR_RESET_ENABLE		BIT(1)30#define CDC_VA_SWR_CLK_EN_MASK		BIT(0)31#define CDC_VA_SWR_CLK_ENABLE		BIT(0)32#define CDC_VA_TOP_CSR_TOP_CFG0			(0x0080)33#define CDC_VA_FS_BROADCAST_EN			BIT(1)34#define CDC_VA_TOP_CSR_DMIC0_CTL		(0x0084)35#define CDC_VA_TOP_CSR_DMIC1_CTL		(0x0088)36#define CDC_VA_TOP_CSR_DMIC2_CTL		(0x008C)37#define CDC_VA_TOP_CSR_DMIC3_CTL		(0x0090)38#define CDC_VA_DMIC_EN_MASK			BIT(0)39#define CDC_VA_DMIC_ENABLE			BIT(0)40#define CDC_VA_DMIC_CLK_SEL_MASK		GENMASK(3, 1)41#define CDC_VA_DMIC_CLK_SEL_SHFT		142#define CDC_VA_DMIC_CLK_SEL_DIV0		0x043#define CDC_VA_DMIC_CLK_SEL_DIV1		0x244#define CDC_VA_DMIC_CLK_SEL_DIV2		0x445#define CDC_VA_DMIC_CLK_SEL_DIV3		0x646#define CDC_VA_DMIC_CLK_SEL_DIV4		0x847#define CDC_VA_DMIC_CLK_SEL_DIV5		0xa48#define CDC_VA_TOP_CSR_DMIC_CFG			(0x0094)49#define CDC_VA_RESET_ALL_DMICS_MASK		BIT(7)50#define CDC_VA_RESET_ALL_DMICS_RESET		BIT(7)51#define CDC_VA_RESET_ALL_DMICS_DISABLE		052#define CDC_VA_DMIC3_FREQ_CHANGE_MASK		BIT(3)53#define CDC_VA_DMIC3_FREQ_CHANGE_EN		BIT(3)54#define CDC_VA_DMIC2_FREQ_CHANGE_MASK		BIT(2)55#define CDC_VA_DMIC2_FREQ_CHANGE_EN		BIT(2)56#define CDC_VA_DMIC1_FREQ_CHANGE_MASK		BIT(1)57#define CDC_VA_DMIC1_FREQ_CHANGE_EN		BIT(1)58#define CDC_VA_DMIC0_FREQ_CHANGE_MASK		BIT(0)59#define CDC_VA_DMIC0_FREQ_CHANGE_EN		BIT(0)60#define CDC_VA_DMIC_FREQ_CHANGE_DISABLE		061#define CDC_VA_TOP_CSR_DEBUG_BUS		(0x009C)62#define CDC_VA_TOP_CSR_DEBUG_EN			(0x00A0)63#define CDC_VA_TOP_CSR_TX_I2S_CTL		(0x00A4)64#define CDC_VA_TOP_CSR_I2S_CLK			(0x00A8)65#define CDC_VA_TOP_CSR_I2S_RESET		(0x00AC)66#define CDC_VA_TOP_CSR_CORE_ID_0		(0x00C0)67#define CDC_VA_TOP_CSR_CORE_ID_1		(0x00C4)68#define CDC_VA_TOP_CSR_CORE_ID_2		(0x00C8)69#define CDC_VA_TOP_CSR_CORE_ID_3		(0x00CC)70#define CDC_VA_TOP_CSR_SWR_MIC_CTL0		(0x00D0)71#define CDC_VA_TOP_CSR_SWR_MIC_CTL1		(0x00D4)72#define CDC_VA_TOP_CSR_SWR_MIC_CTL2		(0x00D8)73#define CDC_VA_SWR_MIC_CLK_SEL_0_1_MASK		(0xEE)74#define CDC_VA_SWR_MIC_CLK_SEL_0_1_DIV1		(0xCC)75#define CDC_VA_TOP_CSR_SWR_CTRL			(0x00DC)76#define CDC_VA_INP_MUX_ADC_MUX0_CFG0		(0x0100)77#define CDC_VA_INP_MUX_ADC_MUX0_CFG1		(0x0104)78#define CDC_VA_INP_MUX_ADC_MUX1_CFG0		(0x0108)79#define CDC_VA_INP_MUX_ADC_MUX1_CFG1		(0x010C)80#define CDC_VA_INP_MUX_ADC_MUX2_CFG0		(0x0110)81#define CDC_VA_INP_MUX_ADC_MUX2_CFG1		(0x0114)82#define CDC_VA_INP_MUX_ADC_MUX3_CFG0		(0x0118)83#define CDC_VA_INP_MUX_ADC_MUX3_CFG1		(0x011C)84#define CDC_VA_TX0_TX_PATH_CTL			(0x0400)85#define CDC_VA_TX_PATH_CLK_EN_MASK		BIT(5)86#define CDC_VA_TX_PATH_CLK_EN			BIT(5)87#define CDC_VA_TX_PATH_CLK_DISABLE		088#define CDC_VA_TX_PATH_PGA_MUTE_EN_MASK		BIT(4)89#define CDC_VA_TX_PATH_PGA_MUTE_EN		BIT(4)90#define CDC_VA_TX_PATH_PGA_MUTE_DISABLE		091#define CDC_VA_TX0_TX_PATH_CFG0			(0x0404)92#define CDC_VA_ADC_MODE_MASK			GENMASK(2, 1)93#define CDC_VA_ADC_MODE_SHIFT			194#define  TX_HPF_CUT_OFF_FREQ_MASK		GENMASK(6, 5)95#define  CF_MIN_3DB_4HZ			0x096#define  CF_MIN_3DB_75HZ		0x197#define  CF_MIN_3DB_150HZ		0x298#define CDC_VA_TX0_TX_PATH_CFG1			(0x0408)99#define CDC_VA_TX0_TX_VOL_CTL			(0x040C)100#define CDC_VA_TX0_TX_PATH_SEC0			(0x0410)101#define CDC_VA_TX0_TX_PATH_SEC1			(0x0414)102#define CDC_VA_TX0_TX_PATH_SEC2			(0x0418)103#define CDC_VA_TX_HPF_CUTOFF_FREQ_CHANGE_MASK	BIT(1)104#define CDC_VA_TX_HPF_CUTOFF_FREQ_CHANGE_REQ	BIT(1)105#define CDC_VA_TX_HPF_ZERO_GATE_MASK		BIT(0)106#define CDC_VA_TX_HPF_ZERO_NO_GATE		BIT(0)107#define CDC_VA_TX_HPF_ZERO_GATE			0108#define CDC_VA_TX0_TX_PATH_SEC3			(0x041C)109#define CDC_VA_TX0_TX_PATH_SEC4			(0x0420)110#define CDC_VA_TX0_TX_PATH_SEC5			(0x0424)111#define CDC_VA_TX0_TX_PATH_SEC6			(0x0428)112#define CDC_VA_TX0_TX_PATH_SEC7			(0x042C)113#define CDC_VA_TX1_TX_PATH_CTL			(0x0480)114#define CDC_VA_TX1_TX_PATH_CFG0			(0x0484)115#define CDC_VA_TX1_TX_PATH_CFG1			(0x0488)116#define CDC_VA_TX1_TX_VOL_CTL			(0x048C)117#define CDC_VA_TX1_TX_PATH_SEC0			(0x0490)118#define CDC_VA_TX1_TX_PATH_SEC1			(0x0494)119#define CDC_VA_TX1_TX_PATH_SEC2			(0x0498)120#define CDC_VA_TX1_TX_PATH_SEC3			(0x049C)121#define CDC_VA_TX1_TX_PATH_SEC4			(0x04A0)122#define CDC_VA_TX1_TX_PATH_SEC5			(0x04A4)123#define CDC_VA_TX1_TX_PATH_SEC6			(0x04A8)124#define CDC_VA_TX2_TX_PATH_CTL			(0x0500)125#define CDC_VA_TX2_TX_PATH_CFG0			(0x0504)126#define CDC_VA_TX2_TX_PATH_CFG1			(0x0508)127#define CDC_VA_TX2_TX_VOL_CTL			(0x050C)128#define CDC_VA_TX2_TX_PATH_SEC0			(0x0510)129#define CDC_VA_TX2_TX_PATH_SEC1			(0x0514)130#define CDC_VA_TX2_TX_PATH_SEC2			(0x0518)131#define CDC_VA_TX2_TX_PATH_SEC3			(0x051C)132#define CDC_VA_TX2_TX_PATH_SEC4			(0x0520)133#define CDC_VA_TX2_TX_PATH_SEC5			(0x0524)134#define CDC_VA_TX2_TX_PATH_SEC6			(0x0528)135#define CDC_VA_TX3_TX_PATH_CTL			(0x0580)136#define CDC_VA_TX3_TX_PATH_CFG0			(0x0584)137#define CDC_VA_TX_PATH_ADC_DMIC_SEL_MASK	BIT(7)138#define CDC_VA_TX_PATH_ADC_DMIC_SEL_DMIC	BIT(7)139#define CDC_VA_TX_PATH_ADC_DMIC_SEL_ADC		0140#define CDC_VA_TX3_TX_PATH_CFG1			(0x0588)141#define CDC_VA_TX3_TX_VOL_CTL			(0x058C)142#define CDC_VA_TX3_TX_PATH_SEC0			(0x0590)143#define CDC_VA_TX3_TX_PATH_SEC1			(0x0594)144#define CDC_VA_TX3_TX_PATH_SEC2			(0x0598)145#define CDC_VA_TX3_TX_PATH_SEC3			(0x059C)146#define CDC_VA_TX3_TX_PATH_SEC4			(0x05A0)147#define CDC_VA_TX3_TX_PATH_SEC5			(0x05A4)148#define CDC_VA_TX3_TX_PATH_SEC6			(0x05A8)149 150#define VA_MAX_OFFSET				(0x07A8)151 152#define VA_MACRO_NUM_DECIMATORS 4153#define VA_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\154			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\155			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)156#define VA_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\157		SNDRV_PCM_FMTBIT_S24_LE |\158		SNDRV_PCM_FMTBIT_S24_3LE)159 160#define VA_MACRO_MCLK_FREQ 9600000161#define VA_MACRO_TX_PATH_OFFSET 0x80162#define VA_MACRO_SWR_MIC_MUX_SEL_MASK 0xF163#define VA_MACRO_ADC_MUX_CFG_OFFSET 0x8164 165static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);166 167enum {168	VA_MACRO_AIF_INVALID = 0,169	VA_MACRO_AIF1_CAP,170	VA_MACRO_AIF2_CAP,171	VA_MACRO_AIF3_CAP,172	VA_MACRO_MAX_DAIS,173};174 175enum {176	VA_MACRO_DEC0,177	VA_MACRO_DEC1,178	VA_MACRO_DEC2,179	VA_MACRO_DEC3,180	VA_MACRO_DEC4,181	VA_MACRO_DEC5,182	VA_MACRO_DEC6,183	VA_MACRO_DEC7,184	VA_MACRO_DEC_MAX,185};186 187enum {188	VA_MACRO_CLK_DIV_2,189	VA_MACRO_CLK_DIV_3,190	VA_MACRO_CLK_DIV_4,191	VA_MACRO_CLK_DIV_6,192	VA_MACRO_CLK_DIV_8,193	VA_MACRO_CLK_DIV_16,194};195 196#define VA_NUM_CLKS_MAX		3197 198struct va_macro {199	struct device *dev;200	unsigned long active_ch_mask[VA_MACRO_MAX_DAIS];201	unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS];202	u16 dmic_clk_div;203	bool has_swr_master;204	bool has_npl_clk;205 206	int dec_mode[VA_MACRO_NUM_DECIMATORS];207	struct regmap *regmap;208	struct clk *mclk;209	struct clk *npl;210	struct clk *macro;211	struct clk *dcodec;212	struct clk *fsgen;213	struct clk_hw hw;214	struct lpass_macro *pds;215 216	s32 dmic_0_1_clk_cnt;217	s32 dmic_2_3_clk_cnt;218	s32 dmic_4_5_clk_cnt;219	s32 dmic_6_7_clk_cnt;220	u8 dmic_0_1_clk_div;221	u8 dmic_2_3_clk_div;222	u8 dmic_4_5_clk_div;223	u8 dmic_6_7_clk_div;224};225 226#define to_va_macro(_hw) container_of(_hw, struct va_macro, hw)227 228struct va_macro_data {229	bool has_swr_master;230	bool has_npl_clk;231	int version;232};233 234static const struct va_macro_data sm8250_va_data = {235	.has_swr_master = false,236	.has_npl_clk = false,237	.version = LPASS_CODEC_VERSION_1_0,238};239 240static const struct va_macro_data sm8450_va_data = {241	.has_swr_master = true,242	.has_npl_clk = true,243};244 245static const struct va_macro_data sm8550_va_data = {246	.has_swr_master = true,247	.has_npl_clk = false,248};249 250static bool va_is_volatile_register(struct device *dev, unsigned int reg)251{252	switch (reg) {253	case CDC_VA_TOP_CSR_CORE_ID_0:254	case CDC_VA_TOP_CSR_CORE_ID_1:255	case CDC_VA_TOP_CSR_CORE_ID_2:256	case CDC_VA_TOP_CSR_CORE_ID_3:257	case CDC_VA_TOP_CSR_DMIC0_CTL:258	case CDC_VA_TOP_CSR_DMIC1_CTL:259	case CDC_VA_TOP_CSR_DMIC2_CTL:260	case CDC_VA_TOP_CSR_DMIC3_CTL:261		return true;262	}263	return false;264}265 266static const struct reg_default va_defaults[] = {267	/* VA macro */268	{ CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, 0x00},269	{ CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},270	{ CDC_VA_CLK_RST_CTRL_SWR_CONTROL, 0x00},271	{ CDC_VA_TOP_CSR_TOP_CFG0, 0x00},272	{ CDC_VA_TOP_CSR_DMIC0_CTL, 0x00},273	{ CDC_VA_TOP_CSR_DMIC1_CTL, 0x00},274	{ CDC_VA_TOP_CSR_DMIC2_CTL, 0x00},275	{ CDC_VA_TOP_CSR_DMIC3_CTL, 0x00},276	{ CDC_VA_TOP_CSR_DMIC_CFG, 0x80},277	{ CDC_VA_TOP_CSR_DEBUG_BUS, 0x00},278	{ CDC_VA_TOP_CSR_DEBUG_EN, 0x00},279	{ CDC_VA_TOP_CSR_TX_I2S_CTL, 0x0C},280	{ CDC_VA_TOP_CSR_I2S_CLK, 0x00},281	{ CDC_VA_TOP_CSR_I2S_RESET, 0x00},282	{ CDC_VA_TOP_CSR_CORE_ID_0, 0x00},283	{ CDC_VA_TOP_CSR_CORE_ID_1, 0x00},284	{ CDC_VA_TOP_CSR_CORE_ID_2, 0x00},285	{ CDC_VA_TOP_CSR_CORE_ID_3, 0x00},286	{ CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE},287	{ CDC_VA_TOP_CSR_SWR_MIC_CTL1, 0xEE},288	{ CDC_VA_TOP_CSR_SWR_MIC_CTL2, 0xEE},289	{ CDC_VA_TOP_CSR_SWR_CTRL, 0x06},290 291	/* VA core */292	{ CDC_VA_INP_MUX_ADC_MUX0_CFG0, 0x00},293	{ CDC_VA_INP_MUX_ADC_MUX0_CFG1, 0x00},294	{ CDC_VA_INP_MUX_ADC_MUX1_CFG0, 0x00},295	{ CDC_VA_INP_MUX_ADC_MUX1_CFG1, 0x00},296	{ CDC_VA_INP_MUX_ADC_MUX2_CFG0, 0x00},297	{ CDC_VA_INP_MUX_ADC_MUX2_CFG1, 0x00},298	{ CDC_VA_INP_MUX_ADC_MUX3_CFG0, 0x00},299	{ CDC_VA_INP_MUX_ADC_MUX3_CFG1, 0x00},300	{ CDC_VA_TX0_TX_PATH_CTL, 0x04},301	{ CDC_VA_TX0_TX_PATH_CFG0, 0x10},302	{ CDC_VA_TX0_TX_PATH_CFG1, 0x0B},303	{ CDC_VA_TX0_TX_VOL_CTL, 0x00},304	{ CDC_VA_TX0_TX_PATH_SEC0, 0x00},305	{ CDC_VA_TX0_TX_PATH_SEC1, 0x00},306	{ CDC_VA_TX0_TX_PATH_SEC2, 0x01},307	{ CDC_VA_TX0_TX_PATH_SEC3, 0x3C},308	{ CDC_VA_TX0_TX_PATH_SEC4, 0x20},309	{ CDC_VA_TX0_TX_PATH_SEC5, 0x00},310	{ CDC_VA_TX0_TX_PATH_SEC6, 0x00},311	{ CDC_VA_TX0_TX_PATH_SEC7, 0x25},312	{ CDC_VA_TX1_TX_PATH_CTL, 0x04},313	{ CDC_VA_TX1_TX_PATH_CFG0, 0x10},314	{ CDC_VA_TX1_TX_PATH_CFG1, 0x0B},315	{ CDC_VA_TX1_TX_VOL_CTL, 0x00},316	{ CDC_VA_TX1_TX_PATH_SEC0, 0x00},317	{ CDC_VA_TX1_TX_PATH_SEC1, 0x00},318	{ CDC_VA_TX1_TX_PATH_SEC2, 0x01},319	{ CDC_VA_TX1_TX_PATH_SEC3, 0x3C},320	{ CDC_VA_TX1_TX_PATH_SEC4, 0x20},321	{ CDC_VA_TX1_TX_PATH_SEC5, 0x00},322	{ CDC_VA_TX1_TX_PATH_SEC6, 0x00},323	{ CDC_VA_TX2_TX_PATH_CTL, 0x04},324	{ CDC_VA_TX2_TX_PATH_CFG0, 0x10},325	{ CDC_VA_TX2_TX_PATH_CFG1, 0x0B},326	{ CDC_VA_TX2_TX_VOL_CTL, 0x00},327	{ CDC_VA_TX2_TX_PATH_SEC0, 0x00},328	{ CDC_VA_TX2_TX_PATH_SEC1, 0x00},329	{ CDC_VA_TX2_TX_PATH_SEC2, 0x01},330	{ CDC_VA_TX2_TX_PATH_SEC3, 0x3C},331	{ CDC_VA_TX2_TX_PATH_SEC4, 0x20},332	{ CDC_VA_TX2_TX_PATH_SEC5, 0x00},333	{ CDC_VA_TX2_TX_PATH_SEC6, 0x00},334	{ CDC_VA_TX3_TX_PATH_CTL, 0x04},335	{ CDC_VA_TX3_TX_PATH_CFG0, 0x10},336	{ CDC_VA_TX3_TX_PATH_CFG1, 0x0B},337	{ CDC_VA_TX3_TX_VOL_CTL, 0x00},338	{ CDC_VA_TX3_TX_PATH_SEC0, 0x00},339	{ CDC_VA_TX3_TX_PATH_SEC1, 0x00},340	{ CDC_VA_TX3_TX_PATH_SEC2, 0x01},341	{ CDC_VA_TX3_TX_PATH_SEC3, 0x3C},342	{ CDC_VA_TX3_TX_PATH_SEC4, 0x20},343	{ CDC_VA_TX3_TX_PATH_SEC5, 0x00},344	{ CDC_VA_TX3_TX_PATH_SEC6, 0x00},345};346 347static bool va_is_rw_register(struct device *dev, unsigned int reg)348{349	switch (reg) {350	case CDC_VA_CLK_RST_CTRL_MCLK_CONTROL:351	case CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL:352	case CDC_VA_CLK_RST_CTRL_SWR_CONTROL:353	case CDC_VA_TOP_CSR_TOP_CFG0:354	case CDC_VA_TOP_CSR_DMIC0_CTL:355	case CDC_VA_TOP_CSR_DMIC1_CTL:356	case CDC_VA_TOP_CSR_DMIC2_CTL:357	case CDC_VA_TOP_CSR_DMIC3_CTL:358	case CDC_VA_TOP_CSR_DMIC_CFG:359	case CDC_VA_TOP_CSR_SWR_MIC_CTL0:360	case CDC_VA_TOP_CSR_SWR_MIC_CTL1:361	case CDC_VA_TOP_CSR_SWR_MIC_CTL2:362	case CDC_VA_TOP_CSR_DEBUG_BUS:363	case CDC_VA_TOP_CSR_DEBUG_EN:364	case CDC_VA_TOP_CSR_TX_I2S_CTL:365	case CDC_VA_TOP_CSR_I2S_CLK:366	case CDC_VA_TOP_CSR_I2S_RESET:367	case CDC_VA_INP_MUX_ADC_MUX0_CFG0:368	case CDC_VA_INP_MUX_ADC_MUX0_CFG1:369	case CDC_VA_INP_MUX_ADC_MUX1_CFG0:370	case CDC_VA_INP_MUX_ADC_MUX1_CFG1:371	case CDC_VA_INP_MUX_ADC_MUX2_CFG0:372	case CDC_VA_INP_MUX_ADC_MUX2_CFG1:373	case CDC_VA_INP_MUX_ADC_MUX3_CFG0:374	case CDC_VA_INP_MUX_ADC_MUX3_CFG1:375	case CDC_VA_TX0_TX_PATH_CTL:376	case CDC_VA_TX0_TX_PATH_CFG0:377	case CDC_VA_TX0_TX_PATH_CFG1:378	case CDC_VA_TX0_TX_VOL_CTL:379	case CDC_VA_TX0_TX_PATH_SEC0:380	case CDC_VA_TX0_TX_PATH_SEC1:381	case CDC_VA_TX0_TX_PATH_SEC2:382	case CDC_VA_TX0_TX_PATH_SEC3:383	case CDC_VA_TX0_TX_PATH_SEC4:384	case CDC_VA_TX0_TX_PATH_SEC5:385	case CDC_VA_TX0_TX_PATH_SEC6:386	case CDC_VA_TX0_TX_PATH_SEC7:387	case CDC_VA_TX1_TX_PATH_CTL:388	case CDC_VA_TX1_TX_PATH_CFG0:389	case CDC_VA_TX1_TX_PATH_CFG1:390	case CDC_VA_TX1_TX_VOL_CTL:391	case CDC_VA_TX1_TX_PATH_SEC0:392	case CDC_VA_TX1_TX_PATH_SEC1:393	case CDC_VA_TX1_TX_PATH_SEC2:394	case CDC_VA_TX1_TX_PATH_SEC3:395	case CDC_VA_TX1_TX_PATH_SEC4:396	case CDC_VA_TX1_TX_PATH_SEC5:397	case CDC_VA_TX1_TX_PATH_SEC6:398	case CDC_VA_TX2_TX_PATH_CTL:399	case CDC_VA_TX2_TX_PATH_CFG0:400	case CDC_VA_TX2_TX_PATH_CFG1:401	case CDC_VA_TX2_TX_VOL_CTL:402	case CDC_VA_TX2_TX_PATH_SEC0:403	case CDC_VA_TX2_TX_PATH_SEC1:404	case CDC_VA_TX2_TX_PATH_SEC2:405	case CDC_VA_TX2_TX_PATH_SEC3:406	case CDC_VA_TX2_TX_PATH_SEC4:407	case CDC_VA_TX2_TX_PATH_SEC5:408	case CDC_VA_TX2_TX_PATH_SEC6:409	case CDC_VA_TX3_TX_PATH_CTL:410	case CDC_VA_TX3_TX_PATH_CFG0:411	case CDC_VA_TX3_TX_PATH_CFG1:412	case CDC_VA_TX3_TX_VOL_CTL:413	case CDC_VA_TX3_TX_PATH_SEC0:414	case CDC_VA_TX3_TX_PATH_SEC1:415	case CDC_VA_TX3_TX_PATH_SEC2:416	case CDC_VA_TX3_TX_PATH_SEC3:417	case CDC_VA_TX3_TX_PATH_SEC4:418	case CDC_VA_TX3_TX_PATH_SEC5:419	case CDC_VA_TX3_TX_PATH_SEC6:420		return true;421	}422 423	return false;424}425 426static bool va_is_readable_register(struct device *dev, unsigned int reg)427{428	switch (reg) {429	case CDC_VA_TOP_CSR_CORE_ID_0:430	case CDC_VA_TOP_CSR_CORE_ID_1:431	case CDC_VA_TOP_CSR_CORE_ID_2:432	case CDC_VA_TOP_CSR_CORE_ID_3:433		return true;434	}435 436	return va_is_rw_register(dev, reg);437}438 439static const struct regmap_config va_regmap_config = {440	.name = "va_macro",441	.reg_bits = 32,442	.val_bits = 32,443	.reg_stride = 4,444	.cache_type = REGCACHE_FLAT,445	.reg_defaults = va_defaults,446	.num_reg_defaults = ARRAY_SIZE(va_defaults),447	.max_register = VA_MAX_OFFSET,448	.volatile_reg = va_is_volatile_register,449	.readable_reg = va_is_readable_register,450	.writeable_reg = va_is_rw_register,451};452 453static int va_clk_rsc_fs_gen_request(struct va_macro *va, bool enable)454{455	struct regmap *regmap = va->regmap;456 457	if (enable) {458		regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_MCLK_CONTROL,459				   CDC_VA_MCLK_CONTROL_EN,460				   CDC_VA_MCLK_CONTROL_EN);461		/* clear the fs counter */462		regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL,463				   CDC_VA_FS_CONTROL_EN | CDC_VA_FS_COUNTER_CLR,464				   CDC_VA_FS_CONTROL_EN | CDC_VA_FS_COUNTER_CLR);465		regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL,466				   CDC_VA_FS_CONTROL_EN | CDC_VA_FS_COUNTER_CLR,467				   CDC_VA_FS_CONTROL_EN);468 469		regmap_update_bits(regmap, CDC_VA_TOP_CSR_TOP_CFG0,470				   CDC_VA_FS_BROADCAST_EN,471				   CDC_VA_FS_BROADCAST_EN);472	} else {473		regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_MCLK_CONTROL,474				   CDC_VA_MCLK_CONTROL_EN, 0x0);475 476		regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL,477				   CDC_VA_FS_CONTROL_EN, 0x0);478 479		regmap_update_bits(regmap, CDC_VA_TOP_CSR_TOP_CFG0,480				   CDC_VA_FS_BROADCAST_EN, 0x0);481	}482 483	return 0;484}485 486static int va_macro_mclk_enable(struct va_macro *va, bool mclk_enable)487{488	struct regmap *regmap = va->regmap;489 490	if (mclk_enable) {491		va_clk_rsc_fs_gen_request(va, true);492		regcache_mark_dirty(regmap);493		regcache_sync_region(regmap, 0x0, VA_MAX_OFFSET);494	} else {495		va_clk_rsc_fs_gen_request(va, false);496	}497 498	return 0;499}500 501static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,502			       struct snd_kcontrol *kcontrol, int event)503{504	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);505	struct va_macro *va = snd_soc_component_get_drvdata(comp);506 507	switch (event) {508	case SND_SOC_DAPM_PRE_PMU:509		return clk_prepare_enable(va->fsgen);510	case SND_SOC_DAPM_POST_PMD:511		clk_disable_unprepare(va->fsgen);512	}513 514	return 0;515}516 517static int va_macro_put_dec_enum(struct snd_kcontrol *kcontrol,518				 struct snd_ctl_elem_value *ucontrol)519{520	struct snd_soc_dapm_widget *widget =521		snd_soc_dapm_kcontrol_widget(kcontrol);522	struct snd_soc_component *component =523		snd_soc_dapm_to_component(widget->dapm);524	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;525	unsigned int val;526	u16 mic_sel_reg;527 528	val = ucontrol->value.enumerated.item[0];529 530	switch (e->reg) {531	case CDC_VA_INP_MUX_ADC_MUX0_CFG0:532		mic_sel_reg = CDC_VA_TX0_TX_PATH_CFG0;533		break;534	case CDC_VA_INP_MUX_ADC_MUX1_CFG0:535		mic_sel_reg = CDC_VA_TX1_TX_PATH_CFG0;536		break;537	case CDC_VA_INP_MUX_ADC_MUX2_CFG0:538		mic_sel_reg = CDC_VA_TX2_TX_PATH_CFG0;539		break;540	case CDC_VA_INP_MUX_ADC_MUX3_CFG0:541		mic_sel_reg = CDC_VA_TX3_TX_PATH_CFG0;542		break;543	default:544		dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",545			__func__, e->reg);546		return -EINVAL;547	}548 549	if (val != 0)550		snd_soc_component_update_bits(component, mic_sel_reg,551					      CDC_VA_TX_PATH_ADC_DMIC_SEL_MASK,552					      CDC_VA_TX_PATH_ADC_DMIC_SEL_DMIC);553 554	return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);555}556 557static int va_macro_tx_mixer_get(struct snd_kcontrol *kcontrol,558				 struct snd_ctl_elem_value *ucontrol)559{560	struct snd_soc_dapm_widget *widget =561		snd_soc_dapm_kcontrol_widget(kcontrol);562	struct snd_soc_component *component =563				snd_soc_dapm_to_component(widget->dapm);564	struct soc_mixer_control *mc =565		(struct soc_mixer_control *)kcontrol->private_value;566	u32 dai_id = widget->shift;567	u32 dec_id = mc->shift;568	struct va_macro *va = snd_soc_component_get_drvdata(component);569 570	if (test_bit(dec_id, &va->active_ch_mask[dai_id]))571		ucontrol->value.integer.value[0] = 1;572	else573		ucontrol->value.integer.value[0] = 0;574 575	return 0;576}577 578static int va_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,579				 struct snd_ctl_elem_value *ucontrol)580{581	struct snd_soc_dapm_widget *widget =582					snd_soc_dapm_kcontrol_widget(kcontrol);583	struct snd_soc_component *component =584				snd_soc_dapm_to_component(widget->dapm);585	struct snd_soc_dapm_update *update = NULL;586	struct soc_mixer_control *mc =587		(struct soc_mixer_control *)kcontrol->private_value;588	u32 dai_id = widget->shift;589	u32 dec_id = mc->shift;590	u32 enable = ucontrol->value.integer.value[0];591	struct va_macro *va = snd_soc_component_get_drvdata(component);592 593	if (enable) {594		set_bit(dec_id, &va->active_ch_mask[dai_id]);595		va->active_ch_cnt[dai_id]++;596	} else {597		clear_bit(dec_id, &va->active_ch_mask[dai_id]);598		va->active_ch_cnt[dai_id]--;599	}600 601	snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);602 603	return 0;604}605 606static int va_dmic_clk_enable(struct snd_soc_component *component,607			      u32 dmic, bool enable)608{609	struct va_macro *va = snd_soc_component_get_drvdata(component);610	u16 dmic_clk_reg;611	s32 *dmic_clk_cnt;612	u8 *dmic_clk_div;613	u8 freq_change_mask;614	u8 clk_div;615 616	switch (dmic) {617	case 0:618	case 1:619		dmic_clk_cnt = &(va->dmic_0_1_clk_cnt);620		dmic_clk_div = &(va->dmic_0_1_clk_div);621		dmic_clk_reg = CDC_VA_TOP_CSR_DMIC0_CTL;622		freq_change_mask = CDC_VA_DMIC0_FREQ_CHANGE_MASK;623		break;624	case 2:625	case 3:626		dmic_clk_cnt = &(va->dmic_2_3_clk_cnt);627		dmic_clk_div = &(va->dmic_2_3_clk_div);628		dmic_clk_reg = CDC_VA_TOP_CSR_DMIC1_CTL;629		freq_change_mask = CDC_VA_DMIC1_FREQ_CHANGE_MASK;630		break;631	case 4:632	case 5:633		dmic_clk_cnt = &(va->dmic_4_5_clk_cnt);634		dmic_clk_div = &(va->dmic_4_5_clk_div);635		dmic_clk_reg = CDC_VA_TOP_CSR_DMIC2_CTL;636		freq_change_mask = CDC_VA_DMIC2_FREQ_CHANGE_MASK;637		break;638	case 6:639	case 7:640		dmic_clk_cnt = &(va->dmic_6_7_clk_cnt);641		dmic_clk_div = &(va->dmic_6_7_clk_div);642		dmic_clk_reg = CDC_VA_TOP_CSR_DMIC3_CTL;643		freq_change_mask = CDC_VA_DMIC3_FREQ_CHANGE_MASK;644		break;645	default:646		dev_err(component->dev, "%s: Invalid DMIC Selection\n",647			__func__);648		return -EINVAL;649	}650 651	if (enable) {652		clk_div = va->dmic_clk_div;653		(*dmic_clk_cnt)++;654		if (*dmic_clk_cnt == 1) {655			snd_soc_component_update_bits(component,656					      CDC_VA_TOP_CSR_DMIC_CFG,657					      CDC_VA_RESET_ALL_DMICS_MASK,658					      CDC_VA_RESET_ALL_DMICS_DISABLE);659			snd_soc_component_update_bits(component, dmic_clk_reg,660					CDC_VA_DMIC_CLK_SEL_MASK,661					clk_div << CDC_VA_DMIC_CLK_SEL_SHFT);662			snd_soc_component_update_bits(component, dmic_clk_reg,663						      CDC_VA_DMIC_EN_MASK,664						      CDC_VA_DMIC_ENABLE);665		} else {666			if (*dmic_clk_div > clk_div) {667				snd_soc_component_update_bits(component,668						CDC_VA_TOP_CSR_DMIC_CFG,669						freq_change_mask,670						freq_change_mask);671				snd_soc_component_update_bits(component, dmic_clk_reg,672						CDC_VA_DMIC_CLK_SEL_MASK,673						clk_div << CDC_VA_DMIC_CLK_SEL_SHFT);674				snd_soc_component_update_bits(component,675					      CDC_VA_TOP_CSR_DMIC_CFG,676					      freq_change_mask,677					      CDC_VA_DMIC_FREQ_CHANGE_DISABLE);678			} else {679				clk_div = *dmic_clk_div;680			}681		}682		*dmic_clk_div = clk_div;683	} else {684		(*dmic_clk_cnt)--;685		if (*dmic_clk_cnt  == 0) {686			snd_soc_component_update_bits(component, dmic_clk_reg,687						      CDC_VA_DMIC_EN_MASK, 0);688			clk_div = 0;689			snd_soc_component_update_bits(component, dmic_clk_reg,690						CDC_VA_DMIC_CLK_SEL_MASK,691						clk_div << CDC_VA_DMIC_CLK_SEL_SHFT);692		} else {693			clk_div = va->dmic_clk_div;694			if (*dmic_clk_div > clk_div) {695				clk_div = va->dmic_clk_div;696				snd_soc_component_update_bits(component,697							CDC_VA_TOP_CSR_DMIC_CFG,698							freq_change_mask,699							freq_change_mask);700				snd_soc_component_update_bits(component, dmic_clk_reg,701						CDC_VA_DMIC_CLK_SEL_MASK,702						clk_div << CDC_VA_DMIC_CLK_SEL_SHFT);703				snd_soc_component_update_bits(component,704						      CDC_VA_TOP_CSR_DMIC_CFG,705						      freq_change_mask,706						      CDC_VA_DMIC_FREQ_CHANGE_DISABLE);707			} else {708				clk_div = *dmic_clk_div;709			}710		}711		*dmic_clk_div = clk_div;712	}713 714	return 0;715}716 717static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w,718				struct snd_kcontrol *kcontrol, int event)719{720	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);721	unsigned int dmic = w->shift;722 723	switch (event) {724	case SND_SOC_DAPM_PRE_PMU:725		va_dmic_clk_enable(comp, dmic, true);726		break;727	case SND_SOC_DAPM_POST_PMD:728		va_dmic_clk_enable(comp, dmic, false);729		break;730	}731 732	return 0;733}734 735static int va_macro_enable_dec(struct snd_soc_dapm_widget *w,736			       struct snd_kcontrol *kcontrol, int event)737{738	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);739	unsigned int decimator;740	u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg;741	u16 tx_gain_ctl_reg;742	u8 hpf_cut_off_freq;743 744	struct va_macro *va = snd_soc_component_get_drvdata(comp);745 746	decimator = w->shift;747 748	tx_vol_ctl_reg = CDC_VA_TX0_TX_PATH_CTL +749				VA_MACRO_TX_PATH_OFFSET * decimator;750	hpf_gate_reg = CDC_VA_TX0_TX_PATH_SEC2 +751				VA_MACRO_TX_PATH_OFFSET * decimator;752	dec_cfg_reg = CDC_VA_TX0_TX_PATH_CFG0 +753				VA_MACRO_TX_PATH_OFFSET * decimator;754	tx_gain_ctl_reg = CDC_VA_TX0_TX_VOL_CTL +755				VA_MACRO_TX_PATH_OFFSET * decimator;756 757	switch (event) {758	case SND_SOC_DAPM_PRE_PMU:759		snd_soc_component_update_bits(comp,760			dec_cfg_reg, CDC_VA_ADC_MODE_MASK,761			va->dec_mode[decimator] << CDC_VA_ADC_MODE_SHIFT);762		/* Enable TX PGA Mute */763		break;764	case SND_SOC_DAPM_POST_PMU:765		/* Enable TX CLK */766		snd_soc_component_update_bits(comp, tx_vol_ctl_reg,767					      CDC_VA_TX_PATH_CLK_EN_MASK,768					      CDC_VA_TX_PATH_CLK_EN);769		snd_soc_component_update_bits(comp, hpf_gate_reg,770					      CDC_VA_TX_HPF_ZERO_GATE_MASK,771					      CDC_VA_TX_HPF_ZERO_GATE);772 773		usleep_range(1000, 1010);774		hpf_cut_off_freq = (snd_soc_component_read(comp, dec_cfg_reg) &775				    TX_HPF_CUT_OFF_FREQ_MASK) >> 5;776 777		if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {778			snd_soc_component_update_bits(comp, dec_cfg_reg,779						      TX_HPF_CUT_OFF_FREQ_MASK,780						      CF_MIN_3DB_150HZ << 5);781 782			snd_soc_component_update_bits(comp, hpf_gate_reg,783				      CDC_VA_TX_HPF_CUTOFF_FREQ_CHANGE_MASK,784				      CDC_VA_TX_HPF_CUTOFF_FREQ_CHANGE_REQ);785 786			/*787			 * Minimum 1 clk cycle delay is required as per HW spec788			 */789			usleep_range(1000, 1010);790 791			snd_soc_component_update_bits(comp,792				hpf_gate_reg,793				CDC_VA_TX_HPF_CUTOFF_FREQ_CHANGE_MASK,794				0x0);795		}796 797 798		usleep_range(1000, 1010);799		snd_soc_component_update_bits(comp, hpf_gate_reg,800					      CDC_VA_TX_HPF_ZERO_GATE_MASK,801					      CDC_VA_TX_HPF_ZERO_NO_GATE);802		/*803		 * 6ms delay is required as per HW spec804		 */805		usleep_range(6000, 6010);806		/* apply gain after decimator is enabled */807		snd_soc_component_write(comp, tx_gain_ctl_reg,808			snd_soc_component_read(comp, tx_gain_ctl_reg));809		break;810	case SND_SOC_DAPM_POST_PMD:811		/* Disable TX CLK */812		snd_soc_component_update_bits(comp, tx_vol_ctl_reg,813						CDC_VA_TX_PATH_CLK_EN_MASK,814						CDC_VA_TX_PATH_CLK_DISABLE);815		break;816	}817	return 0;818}819 820static int va_macro_dec_mode_get(struct snd_kcontrol *kcontrol,821				 struct snd_ctl_elem_value *ucontrol)822{823	struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);824	struct va_macro *va = snd_soc_component_get_drvdata(comp);825	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;826	int path = e->shift_l;827 828	ucontrol->value.enumerated.item[0] = va->dec_mode[path];829 830	return 0;831}832 833static int va_macro_dec_mode_put(struct snd_kcontrol *kcontrol,834				 struct snd_ctl_elem_value *ucontrol)835{836	struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);837	int value = ucontrol->value.enumerated.item[0];838	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;839	int path = e->shift_l;840	struct va_macro *va = snd_soc_component_get_drvdata(comp);841 842	va->dec_mode[path] = value;843 844	return 0;845}846 847static int va_macro_hw_params(struct snd_pcm_substream *substream,848			      struct snd_pcm_hw_params *params,849			      struct snd_soc_dai *dai)850{851	int tx_fs_rate;852	struct snd_soc_component *component = dai->component;853	u32 decimator, sample_rate;854	u16 tx_fs_reg;855	struct device *va_dev = component->dev;856	struct va_macro *va = snd_soc_component_get_drvdata(component);857 858	sample_rate = params_rate(params);859	switch (sample_rate) {860	case 8000:861		tx_fs_rate = 0;862		break;863	case 16000:864		tx_fs_rate = 1;865		break;866	case 32000:867		tx_fs_rate = 3;868		break;869	case 48000:870		tx_fs_rate = 4;871		break;872	case 96000:873		tx_fs_rate = 5;874		break;875	case 192000:876		tx_fs_rate = 6;877		break;878	case 384000:879		tx_fs_rate = 7;880		break;881	default:882		dev_err(va_dev, "%s: Invalid TX sample rate: %d\n",883			__func__, params_rate(params));884		return -EINVAL;885	}886 887	for_each_set_bit(decimator, &va->active_ch_mask[dai->id],888			 VA_MACRO_DEC_MAX) {889		tx_fs_reg = CDC_VA_TX0_TX_PATH_CTL +890			    VA_MACRO_TX_PATH_OFFSET * decimator;891		snd_soc_component_update_bits(component, tx_fs_reg, 0x0F,892					      tx_fs_rate);893	}894	return 0;895}896 897static int va_macro_get_channel_map(const struct snd_soc_dai *dai,898				    unsigned int *tx_num, unsigned int *tx_slot,899				    unsigned int *rx_num, unsigned int *rx_slot)900{901	struct snd_soc_component *component = dai->component;902	struct device *va_dev = component->dev;903	struct va_macro *va = snd_soc_component_get_drvdata(component);904 905	switch (dai->id) {906	case VA_MACRO_AIF1_CAP:907	case VA_MACRO_AIF2_CAP:908	case VA_MACRO_AIF3_CAP:909		*tx_slot = va->active_ch_mask[dai->id];910		*tx_num = va->active_ch_cnt[dai->id];911		break;912	default:913		dev_err(va_dev, "%s: Invalid AIF\n", __func__);914		break;915	}916	return 0;917}918 919static int va_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream)920{921	struct snd_soc_component *component = dai->component;922	struct va_macro *va = snd_soc_component_get_drvdata(component);923	u16 tx_vol_ctl_reg, decimator;924 925	for_each_set_bit(decimator, &va->active_ch_mask[dai->id],926			 VA_MACRO_DEC_MAX) {927		tx_vol_ctl_reg = CDC_VA_TX0_TX_PATH_CTL +928					VA_MACRO_TX_PATH_OFFSET * decimator;929		if (mute)930			snd_soc_component_update_bits(component, tx_vol_ctl_reg,931					CDC_VA_TX_PATH_PGA_MUTE_EN_MASK,932					CDC_VA_TX_PATH_PGA_MUTE_EN);933		else934			snd_soc_component_update_bits(component, tx_vol_ctl_reg,935					CDC_VA_TX_PATH_PGA_MUTE_EN_MASK,936					CDC_VA_TX_PATH_PGA_MUTE_DISABLE);937	}938 939	return 0;940}941 942static const struct snd_soc_dai_ops va_macro_dai_ops = {943	.hw_params = va_macro_hw_params,944	.get_channel_map = va_macro_get_channel_map,945	.mute_stream = va_macro_digital_mute,946};947 948static struct snd_soc_dai_driver va_macro_dais[] = {949	{950		.name = "va_macro_tx1",951		.id = VA_MACRO_AIF1_CAP,952		.capture = {953			.stream_name = "VA_AIF1 Capture",954			.rates = VA_MACRO_RATES,955			.formats = VA_MACRO_FORMATS,956			.rate_max = 192000,957			.rate_min = 8000,958			.channels_min = 1,959			.channels_max = 8,960		},961		.ops = &va_macro_dai_ops,962	},963	{964		.name = "va_macro_tx2",965		.id = VA_MACRO_AIF2_CAP,966		.capture = {967			.stream_name = "VA_AIF2 Capture",968			.rates = VA_MACRO_RATES,969			.formats = VA_MACRO_FORMATS,970			.rate_max = 192000,971			.rate_min = 8000,972			.channels_min = 1,973			.channels_max = 8,974		},975		.ops = &va_macro_dai_ops,976	},977	{978		.name = "va_macro_tx3",979		.id = VA_MACRO_AIF3_CAP,980		.capture = {981			.stream_name = "VA_AIF3 Capture",982			.rates = VA_MACRO_RATES,983			.formats = VA_MACRO_FORMATS,984			.rate_max = 192000,985			.rate_min = 8000,986			.channels_min = 1,987			.channels_max = 8,988		},989		.ops = &va_macro_dai_ops,990	},991};992 993static const char * const adc_mux_text[] = {994	"VA_DMIC", "SWR_MIC"995};996 997static SOC_ENUM_SINGLE_DECL(va_dec0_enum, CDC_VA_INP_MUX_ADC_MUX0_CFG1,998		   0, adc_mux_text);999static SOC_ENUM_SINGLE_DECL(va_dec1_enum, CDC_VA_INP_MUX_ADC_MUX1_CFG1,1000		   0, adc_mux_text);1001static SOC_ENUM_SINGLE_DECL(va_dec2_enum, CDC_VA_INP_MUX_ADC_MUX2_CFG1,1002		   0, adc_mux_text);1003static SOC_ENUM_SINGLE_DECL(va_dec3_enum, CDC_VA_INP_MUX_ADC_MUX3_CFG1,1004		   0, adc_mux_text);1005 1006static const struct snd_kcontrol_new va_dec0_mux = SOC_DAPM_ENUM("va_dec0",1007								 va_dec0_enum);1008static const struct snd_kcontrol_new va_dec1_mux = SOC_DAPM_ENUM("va_dec1",1009								 va_dec1_enum);1010static const struct snd_kcontrol_new va_dec2_mux = SOC_DAPM_ENUM("va_dec2",1011								 va_dec2_enum);1012static const struct snd_kcontrol_new va_dec3_mux = SOC_DAPM_ENUM("va_dec3",1013								 va_dec3_enum);1014 1015static const char * const dmic_mux_text[] = {1016	"ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3",1017	"DMIC4", "DMIC5", "DMIC6", "DMIC7"1018};1019 1020static SOC_ENUM_SINGLE_DECL(va_dmic0_enum, CDC_VA_INP_MUX_ADC_MUX0_CFG0,1021			4, dmic_mux_text);1022 1023static SOC_ENUM_SINGLE_DECL(va_dmic1_enum, CDC_VA_INP_MUX_ADC_MUX1_CFG0,1024			4, dmic_mux_text);1025 1026static SOC_ENUM_SINGLE_DECL(va_dmic2_enum, CDC_VA_INP_MUX_ADC_MUX2_CFG0,1027			4, dmic_mux_text);1028 1029static SOC_ENUM_SINGLE_DECL(va_dmic3_enum, CDC_VA_INP_MUX_ADC_MUX3_CFG0,1030			4, dmic_mux_text);1031 1032static const struct snd_kcontrol_new va_dmic0_mux = SOC_DAPM_ENUM_EXT("va_dmic0",1033			 va_dmic0_enum, snd_soc_dapm_get_enum_double,1034			 va_macro_put_dec_enum);1035 1036static const struct snd_kcontrol_new va_dmic1_mux = SOC_DAPM_ENUM_EXT("va_dmic1",1037			 va_dmic1_enum, snd_soc_dapm_get_enum_double,1038			 va_macro_put_dec_enum);1039 1040static const struct snd_kcontrol_new va_dmic2_mux = SOC_DAPM_ENUM_EXT("va_dmic2",1041			 va_dmic2_enum, snd_soc_dapm_get_enum_double,1042			 va_macro_put_dec_enum);1043 1044static const struct snd_kcontrol_new va_dmic3_mux = SOC_DAPM_ENUM_EXT("va_dmic3",1045			 va_dmic3_enum, snd_soc_dapm_get_enum_double,1046			 va_macro_put_dec_enum);1047 1048static const struct snd_kcontrol_new va_aif1_cap_mixer[] = {1049	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,1050			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1051	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0,1052			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1053	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0,1054			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1055	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0,1056			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1057	SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, VA_MACRO_DEC4, 1, 0,1058			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1059	SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, VA_MACRO_DEC5, 1, 0,1060			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1061	SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, VA_MACRO_DEC6, 1, 0,1062			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1063	SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, VA_MACRO_DEC7, 1, 0,1064			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1065};1066 1067static const struct snd_kcontrol_new va_aif2_cap_mixer[] = {1068	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,1069			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1070	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0,1071			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1072	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0,1073			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1074	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0,1075			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1076	SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, VA_MACRO_DEC4, 1, 0,1077			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1078	SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, VA_MACRO_DEC5, 1, 0,1079			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1080	SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, VA_MACRO_DEC6, 1, 0,1081			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1082	SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, VA_MACRO_DEC7, 1, 0,1083			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1084};1085 1086static const struct snd_kcontrol_new va_aif3_cap_mixer[] = {1087	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,1088			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1089	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0,1090			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1091	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0,1092			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1093	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0,1094			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1095	SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, VA_MACRO_DEC4, 1, 0,1096			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1097	SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, VA_MACRO_DEC5, 1, 0,1098			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1099	SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, VA_MACRO_DEC6, 1, 0,1100			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1101	SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, VA_MACRO_DEC7, 1, 0,1102			va_macro_tx_mixer_get, va_macro_tx_mixer_put),1103};1104 1105static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = {1106	SND_SOC_DAPM_AIF_OUT("VA_AIF1 CAP", "VA_AIF1 Capture", 0,1107		SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0),1108 1109	SND_SOC_DAPM_AIF_OUT("VA_AIF2 CAP", "VA_AIF2 Capture", 0,1110		SND_SOC_NOPM, VA_MACRO_AIF2_CAP, 0),1111 1112	SND_SOC_DAPM_AIF_OUT("VA_AIF3 CAP", "VA_AIF3 Capture", 0,1113		SND_SOC_NOPM, VA_MACRO_AIF3_CAP, 0),1114 1115	SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM,1116		VA_MACRO_AIF1_CAP, 0,1117		va_aif1_cap_mixer, ARRAY_SIZE(va_aif1_cap_mixer)),1118 1119	SND_SOC_DAPM_MIXER("VA_AIF2_CAP Mixer", SND_SOC_NOPM,1120		VA_MACRO_AIF2_CAP, 0,1121		va_aif2_cap_mixer, ARRAY_SIZE(va_aif2_cap_mixer)),1122 1123	SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM,1124		VA_MACRO_AIF3_CAP, 0,1125		va_aif3_cap_mixer, ARRAY_SIZE(va_aif3_cap_mixer)),1126 1127	SND_SOC_DAPM_MUX("VA DMIC MUX0", SND_SOC_NOPM, 0, 0, &va_dmic0_mux),1128	SND_SOC_DAPM_MUX("VA DMIC MUX1", SND_SOC_NOPM, 0, 0, &va_dmic1_mux),1129	SND_SOC_DAPM_MUX("VA DMIC MUX2", SND_SOC_NOPM, 0, 0, &va_dmic2_mux),1130	SND_SOC_DAPM_MUX("VA DMIC MUX3", SND_SOC_NOPM, 0, 0, &va_dmic3_mux),1131 1132	SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-micb", 0, 0),1133	SND_SOC_DAPM_INPUT("DMIC0 Pin"),1134	SND_SOC_DAPM_INPUT("DMIC1 Pin"),1135	SND_SOC_DAPM_INPUT("DMIC2 Pin"),1136	SND_SOC_DAPM_INPUT("DMIC3 Pin"),1137	SND_SOC_DAPM_INPUT("DMIC4 Pin"),1138	SND_SOC_DAPM_INPUT("DMIC5 Pin"),1139	SND_SOC_DAPM_INPUT("DMIC6 Pin"),1140	SND_SOC_DAPM_INPUT("DMIC7 Pin"),1141 1142	SND_SOC_DAPM_ADC_E("VA DMIC0", NULL, SND_SOC_NOPM, 0, 0,1143		va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |1144		SND_SOC_DAPM_POST_PMD),1145 1146	SND_SOC_DAPM_ADC_E("VA DMIC1", NULL, SND_SOC_NOPM, 1, 0,1147		va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |1148		SND_SOC_DAPM_POST_PMD),1149 1150	SND_SOC_DAPM_ADC_E("VA DMIC2", NULL, SND_SOC_NOPM, 2, 0,1151		va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |1152		SND_SOC_DAPM_POST_PMD),1153 1154	SND_SOC_DAPM_ADC_E("VA DMIC3", NULL, SND_SOC_NOPM, 3, 0,1155		va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |1156		SND_SOC_DAPM_POST_PMD),1157 1158	SND_SOC_DAPM_ADC_E("VA DMIC4", NULL, SND_SOC_NOPM, 4, 0,1159		va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |1160		SND_SOC_DAPM_POST_PMD),1161 1162	SND_SOC_DAPM_ADC_E("VA DMIC5", NULL, SND_SOC_NOPM, 5, 0,1163		va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |1164		SND_SOC_DAPM_POST_PMD),1165 1166	SND_SOC_DAPM_ADC_E("VA DMIC6", NULL, SND_SOC_NOPM, 6, 0,1167		va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |1168		SND_SOC_DAPM_POST_PMD),1169 1170	SND_SOC_DAPM_ADC_E("VA DMIC7", NULL, SND_SOC_NOPM, 7, 0,1171		va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |1172		SND_SOC_DAPM_POST_PMD),1173 1174	SND_SOC_DAPM_INPUT("VA SWR_ADC0"),1175	SND_SOC_DAPM_INPUT("VA SWR_ADC1"),1176	SND_SOC_DAPM_INPUT("VA SWR_ADC2"),1177	SND_SOC_DAPM_INPUT("VA SWR_ADC3"),1178	SND_SOC_DAPM_INPUT("VA SWR_MIC0"),1179	SND_SOC_DAPM_INPUT("VA SWR_MIC1"),1180	SND_SOC_DAPM_INPUT("VA SWR_MIC2"),1181	SND_SOC_DAPM_INPUT("VA SWR_MIC3"),1182	SND_SOC_DAPM_INPUT("VA SWR_MIC4"),1183	SND_SOC_DAPM_INPUT("VA SWR_MIC5"),1184	SND_SOC_DAPM_INPUT("VA SWR_MIC6"),1185	SND_SOC_DAPM_INPUT("VA SWR_MIC7"),1186 1187	SND_SOC_DAPM_MUX_E("VA DEC0 MUX", SND_SOC_NOPM, VA_MACRO_DEC0, 0,1188			   &va_dec0_mux, va_macro_enable_dec,1189			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1190			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),1191 1192	SND_SOC_DAPM_MUX_E("VA DEC1 MUX", SND_SOC_NOPM, VA_MACRO_DEC1, 0,1193			   &va_dec1_mux, va_macro_enable_dec,1194			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1195			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),1196 1197	SND_SOC_DAPM_MUX_E("VA DEC2 MUX", SND_SOC_NOPM, VA_MACRO_DEC2, 0,1198			   &va_dec2_mux, va_macro_enable_dec,1199			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1200			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),1201 1202	SND_SOC_DAPM_MUX_E("VA DEC3 MUX", SND_SOC_NOPM, VA_MACRO_DEC3, 0,1203			   &va_dec3_mux, va_macro_enable_dec,1204			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1205			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),1206 1207	SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,1208			      va_macro_mclk_event,1209			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1210};1211 1212static const struct snd_soc_dapm_route va_audio_map[] = {1213	{"VA_AIF1 CAP", NULL, "VA_MCLK"},1214	{"VA_AIF2 CAP", NULL, "VA_MCLK"},1215	{"VA_AIF3 CAP", NULL, "VA_MCLK"},1216 1217	{"VA_AIF1 CAP", NULL, "VA_AIF1_CAP Mixer"},1218	{"VA_AIF2 CAP", NULL, "VA_AIF2_CAP Mixer"},1219	{"VA_AIF3 CAP", NULL, "VA_AIF3_CAP Mixer"},1220 1221	{"VA_AIF1_CAP Mixer", "DEC0", "VA DEC0 MUX"},1222	{"VA_AIF1_CAP Mixer", "DEC1", "VA DEC1 MUX"},1223	{"VA_AIF1_CAP Mixer", "DEC2", "VA DEC2 MUX"},1224	{"VA_AIF1_CAP Mixer", "DEC3", "VA DEC3 MUX"},1225 1226	{"VA_AIF2_CAP Mixer", "DEC0", "VA DEC0 MUX"},1227	{"VA_AIF2_CAP Mixer", "DEC1", "VA DEC1 MUX"},1228	{"VA_AIF2_CAP Mixer", "DEC2", "VA DEC2 MUX"},1229	{"VA_AIF2_CAP Mixer", "DEC3", "VA DEC3 MUX"},1230 1231	{"VA_AIF3_CAP Mixer", "DEC0", "VA DEC0 MUX"},1232	{"VA_AIF3_CAP Mixer", "DEC1", "VA DEC1 MUX"},1233	{"VA_AIF3_CAP Mixer", "DEC2", "VA DEC2 MUX"},1234	{"VA_AIF3_CAP Mixer", "DEC3", "VA DEC3 MUX"},1235 1236	{"VA DEC0 MUX", "VA_DMIC", "VA DMIC MUX0"},1237	{"VA DMIC MUX0", "DMIC0", "VA DMIC0"},1238	{"VA DMIC MUX0", "DMIC1", "VA DMIC1"},1239	{"VA DMIC MUX0", "DMIC2", "VA DMIC2"},1240	{"VA DMIC MUX0", "DMIC3", "VA DMIC3"},1241	{"VA DMIC MUX0", "DMIC4", "VA DMIC4"},1242	{"VA DMIC MUX0", "DMIC5", "VA DMIC5"},1243	{"VA DMIC MUX0", "DMIC6", "VA DMIC6"},1244	{"VA DMIC MUX0", "DMIC7", "VA DMIC7"},1245 1246	{"VA DEC1 MUX", "VA_DMIC", "VA DMIC MUX1"},1247	{"VA DMIC MUX1", "DMIC0", "VA DMIC0"},1248	{"VA DMIC MUX1", "DMIC1", "VA DMIC1"},1249	{"VA DMIC MUX1", "DMIC2", "VA DMIC2"},1250	{"VA DMIC MUX1", "DMIC3", "VA DMIC3"},1251	{"VA DMIC MUX1", "DMIC4", "VA DMIC4"},1252	{"VA DMIC MUX1", "DMIC5", "VA DMIC5"},1253	{"VA DMIC MUX1", "DMIC6", "VA DMIC6"},1254	{"VA DMIC MUX1", "DMIC7", "VA DMIC7"},1255 1256	{"VA DEC2 MUX", "VA_DMIC", "VA DMIC MUX2"},1257	{"VA DMIC MUX2", "DMIC0", "VA DMIC0"},1258	{"VA DMIC MUX2", "DMIC1", "VA DMIC1"},1259	{"VA DMIC MUX2", "DMIC2", "VA DMIC2"},1260	{"VA DMIC MUX2", "DMIC3", "VA DMIC3"},1261	{"VA DMIC MUX2", "DMIC4", "VA DMIC4"},1262	{"VA DMIC MUX2", "DMIC5", "VA DMIC5"},1263	{"VA DMIC MUX2", "DMIC6", "VA DMIC6"},1264	{"VA DMIC MUX2", "DMIC7", "VA DMIC7"},1265 1266	{"VA DEC3 MUX", "VA_DMIC", "VA DMIC MUX3"},1267	{"VA DMIC MUX3", "DMIC0", "VA DMIC0"},1268	{"VA DMIC MUX3", "DMIC1", "VA DMIC1"},1269	{"VA DMIC MUX3", "DMIC2", "VA DMIC2"},1270	{"VA DMIC MUX3", "DMIC3", "VA DMIC3"},1271	{"VA DMIC MUX3", "DMIC4", "VA DMIC4"},1272	{"VA DMIC MUX3", "DMIC5", "VA DMIC5"},1273	{"VA DMIC MUX3", "DMIC6", "VA DMIC6"},1274	{"VA DMIC MUX3", "DMIC7", "VA DMIC7"},1275 1276	{ "VA DMIC0", NULL, "DMIC0 Pin" },1277	{ "VA DMIC1", NULL, "DMIC1 Pin" },1278	{ "VA DMIC2", NULL, "DMIC2 Pin" },1279	{ "VA DMIC3", NULL, "DMIC3 Pin" },1280	{ "VA DMIC4", NULL, "DMIC4 Pin" },1281	{ "VA DMIC5", NULL, "DMIC5 Pin" },1282	{ "VA DMIC6", NULL, "DMIC6 Pin" },1283	{ "VA DMIC7", NULL, "DMIC7 Pin" },1284};1285 1286static const char * const dec_mode_mux_text[] = {1287	"ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",1288};1289 1290static const struct soc_enum dec_mode_mux_enum[] = {1291	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(dec_mode_mux_text),1292			dec_mode_mux_text),1293	SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(dec_mode_mux_text),1294			dec_mode_mux_text),1295	SOC_ENUM_SINGLE(SND_SOC_NOPM, 2,  ARRAY_SIZE(dec_mode_mux_text),1296			dec_mode_mux_text),1297	SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(dec_mode_mux_text),1298			dec_mode_mux_text),1299};1300 1301static const struct snd_kcontrol_new va_macro_snd_controls[] = {1302	SOC_SINGLE_S8_TLV("VA_DEC0 Volume", CDC_VA_TX0_TX_VOL_CTL,1303			  -84, 40, digital_gain),1304	SOC_SINGLE_S8_TLV("VA_DEC1 Volume", CDC_VA_TX1_TX_VOL_CTL,1305			  -84, 40, digital_gain),1306	SOC_SINGLE_S8_TLV("VA_DEC2 Volume", CDC_VA_TX2_TX_VOL_CTL,1307			  -84, 40, digital_gain),1308	SOC_SINGLE_S8_TLV("VA_DEC3 Volume", CDC_VA_TX3_TX_VOL_CTL,1309			  -84, 40, digital_gain),1310 1311	SOC_ENUM_EXT("VA_DEC0 MODE", dec_mode_mux_enum[0],1312		     va_macro_dec_mode_get, va_macro_dec_mode_put),1313	SOC_ENUM_EXT("VA_DEC1 MODE", dec_mode_mux_enum[1],1314		     va_macro_dec_mode_get, va_macro_dec_mode_put),1315	SOC_ENUM_EXT("VA_DEC2 MODE", dec_mode_mux_enum[2],1316		     va_macro_dec_mode_get, va_macro_dec_mode_put),1317	SOC_ENUM_EXT("VA_DEC3 MODE", dec_mode_mux_enum[3],1318		     va_macro_dec_mode_get, va_macro_dec_mode_put),1319};1320 1321static int va_macro_component_probe(struct snd_soc_component *component)1322{1323	struct va_macro *va = snd_soc_component_get_drvdata(component);1324 1325	snd_soc_component_init_regmap(component, va->regmap);1326 1327	return 0;1328}1329 1330static const struct snd_soc_component_driver va_macro_component_drv = {1331	.name = "VA MACRO",1332	.probe = va_macro_component_probe,1333	.controls = va_macro_snd_controls,1334	.num_controls = ARRAY_SIZE(va_macro_snd_controls),1335	.dapm_widgets = va_macro_dapm_widgets,1336	.num_dapm_widgets = ARRAY_SIZE(va_macro_dapm_widgets),1337	.dapm_routes = va_audio_map,1338	.num_dapm_routes = ARRAY_SIZE(va_audio_map),1339};1340 1341static int fsgen_gate_enable(struct clk_hw *hw)1342{1343	struct va_macro *va = to_va_macro(hw);1344	struct regmap *regmap = va->regmap;1345	int ret;1346 1347	if (va->has_swr_master) {1348		ret = clk_prepare_enable(va->mclk);1349		if (ret)1350			return ret;1351	}1352 1353	ret = va_macro_mclk_enable(va, true);1354	if (va->has_swr_master)1355		regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,1356				   CDC_VA_SWR_CLK_EN_MASK, CDC_VA_SWR_CLK_ENABLE);1357 1358	return ret;1359}1360 1361static void fsgen_gate_disable(struct clk_hw *hw)1362{1363	struct va_macro *va = to_va_macro(hw);1364	struct regmap *regmap = va->regmap;1365 1366	if (va->has_swr_master)1367		regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,1368			   CDC_VA_SWR_CLK_EN_MASK, 0x0);1369 1370	va_macro_mclk_enable(va, false);1371	if (va->has_swr_master)1372		clk_disable_unprepare(va->mclk);1373}1374 1375static int fsgen_gate_is_enabled(struct clk_hw *hw)1376{1377	struct va_macro *va = to_va_macro(hw);1378	int val;1379 1380	regmap_read(va->regmap, CDC_VA_TOP_CSR_TOP_CFG0, &val);1381 1382	return  !!(val & CDC_VA_FS_BROADCAST_EN);1383}1384 1385static const struct clk_ops fsgen_gate_ops = {1386	.prepare = fsgen_gate_enable,1387	.unprepare = fsgen_gate_disable,1388	.is_enabled = fsgen_gate_is_enabled,1389};1390 1391static int va_macro_register_fsgen_output(struct va_macro *va)1392{1393	struct clk *parent = va->mclk;1394	struct device *dev = va->dev;1395	struct device_node *np = dev->of_node;1396	const char *parent_clk_name;1397	const char *clk_name = "fsgen";1398	struct clk_init_data init;1399	int ret;1400 1401	if (va->has_npl_clk)1402		parent = va->npl;1403 1404	parent_clk_name = __clk_get_name(parent);1405 1406	of_property_read_string(np, "clock-output-names", &clk_name);1407 1408	init.name = clk_name;1409	init.ops = &fsgen_gate_ops;1410	init.flags = 0;1411	init.parent_names = &parent_clk_name;1412	init.num_parents = 1;1413	va->hw.init = &init;1414	ret = devm_clk_hw_register(va->dev, &va->hw);1415	if (ret)1416		return ret;1417 1418	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &va->hw);1419}1420 1421static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,1422					      struct va_macro *va)1423{1424	u32 div_factor;1425	u32 mclk_rate = VA_MACRO_MCLK_FREQ;1426 1427	if (!dmic_sample_rate || mclk_rate % dmic_sample_rate != 0)1428		goto undefined_rate;1429 1430	div_factor = mclk_rate / dmic_sample_rate;1431 1432	switch (div_factor) {1433	case 2:1434		va->dmic_clk_div = VA_MACRO_CLK_DIV_2;1435		break;1436	case 3:1437		va->dmic_clk_div = VA_MACRO_CLK_DIV_3;1438		break;1439	case 4:1440		va->dmic_clk_div = VA_MACRO_CLK_DIV_4;1441		break;1442	case 6:1443		va->dmic_clk_div = VA_MACRO_CLK_DIV_6;1444		break;1445	case 8:1446		va->dmic_clk_div = VA_MACRO_CLK_DIV_8;1447		break;1448	case 16:1449		va->dmic_clk_div = VA_MACRO_CLK_DIV_16;1450		break;1451	default:1452		/* Any other DIV factor is invalid */1453		goto undefined_rate;1454	}1455 1456	return dmic_sample_rate;1457 1458undefined_rate:1459	dev_err(va->dev, "%s: Invalid rate %d, for mclk %d\n",1460		__func__, dmic_sample_rate, mclk_rate);1461	dmic_sample_rate = 0;1462 1463	return dmic_sample_rate;1464}1465 1466static void va_macro_set_lpass_codec_version(struct va_macro *va)1467{1468	int core_id_0 = 0, core_id_1 = 0, core_id_2 = 0;1469	int version = LPASS_CODEC_VERSION_UNKNOWN;1470 1471	regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_0, &core_id_0);1472	regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_1, &core_id_1);1473	regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_2, &core_id_2);1474 1475	if ((core_id_0 == 0x01) && (core_id_1 == 0x0F))1476		version = LPASS_CODEC_VERSION_2_0;1477	if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && core_id_2 == 0x01)1478		version = LPASS_CODEC_VERSION_2_0;1479	if ((core_id_0 == 0x02) && (core_id_1 == 0x0E))1480		version = LPASS_CODEC_VERSION_2_1;1481	if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x50 || core_id_2 == 0x51))1482		version = LPASS_CODEC_VERSION_2_5;1483	if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x60 || core_id_2 == 0x61))1484		version = LPASS_CODEC_VERSION_2_6;1485	if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x70 || core_id_2 == 0x71))1486		version = LPASS_CODEC_VERSION_2_7;1487	if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x80 || core_id_2 == 0x81))1488		version = LPASS_CODEC_VERSION_2_8;1489 1490	if (version == LPASS_CODEC_VERSION_UNKNOWN)1491		dev_warn(va->dev, "Unknown Codec version, ID: %02x / %02x / %02x\n",1492			 core_id_0, core_id_1, core_id_2);1493 1494	lpass_macro_set_codec_version(version);1495 1496	dev_dbg(va->dev, "LPASS Codec Version %s\n", lpass_macro_get_codec_version_string(version));1497}1498 1499static int va_macro_probe(struct platform_device *pdev)1500{1501	struct device *dev = &pdev->dev;1502	const struct va_macro_data *data;1503	struct va_macro *va;1504	void __iomem *base;1505	u32 sample_rate = 0;1506	int ret;1507 1508	va = devm_kzalloc(dev, sizeof(*va), GFP_KERNEL);1509	if (!va)1510		return -ENOMEM;1511 1512	va->dev = dev;1513 1514	va->macro = devm_clk_get_optional(dev, "macro");1515	if (IS_ERR(va->macro))1516		return dev_err_probe(dev, PTR_ERR(va->macro), "unable to get macro clock\n");1517 1518	va->dcodec = devm_clk_get_optional(dev, "dcodec");1519	if (IS_ERR(va->dcodec))1520		return dev_err_probe(dev, PTR_ERR(va->dcodec), "unable to get dcodec clock\n");1521 1522	va->mclk = devm_clk_get(dev, "mclk");1523	if (IS_ERR(va->mclk))1524		return dev_err_probe(dev, PTR_ERR(va->mclk), "unable to get mclk clock\n");1525 1526	va->pds = lpass_macro_pds_init(dev);1527	if (IS_ERR(va->pds))1528		return PTR_ERR(va->pds);1529 1530	ret = of_property_read_u32(dev->of_node, "qcom,dmic-sample-rate",1531				   &sample_rate);1532	if (ret) {1533		dev_err(dev, "qcom,dmic-sample-rate dt entry missing\n");1534		va->dmic_clk_div = VA_MACRO_CLK_DIV_2;1535	} else {1536		ret = va_macro_validate_dmic_sample_rate(sample_rate, va);1537		if (!ret) {1538			ret = -EINVAL;1539			goto err;1540		}1541	}1542 1543	base = devm_platform_ioremap_resource(pdev, 0);1544	if (IS_ERR(base)) {1545		ret = PTR_ERR(base);1546		goto err;1547	}1548 1549	va->regmap = devm_regmap_init_mmio(dev, base,  &va_regmap_config);1550	if (IS_ERR(va->regmap)) {1551		ret = -EINVAL;1552		goto err;1553	}1554 1555	dev_set_drvdata(dev, va);1556 1557	data = of_device_get_match_data(dev);1558	va->has_swr_master = data->has_swr_master;1559	va->has_npl_clk = data->has_npl_clk;1560 1561	/* mclk rate */1562	clk_set_rate(va->mclk, 2 * VA_MACRO_MCLK_FREQ);1563 1564	if (va->has_npl_clk) {1565		va->npl = devm_clk_get(dev, "npl");1566		if (IS_ERR(va->npl)) {1567			ret = PTR_ERR(va->npl);1568			goto err;1569		}1570 1571		clk_set_rate(va->npl, 2 * VA_MACRO_MCLK_FREQ);1572	}1573 1574	ret = clk_prepare_enable(va->macro);1575	if (ret)1576		goto err;1577 1578	ret = clk_prepare_enable(va->dcodec);1579	if (ret)1580		goto err_dcodec;1581 1582	ret = clk_prepare_enable(va->mclk);1583	if (ret)1584		goto err_mclk;1585 1586	if (va->has_npl_clk) {1587		ret = clk_prepare_enable(va->npl);1588		if (ret)1589			goto err_npl;1590	}1591 1592	/**1593	 * old version of codecs do not have a reliable way to determine the1594	 * version from registers, get them from soc specific data1595	 */1596	if (data->version)1597		lpass_macro_set_codec_version(data->version);1598	else /* read version from register */1599		va_macro_set_lpass_codec_version(va);1600 1601	if (va->has_swr_master) {1602		/* Set default CLK div to 1 */1603		regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL0,1604				  CDC_VA_SWR_MIC_CLK_SEL_0_1_MASK,1605				  CDC_VA_SWR_MIC_CLK_SEL_0_1_DIV1);1606		regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL1,1607				  CDC_VA_SWR_MIC_CLK_SEL_0_1_MASK,1608				  CDC_VA_SWR_MIC_CLK_SEL_0_1_DIV1);1609		regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL2,1610				  CDC_VA_SWR_MIC_CLK_SEL_0_1_MASK,1611				  CDC_VA_SWR_MIC_CLK_SEL_0_1_DIV1);1612 1613	}1614 1615	if (va->has_swr_master) {1616		regmap_update_bits(va->regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,1617				   CDC_VA_SWR_RESET_MASK,  CDC_VA_SWR_RESET_ENABLE);1618		regmap_update_bits(va->regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,1619				   CDC_VA_SWR_CLK_EN_MASK, CDC_VA_SWR_CLK_ENABLE);1620		regmap_update_bits(va->regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,1621				   CDC_VA_SWR_RESET_MASK, 0x0);1622	}1623 1624	ret = devm_snd_soc_register_component(dev, &va_macro_component_drv,1625					      va_macro_dais,1626					      ARRAY_SIZE(va_macro_dais));1627	if (ret)1628		goto err_clkout;1629 1630	pm_runtime_set_autosuspend_delay(dev, 3000);1631	pm_runtime_use_autosuspend(dev);1632	pm_runtime_mark_last_busy(dev);1633	pm_runtime_set_active(dev);1634	pm_runtime_enable(dev);1635 1636	ret = va_macro_register_fsgen_output(va);1637	if (ret)1638		goto err_clkout;1639 1640	va->fsgen = clk_hw_get_clk(&va->hw, "fsgen");1641	if (IS_ERR(va->fsgen)) {1642		ret = PTR_ERR(va->fsgen);1643		goto err_clkout;1644	}1645 1646	return 0;1647 1648err_clkout:1649	if (va->has_npl_clk)1650		clk_disable_unprepare(va->npl);1651err_npl:1652	clk_disable_unprepare(va->mclk);1653err_mclk:1654	clk_disable_unprepare(va->dcodec);1655err_dcodec:1656	clk_disable_unprepare(va->macro);1657err:1658	lpass_macro_pds_exit(va->pds);1659 1660	return ret;1661}1662 1663static void va_macro_remove(struct platform_device *pdev)1664{1665	struct va_macro *va = dev_get_drvdata(&pdev->dev);1666 1667	if (va->has_npl_clk)1668		clk_disable_unprepare(va->npl);1669 1670	clk_disable_unprepare(va->mclk);1671	clk_disable_unprepare(va->dcodec);1672	clk_disable_unprepare(va->macro);1673 1674	lpass_macro_pds_exit(va->pds);1675}1676 1677static int __maybe_unused va_macro_runtime_suspend(struct device *dev)1678{1679	struct va_macro *va = dev_get_drvdata(dev);1680 1681	regcache_cache_only(va->regmap, true);1682	regcache_mark_dirty(va->regmap);1683 1684	if (va->has_npl_clk)1685		clk_disable_unprepare(va->npl);1686 1687	clk_disable_unprepare(va->mclk);1688 1689	return 0;1690}1691 1692static int __maybe_unused va_macro_runtime_resume(struct device *dev)1693{1694	struct va_macro *va = dev_get_drvdata(dev);1695	int ret;1696 1697	ret = clk_prepare_enable(va->mclk);1698	if (ret) {1699		dev_err(va->dev, "unable to prepare mclk\n");1700		return ret;1701	}1702 1703	if (va->has_npl_clk) {1704		ret = clk_prepare_enable(va->npl);1705		if (ret) {1706			clk_disable_unprepare(va->mclk);1707			dev_err(va->dev, "unable to prepare npl\n");1708			return ret;1709		}1710	}1711 1712	regcache_cache_only(va->regmap, false);1713	regcache_sync(va->regmap);1714 1715	return 0;1716}1717 1718 1719static const struct dev_pm_ops va_macro_pm_ops = {1720	SET_RUNTIME_PM_OPS(va_macro_runtime_suspend, va_macro_runtime_resume, NULL)1721};1722 1723static const struct of_device_id va_macro_dt_match[] = {1724	{ .compatible = "qcom,sc7280-lpass-va-macro", .data = &sm8250_va_data },1725	{ .compatible = "qcom,sm8250-lpass-va-macro", .data = &sm8250_va_data },1726	{ .compatible = "qcom,sm8450-lpass-va-macro", .data = &sm8450_va_data },1727	{ .compatible = "qcom,sm8550-lpass-va-macro", .data = &sm8550_va_data },1728	{ .compatible = "qcom,sc8280xp-lpass-va-macro", .data = &sm8450_va_data },1729	{}1730};1731MODULE_DEVICE_TABLE(of, va_macro_dt_match);1732 1733static struct platform_driver va_macro_driver = {1734	.driver = {1735		.name = "va_macro",1736		.of_match_table = va_macro_dt_match,1737		.suppress_bind_attrs = true,1738		.pm = &va_macro_pm_ops,1739	},1740	.probe = va_macro_probe,1741	.remove = va_macro_remove,1742};1743 1744module_platform_driver(va_macro_driver);1745MODULE_DESCRIPTION("VA macro driver");1746MODULE_LICENSE("GPL");1747