File Index
Files and directories
Sign in
FILE

msm8916-wcd-digital.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/codecs/msm8916-wcd-digital.c C
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2016, The Linux Foundation. All rights reserved.
   3
   4#include <linux/module.h>
   5#include <linux/err.h>
   6#include <linux/kernel.h>
   7#include <linux/delay.h>
   8#include <linux/types.h>
   9#include <linux/clk.h>
  10#include <linux/of.h>
  11#include <linux/platform_device.h>
  12#include <linux/regmap.h>
  13#include <linux/mfd/syscon.h>
  14#include <sound/soc.h>
  15#include <sound/pcm.h>
  16#include <sound/pcm_params.h>
  17#include <sound/tlv.h>
  18
  19#define LPASS_CDC_CLK_RX_RESET_CTL		(0x000)
  20#define LPASS_CDC_CLK_TX_RESET_B1_CTL		(0x004)
  21#define CLK_RX_RESET_B1_CTL_TX1_RESET_MASK	BIT(0)
  22#define CLK_RX_RESET_B1_CTL_TX2_RESET_MASK	BIT(1)
  23#define LPASS_CDC_CLK_DMIC_B1_CTL		(0x008)
  24#define DMIC_B1_CTL_DMIC0_CLK_SEL_MASK		GENMASK(3, 1)
  25#define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV2		(0x0 << 1)
  26#define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV3		(0x1 << 1)
  27#define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV4		(0x2 << 1)
  28#define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV6		(0x3 << 1)
  29#define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV16		(0x4 << 1)
  30#define DMIC_B1_CTL_DMIC0_CLK_EN_MASK		BIT(0)
  31#define DMIC_B1_CTL_DMIC0_CLK_EN_ENABLE		BIT(0)
  32
  33#define LPASS_CDC_CLK_RX_I2S_CTL		(0x00C)
  34#define RX_I2S_CTL_RX_I2S_MODE_MASK		BIT(5)
  35#define RX_I2S_CTL_RX_I2S_MODE_16		BIT(5)
  36#define RX_I2S_CTL_RX_I2S_MODE_32		0
  37#define RX_I2S_CTL_RX_I2S_FS_RATE_MASK		GENMASK(2, 0)
  38#define RX_I2S_CTL_RX_I2S_FS_RATE_F_8_KHZ	0x0
  39#define RX_I2S_CTL_RX_I2S_FS_RATE_F_16_KHZ	0x1
  40#define RX_I2S_CTL_RX_I2S_FS_RATE_F_32_KHZ	0x2
  41#define RX_I2S_CTL_RX_I2S_FS_RATE_F_48_KHZ	0x3
  42#define RX_I2S_CTL_RX_I2S_FS_RATE_F_96_KHZ	0x4
  43#define RX_I2S_CTL_RX_I2S_FS_RATE_F_192_KHZ	0x5
  44#define LPASS_CDC_CLK_TX_I2S_CTL		(0x010)
  45#define TX_I2S_CTL_TX_I2S_MODE_MASK		BIT(5)
  46#define TX_I2S_CTL_TX_I2S_MODE_16		BIT(5)
  47#define TX_I2S_CTL_TX_I2S_MODE_32		0
  48#define TX_I2S_CTL_TX_I2S_FS_RATE_MASK		GENMASK(2, 0)
  49#define TX_I2S_CTL_TX_I2S_FS_RATE_F_8_KHZ	0x0
  50#define TX_I2S_CTL_TX_I2S_FS_RATE_F_16_KHZ	0x1
  51#define TX_I2S_CTL_TX_I2S_FS_RATE_F_32_KHZ	0x2
  52#define TX_I2S_CTL_TX_I2S_FS_RATE_F_48_KHZ	0x3
  53#define TX_I2S_CTL_TX_I2S_FS_RATE_F_96_KHZ	0x4
  54#define TX_I2S_CTL_TX_I2S_FS_RATE_F_192_KHZ	0x5
  55
  56#define LPASS_CDC_CLK_OTHR_RESET_B1_CTL		(0x014)
  57#define LPASS_CDC_CLK_TX_CLK_EN_B1_CTL		(0x018)
  58#define LPASS_CDC_CLK_OTHR_CTL			(0x01C)
  59#define LPASS_CDC_CLK_RX_B1_CTL			(0x020)
  60#define LPASS_CDC_CLK_MCLK_CTL			(0x024)
  61#define MCLK_CTL_MCLK_EN_MASK			BIT(0)
  62#define MCLK_CTL_MCLK_EN_ENABLE			BIT(0)
  63#define MCLK_CTL_MCLK_EN_DISABLE		0
  64#define LPASS_CDC_CLK_PDM_CTL			(0x028)
  65#define LPASS_CDC_CLK_PDM_CTL_PDM_EN_MASK	BIT(0)
  66#define LPASS_CDC_CLK_PDM_CTL_PDM_EN		BIT(0)
  67#define LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK	BIT(1)
  68#define LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_FB	BIT(1)
  69#define LPASS_CDC_CLK_PDM_CTL_PDM_CLK_PDM_CLK	0
  70
  71#define LPASS_CDC_CLK_SD_CTL			(0x02C)
  72#define LPASS_CDC_RX1_B1_CTL			(0x040)
  73#define LPASS_CDC_RX2_B1_CTL			(0x060)
  74#define LPASS_CDC_RX3_B1_CTL			(0x080)
  75#define LPASS_CDC_RX1_B2_CTL			(0x044)
  76#define LPASS_CDC_RX2_B2_CTL			(0x064)
  77#define LPASS_CDC_RX3_B2_CTL			(0x084)
  78#define LPASS_CDC_RX1_B3_CTL			(0x048)
  79#define LPASS_CDC_RX2_B3_CTL			(0x068)
  80#define LPASS_CDC_RX3_B3_CTL			(0x088)
  81#define LPASS_CDC_RX1_B4_CTL			(0x04C)
  82#define LPASS_CDC_RX2_B4_CTL			(0x06C)
  83#define LPASS_CDC_RX3_B4_CTL			(0x08C)
  84#define LPASS_CDC_RX1_B5_CTL			(0x050)
  85#define LPASS_CDC_RX2_B5_CTL			(0x070)
  86#define LPASS_CDC_RX3_B5_CTL			(0x090)
  87#define LPASS_CDC_RX1_B6_CTL			(0x054)
  88#define RXn_B6_CTL_MUTE_MASK			BIT(0)
  89#define RXn_B6_CTL_MUTE_ENABLE			BIT(0)
  90#define RXn_B6_CTL_MUTE_DISABLE			0
  91#define LPASS_CDC_RX2_B6_CTL			(0x074)
  92#define LPASS_CDC_RX3_B6_CTL			(0x094)
  93#define LPASS_CDC_RX1_VOL_CTL_B1_CTL		(0x058)
  94#define LPASS_CDC_RX2_VOL_CTL_B1_CTL		(0x078)
  95#define LPASS_CDC_RX3_VOL_CTL_B1_CTL		(0x098)
  96#define LPASS_CDC_RX1_VOL_CTL_B2_CTL		(0x05C)
  97#define LPASS_CDC_RX2_VOL_CTL_B2_CTL		(0x07C)
  98#define LPASS_CDC_RX3_VOL_CTL_B2_CTL		(0x09C)
  99#define LPASS_CDC_TOP_GAIN_UPDATE		(0x0A0)
 100#define LPASS_CDC_TOP_CTL			(0x0A4)
 101#define TOP_CTL_DIG_MCLK_FREQ_MASK		BIT(0)
 102#define TOP_CTL_DIG_MCLK_FREQ_F_12_288MHZ	0
 103#define TOP_CTL_DIG_MCLK_FREQ_F_9_6MHZ		BIT(0)
 104
 105#define LPASS_CDC_DEBUG_DESER1_CTL		(0x0E0)
 106#define LPASS_CDC_DEBUG_DESER2_CTL		(0x0E4)
 107#define LPASS_CDC_DEBUG_B1_CTL_CFG		(0x0E8)
 108#define LPASS_CDC_DEBUG_B2_CTL_CFG		(0x0EC)
 109#define LPASS_CDC_DEBUG_B3_CTL_CFG		(0x0F0)
 110#define LPASS_CDC_IIR1_GAIN_B1_CTL		(0x100)
 111#define LPASS_CDC_IIR2_GAIN_B1_CTL		(0x140)
 112#define LPASS_CDC_IIR1_GAIN_B2_CTL		(0x104)
 113#define LPASS_CDC_IIR2_GAIN_B2_CTL		(0x144)
 114#define LPASS_CDC_IIR1_GAIN_B3_CTL		(0x108)
 115#define LPASS_CDC_IIR2_GAIN_B3_CTL		(0x148)
 116#define LPASS_CDC_IIR1_GAIN_B4_CTL		(0x10C)
 117#define LPASS_CDC_IIR2_GAIN_B4_CTL		(0x14C)
 118#define LPASS_CDC_IIR1_GAIN_B5_CTL		(0x110)
 119#define LPASS_CDC_IIR2_GAIN_B5_CTL		(0x150)
 120#define LPASS_CDC_IIR1_GAIN_B6_CTL		(0x114)
 121#define LPASS_CDC_IIR2_GAIN_B6_CTL		(0x154)
 122#define LPASS_CDC_IIR1_GAIN_B7_CTL		(0x118)
 123#define LPASS_CDC_IIR2_GAIN_B7_CTL		(0x158)
 124#define LPASS_CDC_IIR1_GAIN_B8_CTL		(0x11C)
 125#define LPASS_CDC_IIR2_GAIN_B8_CTL		(0x15C)
 126#define LPASS_CDC_IIR1_CTL			(0x120)
 127#define LPASS_CDC_IIR2_CTL			(0x160)
 128#define LPASS_CDC_IIR1_GAIN_TIMER_CTL		(0x124)
 129#define LPASS_CDC_IIR2_GAIN_TIMER_CTL		(0x164)
 130#define LPASS_CDC_IIR1_COEF_B1_CTL		(0x128)
 131#define LPASS_CDC_IIR2_COEF_B1_CTL		(0x168)
 132#define LPASS_CDC_IIR1_COEF_B2_CTL		(0x12C)
 133#define LPASS_CDC_IIR2_COEF_B2_CTL		(0x16C)
 134#define LPASS_CDC_CONN_RX1_B1_CTL		(0x180)
 135#define LPASS_CDC_CONN_RX1_B2_CTL		(0x184)
 136#define LPASS_CDC_CONN_RX1_B3_CTL		(0x188)
 137#define LPASS_CDC_CONN_RX2_B1_CTL		(0x18C)
 138#define LPASS_CDC_CONN_RX2_B2_CTL		(0x190)
 139#define LPASS_CDC_CONN_RX2_B3_CTL		(0x194)
 140#define LPASS_CDC_CONN_RX3_B1_CTL		(0x198)
 141#define LPASS_CDC_CONN_RX3_B2_CTL		(0x19C)
 142#define LPASS_CDC_CONN_TX_B1_CTL		(0x1A0)
 143#define LPASS_CDC_CONN_EQ1_B1_CTL		(0x1A8)
 144#define LPASS_CDC_CONN_EQ1_B2_CTL		(0x1AC)
 145#define LPASS_CDC_CONN_EQ1_B3_CTL		(0x1B0)
 146#define LPASS_CDC_CONN_EQ1_B4_CTL		(0x1B4)
 147#define LPASS_CDC_CONN_EQ2_B1_CTL		(0x1B8)
 148#define LPASS_CDC_CONN_EQ2_B2_CTL		(0x1BC)
 149#define LPASS_CDC_CONN_EQ2_B3_CTL		(0x1C0)
 150#define LPASS_CDC_CONN_EQ2_B4_CTL		(0x1C4)
 151#define LPASS_CDC_CONN_TX_I2S_SD1_CTL		(0x1C8)
 152#define LPASS_CDC_TX1_VOL_CTL_TIMER		(0x280)
 153#define LPASS_CDC_TX2_VOL_CTL_TIMER		(0x2A0)
 154#define LPASS_CDC_TX1_VOL_CTL_GAIN		(0x284)
 155#define LPASS_CDC_TX2_VOL_CTL_GAIN		(0x2A4)
 156#define LPASS_CDC_TX1_VOL_CTL_CFG		(0x288)
 157#define TX_VOL_CTL_CFG_MUTE_EN_MASK		BIT(0)
 158#define TX_VOL_CTL_CFG_MUTE_EN_ENABLE		BIT(0)
 159
 160#define LPASS_CDC_TX2_VOL_CTL_CFG		(0x2A8)
 161#define LPASS_CDC_TX1_MUX_CTL			(0x28C)
 162#define TX_MUX_CTL_CUT_OFF_FREQ_MASK		GENMASK(5, 4)
 163#define TX_MUX_CTL_CUT_OFF_FREQ_SHIFT		4
 164#define TX_MUX_CTL_CF_NEG_3DB_4HZ		(0x0 << 4)
 165#define TX_MUX_CTL_CF_NEG_3DB_75HZ		(0x1 << 4)
 166#define TX_MUX_CTL_CF_NEG_3DB_150HZ		(0x2 << 4)
 167#define TX_MUX_CTL_HPF_BP_SEL_MASK		BIT(3)
 168#define TX_MUX_CTL_HPF_BP_SEL_BYPASS		BIT(3)
 169#define TX_MUX_CTL_HPF_BP_SEL_NO_BYPASS		0
 170
 171#define LPASS_CDC_TX2_MUX_CTL			(0x2AC)
 172#define LPASS_CDC_TX1_CLK_FS_CTL		(0x290)
 173#define LPASS_CDC_TX2_CLK_FS_CTL		(0x2B0)
 174#define LPASS_CDC_TX1_DMIC_CTL			(0x294)
 175#define LPASS_CDC_TX2_DMIC_CTL			(0x2B4)
 176#define TXN_DMIC_CTL_CLK_SEL_MASK		GENMASK(2, 0)
 177#define TXN_DMIC_CTL_CLK_SEL_DIV2		0x0
 178#define TXN_DMIC_CTL_CLK_SEL_DIV3		0x1
 179#define TXN_DMIC_CTL_CLK_SEL_DIV4		0x2
 180#define TXN_DMIC_CTL_CLK_SEL_DIV6		0x3
 181#define TXN_DMIC_CTL_CLK_SEL_DIV16		0x4
 182
 183#define MSM8916_WCD_DIGITAL_RATES (SNDRV_PCM_RATE_8000 | \
 184				   SNDRV_PCM_RATE_16000 | \
 185				   SNDRV_PCM_RATE_32000 | \
 186				   SNDRV_PCM_RATE_48000)
 187#define MSM8916_WCD_DIGITAL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
 188				     SNDRV_PCM_FMTBIT_S32_LE)
 189
 190/* Codec supports 2 IIR filters */
 191enum {
 192	IIR1 = 0,
 193	IIR2,
 194	IIR_MAX,
 195};
 196
 197/* Codec supports 5 bands */
 198enum {
 199	BAND1 = 0,
 200	BAND2,
 201	BAND3,
 202	BAND4,
 203	BAND5,
 204	BAND_MAX,
 205};
 206
 207#define WCD_IIR_FILTER_SIZE	(sizeof(u32)*BAND_MAX)
 208
 209#define WCD_IIR_FILTER_CTL(xname, iidx, bidx) \
 210{       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 211	.info = wcd_iir_filter_info, \
 212	.get = msm8x16_wcd_get_iir_band_audio_mixer, \
 213	.put = msm8x16_wcd_put_iir_band_audio_mixer, \
 214	.private_value = (unsigned long)&(struct wcd_iir_filter_ctl) { \
 215		.iir_idx = iidx, \
 216		.band_idx = bidx, \
 217		.bytes_ext = {.max = WCD_IIR_FILTER_SIZE, }, \
 218	} \
 219}
 220
 221struct wcd_iir_filter_ctl {
 222	unsigned int iir_idx;
 223	unsigned int band_idx;
 224	struct soc_bytes_ext bytes_ext;
 225};
 226
 227struct msm8916_wcd_digital_priv {
 228	struct clk *ahbclk, *mclk;
 229};
 230
 231static const unsigned long rx_gain_reg[] = {
 232	LPASS_CDC_RX1_VOL_CTL_B2_CTL,
 233	LPASS_CDC_RX2_VOL_CTL_B2_CTL,
 234	LPASS_CDC_RX3_VOL_CTL_B2_CTL,
 235};
 236
 237static const unsigned long tx_gain_reg[] = {
 238	LPASS_CDC_TX1_VOL_CTL_GAIN,
 239	LPASS_CDC_TX2_VOL_CTL_GAIN,
 240};
 241
 242static const char *const rx_mix1_text[] = {
 243	"ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3"
 244};
 245
 246static const char * const rx_mix2_text[] = {
 247	"ZERO", "IIR1", "IIR2"
 248};
 249
 250static const char *const dec_mux_text[] = {
 251	"ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2"
 252};
 253
 254static const char *const cic_mux_text[] = { "AMIC", "DMIC" };
 255
 256/* RX1 MIX1 */
 257static const struct soc_enum rx_mix1_inp_enum[] = {
 258	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B1_CTL, 0, 6, rx_mix1_text),
 259	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B1_CTL, 3, 6, rx_mix1_text),
 260	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B2_CTL, 0, 6, rx_mix1_text),
 261};
 262
 263/* RX2 MIX1 */
 264static const struct soc_enum rx2_mix1_inp_enum[] = {
 265	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text),
 266	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 3, 6, rx_mix1_text),
 267	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B2_CTL, 0, 6, rx_mix1_text),
 268};
 269
 270/* RX3 MIX1 */
 271static const struct soc_enum rx3_mix1_inp_enum[] = {
 272	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text),
 273	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 3, 6, rx_mix1_text),
 274	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B2_CTL, 0, 6, rx_mix1_text),
 275};
 276
 277/* RX1 MIX2 */
 278static const struct soc_enum rx_mix2_inp1_chain_enum =
 279	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B3_CTL,
 280		0, 3, rx_mix2_text);
 281
 282/* RX2 MIX2 */
 283static const struct soc_enum rx2_mix2_inp1_chain_enum =
 284	SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B3_CTL,
 285		0, 3, rx_mix2_text);
 286
 287/* DEC */
 288static const struct soc_enum dec1_mux_enum = SOC_ENUM_SINGLE(
 289				LPASS_CDC_CONN_TX_B1_CTL, 0, 6, dec_mux_text);
 290static const struct soc_enum dec2_mux_enum = SOC_ENUM_SINGLE(
 291				LPASS_CDC_CONN_TX_B1_CTL, 3, 6, dec_mux_text);
 292
 293/* CIC */
 294static const struct soc_enum cic1_mux_enum = SOC_ENUM_SINGLE(
 295				LPASS_CDC_TX1_MUX_CTL, 0, 2, cic_mux_text);
 296static const struct soc_enum cic2_mux_enum = SOC_ENUM_SINGLE(
 297				LPASS_CDC_TX2_MUX_CTL, 0, 2, cic_mux_text);
 298
 299/* RDAC2 MUX */
 300static const struct snd_kcontrol_new dec1_mux = SOC_DAPM_ENUM(
 301				"DEC1 MUX Mux", dec1_mux_enum);
 302static const struct snd_kcontrol_new dec2_mux = SOC_DAPM_ENUM(
 303				"DEC2 MUX Mux",	dec2_mux_enum);
 304static const struct snd_kcontrol_new cic1_mux = SOC_DAPM_ENUM(
 305				"CIC1 MUX Mux", cic1_mux_enum);
 306static const struct snd_kcontrol_new cic2_mux = SOC_DAPM_ENUM(
 307				"CIC2 MUX Mux",	cic2_mux_enum);
 308static const struct snd_kcontrol_new rx_mix1_inp1_mux = SOC_DAPM_ENUM(
 309				"RX1 MIX1 INP1 Mux", rx_mix1_inp_enum[0]);
 310static const struct snd_kcontrol_new rx_mix1_inp2_mux = SOC_DAPM_ENUM(
 311				"RX1 MIX1 INP2 Mux", rx_mix1_inp_enum[1]);
 312static const struct snd_kcontrol_new rx_mix1_inp3_mux = SOC_DAPM_ENUM(
 313				"RX1 MIX1 INP3 Mux", rx_mix1_inp_enum[2]);
 314static const struct snd_kcontrol_new rx2_mix1_inp1_mux = SOC_DAPM_ENUM(
 315				"RX2 MIX1 INP1 Mux", rx2_mix1_inp_enum[0]);
 316static const struct snd_kcontrol_new rx2_mix1_inp2_mux = SOC_DAPM_ENUM(
 317				"RX2 MIX1 INP2 Mux", rx2_mix1_inp_enum[1]);
 318static const struct snd_kcontrol_new rx2_mix1_inp3_mux = SOC_DAPM_ENUM(
 319				"RX2 MIX1 INP3 Mux", rx2_mix1_inp_enum[2]);
 320static const struct snd_kcontrol_new rx3_mix1_inp1_mux = SOC_DAPM_ENUM(
 321				"RX3 MIX1 INP1 Mux", rx3_mix1_inp_enum[0]);
 322static const struct snd_kcontrol_new rx3_mix1_inp2_mux = SOC_DAPM_ENUM(
 323				"RX3 MIX1 INP2 Mux", rx3_mix1_inp_enum[1]);
 324static const struct snd_kcontrol_new rx3_mix1_inp3_mux = SOC_DAPM_ENUM(
 325				"RX3 MIX1 INP3 Mux", rx3_mix1_inp_enum[2]);
 326static const struct snd_kcontrol_new rx1_mix2_inp1_mux = SOC_DAPM_ENUM(
 327				"RX1 MIX2 INP1 Mux", rx_mix2_inp1_chain_enum);
 328static const struct snd_kcontrol_new rx2_mix2_inp1_mux = SOC_DAPM_ENUM(
 329				"RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
 330
 331/* Digital Gain control -84 dB to +40 dB in 1 dB steps */
 332static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
 333
 334/* Cutoff Freq for High Pass Filter at -3dB */
 335static const char * const hpf_cutoff_text[] = {
 336	"4Hz", "75Hz", "150Hz",
 337};
 338
 339static SOC_ENUM_SINGLE_DECL(tx1_hpf_cutoff_enum, LPASS_CDC_TX1_MUX_CTL, 4,
 340			    hpf_cutoff_text);
 341static SOC_ENUM_SINGLE_DECL(tx2_hpf_cutoff_enum, LPASS_CDC_TX2_MUX_CTL, 4,
 342			    hpf_cutoff_text);
 343
 344/* cut off for dc blocker inside rx chain */
 345static const char * const dc_blocker_cutoff_text[] = {
 346	"4Hz", "75Hz", "150Hz",
 347};
 348
 349static SOC_ENUM_SINGLE_DECL(rx1_dcb_cutoff_enum, LPASS_CDC_RX1_B4_CTL, 0,
 350			    dc_blocker_cutoff_text);
 351static SOC_ENUM_SINGLE_DECL(rx2_dcb_cutoff_enum, LPASS_CDC_RX2_B4_CTL, 0,
 352			    dc_blocker_cutoff_text);
 353static SOC_ENUM_SINGLE_DECL(rx3_dcb_cutoff_enum, LPASS_CDC_RX3_B4_CTL, 0,
 354			    dc_blocker_cutoff_text);
 355
 356static int msm8x16_wcd_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
 357		struct snd_kcontrol *kcontrol, int event)
 358{
 359	struct snd_soc_component *component =
 360			snd_soc_dapm_to_component(w->dapm);
 361	int value = 0, reg = 0;
 362
 363	switch (event) {
 364	case SND_SOC_DAPM_POST_PMU:
 365		if (w->shift == 0)
 366			reg = LPASS_CDC_IIR1_GAIN_B1_CTL;
 367		else if (w->shift == 1)
 368			reg = LPASS_CDC_IIR2_GAIN_B1_CTL;
 369		value = snd_soc_component_read(component, reg);
 370		snd_soc_component_write(component, reg, value);
 371		break;
 372	default:
 373		break;
 374	}
 375	return 0;
 376}
 377
 378static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
 379				   int iir_idx, int band_idx,
 380				   int coeff_idx)
 381{
 382	uint32_t value = 0;
 383
 384	/* Address does not automatically update if reading */
 385	snd_soc_component_write(component,
 386		(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
 387		((band_idx * BAND_MAX + coeff_idx)
 388		* sizeof(uint32_t)) & 0x7F);
 389
 390	value |= snd_soc_component_read(component,
 391		(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx));
 392
 393	snd_soc_component_write(component,
 394		(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
 395		((band_idx * BAND_MAX + coeff_idx)
 396		* sizeof(uint32_t) + 1) & 0x7F);
 397
 398	value |= (snd_soc_component_read(component,
 399		(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 8);
 400
 401	snd_soc_component_write(component,
 402		(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
 403		((band_idx * BAND_MAX + coeff_idx)
 404		* sizeof(uint32_t) + 2) & 0x7F);
 405
 406	value |= (snd_soc_component_read(component,
 407		(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 16);
 408
 409	snd_soc_component_write(component,
 410		(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
 411		((band_idx * BAND_MAX + coeff_idx)
 412		* sizeof(uint32_t) + 3) & 0x7F);
 413
 414	/* Mask bits top 2 bits since they are reserved */
 415	value |= ((snd_soc_component_read(component,
 416		 (LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) & 0x3f) << 24);
 417	return value;
 418
 419}
 420
 421static int msm8x16_wcd_get_iir_band_audio_mixer(
 422					struct snd_kcontrol *kcontrol,
 423					struct snd_ctl_elem_value *ucontrol)
 424{
 425
 426	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 427	struct wcd_iir_filter_ctl *ctl =
 428			(struct wcd_iir_filter_ctl *)kcontrol->private_value;
 429	struct soc_bytes_ext *params = &ctl->bytes_ext;
 430	int iir_idx = ctl->iir_idx;
 431	int band_idx = ctl->band_idx;
 432	u32 coeff[BAND_MAX];
 433
 434	coeff[0] = get_iir_band_coeff(component, iir_idx, band_idx, 0);
 435	coeff[1] = get_iir_band_coeff(component, iir_idx, band_idx, 1);
 436	coeff[2] = get_iir_band_coeff(component, iir_idx, band_idx, 2);
 437	coeff[3] = get_iir_band_coeff(component, iir_idx, band_idx, 3);
 438	coeff[4] = get_iir_band_coeff(component, iir_idx, band_idx, 4);
 439
 440	memcpy(ucontrol->value.bytes.data, &coeff[0], params->max);
 441
 442	return 0;
 443}
 444
 445static void set_iir_band_coeff(struct snd_soc_component *component,
 446				int iir_idx, int band_idx,
 447				uint32_t value)
 448{
 449	snd_soc_component_write(component,
 450		(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
 451		(value & 0xFF));
 452
 453	snd_soc_component_write(component,
 454		(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
 455		(value >> 8) & 0xFF);
 456
 457	snd_soc_component_write(component,
 458		(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
 459		(value >> 16) & 0xFF);
 460
 461	/* Mask top 2 bits, 7-8 are reserved */
 462	snd_soc_component_write(component,
 463		(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
 464		(value >> 24) & 0x3F);
 465}
 466
 467static int msm8x16_wcd_put_iir_band_audio_mixer(
 468					struct snd_kcontrol *kcontrol,
 469					struct snd_ctl_elem_value *ucontrol)
 470{
 471	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 472	struct wcd_iir_filter_ctl *ctl =
 473			(struct wcd_iir_filter_ctl *)kcontrol->private_value;
 474	struct soc_bytes_ext *params = &ctl->bytes_ext;
 475	int iir_idx = ctl->iir_idx;
 476	int band_idx = ctl->band_idx;
 477	u32 coeff[BAND_MAX];
 478
 479	memcpy(&coeff[0], ucontrol->value.bytes.data, params->max);
 480
 481	/* Mask top bit it is reserved */
 482	/* Updates addr automatically for each B2 write */
 483	snd_soc_component_write(component,
 484		(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
 485		(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
 486
 487	set_iir_band_coeff(component, iir_idx, band_idx, coeff[0]);
 488	set_iir_band_coeff(component, iir_idx, band_idx, coeff[1]);
 489	set_iir_band_coeff(component, iir_idx, band_idx, coeff[2]);
 490	set_iir_band_coeff(component, iir_idx, band_idx, coeff[3]);
 491	set_iir_band_coeff(component, iir_idx, band_idx, coeff[4]);
 492
 493	return 0;
 494}
 495
 496static int wcd_iir_filter_info(struct snd_kcontrol *kcontrol,
 497				struct snd_ctl_elem_info *ucontrol)
 498{
 499	struct wcd_iir_filter_ctl *ctl =
 500		(struct wcd_iir_filter_ctl *)kcontrol->private_value;
 501	struct soc_bytes_ext *params = &ctl->bytes_ext;
 502
 503	ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES;
 504	ucontrol->count = params->max;
 505
 506	return 0;
 507}
 508
 509static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
 510	SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL,
 511			-84, 40, digital_gain),
 512	SOC_SINGLE_S8_TLV("RX2 Digital Volume", LPASS_CDC_RX2_VOL_CTL_B2_CTL,
 513			-84, 40, digital_gain),
 514	SOC_SINGLE_S8_TLV("RX3 Digital Volume", LPASS_CDC_RX3_VOL_CTL_B2_CTL,
 515			-84, 40, digital_gain),
 516	SOC_SINGLE_S8_TLV("TX1 Digital Volume", LPASS_CDC_TX1_VOL_CTL_GAIN,
 517			-84, 40, digital_gain),
 518	SOC_SINGLE_S8_TLV("TX2 Digital Volume", LPASS_CDC_TX2_VOL_CTL_GAIN,
 519			-84, 40, digital_gain),
 520	SOC_ENUM("TX1 HPF Cutoff", tx1_hpf_cutoff_enum),
 521	SOC_ENUM("TX2 HPF Cutoff", tx2_hpf_cutoff_enum),
 522	SOC_SINGLE("TX1 HPF Switch", LPASS_CDC_TX1_MUX_CTL, 3, 1, 0),
 523	SOC_SINGLE("TX2 HPF Switch", LPASS_CDC_TX2_MUX_CTL, 3, 1, 0),
 524	SOC_ENUM("RX1 DCB Cutoff", rx1_dcb_cutoff_enum),
 525	SOC_ENUM("RX2 DCB Cutoff", rx2_dcb_cutoff_enum),
 526	SOC_ENUM("RX3 DCB Cutoff", rx3_dcb_cutoff_enum),
 527	SOC_SINGLE("RX1 DCB Switch", LPASS_CDC_RX1_B5_CTL, 2, 1, 0),
 528	SOC_SINGLE("RX2 DCB Switch", LPASS_CDC_RX2_B5_CTL, 2, 1, 0),
 529	SOC_SINGLE("RX3 DCB Switch", LPASS_CDC_RX3_B5_CTL, 2, 1, 0),
 530	SOC_SINGLE("RX1 Mute Switch", LPASS_CDC_RX1_B6_CTL, 0, 1, 0),
 531	SOC_SINGLE("RX2 Mute Switch", LPASS_CDC_RX2_B6_CTL, 0, 1, 0),
 532	SOC_SINGLE("RX3 Mute Switch", LPASS_CDC_RX3_B6_CTL, 0, 1, 0),
 533
 534	SOC_SINGLE("IIR1 Band1 Switch", LPASS_CDC_IIR1_CTL, 0, 1, 0),
 535	SOC_SINGLE("IIR1 Band2 Switch", LPASS_CDC_IIR1_CTL, 1, 1, 0),
 536	SOC_SINGLE("IIR1 Band3 Switch", LPASS_CDC_IIR1_CTL, 2, 1, 0),
 537	SOC_SINGLE("IIR1 Band4 Switch", LPASS_CDC_IIR1_CTL, 3, 1, 0),
 538	SOC_SINGLE("IIR1 Band5 Switch", LPASS_CDC_IIR1_CTL, 4, 1, 0),
 539	SOC_SINGLE("IIR2 Band1 Switch", LPASS_CDC_IIR2_CTL, 0, 1, 0),
 540	SOC_SINGLE("IIR2 Band2 Switch", LPASS_CDC_IIR2_CTL, 1, 1, 0),
 541	SOC_SINGLE("IIR2 Band3 Switch", LPASS_CDC_IIR2_CTL, 2, 1, 0),
 542	SOC_SINGLE("IIR2 Band4 Switch", LPASS_CDC_IIR2_CTL, 3, 1, 0),
 543	SOC_SINGLE("IIR2 Band5 Switch", LPASS_CDC_IIR2_CTL, 4, 1, 0),
 544	WCD_IIR_FILTER_CTL("IIR1 Band1", IIR1, BAND1),
 545	WCD_IIR_FILTER_CTL("IIR1 Band2", IIR1, BAND2),
 546	WCD_IIR_FILTER_CTL("IIR1 Band3", IIR1, BAND3),
 547	WCD_IIR_FILTER_CTL("IIR1 Band4", IIR1, BAND4),
 548	WCD_IIR_FILTER_CTL("IIR1 Band5", IIR1, BAND5),
 549	WCD_IIR_FILTER_CTL("IIR2 Band1", IIR2, BAND1),
 550	WCD_IIR_FILTER_CTL("IIR2 Band2", IIR2, BAND2),
 551	WCD_IIR_FILTER_CTL("IIR2 Band3", IIR2, BAND3),
 552	WCD_IIR_FILTER_CTL("IIR2 Band4", IIR2, BAND4),
 553	WCD_IIR_FILTER_CTL("IIR2 Band5", IIR2, BAND5),
 554	SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL,
 555			-84, 40, digital_gain),
 556	SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL,
 557			-84, 40, digital_gain),
 558	SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL,
 559			-84, 40, digital_gain),
 560	SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL,
 561			-84, 40, digital_gain),
 562	SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL,
 563			-84, 40, digital_gain),
 564	SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL,
 565			-84, 40, digital_gain),
 566	SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL,
 567			-84, 40, digital_gain),
 568	SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL,
 569			-84, 40, digital_gain),
 570
 571};
 572
 573static int msm8916_wcd_digital_enable_interpolator(
 574						struct snd_soc_dapm_widget *w,
 575						struct snd_kcontrol *kcontrol,
 576						int event)
 577{
 578	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 579
 580	switch (event) {
 581	case SND_SOC_DAPM_POST_PMU:
 582		/* apply the digital gain after the interpolator is enabled */
 583		usleep_range(10000, 10100);
 584		snd_soc_component_write(component, rx_gain_reg[w->shift],
 585			      snd_soc_component_read(component, rx_gain_reg[w->shift]));
 586		break;
 587	case SND_SOC_DAPM_POST_PMD:
 588		snd_soc_component_update_bits(component, LPASS_CDC_CLK_RX_RESET_CTL,
 589					      1 << w->shift, 1 << w->shift);
 590		snd_soc_component_update_bits(component, LPASS_CDC_CLK_RX_RESET_CTL,
 591					      1 << w->shift, 0x0);
 592		break;
 593	}
 594	return 0;
 595}
 596
 597static int msm8916_wcd_digital_enable_dec(struct snd_soc_dapm_widget *w,
 598					  struct snd_kcontrol *kcontrol,
 599					  int event)
 600{
 601	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 602	unsigned int decimator = w->shift + 1;
 603	u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
 604	u8 dec_hpf_cut_of_freq;
 605
 606	dec_reset_reg = LPASS_CDC_CLK_TX_RESET_B1_CTL;
 607	tx_vol_ctl_reg = LPASS_CDC_TX1_VOL_CTL_CFG + 32 * (decimator - 1);
 608	tx_mux_ctl_reg = LPASS_CDC_TX1_MUX_CTL + 32 * (decimator - 1);
 609
 610	switch (event) {
 611	case SND_SOC_DAPM_PRE_PMU:
 612		/* Enable TX digital mute */
 613		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 614				    TX_VOL_CTL_CFG_MUTE_EN_MASK,
 615				    TX_VOL_CTL_CFG_MUTE_EN_ENABLE);
 616		dec_hpf_cut_of_freq = snd_soc_component_read(component, tx_mux_ctl_reg) &
 617					TX_MUX_CTL_CUT_OFF_FREQ_MASK;
 618		dec_hpf_cut_of_freq >>= TX_MUX_CTL_CUT_OFF_FREQ_SHIFT;
 619		if (dec_hpf_cut_of_freq != TX_MUX_CTL_CF_NEG_3DB_150HZ) {
 620			/* set cut of freq to CF_MIN_3DB_150HZ (0x1) */
 621			snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 622					    TX_MUX_CTL_CUT_OFF_FREQ_MASK,
 623					    TX_MUX_CTL_CF_NEG_3DB_150HZ);
 624		}
 625		break;
 626	case SND_SOC_DAPM_POST_PMU:
 627		/* enable HPF */
 628		snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 629				    TX_MUX_CTL_HPF_BP_SEL_MASK,
 630				    TX_MUX_CTL_HPF_BP_SEL_NO_BYPASS);
 631		/* apply the digital gain after the decimator is enabled */
 632		snd_soc_component_write(component, tx_gain_reg[w->shift],
 633			      snd_soc_component_read(component, tx_gain_reg[w->shift]));
 634		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 635				    TX_VOL_CTL_CFG_MUTE_EN_MASK, 0);
 636		break;
 637	case SND_SOC_DAPM_PRE_PMD:
 638		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 639				    TX_VOL_CTL_CFG_MUTE_EN_MASK,
 640				    TX_VOL_CTL_CFG_MUTE_EN_ENABLE);
 641		snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 642				    TX_MUX_CTL_HPF_BP_SEL_MASK,
 643				    TX_MUX_CTL_HPF_BP_SEL_BYPASS);
 644		break;
 645	case SND_SOC_DAPM_POST_PMD:
 646		snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift,
 647				    1 << w->shift);
 648		snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift, 0x0);
 649		snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 650				    TX_MUX_CTL_HPF_BP_SEL_MASK,
 651				    TX_MUX_CTL_HPF_BP_SEL_BYPASS);
 652		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 653				    TX_VOL_CTL_CFG_MUTE_EN_MASK, 0);
 654		break;
 655	}
 656
 657	return 0;
 658}
 659
 660static int msm8916_wcd_digital_enable_dmic(struct snd_soc_dapm_widget *w,
 661					   struct snd_kcontrol *kcontrol,
 662					   int event)
 663{
 664	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 665	unsigned int dmic;
 666	int ret;
 667	/* get dmic number out of widget name */
 668	char *dmic_num = strpbrk(w->name, "12");
 669
 670	if (dmic_num == NULL) {
 671		dev_err(component->dev, "Invalid DMIC\n");
 672		return -EINVAL;
 673	}
 674	ret = kstrtouint(dmic_num, 10, &dmic);
 675	if (ret < 0 || dmic > 2) {
 676		dev_err(component->dev, "Invalid DMIC line on the component\n");
 677		return -EINVAL;
 678	}
 679
 680	switch (event) {
 681	case SND_SOC_DAPM_PRE_PMU:
 682		snd_soc_component_update_bits(component, LPASS_CDC_CLK_DMIC_B1_CTL,
 683				    DMIC_B1_CTL_DMIC0_CLK_SEL_MASK,
 684				    DMIC_B1_CTL_DMIC0_CLK_SEL_DIV3);
 685		switch (dmic) {
 686		case 1:
 687			snd_soc_component_update_bits(component, LPASS_CDC_TX1_DMIC_CTL,
 688					    TXN_DMIC_CTL_CLK_SEL_MASK,
 689					    TXN_DMIC_CTL_CLK_SEL_DIV3);
 690			break;
 691		case 2:
 692			snd_soc_component_update_bits(component, LPASS_CDC_TX2_DMIC_CTL,
 693					    TXN_DMIC_CTL_CLK_SEL_MASK,
 694					    TXN_DMIC_CTL_CLK_SEL_DIV3);
 695			break;
 696		}
 697		break;
 698	}
 699
 700	return 0;
 701}
 702
 703static const char * const iir_inp1_text[] = {
 704	"ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3"
 705};
 706
 707static const struct soc_enum iir1_inp1_mux_enum =
 708	SOC_ENUM_SINGLE(LPASS_CDC_CONN_EQ1_B1_CTL,
 709		0, 6, iir_inp1_text);
 710
 711static const struct soc_enum iir2_inp1_mux_enum =
 712	SOC_ENUM_SINGLE(LPASS_CDC_CONN_EQ2_B1_CTL,
 713		0, 6, iir_inp1_text);
 714
 715static const struct snd_kcontrol_new iir1_inp1_mux =
 716	SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
 717
 718static const struct snd_kcontrol_new iir2_inp1_mux =
 719	SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
 720
 721static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = {
 722	/*RX stuff */
 723	SND_SOC_DAPM_AIF_IN("I2S RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
 724	SND_SOC_DAPM_AIF_IN("I2S RX2", NULL, 0, SND_SOC_NOPM, 0, 0),
 725	SND_SOC_DAPM_AIF_IN("I2S RX3", NULL, 0, SND_SOC_NOPM, 0, 0),
 726
 727	SND_SOC_DAPM_OUTPUT("PDM_RX1"),
 728	SND_SOC_DAPM_OUTPUT("PDM_RX2"),
 729	SND_SOC_DAPM_OUTPUT("PDM_RX3"),
 730
 731	SND_SOC_DAPM_INPUT("LPASS_PDM_TX"),
 732
 733	SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 734	SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 735	SND_SOC_DAPM_MIXER("RX3 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 736
 737	/* Interpolator */
 738	SND_SOC_DAPM_MIXER_E("RX1 INT", LPASS_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
 739			     0, msm8916_wcd_digital_enable_interpolator,
 740			     SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 741	SND_SOC_DAPM_MIXER_E("RX2 INT", LPASS_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
 742			     0, msm8916_wcd_digital_enable_interpolator,
 743			     SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 744	SND_SOC_DAPM_MIXER_E("RX3 INT", LPASS_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
 745			     0, msm8916_wcd_digital_enable_interpolator,
 746			     SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 747	SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
 748			 &rx_mix1_inp1_mux),
 749	SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
 750			 &rx_mix1_inp2_mux),
 751	SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
 752			 &rx_mix1_inp3_mux),
 753	SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
 754			 &rx2_mix1_inp1_mux),
 755	SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
 756			 &rx2_mix1_inp2_mux),
 757	SND_SOC_DAPM_MUX("RX2 MIX1 INP3", SND_SOC_NOPM, 0, 0,
 758			 &rx2_mix1_inp3_mux),
 759	SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
 760			 &rx3_mix1_inp1_mux),
 761	SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
 762			 &rx3_mix1_inp2_mux),
 763	SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0,
 764			 &rx3_mix1_inp3_mux),
 765	SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0,
 766			 &rx1_mix2_inp1_mux),
 767	SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
 768			 &rx2_mix2_inp1_mux),
 769
 770	SND_SOC_DAPM_MUX("CIC1 MUX", SND_SOC_NOPM, 0, 0, &cic1_mux),
 771	SND_SOC_DAPM_MUX("CIC2 MUX", SND_SOC_NOPM, 0, 0, &cic2_mux),
 772	/* TX */
 773	SND_SOC_DAPM_MIXER("ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
 774	SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
 775	SND_SOC_DAPM_MIXER("ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
 776
 777	SND_SOC_DAPM_MUX_E("DEC1 MUX", LPASS_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
 778			   &dec1_mux, msm8916_wcd_digital_enable_dec,
 779			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 780			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
 781	SND_SOC_DAPM_MUX_E("DEC2 MUX", LPASS_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
 782			   &dec2_mux, msm8916_wcd_digital_enable_dec,
 783			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 784			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
 785	SND_SOC_DAPM_AIF_OUT("I2S TX1", NULL, 0, SND_SOC_NOPM, 0, 0),
 786	SND_SOC_DAPM_AIF_OUT("I2S TX2", NULL, 0, SND_SOC_NOPM, 0, 0),
 787	SND_SOC_DAPM_AIF_OUT("I2S TX3", NULL, 0, SND_SOC_NOPM, 0, 0),
 788
 789	/* Digital Mic Inputs */
 790	SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
 791			   msm8916_wcd_digital_enable_dmic,
 792			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 793	SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
 794			   msm8916_wcd_digital_enable_dmic,
 795			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 796	SND_SOC_DAPM_SUPPLY("DMIC_CLK", LPASS_CDC_CLK_DMIC_B1_CTL, 0, 0,
 797			    NULL, 0),
 798	SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", LPASS_CDC_CLK_RX_I2S_CTL,
 799			    4, 0, NULL, 0),
 800	SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", LPASS_CDC_CLK_TX_I2S_CTL, 4, 0,
 801			    NULL, 0),
 802
 803	SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, NULL, 0),
 804	SND_SOC_DAPM_SUPPLY("PDM_CLK", LPASS_CDC_CLK_PDM_CTL, 0, 0, NULL, 0),
 805	/* Connectivity Clock */
 806	SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, LPASS_CDC_CLK_OTHR_CTL, 2, 0,
 807			      NULL, 0),
 808	SND_SOC_DAPM_MIC("Digital Mic1", NULL),
 809	SND_SOC_DAPM_MIC("Digital Mic2", NULL),
 810
 811	/* Sidetone */
 812	SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
 813	SND_SOC_DAPM_PGA_E("IIR1", LPASS_CDC_CLK_SD_CTL, 0, 0, NULL, 0,
 814		msm8x16_wcd_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
 815
 816	SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux),
 817	SND_SOC_DAPM_PGA_E("IIR2", LPASS_CDC_CLK_SD_CTL, 1, 0, NULL, 0,
 818		msm8x16_wcd_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
 819
 820};
 821
 822static int msm8916_wcd_digital_get_clks(struct platform_device *pdev,
 823					struct msm8916_wcd_digital_priv	*priv)
 824{
 825	struct device *dev = &pdev->dev;
 826
 827	priv->ahbclk = devm_clk_get(dev, "ahbix-clk");
 828	if (IS_ERR(priv->ahbclk)) {
 829		dev_err(dev, "failed to get ahbix clk\n");
 830		return PTR_ERR(priv->ahbclk);
 831	}
 832
 833	priv->mclk = devm_clk_get(dev, "mclk");
 834	if (IS_ERR(priv->mclk)) {
 835		dev_err(dev, "failed to get mclk\n");
 836		return PTR_ERR(priv->mclk);
 837	}
 838
 839	return 0;
 840}
 841
 842static int msm8916_wcd_digital_component_probe(struct snd_soc_component *component)
 843{
 844	struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(component->dev);
 845
 846	snd_soc_component_set_drvdata(component, priv);
 847
 848	return 0;
 849}
 850
 851static int msm8916_wcd_digital_component_set_sysclk(struct snd_soc_component *component,
 852						int clk_id, int source,
 853						unsigned int freq, int dir)
 854{
 855	struct msm8916_wcd_digital_priv *p = dev_get_drvdata(component->dev);
 856
 857	return clk_set_rate(p->mclk, freq);
 858}
 859
 860static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream,
 861					 struct snd_pcm_hw_params *params,
 862					 struct snd_soc_dai *dai)
 863{
 864	u8 tx_fs_rate;
 865	u8 rx_fs_rate;
 866
 867	switch (params_rate(params)) {
 868	case 8000:
 869		tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_8_KHZ;
 870		rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_8_KHZ;
 871		break;
 872	case 16000:
 873		tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_16_KHZ;
 874		rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_16_KHZ;
 875		break;
 876	case 32000:
 877		tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_32_KHZ;
 878		rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_32_KHZ;
 879		break;
 880	case 48000:
 881		tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_48_KHZ;
 882		rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_48_KHZ;
 883		break;
 884	default:
 885		dev_err(dai->component->dev, "Invalid sampling rate %d\n",
 886			params_rate(params));
 887		return -EINVAL;
 888	}
 889
 890	switch (substream->stream) {
 891	case SNDRV_PCM_STREAM_CAPTURE:
 892		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
 893				    TX_I2S_CTL_TX_I2S_FS_RATE_MASK, tx_fs_rate);
 894		break;
 895	case SNDRV_PCM_STREAM_PLAYBACK:
 896		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
 897				    RX_I2S_CTL_RX_I2S_FS_RATE_MASK, rx_fs_rate);
 898		break;
 899	default:
 900		return -EINVAL;
 901	}
 902
 903	switch (params_format(params)) {
 904	case SNDRV_PCM_FORMAT_S16_LE:
 905		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
 906				    TX_I2S_CTL_TX_I2S_MODE_MASK,
 907				    TX_I2S_CTL_TX_I2S_MODE_16);
 908		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
 909				    RX_I2S_CTL_RX_I2S_MODE_MASK,
 910				    RX_I2S_CTL_RX_I2S_MODE_16);
 911		break;
 912
 913	case SNDRV_PCM_FORMAT_S32_LE:
 914		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
 915				    TX_I2S_CTL_TX_I2S_MODE_MASK,
 916				    TX_I2S_CTL_TX_I2S_MODE_32);
 917		snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
 918				    RX_I2S_CTL_RX_I2S_MODE_MASK,
 919				    RX_I2S_CTL_RX_I2S_MODE_32);
 920		break;
 921	default:
 922		dev_err(dai->dev, "%s: wrong format selected\n", __func__);
 923		return -EINVAL;
 924	}
 925
 926	return 0;
 927}
 928
 929static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
 930
 931	{"I2S RX1",  NULL, "AIF1 Playback"},
 932	{"I2S RX2",  NULL, "AIF1 Playback"},
 933	{"I2S RX3",  NULL, "AIF1 Playback"},
 934
 935	{"AIF1 Capture", NULL, "I2S TX1"},
 936	{"AIF1 Capture", NULL, "I2S TX2"},
 937	{"AIF1 Capture", NULL, "I2S TX3"},
 938
 939	{"CIC1 MUX", "DMIC", "DEC1 MUX"},
 940	{"CIC1 MUX", "AMIC", "DEC1 MUX"},
 941	{"CIC2 MUX", "DMIC", "DEC2 MUX"},
 942	{"CIC2 MUX", "AMIC", "DEC2 MUX"},
 943
 944	/* Decimator Inputs */
 945	{"DEC1 MUX", "DMIC1", "DMIC1"},
 946	{"DEC1 MUX", "DMIC2", "DMIC2"},
 947	{"DEC1 MUX", "ADC1", "ADC1"},
 948	{"DEC1 MUX", "ADC2", "ADC2"},
 949	{"DEC1 MUX", "ADC3", "ADC3"},
 950	{"DEC1 MUX", NULL, "CDC_CONN"},
 951
 952	{"DEC2 MUX", "DMIC1", "DMIC1"},
 953	{"DEC2 MUX", "DMIC2", "DMIC2"},
 954	{"DEC2 MUX", "ADC1", "ADC1"},
 955	{"DEC2 MUX", "ADC2", "ADC2"},
 956	{"DEC2 MUX", "ADC3", "ADC3"},
 957	{"DEC2 MUX", NULL, "CDC_CONN"},
 958
 959	{"DMIC1", NULL, "DMIC_CLK"},
 960	{"DMIC2", NULL, "DMIC_CLK"},
 961
 962	{"I2S TX1", NULL, "CIC1 MUX"},
 963	{"I2S TX2", NULL, "CIC2 MUX"},
 964
 965	{"I2S TX1", NULL, "TX_I2S_CLK"},
 966	{"I2S TX2", NULL, "TX_I2S_CLK"},
 967
 968	{"TX_I2S_CLK", NULL, "MCLK"},
 969	{"TX_I2S_CLK", NULL, "PDM_CLK"},
 970
 971	{"ADC1", NULL, "LPASS_PDM_TX"},
 972	{"ADC2", NULL, "LPASS_PDM_TX"},
 973	{"ADC3", NULL, "LPASS_PDM_TX"},
 974
 975	{"I2S RX1", NULL, "RX_I2S_CLK"},
 976	{"I2S RX2", NULL, "RX_I2S_CLK"},
 977	{"I2S RX3", NULL, "RX_I2S_CLK"},
 978
 979	{"RX_I2S_CLK", NULL, "PDM_CLK"},
 980	{"RX_I2S_CLK", NULL, "MCLK"},
 981	{"RX_I2S_CLK", NULL, "CDC_CONN"},
 982
 983	/* RX1 PATH.. */
 984	{"PDM_RX1", NULL, "RX1 INT"},
 985	{"RX1 INT", NULL, "RX1 MIX1"},
 986
 987	{"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
 988	{"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
 989	{"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
 990
 991	{"RX1 MIX1 INP1", "RX1", "I2S RX1"},
 992	{"RX1 MIX1 INP1", "RX2", "I2S RX2"},
 993	{"RX1 MIX1 INP1", "RX3", "I2S RX3"},
 994	{"RX1 MIX1 INP1", "IIR1", "IIR1"},
 995	{"RX1 MIX1 INP1", "IIR2", "IIR2"},
 996
 997	{"RX1 MIX1 INP2", "RX1", "I2S RX1"},
 998	{"RX1 MIX1 INP2", "RX2", "I2S RX2"},
 999	{"RX1 MIX1 INP2", "RX3", "I2S RX3"},
1000	{"RX1 MIX1 INP2", "IIR1", "IIR1"},
1001	{"RX1 MIX1 INP2", "IIR2", "IIR2"},
1002
1003	{"RX1 MIX1 INP3", "RX1", "I2S RX1"},
1004	{"RX1 MIX1 INP3", "RX2", "I2S RX2"},
1005	{"RX1 MIX1 INP3", "RX3", "I2S RX3"},
1006
1007	/* RX2 PATH */
1008	{"PDM_RX2", NULL, "RX2 INT"},
1009	{"RX2 INT", NULL, "RX2 MIX1"},
1010
1011	{"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
1012	{"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
1013	{"RX2 MIX1", NULL, "RX2 MIX1 INP3"},
1014
1015	{"RX2 MIX1 INP1", "RX1", "I2S RX1"},
1016	{"RX2 MIX1 INP1", "RX2", "I2S RX2"},
1017	{"RX2 MIX1 INP1", "RX3", "I2S RX3"},
1018	{"RX2 MIX1 INP1", "IIR1", "IIR1"},
1019	{"RX2 MIX1 INP1", "IIR2", "IIR2"},
1020
1021	{"RX2 MIX1 INP2", "RX1", "I2S RX1"},
1022	{"RX2 MIX1 INP2", "RX2", "I2S RX2"},
1023	{"RX2 MIX1 INP2", "RX3", "I2S RX3"},
1024	{"RX2 MIX1 INP1", "IIR1", "IIR1"},
1025	{"RX2 MIX1 INP1", "IIR2", "IIR2"},
1026
1027	{"RX2 MIX1 INP3", "RX1", "I2S RX1"},
1028	{"RX2 MIX1 INP3", "RX2", "I2S RX2"},
1029	{"RX2 MIX1 INP3", "RX3", "I2S RX3"},
1030
1031	/* RX3 PATH */
1032	{"PDM_RX3", NULL, "RX3 INT"},
1033	{"RX3 INT", NULL, "RX3 MIX1"},
1034
1035	{"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
1036	{"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
1037	{"RX3 MIX1", NULL, "RX3 MIX1 INP3"},
1038
1039	{"RX3 MIX1 INP1", "RX1", "I2S RX1"},
1040	{"RX3 MIX1 INP1", "RX2", "I2S RX2"},
1041	{"RX3 MIX1 INP1", "RX3", "I2S RX3"},
1042	{"RX3 MIX1 INP1", "IIR1", "IIR1"},
1043	{"RX3 MIX1 INP1", "IIR2", "IIR2"},
1044
1045	{"RX3 MIX1 INP2", "RX1", "I2S RX1"},
1046	{"RX3 MIX1 INP2", "RX2", "I2S RX2"},
1047	{"RX3 MIX1 INP2", "RX3", "I2S RX3"},
1048	{"RX3 MIX1 INP2", "IIR1", "IIR1"},
1049	{"RX3 MIX1 INP2", "IIR2", "IIR2"},
1050
1051	{"RX1 MIX2 INP1", "IIR1", "IIR1"},
1052	{"RX2 MIX2 INP1", "IIR1", "IIR1"},
1053	{"RX1 MIX2 INP1", "IIR2", "IIR2"},
1054	{"RX2 MIX2 INP1", "IIR2", "IIR2"},
1055
1056	{"IIR1", NULL, "IIR1 INP1 MUX"},
1057	{"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
1058	{"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
1059
1060	{"IIR2", NULL, "IIR2 INP1 MUX"},
1061	{"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"},
1062	{"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"},
1063
1064	{"RX3 MIX1 INP3", "RX1", "I2S RX1"},
1065	{"RX3 MIX1 INP3", "RX2", "I2S RX2"},
1066	{"RX3 MIX1 INP3", "RX3", "I2S RX3"},
1067
1068};
1069
1070static int msm8916_wcd_digital_startup(struct snd_pcm_substream *substream,
1071				       struct snd_soc_dai *dai)
1072{
1073	struct snd_soc_component *component = dai->component;
1074	struct msm8916_wcd_digital_priv *msm8916_wcd;
1075	unsigned long mclk_rate;
1076
1077	msm8916_wcd = snd_soc_component_get_drvdata(component);
1078	snd_soc_component_update_bits(component, LPASS_CDC_CLK_MCLK_CTL,
1079			    MCLK_CTL_MCLK_EN_MASK,
1080			    MCLK_CTL_MCLK_EN_ENABLE);
1081	snd_soc_component_update_bits(component, LPASS_CDC_CLK_PDM_CTL,
1082			    LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK,
1083			    LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_FB);
1084
1085	mclk_rate = clk_get_rate(msm8916_wcd->mclk);
1086	switch (mclk_rate) {
1087	case 12288000:
1088		snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL,
1089				    TOP_CTL_DIG_MCLK_FREQ_MASK,
1090				    TOP_CTL_DIG_MCLK_FREQ_F_12_288MHZ);
1091		break;
1092	case 9600000:
1093		snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL,
1094				    TOP_CTL_DIG_MCLK_FREQ_MASK,
1095				    TOP_CTL_DIG_MCLK_FREQ_F_9_6MHZ);
1096		break;
1097	default:
1098		dev_err(component->dev, "Invalid mclk rate %ld\n", mclk_rate);
1099		break;
1100	}
1101	return 0;
1102}
1103
1104static void msm8916_wcd_digital_shutdown(struct snd_pcm_substream *substream,
1105					 struct snd_soc_dai *dai)
1106{
1107	snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_PDM_CTL,
1108			    LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK, 0);
1109}
1110
1111static const struct snd_soc_dai_ops msm8916_wcd_digital_dai_ops = {
1112	.startup = msm8916_wcd_digital_startup,
1113	.shutdown = msm8916_wcd_digital_shutdown,
1114	.hw_params = msm8916_wcd_digital_hw_params,
1115};
1116
1117static struct snd_soc_dai_driver msm8916_wcd_digital_dai[] = {
1118	[0] = {
1119	       .name = "msm8916_wcd_digital_i2s_rx1",
1120	       .id = 0,
1121	       .playback = {
1122			    .stream_name = "AIF1 Playback",
1123			    .rates = MSM8916_WCD_DIGITAL_RATES,
1124			    .formats = MSM8916_WCD_DIGITAL_FORMATS,
1125			    .channels_min = 1,
1126			    .channels_max = 3,
1127			    },
1128	       .ops = &msm8916_wcd_digital_dai_ops,
1129	       },
1130	[1] = {
1131	       .name = "msm8916_wcd_digital_i2s_tx1",
1132	       .id = 1,
1133	       .capture = {
1134			   .stream_name = "AIF1 Capture",
1135			   .rates = MSM8916_WCD_DIGITAL_RATES,
1136			   .formats = MSM8916_WCD_DIGITAL_FORMATS,
1137			   .channels_min = 1,
1138			   .channels_max = 4,
1139			   },
1140	       .ops = &msm8916_wcd_digital_dai_ops,
1141	       },
1142};
1143
1144static const struct snd_soc_component_driver msm8916_wcd_digital = {
1145	.probe			= msm8916_wcd_digital_component_probe,
1146	.set_sysclk		= msm8916_wcd_digital_component_set_sysclk,
1147	.controls		= msm8916_wcd_digital_snd_controls,
1148	.num_controls		= ARRAY_SIZE(msm8916_wcd_digital_snd_controls),
1149	.dapm_widgets		= msm8916_wcd_digital_dapm_widgets,
1150	.num_dapm_widgets	= ARRAY_SIZE(msm8916_wcd_digital_dapm_widgets),
1151	.dapm_routes		= msm8916_wcd_digital_audio_map,
1152	.num_dapm_routes	= ARRAY_SIZE(msm8916_wcd_digital_audio_map),
1153	.idle_bias_on		= 1,
1154	.use_pmdown_time	= 1,
1155	.endianness		= 1,
1156};
1157
1158static const struct regmap_config msm8916_codec_regmap_config = {
1159	.reg_bits = 32,
1160	.reg_stride = 4,
1161	.val_bits = 32,
1162	.max_register = LPASS_CDC_TX2_DMIC_CTL,
1163	.cache_type = REGCACHE_FLAT,
1164};
1165
1166static int msm8916_wcd_digital_probe(struct platform_device *pdev)
1167{
1168	struct msm8916_wcd_digital_priv *priv;
1169	struct device *dev = &pdev->dev;
1170	void __iomem *base;
1171	struct regmap *digital_map;
1172	int ret;
1173
1174	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1175	if (!priv)
1176		return -ENOMEM;
1177
1178	base = devm_platform_ioremap_resource(pdev, 0);
1179	if (IS_ERR(base))
1180		return PTR_ERR(base);
1181
1182	digital_map =
1183	    devm_regmap_init_mmio(&pdev->dev, base,
1184				  &msm8916_codec_regmap_config);
1185	if (IS_ERR(digital_map))
1186		return PTR_ERR(digital_map);
1187
1188	ret = msm8916_wcd_digital_get_clks(pdev, priv);
1189	if (ret < 0)
1190		return ret;
1191
1192	ret = clk_prepare_enable(priv->ahbclk);
1193	if (ret < 0) {
1194		dev_err(dev, "failed to enable ahbclk %d\n", ret);
1195		return ret;
1196	}
1197
1198	ret = clk_prepare_enable(priv->mclk);
1199	if (ret < 0) {
1200		dev_err(dev, "failed to enable mclk %d\n", ret);
1201		goto err_clk;
1202	}
1203
1204	dev_set_drvdata(dev, priv);
1205
1206	ret = devm_snd_soc_register_component(dev, &msm8916_wcd_digital,
1207				      msm8916_wcd_digital_dai,
1208				      ARRAY_SIZE(msm8916_wcd_digital_dai));
1209	if (ret)
1210		goto err_mclk;
1211
1212	return 0;
1213
1214err_mclk:
1215	clk_disable_unprepare(priv->mclk);
1216err_clk:
1217	clk_disable_unprepare(priv->ahbclk);
1218	return ret;
1219}
1220
1221static void msm8916_wcd_digital_remove(struct platform_device *pdev)
1222{
1223	struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(&pdev->dev);
1224
1225	clk_disable_unprepare(priv->mclk);
1226	clk_disable_unprepare(priv->ahbclk);
1227}
1228
1229static const struct of_device_id msm8916_wcd_digital_match_table[] = {
1230	{ .compatible = "qcom,msm8916-wcd-digital-codec" },
1231	{ }
1232};
1233
1234MODULE_DEVICE_TABLE(of, msm8916_wcd_digital_match_table);
1235
1236static struct platform_driver msm8916_wcd_digital_driver = {
1237	.driver = {
1238		   .name = "msm8916-wcd-digital-codec",
1239		   .of_match_table = msm8916_wcd_digital_match_table,
1240	},
1241	.probe = msm8916_wcd_digital_probe,
1242	.remove = msm8916_wcd_digital_remove,
1243};
1244
1245module_platform_driver(msm8916_wcd_digital_driver);
1246
1247MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>");
1248MODULE_DESCRIPTION("MSM8916 WCD Digital Codec driver");
1249MODULE_LICENSE("GPL v2");
~/ Read-only file preview.