emcfanctloutputs.c revision 1.1 1 1.1 brad /* $NetBSD: emcfanctloutputs.c,v 1.1 2025/03/11 13:56:48 brad Exp $ */
2 1.1 brad
3 1.1 brad /*
4 1.1 brad * Copyright (c) 2025 Brad Spencer <brad (at) anduin.eldar.org>
5 1.1 brad *
6 1.1 brad * Permission to use, copy, modify, and distribute this software for any
7 1.1 brad * purpose with or without fee is hereby granted, provided that the above
8 1.1 brad * copyright notice and this permission notice appear in all copies.
9 1.1 brad *
10 1.1 brad * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 1.1 brad * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 1.1 brad * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 1.1 brad * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 1.1 brad * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 1.1 brad * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 1.1 brad * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 1.1 brad */
18 1.1 brad
19 1.1 brad #ifdef __RCSID
20 1.1 brad __RCSID("$NetBSD: emcfanctloutputs.c,v 1.1 2025/03/11 13:56:48 brad Exp $");
21 1.1 brad #endif
22 1.1 brad
23 1.1 brad #include <inttypes.h>
24 1.1 brad #include <stdbool.h>
25 1.1 brad #include <stdio.h>
26 1.1 brad #include <stdlib.h>
27 1.1 brad #include <unistd.h>
28 1.1 brad #include <err.h>
29 1.1 brad #include <fcntl.h>
30 1.1 brad #include <string.h>
31 1.1 brad #include <limits.h>
32 1.1 brad #include <errno.h>
33 1.1 brad #include <mj.h>
34 1.1 brad
35 1.1 brad #include <dev/i2c/emcfanreg.h>
36 1.1 brad #include <dev/i2c/emcfaninfo.h>
37 1.1 brad
38 1.1 brad #define EXTERN
39 1.1 brad #include "emcfanctl.h"
40 1.1 brad #include "emcfanctlconst.h"
41 1.1 brad #include "emcfanctlutil.h"
42 1.1 brad #include "emcfanctloutputs.h"
43 1.1 brad
44 1.1 brad int
45 1.1 brad output_emcfan_info(int fd, uint8_t product_id, int product_family, bool jsonify, bool debug)
46 1.1 brad {
47 1.1 brad int err = 0;
48 1.1 brad uint8_t res;
49 1.1 brad mj_t obj;
50 1.1 brad char *s = NULL;
51 1.1 brad char *pn;
52 1.1 brad char fn[8];
53 1.1 brad
54 1.1 brad err = emcfan_read_register(fd, EMCFAN_REVISION, &res, debug);
55 1.1 brad if (err != 0)
56 1.1 brad goto out;
57 1.1 brad
58 1.1 brad if (jsonify) {
59 1.1 brad memset(&obj, 0x0, sizeof(obj));
60 1.1 brad mj_create(&obj, "object");
61 1.1 brad mj_append_field(&obj, "revision", "integer", res);
62 1.1 brad mj_append_field(&obj, "product_id", "integer", product_id);
63 1.1 brad mj_append_field(&obj, "product_family", "integer", product_family);
64 1.1 brad pn = emcfan_product_to_name(product_id);
65 1.1 brad mj_append_field(&obj, "chip_name", "string", pn, strlen(pn));
66 1.1 brad emcfan_family_to_name(product_family, fn, sizeof(fn));
67 1.1 brad mj_append_field(&obj, "family_name", "string", fn, strlen(fn));
68 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
69 1.1 brad printf("%s",s);
70 1.1 brad if (s != NULL)
71 1.1 brad free(s);
72 1.1 brad } else {
73 1.1 brad emcfan_family_to_name(product_family, fn, sizeof(fn));
74 1.1 brad printf("Product Family: %s\n", fn);
75 1.1 brad printf("Chip name: %s\n", emcfan_product_to_name(product_id));
76 1.1 brad printf("Revision: %d\n", res);
77 1.1 brad }
78 1.1 brad
79 1.1 brad out:
80 1.1 brad return(err);
81 1.1 brad }
82 1.1 brad
83 1.1 brad static void
84 1.1 brad output_emcfan_generic_reg_list(uint8_t product_id, const struct emcfan_registers the_registers[], long unsigned int the_registers_size, bool jsonify, bool debug)
85 1.1 brad {
86 1.1 brad mj_t array;
87 1.1 brad mj_t obj;
88 1.1 brad char *s = NULL;
89 1.1 brad int iindex;
90 1.1 brad
91 1.1 brad iindex = emcfan_find_info(product_id);
92 1.1 brad if (iindex == -1) {
93 1.1 brad printf("Unknown info for product_id: %d\n",product_id);
94 1.1 brad exit(2);
95 1.1 brad }
96 1.1 brad
97 1.1 brad if (debug)
98 1.1 brad fprintf(stderr, "output_emcfan_generic_reg_list: iindex=%d\n",iindex);
99 1.1 brad
100 1.1 brad if (jsonify) {
101 1.1 brad memset(&array, 0x0, sizeof(array));
102 1.1 brad mj_create(&array, "array");
103 1.1 brad }
104 1.1 brad
105 1.1 brad for(long unsigned int i = 0;i < the_registers_size;i++) {
106 1.1 brad if (emcfan_reg_is_real(iindex, the_registers[i].reg)) {
107 1.1 brad if (jsonify) {
108 1.1 brad memset(&obj, 0x0, sizeof(obj));
109 1.1 brad mj_create(&obj, "object");
110 1.1 brad mj_append_field(&obj, "register_name", "string", the_registers[i].name, strlen(the_registers[i].name));
111 1.1 brad mj_append_field(&obj, "register", "integer", the_registers[i].reg);
112 1.1 brad mj_append(&array, "object", &obj);
113 1.1 brad mj_delete(&obj);
114 1.1 brad } else {
115 1.1 brad printf("%s\t%d\t0x%02X\n",the_registers[i].name,the_registers[i].reg,the_registers[i].reg);
116 1.1 brad }
117 1.1 brad }
118 1.1 brad }
119 1.1 brad
120 1.1 brad if (jsonify) {
121 1.1 brad mj_asprint(&s, &array, MJ_JSON_ENCODE);
122 1.1 brad printf("%s",s);
123 1.1 brad if (s != NULL)
124 1.1 brad free(s);
125 1.1 brad mj_delete(&array);
126 1.1 brad }
127 1.1 brad }
128 1.1 brad
129 1.1 brad void
130 1.1 brad output_emcfan_register_list(uint8_t product_id, int product_family, bool jsonify, bool debug)
131 1.1 brad {
132 1.1 brad if (debug)
133 1.1 brad fprintf(stderr,"output_emcfan_list: product_id=%d, product_family=%d\n",product_id, product_family);
134 1.1 brad
135 1.1 brad switch(product_family) {
136 1.1 brad case EMCFAN_FAMILY_210X:
137 1.1 brad switch(product_id) {
138 1.1 brad case EMCFAN_PRODUCT_2101:
139 1.1 brad case EMCFAN_PRODUCT_2101R:
140 1.1 brad output_emcfan_generic_reg_list(product_id, emcfanctl_2101_registers, __arraycount(emcfanctl_2101_registers), jsonify, debug);
141 1.1 brad break;
142 1.1 brad case EMCFAN_PRODUCT_2103_1:
143 1.1 brad output_emcfan_generic_reg_list(product_id, emcfanctl_2103_1_registers, __arraycount(emcfanctl_2103_1_registers), jsonify, debug);
144 1.1 brad break;
145 1.1 brad case EMCFAN_PRODUCT_2103_24:
146 1.1 brad output_emcfan_generic_reg_list(product_id, emcfanctl_2103_24_registers, __arraycount(emcfanctl_2103_24_registers), jsonify, debug);
147 1.1 brad break;
148 1.1 brad case EMCFAN_PRODUCT_2104:
149 1.1 brad output_emcfan_generic_reg_list(product_id, emcfanctl_2104_registers, __arraycount(emcfanctl_2104_registers), jsonify, debug);
150 1.1 brad break;
151 1.1 brad case EMCFAN_PRODUCT_2106:
152 1.1 brad output_emcfan_generic_reg_list(product_id, emcfanctl_2106_registers, __arraycount(emcfanctl_2106_registers), jsonify, debug);
153 1.1 brad break;
154 1.1 brad default:
155 1.1 brad printf("UNSUPPORTED YET %d\n",product_id);
156 1.1 brad exit(99);
157 1.1 brad break;
158 1.1 brad };
159 1.1 brad break;
160 1.1 brad case EMCFAN_FAMILY_230X:
161 1.1 brad output_emcfan_generic_reg_list(product_id, emcfanctl_230x_registers, __arraycount(emcfanctl_230x_registers), jsonify, debug);
162 1.1 brad break;
163 1.1 brad };
164 1.1 brad }
165 1.1 brad
166 1.1 brad static int
167 1.1 brad output_emcfan_230x_read_reg(int fd, uint8_t product_id, int product_family, uint8_t start, uint8_t end, bool jsonify, bool debug)
168 1.1 brad {
169 1.1 brad int err = 0;
170 1.1 brad uint8_t res;
171 1.1 brad mj_t array;
172 1.1 brad mj_t obj;
173 1.1 brad char *s = NULL;
174 1.1 brad int iindex;
175 1.1 brad const char *rn;
176 1.1 brad
177 1.1 brad iindex = emcfan_find_info(product_id);
178 1.1 brad if (iindex == -1) {
179 1.1 brad printf("Unknown info for product_id: %d\n",product_id);
180 1.1 brad exit(2);
181 1.1 brad }
182 1.1 brad
183 1.1 brad if (debug)
184 1.1 brad fprintf(stderr, "output_emcfan_230x_read_reg: product_id=%d, product_family=%d, iindex=%d\n",product_id, product_family, iindex);
185 1.1 brad
186 1.1 brad if (jsonify) {
187 1.1 brad memset(&array, 0x0, sizeof(array));
188 1.1 brad mj_create(&array, "array");
189 1.1 brad }
190 1.1 brad
191 1.1 brad for(int i = start; i <= end; i++) {
192 1.1 brad if (emcfan_reg_is_real(iindex, i)) {
193 1.1 brad err = emcfan_read_register(fd, i, &res, debug);
194 1.1 brad if (err != 0)
195 1.1 brad break;
196 1.1 brad if (jsonify) {
197 1.1 brad memset(&obj, 0x0, sizeof(obj));
198 1.1 brad mj_create(&obj, "object");
199 1.1 brad rn = emcfan_regname_by_reg(product_id, product_family, i);
200 1.1 brad mj_append_field(&obj, "register_name", "string", rn, strlen(rn));
201 1.1 brad mj_append_field(&obj, "register", "integer", i);
202 1.1 brad mj_append_field(&obj, "register_value", "integer", res);
203 1.1 brad mj_append(&array, "object", &obj);
204 1.1 brad mj_delete(&obj);
205 1.1 brad } else {
206 1.1 brad printf("%s;%d (0x%02X);%d (0x%02X)\n",emcfan_regname_by_reg(product_id, product_family, i),i,i,res,res);
207 1.1 brad }
208 1.1 brad }
209 1.1 brad }
210 1.1 brad
211 1.1 brad if (jsonify) {
212 1.1 brad mj_asprint(&s, &array, MJ_JSON_ENCODE);
213 1.1 brad printf("%s",s);
214 1.1 brad if (s != NULL)
215 1.1 brad free(s);
216 1.1 brad mj_delete(&array);
217 1.1 brad }
218 1.1 brad
219 1.1 brad return(err);
220 1.1 brad }
221 1.1 brad
222 1.1 brad int
223 1.1 brad output_emcfan_register_read(int fd, uint8_t product_id, int product_family, uint8_t start, uint8_t end, bool jsonify, bool debug)
224 1.1 brad {
225 1.1 brad int err = 0;
226 1.1 brad
227 1.1 brad if (debug)
228 1.1 brad fprintf(stderr,"output_emcfan_register_read: start=%d 0x%02X, end=%d 0x%02X\n",start, start, end, end);
229 1.1 brad
230 1.1 brad switch(product_family) {
231 1.1 brad case EMCFAN_FAMILY_210X:
232 1.1 brad err = output_emcfan_230x_read_reg(fd, product_id, product_family, start, end, jsonify, debug);
233 1.1 brad break;
234 1.1 brad case EMCFAN_FAMILY_230X:
235 1.1 brad err = output_emcfan_230x_read_reg(fd, product_id, product_family, start, end, jsonify, debug);
236 1.1 brad break;
237 1.1 brad };
238 1.1 brad
239 1.1 brad return(err);
240 1.1 brad }
241 1.1 brad
242 1.1 brad int
243 1.1 brad output_emcfan_minexpected_rpm(int fd, uint8_t product_id, int product_family, uint8_t config_reg, bool jsonify, bool debug)
244 1.1 brad {
245 1.1 brad int err = 0;
246 1.1 brad uint8_t raw_res, res;
247 1.1 brad uint8_t clear_mask;
248 1.1 brad int human_value;
249 1.1 brad char *s = NULL;
250 1.1 brad mj_t obj;
251 1.1 brad
252 1.1 brad err = emcfan_read_register(fd, config_reg, &raw_res, debug);
253 1.1 brad if (err != 0)
254 1.1 brad goto out;
255 1.1 brad
256 1.1 brad clear_mask = fan_minexpectedrpm[0].clear_mask;
257 1.1 brad res = raw_res & clear_mask;
258 1.1 brad if (debug)
259 1.1 brad fprintf(stderr,"%s: clear_mask=0x%02X 0x%02X, raw_res=%d (0x%02X), res=%d (0x%02X)\n",__func__,clear_mask,(uint8_t)~clear_mask,raw_res,raw_res,res,res);
260 1.1 brad human_value = find_human_int(fan_minexpectedrpm, __arraycount(fan_minexpectedrpm), res);
261 1.1 brad
262 1.1 brad if (human_value == -10191)
263 1.1 brad return(EINVAL);
264 1.1 brad
265 1.1 brad if (jsonify) {
266 1.1 brad memset(&obj, 0x0, sizeof(obj));
267 1.1 brad mj_create(&obj, "object");
268 1.1 brad mj_append_field(&obj, "minimum_expected_rpm", "integer", human_value);
269 1.1 brad mj_append_field(&obj, "register", "integer", config_reg);
270 1.1 brad mj_append_field(&obj, "register_value", "integer", raw_res);
271 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
272 1.1 brad printf("%s",s);
273 1.1 brad if (s != NULL)
274 1.1 brad free(s);
275 1.1 brad } else {
276 1.1 brad printf("Minumum expected rpm:%d\n",human_value);
277 1.1 brad }
278 1.1 brad
279 1.1 brad out:
280 1.1 brad return(err);
281 1.1 brad }
282 1.1 brad
283 1.1 brad int
284 1.1 brad output_emcfan_edges(int fd, uint8_t product_id, int product_family, uint8_t config_reg, bool jsonify, bool debug)
285 1.1 brad {
286 1.1 brad int err = 0;
287 1.1 brad uint8_t raw_res, res;
288 1.1 brad uint8_t clear_mask;
289 1.1 brad int human_value;
290 1.1 brad char *s = NULL;
291 1.1 brad mj_t obj;
292 1.1 brad
293 1.1 brad err = emcfan_read_register(fd, config_reg, &raw_res, debug);
294 1.1 brad if (err != 0)
295 1.1 brad goto out;
296 1.1 brad
297 1.1 brad clear_mask = fan_numedges[0].clear_mask;
298 1.1 brad res = raw_res & clear_mask;
299 1.1 brad if (debug)
300 1.1 brad fprintf(stderr,"%s: clear_mask=0x%02X 0x%02X, raw_res=%d (0x%02X), res=%d (0x%02X)\n",__func__,clear_mask,(uint8_t)~clear_mask,raw_res,raw_res,res,res);
301 1.1 brad human_value = find_human_int(fan_numedges, __arraycount(fan_numedges), res);
302 1.1 brad
303 1.1 brad if (human_value == -10191)
304 1.1 brad return(EINVAL);
305 1.1 brad
306 1.1 brad if (jsonify) {
307 1.1 brad memset(&obj, 0x0, sizeof(obj));
308 1.1 brad mj_create(&obj, "object");
309 1.1 brad mj_append_field(&obj, "num_edges", "integer", human_value);
310 1.1 brad mj_append_field(&obj, "register", "integer", config_reg);
311 1.1 brad mj_append_field(&obj, "register_value", "integer", raw_res);
312 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
313 1.1 brad printf("%s",s);
314 1.1 brad if (s != NULL)
315 1.1 brad free(s);
316 1.1 brad } else {
317 1.1 brad printf("Number of edges:%d\n",human_value);
318 1.1 brad }
319 1.1 brad
320 1.1 brad out:
321 1.1 brad return(err);
322 1.1 brad }
323 1.1 brad
324 1.1 brad static int
325 1.1 brad output_emcfan_simple_int(int fd, uint8_t product_id, int product_family, uint8_t reg, const char *what, const char *whatj, bool jsonify, bool debug)
326 1.1 brad {
327 1.1 brad int err = 0;
328 1.1 brad uint8_t res;
329 1.1 brad char *s = NULL;
330 1.1 brad mj_t obj;
331 1.1 brad
332 1.1 brad err = emcfan_read_register(fd, reg, &res, debug);
333 1.1 brad if (err != 0)
334 1.1 brad goto out;
335 1.1 brad
336 1.1 brad if (jsonify) {
337 1.1 brad memset(&obj, 0x0, sizeof(obj));
338 1.1 brad mj_create(&obj, "object");
339 1.1 brad mj_append_field(&obj, whatj, "integer", res);
340 1.1 brad mj_append_field(&obj, "register", "integer", reg);
341 1.1 brad mj_append_field(&obj, "register_value", "integer", res);
342 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
343 1.1 brad printf("%s",s);
344 1.1 brad if (s != NULL)
345 1.1 brad free(s);
346 1.1 brad } else {
347 1.1 brad printf("%s:%d\n",what, res);
348 1.1 brad }
349 1.1 brad
350 1.1 brad out:
351 1.1 brad return(err);
352 1.1 brad }
353 1.1 brad
354 1.1 brad int
355 1.1 brad output_emcfan_drive(int fd, uint8_t product_id, int product_family, uint8_t reg, bool jsonify, bool debug)
356 1.1 brad {
357 1.1 brad return(output_emcfan_simple_int(fd, product_id, product_family, reg, "Drive", "drive_level", jsonify, debug));
358 1.1 brad }
359 1.1 brad
360 1.1 brad int
361 1.1 brad output_emcfan_divider(int fd, uint8_t product_id, int product_family, uint8_t reg, bool jsonify, bool debug)
362 1.1 brad {
363 1.1 brad return(output_emcfan_simple_int(fd, product_id, product_family, reg, "Divider", "frequency_divider", jsonify, debug));
364 1.1 brad }
365 1.1 brad
366 1.1 brad int
367 1.1 brad output_emcfan_pwm_basefreq(int fd, uint8_t product_id, int product_family, uint8_t reg, int the_fan, bool jsonify, bool debug)
368 1.1 brad {
369 1.1 brad int err = 0;
370 1.1 brad uint8_t res;
371 1.1 brad int tindex;
372 1.1 brad char *s = NULL;
373 1.1 brad mj_t obj;
374 1.1 brad
375 1.1 brad err = emcfan_read_register(fd, reg, &res, debug);
376 1.1 brad if (err != 0)
377 1.1 brad goto out;
378 1.1 brad
379 1.1 brad tindex = find_translated_blob_by_bits_instance(fan_pwm_basefreq, __arraycount(fan_pwm_basefreq), res, the_fan);
380 1.1 brad
381 1.1 brad if (debug)
382 1.1 brad fprintf(stderr,"%s: reg=%d 0x%02X, res=0x%02x, tindex=%d, the_fan=%d\n",__func__,reg,reg,res,tindex,the_fan);
383 1.1 brad
384 1.1 brad if (jsonify) {
385 1.1 brad memset(&obj, 0x0, sizeof(obj));
386 1.1 brad mj_create(&obj, "object");
387 1.1 brad mj_append_field(&obj, "fan", "integer", the_fan+1);
388 1.1 brad mj_append_field(&obj, "pwm_base_frequency", "integer", fan_pwm_basefreq[tindex].human_int);
389 1.1 brad mj_append_field(&obj, "register", "integer", reg);
390 1.1 brad mj_append_field(&obj, "register_value", "integer", res);
391 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
392 1.1 brad printf("%s",s);
393 1.1 brad if (s != NULL)
394 1.1 brad free(s);
395 1.1 brad } else {
396 1.1 brad printf("PWM Base Frequency:%d\n",fan_pwm_basefreq[tindex].human_int);
397 1.1 brad }
398 1.1 brad
399 1.1 brad out:
400 1.1 brad return(err);
401 1.1 brad }
402 1.1 brad
403 1.1 brad int
404 1.1 brad output_emcfan_polarity(int fd, uint8_t product_id, int product_family, uint8_t reg, int the_fan, bool jsonify, bool debug)
405 1.1 brad {
406 1.1 brad int err = 0;
407 1.1 brad uint8_t res;
408 1.1 brad int mask;
409 1.1 brad bool inverted = false;
410 1.1 brad char *s = NULL;
411 1.1 brad mj_t obj;
412 1.1 brad
413 1.1 brad err = emcfan_read_register(fd, reg, &res, debug);
414 1.1 brad if (err != 0)
415 1.1 brad goto out;
416 1.1 brad
417 1.1 brad if (product_id == EMCFAN_PRODUCT_2101 ||
418 1.1 brad product_id == EMCFAN_PRODUCT_2101R) {
419 1.1 brad mask = 0x10;
420 1.1 brad } else {
421 1.1 brad mask = 1 << the_fan;
422 1.1 brad }
423 1.1 brad
424 1.1 brad if (res & mask)
425 1.1 brad inverted = true;
426 1.1 brad
427 1.1 brad if (jsonify) {
428 1.1 brad memset(&obj, 0x0, sizeof(obj));
429 1.1 brad mj_create(&obj, "object");
430 1.1 brad mj_append_field(&obj, "fan", "integer", the_fan+1);
431 1.1 brad mj_append_field(&obj, "inverted", "integer", inverted);
432 1.1 brad mj_append_field(&obj, "register", "integer", reg);
433 1.1 brad mj_append_field(&obj, "register_value", "integer", res);
434 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
435 1.1 brad printf("%s",s);
436 1.1 brad if (s != NULL)
437 1.1 brad free(s);
438 1.1 brad } else {
439 1.1 brad printf("Inverted:%s\n",(inverted ? "Yes" : "No"));
440 1.1 brad }
441 1.1 brad
442 1.1 brad out:
443 1.1 brad return(err);
444 1.1 brad }
445 1.1 brad
446 1.1 brad int
447 1.1 brad output_emcfan_pwm_output_type(int fd, uint8_t product_id, int product_family, uint8_t reg, int the_fan, bool jsonify, bool debug)
448 1.1 brad {
449 1.1 brad int err = 0;
450 1.1 brad uint8_t res;
451 1.1 brad int mask;
452 1.1 brad bool pushpull = false;
453 1.1 brad char *s = NULL;
454 1.1 brad mj_t obj;
455 1.1 brad
456 1.1 brad err = emcfan_read_register(fd, reg, &res, debug);
457 1.1 brad if (err != 0)
458 1.1 brad goto out;
459 1.1 brad
460 1.1 brad mask = 1 << the_fan;
461 1.1 brad
462 1.1 brad if (res & mask)
463 1.1 brad pushpull= true;
464 1.1 brad
465 1.1 brad if (jsonify) {
466 1.1 brad memset(&obj, 0x0, sizeof(obj));
467 1.1 brad mj_create(&obj, "object");
468 1.1 brad mj_append_field(&obj, "fan", "integer", the_fan+1);
469 1.1 brad mj_append_field(&obj, "pwm_output_type", "integer", pushpull);
470 1.1 brad mj_append_field(&obj, "register", "integer", reg);
471 1.1 brad mj_append_field(&obj, "register_value", "integer", res);
472 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
473 1.1 brad printf("%s",s);
474 1.1 brad if (s != NULL)
475 1.1 brad free(s);
476 1.1 brad } else {
477 1.1 brad printf("PWM Output Type:%s\n",(pushpull ? "push-pull" : "open drain"));
478 1.1 brad }
479 1.1 brad
480 1.1 brad out:
481 1.1 brad return(err);
482 1.1 brad }
483 1.1 brad
484 1.1 brad int
485 1.1 brad output_emcfan_fan_status(int fd, uint8_t product_id, int product_family, uint8_t start_reg, uint8_t end_reg, int the_fan, bool jsonify, bool debug)
486 1.1 brad {
487 1.1 brad int err = 0;
488 1.1 brad uint8_t res[4];
489 1.1 brad bool stalled = false;
490 1.1 brad bool spin_up_fail = false;
491 1.1 brad bool drive_fail = false;
492 1.1 brad uint8_t stall_mask = 0;
493 1.1 brad uint8_t spin_mask = 0;
494 1.1 brad uint8_t drive_mask = 0;
495 1.1 brad char *s = NULL;
496 1.1 brad mj_t obj;
497 1.1 brad
498 1.1 brad res[0] = res[1] = res[2] = res[3] = 0;
499 1.1 brad
500 1.1 brad if (product_family == EMCFAN_FAMILY_210X) {
501 1.1 brad err = emcfan_read_register(fd, start_reg, &res[0], debug);
502 1.1 brad if (err != 0)
503 1.1 brad goto out;
504 1.1 brad err = emcfan_read_register(fd, start_reg, &res[0], debug);
505 1.1 brad if (err != 0)
506 1.1 brad goto out;
507 1.1 brad
508 1.1 brad switch(the_fan) {
509 1.1 brad case 0:
510 1.1 brad stall_mask = 0b00000001;
511 1.1 brad spin_mask = 0b00000010;
512 1.1 brad drive_mask = 0b00100000;
513 1.1 brad break;
514 1.1 brad case 1:
515 1.1 brad stall_mask = 0b00000100;
516 1.1 brad spin_mask = 0b00001000;
517 1.1 brad drive_mask = 0b01000000;
518 1.1 brad break;
519 1.1 brad default:
520 1.1 brad fprintf(stderr,"No status for fan: %d\n", the_fan + 1);
521 1.1 brad err = EINVAL;
522 1.1 brad };
523 1.1 brad if (debug)
524 1.1 brad fprintf(stderr,"%s: product_family=%d, stall_mask=0x%02X, spin_mask=0x%02X, drive_mask=0x%02X, res=0x%02X\n",__func__,
525 1.1 brad product_family, stall_mask, spin_mask, drive_mask, res[0]);
526 1.1 brad stalled = (res[0] & stall_mask);
527 1.1 brad spin_up_fail = (res[0] & spin_mask);
528 1.1 brad drive_fail = (res[0] & drive_mask);
529 1.1 brad } else {
530 1.1 brad int j = 0;
531 1.1 brad for(uint8_t i = start_reg; i <= end_reg;i++,j++) {
532 1.1 brad err = emcfan_read_register(fd, i, &res[j], debug);
533 1.1 brad if (err != 0)
534 1.1 brad goto out;
535 1.1 brad }
536 1.1 brad j = 0;
537 1.1 brad for(uint8_t i = start_reg; i <= end_reg;i++,j++) {
538 1.1 brad err = emcfan_read_register(fd, i, &res[j], debug);
539 1.1 brad if (err != 0)
540 1.1 brad goto out;
541 1.1 brad }
542 1.1 brad
543 1.1 brad if (debug)
544 1.1 brad fprintf(stderr,"%s: product_family=%d, res[0]=0x%02X, res[1]=0x%02X, res[2]=0x%02X, res[3]=0x%02X\n",
545 1.1 brad __func__, product_family, res[0], res[1], res[2], res[3]);
546 1.1 brad stalled = (res[1] & (1 << the_fan));
547 1.1 brad spin_up_fail = (res[2] & (1 << the_fan));
548 1.1 brad drive_fail = (res[3] & (1 << the_fan));
549 1.1 brad }
550 1.1 brad
551 1.1 brad if (jsonify) {
552 1.1 brad memset(&obj, 0x0, sizeof(obj));
553 1.1 brad mj_create(&obj, "object");
554 1.1 brad mj_append_field(&obj, "fan", "integer", the_fan+1);
555 1.1 brad mj_append_field(&obj, "stalled", "integer", stalled);
556 1.1 brad mj_append_field(&obj, "spin_up_fail", "integer", spin_up_fail);
557 1.1 brad mj_append_field(&obj, "drive_fail", "integer", drive_fail);
558 1.1 brad mj_append_field(&obj, "register1", "integer", start_reg);
559 1.1 brad mj_append_field(&obj, "register1_value", "integer", res[0]);
560 1.1 brad mj_append_field(&obj, "register2", "integer", start_reg+1);
561 1.1 brad mj_append_field(&obj, "register2_value", "integer", res[1]);
562 1.1 brad mj_append_field(&obj, "register3", "integer", start_reg+2);
563 1.1 brad mj_append_field(&obj, "register3_value", "integer", res[2]);
564 1.1 brad mj_append_field(&obj, "register4", "integer", start_reg+3);
565 1.1 brad mj_append_field(&obj, "register4_value", "integer", res[3]);
566 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
567 1.1 brad printf("%s",s);
568 1.1 brad if (s != NULL)
569 1.1 brad free(s);
570 1.1 brad } else {
571 1.1 brad printf("Stalled: %s\n",stalled ? "Yes" : "No");
572 1.1 brad printf("Spin up failed: %s\n",spin_up_fail ? "Yes" : "No");
573 1.1 brad printf("Drive failed: %s\n",drive_fail ? "Yes" : "No");
574 1.1 brad }
575 1.1 brad
576 1.1 brad out:
577 1.1 brad return(err);
578 1.1 brad }
579 1.1 brad
580 1.1 brad int
581 1.1 brad output_emcfan_apd(int fd, uint8_t product_id, int product_family, uint8_t reg, bool jsonify, bool debug)
582 1.1 brad {
583 1.1 brad int err = 0;
584 1.1 brad uint8_t res;
585 1.1 brad bool antiparalleldiode = false;
586 1.1 brad char *s = NULL;
587 1.1 brad mj_t obj;
588 1.1 brad
589 1.1 brad err = emcfan_read_register(fd, reg, &res, debug);
590 1.1 brad if (err != 0)
591 1.1 brad goto out;
592 1.1 brad
593 1.1 brad if (res & 0x01)
594 1.1 brad antiparalleldiode = true;
595 1.1 brad
596 1.1 brad if (jsonify) {
597 1.1 brad memset(&obj, 0x0, sizeof(obj));
598 1.1 brad mj_create(&obj, "object");
599 1.1 brad mj_append_field(&obj, "apd", "integer", antiparalleldiode);
600 1.1 brad mj_append_field(&obj, "register", "integer", reg);
601 1.1 brad mj_append_field(&obj, "register_value", "integer", res);
602 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
603 1.1 brad printf("%s",s);
604 1.1 brad if (s != NULL)
605 1.1 brad free(s);
606 1.1 brad } else {
607 1.1 brad printf("APD:%s\n",(antiparalleldiode ? "On" : "Off"));
608 1.1 brad }
609 1.1 brad
610 1.1 brad out:
611 1.1 brad return(err);
612 1.1 brad }
613 1.1 brad
614 1.1 brad int
615 1.1 brad output_emcfan_smbusto(int fd, uint8_t product_id, int product_family, uint8_t reg, int instance, bool jsonify, bool debug)
616 1.1 brad {
617 1.1 brad int err = 0;
618 1.1 brad uint8_t res;
619 1.1 brad int tindex;
620 1.1 brad bool smbusto = false;
621 1.1 brad char *s = NULL;
622 1.1 brad mj_t obj;
623 1.1 brad
624 1.1 brad err = emcfan_read_register(fd, reg, &res, debug);
625 1.1 brad if (err != 0)
626 1.1 brad goto out;
627 1.1 brad
628 1.1 brad tindex = find_translated_blob_by_bits_instance(smbus_timeout, __arraycount(smbus_timeout), res, instance);
629 1.1 brad
630 1.1 brad if (debug)
631 1.1 brad fprintf(stderr,"%s: reg=%d 0x%02X, res=0x%02x, tindex=%d, instance=%d\n",__func__,reg,reg,res,tindex,instance);
632 1.1 brad
633 1.1 brad smbusto = (res & smbus_timeout[tindex].clear_mask) ? true : false;
634 1.1 brad
635 1.1 brad if (jsonify) {
636 1.1 brad memset(&obj, 0x0, sizeof(obj));
637 1.1 brad mj_create(&obj, "object");
638 1.1 brad mj_append_field(&obj, "smbus_timeout", "integer", smbusto);
639 1.1 brad mj_append_field(&obj, "register", "integer", reg);
640 1.1 brad mj_append_field(&obj, "register_value", "integer", res);
641 1.1 brad mj_asprint(&s, &obj, MJ_JSON_ENCODE);
642 1.1 brad printf("%s",s);
643 1.1 brad if (s != NULL)
644 1.1 brad free(s);
645 1.1 brad } else {
646 1.1 brad printf("SMBUS timeout:%s\n",(smbusto ? "Off" : "On"));
647 1.1 brad }
648 1.1 brad
649 1.1 brad out:
650 1.1 brad return(err);
651 1.1 brad }
652 1.1 brad
653