//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  Header: pwm_reg.h
//
//  Defines the PWM Timer register layout and associated types and constants.
//
#ifndef __S5PV210_PWM_H
#define __S5PV210_PWM_H

#if __cplusplus
extern "C" {
#endif

//------------------------------------------------------------------------------
//
//  Type:  PWM_REG
//
//  Defines the PWM Timer control register layout. This register bank is
//  located by the constant BASE_REG_XX_PWM in the configuration file
//  base_reg_cfg.h.
//

typedef struct
{
    UINT32 TCFG0;        //0x00
    UINT32 TCFG1;        //0x04
    UINT32 TCON;        //0x08
    UINT32 TCNTB0;        //0x0C

    UINT32 TCMPB0;        //0x10
    UINT32 TCNTO0;        //0x14
    UINT32 TCNTB1;        //0x18
    UINT32 TCMPB1;        //0x1C

    UINT32 TCNTO1;        //0x20
    UINT32 TCNTB2;        //0x24
    UINT32 TCMPB2;        //0x28
    UINT32 TCNTO2;        //0x2C

    UINT32 TCNTB3;        //0x30
    UINT32 TCMPB3;        //0x34
    UINT32 TCNTO3;        //0x38
    UINT32 TCNTB4;        //0x3C

    UINT32 TCNTO4;        //0x40
    UINT32 TINT_CSTAT;    // 0x44
    UINT32 PAD[2];        // 0x48~0x4f
} PWM_REG, *PPWM_REG;

//------------------------------------------------------------------------------

// Do not use OR/AND operation on TINT_CSTAT SFR
// to clear interrupt pending or enable/disable interrupt
// TINT_CSTAT SFR have multiple pending bit of Timer0~4
// You should write "1" on only corresponding pending bit
#define TINT_CSTAT_INTMASK(n)            ((n)&0x1F)    // Remove Pending Status Value from SFR
#define TIMER4_PENDING_CLEAR            (1<<9)
#define TIMER3_PENDING_CLEAR            (1<<8)
#define TIMER2_PENDING_CLEAR            (1<<7)
#define TIMER1_PENDING_CLEAR            (1<<6)
#define TIMER0_PENDING_CLEAR            (1<<5)
#define TIMER4_INTERRUPT_ENABLE        (1<<4)
#define TIMER3_INTERRUPT_ENABLE        (1<<3)
#define TIMER2_INTERRUPT_ENABLE        (1<<2)
#define TIMER1_INTERRUPT_ENABLE        (1<<1)
#define TIMER0_INTERRUPT_ENABLE        (1<<0)
#define TIMER0_ENABLE	(1<<0)
#define TIMER1_ENABLE	(1<<1)
#define TIMER2_ENABLE	(1<<2)
#define TIMER3_ENABLE	(1<<3)
#define TIMER4_ENABLE	(1<<4)
#define TIMER0_STATUS	(1<<5)
#define TIMER1_STATUS	(1<<6)
#define TIMER2_STATUS	(1<<7)
#define TIMER3_STATUS	(1<<8)
#define TIMER4_STATUS	(1<<9)

#define DEADZONE_LENGTH_START	16
#define PRESCALER1_START		8
#define PRESCALER2_START		0
#define DEADZONE_LENGTH_MASK	(0xFF << DEADZONE_LENGTH_START)
#define PRESCALER1_MASK			(0xFF << PRESCALER1_START)
#define PRESCALER2_MASK			(0xFF << PRESCALER2_START)
#define TCFG0_RSVD_BITS			0xFF000000

#define DIV_MUX2_START			8
#define DIV_MUX2_MASK			(0xF << DIV_MUX2_START)

#define DIV_MUX4_START			16
#define DIV_MUX4_MASK			(0xF << DIV_MUX4_START)

#define D1_2					0x1

#define TIMER4_STATUS	(1<<9)
#define TIMER4_ENABLE	(1<<4)
#define TIMER4_AUTO_RELOAD		(1 << 22)
#define TIMER4_MANUAL_UPDATE	(1 << 21)
#define TIMER4_START			(1 << 20)
#define TIMER4_MASK				(0x7 << 20)

#define TIMER2_STATUS	(1<<7)
#define TIMER2_ENABLE	(1<<2)
#define TIMER2_AUTO_RELOAD		(1 << 15)
#define TIMER2_MANUAL_UPDATE	(1 << 13)
#define TIMER2_START			(1 << 12)
#define TIMER2_MASK				(0xf << 12)

#define TCONT0_Start		(0x1)
#define TCONT0_Update		(0x2)
#define TCONT0_AutoReload	(0x8)

#define MAX_TIMER_VAL			(0xFFFFFFFF)
#define USEC_TICK_NUM			(3)
#define MSEC_TO_USEC				(1000)
#define SEC_TO_MSEC				(1000)

#define PRESCALER_TIMER_01		(32)		// PCLK 66MHz / (32+1)
#define PRESCALER_TIMER_234		(32)		// PCLK 66MHz / (32+1)

#define D1_1					0x0
#define D1_2					0x1
#define D1_4					0x2
#define D1_8					0x3
#define D1_16					0x4
#define DIV1					  1
#define DIV2					  2
#define DIV4					  4
#define DIV8					  8
#define DIV16					 16

#define CLR_PWMINT(Addr_TINT_CSTAT, Idx)    do {                                                                   \
                                            Addr_TINT_CSTAT = (Addr_TINT_CSTAT & 0x1f) | (0x1 << (Idx + 5));    \
                                       } while(0)

#define ENABLE_PWMINT(Addr_TINT_CSTAT, Idx)    do {                                                                   \
                                            Addr_TINT_CSTAT = (Addr_TINT_CSTAT & 0x1f) | (0x1 << (Idx));    \
                                       } while(0)

#define DISABLE_PWMINT(Addr_TINT_CSTAT, Idx)    do {                                                                   \
                                            Addr_TINT_CSTAT = (Addr_TINT_CSTAT & 0x1f) & ~(0x1 << (Idx));    \
                                       } while(0)
//------------------------------------------------------------------------------

#if __cplusplus
}
#endif

#endif    // __S5PV210_PWM_H