1 /*
2 * Copyright (C) 2018 Knowles Electronics
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "iaxxx_odsp_hw"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <log/log.h>
23 #include <sys/ioctl.h>
24 #include <inttypes.h>
25
26 #include "iaxxx_odsp_hw.h"
27
28 #define DEV_NODE "/dev/iaxxx-odsp-celldrv"
29 #define FUNCTION_ENTRY_LOG ALOGV("Entering %s", __func__);
30 #define FUNCTION_EXIT_LOG ALOGV("Exiting %s", __func__);
31
32 #define IAXXX_DEBUG_BLOCK_0_EXEC_STATUS_IDENTIFIER_MASK 0x0000ffff
33 #define IAXXX_DEBUG_BLOCK_0_EXEC_STATUS_IDENTIFIER_POS 0
34 #define IAXXX_DEBUG_BLOCK_0_EXEC_STATUS_TYPE_MASK 0x00070000
35 #define IAXXX_DEBUG_BLOCK_0_EXEC_STATUS_TYPE_POS 16
36
37 struct iaxxx_odsp_hw {
38 FILE *dev_node;
39 };
40
41 /**
42 * Initialize the ODSP HAL
43 *
44 * Input - NA
45 * Output - Handle to iaxxx_odsp_hw on success, NULL on failure
46 */
iaxxx_odsp_init()47 struct iaxxx_odsp_hw* iaxxx_odsp_init()
48 {
49 struct iaxxx_odsp_hw *ioh = NULL;
50
51 FUNCTION_ENTRY_LOG;
52
53 ioh = (struct iaxxx_odsp_hw *)malloc(sizeof(struct iaxxx_odsp_hw));
54 if (ioh == NULL) {
55 ALOGE("%s: ERROR: Failed to allocate memory for iaxxx_odsp_hw",
56 __func__);
57 goto func_exit;
58 }
59
60 ioh->dev_node = fopen(DEV_NODE, "rw");
61 if (ioh->dev_node == NULL) {
62 ALOGE("%s: ERROR: Failed to open %s", __func__, DEV_NODE);
63 free(ioh);
64 ioh = NULL;
65 }
66
67 func_exit:
68 FUNCTION_EXIT_LOG;
69 return ioh;
70 }
71
72 /**
73 * De-Initialize the ODSP HAL
74 *
75 * Input - odsp_hw_hdl - Handle to odsp hw structure
76 * Output - 0 on success, on failure < 0
77 */
iaxxx_odsp_deinit(struct iaxxx_odsp_hw * odsp_hw_hdl)78 int iaxxx_odsp_deinit(struct iaxxx_odsp_hw *odsp_hw_hdl)
79 {
80
81 int err = 0;
82
83 FUNCTION_ENTRY_LOG;
84 if (odsp_hw_hdl == NULL) {
85 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
86 err = -1;
87 goto func_exit;
88 }
89
90 if (odsp_hw_hdl->dev_node) {
91 fclose(odsp_hw_hdl->dev_node);
92 }
93
94 free(odsp_hw_hdl);
95 func_exit:
96 FUNCTION_EXIT_LOG;
97 return err;
98 }
99
100 /**
101 * Load a package
102 *
103 * Input - odsp_hw_hdl - Handle to odsp hw structure
104 * pkg_name - Relative path to the Package binary (Should be placed in
105 * the firmware location)
106 * pkg_id - Package ID
107 * Output - 0 on success, on failure < 0
108 */
iaxxx_odsp_package_load(struct iaxxx_odsp_hw * odsp_hw_hdl,const char * pkg_name,const uint32_t pkg_id)109 int iaxxx_odsp_package_load(struct iaxxx_odsp_hw *odsp_hw_hdl,
110 const char *pkg_name, const uint32_t pkg_id)
111 {
112 int err = 0;
113 struct iaxxx_pkg_mgmt_info pkg_info;
114
115 FUNCTION_ENTRY_LOG;
116
117 if (odsp_hw_hdl == NULL) {
118 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
119 err = -1;
120 goto func_exit;
121 }
122
123 if (pkg_name == NULL) {
124 ALOGE("%s: ERROR: Package name cannot be null", __func__);
125 err = -1;
126 goto func_exit;
127 }
128
129 ALOGV("%s: Package name %s, package id %u",
130 __func__, pkg_name, pkg_id);
131
132 strlcpy(pkg_info.pkg_name, pkg_name, NAME_MAX_SIZE);
133 pkg_info.pkg_id = pkg_id;
134 err = ioctl(fileno(odsp_hw_hdl->dev_node),
135 ODSP_LOAD_PACKAGE, (unsigned long)&pkg_info);
136 if (err < 0) {
137 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
138 }
139
140 func_exit:
141 FUNCTION_EXIT_LOG;
142 return err;
143 }
144
145 /**
146 * Unload a package
147 *
148 * Input - odsp_hw_hdl - Handle to odsp hw structure
149 * pkg_name - Relative path to the Package binary (Should be placed in
150 * the firmware location)
151 * pkg_id - Package ID
152 * Output - 0 on success, on failure < 0
153 */
iaxxx_odsp_package_unload(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t pkg_id)154 int iaxxx_odsp_package_unload(struct iaxxx_odsp_hw *odsp_hw_hdl,
155 const uint32_t pkg_id)
156 {
157 int err = 0;
158 struct iaxxx_pkg_mgmt_info pkg_info;
159
160 FUNCTION_ENTRY_LOG;
161
162 if (odsp_hw_hdl == NULL) {
163 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
164 err = -1;
165 goto func_exit;
166 }
167
168 ALOGV("%s: package id %u", __func__, pkg_id);
169
170 pkg_info.pkg_id = pkg_id;
171 err = ioctl(fileno(odsp_hw_hdl->dev_node),
172 ODSP_UNLOAD_PACKAGE, (unsigned long)&pkg_info);
173 if (err < 0) {
174 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
175 }
176
177 func_exit:
178 FUNCTION_EXIT_LOG;
179 return err;
180 }
181
182 /**
183 * Get package version
184 *
185 * Input - odsp_hw_hdl - Handle to odsp hw structure
186 * inst_id - Instance ID
187 * version - Package version string buffer
188 * len - String buffer size
189 *
190 * Output - 0 on success, on failure < 0
191 */
iaxxx_odsp_plugin_get_package_version(struct iaxxx_odsp_hw * odsp_hw_hdl,uint8_t inst_id,char * version,uint32_t len)192 int iaxxx_odsp_plugin_get_package_version(struct iaxxx_odsp_hw *odsp_hw_hdl,
193 uint8_t inst_id, char *version,
194 uint32_t len)
195 {
196 int err = 0;
197 struct iaxxx_plugin_get_package_version v;
198
199 FUNCTION_ENTRY_LOG;
200
201 if (odsp_hw_hdl == NULL) {
202 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
203 err = -1;
204 goto func_exit;
205 }
206
207 if (len > sizeof(v.version)) {
208 ALOGW("%s: WARNING: Too large len %u, limit it to %zu", __func__, len,
209 sizeof(v.version));
210 len = sizeof(v.version);
211 }
212
213 ALOGV("%s: inst_id %u", __func__, inst_id);
214
215 v.inst_id = inst_id;
216 v.len = len;
217 err = ioctl(fileno(odsp_hw_hdl->dev_node),
218 ODSP_PLG_GET_PACKAGE_VERSION, (unsigned long)&v);
219 if (err < 0) {
220 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
221 } else {
222 memcpy(version, v.version, len);
223 }
224
225 func_exit:
226 FUNCTION_EXIT_LOG;
227 return err;
228 }
229
230 /**
231 * Get plugin version
232 *
233 * Input - odsp_hw_hdl - Handle to odsp hw structure
234 * inst_id - Instance ID
235 * version - Plugin version string buffer
236 * len - String buffer size
237 *
238 * Output - 0 on success, on failure < 0
239 */
iaxxx_odsp_plugin_get_plugin_version(struct iaxxx_odsp_hw * odsp_hw_hdl,uint8_t inst_id,char * version,uint32_t len)240 int iaxxx_odsp_plugin_get_plugin_version(struct iaxxx_odsp_hw *odsp_hw_hdl,
241 uint8_t inst_id, char *version,
242 uint32_t len)
243 {
244 int err = 0;
245 struct iaxxx_plugin_get_plugin_version v;
246
247 FUNCTION_ENTRY_LOG;
248
249 if (odsp_hw_hdl == NULL) {
250 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
251 err = -1;
252 goto func_exit;
253 }
254
255 if (len > sizeof(v.version)) {
256 ALOGW("%s: WARNING: Too large len %u, limit it to %zu", __func__, len,
257 sizeof(v.version));
258 len = sizeof(v.version);
259 }
260
261 ALOGV("%s: inst_id %u", __func__, inst_id);
262
263 v.inst_id = inst_id;
264 v.len = len;
265 err = ioctl(fileno(odsp_hw_hdl->dev_node),
266 ODSP_PLG_GET_PLUGIN_VERSION, (unsigned long)&v);
267 if (err < 0) {
268 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
269 } else {
270 memcpy(version, v.version, len);
271 }
272
273 func_exit:
274 FUNCTION_EXIT_LOG;
275 return err;
276 }
277
278 /**
279 * Create a plugin
280 *
281 * Input - odsp_hw_hdl - Handle to odsp hw structure
282 * inst_id - Instance ID
283 * priority - Priority of the plugin
284 * pkg_id - Package ID
285 * plg_idx - Plugin Index*
286 * block_id - Block ID
287 * config_id - Config ID
288 *
289 * Output - 0 on success, on failure < 0
290 */
iaxxx_odsp_plugin_create(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t priority,const uint32_t pkg_id,const uint32_t plg_idx,const uint32_t block_id,const uint32_t config_id)291 int iaxxx_odsp_plugin_create(struct iaxxx_odsp_hw *odsp_hw_hdl,
292 const uint32_t inst_id,
293 const uint32_t priority,
294 const uint32_t pkg_id,
295 const uint32_t plg_idx,
296 const uint32_t block_id,
297 const uint32_t config_id)
298 {
299 int err = 0;
300 struct iaxxx_plugin_info pi;
301
302 FUNCTION_ENTRY_LOG;
303
304 if (odsp_hw_hdl == NULL) {
305 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
306 err = -1;
307 goto func_exit;
308 }
309
310 ALOGV("%s: Plugin index %u, package id %u, block id %u, instance id %u"
311 " priority %u", __func__, plg_idx, pkg_id, block_id, inst_id, priority);
312
313 pi.plg_idx = plg_idx;
314 pi.pkg_id = pkg_id;
315 pi.block_id = block_id;
316 pi.inst_id = inst_id;
317 pi.priority = priority;
318 pi.config_id = config_id;
319 err = ioctl(fileno(odsp_hw_hdl->dev_node),
320 ODSP_PLG_CREATE, (unsigned long)&pi);
321 if (err < 0) {
322 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
323 }
324
325 func_exit:
326 FUNCTION_EXIT_LOG;
327 return err;
328 }
329
330 /**
331 * Set the creation configuration on a plugin
332 *
333 * Input - odsp_hw_hdl - Handle to odsp hw structure
334 * inst_id - Instance ID
335 * block_id - Block ID
336 * cdata - Creation configuration data
337 * Output - 0 on success, on failure < 0
338 */
iaxxx_odsp_plugin_set_creation_config(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t block_id,struct iaxxx_create_config_data cdata)339 int iaxxx_odsp_plugin_set_creation_config(struct iaxxx_odsp_hw *odsp_hw_hdl,
340 const uint32_t inst_id,
341 const uint32_t block_id,
342 struct iaxxx_create_config_data cdata)
343 {
344 int err = 0;
345 struct iaxxx_plugin_create_cfg pcc;
346
347 FUNCTION_ENTRY_LOG;
348
349 if (odsp_hw_hdl == NULL) {
350 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
351 err = -1;
352 goto func_exit;
353 }
354
355 pcc.inst_id = inst_id;
356 pcc.block_id = block_id;
357 pcc.cfg_size = 0;
358 switch (cdata.type) {
359 case CONFIG_FILE:
360 strlcpy(pcc.file_name, cdata.data.fdata.filename, NAME_MAX_SIZE);
361 ALOGV("%s: Configuration file name %s", __func__, pcc.file_name);
362 break;
363 case CONFIG_VALUE:
364 pcc.cfg_size = cdata.data.vdata.config_val_sz;
365 pcc.cfg_val = cdata.data.vdata.config_val;
366 ALOGV("%s: Configuration value %"PRId64, __func__, pcc.cfg_val);
367 break;
368 default:
369 ALOGE("%s: ERROR: Invalid type of configuration type", __func__);
370 err = -1;
371 goto func_exit;
372 break;
373 }
374
375 ALOGV("%s: Instance id %u, block id %u", __func__, inst_id, block_id);
376
377 err = ioctl(fileno(odsp_hw_hdl->dev_node),
378 ODSP_PLG_SET_CREATE_CFG, (unsigned long)&pcc);
379 if (err < 0) {
380 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
381 }
382
383 func_exit:
384 FUNCTION_EXIT_LOG;
385 return err;
386 }
387
388 /**
389 * Destroy the plugin
390 *
391 * Input - odsp_hw_hdl - Handle to odsp hw structure
392 * inst_id - Instance ID
393 * block_id - Block ID
394 *
395 * Output - 0 on success, on failure < 0
396 */
iaxxx_odsp_plugin_destroy(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t block_id)397 int iaxxx_odsp_plugin_destroy(struct iaxxx_odsp_hw *odsp_hw_hdl,
398 const uint32_t inst_id,
399 const uint32_t block_id)
400 {
401 int err = 0;
402 struct iaxxx_plugin_info pi;
403
404 FUNCTION_ENTRY_LOG;
405
406 if (odsp_hw_hdl == NULL) {
407 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
408 err = -1;
409 goto func_exit;
410 }
411
412 ALOGV("%s: instance id %u, block id %u", __func__, inst_id, block_id);
413
414 pi.block_id = block_id;
415 pi.inst_id = inst_id;
416 err = ioctl(fileno(odsp_hw_hdl->dev_node),
417 ODSP_PLG_DESTROY, (unsigned long) &pi);
418 if (err < 0) {
419 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
420 }
421
422 func_exit:
423 FUNCTION_EXIT_LOG;
424 return err;
425 }
426
427 /**
428 * Enable the plugin
429 *
430 * Input - odsp_hw_hdl - Handle to odsp hw structure
431 * inst_id - Instance ID
432 * block_id - Block ID
433 * Output - 0 on success, on failure < 0
434 */
iaxxx_odsp_plugin_enable(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t block_id)435 int iaxxx_odsp_plugin_enable(struct iaxxx_odsp_hw *odsp_hw_hdl,
436 const uint32_t inst_id,
437 const uint32_t block_id)
438 {
439 int err = 0;
440 struct iaxxx_plugin_info pi;
441
442 FUNCTION_ENTRY_LOG;
443
444 if (odsp_hw_hdl == NULL) {
445 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
446 err = -1;
447 goto func_exit;
448 }
449
450 ALOGV("%s: instance id %u, block id %u", __func__, inst_id, block_id);
451
452 pi.block_id = block_id;
453 pi.inst_id = inst_id;
454 err = ioctl(fileno(odsp_hw_hdl->dev_node),
455 ODSP_PLG_ENABLE, (unsigned long)&pi);
456 if (err < 0) {
457 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
458 }
459
460 func_exit:
461 FUNCTION_EXIT_LOG;
462 return err;
463 }
464
465 /**
466 * Disable the plugin
467 *
468 * Input - odsp_hw_hdl - Handle to odsp hw structure
469 * inst_id - Instance ID
470 * block_id - Block ID
471 * Output - 0 on success, on failure < 0
472 */
iaxxx_odsp_plugin_disable(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t block_id)473 int iaxxx_odsp_plugin_disable(struct iaxxx_odsp_hw *odsp_hw_hdl,
474 const uint32_t inst_id,
475 const uint32_t block_id)
476 {
477 int err = 0;
478 struct iaxxx_plugin_info pi;
479
480 FUNCTION_ENTRY_LOG;
481
482 if (odsp_hw_hdl == NULL) {
483 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
484 err = -1;
485 goto func_exit;
486 }
487
488 ALOGV("%s: instance id %u, block id %u", __func__, inst_id, block_id);
489
490 pi.block_id = block_id;
491 pi.inst_id = inst_id;
492 err = ioctl(fileno(odsp_hw_hdl->dev_node),
493 ODSP_PLG_DISABLE, (unsigned long)&pi);
494 if (err < 0) {
495 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
496 }
497
498 func_exit:
499 FUNCTION_EXIT_LOG;
500 return err;
501 }
502
503 /**
504 * Reset the plugin
505 *
506 * Input - odsp_hw_hdl - Handle to odsp hw structure
507 * inst_id - Instance ID
508 * block_id - Block ID
509 * Output - 0 on success, on failure < 0
510 */
iaxxx_odsp_plugin_reset(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t block_id)511 int iaxxx_odsp_plugin_reset(struct iaxxx_odsp_hw *odsp_hw_hdl,
512 const uint32_t inst_id,
513 const uint32_t block_id)
514 {
515 int err = 0;
516 struct iaxxx_plugin_info pi;
517
518 FUNCTION_ENTRY_LOG;
519
520 if (odsp_hw_hdl == NULL) {
521 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
522 err = -1;
523 goto func_exit;
524 }
525
526 ALOGV("%s: instance id %u, block id %u", __func__, inst_id, block_id);
527
528 pi.block_id = block_id;
529 pi.inst_id = inst_id;
530 err = ioctl(fileno(odsp_hw_hdl->dev_node),
531 ODSP_PLG_RESET, (unsigned long)&pi);
532 if (err < 0) {
533 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
534 }
535
536 func_exit:
537 FUNCTION_EXIT_LOG;
538 return err;
539 }
540
541 /**
542 * Set a parameter on a plugin
543 *
544 * Input - odsp_hw_hdl - Handle to odsp hw structure
545 * inst_id - Instance ID
546 * param_id - Parameter ID
547 * param_val - Parameter Value*
548 * block_id - Block ID
549 * Output - 0 on success, on failure < 0
550 */
iaxxx_odsp_plugin_set_parameter(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t param_id,const uint32_t param_val,const uint32_t block_id)551 int iaxxx_odsp_plugin_set_parameter(struct iaxxx_odsp_hw *odsp_hw_hdl,
552 const uint32_t inst_id,
553 const uint32_t param_id,
554 const uint32_t param_val,
555 const uint32_t block_id)
556 {
557 int err = 0;
558 struct iaxxx_plugin_param pp;
559
560 FUNCTION_ENTRY_LOG;
561
562 if (odsp_hw_hdl == NULL) {
563 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
564 err = -1;
565 goto func_exit;
566 }
567
568 ALOGV("%s: Instance id %u, block id %u param_id %u param_val %u",
569 __func__, inst_id, block_id, param_id, param_val);
570
571 pp.inst_id = inst_id;
572 pp.block_id = block_id;
573 pp.param_id = param_id;
574 pp.param_val = param_val;
575 err = ioctl(fileno(odsp_hw_hdl->dev_node),
576 ODSP_PLG_SET_PARAM, (unsigned long)&pp);
577 if (err < 0) {
578 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
579 }
580
581 func_exit:
582 FUNCTION_EXIT_LOG;
583 return err;
584 }
585
586 /**
587 * Get the value of parameter on a plugin
588 *
589 * Input - odsp_hw_hdl - Handle to odsp hw structure
590 * inst_id - Instance ID
591 * param_id - Parameter ID
592 * block_id - Block ID*
593 * param_val - Parameter Value
594 * Output - 0 on success, on failure < 0
595 */
iaxxx_odsp_plugin_get_parameter(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t param_id,const uint32_t block_id,uint32_t * param_val)596 int iaxxx_odsp_plugin_get_parameter(struct iaxxx_odsp_hw *odsp_hw_hdl,
597 const uint32_t inst_id,
598 const uint32_t param_id,
599 const uint32_t block_id,
600 uint32_t *param_val)
601 {
602 int err = 0;
603 struct iaxxx_plugin_param pp;
604
605 FUNCTION_ENTRY_LOG;
606
607 if (odsp_hw_hdl == NULL) {
608 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
609 err = -1;
610 goto func_exit;
611 }
612
613 pp.inst_id = inst_id;
614 pp.block_id = block_id;
615 pp.param_id = param_id;
616 pp.param_val = 0;
617 err = ioctl(fileno(odsp_hw_hdl->dev_node),
618 ODSP_PLG_GET_PARAM, (unsigned long)&pp);
619 if (err < 0) {
620 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
621 goto func_exit;
622 }
623
624 *param_val = pp.param_val;
625
626 ALOGV("%s: Instance id %u, block id %u param_id %u param_val %u",
627 __func__, inst_id, block_id, param_id, *param_val);
628
629 func_exit:
630 FUNCTION_EXIT_LOG;
631 return err;
632 }
633
634 /**
635 * Set a parameter block on a plugin
636 *
637 * Input - odsp_hw_hdl - Handle to odsp hw structure
638 * inst_id - Instance ID
639 * param_blk_id - Parameter block id
640 * block_id - Block ID
641 * param_buf - Pointer to the parameter block
642 * param_buf_sz - Parameter block size
643 * Output - 0 on success, on failure < 0
644 */
iaxxx_odsp_plugin_set_parameter_blk(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t param_blk_id,const uint32_t block_id,const void * param_buf,const uint32_t param_buf_sz)645 int iaxxx_odsp_plugin_set_parameter_blk(struct iaxxx_odsp_hw *odsp_hw_hdl,
646 const uint32_t inst_id,
647 const uint32_t param_blk_id,
648 const uint32_t block_id,
649 const void *param_buf,
650 const uint32_t param_buf_sz)
651 {
652 int err = 0;
653 struct iaxxx_plugin_param_blk ppb;
654
655 FUNCTION_ENTRY_LOG;
656
657 if (odsp_hw_hdl == NULL) {
658 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
659 err = -1;
660 goto func_exit;
661 }
662
663 ALOGV("%s: Instance id %u, block id %u, param_buf_sz %u, parm_blk_id %u",
664 __func__, inst_id, block_id, param_buf_sz, param_blk_id);
665
666 ppb.inst_id = inst_id;
667 ppb.block_id = block_id;
668 ppb.param_size = param_buf_sz;
669 ppb.param_blk = (uintptr_t)param_buf;
670 ppb.id = param_blk_id;
671 ppb.file_name[0] = '\0';
672 err = ioctl(fileno(odsp_hw_hdl->dev_node),
673 ODSP_PLG_SET_PARAM_BLK, (unsigned long)&ppb);
674 if (err < 0) {
675 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
676 }
677
678 func_exit:
679 FUNCTION_EXIT_LOG;
680 return err;
681 }
682
683 /**
684 * Set a parameter block on a plugin
685 *
686 * Input - odsp_hw_hdl - Handle to odsp hw structure
687 * inst_id - Instance ID
688 * param_blk_id - Parameter block id
689 * block_id - Block ID
690 * file_name - Relative path to the Parameter File(Should be placed in
691 * the firmware location)
692 * Output - 0 on success, on failure < 0
693 */
iaxxx_odsp_plugin_set_parameter_blk_from_file(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t param_blk_id,const uint32_t block_id,const char * file_name)694 int iaxxx_odsp_plugin_set_parameter_blk_from_file(
695 struct iaxxx_odsp_hw *odsp_hw_hdl,
696 const uint32_t inst_id,
697 const uint32_t param_blk_id,
698 const uint32_t block_id,
699 const char *file_name)
700 {
701 int err = 0;
702 struct iaxxx_plugin_param_blk ppb;
703
704 FUNCTION_ENTRY_LOG;
705
706 if (odsp_hw_hdl == NULL) {
707 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
708 err = -1;
709 goto func_exit;
710 }
711
712 ALOGV("%s: Instance id %u, block id %u, file_name %s, parm_blk_id %u",
713 __func__, inst_id, block_id, file_name, param_blk_id);
714
715 ppb.param_size = 0;
716 ppb.param_blk = (uintptr_t) NULL;
717 ppb.inst_id = inst_id;
718 ppb.block_id = block_id;
719 ppb.id = param_blk_id;
720 strlcpy(ppb.file_name, file_name, NAME_MAX_SIZE);
721 err = ioctl(fileno(odsp_hw_hdl->dev_node),
722 ODSP_PLG_SET_PARAM_BLK, (unsigned long)&ppb);
723 if (err < 0) {
724 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
725 }
726
727 func_exit:
728 FUNCTION_EXIT_LOG;
729 return err;
730 }
731
732
733
734 /**
735 * Set custom configuration for plugin
736 *
737 * Input - odsp_hw_hdl - Handle to odsp hw structure
738 * inst_id - Instance ID
739 * block_id - Block ID
740 * param_blk_id - Parameter block id
741 * custom_config_id - Id for what type of custom configuration
742 * filename - Name of file with custom config data
743 *
744 * Output - 0 on success, on failure < 0
745 */
iaxxx_odsp_plugin_set_custom_cfg(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t block_id,const uint32_t param_blk_id,const uint32_t custom_config_id,const char * filename)746 int iaxxx_odsp_plugin_set_custom_cfg(struct iaxxx_odsp_hw *odsp_hw_hdl,
747 const uint32_t inst_id,
748 const uint32_t block_id,
749 const uint32_t param_blk_id,
750 const uint32_t custom_config_id,
751 const char *filename)
752 {
753 int err = 0;
754 struct iaxxx_plugin_custom_cfg pcc;
755
756 FUNCTION_ENTRY_LOG;
757
758 if (odsp_hw_hdl == NULL) {
759 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
760 err = -1;
761 goto func_exit;
762 }
763
764 ALOGV("%s: Instance id %u, block id %u, param blk id %u"
765 " custom-config id %u filename %s",
766 __func__, inst_id, block_id, param_blk_id,custom_config_id, filename);
767
768 strlcpy(pcc.file_name, filename, NAME_MAX_SIZE);
769 pcc.inst_id = inst_id;
770 pcc.block_id = block_id;
771 pcc.param_blk_id = param_blk_id;
772 pcc.custom_config_id = custom_config_id;
773
774 err = ioctl(fileno(odsp_hw_hdl->dev_node),
775 ODSP_PLG_SET_CUSTOM_CFG, (unsigned long)&pcc);
776 if (err < 0) {
777 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
778 }
779
780 func_exit:
781 FUNCTION_EXIT_LOG;
782 return err;
783 }
784
785 /**
786 * Subscribe to an event
787 *
788 * Input - odsp_hw_hdl - Handle to odsp hw structure
789 * src_id - System Id of event source
790 * event_id - Event Id
791 * dst_id - System Id of event destination
792 * dst_opaque - Info sought by destination task when even occurs
793 *
794 * Output - 0 on success, on failure < 0
795 */
iaxxx_odsp_evt_subscribe(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint16_t src_id,const uint16_t event_id,const uint16_t dst_id,const uint32_t dst_opaque)796 int iaxxx_odsp_evt_subscribe(struct iaxxx_odsp_hw *odsp_hw_hdl,
797 const uint16_t src_id,
798 const uint16_t event_id,
799 const uint16_t dst_id,
800 const uint32_t dst_opaque)
801 {
802 int err = 0;
803 struct iaxxx_evt_info ei;
804
805 FUNCTION_ENTRY_LOG;
806
807 if (odsp_hw_hdl == NULL) {
808 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
809 err = -1;
810 goto func_exit;
811 }
812
813 ALOGV("%s: src id %u, event id %u, dst_id %u dst_opq %u",
814 __func__, src_id, event_id, dst_id, dst_opaque);
815
816 ei.src_id = src_id;
817 ei.event_id = event_id;
818 ei.dst_id = dst_id;
819 ei.dst_opaque = dst_opaque;
820
821 err = ioctl(fileno(odsp_hw_hdl->dev_node),
822 ODSP_EVENT_SUBSCRIBE, (unsigned long)&ei);
823 if (err < 0) {
824 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
825 }
826
827 func_exit:
828 FUNCTION_EXIT_LOG;
829 return err;
830 }
831
832 /**
833 * Unsubscribe an event
834 *
835 * Input - odsp_hw_hdl - Handle to odsp hw structure
836 * src_id - System Id of event source
837 * event_id - Event Id
838 * dst_id - System Id of event destination
839 *
840 * Output - 0 on success, on failure < 0
841 */
iaxxx_odsp_evt_unsubscribe(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint16_t src_id,const uint16_t event_id,const uint16_t dst_id)842 int iaxxx_odsp_evt_unsubscribe(struct iaxxx_odsp_hw *odsp_hw_hdl,
843 const uint16_t src_id,
844 const uint16_t event_id,
845 const uint16_t dst_id)
846 {
847 int err = 0;
848 struct iaxxx_evt_info ei;
849
850 FUNCTION_ENTRY_LOG;
851
852 if (odsp_hw_hdl == NULL) {
853 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
854 err = -1;
855 goto func_exit;
856 }
857
858 ALOGV("%s: src id %u, event id %u, dst_id %u",
859 __func__, src_id, event_id, dst_id);
860
861 ei.src_id = src_id;
862 ei.event_id = event_id;
863 ei.dst_id = dst_id;
864
865 err = ioctl(fileno(odsp_hw_hdl->dev_node),
866 ODSP_EVENT_UNSUBSCRIBE, (unsigned long)&ei);
867 if (err < 0) {
868 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
869 }
870
871 func_exit:
872 FUNCTION_EXIT_LOG;
873 return err;
874 }
875
876 /**
877 * Retrieve an event
878 *
879 * Input - odsp_hw_hdl - Handle to odsp hw structure
880 * event_info - Struct to return event info
881 *
882 * Output - 0 on success, on failure < 0
883 */
iaxxx_odsp_evt_getevent(struct iaxxx_odsp_hw * odsp_hw_hdl,struct iaxxx_get_event_info * event_info)884 int iaxxx_odsp_evt_getevent(struct iaxxx_odsp_hw *odsp_hw_hdl,
885 struct iaxxx_get_event_info *event_info)
886 {
887 int err = 0;
888 struct iaxxx_get_event ei;
889
890 FUNCTION_ENTRY_LOG;
891
892 if (odsp_hw_hdl == NULL) {
893 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
894 err = -1;
895 goto func_exit;
896 }
897
898 err = ioctl(fileno(odsp_hw_hdl->dev_node),
899 ODSP_GET_EVENT, (unsigned long) &ei);
900 if (err < 0) {
901 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
902 }
903
904 ALOGV("%s: event id %u, data %u",
905 __func__, ei.event_id, ei.data);
906 event_info->event_id = ei.event_id;
907 event_info->data = ei.data;
908
909 func_exit:
910 FUNCTION_EXIT_LOG;
911 return err;
912 }
913
914
915 /**
916 * Create a plugin for a statically loaded package
917 *
918 * Input - odsp_hw_hdl - Handle to odsp hw structure
919 * inst_id - Instance ID
920 * priority - Priority of the plugin
921 * pkg_id - Package ID
922 * plg_idx - Plugin Index*
923 * block_id - Block ID
924 * config_id - Config ID
925 *
926 * Output - 0 on success, on failure < 0
927 */
iaxxx_odsp_plugin_create_static_package(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t priority,const uint32_t pkg_id,const uint32_t plg_idx,const uint32_t block_id,const uint32_t config_id)928 int iaxxx_odsp_plugin_create_static_package(struct iaxxx_odsp_hw *odsp_hw_hdl,
929 const uint32_t inst_id,
930 const uint32_t priority,
931 const uint32_t pkg_id,
932 const uint32_t plg_idx,
933 const uint32_t block_id,
934 const uint32_t config_id)
935 {
936 int err = 0;
937 struct iaxxx_plugin_info pi;
938
939 FUNCTION_ENTRY_LOG;
940
941 if (odsp_hw_hdl == NULL) {
942 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
943 err = -1;
944 goto func_exit;
945 }
946
947 ALOGV("%s: Plugin index %u, package id %u, block id %u, instance id %u"
948 " priority %u", __func__, plg_idx, pkg_id, block_id, inst_id, priority);
949
950 pi.plg_idx = plg_idx;
951 pi.pkg_id = pkg_id;
952 pi.block_id = block_id;
953 pi.inst_id = inst_id;
954 pi.priority = priority;
955 pi.config_id = config_id;
956 err = ioctl(fileno(odsp_hw_hdl->dev_node),
957 ODSP_PLG_CREATE_STATIC_PACKAGE, (unsigned long)&pi);
958 if (err < 0) {
959 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
960 }
961
962 func_exit:
963 FUNCTION_EXIT_LOG;
964 return err;
965 }
966
967 /**
968 * Get a parameter block from a plugin
969 *
970 * Input - odsp_hw_hdl - Handle to odsp hw structure
971 * inst_id - Instance ID
972 * block_id - Block ID
973 * param_blk_id - Parameter block id
974 * param_buf - Pointer to the parameter block
975 * param_buf_sz - Parameter block size in words
976 *
977 * Output - 0 on success, on failure < 0
978 */
iaxxx_odsp_plugin_get_parameter_blk(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t block_id,const uint32_t param_blk_id,uint32_t * param_buf,const uint32_t param_buf_sz)979 int iaxxx_odsp_plugin_get_parameter_blk(struct iaxxx_odsp_hw *odsp_hw_hdl,
980 const uint32_t inst_id,
981 const uint32_t block_id,
982 const uint32_t param_blk_id,
983 uint32_t *param_buf,
984 const uint32_t param_buf_sz)
985 {
986 int err = 0;
987 struct iaxxx_plugin_param_blk ppb;
988
989 FUNCTION_ENTRY_LOG;
990
991 if (odsp_hw_hdl == NULL) {
992 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
993 err = -1;
994 goto func_exit;
995 }
996
997 ALOGV("%s: Instance id %u, block id %u, param_buf_sz %u, id %u",
998 __func__, inst_id, block_id, param_buf_sz, param_blk_id);
999
1000 ppb.inst_id = inst_id;
1001 ppb.block_id = block_id;
1002 ppb.id = param_blk_id;
1003 ppb.param_size = param_buf_sz;
1004 ppb.param_blk = (uintptr_t)param_buf;
1005
1006 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1007 ODSP_PLG_GET_PARAM_BLK, (unsigned long)&ppb);
1008 if (err < 0) {
1009 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1010 }
1011
1012 func_exit:
1013 FUNCTION_EXIT_LOG;
1014 return err;
1015 }
1016
1017 /**
1018 * Set Event for the plugin
1019 *
1020 * Input - odsp_hw_hdl - Handle to odsp hw structure
1021 * inst_id - Instance ID
1022 * eventEnableMask - event Mask
1023 * block_id - Block ID
1024 *
1025 * Output - 0 on success, on failure < 0
1026 */
iaxxx_odsp_plugin_setevent(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t eventEnableMask,const uint32_t block_id)1027 int iaxxx_odsp_plugin_setevent(struct iaxxx_odsp_hw *odsp_hw_hdl,
1028 const uint32_t inst_id,
1029 const uint32_t eventEnableMask,
1030 const uint32_t block_id)
1031 {
1032 int err = 0;
1033 struct iaxxx_set_event se;
1034
1035 FUNCTION_ENTRY_LOG;
1036
1037 if (odsp_hw_hdl == NULL) {
1038 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1039 err = -1;
1040 goto func_exit;
1041 }
1042
1043 ALOGV("%s: instance id %u, eventEnableMask %x, block id %u",
1044 __func__, inst_id, eventEnableMask, block_id);
1045
1046 se.block_id = block_id;
1047 se.event_enable_mask = eventEnableMask;
1048 se.inst_id = inst_id;
1049 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1050 ODSP_PLG_SET_EVENT, (unsigned long)&se);
1051 if (err == -1) {
1052 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1053 return err;
1054 }
1055
1056 func_exit:
1057 FUNCTION_EXIT_LOG;
1058 return err;
1059 }
1060
1061 /**
1062 * Trigger an event. This may be most useful when debugging the system,
1063 * but can also be used to trigger simultaneous behavior in entities which
1064 * have subscribed, or to simply provide notifications regarding host status:
1065 *
1066 * Input - odsp_hw_hdl - Handle to odsp hw structure
1067 * src_id - SystemId of event source
1068 * evt_id - Id of event
1069 * src_opaque - Source opaque to pass with event notification
1070 *
1071 * Output - 0 on success, on failure < 0
1072 */
iaxxx_odsp_evt_trigger(struct iaxxx_odsp_hw * odsp_hw_hdl,uint16_t src_id,uint16_t evt_id,uint32_t src_opaque)1073 int iaxxx_odsp_evt_trigger(struct iaxxx_odsp_hw *odsp_hw_hdl,
1074 uint16_t src_id,
1075 uint16_t evt_id,
1076 uint32_t src_opaque)
1077 {
1078 int err = 0;
1079 struct iaxxx_evt_trigger et;
1080
1081 FUNCTION_ENTRY_LOG;
1082
1083 if (odsp_hw_hdl == NULL) {
1084 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1085 err = -1;
1086 goto func_exit;
1087 }
1088
1089 ALOGV("%s: src_id=%u, evt_id=%u, src_opaque=%u", __func__, src_id, evt_id,
1090 src_opaque);
1091
1092 et.src_id = src_id;
1093 et.evt_id = evt_id;
1094 et.src_opaque = src_opaque;
1095 err = ioctl(fileno(odsp_hw_hdl->dev_node), ODSP_EVENT_TRIGGER,
1096 (unsigned long)&et);
1097 if (err == -1) {
1098 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1099 }
1100
1101 func_exit:
1102 FUNCTION_EXIT_LOG;
1103 return err;
1104 }
1105
1106 /**
1107 * Fetches next event subscription entry from the last read position
1108 *
1109 * Input - odsp_hw_hdl - Handle to odsp hw structure
1110 * src_id - System Id of event source
1111 * evt_id - Event Id
1112 * dst_id - System Id of event destination
1113 * dst_opaque - Destination opaque data
1114 *
1115 * Output - 0 on success, on failure < 0
1116 */
iaxxx_odsp_evt_read_subscription(struct iaxxx_odsp_hw * odsp_hw_hdl,uint16_t * src_id,uint16_t * evt_id,uint16_t * dst_id,uint32_t * dst_opaque)1117 int iaxxx_odsp_evt_read_subscription(struct iaxxx_odsp_hw *odsp_hw_hdl,
1118 uint16_t *src_id,
1119 uint16_t *evt_id,
1120 uint16_t *dst_id,
1121 uint32_t *dst_opaque)
1122 {
1123 int err = 0;
1124 struct iaxxx_evt_read_subscription ers;
1125
1126 FUNCTION_ENTRY_LOG;
1127
1128 if (odsp_hw_hdl == NULL) {
1129 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1130 err = -1;
1131 goto func_exit;
1132 }
1133
1134 err = ioctl(fileno(odsp_hw_hdl->dev_node), ODSP_EVENT_READ_SUBSCRIPTION,
1135 (unsigned long) &ers);
1136 if (err == -1) {
1137 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1138 } else {
1139 ALOGV("%s: src_id=%u, evt_id=%u, dst_id=%u, dst_opaque=%u", __func__,
1140 ers.src_id, ers.evt_id, ers.dst_id, ers.dst_opaque);
1141
1142 *src_id = ers.src_id;
1143 *evt_id = ers.evt_id;
1144 *dst_id = ers.dst_id;
1145 *dst_opaque = ers.dst_opaque;
1146 }
1147
1148 func_exit:
1149 FUNCTION_EXIT_LOG;
1150 return err;
1151 }
1152
1153 /**
1154 * Reset index for retrieving subscription entries
1155 *
1156 * Input - odsp_hw_hdl - Handle to odsp hw structure
1157 *
1158 * Output - 0 on success, on failure < 0
1159 */
iaxxx_odsp_evt_reset_read_index(struct iaxxx_odsp_hw * odsp_hw_hdl)1160 int iaxxx_odsp_evt_reset_read_index(struct iaxxx_odsp_hw *odsp_hw_hdl)
1161 {
1162 int err = 0;
1163
1164 FUNCTION_ENTRY_LOG;
1165
1166 if (odsp_hw_hdl == NULL) {
1167 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1168 err = -1;
1169 goto func_exit;
1170 }
1171
1172 err = ioctl(fileno(odsp_hw_hdl->dev_node), ODSP_EVENT_RESET_READ_INDEX,
1173 NULL);
1174 if (err == -1) {
1175 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1176 }
1177
1178 func_exit:
1179 FUNCTION_EXIT_LOG;
1180 return err;
1181 }
1182
1183 /**
1184 * Retrieve an event notification
1185 *
1186 * Input - odsp_hw_hdl - Handle to odsp hw structure
1187 * src_id - pointer to uint16_t for reporting SystemId of
1188 * event source
1189 * evt_dd - pointer to uint16_t for reporting Id of event
1190 * src_opaque - pointer to the first parameter of event
1191 * dst_opaque - pointer to the second parameter of event
1192 * This will be destOpaque in case if event is
1193 * subscribed with valid destOpaque otherwise
1194 * it will be used as second parameter.
1195 *
1196 * Output - 0 on success, on failure < 0
1197 */
iaxxx_odsp_evt_retrieve_notification(struct iaxxx_odsp_hw * odsp_hw_hdl,uint16_t * src_id,uint16_t * evt_id,uint32_t * src_opaque,uint32_t * dst_opaque)1198 int iaxxx_odsp_evt_retrieve_notification(struct iaxxx_odsp_hw *odsp_hw_hdl,
1199 uint16_t *src_id,
1200 uint16_t *evt_id,
1201 uint32_t *src_opaque,
1202 uint32_t *dst_opaque)
1203 {
1204 int err = 0;
1205 struct iaxxx_evt_retrieve_notification ern;
1206
1207 FUNCTION_ENTRY_LOG;
1208
1209 if (odsp_hw_hdl == NULL) {
1210 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1211 err = -1;
1212 goto func_exit;
1213 }
1214
1215 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1216 ODSP_EVENT_RETRIEVE_NOTIFICATION, (unsigned long)&ern);
1217 if (err == -1) {
1218 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1219 } else {
1220 ALOGV("%s: src_id=%u, evt_id=%u, src_opaque=%u, dst_opaque=%u",
1221 __func__, ern.src_id, ern.evt_id, ern.src_opaque, ern.dst_opaque);
1222
1223 *src_id = ern.src_id;
1224 *evt_id = ern.evt_id;
1225 *src_opaque = ern.src_opaque;
1226 *dst_opaque = ern.dst_opaque;
1227 }
1228
1229 func_exit:
1230 FUNCTION_EXIT_LOG;
1231 return err;
1232 }
1233
1234 /* Read Plugin Error Info
1235 *
1236 * Input - odsp_hw_hdl - Handle to odsp hw structure
1237 * error_code - Pointer to uint32 to return error code
1238 * error_instance - Pointer to uint8 to return plugin instance
1239 * where error occurred.
1240 *
1241 * Output - 0 on success, on failure < 0
1242 */
iaxxx_odsp_plugin_read_error(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t block_id,uint32_t * error_code,uint8_t * error_instance)1243 int iaxxx_odsp_plugin_read_error(struct iaxxx_odsp_hw *odsp_hw_hdl,
1244 const uint32_t block_id,
1245 uint32_t *error_code,
1246 uint8_t *error_instance)
1247 {
1248 int err = 0;
1249 struct iaxxx_plugin_error_info pei;
1250
1251 FUNCTION_ENTRY_LOG;
1252
1253 if (odsp_hw_hdl == NULL) {
1254 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1255 err = -1;
1256 goto func_exit;
1257 }
1258
1259 ALOGV("%s: Block id %u", __func__, block_id);
1260
1261 pei.block_id = block_id;
1262
1263 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1264 ODSP_PLG_READ_PLUGIN_ERROR, (unsigned long)&pei);
1265 if (err < 0) {
1266 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1267 } else {
1268 *error_code = pei.error_code;
1269 *error_instance = pei.error_instance;
1270 ALOGV("%s: Plugin error code:%x instance=%d", __func__,
1271 pei.error_code, pei.error_instance);
1272 }
1273
1274 func_exit:
1275 FUNCTION_EXIT_LOG;
1276 return err;
1277 }
1278
1279 /* Read the timestamps of all output endpoint
1280 *
1281 * Input - odsp_hw_hdl - Handle to odsp hw structure
1282 * proc_id - Proc id
1283 *
1284 * Output - 0 on success, on failure < 0
1285 */
iaxxx_odsp_plugin_get_ep_timestamps(struct iaxxx_odsp_hw * odsp_hw_hdl,uint64_t * timestamps,uint8_t proc_id)1286 int iaxxx_odsp_plugin_get_ep_timestamps(struct iaxxx_odsp_hw *odsp_hw_hdl,
1287 uint64_t *timestamps,
1288 uint8_t proc_id)
1289 {
1290 int err = 0;
1291 struct iaxxx_plugin_endpoint_timestamps pet = {
1292 .proc_id = proc_id
1293 };
1294
1295 FUNCTION_ENTRY_LOG;
1296
1297 if (odsp_hw_hdl == NULL) {
1298 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1299 err = -1;
1300 goto func_exit;
1301 }
1302
1303 ALOGV("%s: Proc id %u", __func__, proc_id);
1304
1305 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1306 ODSP_PLG_GET_ENDPOINT_TIMESTAMPS, (unsigned long)&pet);
1307 if (err < 0) {
1308 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1309 } else {
1310 memcpy(timestamps, pet.timestamps, sizeof(pet.timestamps));
1311 }
1312
1313 func_exit:
1314 FUNCTION_EXIT_LOG;
1315 return err;
1316 }
1317
1318 /**
1319 * Set a parameter block on a plugin and get ack to
1320 * ensure the data has been sent and retry if not.
1321 *
1322 * Input - odsp_hw_hdl - Handle to odsp hw structure
1323 * inst_id - Instance ID
1324 * param_blk_id - Parameter block id
1325 * block_id - Block ID
1326 * set_param_buf - Pointer to the parameter block
1327 * set_param_buf_sz - Parameter block size in bytes
1328 * response_data_buf - Buffer for response data from plugin
1329 * response_data_sz - Size of Buffer in uint32 words for
1330 * response data from plugin
1331 * max_no_retries - Max number of retries in case of busy
1332 * response from plugin.
1333 * Output - 0 on success, on failure < 0
1334 */
iaxxx_odsp_plugin_set_parameter_blk_with_ack(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint32_t param_blk_id,const uint32_t block_id,const void * set_param_buf,const uint32_t set_param_buf_sz,uint32_t * response_data_buf,const uint32_t response_data_sz,const uint32_t max_no_retries)1335 int iaxxx_odsp_plugin_set_parameter_blk_with_ack(
1336 struct iaxxx_odsp_hw *odsp_hw_hdl,
1337 const uint32_t inst_id,
1338 const uint32_t param_blk_id,
1339 const uint32_t block_id,
1340 const void *set_param_buf,
1341 const uint32_t set_param_buf_sz,
1342 uint32_t* response_data_buf,
1343 const uint32_t response_data_sz,
1344 const uint32_t max_no_retries)
1345 {
1346
1347 int err = 0;
1348 struct iaxxx_plugin_set_param_blk_with_ack_info pspbwa;
1349
1350 FUNCTION_ENTRY_LOG;
1351
1352 if (odsp_hw_hdl == NULL) {
1353 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1354 err = -1;
1355 goto func_exit;
1356 }
1357
1358 ALOGV("%s: Instance id %u, block id %u, param blk id %u max-retries:%u",
1359 __func__, inst_id, block_id, param_blk_id, max_no_retries);
1360
1361 pspbwa.inst_id = inst_id;
1362 pspbwa.block_id = block_id;
1363 pspbwa.param_blk_id = param_blk_id;
1364 pspbwa.set_param_blk_buffer = (uintptr_t)set_param_buf;
1365 pspbwa.set_param_blk_size = set_param_buf_sz;
1366 pspbwa.response_buffer = (uintptr_t)response_data_buf;
1367 pspbwa.response_buf_size = response_data_sz;
1368 pspbwa.max_retries = max_no_retries;
1369
1370 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1371 ODSP_PLG_SET_PARAM_BLK_WITH_ACK, (unsigned long)&pspbwa);
1372 if (err < 0) {
1373 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1374 }
1375
1376
1377 func_exit:
1378 FUNCTION_EXIT_LOG;
1379 return err;
1380 }
1381
1382 /**
1383 * Get Plugin status information.
1384 *
1385 * Input - odsp_hw_hdl - Handle to odsp hw structure
1386 * inst_id - Instance ID
1387 * plugin_status_data - Pointer to struct to return plugin status.
1388 *
1389 * Output - 0 on success, on failure < 0
1390 */
iaxxx_odsp_plugin_get_status_info(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,struct iaxxx_plugin_status_data * plugin_status_data)1391 int iaxxx_odsp_plugin_get_status_info(struct iaxxx_odsp_hw *odsp_hw_hdl,
1392 const uint32_t inst_id,
1393 struct iaxxx_plugin_status_data *plugin_status_data)
1394 {
1395 int err = 0;
1396 struct iaxxx_plugin_status_info psi;
1397
1398 FUNCTION_ENTRY_LOG;
1399
1400 if (odsp_hw_hdl == NULL) {
1401 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1402 err = -1;
1403 goto func_exit;
1404 }
1405
1406 ALOGV("%s: Instance id %u", __func__, inst_id);
1407
1408 psi.inst_id = inst_id;
1409
1410 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1411 ODSP_PLG_GET_STATUS_INFO, (unsigned long) &psi);
1412 if (err < 0) {
1413 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1414 goto func_exit;
1415 }
1416
1417 plugin_status_data->block_id = psi.block_id;
1418 plugin_status_data->create_status = psi.create_status;
1419 plugin_status_data->enable_status = psi.enable_status;
1420 plugin_status_data->process_count = psi.process_count;
1421 plugin_status_data->process_err_count = psi.process_err_count;
1422 plugin_status_data->in_frames_consumed = psi.in_frames_consumed;
1423 plugin_status_data->out_frames_produced = psi.out_frames_produced;
1424 plugin_status_data->private_memsize = psi.private_memsize;
1425 plugin_status_data->frame_notification_mode = psi.frame_notification_mode;
1426 plugin_status_data->state_management_mode = psi.state_management_mode;
1427
1428 ALOGV("%s: block_id:%u create_status:%d enable_status:%d",
1429 __func__, psi.block_id, psi.create_status, psi.enable_status);
1430 ALOGV("%s: in_frames_consumed:%u out_frames_produced:%u",
1431 __func__, psi.in_frames_consumed, psi.out_frames_produced);
1432 ALOGV("%s: process_count:%u process_err_count=%u private_memsize=%u",
1433 __func__, psi.process_count, psi.process_err_count,
1434 psi.private_memsize);
1435 ALOGV("%s: frame_notification_mode:%u state_management_mode=%u",
1436 __func__, psi.frame_notification_mode, psi.state_management_mode);
1437
1438 func_exit:
1439 FUNCTION_EXIT_LOG;
1440 return err;
1441 }
1442
1443 /**
1444 * Get Plugin endpoint status information.
1445 *
1446 * Input - odsp_hw_hdl - Handle to odsp hw structure
1447 * inst_id - Instance ID
1448 * ep_index - Index of Endpoint
1449 * direction - If Input endpoint or Output endpoint
1450 * 0 => input, 1 => output
1451 * plugin_ep_status_data - Pointer to struct to return plugin
1452 * endpoint status.
1453 *
1454 *
1455 * Output - 0 on success, on failure < 0
1456 */
iaxxx_odsp_plugin_get_endpoint_status(struct iaxxx_odsp_hw * odsp_hw_hdl,const uint32_t inst_id,const uint8_t ep_index,const uint8_t direction,struct iaxxx_plugin_endpoint_status_data * plugin_ep_status_data)1457 int iaxxx_odsp_plugin_get_endpoint_status(struct iaxxx_odsp_hw *odsp_hw_hdl,
1458 const uint32_t inst_id,
1459 const uint8_t ep_index,
1460 const uint8_t direction,
1461 struct iaxxx_plugin_endpoint_status_data *plugin_ep_status_data)
1462 {
1463 int err = 0;
1464 struct iaxxx_plugin_endpoint_status_info plugin_ep_status_info;
1465
1466 FUNCTION_ENTRY_LOG;
1467
1468 if (odsp_hw_hdl == NULL) {
1469 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1470 err = -1;
1471 goto func_exit;
1472 }
1473
1474 ALOGV("%s: Instance id %u", __func__, inst_id);
1475
1476 plugin_ep_status_info.inst_id = inst_id;
1477 plugin_ep_status_info.ep_index = ep_index;
1478 plugin_ep_status_info.direction = direction;
1479
1480 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1481 ODSP_PLG_GET_ENDPOINT_STATUS,
1482 (unsigned long) &plugin_ep_status_info);
1483 if (err < 0) {
1484 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1485 goto func_exit;
1486 }
1487
1488 plugin_ep_status_data->status
1489 = plugin_ep_status_info.status;
1490 plugin_ep_status_data->frame_status
1491 = plugin_ep_status_info.frame_status;
1492 plugin_ep_status_data->endpoint_status
1493 = plugin_ep_status_info.endpoint_status;
1494 plugin_ep_status_data->usage
1495 = plugin_ep_status_info.usage;
1496 plugin_ep_status_data->mandatory
1497 = plugin_ep_status_info.mandatory;
1498 plugin_ep_status_data->counter
1499 = plugin_ep_status_info.counter;
1500
1501 if(direction) {
1502 plugin_ep_status_data->op_encoding
1503 = plugin_ep_status_info.op_encoding;
1504 plugin_ep_status_data->op_sample_rate
1505 = plugin_ep_status_info.op_sample_rate;
1506 plugin_ep_status_data->op_frame_length
1507 = plugin_ep_status_info.op_frame_length;
1508 }
1509
1510 ALOGV("%s: status:%u frame_status:%d endpoint_status:%d",
1511 __func__, plugin_ep_status_data->status,
1512 plugin_ep_status_info.frame_status,
1513 plugin_ep_status_info.endpoint_status);
1514
1515 ALOGV("%s: usage:%d mandatory:%d counter:%u",
1516 __func__, plugin_ep_status_data->usage,
1517 plugin_ep_status_info.mandatory,
1518 plugin_ep_status_info.counter);
1519
1520 if(direction)
1521 ALOGV("%s: op_encoding:%d op_sample_rate:%d op_frame_length:%u",
1522 __func__, plugin_ep_status_data->op_encoding,
1523 plugin_ep_status_info.op_sample_rate,
1524 plugin_ep_status_info.op_frame_length);
1525
1526 func_exit:
1527 FUNCTION_EXIT_LOG;
1528 return err;
1529
1530 }
1531
1532 /**
1533 * Returns the execution status of given processor
1534 *
1535 * Input - odsp_hw_hdl - Handle to odsp hw structure
1536 * proc_id - Proc id
1537 * status - Execution status of the processor
1538 *
1539 * Output - 0 on success, on failure < 0
1540 */
iaxxx_odsp_get_proc_execution_status(struct iaxxx_odsp_hw * odsp_hw_hdl,uint8_t proc_id,uint32_t * status)1541 int iaxxx_odsp_get_proc_execution_status(struct iaxxx_odsp_hw *odsp_hw_hdl,
1542 uint8_t proc_id,
1543 uint32_t *status)
1544 {
1545 int err = 0;
1546 struct iaxxx_proc_execution_status s = {
1547 .proc_id = proc_id
1548 };
1549
1550 FUNCTION_ENTRY_LOG;
1551
1552 if (odsp_hw_hdl == NULL) {
1553 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1554 err = -1;
1555 goto func_exit;
1556 }
1557
1558 ALOGV("%s: Proc id %u", __func__, proc_id);
1559
1560 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1561 ODSP_GET_PROC_EXECUTION_STATUS, (unsigned long)&s);
1562 if (err < 0) {
1563 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1564 } else {
1565 uint32_t id, type;
1566
1567 *status = s.status;
1568
1569 id = ((*status & IAXXX_DEBUG_BLOCK_0_EXEC_STATUS_IDENTIFIER_MASK)
1570 >> IAXXX_DEBUG_BLOCK_0_EXEC_STATUS_IDENTIFIER_POS);
1571 type = ((*status & IAXXX_DEBUG_BLOCK_0_EXEC_STATUS_TYPE_MASK)
1572 >> IAXXX_DEBUG_BLOCK_0_EXEC_STATUS_TYPE_POS);
1573 switch (type) {
1574 case 0:
1575 ALOGI("%s() Proc %d is running Firmware\n",
1576 __func__, s.proc_id);
1577 break;
1578 case 1:
1579 ALOGI("%s() Proc %d is running ISR %d\n",
1580 __func__, s.proc_id, id);
1581 break;
1582 case 2:
1583 ALOGI("%s() Proc %d is running Package ID %d\n",
1584 __func__, s.proc_id, id);
1585 break;
1586 case 3:
1587 ALOGI("%s() Proc %d is running Plugin inst ID %d\n",
1588 __func__, s.proc_id, id);
1589 break;
1590 default:
1591 break;
1592 }
1593 }
1594
1595 func_exit:
1596 FUNCTION_EXIT_LOG;
1597 return err;
1598 }
1599
1600 /**
1601 * Returns Rom version number, Rom version string
1602 * Application version number, Application version string
1603 *
1604 * Input - odsp_hw_hdl - Handle to odsp hw structure
1605 * rom_ver_num - Rom version number
1606 * rom_ver_str - Rom version string
1607 * rom_ver_str_len - Rom version string length
1608 * app_ver_num - App version number
1609 * app_ver_str - App version string
1610 * app_ver_str_len - App version string length
1611 *
1612 * Output - 0 on success, on failure < 0
1613 */
iaxxx_odsp_get_sys_versions(struct iaxxx_odsp_hw * odsp_hw_hdl,uint32_t * rom_ver_num,char * rom_ver_str,uint32_t rom_ver_str_len,uint32_t * app_ver_num,char * app_ver_str,uint32_t app_ver_str_len)1614 int iaxxx_odsp_get_sys_versions(struct iaxxx_odsp_hw *odsp_hw_hdl,
1615 uint32_t *rom_ver_num,
1616 char *rom_ver_str,
1617 uint32_t rom_ver_str_len,
1618 uint32_t *app_ver_num,
1619 char *app_ver_str,
1620 uint32_t app_ver_str_len)
1621 {
1622 int err = 0;
1623 struct iaxxx_sys_versions v = {
1624 .app_ver_str_len =
1625 (app_ver_str ? app_ver_str_len : IAXXX_MAX_VER_STR_SIZE),
1626 .rom_ver_str_len =
1627 (rom_ver_str ? rom_ver_str_len : IAXXX_MAX_VER_STR_SIZE)
1628 };
1629
1630 FUNCTION_ENTRY_LOG;
1631
1632 if (odsp_hw_hdl == NULL) {
1633 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1634 err = -1;
1635 goto func_exit;
1636 }
1637
1638 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1639 ODSP_GET_SYS_VERSIONS, (unsigned long)&v);
1640 if (err < 0) {
1641 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1642 } else {
1643 if (rom_ver_num)
1644 *rom_ver_num = v.rom_ver_num;
1645 if (rom_ver_str)
1646 memcpy(rom_ver_str, v.rom_ver_str, v.rom_ver_str_len);
1647 if (app_ver_num)
1648 *app_ver_num = v.app_ver_num;
1649 if (app_ver_str)
1650 memcpy(app_ver_str, v.app_ver_str, v.app_ver_str_len);
1651 }
1652
1653 func_exit:
1654 FUNCTION_EXIT_LOG;
1655 return err;
1656 }
1657
1658 /**
1659 * Returns Device ID
1660 *
1661 * Input - odsp_hw_hdl - Handle to odsp hw structure
1662 * device_id - Returned Device ID
1663 *
1664 * Output - 0 on success, on failure < 0
1665 */
iaxxx_odsp_get_device_id(struct iaxxx_odsp_hw * odsp_hw_hdl,uint32_t * device_id)1666 int iaxxx_odsp_get_device_id(struct iaxxx_odsp_hw *odsp_hw_hdl,
1667 uint32_t *device_id)
1668 {
1669 int err = 0;
1670
1671 FUNCTION_ENTRY_LOG;
1672
1673 if (odsp_hw_hdl == NULL) {
1674 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1675 err = -1;
1676 goto func_exit;
1677 }
1678
1679 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1680 ODSP_GET_SYS_DEVICE_ID, (unsigned long)device_id);
1681 if (err < 0) {
1682 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1683 }
1684
1685 func_exit:
1686 FUNCTION_EXIT_LOG;
1687 return err;
1688 }
1689
1690 /**
1691 * Returns System mode
1692 *
1693 * Input - odsp_hw_hdl - Handle to odsp hw structure
1694 * mode - Returned system mode
1695 * 0: System is in reset mode.
1696 * 1: System is currently in bootloader mode.
1697 * 2: System has entered application mode.
1698 *
1699 * Output - 0 on success, on failure < 0
1700 */
iaxxx_odsp_get_sys_mode(struct iaxxx_odsp_hw * odsp_hw_hdl,uint32_t * mode)1701 int iaxxx_odsp_get_sys_mode(struct iaxxx_odsp_hw *odsp_hw_hdl,
1702 uint32_t *mode)
1703 {
1704 int err = 0;
1705
1706 FUNCTION_ENTRY_LOG;
1707
1708 if (odsp_hw_hdl == NULL) {
1709 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1710 err = -1;
1711 goto func_exit;
1712 }
1713
1714 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1715 ODSP_GET_SYS_MODE, (unsigned long)mode);
1716 if (err < 0) {
1717 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1718 }
1719
1720 func_exit:
1721 FUNCTION_EXIT_LOG;
1722 return err;
1723 }
1724
1725 /**
1726 * Returns Firmware status
1727 *
1728 * Input - odsp_hw_hdl - Handle to odsp hw structure
1729 * mode - Returned firmware status
1730 * 0: Firmware has crashed
1731 * 1: Firmware is idle
1732 * 2: Firmware is active
1733 *
1734 * Output - 0 on success, on failure < 0
1735 */
iaxxx_odsp_get_fw_status(struct iaxxx_odsp_hw * odsp_hw_hdl,uint32_t * status)1736 int iaxxx_odsp_get_fw_status(struct iaxxx_odsp_hw *odsp_hw_hdl,
1737 uint32_t *status)
1738 {
1739 int err = 0;
1740
1741 FUNCTION_ENTRY_LOG;
1742
1743 if (NULL == odsp_hw_hdl) {
1744 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1745 err = -1;
1746 goto func_exit;
1747 }
1748
1749 err = ioctl(fileno(odsp_hw_hdl->dev_node),
1750 ODSP_GET_FW_STATUS, (unsigned long)status);
1751 if (err < 0) {
1752 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1753 }
1754
1755 func_exit:
1756 FUNCTION_EXIT_LOG;
1757 return err;
1758 }
1759
1760 /**
1761 * Resets the firmware by redownloading the firmware
1762 *
1763 * Input - odsp_hw_hdl - Handle to odsp hw structure
1764 *
1765 * Output - 0 on success, on failure < 0
1766 */
iaxxx_odsp_reset_fw(struct iaxxx_odsp_hw * odsp_hw_hdl)1767 int iaxxx_odsp_reset_fw(struct iaxxx_odsp_hw *odsp_hw_hdl)
1768 {
1769 int err = 0;
1770
1771 FUNCTION_ENTRY_LOG;
1772
1773 if (NULL == odsp_hw_hdl) {
1774 ALOGE("%s: ERROR: Invalid handle to iaxxx_odsp_hw", __func__);
1775 err = -1;
1776 goto func_exit;
1777 }
1778
1779 err = ioctl(fileno(odsp_hw_hdl->dev_node), ODSP_RESET_FW);
1780 if (err < 0) {
1781 ALOGE("%s: ERROR: Failed with error %s", __func__, strerror(errno));
1782 }
1783
1784 func_exit:
1785 FUNCTION_EXIT_LOG;
1786 return err;
1787 }
1788
1789