From: Jaroslav Kysela Date: Thu, 28 Jan 2010 12:16:32 +0000 (+0100) Subject: hda-analyzer: More changes regarding proc interface X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=9981ffd7ab8579666a7e13e3dfca98cab42e212a;p=alsa.git hda-analyzer: More changes regarding proc interface - add support for gziped & bzip2ed files files - add support for alsa-info.sh contents Signed-off-by: Jaroslav Kysela --- diff --git a/hda-analyzer/hda_analyzer.py b/hda-analyzer/hda_analyzer.py index 15943be..406cf11 100755 --- a/hda-analyzer/hda_analyzer.py +++ b/hda-analyzer/hda_analyzer.py @@ -32,7 +32,7 @@ DIFF_FILE = "/tmp/hda-analyze.diff" from hda_codec import HDACodec, HDA_card_list, \ EAPDBTL_BITS, PIN_WIDGET_CONTROL_BITS, \ PIN_WIDGET_CONTROL_VREF, DIG1_BITS, GPIO_IDS -from hda_proc import HDACodecProc +from hda_proc import DecodeProcFile, HDACodecProc CODEC_TREE = {} DIFF_TREE = {} @@ -52,8 +52,8 @@ def read_nodes2(card, codec): if not card in CODEC_TREE: CODEC_TREE[card] = {} DIFF_TREE[card] = {} - CODEC_TREE[card][codec] = c - DIFF_TREE[card][codec] = c.dump() + CODEC_TREE[card][c.device] = c + DIFF_TREE[card][c.device] = c.dump() def read_nodes3(card, codec, proc_file): c = HDACodecProc(card, codec, proc_file) @@ -61,8 +61,8 @@ def read_nodes3(card, codec, proc_file): if not card in CODEC_TREE: CODEC_TREE[card] = {} DIFF_TREE[card] = {} - CODEC_TREE[card][codec] = c - DIFF_TREE[card][codec] = c.dump() + CODEC_TREE[card][c.device] = c + DIFF_TREE[card][c.device] = c.dump() def read_nodes(proc_files): l = HDA_card_list() @@ -73,9 +73,33 @@ def read_nodes(proc_files): for f in proc_files: a = f.split('+') idx = 0 + if len(a) == 1: + proc_file = DecodeProcFile(a[0]) + if proc_file.find("ALSA Information Script") > 0: + a = [] + pos = proc_file.find('HDA-Intel Codec information') + if pos >= 0: + proc_file = proc_file[pos:] + pos = proc_file.find('--startcollapse--') + proc_file = proc_file[pos+18:] + pos = proc_file.find('--endcollapse--') + proc_file = proc_file[:pos] + while 1: + pos = proc_file.find('\nCodec: ') + if pos < 0: + break + proc_file = proc_file[pos:] + pos = proc_file[1:].find('\nCodec: ') + if pos < 0: + pos = len(proc_file)-2 + read_nodes3(card, idx, proc_file[:pos+2]) + proc_file = proc_file[pos:] + card += 1 for i in a: - read_nodes3(card, idx, i) + proc_file = DecodeProcFile(i) + read_nodes3(card, idx, proc_file) idx += 1 + card += 1 cnt = 0 for c in CODEC_TREE: if len(CODEC_TREE[c]) > 0: diff --git a/hda-analyzer/hda_codec.py b/hda-analyzer/hda_codec.py index 3359e79..f021250 100644 --- a/hda-analyzer/hda_codec.py +++ b/hda-analyzer/hda_codec.py @@ -229,6 +229,8 @@ DIG1_BITS = { 'LEVEL': 7 } +POWER_STATES = ["D0", "D1", "D2", "D3", "D3cold", "S3D3cold", "CLKSTOP", "EPSS"] + class HDAAmpCaps: def __init__(self, codec, nid, dir): @@ -497,15 +499,20 @@ class HDANode: self.unsol_tag = unsol & 0x3f self.unsol_enabled = (unsol & (1 << 7)) and True or False if self.power: - states = ["D0", "D1", "D2", "D3"] + pwr = self.codec.param_read(self.nid, PARAMS['POWER_STATE']) + self.pwr_state = pwr + self.pwr_states = [] + for a in range(len(POWER_STATES)): + if pwr & (1 << a): + self.pwr_states.append(POWER_STATES[a]) pwr = self.codec.rw(self.nid, VERBS['GET_POWER_STATE'], 0) self.pwr = pwr if self.origin_pwr == None: self.origin_pwr = pwr self.pwr_setting = pwr & 0x0f self.pwr_actual = (pwr >> 4) & 0x0f - self.pwr_setting_name = self.pwr_setting < 4 and states[self.pwr_setting] or "UNKNOWN" - self.pwr_actual_name = self.pwr_actual < 4 and states[self.pwr_actual] or "UNKNOWN" + self.pwr_setting_name = self.pwr_setting < 4 and POWER_STATES[self.pwr_setting] or "UNKNOWN" + self.pwr_actual_name = self.pwr_actual < 4 and POWER_STATES[self.pwr_actual] or "UNKNOWN" # NID 0x20 == Realtek Define Registers if self.codec.vendor_id == 0x10ec and self.nid == 0x20: self.realtek_coeff_proc = self.codec.rw(self.nid, VERBS['GET_PROC_COEF'], 0) @@ -1057,6 +1064,9 @@ class HDACodec: return " Unsolicited: tag=0x%02x, enabled=%d\n" % (node.unsol_tag, node.unsol_enabled and 1 or 0) def print_power_state(node): + str = "" + if node.pwr_states: + str = " Power states: %s\n" % ' '.join(node.pwr_states) return " Power: setting=%s, actual=%s\n" % (node.pwr_setting_name, node.pwr_actual_name) def print_digital_conv(node): diff --git a/hda-analyzer/hda_proc.py b/hda-analyzer/hda_proc.py index 3a5f509..ab911dd 100644 --- a/hda-analyzer/hda_proc.py +++ b/hda-analyzer/hda_proc.py @@ -19,8 +19,36 @@ SET_VERBS = { VERBS['SET_SDI_SELECT']: VERBS['GET_SDI_SELECT'], VERBS['SET_PIN_WIDGET_CONTROL']: VERBS['GET_PIN_WIDGET_CONTROL'], VERBS['SET_CONNECT_SEL']: VERBS['GET_CONNECT_SEL'], + VERBS['SET_EAPD_BTLENABLE']: VERBS['GET_EAPD_BTLENABLE'], + VERBS['SET_POWER_STATE']: VERBS['GET_POWER_STATE'], } +def DecodeProcFile(proc_file): + if len(proc_file) < 256: + fd = open(proc_file) + proc_file = fd.read(1024*1024) + fd.close() + if proc_file.find('Subsystem Id:') < 0: + p = None + try: + from gzip import GzipFile + from StringIO import StringIO + s = StringIO(proc_file) + gz = GzipFile(mode='r', fileobj=s) + p = gz.read(1024*1024) + gz.close() + except: + pass + if p is None: + try: + from bz2 import decompress + p = decompress(proc_file) + except: + pass + if not p is None: + proc_file = p + return proc_file + class HDACardProc: def __init__(self, card): @@ -55,7 +83,7 @@ class HDABaseProc: while ok: ok = False for a in self.delim: - if rem[0] == a: + if rem and rem[0] == a: rem = rem[1:] ok = True return rem.strip(), res.strip() @@ -125,6 +153,8 @@ class ProcNode(HDABaseProc): self.params = {} self.verbs = {} self.controls = [] + if wcaps & (1 << 10): + self.add_param(PARAMS['POWER_STATE'], 0) def rw(self, verb, param): if verb in self.verbs: @@ -201,7 +231,7 @@ class ProcNode(HDABaseProc): 'Pro': DIG1_BITS['PROFESSIONAL'], 'GenLevel': DIG1_BITS['LEVEL'] } - bits = 0 + xbits = 0 a = line.split(' ') for b in a: b = b.strip() @@ -209,8 +239,8 @@ class ProcNode(HDABaseProc): return if not b in bits: self.wrongfile('unknown dig1 bit %s' % repr(b)) - bits |= 1 << bits[b] - self.add_verb(VERBS['GET_DIGI_CONVERT_1'], bits) + xbits |= 1 << bits[b] + self.add_verb(VERBS['GET_DIGI_CONVERT_1'], xbits) def add_digitalcategory(self, line): line, res = self.decodeintw(line) @@ -301,6 +331,31 @@ class ProcNode(HDABaseProc): line, tmp1 = self.decodeintw(line, '') self.add_verb(VERBS['GET_PIN_WIDGET_CONTROL'], tmp1) + def add_eapd(self, line): + line, tmp1 = self.decodeintw(line, '') + self.add_verb(VERBS['GET_EAPD_BTLENABLE'], tmp1) + + def add_power(self, line): + line, setting = self.decodestrw(line, 'setting=') + line, actual = self.decodestrw(line, 'actual=') + if setting in POWER_STATES: + setting = POWER_STATES.index(setting) + else: + self.wrongfile('power setting %s' % setting) + if actual in POWER_STATES: + actual = POWER_STATES.index(actual) + else: + self.wrongfile('power actual %s' % actual) + self.add_verb(VERBS['GET_POWER_STATE'], (setting & 0x0f) | ((actual & 0x0f) << 4)) + + def add_powerstates(self, line): + a = line.strip().split(' ') + tmp1 + for b in a: + if b in POWER_STATES: + tmp1 |= 1 << POWER_STATES.index(b) + self.add_parm(PARAMS['POWER_STATE'], tmp1) + def dump_extra(self): str = '' if self.device: @@ -316,10 +371,6 @@ class HDACodecProc(HDACodec, HDABaseProc): self.card = card self.device = device self.mcard = HDACardProc(card) - if len(proc_file) < 256: - fd = open(proc_file) - proc_file = fd.read(1024*1024) - fd.close() self.proc_codec_id = None self.parse(proc_file) if self.proc_codec_id: @@ -377,10 +428,7 @@ class HDACodecProc(HDACodec, HDABaseProc): def writeval(str, idx, var): res, val = self.decodeintw(str, var + '=') - if not self.proc_gpio.has_key(var): - self.proc_gpio[var] = 0 - if val: - self.proc_gpio[var] |= 1 << idx + self.proc_gpio[var] |= 1 << idx return res res = lines[idx] @@ -398,7 +446,9 @@ class HDACodecProc(HDACodec, HDABaseProc): idx, self.proc_codec_id = lookfor(idx, 'Codec: ') idx, tmp = lookforint(idx, 'Address: ') self.device = tmp # really? - idx, self.proc_function_id = lookforint(idx, 'Function Id: ') + self.proc_function_id = None + if lines[idx].startswith('Function Id: '): + idx, self.proc_function_id = lookforint(idx, 'Function Id: ') idx, self.proc_vendor_id = lookforint(idx, 'Vendor Id: ') idx, self.proc_subsystem_id = lookforint(idx, 'Subsystem Id: ') idx, self.proc_revision_id = lookforint(idx, 'Revision Id:' ) @@ -408,9 +458,13 @@ class HDACodecProc(HDACodec, HDABaseProc): if nomfg: idx += 1 else: + if self.proc_function_id is None: + self.proc_function_id = 2 idx, self.proc_modem_grp = lookforint(idx, 'Modem Function Group: ') self.proc_afd = -1 return + if self.proc_function_id is None: + self.proc_function_id = 1 if not lines[idx].startswith('Default PCM:'): self.wrongfile('default pcm expected') idx, tmp1 = decodeint(idx+1, ' rates [') @@ -419,10 +473,22 @@ class HDACodecProc(HDACodec, HDABaseProc): idx, self.proc_pcm_stream = decodeint(idx, ' formats [') idx, self.proc_amp_caps_in = decodeampcap(idx, 'Default Amp-In caps: ') idx, self.proc_amp_caps_out = decodeampcap(idx, 'Default Amp-Out caps: ') - idx, self.proc_gpio_cap = decodegpiocap(idx, 'GPIO: ') - self.proc_gpio = {} - while lines[idx].startswith(' IO['): - idx = decodegpio(idx, ' IO[') + self.proc_gpio = { + 'enable': 0, + 'dir': 0, + 'wake': 0, + 'sticky': 0, + 'data': 0, + 'unsol': 0 + } + self.proc_gpio_cap = 0 + if lines[idx].startswith('GPIO: '): + idx, self.proc_gpio_cap = decodegpiocap(idx, 'GPIO: ') + while lines[idx].startswith(' IO['): + idx = decodegpio(idx, ' IO[') + if lines[idx].strip() == 'Invalid AFG subtree': + print "Invalid AFG subtree for codec %s?" % self.proc_codec_id + return node = None while idx < len(lines): line = lines[idx] @@ -481,6 +547,12 @@ class HDACodecProc(HDACodec, HDABaseProc): pass elif line.startswith(' Pin-ctls: '): node.add_pinctls(line[12:]) + elif line.startswith(' EAPD '): + node.add_eapd(line[7:]) + elif line.startswith(' Power states: '): + node.add_powerstates(line[16:]) + elif line.startswith(' Power: '): + node.add_power(line[9:]) else: self.wrongfile(line) idx += 1 @@ -519,7 +591,9 @@ class HDACodecProc(HDACodec, HDABaseProc): if nid == AC_NODE_ROOT: return self.proc_afd, 1 elif nid == self.proc_afd: - return len(self.proc_nids), self.proc_nids.keys()[0] + if self.proc_nids: + return len(self.proc_nids), self.proc_nids.keys()[0] + return 0, 0 raise ValueError, "unimplemented get_sub_nodes(0x%x)" % nid def get_wcap(self, nid): diff --git a/hda-analyzer/run.py b/hda-analyzer/run.py index 50b25c6..4d4a1a7 100755 --- a/hda-analyzer/run.py +++ b/hda-analyzer/run.py @@ -1,7 +1,7 @@ #!/usr/bin/env python URL="http://git.alsa-project.org/?p=alsa.git;a=blob_plain;f=hda-analyzer/" -FILES=["hda_analyzer.py", "hda_codec.py"] +FILES=["hda_analyzer.py", "hda_codec.py", "hda_proc.py"] try: import gobject