text: /* ------------------------------------------
   * Copyright (c) 2017, Synopsys, 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:
  
   * 1) Redistributions of source code must retain the above copyright notice, this
   * list of conditions and the following disclaimer.
  
   * 2) 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.
  
   * 3) Neither the name of the Synopsys, Inc., 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.
   *
  --------------------------------------------- */
  
  #ifndef _DW_IIC_H_
  #define _DW_IIC_H_
  
  #include "dev_iic.h"
  #include "arc_exception.h"
  
  /**
   * If this header file is included,
   * will indicate that this designware iic device
   * is used
   */
  #define DEVICE_USE_DESIGNWARE_IIC
  
  #define DW_IIC_MASTER_SUPPORTED		(0x1)	/*!< Support Designware IIC Master Mode */
  #define DW_IIC_SLAVE_SUPPORTED		(0x2)	/*!< Support Designware IIC Slave Mode */
  /*!< Support Designware IIC Both Master and Slave Mode */
  #define DW_IIC_BOTH_SUPPORTED		(DW_IIC_MASTER_SUPPORTED|DW_IIC_SLAVE_SUPPORTED)
  
  #define DW_IIC_INVALID_INTNO		(DEV_INTNO_INVALID)
  
  enum {
  	DW_IIC_CAP_LOADING_100PF = 0,
  	DW_IIC_CAP_LOADING_400PF
  };
  
  
  /**
   * \brief	DesignWare IIC register structure
   * \details	Detailed struct description of DesignWare IIC
   *	block register information, implementation of dev_iic_info::iic_regs
   */
  typedef volatile struct dw_iic_reg {
  	uint32_t IC_CON;		/*!< (0x00) : IIC control */
  	uint32_t IC_TAR;		/*!< (0x04) : IIC target address */
  	uint32_t IC_SAR;		/*!< (0x08) : IIC slave address */
  	uint32_t IC_HS_MADDR;		/*!< (0x0c) : IIC HS Master Mode Code address */
  	uint32_t IC_DATA_CMD;		/*!< (0x10) : IIC Rx/Tx Data Buffer and Command */
  	uint32_t IC_SS_SCL_HCNT;	/*!< (0x14) : Standard Speed IIC clock SCL High Count */
  	uint32_t IC_SS_SCL_LCNT;	/*!< (0x18) : Standard Speed IIC clock SCL Low Count */
  	uint32_t IC_FS_SCL_HCNT;	/*!< (0x1c) : Fast Speed IIC clock SCL Low Count */
  	uint32_t IC_FS_SCL_LCNT;	/*!< (0x20) : Fast Speed IIC clock SCL Low Count */
  	uint32_t IC_HS_SCL_HCNT;	/*!< (0x24) : High Speed IIC clock SCL Low Count */
  	uint32_t IC_HS_SCL_LCNT;	/*!< (0x28) : High Speed IIC clock SCL Low Count */
  	uint32_t IC_INTR_STAT;		/*!< (0x2c) : IIC Interrupt Status */
  	uint32_t IC_INTR_MASK;		/*!< (0x30) : IIC Interrupt Mask */
  	uint32_t IC_RAW_INTR_STAT;	/*!< (0x34) : IIC Raw Interrupt Status */
  	uint32_t IC_RX_TL;		/*!< (0x38) : IIC Receive FIFO Threshold */
  	uint32_t IC_TX_TL;		/*!< (0x3c) : IIC Transmit FIFO Threshold */
  	uint32_t IC_CLR_INTR;		/*!< (0x40) : Clear combined and Individual Interrupts */
  	uint32_t IC_CLR_RX_UNDER;	/*!< (0x44) : Clear RX_UNDER Interrupt */
  	uint32_t IC_CLR_RX_OVER;	/*!< (0x48) : Clear RX_OVER Interrupt */
  	uint32_t IC_CLR_TX_OVER;	/*!< (0x4c) : Clear TX_OVER Interrupt */
  	uint32_t IC_CLR_RD_REQ;		/*!< (0x50) : Clear RQ_REQ Interrupt */
  	uint32_t IC_CLR_TX_ABRT;	/*!< (0x54) : Clear TX_ABRT Interrupt */
  	uint32_t IC_CLR_RX_DONE;	/*!< (0x58) : Clear RX_DONE Interrupt */
  	uint32_t IC_CLR_ACTIVITY;	/*!< (0x5c) : Clear ACTIVITY Interrupt */
  	uint32_t IC_CLR_STOP_DET;	/*!< (0x60) : Clear STOP_DET Interrupt */
  	uint32_t IC_CLR_START_DET;	/*!< (0x64) : Clear START_DET Interrupt */
  	uint32_t IC_CLR_GEN_CALL;	/*!< (0x68) : Clear GEN_CALL Interrupt */
  	uint32_t IC_ENABLE;		/*!< (0x6c) : IIC Enable */
  	uint32_t IC_STATUS;		/*!< (0x70) : IIC Status */
  	uint32_t IC_TXFLR;		/*!< (0x74) : Transmit FIFO Level Register */
  	uint32_t IC_RXFLR;		/*!< (0x78) : Receive FIFO Level Register */
  	uint32_t IC_SDA_HOLD;		/*!< (0x7c) : SDA Hold Time Length Reg */
  	uint32_t IC_TX_ABRT_SOURCE;	/*!< (0x80) : IIC Transmit Abort Status Reg */
  	uint32_t IC_SLV_DATA_NACK_ONLY;	/*!< (0x84) : Generate SLV_DATA_NACK Register */
  	uint32_t IC_DMA_CR;		/*!< (0x88) : DMA Control Register */
  	uint32_t IC_DMA_TDLR;		/*!< (0x8c) : DMA Transmit Data Level */
  	uint32_t IC_DMA_RDLR;		/*!< (0x90) : DMA Receive Data Level */
  	uint32_t IC_SDA_SETUP;		/*!< (0x94) : SDA Setup Register */
  	uint32_t IC_ACK_GENERAL_CALL;	/*!< (0x98) : ACK General Call Register */
  	uint32_t IC_ENABLE_STATUS;	/*!< (0x9c) : Enable Status Register */
  	uint32_t IC_FS_SPKLEN;		/*!< (0xa0) : ISS and FS spike suppression limit */
  	uint32_t IC_HS_SPKLEN;		/*!< (0xa4) : HS spike suppression limit */
  	uint32_t RESERVED[19];		/*!< (0xa8) : Reserved */
  	uint32_t IC_COMP_PARAM_1;	/*!< (0xf4) : Component Parameter Register */
  	uint32_t IC_COMP_VERSION;	/*!< (0xf8) : Component Version ID Reg */
  	uint32_t IC_COMP_TYPE;		/*!< (0xfc) : Component Type Reg */
  } DW_IIC_REG, *DW_IIC_REG_PTR;
  /** @} */
  
  /** Spike Suppression Limit Configurations */
  typedef struct dw_iic_spklen {
  	uint32_t fs_spklen;	/*!< value for IC_FS_SPKLEN, Tsp for fast mode is 50ns */
  	uint32_t hs_spklen;	/*!< value for IC_HS_SPKLEN, Tsp for high-speed mode is 10ns */
  } DW_IIC_SPKLEN, *DW_IIC_SPKLEN_PTR;
  
  /** IIC Clock SCL High and Low Count Configurations for Different Speed */
  typedef struct dw_iic_scl_cnt {
  	uint32_t ss_scl_hcnt;	/*!< value for IC_SS_SCL_HCNT */
  	uint32_t ss_scl_lcnt;	/*!< value for IC_SS_SCL_LCNT */
  	uint32_t fs_scl_hcnt;	/*!< value for IC_FS_SCL_HCNT */
  	uint32_t fs_scl_lcnt;	/*!< value for IC_FS_SCL_LCNT */
  	uint32_t hs_scl_hcnt;	/*!< value for IC_HS_SCL_HCNT */
  	uint32_t hs_scl_lcnt;	/*!< value for IC_HS_SCL_LCNT */
  } DW_IIC_SCL_CNT, *DW_IIC_SCL_CNT_PTR;
  
  #define DW_IIC_GINT_DISABLED		(0)		/*!< designware interrupt disabled for control iic irq/fiq */
  #define DW_IIC_GINT_ENABLE		(1<<0)		/*!< designware interrupt enabled for control iic irq/fiq */
  #define DW_IIC_TXINT_ENABLE		(1<<1)		/*!< designware interrupt enabled for control transmit process */
  #define DW_IIC_RXINT_ENABLE		(1<<2)		/*!< designware interrupt enabled for control transmit process */
  
  typedef struct dw_iic_buffer {
  	DEV_BUFFER *buf;
  	uint32_t ofs;
  	uint32_t len;
  } DW_IIC_BUFFER, *DW_IIC_BUFFER_PTR;
  
  /**
   * \brief	DesignWare IIC control structure definition
   * \details	implement of dev_iic_info::iic_ctrl
   */
  typedef struct dw_iic_ctrl {
  	DW_IIC_REG *dw_iic_regs;	/*!< iic device registers */
  	/* Variables which should be set during object implementation */
  	uint32_t ic_clkhz;		/*!< IC clock in HZ */
  	uint32_t ic_caploading;		/*!< I2C Bus cap loading pf */
  	uint32_t support_modes;		/*!< supported iic modes */
  	uint32_t tx_fifo_len;		/*!< transmit fifo length */
  	uint32_t rx_fifo_len;		/*!< receive fifo length */
  	uint32_t iic_master_code;	/*!< value for IC_HS_MADDR */
  	uint32_t retry_cnt;		/*!< retry count for TX or RX */
  	uint32_t intno;			/*!< iic interrupt vector number */
  	INT_HANDLER dw_iic_int_handler;	/*!< iic interrupt handler */
  	DW_IIC_SPKLEN iic_spklen;	/*!< iic spike suppression length settings */
  	DW_IIC_SCL_CNT iic_scl_cnt;	/*!< iic scl count settings */
  	/* Variables which always change during iic operation */
  	uint32_t int_status;		/*!< iic interrupt status */
  	uint32_t iic_tx_over;		/*!< iic tx overflow count */
  	uint32_t iic_rx_over;		/*!< iic rx overflow count */
  	DW_IIC_BUFFER dw_iic_rxbuf;	/*!< iic read buffer for receive data */
  } DW_IIC_CTRL, *DW_IIC_CTRL_PTR;
  
  /*!< One possible value for \ref dw_iic_ctrl::retry_cnt */
  #define DW_IIC_MAX_RETRY_COUNT			(100000)
  
  #define DW_IIC_FS_SPKLEN_NS			(50)
  #define DW_IIC_HS_SPKLEN_NS			(10)
  
  #define MIN_DW_IIC_SS_SCL_LCNT(spklen)		((spklen)+7)
  #define MIN_DW_IIC_FS_SCL_LCNT(spklen)		((spklen)+7)
  
  #define MIN_DW_IIC_SS_SCL_HCNT(spklen)		((spklen)+5)
  #define MIN_DW_IIC_FS_SCL_HCNT(spklen)		((spklen)+5)
  
  #define MIN_DW_IIC_HS_SCL_LCNT(spklen)		((spklen)+7)
  #define MIN_DW_IIC_HS_SCL_HCNT(spklen)		((spklen)+5)
  
  #define MIN_DW_IIC_SS_HIGH_TIME_NS		(4000)
  #define MIN_DW_IIC_SS_LOW_TIME_NS		(4700)
  
  #define MIN_DW_IIC_FS_HIGH_TIME_NS		(600)
  #define MIN_DW_IIC_FS_LOW_TIME_NS		(1300)
  
  #define MIN_DW_IIC_HS_100PF_HIGH_TIME_NS	(60)
  #define MIN_DW_IIC_HS_100PF_LOW_TIME_NS		(160)
  
  #define MIN_DW_IIC_HS_400PF_HIGH_TIME_NS	(120)
  #define MIN_DW_IIC_HS_400PF_LOW_TIME_NS		(320)
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  extern int32_t dw_iic_open (DEV_IIC *iic_obj, uint32_t mode, uint32_t param);
  extern int32_t dw_iic_close (DEV_IIC *iic_obj);
  extern int32_t dw_iic_control (DEV_IIC *iic_obj, uint32_t ctrl_cmd, void *param);
  extern int32_t dw_iic_write (DEV_IIC *iic_obj, const void *data, uint32_t len);
  extern int32_t dw_iic_read (DEV_IIC *iic_obj, void *data, uint32_t len);
  extern void dw_iic_isr(DEV_IIC *iic_obj, void *ptr);
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif /* _DW_IIC_H_ */
  