Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * cs42l56.c -- CS42L56 ALSA SoC audio driver
0004  *
0005  * Copyright 2014 CirrusLogic, Inc.
0006  *
0007  * Author: Brian Austin <brian.austin@cirrus.com>
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/moduleparam.h>
0012 #include <linux/kernel.h>
0013 #include <linux/init.h>
0014 #include <linux/delay.h>
0015 #include <linux/pm.h>
0016 #include <linux/i2c.h>
0017 #include <linux/input.h>
0018 #include <linux/regmap.h>
0019 #include <linux/slab.h>
0020 #include <linux/workqueue.h>
0021 #include <linux/platform_device.h>
0022 #include <linux/regulator/consumer.h>
0023 #include <linux/of_device.h>
0024 #include <linux/of_gpio.h>
0025 #include <sound/core.h>
0026 #include <sound/pcm.h>
0027 #include <sound/pcm_params.h>
0028 #include <sound/soc.h>
0029 #include <sound/soc-dapm.h>
0030 #include <sound/initval.h>
0031 #include <sound/tlv.h>
0032 #include <sound/cs42l56.h>
0033 #include "cs42l56.h"
0034 
0035 #define CS42L56_NUM_SUPPLIES 3
0036 static const char *const cs42l56_supply_names[CS42L56_NUM_SUPPLIES] = {
0037     "VA",
0038     "VCP",
0039     "VLDO",
0040 };
0041 
0042 struct  cs42l56_private {
0043     struct regmap *regmap;
0044     struct snd_soc_component *component;
0045     struct device *dev;
0046     struct cs42l56_platform_data pdata;
0047     struct regulator_bulk_data supplies[CS42L56_NUM_SUPPLIES];
0048     u32 mclk;
0049     u8 mclk_prediv;
0050     u8 mclk_div2;
0051     u8 mclk_ratio;
0052     u8 iface;
0053     u8 iface_fmt;
0054     u8 iface_inv;
0055 #if IS_ENABLED(CONFIG_INPUT)
0056     struct input_dev *beep;
0057     struct work_struct beep_work;
0058     int beep_rate;
0059 #endif
0060 };
0061 
0062 static const struct reg_default cs42l56_reg_defaults[] = {
0063     { 3, 0x7f },    /* r03  - Power Ctl 1 */
0064     { 4, 0xff },    /* r04  - Power Ctl 2 */
0065     { 5, 0x00 },    /* ro5  - Clocking Ctl 1 */
0066     { 6, 0x0b },    /* r06  - Clocking Ctl 2 */
0067     { 7, 0x00 },    /* r07  - Serial Format */
0068     { 8, 0x05 },    /* r08  - Class H Ctl */
0069     { 9, 0x0c },    /* r09  - Misc Ctl */
0070     { 10, 0x80 },   /* r0a  - INT Status */
0071     { 11, 0x00 },   /* r0b  - Playback Ctl */
0072     { 12, 0x0c },   /* r0c  - DSP Mute Ctl */
0073     { 13, 0x00 },   /* r0d  - ADCA Mixer Volume */
0074     { 14, 0x00 },   /* r0e  - ADCB Mixer Volume */
0075     { 15, 0x00 },   /* r0f  - PCMA Mixer Volume */
0076     { 16, 0x00 },   /* r10  - PCMB Mixer Volume */
0077     { 17, 0x00 },   /* r11  - Analog Input Advisory Volume */
0078     { 18, 0x00 },   /* r12  - Digital Input Advisory Volume */
0079     { 19, 0x00 },   /* r13  - Master A Volume */
0080     { 20, 0x00 },   /* r14  - Master B Volume */
0081     { 21, 0x00 },   /* r15  - Beep Freq / On Time */
0082     { 22, 0x00 },   /* r16  - Beep Volume / Off Time */
0083     { 23, 0x00 },   /* r17  - Beep Tone Ctl */
0084     { 24, 0x88 },   /* r18  - Tone Ctl */
0085     { 25, 0x00 },   /* r19  - Channel Mixer & Swap */
0086     { 26, 0x00 },   /* r1a  - AIN Ref Config / ADC Mux */
0087     { 27, 0xa0 },   /* r1b  - High-Pass Filter Ctl */
0088     { 28, 0x00 },   /* r1c  - Misc ADC Ctl */
0089     { 29, 0x00 },   /* r1d  - Gain & Bias Ctl */
0090     { 30, 0x00 },   /* r1e  - PGAA Mux & Volume */
0091     { 31, 0x00 },   /* r1f  - PGAB Mux & Volume */
0092     { 32, 0x00 },   /* r20  - ADCA Attenuator */
0093     { 33, 0x00 },   /* r21  - ADCB Attenuator */
0094     { 34, 0x00 },   /* r22  - ALC Enable & Attack Rate */
0095     { 35, 0xbf },   /* r23  - ALC Release Rate */
0096     { 36, 0x00 },   /* r24  - ALC Threshold */
0097     { 37, 0x00 },   /* r25  - Noise Gate Ctl */
0098     { 38, 0x00 },   /* r26  - ALC, Limiter, SFT, ZeroCross */
0099     { 39, 0x00 },   /* r27  - Analog Mute, LO & HP Mux */
0100     { 40, 0x00 },   /* r28  - HP A Volume */
0101     { 41, 0x00 },   /* r29  - HP B Volume */
0102     { 42, 0x00 },   /* r2a  - LINEOUT A Volume */
0103     { 43, 0x00 },   /* r2b  - LINEOUT B Volume */
0104     { 44, 0x00 },   /* r2c  - Limit Threshold Ctl */
0105     { 45, 0x7f },   /* r2d  - Limiter Ctl & Release Rate */
0106     { 46, 0x00 },   /* r2e  - Limiter Attack Rate */
0107 };
0108 
0109 static bool cs42l56_readable_register(struct device *dev, unsigned int reg)
0110 {
0111     switch (reg) {
0112     case CS42L56_CHIP_ID_1 ... CS42L56_LIM_ATTACK_RATE:
0113         return true;
0114     default:
0115         return false;
0116     }
0117 }
0118 
0119 static bool cs42l56_volatile_register(struct device *dev, unsigned int reg)
0120 {
0121     switch (reg) {
0122     case CS42L56_INT_STATUS:
0123         return true;
0124     default:
0125         return false;
0126     }
0127 }
0128 
0129 static DECLARE_TLV_DB_SCALE(beep_tlv, -5000, 200, 0);
0130 static DECLARE_TLV_DB_SCALE(hl_tlv, -6000, 50, 0);
0131 static DECLARE_TLV_DB_SCALE(adv_tlv, -10200, 50, 0);
0132 static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, 0);
0133 static DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
0134 static DECLARE_TLV_DB_SCALE(preamp_tlv, 0, 1000, 0);
0135 static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
0136 
0137 static const DECLARE_TLV_DB_RANGE(ngnb_tlv,
0138     0, 1, TLV_DB_SCALE_ITEM(-8200, 600, 0),
0139     2, 5, TLV_DB_SCALE_ITEM(-7600, 300, 0)
0140 );
0141 static const DECLARE_TLV_DB_RANGE(ngb_tlv,
0142     0, 2, TLV_DB_SCALE_ITEM(-6400, 600, 0),
0143     3, 7, TLV_DB_SCALE_ITEM(-4600, 300, 0)
0144 );
0145 static const DECLARE_TLV_DB_RANGE(alc_tlv,
0146     0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
0147     3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0)
0148 );
0149 
0150 static const char * const beep_config_text[] = {
0151     "Off", "Single", "Multiple", "Continuous"
0152 };
0153 
0154 static const struct soc_enum beep_config_enum =
0155     SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 6,
0156             ARRAY_SIZE(beep_config_text), beep_config_text);
0157 
0158 static const char * const beep_pitch_text[] = {
0159     "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
0160     "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
0161 };
0162 
0163 static const struct soc_enum beep_pitch_enum =
0164     SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 4,
0165             ARRAY_SIZE(beep_pitch_text), beep_pitch_text);
0166 
0167 static const char * const beep_ontime_text[] = {
0168     "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s",
0169     "1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s",
0170     "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s"
0171 };
0172 
0173 static const struct soc_enum beep_ontime_enum =
0174     SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 0,
0175             ARRAY_SIZE(beep_ontime_text), beep_ontime_text);
0176 
0177 static const char * const beep_offtime_text[] = {
0178     "1.23 s", "2.58 s", "3.90 s", "5.20 s",
0179     "6.60 s", "8.05 s", "9.35 s", "10.80 s"
0180 };
0181 
0182 static const struct soc_enum beep_offtime_enum =
0183     SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_OFFTIME, 5,
0184             ARRAY_SIZE(beep_offtime_text), beep_offtime_text);
0185 
0186 static const char * const beep_treble_text[] = {
0187     "5kHz", "7kHz", "10kHz", "15kHz"
0188 };
0189 
0190 static const struct soc_enum beep_treble_enum =
0191     SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 3,
0192             ARRAY_SIZE(beep_treble_text), beep_treble_text);
0193 
0194 static const char * const beep_bass_text[] = {
0195     "50Hz", "100Hz", "200Hz", "250Hz"
0196 };
0197 
0198 static const struct soc_enum beep_bass_enum =
0199     SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1,
0200             ARRAY_SIZE(beep_bass_text), beep_bass_text);
0201 
0202 static const char * const pgaa_mux_text[] = {
0203     "AIN1A", "AIN2A", "AIN3A"};
0204 
0205 static const struct soc_enum pgaa_mux_enum =
0206     SOC_ENUM_SINGLE(CS42L56_PGAA_MUX_VOLUME, 0,
0207                   ARRAY_SIZE(pgaa_mux_text),
0208                   pgaa_mux_text);
0209 
0210 static const struct snd_kcontrol_new pgaa_mux =
0211     SOC_DAPM_ENUM("Route", pgaa_mux_enum);
0212 
0213 static const char * const pgab_mux_text[] = {
0214     "AIN1B", "AIN2B", "AIN3B"};
0215 
0216 static const struct soc_enum pgab_mux_enum =
0217     SOC_ENUM_SINGLE(CS42L56_PGAB_MUX_VOLUME, 0,
0218                   ARRAY_SIZE(pgab_mux_text),
0219                   pgab_mux_text);
0220 
0221 static const struct snd_kcontrol_new pgab_mux =
0222     SOC_DAPM_ENUM("Route", pgab_mux_enum);
0223 
0224 static const char * const adca_mux_text[] = {
0225     "PGAA", "AIN1A", "AIN2A", "AIN3A"};
0226 
0227 static const struct soc_enum adca_mux_enum =
0228     SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 0,
0229                   ARRAY_SIZE(adca_mux_text),
0230                   adca_mux_text);
0231 
0232 static const struct snd_kcontrol_new adca_mux =
0233     SOC_DAPM_ENUM("Route", adca_mux_enum);
0234 
0235 static const char * const adcb_mux_text[] = {
0236     "PGAB", "AIN1B", "AIN2B", "AIN3B"};
0237 
0238 static const struct soc_enum adcb_mux_enum =
0239     SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 2,
0240                   ARRAY_SIZE(adcb_mux_text),
0241                   adcb_mux_text);
0242 
0243 static const struct snd_kcontrol_new adcb_mux =
0244     SOC_DAPM_ENUM("Route", adcb_mux_enum);
0245 
0246 static const char * const left_swap_text[] = {
0247     "Left", "LR 2", "Right"};
0248 
0249 static const char * const right_swap_text[] = {
0250     "Right", "LR 2", "Left"};
0251 
0252 static const unsigned int swap_values[] = { 0, 1, 3 };
0253 
0254 static const struct soc_enum adca_swap_enum =
0255     SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 0, 3,
0256                   ARRAY_SIZE(left_swap_text),
0257                   left_swap_text,
0258                   swap_values);
0259 static const struct snd_kcontrol_new adca_swap_mux =
0260     SOC_DAPM_ENUM("Route", adca_swap_enum);
0261 
0262 static const struct soc_enum pcma_swap_enum =
0263     SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 4, 3,
0264                   ARRAY_SIZE(left_swap_text),
0265                   left_swap_text,
0266                   swap_values);
0267 static const struct snd_kcontrol_new pcma_swap_mux =
0268     SOC_DAPM_ENUM("Route", pcma_swap_enum);
0269 
0270 static const struct soc_enum adcb_swap_enum =
0271     SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 2, 3,
0272                   ARRAY_SIZE(right_swap_text),
0273                   right_swap_text,
0274                   swap_values);
0275 static const struct snd_kcontrol_new adcb_swap_mux =
0276     SOC_DAPM_ENUM("Route", adcb_swap_enum);
0277 
0278 static const struct soc_enum pcmb_swap_enum =
0279     SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 6, 3,
0280                   ARRAY_SIZE(right_swap_text),
0281                   right_swap_text,
0282                   swap_values);
0283 static const struct snd_kcontrol_new pcmb_swap_mux =
0284     SOC_DAPM_ENUM("Route", pcmb_swap_enum);
0285 
0286 static const struct snd_kcontrol_new hpa_switch =
0287     SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 6, 1, 1);
0288 
0289 static const struct snd_kcontrol_new hpb_switch =
0290     SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 4, 1, 1);
0291 
0292 static const struct snd_kcontrol_new loa_switch =
0293     SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 2, 1, 1);
0294 
0295 static const struct snd_kcontrol_new lob_switch =
0296     SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 0, 1, 1);
0297 
0298 static const char * const hploa_input_text[] = {
0299     "DACA", "PGAA"};
0300 
0301 static const struct soc_enum lineouta_input_enum =
0302     SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 2,
0303                   ARRAY_SIZE(hploa_input_text),
0304                   hploa_input_text);
0305 
0306 static const struct snd_kcontrol_new lineouta_input =
0307     SOC_DAPM_ENUM("Route", lineouta_input_enum);
0308 
0309 static const struct soc_enum hpa_input_enum =
0310     SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 0,
0311                   ARRAY_SIZE(hploa_input_text),
0312                   hploa_input_text);
0313 
0314 static const struct snd_kcontrol_new hpa_input =
0315     SOC_DAPM_ENUM("Route", hpa_input_enum);
0316 
0317 static const char * const hplob_input_text[] = {
0318     "DACB", "PGAB"};
0319 
0320 static const struct soc_enum lineoutb_input_enum =
0321     SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 3,
0322                   ARRAY_SIZE(hplob_input_text),
0323                   hplob_input_text);
0324 
0325 static const struct snd_kcontrol_new lineoutb_input =
0326     SOC_DAPM_ENUM("Route", lineoutb_input_enum);
0327 
0328 static const struct soc_enum hpb_input_enum =
0329     SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 1,
0330                   ARRAY_SIZE(hplob_input_text),
0331                   hplob_input_text);
0332 
0333 static const struct snd_kcontrol_new hpb_input =
0334     SOC_DAPM_ENUM("Route", hpb_input_enum);
0335 
0336 static const char * const dig_mux_text[] = {
0337     "ADC", "DSP"};
0338 
0339 static const struct soc_enum dig_mux_enum =
0340     SOC_ENUM_SINGLE(CS42L56_MISC_CTL, 7,
0341                   ARRAY_SIZE(dig_mux_text),
0342                   dig_mux_text);
0343 
0344 static const struct snd_kcontrol_new dig_mux =
0345     SOC_DAPM_ENUM("Route", dig_mux_enum);
0346 
0347 static const char * const hpf_freq_text[] = {
0348     "1.8Hz", "119Hz", "236Hz", "464Hz"
0349 };
0350 
0351 static const struct soc_enum hpfa_freq_enum =
0352     SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 0,
0353             ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
0354 
0355 static const struct soc_enum hpfb_freq_enum =
0356     SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 2,
0357             ARRAY_SIZE(hpf_freq_text), hpf_freq_text);
0358 
0359 static const char * const ng_delay_text[] = {
0360     "50ms", "100ms", "150ms", "200ms"
0361 };
0362 
0363 static const struct soc_enum ng_delay_enum =
0364     SOC_ENUM_SINGLE(CS42L56_NOISE_GATE_CTL, 0,
0365             ARRAY_SIZE(ng_delay_text), ng_delay_text);
0366 
0367 static const struct snd_kcontrol_new cs42l56_snd_controls[] = {
0368 
0369     SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L56_MASTER_A_VOLUME,
0370                   CS42L56_MASTER_B_VOLUME, 0, 0x34, 0xE4, adv_tlv),
0371     SOC_DOUBLE("Master Mute Switch", CS42L56_DSP_MUTE_CTL, 0, 1, 1, 1),
0372 
0373     SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", CS42L56_ADCA_MIX_VOLUME,
0374                   CS42L56_ADCB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
0375     SOC_DOUBLE("ADC Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 6, 7, 1, 1),
0376 
0377     SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume", CS42L56_PCMA_MIX_VOLUME,
0378                   CS42L56_PCMB_MIX_VOLUME, 0, 0x88, 0x90, hl_tlv),
0379     SOC_DOUBLE("PCM Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 4, 5, 1, 1),
0380 
0381     SOC_SINGLE_TLV("Analog Advisory Volume",
0382               CS42L56_ANAINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv),
0383     SOC_SINGLE_TLV("Digital Advisory Volume",
0384               CS42L56_DIGINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv),
0385 
0386     SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L56_PGAA_MUX_VOLUME,
0387                   CS42L56_PGAB_MUX_VOLUME, 0, 0x34, 0x24, pga_tlv),
0388     SOC_DOUBLE_R_TLV("ADC Volume", CS42L56_ADCA_ATTENUATOR,
0389                   CS42L56_ADCB_ATTENUATOR, 0, 0x00, 1, adc_tlv),
0390     SOC_DOUBLE("ADC Mute Switch", CS42L56_MISC_ADC_CTL, 2, 3, 1, 1),
0391     SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1),
0392 
0393     SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME,
0394                   CS42L56_HPB_VOLUME, 0, 0x44, 0x48, hl_tlv),
0395     SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME,
0396                   CS42L56_LOB_VOLUME, 0, 0x44, 0x48, hl_tlv),
0397 
0398     SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL,
0399             0, 0x00, 1, tone_tlv),
0400     SOC_SINGLE_TLV("Treble Shelving Volume", CS42L56_TONE_CTL,
0401             4, 0x00, 1, tone_tlv),
0402 
0403     SOC_DOUBLE_TLV("PGA Preamp Volume", CS42L56_GAIN_BIAS_CTL,
0404             4, 6, 0x02, 1, preamp_tlv),
0405 
0406     SOC_SINGLE("DSP Switch", CS42L56_PLAYBACK_CTL, 7, 1, 1),
0407     SOC_SINGLE("Gang Playback Switch", CS42L56_PLAYBACK_CTL, 4, 1, 1),
0408     SOC_SINGLE("Gang ADC Switch", CS42L56_MISC_ADC_CTL, 7, 1, 1),
0409     SOC_SINGLE("Gang PGA Switch", CS42L56_MISC_ADC_CTL, 6, 1, 1),
0410 
0411     SOC_SINGLE("PCMA Invert", CS42L56_PLAYBACK_CTL, 2, 1, 1),
0412     SOC_SINGLE("PCMB Invert", CS42L56_PLAYBACK_CTL, 3, 1, 1),
0413     SOC_SINGLE("ADCA Invert", CS42L56_MISC_ADC_CTL, 2, 1, 1),
0414     SOC_SINGLE("ADCB Invert", CS42L56_MISC_ADC_CTL, 3, 1, 1),
0415 
0416     SOC_DOUBLE("HPF Switch", CS42L56_HPF_CTL, 5, 7, 1, 1),
0417     SOC_DOUBLE("HPF Freeze Switch", CS42L56_HPF_CTL, 4, 6, 1, 1),
0418     SOC_ENUM("HPFA Corner Freq", hpfa_freq_enum),
0419     SOC_ENUM("HPFB Corner Freq", hpfb_freq_enum),
0420 
0421     SOC_SINGLE("Analog Soft Ramp", CS42L56_MISC_CTL, 4, 1, 1),
0422     SOC_DOUBLE("Analog Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC,
0423         7, 5, 1, 1),
0424     SOC_SINGLE("Analog Zero Cross", CS42L56_MISC_CTL, 3, 1, 1),
0425     SOC_DOUBLE("Analog Zero Cross Disable", CS42L56_ALC_LIM_SFT_ZC,
0426         6, 4, 1, 1),
0427     SOC_SINGLE("Digital Soft Ramp", CS42L56_MISC_CTL, 2, 1, 1),
0428     SOC_SINGLE("Digital Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC,
0429         3, 1, 1),
0430 
0431     SOC_SINGLE("HL Deemphasis", CS42L56_PLAYBACK_CTL, 6, 1, 1),
0432 
0433     SOC_SINGLE("ALC Switch", CS42L56_ALC_EN_ATTACK_RATE, 6, 1, 1),
0434     SOC_SINGLE("ALC Limit All Switch", CS42L56_ALC_RELEASE_RATE, 7, 1, 1),
0435     SOC_SINGLE_RANGE("ALC Attack", CS42L56_ALC_EN_ATTACK_RATE,
0436             0, 0, 0x3f, 0),
0437     SOC_SINGLE_RANGE("ALC Release", CS42L56_ALC_RELEASE_RATE,
0438             0, 0x3f, 0, 0),
0439     SOC_SINGLE_TLV("ALC MAX", CS42L56_ALC_THRESHOLD,
0440             5, 0x07, 1, alc_tlv),
0441     SOC_SINGLE_TLV("ALC MIN", CS42L56_ALC_THRESHOLD,
0442             2, 0x07, 1, alc_tlv),
0443 
0444     SOC_SINGLE("Limiter Switch", CS42L56_LIM_CTL_RELEASE_RATE, 7, 1, 1),
0445     SOC_SINGLE("Limit All Switch", CS42L56_LIM_CTL_RELEASE_RATE, 6, 1, 1),
0446     SOC_SINGLE_RANGE("Limiter Attack", CS42L56_LIM_ATTACK_RATE,
0447             0, 0, 0x3f, 0),
0448     SOC_SINGLE_RANGE("Limiter Release", CS42L56_LIM_CTL_RELEASE_RATE,
0449             0, 0x3f, 0, 0),
0450     SOC_SINGLE_TLV("Limiter MAX", CS42L56_LIM_THRESHOLD_CTL,
0451             5, 0x07, 1, alc_tlv),
0452     SOC_SINGLE_TLV("Limiter Cushion", CS42L56_ALC_THRESHOLD,
0453             2, 0x07, 1, alc_tlv),
0454 
0455     SOC_SINGLE("NG Switch", CS42L56_NOISE_GATE_CTL, 6, 1, 1),
0456     SOC_SINGLE("NG All Switch", CS42L56_NOISE_GATE_CTL, 7, 1, 1),
0457     SOC_SINGLE("NG Boost Switch", CS42L56_NOISE_GATE_CTL, 5, 1, 1),
0458     SOC_SINGLE_TLV("NG Unboost Threshold", CS42L56_NOISE_GATE_CTL,
0459             2, 0x07, 1, ngnb_tlv),
0460     SOC_SINGLE_TLV("NG Boost Threshold", CS42L56_NOISE_GATE_CTL,
0461             2, 0x07, 1, ngb_tlv),
0462     SOC_ENUM("NG Delay", ng_delay_enum),
0463 
0464     SOC_ENUM("Beep Config", beep_config_enum),
0465     SOC_ENUM("Beep Pitch", beep_pitch_enum),
0466     SOC_ENUM("Beep on Time", beep_ontime_enum),
0467     SOC_ENUM("Beep off Time", beep_offtime_enum),
0468     SOC_SINGLE_SX_TLV("Beep Volume", CS42L56_BEEP_FREQ_OFFTIME,
0469             0, 0x07, 0x23, beep_tlv),
0470     SOC_SINGLE("Beep Tone Ctl Switch", CS42L56_BEEP_TONE_CFG, 0, 1, 1),
0471     SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum),
0472     SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum),
0473 
0474 };
0475 
0476 static const struct snd_soc_dapm_widget cs42l56_dapm_widgets[] = {
0477 
0478     SND_SOC_DAPM_SIGGEN("Beep"),
0479     SND_SOC_DAPM_SUPPLY("VBUF", CS42L56_PWRCTL_1, 5, 1, NULL, 0),
0480     SND_SOC_DAPM_MICBIAS("MIC1 Bias", CS42L56_PWRCTL_1, 4, 1),
0481     SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L56_PWRCTL_1, 3, 1, NULL, 0),
0482 
0483     SND_SOC_DAPM_INPUT("AIN1A"),
0484     SND_SOC_DAPM_INPUT("AIN2A"),
0485     SND_SOC_DAPM_INPUT("AIN1B"),
0486     SND_SOC_DAPM_INPUT("AIN2B"),
0487     SND_SOC_DAPM_INPUT("AIN3A"),
0488     SND_SOC_DAPM_INPUT("AIN3B"),
0489 
0490     SND_SOC_DAPM_AIF_OUT("SDOUT", NULL,  0,
0491             SND_SOC_NOPM, 0, 0),
0492 
0493     SND_SOC_DAPM_AIF_IN("SDIN", NULL,  0,
0494             SND_SOC_NOPM, 0, 0),
0495 
0496     SND_SOC_DAPM_MUX("Digital Output Mux", SND_SOC_NOPM,
0497              0, 0, &dig_mux),
0498 
0499     SND_SOC_DAPM_PGA("PGAA", SND_SOC_NOPM, 0, 0, NULL, 0),
0500     SND_SOC_DAPM_PGA("PGAB", SND_SOC_NOPM, 0, 0, NULL, 0),
0501     SND_SOC_DAPM_MUX("PGAA Input Mux",
0502             SND_SOC_NOPM, 0, 0, &pgaa_mux),
0503     SND_SOC_DAPM_MUX("PGAB Input Mux",
0504             SND_SOC_NOPM, 0, 0, &pgab_mux),
0505 
0506     SND_SOC_DAPM_MUX("ADCA Mux", SND_SOC_NOPM,
0507              0, 0, &adca_mux),
0508     SND_SOC_DAPM_MUX("ADCB Mux", SND_SOC_NOPM,
0509              0, 0, &adcb_mux),
0510 
0511     SND_SOC_DAPM_ADC("ADCA", NULL, CS42L56_PWRCTL_1, 1, 1),
0512     SND_SOC_DAPM_ADC("ADCB", NULL, CS42L56_PWRCTL_1, 2, 1),
0513 
0514     SND_SOC_DAPM_MUX("ADCA Swap Mux", SND_SOC_NOPM, 0, 0,
0515         &adca_swap_mux),
0516     SND_SOC_DAPM_MUX("ADCB Swap Mux", SND_SOC_NOPM, 0, 0,
0517         &adcb_swap_mux),
0518 
0519     SND_SOC_DAPM_MUX("PCMA Swap Mux", SND_SOC_NOPM, 0, 0,
0520         &pcma_swap_mux),
0521     SND_SOC_DAPM_MUX("PCMB Swap Mux", SND_SOC_NOPM, 0, 0,
0522         &pcmb_swap_mux),
0523 
0524     SND_SOC_DAPM_DAC("DACA", NULL, SND_SOC_NOPM, 0, 0),
0525     SND_SOC_DAPM_DAC("DACB", NULL, SND_SOC_NOPM, 0, 0),
0526 
0527     SND_SOC_DAPM_OUTPUT("HPA"),
0528     SND_SOC_DAPM_OUTPUT("LOA"),
0529     SND_SOC_DAPM_OUTPUT("HPB"),
0530     SND_SOC_DAPM_OUTPUT("LOB"),
0531 
0532     SND_SOC_DAPM_SWITCH("Headphone Right",
0533                 CS42L56_PWRCTL_2, 4, 1, &hpb_switch),
0534     SND_SOC_DAPM_SWITCH("Headphone Left",
0535                 CS42L56_PWRCTL_2, 6, 1, &hpa_switch),
0536 
0537     SND_SOC_DAPM_SWITCH("Lineout Right",
0538                 CS42L56_PWRCTL_2, 0, 1, &lob_switch),
0539     SND_SOC_DAPM_SWITCH("Lineout Left",
0540                 CS42L56_PWRCTL_2, 2, 1, &loa_switch),
0541 
0542     SND_SOC_DAPM_MUX("LINEOUTA Input Mux", SND_SOC_NOPM,
0543              0, 0, &lineouta_input),
0544     SND_SOC_DAPM_MUX("LINEOUTB Input Mux", SND_SOC_NOPM,
0545              0, 0, &lineoutb_input),
0546     SND_SOC_DAPM_MUX("HPA Input Mux", SND_SOC_NOPM,
0547              0, 0, &hpa_input),
0548     SND_SOC_DAPM_MUX("HPB Input Mux", SND_SOC_NOPM,
0549              0, 0, &hpb_input),
0550 
0551 };
0552 
0553 static const struct snd_soc_dapm_route cs42l56_audio_map[] = {
0554 
0555     {"HiFi Capture", "DSP", "Digital Output Mux"},
0556     {"HiFi Capture", "ADC", "Digital Output Mux"},
0557 
0558     {"Digital Output Mux", NULL, "ADCA"},
0559     {"Digital Output Mux", NULL, "ADCB"},
0560 
0561     {"ADCB", NULL, "ADCB Swap Mux"},
0562     {"ADCA", NULL, "ADCA Swap Mux"},
0563 
0564     {"ADCA Swap Mux", NULL, "ADCA"},
0565     {"ADCB Swap Mux", NULL, "ADCB"},
0566 
0567     {"DACA", "Left", "ADCA Swap Mux"},
0568     {"DACA", "LR 2", "ADCA Swap Mux"},
0569     {"DACA", "Right", "ADCA Swap Mux"},
0570 
0571     {"DACB", "Left", "ADCB Swap Mux"},
0572     {"DACB", "LR 2", "ADCB Swap Mux"},
0573     {"DACB", "Right", "ADCB Swap Mux"},
0574 
0575     {"ADCA Mux", NULL, "AIN3A"},
0576     {"ADCA Mux", NULL, "AIN2A"},
0577     {"ADCA Mux", NULL, "AIN1A"},
0578     {"ADCA Mux", NULL, "PGAA"},
0579     {"ADCB Mux", NULL, "AIN3B"},
0580     {"ADCB Mux", NULL, "AIN2B"},
0581     {"ADCB Mux", NULL, "AIN1B"},
0582     {"ADCB Mux", NULL, "PGAB"},
0583 
0584     {"PGAA", "AIN1A", "PGAA Input Mux"},
0585     {"PGAA", "AIN2A", "PGAA Input Mux"},
0586     {"PGAA", "AIN3A", "PGAA Input Mux"},
0587     {"PGAB", "AIN1B", "PGAB Input Mux"},
0588     {"PGAB", "AIN2B", "PGAB Input Mux"},
0589     {"PGAB", "AIN3B", "PGAB Input Mux"},
0590 
0591     {"PGAA Input Mux", NULL, "AIN1A"},
0592     {"PGAA Input Mux", NULL, "AIN2A"},
0593     {"PGAA Input Mux", NULL, "AIN3A"},
0594     {"PGAB Input Mux", NULL, "AIN1B"},
0595     {"PGAB Input Mux", NULL, "AIN2B"},
0596     {"PGAB Input Mux", NULL, "AIN3B"},
0597 
0598     {"LOB", "Switch", "LINEOUTB Input Mux"},
0599     {"LOA", "Switch", "LINEOUTA Input Mux"},
0600 
0601     {"LINEOUTA Input Mux", "PGAA", "PGAA"},
0602     {"LINEOUTB Input Mux", "PGAB", "PGAB"},
0603     {"LINEOUTA Input Mux", "DACA", "DACA"},
0604     {"LINEOUTB Input Mux", "DACB", "DACB"},
0605 
0606     {"HPA", "Switch", "HPB Input Mux"},
0607     {"HPB", "Switch", "HPA Input Mux"},
0608 
0609     {"HPA Input Mux", "PGAA", "PGAA"},
0610     {"HPB Input Mux", "PGAB", "PGAB"},
0611     {"HPA Input Mux", "DACA", "DACA"},
0612     {"HPB Input Mux", "DACB", "DACB"},
0613 
0614     {"DACA", NULL, "PCMA Swap Mux"},
0615     {"DACB", NULL, "PCMB Swap Mux"},
0616 
0617     {"PCMB Swap Mux", "Left", "HiFi Playback"},
0618     {"PCMB Swap Mux", "LR 2", "HiFi Playback"},
0619     {"PCMB Swap Mux", "Right", "HiFi Playback"},
0620 
0621     {"PCMA Swap Mux", "Left", "HiFi Playback"},
0622     {"PCMA Swap Mux", "LR 2", "HiFi Playback"},
0623     {"PCMA Swap Mux", "Right", "HiFi Playback"},
0624 
0625 };
0626 
0627 struct cs42l56_clk_para {
0628     u32 mclk;
0629     u32 srate;
0630     u8 ratio;
0631 };
0632 
0633 static const struct cs42l56_clk_para clk_ratio_table[] = {
0634     /* 8k */
0635     { 6000000, 8000, CS42L56_MCLK_LRCLK_768 },
0636     { 6144000, 8000, CS42L56_MCLK_LRCLK_750 },
0637     { 12000000, 8000, CS42L56_MCLK_LRCLK_768 },
0638     { 12288000, 8000, CS42L56_MCLK_LRCLK_750 },
0639     { 24000000, 8000, CS42L56_MCLK_LRCLK_768 },
0640     { 24576000, 8000, CS42L56_MCLK_LRCLK_750 },
0641     /* 11.025k */
0642     { 5644800, 11025, CS42L56_MCLK_LRCLK_512},
0643     { 11289600, 11025, CS42L56_MCLK_LRCLK_512},
0644     { 22579200, 11025, CS42L56_MCLK_LRCLK_512 },
0645     /* 11.0294k */
0646     { 6000000, 110294, CS42L56_MCLK_LRCLK_544 },
0647     { 12000000, 110294, CS42L56_MCLK_LRCLK_544 },
0648     { 24000000, 110294, CS42L56_MCLK_LRCLK_544 },
0649     /* 12k */
0650     { 6000000, 12000, CS42L56_MCLK_LRCLK_500 },
0651     { 6144000, 12000, CS42L56_MCLK_LRCLK_512 },
0652     { 12000000, 12000, CS42L56_MCLK_LRCLK_500 },
0653     { 12288000, 12000, CS42L56_MCLK_LRCLK_512 },
0654     { 24000000, 12000, CS42L56_MCLK_LRCLK_500 },
0655     { 24576000, 12000, CS42L56_MCLK_LRCLK_512 },
0656     /* 16k */
0657     { 6000000, 16000, CS42L56_MCLK_LRCLK_375 },
0658     { 6144000, 16000, CS42L56_MCLK_LRCLK_384 },
0659     { 12000000, 16000, CS42L56_MCLK_LRCLK_375 },
0660     { 12288000, 16000, CS42L56_MCLK_LRCLK_384 },
0661     { 24000000, 16000, CS42L56_MCLK_LRCLK_375 },
0662     { 24576000, 16000, CS42L56_MCLK_LRCLK_384 },
0663     /* 22.050k */
0664     { 5644800, 22050, CS42L56_MCLK_LRCLK_256 },
0665     { 11289600, 22050, CS42L56_MCLK_LRCLK_256 },
0666     { 22579200, 22050, CS42L56_MCLK_LRCLK_256 },
0667     /* 22.0588k */
0668     { 6000000, 220588, CS42L56_MCLK_LRCLK_272 },
0669     { 12000000, 220588, CS42L56_MCLK_LRCLK_272 },
0670     { 24000000, 220588, CS42L56_MCLK_LRCLK_272 },
0671     /* 24k */
0672     { 6000000, 24000, CS42L56_MCLK_LRCLK_250 },
0673     { 6144000, 24000, CS42L56_MCLK_LRCLK_256 },
0674     { 12000000, 24000, CS42L56_MCLK_LRCLK_250 },
0675     { 12288000, 24000, CS42L56_MCLK_LRCLK_256 },
0676     { 24000000, 24000, CS42L56_MCLK_LRCLK_250 },
0677     { 24576000, 24000, CS42L56_MCLK_LRCLK_256 },
0678     /* 32k */
0679     { 6000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
0680     { 6144000, 32000, CS42L56_MCLK_LRCLK_192 },
0681     { 12000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
0682     { 12288000, 32000, CS42L56_MCLK_LRCLK_192 },
0683     { 24000000, 32000, CS42L56_MCLK_LRCLK_187P5 },
0684     { 24576000, 32000, CS42L56_MCLK_LRCLK_192 },
0685     /* 44.118k */
0686     { 6000000, 44118, CS42L56_MCLK_LRCLK_136 },
0687     { 12000000, 44118, CS42L56_MCLK_LRCLK_136 },
0688     { 24000000, 44118, CS42L56_MCLK_LRCLK_136 },
0689     /* 44.1k */
0690     { 5644800, 44100, CS42L56_MCLK_LRCLK_128 },
0691     { 11289600, 44100, CS42L56_MCLK_LRCLK_128 },
0692     { 22579200, 44100, CS42L56_MCLK_LRCLK_128 },
0693     /* 48k */
0694     { 6000000, 48000, CS42L56_MCLK_LRCLK_125 },
0695     { 6144000, 48000, CS42L56_MCLK_LRCLK_128 },
0696     { 12000000, 48000, CS42L56_MCLK_LRCLK_125 },
0697     { 12288000, 48000, CS42L56_MCLK_LRCLK_128 },
0698     { 24000000, 48000, CS42L56_MCLK_LRCLK_125 },
0699     { 24576000, 48000, CS42L56_MCLK_LRCLK_128 },
0700 };
0701 
0702 static int cs42l56_get_mclk_ratio(int mclk, int rate)
0703 {
0704     int i;
0705 
0706     for (i = 0; i < ARRAY_SIZE(clk_ratio_table); i++) {
0707         if (clk_ratio_table[i].mclk == mclk &&
0708             clk_ratio_table[i].srate == rate)
0709             return clk_ratio_table[i].ratio;
0710     }
0711     return -EINVAL;
0712 }
0713 
0714 static int cs42l56_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 cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
0719 
0720     switch (freq) {
0721     case CS42L56_MCLK_5P6448MHZ:
0722     case CS42L56_MCLK_6MHZ:
0723     case CS42L56_MCLK_6P144MHZ:
0724         cs42l56->mclk_div2 = 0;
0725         cs42l56->mclk_prediv = 0;
0726         break;
0727     case CS42L56_MCLK_11P2896MHZ:
0728     case CS42L56_MCLK_12MHZ:
0729     case CS42L56_MCLK_12P288MHZ:
0730         cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
0731         cs42l56->mclk_prediv = 0;
0732         break;
0733     case CS42L56_MCLK_22P5792MHZ:
0734     case CS42L56_MCLK_24MHZ:
0735     case CS42L56_MCLK_24P576MHZ:
0736         cs42l56->mclk_div2 = CS42L56_MCLK_DIV2;
0737         cs42l56->mclk_prediv = CS42L56_MCLK_PREDIV;
0738         break;
0739     default:
0740         return -EINVAL;
0741     }
0742     cs42l56->mclk = freq;
0743 
0744     snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
0745                 CS42L56_MCLK_PREDIV_MASK,
0746                 cs42l56->mclk_prediv);
0747     snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
0748                 CS42L56_MCLK_DIV2_MASK,
0749                 cs42l56->mclk_div2);
0750 
0751     return 0;
0752 }
0753 
0754 static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
0755 {
0756     struct snd_soc_component *component = codec_dai->component;
0757     struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
0758 
0759     switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
0760     case SND_SOC_DAIFMT_CBM_CFM:
0761         cs42l56->iface = CS42L56_MASTER_MODE;
0762         break;
0763     case SND_SOC_DAIFMT_CBS_CFS:
0764         cs42l56->iface = CS42L56_SLAVE_MODE;
0765         break;
0766     default:
0767         return -EINVAL;
0768     }
0769 
0770      /* interface format */
0771     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0772     case SND_SOC_DAIFMT_I2S:
0773         cs42l56->iface_fmt = CS42L56_DIG_FMT_I2S;
0774         break;
0775     case SND_SOC_DAIFMT_LEFT_J:
0776         cs42l56->iface_fmt = CS42L56_DIG_FMT_LEFT_J;
0777         break;
0778     default:
0779         return -EINVAL;
0780     }
0781 
0782     /* sclk inversion */
0783     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0784     case SND_SOC_DAIFMT_NB_NF:
0785         cs42l56->iface_inv = 0;
0786         break;
0787     case SND_SOC_DAIFMT_IB_NF:
0788         cs42l56->iface_inv = CS42L56_SCLK_INV;
0789         break;
0790     default:
0791         return -EINVAL;
0792     }
0793 
0794     snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
0795                 CS42L56_MS_MODE_MASK, cs42l56->iface);
0796     snd_soc_component_update_bits(component, CS42L56_SERIAL_FMT,
0797                 CS42L56_DIG_FMT_MASK, cs42l56->iface_fmt);
0798     snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
0799                 CS42L56_SCLK_INV_MASK, cs42l56->iface_inv);
0800     return 0;
0801 }
0802 
0803 static int cs42l56_mute(struct snd_soc_dai *dai, int mute, int direction)
0804 {
0805     struct snd_soc_component *component = dai->component;
0806 
0807     if (mute) {
0808         /* Hit the DSP Mixer first */
0809         snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
0810                     CS42L56_ADCAMIX_MUTE_MASK |
0811                     CS42L56_ADCBMIX_MUTE_MASK |
0812                     CS42L56_PCMAMIX_MUTE_MASK |
0813                     CS42L56_PCMBMIX_MUTE_MASK |
0814                     CS42L56_MSTB_MUTE_MASK |
0815                     CS42L56_MSTA_MUTE_MASK,
0816                     CS42L56_MUTE_ALL);
0817         /* Mute ADC's */
0818         snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
0819                     CS42L56_ADCA_MUTE_MASK |
0820                     CS42L56_ADCB_MUTE_MASK,
0821                     CS42L56_MUTE_ALL);
0822         /* HP And LO */
0823         snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
0824                     CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
0825         snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
0826                     CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
0827         snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
0828                     CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
0829         snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
0830                     CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
0831     } else {
0832         snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
0833                     CS42L56_ADCAMIX_MUTE_MASK |
0834                     CS42L56_ADCBMIX_MUTE_MASK |
0835                     CS42L56_PCMAMIX_MUTE_MASK |
0836                     CS42L56_PCMBMIX_MUTE_MASK |
0837                     CS42L56_MSTB_MUTE_MASK |
0838                     CS42L56_MSTA_MUTE_MASK,
0839                     CS42L56_UNMUTE);
0840 
0841         snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
0842                     CS42L56_ADCA_MUTE_MASK |
0843                     CS42L56_ADCB_MUTE_MASK,
0844                     CS42L56_UNMUTE);
0845 
0846         snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
0847                     CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
0848         snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
0849                     CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
0850         snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
0851                     CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
0852         snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
0853                     CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
0854     }
0855     return 0;
0856 }
0857 
0858 static int cs42l56_pcm_hw_params(struct snd_pcm_substream *substream,
0859                      struct snd_pcm_hw_params *params,
0860                      struct snd_soc_dai *dai)
0861 {
0862     struct snd_soc_component *component = dai->component;
0863     struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
0864     int ratio;
0865 
0866     ratio = cs42l56_get_mclk_ratio(cs42l56->mclk, params_rate(params));
0867     if (ratio >= 0) {
0868         snd_soc_component_update_bits(component, CS42L56_CLKCTL_2,
0869                     CS42L56_CLK_RATIO_MASK, ratio);
0870     } else {
0871         dev_err(component->dev, "unsupported mclk/sclk/lrclk ratio\n");
0872         return -EINVAL;
0873     }
0874 
0875     return 0;
0876 }
0877 
0878 static int cs42l56_set_bias_level(struct snd_soc_component *component,
0879                     enum snd_soc_bias_level level)
0880 {
0881     struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
0882     int ret;
0883 
0884     switch (level) {
0885     case SND_SOC_BIAS_ON:
0886         break;
0887     case SND_SOC_BIAS_PREPARE:
0888         snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
0889                     CS42L56_MCLK_DIS_MASK, 0);
0890         snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
0891                     CS42L56_PDN_ALL_MASK, 0);
0892         break;
0893     case SND_SOC_BIAS_STANDBY:
0894         if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
0895             regcache_cache_only(cs42l56->regmap, false);
0896             regcache_sync(cs42l56->regmap);
0897             ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
0898                             cs42l56->supplies);
0899             if (ret != 0) {
0900                 dev_err(cs42l56->dev,
0901                     "Failed to enable regulators: %d\n",
0902                     ret);
0903                 return ret;
0904             }
0905         }
0906         snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
0907                     CS42L56_PDN_ALL_MASK, 1);
0908         break;
0909     case SND_SOC_BIAS_OFF:
0910         snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
0911                     CS42L56_PDN_ALL_MASK, 1);
0912         snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
0913                     CS42L56_MCLK_DIS_MASK, 1);
0914         regcache_cache_only(cs42l56->regmap, true);
0915         regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
0916                             cs42l56->supplies);
0917         break;
0918     }
0919 
0920     return 0;
0921 }
0922 
0923 #define CS42L56_RATES (SNDRV_PCM_RATE_8000_48000)
0924 
0925 #define CS42L56_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \
0926             SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE | \
0927             SNDRV_PCM_FMTBIT_S32_LE)
0928 
0929 
0930 static const struct snd_soc_dai_ops cs42l56_ops = {
0931     .hw_params  = cs42l56_pcm_hw_params,
0932     .mute_stream    = cs42l56_mute,
0933     .set_fmt    = cs42l56_set_dai_fmt,
0934     .set_sysclk = cs42l56_set_sysclk,
0935     .no_capture_mute = 1,
0936 };
0937 
0938 static struct snd_soc_dai_driver cs42l56_dai = {
0939         .name = "cs42l56",
0940         .playback = {
0941             .stream_name = "HiFi Playback",
0942             .channels_min = 1,
0943             .channels_max = 2,
0944             .rates = CS42L56_RATES,
0945             .formats = CS42L56_FORMATS,
0946         },
0947         .capture = {
0948             .stream_name = "HiFi Capture",
0949             .channels_min = 1,
0950             .channels_max = 2,
0951             .rates = CS42L56_RATES,
0952             .formats = CS42L56_FORMATS,
0953         },
0954         .ops = &cs42l56_ops,
0955 };
0956 
0957 static int beep_freq[] = {
0958     261, 522, 585, 667, 706, 774, 889, 1000,
0959     1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
0960 };
0961 
0962 static void cs42l56_beep_work(struct work_struct *work)
0963 {
0964     struct cs42l56_private *cs42l56 =
0965         container_of(work, struct cs42l56_private, beep_work);
0966     struct snd_soc_component *component = cs42l56->component;
0967     struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0968     int i;
0969     int val = 0;
0970     int best = 0;
0971 
0972     if (cs42l56->beep_rate) {
0973         for (i = 0; i < ARRAY_SIZE(beep_freq); i++) {
0974             if (abs(cs42l56->beep_rate - beep_freq[i]) <
0975                 abs(cs42l56->beep_rate - beep_freq[best]))
0976                 best = i;
0977         }
0978 
0979         dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n",
0980             beep_freq[best], cs42l56->beep_rate);
0981 
0982         val = (best << CS42L56_BEEP_RATE_SHIFT);
0983 
0984         snd_soc_dapm_enable_pin(dapm, "Beep");
0985     } else {
0986         dev_dbg(component->dev, "Disabling beep\n");
0987         snd_soc_dapm_disable_pin(dapm, "Beep");
0988     }
0989 
0990     snd_soc_component_update_bits(component, CS42L56_BEEP_FREQ_ONTIME,
0991                 CS42L56_BEEP_FREQ_MASK, val);
0992 
0993     snd_soc_dapm_sync(dapm);
0994 }
0995 
0996 /* For usability define a way of injecting beep events for the device -
0997  * many systems will not have a keyboard.
0998  */
0999 static int cs42l56_beep_event(struct input_dev *dev, unsigned int type,
1000                  unsigned int code, int hz)
1001 {
1002     struct snd_soc_component *component = input_get_drvdata(dev);
1003     struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
1004 
1005     dev_dbg(component->dev, "Beep event %x %x\n", code, hz);
1006 
1007     switch (code) {
1008     case SND_BELL:
1009         if (hz)
1010             hz = 261;
1011         break;
1012     case SND_TONE:
1013         break;
1014     default:
1015         return -1;
1016     }
1017 
1018     /* Kick the beep from a workqueue */
1019     cs42l56->beep_rate = hz;
1020     schedule_work(&cs42l56->beep_work);
1021     return 0;
1022 }
1023 
1024 static ssize_t beep_store(struct device *dev, struct device_attribute *attr,
1025               const char *buf, size_t count)
1026 {
1027     struct cs42l56_private *cs42l56 = dev_get_drvdata(dev);
1028     long int time;
1029     int ret;
1030 
1031     ret = kstrtol(buf, 10, &time);
1032     if (ret != 0)
1033         return ret;
1034 
1035     input_event(cs42l56->beep, EV_SND, SND_TONE, time);
1036 
1037     return count;
1038 }
1039 
1040 static DEVICE_ATTR_WO(beep);
1041 
1042 static void cs42l56_init_beep(struct snd_soc_component *component)
1043 {
1044     struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
1045     int ret;
1046 
1047     cs42l56->beep = devm_input_allocate_device(component->dev);
1048     if (!cs42l56->beep) {
1049         dev_err(component->dev, "Failed to allocate beep device\n");
1050         return;
1051     }
1052 
1053     INIT_WORK(&cs42l56->beep_work, cs42l56_beep_work);
1054     cs42l56->beep_rate = 0;
1055 
1056     cs42l56->beep->name = "CS42L56 Beep Generator";
1057     cs42l56->beep->phys = dev_name(component->dev);
1058     cs42l56->beep->id.bustype = BUS_I2C;
1059 
1060     cs42l56->beep->evbit[0] = BIT_MASK(EV_SND);
1061     cs42l56->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
1062     cs42l56->beep->event = cs42l56_beep_event;
1063     cs42l56->beep->dev.parent = component->dev;
1064     input_set_drvdata(cs42l56->beep, component);
1065 
1066     ret = input_register_device(cs42l56->beep);
1067     if (ret != 0) {
1068         cs42l56->beep = NULL;
1069         dev_err(component->dev, "Failed to register beep device\n");
1070     }
1071 
1072     ret = device_create_file(component->dev, &dev_attr_beep);
1073     if (ret != 0) {
1074         dev_err(component->dev, "Failed to create keyclick file: %d\n",
1075             ret);
1076     }
1077 }
1078 
1079 static void cs42l56_free_beep(struct snd_soc_component *component)
1080 {
1081     struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
1082 
1083     device_remove_file(component->dev, &dev_attr_beep);
1084     cancel_work_sync(&cs42l56->beep_work);
1085     cs42l56->beep = NULL;
1086 
1087     snd_soc_component_update_bits(component, CS42L56_BEEP_TONE_CFG,
1088                 CS42L56_BEEP_EN_MASK, 0);
1089 }
1090 
1091 static int cs42l56_probe(struct snd_soc_component *component)
1092 {
1093     cs42l56_init_beep(component);
1094 
1095     return 0;
1096 }
1097 
1098 static void cs42l56_remove(struct snd_soc_component *component)
1099 {
1100     cs42l56_free_beep(component);
1101 }
1102 
1103 static const struct snd_soc_component_driver soc_component_dev_cs42l56 = {
1104     .probe          = cs42l56_probe,
1105     .remove         = cs42l56_remove,
1106     .set_bias_level     = cs42l56_set_bias_level,
1107     .controls       = cs42l56_snd_controls,
1108     .num_controls       = ARRAY_SIZE(cs42l56_snd_controls),
1109     .dapm_widgets       = cs42l56_dapm_widgets,
1110     .num_dapm_widgets   = ARRAY_SIZE(cs42l56_dapm_widgets),
1111     .dapm_routes        = cs42l56_audio_map,
1112     .num_dapm_routes    = ARRAY_SIZE(cs42l56_audio_map),
1113     .suspend_bias_off   = 1,
1114     .idle_bias_on       = 1,
1115     .use_pmdown_time    = 1,
1116     .endianness     = 1,
1117 };
1118 
1119 static const struct regmap_config cs42l56_regmap = {
1120     .reg_bits = 8,
1121     .val_bits = 8,
1122 
1123     .max_register = CS42L56_MAX_REGISTER,
1124     .reg_defaults = cs42l56_reg_defaults,
1125     .num_reg_defaults = ARRAY_SIZE(cs42l56_reg_defaults),
1126     .readable_reg = cs42l56_readable_register,
1127     .volatile_reg = cs42l56_volatile_register,
1128     .cache_type = REGCACHE_RBTREE,
1129 };
1130 
1131 static int cs42l56_handle_of_data(struct i2c_client *i2c_client,
1132                     struct cs42l56_platform_data *pdata)
1133 {
1134     struct device_node *np = i2c_client->dev.of_node;
1135     u32 val32;
1136 
1137     if (of_property_read_bool(np, "cirrus,ain1a-reference-cfg"))
1138         pdata->ain1a_ref_cfg = true;
1139 
1140     if (of_property_read_bool(np, "cirrus,ain2a-reference-cfg"))
1141         pdata->ain2a_ref_cfg = true;
1142 
1143     if (of_property_read_bool(np, "cirrus,ain1b-reference-cfg"))
1144         pdata->ain1b_ref_cfg = true;
1145 
1146     if (of_property_read_bool(np, "cirrus,ain2b-reference-cfg"))
1147         pdata->ain2b_ref_cfg = true;
1148 
1149     if (of_property_read_u32(np, "cirrus,micbias-lvl", &val32) >= 0)
1150         pdata->micbias_lvl = val32;
1151 
1152     if (of_property_read_u32(np, "cirrus,chgfreq-divisor", &val32) >= 0)
1153         pdata->chgfreq = val32;
1154 
1155     if (of_property_read_u32(np, "cirrus,adaptive-pwr-cfg", &val32) >= 0)
1156         pdata->adaptive_pwr = val32;
1157 
1158     if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1159         pdata->hpfa_freq = val32;
1160 
1161     if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0)
1162         pdata->hpfb_freq = val32;
1163 
1164     pdata->gpio_nreset = of_get_named_gpio(np, "cirrus,gpio-nreset", 0);
1165 
1166     return 0;
1167 }
1168 
1169 static int cs42l56_i2c_probe(struct i2c_client *i2c_client)
1170 {
1171     struct cs42l56_private *cs42l56;
1172     struct cs42l56_platform_data *pdata =
1173         dev_get_platdata(&i2c_client->dev);
1174     int ret, i;
1175     unsigned int devid;
1176     unsigned int alpha_rev, metal_rev;
1177     unsigned int reg;
1178 
1179     cs42l56 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l56), GFP_KERNEL);
1180     if (cs42l56 == NULL)
1181         return -ENOMEM;
1182     cs42l56->dev = &i2c_client->dev;
1183 
1184     cs42l56->regmap = devm_regmap_init_i2c(i2c_client, &cs42l56_regmap);
1185     if (IS_ERR(cs42l56->regmap)) {
1186         ret = PTR_ERR(cs42l56->regmap);
1187         dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1188         return ret;
1189     }
1190 
1191     if (pdata) {
1192         cs42l56->pdata = *pdata;
1193     } else {
1194         pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
1195                      GFP_KERNEL);
1196         if (!pdata)
1197             return -ENOMEM;
1198 
1199         if (i2c_client->dev.of_node) {
1200             ret = cs42l56_handle_of_data(i2c_client,
1201                              &cs42l56->pdata);
1202             if (ret != 0)
1203                 return ret;
1204         }
1205         cs42l56->pdata = *pdata;
1206     }
1207 
1208     if (cs42l56->pdata.gpio_nreset) {
1209         ret = gpio_request_one(cs42l56->pdata.gpio_nreset,
1210                        GPIOF_OUT_INIT_HIGH, "CS42L56 /RST");
1211         if (ret < 0) {
1212             dev_err(&i2c_client->dev,
1213                 "Failed to request /RST %d: %d\n",
1214                 cs42l56->pdata.gpio_nreset, ret);
1215             return ret;
1216         }
1217         gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 0);
1218         gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 1);
1219     }
1220 
1221 
1222     i2c_set_clientdata(i2c_client, cs42l56);
1223 
1224     for (i = 0; i < ARRAY_SIZE(cs42l56->supplies); i++)
1225         cs42l56->supplies[i].supply = cs42l56_supply_names[i];
1226 
1227     ret = devm_regulator_bulk_get(&i2c_client->dev,
1228                       ARRAY_SIZE(cs42l56->supplies),
1229                       cs42l56->supplies);
1230     if (ret != 0) {
1231         dev_err(&i2c_client->dev,
1232             "Failed to request supplies: %d\n", ret);
1233         return ret;
1234     }
1235 
1236     ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
1237                     cs42l56->supplies);
1238     if (ret != 0) {
1239         dev_err(&i2c_client->dev,
1240             "Failed to enable supplies: %d\n", ret);
1241         return ret;
1242     }
1243 
1244     ret = regmap_read(cs42l56->regmap, CS42L56_CHIP_ID_1, &reg);
1245     if (ret) {
1246         dev_err(&i2c_client->dev, "Failed to read chip ID: %d\n", ret);
1247         goto err_enable;
1248     }
1249 
1250     devid = reg & CS42L56_CHIP_ID_MASK;
1251     if (devid != CS42L56_DEVID) {
1252         dev_err(&i2c_client->dev,
1253             "CS42L56 Device ID (%X). Expected %X\n",
1254             devid, CS42L56_DEVID);
1255         ret = -EINVAL;
1256         goto err_enable;
1257     }
1258     alpha_rev = reg & CS42L56_AREV_MASK;
1259     metal_rev = reg & CS42L56_MTLREV_MASK;
1260 
1261     dev_info(&i2c_client->dev, "Cirrus Logic CS42L56 ");
1262     dev_info(&i2c_client->dev, "Alpha Rev %X Metal Rev %X\n",
1263          alpha_rev, metal_rev);
1264 
1265     if (cs42l56->pdata.ain1a_ref_cfg)
1266         regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1267                    CS42L56_AIN1A_REF_MASK,
1268                    CS42L56_AIN1A_REF_MASK);
1269 
1270     if (cs42l56->pdata.ain1b_ref_cfg)
1271         regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1272                    CS42L56_AIN1B_REF_MASK,
1273                    CS42L56_AIN1B_REF_MASK);
1274 
1275     if (cs42l56->pdata.ain2a_ref_cfg)
1276         regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1277                    CS42L56_AIN2A_REF_MASK,
1278                    CS42L56_AIN2A_REF_MASK);
1279 
1280     if (cs42l56->pdata.ain2b_ref_cfg)
1281         regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX,
1282                    CS42L56_AIN2B_REF_MASK,
1283                    CS42L56_AIN2B_REF_MASK);
1284 
1285     if (cs42l56->pdata.micbias_lvl)
1286         regmap_update_bits(cs42l56->regmap, CS42L56_GAIN_BIAS_CTL,
1287                    CS42L56_MIC_BIAS_MASK,
1288                 cs42l56->pdata.micbias_lvl);
1289 
1290     if (cs42l56->pdata.chgfreq)
1291         regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL,
1292                    CS42L56_CHRG_FREQ_MASK,
1293                 cs42l56->pdata.chgfreq);
1294 
1295     if (cs42l56->pdata.hpfb_freq)
1296         regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL,
1297                    CS42L56_HPFB_FREQ_MASK,
1298                 cs42l56->pdata.hpfb_freq);
1299 
1300     if (cs42l56->pdata.hpfa_freq)
1301         regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL,
1302                    CS42L56_HPFA_FREQ_MASK,
1303                 cs42l56->pdata.hpfa_freq);
1304 
1305     if (cs42l56->pdata.adaptive_pwr)
1306         regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL,
1307                    CS42L56_ADAPT_PWR_MASK,
1308                 cs42l56->pdata.adaptive_pwr);
1309 
1310     ret =  devm_snd_soc_register_component(&i2c_client->dev,
1311             &soc_component_dev_cs42l56, &cs42l56_dai, 1);
1312     if (ret < 0)
1313         goto err_enable;
1314 
1315     return 0;
1316 
1317 err_enable:
1318     regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1319                    cs42l56->supplies);
1320     return ret;
1321 }
1322 
1323 static int cs42l56_i2c_remove(struct i2c_client *client)
1324 {
1325     struct cs42l56_private *cs42l56 = i2c_get_clientdata(client);
1326 
1327     regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
1328                    cs42l56->supplies);
1329     return 0;
1330 }
1331 
1332 static const struct of_device_id cs42l56_of_match[] = {
1333     { .compatible = "cirrus,cs42l56", },
1334     { }
1335 };
1336 MODULE_DEVICE_TABLE(of, cs42l56_of_match);
1337 
1338 
1339 static const struct i2c_device_id cs42l56_id[] = {
1340     { "cs42l56", 0 },
1341     { }
1342 };
1343 MODULE_DEVICE_TABLE(i2c, cs42l56_id);
1344 
1345 static struct i2c_driver cs42l56_i2c_driver = {
1346     .driver = {
1347         .name = "cs42l56",
1348         .of_match_table = cs42l56_of_match,
1349     },
1350     .id_table = cs42l56_id,
1351     .probe_new = cs42l56_i2c_probe,
1352     .remove =   cs42l56_i2c_remove,
1353 };
1354 
1355 module_i2c_driver(cs42l56_i2c_driver);
1356 
1357 MODULE_DESCRIPTION("ASoC CS42L56 driver");
1358 MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1359 MODULE_LICENSE("GPL");