@@ -834,6 +834,8 @@ int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *funct
834834}
835835EXPORT_SYMBOL_NS (sdca_asoc_populate_dapm , "SND_SOC_SDCA" );
836836
837+ #define SCALE_FACTOR BIT(8)
838+
837839static int control_limit_kctl (struct device * dev ,
838840 struct sdca_entity * entity ,
839841 struct sdca_control * control ,
@@ -843,7 +845,6 @@ static int control_limit_kctl(struct device *dev,
843845 struct sdca_control_range * range ;
844846 int min , max , step ;
845847 unsigned int * tlv ;
846- int shift ;
847848
848849 if (control -> type != SDCA_CTL_DATATYPE_Q7P8DB )
849850 return 0 ;
@@ -863,43 +864,160 @@ static int control_limit_kctl(struct device *dev,
863864 max = sign_extend32 (max , control -> nbits - 1 );
864865
865866 /*
866- * FIXME: Only support power of 2 step sizes as this can be supported
867- * by a simple shift.
867+ * The SDCA volumes are in steps of 1/256th of a dB, so we need to
868+ * scale them to 1/100ths of a dB for the ALSA TLV.
869+ * The min and max values are in Q7.8 format, so we need to scale
870+ * them to 1/100ths of a dB.
868871 */
869- if (hweight32 (step ) != 1 ) {
870- dev_err (dev , "%s: %s: currently unsupported step size\n" ,
871- entity -> label , control -> label );
872- return - EINVAL ;
873- }
874-
875- /*
876- * The SDCA volumes are in steps of 1/256th of a dB, a step down of
877- * 64 (shift of 6) gives 1/4dB. 1/4dB is the smallest unit that is also
878- * representable in the ALSA TLVs which are in 1/100ths of a dB.
879- */
880- shift = max (ffs (step ) - 1 , 6 );
872+ min = min * 100 / SCALE_FACTOR ;
873+ max = max * 100 / SCALE_FACTOR ;
874+ step = step * 100 / SCALE_FACTOR ;
881875
882876 tlv = devm_kcalloc (dev , 4 , sizeof (* tlv ), GFP_KERNEL );
883877 if (!tlv )
884878 return - ENOMEM ;
885879
886880 tlv [0 ] = SNDRV_CTL_TLVT_DB_SCALE ;
887881 tlv [1 ] = 2 * sizeof (* tlv );
888- tlv [2 ] = ( min * 100 ) >> 8 ;
889- tlv [3 ] = (( 1 << shift ) * 100 ) >> 8 ;
882+ tlv [2 ] = min ;
883+ tlv [3 ] = step ;
890884
891- mc -> min = min >> shift ;
892- mc -> max = max >> shift ;
893- mc -> shift = shift ;
894- mc -> rshift = shift ;
895- mc -> sign_bit = 15 - shift ;
885+ mc -> min = 0 ;
886+ mc -> max = (max - min ) / step ;
896887
897888 kctl -> tlv .p = tlv ;
898889 kctl -> access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ ;
899890
900891 return 0 ;
901892}
902893
894+ // Convert Q7.8 to tlv value
895+ static int q78_to_tlv_val (int16_t q78 )
896+ {
897+ return (int )((q78 * 100 ) / SCALE_FACTOR );
898+ }
899+
900+ static short tlv_value_to_q78 (int value )
901+ {
902+ short value16 ;
903+ int tmp ;
904+ // Clamp value to representable range
905+ if (value > 127996 )
906+ value = 127996 ;
907+ else if (value < -128000 )
908+ value = -128000 ;
909+
910+ tmp = value * SCALE_FACTOR ;
911+ value16 = (short )(tmp / 1000 );
912+
913+ return value16 ;
914+ }
915+
916+ static unsigned int soc_mixer_q78_to_ctl (struct soc_mixer_control * mc ,
917+ struct snd_kcontrol * kcontrol , int val , int max )
918+ {
919+ int reg_val = 0 ;
920+ const unsigned int * tlv ;
921+ int min , step ;
922+
923+ if (mc -> invert )
924+ val = max - val ;
925+
926+ tlv = kcontrol -> tlv .p ;
927+ min = tlv [2 ];
928+ step = tlv [3 ];
929+
930+ reg_val = q78_to_tlv_val (val );
931+ reg_val = reg_val - min ;
932+ reg_val = reg_val / step ;
933+
934+ return reg_val ;
935+ }
936+
937+ static unsigned int soc_mixer_ctl_to_q78 (struct soc_mixer_control * mc ,
938+ struct snd_kcontrol * kcontrol , int val , int max )
939+ {
940+ unsigned int reg_val = 0 ;
941+ const unsigned int * tlv ;
942+ int min , step , dB ;
943+
944+ if (mc -> invert )
945+ val = max - val ;
946+
947+ tlv = kcontrol -> tlv .p ;
948+ min = tlv [2 ];
949+ step = tlv [3 ];
950+
951+ dB = min + (step * val );
952+ reg_val = tlv_value_to_q78 (dB * 10 );
953+
954+ return reg_val ;
955+ }
956+
957+ static int sdca_get_volsw (struct snd_kcontrol * kcontrol ,
958+ struct snd_ctl_elem_value * ucontrol )
959+ {
960+ struct soc_mixer_control * mc =
961+ (struct soc_mixer_control * )kcontrol -> private_value ;
962+ int max = mc -> max - mc -> min ;
963+ struct snd_soc_component * component = snd_kcontrol_chip (kcontrol );
964+ unsigned int reg_val ;
965+ int val ;
966+
967+ reg_val = snd_soc_component_read (component , mc -> reg );
968+ val = soc_mixer_q78_to_ctl (mc , kcontrol , reg_val , max );
969+
970+ ucontrol -> value .integer .value [0 ] = val ;
971+
972+ if (mc -> reg == mc -> rreg ) {
973+ val = soc_mixer_q78_to_ctl (mc , kcontrol , reg_val , max );
974+ } else {
975+ reg_val = snd_soc_component_read (component , mc -> rreg );
976+ val = soc_mixer_q78_to_ctl (mc , kcontrol , reg_val , max );
977+ }
978+
979+ ucontrol -> value .integer .value [1 ] = val ;
980+ return 0 ;
981+ }
982+
983+ static int sdca_put_volsw (struct snd_kcontrol * kcontrol ,
984+ struct snd_ctl_elem_value * ucontrol )
985+ {
986+ struct soc_mixer_control * mc =
987+ (struct soc_mixer_control * )kcontrol -> private_value ;
988+ int max = mc -> max - mc -> min ;
989+ struct snd_soc_component * component = snd_kcontrol_chip (kcontrol );
990+ unsigned int val1 , val_mask = 0xffff ;
991+ unsigned int val2 = 0 ;
992+ bool double_r = false;
993+ int ret ;
994+
995+ val1 = soc_mixer_ctl_to_q78 (mc , kcontrol , ucontrol -> value .integer .value [0 ], max );
996+
997+ if (mc -> reg == mc -> rreg ) {
998+ val1 |= soc_mixer_ctl_to_q78 (mc , kcontrol ,
999+ ucontrol -> value .integer .value [1 ], max );
1000+ } else {
1001+ val2 = soc_mixer_ctl_to_q78 (mc , kcontrol ,
1002+ ucontrol -> value .integer .value [1 ], max );
1003+ double_r = true;
1004+ }
1005+
1006+ ret = snd_soc_component_update_bits (component , mc -> reg , val_mask , val1 );
1007+ if (ret < 0 )
1008+ return ret ;
1009+
1010+ if (double_r ) {
1011+ int err = snd_soc_component_update_bits (component , mc -> rreg ,
1012+ val_mask , val2 );
1013+ /* Don't drop change flag */
1014+ if (err )
1015+ return err ;
1016+ }
1017+
1018+ return ret ;
1019+ }
1020+
9031021static int populate_control (struct device * dev ,
9041022 struct sdca_function_data * function ,
9051023 struct sdca_entity * entity ,
@@ -924,7 +1042,7 @@ static int populate_control(struct device *dev,
9241042 if (!control_name )
9251043 return - ENOMEM ;
9261044
927- mc = devm_kmalloc (dev , sizeof (* mc ), GFP_KERNEL );
1045+ mc = devm_kzalloc (dev , sizeof (* mc ), GFP_KERNEL );
9281046 if (!mc )
9291047 return - ENOMEM ;
9301048
@@ -954,8 +1072,13 @@ static int populate_control(struct device *dev,
9541072 (* kctl )-> private_value = (unsigned long )mc ;
9551073 (* kctl )-> iface = SNDRV_CTL_ELEM_IFACE_MIXER ;
9561074 (* kctl )-> info = snd_soc_info_volsw ;
957- (* kctl )-> get = snd_soc_get_volsw ;
958- (* kctl )-> put = snd_soc_put_volsw ;
1075+ if (strstr (control_name , "Volume" )) {
1076+ (* kctl )-> get = sdca_get_volsw ;
1077+ (* kctl )-> put = sdca_put_volsw ;
1078+ } else {
1079+ (* kctl )-> get = snd_soc_get_volsw ;
1080+ (* kctl )-> put = snd_soc_put_volsw ;
1081+ }
9591082
9601083 if (readonly_control (control ))
9611084 (* kctl )-> access = SNDRV_CTL_ELEM_ACCESS_READ ;
0 commit comments