#ifndef _CECILIE_H_
#define _CECILIE_H_

#include <stdint.h>

/*
 * CEC_REG_CHx_CONTROL		1 - Clear channel
 *
 * CEC_REG_COMMON_CONTROL	0 - Sync (use synchronized mode)
 * 				2 - Clear both channels
 *
 * CEC_REG_CHx_STATUS0		0 - channel overflow - has to be cleared by 
 * 					control register after overflow
 *
 * CEC_REG_CHx_STATUS1		0 - together with CEC_REG_CHx_STATUS2 64bit counter
 *
 * CEC_REG_CHx_STATUS2		0 - together with CEC_REG_CHx_STATUS1 64bit counter
 *
 * CEC_REG_COMMON_STATUS	0 - Overflow on one of channels
 *
 * CEC_REG_ID			0 - Constant ID word 0xDFC0CEC0
 */


/* Control registers */
#define CEC_REG_CH0_CONTROL	0x00000000
#define CEC_REG_CH1_CONTROL	0x00000004
#define CEC_REG_COMMON_CONTROL	0x00000008

/* Status registers */
/* Channel 0 */
#define CEC_REG_CH0_STATUS0	0x0000000C
#define CEC_REG_CH0_STATUS1	0x00000010
#define CEC_REG_CH0_STATUS2	0x00000014

/* Channel 1 */
#define CEC_REG_CH1_STATUS0	0x00000018
#define CEC_REG_CH1_STATUS1	0x0000001C
#define CEC_REG_CH1_STATUS2	0x00000020

/* Common - if synced */
#define CEC_REG_COMMON_STATUS	0x00000024

/* ID register */
#define CEC_REG_ID		0x00000028



/* Control register offsets */
#define CEC_CLEAR_OFFSET		1

/* Status regiseter offsets */
#define CEC_OVERFLOW_OFFSET		0

/* Common control register offsets */
#define CEC_COMMON_SYNC_OFFSET		0
#define CEC_COMMON_TRIG_OFFSET		1
#define CEC_COMMON_CLEAR_OFFSET		2
#define CEC_COMMON_TRIG_CHANNEL_OFFSET	3
#define CEC_COMMON_TRIG_EDGE_OFFSET	4
#define CEC_COMMON_TRIG_LEVEL_OFFSET	5

/* Common status register offsets */
#define CEC_COMMON_OVERFLOW_OFFSET	0

/* Usefull Macros */
#define CEC_CLEAR_CHANNEL_EN(r)		(r | (1 << CEC_CLEAR_OFFSET))
#define CEC_CLEAR_CHANNEL_DIS(r)	(r & ~(1 << CEC_CLEAR_OFFSET))

#define CEC_TRIG_EN(r)			(r | (1 << CEC_COMMON_TRIG_OFFSET))
#define CEC_TRIG_DIS(r)			(r & ~(1 << CEC_COMMON_TRIG_OFFSET))

#define CEC_SYNC_EN(r)			(r | (1 << CEC_COMMON_SYNC_OFFSET))
#define CEC_SYNC_DIS(r)			(r & ~(1 << CEC_COMMON_SYNC_OFFSET))

#define CEC_CLEAR_EN(r)			(r | (1 << CEC_COMMON_CLEAR_OFFSET))
#define CEC_CLEAR_DIS(r)		(r & ~(1 << CEC_COMMON_CLEAR_OFFSET))

#define CEC_TRIG_CHANNEL0(r)		(r & ~(1 << CEC_COMMON_TRIG_CHANNEL_OFFSET))
#define CEC_TRIG_CHANNEL1(r)		(r | (1 << CEC_COMMON_TRIG_CHANNEL_OFFSET))

#define CEC_TRIG_RISING_EDGE(r)		(r & ~(1 << CEC_COMMON_TRIG_EDGE_OFFSET))
#define CEC_TRIG_FALLING_EDGE(r)	(r | (1 << CEC_COMMON_TRIG_EDGE_OFFSET))

#define CEC_TRIG_LEVEL(r,l)		(r | ((0x00003fff & l) << CEC_COMMON_TRIG_LEVEL_OFFSET))

void registers();

struct cecilie_pcie_reg_desc_t {
	uint32_t reg_addr;
	char *name;
	char *description;
};


#endif
