@@ -814,6 +814,43 @@ static int find_sdca_control_range(struct device *dev,
814
814
return 0 ;
815
815
}
816
816
817
+ static int find_sdca_control_value (struct device * dev , struct sdca_entity * entity ,
818
+ struct fwnode_handle * control_node ,
819
+ struct sdca_control * control ,
820
+ const char * const label )
821
+ {
822
+ char property [SDCA_PROPERTY_LENGTH ];
823
+ bool global = true;
824
+ int ret , cn , i ;
825
+ u32 tmp ;
826
+
827
+ snprintf (property , sizeof (property ), "mipi-sdca-control-%s" , label );
828
+
829
+ ret = fwnode_property_read_u32 (control_node , property , & tmp );
830
+ if (ret == - EINVAL )
831
+ global = false;
832
+ else if (ret )
833
+ return ret ;
834
+
835
+ i = 0 ;
836
+ for_each_set_bit (cn , (unsigned long * )& control -> cn_list ,
837
+ BITS_PER_TYPE (control -> cn_list )) {
838
+ if (!global ) {
839
+ snprintf (property , sizeof (property ),
840
+ "mipi-sdca-control-cn-%d-%s" , cn , label );
841
+
842
+ ret = fwnode_property_read_u32 (control_node , property , & tmp );
843
+ if (ret )
844
+ return ret ;
845
+ }
846
+
847
+ control -> values [i ] = tmp ;
848
+ i ++ ;
849
+ }
850
+
851
+ return 0 ;
852
+ }
853
+
817
854
/*
818
855
* TODO: Add support for -cn- properties, allowing different channels to have
819
856
* different defaults etc.
@@ -843,44 +880,44 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
843
880
844
881
control -> layers = tmp ;
845
882
883
+ ret = fwnode_property_read_u64 (control_node , "mipi-sdca-control-cn-list" ,
884
+ & control -> cn_list );
885
+ if (ret == - EINVAL ) {
886
+ /* Spec allows not specifying cn-list if only the first number is used */
887
+ control -> cn_list = 0x1 ;
888
+ } else if (ret || !control -> cn_list ) {
889
+ dev_err (dev , "%s: control %#x: cn list missing: %d\n" ,
890
+ entity -> label , control -> sel , ret );
891
+ return ret ;
892
+ }
893
+
894
+ control -> values = devm_kzalloc (dev , hweight64 (control -> cn_list ), GFP_KERNEL );
895
+ if (!control -> values )
896
+ return - ENOMEM ;
897
+
846
898
switch (control -> mode ) {
847
899
case SDCA_ACCESS_MODE_DC :
848
- ret = fwnode_property_read_u32 (control_node ,
849
- "mipi-sdca-control-dc-value" ,
850
- & tmp );
900
+ ret = find_sdca_control_value (dev , entity , control_node , control ,
901
+ "dc-value" );
851
902
if (ret ) {
852
903
dev_err (dev , "%s: control %#x: dc value missing: %d\n" ,
853
904
entity -> label , control -> sel , ret );
854
905
return ret ;
855
906
}
856
907
857
- control -> value = tmp ;
858
908
control -> has_fixed = true;
859
909
break ;
860
910
case SDCA_ACCESS_MODE_RW :
861
911
case SDCA_ACCESS_MODE_DUAL :
862
- ret = fwnode_property_read_u32 (control_node ,
863
- "mipi-sdca-control-default-value" ,
864
- & tmp );
865
- if (!ret ) {
866
- control -> value = tmp ;
912
+ ret = find_sdca_control_value (dev , entity , control_node , control ,
913
+ "default-value" );
914
+ if (!ret )
867
915
control -> has_default = true;
868
- }
869
-
870
- ret = fwnode_property_read_u32 (control_node ,
871
- "mipi-sdca-control-fixed-value" ,
872
- & tmp );
873
- if (!ret ) {
874
- if (control -> has_default && control -> value != tmp ) {
875
- dev_err (dev ,
876
- "%s: control %#x: default and fixed value don't match\n" ,
877
- entity -> label , control -> sel );
878
- return - EINVAL ;
879
- }
880
916
881
- control -> value = tmp ;
917
+ ret = find_sdca_control_value (dev , entity , control_node , control ,
918
+ "fixed-value" );
919
+ if (!ret )
882
920
control -> has_fixed = true;
883
- }
884
921
fallthrough ;
885
922
case SDCA_ACCESS_MODE_RO :
886
923
control -> deferrable = fwnode_property_read_bool (control_node ,
@@ -897,17 +934,6 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
897
934
return ret ;
898
935
}
899
936
900
- ret = fwnode_property_read_u64 (control_node , "mipi-sdca-control-cn-list" ,
901
- & control -> cn_list );
902
- if (ret == - EINVAL ) {
903
- /* Spec allows not specifying cn-list if only the first number is used */
904
- control -> cn_list = 0x1 ;
905
- } else if (ret || !control -> cn_list ) {
906
- dev_err (dev , "%s: control %#x: cn list missing: %d\n" ,
907
- entity -> label , control -> sel , ret );
908
- return ret ;
909
- }
910
-
911
937
ret = fwnode_property_read_u32 (control_node ,
912
938
"mipi-sdca-control-interrupt-position" ,
913
939
& tmp );
@@ -923,11 +949,10 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
923
949
control -> type = find_sdca_control_datatype (entity , control );
924
950
control -> nbits = find_sdca_control_bits (entity , control );
925
951
926
- dev_info (dev , "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d value %#x %s\n" ,
952
+ dev_info (dev , "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d %s\n" ,
927
953
entity -> label , control -> label , control -> sel ,
928
954
control -> mode , control -> layers , control -> cn_list ,
929
- control -> interrupt_position , control -> value ,
930
- control -> deferrable ? "deferrable" : "" );
955
+ control -> interrupt_position , control -> deferrable ? "deferrable" : "" );
931
956
932
957
return 0 ;
933
958
}
0 commit comments