linux/sound/soc/codecs/msm8916-wcd-digital.c
<<
>>
Prefs
   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
 190struct msm8916_wcd_digital_priv {
 191        struct clk *ahbclk, *mclk;
 192};
 193
 194static const unsigned long rx_gain_reg[] = {
 195        LPASS_CDC_RX1_VOL_CTL_B2_CTL,
 196        LPASS_CDC_RX2_VOL_CTL_B2_CTL,
 197        LPASS_CDC_RX3_VOL_CTL_B2_CTL,
 198};
 199
 200static const unsigned long tx_gain_reg[] = {
 201        LPASS_CDC_TX1_VOL_CTL_GAIN,
 202        LPASS_CDC_TX2_VOL_CTL_GAIN,
 203};
 204
 205static const char *const rx_mix1_text[] = {
 206        "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3"
 207};
 208
 209static const char *const dec_mux_text[] = {
 210        "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2"
 211};
 212
 213static const char *const cic_mux_text[] = { "AMIC", "DMIC" };
 214
 215/* RX1 MIX1 */
 216static const struct soc_enum rx_mix1_inp_enum[] = {
 217        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B1_CTL, 0, 6, rx_mix1_text),
 218        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B1_CTL, 3, 6, rx_mix1_text),
 219        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B2_CTL, 0, 6, rx_mix1_text),
 220};
 221
 222/* RX2 MIX1 */
 223static const struct soc_enum rx2_mix1_inp_enum[] = {
 224        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text),
 225        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 3, 6, rx_mix1_text),
 226        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B2_CTL, 0, 6, rx_mix1_text),
 227};
 228
 229/* RX3 MIX1 */
 230static const struct soc_enum rx3_mix1_inp_enum[] = {
 231        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text),
 232        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 3, 6, rx_mix1_text),
 233        SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B2_CTL, 0, 6, rx_mix1_text),
 234};
 235
 236/* DEC */
 237static const struct soc_enum dec1_mux_enum = SOC_ENUM_SINGLE(
 238                                LPASS_CDC_CONN_TX_B1_CTL, 0, 6, dec_mux_text);
 239static const struct soc_enum dec2_mux_enum = SOC_ENUM_SINGLE(
 240                                LPASS_CDC_CONN_TX_B1_CTL, 3, 6, dec_mux_text);
 241
 242/* CIC */
 243static const struct soc_enum cic1_mux_enum = SOC_ENUM_SINGLE(
 244                                LPASS_CDC_TX1_MUX_CTL, 0, 2, cic_mux_text);
 245static const struct soc_enum cic2_mux_enum = SOC_ENUM_SINGLE(
 246                                LPASS_CDC_TX2_MUX_CTL, 0, 2, cic_mux_text);
 247
 248/* RDAC2 MUX */
 249static const struct snd_kcontrol_new dec1_mux = SOC_DAPM_ENUM(
 250                                "DEC1 MUX Mux", dec1_mux_enum);
 251static const struct snd_kcontrol_new dec2_mux = SOC_DAPM_ENUM(
 252                                "DEC2 MUX Mux", dec2_mux_enum);
 253static const struct snd_kcontrol_new cic1_mux = SOC_DAPM_ENUM(
 254                                "CIC1 MUX Mux", cic1_mux_enum);
 255static const struct snd_kcontrol_new cic2_mux = SOC_DAPM_ENUM(
 256                                "CIC2 MUX Mux", cic2_mux_enum);
 257static const struct snd_kcontrol_new rx_mix1_inp1_mux = SOC_DAPM_ENUM(
 258                                "RX1 MIX1 INP1 Mux", rx_mix1_inp_enum[0]);
 259static const struct snd_kcontrol_new rx_mix1_inp2_mux = SOC_DAPM_ENUM(
 260                                "RX1 MIX1 INP2 Mux", rx_mix1_inp_enum[1]);
 261static const struct snd_kcontrol_new rx_mix1_inp3_mux = SOC_DAPM_ENUM(
 262                                "RX1 MIX1 INP3 Mux", rx_mix1_inp_enum[2]);
 263static const struct snd_kcontrol_new rx2_mix1_inp1_mux = SOC_DAPM_ENUM(
 264                                "RX2 MIX1 INP1 Mux", rx2_mix1_inp_enum[0]);
 265static const struct snd_kcontrol_new rx2_mix1_inp2_mux = SOC_DAPM_ENUM(
 266                                "RX2 MIX1 INP2 Mux", rx2_mix1_inp_enum[1]);
 267static const struct snd_kcontrol_new rx2_mix1_inp3_mux = SOC_DAPM_ENUM(
 268                                "RX2 MIX1 INP3 Mux", rx2_mix1_inp_enum[2]);
 269static const struct snd_kcontrol_new rx3_mix1_inp1_mux = SOC_DAPM_ENUM(
 270                                "RX3 MIX1 INP1 Mux", rx3_mix1_inp_enum[0]);
 271static const struct snd_kcontrol_new rx3_mix1_inp2_mux = SOC_DAPM_ENUM(
 272                                "RX3 MIX1 INP2 Mux", rx3_mix1_inp_enum[1]);
 273static const struct snd_kcontrol_new rx3_mix1_inp3_mux = SOC_DAPM_ENUM(
 274                                "RX3 MIX1 INP3 Mux", rx3_mix1_inp_enum[2]);
 275
 276/* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */
 277static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0);
 278
 279/* Cutoff Freq for High Pass Filter at -3dB */
 280static const char * const hpf_cutoff_text[] = {
 281        "4Hz", "75Hz", "150Hz",
 282};
 283
 284static SOC_ENUM_SINGLE_DECL(tx1_hpf_cutoff_enum, LPASS_CDC_TX1_MUX_CTL, 4,
 285                            hpf_cutoff_text);
 286static SOC_ENUM_SINGLE_DECL(tx2_hpf_cutoff_enum, LPASS_CDC_TX2_MUX_CTL, 4,
 287                            hpf_cutoff_text);
 288
 289/* cut off for dc blocker inside rx chain */
 290static const char * const dc_blocker_cutoff_text[] = {
 291        "4Hz", "75Hz", "150Hz",
 292};
 293
 294static SOC_ENUM_SINGLE_DECL(rx1_dcb_cutoff_enum, LPASS_CDC_RX1_B4_CTL, 0,
 295                            dc_blocker_cutoff_text);
 296static SOC_ENUM_SINGLE_DECL(rx2_dcb_cutoff_enum, LPASS_CDC_RX2_B4_CTL, 0,
 297                            dc_blocker_cutoff_text);
 298static SOC_ENUM_SINGLE_DECL(rx3_dcb_cutoff_enum, LPASS_CDC_RX3_B4_CTL, 0,
 299                            dc_blocker_cutoff_text);
 300
 301static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
 302        SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL,
 303                          -128, 127, digital_gain),
 304        SOC_SINGLE_S8_TLV("RX2 Digital Volume", LPASS_CDC_RX2_VOL_CTL_B2_CTL,
 305                          -128, 127, digital_gain),
 306        SOC_SINGLE_S8_TLV("RX3 Digital Volume", LPASS_CDC_RX3_VOL_CTL_B2_CTL,
 307                          -128, 127, digital_gain),
 308        SOC_SINGLE_S8_TLV("TX1 Digital Volume", LPASS_CDC_TX1_VOL_CTL_GAIN,
 309                          -128, 127, digital_gain),
 310        SOC_SINGLE_S8_TLV("TX2 Digital Volume", LPASS_CDC_TX2_VOL_CTL_GAIN,
 311                          -128, 127, digital_gain),
 312        SOC_ENUM("TX1 HPF Cutoff", tx1_hpf_cutoff_enum),
 313        SOC_ENUM("TX2 HPF Cutoff", tx2_hpf_cutoff_enum),
 314        SOC_SINGLE("TX1 HPF Switch", LPASS_CDC_TX1_MUX_CTL, 3, 1, 0),
 315        SOC_SINGLE("TX2 HPF Switch", LPASS_CDC_TX2_MUX_CTL, 3, 1, 0),
 316        SOC_ENUM("RX1 DCB Cutoff", rx1_dcb_cutoff_enum),
 317        SOC_ENUM("RX2 DCB Cutoff", rx2_dcb_cutoff_enum),
 318        SOC_ENUM("RX3 DCB Cutoff", rx3_dcb_cutoff_enum),
 319        SOC_SINGLE("RX1 DCB Switch", LPASS_CDC_RX1_B5_CTL, 2, 1, 0),
 320        SOC_SINGLE("RX2 DCB Switch", LPASS_CDC_RX2_B5_CTL, 2, 1, 0),
 321        SOC_SINGLE("RX3 DCB Switch", LPASS_CDC_RX3_B5_CTL, 2, 1, 0),
 322        SOC_SINGLE("RX1 Mute Switch", LPASS_CDC_RX1_B6_CTL, 0, 1, 0),
 323        SOC_SINGLE("RX2 Mute Switch", LPASS_CDC_RX2_B6_CTL, 0, 1, 0),
 324        SOC_SINGLE("RX3 Mute Switch", LPASS_CDC_RX3_B6_CTL, 0, 1, 0),
 325};
 326
 327static int msm8916_wcd_digital_enable_interpolator(
 328                                                struct snd_soc_dapm_widget *w,
 329                                                struct snd_kcontrol *kcontrol,
 330                                                int event)
 331{
 332        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 333
 334        switch (event) {
 335        case SND_SOC_DAPM_POST_PMU:
 336                /* apply the digital gain after the interpolator is enabled */
 337                usleep_range(10000, 10100);
 338                snd_soc_component_write(component, rx_gain_reg[w->shift],
 339                              snd_soc_component_read32(component, rx_gain_reg[w->shift]));
 340                break;
 341        }
 342        return 0;
 343}
 344
 345static int msm8916_wcd_digital_enable_dec(struct snd_soc_dapm_widget *w,
 346                                          struct snd_kcontrol *kcontrol,
 347                                          int event)
 348{
 349        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 350        unsigned int decimator = w->shift + 1;
 351        u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
 352        u8 dec_hpf_cut_of_freq;
 353
 354        dec_reset_reg = LPASS_CDC_CLK_TX_RESET_B1_CTL;
 355        tx_vol_ctl_reg = LPASS_CDC_TX1_VOL_CTL_CFG + 32 * (decimator - 1);
 356        tx_mux_ctl_reg = LPASS_CDC_TX1_MUX_CTL + 32 * (decimator - 1);
 357
 358        switch (event) {
 359        case SND_SOC_DAPM_PRE_PMU:
 360                /* Enable TX digital mute */
 361                snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 362                                    TX_VOL_CTL_CFG_MUTE_EN_MASK,
 363                                    TX_VOL_CTL_CFG_MUTE_EN_ENABLE);
 364                dec_hpf_cut_of_freq = snd_soc_component_read32(component, tx_mux_ctl_reg) &
 365                                        TX_MUX_CTL_CUT_OFF_FREQ_MASK;
 366                dec_hpf_cut_of_freq >>= TX_MUX_CTL_CUT_OFF_FREQ_SHIFT;
 367                if (dec_hpf_cut_of_freq != TX_MUX_CTL_CF_NEG_3DB_150HZ) {
 368                        /* set cut of freq to CF_MIN_3DB_150HZ (0x1) */
 369                        snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 370                                            TX_MUX_CTL_CUT_OFF_FREQ_MASK,
 371                                            TX_MUX_CTL_CF_NEG_3DB_150HZ);
 372                }
 373                break;
 374        case SND_SOC_DAPM_POST_PMU:
 375                /* enable HPF */
 376                snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 377                                    TX_MUX_CTL_HPF_BP_SEL_MASK,
 378                                    TX_MUX_CTL_HPF_BP_SEL_NO_BYPASS);
 379                /* apply the digital gain after the decimator is enabled */
 380                snd_soc_component_write(component, tx_gain_reg[w->shift],
 381                              snd_soc_component_read32(component, tx_gain_reg[w->shift]));
 382                snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 383                                    TX_VOL_CTL_CFG_MUTE_EN_MASK, 0);
 384                break;
 385        case SND_SOC_DAPM_PRE_PMD:
 386                snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 387                                    TX_VOL_CTL_CFG_MUTE_EN_MASK,
 388                                    TX_VOL_CTL_CFG_MUTE_EN_ENABLE);
 389                snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 390                                    TX_MUX_CTL_HPF_BP_SEL_MASK,
 391                                    TX_MUX_CTL_HPF_BP_SEL_BYPASS);
 392                break;
 393        case SND_SOC_DAPM_POST_PMD:
 394                snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift,
 395                                    1 << w->shift);
 396                snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift, 0x0);
 397                snd_soc_component_update_bits(component, tx_mux_ctl_reg,
 398                                    TX_MUX_CTL_HPF_BP_SEL_MASK,
 399                                    TX_MUX_CTL_HPF_BP_SEL_BYPASS);
 400                snd_soc_component_update_bits(component, tx_vol_ctl_reg,
 401                                    TX_VOL_CTL_CFG_MUTE_EN_MASK, 0);
 402                break;
 403        }
 404
 405        return 0;
 406}
 407
 408static int msm8916_wcd_digital_enable_dmic(struct snd_soc_dapm_widget *w,
 409                                           struct snd_kcontrol *kcontrol,
 410                                           int event)
 411{
 412        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 413        unsigned int dmic;
 414        int ret;
 415        /* get dmic number out of widget name */
 416        char *dmic_num = strpbrk(w->name, "12");
 417
 418        if (dmic_num == NULL) {
 419                dev_err(component->dev, "Invalid DMIC\n");
 420                return -EINVAL;
 421        }
 422        ret = kstrtouint(dmic_num, 10, &dmic);
 423        if (ret < 0 || dmic > 2) {
 424                dev_err(component->dev, "Invalid DMIC line on the component\n");
 425                return -EINVAL;
 426        }
 427
 428        switch (event) {
 429        case SND_SOC_DAPM_PRE_PMU:
 430                snd_soc_component_update_bits(component, LPASS_CDC_CLK_DMIC_B1_CTL,
 431                                    DMIC_B1_CTL_DMIC0_CLK_SEL_MASK,
 432                                    DMIC_B1_CTL_DMIC0_CLK_SEL_DIV3);
 433                switch (dmic) {
 434                case 1:
 435                        snd_soc_component_update_bits(component, LPASS_CDC_TX1_DMIC_CTL,
 436                                            TXN_DMIC_CTL_CLK_SEL_MASK,
 437                                            TXN_DMIC_CTL_CLK_SEL_DIV3);
 438                        break;
 439                case 2:
 440                        snd_soc_component_update_bits(component, LPASS_CDC_TX2_DMIC_CTL,
 441                                            TXN_DMIC_CTL_CLK_SEL_MASK,
 442                                            TXN_DMIC_CTL_CLK_SEL_DIV3);
 443                        break;
 444                }
 445                break;
 446        }
 447
 448        return 0;
 449}
 450
 451static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = {
 452        /*RX stuff */
 453        SND_SOC_DAPM_AIF_IN("I2S RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
 454        SND_SOC_DAPM_AIF_IN("I2S RX2", NULL, 0, SND_SOC_NOPM, 0, 0),
 455        SND_SOC_DAPM_AIF_IN("I2S RX3", NULL, 0, SND_SOC_NOPM, 0, 0),
 456
 457        SND_SOC_DAPM_OUTPUT("PDM_RX1"),
 458        SND_SOC_DAPM_OUTPUT("PDM_RX2"),
 459        SND_SOC_DAPM_OUTPUT("PDM_RX3"),
 460
 461        SND_SOC_DAPM_INPUT("LPASS_PDM_TX"),
 462
 463        SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 464        SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 465        SND_SOC_DAPM_MIXER("RX3 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
 466
 467        /* Interpolator */
 468        SND_SOC_DAPM_MIXER_E("RX1 INT", LPASS_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
 469                             0, msm8916_wcd_digital_enable_interpolator,
 470                             SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 471        SND_SOC_DAPM_MIXER_E("RX2 INT", LPASS_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
 472                             0, msm8916_wcd_digital_enable_interpolator,
 473                             SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 474        SND_SOC_DAPM_MIXER_E("RX3 INT", LPASS_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
 475                             0, msm8916_wcd_digital_enable_interpolator,
 476                             SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 477        SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
 478                         &rx_mix1_inp1_mux),
 479        SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
 480                         &rx_mix1_inp2_mux),
 481        SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0,
 482                         &rx_mix1_inp3_mux),
 483        SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
 484                         &rx2_mix1_inp1_mux),
 485        SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
 486                         &rx2_mix1_inp2_mux),
 487        SND_SOC_DAPM_MUX("RX2 MIX1 INP3", SND_SOC_NOPM, 0, 0,
 488                         &rx2_mix1_inp3_mux),
 489        SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
 490                         &rx3_mix1_inp1_mux),
 491        SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
 492                         &rx3_mix1_inp2_mux),
 493        SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0,
 494                         &rx3_mix1_inp3_mux),
 495
 496        SND_SOC_DAPM_MUX("CIC1 MUX", SND_SOC_NOPM, 0, 0, &cic1_mux),
 497        SND_SOC_DAPM_MUX("CIC2 MUX", SND_SOC_NOPM, 0, 0, &cic2_mux),
 498        /* TX */
 499        SND_SOC_DAPM_MIXER("ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
 500        SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
 501        SND_SOC_DAPM_MIXER("ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
 502
 503        SND_SOC_DAPM_MUX_E("DEC1 MUX", LPASS_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
 504                           &dec1_mux, msm8916_wcd_digital_enable_dec,
 505                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 506                           SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
 507        SND_SOC_DAPM_MUX_E("DEC2 MUX", LPASS_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
 508                           &dec2_mux, msm8916_wcd_digital_enable_dec,
 509                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 510                           SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
 511        SND_SOC_DAPM_AIF_OUT("I2S TX1", NULL, 0, SND_SOC_NOPM, 0, 0),
 512        SND_SOC_DAPM_AIF_OUT("I2S TX2", NULL, 0, SND_SOC_NOPM, 0, 0),
 513        SND_SOC_DAPM_AIF_OUT("I2S TX3", NULL, 0, SND_SOC_NOPM, 0, 0),
 514
 515        /* Digital Mic Inputs */
 516        SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
 517                           msm8916_wcd_digital_enable_dmic,
 518                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 519        SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
 520                           msm8916_wcd_digital_enable_dmic,
 521                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 522        SND_SOC_DAPM_SUPPLY("DMIC_CLK", LPASS_CDC_CLK_DMIC_B1_CTL, 0, 0,
 523                            NULL, 0),
 524        SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", LPASS_CDC_CLK_RX_I2S_CTL,
 525                            4, 0, NULL, 0),
 526        SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", LPASS_CDC_CLK_TX_I2S_CTL, 4, 0,
 527                            NULL, 0),
 528
 529        SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, NULL, 0),
 530        SND_SOC_DAPM_SUPPLY("PDM_CLK", LPASS_CDC_CLK_PDM_CTL, 0, 0, NULL, 0),
 531        /* Connectivity Clock */
 532        SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, LPASS_CDC_CLK_OTHR_CTL, 2, 0,
 533                              NULL, 0),
 534        SND_SOC_DAPM_MIC("Digital Mic1", NULL),
 535        SND_SOC_DAPM_MIC("Digital Mic2", NULL),
 536
 537};
 538
 539static int msm8916_wcd_digital_get_clks(struct platform_device *pdev,
 540                                        struct msm8916_wcd_digital_priv *priv)
 541{
 542        struct device *dev = &pdev->dev;
 543
 544        priv->ahbclk = devm_clk_get(dev, "ahbix-clk");
 545        if (IS_ERR(priv->ahbclk)) {
 546                dev_err(dev, "failed to get ahbix clk\n");
 547                return PTR_ERR(priv->ahbclk);
 548        }
 549
 550        priv->mclk = devm_clk_get(dev, "mclk");
 551        if (IS_ERR(priv->mclk)) {
 552                dev_err(dev, "failed to get mclk\n");
 553                return PTR_ERR(priv->mclk);
 554        }
 555
 556        return 0;
 557}
 558
 559static int msm8916_wcd_digital_component_probe(struct snd_soc_component *component)
 560{
 561        struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(component->dev);
 562
 563        snd_soc_component_set_drvdata(component, priv);
 564
 565        return 0;
 566}
 567
 568static int msm8916_wcd_digital_component_set_sysclk(struct snd_soc_component *component,
 569                                                int clk_id, int source,
 570                                                unsigned int freq, int dir)
 571{
 572        struct msm8916_wcd_digital_priv *p = dev_get_drvdata(component->dev);
 573
 574        return clk_set_rate(p->mclk, freq);
 575}
 576
 577static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream,
 578                                         struct snd_pcm_hw_params *params,
 579                                         struct snd_soc_dai *dai)
 580{
 581        u8 tx_fs_rate;
 582        u8 rx_fs_rate;
 583
 584        switch (params_rate(params)) {
 585        case 8000:
 586                tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_8_KHZ;
 587                rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_8_KHZ;
 588                break;
 589        case 16000:
 590                tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_16_KHZ;
 591                rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_16_KHZ;
 592                break;
 593        case 32000:
 594                tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_32_KHZ;
 595                rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_32_KHZ;
 596                break;
 597        case 48000:
 598                tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_48_KHZ;
 599                rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_48_KHZ;
 600                break;
 601        default:
 602                dev_err(dai->component->dev, "Invalid sampling rate %d\n",
 603                        params_rate(params));
 604                return -EINVAL;
 605        }
 606
 607        switch (substream->stream) {
 608        case SNDRV_PCM_STREAM_CAPTURE:
 609                snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
 610                                    TX_I2S_CTL_TX_I2S_FS_RATE_MASK, tx_fs_rate);
 611                break;
 612        case SNDRV_PCM_STREAM_PLAYBACK:
 613                snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
 614                                    RX_I2S_CTL_RX_I2S_FS_RATE_MASK, rx_fs_rate);
 615                break;
 616        default:
 617                return -EINVAL;
 618        }
 619
 620        switch (params_format(params)) {
 621        case SNDRV_PCM_FORMAT_S16_LE:
 622                snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
 623                                    TX_I2S_CTL_TX_I2S_MODE_MASK,
 624                                    TX_I2S_CTL_TX_I2S_MODE_16);
 625                snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
 626                                    RX_I2S_CTL_RX_I2S_MODE_MASK,
 627                                    RX_I2S_CTL_RX_I2S_MODE_16);
 628                break;
 629
 630        case SNDRV_PCM_FORMAT_S32_LE:
 631                snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
 632                                    TX_I2S_CTL_TX_I2S_MODE_MASK,
 633                                    TX_I2S_CTL_TX_I2S_MODE_32);
 634                snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
 635                                    RX_I2S_CTL_RX_I2S_MODE_MASK,
 636                                    RX_I2S_CTL_RX_I2S_MODE_32);
 637                break;
 638        default:
 639                dev_err(dai->dev, "%s: wrong format selected\n", __func__);
 640                return -EINVAL;
 641        }
 642
 643        return 0;
 644}
 645
 646static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
 647
 648        {"I2S RX1",  NULL, "AIF1 Playback"},
 649        {"I2S RX2",  NULL, "AIF1 Playback"},
 650        {"I2S RX3",  NULL, "AIF1 Playback"},
 651
 652        {"AIF1 Capture", NULL, "I2S TX1"},
 653        {"AIF1 Capture", NULL, "I2S TX2"},
 654        {"AIF1 Capture", NULL, "I2S TX3"},
 655
 656        {"CIC1 MUX", "DMIC", "DEC1 MUX"},
 657        {"CIC1 MUX", "AMIC", "DEC1 MUX"},
 658        {"CIC2 MUX", "DMIC", "DEC2 MUX"},
 659        {"CIC2 MUX", "AMIC", "DEC2 MUX"},
 660
 661        /* Decimator Inputs */
 662        {"DEC1 MUX", "DMIC1", "DMIC1"},
 663        {"DEC1 MUX", "DMIC2", "DMIC2"},
 664        {"DEC1 MUX", "ADC1", "ADC1"},
 665        {"DEC1 MUX", "ADC2", "ADC2"},
 666        {"DEC1 MUX", "ADC3", "ADC3"},
 667        {"DEC1 MUX", NULL, "CDC_CONN"},
 668
 669        {"DEC2 MUX", "DMIC1", "DMIC1"},
 670        {"DEC2 MUX", "DMIC2", "DMIC2"},
 671        {"DEC2 MUX", "ADC1", "ADC1"},
 672        {"DEC2 MUX", "ADC2", "ADC2"},
 673        {"DEC2 MUX", "ADC3", "ADC3"},
 674        {"DEC2 MUX", NULL, "CDC_CONN"},
 675
 676        {"DMIC1", NULL, "DMIC_CLK"},
 677        {"DMIC2", NULL, "DMIC_CLK"},
 678
 679        {"I2S TX1", NULL, "CIC1 MUX"},
 680        {"I2S TX2", NULL, "CIC2 MUX"},
 681
 682        {"I2S TX1", NULL, "TX_I2S_CLK"},
 683        {"I2S TX2", NULL, "TX_I2S_CLK"},
 684
 685        {"TX_I2S_CLK", NULL, "MCLK"},
 686        {"TX_I2S_CLK", NULL, "PDM_CLK"},
 687
 688        {"ADC1", NULL, "LPASS_PDM_TX"},
 689        {"ADC2", NULL, "LPASS_PDM_TX"},
 690        {"ADC3", NULL, "LPASS_PDM_TX"},
 691
 692        {"I2S RX1", NULL, "RX_I2S_CLK"},
 693        {"I2S RX2", NULL, "RX_I2S_CLK"},
 694        {"I2S RX3", NULL, "RX_I2S_CLK"},
 695
 696        {"RX_I2S_CLK", NULL, "PDM_CLK"},
 697        {"RX_I2S_CLK", NULL, "MCLK"},
 698        {"RX_I2S_CLK", NULL, "CDC_CONN"},
 699
 700        /* RX1 PATH.. */
 701        {"PDM_RX1", NULL, "RX1 INT"},
 702        {"RX1 INT", NULL, "RX1 MIX1"},
 703
 704        {"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
 705        {"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
 706        {"RX1 MIX1", NULL, "RX1 MIX1 INP3"},
 707
 708        {"RX1 MIX1 INP1", "RX1", "I2S RX1"},
 709        {"RX1 MIX1 INP1", "RX2", "I2S RX2"},
 710        {"RX1 MIX1 INP1", "RX3", "I2S RX3"},
 711
 712        {"RX1 MIX1 INP2", "RX1", "I2S RX1"},
 713        {"RX1 MIX1 INP2", "RX2", "I2S RX2"},
 714        {"RX1 MIX1 INP2", "RX3", "I2S RX3"},
 715
 716        {"RX1 MIX1 INP3", "RX1", "I2S RX1"},
 717        {"RX1 MIX1 INP3", "RX2", "I2S RX2"},
 718        {"RX1 MIX1 INP3", "RX3", "I2S RX3"},
 719
 720        /* RX2 PATH */
 721        {"PDM_RX2", NULL, "RX2 INT"},
 722        {"RX2 INT", NULL, "RX2 MIX1"},
 723
 724        {"RX2 MIX1", NULL, "RX2 MIX1 INP1"},
 725        {"RX2 MIX1", NULL, "RX2 MIX1 INP2"},
 726        {"RX2 MIX1", NULL, "RX2 MIX1 INP3"},
 727
 728        {"RX2 MIX1 INP1", "RX1", "I2S RX1"},
 729        {"RX2 MIX1 INP1", "RX2", "I2S RX2"},
 730        {"RX2 MIX1 INP1", "RX3", "I2S RX3"},
 731
 732        {"RX2 MIX1 INP2", "RX1", "I2S RX1"},
 733        {"RX2 MIX1 INP2", "RX2", "I2S RX2"},
 734        {"RX2 MIX1 INP2", "RX3", "I2S RX3"},
 735
 736        {"RX2 MIX1 INP3", "RX1", "I2S RX1"},
 737        {"RX2 MIX1 INP3", "RX2", "I2S RX2"},
 738        {"RX2 MIX1 INP3", "RX3", "I2S RX3"},
 739
 740        /* RX3 PATH */
 741        {"PDM_RX3", NULL, "RX3 INT"},
 742        {"RX3 INT", NULL, "RX3 MIX1"},
 743
 744        {"RX3 MIX1", NULL, "RX3 MIX1 INP1"},
 745        {"RX3 MIX1", NULL, "RX3 MIX1 INP2"},
 746        {"RX3 MIX1", NULL, "RX3 MIX1 INP3"},
 747
 748        {"RX3 MIX1 INP1", "RX1", "I2S RX1"},
 749        {"RX3 MIX1 INP1", "RX2", "I2S RX2"},
 750        {"RX3 MIX1 INP1", "RX3", "I2S RX3"},
 751
 752        {"RX3 MIX1 INP2", "RX1", "I2S RX1"},
 753        {"RX3 MIX1 INP2", "RX2", "I2S RX2"},
 754        {"RX3 MIX1 INP2", "RX3", "I2S RX3"},
 755
 756        {"RX3 MIX1 INP3", "RX1", "I2S RX1"},
 757        {"RX3 MIX1 INP3", "RX2", "I2S RX2"},
 758        {"RX3 MIX1 INP3", "RX3", "I2S RX3"},
 759
 760};
 761
 762static int msm8916_wcd_digital_startup(struct snd_pcm_substream *substream,
 763                                       struct snd_soc_dai *dai)
 764{
 765        struct snd_soc_component *component = dai->component;
 766        struct msm8916_wcd_digital_priv *msm8916_wcd;
 767        unsigned long mclk_rate;
 768
 769        msm8916_wcd = snd_soc_component_get_drvdata(component);
 770        snd_soc_component_update_bits(component, LPASS_CDC_CLK_MCLK_CTL,
 771                            MCLK_CTL_MCLK_EN_MASK,
 772                            MCLK_CTL_MCLK_EN_ENABLE);
 773        snd_soc_component_update_bits(component, LPASS_CDC_CLK_PDM_CTL,
 774                            LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK,
 775                            LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_FB);
 776
 777        mclk_rate = clk_get_rate(msm8916_wcd->mclk);
 778        switch (mclk_rate) {
 779        case 12288000:
 780                snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL,
 781                                    TOP_CTL_DIG_MCLK_FREQ_MASK,
 782                                    TOP_CTL_DIG_MCLK_FREQ_F_12_288MHZ);
 783                break;
 784        case 9600000:
 785                snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL,
 786                                    TOP_CTL_DIG_MCLK_FREQ_MASK,
 787                                    TOP_CTL_DIG_MCLK_FREQ_F_9_6MHZ);
 788                break;
 789        default:
 790                dev_err(component->dev, "Invalid mclk rate %ld\n", mclk_rate);
 791                break;
 792        }
 793        return 0;
 794}
 795
 796static void msm8916_wcd_digital_shutdown(struct snd_pcm_substream *substream,
 797                                         struct snd_soc_dai *dai)
 798{
 799        snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_PDM_CTL,
 800                            LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK, 0);
 801}
 802
 803static const struct snd_soc_dai_ops msm8916_wcd_digital_dai_ops = {
 804        .startup = msm8916_wcd_digital_startup,
 805        .shutdown = msm8916_wcd_digital_shutdown,
 806        .hw_params = msm8916_wcd_digital_hw_params,
 807};
 808
 809static struct snd_soc_dai_driver msm8916_wcd_digital_dai[] = {
 810        [0] = {
 811               .name = "msm8916_wcd_digital_i2s_rx1",
 812               .id = 0,
 813               .playback = {
 814                            .stream_name = "AIF1 Playback",
 815                            .rates = MSM8916_WCD_DIGITAL_RATES,
 816                            .formats = MSM8916_WCD_DIGITAL_FORMATS,
 817                            .channels_min = 1,
 818                            .channels_max = 3,
 819                            },
 820               .ops = &msm8916_wcd_digital_dai_ops,
 821               },
 822        [1] = {
 823               .name = "msm8916_wcd_digital_i2s_tx1",
 824               .id = 1,
 825               .capture = {
 826                           .stream_name = "AIF1 Capture",
 827                           .rates = MSM8916_WCD_DIGITAL_RATES,
 828                           .formats = MSM8916_WCD_DIGITAL_FORMATS,
 829                           .channels_min = 1,
 830                           .channels_max = 4,
 831                           },
 832               .ops = &msm8916_wcd_digital_dai_ops,
 833               },
 834};
 835
 836static const struct snd_soc_component_driver msm8916_wcd_digital = {
 837        .probe                  = msm8916_wcd_digital_component_probe,
 838        .set_sysclk             = msm8916_wcd_digital_component_set_sysclk,
 839        .controls               = msm8916_wcd_digital_snd_controls,
 840        .num_controls           = ARRAY_SIZE(msm8916_wcd_digital_snd_controls),
 841        .dapm_widgets           = msm8916_wcd_digital_dapm_widgets,
 842        .num_dapm_widgets       = ARRAY_SIZE(msm8916_wcd_digital_dapm_widgets),
 843        .dapm_routes            = msm8916_wcd_digital_audio_map,
 844        .num_dapm_routes        = ARRAY_SIZE(msm8916_wcd_digital_audio_map),
 845        .idle_bias_on           = 1,
 846        .use_pmdown_time        = 1,
 847        .endianness             = 1,
 848        .non_legacy_dai_naming  = 1,
 849};
 850
 851static const struct regmap_config msm8916_codec_regmap_config = {
 852        .reg_bits = 32,
 853        .reg_stride = 4,
 854        .val_bits = 32,
 855        .max_register = LPASS_CDC_TX2_DMIC_CTL,
 856        .cache_type = REGCACHE_FLAT,
 857};
 858
 859static int msm8916_wcd_digital_probe(struct platform_device *pdev)
 860{
 861        struct msm8916_wcd_digital_priv *priv;
 862        struct device *dev = &pdev->dev;
 863        void __iomem *base;
 864        struct resource *mem_res;
 865        struct regmap *digital_map;
 866        int ret;
 867
 868        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 869        if (!priv)
 870                return -ENOMEM;
 871
 872        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 873        base = devm_ioremap_resource(&pdev->dev, mem_res);
 874        if (IS_ERR(base))
 875                return PTR_ERR(base);
 876
 877        digital_map =
 878            devm_regmap_init_mmio(&pdev->dev, base,
 879                                  &msm8916_codec_regmap_config);
 880        if (IS_ERR(digital_map))
 881                return PTR_ERR(digital_map);
 882
 883        ret = msm8916_wcd_digital_get_clks(pdev, priv);
 884        if (ret < 0)
 885                return ret;
 886
 887        ret = clk_prepare_enable(priv->ahbclk);
 888        if (ret < 0) {
 889                dev_err(dev, "failed to enable ahbclk %d\n", ret);
 890                return ret;
 891        }
 892
 893        ret = clk_prepare_enable(priv->mclk);
 894        if (ret < 0) {
 895                dev_err(dev, "failed to enable mclk %d\n", ret);
 896                return ret;
 897        }
 898
 899        dev_set_drvdata(dev, priv);
 900
 901        return devm_snd_soc_register_component(dev, &msm8916_wcd_digital,
 902                                      msm8916_wcd_digital_dai,
 903                                      ARRAY_SIZE(msm8916_wcd_digital_dai));
 904}
 905
 906static int msm8916_wcd_digital_remove(struct platform_device *pdev)
 907{
 908        struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(&pdev->dev);
 909
 910        clk_disable_unprepare(priv->mclk);
 911        clk_disable_unprepare(priv->ahbclk);
 912
 913        return 0;
 914}
 915
 916static const struct of_device_id msm8916_wcd_digital_match_table[] = {
 917        { .compatible = "qcom,msm8916-wcd-digital-codec" },
 918        { }
 919};
 920
 921MODULE_DEVICE_TABLE(of, msm8916_wcd_digital_match_table);
 922
 923static struct platform_driver msm8916_wcd_digital_driver = {
 924        .driver = {
 925                   .name = "msm8916-wcd-digital-codec",
 926                   .of_match_table = msm8916_wcd_digital_match_table,
 927        },
 928        .probe = msm8916_wcd_digital_probe,
 929        .remove = msm8916_wcd_digital_remove,
 930};
 931
 932module_platform_driver(msm8916_wcd_digital_driver);
 933
 934MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>");
 935MODULE_DESCRIPTION("MSM8916 WCD Digital Codec driver");
 936MODULE_LICENSE("GPL v2");
 937