/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser 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 https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 *
 * $Author: dtvbm11 $
 * $Date: 2015/11/10 $
 * $RCSfile: sif_hw.h,v $
 * $Revision: #1 $
 *
 *---------------------------------------------------------------------------*/

/** @file sif_hw.h
 *  Define SIF hardware information.
 */

#ifndef SIF_HW_H
#define SIF_HW_H

//---------------------------------------------------------------------------
// Include files
//---------------------------------------------------------------------------
#include "x_typedef.h"

//---------------------------------------------------------------------------
// Macro definitions
//---------------------------------------------------------------------------
//only test for 5399
#if defined(CC_MT5399) || defined(CC_MT5890)
#define SIF_USE_LENGTHER_PAGE            1
#else
#define SIF_USE_LENGTHER_PAGE            0
#endif

#define IO_VAL 0x21000
/// SIF Engine Version Control Register
#define RW_PERMISC_REG                ((UINT32)(IO_VAL+0x0000))
#define SIF1_SW_RST                   ((UINT32)1<<29 )
#define SIF0_SW_RST                   ((UINT32)1<<28 )
#define SIF2_SW_RST                   ((UINT32)1<<26 )

#define SIF0_SW_RST_MSK               (0x10000000)
#define SIF1_SW_RST_MSK               (0x20000000)
#define SIF2_SW_RST_MSK               (0x04000000)

/// SCL Stretch Enable bit
#define SCL_STRETCH                   ((UINT32)1 << 0)
/// SM0EN: Serial interface master 0 enable.
#define SM0EN                         ((UINT32)1 << 1)
/// SM1EN: Serial interface master 1 enable.
#define SM1EN                         ((UINT32)1 << 1)
/// SDA_STATE:	SDA Value (1:high, 0:low)
#define SDA_STATE                     ((UINT32)1 << 2)
/// SCL_STATE:	SDA Value (1:high, 0:low)
#define SCL_STATE                     ((UINT32)1 << 3)
/// CS_STATUS:	SCL stretching status
#define CS_STATUS                     ((UINT32)1 << 4)
/// PAD selection from OSDA0 or TUNER_DATA
//#define PSEL                          ((UINT32)1 << 5)

#define DEGLITCH_EN                   ((UINT32)1 << 5)
//deglitch set
#define DEGLITCH_SET(x)                    ((((UINT32)(x)) & 0x00FF) << 8)
#define DEGLITCH_SET_MSK                   (0x00FF<< 8)

/// CLK_DIV: Parameter of divider to divide 27M for SCL.
#define ODRAIN                        ((UINT32)1 << 31)
#define CLK_DIV(x)                    ((((UINT32)(x)) & 0x0FFF) << 16)
#define CLK_DIV_MSK                   (0x0FFF << 16)

/// TRI: Trigger serial interface. Read back as serial interface busy.
#define TRI                           ((UINT32)1 << 0)
#define TRI_MSK                       ((UINT32)1 << 0)
/// PGLEN: Page length of sequential read/write. The maximum is 8 bytes. Set 0 as 1 bytes.
#if SIF_USE_LENGTHER_PAGE
#define PGLEN(x)                      ((((UINT32)(x)) & 0x003f) << 8)
#define PGLEN_MSK                     (0x3f00)
#else
#define PGLEN(x)                      ((((UINT32)(x)) & 0x0007) << 8)
#define PGLEN_MSK                     (0x0700)
#endif
/// SIF_MODE: start ==>data==>stop, start==>data, data==>stop, only data
#define SIF_MODE(x)                   ((((UINT32)(x)) & 0x0007) << 4)
typedef enum {
    MODE_START        = 0x1,
    MODE_WR_DATA      = 0x2,
    MODE_STOP         = 0x3,
    MODE_RD_DATA_LAST = 0x4,
    MODE_RD_DATA      = 0x5,
} SIF_MODE_T;
#define SIF_MODE_MSK                  ((UINT32)0x70)
/// ACK: 	Acknowledge bits.


#if SIF_USE_LENGTHER_PAGE
#define ACK(x)                        ((((UINT32)(x)) & 0xFFFF0000) >> 16)
#define ACKH(x)                        ((((UINT32)(x)) & 0x7FFFF800) >> 11)
#else
#define ACK(x)                        ((((UINT32)(x)) & 0x00FF0000) >> 16)
#endif

/*
* 5399 sif register 
*/
/// SM0CTL0_REG: Serial interface master 0 control 0 register.
#define RW_SM0_CTRL0_REG              ((UINT32)(IO_VAL+0x0240))
#define RW_SM0_CTRL1_REG              ((UINT32)(IO_VAL+0x0244))
#define RW_SM0_CTRL2_REG              ((UINT32)(IO_VAL+0x0248))
#define RW_SM0_CTRL3_REG              ((UINT32)(IO_VAL+0x02fc))

/// RW_SM0_DEV_REG: Serial interface master 0 device address 
#define RW_SM0_DEV_REG                ((UINT32)(IO_VAL+0x024c))

/// SM0D0_REG: Serial interface master 0 data port 0 register.
#define RW_SM0_D0_REG                 ((UINT32)(IO_VAL+0x0250))
#define RW_SM0_D1_REG                 ((UINT32)(IO_VAL+0x0254))
#define RW_SM0_D2_REG                 ((UINT32)(IO_VAL+0x02E0))
#define RW_SM0_D3_REG                 ((UINT32)(IO_VAL+0x02E4))
#define RW_SM0_D4_REG                 ((UINT32)(IO_VAL+0x02E8))
#define RW_SM0_D5_REG                 ((UINT32)(IO_VAL+0x02EC))
#define RW_SM0_D6_REG                 ((UINT32)(IO_VAL+0x02F0))
#define RW_SM0_D7_REG                 ((UINT32)(IO_VAL+0x02F4))
#define RW_SM0_D8_REG                 ((UINT32)(IO_VAL+0x02F8))


/// PINTEN_REG: Peripheral interrupt enable register.
#define RW_PINTEN_REG                 ((UINT32)(IO_VAL+0x025C))
#define SIF_M1_INTEN                  ((UINT32)1 << 1)
#define SIF_M0_INTEN                  ((UINT32)1 << 0)

/// PINTST_REG: Peripheral interrupt status register.
#define RW_PINTST_REG                 ((UINT32)(IO_VAL+0x0260))
#define SIF_M1_INTST                  ((UINT32)1 << 1)
#define SIF_M0_INTST                  ((UINT32)1 << 0)

/// PINTCLR_REG: Peripheral interrupt clear register.
#define RW_PINTCLR_REG                ((UINT32)(IO_VAL+0x0264))
#define SIF_M1_INTCLR                 ((UINT32)1 << 1)
#define SIF_M0_INTCLR                 ((UINT32)1 << 0)

/// AINTEN_REG: Pdwnc interrupt enable register.
#define RW_AINTEN_REG                 ((UINT32)0x0044)
#define SIF_M2_INTEN                  ((UINT32)1 << 8)
#define SIF_M3_INTEN                  ((UINT32)1 << 20)


/// AINTSTA_REG: Pdwnc interrupt status register.
#define RW_AINTSTA_REG                 ((UINT32)0x0040)
#define SIF_M2_INTST                  ((UINT32)1 << 8)
#define SIF_M3_INTST                  ((UINT32)1 << 20)


/// AINTCLR_REG: Pdwnc interrupt clear register.
#define RW_AINTCLR_REG                ((UINT32)0x0048)
#define SIF_M2_INTCLR                 ((UINT32)1 << 8)	//clear SIF0 interrupt
#define SIF_M3_INTCLR                 ((UINT32)1 << 20)	//clear SIF1 interrupt


/// WSM0CTL0_REG: 8295B Serial interface master 0 control 0 register.
#define RW_WSM0_CTRL0_REG              ((UINT32)0x7800)

/// WSM0CTL1_REG: 8295B Serial interface master 0 control 1 register.
#define RW_WSM0_CTRL1_REG              ((UINT32)0x7804)

/// WSM0D0_REG:8295B Serial interface master 0 data port 0 register.
#define RW_WSM0_D0_REG                 ((UINT32)0x7808)

/// WSM0D1_REG:8295B Serial interface master 0 data port 1 register.
#define RW_WSM0_D1_REG                 ((UINT32)0x780C)

//WINTEN_REG: 8295b interrupt enable register.
#define RW_WINTEN_REG                  ((UINT32)0x7004)
#define SIF_M4_INTEN                  ((UINT32)1 << 0)
#define SIF_M5_INTEN                  ((UINT32)1 << 1)

/// WINTSTA_REG: 8295B interrupt status register.
#define RW_WINTSTA_REG                 ((UINT32)0x7008)
#define SIF_M4_INTST                  ((UINT32)1 << 0)
#define SIF_M5_INTST                  ((UINT32)1 << 1)

/// WINTCLR_REG: 8295B interrupt clear register.
#define RW_WINTCLR_REG                ((UINT32)0x700c) 
#define SIF_M4_INTCLR                  ((UINT32)1 << 0)
#define SIF_M5_INTCLR                  ((UINT32)1 << 1)

// For OLD SIF H/W
/// SM1CTL0_REG: Serial interface master 1 control 0 register. 
#define RW_SM1_CTRL0_REG             ((UINT32)(IO_VAL+0x0270))

/// SM1CTL1_REG: Serial interface master 1 control 1 register. 
#define RW_SM1_CTRL1_REG               ((UINT32)(IO_VAL+0x0274))

/// SM1CTL2_REG: Serial interface master 1 control 2 register. 
#define RW_SM1_CTRL2_REG               ((UINT32)(IO_VAL+0x0278))

/// SM1CTL2_REG: Serial interface master 1 control 3 register. 
#define RW_SM1_CTRL3_REG               ((UINT32)(IO_VAL+0x02A8))

/// SM1DEV_REG: Serial interface master 1 device address register. 
#define RW_SM1_DEV_REG                 ((UINT32)(IO_VAL+0x027C))

/// SM1WD_REG: Serial interface master 1 word address register. 
#define RW_SM1_WD_REG                  ((UINT32)(IO_VAL+0x027c))

/// SM1D0_REG: Serial interface master 1 data port 0 register. 
#define RW_SM1_D0_REG                 ((UINT32)(IO_VAL+0x0280))

/// SM1D1_REG: Serial interface master 1 data port 1 register. 
#define RW_SM1_D1_REG                 ((UINT32)(IO_VAL+0x0284))

/// SM1D2_REG: Serial interface master 1 data port 2 register. 
#define RW_SM1_D2_REG                 ((UINT32)(IO_VAL+0x0288))

/// SM1D3_REG: Serial interface master 1 data port 3 register. 
#define RW_SM1_D3_REG                 ((UINT32)(IO_VAL+0x028C))

/// SM1D4_REG: Serial interface master 1 data port 4 register. 
#define RW_SM1_D4_REG                 ((UINT32)(IO_VAL+0x0290))

/// SM1D5_REG: Serial interface master 1 data port 5 register. 
#define RW_SM1_D5_REG                 ((UINT32)(IO_VAL+0x0294))

/// SM1D6_REG: Serial interface master 1 data port 6 register. 
#define RW_SM1_D6_REG                 ((UINT32)(IO_VAL+0x0298))

/// SM1D7_REG: Serial interface master 1 data port 7 register. 
#define RW_SM1_D7_REG                 ((UINT32)(IO_VAL+0x029C))

/// SM1D8_REG: Serial interface master 1 data port 8 register. 
#define RW_SM1_D8_REG                 ((UINT32)(IO_VAL+0x02A4))


//---------------------------------------------------------------------------
// Inter-file functions
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Public functions
//---------------------------------------------------------------------------

#endif // SIF_HW_H
