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