aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShreyas NC <shreyas.nc@intel.com>2016-08-23 00:01:03 -0400
committerMark Brown <broonie@kernel.org>2016-08-23 07:35:45 -0400
commit541070cec4f9be18ce9fcc74ac5e1036965ceb63 (patch)
tree87dadb1d1ab413daf57fd26432e940ae1bd62ef2
parent33ece7f9c8e8a2abfcca681ec9424b15271f7afb (diff)
ASoC: Intel: Skylake: Parse manifest data
Topology manifest has lib names and lib count info. So, define tokens to represent module private data and parse these tokens to fill up the manifest structure in the driver accordingly. Signed-off-by: Shreyas NC <shreyas.nc@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/uapi/sound/snd_sst_tokens.h8
-rw-r--r--sound/soc/intel/skylake/skl-topology.c194
2 files changed, 200 insertions, 2 deletions
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h
index f56a932736ca..1ee2e943d66a 100644
--- a/include/uapi/sound/snd_sst_tokens.h
+++ b/include/uapi/sound/snd_sst_tokens.h
@@ -153,6 +153,10 @@
153 * 153 *
154 * %SKL_TKN_U32_PROC_DOMAIN: Specify processing domain 154 * %SKL_TKN_U32_PROC_DOMAIN: Specify processing domain
155 * 155 *
156 * %SKL_TKN_U32_LIB_COUNT: Specifies the number of libraries
157 *
158 * %SKL_TKN_STR_LIB_NAME: Specifies the library name
159 *
156 * module_id and loadable flags dont have tokens as these values will be 160 * module_id and loadable flags dont have tokens as these values will be
157 * read from the DSP FW manifest 161 * read from the DSP FW manifest
158 */ 162 */
@@ -202,7 +206,9 @@ enum SKL_TKNS {
202 SKL_TKN_U32_CAPS_PARAMS_ID, 206 SKL_TKN_U32_CAPS_PARAMS_ID,
203 SKL_TKN_U32_CAPS_SIZE, 207 SKL_TKN_U32_CAPS_SIZE,
204 SKL_TKN_U32_PROC_DOMAIN, 208 SKL_TKN_U32_PROC_DOMAIN,
205 SKL_TKN_MAX = SKL_TKN_U32_PROC_DOMAIN, 209 SKL_TKN_U32_LIB_COUNT,
210 SKL_TKN_STR_LIB_NAME,
211 SKL_TKN_MAX = SKL_TKN_STR_LIB_NAME,
206}; 212};
207 213
208#endif 214#endif
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 000482e6e2f7..108ebb9ab329 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -2201,6 +2201,197 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
2201 return 0; 2201 return 0;
2202} 2202}
2203 2203
2204static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
2205 struct snd_soc_tplg_vendor_string_elem *str_elem,
2206 struct skl_dfw_manifest *minfo)
2207{
2208 int tkn_count = 0;
2209 static int ref_count;
2210
2211 switch (str_elem->token) {
2212 case SKL_TKN_STR_LIB_NAME:
2213 if (ref_count > minfo->lib_count - 1) {
2214 ref_count = 0;
2215 return -EINVAL;
2216 }
2217
2218 strncpy(minfo->lib[ref_count].name, str_elem->string,
2219 ARRAY_SIZE(minfo->lib[ref_count].name));
2220 ref_count++;
2221 tkn_count++;
2222 break;
2223
2224 default:
2225 dev_err(dev, "Not a string token %d", str_elem->token);
2226 break;
2227 }
2228
2229 return tkn_count;
2230}
2231
2232static int skl_tplg_get_str_tkn(struct device *dev,
2233 struct snd_soc_tplg_vendor_array *array,
2234 struct skl_dfw_manifest *minfo)
2235{
2236 int tkn_count = 0, ret;
2237 struct snd_soc_tplg_vendor_string_elem *str_elem;
2238
2239 str_elem = (struct snd_soc_tplg_vendor_string_elem *)array->value;
2240 while (tkn_count < array->num_elems) {
2241 ret = skl_tplg_fill_str_mfest_tkn(dev, str_elem, minfo);
2242 str_elem++;
2243
2244 if (ret < 0)
2245 return ret;
2246
2247 tkn_count = tkn_count + ret;
2248 }
2249
2250 return tkn_count;
2251}
2252
2253static int skl_tplg_get_int_tkn(struct device *dev,
2254 struct snd_soc_tplg_vendor_value_elem *tkn_elem,
2255 struct skl_dfw_manifest *minfo)
2256{
2257 int tkn_count = 0;
2258
2259 switch (tkn_elem->token) {
2260 case SKL_TKN_U32_LIB_COUNT:
2261 minfo->lib_count = tkn_elem->value;
2262 tkn_count++;
2263 break;
2264
2265 default:
2266 dev_err(dev, "Not a manifest token %d", tkn_elem->token);
2267 return -EINVAL;
2268 }
2269
2270 return tkn_count;
2271}
2272
2273/*
2274 * Fill the manifest structure by parsing the tokens based on the
2275 * type.
2276 */
2277static int skl_tplg_get_manifest_tkn(struct device *dev,
2278 char *pvt_data, struct skl_dfw_manifest *minfo,
2279 int block_size)
2280{
2281 int tkn_count = 0, ret;
2282 int off = 0, tuple_size = 0;
2283 struct snd_soc_tplg_vendor_array *array;
2284 struct snd_soc_tplg_vendor_value_elem *tkn_elem;
2285
2286 if (block_size <= 0)
2287 return -EINVAL;
2288
2289 while (tuple_size < block_size) {
2290 array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
2291 off += array->size;
2292 switch (array->type) {
2293 case SND_SOC_TPLG_TUPLE_TYPE_STRING:
2294 ret = skl_tplg_get_str_tkn(dev, array, minfo);
2295
2296 if (ret < 0)
2297 return ret;
2298 tkn_count += ret;
2299
2300 tuple_size += tkn_count *
2301 sizeof(struct snd_soc_tplg_vendor_string_elem);
2302 continue;
2303
2304 case SND_SOC_TPLG_TUPLE_TYPE_UUID:
2305 dev_warn(dev, "no uuid tokens for skl tplf manifest");
2306 continue;
2307
2308 default:
2309 tkn_elem = array->value;
2310 tkn_count = 0;
2311 break;
2312 }
2313
2314 while (tkn_count <= array->num_elems - 1) {
2315 ret = skl_tplg_get_int_tkn(dev,
2316 tkn_elem, minfo);
2317 if (ret < 0)
2318 return ret;
2319
2320 tkn_count = tkn_count + ret;
2321 tkn_elem++;
2322 tuple_size += tkn_count *
2323 sizeof(struct snd_soc_tplg_vendor_value_elem);
2324 break;
2325 }
2326 tkn_count = 0;
2327 }
2328
2329 return 0;
2330}
2331
2332/*
2333 * Parse manifest private data for tokens. The private data block is
2334 * preceded by descriptors for type and size of data block.
2335 */
2336static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
2337 struct device *dev, struct skl_dfw_manifest *minfo)
2338{
2339 struct snd_soc_tplg_vendor_array *array;
2340 int num_blocks, block_size = 0, block_type, off = 0;
2341 char *data;
2342 int ret;
2343
2344 /* Read the NUM_DATA_BLOCKS descriptor */
2345 array = (struct snd_soc_tplg_vendor_array *)manifest->priv.data;
2346 ret = skl_tplg_get_desc_blocks(dev, array);
2347 if (ret < 0)
2348 return ret;
2349 num_blocks = ret;
2350
2351 off += array->size;
2352 array = (struct snd_soc_tplg_vendor_array *)
2353 (manifest->priv.data + off);
2354
2355 /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
2356 while (num_blocks > 0) {
2357 ret = skl_tplg_get_desc_blocks(dev, array);
2358
2359 if (ret < 0)
2360 return ret;
2361 block_type = ret;
2362 off += array->size;
2363
2364 array = (struct snd_soc_tplg_vendor_array *)
2365 (manifest->priv.data + off);
2366
2367 ret = skl_tplg_get_desc_blocks(dev, array);
2368
2369 if (ret < 0)
2370 return ret;
2371 block_size = ret;
2372 off += array->size;
2373
2374 array = (struct snd_soc_tplg_vendor_array *)
2375 (manifest->priv.data + off);
2376
2377 data = (manifest->priv.data + off);
2378
2379 if (block_type == SKL_TYPE_TUPLE) {
2380 ret = skl_tplg_get_manifest_tkn(dev, data, minfo,
2381 block_size);
2382
2383 if (ret < 0)
2384 return ret;
2385
2386 --num_blocks;
2387 } else {
2388 return -EINVAL;
2389 }
2390 }
2391
2392 return 0;
2393}
2394
2204static int skl_manifest_load(struct snd_soc_component *cmpnt, 2395static int skl_manifest_load(struct snd_soc_component *cmpnt,
2205 struct snd_soc_tplg_manifest *manifest) 2396 struct snd_soc_tplg_manifest *manifest)
2206{ 2397{
@@ -2211,7 +2402,8 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt,
2211 int ret = 0; 2402 int ret = 0;
2212 2403
2213 minfo = &skl->skl_sst->manifest; 2404 minfo = &skl->skl_sst->manifest;
2214 memcpy(minfo, manifest->priv.data, sizeof(struct skl_dfw_manifest)); 2405
2406 skl_tplg_get_manifest_data(manifest, bus->dev, minfo);
2215 2407
2216 if (minfo->lib_count > HDA_MAX_LIB) { 2408 if (minfo->lib_count > HDA_MAX_LIB) {
2217 dev_err(bus->dev, "Exceeding max Library count. Got:%d\n", 2409 dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",