]> git.alsa-project.org Git - alsa.git/commitdiff
hda-analyzer: implement revert function
authorJaroslav Kysela <perex@t61.perex-int.cz>
Mon, 1 Dec 2008 13:00:48 +0000 (14:00 +0100)
committerJaroslav Kysela <perex@t61.perex-int.cz>
Mon, 1 Dec 2008 13:00:48 +0000 (14:00 +0100)
hda-analyzer/hda_analyzer.py
hda-analyzer/hda_codec.py

index 0c76be969f8fdcc06322ec3b15add637073651d0..7d687ce01fbf4446eebeec2ab546df355432b428 100755 (executable)
@@ -17,7 +17,7 @@ import gtk
 import pango
 
 from dircache import listdir
-from hda_codec import HDACodec, HDANode, HDA_card_list, \
+from hda_codec import HDACodec, HDA_card_list, \
                       EAPDBTL_BITS, PIN_WIDGET_CONTROL_BITS, \
                       PIN_WIDGET_CONTROL_VREF, DIG1_BITS, GPIO_IDS
 
@@ -28,7 +28,7 @@ def read_nodes2(card, codec):
     c = HDACodec(card, codec)
   except OSError, msg:
     return
-  c.analyze_root_nodes()
+  c.analyze()
   CODEC_TREE[card][codec] = c
 
 def read_nodes():
@@ -57,12 +57,9 @@ class HDAAnalyzer(gtk.Window):
   codec = None
   node = None
 
-  def __init__(self, parent=None):
+  def __init__(self):
     gtk.Window.__init__(self)
-    try:
-      self.set_screen(parent.get_screen())
-    except AttributeError:
-      self.connect('destroy', lambda *w: gtk.main_quit())
+    self.connect('destroy', self.__destroy)
     self.set_default_size(800, 400)
     self.set_title(self.__class__.__name__)
     self.set_border_width(10)
@@ -87,7 +84,7 @@ class HDAAnalyzer(gtk.Window):
     hbox1.pack_start(button)
     button = gtk.Button("Revert")
     button.connect("clicked", self.__revert_clicked)
-    self.tooltips.set_tip(button, "Revert settings for all codecs.")
+    self.tooltips.set_tip(button, "Revert settings for selected codec.")
     hbox1.pack_start(button)
     vbox.pack_start(hbox1, False, False)
     hbox.pack_start(vbox, False, False)
@@ -103,10 +100,27 @@ class HDAAnalyzer(gtk.Window):
 
     self.show_all()    
 
+  def __destroy(self, widget):
+    dialog = gtk.MessageDialog(self,
+                      gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+                      gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO,
+                      "HDA-Analyzer: Would you like to revert\n"
+                      "settings for all HDA codecs?")
+    response = dialog.run()
+    dialog.destroy()
+    
+    if response == gtk.RESPONSE_YES:
+      for card in CODEC_TREE:
+        for codec in CODEC_TREE[card]:
+          CODEC_TREE[card][codec].revert()
+      print "Settings for all codecs were reverted..."
+    
+    gtk.main_quit()
+
   def __about_clicked(self, button):
     dialog = gtk.Dialog('About', self,
                         gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
-                          (gtk.STOCK_OK, gtk.RESPONSE_OK))
+                        gtk.BUTTONS_OK)
     text_view = gtk.TextView()
     text_view.set_border_width(4)
     str =  """\
@@ -133,8 +147,20 @@ mailing list - http://www.alsa-project.org .
     dialog.destroy()
     
   def __revert_clicked(self, button):
-    self.__refresh()
-    pass
+    if not self.codec:
+      msg = "Please, select a codec in left codec/node tree."
+      type = gtk.MESSAGE_WARNING
+    else:
+      self.codec.revert()
+      self.__refresh()
+      msg = "Setting for codec %s/%s (%s) was reverted!" % (self.codec.card, self.codec.device, self.codec.name)
+      type = gtk.MESSAGE_INFO
+
+    dialog = gtk.MessageDialog(self,
+                      gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+                      type, gtk.BUTTONS_OK, msg)
+    dialog.run()
+    dialog.destroy()
 
   def __refresh(self):
     self.load()
@@ -148,7 +174,8 @@ mailing list - http://www.alsa-project.org .
     elif codec and self.node < 0:
       txt = codec.dump(skip_nodes=True)
     else:
-      txt, n = codec.dump_node(node)
+      n = codec.get_node(node)
+      txt = codec.dump_node(n)
     buffer = self.info_buffer
     start, end = buffer.get_bounds()
     buffer.delete(start, end)
@@ -168,7 +195,7 @@ mailing list - http://www.alsa-project.org .
     if codec >= 0:
       self.codec = CODEC_TREE[card][codec]
     self.node = node
-    self.load()
+    self.__refresh()
 
   def load(self):
     codec = self.codec
@@ -179,13 +206,7 @@ mailing list - http://www.alsa-project.org .
     elif codec and node < 0:
       txt = codec.dump(skip_nodes=True)
     else:
-      txt, n = codec.dump_node(node)
-    buffer = self.info_buffer
-    start, end = buffer.get_bounds()
-    buffer.delete(start, end)
-    if not txt: return
-    iter = buffer.get_iter_at_offset(0)
-    buffer.insert(iter, txt)
+      n = codec.get_node(node)
 
     for child in self.node_window.get_children():
       self.node_window.remove(child)
@@ -240,15 +261,11 @@ mailing list - http://www.alsa-project.org .
                     CODEC_COLUMN, codec.device,
                     NODE_COLUMN, -1,
                     ITALIC_COLUMN, False)
-        nid = codec.base_nid
-        for verb in range(codec.nodes):
+        for nid in codec.nodes:
           viter = model.append(citer)
-          node = None
-          if type(1) == type(nid):
-            node = HDANode(codec, nid)
+          node = codec.get_node(nid)
           model.set(viter,
-                      TITLE_COLUMN, node and
-                              'Node[0x%02x] %s' % (nid, node.wtype_id) or nid,
+                      TITLE_COLUMN, 'Node[0x%02x] %s' % (nid, node.wtype_id),
                       CARD_COLUMN, card,
                       CODEC_COLUMN, codec.device,
                       NODE_COLUMN, nid,
@@ -346,7 +363,7 @@ mailing list - http://www.alsa-project.org .
       idx = 0
       for i in node.connections:
         iter = model.append()
-        node1 = HDANode(node.codec, node.connections[idx])
+        node1 = self.codec.get_node(node.connections[idx])
         model.set(iter, 0, node.active_connection == idx,
                         1, node1.name())
         idx += 1
index 9490b5e9da762c1d2327b5971bd22a6957b03065..04570253f969c32ed2ca64ae4c70920ff622d542 100644 (file)
@@ -260,6 +260,7 @@ class HDAAmpVal:
     self.nid = node.nid
     self.stereo = node.stereo
     self.indices = 1
+    self.origin_vals = None
     if dir == HDA_INPUT:
       self.indices = node.wtype_id == 'PIN' and 1 or len(node.connections)
     self.reread()
@@ -298,6 +299,22 @@ class HDAAmpVal:
         self.vals.append(val)
       val = self.codec.rw(self.nid, verb, (0 << 13) | dir | i)
       self.vals.append(val)
+    if self.origin_vals == None:
+      self.origin_vals = self.vals[:]
+
+  def revert(self):
+    self.vals = self.origin_vals[:]
+    for idx in range(len(self.vals)):
+      self.__write_val(idx)
+
+class HDARootNode:
+
+  def __init__(self, codec, _name):
+    self.codec = codec
+    self._name = _name
+
+  def name(self):
+    return self._name
 
 class HDANode:
   
@@ -340,6 +357,13 @@ class HDANode:
     if self.lr_swap: self.wcaps_list.append('LR_SWAP')
     if self.cp_caps: self.wcaps_list.append('CP_CAPS')
 
+    self.origin_active_connection = None
+    self.origin_pwr = None
+    self.origin_digi1 = None
+    self.origin_pincap_eapdbtls = None
+    self.origin_pinctls = None
+    self.origin_vol_knb = None
+    self.origin_sdi_select = None
     self.reread()
     
   def wtype_name(self):
@@ -396,6 +420,8 @@ class HDANode:
       self.connections = self.codec.get_connections(self.nid)
       if not self.wtype_id in ['AUD_MIX', 'POWER']:
         self.active_connection = self.codec.rw(self.nid, VERBS['GET_CONNECT_SEL'], 0)
+        if self.origin_active_connection == None:
+          self.origin_active_connection = self.active_connection
     if self.in_amp:
       self.amp_caps_in = HDAAmpCaps(self.codec, self.nid, HDA_INPUT)
       self.amp_vals_in = HDAAmpVal(self.codec, self, HDA_INPUT)
@@ -473,6 +499,9 @@ class HDANode:
     if self.power:
       states = ["D0", "D1", "D2", "D3"]
       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"
@@ -489,6 +518,8 @@ class HDANode:
       return
     val = self.codec.rw(self.nid, VERBS['GET_EAPD_BTLENABLE'], 0)
     self.pincap_eapdbtls = val
+    if self.origin_pincap_eapdbtls == None:
+     self.origin_pincap_eapdbtls = val
     for name in EAPDBTL_BITS:
       bit = EAPDBTL_BITS[name]
       if val & (1 << bit): self.pincap_eapdbtl.append(name)
@@ -505,6 +536,8 @@ class HDANode:
   def reread_pin_widget_control(self):
     pinctls = self.codec.rw(self.nid, VERBS['GET_PIN_WIDGET_CONTROL'], 0)
     self.pinctls = pinctls
+    if self.origin_pinctls == None:
+      self.origin_pinctls = pinctls
     self.pinctl = []
     for name in PIN_WIDGET_CONTROL_BITS:
       bit = PIN_WIDGET_CONTROL_BITS[name]
@@ -530,6 +563,8 @@ class HDANode:
   def reread_vol_knb(self):
     cap = self.codec.rw(self.nid, VERBS['GET_VOLUME_KNOB_CONTROL'], 0)
     self.vol_knb = cap
+    if self.origin_vol_knb == None:
+      self.origin_vol_knb = cap
     self.vol_knb_direct = (cap >> 7) & 1
     self.vol_knb_val = cap & 0x7f
     
@@ -550,6 +585,8 @@ class HDANode:
     if self.wtype_id == 'AUD_IN' and self.aud_channel == 0:
       sdi = self.codec.rw(self.nid, VERBS['GET_SDI_SELECT'], 0)
       self.sdi_select = sdi & 0x0f
+      if self.origin_sdi_select == None:
+        self.origin_sdi_select = sdi
 
   def sdi_select_set_value(self, value):
     if self.sdi_select != None:
@@ -564,6 +601,8 @@ class HDANode:
       return
     digi1 = self.codec.rw(self.nid, VERBS['GET_DIGI_CONVERT_1'], 0)
     self.digi1 = digi1
+    if self.origin_digi1 == None:
+      self.origin_digi1 = digi1
     for name in DIG1_BITS:
       bit = DIG1_BITS[name]
       if digi1 & (1 << bit): self.dig1.append(name)
@@ -582,19 +621,41 @@ class HDANode:
         self.digi1 &= ~mask
       self.codec.rw(self.nid, VERBS['SET_DIGI_CONVERT_1'], self.digi1 & 0xff)
     self.reread_dig1()
-    
+
+  def revert(self):
+    if self.origin_active_connection != None:
+      self.set_active_connection(self.origin_active_connection)
+    if self.origin_pwr != None:
+      self.codec.rw(self.nid, VERBS['SET_POWER_STATE'], self.origin_pwr)
+    if self.in_amp:
+      self.amp_vals_in.revert()
+    if self.out_amp:
+      self.amp_vals_out.revert()
+    if self.origin_pincap_eapdbtls != None:
+      self.codec.rw(self.nid, VERBS['SET_EAPD_BTLENABLE'], self.origin_pincap_eapdbtls)
+    if self.origin_vol_knb != None:
+      self.codec.rw(self.nid, VERBS['SET_VOLUME_KNOB_CONTROL'], self.origin_vol_knb)
+    if self.origin_sdi_select != None:
+      self.codec.rw(self.nid, VERBS['SET_SDI_SELECT'], self.origin_sdi_select)
+    if self.origin_digi1 != None:
+      self.codec.rw(self.nid, VERBS['SET_DIGI_CONVERT_1'], self.origin_digi1 & 0xff)
+      self.codec.rw(self.nid, VERBS['SET_DIGI_CONVERT_2'], (self.origin_digi1 >> 8) & 0xff)
+    self.reread()
 
 class HDAGPIO:
 
   def __init__(self, codec, nid):
     self.codec = codec
     self.nid = nid
+    self.originval = None
     self.reread()
 
   def reread(self):
     self.val = {}
     for i in GPIO_IDS:
-      self.val[i] = self.codec.rw(self.nid, GPIO_IDS[i][0], 0)
+     self.val[i] = self.codec.rw(self.nid, GPIO_IDS[i][0], 0)
+    if self.originval == None:
+      self.originval = self.val.copy()
 
   def test(self, name, bit):
     return (self.val[name] & (1 << bit)) and True or False
@@ -616,6 +677,11 @@ class HDAGPIO:
       return
     self.write(name)
 
+  def revert(self):
+    for i in GPIO_IDS:
+      self.val[i] = self.originval[i]
+      self.write(i)
+
 class HDACard:
 
   def __init__(self, card, ctl_fd=None):
@@ -719,7 +785,17 @@ class HDACodec:
       prev_nid = val
     return res
 
-  def analyze_root_nodes(self):
+  def revert(self):
+    self.gpio.revert()
+    for nid in self.nodes:
+      self.nodes[nid].revert()
+
+  def get_node(self, nid):
+    if nid == self.afg:
+      return HDARootNode(self, "Audio Root Node")
+    return self.nodes[nid]
+
+  def analyze(self):
     self.afg = None
     self.mfg = None
     self.vendor_id = self.param_read(AC_NODE_ROOT, PARAMS['VENDOR_ID'])
@@ -762,7 +838,12 @@ class HDACodec:
     self.gpio_wake = (self.gpio_cap >> 31) & 1 and True or False
     self.gpio = HDAGPIO(self, self.afg)
 
-    self.nodes, self.base_nid = self.get_sub_nodes(self.afg)
+    nodes_count, nid = self.get_sub_nodes(self.afg)
+    self.base_nid = nid
+    self.nodes = {}
+    for i in range(nodes_count):
+      self.nodes[nid] = HDANode(self, nid)
+      nid += 1
 
   def analyze_pcm_rates(self, pcm):
     rates = [8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
@@ -836,7 +917,7 @@ class HDACodec:
               (caps.ofs, caps.nsteps, caps.stepsize, caps.mute and 1 or 0)
 
     if not self.afg and not self.mfg:
-      self.analyze_root_nodes()
+      self.analyze()
     str = 'Vendor Id: 0x%x\n' % self.vendor_id
     str += 'Subsystem Id: 0x%x\n' % self.subsystem_id
     str += 'Revision Id: 0x%x\n' % self.revision_id
@@ -858,16 +939,12 @@ class HDACodec:
     
     str += print_gpio(self)
 
-    if not skip_nodes:
-      nid = self.base_nid
-      for i in range(self.nodes):
-        s, n = self.dump_node(nid)
-        str += s
-        nid += 1
+    for i in self.nodes:
+      self.dump_node(self.nodes[i])
     
     return str
 
-  def dump_node(self, nid):
+  def dump_node(self, node):
 
     def print_pcm_rates(node):
       s = ''
@@ -1008,8 +1085,7 @@ class HDACodec:
       str = "  Processing Coefficient: 0x%02x\n" % node.realtek_coeff_proc
       return str + "  Coefficient Index: 0x%02x\n" % node.realtek_coeff_index
 
-    node = HDANode(self, nid)
-    str = "Node 0x%02x [%s] wcaps 0x%x:" % (nid, node.wtype_name(), node.wcaps)
+    str = "Node 0x%02x [%s] wcaps 0x%x:" % (node.nid, node.wtype_name(), node.wcaps)
     if node.stereo:
       str += node.channels == 2 and " Stereo" or " %d-Channels" % node.channels
     else:
@@ -1055,7 +1131,7 @@ class HDACodec:
       str += print_proc_caps(node)
     if hasattr(node, 'realtek_coeff_proc'):
       str += print_realtek_coef(node)
-    return str, node
+    return str
 
 def HDA_card_list():
   from dircache import listdir
@@ -1077,7 +1153,7 @@ def HDA_card_list():
 
 if __name__ == '__main__':
   v = HDACodec()
-  v.analyze_root_nodes()
+  v.analyze()
   print "vendor_id = 0x%x, subsystem_id = 0x%x, revision_id = 0x%x" % (v.vendor_id, v.subsystem_id, v.revision_id)
   print "afg = %s, mfg = %s" % (v.afg and "0x%x" % v.afg or 'None', v.mfg and "0x%x" % v.mfg or 'None')
   print