From ecf726f5414489fe749477eb77d6cb12bb93c8bc Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 9 Aug 2011 14:22:44 +0200
Subject: [PATCH] ALSA: hda - Add tracepoint for unsolicited events
Git-commit: ecf726f5414489fe749477eb77d6cb12bb93c8bc
Patch-mainline: 3.2-rc1
References: FATE#314311

Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 Documentation/sound/alsa/HD-Audio.txt |   48 +++++++++++++++++++++++++++++++++-
 sound/pci/hda/hda_codec.c             |    1 
 sound/pci/hda/hda_trace.h             |   22 +++++++++++++++
 3 files changed, 70 insertions(+), 1 deletion(-)

--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -523,11 +523,57 @@ cable is unplugged.  Thus, if you hear n
 power-saving.  See /sys/module/snd_hda_intel/parameters/power_save to
 check the current value.  If it's non-zero, the feature is turned on.
 
+Tracepoints
+~~~~~~~~~~~
+The hd-audio driver gives a few basic tracepoints.
+`hda:hda_send_cmd` traces each CORB write while `hda:hda_get_response`
+traces the response from RIRB (only when read from the codec driver).
+`hda:hda_bus_reset` traces the bus-reset due to fatal error, etc,
+`hda:hda_unsol_event` traces the unsolicited events, and
+`hda:hda_power_down` and `hda:hda_power_up` trace the power down/up
+via power-saving behavior.
+
+Enabling all tracepoints can be done like
+------------------------------------------------------------------------
+  # echo 1 > /sys/kernel/debug/tracing/events/hda/enable
+------------------------------------------------------------------------
+then after some commands, you can traces from
+/sys/kernel/debug/tracing/trace file.  For example, when you want to
+trace what codec command is sent, enable the tracepoint like:
+------------------------------------------------------------------------
+  # cat /sys/kernel/debug/tracing/trace
+  # tracer: nop
+  #
+  #       TASK-PID    CPU#    TIMESTAMP  FUNCTION
+  #          | |       |          |         |
+         <...>-7807  [002] 105147.774889: hda_send_cmd: [0:0] val=e3a019
+         <...>-7807  [002] 105147.774893: hda_send_cmd: [0:0] val=e39019
+         <...>-7807  [002] 105147.999542: hda_send_cmd: [0:0] val=e3a01a
+         <...>-7807  [002] 105147.999543: hda_send_cmd: [0:0] val=e3901a
+         <...>-26764 [001] 349222.837143: hda_send_cmd: [0:0] val=e3a019
+         <...>-26764 [001] 349222.837148: hda_send_cmd: [0:0] val=e39019
+         <...>-26764 [001] 349223.058539: hda_send_cmd: [0:0] val=e3a01a
+         <...>-26764 [001] 349223.058541: hda_send_cmd: [0:0] val=e3901a
+------------------------------------------------------------------------
+Here `[0:0]` indicates the card number and the codec address, and
+`val` shows the value sent to the codec, respectively.  The value is
+a packed value, and you can decode it via hda-decode-verb program
+included in hda-emu package below.  For example, the value e3a019 is
+to set the left output-amp value to 25.
+------------------------------------------------------------------------
+  % hda-decode-verb 0xe3a019
+  raw value = 0x00e3a019
+  cid = 0, nid = 0x0e, verb = 0x3a0, parm = 0x19
+  raw value: verb = 0x3a0, parm = 0x19
+  verbname = set_amp_gain_mute
+  amp raw val = 0xa019
+  output, left, idx=0, mute=0, val=25
+------------------------------------------------------------------------
+
 
 Development Tree
 ~~~~~~~~~~~~~~~~
 The latest development codes for HD-audio are found on sound git tree:
-
 - git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
 
 The master branch or for-next branches can be used as the main
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -610,6 +610,7 @@ int snd_hda_queue_unsol_event(struct hda
 	struct hda_bus_unsolicited *unsol;
 	unsigned int wp;
 
+	trace_hda_unsol_event(bus, res, res_ex);
 	unsol = bus->unsol;
 	if (!unsol)
 		return 0;
--- a/sound/pci/hda/hda_trace.h
+++ b/sound/pci/hda/hda_trace.h
@@ -87,6 +87,28 @@ DEFINE_EVENT(hda_power, hda_power_up,
 	TP_ARGS(codec)
 );
 
+TRACE_EVENT(hda_unsol_event,
+
+	TP_PROTO(struct hda_bus *bus, u32 res, u32 res_ex),
+
+	TP_ARGS(bus, res, res_ex),
+
+	TP_STRUCT__entry(
+		__field( unsigned int, card )
+		__field( u32, res )
+		__field( u32, res_ex )
+	),
+
+	TP_fast_assign(
+		__entry->card = (bus)->card->number;
+		__entry->res = res;
+		__entry->res_ex = res_ex;
+	),
+
+	TP_printk("[%d] res=%x, res_ex=%x", __entry->card,
+		  __entry->res, __entry->res_ex)
+);
+
 #endif /* _TRACE_HDA_H */
 
 /* This part must be outside protection */
