@@ -786,6 +786,126 @@ int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *funct
786786}
787787EXPORT_SYMBOL_NS (sdca_asoc_populate_dapm , "SND_SOC_SDCA" );
788788
789+ static int sdca_soc_vol_reg_to_ctl (struct soc_mixer_control * mc , unsigned int reg_val ,
790+ unsigned int mask , int max )
791+ {
792+ int val = reg_val ;
793+
794+ if (WARN_ON (!mc -> step ))
795+ return - EINVAL ;
796+
797+ if (mc -> sign_bit )
798+ val = sign_extend32 (val , mc -> sign_bit );
799+
800+ val = (((val * 100 ) >> 8 ) / mc -> step );
801+
802+ val -= mc -> min ;
803+
804+ if (mc -> invert )
805+ val = max - val ;
806+
807+ return val & mask ;
808+ }
809+
810+ static unsigned int sdca_soc_vol_ctl_to_reg (struct soc_mixer_control * mc , int val ,
811+ unsigned int mask , int max )
812+ {
813+ unsigned int reg_val , ret_val ;
814+
815+ if (WARN_ON (!mc -> step ))
816+ return - EINVAL ;
817+
818+ if (mc -> invert )
819+ val = max - val ;
820+
821+ reg_val = val + mc -> min ;
822+
823+ ret_val = (((int )(((int )reg_val * mc -> step ) << 8 )) / 100 );
824+
825+ return ret_val & mask ;
826+ }
827+
828+ static int sdca_soc_put_volsw (struct snd_kcontrol * kcontrol ,
829+ struct snd_ctl_elem_value * ucontrol )
830+ {
831+ struct soc_mixer_control * mc =
832+ (struct soc_mixer_control * )kcontrol -> private_value ;
833+ struct snd_soc_component * component = snd_kcontrol_chip (kcontrol );
834+ int max = mc -> max - mc -> min ;
835+ unsigned int val1 , val2 ;
836+ bool double_r = false;
837+ unsigned int mask ;
838+ int ret ;
839+
840+ if (mc -> sign_bit )
841+ mask = GENMASK (mc -> sign_bit , 0 );
842+ else
843+ mask = GENMASK (fls (mc -> max ) - 1 , 0 );
844+
845+ val1 = sdca_soc_vol_ctl_to_reg (mc , ucontrol -> value .integer .value [0 ], mask , max );
846+
847+ if (snd_soc_volsw_is_stereo (mc )) {
848+ if (mc -> reg == mc -> rreg ) {
849+ val1 |= sdca_soc_vol_ctl_to_reg (mc ,
850+ ucontrol -> value .integer .value [1 ],
851+ mask , max );
852+ } else {
853+ val2 = sdca_soc_vol_ctl_to_reg (mc ,
854+ ucontrol -> value .integer .value [1 ],
855+ mask , max );
856+ double_r = true;
857+ }
858+ }
859+
860+ ret = snd_soc_component_update_bits (component , mc -> reg , mask , val1 );
861+ if (ret < 0 )
862+ return ret ;
863+
864+ if (double_r ) {
865+ int err = snd_soc_component_update_bits (component , mc -> rreg ,
866+ mask , val2 );
867+ if (err )
868+ return err ;
869+ }
870+
871+ return ret ;
872+ }
873+
874+ static int sdca_soc_get_volsw (struct snd_kcontrol * kcontrol ,
875+ struct snd_ctl_elem_value * ucontrol )
876+ {
877+ struct soc_mixer_control * mc =
878+ (struct soc_mixer_control * )kcontrol -> private_value ;
879+ struct snd_soc_component * component = snd_kcontrol_chip (kcontrol );
880+ int max = mc -> max - mc -> min ;
881+ unsigned int reg_val ;
882+ unsigned int mask ;
883+ int val ;
884+
885+ if (mc -> sign_bit )
886+ mask = GENMASK (mc -> sign_bit , 0 );
887+ else
888+ mask = GENMASK (fls (mc -> max ) - 1 , 0 );
889+
890+ reg_val = snd_soc_component_read (component , mc -> reg );
891+ val = sdca_soc_vol_reg_to_ctl (mc , reg_val , mask , max );
892+
893+ ucontrol -> value .integer .value [0 ] = val ;
894+
895+ if (snd_soc_volsw_is_stereo (mc )) {
896+ if (mc -> reg == mc -> rreg ) {
897+ val = sdca_soc_vol_reg_to_ctl (mc , reg_val , mask , max );
898+ } else {
899+ reg_val = snd_soc_component_read (component , mc -> rreg );
900+ val = sdca_soc_vol_reg_to_ctl (mc , reg_val , mask , max );
901+ }
902+
903+ ucontrol -> value .integer .value [1 ] = val ;
904+ }
905+
906+ return 0 ;
907+ }
908+
789909static int control_limit_kctl (struct device * dev ,
790910 struct sdca_entity * entity ,
791911 struct sdca_control * control ,
@@ -795,7 +915,6 @@ static int control_limit_kctl(struct device *dev,
795915 struct sdca_control_range * range ;
796916 int min , max , step ;
797917 unsigned int * tlv ;
798- int shift ;
799918
800919 if (control -> type != SDCA_CTL_DATATYPE_Q7P8DB )
801920 return 0 ;
@@ -814,41 +933,29 @@ static int control_limit_kctl(struct device *dev,
814933 min = sign_extend32 (min , control -> nbits - 1 );
815934 max = sign_extend32 (max , control -> nbits - 1 );
816935
817- /*
818- * FIXME: Only support power of 2 step sizes as this can be supported
819- * by a simple shift.
820- */
821- if (hweight32 (step ) != 1 ) {
822- dev_err (dev , "%s: %s: currently unsupported step size\n" ,
823- entity -> label , control -> label );
824- return - EINVAL ;
825- }
826-
827- /*
828- * The SDCA volumes are in steps of 1/256th of a dB, a step down of
829- * 64 (shift of 6) gives 1/4dB. 1/4dB is the smallest unit that is also
830- * representable in the ALSA TLVs which are in 1/100ths of a dB.
831- */
832- shift = max (ffs (step ) - 1 , 6 );
833-
834936 tlv = devm_kcalloc (dev , 4 , sizeof (* tlv ), GFP_KERNEL );
835937 if (!tlv )
836938 return - ENOMEM ;
837939
838- tlv [0 ] = SNDRV_CTL_TLVT_DB_SCALE ;
940+ tlv [0 ] = SNDRV_CTL_TLVT_DB_MINMAX ;
839941 tlv [1 ] = 2 * sizeof (* tlv );
840942 tlv [2 ] = (min * 100 ) >> 8 ;
841- tlv [3 ] = ((1 << shift ) * 100 ) >> 8 ;
943+ tlv [3 ] = (max * 100 ) >> 8 ;
944+
945+ step = (step * 100 ) >> 8 ;
842946
843- mc -> min = min >> shift ;
844- mc -> max = max >> shift ;
845- mc -> shift = shift ;
846- mc -> rshift = shift ;
847- mc -> sign_bit = 15 - shift ;
947+ mc -> min = (( int ) tlv [ 2 ] / step ) ;
948+ mc -> max = (( int ) tlv [ 3 ] / step ) ;
949+ mc -> shift = mc -> rshift = 0 ;
950+ mc -> sign_bit = 15 ;
951+ mc -> step = step ;
848952
849953 kctl -> tlv .p = tlv ;
850954 kctl -> access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ ;
851955
956+ kctl -> get = sdca_soc_get_volsw ;
957+ kctl -> put = sdca_soc_put_volsw ;
958+
852959 return 0 ;
853960}
854961
0 commit comments