blob: a81d352ff0f3aba9e9c84511a38e04ea6e0d8e3b [file] [log] [blame]
Amaury Poulyba91ff12016-10-19 17:03:52 +02001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "nwz_lib.h"
Amaury Poulyc95e30b2016-11-11 16:01:14 +010022#include "nwz_db.h"
Amaury Pouly30972392016-10-28 23:27:29 +020023
Amaury Poulyd492f252016-11-01 17:04:26 +010024int nwz_run(const char *file, const char *args[], bool wait)
Amaury Poulyba91ff12016-10-19 17:03:52 +020025{
26 pid_t child_pid = fork();
27 if(child_pid != 0)
28 {
29 if(wait)
30 {
31 int status;
32 waitpid(child_pid, &status, 0);
Amaury Poulyd492f252016-11-01 17:04:26 +010033 return status;
Amaury Poulyba91ff12016-10-19 17:03:52 +020034 }
Amaury Poulyd492f252016-11-01 17:04:26 +010035 else
36 return 0;
Amaury Poulyba91ff12016-10-19 17:03:52 +020037 }
38 else
39 {
40 execvp(file, (char * const *)args);
41 _exit(1);
42 }
43}
44
Amaury Poulyd492f252016-11-01 17:04:26 +010045char *nwz_run_pipe(const char *file, const char *args[], int *status)
46{
47 int pipe_fds[2];
48 pipe(pipe_fds);
49 pid_t child_pid = fork();
50 if(child_pid == 0)
51 {
52 dup2(pipe_fds[1], 1); /* redirect stdout */
53 dup2(pipe_fds[1], 2); /* redirect stderr */
54 close(pipe_fds[0]); /* close reading */
55 close(pipe_fds[1]); /* close writing */
56 execvp(file, (char * const *)args);
57 _exit(1);
58 }
59 else
60 {
61 close(pipe_fds[1]); /* close writing */
62 char buffer[1024];
63 char *output = malloc(1);
64 ssize_t count;
65 size_t size = 0;
66 while((count = read(pipe_fds[0], buffer, sizeof(buffer))) > 0)
67 {
68 output = realloc(output, size + count + 1);
69 memcpy(output + size, buffer, count);
70 size += count;
71 }
72 close(pipe_fds[0]);
73 output[size] = 0;
74 waitpid(child_pid, status, 0);
75 return output;
76 }
77}
78
Amaury Poulyba91ff12016-10-19 17:03:52 +020079void nwz_lcdmsg(bool clear, int x, int y, const char *msg)
80{
81 const char *path_lcdmsg = "/usr/local/bin/lcdmsg";
82 const char *args[16];
83 int index = 0;
84 char locate[32];
Amaury Poulyc95e30b2016-11-11 16:01:14 +010085 args[index++] = "lcdmsg";
Amaury Poulyba91ff12016-10-19 17:03:52 +020086 if(clear)
87 args[index++] = "-c";
88 args[index++] = "-f";
89 args[index++] = "/usr/local/bin/font_08x12.bmp";
90 args[index++] = "-l";
91 sprintf(locate, "%d,%d", x, y);
92 args[index++] = locate;
93 args[index++] = msg;
94 args[index++] = NULL;
95 /* wait for lcdmsg to finish to avoid any race conditions in framebuffer
96 * accesses */
97 nwz_run(path_lcdmsg, args, true);
98}
99
100void nwz_lcdmsgf(bool clear, int x, int y, const char *format, ...)
101{
102 char buffer[1024];
103 va_list args;
104 va_start(args, format);
105 vsprintf(buffer, format, args);
106 va_end(args);
107 nwz_lcdmsg(clear, x, y, buffer);
108}
109
Amaury Poulyc95e30b2016-11-11 16:01:14 +0100110#define NWZ_COLOR_RGB(col) \
111 NWZ_COLOR_RED(col), NWZ_COLOR_GREEN(col), NWZ_COLOR_BLUE(col)
112
113void nwz_display_clear(nwz_color_t color)
114{
115 const char *path_display = "/usr/local/bin/display";
116 const char *args[16];
117 int index = 0;
118 char col[32];
119 args[index++] = "display";
120 args[index++] = "lcd";
121 args[index++] = "clear";
122 sprintf(col, "%d,%d,%d", NWZ_COLOR_RGB(color));
123 args[index++] = col;
124 args[index++] = NULL;
125 /* wait for lcdmsg to finish to avoid any race conditions in framebuffer
126 * accesses */
127 nwz_run(path_display, args, true);
128}
129
130void nwz_display_text(int x, int y, bool big_font, nwz_color_t foreground_col,
131 nwz_color_t background_col, int alpha, const char *text)
132{
133 const char *path_display = "/usr/local/bin/display";
134 const char *args[16];
135 int index = 0;
136 char fg[32],bg[32], pos[32], transp[16];
137 args[index++] = "display";
138 args[index++] = "lcd";
139 args[index++] = "text";
140 sprintf(pos, "%d,%d", x, y);
141 args[index++] = pos;
142 if(big_font)
143 args[index++] = "/usr/local/bin/font_14x24.bmp";
144 else
145 args[index++] = "/usr/local/bin/font_08x12.bmp";
146 sprintf(fg, "%d,%d,%d", NWZ_COLOR_RGB(foreground_col));
147 args[index++] = fg;
148 sprintf(bg, "%d,%d,%d", NWZ_COLOR_RGB(background_col));
149 args[index++] = bg;
150 sprintf(transp, "%d", alpha);
151 args[index++] = transp;
152 args[index++] = text;
153 args[index++] = NULL;
154 /* wait for lcdmsg to finish to avoid any race conditions in framebuffer
155 * accesses */
156 nwz_run(path_display, args, true);
157}
158
Amaury Pouly0c1a9612016-11-12 22:16:48 +0100159void nwz_display_text_center(int width, int y, bool big_font, nwz_color_t fg,
160 nwz_color_t bg, int alpha, const char *text)
161{
162 int txt_w = NWZ_FONT_W(big_font) * strlen(text);
163 nwz_display_text((width - txt_w) / 2, y, big_font, fg, bg, alpha, text);
164}
165
Amaury Poulyc95e30b2016-11-11 16:01:14 +0100166void nwz_display_textf(int x, int y, bool big_font, nwz_color_t foreground_col,
167 nwz_color_t background_col, int alpha, const char *fmt, ...)
168{
169 char buffer[1024];
170 va_list args;
171 va_start(args, fmt);
172 vsprintf(buffer, fmt, args);
173 va_end(args);
174 nwz_display_text(x, y, big_font, foreground_col, background_col, alpha, buffer);
175}
176
Amaury Pouly0c1a9612016-11-12 22:16:48 +0100177void nwz_display_textf_center(int width, int y, bool big_font, nwz_color_t fg,
178 nwz_color_t bg, int alpha, const char *fmt, ...)
179{
180 char buffer[1024];
181 va_list args;
182 va_start(args, fmt);
183 vsprintf(buffer, fmt, args);
184 va_end(args);
185 nwz_display_text_center(width, y, big_font, fg, bg, alpha, buffer);
186}
187
Amaury Poulyc95e30b2016-11-11 16:01:14 +0100188void nwz_display_bitmap(int x, int y, const char *file, int left, int top,
189 int width, int height, nwz_color_t key_col, int bmp_alpha)
190{
191 const char *path_display = "/usr/local/bin/display";
192 const char *args[16];
193 int index = 0;
194 char pos[32], topleft[32], dim[32], key[32], transp[16];
195 args[index++] = "display";
196 args[index++] = "lcd";
197 args[index++] = "bitmap";
198 sprintf(pos, "%d,%d", x, y);
199 args[index++] = pos;
200 args[index++] = file;
201 sprintf(topleft, "%d,%d", left, top);
202 args[index++] = topleft;
203 sprintf(dim, "%d,%d", width, height);
204 args[index++] = dim;
205 if(key_col == NWZ_COLOR_NO_KEY)
206 sprintf(key, "no");
207 else
208 sprintf(key, "%d,%d,%d", NWZ_COLOR_RGB(key_col));
209 args[index++] = key;
210 sprintf(transp, "%d", bmp_alpha);
211 args[index++] = transp;
212 args[index++] = NULL;
213 /* wait for lcdmsg to finish to avoid any race conditions in framebuffer
214 * accesses */
215 nwz_run(path_display, args, true);
216}
217
Amaury Poulyd42b43c2016-10-20 18:21:00 +0200218int nwz_input_open(const char *requested_name)
219{
220 /* try all /dev/input/eventX, there can't a lot of them */
221 for(int index = 0; index < 8; index++)
222 {
223 char buffer[32];
224 sprintf(buffer, "/dev/input/event%d", index);
225 int fd = open(buffer, O_RDWR);
226 if(fd < 0)
227 continue; /* try next one */
228 /* query name */
229 char name[256];
230 if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) >= 0 &&
231 strcmp(name, requested_name) == 0)
232 return fd;
233 close(fd);
234 }
235 return -1;
236}
237
Amaury Poulyba91ff12016-10-19 17:03:52 +0200238int nwz_key_open(void)
239{
Amaury Poulyd42b43c2016-10-20 18:21:00 +0200240 return nwz_input_open(NWZ_KEY_NAME);
Amaury Poulyba91ff12016-10-19 17:03:52 +0200241}
242
243void nwz_key_close(int fd)
244{
245 close(fd);
246}
247
248int nwz_key_get_hold_status(int fd)
249{
250 unsigned long led_hold = 0;
251 if(ioctl(fd, EVIOCGLED(sizeof(led_hold)), &led_hold) < 0)
252 return -1;
253 return led_hold;
254}
255
256int nwz_key_wait_event(int fd, long tmo_us)
257{
Amaury Poulyd42b43c2016-10-20 18:21:00 +0200258 return nwz_wait_fds(&fd, 1, tmo_us);
Amaury Poulyba91ff12016-10-19 17:03:52 +0200259}
260
261int nwz_key_read_event(int fd, struct input_event *evt)
262{
263 int ret = read(fd, evt, sizeof(struct input_event));
264 if(ret != sizeof(struct input_event))
265 return -1;
266 return 1;
267}
268
269int nwz_key_event_get_keycode(struct input_event *evt)
270{
271 return evt->code & NWZ_KEY_MASK;
272}
273
274bool nwz_key_event_is_press(struct input_event *evt)
275{
276 return evt->value == 0;
277}
278
279bool nwz_key_event_get_hold_status(struct input_event *evt)
280{
281 return !!(evt->code & NWZ_KEY_HOLD_MASK);
282}
283
284static const char *nwz_keyname[NWZ_KEY_MASK + 1] =
285{
286 [0 ... NWZ_KEY_MASK] = "unknown",
287 [NWZ_KEY_PLAY] = "PLAY",
288 [NWZ_KEY_RIGHT] = "RIGHT",
289 [NWZ_KEY_LEFT] = "LEFT",
290 [NWZ_KEY_UP] = "UP",
291 [NWZ_KEY_DOWN] = "DOWN",
292 [NWZ_KEY_ZAPPIN] = "ZAPPIN",
293 [NWZ_KEY_AD0_6] = "AD0_6",
294 [NWZ_KEY_AD0_7] = "AD0_7",
295 [NWZ_KEY_NONE] = "NONE",
296 [NWZ_KEY_VOL_DOWN] = "VOL DOWN",
297 [NWZ_KEY_VOL_UP] = "VOL UP",
298 [NWZ_KEY_BACK] = "BACK",
299 [NWZ_KEY_OPTION] = "OPTION",
300 [NWZ_KEY_BT] = "BT",
301 [NWZ_KEY_AD1_5] = "AD1_5",
302 [NWZ_KEY_AD1_6] = "AD1_6",
303 [NWZ_KEY_AD1_7] = "AD1_7",
304};
305
306const char *nwz_key_get_name(int keycode)
307{
308 if(keycode <0 || keycode > NWZ_KEY_MASK)
309 return "invalid";
310 else
311 return nwz_keyname[keycode];
312}
Amaury Pouly8d24b622016-10-19 17:58:40 +0200313
314int nwz_fb_open(bool lcd)
315{
Amaury Pouly0b01ca62016-10-19 18:19:57 +0200316 return open(lcd ? NWZ_FB_LCD_DEV : NWZ_FB_TV_DEV, O_RDWR);
Amaury Pouly8d24b622016-10-19 17:58:40 +0200317}
318
319void nwz_fb_close(int fd)
320{
321 close(fd);
322}
323
324int nwz_fb_get_brightness(int fd, struct nwz_fb_brightness *bl)
325{
326 if(ioctl(fd, NWZ_FB_GET_BRIGHTNESS, bl) < 0)
327 return -1;
328 else
329 return 1;
330}
331
332int nwz_fb_set_brightness(int fd, struct nwz_fb_brightness *bl)
333{
334 if(ioctl(fd, NWZ_FB_SET_BRIGHTNESS, bl) < 0)
335 return -1;
336 else
337 return 1;
338}
Amaury Pouly0b01ca62016-10-19 18:19:57 +0200339
Amaury Pouly0c1a9612016-11-12 22:16:48 +0100340int nwz_fb_set_page(int fd, int page)
341{
342 /* set page mode to no transparency and no rotation */
343 struct nwz_fb_image_info mode_info;
344 mode_info.tc_enable = 0;
345 mode_info.t_color = 0;
346 mode_info.alpha = 0;
347 mode_info.rot = 0;
348 mode_info.page = page;
349 mode_info.update = NWZ_FB_ONLY_2D_MODE;
350 if(ioctl(fd, NWZ_FB_UPDATE, &mode_info) < 0)
351 return -2;
352 return 0;
353}
354
Amaury Pouly5017bab2016-11-06 00:12:04 +0100355int nwz_fb_set_standard_mode(int fd)
356{
357 /* disable timer (apparently useless with LCD) */
358 struct nwz_fb_update_timer update_timer;
359 update_timer.timerflag = NWZ_FB_TIMER_OFF;
360 update_timer.timeout = NWZ_FB_DEFAULT_TIMEOUT;
361 if(ioctl(fd, NWZ_FB_UPDATE_TIMER, &update_timer) < 0)
362 return -1;
Amaury Pouly0c1a9612016-11-12 22:16:48 +0100363 return nwz_fb_set_page(fd, 0);
Amaury Pouly5017bab2016-11-06 00:12:04 +0100364}
365
Amaury Poulyc95e30b2016-11-11 16:01:14 +0100366int nwz_fb_get_resolution(int fd, int *x, int *y, int *bpp)
367{
368 struct fb_var_screeninfo vinfo;
369 if(ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
370 return -1;
371 if(x)
372 *x = vinfo.xres;
373 if(y)
374 *y = vinfo.yres;
375 if(bpp)
376 *bpp = vinfo.bits_per_pixel;
377 return 0;
378}
379
Amaury Pouly0c1a9612016-11-12 22:16:48 +0100380void *nwz_fb_mmap(int fd, int offset, int size)
381{
382 return mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)offset);
383}
384
Amaury Pouly0b01ca62016-10-19 18:19:57 +0200385int nwz_adc_open(void)
386{
387 return open(NWZ_ADC_DEV, O_RDONLY);
388}
389
390void nwz_adc_close(int fd)
391{
392 close(fd);
393}
394
395static const char *nwz_adc_name[] =
396{
397 [NWZ_ADC_VCCBAT] = "VCCBAT",
398 [NWZ_ADC_VCCVBUS] = "VCCVBUS",
399 [NWZ_ADC_ADIN3] = "ADIN3",
400 [NWZ_ADC_ADIN4] = "ADIN4",
401 [NWZ_ADC_ADIN5] = "ADIN5",
402 [NWZ_ADC_ADIN6] = "ADIN6",
403 [NWZ_ADC_ADIN7] = "ADIN7",
404 [NWZ_ADC_ADIN8] = "ADIN8",
405};
406
407const char *nwz_adc_get_name(int ch)
408{
409 return nwz_adc_name[ch];
410}
411
412int nwz_adc_get_val(int fd, int ch)
413{
414 unsigned char val;
415 if(ioctl(fd, NWZ_ADC_GET_VAL(ch), &val) < 0)
416 return -1;
417 else
418 return val;
419}
Amaury Poulyd42b43c2016-10-20 18:21:00 +0200420
421int nwz_ts_open(void)
422{
423 return nwz_input_open(NWZ_TS_NAME);
424}
425
426void nwz_ts_close(int fd)
427{
428 close(fd);
429}
430
431int nwz_ts_state_init(int fd, struct nwz_ts_state_t *state)
432{
433 memset(state, 0, sizeof(struct nwz_ts_state_t));
434 struct input_absinfo info;
435 if(ioctl(fd, EVIOCGABS(ABS_X), &info) < 0)
436 return -1;
437 state->max_x = info.maximum;
438 if(ioctl(fd, EVIOCGABS(ABS_Y), &info) < 0)
439 return -1;
440 state->max_y = info.maximum;
441 if(ioctl(fd, EVIOCGABS(ABS_PRESSURE), &info) < 0)
442 return -1;
443 state->max_pressure = info.maximum;
444 if(ioctl(fd, EVIOCGABS(ABS_TOOL_WIDTH), &info) < 0)
445 return -1;
446 state->max_tool_width = info.maximum;
447 return 1;
448}
449
450int nwz_ts_state_update(struct nwz_ts_state_t *state, struct input_event *evt)
451{
452 switch(evt->type)
453 {
454 case EV_SYN:
455 return 1;
456 case EV_REL:
457 if(evt->code == REL_RX)
458 state->flick_x = evt->value;
459 else if(evt->code == REL_RY)
460 state->flick_y = evt->value;
461 else
462 return -1;
463 state->flick = true;
464 break;
465 case EV_ABS:
466 if(evt->code == ABS_X)
467 state->x = evt->value;
468 else if(evt->code == ABS_Y)
469 state->y = evt->value;
470 else if(evt->code == ABS_PRESSURE)
471 state->pressure = evt->value;
472 else if(evt->code == ABS_TOOL_WIDTH)
473 state->tool_width = evt->value;
474 else
475 return -1;
476 break;
477 case EV_KEY:
478 if(evt->code == BTN_TOUCH)
479 state->touch = evt->value;
480 else
481 return -1;
482 break;
483 default:
484 return -1;
485 }
486 return 0;
487}
488
489int nwz_ts_state_post_syn(struct nwz_ts_state_t *state)
490{
491 state->flick = false;
492 return 1;
493}
494
495int nwz_ts_read_events(int fd, struct input_event *evts, int nr_evts)
496{
497 int ret = read(fd, evts, nr_evts * sizeof(struct input_event));
498 if(ret < 0)
499 return -1;
500 return ret / sizeof(struct input_event);
501}
502
503long nwz_wait_fds(int *fds, int nr_fds, long tmo_us)
504{
505 fd_set rfds;
506 struct timeval tv;
507 struct timeval *tv_ptr = NULL;
508 /* watch the input device */
509 FD_ZERO(&rfds);
510 int max_fd = 0;
511 for(int i = 0; i < nr_fds; i++)
512 {
513 FD_SET(fds[i], &rfds);
514 if(fds[i] > max_fd)
515 max_fd = fds[i];
516 }
517 /* setup timeout */
518 if(tmo_us >= 0)
519 {
520 tv.tv_sec = 0;
521 tv.tv_usec = tmo_us;
522 tv_ptr = &tv;
523 }
524 int ret = select(max_fd + 1, &rfds, NULL, NULL, tv_ptr);
525 if(ret <= 0)
526 return ret;
527 long bitmap = 0;
528 for(int i = 0; i < nr_fds; i++)
529 if(FD_ISSET(fds[i], &rfds))
530 bitmap |= 1 << i;
531 return bitmap;
532}
533
534int nwz_power_open(void)
535{
536 return open(NWZ_POWER_DEV, O_RDWR);
537}
538
539void nwz_power_close(int fd)
540{
541 close(fd);
542}
543
544int nwz_power_get_status(int fd)
545{
546 int status;
547 if(ioctl(fd, NWZ_POWER_GET_STATUS, &status) < 0)
548 return -1;
549 return status;
550}
551
552static int nwz_power_adval_to_mv(int adval, int ad_base)
553{
554 if(adval == -1)
555 return -1;
556 /* the AD base corresponds to the millivolt value if adval was 255 */
557 return (adval * ad_base) / 255;
558}
559
560int nwz_power_get_vbus_adval(int fd)
561{
562 int status;
563 if(ioctl(fd, NWZ_POWER_GET_VBUS_ADVAL, &status) < 0)
564 return -1;
565 return status;
566}
567
568int nwz_power_get_vbus_voltage(int fd)
569{
570 return nwz_power_adval_to_mv(nwz_power_get_vbus_adval(fd), NWZ_POWER_AD_BASE_VBUS);
571}
572
573int nwz_power_get_vbus_limit(int fd)
574{
575 int status;
576 if(ioctl(fd, NWZ_POWER_GET_VBUS_LIMIT, &status) < 0)
577 return -1;
578 return status;
579}
580
581int nwz_power_get_charge_switch(int fd)
582{
583 int status;
584 if(ioctl(fd, NWZ_POWER_GET_CHARGE_SWITCH, &status) < 0)
585 return -1;
586 return status;
587}
588
589int nwz_power_get_charge_current(int fd)
590{
591 int status;
592 if(ioctl(fd, NWZ_POWER_GET_CHARGE_CURRENT, &status) < 0)
593 return -1;
594 return status;
595}
596
597int nwz_power_get_battery_gauge(int fd)
598{
599 int status;
600 if(ioctl(fd, NWZ_POWER_GET_BAT_GAUGE, &status) < 0)
601 return -1;
602 return status;
603}
604
605int nwz_power_get_battery_adval(int fd)
606{
607 int status;
608 if(ioctl(fd, NWZ_POWER_GET_BAT_ADVAL, &status) < 0)
609 return -1;
610 return status;
611}
612
613int nwz_power_get_battery_voltage(int fd)
614{
615 return nwz_power_adval_to_mv(nwz_power_get_battery_adval(fd), NWZ_POWER_AD_BASE_VBAT);
616}
617
618int nwz_power_get_vbat_adval(int fd)
619{
620 int status;
621 if(ioctl(fd, NWZ_POWER_GET_VBAT_ADVAL, &status) < 0)
622 return -1;
623 return status;
624}
625
626int nwz_power_get_vbat_voltage(int fd)
627{
628 return nwz_power_adval_to_mv(nwz_power_get_vbat_adval(fd), NWZ_POWER_AD_BASE_VBAT);
629}
630
631int nwz_power_get_sample_count(int fd)
632{
633 int status;
634 if(ioctl(fd, NWZ_POWER_GET_SAMPLE_COUNT, &status) < 0)
635 return -1;
636 return status;
637}
638
639int nwz_power_get_vsys_adval(int fd)
640{
641 int status;
642 if(ioctl(fd, NWZ_POWER_GET_VSYS_ADVAL, &status) < 0)
643 return -1;
644 return status;
645}
646
647int nwz_power_get_vsys_voltage(int fd)
648{
649 return nwz_power_adval_to_mv(nwz_power_get_vsys_adval(fd), NWZ_POWER_AD_BASE_VSYS);
650}
651
652int nwz_power_get_acc_charge_mode(int fd)
653{
654 int status;
655 if(ioctl(fd, NWZ_POWER_GET_ACCESSARY_CHARGE_MODE, &status) < 0)
656 return -1;
657 return status;
658}
659
660int nwz_power_is_fully_charged(int fd)
661{
662 int status;
663 if(ioctl(fd, NWZ_POWER_IS_FULLY_CHARGED, &status) < 0)
664 return -1;
665 return status;
666}
Amaury Pouly0a229062016-10-31 17:50:16 +0100667
668int nwz_pminfo_open(void)
669{
670 return open(NWZ_PMINFO_DEV, O_RDONLY);
671}
672
673void nwz_pminfo_close(int fd)
674{
675 close(fd);
676}
677
678unsigned int nwz_pminfo_get_factor(int fd)
679{
680 unsigned int val;
681 if(ioctl(fd, NWZ_PMINFO_GET_FACTOR, &val) < 0)
682 return 0;
683 else
684 return val;
685}
Amaury Poulyc95e30b2016-11-11 16:01:14 +0100686
687static unsigned long find_model_id(void)
688{
689 /* try with the environment variable */
690 const char *mid = getenv("ICX_MODEL_ID");
691 if(mid == NULL)
692 return 0;
693 char *end;
694 unsigned long v = strtoul(mid, &end, 0);
695 if(*end)
696 return 0;
697 else
698 return v;
699}
700
701unsigned long nwz_get_model_id(void)
702{
703 static unsigned long model_id = 0xffffffff;
704 if(model_id == 0xffffffff)
705 model_id = find_model_id();
706 return model_id;
707}
708
709const char *nwz_get_model_name()
710{
711 for(int i = 0; i < NWZ_MODEL_COUNT; i++)
712 if(nwz_model[i].mid == nwz_get_model_id())
713 return nwz_model[i].name;
714 return NULL;
715}
716
717static int find_series(void)
718{
719 for(int i = 0; i < NWZ_SERIES_COUNT; i++)
720 for(int j = 0; j < nwz_series[i].mid_count; j++)
721 if(nwz_series[i].mid[j] == nwz_get_model_id())
722 return i;
723 return -1;
724}
725
726int nwz_get_series(void)
727{
728 static int series = -2;
729 if(series == -2)
730 series = find_series();
731 return series;
732}
733
734static nwz_nvp_index_t *get_nvp_index(void)
735{
736 static nwz_nvp_index_t *index = 0;
737 if(index == 0)
738 {
739 int series = nwz_get_series();
740 index = series < 0 ? 0 : nwz_series[series].nvp_index;
741 }
742 return index;
743}
744
745int nwz_nvp_read(enum nwz_nvp_node_t node, void *data)
746{
747 int size = nwz_nvp[node].size;
748 if(data == 0)
749 return size;
750 nwz_nvp_index_t *index = get_nvp_index();
751 if(index == 0 || (*index)[node] == NWZ_NVP_INVALID)
752 return -1;
753 char nvp_path[32];
754 snprintf(nvp_path, sizeof(nvp_path), "/dev/icx_nvp/%03d", (*index)[node]);
755 int fd = open(nvp_path, O_RDONLY);
756 if(fd < 0)
757 return -1;
758 int cnt = read(fd, data, size);
759 close(fd);
760 return cnt == size ? size : -1;
761}
762
763int nwz_nvp_write(enum nwz_nvp_node_t node, void *data)
764{
765 int size = nwz_nvp[node].size;
766 nwz_nvp_index_t *index = get_nvp_index();
767 if(index == 0 || (*index)[node] == NWZ_NVP_INVALID)
768 return -1;
769 char nvp_path[32];
770 snprintf(nvp_path, sizeof(nvp_path), "/dev/icx_nvp/%03d", (*index)[node]);
771 int fd = open(nvp_path, O_WRONLY);
772 if(fd < 0)
773 return -1;
774 int cnt = write(fd, data, size);
775 close(fd);
776 return cnt == size ? 0 : -1;
777}