18 #include <linux/module.h>
19 #include <linux/kernel.h>
23 #include <linux/i2c.h>
24 #include <linux/slab.h>
38 static struct reg_default alc5632_reg_defaults[] = {
90 static bool alc5632_volatile_register(
struct device *
dev,
111 static inline int alc5632_reset(
struct regmap *
map)
147 static const unsigned int boost_tlv[] = {
280 static const char *
const alc5632_spk_n_sour_sel[] = {
281 "RN/-R",
"RP/+R",
"LN/-R",
"Mute"};
282 static const char *
const alc5632_hpl_out_input_sel[] = {
283 "Vmid",
"HP Left Mix"};
284 static const char *
const alc5632_hpr_out_input_sel[] = {
285 "Vmid",
"HP Right Mix"};
286 static const char *
const alc5632_spkout_input_sel[] = {
287 "Vmid",
"HPOut Mix",
"Speaker Mix",
"Mono Mix"};
288 static const char *
const alc5632_aux_out_input_sel[] = {
289 "Vmid",
"HPOut Mix",
"Speaker Mix",
"Mono Mix"};
290 static const char *
const alc5632_adcr_func_sel[] = {
291 "Stereo ADC",
"Voice ADC"};
292 static const char *
const alc5632_i2s_out_sel[] = {
293 "ADC LR",
"Voice Stereo Digital"};
296 static const struct soc_enum alc5632_aux_out_input_enum =
302 static const struct soc_enum alc5632_spkout_input_enum =
308 static const struct soc_enum alc5632_hpl_out_input_enum =
311 SOC_DAPM_ENUM(
"Left Headphone Mux", alc5632_hpl_out_input_enum);
314 static const struct soc_enum alc5632_hpr_out_input_enum =
317 SOC_DAPM_ENUM(
"Right Headphone Mux", alc5632_hpr_out_input_enum);
320 static const struct soc_enum alc5632_spk_n_sour_enum =
326 static const char *alc5632_amp_names[] = {
"AB Amp",
"D Amp"};
327 static const struct soc_enum alc5632_amp_enum =
333 static const struct soc_enum alc5632_adcr_func_enum =
339 static const struct soc_enum alc5632_i2s_out_enum =
347 &alc5632_auxout_mux_controls),
349 &alc5632_spkout_mux_controls),
351 &alc5632_hpl_out_mux_controls),
353 &alc5632_hpr_out_mux_controls),
355 &alc5632_spkoutn_mux_controls),
357 &alc5632_adcr_func_controls),
359 &alc5632_i2s_out_controls),
363 &alc5632_hp_mixer_controls[0],
366 &alc5632_hpr_mixer_controls[0],
369 &alc5632_hpl_mixer_controls[0],
373 &alc5632_mono_mixer_controls[0],
376 &alc5632_speaker_mixer_controls[0],
379 &alc5632_dmicl_mixer_controls[0],
382 &alc5632_dmicr_mixer_controls[0],
387 &alc5632_captureL_mixer_controls[0],
390 &alc5632_captureR_mixer_controls[0],
435 &alc5632_amp_mux_controls),
456 {
"Left DAC",
NULL,
"AIFRXL"},
457 {
"Right DAC",
NULL,
"AIFRXR"},
460 {
"I2S Mix",
NULL,
"Left DAC"},
461 {
"I2S Mix",
NULL,
"Right DAC"},
462 {
"Line Mix",
NULL,
"Right LineIn"},
463 {
"Line Mix",
NULL,
"Left LineIn"},
464 {
"Phone Mix",
NULL,
"Phone"},
465 {
"Phone Mix",
NULL,
"Phone ADMix"},
466 {
"AUXOUT",
NULL,
"Aux Out"},
469 {
"DAC Right Channel",
NULL,
"I2S Mix"},
470 {
"DAC Left Channel",
NULL,
"I2S Mix"},
473 {
"HPL Mix",
"ADC2HP_L Playback Switch",
"Left Capture Mix"},
474 {
"HPL Mix",
NULL,
"HP Mix"},
475 {
"HPR Mix",
"ADC2HP_R Playback Switch",
"Right Capture Mix"},
476 {
"HPR Mix",
NULL,
"HP Mix"},
477 {
"HP Mix",
"LI2HP Playback Switch",
"Line Mix"},
478 {
"HP Mix",
"PHONE2HP Playback Switch",
"Phone Mix"},
479 {
"HP Mix",
"MIC12HP Playback Switch",
"MIC1 PGA"},
480 {
"HP Mix",
"MIC22HP Playback Switch",
"MIC2 PGA"},
481 {
"HP Mix",
"VOICE2HP Playback Switch",
"Voice Mix"},
482 {
"HPR Mix",
"DACR2HP Playback Switch",
"DAC Right Channel"},
483 {
"HPL Mix",
"DACL2HP Playback Switch",
"DAC Left Channel"},
484 {
"HPOut Mix",
NULL,
"HP Mix"},
485 {
"HPOut Mix",
NULL,
"HPR Mix"},
486 {
"HPOut Mix",
NULL,
"HPL Mix"},
489 {
"Speaker Mix",
"LI2SPK Playback Switch",
"Line Mix"},
490 {
"Speaker Mix",
"PHONE2SPK Playback Switch",
"Phone Mix"},
491 {
"Speaker Mix",
"MIC12SPK Playback Switch",
"MIC1 PGA"},
492 {
"Speaker Mix",
"MIC22SPK Playback Switch",
"MIC2 PGA"},
493 {
"Speaker Mix",
"DAC2SPK Playback Switch",
"DAC Left Channel"},
494 {
"Speaker Mix",
"VOICE2SPK Playback Switch",
"Voice Mix"},
497 {
"Mono Mix",
"ADC2MONO_L Playback Switch",
"Left Capture Mix"},
498 {
"Mono Mix",
"ADC2MONO_R Playback Switch",
"Right Capture Mix"},
499 {
"Mono Mix",
"LI2MONO Playback Switch",
"Line Mix"},
500 {
"Mono Mix",
"MIC12MONO Playback Switch",
"MIC1 PGA"},
501 {
"Mono Mix",
"MIC22MONO Playback Switch",
"MIC2 PGA"},
502 {
"Mono Mix",
"DAC2MONO Playback Switch",
"DAC Left Channel"},
503 {
"Mono Mix",
"VOICE2MONO Playback Switch",
"Voice Mix"},
506 {
"Left Capture Mix",
"LIL2REC Capture Switch",
"LINEINL"},
507 {
"Left Capture Mix",
"PH2REC_L Capture Switch",
"PHONEN"},
508 {
"Left Capture Mix",
"MIC12REC_L Capture Switch",
"MIC1 Pre Amp"},
509 {
"Left Capture Mix",
"MIC22REC_L Capture Switch",
"MIC2 Pre Amp"},
510 {
"Left Capture Mix",
"HPL2REC Capture Switch",
"HPL Mix"},
511 {
"Left Capture Mix",
"SPK2REC_L Capture Switch",
"Speaker Mix"},
512 {
"Left Capture Mix",
"MONO2REC_L Capture Switch",
"Mono Mix"},
515 {
"Right Capture Mix",
"LIR2REC Capture Switch",
"LINEINR"},
516 {
"Right Capture Mix",
"PH2REC_R Capture Switch",
"PHONEP"},
517 {
"Right Capture Mix",
"MIC12REC_R Capture Switch",
"MIC1 Pre Amp"},
518 {
"Right Capture Mix",
"MIC22REC_R Capture Switch",
"MIC2 Pre Amp"},
519 {
"Right Capture Mix",
"HPR2REC Capture Switch",
"HPR Mix"},
520 {
"Right Capture Mix",
"SPK2REC_R Capture Switch",
"Speaker Mix"},
521 {
"Right Capture Mix",
"MONO2REC_R Capture Switch",
"Mono Mix"},
524 {
"Left Headphone Mux",
"HP Left Mix",
"HPL Mix"},
525 {
"Left Headphone Mux",
"Vmid",
"Vmid"},
528 {
"Right Headphone Mux",
"HP Right Mix",
"HPR Mix"},
529 {
"Right Headphone Mux",
"Vmid",
"Vmid"},
532 {
"SpeakerOut Mux",
"Vmid",
"Vmid"},
533 {
"SpeakerOut Mux",
"HPOut Mix",
"HPOut Mix"},
534 {
"SpeakerOut Mux",
"Speaker Mix",
"Speaker Mix"},
535 {
"SpeakerOut Mux",
"Mono Mix",
"Mono Mix"},
538 {
"AuxOut Mux",
"Vmid",
"Vmid"},
539 {
"AuxOut Mux",
"HPOut Mix",
"HPOut Mix"},
540 {
"AuxOut Mux",
"Speaker Mix",
"Speaker Mix"},
541 {
"AuxOut Mux",
"Mono Mix",
"Mono Mix"},
544 {
"HPL",
NULL,
"Left Headphone"},
545 {
"Left Headphone",
NULL,
"Left Headphone Mux"},
546 {
"HPR",
NULL,
"Right Headphone"},
547 {
"Right Headphone",
NULL,
"Right Headphone Mux"},
548 {
"Aux Out",
NULL,
"AuxOut Mux"},
551 {
"Left LineIn",
NULL,
"LINEINL"},
552 {
"Right LineIn",
NULL,
"LINEINR"},
553 {
"Phone",
NULL,
"PHONEP"},
554 {
"MIC1 Pre Amp",
NULL,
"MIC1"},
555 {
"MIC2 Pre Amp",
NULL,
"MIC2"},
556 {
"MIC1 PGA",
NULL,
"MIC1 Pre Amp"},
557 {
"MIC2 PGA",
NULL,
"MIC2 Pre Amp"},
560 {
"Left ADC",
NULL,
"Left Capture Mix"},
561 {
"DMICL Mix",
"DMICL2ADC Capture Switch",
"DMICDAT"},
562 {
"Left ADC",
NULL,
"DMICL Mix"},
563 {
"ADCLR",
NULL,
"Left ADC"},
566 {
"Right ADC",
NULL,
"Right Capture Mix"},
567 {
"DMICR Mix",
"DMICR2ADC Capture Switch",
"DMICDAT"},
568 {
"Right ADC",
NULL,
"DMICR Mix"},
569 {
"ADCR Mux",
"Stereo ADC",
"Right ADC"},
570 {
"ADCR Mux",
"Voice ADC",
"Right ADC"},
571 {
"ADCLR",
NULL,
"ADCR Mux"},
572 {
"VAIFTX",
NULL,
"ADCR Mux"},
575 {
"I2SOut Mux",
"ADC LR",
"ADCLR"},
576 {
"I2SOut Mux",
"Voice Stereo Digital",
"VAIFRX"},
577 {
"AIFTXL",
NULL,
"I2SOut Mux"},
578 {
"AIFTXR",
NULL,
"I2SOut Mux"},
581 {
"Voice DAC",
NULL,
"VAIFRX"},
582 {
"Voice Mix",
NULL,
"Voice DAC"},
585 {
"SpeakerOut N Mux",
"RN/-R",
"Left Speaker"},
586 {
"SpeakerOut N Mux",
"RP/+R",
"Left Speaker"},
587 {
"SpeakerOut N Mux",
"LN/-R",
"Left Speaker"},
588 {
"SpeakerOut N Mux",
"Mute",
"Vmid"},
590 {
"SpeakerOut N Mux",
"RN/-R",
"Right Speaker"},
591 {
"SpeakerOut N Mux",
"RP/+R",
"Right Speaker"},
592 {
"SpeakerOut N Mux",
"LN/-R",
"Right Speaker"},
593 {
"SpeakerOut N Mux",
"Mute",
"Vmid"},
595 {
"AB Amp",
NULL,
"SpeakerOut Mux"},
596 {
"D Amp",
NULL,
"SpeakerOut Mux"},
597 {
"AB-D Amp Mux",
"AB Amp",
"AB Amp"},
598 {
"AB-D Amp Mux",
"D Amp",
"D Amp"},
599 {
"Left Speaker",
NULL,
"AB-D Amp Mux"},
600 {
"Right Speaker",
NULL,
"AB-D Amp Mux"},
602 {
"SPKOUT",
NULL,
"Left Speaker"},
603 {
"SPKOUT",
NULL,
"Right Speaker"},
605 {
"SPKOUTN",
NULL,
"SpeakerOut N Mux"},
618 static const struct _pll_div codec_master_pll_div[] = {
620 { 2048000, 8192000, 0x0ea0},
621 { 3686400, 8192000, 0x4e27},
622 { 12000000, 8192000, 0x456b},
623 { 13000000, 8192000, 0x495f},
624 { 13100000, 8192000, 0x0320},
625 { 2048000, 11289600, 0xf637},
626 { 3686400, 11289600, 0x2f22},
627 { 12000000, 11289600, 0x3e2f},
628 { 13000000, 11289600, 0x4d5b},
629 { 13100000, 11289600, 0x363b},
630 { 2048000, 16384000, 0x1ea0},
631 { 3686400, 16384000, 0x9e27},
632 { 12000000, 16384000, 0x452b},
633 { 13000000, 16384000, 0x542f},
634 { 13100000, 16384000, 0x03a0},
635 { 2048000, 16934400, 0xe625},
636 { 3686400, 16934400, 0x9126},
637 { 12000000, 16934400, 0x4d2c},
638 { 13000000, 16934400, 0x742f},
639 { 13100000, 16934400, 0x3c27},
640 { 2048000, 22579200, 0x2aa0},
641 { 3686400, 22579200, 0x2f20},
642 { 12000000, 22579200, 0x7e2f},
643 { 13000000, 22579200, 0x742f},
644 { 13100000, 22579200, 0x3c27},
645 { 2048000, 24576000, 0x2ea0},
646 { 3686400, 24576000, 0xee27},
647 { 12000000, 24576000, 0x2915},
648 { 13000000, 24576000, 0x772e},
649 { 13100000, 24576000, 0x0d20},
660 static const struct _pll_div codec_slave_pll_div[] = {
662 { 1024000, 16384000, 0x3ea0},
663 { 1411200, 22579200, 0x3ea0},
664 { 1536000, 24576000, 0x3ea0},
665 { 2048000, 16384000, 0x1ea0},
666 { 2822400, 22579200, 0x1ea0},
667 { 3072000, 24576000, 0x1ea0},
671 static int alc5632_set_dai_pll(
struct snd_soc_dai *codec_dai,
int pll_id,
672 int source,
unsigned int freq_in,
unsigned int freq_out)
695 if (!freq_in || !freq_out)
700 for (i = 0; i <
ARRAY_SIZE(codec_master_pll_div); i++) {
701 if (codec_master_pll_div[i].pll_in == freq_in
702 && codec_master_pll_div[i].pll_out == freq_out) {
710 for (i = 0; i <
ARRAY_SIZE(codec_slave_pll_div); i++) {
711 if (codec_slave_pll_div[i].pll_in == freq_in
712 && codec_slave_pll_div[i].pll_out == freq_out) {
720 case ALC5632_PLL_FR_VBCLK:
721 for (i = 0; i <
ARRAY_SIZE(codec_slave_pll_div); i++) {
722 if (codec_slave_pll_div[i].pll_in == freq_in
723 && codec_slave_pll_div[i].pll_out == freq_out) {
765 static const struct _coeff_div coeff_div[] = {
771 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
775 if (coeff_div[i].
fs * rate == alc5632->
sysclk)
784 static int alc5632_set_dai_sysclk(
struct snd_soc_dai *codec_dai,
785 int clk_id,
unsigned int freq,
int dir)
788 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
806 static int alc5632_set_dai_fmt(
struct snd_soc_dai *codec_dai,
889 coeff = get_coeff(codec, rate);
912 #define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF)
914 #define ALC5632_ADD3_POWER_EN (ALC5632_PWR_ADD3_MIC1_BOOST_AD)
916 #define ALC5632_ADD1_POWER_EN \
917 (ALC5632_PWR_ADD1_DAC_REF \
918 | ALC5632_PWR_ADD1_SOFTGEN_EN \
919 | ALC5632_PWR_ADD1_HP_OUT_AMP \
920 | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \
921 | ALC5632_PWR_ADD1_MAIN_BIAS)
960 static int alc5632_set_bias_level(
struct snd_soc_codec *codec,
965 enable_power_depop(codec);
997 #define ALC5632_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
998 | SNDRV_PCM_FMTBIT_S24_LE \
999 | SNDRV_PCM_FMTBIT_S32_LE)
1002 .hw_params = alc5632_pcm_hw_params,
1003 .digital_mute = alc5632_mute,
1004 .set_fmt = alc5632_set_dai_fmt,
1005 .set_sysclk = alc5632_set_dai_sysclk,
1006 .set_pll = alc5632_set_dai_pll,
1010 .name =
"alc5632-hifi",
1012 .stream_name =
"HiFi Playback",
1020 .stream_name =
"HiFi Capture",
1028 .ops = &alc5632_dai_ops,
1029 .symmetric_rates = 1,
1041 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
1049 #define alc5632_suspend NULL
1050 #define alc5632_resume NULL
1055 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
1062 dev_err(codec->
dev,
"Failed to set cache I/O: %d\n", ret);
1069 switch (alc5632->
id) {
1089 .probe = alc5632_probe,
1090 .remove = alc5632_remove,
1093 .set_bias_level = alc5632_set_bias_level,
1094 .controls = alc5632_snd_controls,
1095 .num_controls =
ARRAY_SIZE(alc5632_snd_controls),
1096 .dapm_widgets = alc5632_dapm_widgets,
1097 .num_dapm_widgets =
ARRAY_SIZE(alc5632_dapm_widgets),
1098 .dapm_routes = alc5632_dapm_routes,
1099 .num_dapm_routes =
ARRAY_SIZE(alc5632_dapm_routes),
1102 static struct regmap_config alc5632_regmap = {
1107 .reg_defaults = alc5632_reg_defaults,
1108 .num_reg_defaults =
ARRAY_SIZE(alc5632_reg_defaults),
1109 .volatile_reg = alc5632_volatile_register,
1123 int ret, ret1, ret2;
1124 unsigned int vid1, vid2;
1128 if (alc5632 ==
NULL)
1131 i2c_set_clientdata(client, alc5632);
1134 if (IS_ERR(alc5632->
regmap)) {
1135 ret = PTR_ERR(alc5632->
regmap);
1136 dev_err(&client->
dev,
"regmap_init() failed: %d\n", ret);
1142 if (ret1 != 0 || ret2 != 0) {
1144 "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2);
1150 if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) {
1152 "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2);
1156 ret = alc5632_reset(alc5632->
regmap);
1158 dev_err(&client->
dev,
"Failed to issue reset\n");
1163 switch (alc5632->
id) {
1165 alc5632_dai.
name =
"alc5632-hifi";
1172 &soc_codec_device_alc5632, &alc5632_dai, 1);
1175 dev_err(&client->
dev,
"Failed to register codec: %d\n", ret);
1195 static struct i2c_driver alc5632_i2c_driver = {
1200 .probe = alc5632_i2c_probe,
1202 .id_table = alc5632_i2c_table,