Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions case-lib/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,8 @@ sudo sync -f || true
if [ ! "$DMESG_LOG_START_LINE" ]; then
DMESG_LOG_START_LINE=$(wc -l /var/log/kern.log|awk '{print $1;}')
fi

is_sof_used()
{
grep -q "sof" /proc/asound/cards;
}
28 changes: 25 additions & 3 deletions case-lib/pipeline.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
#!/bin/bash

# This function will evaluate pipeline parameter related shell code generated by
# - sof-tplgreader.py (for SOF, pipeline parameters dumped from topology)
# - sof-dump-status.py (for legacy HDA, pipeline paramters dumped from proc)
# Args: $1: SOF topology path
# $2: Pipeline filter in string form
# Note: for legacy HDA, topology is not present, $1 will be empty.
func_pipeline_export()
{
# no parameter input the function
if [ $# -lt 1 ]; then
die "Topology file name is not specified, unable to run command: $SCRIPT_NAME"

# function parameter check
if [ $# -ne 2 ]; then
die "Not enough parameters, expect two parameters: topology path and pipeline filter"
fi

# For legacy HDA platform, there is no topology, we have to export pipeline
# parameters from proc file system.
is_sof_used || {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this test work where we have dmi info available and the card name doesnt contain "sof"? like the chromebooks?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example : on my helios, card name is GoogleHeliosRev1. There's no sof prefix there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, the procfs info for PCMs is valid for all cases. Why not just use that instead of topology?

Copy link
Collaborator

@marc-hb marc-hb Oct 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, the procfs info for PCMs is valid for all cases. Why not just use that instead of topology?

I guess part of the answer is in this code comment:

   for pcm in card_info['pcm']:
                # There are limited pipeline parameters in the proc file system,
                # add some default parameters to make use of sof-test for legacy HDA test
                pcm['fmt'] = 'S16_LE'
                pcm['fmts'] = 'S16_LE S24_LE S32_LE'
                ...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ranj063 I guess you are talking about Chromebook under ChromeOS, because the content of /proc/asound/cards on my Helios looks like this:

ubuntu@helios:~$ cat /proc/asound/cards
 0 [sofcmlrt1011rt5]: sof-cml_rt1011_ - sof-cml_rt1011_rt5682
                      Google-Helios-rev2

Currently, sof-test cannot run on ChromeOS, because most infrastructure level python scripts cannot run on that OS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont know why but yesterday my card name was GoogleHeliosrev2 but its back to sof-nocodec now

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, sof-test cannot run on ChromeOS, because most infrastructure level python scripts cannot run on that OS.

In theory the dev_install command can install python
https://chromium.googlesource.com/chromiumos/platform2/+/refs/heads/master/dev-install/

It does NOT mean everything would work but it would be a good start.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ranj063 I guess you are talking about Chromebook under ChromeOS, because the content of /proc/asound/cards on my Helios looks like this:

ubuntu@helios:~$ cat /proc/asound/cards
 0 [sofcmlrt1011rt5]: sof-cml_rt1011_ - sof-cml_rt1011_rt5682
                      Google-Helios-rev2

Currently, sof-test cannot run on ChromeOS, because most infrastructure level python scripts cannot run on that OS.

that's not a good-enough reason to screw-up the card name parsing.

I think you guys are confusing things, the syntax is

cardIndex [mixer_name]: driver_name - card_name
long_card_name

@ranj063 can you provide what you have on your device w/ Chrome?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart this is what we see on chrome:
localhost ~ # cat /proc/asound/cards
0 [sofrt5682 ]: sof-rt5682 - sof-rt5682
Google-Delbin-1.0

Copy link
Contributor

@ranj063 ranj063 Oct 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but for some reason when I was testing yesterday my card name was as below on my helios running Linux. I am unable to reproduce this. So I do not know where this was coming from.
root@ranjani-Helios:~# cat /proc/asound/cards
0 [GoogleHeliosrev]: -
Google-Helios-rev2

filter_str="$2"
dlogi "No SOF sound card found, exporting pipeline parameters from proc file system"
tmp_pipeline_params=$(mktemp /tmp/pipeline-params.XXXXXXXX)
sof-dump-status.py -e "$filter_str" > "$tmp_pipeline_params" ||
die "Failed to export pipeline parameters from proc file system"
# shellcheck disable=SC1090
source "$tmp_pipeline_params" || return 1
rm "$tmp_pipeline_params"
return 0
}

# got tplg_file, verify file exist
tplg_path=$(func_lib_get_tplg_path "$1") || {
die "Topology $1 not found, check the TPLG environment variable or specify topology path with -t"
Expand Down
30 changes: 30 additions & 0 deletions tools/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
def format_pipeline(pipeline, noKey=False):
output = ""
for key, value in pipeline.items():
if noKey is True:
output += str(value) + " "
else:
output += key + "=" + str(value) + ";"
return output.strip()

# This function will generate shell code according to pipeline parameters,
# then pipeline parameters can be accessed from test case by sourcing or
# executing the generated code.
def export_pipeline(pipeline_lst):
length = len(pipeline_lst)
keyword = 'PIPELINE'
# clear up the older define
print('unset %s_COUNT' % (keyword))
print('unset %s_LST' % (keyword))
print('declare -g %s_COUNT' % (keyword))
print('declare -ag %s_LST' % (keyword))
print('%s_COUNT=%d' % (keyword, length))
for idx in range(0, length):
# store pipeline
print('%s_LST[%d]="%s"' % (keyword, idx, format_pipeline(pipeline_lst[idx])))
# store pipeline to each list
print('unset %s_%d' % (keyword, idx))
print('declare -Ag %s_%d' % (keyword, idx))
for key, value in pipeline_lst[idx].items():
print('%s_%d["%s"]="%s"' % (keyword, idx, key, value))
return 0
49 changes: 43 additions & 6 deletions tools/sof-dump-status.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import subprocess
import os
from common import format_pipeline, export_pipeline

class clsSYSCardInfo():
def __init__(self):
Expand Down Expand Up @@ -364,12 +365,8 @@ def export_proc_sound(proc_card):
return

def dump_cardinfo_pcm(card_info):
pcm_lst = card_info.get('pcm')
def _getStr(tmp_dict, key):
return '%s=%s'%(key, tmp_dict.get(key))
for pcm in pcm_lst:
print('%s;%s;%s;' % (_getStr(pcm, 'id'), _getStr(pcm, 'pcm'), _getStr(pcm, 'type')))
return 0
for pipeline in card_info.get('pcm'):
print(format_pipeline(pipeline))

def dump_dapm(dapm, filter = "all"):
if filter == "all" and len(dapm['dapm_lst']) == 0:
Expand Down Expand Up @@ -413,6 +410,11 @@ def dump_dapm(dapm, filter = "all"):
parser.add_argument('-P', '--fwpath', action='store_true', help='get firmware path according to DMI info')
parser.add_argument('-S', '--dsp_status', type=int, help='get current dsp power status, should specify sof card number')
parser.add_argument('-d', '--dapm', choices=['all', 'on', 'off', 'standby'], help='get current dapm status, this option need root permission to access debugfs')
# The filter string here is compatible with the filter string for pipeline from topology,
# and takes the form of 'type:playback & pga:any & ~asrc:any | id:5'.
parser.add_argument('-e', '--export', type=str, help='export pipeline parameters of specified type from proc file system,\n'
'to specify pipeline type, use "-e type:playback", complex string like\n'
'"type:playback & pga:any" can be used, but only "type" is processed')
parser.add_argument('--version', action='version', version='%(prog)s 1.0')

ret_args = vars(parser.parse_args())
Expand All @@ -437,6 +439,41 @@ def dump_dapm(dapm, filter = "all"):
print(run_status['status'])
exit(0)

if ret_args['export'] is not None:
sysinfo.loadProcSound()
pipeline_lst = []
for (card_id, card_info) in sysinfo.proc_card.items():
for pcm in card_info['pcm']:
# There are limited pipeline parameters in the proc file system,
# add some default parameters to make use of sof-test for legacy HDA test
pcm['fmt'] = 'S16_LE'
pcm['fmts'] = 'S16_LE S24_LE S32_LE'
pcm['rate'] = '48000'
pcm['channel'] = '2'
pcm['dev'] = 'hw:{},{}'.format(card_id, pcm['id'])
pipeline_lst.extend(card_info['pcm'])
# The filter string may be very complex due to the compatibility with topology pipeline
# filter string, but we only implement a simple type filter here.
try:
# ret_args['export'] contains filter string, and it may looks like 'type:capture & pga:any | id:3'
# extract filter elements, and drop logic operator
filter_elements = [elem for elem in ret_args['export'].split(' ') if ':' in elem]
# extract requested pipeline type from filter elements, and ignore others.
requested_type = [f.split(':')[1] for f in filter_elements if f.strip().startswith('type')][0]
except:
print('Invalid filter string')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this filter exactly? What else can the type be?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some test case may only want to test on playback pipelines, or capture pipelines. so the type here may be one of the following: playback, capture, any. As we want to make it compatible with the topology pipeline, so the filter string should be written like this: 'type:playback'

exit(1)
# requested_type may take one of the values: playback, capture, any
if requested_type in ['playback', 'capture']:
export_pipeline([p for p in pipeline_lst if p['type'] == requested_type])
elif requested_type == 'any':
export_pipeline(pipeline_lst)
else:
print('Unknown requested pipeline type: %s' % requested_type)
print('Available requested pipeline types are: playback, capture, any')
exit(1)
exit(0)

if ret_args.get('id') is not None:
sysinfo.loadProcSound()
card_info = sysinfo.proc_card.get(str(ret_args['id']))
Expand Down
34 changes: 4 additions & 30 deletions tools/sof-tplgreader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import re
from tplgtool import TplgParser, TplgFormatter
from common import format_pipeline, export_pipeline

class clsTPLGReader:
def __init__(self):
Expand Down Expand Up @@ -243,33 +244,6 @@ def getPipeline(self, sort=False):
return self._output_lst

if __name__ == "__main__":
def func_dump_pipeline(pipeline, noKey=False):
output = ""
for key, value in pipeline.items():
if noKey is True:
output += str(value) + " "
else:
output += key + "=" + str(value) + ";"
return output.strip()

def func_export_pipeline(pipeline_lst):
length = len(pipeline_lst)
keyword = 'PIPELINE'
# clear up the older define
print('unset %s_COUNT' % (keyword))
print('unset %s_LST' % (keyword))
print('declare -g %s_COUNT' % (keyword))
print('declare -ag %s_LST' % (keyword))
print('%s_COUNT=%d' % (keyword, length))
for idx in range(0, length):
# store pipeline
print('%s_LST[%d]="%s"' % (keyword, idx, func_dump_pipeline(pipeline_lst[idx])))
# store pipeline to each list
print('unset %s_%d' % (keyword, idx))
print('declare -Ag %s_%d' % (keyword, idx))
for key, value in pipeline_lst[idx].items():
print('%s_%d["%s"]="%s"' % (keyword, idx, key, value))
return 0

def func_getPipeline(tplgObj, tplgName, sdcard_id, sort):
if tplgObj.loadFile(tplgName, sdcard_id) != 0:
Expand Down Expand Up @@ -376,15 +350,15 @@ def parse_and_set_block_keyword(block_str, tplgreader):
pipeline_lst += func_getPipeline(tplgreader, f, ret_args['sofcard'], ret_args['sort'])[:]

if ret_args['export'] is True:
exit(func_export_pipeline(pipeline_lst))
exit(export_pipeline(pipeline_lst))

if ret_args['count'] is True:
if ret_args['value'] is True:
print(len(pipeline_lst))
else:
print("Pipeline Count: %d" % (len(pipeline_lst)))
elif ret_args['index'] is not None and ret_args['index'] < len(pipeline_lst):
print(func_dump_pipeline(pipeline_lst[ret_args['index']], ret_args['value']))
print(format_pipeline(pipeline_lst[ret_args['index']], ret_args['value']))
else:
for pipeline in pipeline_lst:
print(func_dump_pipeline(pipeline, ret_args['value']))
print(format_pipeline(pipeline, ret_args['value']))