blob: b5444b134732e37bdcfdcdf32abfbfde80198d5f [file] [log] [blame]
Meng Wang688a8672019-01-29 13:43:33 +08001// SPDX-License-Identifier: GPL-2.0-only
Meng Wang61af6842018-09-10 17:47:55 +08002/*
Aditya Bavanari23513e02019-02-28 11:06:41 +05303 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
Vignesh Kulothungan5c109922018-01-24 17:36:18 -08004 */
5
6#include <dsp/q6common.h>
7
8struct q6common_ctl {
9 bool instance_id_supported;
10};
11
12static struct q6common_ctl common;
13
14/**
15 * q6common_update_instance_id_support
16 *
17 * Update instance ID support flag to true/false
18 *
19 * @supported: enable/disable for instance ID support
20 */
21void q6common_update_instance_id_support(bool supported)
22{
23 common.instance_id_supported = supported;
24}
25EXPORT_SYMBOL(q6common_update_instance_id_support);
26
27/**
28 * q6common_is_instance_id_supported
29 *
30 * Returns true/false for instance ID support
31 */
32bool q6common_is_instance_id_supported(void)
33{
34 return common.instance_id_supported;
35}
36EXPORT_SYMBOL(q6common_is_instance_id_supported);
Vignesh Kulothungan13d0d352018-01-24 17:43:25 -080037
38/**
39 * q6common_pack_pp_params
40 *
41 * Populate params header based on instance ID support and pack
42 * it with payload.
43 * Instance ID support -
44 * yes - param_hdr_v3 + payload
45 * no - param_hdr_v1 + payload
46 *
47 * @dest: destination data pointer to be packed into
48 * @v3_hdr: param header v3
49 * @param_data: param payload
50 * @total_size: total size of packed data (hdr + payload)
51 *
52 * Returns 0 on success or error on failure
53 */
54int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr,
55 u8 *param_data, u32 *total_size)
56{
57 struct param_hdr_v1 *v1_hdr = NULL;
58 u32 packed_size = 0;
59 u32 param_size = 0;
60 bool iid_supported = q6common_is_instance_id_supported();
61
62 if (dest == NULL) {
63 pr_err("%s: Received NULL pointer for destination\n", __func__);
64 return -EINVAL;
65 } else if (v3_hdr == NULL) {
66 pr_err("%s: Received NULL pointer for header\n", __func__);
67 return -EINVAL;
68 } else if (total_size == NULL) {
69 pr_err("%s: Received NULL pointer for total size\n", __func__);
70 return -EINVAL;
71 }
72
73 param_size = v3_hdr->param_size;
74 packed_size = iid_supported ? sizeof(struct param_hdr_v3) :
75 sizeof(struct param_hdr_v1);
76
77 if (iid_supported) {
78 memcpy(dest, v3_hdr, packed_size);
79 } else {
80 v1_hdr = (struct param_hdr_v1 *) dest;
81 v1_hdr->module_id = v3_hdr->module_id;
82 v1_hdr->param_id = v3_hdr->param_id;
83
84 if (param_size > U16_MAX) {
85 pr_err("%s: Invalid param size for V1 %d\n", __func__,
86 param_size);
87 return -EINVAL;
88 }
89 v1_hdr->param_size = param_size;
90 v1_hdr->reserved = 0;
91 }
92
93 /*
94 * Make param_data optional for cases when there is no data
95 * present as in some set cases and all get cases.
96 */
97 if (param_data != NULL) {
98 memcpy(dest + packed_size, param_data, param_size);
99 packed_size += param_size;
100 }
101
102 *total_size = packed_size;
103
104 return 0;
105}
106EXPORT_SYMBOL(q6common_pack_pp_params);
Aditya Bavanari23513e02019-02-28 11:06:41 +0530107
108/**
109 * q6common_pack_pp_params_v2
110 *
111 * Populate params header based on instance ID support and pack
112 * it with payload.
113 * Instance ID support -
114 * yes - param_hdr_v3 + payload
115 * no - param_hdr_v1 + payload
116 *
117 * @dest: destination data pointer to be packed into
118 * @v3_hdr: param header v3
119 * @param_data: param payload
120 * @total_size: total size of packed data (hdr + payload)
121 * @iid_supported: Instance ID supported or not
122 *
123 * Returns 0 on success or error on failure
124 */
125int q6common_pack_pp_params_v2(u8 *dest, struct param_hdr_v3 *v3_hdr,
126 u8 *param_data, u32 *total_size,
127 bool iid_supported)
128{
129 struct param_hdr_v1 *v1_hdr = NULL;
130 u32 packed_size = 0;
131 u32 param_size = 0;
132
133 if (dest == NULL) {
134 pr_err("%s: Received NULL pointer for destination\n", __func__);
135 return -EINVAL;
136 } else if (v3_hdr == NULL) {
137 pr_err("%s: Received NULL pointer for header\n", __func__);
138 return -EINVAL;
139 } else if (total_size == NULL) {
140 pr_err("%s: Received NULL pointer for total size\n", __func__);
141 return -EINVAL;
142 }
143
144 param_size = v3_hdr->param_size;
145 packed_size = iid_supported ? sizeof(struct param_hdr_v3) :
146 sizeof(struct param_hdr_v1);
147
148 if (iid_supported) {
149 memcpy(dest, v3_hdr, packed_size);
150 } else {
151 v1_hdr = (struct param_hdr_v1 *) dest;
152 v1_hdr->module_id = v3_hdr->module_id;
153 v1_hdr->param_id = v3_hdr->param_id;
154
155 if (param_size > U16_MAX) {
156 pr_err("%s: Invalid param size for V1 %d\n", __func__,
157 param_size);
158 return -EINVAL;
159 }
160 v1_hdr->param_size = param_size;
161 v1_hdr->reserved = 0;
162 }
163
164 /*
165 * Make param_data optional for cases when there is no data
166 * present as in some set cases and all get cases.
167 */
168 if (param_data != NULL) {
169 memcpy(dest + packed_size, param_data, param_size);
170 packed_size += param_size;
171 }
172
173 *total_size = packed_size;
174
175 return 0;
176}
177EXPORT_SYMBOL(q6common_pack_pp_params_v2);