0001
0002
0003
0004
0005
0006
0007
0008
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 },
0056 { CS42L52_PWRCTL2, 0x07 },
0057 { CS42L52_PWRCTL3, 0xFF },
0058 { CS42L52_CLK_CTL, 0xA0 },
0059 { CS42L52_IFACE_CTL1, 0x00 },
0060 { CS42L52_ADC_PGA_A, 0x80 },
0061 { CS42L52_ADC_PGA_B, 0x80 },
0062 { CS42L52_ANALOG_HPF_CTL, 0xA5 },
0063 { CS42L52_ADC_HPF_FREQ, 0x00 },
0064 { CS42L52_ADC_MISC_CTL, 0x00 },
0065 { CS42L52_PB_CTL1, 0x60 },
0066 { CS42L52_MISC_CTL, 0x02 },
0067 { CS42L52_PB_CTL2, 0x00 },
0068 { CS42L52_MICA_CTL, 0x00 },
0069 { CS42L52_MICB_CTL, 0x00 },
0070 { CS42L52_PGAA_CTL, 0x00 },
0071 { CS42L52_PGAB_CTL, 0x00 },
0072 { CS42L52_PASSTHRUA_VOL, 0x00 },
0073 { CS42L52_PASSTHRUB_VOL, 0x00 },
0074 { CS42L52_ADCA_VOL, 0x00 },
0075 { CS42L52_ADCB_VOL, 0x00 },
0076 { CS42L52_ADCA_MIXER_VOL, 0x80 },
0077 { CS42L52_ADCB_MIXER_VOL, 0x80 },
0078 { CS42L52_PCMA_MIXER_VOL, 0x00 },
0079 { CS42L52_PCMB_MIXER_VOL, 0x00 },
0080 { CS42L52_BEEP_FREQ, 0x00 },
0081 { CS42L52_BEEP_VOL, 0x00 },
0082 { CS42L52_BEEP_TONE_CTL, 0x00 },
0083 { CS42L52_TONE_CTL, 0x00 },
0084 { CS42L52_MASTERA_VOL, 0x00 },
0085 { CS42L52_MASTERB_VOL, 0x00 },
0086 { CS42L52_HPA_VOL, 0x00 },
0087 { CS42L52_HPB_VOL, 0x00 },
0088 { CS42L52_SPKA_VOL, 0x00 },
0089 { CS42L52_SPKB_VOL, 0x00 },
0090 { CS42L52_ADC_PCM_MIXER, 0x00 },
0091 { CS42L52_LIMITER_CTL1, 0x00 },
0092 { CS42L52_LIMITER_CTL2, 0x7F },
0093 { CS42L52_LIMITER_AT_RATE, 0xC0 },
0094 { CS42L52_ALC_CTL, 0x00 },
0095 { CS42L52_ALC_RATE, 0x3F },
0096 { CS42L52_ALC_THRESHOLD, 0x3f },
0097 { CS42L52_NOISE_GATE_CTL, 0x00 },
0098 { CS42L52_CLK_STATUS, 0x00 },
0099 { CS42L52_BATT_COMPEN, 0x00 },
0100 { CS42L52_BATT_LEVEL, 0x00 },
0101 { CS42L52_SPK_STATUS, 0x00 },
0102 { CS42L52_TEM_CTL, 0x3B },
0103 { CS42L52_THE_FOLDBACK, 0x00 },
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
0935
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
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
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, ®);
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
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");