/*
 * Copyright (C) ST-Ericsson SA 2010
 *
 * ST-Ericsson STM Trace driver
 *
 * Author: Pierre Peiffer <pierre.peiffer@stericsson.com> for ST-Ericsson.
 *         Philippe Langlais <philippe.langlais@stericsson.com> for ST-Ericsson.
 * License terms:  GNU General Public License (GPL), version 2.
 */

#ifndef STM_H
#define STM_H

#define STM_DEV_NAME "stm"

/* One single channel mapping */
struct stm_channel {
	union {
		__u8  no_stamp8;
		__u16 no_stamp16;
		__u32 no_stamp32;
		__u64 no_stamp64;
	};
	union {
		__u8   stamp8;
		__u16 stamp16;
		__u32 stamp32;
		__u64 stamp64;
	};
};

/* Possible trace modes */
#define STM_SW_LOSSLESS	0 /* Software mode: lossless data but intrusive */
#define STM_HW_LOSSY	1 /* Hardware mode: lossy data but less intrusive */

/* Possible clock setting */
enum clock_div {
	STM_CLOCK_DIV2 = 0,
	STM_CLOCK_DIV4,
	STM_CLOCK_DIV6,
	STM_CLOCK_DIV8,
	STM_CLOCK_DIV10,
	STM_CLOCK_DIV12,
	STM_CLOCK_DIV14,
	STM_CLOCK_DIV16,
};

/* ioctl commands */
#define STM_CONNECTION            _IOW('t', 0, enum stm_connection_type)
#define STM_DISABLE               _IO('t', 1)
#define STM_GET_NB_MAX_CHANNELS   _IOR('t', 2, int)
#define STM_GET_NB_FREE_CHANNELS  _IOR('t', 3, int)
#define STM_GET_CHANNEL_NO        _IOR('t', 4, int)
#define STM_SET_CLOCK_DIV         _IOW('t', 5, enum clock_div)
#define STM_GET_CTRL_REG          _IOR('t', 6, int)
#define STM_ENABLE_SRC            _IOWR('t', 7, int)
#define STM_GET_FREE_CHANNEL      _IOW('t', 8, int)
#define STM_RELEASE_CHANNEL       _IOW('t', 9, int)
#define STM_SET_MODE              _IOWR('t', 10, int)
#define STM_GET_MODE              _IOR('t', 11, int)

enum stm_connection_type {
	STM_DISCONNECT = 0,
	STM_DEFAULT_CONNECTION = 1,
	STM_STE_MODEM_ON_MIPI34_NONE_ON_MIPI60 = 2,
	STM_STE_APE_ON_MIPI34_NONE_ON_MIPI60 = 3,
	STM_STE_MODEM_ON_MIPI34_APE_ON_MIPI60 = 4
};

#ifdef __KERNEL__

struct stm_platform_data {
	u32        regs_phys_base;
	u32        channels_phys_base;
	u32        id_mask;
	u32        masters_enabled;
	const s16 *channels_reserved;
	int        channels_reserved_sz;
	int        (*stm_connection)(enum stm_connection_type);
};

/* Channels base address */
extern volatile struct stm_channel __iomem *stm_channels;

/* Provides stm_trace_XX() and stm_tracet_XX() trace API */
#define DEFLLTFUN(size) \
static inline void stm_trace_##size(int channel, __u##size data) \
{ \
	stm_channels[channel].no_stamp##size = data; \
} \
static inline void stm_tracet_##size(int channel, __u##size data) \
{ \
	stm_channels[channel].stamp##size = data; \
} \

DEFLLTFUN(8);
DEFLLTFUN(16);
DEFLLTFUN(32);
DEFLLTFUN(64);

/*
 * Trace a buffer on a given channel
 * with auto time stamping on the last byte(s) only.
 */
int stm_trace_buffer_onchannel(int channel, const void *data, size_t length);
/*
 * Trace a buffer on a dynamically allocated channel
 * with auto time stamping on the last byte(s) only.
 * Dynamic channel are allocated in the 128 highest channels
 */
int stm_trace_buffer(const void *data, size_t length);

/* printk equivalent for STM */
int stm_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));

/* Alloc/Free STM channel */
int stm_alloc_channel(int offset);
void stm_free_channel(int channel);

#endif /* __KERNEL__ */

#endif /* STM_H */
