/*

    Copyright (C) 1997-2017  AudioScience Inc. <support@audioscience.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of version 2 of the GNU General Public License as
    published by the Free Software Foundation;

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

*/

#undef TRACE_SYSTEM
#define TRACE_SYSTEM asihpi
#define TRACE_INCLUDE_FILE trace_asihpi

#if !defined(_TRACE_ASIHPI_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_ASIHPI_H

#include <linux/tracepoint.h>

struct snd_card_asihpi_pcm;

TRACE_EVENT(asihpi_stream_trigger,

	TP_PROTO(struct snd_pcm_substream *substream, int cmd),

	TP_ARGS(substream, cmd),

	TP_STRUCT__entry(
		__field( unsigned int, card )
		__field( unsigned int, number )
		__field( unsigned int, stream )
		__field( int, cmd )
	),

	TP_fast_assign(
		__entry->card = (substream)->pcm->card->number;
		__entry->number = (substream)->number;
		__entry->stream = (substream)->stream;
		__entry->cmd = cmd;
	),

	TP_printk("pcmC%dD0%c/sub%d: %d",
		  __entry->card,
		  __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c',
		  __entry->number,
		  __entry->cmd
		  )
);

TRACE_EVENT(asihpi_hwptr_update,

	TP_PROTO(struct snd_pcm_substream *substream, snd_pcm_uframes_t hwptr),

	TP_ARGS(substream, hwptr),

	TP_STRUCT__entry(
		__field( unsigned int, card )
		__field( unsigned int, number )
		__field( unsigned int, stream )
		__field( snd_pcm_uframes_t, hwptr )
	),

	TP_fast_assign(
		__entry->card = (substream)->pcm->card->number;
		__entry->number = (substream)->number;
		__entry->stream = (substream)->stream;
		__entry->hwptr = hwptr;
	),

	TP_printk("pcmC%dD0%c/sub%d: hptr update %lu",
		  __entry->card,
		  __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c',
		  __entry->number,
		  __entry->hwptr
		  )
);

TRACE_EVENT(asihpi_stream_xfer,

	TP_PROTO(struct snd_pcm_substream *substream, int xfer),

	TP_ARGS(substream, xfer),

	TP_STRUCT__entry(
		__field( unsigned int, card )
		__field( unsigned int, number )
		__field( unsigned int, stream )
		__field( int, xfer )
	),

	TP_fast_assign(
		__entry->card = (substream)->pcm->card->number;
		__entry->number = (substream)->number;
		__entry->stream = (substream)->stream;
		__entry->xfer = bytes_to_frames((substream)->runtime, xfer);
	),

	TP_printk("pcmC%dD0%c/sub%d : %d",
		  __entry->card,
		  __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c',
		  __entry->number,
		  __entry->xfer
		  )
);

TRACE_EVENT(asihpi_stream_state,

	TP_PROTO(char * loc, struct snd_pcm_substream *substream, struct hpi_hostbuffer_status *hhs),

	TP_ARGS(loc, substream, hhs),

	TP_STRUCT__entry(
		__field( unsigned int, card   )
		__field( unsigned int, number )
		__field( unsigned int, stream )

		__field( char *, loc )

		__field( snd_pcm_uframes_t, appl_ptr   )
		__field( snd_pcm_uframes_t, hw_ptr     )
		__field( snd_pcm_uframes_t, alsa_avail )

		__field( snd_pcm_uframes_t, hpi_bufsize          )
		__field( snd_pcm_uframes_t, hpi_hostindex        )
		__field( snd_pcm_uframes_t, hpi_hostindex_mod    )
		__field( snd_pcm_uframes_t, hpi_dspindex         )
		__field( snd_pcm_uframes_t, hpi_dspindex_mod_1   )
		__field( snd_pcm_uframes_t, hpi_dspindex_mod_2   )
		__field( snd_pcm_uframes_t, hpi_auxdata          )
		__field( snd_pcm_uframes_t, hpi_avail            )
		__field( snd_pcm_uframes_t, hpi_sample_processed )
	),

	TP_fast_assign(
		__entry->card   = substream->pcm->card->number;
		__entry->stream = substream->stream;
		__entry->number = substream->number;

		__entry->loc   = loc;

		__entry->appl_ptr   = substream->runtime->control->appl_ptr;
		__entry->hw_ptr     = substream->runtime->status->hw_ptr;
		__entry->alsa_avail = snd_pcm_asihpi_playback_avail(substream->runtime);

		__entry->hpi_bufsize          = bytes_to_frames(substream->runtime, hhs->dwSizeInBytes);
		__entry->hpi_hostindex        = bytes_to_frames(substream->runtime, hhs->dwHostIndex);
		__entry->hpi_hostindex_mod    = bytes_to_frames(substream->runtime, hhs->dwHostIndex % hhs->dwSizeInBytes);
		__entry->hpi_dspindex         = bytes_to_frames(substream->runtime, hhs->dwDspIndex);
		__entry->hpi_dspindex_mod_1   = bytes_to_frames(substream->runtime, hhs->dwDspIndex % hhs->dwSizeInBytes);
		__entry->hpi_dspindex_mod_2   = bytes_to_frames(substream->runtime, (hhs->dwSizeInBytes + (hhs->dwDspIndex - hhs->dwAuxiliaryDataAvailable)) % hhs->dwSizeInBytes);
		__entry->hpi_auxdata          = bytes_to_frames(substream->runtime, hhs->dwAuxiliaryDataAvailable);
		__entry->hpi_avail            = bytes_to_frames(substream->runtime, (hhs->dwSizeInBytes - (hhs->dwHostIndex - (hhs->dwDspIndex - hhs->dwAuxiliaryDataAvailable))));
		__entry->hpi_sample_processed = hhs->dwSamplesProcessed;
	),

	TP_printk("pcmC%dD0%c/sub%d in %s: ALSA: aptr %lu, hptr %lu, avail %lu; HPI size %lu, host %lu (%lu), dsp %lu (%lu, %lu), fifo %lu, avail %lu, xfer %lu",
		__entry->card,
		__entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c',
		__entry->number,

		__entry->loc,

		__entry->appl_ptr,
		__entry->hw_ptr,
		__entry->alsa_avail,

		__entry->hpi_bufsize,
		__entry->hpi_hostindex,
		__entry->hpi_hostindex_mod,
		__entry->hpi_dspindex,
		__entry->hpi_dspindex_mod_1,
		__entry->hpi_dspindex_mod_2,
		__entry->hpi_auxdata,
		__entry->hpi_avail,
		__entry->hpi_sample_processed
	)
);

#endif /* _TRACE_ASIHPI_H */

/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#include <trace/define_trace.h>
