1818#include <linux/mfd/rk808.h>
1919#include <linux/module.h>
2020#include <linux/of.h>
21+ #include <linux/of_gpio.h>
2122#include <linux/platform_device.h>
2223#include <linux/regmap.h>
2324#include <sound/core.h>
@@ -62,6 +63,9 @@ module_param_named(dbg_level, dbg_enable, int, 0644);
6263 */
6364#define CAPTURE_VOLUME (0x0)
6465
66+ #define CODEC_SET_SPK 1
67+ #define CODEC_SET_HP 2
68+
6569struct rk817_codec_priv {
6670 struct snd_soc_codec * codec ;
6771 struct regmap * regmap ;
@@ -77,9 +81,16 @@ struct rk817_codec_priv {
7781
7882 bool mic_in_differential ;
7983 bool pdmdata_out_enable ;
84+ bool use_ext_amplifier ;
85+ bool adc_for_loopback ;
8086
8187 long int playback_path ;
8288 long int capture_path ;
89+
90+ struct gpio_desc * spk_ctl_gpio ;
91+ struct gpio_desc * hp_ctl_gpio ;
92+ int spk_mute_delay ;
93+ int hp_mute_delay ;
8394};
8495
8596static const struct reg_default rk817_reg_defaults [] = {
@@ -216,6 +227,26 @@ static bool rk817_codec_register(struct device *dev, unsigned int reg)
216227 }
217228}
218229
230+ static int rk817_codec_ctl_gpio (struct rk817_codec_priv * rk817 ,
231+ int gpio , int level )
232+ {
233+ if ((gpio & CODEC_SET_SPK ) &&
234+ rk817 -> spk_ctl_gpio ) {
235+ gpiod_set_value (rk817 -> spk_ctl_gpio , level );
236+ DBG ("%s set spk clt %d\n" , __func__ , level );
237+ msleep (rk817 -> spk_mute_delay );
238+ }
239+
240+ if ((gpio & CODEC_SET_HP ) &&
241+ rk817 -> hp_ctl_gpio ) {
242+ gpiod_set_value (rk817 -> hp_ctl_gpio , level );
243+ DBG ("%s set hp clt %d\n" , __func__ , level );
244+ msleep (rk817 -> hp_mute_delay );
245+ }
246+
247+ return 0 ;
248+ }
249+
219250static struct rk817_reg_val_typ playback_power_up_list [] = {
220251 {RK817_CODEC_AREF_RTCFG1 , 0x40 },
221252 {RK817_CODEC_DDAC_POPD_DACST , 0x02 },
@@ -471,17 +502,29 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
471502 case RING_SPK :
472503 if (pre_path == OFF )
473504 rk817_codec_power_up (codec , RK817_CODEC_PLAYBACK );
474- /* power on dac ibias/l/r */
475- snd_soc_write (codec , RK817_CODEC_ADAC_CFG1 ,
476- PWD_DACBIAS_ON | PWD_DACD_ON |
477- PWD_DACL_ON | PWD_DACR_ON );
478- /* CLASS D mode */
479- snd_soc_write (codec , RK817_CODEC_DDAC_MUTE_MIXCTL , 0x10 );
480- /* CLASS D enable */
481- snd_soc_write (codec , RK817_CODEC_ACLASSD_CFG1 , 0xa5 );
482- /* restart CLASS D, OCPP/N */
483- snd_soc_write (codec , RK817_CODEC_ACLASSD_CFG2 , 0xc4 );
484-
505+ if (!rk817 -> use_ext_amplifier ) {
506+ /* power on dac ibias/l/r */
507+ snd_soc_write (codec , RK817_CODEC_ADAC_CFG1 ,
508+ PWD_DACBIAS_ON | PWD_DACD_ON |
509+ PWD_DACL_ON | PWD_DACR_ON );
510+ /* CLASS D mode */
511+ snd_soc_write (codec , RK817_CODEC_DDAC_MUTE_MIXCTL , 0x10 );
512+ /* CLASS D enable */
513+ snd_soc_write (codec , RK817_CODEC_ACLASSD_CFG1 , 0xa5 );
514+ /* restart CLASS D, OCPP/N */
515+ snd_soc_write (codec , RK817_CODEC_ACLASSD_CFG2 , 0xc4 );
516+ } else {
517+ /* HP_CP_EN , CP 2.3V */
518+ snd_soc_write (codec , RK817_CODEC_AHP_CP , 0x11 );
519+ /* power on HP two stage opamp ,HP amplitude 0db */
520+ snd_soc_write (codec , RK817_CODEC_AHP_CFG0 , 0x80 );
521+ /* power on dac ibias/l/r */
522+ snd_soc_write (codec , RK817_CODEC_ADAC_CFG1 ,
523+ PWD_DACBIAS_ON | PWD_DACD_DOWN |
524+ PWD_DACL_ON | PWD_DACR_ON );
525+ snd_soc_update_bits (codec , RK817_CODEC_DDAC_MUTE_MIXCTL ,
526+ DACMT_ENABLE , DACMT_DISABLE );
527+ }
485528 snd_soc_write (codec , RK817_CODEC_DDAC_VOLL , rk817 -> spk_volume );
486529 snd_soc_write (codec , RK817_CODEC_DDAC_VOLR , rk817 -> spk_volume );
487530 break ;
@@ -511,6 +554,7 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
511554 case RING_SPK_HP :
512555 if (pre_path == OFF )
513556 rk817_codec_power_up (codec , RK817_CODEC_PLAYBACK );
557+
514558 /* HP_CP_EN , CP 2.3V */
515559 snd_soc_write (codec , RK817_CODEC_AHP_CP , 0x11 );
516560 /* power on HP two stage opamp ,HP amplitude 0db */
@@ -520,12 +564,15 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
520564 snd_soc_write (codec , RK817_CODEC_ADAC_CFG1 ,
521565 PWD_DACBIAS_ON | PWD_DACD_ON |
522566 PWD_DACL_ON | PWD_DACR_ON );
523- /* CLASS D mode */
524- snd_soc_write (codec , RK817_CODEC_DDAC_MUTE_MIXCTL , 0x10 );
525- /* CLASS D enable */
526- snd_soc_write (codec , RK817_CODEC_ACLASSD_CFG1 , 0xa5 );
527- /* restart CLASS D, OCPP/N */
528- snd_soc_write (codec , RK817_CODEC_ACLASSD_CFG2 , 0xc4 );
567+
568+ if (!rk817 -> use_ext_amplifier ) {
569+ /* CLASS D mode */
570+ snd_soc_write (codec , RK817_CODEC_DDAC_MUTE_MIXCTL , 0x10 );
571+ /* CLASS D enable */
572+ snd_soc_write (codec , RK817_CODEC_ACLASSD_CFG1 , 0xa5 );
573+ /* restart CLASS D, OCPP/N */
574+ snd_soc_write (codec , RK817_CODEC_ACLASSD_CFG2 , 0xc4 );
575+ }
529576
530577 snd_soc_write (codec , RK817_CODEC_DDAC_VOLL , rk817 -> hp_volume );
531578 snd_soc_write (codec , RK817_CODEC_DDAC_VOLR , rk817 -> hp_volume );
@@ -534,6 +581,10 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
534581 return - EINVAL ;
535582 }
536583
584+ if (rk817 -> capture_path != 0 && rk817 -> pdmdata_out_enable )
585+ snd_soc_update_bits (codec , RK817_CODEC_DI2S_CKM ,
586+ PDM_EN_MASK , PDM_EN_ENABLE );
587+
537588 return 0 ;
538589}
539590
@@ -584,6 +635,14 @@ static int rk817_capture_path_put(struct snd_kcontrol *kcontrol,
584635 if (pre_path == MIC_OFF )
585636 rk817_codec_power_up (codec , RK817_CODEC_CAPTURE );
586637
638+ if (rk817 -> adc_for_loopback ) {
639+ /* don't need to gain when adc use for loopback */
640+ snd_soc_write (codec , RK817_CODEC_AMIC_CFG0 , 0x00 );
641+ snd_soc_write (codec , RK817_CODEC_DMIC_PGA_GAIN , 0x66 );
642+ snd_soc_write (codec , RK817_CODEC_DADC_VOLL , 0x00 );
643+ snd_soc_write (codec , RK817_CODEC_DADC_VOLR , 0x00 );
644+ break ;
645+ }
587646 if (!rk817 -> mic_in_differential ) {
588647 snd_soc_write (codec , RK817_CODEC_DADC_VOLR , 0xff );
589648 snd_soc_update_bits (codec , RK817_CODEC_AADC_CFG0 ,
@@ -596,13 +655,21 @@ static int rk817_capture_path_put(struct snd_kcontrol *kcontrol,
596655 if (pre_path == MIC_OFF )
597656 rk817_codec_power_up (codec , RK817_CODEC_CAPTURE );
598657
658+ if (rk817 -> adc_for_loopback ) {
659+ /* don't need to gain when adc use for loopback */
660+ snd_soc_write (codec , RK817_CODEC_AMIC_CFG0 , 0x00 );
661+ snd_soc_write (codec , RK817_CODEC_DMIC_PGA_GAIN , 0x66 );
662+ snd_soc_write (codec , RK817_CODEC_DADC_VOLL , 0x00 );
663+ snd_soc_write (codec , RK817_CODEC_DADC_VOLR , 0x00 );
664+ break ;
665+ }
599666 if (!rk817 -> mic_in_differential ) {
600667 snd_soc_write (codec , RK817_CODEC_DADC_VOLL , 0xff );
601668 snd_soc_update_bits (codec , RK817_CODEC_AADC_CFG0 ,
602669 ADC_L_PWD_MASK , ADC_L_PWD_EN );
603670 snd_soc_update_bits (codec , RK817_CODEC_AMIC_CFG0 ,
604671 PWD_PGA_L_MASK , PWD_PGA_L_EN );
605- }
672+ }
606673 break ;
607674 case BT_SCO_MIC :
608675 break ;
@@ -692,6 +759,7 @@ static int rk817_hw_params(struct snd_pcm_substream *substream,
692759static int rk817_digital_mute (struct snd_soc_dai * dai , int mute )
693760{
694761 struct snd_soc_codec * codec = dai -> codec ;
762+ struct rk817_codec_priv * rk817 = snd_soc_codec_get_drvdata (codec );
695763
696764 DBG ("%s %d\n" , __func__ , mute );
697765 if (mute )
@@ -701,6 +769,33 @@ static int rk817_digital_mute(struct snd_soc_dai *dai, int mute)
701769 snd_soc_update_bits (codec , RK817_CODEC_DDAC_MUTE_MIXCTL ,
702770 DACMT_ENABLE , DACMT_DISABLE );
703771
772+ if (mute ) {
773+ rk817_codec_ctl_gpio (rk817 , CODEC_SET_SPK , 0 );
774+ rk817_codec_ctl_gpio (rk817 , CODEC_SET_HP , 0 );
775+ } else {
776+ switch (rk817 -> playback_path ) {
777+ case SPK_PATH :
778+ case RING_SPK :
779+ rk817_codec_ctl_gpio (rk817 , CODEC_SET_SPK , 1 );
780+ rk817_codec_ctl_gpio (rk817 , CODEC_SET_HP , 0 );
781+ break ;
782+ case HP_PATH :
783+ case HP_NO_MIC :
784+ case RING_HP :
785+ case RING_HP_NO_MIC :
786+ rk817_codec_ctl_gpio (rk817 , CODEC_SET_SPK , 0 );
787+ rk817_codec_ctl_gpio (rk817 , CODEC_SET_HP , 1 );
788+ break ;
789+ case SPK_HP :
790+ case RING_SPK_HP :
791+ rk817_codec_ctl_gpio (rk817 , CODEC_SET_SPK , 1 );
792+ rk817_codec_ctl_gpio (rk817 , CODEC_SET_HP , 1 );
793+ break ;
794+ default :
795+ break ;
796+ }
797+ }
798+
704799 return 0 ;
705800}
706801
@@ -750,6 +845,26 @@ static struct snd_soc_dai_driver rk817_dai[] = {
750845 },
751846 .ops = & rk817_dai_ops ,
752847 },
848+ {
849+ .name = "rk817-voice" ,
850+ .id = RK817_VOICE ,
851+ .playback = {
852+ .stream_name = "Voice Playback" ,
853+ .channels_min = 1 ,
854+ .channels_max = 2 ,
855+ .rates = RK817_PLAYBACK_RATES ,
856+ .formats = RK817_FORMATS ,
857+ },
858+ .capture = {
859+ .stream_name = "Voice Capture" ,
860+ .channels_min = 2 ,
861+ .channels_max = 8 ,
862+ .rates = RK817_CAPTURE_RATES ,
863+ .formats = RK817_FORMATS ,
864+ },
865+ .ops = & rk817_dai_ops ,
866+ },
867+
753868};
754869
755870static int rk817_suspend (struct snd_soc_codec * codec )
@@ -837,6 +952,38 @@ static int rk817_codec_parse_dt_property(struct device *dev,
837952 return - ENODEV ;
838953 }
839954
955+ rk817 -> hp_ctl_gpio = devm_gpiod_get_optional (dev , "hp-ctl" ,
956+ GPIOD_OUT_LOW );
957+ if (!IS_ERR_OR_NULL (rk817 -> hp_ctl_gpio )) {
958+ DBG ("%s : hp-ctl-gpio %d\n" , __func__ ,
959+ desc_to_gpio (rk817 -> hp_ctl_gpio ));
960+ }
961+
962+ rk817 -> spk_ctl_gpio = devm_gpiod_get_optional (dev , "spk-ctl" ,
963+ GPIOD_OUT_LOW );
964+ if (!IS_ERR_OR_NULL (rk817 -> spk_ctl_gpio )) {
965+ DBG ("%s : spk-ctl-gpio %d\n" , __func__ ,
966+ desc_to_gpio (rk817 -> spk_ctl_gpio ));
967+ }
968+
969+ ret = of_property_read_u32 (node , "spk-mute-delay-ms" ,
970+ & rk817 -> spk_mute_delay );
971+ if (ret < 0 ) {
972+ DBG ("%s() Can not read property spk-mute-delay-ms\n" ,
973+ __func__ );
974+ rk817 -> spk_mute_delay = 0 ;
975+ }
976+
977+ ret = of_property_read_u32 (node , "hp-mute-delay-ms" ,
978+ & rk817 -> hp_mute_delay );
979+ if (ret < 0 ) {
980+ DBG ("%s() Can not read property hp-mute-delay-ms\n" ,
981+ __func__ );
982+ rk817 -> hp_mute_delay = 0 ;
983+ }
984+ DBG ("spk mute delay %dms --- hp mute delay %dms\n" ,
985+ rk817 -> spk_mute_delay , rk817 -> hp_mute_delay );
986+
840987 ret = of_property_read_u32 (node , "skp-volume" , & rk817 -> spk_volume );
841988 if (ret < 0 ) {
842989 DBG ("%s() Can not read property skp-volume\n" , __func__ );
@@ -869,6 +1016,12 @@ static int rk817_codec_parse_dt_property(struct device *dev,
8691016 rk817 -> pdmdata_out_enable =
8701017 of_property_read_bool (node , "pdmdata-out-enable" );
8711018
1019+ rk817 -> use_ext_amplifier =
1020+ of_property_read_bool (node , "use-ext-amplifier" );
1021+
1022+ rk817 -> adc_for_loopback =
1023+ of_property_read_bool (node , "adc-for-loopback" );
1024+
8721025 return 0 ;
8731026}
8741027
0 commit comments