@@ -525,6 +525,38 @@ enum {
525
525
INTERP_MIX_PATH ,
526
526
};
527
527
528
+ /* Codec supports 2 IIR filters */
529
+ enum {
530
+ IIR0 = 0 ,
531
+ IIR1 ,
532
+ IIR_MAX ,
533
+ };
534
+
535
+ /* Each IIR has 5 Filter Stages */
536
+ enum {
537
+ BAND1 = 0 ,
538
+ BAND2 ,
539
+ BAND3 ,
540
+ BAND4 ,
541
+ BAND5 ,
542
+ BAND_MAX ,
543
+ };
544
+
545
+ #define RX_MACRO_IIR_FILTER_SIZE (sizeof(u32) * BAND_MAX)
546
+
547
+ #define RX_MACRO_IIR_FILTER_CTL (xname , iidx , bidx ) \
548
+ { \
549
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
550
+ .info = rx_macro_iir_filter_info, \
551
+ .get = rx_macro_get_iir_band_audio_mixer, \
552
+ .put = rx_macro_put_iir_band_audio_mixer, \
553
+ .private_value = (unsigned long)&(struct wcd_iir_filter_ctl) { \
554
+ .iir_idx = iidx, \
555
+ .band_idx = bidx, \
556
+ .bytes_ext = {.max = RX_MACRO_IIR_FILTER_SIZE, }, \
557
+ } \
558
+ }
559
+
528
560
struct interp_sample_rate {
529
561
int sample_rate ;
530
562
int rate_val ;
@@ -581,6 +613,12 @@ struct rx_macro {
581
613
};
582
614
#define to_rx_macro (_hw ) container_of(_hw, struct rx_macro, hw)
583
615
616
+ struct wcd_iir_filter_ctl {
617
+ unsigned int iir_idx ;
618
+ unsigned int band_idx ;
619
+ struct soc_bytes_ext bytes_ext ;
620
+ };
621
+
584
622
static const DECLARE_TLV_DB_SCALE (digital_gain , -8400 , 100 , -8400 ) ;
585
623
586
624
static const char * const rx_int_mix_mux_text [] = {
@@ -2596,6 +2634,166 @@ static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w,
2596
2634
return 0 ;
2597
2635
}
2598
2636
2637
+ static int rx_macro_set_iir_gain (struct snd_soc_dapm_widget * w ,
2638
+ struct snd_kcontrol * kcontrol , int event )
2639
+ {
2640
+ struct snd_soc_component * component = snd_soc_dapm_to_component (w -> dapm );
2641
+
2642
+ switch (event ) {
2643
+ case SND_SOC_DAPM_POST_PMU : /* fall through */
2644
+ case SND_SOC_DAPM_PRE_PMD :
2645
+ if (strnstr (w -> name , "IIR0" , sizeof ("IIR0" ))) {
2646
+ snd_soc_component_write (component ,
2647
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL ,
2648
+ snd_soc_component_read (component ,
2649
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL ));
2650
+ snd_soc_component_write (component ,
2651
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL ,
2652
+ snd_soc_component_read (component ,
2653
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL ));
2654
+ snd_soc_component_write (component ,
2655
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL ,
2656
+ snd_soc_component_read (component ,
2657
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL ));
2658
+ snd_soc_component_write (component ,
2659
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL ,
2660
+ snd_soc_component_read (component ,
2661
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL ));
2662
+ } else {
2663
+ snd_soc_component_write (component ,
2664
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL ,
2665
+ snd_soc_component_read (component ,
2666
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL ));
2667
+ snd_soc_component_write (component ,
2668
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL ,
2669
+ snd_soc_component_read (component ,
2670
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL ));
2671
+ snd_soc_component_write (component ,
2672
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL ,
2673
+ snd_soc_component_read (component ,
2674
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL ));
2675
+ snd_soc_component_write (component ,
2676
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL ,
2677
+ snd_soc_component_read (component ,
2678
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL ));
2679
+ }
2680
+ break ;
2681
+ }
2682
+ return 0 ;
2683
+ }
2684
+
2685
+ static uint32_t get_iir_band_coeff (struct snd_soc_component * component ,
2686
+ int iir_idx , int band_idx , int coeff_idx )
2687
+ {
2688
+ u32 value ;
2689
+ int reg , b2_reg ;
2690
+
2691
+ /* Address does not automatically update if reading */
2692
+ reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx ;
2693
+ b2_reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx ;
2694
+
2695
+ snd_soc_component_write (component , reg ,
2696
+ ((band_idx * BAND_MAX + coeff_idx ) *
2697
+ sizeof (uint32_t )) & 0x7F );
2698
+
2699
+ value = snd_soc_component_read (component , b2_reg );
2700
+ snd_soc_component_write (component , reg ,
2701
+ ((band_idx * BAND_MAX + coeff_idx )
2702
+ * sizeof (uint32_t ) + 1 ) & 0x7F );
2703
+
2704
+ value |= (snd_soc_component_read (component , b2_reg ) << 8 );
2705
+ snd_soc_component_write (component , reg ,
2706
+ ((band_idx * BAND_MAX + coeff_idx )
2707
+ * sizeof (uint32_t ) + 2 ) & 0x7F );
2708
+
2709
+ value |= (snd_soc_component_read (component , b2_reg ) << 16 );
2710
+ snd_soc_component_write (component , reg ,
2711
+ ((band_idx * BAND_MAX + coeff_idx )
2712
+ * sizeof (uint32_t ) + 3 ) & 0x7F );
2713
+
2714
+ /* Mask bits top 2 bits since they are reserved */
2715
+ value |= (snd_soc_component_read (component , b2_reg ) << 24 );
2716
+ return value ;
2717
+ }
2718
+
2719
+ static void set_iir_band_coeff (struct snd_soc_component * component ,
2720
+ int iir_idx , int band_idx , uint32_t value )
2721
+ {
2722
+ int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx ;
2723
+
2724
+ snd_soc_component_write (component , reg , (value & 0xFF ));
2725
+ snd_soc_component_write (component , reg , (value >> 8 ) & 0xFF );
2726
+ snd_soc_component_write (component , reg , (value >> 16 ) & 0xFF );
2727
+ /* Mask top 2 bits, 7-8 are reserved */
2728
+ snd_soc_component_write (component , reg , (value >> 24 ) & 0x3F );
2729
+ }
2730
+
2731
+ static int rx_macro_put_iir_band_audio_mixer (
2732
+ struct snd_kcontrol * kcontrol ,
2733
+ struct snd_ctl_elem_value * ucontrol )
2734
+ {
2735
+ struct snd_soc_component * component =
2736
+ snd_soc_kcontrol_component (kcontrol );
2737
+ struct wcd_iir_filter_ctl * ctl =
2738
+ (struct wcd_iir_filter_ctl * )kcontrol -> private_value ;
2739
+ struct soc_bytes_ext * params = & ctl -> bytes_ext ;
2740
+ int iir_idx = ctl -> iir_idx ;
2741
+ int band_idx = ctl -> band_idx ;
2742
+ u32 coeff [BAND_MAX ];
2743
+ int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx ;
2744
+
2745
+ memcpy (& coeff [0 ], ucontrol -> value .bytes .data , params -> max );
2746
+
2747
+ /* Mask top bit it is reserved */
2748
+ /* Updates addr automatically for each B2 write */
2749
+ snd_soc_component_write (component , reg , (band_idx * BAND_MAX *
2750
+ sizeof (uint32_t )) & 0x7F );
2751
+
2752
+ set_iir_band_coeff (component , iir_idx , band_idx , coeff [0 ]);
2753
+ set_iir_band_coeff (component , iir_idx , band_idx , coeff [1 ]);
2754
+ set_iir_band_coeff (component , iir_idx , band_idx , coeff [2 ]);
2755
+ set_iir_band_coeff (component , iir_idx , band_idx , coeff [3 ]);
2756
+ set_iir_band_coeff (component , iir_idx , band_idx , coeff [4 ]);
2757
+
2758
+ return 0 ;
2759
+ }
2760
+
2761
+ static int rx_macro_get_iir_band_audio_mixer (struct snd_kcontrol * kcontrol ,
2762
+ struct snd_ctl_elem_value * ucontrol )
2763
+ {
2764
+ struct snd_soc_component * component =
2765
+ snd_soc_kcontrol_component (kcontrol );
2766
+ struct wcd_iir_filter_ctl * ctl =
2767
+ (struct wcd_iir_filter_ctl * )kcontrol -> private_value ;
2768
+ struct soc_bytes_ext * params = & ctl -> bytes_ext ;
2769
+ int iir_idx = ctl -> iir_idx ;
2770
+ int band_idx = ctl -> band_idx ;
2771
+ u32 coeff [BAND_MAX ];
2772
+
2773
+ coeff [0 ] = get_iir_band_coeff (component , iir_idx , band_idx , 0 );
2774
+ coeff [1 ] = get_iir_band_coeff (component , iir_idx , band_idx , 1 );
2775
+ coeff [2 ] = get_iir_band_coeff (component , iir_idx , band_idx , 2 );
2776
+ coeff [3 ] = get_iir_band_coeff (component , iir_idx , band_idx , 3 );
2777
+ coeff [4 ] = get_iir_band_coeff (component , iir_idx , band_idx , 4 );
2778
+
2779
+ memcpy (ucontrol -> value .bytes .data , & coeff [0 ], params -> max );
2780
+
2781
+ return 0 ;
2782
+ }
2783
+
2784
+ static int rx_macro_iir_filter_info (struct snd_kcontrol * kcontrol ,
2785
+ struct snd_ctl_elem_info * ucontrol )
2786
+ {
2787
+ struct wcd_iir_filter_ctl * ctl =
2788
+ (struct wcd_iir_filter_ctl * )kcontrol -> private_value ;
2789
+ struct soc_bytes_ext * params = & ctl -> bytes_ext ;
2790
+
2791
+ ucontrol -> type = SNDRV_CTL_ELEM_TYPE_BYTES ;
2792
+ ucontrol -> count = params -> max ;
2793
+
2794
+ return 0 ;
2795
+ }
2796
+
2599
2797
static const struct snd_kcontrol_new rx_macro_snd_controls [] = {
2600
2798
SOC_SINGLE_S8_TLV ("RX_RX0 Digital Volume" , CDC_RX_RX0_RX_VOL_CTL ,
2601
2799
-84 , 40 , digital_gain ),
@@ -2630,6 +2828,65 @@ static const struct snd_kcontrol_new rx_macro_snd_controls[] = {
2630
2828
SOC_SINGLE_EXT ("AUX_HPF Switch" , SND_SOC_NOPM , 0 , 1 , 0 ,
2631
2829
rx_macro_aux_hpf_mode_get ,
2632
2830
rx_macro_aux_hpf_mode_put ),
2831
+
2832
+ SOC_SINGLE_S8_TLV ("IIR0 INP0 Volume" ,
2833
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL , -84 , 40 ,
2834
+ digital_gain ),
2835
+ SOC_SINGLE_S8_TLV ("IIR0 INP1 Volume" ,
2836
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL , -84 , 40 ,
2837
+ digital_gain ),
2838
+ SOC_SINGLE_S8_TLV ("IIR0 INP2 Volume" ,
2839
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL , -84 , 40 ,
2840
+ digital_gain ),
2841
+ SOC_SINGLE_S8_TLV ("IIR0 INP3 Volume" ,
2842
+ CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL , -84 , 40 ,
2843
+ digital_gain ),
2844
+ SOC_SINGLE_S8_TLV ("IIR1 INP0 Volume" ,
2845
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL , -84 , 40 ,
2846
+ digital_gain ),
2847
+ SOC_SINGLE_S8_TLV ("IIR1 INP1 Volume" ,
2848
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL , -84 , 40 ,
2849
+ digital_gain ),
2850
+ SOC_SINGLE_S8_TLV ("IIR1 INP2 Volume" ,
2851
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL , -84 , 40 ,
2852
+ digital_gain ),
2853
+ SOC_SINGLE_S8_TLV ("IIR1 INP3 Volume" ,
2854
+ CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL , -84 , 40 ,
2855
+ digital_gain ),
2856
+
2857
+ SOC_SINGLE ("IIR1 Band1 Switch" , CDC_RX_SIDETONE_IIR0_IIR_CTL ,
2858
+ 0 , 1 , 0 ),
2859
+ SOC_SINGLE ("IIR1 Band2 Switch" , CDC_RX_SIDETONE_IIR0_IIR_CTL ,
2860
+ 1 , 1 , 0 ),
2861
+ SOC_SINGLE ("IIR1 Band3 Switch" , CDC_RX_SIDETONE_IIR0_IIR_CTL ,
2862
+ 2 , 1 , 0 ),
2863
+ SOC_SINGLE ("IIR1 Band4 Switch" , CDC_RX_SIDETONE_IIR0_IIR_CTL ,
2864
+ 3 , 1 , 0 ),
2865
+ SOC_SINGLE ("IIR1 Band5 Switch" , CDC_RX_SIDETONE_IIR0_IIR_CTL ,
2866
+ 4 , 1 , 0 ),
2867
+ SOC_SINGLE ("IIR2 Band1 Switch" , CDC_RX_SIDETONE_IIR1_IIR_CTL ,
2868
+ 0 , 1 , 0 ),
2869
+ SOC_SINGLE ("IIR2 Band2 Switch" , CDC_RX_SIDETONE_IIR1_IIR_CTL ,
2870
+ 1 , 1 , 0 ),
2871
+ SOC_SINGLE ("IIR2 Band3 Switch" , CDC_RX_SIDETONE_IIR1_IIR_CTL ,
2872
+ 2 , 1 , 0 ),
2873
+ SOC_SINGLE ("IIR2 Band4 Switch" , CDC_RX_SIDETONE_IIR1_IIR_CTL ,
2874
+ 3 , 1 , 0 ),
2875
+ SOC_SINGLE ("IIR2 Band5 Switch" , CDC_RX_SIDETONE_IIR1_IIR_CTL ,
2876
+ 4 , 1 , 0 ),
2877
+
2878
+ RX_MACRO_IIR_FILTER_CTL ("IIR0 Band1" , IIR0 , BAND1 ),
2879
+ RX_MACRO_IIR_FILTER_CTL ("IIR0 Band2" , IIR0 , BAND2 ),
2880
+ RX_MACRO_IIR_FILTER_CTL ("IIR0 Band3" , IIR0 , BAND3 ),
2881
+ RX_MACRO_IIR_FILTER_CTL ("IIR0 Band4" , IIR0 , BAND4 ),
2882
+ RX_MACRO_IIR_FILTER_CTL ("IIR0 Band5" , IIR0 , BAND5 ),
2883
+
2884
+ RX_MACRO_IIR_FILTER_CTL ("IIR1 Band1" , IIR1 , BAND1 ),
2885
+ RX_MACRO_IIR_FILTER_CTL ("IIR1 Band2" , IIR1 , BAND2 ),
2886
+ RX_MACRO_IIR_FILTER_CTL ("IIR1 Band3" , IIR1 , BAND3 ),
2887
+ RX_MACRO_IIR_FILTER_CTL ("IIR1 Band4" , IIR1 , BAND4 ),
2888
+ RX_MACRO_IIR_FILTER_CTL ("IIR1 Band5" , IIR1 , BAND5 ),
2889
+
2633
2890
};
2634
2891
2635
2892
static int rx_macro_enable_echo (struct snd_soc_dapm_widget * w ,
@@ -2725,6 +2982,13 @@ static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = {
2725
2982
RX_MACRO_EC2_MUX , 0 ,
2726
2983
& rx_mix_tx2_mux , rx_macro_enable_echo ,
2727
2984
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD ),
2985
+
2986
+ SND_SOC_DAPM_MIXER_E ("IIR0" , CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL ,
2987
+ 4 , 0 , NULL , 0 , rx_macro_set_iir_gain ,
2988
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD ),
2989
+ SND_SOC_DAPM_MIXER_E ("IIR1" , CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL ,
2990
+ 4 , 0 , NULL , 0 , rx_macro_set_iir_gain ,
2991
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD ),
2728
2992
SND_SOC_DAPM_MIXER ("SRC0" , CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL ,
2729
2993
4 , 0 , NULL , 0 ),
2730
2994
SND_SOC_DAPM_MIXER ("SRC1" , CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL ,
0 commit comments