aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/pmbus_core.c935
1 files changed, 421 insertions, 514 deletions
diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c
index 196ffafafd88..4e42a2994644 100644
--- a/drivers/hwmon/pmbus_core.c
+++ b/drivers/hwmon/pmbus_core.c
@@ -793,53 +793,6 @@ static void pmbus_add_label(struct pmbus_data *data,
793 data->num_labels++; 793 data->num_labels++;
794} 794}
795 795
796static const int pmbus_temp_registers[] = {
797 PMBUS_READ_TEMPERATURE_1,
798 PMBUS_READ_TEMPERATURE_2,
799 PMBUS_READ_TEMPERATURE_3
800};
801
802static const int pmbus_temp_flags[] = {
803 PMBUS_HAVE_TEMP,
804 PMBUS_HAVE_TEMP2,
805 PMBUS_HAVE_TEMP3
806};
807
808static const int pmbus_fan_registers[] = {
809 PMBUS_READ_FAN_SPEED_1,
810 PMBUS_READ_FAN_SPEED_2,
811 PMBUS_READ_FAN_SPEED_3,
812 PMBUS_READ_FAN_SPEED_4
813};
814
815static const int pmbus_fan_config_registers[] = {
816 PMBUS_FAN_CONFIG_12,
817 PMBUS_FAN_CONFIG_12,
818 PMBUS_FAN_CONFIG_34,
819 PMBUS_FAN_CONFIG_34
820};
821
822static const int pmbus_fan_status_registers[] = {
823 PMBUS_STATUS_FAN_12,
824 PMBUS_STATUS_FAN_12,
825 PMBUS_STATUS_FAN_34,
826 PMBUS_STATUS_FAN_34
827};
828
829static const u32 pmbus_fan_flags[] = {
830 PMBUS_HAVE_FAN12,
831 PMBUS_HAVE_FAN12,
832 PMBUS_HAVE_FAN34,
833 PMBUS_HAVE_FAN34
834};
835
836static const u32 pmbus_fan_status_flags[] = {
837 PMBUS_HAVE_STATUS_FAN12,
838 PMBUS_HAVE_STATUS_FAN12,
839 PMBUS_HAVE_STATUS_FAN34,
840 PMBUS_HAVE_STATUS_FAN34
841};
842
843/* 796/*
844 * Determine maximum number of sensors, booleans, and labels. 797 * Determine maximum number of sensors, booleans, and labels.
845 * To keep things simple, only make a rough high estimate. 798 * To keep things simple, only make a rough high estimate.
@@ -900,499 +853,431 @@ static void pmbus_find_max_attr(struct i2c_client *client,
900/* 853/*
901 * Search for attributes. Allocate sensors, booleans, and labels as needed. 854 * Search for attributes. Allocate sensors, booleans, and labels as needed.
902 */ 855 */
903static void pmbus_find_attributes(struct i2c_client *client,
904 struct pmbus_data *data)
905{
906 const struct pmbus_driver_info *info = data->info;
907 int page, i0, i1, in_index;
908 856
909 /* 857/*
910 * Input voltage sensors 858 * The pmbus_limit_attr structure describes a single limit attribute
911 */ 859 * and its associated alarm attribute.
912 in_index = 1; 860 */
913 if (info->func[0] & PMBUS_HAVE_VIN) { 861struct pmbus_limit_attr {
914 bool have_alarm = false; 862 u8 reg; /* Limit register */
915 863 const char *attr; /* Attribute name */
916 i0 = data->num_sensors; 864 const char *alarm; /* Alarm attribute name */
917 pmbus_add_label(data, "in", in_index, "vin", 0); 865 u32 sbit; /* Alarm attribute status bit */
918 pmbus_add_sensor(data, "in", "input", in_index, 0, 866};
919 PMBUS_READ_VIN, PSC_VOLTAGE_IN, true, true); 867
920 if (pmbus_check_word_register(client, 0, 868/*
921 PMBUS_VIN_UV_WARN_LIMIT)) { 869 * The pmbus_sensor_attr structure describes one sensor attribute. This
922 i1 = data->num_sensors; 870 * description includes a reference to the associated limit attributes.
923 pmbus_add_sensor(data, "in", "min", in_index, 871 */
924 0, PMBUS_VIN_UV_WARN_LIMIT, 872struct pmbus_sensor_attr {
925 PSC_VOLTAGE_IN, false, false); 873 u8 reg; /* sensor register */
926 if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { 874 enum pmbus_sensor_classes class;/* sensor class */
927 pmbus_add_boolean_reg(data, "in", "min_alarm", 875 const char *label; /* sensor label */
928 in_index, 876 bool paged; /* true if paged sensor */
929 PB_STATUS_INPUT_BASE, 877 bool update; /* true if update needed */
930 PB_VOLTAGE_UV_WARNING); 878 bool compare; /* true if compare function needed */
931 have_alarm = true; 879 u32 func; /* sensor mask */
932 } 880 u32 sfunc; /* sensor status mask */
933 } 881 int sbase; /* status base register */
934 if (pmbus_check_word_register(client, 0, 882 u32 gbit; /* generic status bit */
935 PMBUS_VIN_UV_FAULT_LIMIT)) { 883 const struct pmbus_limit_attr *limit;/* limit registers */
936 i1 = data->num_sensors; 884 int nlimit; /* # of limit registers */
937 pmbus_add_sensor(data, "in", "lcrit", in_index, 885};
938 0, PMBUS_VIN_UV_FAULT_LIMIT, 886
939 PSC_VOLTAGE_IN, false, false); 887/*
940 if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { 888 * Add a set of limit attributes and, if supported, the associated
941 pmbus_add_boolean_reg(data, "in", "lcrit_alarm", 889 * alarm attributes.
942 in_index, 890 */
943 PB_STATUS_INPUT_BASE, 891static bool pmbus_add_limit_attrs(struct i2c_client *client,
944 PB_VOLTAGE_UV_FAULT); 892 struct pmbus_data *data,
945 have_alarm = true; 893 const struct pmbus_driver_info *info,
946 } 894 const char *name, int index, int page,
947 } 895 int cbase,
948 if (pmbus_check_word_register(client, 0, 896 const struct pmbus_sensor_attr *attr)
949 PMBUS_VIN_OV_WARN_LIMIT)) { 897{
950 i1 = data->num_sensors; 898 const struct pmbus_limit_attr *l = attr->limit;
951 pmbus_add_sensor(data, "in", "max", in_index, 899 int nlimit = attr->nlimit;
952 0, PMBUS_VIN_OV_WARN_LIMIT, 900 bool have_alarm = false;
953 PSC_VOLTAGE_IN, false, false); 901 int i, cindex;
954 if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { 902
955 pmbus_add_boolean_reg(data, "in", "max_alarm", 903 for (i = 0; i < nlimit; i++) {
956 in_index, 904 if (pmbus_check_word_register(client, page, l->reg)) {
957 PB_STATUS_INPUT_BASE, 905 cindex = data->num_sensors;
958 PB_VOLTAGE_OV_WARNING); 906 pmbus_add_sensor(data, name, l->attr, index, page,
959 have_alarm = true; 907 l->reg, attr->class, attr->update,
960 } 908 false);
961 } 909 if (info->func[page] & attr->sfunc) {
962 if (pmbus_check_word_register(client, 0, 910 if (attr->compare) {
963 PMBUS_VIN_OV_FAULT_LIMIT)) { 911 pmbus_add_boolean_cmp(data, name,
964 i1 = data->num_sensors; 912 l->alarm, index,
965 pmbus_add_sensor(data, "in", "crit", in_index, 913 cbase, cindex,
966 0, PMBUS_VIN_OV_FAULT_LIMIT, 914 attr->sbase + page, l->sbit);
967 PSC_VOLTAGE_IN, false, false); 915 } else {
968 if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) { 916 pmbus_add_boolean_reg(data, name,
969 pmbus_add_boolean_reg(data, "in", "crit_alarm", 917 l->alarm, index,
970 in_index, 918 attr->sbase + page, l->sbit);
971 PB_STATUS_INPUT_BASE, 919 }
972 PB_VOLTAGE_OV_FAULT);
973 have_alarm = true; 920 have_alarm = true;
974 } 921 }
975 } 922 }
976 /* 923 l++;
977 * Add generic alarm attribute only if there are no individual
978 * attributes.
979 */
980 if (!have_alarm)
981 pmbus_add_boolean_reg(data, "in", "alarm",
982 in_index,
983 PB_STATUS_BASE,
984 PB_STATUS_VIN_UV);
985 in_index++;
986 }
987 if (info->func[0] & PMBUS_HAVE_VCAP) {
988 pmbus_add_label(data, "in", in_index, "vcap", 0);
989 pmbus_add_sensor(data, "in", "input", in_index, 0,
990 PMBUS_READ_VCAP, PSC_VOLTAGE_IN, true, true);
991 in_index++;
992 } 924 }
925 return have_alarm;
926}
993 927
994 /* 928static void pmbus_add_sensor_attrs_one(struct i2c_client *client,
995 * Output voltage sensors 929 struct pmbus_data *data,
996 */ 930 const struct pmbus_driver_info *info,
997 for (page = 0; page < info->pages; page++) { 931 const char *name,
998 bool have_alarm = false; 932 int index, int page,
999 933 const struct pmbus_sensor_attr *attr)
1000 if (!(info->func[page] & PMBUS_HAVE_VOUT)) 934{
1001 continue; 935 bool have_alarm;
1002 936 int cbase = data->num_sensors;
1003 i0 = data->num_sensors; 937
1004 pmbus_add_label(data, "in", in_index, "vout", page + 1); 938 if (attr->label)
1005 pmbus_add_sensor(data, "in", "input", in_index, page, 939 pmbus_add_label(data, name, index, attr->label,
1006 PMBUS_READ_VOUT, PSC_VOLTAGE_OUT, true, true); 940 attr->paged ? page + 1 : 0);
1007 if (pmbus_check_word_register(client, page, 941 pmbus_add_sensor(data, name, "input", index, page, attr->reg,
1008 PMBUS_VOUT_UV_WARN_LIMIT)) { 942 attr->class, true, true);
1009 i1 = data->num_sensors; 943 if (attr->sfunc) {
1010 pmbus_add_sensor(data, "in", "min", in_index, page, 944 have_alarm = pmbus_add_limit_attrs(client, data, info, name,
1011 PMBUS_VOUT_UV_WARN_LIMIT, 945 index, page, cbase, attr);
1012 PSC_VOLTAGE_OUT, false, false);
1013 if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
1014 pmbus_add_boolean_reg(data, "in", "min_alarm",
1015 in_index,
1016 PB_STATUS_VOUT_BASE +
1017 page,
1018 PB_VOLTAGE_UV_WARNING);
1019 have_alarm = true;
1020 }
1021 }
1022 if (pmbus_check_word_register(client, page,
1023 PMBUS_VOUT_UV_FAULT_LIMIT)) {
1024 i1 = data->num_sensors;
1025 pmbus_add_sensor(data, "in", "lcrit", in_index, page,
1026 PMBUS_VOUT_UV_FAULT_LIMIT,
1027 PSC_VOLTAGE_OUT, false, false);
1028 if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
1029 pmbus_add_boolean_reg(data, "in", "lcrit_alarm",
1030 in_index,
1031 PB_STATUS_VOUT_BASE +
1032 page,
1033 PB_VOLTAGE_UV_FAULT);
1034 have_alarm = true;
1035 }
1036 }
1037 if (pmbus_check_word_register(client, page,
1038 PMBUS_VOUT_OV_WARN_LIMIT)) {
1039 i1 = data->num_sensors;
1040 pmbus_add_sensor(data, "in", "max", in_index, page,
1041 PMBUS_VOUT_OV_WARN_LIMIT,
1042 PSC_VOLTAGE_OUT, false, false);
1043 if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
1044 pmbus_add_boolean_reg(data, "in", "max_alarm",
1045 in_index,
1046 PB_STATUS_VOUT_BASE +
1047 page,
1048 PB_VOLTAGE_OV_WARNING);
1049 have_alarm = true;
1050 }
1051 }
1052 if (pmbus_check_word_register(client, page,
1053 PMBUS_VOUT_OV_FAULT_LIMIT)) {
1054 i1 = data->num_sensors;
1055 pmbus_add_sensor(data, "in", "crit", in_index, page,
1056 PMBUS_VOUT_OV_FAULT_LIMIT,
1057 PSC_VOLTAGE_OUT, false, false);
1058 if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
1059 pmbus_add_boolean_reg(data, "in", "crit_alarm",
1060 in_index,
1061 PB_STATUS_VOUT_BASE +
1062 page,
1063 PB_VOLTAGE_OV_FAULT);
1064 have_alarm = true;
1065 }
1066 }
1067 /* 946 /*
1068 * Add generic alarm attribute only if there are no individual 947 * Add generic alarm attribute only if there are no individual
1069 * attributes. 948 * alarm attributes, and if there is a global alarm bit.
1070 */ 949 */
1071 if (!have_alarm) 950 if (!have_alarm && attr->gbit)
1072 pmbus_add_boolean_reg(data, "in", "alarm", 951 pmbus_add_boolean_reg(data, name, "alarm", index,
1073 in_index,
1074 PB_STATUS_BASE + page, 952 PB_STATUS_BASE + page,
1075 PB_STATUS_VOUT_OV); 953 attr->gbit);
1076 in_index++;
1077 } 954 }
955}
1078 956
1079 /* 957static void pmbus_add_sensor_attrs(struct i2c_client *client,
1080 * Current sensors 958 struct pmbus_data *data,
1081 */ 959 const char *name,
960 const struct pmbus_sensor_attr *attrs,
961 int nattrs)
962{
963 const struct pmbus_driver_info *info = data->info;
964 int index, i;
1082 965
1083 /* 966 index = 1;
1084 * Input current sensors 967 for (i = 0; i < nattrs; i++) {
1085 */ 968 int page, pages;
1086 in_index = 1; 969
1087 if (info->func[0] & PMBUS_HAVE_IIN) { 970 pages = attrs->paged ? info->pages : 1;
1088 i0 = data->num_sensors; 971 for (page = 0; page < pages; page++) {
1089 pmbus_add_label(data, "curr", in_index, "iin", 0); 972 if (!(info->func[page] & attrs->func))
1090 pmbus_add_sensor(data, "curr", "input", in_index, 0, 973 continue;
1091 PMBUS_READ_IIN, PSC_CURRENT_IN, true, true); 974 pmbus_add_sensor_attrs_one(client, data, info, name,
1092 if (pmbus_check_word_register(client, 0, 975 index, page, attrs);
1093 PMBUS_IIN_OC_WARN_LIMIT)) { 976 index++;
1094 i1 = data->num_sensors;
1095 pmbus_add_sensor(data, "curr", "max", in_index,
1096 0, PMBUS_IIN_OC_WARN_LIMIT,
1097 PSC_CURRENT_IN, false, false);
1098 if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
1099 pmbus_add_boolean_reg(data, "curr", "max_alarm",
1100 in_index,
1101 PB_STATUS_INPUT_BASE,
1102 PB_IIN_OC_WARNING);
1103 }
1104 }
1105 if (pmbus_check_word_register(client, 0,
1106 PMBUS_IIN_OC_FAULT_LIMIT)) {
1107 i1 = data->num_sensors;
1108 pmbus_add_sensor(data, "curr", "crit", in_index,
1109 0, PMBUS_IIN_OC_FAULT_LIMIT,
1110 PSC_CURRENT_IN, false, false);
1111 if (info->func[0] & PMBUS_HAVE_STATUS_INPUT)
1112 pmbus_add_boolean_reg(data, "curr",
1113 "crit_alarm",
1114 in_index,
1115 PB_STATUS_INPUT_BASE,
1116 PB_IIN_OC_FAULT);
1117 } 977 }
1118 in_index++; 978 attrs++;
1119 } 979 }
980}
1120 981
1121 /* 982static const struct pmbus_limit_attr vin_limit_attrs[] = {
1122 * Output current sensors 983 {
1123 */ 984 .reg = PMBUS_VIN_UV_WARN_LIMIT,
1124 for (page = 0; page < info->pages; page++) { 985 .attr = "min",
1125 bool have_alarm = false; 986 .alarm = "min_alarm",
1126 987 .sbit = PB_VOLTAGE_UV_WARNING,
1127 if (!(info->func[page] & PMBUS_HAVE_IOUT)) 988 }, {
1128 continue; 989 .reg = PMBUS_VIN_UV_FAULT_LIMIT,
1129 990 .attr = "lcrit",
1130 i0 = data->num_sensors; 991 .alarm = "lcrit_alarm",
1131 pmbus_add_label(data, "curr", in_index, "iout", page + 1); 992 .sbit = PB_VOLTAGE_UV_FAULT,
1132 pmbus_add_sensor(data, "curr", "input", in_index, page, 993 }, {
1133 PMBUS_READ_IOUT, PSC_CURRENT_OUT, true, true); 994 .reg = PMBUS_VIN_OV_WARN_LIMIT,
1134 if (pmbus_check_word_register(client, page, 995 .attr = "max",
1135 PMBUS_IOUT_OC_WARN_LIMIT)) { 996 .alarm = "max_alarm",
1136 i1 = data->num_sensors; 997 .sbit = PB_VOLTAGE_OV_WARNING,
1137 pmbus_add_sensor(data, "curr", "max", in_index, page, 998 }, {
1138 PMBUS_IOUT_OC_WARN_LIMIT, 999 .reg = PMBUS_VIN_OV_FAULT_LIMIT,
1139 PSC_CURRENT_OUT, false, false); 1000 .attr = "crit",
1140 if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) { 1001 .alarm = "crit_alarm",
1141 pmbus_add_boolean_reg(data, "curr", "max_alarm", 1002 .sbit = PB_VOLTAGE_OV_FAULT,
1142 in_index, 1003 },
1143 PB_STATUS_IOUT_BASE + 1004};
1144 page, PB_IOUT_OC_WARNING); 1005
1145 have_alarm = true; 1006static const struct pmbus_limit_attr vout_limit_attrs[] = {
1146 } 1007 {
1147 } 1008 .reg = PMBUS_VOUT_UV_WARN_LIMIT,
1148 if (pmbus_check_word_register(client, page, 1009 .attr = "min",
1149 PMBUS_IOUT_UC_FAULT_LIMIT)) { 1010 .alarm = "min_alarm",
1150 i1 = data->num_sensors; 1011 .sbit = PB_VOLTAGE_UV_WARNING,
1151 pmbus_add_sensor(data, "curr", "lcrit", in_index, page, 1012 }, {
1152 PMBUS_IOUT_UC_FAULT_LIMIT, 1013 .reg = PMBUS_VOUT_UV_FAULT_LIMIT,
1153 PSC_CURRENT_OUT, false, false); 1014 .attr = "lcrit",
1154 if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) { 1015 .alarm = "lcrit_alarm",
1155 pmbus_add_boolean_reg(data, "curr", 1016 .sbit = PB_VOLTAGE_UV_FAULT,
1156 "lcrit_alarm", 1017 }, {
1157 in_index, 1018 .reg = PMBUS_VOUT_OV_WARN_LIMIT,
1158 PB_STATUS_IOUT_BASE + 1019 .attr = "max",
1159 page, PB_IOUT_UC_FAULT); 1020 .alarm = "max_alarm",
1160 have_alarm = true; 1021 .sbit = PB_VOLTAGE_OV_WARNING,
1161 } 1022 }, {
1162 } 1023 .reg = PMBUS_VOUT_OV_FAULT_LIMIT,
1163 if (pmbus_check_word_register(client, page, 1024 .attr = "crit",
1164 PMBUS_IOUT_OC_FAULT_LIMIT)) { 1025 .alarm = "crit_alarm",
1165 i1 = data->num_sensors; 1026 .sbit = PB_VOLTAGE_OV_FAULT,
1166 pmbus_add_sensor(data, "curr", "crit", in_index, page,
1167 PMBUS_IOUT_OC_FAULT_LIMIT,
1168 PSC_CURRENT_OUT, false, false);
1169 if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) {
1170 pmbus_add_boolean_reg(data, "curr",
1171 "crit_alarm",
1172 in_index,
1173 PB_STATUS_IOUT_BASE +
1174 page, PB_IOUT_OC_FAULT);
1175 have_alarm = true;
1176 }
1177 }
1178 /*
1179 * Add generic alarm attribute only if there are no individual
1180 * attributes.
1181 */
1182 if (!have_alarm)
1183 pmbus_add_boolean_reg(data, "curr", "alarm",
1184 in_index,
1185 PB_STATUS_BASE + page,
1186 PB_STATUS_IOUT_OC);
1187 in_index++;
1188 } 1027 }
1028};
1189 1029
1190 /* 1030static const struct pmbus_sensor_attr voltage_attributes[] = {
1191 * Power sensors 1031 {
1192 */ 1032 .reg = PMBUS_READ_VIN,
1193 /* 1033 .class = PSC_VOLTAGE_IN,
1194 * Input Power sensors 1034 .label = "vin",
1195 */ 1035 .func = PMBUS_HAVE_VIN,
1196 in_index = 1; 1036 .sfunc = PMBUS_HAVE_STATUS_INPUT,
1197 if (info->func[0] & PMBUS_HAVE_PIN) { 1037 .sbase = PB_STATUS_INPUT_BASE,
1198 i0 = data->num_sensors; 1038 .gbit = PB_STATUS_VIN_UV,
1199 pmbus_add_label(data, "power", in_index, "pin", 0); 1039 .limit = vin_limit_attrs,
1200 pmbus_add_sensor(data, "power", "input", in_index, 1040 .nlimit = ARRAY_SIZE(vin_limit_attrs),
1201 0, PMBUS_READ_PIN, PSC_POWER, true, true); 1041 }, {
1202 if (pmbus_check_word_register(client, 0, 1042 .reg = PMBUS_READ_VCAP,
1203 PMBUS_PIN_OP_WARN_LIMIT)) { 1043 .class = PSC_VOLTAGE_IN,
1204 i1 = data->num_sensors; 1044 .label = "vcap",
1205 pmbus_add_sensor(data, "power", "max", in_index, 1045 .func = PMBUS_HAVE_VCAP,
1206 0, PMBUS_PIN_OP_WARN_LIMIT, PSC_POWER, 1046 }, {
1207 false, false); 1047 .reg = PMBUS_READ_VOUT,
1208 if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) 1048 .class = PSC_VOLTAGE_OUT,
1209 pmbus_add_boolean_reg(data, "power", 1049 .label = "vout",
1210 "alarm", 1050 .paged = true,
1211 in_index, 1051 .func = PMBUS_HAVE_VOUT,
1212 PB_STATUS_INPUT_BASE, 1052 .sfunc = PMBUS_HAVE_STATUS_VOUT,
1213 PB_PIN_OP_WARNING); 1053 .sbase = PB_STATUS_VOUT_BASE,
1214 } 1054 .gbit = PB_STATUS_VOUT_OV,
1215 in_index++; 1055 .limit = vout_limit_attrs,
1056 .nlimit = ARRAY_SIZE(vout_limit_attrs),
1216 } 1057 }
1058};
1217 1059
1218 /* 1060/* Current attributes */
1219 * Output Power sensors 1061
1220 */ 1062static const struct pmbus_limit_attr iin_limit_attrs[] = {
1221 for (page = 0; page < info->pages; page++) { 1063 {
1222 bool need_alarm = false; 1064 .reg = PMBUS_IIN_OC_WARN_LIMIT,
1065 .attr = "max",
1066 .alarm = "max_alarm",
1067 .sbit = PB_IIN_OC_WARNING,
1068 }, {
1069 .reg = PMBUS_IIN_OC_FAULT_LIMIT,
1070 .attr = "crit",
1071 .alarm = "crit_alarm",
1072 .sbit = PB_IIN_OC_FAULT,
1073 }
1074};
1223 1075
1224 if (!(info->func[page] & PMBUS_HAVE_POUT)) 1076static const struct pmbus_limit_attr iout_limit_attrs[] = {
1225 continue; 1077 {
1078 .reg = PMBUS_IOUT_OC_WARN_LIMIT,
1079 .attr = "max",
1080 .alarm = "max_alarm",
1081 .sbit = PB_IOUT_OC_WARNING,
1082 }, {
1083 .reg = PMBUS_IOUT_UC_FAULT_LIMIT,
1084 .attr = "lcrit",
1085 .alarm = "lcrit_alarm",
1086 .sbit = PB_IOUT_UC_FAULT,
1087 }, {
1088 .reg = PMBUS_IOUT_OC_FAULT_LIMIT,
1089 .attr = "crit",
1090 .alarm = "crit_alarm",
1091 .sbit = PB_IOUT_OC_FAULT,
1092 }
1093};
1226 1094
1227 i0 = data->num_sensors; 1095static const struct pmbus_sensor_attr current_attributes[] = {
1228 pmbus_add_label(data, "power", in_index, "pout", page + 1); 1096 {
1229 pmbus_add_sensor(data, "power", "input", in_index, page, 1097 .reg = PMBUS_READ_IIN,
1230 PMBUS_READ_POUT, PSC_POWER, true, true); 1098 .class = PSC_CURRENT_IN,
1231 /* 1099 .label = "iin",
1232 * Per hwmon sysfs API, power_cap is to be used to limit output 1100 .func = PMBUS_HAVE_IIN,
1233 * power. 1101 .sfunc = PMBUS_HAVE_STATUS_INPUT,
1234 * We have two registers related to maximum output power, 1102 .sbase = PB_STATUS_INPUT_BASE,
1235 * PMBUS_POUT_MAX and PMBUS_POUT_OP_WARN_LIMIT. 1103 .limit = iin_limit_attrs,
1236 * PMBUS_POUT_MAX matches the powerX_cap attribute definition. 1104 .nlimit = ARRAY_SIZE(iin_limit_attrs),
1237 * There is no attribute in the API to match 1105 }, {
1238 * PMBUS_POUT_OP_WARN_LIMIT. We use powerX_max for now. 1106 .reg = PMBUS_READ_IOUT,
1239 */ 1107 .class = PSC_CURRENT_OUT,
1240 if (pmbus_check_word_register(client, page, PMBUS_POUT_MAX)) { 1108 .label = "iout",
1241 i1 = data->num_sensors; 1109 .paged = true,
1242 pmbus_add_sensor(data, "power", "cap", in_index, page, 1110 .func = PMBUS_HAVE_IOUT,
1243 PMBUS_POUT_MAX, PSC_POWER, 1111 .sfunc = PMBUS_HAVE_STATUS_IOUT,
1244 false, false); 1112 .sbase = PB_STATUS_IOUT_BASE,
1245 need_alarm = true; 1113 .gbit = PB_STATUS_IOUT_OC,
1246 } 1114 .limit = iout_limit_attrs,
1247 if (pmbus_check_word_register(client, page, 1115 .nlimit = ARRAY_SIZE(iout_limit_attrs),
1248 PMBUS_POUT_OP_WARN_LIMIT)) {
1249 i1 = data->num_sensors;
1250 pmbus_add_sensor(data, "power", "max", in_index, page,
1251 PMBUS_POUT_OP_WARN_LIMIT, PSC_POWER,
1252 false, false);
1253 need_alarm = true;
1254 }
1255 if (need_alarm && (info->func[page] & PMBUS_HAVE_STATUS_IOUT))
1256 pmbus_add_boolean_reg(data, "power", "alarm",
1257 in_index,
1258 PB_STATUS_IOUT_BASE + page,
1259 PB_POUT_OP_WARNING
1260 | PB_POWER_LIMITING);
1261
1262 if (pmbus_check_word_register(client, page,
1263 PMBUS_POUT_OP_FAULT_LIMIT)) {
1264 i1 = data->num_sensors;
1265 pmbus_add_sensor(data, "power", "crit", in_index, page,
1266 PMBUS_POUT_OP_FAULT_LIMIT, PSC_POWER,
1267 false, false);
1268 if (info->func[page] & PMBUS_HAVE_STATUS_IOUT)
1269 pmbus_add_boolean_reg(data, "power",
1270 "crit_alarm",
1271 in_index,
1272 PB_STATUS_IOUT_BASE
1273 + page,
1274 PB_POUT_OP_FAULT);
1275 }
1276 in_index++;
1277 } 1116 }
1117};
1278 1118
1279 /* 1119/* Power attributes */
1280 * Temperature sensors
1281 */
1282 in_index = 1;
1283 for (page = 0; page < info->pages; page++) {
1284 int t;
1285 1120
1286 for (t = 0; t < ARRAY_SIZE(pmbus_temp_registers); t++) { 1121static const struct pmbus_limit_attr pin_limit_attrs[] = {
1287 bool have_alarm = false; 1122 {
1123 .reg = PMBUS_PIN_OP_WARN_LIMIT,
1124 .attr = "max",
1125 .alarm = "alarm",
1126 .sbit = PB_PIN_OP_WARNING,
1127 }
1128};
1288 1129
1289 /* 1130static const struct pmbus_limit_attr pout_limit_attrs[] = {
1290 * A PMBus chip may support any combination of 1131 {
1291 * temperature registers on any page. So we can not 1132 .reg = PMBUS_POUT_MAX,
1292 * abort after a failure to detect a register, but have 1133 .attr = "cap",
1293 * to continue checking for all registers on all pages. 1134 .alarm = "cap_alarm",
1294 */ 1135 .sbit = PB_POWER_LIMITING,
1295 if (!(info->func[page] & pmbus_temp_flags[t])) 1136 }, {
1296 continue; 1137 .reg = PMBUS_POUT_OP_WARN_LIMIT,
1138 .attr = "max",
1139 .alarm = "max_alarm",
1140 .sbit = PB_POUT_OP_WARNING,
1141 }, {
1142 .reg = PMBUS_POUT_OP_FAULT_LIMIT,
1143 .attr = "crit",
1144 .alarm = "crit_alarm",
1145 .sbit = PB_POUT_OP_FAULT,
1146 }
1147};
1297 1148
1298 if (!pmbus_check_word_register 1149static const struct pmbus_sensor_attr power_attributes[] = {
1299 (client, page, pmbus_temp_registers[t])) 1150 {
1300 continue; 1151 .reg = PMBUS_READ_PIN,
1152 .class = PSC_POWER,
1153 .label = "pin",
1154 .func = PMBUS_HAVE_PIN,
1155 .sfunc = PMBUS_HAVE_STATUS_INPUT,
1156 .sbase = PB_STATUS_INPUT_BASE,
1157 .limit = pin_limit_attrs,
1158 .nlimit = ARRAY_SIZE(pin_limit_attrs),
1159 }, {
1160 .reg = PMBUS_READ_POUT,
1161 .class = PSC_POWER,
1162 .label = "pout",
1163 .paged = true,
1164 .func = PMBUS_HAVE_POUT,
1165 .sfunc = PMBUS_HAVE_STATUS_IOUT,
1166 .sbase = PB_STATUS_IOUT_BASE,
1167 .limit = pout_limit_attrs,
1168 .nlimit = ARRAY_SIZE(pout_limit_attrs),
1169 }
1170};
1301 1171
1302 i0 = data->num_sensors; 1172/* Temperature atributes */
1303 pmbus_add_sensor(data, "temp", "input", in_index, page, 1173
1304 pmbus_temp_registers[t], 1174static const struct pmbus_limit_attr temp_limit_attrs[] = {
1305 PSC_TEMPERATURE, true, true); 1175 {
1176 .reg = PMBUS_UT_WARN_LIMIT,
1177 .attr = "min",
1178 .alarm = "min_alarm",
1179 .sbit = PB_TEMP_UT_WARNING,
1180 }, {
1181 .reg = PMBUS_UT_FAULT_LIMIT,
1182 .attr = "lcrit",
1183 .alarm = "lcrit_alarm",
1184 .sbit = PB_TEMP_UT_FAULT,
1185 }, {
1186 .reg = PMBUS_OT_WARN_LIMIT,
1187 .attr = "max",
1188 .alarm = "max_alarm",
1189 .sbit = PB_TEMP_OT_WARNING,
1190 }, {
1191 .reg = PMBUS_OT_FAULT_LIMIT,
1192 .attr = "crit",
1193 .alarm = "crit_alarm",
1194 .sbit = PB_TEMP_OT_FAULT,
1195 }
1196};
1306 1197
1307 /* 1198static const struct pmbus_sensor_attr temp_attributes[] = {
1308 * PMBus provides only one status register for TEMP1-3. 1199 {
1309 * Thus, we can not use the status register to determine 1200 .reg = PMBUS_READ_TEMPERATURE_1,
1310 * which of the three sensors actually caused an alarm. 1201 .class = PSC_TEMPERATURE,
1311 * Always compare current temperature against the limit 1202 .paged = true,
1312 * registers to determine alarm conditions for a 1203 .update = true,
1313 * specific sensor. 1204 .compare = true,
1314 * 1205 .func = PMBUS_HAVE_TEMP,
1315 * Since there is only one set of limit registers for 1206 .sfunc = PMBUS_HAVE_STATUS_TEMP,
1316 * up to three temperature sensors, we need to update 1207 .sbase = PB_STATUS_TEMP_BASE,
1317 * all limit registers after the limit was changed for 1208 .gbit = PB_STATUS_TEMPERATURE,
1318 * one of the sensors. This ensures that correct limits 1209 .limit = temp_limit_attrs,
1319 * are reported for all temperature sensors. 1210 .nlimit = ARRAY_SIZE(temp_limit_attrs),
1320 */ 1211 }, {
1321 if (pmbus_check_word_register 1212 .reg = PMBUS_READ_TEMPERATURE_2,
1322 (client, page, PMBUS_UT_WARN_LIMIT)) { 1213 .class = PSC_TEMPERATURE,
1323 i1 = data->num_sensors; 1214 .paged = true,
1324 pmbus_add_sensor(data, "temp", "min", in_index, 1215 .update = true,
1325 page, PMBUS_UT_WARN_LIMIT, 1216 .compare = true,
1326 PSC_TEMPERATURE, true, false); 1217 .func = PMBUS_HAVE_TEMP2,
1327 if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { 1218 .sfunc = PMBUS_HAVE_STATUS_TEMP,
1328 pmbus_add_boolean_cmp(data, "temp", 1219 .sbase = PB_STATUS_TEMP_BASE,
1329 "min_alarm", in_index, i1, i0, 1220 .gbit = PB_STATUS_TEMPERATURE,
1330 PB_STATUS_TEMP_BASE + page, 1221 .limit = temp_limit_attrs,
1331 PB_TEMP_UT_WARNING); 1222 .nlimit = ARRAY_SIZE(temp_limit_attrs),
1332 have_alarm = true; 1223 }, {
1333 } 1224 .reg = PMBUS_READ_TEMPERATURE_3,
1334 } 1225 .class = PSC_TEMPERATURE,
1335 if (pmbus_check_word_register(client, page, 1226 .paged = true,
1336 PMBUS_UT_FAULT_LIMIT)) { 1227 .update = true,
1337 i1 = data->num_sensors; 1228 .compare = true,
1338 pmbus_add_sensor(data, "temp", "lcrit", 1229 .func = PMBUS_HAVE_TEMP3,
1339 in_index, page, 1230 .sfunc = PMBUS_HAVE_STATUS_TEMP,
1340 PMBUS_UT_FAULT_LIMIT, 1231 .sbase = PB_STATUS_TEMP_BASE,
1341 PSC_TEMPERATURE, true, false); 1232 .gbit = PB_STATUS_TEMPERATURE,
1342 if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) { 1233 .limit = temp_limit_attrs,
1343 pmbus_add_boolean_cmp(data, "temp", 1234 .nlimit = ARRAY_SIZE(temp_limit_attrs),
1344 "lcrit_alarm", in_index, i1, i0,
1345 PB_STATUS_TEMP_BASE + page,
1346 PB_TEMP_UT_FAULT);
1347 have_alarm = true;
1348 }
1349 }
1350 if (pmbus_check_word_register
1351 (client, page, PMBUS_OT_WARN_LIMIT)) {
1352 i1 = data->num_sensors;
1353 pmbus_add_sensor(data, "temp", "max", in_index,
1354 page, PMBUS_OT_WARN_LIMIT,
1355 PSC_TEMPERATURE, true, false);
1356 if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
1357 pmbus_add_boolean_cmp(data, "temp",
1358 "max_alarm", in_index, i0, i1,
1359 PB_STATUS_TEMP_BASE + page,
1360 PB_TEMP_OT_WARNING);
1361 have_alarm = true;
1362 }
1363 }
1364 if (pmbus_check_word_register(client, page,
1365 PMBUS_OT_FAULT_LIMIT)) {
1366 i1 = data->num_sensors;
1367 pmbus_add_sensor(data, "temp", "crit", in_index,
1368 page, PMBUS_OT_FAULT_LIMIT,
1369 PSC_TEMPERATURE, true, false);
1370 if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
1371 pmbus_add_boolean_cmp(data, "temp",
1372 "crit_alarm", in_index, i0, i1,
1373 PB_STATUS_TEMP_BASE + page,
1374 PB_TEMP_OT_FAULT);
1375 have_alarm = true;
1376 }
1377 }
1378 /*
1379 * Last resort - we were not able to create any alarm
1380 * registers. Report alarm for all sensors using the
1381 * status register temperature alarm bit.
1382 */
1383 if (!have_alarm)
1384 pmbus_add_boolean_reg(data, "temp", "alarm",
1385 in_index,
1386 PB_STATUS_BASE + page,
1387 PB_STATUS_TEMPERATURE);
1388 in_index++;
1389 }
1390 } 1235 }
1236};
1237
1238static const int pmbus_fan_registers[] = {
1239 PMBUS_READ_FAN_SPEED_1,
1240 PMBUS_READ_FAN_SPEED_2,
1241 PMBUS_READ_FAN_SPEED_3,
1242 PMBUS_READ_FAN_SPEED_4
1243};
1244
1245static const int pmbus_fan_config_registers[] = {
1246 PMBUS_FAN_CONFIG_12,
1247 PMBUS_FAN_CONFIG_12,
1248 PMBUS_FAN_CONFIG_34,
1249 PMBUS_FAN_CONFIG_34
1250};
1251
1252static const int pmbus_fan_status_registers[] = {
1253 PMBUS_STATUS_FAN_12,
1254 PMBUS_STATUS_FAN_12,
1255 PMBUS_STATUS_FAN_34,
1256 PMBUS_STATUS_FAN_34
1257};
1258
1259static const u32 pmbus_fan_flags[] = {
1260 PMBUS_HAVE_FAN12,
1261 PMBUS_HAVE_FAN12,
1262 PMBUS_HAVE_FAN34,
1263 PMBUS_HAVE_FAN34
1264};
1265
1266static const u32 pmbus_fan_status_flags[] = {
1267 PMBUS_HAVE_STATUS_FAN12,
1268 PMBUS_HAVE_STATUS_FAN12,
1269 PMBUS_HAVE_STATUS_FAN34,
1270 PMBUS_HAVE_STATUS_FAN34
1271};
1272
1273/* Fans */
1274static void pmbus_add_fan_attributes(struct i2c_client *client,
1275 struct pmbus_data *data)
1276{
1277 const struct pmbus_driver_info *info = data->info;
1278 int index = 1;
1279 int page;
1391 1280
1392 /*
1393 * Fans
1394 */
1395 in_index = 1;
1396 for (page = 0; page < info->pages; page++) { 1281 for (page = 0; page < info->pages; page++) {
1397 int f; 1282 int f;
1398 1283
@@ -1419,8 +1304,7 @@ static void pmbus_find_attributes(struct i2c_client *client,
1419 (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) 1304 (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4)))))
1420 continue; 1305 continue;
1421 1306
1422 i0 = data->num_sensors; 1307 pmbus_add_sensor(data, "fan", "input", index, page,
1423 pmbus_add_sensor(data, "fan", "input", in_index, page,
1424 pmbus_fan_registers[f], PSC_FAN, true, 1308 pmbus_fan_registers[f], PSC_FAN, true,
1425 true); 1309 true);
1426 1310
@@ -1438,17 +1322,40 @@ static void pmbus_find_attributes(struct i2c_client *client,
1438 else 1322 else
1439 base = PB_STATUS_FAN_BASE + page; 1323 base = PB_STATUS_FAN_BASE + page;
1440 pmbus_add_boolean_reg(data, "fan", "alarm", 1324 pmbus_add_boolean_reg(data, "fan", "alarm",
1441 in_index, base, 1325 index, base,
1442 PB_FAN_FAN1_WARNING >> (f & 1)); 1326 PB_FAN_FAN1_WARNING >> (f & 1));
1443 pmbus_add_boolean_reg(data, "fan", "fault", 1327 pmbus_add_boolean_reg(data, "fan", "fault",
1444 in_index, base, 1328 index, base,
1445 PB_FAN_FAN1_FAULT >> (f & 1)); 1329 PB_FAN_FAN1_FAULT >> (f & 1));
1446 } 1330 }
1447 in_index++; 1331 index++;
1448 } 1332 }
1449 } 1333 }
1450} 1334}
1451 1335
1336static void pmbus_find_attributes(struct i2c_client *client,
1337 struct pmbus_data *data)
1338{
1339 /* Voltage sensors */
1340 pmbus_add_sensor_attrs(client, data, "in", voltage_attributes,
1341 ARRAY_SIZE(voltage_attributes));
1342
1343 /* Current sensors */
1344 pmbus_add_sensor_attrs(client, data, "curr", current_attributes,
1345 ARRAY_SIZE(current_attributes));
1346
1347 /* Power sensors */
1348 pmbus_add_sensor_attrs(client, data, "power", power_attributes,
1349 ARRAY_SIZE(power_attributes));
1350
1351 /* Temperature sensors */
1352 pmbus_add_sensor_attrs(client, data, "temp", temp_attributes,
1353 ARRAY_SIZE(temp_attributes));
1354
1355 /* Fans */
1356 pmbus_add_fan_attributes(client, data);
1357}
1358
1452/* 1359/*
1453 * Identify chip parameters. 1360 * Identify chip parameters.
1454 * This function is called for all chips. 1361 * This function is called for all chips.