1#!/usr/bin/env python 2# Copyright 2014 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Dump DAPM widgets status as a 'dot' graph file. 7 8To generate widget status for a device run 9 ssh $REMOTE asoc_dapm_graph > dot.txt && dot -Kfdp -Tpng dot.txt -o widgets.png 10""" 11 12from __future__ import print_function 13import os 14import platform 15import re 16import sys 17import time 18 19ROOTDIR = '/sys/kernel/debug/asoc/' 20# Some widget names are widely used by many codecs, adding them to the graph 21# creates a mess. 22IGNORE_WIDGETS = ('Playback', 'Capture', 'bias_level') 23 24 25def handle_widgets(path): 26 """Reads DAPM widget information from sysfs and generates dot graph entry. 27 28 Args: 29 path: path for sysfs file that exports information about DAPM widget. 30 """ 31 for w in os.listdir(path): 32 if w in IGNORE_WIDGETS: 33 continue 34 35 with open(os.path.join(path, w)) as f: 36 lines = f.readlines() 37 38 active = lines[0].startswith(w + ': On ') 39 color = 'green' if active else 'red' 40 print('\t"%s" [color = %s]' % (w, color)) 41 42 for l in lines[1:]: 43 l = l.rstrip() 44 # The string format is (in/out) "switch" "widget". 45 edge = list(filter(None, re.split(r' (in|out) "(.+)" "(.+)"', l))) 46 47 if len(edge) != 3: 48 continue 49 50 direction = edge[0] 51 source = edge[2] 52 53 if source in IGNORE_WIDGETS: 54 continue 55 56 # We need to output the edge only once (e.g. inbound). 57 if direction != 'in': 58 continue 59 60 print('\t"%s" -> "%s"' % (source, w)) 61 62 63def handle_card(path): 64 """Generates dot graph file for the given card. 65 66 Args: 67 path: path to sysfs directory that exports DAPM information for a sound card. 68 """ 69 host = platform.uname()[1] 70 print('// Generated %s at %s.' % (time.strftime("%c"), host)) 71 print('// To visualize the graph run "dot -Kfdp -Tpng $SCRIPT_OUTPUT_FILE -o widgets.png".') 72 print('digraph G {') 73 print('\tbgcolor = grey') 74 for root, dirs, files in os.walk(path): 75 if 'dapm' in dirs: 76 handle_widgets(os.path.join(root, 'dapm')) 77 dirs.remove('dapm') 78 print('}') 79 80 81def main(argv): 82 for c in os.listdir(ROOTDIR): 83 path = os.path.join(ROOTDIR, c) 84 # We assume that directories in ROOTDIR are cards. 85 if os.path.isdir(path): 86 handle_card(path) 87 sys.exit(0) 88 89 print('No cards found', file=sys.stderr) 90 sys.exit(1) 91 92 93if __name__ == '__main__': 94 main(sys.argv[1:]) 95 96