@@ -74,6 +74,7 @@ struct fsl_micfil {
7474 int irq [MICFIL_IRQ_LINES ];
7575 enum quality quality ;
7676 int dc_remover ;
77+ int dc_out_remover ;
7778 int vad_init_mode ;
7879 int vad_enabled ;
7980 int vad_detected ;
@@ -315,6 +316,11 @@ static const char * const micfil_dc_remover_texts[] = {
315316 "Cut-off @152Hz" , "Bypass" ,
316317};
317318
319+ static const char * const micfil_dc_out_remover_texts [] = {
320+ "Cut-off @20Hz" , "Cut-off @13.3Hz" ,
321+ "Cut-off @40Hz" , "Bypass" ,
322+ };
323+
318324static const struct soc_enum hwvad_enable_enum =
319325 SOC_ENUM_SINGLE_EXT (ARRAY_SIZE (micfil_hwvad_enable ),
320326 micfil_hwvad_enable );
@@ -328,6 +334,9 @@ static const struct soc_enum hwvad_hpf_enum =
328334static const struct soc_enum fsl_micfil_dc_remover_enum =
329335 SOC_ENUM_SINGLE_EXT (ARRAY_SIZE (micfil_dc_remover_texts ),
330336 micfil_dc_remover_texts );
337+ static const struct soc_enum fsl_micfil_dc_out_remover_enum =
338+ SOC_ENUM_SINGLE_EXT (ARRAY_SIZE (micfil_dc_out_remover_texts ),
339+ micfil_dc_out_remover_texts );
331340
332341static int micfil_put_dc_remover_state (struct snd_kcontrol * kcontrol ,
333342 struct snd_ctl_elem_value * ucontrol )
@@ -369,6 +378,50 @@ static int micfil_get_dc_remover_state(struct snd_kcontrol *kcontrol,
369378 return 0 ;
370379}
371380
381+ static int micfil_put_dc_out_remover_state (struct snd_kcontrol * kcontrol ,
382+ struct snd_ctl_elem_value * ucontrol )
383+ {
384+ struct soc_enum * e = (struct soc_enum * )kcontrol -> private_value ;
385+ struct snd_soc_component * comp = snd_kcontrol_chip (kcontrol );
386+ struct fsl_micfil * micfil = snd_soc_component_get_drvdata (comp );
387+ unsigned int * item = ucontrol -> value .enumerated .item ;
388+ int val = snd_soc_enum_item_to_val (e , item [0 ]);
389+ int i = 0 , ret = 0 ;
390+ u32 reg_val = 0 ;
391+
392+ if (val < 0 || val > 3 )
393+ return - EINVAL ;
394+
395+ ret = pm_runtime_resume_and_get (comp -> dev );
396+ if (ret )
397+ return ret ;
398+
399+ micfil -> dc_out_remover = val ;
400+
401+ /* Calculate total value for all channels */
402+ for (i = 0 ; i < MICFIL_OUTPUT_CHANNELS ; i ++ )
403+ reg_val |= val << MICFIL_DC_CHX_SHIFT (i );
404+
405+ /* Update DC Remover mode for all channels */
406+ ret = snd_soc_component_update_bits (comp , REG_MICFIL_DC_OUT_CTRL ,
407+ MICFIL_DC_CTRL_CONFIG , reg_val );
408+
409+ pm_runtime_put_autosuspend (comp -> dev );
410+
411+ return ret ;
412+ }
413+
414+ static int micfil_get_dc_out_remover_state (struct snd_kcontrol * kcontrol ,
415+ struct snd_ctl_elem_value * ucontrol )
416+ {
417+ struct snd_soc_component * comp = snd_kcontrol_chip (kcontrol );
418+ struct fsl_micfil * micfil = snd_soc_component_get_drvdata (comp );
419+
420+ ucontrol -> value .enumerated .item [0 ] = micfil -> dc_out_remover ;
421+
422+ return 0 ;
423+ }
424+
372425static int hwvad_put_enable (struct snd_kcontrol * kcontrol ,
373426 struct snd_ctl_elem_value * ucontrol )
374427{
@@ -479,6 +532,11 @@ static const struct snd_kcontrol_new fsl_micfil_volume_sx_controls[] = {
479532 MICFIL_OUTGAIN_CHX_SHIFT (7 ), 0x8 , 0xF , gain_tlv ),
480533};
481534
535+ static const struct snd_kcontrol_new fsl_micfil_dc_out_controls [] = {
536+ SOC_ENUM_EXT ("MICFIL DC Out Remover Control" , fsl_micfil_dc_out_remover_enum ,
537+ micfil_get_dc_out_remover_state , micfil_put_dc_out_remover_state ),
538+ };
539+
482540static const struct snd_kcontrol_new fsl_micfil_snd_controls [] = {
483541 SOC_ENUM_EXT ("MICFIL Quality Select" ,
484542 fsl_micfil_quality_enum ,
@@ -995,6 +1053,19 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
9951053 }
9961054 micfil -> dc_remover = MICFIL_DC_BYPASS ;
9971055
1056+ if (micfil -> soc -> use_verid ) {
1057+ val = 0 ;
1058+ for (i = 0 ; i < MICFIL_OUTPUT_CHANNELS ; i ++ )
1059+ val |= MICFIL_DC_BYPASS << MICFIL_DC_CHX_SHIFT (i );
1060+ ret = regmap_update_bits (micfil -> regmap , REG_MICFIL_DC_OUT_CTRL ,
1061+ MICFIL_DC_CTRL_CONFIG , val );
1062+ if (ret ) {
1063+ dev_err (dev , "failed to set DC OUT Remover mode bits\n" );
1064+ return ret ;
1065+ }
1066+ micfil -> dc_out_remover = MICFIL_DC_BYPASS ;
1067+ }
1068+
9981069 snd_soc_dai_init_dma_data (cpu_dai , NULL ,
9991070 & micfil -> dma_params_rx );
10001071
@@ -1019,6 +1090,10 @@ static int fsl_micfil_component_probe(struct snd_soc_component *component)
10191090 snd_soc_add_component_controls (component , fsl_micfil_range_controls ,
10201091 ARRAY_SIZE (fsl_micfil_range_controls ));
10211092
1093+ if (micfil -> soc -> use_verid )
1094+ snd_soc_add_component_controls (component , fsl_micfil_dc_out_controls ,
1095+ ARRAY_SIZE (fsl_micfil_dc_out_controls ));
1096+
10221097 return 0 ;
10231098}
10241099
@@ -1065,6 +1140,7 @@ static const struct reg_default fsl_micfil_reg_defaults[] = {
10651140 {REG_MICFIL_DATACH6 , 0x00000000 },
10661141 {REG_MICFIL_DATACH7 , 0x00000000 },
10671142 {REG_MICFIL_DC_CTRL , 0x00000000 },
1143+ {REG_MICFIL_DC_OUT_CTRL , 0x00000000 },
10681144 {REG_MICFIL_OUT_CTRL , 0x00000000 },
10691145 {REG_MICFIL_OUT_STAT , 0x00000000 },
10701146 {REG_MICFIL_VAD0_CTRL1 , 0x00000000 },
@@ -1091,6 +1167,7 @@ static const struct reg_default fsl_micfil_reg_defaults_v2[] = {
10911167 {REG_MICFIL_DATACH6 - 0x4 , 0x00000000 },
10921168 {REG_MICFIL_DATACH7 - 0x4 , 0x00000000 },
10931169 {REG_MICFIL_DC_CTRL , 0x00000000 },
1170+ {REG_MICFIL_DC_OUT_CTRL , 0x00000000 },
10941171 {REG_MICFIL_OUT_CTRL , 0x00000000 },
10951172 {REG_MICFIL_OUT_STAT , 0x00000000 },
10961173 {REG_MICFIL_VAD0_CTRL1 , 0x00000000 },
@@ -1127,6 +1204,7 @@ static bool fsl_micfil_readable_reg(struct device *dev, unsigned int reg)
11271204 case REG_MICFIL_VAD0_NDATA :
11281205 case REG_MICFIL_VAD0_ZCD :
11291206 return true;
1207+ case REG_MICFIL_DC_OUT_CTRL :
11301208 case REG_MICFIL_FSYNC_CTRL :
11311209 case REG_MICFIL_VERID :
11321210 case REG_MICFIL_PARAM :
@@ -1158,6 +1236,7 @@ static bool fsl_micfil_writeable_reg(struct device *dev, unsigned int reg)
11581236 case REG_MICFIL_VAD0_NCONFIG :
11591237 case REG_MICFIL_VAD0_ZCD :
11601238 return true;
1239+ case REG_MICFIL_DC_OUT_CTRL :
11611240 case REG_MICFIL_FSYNC_CTRL :
11621241 if (micfil -> soc -> use_verid )
11631242 return true;
0 commit comments