15 #include <linux/module.h>
17 #include <linux/kernel.h>
21 #include <linux/i2c.h>
22 #include <linux/input.h>
24 #include <linux/slab.h>
52 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
53 struct input_dev *beep;
59 static const struct reg_default cs42l52_reg_defaults[] = {
111 static bool cs42l52_readable_register(
struct device *
dev,
unsigned int reg)
172 static bool cs42l52_volatile_register(
struct device *dev,
unsigned int reg)
196 static const unsigned int limiter_tlv[] = {
202 static const char *
const cs42l52_adca_text[] = {
203 "Input1A",
"Input2A",
"Input3A",
"Input4A",
"PGA Input Left"};
205 static const char *
const cs42l52_adcb_text[] = {
206 "Input1B",
"Input2B",
"Input3B",
"Input4B",
"PGA Input Right"};
208 static const struct soc_enum adca_enum =
210 ARRAY_SIZE(cs42l52_adca_text), cs42l52_adca_text);
212 static const struct soc_enum adcb_enum =
214 ARRAY_SIZE(cs42l52_adcb_text), cs42l52_adcb_text);
222 static const char *
const mic_bias_level_text[] = {
223 "0.5 +VA",
"0.6 +VA",
"0.7 +VA",
224 "0.8 +VA",
"0.83 +VA",
"0.91 +VA"
227 static const struct soc_enum mic_bias_level_enum =
229 ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text);
231 static const char *
const cs42l52_mic_text[] = {
"Single",
"Differential" };
233 static const struct soc_enum mica_enum =
235 ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
237 static const struct soc_enum micb_enum =
239 ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
247 static const char *
const digital_output_mux_text[] = {
"ADC",
"DSP"};
249 static const struct soc_enum digital_output_mux_enum =
252 digital_output_mux_text);
255 SOC_DAPM_ENUM(
"Digital Output Mux", digital_output_mux_enum);
257 static const char *
const hp_gain_num_text[] = {
258 "0.3959",
"0.4571",
"0.5111",
"0.6047",
259 "0.7099",
"0.8399",
"1.000",
"1.1430"
262 static const struct soc_enum hp_gain_enum =
264 ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text);
266 static const char *
const beep_pitch_text[] = {
267 "C4",
"C5",
"D5",
"E5",
"F5",
"G5",
"A5",
"B5",
268 "C6",
"D6",
"E6",
"F6",
"G6",
"A6",
"B6",
"C7"
271 static const struct soc_enum beep_pitch_enum =
273 ARRAY_SIZE(beep_pitch_text), beep_pitch_text);
275 static const char *
const beep_ontime_text[] = {
276 "86 ms",
"430 ms",
"780 ms",
"1.20 s",
"1.50 s",
277 "1.80 s",
"2.20 s",
"2.50 s",
"2.80 s",
"3.20 s",
278 "3.50 s",
"3.80 s",
"4.20 s",
"4.50 s",
"4.80 s",
"5.20 s"
281 static const struct soc_enum beep_ontime_enum =
283 ARRAY_SIZE(beep_ontime_text), beep_ontime_text);
285 static const char *
const beep_offtime_text[] = {
286 "1.23 s",
"2.58 s",
"3.90 s",
"5.20 s",
287 "6.60 s",
"8.05 s",
"9.35 s",
"10.80 s"
290 static const struct soc_enum beep_offtime_enum =
292 ARRAY_SIZE(beep_offtime_text), beep_offtime_text);
294 static const char *
const beep_config_text[] = {
295 "Off",
"Single",
"Multiple",
"Continuous"
298 static const struct soc_enum beep_config_enum =
300 ARRAY_SIZE(beep_config_text), beep_config_text);
302 static const char *
const beep_bass_text[] = {
303 "50 Hz",
"100 Hz",
"200 Hz",
"250 Hz"
306 static const struct soc_enum beep_bass_enum =
310 static const char *
const beep_treble_text[] = {
311 "5 kHz",
"7 kHz",
"10 kHz",
" 15 kHz"
314 static const struct soc_enum beep_treble_enum =
316 ARRAY_SIZE(beep_treble_text), beep_treble_text);
318 static const char *
const ng_threshold_text[] = {
319 "-34dB",
"-37dB",
"-40dB",
"-43dB",
320 "-46dB",
"-52dB",
"-58dB",
"-64dB"
323 static const struct soc_enum ng_threshold_enum =
325 ARRAY_SIZE(ng_threshold_text), ng_threshold_text);
327 static const char *
const cs42l52_ng_delay_text[] = {
328 "50ms",
"100ms",
"150ms",
"200ms"};
330 static const struct soc_enum ng_delay_enum =
332 ARRAY_SIZE(cs42l52_ng_delay_text), cs42l52_ng_delay_text);
334 static const char *
const cs42l52_ng_type_text[] = {
335 "Apply Specific",
"Apply All"
338 static const struct soc_enum ng_type_enum =
340 ARRAY_SIZE(cs42l52_ng_type_text), cs42l52_ng_type_text);
342 static const char *
const left_swap_text[] = {
343 "Left",
"LR 2",
"Right"};
345 static const char *
const right_swap_text[] = {
346 "Right",
"LR 2",
"Left"};
348 static const unsigned int swap_values[] = { 0, 1, 3 };
350 static const struct soc_enum adca_swap_enum =
359 static const struct soc_enum pcma_swap_enum =
368 static const struct soc_enum adcb_swap_enum =
377 static const struct soc_enum pcmb_swap_enum =
413 SOC_ENUM(
"Headphone Analog Gain", hp_gain_enum),
426 SOC_ENUM(
"MIC Bias Level", mic_bias_level_enum),
432 6, 0x7f, 0x19, ipd_tlv),
444 6, 0x7f, 0x19, hl_tlv),
448 SOC_ENUM(
"Beep Config", beep_config_enum),
449 SOC_ENUM(
"Beep Pitch", beep_pitch_enum),
450 SOC_ENUM(
"Beep on Time", beep_ontime_enum),
451 SOC_ENUM(
"Beep off Time", beep_offtime_enum),
454 SOC_ENUM(
"Beep Treble Corner Freq", beep_treble_enum),
455 SOC_ENUM(
"Beep Bass Corner Freq", beep_bass_enum),
479 0, 63, 0, limiter_tlv),
481 0, 63, 0, limiter_tlv),
483 5, 7, 0, limiter_tlv),
485 2, 7, 0, limiter_tlv),
494 SOC_ENUM(
"NG Type Switch", ng_type_enum),
497 SOC_ENUM(
"NG Threshold", ng_threshold_enum),
498 SOC_ENUM(
"NG Delay", ng_delay_enum),
564 0, 0, &digital_output_mux),
581 6, 0, &passthrul_ctl),
583 7, 0, &passthrur_ctl),
605 {
"Capture",
NULL,
"AIFOUTL"},
606 {
"Capture",
NULL,
"AIFOUTL"},
608 {
"AIFOUTL",
NULL,
"Output Mux"},
609 {
"AIFOUTR",
NULL,
"Output Mux"},
611 {
"Output Mux",
"ADC",
"ADC Left"},
612 {
"Output Mux",
"ADC",
"ADC Right"},
614 {
"ADC Left",
NULL,
"Charge Pump"},
615 {
"ADC Right",
NULL,
"Charge Pump"},
617 {
"Charge Pump",
NULL,
"ADC Left Mux"},
618 {
"Charge Pump",
NULL,
"ADC Right Mux"},
620 {
"ADC Left Mux",
"Input1A",
"AIN1L"},
621 {
"ADC Right Mux",
"Input1B",
"AIN1R"},
622 {
"ADC Left Mux",
"Input2A",
"AIN2L"},
623 {
"ADC Right Mux",
"Input2B",
"AIN2R"},
624 {
"ADC Left Mux",
"Input3A",
"AIN3L"},
625 {
"ADC Right Mux",
"Input3B",
"AIN3R"},
626 {
"ADC Left Mux",
"Input4A",
"AIN4L"},
627 {
"ADC Right Mux",
"Input4B",
"AIN4R"},
628 {
"ADC Left Mux",
"PGA Input Left",
"PGA Left"},
629 {
"ADC Right Mux",
"PGA Input Right" ,
"PGA Right"},
631 {
"PGA Left",
"Switch",
"AIN1L"},
632 {
"PGA Right",
"Switch",
"AIN1R"},
633 {
"PGA Left",
"Switch",
"AIN2L"},
634 {
"PGA Right",
"Switch",
"AIN2R"},
635 {
"PGA Left",
"Switch",
"AIN3L"},
636 {
"PGA Right",
"Switch",
"AIN3R"},
637 {
"PGA Left",
"Switch",
"AIN4L"},
638 {
"PGA Right",
"Switch",
"AIN4R"},
640 {
"PGA Left",
"Switch",
"PGA MICA"},
641 {
"PGA MICA",
NULL,
"MICA"},
643 {
"PGA Right",
"Switch",
"PGA MICB"},
644 {
"PGA MICB",
NULL,
"MICB"},
646 {
"HPOUTA",
NULL,
"HP Left Amp"},
647 {
"HPOUTB",
NULL,
"HP Right Amp"},
648 {
"HP Left Amp",
NULL,
"Bypass Left"},
649 {
"HP Right Amp",
NULL,
"Bypass Right"},
650 {
"Bypass Left",
"Switch",
"PGA Left"},
651 {
"Bypass Right",
"Switch",
"PGA Right"},
652 {
"HP Left Amp",
"Switch",
"DAC Left"},
653 {
"HP Right Amp",
"Switch",
"DAC Right"},
655 {
"SPKOUTA",
NULL,
"SPK Left Amp"},
656 {
"SPKOUTB",
NULL,
"SPK Right Amp"},
658 {
"SPK Left Amp",
NULL,
"Beep"},
659 {
"SPK Right Amp",
NULL,
"Beep"},
660 {
"SPK Left Amp",
"Switch",
"Playback"},
661 {
"SPK Right Amp",
"Switch",
"Playback"},
663 {
"DAC Left",
NULL,
"Beep"},
664 {
"DAC Right",
NULL,
"Beep"},
665 {
"DAC Left",
NULL,
"Playback"},
666 {
"DAC Right",
NULL,
"Playback"},
668 {
"Output Mux",
"DSP",
"Playback"},
669 {
"Output Mux",
"DSP",
"Playback"},
671 {
"AIFINL",
NULL,
"Playback"},
672 {
"AIFINR",
NULL,
"Playback"},
738 static int cs42l52_get_clk(
int mclk,
int rate)
741 u_int mclk1, mclk2 = 0;
743 for (i = 0; i <
ARRAY_SIZE(clk_map_table); i++) {
744 if (clk_map_table[i].rate == rate) {
745 mclk1 = clk_map_table[
i].
mclk;
746 if (
abs(mclk - mclk1) <
abs(mclk - mclk2)) {
757 static int cs42l52_set_sysclk(
struct snd_soc_dai *codec_dai,
758 int clk_id,
unsigned int freq,
int dir)
766 dev_err(codec->
dev,
"Invalid freq parameter\n");
772 static int cs42l52_set_fmt(
struct snd_soc_dai *codec_dai,
unsigned int fmt)
826 cs42l52->
config.format = iface;
869 dev_err(codec->
dev,
"can't get correct mclk\n");
876 static int cs42l52_set_bias_level(
struct snd_soc_codec *codec,
905 #define CS42L52_RATES (SNDRV_PCM_RATE_8000_96000)
907 #define CS42L52_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
908 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \
909 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
910 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE)
913 .hw_params = cs42l52_pcm_hw_params,
914 .digital_mute = cs42l52_digital_mute,
915 .set_fmt = cs42l52_set_fmt,
916 .set_sysclk = cs42l52_set_sysclk,
922 .stream_name =
"Playback",
929 .stream_name =
"Capture",
952 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
953 static int beep_rates[] = {
954 261, 522, 585, 667, 706, 774, 889, 1000,
955 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
968 if (cs42l52->beep_rate) {
969 for (i = 0; i <
ARRAY_SIZE(beep_rates); i++) {
970 if (
abs(cs42l52->beep_rate - beep_rates[i]) <
971 abs(cs42l52->beep_rate - beep_rates[best]))
975 dev_dbg(codec->
dev,
"Set beep rate %dHz for requested %dHz\n",
976 beep_rates[best], cs42l52->beep_rate);
995 static int cs42l52_beep_event(
struct input_dev *dev,
unsigned int type,
996 unsigned int code,
int hz)
1001 dev_dbg(codec->
dev,
"Beep event %x %x\n", code, hz);
1014 cs42l52->beep_rate = hz;
1027 ret = kstrtol(buf, 10, &time);
1043 cs42l52->beep = input_allocate_device();
1044 if (!cs42l52->beep) {
1045 dev_err(codec->
dev,
"Failed to allocate beep device\n");
1049 INIT_WORK(&cs42l52->beep_work, cs42l52_beep_work);
1050 cs42l52->beep_rate = 0;
1052 cs42l52->beep->name =
"CS42L52 Beep Generator";
1053 cs42l52->beep->phys = dev_name(codec->
dev);
1054 cs42l52->beep->id.bustype =
BUS_I2C;
1058 cs42l52->beep->event = cs42l52_beep_event;
1059 cs42l52->beep->
dev.parent = codec->
dev;
1060 input_set_drvdata(cs42l52->beep, codec);
1062 ret = input_register_device(cs42l52->beep);
1064 input_free_device(cs42l52->beep);
1065 cs42l52->beep =
NULL;
1066 dev_err(codec->
dev,
"Failed to register beep device\n");
1071 dev_err(codec->
dev,
"Failed to create keyclick file: %d\n",
1081 input_unregister_device(cs42l52->beep);
1083 cs42l52->beep =
NULL;
1106 dev_err(codec->
dev,
"Failed to set cache I/O: %d\n", ret);
1111 cs42l52_init_beep(codec);
1121 cs42l52->
pdata.mica_cfg <<
1126 cs42l52->
pdata.micb_cfg <<
1130 if (cs42l52->
pdata.mica_cfg)
1133 cs42l52->
pdata.mica_sel <<
1135 if (cs42l52->
pdata.micb_cfg)
1138 cs42l52->
pdata.micb_sel <<
1144 cs42l52->
pdata.chgfreq <<
1150 cs42l52->
pdata.micbias_lvl);
1157 cs42l52_free_beep(codec);
1164 .probe = cs42l52_probe,
1165 .remove = cs42l52_remove,
1166 .suspend = cs42l52_suspend,
1167 .resume = cs42l52_resume,
1168 .set_bias_level = cs42l52_set_bias_level,
1170 .dapm_widgets = cs42l52_dapm_widgets,
1171 .num_dapm_widgets =
ARRAY_SIZE(cs42l52_dapm_widgets),
1172 .dapm_routes = cs42l52_audio_map,
1173 .num_dapm_routes =
ARRAY_SIZE(cs42l52_audio_map),
1175 .controls = cs42l52_snd_controls,
1176 .num_controls =
ARRAY_SIZE(cs42l52_snd_controls),
1180 static const struct reg_default cs42l52_threshold_patch[] = {
1191 static struct regmap_config cs42l52_regmap = {
1196 .reg_defaults = cs42l52_reg_defaults,
1197 .num_reg_defaults =
ARRAY_SIZE(cs42l52_reg_defaults),
1198 .readable_reg = cs42l52_readable_register,
1199 .volatile_reg = cs42l52_volatile_register,
1208 unsigned int devid = 0;
1213 if (cs42l52 ==
NULL)
1215 cs42l52->
dev = &i2c_client->
dev;
1218 if (IS_ERR(cs42l52->
regmap)) {
1219 ret = PTR_ERR(cs42l52->
regmap);
1220 dev_err(&i2c_client->
dev,
"regmap_init() failed: %d\n", ret);
1224 i2c_set_clientdata(i2c_client, cs42l52);
1226 if (dev_get_platdata(&i2c_client->
dev))
1228 sizeof(cs42l52->
pdata));
1233 dev_warn(cs42l52->
dev,
"Failed to apply regmap patch: %d\n",
1241 "CS42L52 Device ID (%X). Expected %X\n",
1249 &soc_codec_dev_cs42l52, &cs42l52_dai, 1);
1255 static int cs42l52_i2c_remove(
struct i2c_client *
client)
1267 static struct i2c_driver cs42l52_i2c_driver = {
1272 .id_table = cs42l52_id,
1273 .probe = cs42l52_i2c_probe,