Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * cs42l52.c -- CS42L52 ALSA SoC audio driver
0004  *
0005  * Copyright 2012 CirrusLogic, Inc.
0006  *
0007  * Author: Georgi Vlaev <joe@nucleusys.com>
0008  * Author: Brian Austin <brian.austin@cirrus.com>
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/moduleparam.h>
0013 #include <linux/kernel.h>
0014 #include <linux/init.h>
0015 #include <linux/delay.h>
0016 #include <linux/of_gpio.h>
0017 #include <linux/pm.h>
0018 #include <linux/i2c.h>
0019 #include <linux/input.h>
0020 #include <linux/regmap.h>
0021 #include <linux/slab.h>
0022 #include <linux/workqueue.h>
0023 #include <linux/platform_device.h>
0024 #include <sound/core.h>
0025 #include <sound/pcm.h>
0026 #include <sound/pcm_params.h>
0027 #include <sound/soc.h>
0028 #include <sound/soc-dapm.h>
0029 #include <sound/initval.h>
0030 #include <sound/tlv.h>
0031 #include <sound/cs42l52.h>
0032 #include "cs42l52.h"
0033 
0034 struct sp_config {
0035     u8 spc, format, spfs;
0036     u32 srate;
0037 };
0038 
0039 struct  cs42l52_private {
0040     struct regmap *regmap;
0041     struct snd_soc_component *component;
0042     struct device *dev;
0043     struct sp_config config;
0044     struct cs42l52_platform_data pdata;
0045     u32 sysclk;
0046     u8 mclksel;
0047     u32 mclk;
0048     u8 flags;
0049     struct input_dev *beep;
0050     struct work_struct beep_work;
0051     int beep_rate;
0052 };
0053 
0054 static const struct reg_default cs42l52_reg_defaults[] = {
0055     { CS42L52_PWRCTL1, 0x9F },  /* r02 PWRCTL 1 */
0056     { CS42L52_PWRCTL2, 0x07 },  /* r03 PWRCTL 2 */
0057     { CS42L52_PWRCTL3, 0xFF },  /* r04 PWRCTL 3 */
0058     { CS42L52_CLK_CTL, 0xA0 },  /* r05 Clocking Ctl */
0059     { CS42L52_IFACE_CTL1, 0x00 },   /* r06 Interface Ctl 1 */
0060     { CS42L52_ADC_PGA_A, 0x80 },    /* r08 Input A Select */
0061     { CS42L52_ADC_PGA_B, 0x80 },    /* r09 Input B Select */
0062     { CS42L52_ANALOG_HPF_CTL, 0xA5 },   /* r0A Analog HPF Ctl */
0063     { CS42L52_ADC_HPF_FREQ, 0x00 }, /* r0B ADC HPF Corner Freq */
0064     { CS42L52_ADC_MISC_CTL, 0x00 }, /* r0C Misc. ADC Ctl */
0065     { CS42L52_PB_CTL1, 0x60 },  /* r0D Playback Ctl 1 */
0066     { CS42L52_MISC_CTL, 0x02 }, /* r0E Misc. Ctl */
0067     { CS42L52_PB_CTL2, 0x00 },  /* r0F Playback Ctl 2 */
0068     { CS42L52_MICA_CTL, 0x00 }, /* r10 MICA Amp Ctl */
0069     { CS42L52_MICB_CTL, 0x00 }, /* r11 MICB Amp Ctl */
0070     { CS42L52_PGAA_CTL, 0x00 }, /* r12 PGAA Vol, Misc. */
0071     { CS42L52_PGAB_CTL, 0x00 }, /* r13 PGAB Vol, Misc. */
0072     { CS42L52_PASSTHRUA_VOL, 0x00 },    /* r14 Bypass A Vol */
0073     { CS42L52_PASSTHRUB_VOL, 0x00 },    /* r15 Bypass B Vol */
0074     { CS42L52_ADCA_VOL, 0x00 }, /* r16 ADCA Volume */
0075     { CS42L52_ADCB_VOL, 0x00 }, /* r17 ADCB Volume */
0076     { CS42L52_ADCA_MIXER_VOL, 0x80 },   /* r18 ADCA Mixer Volume */
0077     { CS42L52_ADCB_MIXER_VOL, 0x80 },   /* r19 ADCB Mixer Volume */
0078     { CS42L52_PCMA_MIXER_VOL, 0x00 },   /* r1A PCMA Mixer Volume */
0079     { CS42L52_PCMB_MIXER_VOL, 0x00 },   /* r1B PCMB Mixer Volume */
0080     { CS42L52_BEEP_FREQ, 0x00 },    /* r1C Beep Freq on Time */
0081     { CS42L52_BEEP_VOL, 0x00 }, /* r1D Beep Volume off Time */
0082     { CS42L52_BEEP_TONE_CTL, 0x00 },    /* r1E Beep Tone Cfg. */
0083     { CS42L52_TONE_CTL, 0x00 }, /* r1F Tone Ctl */
0084     { CS42L52_MASTERA_VOL, 0x00 },  /* r20 Master A Volume */
0085     { CS42L52_MASTERB_VOL, 0x00 },  /* r21 Master B Volume */
0086     { CS42L52_HPA_VOL, 0x00 },  /* r22 Headphone A Volume */
0087     { CS42L52_HPB_VOL, 0x00 },  /* r23 Headphone B Volume */
0088     { CS42L52_SPKA_VOL, 0x00 }, /* r24 Speaker A Volume */
0089     { CS42L52_SPKB_VOL, 0x00 }, /* r25 Speaker B Volume */
0090     { CS42L52_ADC_PCM_MIXER, 0x00 },    /* r26 Channel Mixer and Swap */
0091     { CS42L52_LIMITER_CTL1, 0x00 }, /* r27 Limit Ctl 1 Thresholds */
0092     { CS42L52_LIMITER_CTL2, 0x7F }, /* r28 Limit Ctl 2 Release Rate */
0093     { CS42L52_LIMITER_AT_RATE, 0xC0 },  /* r29 Limiter Attack Rate */
0094     { CS42L52_ALC_CTL, 0x00 },  /* r2A ALC Ctl 1 Attack Rate */
0095     { CS42L52_ALC_RATE, 0x3F }, /* r2B ALC Release Rate */
0096     { CS42L52_ALC_THRESHOLD, 0x3f },    /* r2C ALC Thresholds */
0097     { CS42L52_NOISE_GATE_CTL, 0x00 },   /* r2D Noise Gate Ctl */
0098     { CS42L52_CLK_STATUS, 0x00 },   /* r2E Overflow and Clock Status */
0099     { CS42L52_BATT_COMPEN, 0x00 },  /* r2F battery Compensation */
0100     { CS42L52_BATT_LEVEL, 0x00 },   /* r30 VP Battery Level */
0101     { CS42L52_SPK_STATUS, 0x00 },   /* r31 Speaker Status */
0102     { CS42L52_TEM_CTL, 0x3B },  /* r32 Temp Ctl */
0103     { CS42L52_THE_FOLDBACK, 0x00 }, /* r33 Foldback */
0104 };
0105 
0106 static bool cs42l52_readable_register(struct device *dev, unsigned int reg)
0107 {
0108     switch (reg) {
0109     case CS42L52_CHIP ... CS42L52_CHARGE_PUMP:
0110         return true;
0111     default:
0112         return false;
0113     }
0114 }
0115 
0116 static bool cs42l52_volatile_register(struct device *dev, unsigned int reg)
0117 {
0118     switch (reg) {
0119     case CS42L52_IFACE_CTL2:
0120     case CS42L52_CLK_STATUS:
0121     case CS42L52_BATT_LEVEL:
0122     case CS42L52_SPK_STATUS:
0123     case CS42L52_CHARGE_PUMP:
0124         return true;
0125     default:
0126         return false;
0127     }
0128 }
0129 
0130 static DECLARE_TLV_DB_SCALE(hl_tlv, -10200, 50, 0);
0131 
0132 static DECLARE_TLV_DB_SCALE(hpd_tlv, -9600, 50, 1);
0133 
0134 static DECLARE_TLV_DB_SCALE(ipd_tlv, -9600, 100, 0);
0135 
0136 static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0);
0137 
0138 static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
0139 
0140 static DECLARE_TLV_DB_SCALE(pass_tlv, -6000, 50, 0);
0141 
0142 static DECLARE_TLV_DB_SCALE(mix_tlv, -5150, 50, 0);
0143 
0144 static DECLARE_TLV_DB_SCALE(beep_tlv, -56, 200, 0);
0145 
0146 static const DECLARE_TLV_DB_RANGE(limiter_tlv,
0147     0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
0148     3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0)
0149 );
0150 
0151 static const char * const cs42l52_adca_text[] = {
0152     "Input1A", "Input2A", "Input3A", "Input4A", "PGA Input Left"};
0153 
0154 static const char * const cs42l52_adcb_text[] = {
0155     "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"};
0156 
0157 static SOC_ENUM_SINGLE_DECL(adca_enum,
0158                 CS42L52_ADC_PGA_A, 5, cs42l52_adca_text);
0159 
0160 static SOC_ENUM_SINGLE_DECL(adcb_enum,
0161                 CS42L52_ADC_PGA_B, 5, cs42l52_adcb_text);
0162 
0163 static const struct snd_kcontrol_new adca_mux =
0164     SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum);
0165 
0166 static const struct snd_kcontrol_new adcb_mux =
0167     SOC_DAPM_ENUM("Right ADC Input Capture Mux", adcb_enum);
0168 
0169 static const char * const mic_bias_level_text[] = {
0170     "0.5 +VA", "0.6 +VA", "0.7 +VA",
0171     "0.8 +VA", "0.83 +VA", "0.91 +VA"
0172 };
0173 
0174 static SOC_ENUM_SINGLE_DECL(mic_bias_level_enum,
0175                 CS42L52_IFACE_CTL2, 0, mic_bias_level_text);
0176 
0177 static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" };
0178 
0179 static SOC_ENUM_SINGLE_DECL(mica_enum,
0180                 CS42L52_MICA_CTL, 5, cs42l52_mic_text);
0181 
0182 static SOC_ENUM_SINGLE_DECL(micb_enum,
0183                 CS42L52_MICB_CTL, 5, cs42l52_mic_text);
0184 
0185 static const char * const digital_output_mux_text[] = {"ADC", "DSP"};
0186 
0187 static SOC_ENUM_SINGLE_DECL(digital_output_mux_enum,
0188                 CS42L52_ADC_MISC_CTL, 6,
0189                 digital_output_mux_text);
0190 
0191 static const struct snd_kcontrol_new digital_output_mux =
0192     SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum);
0193 
0194 static const char * const hp_gain_num_text[] = {
0195     "0.3959", "0.4571", "0.5111", "0.6047",
0196     "0.7099", "0.8399", "1.000", "1.1430"
0197 };
0198 
0199 static SOC_ENUM_SINGLE_DECL(hp_gain_enum,
0200                 CS42L52_PB_CTL1, 5,
0201                 hp_gain_num_text);
0202 
0203 static const char * const beep_pitch_text[] = {
0204     "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
0205     "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
0206 };
0207 
0208 static SOC_ENUM_SINGLE_DECL(beep_pitch_enum,
0209                 CS42L52_BEEP_FREQ, 4,
0210                 beep_pitch_text);
0211 
0212 static const char * const beep_ontime_text[] = {
0213     "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s",
0214     "1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s",
0215     "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s"
0216 };
0217 
0218 static SOC_ENUM_SINGLE_DECL(beep_ontime_enum,
0219                 CS42L52_BEEP_FREQ, 0,
0220                 beep_ontime_text);
0221 
0222 static const char * const beep_offtime_text[] = {
0223     "1.23 s", "2.58 s", "3.90 s", "5.20 s",
0224     "6.60 s", "8.05 s", "9.35 s", "10.80 s"
0225 };
0226 
0227 static SOC_ENUM_SINGLE_DECL(beep_offtime_enum,
0228                 CS42L52_BEEP_VOL, 5,
0229                 beep_offtime_text);
0230 
0231 static const char * const beep_config_text[] = {
0232     "Off", "Single", "Multiple", "Continuous"
0233 };
0234 
0235 static SOC_ENUM_SINGLE_DECL(beep_config_enum,
0236                 CS42L52_BEEP_TONE_CTL, 6,
0237                 beep_config_text);
0238 
0239 static const char * const beep_bass_text[] = {
0240     "50 Hz", "100 Hz", "200 Hz", "250 Hz"
0241 };
0242 
0243 static SOC_ENUM_SINGLE_DECL(beep_bass_enum,
0244                 CS42L52_BEEP_TONE_CTL, 1,
0245                 beep_bass_text);
0246 
0247 static const char * const beep_treble_text[] = {
0248     "5 kHz", "7 kHz", "10 kHz", " 15 kHz"
0249 };
0250 
0251 static SOC_ENUM_SINGLE_DECL(beep_treble_enum,
0252                 CS42L52_BEEP_TONE_CTL, 3,
0253                 beep_treble_text);
0254 
0255 static const char * const ng_threshold_text[] = {
0256     "-34dB", "-37dB", "-40dB", "-43dB",
0257     "-46dB", "-52dB", "-58dB", "-64dB"
0258 };
0259 
0260 static SOC_ENUM_SINGLE_DECL(ng_threshold_enum,
0261                 CS42L52_NOISE_GATE_CTL, 2,
0262                 ng_threshold_text);
0263 
0264 static const char * const cs42l52_ng_delay_text[] = {
0265     "50ms", "100ms", "150ms", "200ms"};
0266 
0267 static SOC_ENUM_SINGLE_DECL(ng_delay_enum,
0268                 CS42L52_NOISE_GATE_CTL, 0,
0269                 cs42l52_ng_delay_text);
0270 
0271 static const char * const cs42l52_ng_type_text[] = {
0272     "Apply Specific", "Apply All"
0273 };
0274 
0275 static SOC_ENUM_SINGLE_DECL(ng_type_enum,
0276                 CS42L52_NOISE_GATE_CTL, 6,
0277                 cs42l52_ng_type_text);
0278 
0279 static const char * const left_swap_text[] = {
0280     "Left", "LR 2", "Right"};
0281 
0282 static const char * const right_swap_text[] = {
0283     "Right", "LR 2", "Left"};
0284 
0285 static const unsigned int swap_values[] = { 0, 1, 3 };
0286 
0287 static const struct soc_enum adca_swap_enum =
0288     SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 2, 3,
0289                   ARRAY_SIZE(left_swap_text),
0290                   left_swap_text,
0291                   swap_values);
0292 
0293 static const struct snd_kcontrol_new adca_mixer =
0294     SOC_DAPM_ENUM("Route", adca_swap_enum);
0295 
0296 static const struct soc_enum pcma_swap_enum =
0297     SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 6, 3,
0298                   ARRAY_SIZE(left_swap_text),
0299                   left_swap_text,
0300                   swap_values);
0301 
0302 static const struct snd_kcontrol_new pcma_mixer =
0303     SOC_DAPM_ENUM("Route", pcma_swap_enum);
0304 
0305 static const struct soc_enum adcb_swap_enum =
0306     SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 0, 3,
0307                   ARRAY_SIZE(right_swap_text),
0308                   right_swap_text,
0309                   swap_values);
0310 
0311 static const struct snd_kcontrol_new adcb_mixer =
0312     SOC_DAPM_ENUM("Route", adcb_swap_enum);
0313 
0314 static const struct soc_enum pcmb_swap_enum =
0315     SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 4, 3,
0316                   ARRAY_SIZE(right_swap_text),
0317                   right_swap_text,
0318                   swap_values);
0319 
0320 static const struct snd_kcontrol_new pcmb_mixer =
0321     SOC_DAPM_ENUM("Route", pcmb_swap_enum);
0322 
0323 
0324 static const struct snd_kcontrol_new passthrul_ctl =
0325     SOC_DAPM_SINGLE("Switch", CS42L52_MISC_CTL, 6, 1, 0);
0326 
0327 static const struct snd_kcontrol_new passthrur_ctl =
0328     SOC_DAPM_SINGLE("Switch", CS42L52_MISC_CTL, 7, 1, 0);
0329 
0330 static const struct snd_kcontrol_new spkl_ctl =
0331     SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 0, 1, 1);
0332 
0333 static const struct snd_kcontrol_new spkr_ctl =
0334     SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 2, 1, 1);
0335 
0336 static const struct snd_kcontrol_new hpl_ctl =
0337     SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 4, 1, 1);
0338 
0339 static const struct snd_kcontrol_new hpr_ctl =
0340     SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 6, 1, 1);
0341 
0342 static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
0343 
0344     SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L52_MASTERA_VOL,
0345                   CS42L52_MASTERB_VOL, 0, 0x34, 0xE4, hl_tlv),
0346 
0347     SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L52_HPA_VOL,
0348                   CS42L52_HPB_VOL, 0, 0x34, 0xC0, hpd_tlv),
0349 
0350     SOC_ENUM("Headphone Analog Gain", hp_gain_enum),
0351 
0352     SOC_DOUBLE_R_SX_TLV("Speaker Volume", CS42L52_SPKA_VOL,
0353                   CS42L52_SPKB_VOL, 0, 0x40, 0xC0, hl_tlv),
0354 
0355     SOC_DOUBLE_R_SX_TLV("Bypass Volume", CS42L52_PASSTHRUA_VOL,
0356                   CS42L52_PASSTHRUB_VOL, 0, 0x88, 0x90, pass_tlv),
0357 
0358     SOC_DOUBLE("Bypass Mute", CS42L52_MISC_CTL, 4, 5, 1, 0),
0359 
0360     SOC_DOUBLE_R_TLV("MIC Gain Volume", CS42L52_MICA_CTL,
0361                   CS42L52_MICB_CTL, 0, 0x10, 0, mic_tlv),
0362 
0363     SOC_ENUM("MIC Bias Level", mic_bias_level_enum),
0364 
0365     SOC_DOUBLE_R_SX_TLV("ADC Volume", CS42L52_ADCA_VOL,
0366                   CS42L52_ADCB_VOL, 0, 0xA0, 0x78, ipd_tlv),
0367     SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
0368                  CS42L52_ADCA_MIXER_VOL, CS42L52_ADCB_MIXER_VOL,
0369                 0, 0x19, 0x7F, mix_tlv),
0370 
0371     SOC_DOUBLE("ADC Switch", CS42L52_ADC_MISC_CTL, 0, 1, 1, 0),
0372 
0373     SOC_DOUBLE_R("ADC Mixer Switch", CS42L52_ADCA_MIXER_VOL,
0374              CS42L52_ADCB_MIXER_VOL, 7, 1, 1),
0375 
0376     SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L52_PGAA_CTL,
0377                 CS42L52_PGAB_CTL, 0, 0x28, 0x24, pga_tlv),
0378 
0379     SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume",
0380                 CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL,
0381                 0, 0x19, 0x7f, mix_tlv),
0382     SOC_DOUBLE_R("PCM Mixer Switch",
0383              CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL, 7, 1, 1),
0384 
0385     SOC_ENUM("Beep Config", beep_config_enum),
0386     SOC_ENUM("Beep Pitch", beep_pitch_enum),
0387     SOC_ENUM("Beep on Time", beep_ontime_enum),
0388     SOC_ENUM("Beep off Time", beep_offtime_enum),
0389     SOC_SINGLE_SX_TLV("Beep Volume", CS42L52_BEEP_VOL,
0390             0, 0x07, 0x1f, beep_tlv),
0391     SOC_SINGLE("Beep Mixer Switch", CS42L52_BEEP_TONE_CTL, 5, 1, 1),
0392     SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum),
0393     SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum),
0394 
0395     SOC_SINGLE("Tone Control Switch", CS42L52_BEEP_TONE_CTL, 0, 1, 1),
0396     SOC_SINGLE_TLV("Treble Gain Volume",
0397                 CS42L52_TONE_CTL, 4, 15, 1, hl_tlv),
0398     SOC_SINGLE_TLV("Bass Gain Volume",
0399                 CS42L52_TONE_CTL, 0, 15, 1, hl_tlv),
0400 
0401     /* Limiter */
0402     SOC_SINGLE_TLV("Limiter Max Threshold Volume",
0403                CS42L52_LIMITER_CTL1, 5, 7, 0, limiter_tlv),
0404     SOC_SINGLE_TLV("Limiter Cushion Threshold Volume",
0405                CS42L52_LIMITER_CTL1, 2, 7, 0, limiter_tlv),
0406     SOC_SINGLE_TLV("Limiter Release Rate Volume",
0407                CS42L52_LIMITER_CTL2, 0, 63, 0, limiter_tlv),
0408     SOC_SINGLE_TLV("Limiter Attack Rate Volume",
0409                CS42L52_LIMITER_AT_RATE, 0, 63, 0, limiter_tlv),
0410 
0411     SOC_SINGLE("Limiter SR Switch", CS42L52_LIMITER_CTL1, 1, 1, 0),
0412     SOC_SINGLE("Limiter ZC Switch", CS42L52_LIMITER_CTL1, 0, 1, 0),
0413     SOC_SINGLE("Limiter Switch", CS42L52_LIMITER_CTL2, 7, 1, 0),
0414 
0415     /* ALC */
0416     SOC_SINGLE_TLV("ALC Attack Rate Volume", CS42L52_ALC_CTL,
0417                0, 63, 0, limiter_tlv),
0418     SOC_SINGLE_TLV("ALC Release Rate Volume", CS42L52_ALC_RATE,
0419                0, 63, 0, limiter_tlv),
0420     SOC_SINGLE_TLV("ALC Max Threshold Volume", CS42L52_ALC_THRESHOLD,
0421                5, 7, 0, limiter_tlv),
0422     SOC_SINGLE_TLV("ALC Min Threshold Volume", CS42L52_ALC_THRESHOLD,
0423                2, 7, 0, limiter_tlv),
0424 
0425     SOC_DOUBLE_R("ALC SR Capture Switch", CS42L52_PGAA_CTL,
0426              CS42L52_PGAB_CTL, 7, 1, 1),
0427     SOC_DOUBLE_R("ALC ZC Capture Switch", CS42L52_PGAA_CTL,
0428              CS42L52_PGAB_CTL, 6, 1, 1),
0429     SOC_DOUBLE("ALC Capture Switch", CS42L52_ALC_CTL, 6, 7, 1, 0),
0430 
0431     /* Noise gate */
0432     SOC_ENUM("NG Type Switch", ng_type_enum),
0433     SOC_SINGLE("NG Enable Switch", CS42L52_NOISE_GATE_CTL, 6, 1, 0),
0434     SOC_SINGLE("NG Boost Switch", CS42L52_NOISE_GATE_CTL, 5, 1, 1),
0435     SOC_ENUM("NG Threshold", ng_threshold_enum),
0436     SOC_ENUM("NG Delay", ng_delay_enum),
0437 
0438     SOC_DOUBLE("HPF Switch", CS42L52_ANALOG_HPF_CTL, 5, 7, 1, 0),
0439 
0440     SOC_DOUBLE("Analog SR Switch", CS42L52_ANALOG_HPF_CTL, 1, 3, 1, 1),
0441     SOC_DOUBLE("Analog ZC Switch", CS42L52_ANALOG_HPF_CTL, 0, 2, 1, 1),
0442     SOC_SINGLE("Digital SR Switch", CS42L52_MISC_CTL, 1, 1, 0),
0443     SOC_SINGLE("Digital ZC Switch", CS42L52_MISC_CTL, 0, 1, 0),
0444     SOC_SINGLE("Deemphasis Switch", CS42L52_MISC_CTL, 2, 1, 0),
0445 
0446     SOC_SINGLE("Batt Compensation Switch", CS42L52_BATT_COMPEN, 7, 1, 0),
0447     SOC_SINGLE("Batt VP Monitor Switch", CS42L52_BATT_COMPEN, 6, 1, 0),
0448     SOC_SINGLE("Batt VP ref", CS42L52_BATT_COMPEN, 0, 0x0f, 0),
0449 
0450     SOC_SINGLE("PGA AIN1L Switch", CS42L52_ADC_PGA_A, 0, 1, 0),
0451     SOC_SINGLE("PGA AIN1R Switch", CS42L52_ADC_PGA_B, 0, 1, 0),
0452     SOC_SINGLE("PGA AIN2L Switch", CS42L52_ADC_PGA_A, 1, 1, 0),
0453     SOC_SINGLE("PGA AIN2R Switch", CS42L52_ADC_PGA_B, 1, 1, 0),
0454 
0455     SOC_SINGLE("PGA AIN3L Switch", CS42L52_ADC_PGA_A, 2, 1, 0),
0456     SOC_SINGLE("PGA AIN3R Switch", CS42L52_ADC_PGA_B, 2, 1, 0),
0457 
0458     SOC_SINGLE("PGA AIN4L Switch", CS42L52_ADC_PGA_A, 3, 1, 0),
0459     SOC_SINGLE("PGA AIN4R Switch", CS42L52_ADC_PGA_B, 3, 1, 0),
0460 
0461     SOC_SINGLE("PGA MICA Switch", CS42L52_ADC_PGA_A, 4, 1, 0),
0462     SOC_SINGLE("PGA MICB Switch", CS42L52_ADC_PGA_B, 4, 1, 0),
0463 
0464 };
0465 
0466 static const struct snd_kcontrol_new cs42l52_mica_controls[] = {
0467     SOC_ENUM("MICA Select", mica_enum),
0468 };
0469 
0470 static const struct snd_kcontrol_new cs42l52_micb_controls[] = {
0471     SOC_ENUM("MICB Select", micb_enum),
0472 };
0473 
0474 static int cs42l52_add_mic_controls(struct snd_soc_component *component)
0475 {
0476     struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
0477     struct cs42l52_platform_data *pdata = &cs42l52->pdata;
0478 
0479     if (!pdata->mica_diff_cfg)
0480         snd_soc_add_component_controls(component, cs42l52_mica_controls,
0481                      ARRAY_SIZE(cs42l52_mica_controls));
0482 
0483     if (!pdata->micb_diff_cfg)
0484         snd_soc_add_component_controls(component, cs42l52_micb_controls,
0485                      ARRAY_SIZE(cs42l52_micb_controls));
0486 
0487     return 0;
0488 }
0489 
0490 static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = {
0491 
0492     SND_SOC_DAPM_INPUT("AIN1L"),
0493     SND_SOC_DAPM_INPUT("AIN1R"),
0494     SND_SOC_DAPM_INPUT("AIN2L"),
0495     SND_SOC_DAPM_INPUT("AIN2R"),
0496     SND_SOC_DAPM_INPUT("AIN3L"),
0497     SND_SOC_DAPM_INPUT("AIN3R"),
0498     SND_SOC_DAPM_INPUT("AIN4L"),
0499     SND_SOC_DAPM_INPUT("AIN4R"),
0500     SND_SOC_DAPM_INPUT("MICA"),
0501     SND_SOC_DAPM_INPUT("MICB"),
0502     SND_SOC_DAPM_SIGGEN("Beep"),
0503 
0504     SND_SOC_DAPM_AIF_OUT("AIFOUTL", NULL,  0,
0505             SND_SOC_NOPM, 0, 0),
0506     SND_SOC_DAPM_AIF_OUT("AIFOUTR", NULL,  0,
0507             SND_SOC_NOPM, 0, 0),
0508 
0509     SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L52_PWRCTL1, 1, 1),
0510     SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L52_PWRCTL1, 2, 1),
0511     SND_SOC_DAPM_PGA("PGA Left", CS42L52_PWRCTL1, 3, 1, NULL, 0),
0512     SND_SOC_DAPM_PGA("PGA Right", CS42L52_PWRCTL1, 4, 1, NULL, 0),
0513 
0514     SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adca_mux),
0515     SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcb_mux),
0516 
0517     SND_SOC_DAPM_MUX("ADC Left Swap", SND_SOC_NOPM,
0518              0, 0, &adca_mixer),
0519     SND_SOC_DAPM_MUX("ADC Right Swap", SND_SOC_NOPM,
0520              0, 0, &adcb_mixer),
0521 
0522     SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM,
0523              0, 0, &digital_output_mux),
0524 
0525     SND_SOC_DAPM_PGA("PGA MICA", CS42L52_PWRCTL2, 1, 1, NULL, 0),
0526     SND_SOC_DAPM_PGA("PGA MICB", CS42L52_PWRCTL2, 2, 1, NULL, 0),
0527 
0528     SND_SOC_DAPM_SUPPLY("Mic Bias", CS42L52_PWRCTL2, 0, 1, NULL, 0),
0529     SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L52_PWRCTL1, 7, 1, NULL, 0),
0530 
0531     SND_SOC_DAPM_AIF_IN("AIFINL", NULL,  0,
0532             SND_SOC_NOPM, 0, 0),
0533     SND_SOC_DAPM_AIF_IN("AIFINR", NULL,  0,
0534             SND_SOC_NOPM, 0, 0),
0535 
0536     SND_SOC_DAPM_DAC("DAC Left", NULL, SND_SOC_NOPM, 0, 0),
0537     SND_SOC_DAPM_DAC("DAC Right", NULL, SND_SOC_NOPM, 0, 0),
0538 
0539     SND_SOC_DAPM_SWITCH("Bypass Left", CS42L52_MISC_CTL,
0540                 6, 0, &passthrul_ctl),
0541     SND_SOC_DAPM_SWITCH("Bypass Right", CS42L52_MISC_CTL,
0542                 7, 0, &passthrur_ctl),
0543 
0544     SND_SOC_DAPM_MUX("PCM Left Swap", SND_SOC_NOPM,
0545              0, 0, &pcma_mixer),
0546     SND_SOC_DAPM_MUX("PCM Right Swap", SND_SOC_NOPM,
0547              0, 0, &pcmb_mixer),
0548 
0549     SND_SOC_DAPM_SWITCH("HP Left Amp", SND_SOC_NOPM, 0, 0, &hpl_ctl),
0550     SND_SOC_DAPM_SWITCH("HP Right Amp", SND_SOC_NOPM, 0, 0, &hpr_ctl),
0551 
0552     SND_SOC_DAPM_SWITCH("SPK Left Amp", SND_SOC_NOPM, 0, 0, &spkl_ctl),
0553     SND_SOC_DAPM_SWITCH("SPK Right Amp", SND_SOC_NOPM, 0, 0, &spkr_ctl),
0554 
0555     SND_SOC_DAPM_OUTPUT("HPOUTA"),
0556     SND_SOC_DAPM_OUTPUT("HPOUTB"),
0557     SND_SOC_DAPM_OUTPUT("SPKOUTA"),
0558     SND_SOC_DAPM_OUTPUT("SPKOUTB"),
0559 
0560 };
0561 
0562 static const struct snd_soc_dapm_route cs42l52_audio_map[] = {
0563 
0564     {"Capture", NULL, "AIFOUTL"},
0565     {"Capture", NULL, "AIFOUTL"},
0566 
0567     {"AIFOUTL", NULL, "Output Mux"},
0568     {"AIFOUTR", NULL, "Output Mux"},
0569 
0570     {"Output Mux", "ADC", "ADC Left"},
0571     {"Output Mux", "ADC", "ADC Right"},
0572 
0573     {"ADC Left", NULL, "Charge Pump"},
0574     {"ADC Right", NULL, "Charge Pump"},
0575 
0576     {"Charge Pump", NULL, "ADC Left Mux"},
0577     {"Charge Pump", NULL, "ADC Right Mux"},
0578 
0579     {"ADC Left Mux", "Input1A", "AIN1L"},
0580     {"ADC Right Mux", "Input1B", "AIN1R"},
0581     {"ADC Left Mux", "Input2A", "AIN2L"},
0582     {"ADC Right Mux", "Input2B", "AIN2R"},
0583     {"ADC Left Mux", "Input3A", "AIN3L"},
0584     {"ADC Right Mux", "Input3B", "AIN3R"},
0585     {"ADC Left Mux", "Input4A", "AIN4L"},
0586     {"ADC Right Mux", "Input4B", "AIN4R"},
0587     {"ADC Left Mux", "PGA Input Left", "PGA Left"},
0588     {"ADC Right Mux", "PGA Input Right" , "PGA Right"},
0589 
0590     {"PGA Left", "Switch", "AIN1L"},
0591     {"PGA Right", "Switch", "AIN1R"},
0592     {"PGA Left", "Switch", "AIN2L"},
0593     {"PGA Right", "Switch", "AIN2R"},
0594     {"PGA Left", "Switch", "AIN3L"},
0595     {"PGA Right", "Switch", "AIN3R"},
0596     {"PGA Left", "Switch", "AIN4L"},
0597     {"PGA Right", "Switch", "AIN4R"},
0598 
0599     {"PGA Left", "Switch", "PGA MICA"},
0600     {"PGA MICA", NULL, "MICA"},
0601 
0602     {"PGA Right", "Switch", "PGA MICB"},
0603     {"PGA MICB", NULL, "MICB"},
0604 
0605     {"HPOUTA", NULL, "HP Left Amp"},
0606     {"HPOUTB", NULL, "HP Right Amp"},
0607     {"HP Left Amp", NULL, "Bypass Left"},
0608     {"HP Right Amp", NULL, "Bypass Right"},
0609     {"Bypass Left", "Switch", "PGA Left"},
0610     {"Bypass Right", "Switch", "PGA Right"},
0611     {"HP Left Amp", "Switch", "DAC Left"},
0612     {"HP Right Amp", "Switch", "DAC Right"},
0613 
0614     {"SPKOUTA", NULL, "SPK Left Amp"},
0615     {"SPKOUTB", NULL, "SPK Right Amp"},
0616 
0617     {"SPK Left Amp", NULL, "Beep"},
0618     {"SPK Right Amp", NULL, "Beep"},
0619     {"SPK Left Amp", "Switch", "Playback"},
0620     {"SPK Right Amp", "Switch", "Playback"},
0621 
0622     {"DAC Left", NULL, "Beep"},
0623     {"DAC Right", NULL, "Beep"},
0624     {"DAC Left", NULL, "Playback"},
0625     {"DAC Right", NULL, "Playback"},
0626 
0627     {"Output Mux", "DSP", "Playback"},
0628     {"Output Mux", "DSP", "Playback"},
0629 
0630     {"AIFINL", NULL, "Playback"},
0631     {"AIFINR", NULL, "Playback"},
0632 
0633 };
0634 
0635 struct cs42l52_clk_para {
0636     u32 mclk;
0637     u32 rate;
0638     u8 speed;
0639     u8 group;
0640     u8 videoclk;
0641     u8 ratio;
0642     u8 mclkdiv2;
0643 };
0644 
0645 static const struct cs42l52_clk_para clk_map_table[] = {
0646     /*8k*/
0647     {12288000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
0648     {18432000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
0649     {12000000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0},
0650     {24000000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1},
0651     {27000000, 8000, CLK_QS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 0},
0652 
0653     /*11.025k*/
0654     {11289600, 11025, CLK_QS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0655     {16934400, 11025, CLK_QS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0656 
0657     /*16k*/
0658     {12288000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
0659     {18432000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
0660     {12000000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0},
0661     {24000000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1},
0662     {27000000, 16000, CLK_HS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 1},
0663 
0664     /*22.05k*/
0665     {11289600, 22050, CLK_HS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0666     {16934400, 22050, CLK_HS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0667 
0668     /* 32k */
0669     {12288000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
0670     {18432000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
0671     {12000000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0},
0672     {24000000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1},
0673     {27000000, 32000, CLK_SS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 0},
0674 
0675     /* 44.1k */
0676     {11289600, 44100, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0677     {16934400, 44100, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0678 
0679     /* 48k */
0680     {12288000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0681     {18432000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0682     {12000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 0},
0683     {24000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 1},
0684     {27000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_27M_MCLK, CLK_R_125, 1},
0685 
0686     /* 88.2k */
0687     {11289600, 88200, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0688     {16934400, 88200, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0689 
0690     /* 96k */
0691     {12288000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0692     {18432000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
0693     {12000000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 0},
0694     {24000000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 1},
0695 };
0696 
0697 static int cs42l52_get_clk(int mclk, int rate)
0698 {
0699     int i, ret = -EINVAL;
0700     u_int mclk1, mclk2 = 0;
0701 
0702     for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
0703         if (clk_map_table[i].rate == rate) {
0704             mclk1 = clk_map_table[i].mclk;
0705             if (abs(mclk - mclk1) < abs(mclk - mclk2)) {
0706                 mclk2 = mclk1;
0707                 ret = i;
0708             }
0709         }
0710     }
0711     return ret;
0712 }
0713 
0714 static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai,
0715             int clk_id, unsigned int freq, int dir)
0716 {
0717     struct snd_soc_component *component = codec_dai->component;
0718     struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
0719 
0720     if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) {
0721         cs42l52->sysclk = freq;
0722     } else {
0723         dev_err(component->dev, "Invalid freq parameter\n");
0724         return -EINVAL;
0725     }
0726     return 0;
0727 }
0728 
0729 static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
0730 {
0731     struct snd_soc_component *component = codec_dai->component;
0732     struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
0733     u8 iface = 0;
0734 
0735     switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
0736     case SND_SOC_DAIFMT_CBM_CFM:
0737         iface = CS42L52_IFACE_CTL1_MASTER;
0738         break;
0739     case SND_SOC_DAIFMT_CBS_CFS:
0740         iface = CS42L52_IFACE_CTL1_SLAVE;
0741         break;
0742     default:
0743         return -EINVAL;
0744     }
0745 
0746      /* interface format */
0747     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0748     case SND_SOC_DAIFMT_I2S:
0749         iface |= CS42L52_IFACE_CTL1_ADC_FMT_I2S |
0750                 CS42L52_IFACE_CTL1_DAC_FMT_I2S;
0751         break;
0752     case SND_SOC_DAIFMT_RIGHT_J:
0753         iface |= CS42L52_IFACE_CTL1_DAC_FMT_RIGHT_J;
0754         break;
0755     case SND_SOC_DAIFMT_LEFT_J:
0756         iface |= CS42L52_IFACE_CTL1_ADC_FMT_LEFT_J |
0757                 CS42L52_IFACE_CTL1_DAC_FMT_LEFT_J;
0758         break;
0759     case SND_SOC_DAIFMT_DSP_A:
0760         iface |= CS42L52_IFACE_CTL1_DSP_MODE_EN;
0761         break;
0762     case SND_SOC_DAIFMT_DSP_B:
0763         break;
0764     default:
0765         return -EINVAL;
0766     }
0767 
0768     /* clock inversion */
0769     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0770     case SND_SOC_DAIFMT_NB_NF:
0771         break;
0772     case SND_SOC_DAIFMT_IB_IF:
0773         iface |= CS42L52_IFACE_CTL1_INV_SCLK;
0774         break;
0775     case SND_SOC_DAIFMT_IB_NF:
0776         iface |= CS42L52_IFACE_CTL1_INV_SCLK;
0777         break;
0778     case SND_SOC_DAIFMT_NB_IF:
0779         break;
0780     default:
0781         return -EINVAL;
0782     }
0783     cs42l52->config.format = iface;
0784     snd_soc_component_write(component, CS42L52_IFACE_CTL1, cs42l52->config.format);
0785 
0786     return 0;
0787 }
0788 
0789 static int cs42l52_mute(struct snd_soc_dai *dai, int mute, int direction)
0790 {
0791     struct snd_soc_component *component = dai->component;
0792 
0793     if (mute)
0794         snd_soc_component_update_bits(component, CS42L52_PB_CTL1,
0795                     CS42L52_PB_CTL1_MUTE_MASK,
0796                 CS42L52_PB_CTL1_MUTE);
0797     else
0798         snd_soc_component_update_bits(component, CS42L52_PB_CTL1,
0799                     CS42L52_PB_CTL1_MUTE_MASK,
0800                 CS42L52_PB_CTL1_UNMUTE);
0801 
0802     return 0;
0803 }
0804 
0805 static int cs42l52_pcm_hw_params(struct snd_pcm_substream *substream,
0806                      struct snd_pcm_hw_params *params,
0807                      struct snd_soc_dai *dai)
0808 {
0809     struct snd_soc_component *component = dai->component;
0810     struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
0811     u32 clk = 0;
0812     int index;
0813 
0814     index = cs42l52_get_clk(cs42l52->sysclk, params_rate(params));
0815     if (index >= 0) {
0816         cs42l52->sysclk = clk_map_table[index].mclk;
0817 
0818         clk |= (clk_map_table[index].speed << CLK_SPEED_SHIFT) |
0819         (clk_map_table[index].group << CLK_32K_SR_SHIFT) |
0820         (clk_map_table[index].videoclk << CLK_27M_MCLK_SHIFT) |
0821         (clk_map_table[index].ratio << CLK_RATIO_SHIFT) |
0822         clk_map_table[index].mclkdiv2;
0823 
0824         snd_soc_component_write(component, CS42L52_CLK_CTL, clk);
0825     } else {
0826         dev_err(component->dev, "can't get correct mclk\n");
0827         return -EINVAL;
0828     }
0829 
0830     return 0;
0831 }
0832 
0833 static int cs42l52_set_bias_level(struct snd_soc_component *component,
0834                     enum snd_soc_bias_level level)
0835 {
0836     struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
0837 
0838     switch (level) {
0839     case SND_SOC_BIAS_ON:
0840         break;
0841     case SND_SOC_BIAS_PREPARE:
0842         snd_soc_component_update_bits(component, CS42L52_PWRCTL1,
0843                     CS42L52_PWRCTL1_PDN_CODEC, 0);
0844         break;
0845     case SND_SOC_BIAS_STANDBY:
0846         if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
0847             regcache_cache_only(cs42l52->regmap, false);
0848             regcache_sync(cs42l52->regmap);
0849         }
0850         snd_soc_component_write(component, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
0851         break;
0852     case SND_SOC_BIAS_OFF:
0853         snd_soc_component_write(component, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
0854         regcache_cache_only(cs42l52->regmap, true);
0855         break;
0856     }
0857 
0858     return 0;
0859 }
0860 
0861 #define CS42L52_RATES (SNDRV_PCM_RATE_8000_96000)
0862 
0863 #define CS42L52_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
0864             SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \
0865             SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
0866             SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE)
0867 
0868 static const struct snd_soc_dai_ops cs42l52_ops = {
0869     .hw_params  = cs42l52_pcm_hw_params,
0870     .mute_stream    = cs42l52_mute,
0871     .set_fmt    = cs42l52_set_fmt,
0872     .set_sysclk = cs42l52_set_sysclk,
0873     .no_capture_mute = 1,
0874 };
0875 
0876 static struct snd_soc_dai_driver cs42l52_dai = {
0877         .name = "cs42l52",
0878         .playback = {
0879             .stream_name = "Playback",
0880             .channels_min = 1,
0881             .channels_max = 2,
0882             .rates = CS42L52_RATES,
0883             .formats = CS42L52_FORMATS,
0884         },
0885         .capture = {
0886             .stream_name = "Capture",
0887             .channels_min = 1,
0888             .channels_max = 2,
0889             .rates = CS42L52_RATES,
0890             .formats = CS42L52_FORMATS,
0891         },
0892         .ops = &cs42l52_ops,
0893 };
0894 
0895 static int beep_rates[] = {
0896     261, 522, 585, 667, 706, 774, 889, 1000,
0897     1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
0898 };
0899 
0900 static void cs42l52_beep_work(struct work_struct *work)
0901 {
0902     struct cs42l52_private *cs42l52 =
0903         container_of(work, struct cs42l52_private, beep_work);
0904     struct snd_soc_component *component = cs42l52->component;
0905     struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0906     int i;
0907     int val = 0;
0908     int best = 0;
0909 
0910     if (cs42l52->beep_rate) {
0911         for (i = 0; i < ARRAY_SIZE(beep_rates); i++) {
0912             if (abs(cs42l52->beep_rate - beep_rates[i]) <
0913                 abs(cs42l52->beep_rate - beep_rates[best]))
0914                 best = i;
0915         }
0916 
0917         dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n",
0918             beep_rates[best], cs42l52->beep_rate);
0919 
0920         val = (best << CS42L52_BEEP_RATE_SHIFT);
0921 
0922         snd_soc_dapm_enable_pin(dapm, "Beep");
0923     } else {
0924         dev_dbg(component->dev, "Disabling beep\n");
0925         snd_soc_dapm_disable_pin(dapm, "Beep");
0926     }
0927 
0928     snd_soc_component_update_bits(component, CS42L52_BEEP_FREQ,
0929                 CS42L52_BEEP_RATE_MASK, val);
0930 
0931     snd_soc_dapm_sync(dapm);
0932 }
0933 
0934 /* For usability define a way of injecting beep events for the device -
0935  * many systems will not have a keyboard.
0936  */
0937 static int cs42l52_beep_event(struct input_dev *dev, unsigned int type,
0938                  unsigned int code, int hz)
0939 {
0940     struct snd_soc_component *component = input_get_drvdata(dev);
0941     struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
0942 
0943     dev_dbg(component->dev, "Beep event %x %x\n", code, hz);
0944 
0945     switch (code) {
0946     case SND_BELL:
0947         if (hz)
0948             hz = 261;
0949         break;
0950     case SND_TONE:
0951         break;
0952     default:
0953         return -1;
0954     }
0955 
0956     /* Kick the beep from a workqueue */
0957     cs42l52->beep_rate = hz;
0958     schedule_work(&cs42l52->beep_work);
0959     return 0;
0960 }
0961 
0962 static ssize_t beep_store(struct device *dev, struct device_attribute *attr,
0963               const char *buf, size_t count)
0964 {
0965     struct cs42l52_private *cs42l52 = dev_get_drvdata(dev);
0966     long int time;
0967     int ret;
0968 
0969     ret = kstrtol(buf, 10, &time);
0970     if (ret != 0)
0971         return ret;
0972 
0973     input_event(cs42l52->beep, EV_SND, SND_TONE, time);
0974 
0975     return count;
0976 }
0977 
0978 static DEVICE_ATTR_WO(beep);
0979 
0980 static void cs42l52_init_beep(struct snd_soc_component *component)
0981 {
0982     struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
0983     int ret;
0984 
0985     cs42l52->beep = devm_input_allocate_device(component->dev);
0986     if (!cs42l52->beep) {
0987         dev_err(component->dev, "Failed to allocate beep device\n");
0988         return;
0989     }
0990 
0991     INIT_WORK(&cs42l52->beep_work, cs42l52_beep_work);
0992     cs42l52->beep_rate = 0;
0993 
0994     cs42l52->beep->name = "CS42L52 Beep Generator";
0995     cs42l52->beep->phys = dev_name(component->dev);
0996     cs42l52->beep->id.bustype = BUS_I2C;
0997 
0998     cs42l52->beep->evbit[0] = BIT_MASK(EV_SND);
0999     cs42l52->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
1000     cs42l52->beep->event = cs42l52_beep_event;
1001     cs42l52->beep->dev.parent = component->dev;
1002     input_set_drvdata(cs42l52->beep, component);
1003 
1004     ret = input_register_device(cs42l52->beep);
1005     if (ret != 0) {
1006         cs42l52->beep = NULL;
1007         dev_err(component->dev, "Failed to register beep device\n");
1008     }
1009 
1010     ret = device_create_file(component->dev, &dev_attr_beep);
1011     if (ret != 0) {
1012         dev_err(component->dev, "Failed to create keyclick file: %d\n",
1013             ret);
1014     }
1015 }
1016 
1017 static void cs42l52_free_beep(struct snd_soc_component *component)
1018 {
1019     struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
1020 
1021     device_remove_file(component->dev, &dev_attr_beep);
1022     cancel_work_sync(&cs42l52->beep_work);
1023     cs42l52->beep = NULL;
1024 
1025     snd_soc_component_update_bits(component, CS42L52_BEEP_TONE_CTL,
1026                 CS42L52_BEEP_EN_MASK, 0);
1027 }
1028 
1029 static int cs42l52_probe(struct snd_soc_component *component)
1030 {
1031     struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
1032 
1033     regcache_cache_only(cs42l52->regmap, true);
1034 
1035     cs42l52_add_mic_controls(component);
1036 
1037     cs42l52_init_beep(component);
1038 
1039     cs42l52->sysclk = CS42L52_DEFAULT_CLK;
1040     cs42l52->config.format = CS42L52_DEFAULT_FORMAT;
1041 
1042     return 0;
1043 }
1044 
1045 static void cs42l52_remove(struct snd_soc_component *component)
1046 {
1047     cs42l52_free_beep(component);
1048 }
1049 
1050 static const struct snd_soc_component_driver soc_component_dev_cs42l52 = {
1051     .probe          = cs42l52_probe,
1052     .remove         = cs42l52_remove,
1053     .set_bias_level     = cs42l52_set_bias_level,
1054     .controls       = cs42l52_snd_controls,
1055     .num_controls       = ARRAY_SIZE(cs42l52_snd_controls),
1056     .dapm_widgets       = cs42l52_dapm_widgets,
1057     .num_dapm_widgets   = ARRAY_SIZE(cs42l52_dapm_widgets),
1058     .dapm_routes        = cs42l52_audio_map,
1059     .num_dapm_routes    = ARRAY_SIZE(cs42l52_audio_map),
1060     .suspend_bias_off   = 1,
1061     .idle_bias_on       = 1,
1062     .use_pmdown_time    = 1,
1063     .endianness     = 1,
1064 };
1065 
1066 /* Current and threshold powerup sequence Pg37 */
1067 static const struct reg_sequence cs42l52_threshold_patch[] = {
1068 
1069     { 0x00, 0x99 },
1070     { 0x3E, 0xBA },
1071     { 0x47, 0x80 },
1072     { 0x32, 0xBB },
1073     { 0x32, 0x3B },
1074     { 0x00, 0x00 },
1075 
1076 };
1077 
1078 static const struct regmap_config cs42l52_regmap = {
1079     .reg_bits = 8,
1080     .val_bits = 8,
1081 
1082     .max_register = CS42L52_MAX_REGISTER,
1083     .reg_defaults = cs42l52_reg_defaults,
1084     .num_reg_defaults = ARRAY_SIZE(cs42l52_reg_defaults),
1085     .readable_reg = cs42l52_readable_register,
1086     .volatile_reg = cs42l52_volatile_register,
1087     .cache_type = REGCACHE_RBTREE,
1088 };
1089 
1090 static int cs42l52_i2c_probe(struct i2c_client *i2c_client)
1091 {
1092     struct cs42l52_private *cs42l52;
1093     struct cs42l52_platform_data *pdata = dev_get_platdata(&i2c_client->dev);
1094     int ret;
1095     unsigned int devid;
1096     unsigned int reg;
1097     u32 val32;
1098 
1099     cs42l52 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l52), GFP_KERNEL);
1100     if (cs42l52 == NULL)
1101         return -ENOMEM;
1102     cs42l52->dev = &i2c_client->dev;
1103 
1104     cs42l52->regmap = devm_regmap_init_i2c(i2c_client, &cs42l52_regmap);
1105     if (IS_ERR(cs42l52->regmap)) {
1106         ret = PTR_ERR(cs42l52->regmap);
1107         dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1108         return ret;
1109     }
1110     if (pdata) {
1111         cs42l52->pdata = *pdata;
1112     } else {
1113         pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
1114                      GFP_KERNEL);
1115         if (!pdata)
1116             return -ENOMEM;
1117 
1118         if (i2c_client->dev.of_node) {
1119             if (of_property_read_bool(i2c_client->dev.of_node,
1120                 "cirrus,mica-differential-cfg"))
1121                 pdata->mica_diff_cfg = true;
1122 
1123             if (of_property_read_bool(i2c_client->dev.of_node,
1124                 "cirrus,micb-differential-cfg"))
1125                 pdata->micb_diff_cfg = true;
1126 
1127             if (of_property_read_u32(i2c_client->dev.of_node,
1128                 "cirrus,micbias-lvl", &val32) >= 0)
1129                 pdata->micbias_lvl = val32;
1130 
1131             if (of_property_read_u32(i2c_client->dev.of_node,
1132                 "cirrus,chgfreq-divisor", &val32) >= 0)
1133                 pdata->chgfreq = val32;
1134 
1135             pdata->reset_gpio =
1136                 of_get_named_gpio(i2c_client->dev.of_node,
1137                         "cirrus,reset-gpio", 0);
1138         }
1139         cs42l52->pdata = *pdata;
1140     }
1141 
1142     if (cs42l52->pdata.reset_gpio) {
1143         ret = devm_gpio_request_one(&i2c_client->dev,
1144                         cs42l52->pdata.reset_gpio,
1145                         GPIOF_OUT_INIT_HIGH,
1146                         "CS42L52 /RST");
1147         if (ret < 0) {
1148             dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n",
1149                 cs42l52->pdata.reset_gpio, ret);
1150             return ret;
1151         }
1152         gpio_set_value_cansleep(cs42l52->pdata.reset_gpio, 0);
1153         gpio_set_value_cansleep(cs42l52->pdata.reset_gpio, 1);
1154     }
1155 
1156     i2c_set_clientdata(i2c_client, cs42l52);
1157 
1158     ret = regmap_register_patch(cs42l52->regmap, cs42l52_threshold_patch,
1159                     ARRAY_SIZE(cs42l52_threshold_patch));
1160     if (ret != 0)
1161         dev_warn(cs42l52->dev, "Failed to apply regmap patch: %d\n",
1162              ret);
1163 
1164     ret = regmap_read(cs42l52->regmap, CS42L52_CHIP, &reg);
1165     if (ret) {
1166         dev_err(&i2c_client->dev, "Failed to read chip ID: %d\n", ret);
1167         return ret;
1168     }
1169 
1170     devid = reg & CS42L52_CHIP_ID_MASK;
1171     if (devid != CS42L52_CHIP_ID) {
1172         ret = -ENODEV;
1173         dev_err(&i2c_client->dev,
1174             "CS42L52 Device ID (%X). Expected %X\n",
1175             devid, CS42L52_CHIP_ID);
1176         return ret;
1177     }
1178 
1179     dev_info(&i2c_client->dev, "Cirrus Logic CS42L52, Revision: %02X\n",
1180          reg & CS42L52_CHIP_REV_MASK);
1181 
1182     /* Set Platform Data */
1183     if (cs42l52->pdata.mica_diff_cfg)
1184         regmap_update_bits(cs42l52->regmap, CS42L52_MICA_CTL,
1185                    CS42L52_MIC_CTL_TYPE_MASK,
1186                 cs42l52->pdata.mica_diff_cfg <<
1187                 CS42L52_MIC_CTL_TYPE_SHIFT);
1188 
1189     if (cs42l52->pdata.micb_diff_cfg)
1190         regmap_update_bits(cs42l52->regmap, CS42L52_MICB_CTL,
1191                    CS42L52_MIC_CTL_TYPE_MASK,
1192                 cs42l52->pdata.micb_diff_cfg <<
1193                 CS42L52_MIC_CTL_TYPE_SHIFT);
1194 
1195     if (cs42l52->pdata.chgfreq)
1196         regmap_update_bits(cs42l52->regmap, CS42L52_CHARGE_PUMP,
1197                    CS42L52_CHARGE_PUMP_MASK,
1198                 cs42l52->pdata.chgfreq <<
1199                 CS42L52_CHARGE_PUMP_SHIFT);
1200 
1201     if (cs42l52->pdata.micbias_lvl)
1202         regmap_update_bits(cs42l52->regmap, CS42L52_IFACE_CTL2,
1203                    CS42L52_IFACE_CTL2_BIAS_LVL,
1204                 cs42l52->pdata.micbias_lvl);
1205 
1206     return devm_snd_soc_register_component(&i2c_client->dev,
1207             &soc_component_dev_cs42l52, &cs42l52_dai, 1);
1208 }
1209 
1210 static const struct of_device_id cs42l52_of_match[] = {
1211     { .compatible = "cirrus,cs42l52", },
1212     {},
1213 };
1214 MODULE_DEVICE_TABLE(of, cs42l52_of_match);
1215 
1216 
1217 static const struct i2c_device_id cs42l52_id[] = {
1218     { "cs42l52", 0 },
1219     { }
1220 };
1221 MODULE_DEVICE_TABLE(i2c, cs42l52_id);
1222 
1223 static struct i2c_driver cs42l52_i2c_driver = {
1224     .driver = {
1225         .name = "cs42l52",
1226         .of_match_table = cs42l52_of_match,
1227     },
1228     .id_table = cs42l52_id,
1229     .probe_new = cs42l52_i2c_probe,
1230 };
1231 
1232 module_i2c_driver(cs42l52_i2c_driver);
1233 
1234 MODULE_DESCRIPTION("ASoC CS42L52 driver");
1235 MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>");
1236 MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1237 MODULE_LICENSE("GPL");