Commit ef5c2eba2412596f1a022c11caf74428bffd9abe

Authored by Adam Thomson
Committed by Mark Brown
1 parent 836dc9e3fb

ASoC: codecs: Add da7213 codec

This patch adds support for the Dialog DA7213 audio codec.

Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

Showing 5 changed files with 2180 additions and 0 deletions Side-by-side Diff

include/sound/da7213.h
  1 +/*
  2 + * da7213.h - DA7213 ASoC Codec Driver Platform Data
  3 + *
  4 + * Copyright (c) 2013 Dialog Semiconductor
  5 + *
  6 + * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
  7 + *
  8 + * This program is free software; you can redistribute it and/or modify
  9 + * it under the terms of the GNU General Public License version 2 as
  10 + * published by the Free Software Foundation.
  11 + */
  12 +
  13 +#ifndef _DA7213_PDATA_H
  14 +#define _DA7213_PDATA_H
  15 +
  16 +enum da7213_micbias_voltage {
  17 + DA7213_MICBIAS_1_6V = 0,
  18 + DA7213_MICBIAS_2_2V = 1,
  19 + DA7213_MICBIAS_2_5V = 2,
  20 + DA7213_MICBIAS_3_0V = 3,
  21 +};
  22 +
  23 +enum da7213_dmic_data_sel {
  24 + DA7213_DMIC_DATA_LRISE_RFALL = 0,
  25 + DA7213_DMIC_DATA_LFALL_RRISE = 1,
  26 +};
  27 +
  28 +enum da7213_dmic_samplephase {
  29 + DA7213_DMIC_SAMPLE_ON_CLKEDGE = 0,
  30 + DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE = 1,
  31 +};
  32 +
  33 +enum da7213_dmic_clk_rate {
  34 + DA7213_DMIC_CLK_3_0MHZ = 0,
  35 + DA7213_DMIC_CLK_1_5MHZ = 1,
  36 +};
  37 +
  38 +struct da7213_platform_data {
  39 + /* Mic Bias voltage */
  40 + enum da7213_micbias_voltage micbias1_lvl;
  41 + enum da7213_micbias_voltage micbias2_lvl;
  42 +
  43 + /* DMIC config */
  44 + enum da7213_dmic_data_sel dmic_data_sel;
  45 + enum da7213_dmic_samplephase dmic_samplephase;
  46 + enum da7213_dmic_clk_rate dmic_clk_rate;
  47 +
  48 + /* MCLK squaring config */
  49 + bool mclk_squaring;
  50 +};
  51 +
  52 +#endif /* _DA7213_PDATA_H */
sound/soc/codecs/Kconfig
... ... @@ -36,6 +36,7 @@
36 36 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
37 37 select SND_SOC_CX20442
38 38 select SND_SOC_DA7210 if I2C
  39 + select SND_SOC_DA7213 if I2C
39 40 select SND_SOC_DA732X if I2C
40 41 select SND_SOC_DA9055 if I2C
41 42 select SND_SOC_DFBMCS320
... ... @@ -245,6 +246,9 @@
245 246 tristate
246 247  
247 248 config SND_SOC_DA7210
  249 + tristate
  250 +
  251 +config SND_SOC_DA7213
248 252 tristate
249 253  
250 254 config SND_SOC_DA732X
sound/soc/codecs/Makefile
... ... @@ -23,6 +23,7 @@
23 23 snd-soc-cs4271-objs := cs4271.o
24 24 snd-soc-cx20442-objs := cx20442.o
25 25 snd-soc-da7210-objs := da7210.o
  26 +snd-soc-da7213-objs := da7213.o
26 27 snd-soc-da732x-objs := da732x.o
27 28 snd-soc-da9055-objs := da9055.o
28 29 snd-soc-dfbmcs320-objs := dfbmcs320.o
... ... @@ -147,6 +148,7 @@
147 148 obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
148 149 obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
149 150 obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
  151 +obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
150 152 obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
151 153 obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
152 154 obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
sound/soc/codecs/da7213.c
Changes suppressed. Click to show
  1 +/*
  2 + * DA7213 ALSA SoC Codec Driver
  3 + *
  4 + * Copyright (c) 2013 Dialog Semiconductor
  5 + *
  6 + * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
  7 + * Based on DA9055 ALSA SoC codec driver.
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify it
  10 + * under the terms of the GNU General Public License as published by the
  11 + * Free Software Foundation; either version 2 of the License, or (at your
  12 + * option) any later version.
  13 + */
  14 +
  15 +#include <linux/delay.h>
  16 +#include <linux/i2c.h>
  17 +#include <linux/regmap.h>
  18 +#include <linux/slab.h>
  19 +#include <linux/module.h>
  20 +#include <sound/pcm.h>
  21 +#include <sound/pcm_params.h>
  22 +#include <sound/soc.h>
  23 +#include <sound/initval.h>
  24 +#include <sound/tlv.h>
  25 +
  26 +#include <sound/da7213.h>
  27 +#include "da7213.h"
  28 +
  29 +
  30 +/* Gain and Volume */
  31 +static const unsigned int aux_vol_tlv[] = {
  32 + TLV_DB_RANGE_HEAD(2),
  33 + /* -54dB */
  34 + 0x0, 0x11, TLV_DB_SCALE_ITEM(-5400, 0, 0),
  35 + /* -52.5dB to 15dB */
  36 + 0x12, 0x3f, TLV_DB_SCALE_ITEM(-5250, 150, 0)
  37 +};
  38 +
  39 +static const unsigned int digital_gain_tlv[] = {
  40 + TLV_DB_RANGE_HEAD(2),
  41 + 0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
  42 + /* -78dB to 12dB */
  43 + 0x08, 0x7f, TLV_DB_SCALE_ITEM(-7800, 75, 0)
  44 +};
  45 +
  46 +static const unsigned int alc_analog_gain_tlv[] = {
  47 + TLV_DB_RANGE_HEAD(2),
  48 + 0x0, 0x0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
  49 + /* 0dB to 36dB */
  50 + 0x01, 0x07, TLV_DB_SCALE_ITEM(0, 600, 0)
  51 +};
  52 +
  53 +static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0);
  54 +static const DECLARE_TLV_DB_SCALE(mixin_gain_tlv, -450, 150, 0);
  55 +static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
  56 +static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -5700, 100, 0);
  57 +static const DECLARE_TLV_DB_SCALE(lineout_vol_tlv, -4800, 100, 0);
  58 +static const DECLARE_TLV_DB_SCALE(alc_threshold_tlv, -9450, 150, 0);
  59 +static const DECLARE_TLV_DB_SCALE(alc_gain_tlv, 0, 600, 0);
  60 +
  61 +/* ADC and DAC voice mode (8kHz) high pass cutoff value */
  62 +static const char * const da7213_voice_hpf_corner_txt[] = {
  63 + "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
  64 +};
  65 +
  66 +static const struct soc_enum da7213_dac_voice_hpf_corner =
  67 + SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT,
  68 + DA7213_VOICE_HPF_CORNER_MAX,
  69 + da7213_voice_hpf_corner_txt);
  70 +
  71 +static const struct soc_enum da7213_adc_voice_hpf_corner =
  72 + SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT,
  73 + DA7213_VOICE_HPF_CORNER_MAX,
  74 + da7213_voice_hpf_corner_txt);
  75 +
  76 +/* ADC and DAC high pass filter cutoff value */
  77 +static const char * const da7213_audio_hpf_corner_txt[] = {
  78 + "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
  79 +};
  80 +
  81 +static const struct soc_enum da7213_dac_audio_hpf_corner =
  82 + SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT,
  83 + DA7213_AUDIO_HPF_CORNER_MAX,
  84 + da7213_audio_hpf_corner_txt);
  85 +
  86 +static const struct soc_enum da7213_adc_audio_hpf_corner =
  87 + SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT,
  88 + DA7213_AUDIO_HPF_CORNER_MAX,
  89 + da7213_audio_hpf_corner_txt);
  90 +
  91 +/* Gain ramping rate value */
  92 +static const char * const da7213_gain_ramp_rate_txt[] = {
  93 + "nominal rate * 8", "nominal rate * 16", "nominal rate / 16",
  94 + "nominal rate / 32"
  95 +};
  96 +
  97 +static const struct soc_enum da7213_gain_ramp_rate =
  98 + SOC_ENUM_SINGLE(DA7213_GAIN_RAMP_CTRL, DA7213_GAIN_RAMP_RATE_SHIFT,
  99 + DA7213_GAIN_RAMP_RATE_MAX, da7213_gain_ramp_rate_txt);
  100 +
  101 +/* DAC noise gate setup time value */
  102 +static const char * const da7213_dac_ng_setup_time_txt[] = {
  103 + "256 samples", "512 samples", "1024 samples", "2048 samples"
  104 +};
  105 +
  106 +static const struct soc_enum da7213_dac_ng_setup_time =
  107 + SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
  108 + DA7213_DAC_NG_SETUP_TIME_SHIFT,
  109 + DA7213_DAC_NG_SETUP_TIME_MAX,
  110 + da7213_dac_ng_setup_time_txt);
  111 +
  112 +/* DAC noise gate rampup rate value */
  113 +static const char * const da7213_dac_ng_rampup_txt[] = {
  114 + "0.02 ms/dB", "0.16 ms/dB"
  115 +};
  116 +
  117 +static const struct soc_enum da7213_dac_ng_rampup_rate =
  118 + SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
  119 + DA7213_DAC_NG_RAMPUP_RATE_SHIFT,
  120 + DA7213_DAC_NG_RAMP_RATE_MAX,
  121 + da7213_dac_ng_rampup_txt);
  122 +
  123 +/* DAC noise gate rampdown rate value */
  124 +static const char * const da7213_dac_ng_rampdown_txt[] = {
  125 + "0.64 ms/dB", "20.48 ms/dB"
  126 +};
  127 +
  128 +static const struct soc_enum da7213_dac_ng_rampdown_rate =
  129 + SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
  130 + DA7213_DAC_NG_RAMPDN_RATE_SHIFT,
  131 + DA7213_DAC_NG_RAMP_RATE_MAX,
  132 + da7213_dac_ng_rampdown_txt);
  133 +
  134 +/* DAC soft mute rate value */
  135 +static const char * const da7213_dac_soft_mute_rate_txt[] = {
  136 + "1", "2", "4", "8", "16", "32", "64"
  137 +};
  138 +
  139 +static const struct soc_enum da7213_dac_soft_mute_rate =
  140 + SOC_ENUM_SINGLE(DA7213_DAC_FILTERS5, DA7213_DAC_SOFTMUTE_RATE_SHIFT,
  141 + DA7213_DAC_SOFTMUTE_RATE_MAX,
  142 + da7213_dac_soft_mute_rate_txt);
  143 +
  144 +/* ALC Attack Rate select */
  145 +static const char * const da7213_alc_attack_rate_txt[] = {
  146 + "44/fs", "88/fs", "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs",
  147 + "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
  148 +};
  149 +
  150 +static const struct soc_enum da7213_alc_attack_rate =
  151 + SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_ATTACK_SHIFT,
  152 + DA7213_ALC_ATTACK_MAX, da7213_alc_attack_rate_txt);
  153 +
  154 +/* ALC Release Rate select */
  155 +static const char * const da7213_alc_release_rate_txt[] = {
  156 + "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs", "5632/fs",
  157 + "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
  158 +};
  159 +
  160 +static const struct soc_enum da7213_alc_release_rate =
  161 + SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_RELEASE_SHIFT,
  162 + DA7213_ALC_RELEASE_MAX, da7213_alc_release_rate_txt);
  163 +
  164 +/* ALC Hold Time select */
  165 +static const char * const da7213_alc_hold_time_txt[] = {
  166 + "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",
  167 + "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",
  168 + "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
  169 +};
  170 +
  171 +static const struct soc_enum da7213_alc_hold_time =
  172 + SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_HOLD_SHIFT,
  173 + DA7213_ALC_HOLD_MAX, da7213_alc_hold_time_txt);
  174 +
  175 +/* ALC Input Signal Tracking rate select */
  176 +static const char * const da7213_alc_integ_rate_txt[] = {
  177 + "1/4", "1/16", "1/256", "1/65536"
  178 +};
  179 +
  180 +static const struct soc_enum da7213_alc_integ_attack_rate =
  181 + SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_ATTACK_SHIFT,
  182 + DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt);
  183 +
  184 +static const struct soc_enum da7213_alc_integ_release_rate =
  185 + SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_RELEASE_SHIFT,
  186 + DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt);
  187 +
  188 +
  189 +/*
  190 + * Control Functions
  191 + */
  192 +
  193 +static int da7213_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
  194 +{
  195 + int mid_data, top_data;
  196 + int sum = 0;
  197 + u8 iteration;
  198 +
  199 + for (iteration = 0; iteration < DA7213_ALC_AVG_ITERATIONS;
  200 + iteration++) {
  201 + /* Select the left or right channel and capture data */
  202 + snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL, reg_val);
  203 +
  204 + /* Select middle 8 bits for read back from data register */
  205 + snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL,
  206 + reg_val | DA7213_ALC_DATA_MIDDLE);
  207 + mid_data = snd_soc_read(codec, DA7213_ALC_CIC_OP_LVL_DATA);
  208 +
  209 + /* Select top 8 bits for read back from data register */
  210 + snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL,
  211 + reg_val | DA7213_ALC_DATA_TOP);
  212 + top_data = snd_soc_read(codec, DA7213_ALC_CIC_OP_LVL_DATA);
  213 +
  214 + sum += ((mid_data << 8) | (top_data << 16));
  215 + }
  216 +
  217 + return sum / DA7213_ALC_AVG_ITERATIONS;
  218 +}
  219 +
  220 +static void da7213_alc_calib_man(struct snd_soc_codec *codec)
  221 +{
  222 + u8 reg_val;
  223 + int avg_left_data, avg_right_data, offset_l, offset_r;
  224 +
  225 + /* Calculate average for Left and Right data */
  226 + /* Left Data */
  227 + avg_left_data = da7213_get_alc_data(codec,
  228 + DA7213_ALC_CIC_OP_CHANNEL_LEFT);
  229 + /* Right Data */
  230 + avg_right_data = da7213_get_alc_data(codec,
  231 + DA7213_ALC_CIC_OP_CHANNEL_RIGHT);
  232 +
  233 + /* Calculate DC offset */
  234 + offset_l = -avg_left_data;
  235 + offset_r = -avg_right_data;
  236 +
  237 + reg_val = (offset_l & DA7213_ALC_OFFSET_15_8) >> 8;
  238 + snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_M_L, reg_val);
  239 + reg_val = (offset_l & DA7213_ALC_OFFSET_19_16) >> 16;
  240 + snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_U_L, reg_val);
  241 +
  242 + reg_val = (offset_r & DA7213_ALC_OFFSET_15_8) >> 8;
  243 + snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_M_R, reg_val);
  244 + reg_val = (offset_r & DA7213_ALC_OFFSET_19_16) >> 16;
  245 + snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_U_R, reg_val);
  246 +
  247 + /* Enable analog/digital gain mode & offset cancellation */
  248 + snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
  249 + DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
  250 + DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE);
  251 +}
  252 +
  253 +static void da7213_alc_calib_auto(struct snd_soc_codec *codec)
  254 +{
  255 + u8 alc_ctrl1;
  256 +
  257 + /* Begin auto calibration and wait for completion */
  258 + snd_soc_update_bits(codec, DA7213_ALC_CTRL1, DA7213_ALC_AUTO_CALIB_EN,
  259 + DA7213_ALC_AUTO_CALIB_EN);
  260 + do {
  261 + alc_ctrl1 = snd_soc_read(codec, DA7213_ALC_CTRL1);
  262 + } while (alc_ctrl1 & DA7213_ALC_AUTO_CALIB_EN);
  263 +
  264 + /* If auto calibration fails, fall back to digital gain only mode */
  265 + if (alc_ctrl1 & DA7213_ALC_CALIB_OVERFLOW) {
  266 + dev_warn(codec->dev,
  267 + "ALC auto calibration failed with overflow\n");
  268 + snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
  269 + DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
  270 + 0);
  271 + } else {
  272 + /* Enable analog/digital gain mode & offset cancellation */
  273 + snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
  274 + DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
  275 + DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE);
  276 + }
  277 +
  278 +}
  279 +
  280 +static void da7213_alc_calib(struct snd_soc_codec *codec)
  281 +{
  282 + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
  283 + u8 adc_l_ctrl, adc_r_ctrl;
  284 + u8 mixin_l_sel, mixin_r_sel;
  285 + u8 mic_1_ctrl, mic_2_ctrl;
  286 +
  287 + /* Save current values from ADC control registers */
  288 + adc_l_ctrl = snd_soc_read(codec, DA7213_ADC_L_CTRL);
  289 + adc_r_ctrl = snd_soc_read(codec, DA7213_ADC_R_CTRL);
  290 +
  291 + /* Save current values from MIXIN_L/R_SELECT registers */
  292 + mixin_l_sel = snd_soc_read(codec, DA7213_MIXIN_L_SELECT);
  293 + mixin_r_sel = snd_soc_read(codec, DA7213_MIXIN_R_SELECT);
  294 +
  295 + /* Save current values from MIC control registers */
  296 + mic_1_ctrl = snd_soc_read(codec, DA7213_MIC_1_CTRL);
  297 + mic_2_ctrl = snd_soc_read(codec, DA7213_MIC_2_CTRL);
  298 +
  299 + /* Enable ADC Left and Right */
  300 + snd_soc_update_bits(codec, DA7213_ADC_L_CTRL, DA7213_ADC_EN,
  301 + DA7213_ADC_EN);
  302 + snd_soc_update_bits(codec, DA7213_ADC_R_CTRL, DA7213_ADC_EN,
  303 + DA7213_ADC_EN);
  304 +
  305 + /* Enable MIC paths */
  306 + snd_soc_update_bits(codec, DA7213_MIXIN_L_SELECT,
  307 + DA7213_MIXIN_L_MIX_SELECT_MIC_1 |
  308 + DA7213_MIXIN_L_MIX_SELECT_MIC_2,
  309 + DA7213_MIXIN_L_MIX_SELECT_MIC_1 |
  310 + DA7213_MIXIN_L_MIX_SELECT_MIC_2);
  311 + snd_soc_update_bits(codec, DA7213_MIXIN_R_SELECT,
  312 + DA7213_MIXIN_R_MIX_SELECT_MIC_2 |
  313 + DA7213_MIXIN_R_MIX_SELECT_MIC_1,
  314 + DA7213_MIXIN_R_MIX_SELECT_MIC_2 |
  315 + DA7213_MIXIN_R_MIX_SELECT_MIC_1);
  316 +
  317 + /* Mute MIC PGAs */
  318 + snd_soc_update_bits(codec, DA7213_MIC_1_CTRL, DA7213_MUTE_EN,
  319 + DA7213_MUTE_EN);
  320 + snd_soc_update_bits(codec, DA7213_MIC_2_CTRL, DA7213_MUTE_EN,
  321 + DA7213_MUTE_EN);
  322 +
  323 + /* Perform calibration */
  324 + if (da7213->alc_calib_auto)
  325 + da7213_alc_calib_auto(codec);
  326 + else
  327 + da7213_alc_calib_man(codec);
  328 +
  329 + /* Restore MIXIN_L/R_SELECT registers to their original states */
  330 + snd_soc_write(codec, DA7213_MIXIN_L_SELECT, mixin_l_sel);
  331 + snd_soc_write(codec, DA7213_MIXIN_R_SELECT, mixin_r_sel);
  332 +
  333 + /* Restore ADC control registers to their original states */
  334 + snd_soc_write(codec, DA7213_ADC_L_CTRL, adc_l_ctrl);
  335 + snd_soc_write(codec, DA7213_ADC_R_CTRL, adc_r_ctrl);
  336 +
  337 + /* Restore original values of MIC control registers */
  338 + snd_soc_write(codec, DA7213_MIC_1_CTRL, mic_1_ctrl);
  339 + snd_soc_write(codec, DA7213_MIC_2_CTRL, mic_2_ctrl);
  340 +}
  341 +
  342 +static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol,
  343 + struct snd_ctl_elem_value *ucontrol)
  344 +{
  345 + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  346 + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
  347 + int ret;
  348 +
  349 + ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
  350 +
  351 + /* If ALC in operation, make sure calibrated offsets are updated */
  352 + if ((!ret) && (da7213->alc_en))
  353 + da7213_alc_calib(codec);
  354 +
  355 + return ret;
  356 +}
  357 +
  358 +static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol,
  359 + struct snd_ctl_elem_value *ucontrol)
  360 +{
  361 + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  362 + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
  363 +
  364 + /* Force ALC offset calibration if enabling ALC */
  365 + if (ucontrol->value.integer.value[0] ||
  366 + ucontrol->value.integer.value[1]) {
  367 + if (!da7213->alc_en) {
  368 + da7213_alc_calib(codec);
  369 + da7213->alc_en = true;
  370 + }
  371 + } else {
  372 + da7213->alc_en = false;
  373 + }
  374 +
  375 + return snd_soc_put_volsw(kcontrol, ucontrol);
  376 +}
  377 +
  378 +
  379 +/*
  380 + * KControls
  381 + */
  382 +
  383 +static const struct snd_kcontrol_new da7213_snd_controls[] = {
  384 +
  385 + /* Volume controls */
  386 + SOC_SINGLE_TLV("Mic 1 Volume", DA7213_MIC_1_GAIN,
  387 + DA7213_MIC_AMP_GAIN_SHIFT, DA7213_MIC_AMP_GAIN_MAX,
  388 + DA7213_NO_INVERT, mic_vol_tlv),
  389 + SOC_SINGLE_TLV("Mic 2 Volume", DA7213_MIC_2_GAIN,
  390 + DA7213_MIC_AMP_GAIN_SHIFT, DA7213_MIC_AMP_GAIN_MAX,
  391 + DA7213_NO_INVERT, mic_vol_tlv),
  392 + SOC_DOUBLE_R_TLV("Aux Volume", DA7213_AUX_L_GAIN, DA7213_AUX_R_GAIN,
  393 + DA7213_AUX_AMP_GAIN_SHIFT, DA7213_AUX_AMP_GAIN_MAX,
  394 + DA7213_NO_INVERT, aux_vol_tlv),
  395 + SOC_DOUBLE_R_EXT_TLV("Mixin PGA Volume", DA7213_MIXIN_L_GAIN,
  396 + DA7213_MIXIN_R_GAIN, DA7213_MIXIN_AMP_GAIN_SHIFT,
  397 + DA7213_MIXIN_AMP_GAIN_MAX, DA7213_NO_INVERT,
  398 + snd_soc_get_volsw_2r, da7213_put_mixin_gain,
  399 + mixin_gain_tlv),
  400 + SOC_DOUBLE_R_TLV("ADC Volume", DA7213_ADC_L_GAIN, DA7213_ADC_R_GAIN,
  401 + DA7213_ADC_AMP_GAIN_SHIFT, DA7213_ADC_AMP_GAIN_MAX,
  402 + DA7213_NO_INVERT, digital_gain_tlv),
  403 + SOC_DOUBLE_R_TLV("DAC Volume", DA7213_DAC_L_GAIN, DA7213_DAC_R_GAIN,
  404 + DA7213_DAC_AMP_GAIN_SHIFT, DA7213_DAC_AMP_GAIN_MAX,
  405 + DA7213_NO_INVERT, digital_gain_tlv),
  406 + SOC_DOUBLE_R_TLV("Headphone Volume", DA7213_HP_L_GAIN, DA7213_HP_R_GAIN,
  407 + DA7213_HP_AMP_GAIN_SHIFT, DA7213_HP_AMP_GAIN_MAX,
  408 + DA7213_NO_INVERT, hp_vol_tlv),
  409 + SOC_SINGLE_TLV("Lineout Volume", DA7213_LINE_GAIN,
  410 + DA7213_LINE_AMP_GAIN_SHIFT, DA7213_LINE_AMP_GAIN_MAX,
  411 + DA7213_NO_INVERT, lineout_vol_tlv),
  412 +
  413 + /* DAC Equalizer controls */
  414 + SOC_SINGLE("DAC EQ Switch", DA7213_DAC_FILTERS4, DA7213_DAC_EQ_EN_SHIFT,
  415 + DA7213_DAC_EQ_EN_MAX, DA7213_NO_INVERT),
  416 + SOC_SINGLE_TLV("DAC EQ1 Volume", DA7213_DAC_FILTERS2,
  417 + DA7213_DAC_EQ_BAND1_SHIFT, DA7213_DAC_EQ_BAND_MAX,
  418 + DA7213_NO_INVERT, eq_gain_tlv),
  419 + SOC_SINGLE_TLV("DAC EQ2 Volume", DA7213_DAC_FILTERS2,
  420 + DA7213_DAC_EQ_BAND2_SHIFT, DA7213_DAC_EQ_BAND_MAX,
  421 + DA7213_NO_INVERT, eq_gain_tlv),
  422 + SOC_SINGLE_TLV("DAC EQ3 Volume", DA7213_DAC_FILTERS3,
  423 + DA7213_DAC_EQ_BAND3_SHIFT, DA7213_DAC_EQ_BAND_MAX,
  424 + DA7213_NO_INVERT, eq_gain_tlv),
  425 + SOC_SINGLE_TLV("DAC EQ4 Volume", DA7213_DAC_FILTERS3,
  426 + DA7213_DAC_EQ_BAND4_SHIFT, DA7213_DAC_EQ_BAND_MAX,
  427 + DA7213_NO_INVERT, eq_gain_tlv),
  428 + SOC_SINGLE_TLV("DAC EQ5 Volume", DA7213_DAC_FILTERS4,
  429 + DA7213_DAC_EQ_BAND5_SHIFT, DA7213_DAC_EQ_BAND_MAX,
  430 + DA7213_NO_INVERT, eq_gain_tlv),
  431 +
  432 + /* High Pass Filter and Voice Mode controls */
  433 + SOC_SINGLE("ADC HPF Switch", DA7213_ADC_FILTERS1, DA7213_HPF_EN_SHIFT,
  434 + DA7213_HPF_EN_MAX, DA7213_NO_INVERT),
  435 + SOC_ENUM("ADC HPF Cutoff", da7213_adc_audio_hpf_corner),
  436 + SOC_SINGLE("ADC Voice Mode Switch", DA7213_ADC_FILTERS1,
  437 + DA7213_VOICE_EN_SHIFT, DA7213_VOICE_EN_MAX,
  438 + DA7213_NO_INVERT),
  439 + SOC_ENUM("ADC Voice Cutoff", da7213_adc_voice_hpf_corner),
  440 +
  441 + SOC_SINGLE("DAC HPF Switch", DA7213_DAC_FILTERS1, DA7213_HPF_EN_SHIFT,
  442 + DA7213_HPF_EN_MAX, DA7213_NO_INVERT),
  443 + SOC_ENUM("DAC HPF Cutoff", da7213_dac_audio_hpf_corner),
  444 + SOC_SINGLE("DAC Voice Mode Switch", DA7213_DAC_FILTERS1,
  445 + DA7213_VOICE_EN_SHIFT, DA7213_VOICE_EN_MAX,
  446 + DA7213_NO_INVERT),
  447 + SOC_ENUM("DAC Voice Cutoff", da7213_dac_voice_hpf_corner),
  448 +
  449 + /* Mute controls */
  450 + SOC_SINGLE("Mic 1 Switch", DA7213_MIC_1_CTRL, DA7213_MUTE_EN_SHIFT,
  451 + DA7213_MUTE_EN_MAX, DA7213_INVERT),
  452 + SOC_SINGLE("Mic 2 Switch", DA7213_MIC_2_CTRL, DA7213_MUTE_EN_SHIFT,
  453 + DA7213_MUTE_EN_MAX, DA7213_INVERT),
  454 + SOC_DOUBLE_R("Aux Switch", DA7213_AUX_L_CTRL, DA7213_AUX_R_CTRL,
  455 + DA7213_MUTE_EN_SHIFT, DA7213_MUTE_EN_MAX, DA7213_INVERT),
  456 + SOC_DOUBLE_R("Mixin PGA Switch", DA7213_MIXIN_L_CTRL,
  457 + DA7213_MIXIN_R_CTRL, DA7213_MUTE_EN_SHIFT,
  458 + DA7213_MUTE_EN_MAX, DA7213_INVERT),
  459 + SOC_DOUBLE_R("ADC Switch", DA7213_ADC_L_CTRL, DA7213_ADC_R_CTRL,
  460 + DA7213_MUTE_EN_SHIFT, DA7213_MUTE_EN_MAX, DA7213_INVERT),
  461 + SOC_DOUBLE_R("Headphone Switch", DA7213_HP_L_CTRL, DA7213_HP_R_CTRL,
  462 + DA7213_MUTE_EN_SHIFT, DA7213_MUTE_EN_MAX, DA7213_INVERT),
  463 + SOC_SINGLE("Lineout Switch", DA7213_LINE_CTRL, DA7213_MUTE_EN_SHIFT,
  464 + DA7213_MUTE_EN_MAX, DA7213_INVERT),
  465 + SOC_SINGLE("DAC Soft Mute Switch", DA7213_DAC_FILTERS5,
  466 + DA7213_DAC_SOFTMUTE_EN_SHIFT, DA7213_DAC_SOFTMUTE_EN_MAX,
  467 + DA7213_NO_INVERT),
  468 + SOC_ENUM("DAC Soft Mute Rate", da7213_dac_soft_mute_rate),
  469 +
  470 + /* Zero Cross controls */
  471 + SOC_DOUBLE_R("Aux ZC Switch", DA7213_AUX_L_CTRL, DA7213_AUX_R_CTRL,
  472 + DA7213_ZC_EN_SHIFT, DA7213_ZC_EN_MAX, DA7213_NO_INVERT),
  473 + SOC_DOUBLE_R("Mixin PGA ZC Switch", DA7213_MIXIN_L_CTRL,
  474 + DA7213_MIXIN_R_CTRL, DA7213_ZC_EN_SHIFT, DA7213_ZC_EN_MAX,
  475 + DA7213_NO_INVERT),
  476 + SOC_DOUBLE_R("Headphone ZC Switch", DA7213_HP_L_CTRL, DA7213_HP_R_CTRL,
  477 + DA7213_ZC_EN_SHIFT, DA7213_ZC_EN_MAX, DA7213_NO_INVERT),
  478 +
  479 + /* Gain Ramping controls */
  480 + SOC_DOUBLE_R("Aux Gain Ramping Switch", DA7213_AUX_L_CTRL,
  481 + DA7213_AUX_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
  482 + DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
  483 + SOC_DOUBLE_R("Mixin Gain Ramping Switch", DA7213_MIXIN_L_CTRL,
  484 + DA7213_MIXIN_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
  485 + DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
  486 + SOC_DOUBLE_R("ADC Gain Ramping Switch", DA7213_ADC_L_CTRL,
  487 + DA7213_ADC_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
  488 + DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
  489 + SOC_DOUBLE_R("DAC Gain Ramping Switch", DA7213_DAC_L_CTRL,
  490 + DA7213_DAC_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
  491 + DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
  492 + SOC_DOUBLE_R("Headphone Gain Ramping Switch", DA7213_HP_L_CTRL,
  493 + DA7213_HP_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
  494 + DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
  495 + SOC_SINGLE("Lineout Gain Ramping Switch", DA7213_LINE_CTRL,
  496 + DA7213_GAIN_RAMP_EN_SHIFT, DA7213_GAIN_RAMP_EN_MAX,
  497 + DA7213_NO_INVERT),
  498 + SOC_ENUM("Gain Ramping Rate", da7213_gain_ramp_rate),
  499 +
  500 + /* DAC Noise Gate controls */
  501 + SOC_SINGLE("DAC NG Switch", DA7213_DAC_NG_CTRL, DA7213_DAC_NG_EN_SHIFT,
  502 + DA7213_DAC_NG_EN_MAX, DA7213_NO_INVERT),
  503 + SOC_ENUM("DAC NG Setup Time", da7213_dac_ng_setup_time),
  504 + SOC_ENUM("DAC NG Rampup Rate", da7213_dac_ng_rampup_rate),
  505 + SOC_ENUM("DAC NG Rampdown Rate", da7213_dac_ng_rampdown_rate),
  506 + SOC_SINGLE("DAC NG OFF Threshold", DA7213_DAC_NG_OFF_THRESHOLD,
  507 + DA7213_DAC_NG_THRESHOLD_SHIFT, DA7213_DAC_NG_THRESHOLD_MAX,
  508 + DA7213_NO_INVERT),
  509 + SOC_SINGLE("DAC NG ON Threshold", DA7213_DAC_NG_ON_THRESHOLD,
  510 + DA7213_DAC_NG_THRESHOLD_SHIFT, DA7213_DAC_NG_THRESHOLD_MAX,
  511 + DA7213_NO_INVERT),
  512 +
  513 + /* DAC Routing & Inversion */
  514 + SOC_DOUBLE("DAC Mono Switch", DA7213_DIG_ROUTING_DAC,
  515 + DA7213_DAC_L_MONO_SHIFT, DA7213_DAC_R_MONO_SHIFT,
  516 + DA7213_DAC_MONO_MAX, DA7213_NO_INVERT),
  517 + SOC_DOUBLE("DAC Invert Switch", DA7213_DIG_CTRL, DA7213_DAC_L_INV_SHIFT,
  518 + DA7213_DAC_R_INV_SHIFT, DA7213_DAC_INV_MAX,
  519 + DA7213_NO_INVERT),
  520 +
  521 + /* DMIC controls */
  522 + SOC_DOUBLE_R("DMIC Switch", DA7213_MIXIN_L_SELECT,
  523 + DA7213_MIXIN_R_SELECT, DA7213_DMIC_EN_SHIFT,
  524 + DA7213_DMIC_EN_MAX, DA7213_NO_INVERT),
  525 +
  526 + /* ALC Controls */
  527 + SOC_DOUBLE_EXT("ALC Switch", DA7213_ALC_CTRL1, DA7213_ALC_L_EN_SHIFT,
  528 + DA7213_ALC_R_EN_SHIFT, DA7213_ALC_EN_MAX,
  529 + DA7213_NO_INVERT, snd_soc_get_volsw, da7213_put_alc_sw),
  530 + SOC_ENUM("ALC Attack Rate", da7213_alc_attack_rate),
  531 + SOC_ENUM("ALC Release Rate", da7213_alc_release_rate),
  532 + SOC_ENUM("ALC Hold Time", da7213_alc_hold_time),
  533 + /*
  534 + * Rate at which input signal envelope is tracked as the signal gets
  535 + * larger
  536 + */
  537 + SOC_ENUM("ALC Integ Attack Rate", da7213_alc_integ_attack_rate),
  538 + /*
  539 + * Rate at which input signal envelope is tracked as the signal gets
  540 + * smaller
  541 + */
  542 + SOC_ENUM("ALC Integ Release Rate", da7213_alc_integ_release_rate),
  543 + SOC_SINGLE_TLV("ALC Noise Threshold Volume", DA7213_ALC_NOISE,
  544 + DA7213_ALC_THRESHOLD_SHIFT, DA7213_ALC_THRESHOLD_MAX,
  545 + DA7213_INVERT, alc_threshold_tlv),
  546 + SOC_SINGLE_TLV("ALC Min Threshold Volume", DA7213_ALC_TARGET_MIN,
  547 + DA7213_ALC_THRESHOLD_SHIFT, DA7213_ALC_THRESHOLD_MAX,
  548 + DA7213_INVERT, alc_threshold_tlv),
  549 + SOC_SINGLE_TLV("ALC Max Threshold Volume", DA7213_ALC_TARGET_MAX,
  550 + DA7213_ALC_THRESHOLD_SHIFT, DA7213_ALC_THRESHOLD_MAX,
  551 + DA7213_INVERT, alc_threshold_tlv),
  552 + SOC_SINGLE_TLV("ALC Max Attenuation Volume", DA7213_ALC_GAIN_LIMITS,
  553 + DA7213_ALC_ATTEN_MAX_SHIFT,
  554 + DA7213_ALC_ATTEN_GAIN_MAX_MAX, DA7213_NO_INVERT,
  555 + alc_gain_tlv),
  556 + SOC_SINGLE_TLV("ALC Max Gain Volume", DA7213_ALC_GAIN_LIMITS,
  557 + DA7213_ALC_GAIN_MAX_SHIFT, DA7213_ALC_ATTEN_GAIN_MAX_MAX,
  558 + DA7213_NO_INVERT, alc_gain_tlv),
  559 + SOC_SINGLE_TLV("ALC Min Analog Gain Volume", DA7213_ALC_ANA_GAIN_LIMITS,
  560 + DA7213_ALC_ANA_GAIN_MIN_SHIFT, DA7213_ALC_ANA_GAIN_MAX,
  561 + DA7213_NO_INVERT, alc_analog_gain_tlv),
  562 + SOC_SINGLE_TLV("ALC Max Analog Gain Volume", DA7213_ALC_ANA_GAIN_LIMITS,
  563 + DA7213_ALC_ANA_GAIN_MAX_SHIFT, DA7213_ALC_ANA_GAIN_MAX,
  564 + DA7213_NO_INVERT, alc_analog_gain_tlv),
  565 + SOC_SINGLE("ALC Anticlip Mode Switch", DA7213_ALC_ANTICLIP_CTRL,
  566 + DA7213_ALC_ANTICLIP_EN_SHIFT, DA7213_ALC_ANTICLIP_EN_MAX,
  567 + DA7213_NO_INVERT),
  568 + SOC_SINGLE("ALC Anticlip Level", DA7213_ALC_ANTICLIP_LEVEL,
  569 + DA7213_ALC_ANTICLIP_LEVEL_SHIFT,
  570 + DA7213_ALC_ANTICLIP_LEVEL_MAX, DA7213_NO_INVERT),
  571 +};
  572 +
  573 +
  574 +/*
  575 + * DAPM
  576 + */
  577 +
  578 +/*
  579 + * Enums
  580 + */
  581 +
  582 +/* MIC PGA source select */
  583 +static const char * const da7213_mic_amp_in_sel_txt[] = {
  584 + "Differential", "MIC_P", "MIC_N"
  585 +};
  586 +
  587 +static const struct soc_enum da7213_mic_1_amp_in_sel =
  588 + SOC_ENUM_SINGLE(DA7213_MIC_1_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT,
  589 + DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt);
  590 +static const struct snd_kcontrol_new da7213_mic_1_amp_in_sel_mux =
  591 + SOC_DAPM_ENUM("Mic 1 Amp Source MUX", da7213_mic_1_amp_in_sel);
  592 +
  593 +static const struct soc_enum da7213_mic_2_amp_in_sel =
  594 + SOC_ENUM_SINGLE(DA7213_MIC_2_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT,
  595 + DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt);
  596 +static const struct snd_kcontrol_new da7213_mic_2_amp_in_sel_mux =
  597 + SOC_DAPM_ENUM("Mic 2 Amp Source MUX", da7213_mic_2_amp_in_sel);
  598 +
  599 +/* DAI routing select */
  600 +static const char * const da7213_dai_src_txt[] = {
  601 + "ADC Left", "ADC Right", "DAI Input Left", "DAI Input Right"
  602 +};
  603 +
  604 +static const struct soc_enum da7213_dai_l_src =
  605 + SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_L_SRC_SHIFT,
  606 + DA7213_DAI_SRC_MAX, da7213_dai_src_txt);
  607 +static const struct snd_kcontrol_new da7213_dai_l_src_mux =
  608 + SOC_DAPM_ENUM("DAI Left Source MUX", da7213_dai_l_src);
  609 +
  610 +static const struct soc_enum da7213_dai_r_src =
  611 + SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_R_SRC_SHIFT,
  612 + DA7213_DAI_SRC_MAX, da7213_dai_src_txt);
  613 +static const struct snd_kcontrol_new da7213_dai_r_src_mux =
  614 + SOC_DAPM_ENUM("DAI Right Source MUX", da7213_dai_r_src);
  615 +
  616 +/* DAC routing select */
  617 +static const char * const da7213_dac_src_txt[] = {
  618 + "ADC Output Left", "ADC Output Right", "DAI Input Left",
  619 + "DAI Input Right"
  620 +};
  621 +
  622 +static const struct soc_enum da7213_dac_l_src =
  623 + SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_L_SRC_SHIFT,
  624 + DA7213_DAC_SRC_MAX, da7213_dac_src_txt);
  625 +static const struct snd_kcontrol_new da7213_dac_l_src_mux =
  626 + SOC_DAPM_ENUM("DAC Left Source MUX", da7213_dac_l_src);
  627 +
  628 +static const struct soc_enum da7213_dac_r_src =
  629 + SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_R_SRC_SHIFT,
  630 + DA7213_DAC_SRC_MAX, da7213_dac_src_txt);
  631 +static const struct snd_kcontrol_new da7213_dac_r_src_mux =
  632 + SOC_DAPM_ENUM("DAC Right Source MUX", da7213_dac_r_src);
  633 +
  634 +/*
  635 + * Mixer Controls
  636 + */
  637 +
  638 +/* Mixin Left */
  639 +static const struct snd_kcontrol_new da7213_dapm_mixinl_controls[] = {
  640 + SOC_DAPM_SINGLE("Aux Left Switch", DA7213_MIXIN_L_SELECT,
  641 + DA7213_MIXIN_L_MIX_SELECT_AUX_L_SHIFT,
  642 + DA7213_MIXIN_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  643 + SOC_DAPM_SINGLE("Mic 1 Switch", DA7213_MIXIN_L_SELECT,
  644 + DA7213_MIXIN_L_MIX_SELECT_MIC_1_SHIFT,
  645 + DA7213_MIXIN_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  646 + SOC_DAPM_SINGLE("Mic 2 Switch", DA7213_MIXIN_L_SELECT,
  647 + DA7213_MIXIN_L_MIX_SELECT_MIC_2_SHIFT,
  648 + DA7213_MIXIN_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  649 + SOC_DAPM_SINGLE("Mixin Right Switch", DA7213_MIXIN_L_SELECT,
  650 + DA7213_MIXIN_L_MIX_SELECT_MIXIN_R_SHIFT,
  651 + DA7213_MIXIN_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  652 +};
  653 +
  654 +/* Mixin Right */
  655 +static const struct snd_kcontrol_new da7213_dapm_mixinr_controls[] = {
  656 + SOC_DAPM_SINGLE("Aux Right Switch", DA7213_MIXIN_R_SELECT,
  657 + DA7213_MIXIN_R_MIX_SELECT_AUX_R_SHIFT,
  658 + DA7213_MIXIN_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  659 + SOC_DAPM_SINGLE("Mic 2 Switch", DA7213_MIXIN_R_SELECT,
  660 + DA7213_MIXIN_R_MIX_SELECT_MIC_2_SHIFT,
  661 + DA7213_MIXIN_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  662 + SOC_DAPM_SINGLE("Mic 1 Switch", DA7213_MIXIN_R_SELECT,
  663 + DA7213_MIXIN_R_MIX_SELECT_MIC_1_SHIFT,
  664 + DA7213_MIXIN_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  665 + SOC_DAPM_SINGLE("Mixin Left Switch", DA7213_MIXIN_R_SELECT,
  666 + DA7213_MIXIN_R_MIX_SELECT_MIXIN_L_SHIFT,
  667 + DA7213_MIXIN_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  668 +};
  669 +
  670 +/* Mixout Left */
  671 +static const struct snd_kcontrol_new da7213_dapm_mixoutl_controls[] = {
  672 + SOC_DAPM_SINGLE("Aux Left Switch", DA7213_MIXOUT_L_SELECT,
  673 + DA7213_MIXOUT_L_MIX_SELECT_AUX_L_SHIFT,
  674 + DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  675 + SOC_DAPM_SINGLE("Mixin Left Switch", DA7213_MIXOUT_L_SELECT,
  676 + DA7213_MIXOUT_L_MIX_SELECT_MIXIN_L_SHIFT,
  677 + DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  678 + SOC_DAPM_SINGLE("Mixin Right Switch", DA7213_MIXOUT_L_SELECT,
  679 + DA7213_MIXOUT_L_MIX_SELECT_MIXIN_R_SHIFT,
  680 + DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  681 + SOC_DAPM_SINGLE("DAC Left Switch", DA7213_MIXOUT_L_SELECT,
  682 + DA7213_MIXOUT_L_MIX_SELECT_DAC_L_SHIFT,
  683 + DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  684 + SOC_DAPM_SINGLE("Aux Left Invert Switch", DA7213_MIXOUT_L_SELECT,
  685 + DA7213_MIXOUT_L_MIX_SELECT_AUX_L_INVERTED_SHIFT,
  686 + DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  687 + SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA7213_MIXOUT_L_SELECT,
  688 + DA7213_MIXOUT_L_MIX_SELECT_MIXIN_L_INVERTED_SHIFT,
  689 + DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  690 + SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA7213_MIXOUT_L_SELECT,
  691 + DA7213_MIXOUT_L_MIX_SELECT_MIXIN_R_INVERTED_SHIFT,
  692 + DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
  693 +};
  694 +
  695 +/* Mixout Right */
  696 +static const struct snd_kcontrol_new da7213_dapm_mixoutr_controls[] = {
  697 + SOC_DAPM_SINGLE("Aux Right Switch", DA7213_MIXOUT_R_SELECT,
  698 + DA7213_MIXOUT_R_MIX_SELECT_AUX_R_SHIFT,
  699 + DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  700 + SOC_DAPM_SINGLE("Mixin Right Switch", DA7213_MIXOUT_R_SELECT,
  701 + DA7213_MIXOUT_R_MIX_SELECT_MIXIN_R_SHIFT,
  702 + DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  703 + SOC_DAPM_SINGLE("Mixin Left Switch", DA7213_MIXOUT_R_SELECT,
  704 + DA7213_MIXOUT_R_MIX_SELECT_MIXIN_L_SHIFT,
  705 + DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  706 + SOC_DAPM_SINGLE("DAC Right Switch", DA7213_MIXOUT_R_SELECT,
  707 + DA7213_MIXOUT_R_MIX_SELECT_DAC_R_SHIFT,
  708 + DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  709 + SOC_DAPM_SINGLE("Aux Right Invert Switch", DA7213_MIXOUT_R_SELECT,
  710 + DA7213_MIXOUT_R_MIX_SELECT_AUX_R_INVERTED_SHIFT,
  711 + DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  712 + SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA7213_MIXOUT_R_SELECT,
  713 + DA7213_MIXOUT_R_MIX_SELECT_MIXIN_R_INVERTED_SHIFT,
  714 + DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  715 + SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA7213_MIXOUT_R_SELECT,
  716 + DA7213_MIXOUT_R_MIX_SELECT_MIXIN_L_INVERTED_SHIFT,
  717 + DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
  718 +};
  719 +
  720 +
  721 +/*
  722 + * DAPM widgets
  723 + */
  724 +
  725 +static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = {
  726 + /*
  727 + * Input & Output
  728 + */
  729 +
  730 + /* Use a supply here as this controls both input & output DAIs */
  731 + SND_SOC_DAPM_SUPPLY("DAI", DA7213_DAI_CTRL, DA7213_DAI_EN_SHIFT,
  732 + DA7213_NO_INVERT, NULL, 0),
  733 +
  734 + /*
  735 + * Input
  736 + */
  737 +
  738 + /* Input Lines */
  739 + SND_SOC_DAPM_INPUT("MIC1"),
  740 + SND_SOC_DAPM_INPUT("MIC2"),
  741 + SND_SOC_DAPM_INPUT("AUXL"),
  742 + SND_SOC_DAPM_INPUT("AUXR"),
  743 +
  744 + /* MUXs for Mic PGA source selection */
  745 + SND_SOC_DAPM_MUX("Mic 1 Amp Source MUX", SND_SOC_NOPM, 0, 0,
  746 + &da7213_mic_1_amp_in_sel_mux),
  747 + SND_SOC_DAPM_MUX("Mic 2 Amp Source MUX", SND_SOC_NOPM, 0, 0,
  748 + &da7213_mic_2_amp_in_sel_mux),
  749 +
  750 + /* Input PGAs */
  751 + SND_SOC_DAPM_PGA("Mic 1 PGA", DA7213_MIC_1_CTRL, DA7213_AMP_EN_SHIFT,
  752 + DA7213_NO_INVERT, NULL, 0),
  753 + SND_SOC_DAPM_PGA("Mic 2 PGA", DA7213_MIC_2_CTRL, DA7213_AMP_EN_SHIFT,
  754 + DA7213_NO_INVERT, NULL, 0),
  755 + SND_SOC_DAPM_PGA("Aux Left PGA", DA7213_AUX_L_CTRL, DA7213_AMP_EN_SHIFT,
  756 + DA7213_NO_INVERT, NULL, 0),
  757 + SND_SOC_DAPM_PGA("Aux Right PGA", DA7213_AUX_R_CTRL,
  758 + DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
  759 + SND_SOC_DAPM_PGA("Mixin Left PGA", DA7213_MIXIN_L_CTRL,
  760 + DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
  761 + SND_SOC_DAPM_PGA("Mixin Right PGA", DA7213_MIXIN_R_CTRL,
  762 + DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
  763 +
  764 + /* Mic Biases */
  765 + SND_SOC_DAPM_SUPPLY("Mic Bias 1", DA7213_MICBIAS_CTRL,
  766 + DA7213_MICBIAS1_EN_SHIFT, DA7213_NO_INVERT,
  767 + NULL, 0),
  768 + SND_SOC_DAPM_SUPPLY("Mic Bias 2", DA7213_MICBIAS_CTRL,
  769 + DA7213_MICBIAS2_EN_SHIFT, DA7213_NO_INVERT,
  770 + NULL, 0),
  771 +
  772 + /* Input Mixers */
  773 + SND_SOC_DAPM_MIXER("Mixin Left", SND_SOC_NOPM, 0, 0,
  774 + &da7213_dapm_mixinl_controls[0],
  775 + ARRAY_SIZE(da7213_dapm_mixinl_controls)),
  776 + SND_SOC_DAPM_MIXER("Mixin Right", SND_SOC_NOPM, 0, 0,
  777 + &da7213_dapm_mixinr_controls[0],
  778 + ARRAY_SIZE(da7213_dapm_mixinr_controls)),
  779 +
  780 + /* ADCs */
  781 + SND_SOC_DAPM_ADC("ADC Left", NULL, DA7213_ADC_L_CTRL,
  782 + DA7213_ADC_EN_SHIFT, DA7213_NO_INVERT),
  783 + SND_SOC_DAPM_ADC("ADC Right", NULL, DA7213_ADC_R_CTRL,
  784 + DA7213_ADC_EN_SHIFT, DA7213_NO_INVERT),
  785 +
  786 + /* DAI */
  787 + SND_SOC_DAPM_MUX("DAI Left Source MUX", SND_SOC_NOPM, 0, 0,
  788 + &da7213_dai_l_src_mux),
  789 + SND_SOC_DAPM_MUX("DAI Right Source MUX", SND_SOC_NOPM, 0, 0,
  790 + &da7213_dai_r_src_mux),
  791 + SND_SOC_DAPM_AIF_OUT("DAIOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
  792 + SND_SOC_DAPM_AIF_OUT("DAIOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
  793 +
  794 + /*
  795 + * Output
  796 + */
  797 +
  798 + /* DAI */
  799 + SND_SOC_DAPM_AIF_IN("DAIINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
  800 + SND_SOC_DAPM_AIF_IN("DAIINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
  801 + SND_SOC_DAPM_MUX("DAC Left Source MUX", SND_SOC_NOPM, 0, 0,
  802 + &da7213_dac_l_src_mux),
  803 + SND_SOC_DAPM_MUX("DAC Right Source MUX", SND_SOC_NOPM, 0, 0,
  804 + &da7213_dac_r_src_mux),
  805 +
  806 + /* DACs */
  807 + SND_SOC_DAPM_DAC("DAC Left", NULL, DA7213_DAC_L_CTRL,
  808 + DA7213_DAC_EN_SHIFT, DA7213_NO_INVERT),
  809 + SND_SOC_DAPM_DAC("DAC Right", NULL, DA7213_DAC_R_CTRL,
  810 + DA7213_DAC_EN_SHIFT, DA7213_NO_INVERT),
  811 +
  812 + /* Output Mixers */
  813 + SND_SOC_DAPM_MIXER("Mixout Left", SND_SOC_NOPM, 0, 0,
  814 + &da7213_dapm_mixoutl_controls[0],
  815 + ARRAY_SIZE(da7213_dapm_mixoutl_controls)),
  816 + SND_SOC_DAPM_MIXER("Mixout Right", SND_SOC_NOPM, 0, 0,
  817 + &da7213_dapm_mixoutr_controls[0],
  818 + ARRAY_SIZE(da7213_dapm_mixoutr_controls)),
  819 +
  820 + /* Output PGAs */
  821 + SND_SOC_DAPM_PGA("Mixout Left PGA", DA7213_MIXOUT_L_CTRL,
  822 + DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
  823 + SND_SOC_DAPM_PGA("Mixout Right PGA", DA7213_MIXOUT_R_CTRL,
  824 + DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
  825 + SND_SOC_DAPM_PGA("Lineout PGA", DA7213_LINE_CTRL, DA7213_AMP_EN_SHIFT,
  826 + DA7213_NO_INVERT, NULL, 0),
  827 + SND_SOC_DAPM_PGA("Headphone Left PGA", DA7213_HP_L_CTRL,
  828 + DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
  829 + SND_SOC_DAPM_PGA("Headphone Right PGA", DA7213_HP_R_CTRL,
  830 + DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
  831 +
  832 + /* Charge Pump */
  833 + SND_SOC_DAPM_SUPPLY("Charge Pump", DA7213_CP_CTRL, DA7213_CP_EN_SHIFT,
  834 + DA7213_NO_INVERT, NULL, 0),
  835 +
  836 + /* Output Lines */
  837 + SND_SOC_DAPM_OUTPUT("HPL"),
  838 + SND_SOC_DAPM_OUTPUT("HPR"),
  839 + SND_SOC_DAPM_OUTPUT("LINE"),
  840 +};
  841 +
  842 +
  843 +/*
  844 + * DAPM audio route definition
  845 + */
  846 +
  847 +static const struct snd_soc_dapm_route da7213_audio_map[] = {
  848 + /* Dest Connecting Widget source */
  849 +
  850 + /* Input path */
  851 + {"MIC1", NULL, "Mic Bias 1"},
  852 + {"MIC2", NULL, "Mic Bias 2"},
  853 +
  854 + {"Mic 1 Amp Source MUX", "Differential", "MIC1"},
  855 + {"Mic 1 Amp Source MUX", "MIC_P", "MIC1"},
  856 + {"Mic 1 Amp Source MUX", "MIC_N", "MIC1"},
  857 +
  858 + {"Mic 2 Amp Source MUX", "Differential", "MIC2"},
  859 + {"Mic 2 Amp Source MUX", "MIC_P", "MIC2"},
  860 + {"Mic 2 Amp Source MUX", "MIC_N", "MIC2"},
  861 +
  862 + {"Mic 1 PGA", NULL, "Mic 1 Amp Source MUX"},
  863 + {"Mic 2 PGA", NULL, "Mic 2 Amp Source MUX"},
  864 +
  865 + {"Aux Left PGA", NULL, "AUXL"},
  866 + {"Aux Right PGA", NULL, "AUXR"},
  867 +
  868 + {"Mixin Left", "Aux Left Switch", "Aux Left PGA"},
  869 + {"Mixin Left", "Mic 1 Switch", "Mic 1 PGA"},
  870 + {"Mixin Left", "Mic 2 Switch", "Mic 2 PGA"},
  871 + {"Mixin Left", "Mixin Right Switch", "Mixin Right PGA"},
  872 +
  873 + {"Mixin Right", "Aux Right Switch", "Aux Right PGA"},
  874 + {"Mixin Right", "Mic 2 Switch", "Mic 2 PGA"},
  875 + {"Mixin Right", "Mic 1 Switch", "Mic 1 PGA"},
  876 + {"Mixin Right", "Mixin Left Switch", "Mixin Left PGA"},
  877 +
  878 + {"Mixin Left PGA", NULL, "Mixin Left"},
  879 + {"ADC Left", NULL, "Mixin Left PGA"},
  880 +
  881 + {"Mixin Right PGA", NULL, "Mixin Right"},
  882 + {"ADC Right", NULL, "Mixin Right PGA"},
  883 +
  884 + {"DAI Left Source MUX", "ADC Left", "ADC Left"},
  885 + {"DAI Left Source MUX", "ADC Right", "ADC Right"},
  886 + {"DAI Left Source MUX", "DAI Input Left", "DAIINL"},
  887 + {"DAI Left Source MUX", "DAI Input Right", "DAIINR"},
  888 +
  889 + {"DAI Right Source MUX", "ADC Left", "ADC Left"},
  890 + {"DAI Right Source MUX", "ADC Right", "ADC Right"},
  891 + {"DAI Right Source MUX", "DAI Input Left", "DAIINL"},
  892 + {"DAI Right Source MUX", "DAI Input Right", "DAIINR"},
  893 +
  894 + {"DAIOUTL", NULL, "DAI Left Source MUX"},
  895 + {"DAIOUTR", NULL, "DAI Right Source MUX"},
  896 +
  897 + {"DAIOUTL", NULL, "DAI"},
  898 + {"DAIOUTR", NULL, "DAI"},
  899 +
  900 + /* Output path */
  901 + {"DAIINL", NULL, "DAI"},
  902 + {"DAIINR", NULL, "DAI"},
  903 +
  904 + {"DAC Left Source MUX", "ADC Output Left", "ADC Left"},
  905 + {"DAC Left Source MUX", "ADC Output Right", "ADC Right"},
  906 + {"DAC Left Source MUX", "DAI Input Left", "DAIINL"},
  907 + {"DAC Left Source MUX", "DAI Input Right", "DAIINR"},
  908 +
  909 + {"DAC Right Source MUX", "ADC Output Left", "ADC Left"},
  910 + {"DAC Right Source MUX", "ADC Output Right", "ADC Right"},
  911 + {"DAC Right Source MUX", "DAI Input Left", "DAIINL"},
  912 + {"DAC Right Source MUX", "DAI Input Right", "DAIINR"},
  913 +
  914 + {"DAC Left", NULL, "DAC Left Source MUX"},
  915 + {"DAC Right", NULL, "DAC Right Source MUX"},
  916 +
  917 + {"Mixout Left", "Aux Left Switch", "Aux Left PGA"},
  918 + {"Mixout Left", "Mixin Left Switch", "Mixin Left PGA"},
  919 + {"Mixout Left", "Mixin Right Switch", "Mixin Right PGA"},
  920 + {"Mixout Left", "DAC Left Switch", "DAC Left"},
  921 + {"Mixout Left", "Aux Left Invert Switch", "Aux Left PGA"},
  922 + {"Mixout Left", "Mixin Left Invert Switch", "Mixin Left PGA"},
  923 + {"Mixout Left", "Mixin Right Invert Switch", "Mixin Right PGA"},
  924 +
  925 + {"Mixout Right", "Aux Right Switch", "Aux Right PGA"},
  926 + {"Mixout Right", "Mixin Right Switch", "Mixin Right PGA"},
  927 + {"Mixout Right", "Mixin Left Switch", "Mixin Left PGA"},
  928 + {"Mixout Right", "DAC Right Switch", "DAC Right"},
  929 + {"Mixout Right", "Aux Right Invert Switch", "Aux Right PGA"},
  930 + {"Mixout Right", "Mixin Right Invert Switch", "Mixin Right PGA"},
  931 + {"Mixout Right", "Mixin Left Invert Switch", "Mixin Left PGA"},
  932 +
  933 + {"Mixout Left PGA", NULL, "Mixout Left"},
  934 + {"Mixout Right PGA", NULL, "Mixout Right"},
  935 +
  936 + {"Headphone Left PGA", NULL, "Mixout Left PGA"},
  937 + {"Headphone Left PGA", NULL, "Charge Pump"},
  938 + {"HPL", NULL, "Headphone Left PGA"},
  939 +
  940 + {"Headphone Right PGA", NULL, "Mixout Right PGA"},
  941 + {"Headphone Right PGA", NULL, "Charge Pump"},
  942 + {"HPR", NULL, "Headphone Right PGA"},
  943 +
  944 + {"Lineout PGA", NULL, "Mixout Right PGA"},
  945 + {"LINE", NULL, "Lineout PGA"},
  946 +};
  947 +
  948 +static struct reg_default da7213_reg_defaults[] = {
  949 + { DA7213_DIG_ROUTING_DAI, 0x10 },
  950 + { DA7213_SR, 0x0A },
  951 + { DA7213_REFERENCES, 0x80 },
  952 + { DA7213_PLL_FRAC_TOP, 0x00 },
  953 + { DA7213_PLL_FRAC_BOT, 0x00 },
  954 + { DA7213_PLL_INTEGER, 0x20 },
  955 + { DA7213_PLL_CTRL, 0x0C },
  956 + { DA7213_DAI_CLK_MODE, 0x01 },
  957 + { DA7213_DAI_CTRL, 0x08 },
  958 + { DA7213_DIG_ROUTING_DAC, 0x32 },
  959 + { DA7213_AUX_L_GAIN, 0x35 },
  960 + { DA7213_AUX_R_GAIN, 0x35 },
  961 + { DA7213_MIXIN_L_SELECT, 0x00 },
  962 + { DA7213_MIXIN_R_SELECT, 0x00 },
  963 + { DA7213_MIXIN_L_GAIN, 0x03 },
  964 + { DA7213_MIXIN_R_GAIN, 0x03 },
  965 + { DA7213_ADC_L_GAIN, 0x6F },
  966 + { DA7213_ADC_R_GAIN, 0x6F },
  967 + { DA7213_ADC_FILTERS1, 0x80 },
  968 + { DA7213_MIC_1_GAIN, 0x01 },
  969 + { DA7213_MIC_2_GAIN, 0x01 },
  970 + { DA7213_DAC_FILTERS5, 0x00 },
  971 + { DA7213_DAC_FILTERS2, 0x88 },
  972 + { DA7213_DAC_FILTERS3, 0x88 },
  973 + { DA7213_DAC_FILTERS4, 0x08 },
  974 + { DA7213_DAC_FILTERS1, 0x80 },
  975 + { DA7213_DAC_L_GAIN, 0x6F },
  976 + { DA7213_DAC_R_GAIN, 0x6F },
  977 + { DA7213_CP_CTRL, 0x61 },
  978 + { DA7213_HP_L_GAIN, 0x39 },
  979 + { DA7213_HP_R_GAIN, 0x39 },
  980 + { DA7213_LINE_GAIN, 0x30 },
  981 + { DA7213_MIXOUT_L_SELECT, 0x00 },
  982 + { DA7213_MIXOUT_R_SELECT, 0x00 },
  983 + { DA7213_SYSTEM_MODES_INPUT, 0x00 },
  984 + { DA7213_SYSTEM_MODES_OUTPUT, 0x00 },
  985 + { DA7213_AUX_L_CTRL, 0x44 },
  986 + { DA7213_AUX_R_CTRL, 0x44 },
  987 + { DA7213_MICBIAS_CTRL, 0x11 },
  988 + { DA7213_MIC_1_CTRL, 0x40 },
  989 + { DA7213_MIC_2_CTRL, 0x40 },
  990 + { DA7213_MIXIN_L_CTRL, 0x40 },
  991 + { DA7213_MIXIN_R_CTRL, 0x40 },
  992 + { DA7213_ADC_L_CTRL, 0x40 },
  993 + { DA7213_ADC_R_CTRL, 0x40 },
  994 + { DA7213_DAC_L_CTRL, 0x48 },
  995 + { DA7213_DAC_R_CTRL, 0x40 },
  996 + { DA7213_HP_L_CTRL, 0x41 },
  997 + { DA7213_HP_R_CTRL, 0x40 },
  998 + { DA7213_LINE_CTRL, 0x40 },
  999 + { DA7213_MIXOUT_L_CTRL, 0x10 },
  1000 + { DA7213_MIXOUT_R_CTRL, 0x10 },
  1001 + { DA7213_LDO_CTRL, 0x00 },
  1002 + { DA7213_IO_CTRL, 0x00 },
  1003 + { DA7213_GAIN_RAMP_CTRL, 0x00},
  1004 + { DA7213_MIC_CONFIG, 0x00 },
  1005 + { DA7213_PC_COUNT, 0x00 },
  1006 + { DA7213_CP_VOL_THRESHOLD1, 0x32 },
  1007 + { DA7213_CP_DELAY, 0x95 },
  1008 + { DA7213_CP_DETECTOR, 0x00 },
  1009 + { DA7213_DAI_OFFSET, 0x00 },
  1010 + { DA7213_DIG_CTRL, 0x00 },
  1011 + { DA7213_ALC_CTRL2, 0x00 },
  1012 + { DA7213_ALC_CTRL3, 0x00 },
  1013 + { DA7213_ALC_NOISE, 0x3F },
  1014 + { DA7213_ALC_TARGET_MIN, 0x3F },
  1015 + { DA7213_ALC_TARGET_MAX, 0x00 },
  1016 + { DA7213_ALC_GAIN_LIMITS, 0xFF },
  1017 + { DA7213_ALC_ANA_GAIN_LIMITS, 0x71 },
  1018 + { DA7213_ALC_ANTICLIP_CTRL, 0x00 },
  1019 + { DA7213_ALC_ANTICLIP_LEVEL, 0x00 },
  1020 + { DA7213_ALC_OFFSET_MAN_M_L, 0x00 },
  1021 + { DA7213_ALC_OFFSET_MAN_U_L, 0x00 },
  1022 + { DA7213_ALC_OFFSET_MAN_M_R, 0x00 },
  1023 + { DA7213_ALC_OFFSET_MAN_U_R, 0x00 },
  1024 + { DA7213_ALC_CIC_OP_LVL_CTRL, 0x00 },
  1025 + { DA7213_DAC_NG_SETUP_TIME, 0x00 },
  1026 + { DA7213_DAC_NG_OFF_THRESHOLD, 0x00 },
  1027 + { DA7213_DAC_NG_ON_THRESHOLD, 0x00 },
  1028 + { DA7213_DAC_NG_CTRL, 0x00 },
  1029 +};
  1030 +
  1031 +static bool da7213_volatile_register(struct device *dev, unsigned int reg)
  1032 +{
  1033 + switch (reg) {
  1034 + case DA7213_STATUS1:
  1035 + case DA7213_PLL_STATUS:
  1036 + case DA7213_AUX_L_GAIN_STATUS:
  1037 + case DA7213_AUX_R_GAIN_STATUS:
  1038 + case DA7213_MIC_1_GAIN_STATUS:
  1039 + case DA7213_MIC_2_GAIN_STATUS:
  1040 + case DA7213_MIXIN_L_GAIN_STATUS:
  1041 + case DA7213_MIXIN_R_GAIN_STATUS:
  1042 + case DA7213_ADC_L_GAIN_STATUS:
  1043 + case DA7213_ADC_R_GAIN_STATUS:
  1044 + case DA7213_DAC_L_GAIN_STATUS:
  1045 + case DA7213_DAC_R_GAIN_STATUS:
  1046 + case DA7213_HP_L_GAIN_STATUS:
  1047 + case DA7213_HP_R_GAIN_STATUS:
  1048 + case DA7213_LINE_GAIN_STATUS:
  1049 + case DA7213_ALC_CTRL1:
  1050 + case DA7213_ALC_OFFSET_AUTO_M_L:
  1051 + case DA7213_ALC_OFFSET_AUTO_U_L:
  1052 + case DA7213_ALC_OFFSET_AUTO_M_R:
  1053 + case DA7213_ALC_OFFSET_AUTO_U_R:
  1054 + case DA7213_ALC_CIC_OP_LVL_DATA:
  1055 + return 1;
  1056 + default:
  1057 + return 0;
  1058 + }
  1059 +}
  1060 +
  1061 +static int da7213_hw_params(struct snd_pcm_substream *substream,
  1062 + struct snd_pcm_hw_params *params,
  1063 + struct snd_soc_dai *dai)
  1064 +{
  1065 + struct snd_soc_codec *codec = dai->codec;
  1066 + u8 dai_ctrl = 0;
  1067 + u8 fs;
  1068 +
  1069 + /* Set DAI format */
  1070 + switch (params_format(params)) {
  1071 + case SNDRV_PCM_FORMAT_S16_LE:
  1072 + dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE;
  1073 + break;
  1074 + case SNDRV_PCM_FORMAT_S20_3LE:
  1075 + dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE;
  1076 + break;
  1077 + case SNDRV_PCM_FORMAT_S24_LE:
  1078 + dai_ctrl |= DA7213_DAI_WORD_LENGTH_S24_LE;
  1079 + break;
  1080 + case SNDRV_PCM_FORMAT_S32_LE:
  1081 + dai_ctrl |= DA7213_DAI_WORD_LENGTH_S32_LE;
  1082 + break;
  1083 + default:
  1084 + return -EINVAL;
  1085 + }
  1086 +
  1087 + /* Set sampling rate */
  1088 + switch (params_rate(params)) {
  1089 + case 8000:
  1090 + fs = DA7213_SR_8000;
  1091 + break;
  1092 + case 11025:
  1093 + fs = DA7213_SR_11025;
  1094 + break;
  1095 + case 12000:
  1096 + fs = DA7213_SR_12000;
  1097 + break;
  1098 + case 16000:
  1099 + fs = DA7213_SR_16000;
  1100 + break;
  1101 + case 22050:
  1102 + fs = DA7213_SR_22050;
  1103 + break;
  1104 + case 32000:
  1105 + fs = DA7213_SR_32000;
  1106 + break;
  1107 + case 44100:
  1108 + fs = DA7213_SR_44100;
  1109 + break;
  1110 + case 48000:
  1111 + fs = DA7213_SR_48000;
  1112 + break;
  1113 + case 88200:
  1114 + fs = DA7213_SR_88200;
  1115 + break;
  1116 + case 96000:
  1117 + fs = DA7213_SR_96000;
  1118 + break;
  1119 + default:
  1120 + return -EINVAL;
  1121 + }
  1122 +
  1123 + snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_WORD_LENGTH_MASK,
  1124 + dai_ctrl);
  1125 + snd_soc_write(codec, DA7213_SR, fs);
  1126 +
  1127 + return 0;
  1128 +}
  1129 +
  1130 +static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
  1131 +{
  1132 + struct snd_soc_codec *codec = codec_dai->codec;
  1133 + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
  1134 + u8 dai_clk_mode = 0, dai_ctrl = 0;
  1135 +
  1136 + /* Set master/slave mode */
  1137 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  1138 + case SND_SOC_DAIFMT_CBM_CFM:
  1139 + dai_clk_mode |= DA7213_DAI_CLK_EN_MASTER_MODE;
  1140 + da7213->master = true;
  1141 + break;
  1142 + case SND_SOC_DAIFMT_CBS_CFS:
  1143 + dai_clk_mode |= DA7213_DAI_CLK_EN_SLAVE_MODE;
  1144 + da7213->master = false;
  1145 + break;
  1146 + default:
  1147 + return -EINVAL;
  1148 + }
  1149 +
  1150 + /* Set clock normal/inverted */
  1151 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  1152 + case SND_SOC_DAIFMT_NB_NF:
  1153 + break;
  1154 + case SND_SOC_DAIFMT_NB_IF:
  1155 + dai_clk_mode |= DA7213_DAI_WCLK_POL_INV;
  1156 + break;
  1157 + case SND_SOC_DAIFMT_IB_NF:
  1158 + dai_clk_mode |= DA7213_DAI_CLK_POL_INV;
  1159 + break;
  1160 + case SND_SOC_DAIFMT_IB_IF:
  1161 + dai_clk_mode |= DA7213_DAI_WCLK_POL_INV | DA7213_DAI_CLK_POL_INV;
  1162 + break;
  1163 + default:
  1164 + return -EINVAL;
  1165 + }
  1166 +
  1167 + /* Only I2S is supported */
  1168 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  1169 + case SND_SOC_DAIFMT_I2S:
  1170 + dai_ctrl |= DA7213_DAI_FORMAT_I2S_MODE;
  1171 + break;
  1172 + case SND_SOC_DAIFMT_LEFT_J:
  1173 + dai_ctrl |= DA7213_DAI_FORMAT_LEFT_J;
  1174 + break;
  1175 + case SND_SOC_DAIFMT_RIGHT_J:
  1176 + dai_ctrl |= DA7213_DAI_FORMAT_RIGHT_J;
  1177 + break;
  1178 + default:
  1179 + return -EINVAL;
  1180 + }
  1181 +
  1182 + /* By default only 32 BCLK per WCLK is supported */
  1183 + dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_32;
  1184 +
  1185 + snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode);
  1186 + snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
  1187 + dai_ctrl);
  1188 +
  1189 + return 0;
  1190 +}
  1191 +
  1192 +static int da7213_mute(struct snd_soc_dai *dai, int mute)
  1193 +{
  1194 + struct snd_soc_codec *codec = dai->codec;
  1195 +
  1196 + if (mute) {
  1197 + snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
  1198 + DA7213_MUTE_EN, DA7213_MUTE_EN);
  1199 + snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
  1200 + DA7213_MUTE_EN, DA7213_MUTE_EN);
  1201 + } else {
  1202 + snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
  1203 + DA7213_MUTE_EN, 0);
  1204 + snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
  1205 + DA7213_MUTE_EN, 0);
  1206 + }
  1207 +
  1208 + return 0;
  1209 +}
  1210 +
  1211 +#define DA7213_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  1212 + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  1213 +
  1214 +static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  1215 + int clk_id, unsigned int freq, int dir)
  1216 +{
  1217 + struct snd_soc_codec *codec = codec_dai->codec;
  1218 + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
  1219 +
  1220 + switch (clk_id) {
  1221 + case DA7213_CLKSRC_MCLK:
  1222 + if ((freq == 32768) ||
  1223 + ((freq >= 5000000) && (freq <= 54000000))) {
  1224 + da7213->mclk_rate = freq;
  1225 + return 0;
  1226 + } else {
  1227 + dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
  1228 + freq);
  1229 + return -EINVAL;
  1230 + }
  1231 + break;
  1232 + default:
  1233 + dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
  1234 + return -EINVAL;
  1235 + }
  1236 +}
  1237 +
  1238 +/* Supported PLL input frequencies are 5MHz - 54MHz. */
  1239 +static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
  1240 + int source, unsigned int fref, unsigned int fout)
  1241 +{
  1242 + struct snd_soc_codec *codec = codec_dai->codec;
  1243 + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
  1244 +
  1245 + u8 pll_ctrl, indiv_bits, indiv;
  1246 + u8 pll_frac_top, pll_frac_bot, pll_integer;
  1247 + u32 freq_ref;
  1248 + u64 frac_div;
  1249 +
  1250 + /* Reset PLL configuration */
  1251 + snd_soc_write(codec, DA7213_PLL_CTRL, 0);
  1252 +
  1253 + pll_ctrl = 0;
  1254 +
  1255 + /* Workout input divider based on MCLK rate */
  1256 + if ((da7213->mclk_rate == 32768) && (source == DA7213_SYSCLK_PLL)) {
  1257 + /* 32KHz PLL Mode */
  1258 + indiv_bits = DA7213_PLL_INDIV_10_20_MHZ;
  1259 + indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL;
  1260 + freq_ref = 3750000;
  1261 + pll_ctrl |= DA7213_PLL_32K_MODE;
  1262 + } else {
  1263 + /* 5 - 54MHz MCLK */
  1264 + if (da7213->mclk_rate < 5000000) {
  1265 + goto pll_err;
  1266 + } else if (da7213->mclk_rate <= 10000000) {
  1267 + indiv_bits = DA7213_PLL_INDIV_5_10_MHZ;
  1268 + indiv = DA7213_PLL_INDIV_5_10_MHZ_VAL;
  1269 + } else if (da7213->mclk_rate <= 20000000) {
  1270 + indiv_bits = DA7213_PLL_INDIV_10_20_MHZ;
  1271 + indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL;
  1272 + } else if (da7213->mclk_rate <= 40000000) {
  1273 + indiv_bits = DA7213_PLL_INDIV_20_40_MHZ;
  1274 + indiv = DA7213_PLL_INDIV_20_40_MHZ_VAL;
  1275 + } else if (da7213->mclk_rate <= 54000000) {
  1276 + indiv_bits = DA7213_PLL_INDIV_40_54_MHZ;
  1277 + indiv = DA7213_PLL_INDIV_40_54_MHZ_VAL;
  1278 + } else {
  1279 + goto pll_err;
  1280 + }
  1281 + freq_ref = (da7213->mclk_rate / indiv);
  1282 + }
  1283 +
  1284 + pll_ctrl |= indiv_bits;
  1285 +
  1286 + /* PLL Bypass mode */
  1287 + if (source == DA7213_SYSCLK_MCLK) {
  1288 + snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl);
  1289 + return 0;
  1290 + }
  1291 +
  1292 + /*
  1293 + * If Codec is slave and SRM enabled,
  1294 + * freq_out is (98304000 + 90316800)/2 = 94310400
  1295 + */
  1296 + if (!da7213->master && da7213->srm_en) {
  1297 + fout = DA7213_PLL_FREQ_OUT_94310400;
  1298 + pll_ctrl |= DA7213_PLL_SRM_EN;
  1299 + }
  1300 +
  1301 + /* Enable MCLK squarer if required */
  1302 + if (da7213->mclk_squarer_en)
  1303 + pll_ctrl |= DA7213_PLL_MCLK_SQR_EN;
  1304 +
  1305 + /* Calculate dividers for PLL */
  1306 + pll_integer = fout / freq_ref;
  1307 + frac_div = (u64)(fout % freq_ref) * 8192ULL;
  1308 + do_div(frac_div, freq_ref);
  1309 + pll_frac_top = (frac_div >> DA7213_BYTE_SHIFT) & DA7213_BYTE_MASK;
  1310 + pll_frac_bot = (frac_div) & DA7213_BYTE_MASK;
  1311 +
  1312 + /* Write PLL dividers */
  1313 + snd_soc_write(codec, DA7213_PLL_FRAC_TOP, pll_frac_top);
  1314 + snd_soc_write(codec, DA7213_PLL_FRAC_BOT, pll_frac_bot);
  1315 + snd_soc_write(codec, DA7213_PLL_INTEGER, pll_integer);
  1316 +
  1317 + /* Enable PLL */
  1318 + pll_ctrl |= DA7213_PLL_EN;
  1319 + snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl);
  1320 +
  1321 + return 0;
  1322 +
  1323 +pll_err:
  1324 + dev_err(codec_dai->dev, "Unsupported PLL input frequency %d\n",
  1325 + da7213->mclk_rate);
  1326 + return -EINVAL;
  1327 +}
  1328 +
  1329 +/* DAI operations */
  1330 +static const struct snd_soc_dai_ops da7213_dai_ops = {
  1331 + .hw_params = da7213_hw_params,
  1332 + .set_fmt = da7213_set_dai_fmt,
  1333 + .set_sysclk = da7213_set_dai_sysclk,
  1334 + .set_pll = da7213_set_dai_pll,
  1335 + .digital_mute = da7213_mute,
  1336 +};
  1337 +
  1338 +static struct snd_soc_dai_driver da7213_dai = {
  1339 + .name = "da7213-hifi",
  1340 + /* Playback Capabilities */
  1341 + .playback = {
  1342 + .stream_name = "Playback",
  1343 + .channels_min = 1,
  1344 + .channels_max = 2,
  1345 + .rates = SNDRV_PCM_RATE_8000_96000,
  1346 + .formats = DA7213_FORMATS,
  1347 + },
  1348 + /* Capture Capabilities */
  1349 + .capture = {
  1350 + .stream_name = "Capture",
  1351 + .channels_min = 1,
  1352 + .channels_max = 2,
  1353 + .rates = SNDRV_PCM_RATE_8000_96000,
  1354 + .formats = DA7213_FORMATS,
  1355 + },
  1356 + .ops = &da7213_dai_ops,
  1357 + .symmetric_rates = 1,
  1358 +};
  1359 +
  1360 +static int da7213_set_bias_level(struct snd_soc_codec *codec,
  1361 + enum snd_soc_bias_level level)
  1362 +{
  1363 + switch (level) {
  1364 + case SND_SOC_BIAS_ON:
  1365 + case SND_SOC_BIAS_PREPARE:
  1366 + break;
  1367 + case SND_SOC_BIAS_STANDBY:
  1368 + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
  1369 + /* Enable VMID reference & master bias */
  1370 + snd_soc_update_bits(codec, DA7213_REFERENCES,
  1371 + DA7213_VMID_EN | DA7213_BIAS_EN,
  1372 + DA7213_VMID_EN | DA7213_BIAS_EN);
  1373 + }
  1374 + break;
  1375 + case SND_SOC_BIAS_OFF:
  1376 + /* Disable VMID reference & master bias */
  1377 + snd_soc_update_bits(codec, DA7213_REFERENCES,
  1378 + DA7213_VMID_EN | DA7213_BIAS_EN, 0);
  1379 + break;
  1380 + }
  1381 + codec->dapm.bias_level = level;
  1382 + return 0;
  1383 +}
  1384 +
  1385 +static int da7213_probe(struct snd_soc_codec *codec)
  1386 +{
  1387 + int ret;
  1388 + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
  1389 + struct da7213_platform_data *pdata = da7213->pdata;
  1390 +
  1391 + codec->control_data = da7213->regmap;
  1392 + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
  1393 + if (ret < 0) {
  1394 + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
  1395 + return ret;
  1396 + }
  1397 +
  1398 + /* Default to using ALC auto offset calibration mode. */
  1399 + snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
  1400 + DA7213_ALC_CALIB_MODE_MAN, 0);
  1401 + da7213->alc_calib_auto = true;
  1402 +
  1403 + /* Default to using SRM for slave mode */
  1404 + da7213->srm_en = true;
  1405 +
  1406 + /* Enable all Gain Ramps */
  1407 + snd_soc_update_bits(codec, DA7213_AUX_L_CTRL,
  1408 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1409 + snd_soc_update_bits(codec, DA7213_AUX_R_CTRL,
  1410 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1411 + snd_soc_update_bits(codec, DA7213_MIXIN_L_CTRL,
  1412 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1413 + snd_soc_update_bits(codec, DA7213_MIXIN_R_CTRL,
  1414 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1415 + snd_soc_update_bits(codec, DA7213_ADC_L_CTRL,
  1416 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1417 + snd_soc_update_bits(codec, DA7213_ADC_R_CTRL,
  1418 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1419 + snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
  1420 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1421 + snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
  1422 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1423 + snd_soc_update_bits(codec, DA7213_HP_L_CTRL,
  1424 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1425 + snd_soc_update_bits(codec, DA7213_HP_R_CTRL,
  1426 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1427 + snd_soc_update_bits(codec, DA7213_LINE_CTRL,
  1428 + DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
  1429 +
  1430 + /*
  1431 + * There are two separate control bits for input and output mixers as
  1432 + * well as headphone and line outs.
  1433 + * One to enable corresponding amplifier and other to enable its
  1434 + * output. As amplifier bits are related to power control, they are
  1435 + * being managed by DAPM while other (non power related) bits are
  1436 + * enabled here
  1437 + */
  1438 + snd_soc_update_bits(codec, DA7213_MIXIN_L_CTRL,
  1439 + DA7213_MIXIN_MIX_EN, DA7213_MIXIN_MIX_EN);
  1440 + snd_soc_update_bits(codec, DA7213_MIXIN_R_CTRL,
  1441 + DA7213_MIXIN_MIX_EN, DA7213_MIXIN_MIX_EN);
  1442 +
  1443 + snd_soc_update_bits(codec, DA7213_MIXOUT_L_CTRL,
  1444 + DA7213_MIXOUT_MIX_EN, DA7213_MIXOUT_MIX_EN);
  1445 + snd_soc_update_bits(codec, DA7213_MIXOUT_R_CTRL,
  1446 + DA7213_MIXOUT_MIX_EN, DA7213_MIXOUT_MIX_EN);
  1447 +
  1448 + snd_soc_update_bits(codec, DA7213_HP_L_CTRL,
  1449 + DA7213_HP_AMP_OE, DA7213_HP_AMP_OE);
  1450 + snd_soc_update_bits(codec, DA7213_HP_R_CTRL,
  1451 + DA7213_HP_AMP_OE, DA7213_HP_AMP_OE);
  1452 +
  1453 + snd_soc_update_bits(codec, DA7213_LINE_CTRL,
  1454 + DA7213_LINE_AMP_OE, DA7213_LINE_AMP_OE);
  1455 +
  1456 + /* Set platform data values */
  1457 + if (da7213->pdata) {
  1458 + u8 micbias_lvl = 0, dmic_cfg = 0;
  1459 +
  1460 + /* Set Mic Bias voltages */
  1461 + switch (pdata->micbias1_lvl) {
  1462 + case DA7213_MICBIAS_1_6V:
  1463 + case DA7213_MICBIAS_2_2V:
  1464 + case DA7213_MICBIAS_2_5V:
  1465 + case DA7213_MICBIAS_3_0V:
  1466 + micbias_lvl |= (pdata->micbias1_lvl <<
  1467 + DA7213_MICBIAS1_LEVEL_SHIFT);
  1468 + break;
  1469 + }
  1470 + switch (pdata->micbias2_lvl) {
  1471 + case DA7213_MICBIAS_1_6V:
  1472 + case DA7213_MICBIAS_2_2V:
  1473 + case DA7213_MICBIAS_2_5V:
  1474 + case DA7213_MICBIAS_3_0V:
  1475 + micbias_lvl |= (pdata->micbias2_lvl <<
  1476 + DA7213_MICBIAS2_LEVEL_SHIFT);
  1477 + break;
  1478 + }
  1479 + snd_soc_update_bits(codec, DA7213_MICBIAS_CTRL,
  1480 + DA7213_MICBIAS1_LEVEL_MASK |
  1481 + DA7213_MICBIAS2_LEVEL_MASK, micbias_lvl);
  1482 +
  1483 + /* Set DMIC configuration */
  1484 + switch (pdata->dmic_data_sel) {
  1485 + case DA7213_DMIC_DATA_LFALL_RRISE:
  1486 + case DA7213_DMIC_DATA_LRISE_RFALL:
  1487 + dmic_cfg |= (pdata->dmic_data_sel <<
  1488 + DA7213_DMIC_DATA_SEL_SHIFT);
  1489 + break;
  1490 + }
  1491 + switch (pdata->dmic_data_sel) {
  1492 + case DA7213_DMIC_SAMPLE_ON_CLKEDGE:
  1493 + case DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE:
  1494 + dmic_cfg |= (pdata->dmic_data_sel <<
  1495 + DA7213_DMIC_SAMPLEPHASE_SHIFT);
  1496 + break;
  1497 + }
  1498 + switch (pdata->dmic_data_sel) {
  1499 + case DA7213_DMIC_CLK_3_0MHZ:
  1500 + case DA7213_DMIC_CLK_1_5MHZ:
  1501 + dmic_cfg |= (pdata->dmic_data_sel <<
  1502 + DA7213_DMIC_CLK_RATE_SHIFT);
  1503 + break;
  1504 + }
  1505 + snd_soc_update_bits(codec, DA7213_MIC_CONFIG,
  1506 + DA7213_DMIC_DATA_SEL_MASK |
  1507 + DA7213_DMIC_SAMPLEPHASE_MASK |
  1508 + DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
  1509 +
  1510 + /* Set MCLK squaring */
  1511 + da7213->mclk_squarer_en = pdata->mclk_squaring;
  1512 + }
  1513 + return 0;
  1514 +}
  1515 +
  1516 +static struct snd_soc_codec_driver soc_codec_dev_da7213 = {
  1517 + .probe = da7213_probe,
  1518 + .set_bias_level = da7213_set_bias_level,
  1519 +
  1520 + .controls = da7213_snd_controls,
  1521 + .num_controls = ARRAY_SIZE(da7213_snd_controls),
  1522 +
  1523 + .dapm_widgets = da7213_dapm_widgets,
  1524 + .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets),
  1525 + .dapm_routes = da7213_audio_map,
  1526 + .num_dapm_routes = ARRAY_SIZE(da7213_audio_map),
  1527 +};
  1528 +
  1529 +static const struct regmap_config da7213_regmap_config = {
  1530 + .reg_bits = 8,
  1531 + .val_bits = 8,
  1532 +
  1533 + .reg_defaults = da7213_reg_defaults,
  1534 + .num_reg_defaults = ARRAY_SIZE(da7213_reg_defaults),
  1535 + .volatile_reg = da7213_volatile_register,
  1536 + .cache_type = REGCACHE_RBTREE,
  1537 +};
  1538 +
  1539 +static int da7213_i2c_probe(struct i2c_client *i2c,
  1540 + const struct i2c_device_id *id)
  1541 +{
  1542 + struct da7213_priv *da7213;
  1543 + struct da7213_platform_data *pdata = dev_get_platdata(&i2c->dev);
  1544 + int ret;
  1545 +
  1546 + da7213 = devm_kzalloc(&i2c->dev, sizeof(struct da7213_priv),
  1547 + GFP_KERNEL);
  1548 + if (!da7213)
  1549 + return -ENOMEM;
  1550 +
  1551 + if (pdata)
  1552 + da7213->pdata = pdata;
  1553 +
  1554 + i2c_set_clientdata(i2c, da7213);
  1555 +
  1556 + da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config);
  1557 + if (IS_ERR(da7213->regmap)) {
  1558 + ret = PTR_ERR(da7213->regmap);
  1559 + dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
  1560 + return ret;
  1561 + }
  1562 +
  1563 + ret = snd_soc_register_codec(&i2c->dev,
  1564 + &soc_codec_dev_da7213, &da7213_dai, 1);
  1565 + if (ret < 0) {
  1566 + dev_err(&i2c->dev, "Failed to register da7213 codec: %d\n",
  1567 + ret);
  1568 + }
  1569 + return ret;
  1570 +}
  1571 +
  1572 +static int da7213_remove(struct i2c_client *client)
  1573 +{
  1574 + snd_soc_unregister_codec(&client->dev);
  1575 + return 0;
  1576 +}
  1577 +
  1578 +static const struct i2c_device_id da7213_i2c_id[] = {
  1579 + { "da7213", 0 },
  1580 + { }
  1581 +};
  1582 +MODULE_DEVICE_TABLE(i2c, da7213_i2c_id);
  1583 +
  1584 +/* I2C codec control layer */
  1585 +static struct i2c_driver da7213_i2c_driver = {
  1586 + .driver = {
  1587 + .name = "da7213",
  1588 + .owner = THIS_MODULE,
  1589 + },
  1590 + .probe = da7213_i2c_probe,
  1591 + .remove = da7213_remove,
  1592 + .id_table = da7213_i2c_id,
  1593 +};
  1594 +
  1595 +module_i2c_driver(da7213_i2c_driver);
  1596 +
  1597 +MODULE_DESCRIPTION("ASoC DA7213 Codec driver");
  1598 +MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
  1599 +MODULE_LICENSE("GPL");
sound/soc/codecs/da7213.h
  1 +/*
  2 + * da7213.h - DA7213 ASoC Codec Driver
  3 + *
  4 + * Copyright (c) 2013 Dialog Semiconductor
  5 + *
  6 + * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
  7 + *
  8 + * This program is free software; you can redistribute it and/or modify
  9 + * it under the terms of the GNU General Public License version 2 as
  10 + * published by the Free Software Foundation.
  11 + */
  12 +
  13 +#ifndef _DA7213_H
  14 +#define _DA7213_H
  15 +
  16 +#include <linux/regmap.h>
  17 +#include <sound/da7213.h>
  18 +
  19 +/*
  20 + * Registers
  21 + */
  22 +
  23 +/* Status Registers */
  24 +#define DA7213_STATUS1 0x02
  25 +#define DA7213_PLL_STATUS 0x03
  26 +#define DA7213_AUX_L_GAIN_STATUS 0x04
  27 +#define DA7213_AUX_R_GAIN_STATUS 0x05
  28 +#define DA7213_MIC_1_GAIN_STATUS 0x06
  29 +#define DA7213_MIC_2_GAIN_STATUS 0x07
  30 +#define DA7213_MIXIN_L_GAIN_STATUS 0x08
  31 +#define DA7213_MIXIN_R_GAIN_STATUS 0x09
  32 +#define DA7213_ADC_L_GAIN_STATUS 0x0A
  33 +#define DA7213_ADC_R_GAIN_STATUS 0x0B
  34 +#define DA7213_DAC_L_GAIN_STATUS 0x0C
  35 +#define DA7213_DAC_R_GAIN_STATUS 0x0D
  36 +#define DA7213_HP_L_GAIN_STATUS 0x0E
  37 +#define DA7213_HP_R_GAIN_STATUS 0x0F
  38 +#define DA7213_LINE_GAIN_STATUS 0x10
  39 +
  40 +/* System Initialisation Registers */
  41 +#define DA7213_DIG_ROUTING_DAI 0x21
  42 +#define DA7213_SR 0x22
  43 +#define DA7213_REFERENCES 0x23
  44 +#define DA7213_PLL_FRAC_TOP 0x24
  45 +#define DA7213_PLL_FRAC_BOT 0x25
  46 +#define DA7213_PLL_INTEGER 0x26
  47 +#define DA7213_PLL_CTRL 0x27
  48 +#define DA7213_DAI_CLK_MODE 0x28
  49 +#define DA7213_DAI_CTRL 0x29
  50 +#define DA7213_DIG_ROUTING_DAC 0x2A
  51 +#define DA7213_ALC_CTRL1 0x2B
  52 +
  53 +/* Input - Gain, Select and Filter Registers */
  54 +#define DA7213_AUX_L_GAIN 0x30
  55 +#define DA7213_AUX_R_GAIN 0x31
  56 +#define DA7213_MIXIN_L_SELECT 0x32
  57 +#define DA7213_MIXIN_R_SELECT 0x33
  58 +#define DA7213_MIXIN_L_GAIN 0x34
  59 +#define DA7213_MIXIN_R_GAIN 0x35
  60 +#define DA7213_ADC_L_GAIN 0x36
  61 +#define DA7213_ADC_R_GAIN 0x37
  62 +#define DA7213_ADC_FILTERS1 0x38
  63 +#define DA7213_MIC_1_GAIN 0x39
  64 +#define DA7213_MIC_2_GAIN 0x3A
  65 +
  66 +/* Output - Gain, Select and Filter Registers */
  67 +#define DA7213_DAC_FILTERS5 0x40
  68 +#define DA7213_DAC_FILTERS2 0x41
  69 +#define DA7213_DAC_FILTERS3 0x42
  70 +#define DA7213_DAC_FILTERS4 0x43
  71 +#define DA7213_DAC_FILTERS1 0x44
  72 +#define DA7213_DAC_L_GAIN 0x45
  73 +#define DA7213_DAC_R_GAIN 0x46
  74 +#define DA7213_CP_CTRL 0x47
  75 +#define DA7213_HP_L_GAIN 0x48
  76 +#define DA7213_HP_R_GAIN 0x49
  77 +#define DA7213_LINE_GAIN 0x4A
  78 +#define DA7213_MIXOUT_L_SELECT 0x4B
  79 +#define DA7213_MIXOUT_R_SELECT 0x4C
  80 +
  81 +/* System Controller Registers */
  82 +#define DA7213_SYSTEM_MODES_INPUT 0x50
  83 +#define DA7213_SYSTEM_MODES_OUTPUT 0x51
  84 +
  85 +/* Control Registers */
  86 +#define DA7213_AUX_L_CTRL 0x60
  87 +#define DA7213_AUX_R_CTRL 0x61
  88 +#define DA7213_MICBIAS_CTRL 0x62
  89 +#define DA7213_MIC_1_CTRL 0x63
  90 +#define DA7213_MIC_2_CTRL 0x64
  91 +#define DA7213_MIXIN_L_CTRL 0x65
  92 +#define DA7213_MIXIN_R_CTRL 0x66
  93 +#define DA7213_ADC_L_CTRL 0x67
  94 +#define DA7213_ADC_R_CTRL 0x68
  95 +#define DA7213_DAC_L_CTRL 0x69
  96 +#define DA7213_DAC_R_CTRL 0x6A
  97 +#define DA7213_HP_L_CTRL 0x6B
  98 +#define DA7213_HP_R_CTRL 0x6C
  99 +#define DA7213_LINE_CTRL 0x6D
  100 +#define DA7213_MIXOUT_L_CTRL 0x6E
  101 +#define DA7213_MIXOUT_R_CTRL 0x6F
  102 +
  103 +/* Configuration Registers */
  104 +#define DA7213_LDO_CTRL 0x90
  105 +#define DA7213_IO_CTRL 0x91
  106 +#define DA7213_GAIN_RAMP_CTRL 0x92
  107 +#define DA7213_MIC_CONFIG 0x93
  108 +#define DA7213_PC_COUNT 0x94
  109 +#define DA7213_CP_VOL_THRESHOLD1 0x95
  110 +#define DA7213_CP_DELAY 0x96
  111 +#define DA7213_CP_DETECTOR 0x97
  112 +#define DA7213_DAI_OFFSET 0x98
  113 +#define DA7213_DIG_CTRL 0x99
  114 +#define DA7213_ALC_CTRL2 0x9A
  115 +#define DA7213_ALC_CTRL3 0x9B
  116 +#define DA7213_ALC_NOISE 0x9C
  117 +#define DA7213_ALC_TARGET_MIN 0x9D
  118 +#define DA7213_ALC_TARGET_MAX 0x9E
  119 +#define DA7213_ALC_GAIN_LIMITS 0x9F
  120 +#define DA7213_ALC_ANA_GAIN_LIMITS 0xA0
  121 +#define DA7213_ALC_ANTICLIP_CTRL 0xA1
  122 +#define DA7213_ALC_ANTICLIP_LEVEL 0xA2
  123 +
  124 +#define DA7213_ALC_OFFSET_AUTO_M_L 0xA3
  125 +#define DA7213_ALC_OFFSET_AUTO_U_L 0xA4
  126 +#define DA7213_ALC_OFFSET_MAN_M_L 0xA6
  127 +#define DA7213_ALC_OFFSET_MAN_U_L 0xA7
  128 +#define DA7213_ALC_OFFSET_AUTO_M_R 0xA8
  129 +#define DA7213_ALC_OFFSET_AUTO_U_R 0xA9
  130 +#define DA7213_ALC_OFFSET_MAN_M_R 0xAB
  131 +#define DA7213_ALC_OFFSET_MAN_U_R 0xAC
  132 +#define DA7213_ALC_CIC_OP_LVL_CTRL 0xAD
  133 +#define DA7213_ALC_CIC_OP_LVL_DATA 0xAE
  134 +#define DA7213_DAC_NG_SETUP_TIME 0xAF
  135 +#define DA7213_DAC_NG_OFF_THRESHOLD 0xB0
  136 +#define DA7213_DAC_NG_ON_THRESHOLD 0xB1
  137 +#define DA7213_DAC_NG_CTRL 0xB2
  138 +
  139 +
  140 +/*
  141 + * Bit fields
  142 + */
  143 +
  144 +/* DA7213_SR = 0x22 */
  145 +#define DA7213_SR_8000 (0x1 << 0)
  146 +#define DA7213_SR_11025 (0x2 << 0)
  147 +#define DA7213_SR_12000 (0x3 << 0)
  148 +#define DA7213_SR_16000 (0x5 << 0)
  149 +#define DA7213_SR_22050 (0x6 << 0)
  150 +#define DA7213_SR_24000 (0x7 << 0)
  151 +#define DA7213_SR_32000 (0x9 << 0)
  152 +#define DA7213_SR_44100 (0xA << 0)
  153 +#define DA7213_SR_48000 (0xB << 0)
  154 +#define DA7213_SR_88200 (0xE << 0)
  155 +#define DA7213_SR_96000 (0xF << 0)
  156 +
  157 +/* DA7213_REFERENCES = 0x23 */
  158 +#define DA7213_BIAS_EN (0x1 << 3)
  159 +#define DA7213_VMID_EN (0x1 << 7)
  160 +
  161 +/* DA7213_PLL_CTRL = 0x27 */
  162 +#define DA7213_PLL_INDIV_5_10_MHZ (0x0 << 2)
  163 +#define DA7213_PLL_INDIV_10_20_MHZ (0x1 << 2)
  164 +#define DA7213_PLL_INDIV_20_40_MHZ (0x2 << 2)
  165 +#define DA7213_PLL_INDIV_40_54_MHZ (0x3 << 2)
  166 +#define DA7213_PLL_INDIV_MASK (0x3 << 2)
  167 +#define DA7213_PLL_MCLK_SQR_EN (0x1 << 4)
  168 +#define DA7213_PLL_32K_MODE (0x1 << 5)
  169 +#define DA7213_PLL_SRM_EN (0x1 << 6)
  170 +#define DA7213_PLL_EN (0x1 << 7)
  171 +
  172 +/* DA7213_DAI_CLK_MODE = 0x28 */
  173 +#define DA7213_DAI_BCLKS_PER_WCLK_32 (0x0 << 0)
  174 +#define DA7213_DAI_BCLKS_PER_WCLK_64 (0x1 << 0)
  175 +#define DA7213_DAI_BCLKS_PER_WCLK_128 (0x2 << 0)
  176 +#define DA7213_DAI_BCLKS_PER_WCLK_256 (0x3 << 0)
  177 +#define DA7213_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0)
  178 +#define DA7213_DAI_CLK_POL_INV (0x1 << 2)
  179 +#define DA7213_DAI_WCLK_POL_INV (0x1 << 3)
  180 +#define DA7213_DAI_CLK_EN_SLAVE_MODE (0x0 << 7)
  181 +#define DA7213_DAI_CLK_EN_MASTER_MODE (0x1 << 7)
  182 +#define DA7213_DAI_CLK_EN_MASK (0x1 << 7)
  183 +
  184 +/* DA7213_DAI_CTRL = 0x29 */
  185 +#define DA7213_DAI_FORMAT_I2S_MODE (0x0 << 0)
  186 +#define DA7213_DAI_FORMAT_LEFT_J (0x1 << 0)
  187 +#define DA7213_DAI_FORMAT_RIGHT_J (0x2 << 0)
  188 +#define DA7213_DAI_FORMAT_MASK (0x3 << 0)
  189 +#define DA7213_DAI_WORD_LENGTH_S16_LE (0x0 << 2)
  190 +#define DA7213_DAI_WORD_LENGTH_S20_LE (0x1 << 2)
  191 +#define DA7213_DAI_WORD_LENGTH_S24_LE (0x2 << 2)
  192 +#define DA7213_DAI_WORD_LENGTH_S32_LE (0x3 << 2)
  193 +#define DA7213_DAI_WORD_LENGTH_MASK (0x3 << 2)
  194 +#define DA7213_DAI_EN_SHIFT 7
  195 +
  196 +/* DA7213_DIG_ROUTING_DAI = 0x21 */
  197 +#define DA7213_DAI_L_SRC_SHIFT 0
  198 +#define DA7213_DAI_R_SRC_SHIFT 4
  199 +#define DA7213_DAI_SRC_MAX 4
  200 +
  201 +/* DA7213_DIG_ROUTING_DAC = 0x2A */
  202 +#define DA7213_DAC_L_SRC_SHIFT 0
  203 +#define DA7213_DAC_L_MONO_SHIFT 3
  204 +#define DA7213_DAC_R_SRC_SHIFT 4
  205 +#define DA7213_DAC_R_MONO_SHIFT 7
  206 +#define DA7213_DAC_SRC_MAX 4
  207 +#define DA7213_DAC_MONO_MAX 0x1
  208 +
  209 +/* DA7213_ALC_CTRL1 = 0x2B */
  210 +#define DA7213_ALC_OFFSET_EN_SHIFT 0
  211 +#define DA7213_ALC_OFFSET_EN_MAX 0x1
  212 +#define DA7213_ALC_OFFSET_EN (0x1 << 0)
  213 +#define DA7213_ALC_SYNC_MODE (0x1 << 1)
  214 +#define DA7213_ALC_CALIB_MODE_MAN (0x1 << 2)
  215 +#define DA7213_ALC_L_EN_SHIFT 3
  216 +#define DA7213_ALC_AUTO_CALIB_EN (0x1 << 4)
  217 +#define DA7213_ALC_CALIB_OVERFLOW (0x1 << 5)
  218 +#define DA7213_ALC_R_EN_SHIFT 7
  219 +#define DA7213_ALC_EN_MAX 0x1
  220 +
  221 +/* DA7213_AUX_L/R_GAIN = 0x30/0x31 */
  222 +#define DA7213_AUX_AMP_GAIN_SHIFT 0
  223 +#define DA7213_AUX_AMP_GAIN_MAX 0x3F
  224 +
  225 +/* DA7213_MIXIN_L/R_SELECT = 0x32/0x33 */
  226 +#define DA7213_DMIC_EN_SHIFT 7
  227 +#define DA7213_DMIC_EN_MAX 0x1
  228 +
  229 +/* DA7213_MIXIN_L_SELECT = 0x32 */
  230 +#define DA7213_MIXIN_L_MIX_SELECT_AUX_L_SHIFT 0
  231 +#define DA7213_MIXIN_L_MIX_SELECT_MIC_1_SHIFT 1
  232 +#define DA7213_MIXIN_L_MIX_SELECT_MIC_1 (0x1 << 1)
  233 +#define DA7213_MIXIN_L_MIX_SELECT_MIC_2_SHIFT 2
  234 +#define DA7213_MIXIN_L_MIX_SELECT_MIC_2 (0x1 << 2)
  235 +#define DA7213_MIXIN_L_MIX_SELECT_MIXIN_R_SHIFT 3
  236 +#define DA7213_MIXIN_L_MIX_SELECT_MAX 0x1
  237 +
  238 +/* DA7213_MIXIN_R_SELECT = 0x33 */
  239 +#define DA7213_MIXIN_R_MIX_SELECT_AUX_R_SHIFT 0
  240 +#define DA7213_MIXIN_R_MIX_SELECT_MIC_2_SHIFT 1
  241 +#define DA7213_MIXIN_R_MIX_SELECT_MIC_2 (0x1 << 1)
  242 +#define DA7213_MIXIN_R_MIX_SELECT_MIC_1_SHIFT 2
  243 +#define DA7213_MIXIN_R_MIX_SELECT_MIC_1 (0x1 << 2)
  244 +#define DA7213_MIXIN_R_MIX_SELECT_MIXIN_L_SHIFT 3
  245 +#define DA7213_MIXIN_R_MIX_SELECT_MAX 0x1
  246 +#define DA7213_MIC_BIAS_OUTPUT_SELECT_2 (0x1 << 6)
  247 +
  248 +/* DA7213_MIXIN_L/R_GAIN = 0x34/0x35 */
  249 +#define DA7213_MIXIN_AMP_GAIN_SHIFT 0
  250 +#define DA7213_MIXIN_AMP_GAIN_MAX 0xF
  251 +
  252 +/* DA7213_ADC_L/R_GAIN = 0x36/0x37 */
  253 +#define DA7213_ADC_AMP_GAIN_SHIFT 0
  254 +#define DA7213_ADC_AMP_GAIN_MAX 0x7F
  255 +
  256 +/* DA7213_ADC/DAC_FILTERS1 = 0x38/0x44 */
  257 +#define DA7213_VOICE_HPF_CORNER_SHIFT 0
  258 +#define DA7213_VOICE_HPF_CORNER_MAX 8
  259 +#define DA7213_VOICE_EN_SHIFT 3
  260 +#define DA7213_VOICE_EN_MAX 0x1
  261 +#define DA7213_AUDIO_HPF_CORNER_SHIFT 4
  262 +#define DA7213_AUDIO_HPF_CORNER_MAX 4
  263 +#define DA7213_HPF_EN_SHIFT 7
  264 +#define DA7213_HPF_EN_MAX 0x1
  265 +
  266 +/* DA7213_MIC_1/2_GAIN = 0x39/0x3A */
  267 +#define DA7213_MIC_AMP_GAIN_SHIFT 0
  268 +#define DA7213_MIC_AMP_GAIN_MAX 0x7
  269 +
  270 +/* DA7213_DAC_FILTERS5 = 0x40 */
  271 +#define DA7213_DAC_SOFTMUTE_EN_SHIFT 7
  272 +#define DA7213_DAC_SOFTMUTE_EN_MAX 0x1
  273 +#define DA7213_DAC_SOFTMUTE_RATE_SHIFT 4
  274 +#define DA7213_DAC_SOFTMUTE_RATE_MAX 7
  275 +
  276 +/* DA7213_DAC_FILTERS2/3/4 = 0x41/0x42/0x43 */
  277 +#define DA7213_DAC_EQ_BAND_MAX 0xF
  278 +
  279 +/* DA7213_DAC_FILTERS2 = 0x41 */
  280 +#define DA7213_DAC_EQ_BAND1_SHIFT 0
  281 +#define DA7213_DAC_EQ_BAND2_SHIFT 4
  282 +
  283 +/* DA7213_DAC_FILTERS2 = 0x42 */
  284 +#define DA7213_DAC_EQ_BAND3_SHIFT 0
  285 +#define DA7213_DAC_EQ_BAND4_SHIFT 4
  286 +
  287 +/* DA7213_DAC_FILTERS4 = 0x43 */
  288 +#define DA7213_DAC_EQ_BAND5_SHIFT 0
  289 +#define DA7213_DAC_EQ_EN_SHIFT 7
  290 +#define DA7213_DAC_EQ_EN_MAX 0x1
  291 +
  292 +/* DA7213_DAC_L/R_GAIN = 0x45/0x46 */
  293 +#define DA7213_DAC_AMP_GAIN_SHIFT 0
  294 +#define DA7213_DAC_AMP_GAIN_MAX 0x7F
  295 +
  296 +/* DA7213_HP_L/R_GAIN = 0x45/0x46 */
  297 +#define DA7213_HP_AMP_GAIN_SHIFT 0
  298 +#define DA7213_HP_AMP_GAIN_MAX 0x3F
  299 +
  300 +/* DA7213_CP_CTRL = 0x47 */
  301 +#define DA7213_CP_EN_SHIFT 7
  302 +
  303 +/* DA7213_LINE_GAIN = 0x4A */
  304 +#define DA7213_LINE_AMP_GAIN_SHIFT 0
  305 +#define DA7213_LINE_AMP_GAIN_MAX 0x3F
  306 +
  307 +/* DA7213_MIXOUT_L_SELECT = 0x4B */
  308 +#define DA7213_MIXOUT_L_MIX_SELECT_AUX_L_SHIFT 0
  309 +#define DA7213_MIXOUT_L_MIX_SELECT_MIXIN_L_SHIFT 1
  310 +#define DA7213_MIXOUT_L_MIX_SELECT_MIXIN_R_SHIFT 2
  311 +#define DA7213_MIXOUT_L_MIX_SELECT_DAC_L_SHIFT 3
  312 +#define DA7213_MIXOUT_L_MIX_SELECT_AUX_L_INVERTED_SHIFT 4
  313 +#define DA7213_MIXOUT_L_MIX_SELECT_MIXIN_L_INVERTED_SHIFT 5
  314 +#define DA7213_MIXOUT_L_MIX_SELECT_MIXIN_R_INVERTED_SHIFT 6
  315 +#define DA7213_MIXOUT_L_MIX_SELECT_MAX 0x1
  316 +
  317 +/* DA7213_MIXOUT_R_SELECT = 0x4C */
  318 +#define DA7213_MIXOUT_R_MIX_SELECT_AUX_R_SHIFT 0
  319 +#define DA7213_MIXOUT_R_MIX_SELECT_MIXIN_R_SHIFT 1
  320 +#define DA7213_MIXOUT_R_MIX_SELECT_MIXIN_L_SHIFT 2
  321 +#define DA7213_MIXOUT_R_MIX_SELECT_DAC_R_SHIFT 3
  322 +#define DA7213_MIXOUT_R_MIX_SELECT_AUX_R_INVERTED_SHIFT 4
  323 +#define DA7213_MIXOUT_R_MIX_SELECT_MIXIN_R_INVERTED_SHIFT 5
  324 +#define DA7213_MIXOUT_R_MIX_SELECT_MIXIN_L_INVERTED_SHIFT 6
  325 +#define DA7213_MIXOUT_R_MIX_SELECT_MAX 0x1
  326 +
  327 +/*
  328 + * DA7213_AUX_L/R_CTRL = 0x60/0x61,
  329 + * DA7213_MIC_1/2_CTRL = 0x63/0x64,
  330 + * DA7213_MIXIN_L/R_CTRL = 0x65/0x66,
  331 + * DA7213_ADC_L/R_CTRL = 0x65/0x66,
  332 + * DA7213_DAC_L/R_CTRL = 0x69/0x6A,
  333 + * DA7213_HP_L/R_CTRL = 0x6B/0x6C,
  334 + * DA7213_LINE_CTRL = 0x6D
  335 + */
  336 +#define DA7213_MUTE_EN_SHIFT 6
  337 +#define DA7213_MUTE_EN_MAX 0x1
  338 +#define DA7213_MUTE_EN (0x1 << 6)
  339 +
  340 +/*
  341 + * DA7213_AUX_L/R_CTRL = 0x60/0x61,
  342 + * DA7213_MIXIN_L/R_CTRL = 0x65/0x66,
  343 + * DA7213_ADC_L/R_CTRL = 0x65/0x66,
  344 + * DA7213_DAC_L/R_CTRL = 0x69/0x6A,
  345 + * DA7213_HP_L/R_CTRL = 0x6B/0x6C,
  346 + * DA7213_LINE_CTRL = 0x6D
  347 + */
  348 +#define DA7213_GAIN_RAMP_EN_SHIFT 5
  349 +#define DA7213_GAIN_RAMP_EN_MAX 0x1
  350 +#define DA7213_GAIN_RAMP_EN (0x1 << 5)
  351 +
  352 +/*
  353 + * DA7213_AUX_L/R_CTRL = 0x60/0x61,
  354 + * DA7213_MIXIN_L/R_CTRL = 0x65/0x66,
  355 + * DA7213_HP_L/R_CTRL = 0x6B/0x6C,
  356 + * DA7213_LINE_CTRL = 0x6D
  357 + */
  358 +#define DA7213_ZC_EN_SHIFT 4
  359 +#define DA7213_ZC_EN_MAX 0x1
  360 +
  361 +/*
  362 + * DA7213_AUX_L/R_CTRL = 0x60/0x61,
  363 + * DA7213_MIC_1/2_CTRL = 0x63/0x64,
  364 + * DA7213_MIXIN_L/R_CTRL = 0x65/0x66,
  365 + * DA7213_HP_L/R_CTRL = 0x6B/0x6C,
  366 + * DA7213_MIXOUT_L/R_CTRL = 0x6E/0x6F,
  367 + * DA7213_LINE_CTRL = 0x6D
  368 + */
  369 +#define DA7213_AMP_EN_SHIFT 7
  370 +
  371 +/* DA7213_MIC_1/2_CTRL = 0x63/0x64 */
  372 +#define DA7213_MIC_AMP_IN_SEL_SHIFT 2
  373 +#define DA7213_MIC_AMP_IN_SEL_MAX 3
  374 +
  375 +/* DA7213_MICBIAS_CTRL = 0x62 */
  376 +#define DA7213_MICBIAS1_LEVEL_SHIFT 0
  377 +#define DA7213_MICBIAS1_LEVEL_MASK (0x3 << 0)
  378 +#define DA7213_MICBIAS1_EN_SHIFT 3
  379 +#define DA7213_MICBIAS2_LEVEL_SHIFT 4
  380 +#define DA7213_MICBIAS2_LEVEL_MASK (0x3 << 4)
  381 +#define DA7213_MICBIAS2_EN_SHIFT 7
  382 +
  383 +/* DA7213_MIXIN_L/R_CTRL = 0x65/0x66 */
  384 +#define DA7213_MIXIN_MIX_EN (0x1 << 3)
  385 +
  386 +/* DA7213_ADC_L/R_CTRL = 0x67/0x68 */
  387 +#define DA7213_ADC_EN_SHIFT 7
  388 +#define DA7213_ADC_EN (0x1 << 7)
  389 +
  390 +/* DA7213_DAC_L/R_CTRL = 0x69/0x6A*/
  391 +#define DA7213_DAC_EN_SHIFT 7
  392 +
  393 +/* DA7213_HP_L/R_CTRL = 0x6B/0x6C */
  394 +#define DA7213_HP_AMP_OE (0x1 << 3)
  395 +
  396 +/* DA7213_LINE_CTRL = 0x6D */
  397 +#define DA7213_LINE_AMP_OE (0x1 << 3)
  398 +
  399 +/* DA7213_MIXOUT_L/R_CTRL = 0x6E/0x6F */
  400 +#define DA7213_MIXOUT_MIX_EN (0x1 << 3)
  401 +
  402 +/* DA7213_GAIN_RAMP_CTRL = 0x92 */
  403 +#define DA7213_GAIN_RAMP_RATE_SHIFT 0
  404 +#define DA7213_GAIN_RAMP_RATE_MAX 4
  405 +
  406 +/* DA7213_MIC_CONFIG = 0x93 */
  407 +#define DA7213_DMIC_DATA_SEL_SHIFT 0
  408 +#define DA7213_DMIC_DATA_SEL_MASK (0x1 << 0)
  409 +#define DA7213_DMIC_SAMPLEPHASE_SHIFT 1
  410 +#define DA7213_DMIC_SAMPLEPHASE_MASK (0x1 << 1)
  411 +#define DA7213_DMIC_CLK_RATE_SHIFT 2
  412 +#define DA7213_DMIC_CLK_RATE_MASK (0x1 << 2)
  413 +
  414 +/* DA7213_DIG_CTRL = 0x99 */
  415 +#define DA7213_DAC_L_INV_SHIFT 3
  416 +#define DA7213_DAC_R_INV_SHIFT 7
  417 +#define DA7213_DAC_INV_MAX 0x1
  418 +
  419 +/* DA7213_ALC_CTRL2 = 0x9A */
  420 +#define DA7213_ALC_ATTACK_SHIFT 0
  421 +#define DA7213_ALC_ATTACK_MAX 13
  422 +#define DA7213_ALC_RELEASE_SHIFT 4
  423 +#define DA7213_ALC_RELEASE_MAX 11
  424 +
  425 +/* DA7213_ALC_CTRL3 = 0x9B */
  426 +#define DA7213_ALC_HOLD_SHIFT 0
  427 +#define DA7213_ALC_HOLD_MAX 16
  428 +#define DA7213_ALC_INTEG_ATTACK_SHIFT 4
  429 +#define DA7213_ALC_INTEG_RELEASE_SHIFT 6
  430 +#define DA7213_ALC_INTEG_MAX 4
  431 +
  432 +/*
  433 + * DA7213_ALC_NOISE = 0x9C,
  434 + * DA7213_ALC_TARGET_MIN/MAX = 0x9D/0x9E
  435 + */
  436 +#define DA7213_ALC_THRESHOLD_SHIFT 0
  437 +#define DA7213_ALC_THRESHOLD_MAX 0x3F
  438 +
  439 +/* DA7213_ALC_GAIN_LIMITS = 0x9F */
  440 +#define DA7213_ALC_ATTEN_MAX_SHIFT 0
  441 +#define DA7213_ALC_GAIN_MAX_SHIFT 4
  442 +#define DA7213_ALC_ATTEN_GAIN_MAX_MAX 0xF
  443 +
  444 +/* DA7213_ALC_ANA_GAIN_LIMITS = 0xA0 */
  445 +#define DA7213_ALC_ANA_GAIN_MIN_SHIFT 0
  446 +#define DA7213_ALC_ANA_GAIN_MAX_SHIFT 4
  447 +#define DA7213_ALC_ANA_GAIN_MAX 0x7
  448 +
  449 +/* DA7213_ALC_ANTICLIP_CTRL = 0xA1 */
  450 +#define DA7213_ALC_ANTICLIP_EN_SHIFT 7
  451 +#define DA7213_ALC_ANTICLIP_EN_MAX 0x1
  452 +
  453 +/* DA7213_ALC_ANTICLIP_LEVEL = 0xA2 */
  454 +#define DA7213_ALC_ANTICLIP_LEVEL_SHIFT 0
  455 +#define DA7213_ALC_ANTICLIP_LEVEL_MAX 0x7F
  456 +
  457 +/* DA7213_ALC_CIC_OP_LVL_CTRL = 0xAD */
  458 +#define DA7213_ALC_DATA_MIDDLE (0x2 << 0)
  459 +#define DA7213_ALC_DATA_TOP (0x3 << 0)
  460 +#define DA7213_ALC_CIC_OP_CHANNEL_LEFT (0x0 << 7)
  461 +#define DA7213_ALC_CIC_OP_CHANNEL_RIGHT (0x1 << 7)
  462 +
  463 +/* DA7213_DAC_NG_SETUP_TIME = 0xAF */
  464 +#define DA7213_DAC_NG_SETUP_TIME_SHIFT 0
  465 +#define DA7213_DAC_NG_SETUP_TIME_MAX 4
  466 +#define DA7213_DAC_NG_RAMPUP_RATE_SHIFT 2
  467 +#define DA7213_DAC_NG_RAMPDN_RATE_SHIFT 3
  468 +#define DA7213_DAC_NG_RAMP_RATE_MAX 2
  469 +
  470 +/* DA7213_DAC_NG_OFF/ON_THRESH = 0xB0/0xB1 */
  471 +#define DA7213_DAC_NG_THRESHOLD_SHIFT 0
  472 +#define DA7213_DAC_NG_THRESHOLD_MAX 0x7
  473 +
  474 +/* DA7213_DAC_NG_CTRL = 0xB2 */
  475 +#define DA7213_DAC_NG_EN_SHIFT 7
  476 +#define DA7213_DAC_NG_EN_MAX 0x1
  477 +
  478 +
  479 +/*
  480 + * General defines
  481 + */
  482 +
  483 +/* Register inversion */
  484 +#define DA7213_NO_INVERT 0
  485 +#define DA7213_INVERT 1
  486 +
  487 +/* Byte related defines */
  488 +#define DA7213_BYTE_SHIFT 8
  489 +#define DA7213_BYTE_MASK 0xFF
  490 +
  491 +/* ALC related */
  492 +#define DA7213_ALC_OFFSET_15_8 0x00FF00
  493 +#define DA7213_ALC_OFFSET_19_16 0x0F0000
  494 +#define DA7213_ALC_AVG_ITERATIONS 5
  495 +
  496 +/* PLL related */
  497 +#define DA7213_SYSCLK_MCLK 0
  498 +#define DA7213_SYSCLK_PLL 1
  499 +#define DA7213_PLL_FREQ_OUT_90316800 90316800
  500 +#define DA7213_PLL_FREQ_OUT_98304000 98304000
  501 +#define DA7213_PLL_FREQ_OUT_94310400 94310400
  502 +#define DA7213_PLL_INDIV_5_10_MHZ_VAL 2
  503 +#define DA7213_PLL_INDIV_10_20_MHZ_VAL 4
  504 +#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8
  505 +#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16
  506 +
  507 +enum clk_src {
  508 + DA7213_CLKSRC_MCLK
  509 +};
  510 +
  511 +/* Codec private data */
  512 +struct da7213_priv {
  513 + struct regmap *regmap;
  514 + unsigned int mclk_rate;
  515 + bool master;
  516 + bool mclk_squarer_en;
  517 + bool srm_en;
  518 + bool alc_calib_auto;
  519 + bool alc_en;
  520 + struct da7213_platform_data *pdata;
  521 +};
  522 +
  523 +#endif /* _DA7213_H */