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 = {}
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)
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()
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:
'LEVEL': 7
}
+POWER_STATES = ["D0", "D1", "D2", "D3", "D3cold", "S3D3cold", "CLKSTOP", "EPSS"]
+
class HDAAmpCaps:
def __init__(self, codec, nid, dir):
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)
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):
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):
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()
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:
'Pro': DIG1_BITS['PROFESSIONAL'],
'GenLevel': DIG1_BITS['LEVEL']
}
- bits = 0
+ xbits = 0
a = line.split(' ')
for b in a:
b = b.strip()
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)
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:
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:
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]
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:' )
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 [')
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]
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
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):