Adding i2c and clock changes for audio framework
authorShivam Garg <garg.shivam@samsung.com>
Thu, 14 Sep 2017 08:02:20 +0000 (17:02 +0900)
committerShivam Garg <garg.shivam@samsung.com>
Mon, 18 Sep 2017 14:03:33 +0000 (23:03 +0900)
os/arch/arm/src/s5j/Make.defs
os/arch/arm/src/s5j/chip/s5jt200_cmu.h [new file with mode: 0644]
os/arch/arm/src/s5j/chip/s5jt200_i2c.h [new file with mode: 0644]
os/arch/arm/src/s5j/s5j_clock.c [new file with mode: 0644]
os/arch/arm/src/s5j/s5j_clock.h [new file with mode: 0644]
os/arch/arm/src/s5j/s5j_i2c.c
os/arch/arm/src/s5j/s5j_i2c.h

index 541635d..22360a5 100644 (file)
@@ -144,6 +144,8 @@ ifeq ($(CONFIG_S5J_I2C),y)
 CHIP_CSRCS += s5j_i2c.c
 endif
 
+CHIP_CSRCS += s5j_clock.c
+
 ifeq ($(CONFIG_S5J_MCT),y)
 CHIP_CSRCS += s5j_mct.c
 ifeq ($(CONFIG_TIMER),y)
diff --git a/os/arch/arm/src/s5j/chip/s5jt200_cmu.h b/os/arch/arm/src/s5j/chip/s5jt200_cmu.h
new file mode 100644 (file)
index 0000000..92c21e6
--- /dev/null
@@ -0,0 +1,455 @@
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * arch/arm/src/s5j/chip/s5j200_clock.h
+ *
+ *   Copyright (C) 2009-2010, 2014-2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 NuttX 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 OWNER 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 _ARCH_ARM_SRC_S5J_CHIP_S5JT200_CLOCK_H
+#define _ARCH_ARM_SRC_S5J_CHIP_S5JT200_CLOCK_H
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register Address *********************************************************/
+
+/* PLL control register (24 entries) */
+#define S5J_CMU_WPLL_CON0                                      0x80080000
+#define S5J_CMU_WPLL_CON1                                      0x80080004
+#define S5J_CMU_WPLL_CON2                                      0x80080008
+#define S5J_CMU_WPLL_CON3                                      0x8008000C
+#define S5J_CMU_WPLL_CON4                                      0x80080010
+#define S5J_CMU_WPLL_CON5                                      0x80080014
+#define S5J_CMU_WPLL_STAT                                      0x80080018
+#define S5J_CMU_PLL_CON0                                       0x80080180
+#define S5J_CMU_PLL_CON1                                       0x80080184
+#define S5J_CMU_PLL_CON2                                       0x80080188
+
+/* Miscellaneous functions */
+#define S5J_CMU_CMU_CON                                                0x80080800
+#define S5J_CMU_CLKOUT_CON                                     0x80080810
+#define S5J_CMU_MCU_SPARE0                                     0x80080a00
+#define S5J_CMU_MCU_SPARE1                                     0x80080a04
+
+/* MUX controls such as MUX selection, enable and status */
+#define S5J_CMU_MUX_I2SB                                       0x80081000
+#define S5J_CMU_MUX_UART                                       0x8008100c
+
+/* Clock divider controls such as divider ratio and status */
+#define S5J_CMU_DIV_SFLASH                                     0x80081800
+#define S5J_CMU_DIV_SPI0                                       0x80081804
+#define S5J_CMU_DIV_SPI1                                       0x80081808
+#define S5J_CMU_DIV_SPI2                                       0x8008180C
+#define S5J_CMU_DIV_SPI3                                       0x80081810
+#define S5J_CMU_DIV_WPLL_DIV12                         0x80081814
+#define S5J_CMU_DIV_WPLL_DIV3                          0x80081818
+#define S5J_CMU_DIV_WPLL_DIV6                          0x8008181C
+
+/* Clock gating controls such as clock gating of IPs and function blocks */
+#define S5J_CMU_GAT_WPLL_DIV12                         0x80082000
+#define S5J_CMU_GAT_ADC                                                0x80082004
+#define S5J_CMU_GAT_CM0P                                       0x80082008
+#define S5J_CMU_GAT_GPIOCON_CLK                                0x8008200c
+#define S5J_CMU_GAT_I2S_I2SBCLKI                       0x80082010
+#define S5J_CMU_GAT_MCT0                                       0x80082014
+#define S5J_CMU_GAT_CMU_PCLK                           0x80082018
+#define S5J_CMU_GAT_PWM0                                       0x8008201C
+#define S5J_CMU_GAT_PWM1                                       0x80082020
+#define S5J_CMU_GAT_SYSREG_CLK                         0x80082028
+#define S5J_CMU_GAT_CHIPID                                     0x80082034
+#define S5J_CMU_GAT_WDT                                                0x80082038
+#define S5J_CMU_GAT_ADC_PCLK                           0x8008203C
+#define S5J_CMU_GAT_AHB2AXI_CM0P_ACLK          0x80082040
+#define S5J_CMU_GAT_AHB2AXI_SDIO_ACLK          0x80082048
+#define S5J_CMU_GAT_APB_CSSYS_PCLKM                    0x80082048
+#define S5J_CMU_GAT_APB_CSSYS_PCLKS                    0x8008204C
+#define S5J_CMU_GAT_APB_PDMA_PCLKM                     0x80082050
+#define S5J_CMU_GAT_APB_PDMA_PCLKS                     0x80082054
+#define S5J_CMU_GAT_AXI2AHB_FLASH_ACLK         0x80082058
+#define S5J_CMU_GAT_AXI2AHB_SDIO_PCLK          0x8008205C
+#define S5J_CMU_GAT_PERIC_ACLK                         0x80082060
+#define S5J_CMU_GAT_PERIS0_ACLK                                0x80082064
+#define S5J_CMU_GAT_PERIS1_ACLK                                0x80082068
+#define S5J_CMU_GAT_CM0P_DCLK                          0x8008206C
+#define S5J_CMU_GAT_CM0P_HCLK                          0x80082070
+#define S5J_CMU_GAT_CM0P_SCLK                          0x80082074
+#define S5J_CMU_GAT_CSSYS_PCLKDBG                      0x80082078
+#define S5J_CMU_GAT_DS_64TO32_SDIO_ACLK                0x8008207C
+#define S5J_CMU_GAT_DS_64TO32_DP_ACLK          0x80082080
+#define S5J_CMU_GAT_DS_64TO32_FLASH_ACLK       0x80082084
+#define S5J_CMU_GAT_GIC400_INPUT                       0x80082088
+#define S5J_CMU_GAT_GIC400                                     0x8008208C
+#define S5J_CMU_GAT_HSI2C0                                     0x80082090
+#define S5J_CMU_GAT_HSI2C1                                     0x80082094
+#define S5J_CMU_GAT_HSI2C2                                     0x80082098
+#define S5J_CMU_GAT_HSI2C3                                     0x8008209C
+#define S5J_CMU_GAT_I2S_PCLK                           0x800820a0
+#define S5J_CMU_GAT_INTMEM_ACLK                                0x800820a4
+#define S5J_CMU_GAT_INTMEM_SHARED_ACLK         0x800820a8
+#define S5J_CMU_GAT_CR4_CLKIN                          0x800820ac
+#define S5J_CMU_GAT_CR4_FREECLKIN                      0x800820b0
+#define S5J_CMU_GAT_CR4_PCLKDBG                                0x800820b4
+#define S5J_CMU_GAT_LHM_AXI_D_WIFI_ICLK                0x800820b8
+#define S5J_CMU_GAT_LHM_DP_ICLK                                0x800820bc
+#define S5J_CMU_GAT_LHS_DP_ICLK                                0x800820c0
+#define S5J_CMU_GAT_MAILBOX_M0                         0x800820c4
+#define S5J_CMU_GAT_MAILBOX_WIFI                       0x800820c8
+#define S5J_CMU_GAT_MCT0_PCLK                          0x800820cc
+#define S5J_CMU_GAT_PDMA_ACLK                          0x800820d0
+#define S5J_CMU_GAT_PMU_PCLK                           0x800820d4
+#define S5J_CMU_GAT_PMU_PCLK_CSSYS                     0x800820d8
+#define S5J_CMU_GAT_PUF_SYSTEM_ICLK                    0x800820dc
+#define S5J_CMU_GAT_PWM0_PCLK                          0x800820e0
+#define S5J_CMU_GAT_PWM1_PCLK                          0x800820e4
+#define S5J_CMU_GAT_SDIO_DEVICE_CLK_AHB                0x800820f4
+#define S5J_CMU_GAT_SFLASH_HCLK                                0x800820f8
+#define S5J_CMU_GAT_SFLASH_SFCLK                       0x800820fc
+#define S5J_CMU_GAT_SFR_APBIF_GPIO_PCLK                0x80082100
+#define S5J_CMU_GAT_SPI0_PCLK                          0x80082104
+#define S5J_CMU_GAT_SPI0_EXTCLK                                0x80082108
+#define S5J_CMU_GAT_SPI1_PCLK                          0x8008210C
+#define S5J_CMU_GAT_SPI1_EXTCLK                                0x80082110
+#define S5J_CMU_GAT_SPI2_PCLK                          0x80082114
+#define S5J_CMU_GAT_SPI2_EXTCLK                                0x80082118
+#define S5J_CMU_GAT_SPI3_PCLK                          0x8008211c
+#define S5J_CMU_GAT_SPI3_EXTCLK                                0x80082120
+#define S5J_CMU_GAT_SWEEPER_WIFI_ACLK          0x80082124
+#define S5J_CMU_GAT_SYSREG_PCLK                                0x80082128
+#define S5J_CMU_GAT_TICKCNT_PCLK                       0x8008212C
+#define S5J_CMU_GAT_TOPRTC_PCLK                                0x80082130
+#define S5J_CMU_GAT_UART0_EXTCLK                       0x80082134
+#define S5J_CMU_GAT_UART0_PCLK                         0x80082138
+#define S5J_CMU_GAT_UART1_EXTCLK                       0x8008213C
+#define S5J_CMU_GAT_UART1_PCLK                         0x80082140
+#define S5J_CMU_GAT_UART2_EXTCLK                       0x80082144
+#define S5J_CMU_GAT_UART2_PCLK                         0x80082148
+#define S5J_CMU_GAT_UART3_EXTCLK                       0x8008214C
+#define S5J_CMU_GAT_UART3_PCLK                         0x80082150
+#define S5J_CMU_GAT_UARTDBG_EXTCLK                     0x80082154
+#define S5J_CMU_GAT_UARTDBG_PCLK                       0x80082158
+#define S5J_CMU_GAT_CHIPID_PCLK                                0x8008215C
+#define S5J_CMU_GAT_US_32TO64_CM0P_ACLK                0x80082160
+#define S5J_CMU_GAT_US_32TO64_PDMA_ACLK                0x80082164
+#define S5J_CMU_GAT_US_32TO64_SDIO_ACLK                0x80082168
+#define S5J_CMU_GAT_WDT_PCLK                           0x8008216C
+#define S5J_CMU_GAT_XIU_D_T20_ACLK                     0x80082174
+
+/* Q-Channel controls such as Q-channel enable and counter */
+#define S5J_CMU_DMYQCH_CON_CR4                         0x80083014
+#define S5J_CMU_DMYQCH_CON_XIU                         0x80083020
+#define S5J_CMU_QCH_CON_LHM_AXI                                0x80083024
+#define S5J_CMU_QCH_CON_LHM_DP                         0x80083028
+#define S5J_CMU_QCH_CON_LHS_DP                         0x8008302C
+#define S5J_CMU_QCH_CON_MCU                                    0x80083030
+
+/* Q-state controls */
+#define S5J_CMU_QUEUE_CTRL                                     0x80083C00
+
+/* Register Bitfield Definitions ********************************************/
+
+/* WPLL_CON0 ****************************************************************/
+#define CMU_WPLL_CON0_FREF_SEL                         (1 << 28)
+#define CMU_WPLL_CON0_EN                                       (1 << 22)
+#define CMU_WPLL_CON0_FREF_EN                          (1 << 21)
+#define CMU_WPLL_CON0_PFD_EN                           (1 << 20)
+#define CMU_WPLL_CON0_CP_EN                                    (1 << 19)
+#define CMU_WPLL_CON0_VCO_EN                           (1 << 18)
+#define CMU_WPLL_CON0_ABC_EN                           (1 << 17)
+#define CMU_WPLL_CON0_BGR_EN                           (1 << 16)
+#define CMU_WPLL_CON0_PFD_TRI                          (1 << 2)
+#define CMU_WPLL_CON0_CP0                                      (1 << 1)
+#define CMU_WPLL_CON0_PFD_TRI_EXT_SEL          (1 << 0)
+
+/* WPLL_CON1 ****************************************************************/
+#define CMU_WPLL_CON1_VCO_ED                           (1 << 30)
+#define CMU_WPLL_CON1_VCO_REF_EN                       (1 << 29)
+#define CMU_WPLL_CON1_REF_EXT_SEL                      (1 << 28)
+
+#define CMU_WPLL_CON1_VCO_REF_CTRL_SHIFT       27
+#define CMU_WPLL_CON1_VCO_REF_CTRL_MASK                (0x3 << CMU_WPLL_CON1_VCO_REF_CTRL_SHIFT)
+
+#define CMU_WPLL_CON1_ABC_START                                (1 << 26)
+
+#define CMU_WPLL_CON1_ABC_DIV_SHIFT                    8
+#define CMU_WPLL_CON1_ABC_DIV_MASK                     (0xff << CMU_WPLL_CON1_ABC_DIV_SHIFT)
+
+#define CMU_WPLL_CON1_ABC_FBIT_SHIFT           4
+#define CMU_WPLL_CON1_ABC_FBIT_MASK                    (0xf << CMU_WPLL_CON1_ABC_FBIT_SHIFT)
+
+#define CMU_WPLL_CON1_ABC_FBIT_SEL                     (1 << 0)
+
+/* WPLL_CON2 ****************************************************************/
+#define CMU_WPLL_CON2_BGR_SEL_SHIFT                    28
+#define CMU_WPLL_CON2_BGR_SEL_MASK                     (0x3 << CMU_WPLL_CON2_BGR_SEL_SHIFT)
+
+#define CMU_WPLL_CON2_BGR_CNT_SHIFT                    24
+#define CMU_WPLL_CON2_BGR_CNT_MASK                     (0xf << CMU_WPLL_CON2_BGR_CNT_SHIFT)
+
+#define CMU_WPLL_CON2_MMD_DIV_SHIFT                    16
+#define CMU_WPLL_CON2_MMD_DIV_MASK                     (0x3f << CMU_WPLL_CON2_MMD_DIV_SHIFT)
+
+#define CMU_WPLL_CON2_MMD_LOAD_SEL                     (1 << 8)
+
+#define CMU_WPLL_CON2_LF_SHIFT                         0
+#define CMU_WPLL_CON2_LF_MASK                          (0x1f << CMU_WPLL_CON2_LF_SHIFT)
+
+/* WPLL_CON3 ****************************************************************/
+#define CMU_WPLL_CON3_DSM_EN_SEL                       (1 << 29)
+#define CMU_WPLL_CON3_DSM_EN                           (1 << 28)
+
+#define CMU_WPLL_CON3_DSM_F_SHIFT                      0
+#define CMU_WPLL_CON3_DSM_F_MASK                       (0x7ffffff << CMU_WPLL_CON3_DSM_F_SHIFT)
+
+/* WPLL_CON4 ****************************************************************/
+#define CMU_WPLL_CON4_DSM_K_SHIFT                      0
+#define CMU_WPLL_CON4_DSM_K_MASK                       (0x7ffffff << CMU_WPLL_CON4_DSM_K_SHIFT)
+
+/* WPLL_CON5 ****************************************************************/
+#define CMU_WPLL_CON5_CLK_ADC_SEL_SHIFT                0
+#define CMU_WPLL_CON5_CLK_ADC_SEL_MASK         (0x7 << CMU_WPLL_CON5_CLK_ADC_SEL_SHIFT)
+
+#define CMU_WPLL_CON5_CLK320M_SEL                      (1 << 4)
+#define CMU_WPLL_CON5_CLK20M_SEL                       (1 << 5)
+
+#define CMU_WPLL_CON5_LOCK_TRY_SHIFT           8
+#define CMU_WPLL_CON5_LOCK_TRY_MASK                    (0xf << CMU_WPLL_CON5_LOCK_TRY_SHIFT)
+
+#define CMU_WPLL_CON5_LOCK_CNT_SHIFT           12
+#define CMU_WPLL_CON5_LOCK_CNT_MASK                    (0xf << CMU_WPLL_CON5_LOCK_CNT_SHIFT)
+
+#define CMU_WPLL_CON5_EN_CLK_ADC                       (1 << 16)
+#define CMU_WPLL_CON5_EN_CLK20M                                (1 << 17)
+#define CMU_WPLL_CON5_EN_CLK80M                                (1 << 18)
+#define CMU_WPLL_CON5_EN_CLK160M                       (1 << 19)
+#define CMU_WPLL_CON5_EN_CLK240M                       (1 << 20)
+#define CMU_WPLL_CON5_EN_CLK480M                       (1 << 21)
+#define CMU_WPLL_CON5_EN_CLK960M                       (1 << 22)
+#define CMU_WPLL_CON5_IGNORE_SYSREQ                    (1 << 24)
+
+#define CMU_WPLL_CON5_LOCK_MASK_SHIFT          25
+#define CMU_WPLL_CON5_LOCK_MASK_MASK           (0x7 << CMU_WPLL_CON5_LOCK_MASK_SHIFT)
+#define CMU_WPLL_CON5_LOCK_MASK_FBIT_STATUS    (0x0 << CMU_WPLL_CON5_LOCK_MASK_SHIFT)
+#define CMU_WPLL_CON5_LOCK_MASK_ABC_DONE       (0x1 << CMU_WPLL_CON5_LOCK_MASK_SHIFT)
+#define CMU_WPLL_CON5_LOCK_MASK_LOCK_CNT       (0x2 << CMU_WPLL_CON5_LOCK_MASK_SHIFT)
+
+#define CMU_WPLL_CON5_EN_CLK_DIV                       (1 << 28)
+
+/* WPLL_STAT ****************************************************************/
+#define CMU_WPLL_STAT_LOCK                                     (1 << 28)
+
+#define CMU_WPLL_STAT_HW_STATUS_SHIFT          25
+#define CMU_WPLL_STAT_HW_STATUS_MASK           (0x3 << CMU_WPLL_STAT_HW_STATUS_SHIFT)
+
+#define CMU_WPLL_STAT_HW_OVERRIDE                      (1 << 24)
+
+#define CMU_WPLL_STAT_FBIT_STATUS_SHIFT                16
+#define CMU_WPLL_STAT_FBIT_STATUS_MASK         (0xf << CMU_WPLL_STAT_FBIT_STATUS_SHIFT)
+
+#define CMU_WPLL_STAT_TEST_STATUS                      (1 << 8)
+#define CMU_WPLL_STAT_ABC_DONE                         (1 << 0)
+
+/* CON0_MUX *****************************************************************/
+#define CMU_CON0_MUX_BUSY                                      (1 << 7)
+
+#define CMU_CON0_MUX_SEL_SHIFT                         4
+#define CMU_CON0_MUX_SEL_MASK                          (1 << CMU_CON0_MUX_SEL_SHIFT)
+#define CMU_CON0_MUX_SEL_OSCCLK                                (0 << CMU_CON0_MUX_SEL_SHIFT)
+#define CMU_CON0_MUX_SEL_CLK960M                       (1 << CMU_CON0_MUX_SEL_SHIFT)
+
+/* CON1_MUX *****************************************************************/
+#define CMU_CON1_MUX_IGNORE_REQ_SYSCLK         (1 << 5)
+
+/* CON2_MUX *****************************************************************/
+#define CMU_CON2_MUX_OVERRIDE_BY_HCH           (1 << 30)
+#define CMU_CON2_MUX_AUTO_CLKGATING                    (1 << 28)
+
+/* CMU_CON ******************************************************************/
+#define CMU_CMU_CON_ENABLE_POWER_MANAGEMENT    (1 << 29)
+#define CMU_CMU_CON_AUTO_CLKGATING                     (1 << 28)
+
+/* CLKOUT_CON ***************************************************************/
+#define CMU_CLKOUT_CON_ENABLE                          (1 << 29)
+#define CMU_CLKOUT_CON_AUTO_CLKGATING          (1 << 28)
+#define CMU_CLKOUT_CON_VALIDATE_CLK_REQ                (1 << 20)
+#define CMU_CLKOUT_CON_BUSY                                    (1 << 16)
+
+#define CMU_CLKOUT_CON_SEL_SHIFT                       8
+#define CMU_CLKOUT_CON_SEL_MASK                                (0x1f << CMU_CLKOUT_CON_SEL_SHIFT)
+#define CMU_CLKOUT_CON_SEL_OSCCLK                      (0x0 << CMU_CLKOUT_CON_SEL_SHIFT)
+#define CMU_CLKOUT_CON_SEL_XIU_D_T20_ACLK      (0x1 << CMU_CLKOUT_CON_SEL_SHIFT)
+#define CMU_CLKOUT_CON_SEL_XIU_P_T20_ACLK      (0x2 << CMU_CLKOUT_CON_SEL_SHIFT)
+#define CMU_CLKOUT_CON_SEL_UART0_EXTCLK                (0x3 << CMU_CLKOUT_CON_SEL_SHIFT)
+#define CMU_CLKOUT_CON_SEL_UART1_EXTCLK                (0x4 << CMU_CLKOUT_CON_SEL_SHIFT)
+#define CMU_CLKOUT_CON_SEL_UART2_EXTCLK                (0x5 << CMU_CLKOUT_CON_SEL_SHIFT)
+#define CMU_CLKOUT_CON_SEL_UART3_EXTCLK                (0x6 << CMU_CLKOUT_CON_SEL_SHIFT)
+#define CMU_CLKOUT_CON_SEL_UARTDBG_EXTCLK      (0x7 << CMU_CLKOUT_CON_SEL_SHIFT)
+
+#define CMU_CLKOUT_CON_DIV_RATIO_SHIFT         0
+#define CMU_CLKOUT_CON_DIV_RATIO_MASK          (0xf << CMU_CLKOUT_CON_DIV_RATIO_SHIFT)
+
+/* MUX_I2SB *****************************************************************/
+#define CMU_MUX_I2SB_OVERRIDE_BY_HCH           (1 << 30)
+#define CMU_MUX_I2SB_AUTO_CLKGATING                    (1 << 28)
+#define CMU_MUX_I2SB_BUSY                                      (1 << 16)
+
+#define CMU_MUX_I2SB_SELECT_SHIFT                      0
+#define CMU_MUX_I2SB_SELECT_MASK                       (1 << CMU_MUX_I2SB_SELECT_SHIFT)
+#define CMU_MUX_I2SB_SELECT_OSCCLK                     (0 << CMU_MUX_I2SB_SELECT_SHIFT)
+#define CMU_MUX_I2SB_SELECT_PADCLK_I2S_BCLK    (1 << CMU_MUX_I2SB_SELECT_SHIFT)
+
+/* MUX_UART *****************************************************************/
+#define CMU_MUX_UART_OVERRIDE_BY_HCH           (1 << 30)
+#define CMU_MUX_UART_AUTO_CLKGATING                    (1 << 28)
+#define CMU_MUX_UART_BUSY                                      (1 << 16)
+
+#define CMU_MUX_UART_SELECT_SHIFT                      0
+#define CMU_MUX_UART_SELECT_MASK                       (1 << CMU_MUX_UART_SELECT_SHIFT)
+#define CMU_MUX_UART_SELECT_OSCCLK                     (0 << CMU_MUX_UART_SELECT_SHIFT)
+#define CMU_MUX_UART_SELECT_WPLL_DIV12         (1 << CMU_MUX_UART_SELECT_SHIFT)
+
+/* DIV_SFLASH ***************************************************************/
+#define CMU_DIV_SFLASH_OVERRIDE_BY_HCH         (1 << 30)
+#define CMU_DIV_SFLASH_AUTO_CLKGATING          (1 << 28)
+#define CMU_DIV_SFLASH_BUSY                                    (1 << 16)
+
+#define CMU_DIV_SFLASH_DIV_RATIO_SHIFT         0
+#define CMU_DIV_SFLASH_DIV_RATIO_MASK          (0xf << CMU_DIV_SFLASH_DIV_RATIO_SHIFT)
+
+/* DIV_SPI0 *****************************************************************/
+#define CMU_DIV_SPI0_OVERRIDE_BY_HCH           (1 << 30)
+#define CMU_DIV_SPI0_AUTO_CLKGATING                    (1 << 28)
+#define CMU_DIV_SPI0_BUSY                                      (1 << 16)
+
+#define CMU_DIV_SPI0_DIV_RATIO_SHIFT           0
+#define CMU_DIV_SPI0_DIV_RATIO_MASK                    (0x7ff << CMU_DIV_SPI0_DIV_RATIO_SHIFT)
+
+/* DIV_SPI1 *****************************************************************/
+#define CMU_DIV_SPI1_OVERRIDE_BY_HCH           (1 << 30)
+#define CMU_DIV_SPI1_AUTO_CLKGATING                    (1 << 28)
+#define CMU_DIV_SPI1_BUSY                                      (1 << 16)
+
+#define CMU_DIV_SPI1_DIV_RATIO_SHIFT           0
+#define CMU_DIV_SPI1_DIV_RATIO_MASK                    (0x7ff << CMU_DIV_SPI1_DIV_RATIO_SHIFT)
+
+/* DIV_SPI2 *****************************************************************/
+#define CMU_DIV_SPI2_OVERRIDE_BY_HCH           (1 << 30)
+#define CMU_DIV_SPI2_AUTO_CLKGATING                    (1 << 28)
+#define CMU_DIV_SPI2_BUSY                                      (1 << 16)
+
+#define CMU_DIV_SPI2_DIV_RATIO_SHIFT           0
+#define CMU_DIV_SPI2_DIV_RATIO_MASK                    (0x7ff << CMU_DIV_SPI2_DIV_RATIO_SHIFT)
+
+/* DIV_SPI3 *****************************************************************/
+#define CMU_DIV_SPI3_OVERRIDE_BY_HCH           (1 << 30)
+#define CMU_DIV_SPI3_AUTO_CLKGATING                    (1 << 28)
+#define CMU_DIV_SPI3_BUSY                                      (1 << 16)
+
+#define CMU_DIV_SPI3_DIV_RATIO_SHIFT           0
+#define CMU_DIV_SPI3_DIV_RATIO_MASK                    (0x7ff << CMU_DIV_SPI3_DIV_RATIO_SHIFT)
+
+/* DIV_WPLL_DIV12 ***********************************************************/
+#define CMU_DIV_WPLL_DIV12_OVERRIDE_BY_HCH     (1 << 30)
+#define CMU_DIV_WPLL_DIV12_AUTO_CLKGATING      (1 << 28)
+#define CMU_DIV_WPLL_DIV12_BUSY                                (1 << 16)
+
+#define CMU_DIV_WPLL_DIV12_RATIO_SHIFT         0
+#define CMU_DIV_WPLL_DIV12_RATIO_MASK          (0x7ff << CMU_DIV_WPLL_DIV12_RATIO_SHIFT)
+
+/* DIV_WPLL_DIV3 ************************************************************/
+#define CMU_DIV_WPLL_DIV3_OVERRIDE_BY_HCH      (1 << 30)
+#define CMU_DIV_WPLL_DIV3_AUTO_CLKGATING       (1 << 28)
+#define CMU_DIV_WPLL_DIV3_BUSY                         (1 << 16)
+
+#define CMU_DIV_WPLL_DIV3_RATIO_SHIFT          0
+#define CMU_DIV_WPLL_DIV3_RATIO_MASK           (0xf << CMU_DIV_WPLL_DIV3_RATIO_SHIFT)
+
+/* DIV_WPLL_DIV6 ************************************************************/
+#define CMU_DIV_WPLL_DIV6_OVERRIDE_BY_HCH      (1 << 30)
+#define CMU_DIV_WPLL_DIV6_AUTO_CLKGATING       (1 << 28)
+#define CMU_DIV_WPLL_DIV6_BUSY                         (1 << 16)
+
+#define CMU_DIV_WPLL_DIV6_RATIO_SHIFT          0
+#define CMU_DIV_WPLL_DIV6_RATIO_MASK           (0x1 << CMU_DIV_WPLL_DIV6_RATIO_SHIFT)
+
+/* Clock Gating Control/Status for Clock Nodes ******************************/
+#define CMU_GAT_MODE_SHIFT                                     20
+#define CMU_GAT_MODE_MASK                                      (1 << CMU_GAT_MODE_SHIFT)
+#define CMU_GAT_MODE_AUTO                                      (0 << CMU_GAT_MODE_SHIFT)
+#define CMU_GAT_MODE_MANUAL                                    (1 << CMU_GAT_MODE_SHIFT)
+
+#define CMU_GAT_CG_SHIFT                                       21
+#define CMU_GAT_CG_MASK                                                (1 << CMU_GAT_CG_SHIFT)
+#define CMU_GAT_CG_DISABLE                                     (0 << CMU_GAT_CG_SHIFT)
+#define CMU_GAT_CG_ENABLE                                      (1 << CMU_GAT_CG_SHIFT)
+
+/* PM Protocol Control/Status for ISO_CR4/QCH *******************************/
+#define CMU_DMYQCH_CON_CR4_CLOCK_REQ           (1 << 1)
+#define CMU_DMYQCH_CON_CR4_ENABLE                      (1 << 0)
+
+/* PM Protocol Control/Status for XIU_D_T20/QCH *****************************/
+#define CMU_DMYQCH_CON_XIU_CLOCK_REQ           (1 << 1)
+#define CMU_DMYQCH_CON_XIU_ENABLE                      (1 << 0)
+
+/* PM Protocol Control/Status for LHM_AXI_D_WIFI/QCH ************************/
+#define CMU_QCH_CON_LHM_AXI_CLOCK_REQ          (1 << 1)
+#define CMU_QCH_CON_LHM_AXI_ENABLE                     (1 << 0)
+
+/* PM Protocol Control/Status for LHM_DP/QCH ********************************/
+#define CMU_QCH_CON_LHM_DP_CLOCK_REQ           (1 << 1)
+#define CMU_QCH_CON_LHM_DP_ENABLE                      (1 << 0)
+
+/* PM Protocol Control/Status for LHS_DP/QCH ********************************/
+#define CMU_QCH_CON_LHS_DP_CLOCK_REQ           (1 << 1)
+#define CMU_QCH_CON_LHS_DP_ENABLE                      (1 << 0)
+
+/* PM Protocol Control/Status for MCU/QCH ***********************************/
+#define CMU_QCH_CON_MCU_CLOCK_REQ                      (1 << 1)
+#define CMU_QCH_CON_MCU_ENABLE                         (1 << 0)
+
+#endif                                                 /* _ARCH_ARM_SRC_S5J_CHIP_S5JT200_CLOCK_H */
diff --git a/os/arch/arm/src/s5j/chip/s5jt200_i2c.h b/os/arch/arm/src/s5j/chip/s5jt200_i2c.h
new file mode 100644 (file)
index 0000000..f42486c
--- /dev/null
@@ -0,0 +1,136 @@
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * arch/arm/src/s5j/chip/s5j200_i2c.h
+ *
+ *   Copyright (C) 2009-2010, 2014-2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 NuttX 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 OWNER 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 __ARCH_ARM_SRC_S5J_CHIP_S5JT200_I2C_H
+#define __ARCH_ARM_SRC_S5J_CHIP_S5JT200_I2C_H
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Register Offset **********************************************************/
+#define S5J_I2C_CTL                                    0x0000
+#define S5J_I2C_TRAILING_CTL           0x0008
+#define S5J_I2C_INT_EN                         0x0020
+#define S5J_I2C_INT_STAT                       0x0024
+#define S5J_I2C_FIFO_STAT                      0x0030
+#define S5J_I2C_TXDATA                         0x0034
+#define S5J_I2C_RXDATA                         0x0038
+#define S5J_I2C_CONF                           0x0040
+#define S5J_I2C_AUTO_CONF                      0x0044
+#define S5J_I2C_TIMEOUT                                0x0048
+#define S5J_I2C_MANUAL_CMD                     0x004C
+#define S5J_I2C_TRANS_STATUS           0x0050
+#define S5J_I2C_TIMING_HS1                     0x0054
+#define S5J_I2C_TIMING_HS2                     0x0058
+#define S5J_I2C_TIMING_HS3                     0x005C
+#define S5J_I2C_TIMING_FS1                     0x0060
+#define S5J_I2C_TIMING_FS2                     0x0064
+#define S5J_I2C_TIMING_FS3                     0x0068
+#define S5J_I2C_TIMING_SLA                     0x006C
+#define S5J_I2C_ADDR                           0x0070
+
+/* Register Bitfield Definitions ********************************************/
+
+/* I2C_CTL register */
+#define I2C_CTL_RESET_VALUE                                            0x0
+#define I2C_CTL_CS_ENB                                                 (1 << 0)
+#define I2C_CTL_MASTER                                                 (1 << 3)
+#define I2C_CTL_RXCHON                                                 (1 << 6)
+#define I2C_CTL_TXCHON                                                 (1 << 7)
+#define I2C_CTL_SW_RST                                                 (1 << 31)
+
+/* I2C_INT_EN & I2C_INT_STAT register */
+#define I2C_INT_TX_ALMOSTEMPTY_EN                              (1 << 0)
+#define I2C_INT_RX_ALMOSTFULL_EN                               (1 << 1)
+#define I2C_INT_TX_UNDERRUN_EN                                 (1 << 2)
+#define I2C_INT_RX_OVERRUN_EN                                  (1 << 5)
+#define I2C_INT_TRANSFER_DONE_AUTO_EN                  (1 << 7)
+#define I2C_INT_TRANSFER_DONE_NOACK_MANUAL_EN  (1 << 12)
+#define I2C_INT_TRANSFER_DONE_MANUAL_EN                        (1 << 13)
+#define I2C_INT_SLAVE_ADDR_MATCH_EN                            (1 << 15)
+#define I2C_INT_ALL                                                            0xFFFF
+
+/* I2C_CONF register */
+#define I2C_CONF_HS_MODE                                               (1 << 29)
+#define I2C_CONF_ADDRMODE                                              (1 << 30)
+#define I2C_CONF_AUTO_MODE                                             (1 << 31)
+
+/* I2C_AUTO_CONF register */
+#define I2C_AUTO_CONF_TRANS_LEN_ALL                            0xFFFF
+#define I2C_AUTO_CONF_READ_WRITE                               (1 << 16)
+#define I2C_AUTO_CONF_STOP_AFTER_TRANS                 (1 << 17)
+#define I2C_AUTO_CONF_MASTER_RUN                               (1 << 31)
+
+/* I2C_MANUAL_CMD register */
+#define I2C_MANUAL_CMD_SEND_START                              (1 << 0)
+#define I2C_MANUAL_CMD_SEND_RESTART                            (1 << 1)
+#define I2C_MANUAL_CMD_SEND_STOP                               (1 << 2)
+#define I2C_MANUAL_CMD_SEND_DATA                               (1 << 3)
+#define I2C_MANUAL_CMD_READ_DATA                               (1 << 4)
+#define I2C_MANUAL_CMD_RX_ACK                                  (1 << 5)
+#define I2C_MANUAL_CMD_TX_DATA(x)                              ((x & 0xFF) << 24)
+
+/* I2C_TIMING_HS & I2C_TIMING_FS & I2C_TIMING_SLA register */
+#define I2C_TIMING_TSTOP_SU(x)                                 ((x & 0xFF) << 8)
+#define I2C_TIMING_TSTART_HD(x)                                        ((x & 0xFF) << 16)
+#define I2C_TIMING_TSTART_SU(x)                                        ((x & 0xFF) << 24)
+#define I2C_TIMING_TSCL_H(x)                                   ((x & 0xFF) << 0)
+#define I2C_TIMING_TSCL_L(x)                                   ((x & 0xFF) << 8)
+#define I2C_TIMING_TDATA_SU(x)                                 ((x & 0xFF) << 24)
+#define I2C_TIMING_TSR_RELEASE(x)                              ((x & 0xFF) << 0)
+#define I2C_TIMING_CLK_DIV(x)                                  ((x & 0xFF) << 16)
+#define I2C_TIMING_TDATA_HD_SLA(x)                             ((x & 0xFFFF) << 0)
+
+/* I2C_ADDR register */
+#define I2C_ADDR_SLAVE_ADDR_SLA(x)                             ((x & 0x3FF) << 0)
+
+#endif                                                 /* __ARCH_ARM_SRC_S5J_CHIP_S5JT200_I2C_H */
diff --git a/os/arch/arm/src/s5j/s5j_clock.c b/os/arch/arm/src/s5j/s5j_clock.c
new file mode 100644 (file)
index 0000000..90680a7
--- /dev/null
@@ -0,0 +1,340 @@
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * arch/arm/src/s5j/s5j_clock.c
+ *
+ *   Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 NuttX 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 OWNER 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.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+#include <tinyara/config.h>
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <assert.h>
+
+#include <chip.h>
+
+#include "s5j_clock.h"
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+#define FIXED_RATE_OSCCLK_MCU          26000000
+#define FIXED_RATE_WPLL_CLK240M                240000000
+#define FIXED_RATE_WPLL_CLK480M                480000000
+#define FIXED_RATE_WPLL_CLK960M                960000000
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+static struct clk_div *get_clk_div(enum clk_divider_id id)
+{
+       struct mcu_clk *cmu = (struct mcu_clk *)S5J_CMU_BASE;
+
+       return &cmu->dividers[id];
+}
+
+static int clk_div_get_ratio(enum clk_divider_id id)
+{
+       struct clk_div *clkdiv = get_clk_div(id);
+
+       return clkdiv->divratio + 1;
+}
+
+static void clk_div_set_ratio(enum clk_divider_id id, unsigned long divratio)
+{
+       struct clk_div *clkdiv = get_clk_div(id);
+
+       clkdiv->divratio = divratio - 1;
+}
+
+static struct clk_mux *get_clk_mux(enum clk_mux_id id)
+{
+       struct mcu_clk *cmu = (struct mcu_clk *)S5J_CMU_BASE;
+
+       return &cmu->muxes[id];
+}
+
+static unsigned long clk_wpll_get_rate(enum clk_id id)
+{
+       unsigned long sclk, div;
+       struct mcu_clk *cmu = (struct mcu_clk *)S5J_CMU_BASE;
+
+       if (cmu->pll_con0.mux_sel) {
+               sclk = FIXED_RATE_WPLL_CLK960M;
+       } else {
+               sclk = FIXED_RATE_OSCCLK_MCU;
+       }
+
+       div = 1;
+
+       switch (id) {
+       case CLK_WPLL_DIV12:
+               div = clk_div_get_ratio(CLK_DIV_WPLL_DIV12);
+       /* fall through */
+       case CLK_WPLL_DIV6:
+               div = div * clk_div_get_ratio(CLK_DIV_WPLL_DIV6);
+       /* fall through */
+       case CLK_WPLL_DIV3:
+               div = div * clk_div_get_ratio(CLK_DIV_WPLL_DIV3);
+               break;
+       default:
+               break;
+       }
+
+       return sclk / div;
+}
+
+static unsigned long clk_sflash_get_rate(void)
+{
+       unsigned long sclk, div;
+
+       sclk = clk_wpll_get_rate(CLK_WPLL_DIV3);
+       div = clk_div_get_ratio(CLK_DIV_SFLASH);
+
+       return sclk / div;
+}
+
+static unsigned long clk_uart_get_rate(void)
+{
+       struct clk_mux *mux = get_clk_mux(CLK_MUX_UART);
+
+       if (mux->select == CLK_MUX_SELECT_OSCCLK) {
+               return FIXED_RATE_OSCCLK_MCU;
+       }
+
+       return clk_wpll_get_rate(CLK_WPLL_DIV12);
+}
+
+static unsigned long clk_spi_get_rate(unsigned int id)
+{
+       unsigned long sclk, div;
+
+       sclk = clk_wpll_get_rate(CLK_WPLL_DIV12);
+
+       switch (id) {
+       case CLK_SPL_SPI0:
+               div = clk_div_get_ratio(CLK_DIV_SPI0);
+               break;
+       case CLK_SPL_SPI1:
+               div = clk_div_get_ratio(CLK_DIV_SPI1);
+               break;
+       case CLK_SPL_SPI2:
+               div = clk_div_get_ratio(CLK_DIV_SPI2);
+               break;
+       case CLK_SPL_SPI3:
+               div = clk_div_get_ratio(CLK_DIV_SPI3);
+               break;
+       }
+
+       return sclk / div;
+}
+
+static unsigned long clk_i2sb_get_rate(void)
+{
+       struct clk_mux *mux = get_clk_mux(CLK_MUX_I2SB);
+
+       ASSERT(mux->select == CLK_MUX_SELECT_OSCCLK);
+
+       return FIXED_RATE_OSCCLK_MCU;
+}
+
+unsigned long s5j_clk_get_rate(unsigned int id);
+
+static void clk_sflash_set_rate(unsigned long rate)
+{
+       unsigned long div = s5j_clk_get_rate(CLK_WPLL_DIV3) / rate;
+
+       clk_div_set_ratio(CLK_DIV_SFLASH, div);
+}
+
+static void clk_spi_set_rate(unsigned int id, unsigned long rate)
+{
+       unsigned long div = s5j_clk_get_rate(CLK_WPLL_DIV12) / rate;
+
+       switch (id) {
+       case CLK_SPL_SPI0:
+               clk_div_set_ratio(CLK_DIV_SPI0, div);
+               break;
+       case CLK_SPL_SPI1:
+               clk_div_set_ratio(CLK_DIV_SPI1, div);
+               break;
+       case CLK_SPL_SPI2:
+               clk_div_set_ratio(CLK_DIV_SPI2, div);
+               break;
+       case CLK_SPL_SPI3:
+               clk_div_set_ratio(CLK_DIV_SPI3, div);
+               break;
+       }
+}
+
+void s5j_clk_set_rate(unsigned int id, unsigned long rate)
+{
+       switch (id) {
+       case CLK_SPL_SFLASH:
+               clk_sflash_set_rate(rate);
+               break;
+
+       case CLK_SPL_SPI0:
+       case CLK_SPL_SPI1:
+       case CLK_SPL_SPI2:
+       case CLK_SPL_SPI3:
+               clk_spi_set_rate(id, rate);
+               break;
+
+       default:
+               /* Not supported */
+               ASSERT(0);
+               break;
+       }
+}
+
+unsigned long s5j_clk_get_rate(unsigned int id)
+{
+       unsigned long rate = 0;
+
+       switch (id) {
+       case CLK_DFT_OSCCLK:
+       case CLK_DFT_OSCCLK_SSS:
+               rate = FIXED_RATE_OSCCLK_MCU;
+               break;
+
+       case CLK_WPLL_DIV3:
+       case CLK_WPLL_DIV6:
+       case CLK_WPLL_DIV12:
+               rate = clk_wpll_get_rate(id);
+               break;
+
+       case CLK_SPL_SFLASH:
+               rate = clk_sflash_get_rate();
+               break;
+
+       case CLK_SPL_UART:
+               rate = clk_uart_get_rate();
+               break;
+
+       case CLK_SPL_SPI0:
+       case CLK_SPL_SPI1:
+       case CLK_SPL_SPI2:
+       case CLK_SPL_SPI3:
+               rate = clk_spi_get_rate(id);
+               break;
+
+       case CLK_SPL_I2SB:
+               rate = clk_i2sb_get_rate();
+               break;
+
+       case CLK_SPL_BUS_D0:
+       case CLK_SPL_BUS_D0_SSS:
+               rate = clk_wpll_get_rate(CLK_WPLL_DIV3);
+               break;
+
+       case CLK_SPL_BUS_P0:
+       case CLK_SPL_BUS_P0_SSS:
+               rate = clk_wpll_get_rate(CLK_WPLL_DIV6);
+               break;
+       }
+
+       return rate;
+}
+
+int s5j_clk_mux_select(enum clk_mux_id mux_id, enum clk_mux_source src)
+{
+       struct clk_mux *mux = get_clk_mux(mux_id);
+
+       mux->select = src;
+
+       return src;
+}
+
+void s5j_clk_enable(enum clk_gate_id id)
+{
+       struct mcu_clk *cmu = (struct mcu_clk *)S5J_CMU_BASE;
+
+       cmu->gates[id].cg = 1;
+       cmu->gates[id].mode = 1;
+}
+
+void s5j_clk_disable(enum clk_gate_id id)
+{
+       struct mcu_clk *cmu = (struct mcu_clk *)S5J_CMU_BASE;
+
+       cmu->gates[id].cg = 0;
+       cmu->gates[id].mode = 1;
+}
+
+void s5j_clk_pll_select_mux(bool clk960m)
+{
+       struct mcu_clk *cmu = (struct mcu_clk *)S5J_CMU_BASE;
+
+       cmu->pll_con0.mux_sel = clk960m;
+}
+
+int s5j_clkinit(void)
+{
+       /* Clock gating on CM0 */
+       s5j_clk_disable(CLK_GATE_CM0P);
+       s5j_clk_disable(CLK_GATE_AHB2AXI_CM0P);
+       s5j_clk_disable(CLK_GATE_CM0P_DCLK);
+       s5j_clk_disable(CLK_GATE_CM0P_HCLK);
+       s5j_clk_disable(CLK_GATE_CM0P_SCLK);
+
+       /* actually, we never use SDIO and it is not working. */
+       s5j_clk_disable(CLK_GATE_AHB2AXI_SDIO);
+       s5j_clk_disable(CLK_GATE_AXI2AHB_SDIO);
+       s5j_clk_disable(CLK_GATE_64TO32_SDIO);
+       s5j_clk_disable(CLK_GATE_SDIO_ACLK);
+       s5j_clk_disable(CLK_GATE_32TO64_SDIO);
+
+       /* we do not use the tickcounter also. */
+       s5j_clk_disable(CLK_GATE_TICKCNT_PCLK);
+
+       return 0;
+}
diff --git a/os/arch/arm/src/s5j/s5j_clock.h b/os/arch/arm/src/s5j/s5j_clock.h
new file mode 100644 (file)
index 0000000..d1d3d35
--- /dev/null
@@ -0,0 +1,323 @@
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * arch/arm/src/s5j/s5j_clock.h
+ *
+ *   Copyright (C) 2009-2010, 2014-2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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 NuttX 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 OWNER 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 _ARCH_ARM_SRC_S5J_S5J_CLOCK_H
+#define _ARCH_ARM_SRC_S5J_S5J_CLOCK_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+#include <tinyara/config.h>
+
+#include "up_arch.h"
+#include "chip/s5jt200_cmu.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* multiplexer */
+struct clk_mux {
+       unsigned int select: 1;
+       unsigned int res0: 15;
+       unsigned int busy: 1;
+       unsigned int res1: 11;
+       unsigned int enable_automatic_clkgating: 1;
+       unsigned int res2: 1;
+       unsigned int override_by_hch: 1;
+       unsigned int res3: 1;
+};
+
+/* clock divider */
+struct clk_div {
+       unsigned int divratio: 16;
+       unsigned int busy: 1;
+       unsigned int res0: 11;
+       unsigned int enable_automatic_clkgating: 1;
+       unsigned int res1: 1;
+       unsigned int override_by_hch: 1;
+       unsigned int res2: 1;
+};
+
+/* clock gating control register */
+struct clk_gate {
+       unsigned int res0: 20;
+       unsigned int mode: 1;
+       unsigned int cg: 1;
+       unsigned int res1: 6;
+       unsigned int enable_automatic_clkgating: 1;
+       unsigned int res2: 3;
+};
+
+enum clk_mux_source {
+       CLK_MUX_SELECT_OSCCLK = 0,
+       CLK_MUX_SELECT_BCLK = 1,
+       CLK_MUX_SELECT_WPLL_DIV12 = 1,
+};
+
+enum clk_mux_id {
+       CLK_MUX_I2SB,
+       CLK_MUX_RESERVED0,
+       CLK_MUX_RESERVED1,
+       CLK_MUX_UART,
+       CLK_MUX_MAX,
+};
+
+enum clk_divider_id {
+       CLK_DIV_SFLASH,
+       CLK_DIV_SPI0,
+       CLK_DIV_SPI1,
+       CLK_DIV_SPI2,
+       CLK_DIV_SPI3,
+       CLK_DIV_WPLL_DIV12,
+       CLK_DIV_WPLL_DIV3,
+       CLK_DIV_WPLL_DIV6,
+       CLK_DIV_MAX,
+};
+
+enum clk_gate_id {
+       CLK_GATE_WPLL_DIV12,
+       CLK_GATE_ADC,
+       CLK_GATE_CM0P,
+       CLK_GATE_GPIOCON,
+       CLK_GATE_I2S,
+       CLK_GATE_MCT0,
+       CLK_GATE_CMU,
+       CLK_GATE_PWM0,
+       CLK_GATE_PWM1,
+       CLK_GATE_RESERVED0,
+       CLK_GATE_SYSREG,
+       CLK_GATE_RESERVED1,
+       CLK_GATE_RESERVED2,
+       CLK_GATE_EFUSE,
+       CLK_GATE_WDT,
+       CLK_GATE_ADC_PCLK,
+       CLK_GATE_AHB2AXI_CM0P,
+       CLK_GATE_AHB2AXI_SDIO,
+       CLK_GATE_CSSYS_PCLKM,
+       CLK_GATE_CSSYS_PCLKS,
+       CLK_GATE_PDMA_PCLKM,
+       CLK_GATE_PDMA_PCLKS,
+       CLK_GATE_AXI2AHB_FLASH,
+       CLK_GATE_AXI2AHB_SDIO,
+       CLK_GATE_AXI2APB_PERIC,
+       CLK_GATE_AXI2APB_PERIS0,
+       CLK_GATE_AXI2APB_PERIS1,
+       CLK_GATE_CM0P_DCLK,
+       CLK_GATE_CM0P_HCLK,
+       CLK_GATE_CM0P_SCLK,
+       CLK_GATE_CSSYS_PCLKDBG,
+       CLK_GATE_64TO32_SDIO,
+       CLK_GATE_64TO32_DP,
+       CLK_GATE_64TO32_FLASH,
+       CLK_GATE_GIC400_INPUT,
+       CLK_GATE_GIC400,
+       CLK_GATE_HSI2C0,
+       CLK_GATE_HSI2C1,
+       CLK_GATE_HSI2C2,
+       CLK_GATE_HSI2C3,
+       CLK_GATE_I2S_PCLK,
+       CLK_GATE_INTMEM,
+       CLK_GATE_INTMEM_SHARED,
+       CLK_GATE_CR4_CLKIN,
+       CLK_GATE_CR4_FCLKIN,
+       CLK_GATE_CR4_PCLKDBG,
+       CLK_GATE_LHM_AXI,
+       CLK_GATE_LHM_DP,
+       CLK_GATE_LHS_DP,
+       CLK_GATE_MAILBOX_M0,
+       CLK_GATE_MAILBOX_WIFI,
+       CLK_GATE_MCT0_PCLK,
+       CLK_GATE_MCT0_ACLK,
+       CLK_GATE_PMU_PCLK,
+       CLK_GATE_PMU_PCLK_CSSYS,
+       CLK_GATE_PUF,
+       CLK_GATE_PWM0_PCLK,
+       CLK_GATE_PWM1_PCLK,
+       CLK_GATE_RESERVED3,
+       CLK_GATE_RESERVED4,
+       CLK_GATE_RESERVED5,
+       CLK_GATE_SDIO_ACLK,
+       CLK_GATE_SFLASH_HCLK,
+       CLK_GATE_SFLASH_SFCLK,
+       CLK_GATE_GPIO_PCLK,
+       CLK_GATE_SPI0_PCLK,
+       CLK_GATE_SPI0_EXTCLK,
+       CLK_GATE_SPI1_PCLK,
+       CLK_GATE_SPI1_EXTCLK,
+       CLK_GATE_SPI2_PCLK,
+       CLK_GATE_SPI2_EXTCLK,
+       CLK_GATE_SPI3_PCLK,
+       CLK_GATE_SPI3_EXTCLK,
+       CLK_GATE_WIFI_ACLK,
+       CLK_GATE_SYSREG_PCLK,
+       CLK_GATE_TICKCNT_PCLK,
+       CLK_GATE_RTC_PCLK,
+       CLK_GATE_UART0_EXTCLK,
+       CLK_GATE_UART0_PCLK,
+       CLK_GATE_UART1_EXTCLK,
+       CLK_GATE_UART1_PCLK,
+       CLK_GATE_UART2_EXTCLK,
+       CLK_GATE_UART2_PCLK,
+       CLK_GATE_UART3_EXTCLK,
+       CLK_GATE_UART3_PCLK,
+       CLK_GATE_UARTDBG_EXTCLK,
+       CLK_GATE_UARTDBG_PCLK,
+       CLK_GATE_EFUSE_PCLK,
+       CLK_GATE_32TO64_CM0P,
+       CLK_GATE_32TO64_PDMA,
+       CLK_GATE_32TO64_SDIO,
+       CLK_GATE_WDT_PCLK,
+       CLK_GATE_RESERVED6,
+       CLK_GATE_XIU,
+       CLK_GATE_MAX,
+};
+
+enum clk_id {
+       CLK_DFT_OSCCLK,
+       CLK_DFT_OSCCLK_SSS,
+       CLK_WPLL_DIV3,
+       CLK_WPLL_DIV6,
+       CLK_WPLL_DIV12,
+       CLK_SPL_SPI0,
+       CLK_SPL_SPI1,
+       CLK_SPL_SPI2,
+       CLK_SPL_SPI3,
+       CLK_SPL_UART,
+       CLK_SPL_I2SB,
+       CLK_SPL_SFLASH,
+       CLK_SPL_BUS_D0,
+       CLK_SPL_BUS_D0_SSS,
+       CLK_SPL_BUS_P0,
+       CLK_SPL_BUS_P0_SSS,
+};
+
+/* Q-Channel control register */
+struct clk_qch {
+       unsigned int res0: 6;
+       unsigned int expire_val: 10;
+       unsigned int res1: 14;
+       unsigned int clock_req: 1;
+       unsigned int enable: 1;
+};
+
+/* Clock management unit - MCU part */
+struct mcu_clk {
+       /* PLL control register */
+       unsigned int wpll_con0;
+       unsigned int wpll_con1;
+       unsigned int wpll_con2;
+       unsigned int wpll_con3;
+       unsigned int wpll_con4;
+       unsigned int wpll_con5;
+       unsigned int wpll_stat;
+       unsigned char res0[0x0164];
+
+       struct {
+               unsigned int res0: 4;
+               unsigned int mux_sel: 1;
+               unsigned int res1: 2;
+               unsigned int busy: 1;
+               unsigned int res2: 24;
+       } pll_con0;
+
+       struct {
+               unsigned int res0: 5;
+               unsigned int ignore_req_sysclk: 1;
+               unsigned int res1: 26;
+       } pll_con1;
+
+       struct {
+               unsigned int res0: 28;
+               unsigned int enable_automatic_clkgating: 1;
+               unsigned int res1: 1;
+               unsigned int override_by_hch: 1;
+               unsigned int res2: 1;
+       } pll_con2;
+
+       unsigned char res1[0x674];
+
+       /* Miscellaneous functions */
+       unsigned int cmu_con;
+       unsigned char res2[0xc];
+       unsigned int clkout_con;
+       unsigned char res3[0x1ec];
+       unsigned int spare0;
+       unsigned int spare1;
+       unsigned char res4[0x5f8];
+
+       /* MUX controls such as MUX selection, enable and status */
+       struct clk_mux muxes[CLK_MUX_MAX];
+       unsigned char res5[0x7f0];
+
+       /* Clock divider controls such as divider ratio and status */
+       struct clk_div dividers[CLK_DIV_MAX];
+       unsigned char res6[0x7e0];
+
+       /* Clock gating controls such as clock gating of IPs and function blocks */
+       struct clk_gate gates[CLK_GATE_MAX];
+       unsigned char res7[0xe9c];
+
+       /* Q-Channel controls such as Q-channel enable and counter */
+       unsigned int qch_con_cr4;
+       unsigned char res8[0x8];
+       unsigned int qch_con_t20;
+       unsigned int qch_con_wifi;
+       unsigned int qch_con_lhm_dp;
+       unsigned int qch_con_lhs_dp;
+       unsigned int qch_con_cmu;
+       unsigned char res9[0xbcc];
+
+       /* Q-state controls */
+       unsigned int queue_ctrl;
+};
+#endif                                                 /* _ARCH_ARM_SRC_S5J_S5J_CLOCK_H */
index 7b926fb..2221fe0 100644 (file)
 
 #include <sys/types.h>
 #include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
 #include <semaphore.h>
 #include <errno.h>
 #include <assert.h>
 #include <debug.h>
-
 #include <tinyara/arch.h>
-#include <tinyara/irq.h>
 #include <tinyara/i2c.h>
-#include <tinyara/clock.h>
-
-#include <arch/serial.h>
 #include <arch/board/board.h>
 
 #include "up_arch.h"
 #include "s5j_gpio.h"
 #include "s5j_i2c.h"
-#include "s5j_vclk.h"
+#include "s5j_clock.h"
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+
 #define S5J_DEFAULT_I2CXFER_CLOCK      (100 * 1000)    /* 100Khz */
 #define S5J_DEFAULT_I2CSLAVE_ADDR      0x22
 #define S5J_DEFAULT_I2C_TIMEOUT                10000
-
-#define HSI2C_INT_XFER_DONE (HSI2C_INT_XFER_DONE_NOACK_MANUAL | HSI2C_INT_XFER_DONE_MANUAL)
+#define S5J_DEFAULT_HS_CLOCK           400000  /* 400Khz */
 
 /****************************************************************************
  * Private Types
  ****************************************************************************/
+
 struct s5j_i2c_priv_s *g_s5j_i2c_priv[4] = { NULL };
 
+/* I2C Device hardware configuration */
+struct s5j_i2c_config_s {
+       uintptr_t base;                         /* I2C base address */
+       unsigned int scl_pin;           /* GPIO configuration for SCL as SCL */
+       unsigned int sda_pin;           /* GPIO configuration for SDA as SDA */
+};
+
+/* I2C Device Private Data */
+struct s5j_i2c_priv_s {
+       const struct i2c_ops_s *ops;    /* Standard I2C operations */
+       const struct s5j_i2c_config_s *config;  /* Port configuration */
+       sem_t sem_excl;                         /* Mutual exclusion semaphore */
+#ifndef CONFIG_I2C_POLLED
+       sem_t sem_isr;                          /* Interrupt wait semaphore */
+#endif
+       uint8_t refs;                           /* Reference count */
+
+       int clock;
+       int xfer_speed;
+       unsigned int slave_addr;
+       unsigned int timeout;
+
+       unsigned int initialized;
+       unsigned int retries;
+       /*  master data  */
+       uint8_t msgc;                           /* Message count */
+       struct i2c_msg_s *msgv;         /* Message list */
+       uint8_t *ptr;                           /* Current message buffer */
+       int mcnt;                                       /* Current message length */
+       uint16_t mflags;                        /* Current message flags */
+
+       struct i2c_msg_s *msg;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void hsi2c_set_hs_timing(struct s5j_i2c_priv_s *priv, unsigned int nClkDiv, unsigned int tSTART_SU, unsigned int tSTART_HD, unsigned int tSTOP_SU, unsigned int tDATA_SU, unsigned int tDATA_HD, unsigned int tSCL_L, unsigned int tSCL_H, unsigned int tSR_RELEASE);
+static void hsi2c_set_fs_timing(struct s5j_i2c_priv_s *priv, unsigned int nClkDiv, unsigned int tSTART_SU, unsigned int tSTART_HD, unsigned int tSTOP_SU, unsigned int tDATA_SU, unsigned int tDATA_HD, unsigned int tSCL_L, unsigned int tSCL_H, unsigned int tSR_RELEASE);
+static void hsi2c_calculate_timing(struct s5j_i2c_priv_s *priv, unsigned int nOpClk);
+static void hsi2c_conf(struct s5j_i2c_priv_s *priv, unsigned int nOpClk);
+static void hsi2c_enable_int(struct s5j_i2c_priv_s *priv, unsigned int bit);
+static void hsi2c_set_slave_addr(struct s5j_i2c_priv_s *priv, u16 addr);
+static int hsi2c_manual_fast_init(struct s5j_i2c_priv_s *priv);
+static int hsi2c_wait_xfer_done(struct s5j_i2c_priv_s *priv);
+static int hsi2c_wait_xfer_noack(struct s5j_i2c_priv_s *priv);
+static void hsi2c_start(struct s5j_i2c_priv_s *priv);
+static void hsi2c_stop(struct s5j_i2c_priv_s *priv);
+static void hsi2c_repstart(struct s5j_i2c_priv_s *priv);
+static int hsi2c_outb(struct s5j_i2c_priv_s *priv, u8 data);
+static int hsi2c_inb(struct s5j_i2c_priv_s *priv, bool is_ack);
+static int sendbytes(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg);
+static int readbytes(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg);
+static int try_address(struct s5j_i2c_priv_s *priv, u8 addr, int retries);
+static int do_address(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg);
+static int hsi2c_setup(struct s5j_i2c_priv_s *priv);
+static int hsi2c_cleanup(struct s5j_i2c_priv_s *priv);
+static inline void s5j_i2c_sem_wait(struct s5j_i2c_priv_s *priv);
+static inline void s5j_i2c_sem_post(struct s5j_i2c_priv_s *priv);
+static inline void s5j_i2c_sem_init(struct s5j_i2c_priv_s *priv);
+static inline void s5j_i2c_sem_destroy(struct s5j_i2c_priv_s *priv);
+static int s5j_i2c_initialize(struct s5j_i2c_priv_s *priv);
+static int s5j_i2c_uninitialize(struct s5j_i2c_priv_s *priv);
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
@@ -105,7 +163,7 @@ struct s5j_i2c_priv_s *g_s5j_i2c_priv[4] = { NULL };
 /* I2C Interface */
 static const struct i2c_ops_s s5j_i2c_ops = {
        .setfrequency = s5j_i2c_setclock,
-       .setaddress = s5j_i2c_setownaddress,
+       .setaddress = s5j_i2c_setaddress,
        .write = s5j_i2c_write,
        .read = s5j_i2c_read,
 #ifdef CONFIG_I2C_TRANSFER
@@ -121,19 +179,12 @@ static const struct s5j_i2c_config_s s5j_i2c0_config = {
        .base = S5J_HSI2C0_BASE,
        .scl_pin = GPIO_I2C0_SCL,
        .sda_pin = GPIO_I2C0_SDA,
-       .isr = s5j_i2c0_interrupt,
-       .irq = IRQ_HSI2C_0,
-       .devno = 0,
 };
 
 static struct s5j_i2c_priv_s s5j_i2c0_priv = {
        .xfer_speed = S5J_DEFAULT_I2CXFER_CLOCK,
-       .master = I2C_MASTER,
-       .mode = I2C_POLLING,
        .slave_addr = S5J_DEFAULT_I2CSLAVE_ADDR,
-       .addrlen = 7,
        .timeout = S5J_DEFAULT_I2C_TIMEOUT,
-       .name = "s5j_i2c0",
        .initialized = 0,
        .retries = 3,
 };
@@ -142,19 +193,12 @@ static const struct s5j_i2c_config_s s5j_i2c1_config = {
        .base = S5J_HSI2C1_BASE,
        .scl_pin = GPIO_I2C1_SCL,
        .sda_pin = GPIO_I2C1_SDA,
-       .isr = s5j_i2c1_interrupt,
-       .irq = IRQ_HSI2C_1,
-       .devno = 1,
 };
 
 static struct s5j_i2c_priv_s s5j_i2c1_priv = {
        .xfer_speed = S5J_DEFAULT_I2CXFER_CLOCK,
-       .master = I2C_MASTER,
-       .mode = I2C_POLLING,
        .slave_addr = S5J_DEFAULT_I2CSLAVE_ADDR,
-       .addrlen = 7,
        .timeout = S5J_DEFAULT_I2C_TIMEOUT,
-       .name = "s5j_i2c1",
        .initialized = 0,
        .retries = 3,
 };
@@ -163,19 +207,12 @@ static const struct s5j_i2c_config_s s5j_i2c2_config = {
        .base = S5J_HSI2C2_BASE,
        .scl_pin = GPIO_I2C2_SCL,
        .sda_pin = GPIO_I2C2_SDA,
-       .isr = s5j_i2c2_interrupt,
-       .irq = IRQ_HSI2C_2,
-       .devno = 2,
 };
 
 static struct s5j_i2c_priv_s s5j_i2c2_priv = {
        .xfer_speed = S5J_DEFAULT_I2CXFER_CLOCK,
-       .master = I2C_MASTER,
-       .mode = I2C_POLLING,
        .slave_addr = S5J_DEFAULT_I2CSLAVE_ADDR,
-       .addrlen = 7,
        .timeout = S5J_DEFAULT_I2C_TIMEOUT,
-       .name = "s5j_i2c2",
        .initialized = 0,
        .retries = 3,
 };
@@ -184,19 +221,12 @@ static const struct s5j_i2c_config_s s5j_i2c3_config = {
        .base = S5J_HSI2C3_BASE,
        .scl_pin = GPIO_I2C3_SCL,
        .sda_pin = GPIO_I2C3_SDA,
-       .isr = s5j_i2c3_interrupt,
-       .irq = IRQ_HSI2C_3,
-       .devno = 3,
 };
 
 static struct s5j_i2c_priv_s s5j_i2c3_priv = {
        .xfer_speed = S5J_DEFAULT_I2CXFER_CLOCK,
-       .master = I2C_MASTER,
-       .mode = I2C_POLLING,
        .slave_addr = S5J_DEFAULT_I2CSLAVE_ADDR,
-       .addrlen = 7,
        .timeout = S5J_DEFAULT_I2C_TIMEOUT,
-       .name = "s5j_i2c3",
        .initialized = 0,
        .retries = 3,
 };
@@ -204,81 +234,62 @@ static struct s5j_i2c_priv_s s5j_i2c3_priv = {
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
-static void hsi2c_set_hs_timing(unsigned int base, unsigned int nClkDiv,
-                               unsigned int tSTART_SU, unsigned int tSTART_HD,
-                               unsigned int tSTOP_SU, unsigned int tSDA_SU,
-                               unsigned int tDATA_SU, unsigned int tDATA_HD,
-                               unsigned int tSCL_L, unsigned int tSCL_H,
-                               unsigned int tSR_RELEASE)
+static uint32_t i2c_getreg32(struct s5j_i2c_priv_s *priv, int offset)
 {
-       tSTART_SU &= 0xFF;
-       tSTART_HD &= 0xFF;
-       tSTOP_SU &= 0xFF;
-       putreg32(((tSTART_SU << 24) | (tSTART_HD << 16) | (tSTOP_SU << 8)), base + I2C_TIMING_HS1);
+       return getreg32(priv->config->base + offset);
+}
 
-       tDATA_SU &= 0xFF;
-       tSCL_L &= 0xFF;
-       tSCL_H &= 0xFF;
-       putreg32(((tDATA_SU << 24) | (tSCL_L << 8) | (tSCL_H << 0)), base + I2C_TIMING_HS2);
+static void i2c_putreg32(struct s5j_i2c_priv_s *priv, int offset, uint32_t value)
+{
+       putreg32(value, priv->config->base + offset);
+}
+
+static void hsi2c_set_hs_timing(struct s5j_i2c_priv_s *priv, unsigned int nClkDiv, unsigned int tSTART_SU, unsigned int tSTART_HD, unsigned int tSTOP_SU, unsigned int tDATA_SU, unsigned int tDATA_HD, unsigned int tSCL_L, unsigned int tSCL_H, unsigned int tSR_RELEASE)
+{
+       i2c_putreg32(priv, S5J_I2C_TIMING_HS1, I2C_TIMING_TSTART_SU(tSTART_SU) | I2C_TIMING_TSTART_HD(tSTART_HD) | I2C_TIMING_TSTOP_SU(tSTOP_SU));
 
-       nClkDiv &= 0xFF;
-       tSR_RELEASE &= 0xFF;
-       putreg32(((nClkDiv << 16) | (tSR_RELEASE << 0)), base + I2C_TIMING_HS3);
+       i2c_putreg32(priv, S5J_I2C_TIMING_HS2, I2C_TIMING_TDATA_SU(tDATA_SU) | I2C_TIMING_TSCL_L(tSCL_L) | I2C_TIMING_TSCL_H(tSCL_H));
 
-       tDATA_HD &= 0xFFFF;
-       putreg32(tDATA_HD, base + I2C_TIMING_SLA);
+       i2c_putreg32(priv, S5J_I2C_TIMING_HS3, I2C_TIMING_CLK_DIV(nClkDiv) | I2C_TIMING_TSR_RELEASE(tSR_RELEASE));
 
+       i2c_putreg32(priv, S5J_I2C_TIMING_SLA, I2C_TIMING_TDATA_HD_SLA(tDATA_HD));
 }
 
-static void hsi2c_set_fs_timing(unsigned int base, unsigned int nClkDiv,
-                               unsigned int tSTART_SU, unsigned int tSTART_HD,
-                               unsigned int tSTOP_SU, unsigned int tDATA_SU,
-                               unsigned int tDATA_HD, unsigned int tSCL_L,
-                               unsigned int tSCL_H, unsigned int tSR_RELEASE)
+static void hsi2c_set_fs_timing(struct s5j_i2c_priv_s *priv, unsigned int nClkDiv, unsigned int tSTART_SU, unsigned int tSTART_HD, unsigned int tSTOP_SU, unsigned int tDATA_SU, unsigned int tDATA_HD, unsigned int tSCL_L, unsigned int tSCL_H, unsigned int tSR_RELEASE)
 {
-       tSTART_SU &= 0xFF;
-       tSTART_HD &= 0xFF;
-       tSTOP_SU &= 0xFF;
-       putreg32(((tSTART_SU << 24) | (tSTART_HD << 16) | (tSTOP_SU << 8)), base + I2C_TIMING_FS1);
-
-       tDATA_SU &= 0xFF;
-       tSCL_L &= 0xFF;
-       tSCL_H &= 0xFF;
-       putreg32(((tDATA_SU << 24) | (tSCL_L << 8) | (tSCL_H << 0)), base + I2C_TIMING_FS2);
-
-       nClkDiv &= 0xFF;
-       tSR_RELEASE &= 0xFF;
-       putreg32(((nClkDiv << 16) | (tSR_RELEASE << 0)), base + I2C_TIMING_FS3);
-
-       tDATA_HD &= 0xFFFF;
-       putreg32(tDATA_HD, base + I2C_TIMING_SLA);
+       i2c_putreg32(priv, S5J_I2C_TIMING_FS1, I2C_TIMING_TSTART_SU(tSTART_SU) | I2C_TIMING_TSTART_HD(tSTART_HD) | I2C_TIMING_TSTOP_SU(tSTOP_SU));
+
+       i2c_putreg32(priv, S5J_I2C_TIMING_FS2, I2C_TIMING_TDATA_SU(tDATA_SU) | I2C_TIMING_TSCL_L(tSCL_L) | I2C_TIMING_TSCL_H(tSCL_H));
+
+       i2c_putreg32(priv, S5J_I2C_TIMING_FS3, I2C_TIMING_CLK_DIV(nClkDiv) | I2C_TIMING_TSR_RELEASE(tSR_RELEASE));
+
+       i2c_putreg32(priv, S5J_I2C_TIMING_SLA, I2C_TIMING_TDATA_HD_SLA(tDATA_HD));
 }
 
-static void hsi2c_calculate_timing(unsigned int base, unsigned int nPclk,
-                               unsigned int nOpClk)
+static void hsi2c_calculate_timing(struct s5j_i2c_priv_s *priv, unsigned int nOpClk)
 {
        unsigned int reg;
        unsigned int nClkDiv;
        unsigned int tFTL_CYCLE_SCL;
        s32 i;
-       s32 uTemp0;
+       float uTemp0;
        s32 uTemp1;
        s32 uTemp2 = 0;
 
-       reg = getreg32(base + I2C_CONF);
+       reg = i2c_getreg32(priv, S5J_I2C_CONF);
        reg &= ~(0x7 << 13);
-       putreg32(reg, base + I2C_CONF);
+       i2c_putreg32(priv, S5J_I2C_CONF, reg);
 
-       reg = getreg32(base + I2C_CONF);
+       reg = i2c_getreg32(priv, S5J_I2C_CONF);
        reg &= ~(0x7 << 16);
-       putreg32(reg, base + I2C_CONF);
+       i2c_putreg32(priv, S5J_I2C_CONF, reg);
 
-       tFTL_CYCLE_SCL = getreg32((base + I2C_CONF) >> 16) & 0x7;
+       tFTL_CYCLE_SCL = (i2c_getreg32(priv, S5J_I2C_CONF) >> 16) & 0x7;
 
-       uTemp0 = (float)(nPclk / nOpClk) - (tFTL_CYCLE_SCL + 3) * 2;
+       uTemp0 = (priv->clock / nOpClk) - (tFTL_CYCLE_SCL + 3) * 2;
 
        for (i = 0; i < 256; i++) {
-               uTemp1 = (uTemp0 + ((tFTL_CYCLE_SCL + 3) % (i + 1)) * 2) / (i + 1);
+               uTemp1 = ((int)uTemp0 + ((tFTL_CYCLE_SCL + 3) % (i + 1)) * 2) / (i + 1);
                if (uTemp1 < 512) {             /*  TSCL_L/H max is 512 / 2 */
                        uTemp2 = uTemp1 - 2;
                        break;
@@ -287,7 +298,7 @@ static void hsi2c_calculate_timing(unsigned int base, unsigned int nPclk,
 
        unsigned int tSCL_H;
        nClkDiv = i;
-       if (nOpClk > I2C_SPEED_400KHZ) {
+       if (nOpClk > S5J_DEFAULT_HS_CLOCK) {
                tSCL_H = ((uTemp2 + 10) / 3) - 5;
        } else {
                tSCL_H = uTemp2 / 2;
@@ -297,113 +308,79 @@ static void hsi2c_calculate_timing(unsigned int base, unsigned int nPclk,
        unsigned int tSTART_SU = tSCL_L;
        unsigned int tSTART_HD = tSCL_L;
        unsigned int tSTOP_SU = tSCL_L;
-       unsigned int tSDA_SU = tSCL_L;
        unsigned int tDATA_SU = tSCL_L;
        unsigned int tDATA_HD = tSCL_L / 2;
        unsigned int tSR_RELEASE = uTemp2;
 
-       if (nOpClk > I2C_SPEED_400KHZ) {
+       if (nOpClk > S5J_DEFAULT_HS_CLOCK) {
                /* 400Khz setting for Extended ID */
-               hsi2c_set_fs_timing(base, 1, 38, 38, 38, 19, 19, 38, 38, 76);
-               hsi2c_set_hs_timing(base, nClkDiv, tSTART_SU, tSTART_HD, tSTOP_SU,
-                                       tSDA_SU, tDATA_SU, tDATA_HD, tSCL_L, tSCL_H, tSR_RELEASE);
+               hsi2c_set_fs_timing(priv, 1, 38, 38, 38, 19, 19, 38, 38, 76);
+               hsi2c_set_hs_timing(priv, nClkDiv, tSTART_SU, tSTART_HD, tSTOP_SU, tDATA_SU, tDATA_HD, tSCL_L, tSCL_H, tSR_RELEASE);
        } else {
-               hsi2c_set_fs_timing(base, nClkDiv, tSTART_SU, tSTART_HD, tSTOP_SU,
-                                       tDATA_SU, tDATA_HD, tSCL_L, tSCL_H, tSR_RELEASE);
+               hsi2c_set_fs_timing(priv, nClkDiv, tSTART_SU, tSTART_HD, tSTOP_SU, tDATA_SU, tDATA_HD, tSCL_L, tSCL_H, tSR_RELEASE);
        }
 }
 
-static void hsi2c_conf(unsigned int base, unsigned int nOpClk)
+static void hsi2c_conf(struct s5j_i2c_priv_s *priv, unsigned int nOpClk)
 {
        unsigned int val;
 
-       val = getreg32(base + I2C_CONF);
-       val &= ~(3 << 30);
-       if (nOpClk > I2C_SPEED_400KHZ) {
-               val |= (1 << 29);
+       val = i2c_getreg32(priv, S5J_I2C_CONF);
+       val &= ~(I2C_CONF_ADDRMODE | I2C_CONF_AUTO_MODE);
+
+       if (nOpClk > S5J_DEFAULT_HS_CLOCK) {
+               val |= I2C_CONF_HS_MODE;
        } else {
-               val &= ~(1 << 29);
+               val &= ~I2C_CONF_HS_MODE;
        }
-       putreg32(val, base + I2C_CONF);
-}
 
-static void hsi2c_enable_int(unsigned int base, unsigned int bit)
-{
-       unsigned int val;
-       val = getreg32(base + INT_EN);
-       val |= bit;
-       putreg32(val, base + INT_EN);
+       i2c_putreg32(priv, S5J_I2C_CONF, val);
 }
 
-static void hsi2c_disable_int(unsigned int base, unsigned int bit)
+static void hsi2c_enable_int(struct s5j_i2c_priv_s *priv, unsigned int bit)
 {
        unsigned int val;
 
-       val = getreg32(base + INT_EN);
-       val &= ~bit;
-       putreg32(val, base + INT_EN);
-}
+       val = i2c_getreg32(priv, S5J_I2C_INT_EN);
+       val |= bit;
 
-static void hsi2c_clear_int(unsigned int base, unsigned int bit)
-{
-       putreg32(bit, base + INT_STAT);
+       i2c_putreg32(priv, S5J_I2C_INT_EN, val);
 }
 
-static unsigned int hsi2c_read_int_status(unsigned int base)
+static void hsi2c_set_slave_addr(struct s5j_i2c_priv_s *priv, u16 addr)
 {
-       return getreg32(base + INT_STAT) & getreg32(base + INT_EN);
-}
-
-static void hsi2c_set_slave_addr(unsigned int base, u16 addr,
-                               unsigned int is_master)
-{
-       unsigned int val;
-
-       addr &= 0x3FF;
-
-       val = getreg32(base + I2C_ADDR);
-
-       if (is_master == 0) {
-               val &= ~0x3ff;
-               val |= addr;
-       } else {
-               val &= ~(0x3FF << 10);
-               val |= (addr << 10);
-       }
-       putreg32(val, base + I2C_ADDR);
+       i2c_putreg32(priv, S5J_I2C_ADDR, I2C_ADDR_SLAVE_ADDR_SLA(addr));
 }
 
 static int hsi2c_manual_fast_init(struct s5j_i2c_priv_s *priv)
 {
        unsigned int val;
-       unsigned int base = priv->config->base;
 
-       hsi2c_conf(base, priv->xfer_speed);
-       hsi2c_calculate_timing(base, priv->clock, priv->xfer_speed);
-       hsi2c_enable_int(base, HSI2C_INT_XFER_DONE_MANUAL | HSI2C_INT_XFER_DONE_NOACK_MANUAL);
+       hsi2c_conf(priv, priv->xfer_speed);
+       hsi2c_calculate_timing(priv, priv->xfer_speed);
+       hsi2c_enable_int(priv, I2C_INT_TRANSFER_DONE_MANUAL_EN | I2C_INT_TRANSFER_DONE_NOACK_MANUAL_EN);
 
        priv->initialized = 1;
 
-       val = getreg32(base + I2C_CONF);
-       val &= ~((1 << 31) | (1 << 29));
-       putreg32(val, base + I2C_CONF);
+       val = i2c_getreg32(priv, S5J_I2C_CONF);
+       val &= ~(I2C_CONF_AUTO_MODE | I2C_CONF_HS_MODE);
+       i2c_putreg32(priv, S5J_I2C_CONF, val);
 
-       hsi2c_enable_int(base, HSI2C_INT_XFER_DONE);
+       hsi2c_enable_int(priv, I2C_INT_TRANSFER_DONE_NOACK_MANUAL_EN | I2C_INT_TRANSFER_DONE_MANUAL_EN);
 
-       return 0;
+       return OK;
 }
 
 static int hsi2c_wait_xfer_done(struct s5j_i2c_priv_s *priv)
 {
        int val;
        int timeout = priv->timeout;
-       unsigned int base = priv->config->base;
 
        while (timeout-- > 0) {
-               val = getreg32(base + INT_STAT) & HSI2C_INT_XFER_DONE_MANUAL;
+               val = i2c_getreg32(priv, S5J_I2C_INT_STAT) & I2C_INT_TRANSFER_DONE_MANUAL_EN;
                if (val) {
-                       putreg32(val, base + INT_STAT);
-                       return (val == HSI2C_INT_XFER_DONE_MANUAL);
+                       i2c_putreg32(priv, S5J_I2C_INT_STAT, val);
+                       return (val == I2C_INT_TRANSFER_DONE_MANUAL_EN);
                }
        }
 
@@ -414,13 +391,12 @@ static int hsi2c_wait_xfer_noack(struct s5j_i2c_priv_s *priv)
 {
        int val;
        int timeout = priv->timeout;
-       unsigned int base = priv->config->base;
 
        while (timeout-- > 0) {
-               val = getreg32(base + INT_STAT) & HSI2C_INT_XFER_DONE_NOACK_MANUAL;
+               val = i2c_getreg32(priv, S5J_I2C_INT_STAT) & I2C_INT_TRANSFER_DONE_NOACK_MANUAL_EN;
                if (val) {
-                       putreg32(val, base + INT_STAT);
-                       return (val == HSI2C_INT_XFER_DONE_NOACK_MANUAL);
+                       i2c_putreg32(priv, S5J_I2C_INT_STAT, val);
+                       return (val == I2C_INT_TRANSFER_DONE_NOACK_MANUAL_EN);
                }
        }
 
@@ -429,25 +405,23 @@ static int hsi2c_wait_xfer_noack(struct s5j_i2c_priv_s *priv)
 
 static void hsi2c_start(struct s5j_i2c_priv_s *priv)
 {
-       int debug_msg;
-
-       putreg32(0x88, priv->config->base + CTL);
+       i2c_putreg32(priv, S5J_I2C_CTL, I2C_CTL_MASTER | I2C_CTL_TXCHON);       /* 0x88 */
 
-       putreg32(I2C_START, priv->config->base + I2C_MANUAL_CMD);
+       i2c_putreg32(priv, S5J_I2C_MANUAL_CMD, I2C_MANUAL_CMD_SEND_START);
 
-       debug_msg = hsi2c_wait_xfer_done(priv);
+       hsi2c_wait_xfer_done(priv);
 }
 
 static void hsi2c_stop(struct s5j_i2c_priv_s *priv)
 {
-       putreg32(I2C_STOP, priv->config->base + I2C_MANUAL_CMD);
+       i2c_putreg32(priv, S5J_I2C_MANUAL_CMD, I2C_MANUAL_CMD_SEND_STOP);
 
        hsi2c_wait_xfer_done(priv);
 }
 
 static void hsi2c_repstart(struct s5j_i2c_priv_s *priv)
 {
-       putreg32(I2C_RESTART, priv->config->base + I2C_MANUAL_CMD);
+       i2c_putreg32(priv, S5J_I2C_MANUAL_CMD, I2C_MANUAL_CMD_SEND_RESTART);
 }
 
 static int hsi2c_outb(struct s5j_i2c_priv_s *priv, u8 data)
@@ -455,8 +429,8 @@ static int hsi2c_outb(struct s5j_i2c_priv_s *priv, u8 data)
        unsigned int val;
        int ret;
 
-       val = ((unsigned int)data) << 24 | I2C_SEND_DATA;
-       putreg32(val, priv->config->base + I2C_MANUAL_CMD);
+       val = I2C_MANUAL_CMD_TX_DATA(data) | I2C_MANUAL_CMD_SEND_DATA;
+       i2c_putreg32(priv, S5J_I2C_MANUAL_CMD, val);
 
        ret = hsi2c_wait_xfer_done(priv);
 
@@ -465,23 +439,22 @@ static int hsi2c_outb(struct s5j_i2c_priv_s *priv, u8 data)
 
 static int hsi2c_inb(struct s5j_i2c_priv_s *priv, bool is_ack)
 {
-       unsigned int val = I2C_READ_DATA;
+       unsigned int val = I2C_MANUAL_CMD_READ_DATA;
        u8 data;
        int ret;
-       unsigned int base = priv->config->base;
 
-       /* Looks awkward, but if I2C_RX_ACK is set, ACK is NOT generated */
+       /* Looks awkward, but if I2C_MANUAL_CMD_RX_ACK is set, ACK is NOT generated */
        if (!is_ack) {
-               val |= I2C_RX_ACK;
+               val |= I2C_MANUAL_CMD_RX_ACK;
        }
-       putreg32(val, base + I2C_MANUAL_CMD);
+       i2c_putreg32(priv, S5J_I2C_MANUAL_CMD, val);
 
        ret = hsi2c_wait_xfer_done(priv);
        if (ret < 0) {
-               return ret; /* timeout */
+               return ret;                             /* timeout */
        }
 
-       data = (getreg32(base + I2C_MANUAL_CMD) >> 16) & 0xff;
+       data = (i2c_getreg32(priv, S5J_I2C_MANUAL_CMD) >> 16) & 0xFF;
 
        return data;
 }
@@ -569,7 +542,7 @@ static int do_address(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg)
                }
 
                /* the remaining 8 bit address */
-               ret = hsi2c_outb(priv, msg->addr & 0xff);
+               ret = hsi2c_outb(priv, msg->addr);
                if ((ret != 1) && !nak_ok) {
                        return -ENXIO;
                }
@@ -596,435 +569,68 @@ static int do_address(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg)
                }
        }
 
-       return 0;
-}
-
-static void hsi2c_run_auto_mode(unsigned int base, int on)
-{
-       unsigned int val = getreg32(base + I2C_AUTO_CONF);
-
-       if (on) {
-               val |= (1 << 31);
-       } else {
-               val &= ~(1 << 31);
-       }
-
-       putreg32(val, base + I2C_AUTO_CONF);
-}
-
-static void hsi2c_tx_fifo_reset(unsigned int base, int resetb)
-{
-       unsigned int val = getreg32(base + FIFO_CTL);
-
-       if (resetb) {
-               val |= (1 << 3);
-       } else {
-               val &= ~(1 << 3);
-       }
-
-       putreg32(val, base + FIFO_CTL);
-}
-
-static void hsi2c_set_auto_config(unsigned int base, unsigned int stop,
-                               unsigned int tx, unsigned int len)
-{
-       unsigned int val = getreg32(base + I2C_AUTO_CONF);
-
-       if (stop) {
-               val |= (1 << 17);
-       } else {
-               val &= ~(1 << 17);
-       }
-       if (tx) {
-               val &= ~(1 << 16);
-       } else {
-               val |= (1 << 16);
-       }
-
-       val &= ~0xFFFF;
-       val |= len;
-       putreg32(val, base + I2C_AUTO_CONF);
-}
-
-static void hsi2c_set_trans_mode(unsigned int base, unsigned int master,
-                               unsigned int tx)
-{
-       unsigned int val = getreg32(base + CTL);
-
-       val |= (1 << 0); /* ctrl 0 bit write 1 */
-
-       if (master) {
-               val |= (1 << 3);
-       } else {
-               val &= ~(1 << 3);
-       }
-
-       val &= ~(3 << 6);
-       if (tx) {
-               val |= (1 << 7);
-       } else {
-               val |= (1 << 6);
-       }
-
-       putreg32(val, base + CTL);
-}
-
-static void hsi2c_set_hwacg_mode(unsigned int base, unsigned int slave)
-{
-       unsigned int val = getreg32(base + CTL);
-
-       val &= ~(0x3 << 24);
-
-       if (slave) {
-               val |= (0x1 << 24);
-       } else {
-               val &= ~(0x1 << 24);
-       }
-
-       putreg32(val, base + CTL);
-}
-
-static int hsi2c_master_handler(void *args)
-{
-       struct s5j_i2c_priv_s *priv = args;
-       unsigned int int_status;
-       int off = priv->master_test_data->cur_msg, buf_off = priv->master_test_data->buf_count;
-       int trans_count = priv->master_test_data->num;
-       struct i2c_msg_s *msg = &priv->master_test_data->msg[off];
-       unsigned int base = priv->config->base;
-
-       int_status = hsi2c_read_int_status(base);
-       if (int_status & HSI2C_INT_TX_ALMOST_EMPTY) {
-               if (buf_off < msg->length) {
-                       putreg32(msg->buffer[buf_off], base + TXDATA);
-                       priv->master_test_data->buf_count++;
-               } else {
-                       hsi2c_disable_int(base, HSI2C_INT_TX_ALMOST_EMPTY);
-               }
-               hsi2c_clear_int(base, HSI2C_INT_TX_ALMOST_EMPTY);
-       }
-       if (int_status & HSI2C_INT_RX_ALMOST_FULL) {
-               msg->buffer[buf_off] = (u8)getreg32(base + RXDATA);
-               priv->master_test_data->buf_count++;
-               hsi2c_clear_int(base, HSI2C_INT_RX_ALMOST_FULL);
-       }
-       if (int_status & HSI2C_INT_TRANSFER_DONE_AUTO) {
-               if ((off + 1) == trans_count) {
-                       /* complete(&priv->master_test_data->done); ?? */
-               } else {
-                       off = ++priv->master_test_data->cur_msg;
-                       priv->master_test_data->buf_count = 0;
-                       msg++;
-
-                       if ((off + 1) == trans_count) {
-                               if (msg->flags & I2C_M_READ) {
-                                       hsi2c_set_auto_config(base, 1, 0, msg->length);
-                               } else {
-                                       hsi2c_set_auto_config(base, 1, 1, msg->length);
-                               }
-                       } else {
-                               if (msg->flags & I2C_M_READ) {
-                                       hsi2c_set_auto_config(base, 0, 0, msg->length);
-                               } else {
-                                       hsi2c_set_auto_config(base, 0, 1, msg->length);
-                               }
-                       }
-
-                       if (msg->flags & I2C_M_READ) {
-                               hsi2c_set_trans_mode(base, 1, 0);
-                       } else {
-                               hsi2c_set_trans_mode(base, 1, 1);
-                       }
-
-                       hsi2c_run_auto_mode(base, 1);
-
-               }
-               hsi2c_clear_int(base, HSI2C_INT_TRANSFER_DONE_AUTO);
-       }
-
-       return 0;
-}
-
-static int hsi2c_slave_handler(void *args)
-{
-       struct s5j_i2c_priv_s *priv = args;
-       unsigned int int_status;
-       unsigned int val;
-       unsigned int base = priv->config->base;
-
-       int_status = hsi2c_read_int_status(base);
-       if (int_status & HSI2C_INT_SLAVE_ADDR_MATCH) {
-               val = getreg32(base + I2C_TRANS_STATUS);
-               if (val & SLAVE_TX_MODE) {
-                       priv->slave_test_data->status = SLAVE_SET_DATA;
-                       hsi2c_enable_int(base, HSI2C_INT_TX_ALMOST_EMPTY);
-               } else {
-                       priv->slave_test_data->status = SLAVE_GET_REG;
-               }
-
-               hsi2c_clear_int(base, HSI2C_INT_SLAVE_ADDR_MATCH);
-       } else if (int_status & HSI2C_INT_RX_ALMOST_FULL) {
-               if (priv->slave_test_data->status == SLAVE_GET_REG) {
-                       priv->slave_test_data->current_reg = getreg32(base + RXDATA);
-                       priv->slave_test_data->status = SLAVE_GET_DATA;
-               } else if (priv->slave_test_data->status == SLAVE_GET_DATA) {
-                       priv->slave_test_data->data[priv->slave_test_data->current_reg] = getreg32(base + RXDATA);
-                       priv->slave_test_data->current_reg++;
-               }
-               hsi2c_clear_int(base, HSI2C_INT_RX_ALMOST_FULL);
-       } else if (int_status & HSI2C_INT_TX_ALMOST_EMPTY) {
-               if (getreg32(base + I2C_TRANS_STATUS) & STOP_COND) {
-                       hsi2c_disable_int(base, HSI2C_INT_TX_ALMOST_EMPTY);
-               } else {
-                       if (priv->slave_test_data->status == SLAVE_SET_DATA) {
-                               putreg32(priv->slave_test_data->data[priv->slave_test_data->current_reg], base + TXDATA);
-                               priv->slave_test_data->current_reg++;
-                       }
-               }
-               hsi2c_clear_int(base, HSI2C_INT_TX_ALMOST_EMPTY);
-       }
-       if (int_status & HSI2C_INT_RX_OVERRUN) {
-               /* for Rx_overrun test */
-               hsi2c_clear_int(base, HSI2C_INT_RX_OVERRUN);
-       }
-       if (int_status & HSI2C_INT_TX_UNDERRUN) {
-               /* for Tx_underrun test */
-               hsi2c_clear_int(base, HSI2C_INT_RX_OVERRUN);
-       }
-
-       return 0;
-}
-
-static void hsi2c_set_auto_mode(unsigned int base)
-{
-       unsigned int val;
-
-       val = getreg32(base + I2C_CONF);
-       val |= (1 << 31);
-       putreg32(val, base + I2C_CONF);
-}
-
-static void hsi2c_set_fifo_level(unsigned int base)
-{
-       putreg32(0x10013, base + FIFO_CTL);
-}
-
-static void hsi2c_master_setup(struct s5j_i2c_priv_s *priv, unsigned int mode,
-                               unsigned int speed, unsigned int slave_addr)
-{
-       if (priv->mode == I2C_POLLING) {
-               priv->xfer_speed = speed;
-               hsi2c_calculate_timing(priv->config->base, priv->clock, speed);
-       }
-#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
-       else if (priv->mode == I2C_INTERRUPT) {
-               priv->master_test_data = (struct master_data *)malloc(sizeof(struct master_data));
-               /* complete_init(&priv->master_test_data->done); */
-               hsi2c_set_trans_mode(priv->config->base, 1, 1); /* set master mode */
-               hsi2c_conf(priv->config->base, speed);
-               hsi2c_calculate_timing(priv->config->base, priv->clock, speed);
-               hsi2c_set_slave_addr(priv->config->base, slave_addr, 1);
-               hsi2c_set_auto_mode(priv->config->base);
-               hsi2c_set_fifo_level(priv->config->base);
-       }
-#endif
-}
-
-static void hsi2c_slave_setup(struct s5j_i2c_priv_s *priv, unsigned int mode,
-                               unsigned int speed, unsigned int slave_addr)
-{
-       priv->slave_test_data = (struct slave_data *)malloc(sizeof(struct slave_data));
-
-       /* slave mode is only support slave mode */
-       hsi2c_set_trans_mode(priv->config->base, 0, 0); /* set slave mode */
-
-       /*set hwacg for slave mode */
-       hsi2c_set_hwacg_mode(priv->config->base, 1);
-
-       hsi2c_conf(priv->config->base, speed);
-       hsi2c_calculate_timing(priv->config->base, priv->clock, speed);
-       hsi2c_set_slave_addr(priv->config->base, slave_addr, 0);
-
-       hsi2c_disable_int(priv->config->base, HSI2C_INT_ALL);
-       hsi2c_enable_int(priv->config->base, HSI2C_INT_SLAVE_ADDR_MATCH | HSI2C_INT_RX_ALMOST_FULL);
-
-       hsi2c_set_fifo_level(priv->config->base);
-       hsi2c_set_auto_config(priv->config->base, 0, 0, 0);
-
-       hsi2c_set_trans_mode(priv->config->base, 0, 0);
-
-#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
-       if ((priv->master == I2C_SLAVE_MODE) || (priv->mode == I2C_INTERRUPT)) {
-               irq_attach(priv->config->irq, priv->config->isr, NULL);
-       }
-#endif
-}
-
-static void hsi2c_master_cleanup(struct s5j_i2c_priv_s *priv)
-{
-#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
-       if (priv->mode == I2C_INTERRUPT) {
-               free(priv->master_test_data);
-               priv->master_test_data = NULL;
-               irq_detach(priv->config->irq);
-       }
-#endif
-}
-
-static void hsi2c_slave_cleanup(struct s5j_i2c_priv_s *priv)
-{
-       /*  FreeHwMemP(priv->slave_test_data); */
-       free(priv->slave_test_data);
-       priv->slave_test_data = NULL;
-#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
-       if ((priv->master == I2C_SLAVE_MODE) || (priv->mode = I2C_INTERRUPT)) {
-               irq_detach(priv->config->irq);
-       }
-#endif
+       return OK;
 }
 
-static int hsi2c_setup(struct s5j_i2c_priv_s *priv, unsigned int master,
-                               unsigned int mode, unsigned int speed, unsigned int slave_addr)
+static int hsi2c_setup(struct s5j_i2c_priv_s *priv)
 {
-       priv->master = master;
-       priv->mode = mode;
-       priv->xfer_speed = speed;
-       priv->slave_addr = slave_addr;
-
        hsi2c_manual_fast_init(priv);
 
-       if (master == I2C_MASTER) {
-               hsi2c_master_setup(priv, mode, speed, slave_addr);
-       } else if (master == I2C_SLAVE_MODE) {
-               hsi2c_slave_setup(priv, mode, speed, slave_addr);
-       }
+       hsi2c_calculate_timing(priv, priv->xfer_speed);
 
-       return 0;
+       return OK;
 }
 
 static int hsi2c_cleanup(struct s5j_i2c_priv_s *priv)
 {
-       if (priv->master == I2C_MASTER) {
-               hsi2c_master_cleanup(priv);
-       } else if (priv->master == I2C_SLAVE_MODE) {
-               hsi2c_slave_cleanup(priv);
-       }
+       priv->xfer_speed = S5J_DEFAULT_HS_CLOCK;
 
-       priv->master = I2C_MASTER;
-       priv->mode = I2C_POLLING;
-       priv->xfer_speed = I2C_SPEED_400KHZ;
-
-       putreg32(0x80000000, priv->config->base + CTL);
+       i2c_putreg32(priv, S5J_I2C_CTL, I2C_CTL_SW_RST);
        up_udelay(10);
 
-       putreg32(0x0, priv->config->base + CTL);
+       i2c_putreg32(priv, S5J_I2C_CTL, I2C_CTL_RESET_VALUE);
        up_udelay(100);
 
-       return 0;
+       return OK;
 }
 
 static inline void s5j_i2c_sem_wait(struct s5j_i2c_priv_s *priv)
 {
-       while (sem_wait(&priv->exclsem) != 0) {
+       while (sem_wait(&priv->sem_excl) != 0) {
                ASSERT(errno == EINTR);
        }
 }
 
 static inline void s5j_i2c_sem_post(struct s5j_i2c_priv_s *priv)
 {
-       sem_post(&priv->exclsem);
+       sem_post(&priv->sem_excl);
 }
 
 static inline void s5j_i2c_sem_init(struct s5j_i2c_priv_s *priv)
 {
-       sem_init(&priv->exclsem, 0, 1);
+       sem_init(&priv->sem_excl, 0, 1);
 #ifndef CONFIG_I2C_POLLED
-       sem_init(&priv->waitsem, 0, 0);
+       sem_init(&priv->sem_isr, 0, 0);
+       sem_setprotocol(&priv->sem_isr, SEM_PRIO_NONE);
 #endif
 }
 
 static inline void s5j_i2c_sem_destroy(struct s5j_i2c_priv_s *priv)
 {
-       sem_destroy(&priv->exclsem);
+       sem_destroy(&priv->sem_excl);
 #ifndef CONFIG_I2C_POLLED
-       sem_destroy(&priv->waitsem);
+       sem_destroy(&priv->sem_isr);
 #endif
 }
 
-static int s5j_i2c0_interrupt(int irq, void *context, void *arg)
-{
-       struct s5j_i2c_priv_s *priv;
-
-       /* Read the masked interrupt status */
-       priv = &s5j_i2c0_priv;
-
-       /* Let the common interrupt handler do the rest of the work */
-       return hsi2c_master_handler(priv);
-}
-
-static int s5j_i2c1_interrupt(int irq, void *context, void *arg)
-{
-       struct s5j_i2c_priv_s *priv;
-
-       /* Read the masked interrupt status */
-       priv = &s5j_i2c1_priv;
-
-       /* Let the common interrupt handler do the rest of the work */
-       return hsi2c_master_handler(priv);
-}
-
-static int s5j_i2c2_interrupt(int irq, void *context, void *arg)
-{
-       struct s5j_i2c_priv_s *priv;
-
-       /* Read the masked interrupt status */
-       priv = &s5j_i2c2_priv;
-
-       /* Let the common interrupt handler do the rest of the work */
-       return hsi2c_master_handler(priv);
-}
-
-static int s5j_i2c3_interrupt(int irq, void *context, void *arg)
-{
-       struct s5j_i2c_priv_s *priv;
-
-       /* Read the masked interrupt status */
-       priv = &s5j_i2c3_priv;
-
-       /* Let the common interrupt handler do the rest of the work */
-       return hsi2c_master_handler(priv);
-}
-
-static int s5j_i2c_initialize(struct s5j_i2c_priv_s *priv, unsigned int frequency)
+static int s5j_i2c_initialize(struct s5j_i2c_priv_s *priv)
 {
-       const struct s5j_i2c_config_s *config = priv->config;
-       int ret;
+       /* Configure GPIO pins */
+       s5j_configgpio(priv->config->scl_pin);
+       s5j_configgpio(priv->config->sda_pin);
 
-       ret = s5j_configgpio(config->scl_pin);
-       if (ret < 0) {
-               return ret;
-       }
-
-       ret = s5j_configgpio(config->sda_pin);
-       if (ret < 0) {
-               return ret;
-       }
-
-       /* Enable the I2C master block */
-       /* Configure the the initial I2C clock frequency. */
-       priv->xfer_speed = frequency;
-       hsi2c_setup(priv, priv->master, priv->mode, priv->xfer_speed, priv->slave_addr);
-
-       /*
-        * Attach interrupt handlers and enable interrupts at the NVIC (still
-        * disabled at the source).
-        */
-#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
-       if ((priv->master == I2C_SLAVE_MODE) || (priv->mode == I2C_INTERRUPT)) {
-               irq_attach(config->irq, config->isr, NULL);
-               up_enable_irq(config->irq);
-       }
-#endif
+       /* Enable I2C */
+       hsi2c_setup(priv);
 
        return OK;
 }
@@ -1038,14 +644,6 @@ static int s5j_i2c_uninitialize(struct s5j_i2c_priv_s *priv)
        s5j_unconfiggpio(priv->config->scl_pin);
        s5j_unconfiggpio(priv->config->sda_pin);
 
-       /* Disable and detach interrupts */
-#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
-       if ((priv->master == I2C_SLAVE_MODE) || (priv->mode == I2C_INTERRUPT)) {
-               up_disable_irq(priv->config->irq);
-               irq_detach(priv->config->irq);
-       }
-#endif
-
        return OK;
 }
 
@@ -1065,20 +663,12 @@ unsigned int s5j_i2c_setclock(FAR struct i2c_dev_s *dev, unsigned int frequency)
 
        /* Has the I2C bus frequency changed? */
        if (frequency != priv->xfer_speed) {
-               /*
-                * Calculate the clock divider that results in the highest frequency
-                * that is than or equal to the desired speed.
-                */
-               if (priv->mode != I2C_POLLING) {
-                       hsi2c_conf(priv->config->base, frequency);
-               }
-
-               hsi2c_calculate_timing(priv->config->base, priv->clock, frequency);
+               hsi2c_calculate_timing(priv, frequency);
        }
 
        /* Save the new I2C frequency */
        priv->xfer_speed = frequency;
-       return 0;
+       return OK;
 }
 
 /**
@@ -1090,7 +680,7 @@ unsigned int s5j_i2c_setclock(FAR struct i2c_dev_s *dev, unsigned int frequency)
  * @return    = 0
  * @note
  */
-int s5j_i2c_setownaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
+int s5j_i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
 {
        struct s5j_i2c_priv_s *priv = (struct s5j_i2c_priv_s *)dev;
 
@@ -1098,8 +688,8 @@ int s5j_i2c_setownaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
        if (nbits == 1) {
                priv->msgv->flags |= I2C_M_TEN;
        }
-       hsi2c_set_slave_addr(priv->config->base, addr, 0);
-       return 0;
+       hsi2c_set_slave_addr(priv, addr);
+       return OK;
 }
 
 /**
@@ -1119,7 +709,6 @@ int s5j_i2c_transfer(struct i2c_dev_s *dev, struct i2c_msg_s *msgv, int msgc)
        int nak_ok;
        int start = 1;
        int stop = 1;
-       unsigned int base = priv->config->base;
 
        /* Ensure that address or flags don't change meanwhile */
        s5j_i2c_sem_wait(priv);
@@ -1138,7 +727,7 @@ int s5j_i2c_transfer(struct i2c_dev_s *dev, struct i2c_msg_s *msgv, int msgc)
        }
 
        priv->mcnt = 0;
-       priv->mptr = NULL;
+       priv->ptr = NULL;
        priv->msgv = msgv;
        priv->msgc = msgc;
 
@@ -1147,12 +736,12 @@ int s5j_i2c_transfer(struct i2c_dev_s *dev, struct i2c_msg_s *msgv, int msgc)
                hsi2c_start(priv);
        }
 
-       if (priv->xfer_speed > I2C_SPEED_400KHZ) {
-               hsi2c_conf(base, I2C_SPEED_400KHZ);
-               putreg32((0xF << 24 | I2C_SEND_DATA), base + I2C_MANUAL_CMD);
+       if (priv->xfer_speed > S5J_DEFAULT_HS_CLOCK) {
+               hsi2c_conf(priv, S5J_DEFAULT_HS_CLOCK);
+               i2c_putreg32(priv, S5J_I2C_MANUAL_CMD, I2C_MANUAL_CMD_TX_DATA(0xF) | I2C_MANUAL_CMD_SEND_DATA);
                hsi2c_wait_xfer_noack(priv);
 
-               hsi2c_conf(base, priv->xfer_speed);
+               hsi2c_conf(priv, priv->xfer_speed);
                hsi2c_repstart(priv);
                hsi2c_wait_xfer_noack(priv);
        }
@@ -1194,7 +783,7 @@ int s5j_i2c_transfer(struct i2c_dev_s *dev, struct i2c_msg_s *msgv, int msgc)
 
 fail:
        priv->mcnt = 0;
-       priv->mptr = NULL;
+       priv->ptr = NULL;
        if (stop) {
                hsi2c_stop(priv);
        }
@@ -1211,12 +800,11 @@ int s5j_i2c_read(FAR struct i2c_dev_s *dev, FAR uint8_t *buffer, int buflen)
        struct i2c_msg_s msg;
        unsigned int flags;
 
-       /* 7- or 10-bit? */
-       flags = (priv->addrlen == 10) ? I2C_M_TEN : 0;
+       flags = 0;
 
        /* Setup for the transfer */
        msg.addr = priv->slave_addr, msg.flags = (flags | I2C_M_READ);
-       msg.buffer = (FAR uint8_t *)buffer;
+       msg.buffer = (FAR uint8_t *) buffer;
        msg.length = buflen;
 
        /*
@@ -1229,16 +817,15 @@ int s5j_i2c_read(FAR struct i2c_dev_s *dev, FAR uint8_t *buffer, int buflen)
        return s5j_i2c_transfer(dev, &msg, 1);
 }
 
-int s5j_i2c_write(FAR struct i2c_dev_s *dev, FAR const uint8_t *buffer,
-                               int buflen)
+int s5j_i2c_write(FAR struct i2c_dev_s *dev, FAR const uint8_t *buffer, int buflen)
 {
        struct s5j_i2c_priv_s *priv = (struct s5j_i2c_priv_s *)dev;
        struct i2c_msg_s msg;
 
        /* Setup for the transfer */
        msg.addr = priv->slave_addr;
-       msg.flags = (priv->addrlen == 10) ? I2C_M_TEN : 0;
-       msg.buffer = (FAR uint8_t *)buffer; /* Override const */
+       msg.flags = 0;
+       msg.buffer = (FAR uint8_t *) buffer;    /* Override const */
        msg.length = buflen;
 
        /*
@@ -1279,29 +866,25 @@ struct i2c_dev_s *up_i2cinitialize(int port)
        case 0:
                priv = &s5j_i2c0_priv;
                config = &s5j_i2c0_config;
-               cal_clk_enable(gate_hsi2c0);
-               priv->clock = cal_clk_getrate(gate_hsi2c0);
+               priv->clock = s5j_clk_get_rate(CLK_SPL_BUS_P0);
                break;
 
        case 1:
                priv = &s5j_i2c1_priv;
                config = &s5j_i2c1_config;
-               cal_clk_enable(gate_hsi2c1);
-               priv->clock = cal_clk_getrate(gate_hsi2c1);
+               priv->clock = s5j_clk_get_rate(CLK_SPL_BUS_P0);
                break;
 
        case 2:
                priv = &s5j_i2c2_priv;
                config = &s5j_i2c2_config;
-               cal_clk_enable(gate_hsi2c2);
-               priv->clock = cal_clk_getrate(gate_hsi2c2);
+               priv->clock = s5j_clk_get_rate(CLK_SPL_BUS_P0);
                break;
 
        case 3:
                priv = &s5j_i2c3_priv;
                config = &s5j_i2c3_config;
-               cal_clk_enable(gate_hsi2c3);
-               priv->clock = cal_clk_getrate(gate_hsi2c3);
+               priv->clock = s5j_clk_get_rate(CLK_SPL_BUS_P0);
                break;
 
        default:
@@ -1324,7 +907,7 @@ struct i2c_dev_s *up_i2cinitialize(int port)
                s5j_i2c_sem_init(priv);
 
                /* Initialize the I2C hardware */
-               s5j_i2c_initialize(priv, priv->xfer_speed);
+               s5j_i2c_initialize(priv);
        }
 
        g_s5j_i2c_priv[port] = priv;
@@ -1382,13 +965,11 @@ void s5j_i2c_register(int bus)
 {
        FAR struct i2c_dev_s *i2c;
        char path[16];
-       int ret;
 
        i2c = up_i2cinitialize(bus);
        if (i2c != NULL) {
                snprintf(path, 16, "/dev/i2c-%d", bus);
-               ret = i2c_uioregister(path, i2c);
-               if (ret < 0) {
+               if (i2c_uioregister(path, i2c) < 0) {
                        s5j_i2cbus_uninitialize(i2c);
                }
        }
index 30c6f93..f01a9be 100644 (file)
  * Included Files
  ****************************************************************************/
 #include <tinyara/config.h>
-#include <tinyara/i2c.h>
-
-#include "chip.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* I2C Register Offsets *****************************************************/
-#define HSI2C_MASTER_TX_SLAVE_RX    1
-#define HSI2C_SLAVE_TX_MASTER_RX    2
-#define HSI2C_MASTER_TX_MASTER_RX   4
-
-#define HSI2C_MASTER_BUFFER_BASE    0x44000000
-#define HSI2C_SLAVE_BUFFER_BASE     0x44800000
-
-#define HSI2C_MASTER_ID             0x9        /*  Master ID 00001xxx */
-#define HSI2C_SLAVE_ADDRESS         0x50
-
-/* Register Map *************************************************************/
-#define CTL               0x0000
-#define FIFO_CTL          0x0004
-#define TRAILING_CTL      0x0008
-#define INT_EN            0x0020
-#define INT_STAT          0x0024
-#define FIFO_STAT         0x0030
-#define TXDATA            0x0034
-#define RXDATA            0x0038
-#define I2C_CONF          0x0040
-#define I2C_AUTO_CONF     0x0044
-#define I2C_TIMEOUT       0x0048
-#define I2C_MANUAL_CMD    0x004C
-#define I2C_TRANS_STATUS  0x0050
-#define I2C_TIMING_HS1    0x0054
-#define I2C_TIMING_HS2    0x0058
-#define I2C_TIMING_HS3    0x005C
-#define I2C_TIMING_FS1    0x0060
-#define I2C_TIMING_FS2    0x0064
-#define I2C_TIMING_FS3    0x0068
-#define I2C_TIMING_SLA    0x006C
-#define I2C_ADDR          0x0070
-
-#define I2C_START         (1 << 0)
-#define I2C_RESTART       (1 << 1)
-#define I2C_STOP          (1 << 2)
-#define I2C_SEND_DATA     (1 << 3)
-#define I2C_READ_DATA     (1 << 4)
-#define I2C_RX_ACK        (1 << 5)
-#define I2C_TX_MASK       (0xFF << 24)
-#define I2C_RX_MASK       (0xFF << 16)
-
-#define I2C_SPEED_400KHZ  400000
-
-#define HSI2C_INT_SLAVE_ADDR_MATCH        (1 << 15)
-#define HSI2C_INT_XFER_DONE_MANUAL        (1 << 13)
-#define HSI2C_INT_XFER_DONE_NOACK_MANUAL  (1 << 12)
-#define HSI2C_INT_NO_DEV_AUTO             (1 << 10)
-#define HSI2C_INT_NO_DEV_ACK_AUTO         (1 << 9)
-#define HSI2C_INT_TRANS_ABORT_AUTO        (1 << 8)
-#define HSI2C_INT_TRANSFER_DONE_AUTO      (1 << 7)
-#define HSI2C_INT_RX_OVERRUN              (1 << 5)
-#define HSI2C_INT_TX_UNDERRUN             (1 << 2)
-#define HSI2C_INT_RX_ALMOST_FULL          (1 << 1)
-#define HSI2C_INT_TX_ALMOST_EMPTY         (1 << 0)
-
-#define HSI2C_INT_ALL  0xFFFF
-
-#define SLAVE_TX_MODE  (1 << 19)
-
-#define STOP_COND      (1 << 18)
 
-#define I2C_MASTER      0
-#define I2C_SLAVE_MODE  1
-#define I2C_POLLING     0
-/* #define I2C_INTERRUPT   1 */
-
-enum slave_status {
-       SLAVE_IDLE,
-       SLAVE_GET_REG,
-       SLAVE_GET_DATA,
-       SLAVE_SET_DATA,
-};
-
-struct slave_data {
-       enum slave_status status;
-       u32 current_reg;
-       u8 data[20];
-};
-
-struct master_data {
-       struct i2c_msg_s *msg;
-       int num;
-       int cur_msg;
-       int buf_count;
-       /*  struct completion done; */
-};
-
-/* I2C Device hardware configuration */
-struct s5j_i2c_config_s {
-       uintptr_t base;                                         /* I2C base address */
-       unsigned int scl_pin;                           /* GPIO configuration for SCL as SCL */
-       unsigned int sda_pin;                           /* GPIO configuration for SDA as SDA */
-       int (*isr)(int, void *, void *);        /* Interrupt handler */
-       unsigned int irq;                                       /* IRQ number */
-       uint8_t devno;                                          /* I2Cn where n = devno */
-};
+#include <tinyara/i2c.h>
 
-/* I2C Device Private Data */
-struct s5j_i2c_priv_s {
-       const struct i2c_ops_s *ops;    /* Standard I2C operations */
-       const struct s5j_i2c_config_s *config;  /* Port configuration */
-       sem_t exclsem;                                  /* Mutual exclusion semaphore */
-#ifndef CONFIG_I2C_POLLED
-       sem_t waitsem;                                  /* Interrupt wait semaphore */
+#ifdef CONFIG_S5J_S5JT200
+#include "chip/s5jt200_i2c.h"
+#else
+#error "S5J chip is not specified"
 #endif
-       uint8_t refs;                                   /* Reference count */
-       volatile uint8_t intstate;              /* Interrupt handshake (see enum s5j_intstate_e) */
-
-       int state;
-       int clock;
-       int xfer_speed;
-       unsigned int master;
-       unsigned int mode;
-       unsigned int slave_addr;
-       unsigned int addrlen;
-       unsigned int timeout;
-       char name[16];
-
-       unsigned int initialized;
-       unsigned int retries;
-       /*  master data  */
-       uint8_t msgc;                                   /* Message count */
-       struct i2c_msg_s *msgv;                 /* Message list */
-       uint8_t *mptr;                                  /* Current message buffer */
-       int mcnt;                                               /* Current message length */
-       uint16_t mflags;                                /* Current message flags */
-
-       struct i2c_msg_s *msg;
-
-       /* interrupt */
-       struct slave_data *slave_test_data;
-       struct master_data *master_test_data;
-
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-static void hsi2c_set_hs_timing(unsigned int base, unsigned int nClkDiv,
-                               unsigned int tSTART_SU, unsigned int tSTART_HD,
-                               unsigned int tSTOP_SU, unsigned int tSDA_SU,
-                               unsigned int tDATA_SU, unsigned int tDATA_HD,
-                               unsigned int tSCL_L, unsigned int tSCL_H,
-                               unsigned int tSR_RELEASE);
-static void hsi2c_set_fs_timing(unsigned int base, unsigned int nClkDiv,
-                               unsigned int tSTART_SU, unsigned int tSTART_HD,
-                               unsigned int tSTOP_SU, unsigned int tDATA_SU,
-                               unsigned int tDATA_HD, unsigned int tSCL_L,
-                               unsigned int tSCL_H, unsigned int tSR_RELEASE);
-static void hsi2c_calculate_timing(unsigned int base, unsigned int nPclk, unsigned int nOpClk);
-static void hsi2c_conf(unsigned int base, unsigned int nOpClk);
-static void hsi2c_enable_int(unsigned int base, unsigned int bit);
-static void hsi2c_disable_int(unsigned int base, unsigned int bit);
-static void hsi2c_clear_int(unsigned int base, unsigned int bit);
-static unsigned int hsi2c_read_int_status(unsigned int base);
-static void hsi2c_set_slave_addr(unsigned int base, u16 addr, unsigned int is_master);
-static int hsi2c_manual_fast_init(struct s5j_i2c_priv_s *priv);
-static int hsi2c_wait_xfer_done(struct s5j_i2c_priv_s *priv);
-static int hsi2c_wait_xfer_noack(struct s5j_i2c_priv_s *priv);
-static void hsi2c_start(struct s5j_i2c_priv_s *priv);
-static void hsi2c_stop(struct s5j_i2c_priv_s *priv);
-static void hsi2c_repstart(struct s5j_i2c_priv_s *priv);
-static int hsi2c_outb(struct s5j_i2c_priv_s *priv, u8 data);
-static int hsi2c_inb(struct s5j_i2c_priv_s *priv, bool is_ack);
-static int sendbytes(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg);
-static int readbytes(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg);
-static int try_address(struct s5j_i2c_priv_s *priv, u8 addr, int retries);
-static int do_address(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg);
-static void hsi2c_run_auto_mode(unsigned int base, int on);
-static void hsi2c_tx_fifo_reset(unsigned int base, int resetb);
-static void hsi2c_set_auto_config(unsigned int base, unsigned int stop, unsigned int tx, unsigned int len);
-static void hsi2c_set_trans_mode(unsigned int base, unsigned int master, unsigned int tx);
-static void hsi2c_set_hwacg_mode(unsigned int base, unsigned int slave);
-static int hsi2c_master_handler(void *args);
-static int hsi2c_slave_handler(void *args);
-static void hsi2c_set_auto_mode(unsigned int base);
-static void hsi2c_set_fifo_level(unsigned int base);
-static void hsi2c_master_setup(struct s5j_i2c_priv_s *priv, unsigned int mode, unsigned int speed, unsigned int slave_addr);
-static void hsi2c_slave_setup(struct s5j_i2c_priv_s *priv, unsigned int mode, unsigned int speed, unsigned int slave_addr);
-static void hsi2c_master_cleanup(struct s5j_i2c_priv_s *priv);
-static void hsi2c_slave_cleanup(struct s5j_i2c_priv_s *priv);
-static int hsi2c_setup(struct s5j_i2c_priv_s *priv, unsigned int master, unsigned int mode, unsigned int speed, unsigned int slave_addr);
-static int hsi2c_cleanup(struct s5j_i2c_priv_s *priv);
-static inline void s5j_i2c_sem_wait(struct s5j_i2c_priv_s *priv);
-static inline void s5j_i2c_sem_post(struct s5j_i2c_priv_s *priv);
-static inline void s5j_i2c_sem_init(struct s5j_i2c_priv_s *priv);
-static inline void s5j_i2c_sem_destroy(struct s5j_i2c_priv_s *priv);
-static int s5j_i2c_interrupt(struct s5j_i2c_priv_s *priv, unsigned int status);
-static int s5j_i2c0_interrupt(int irq, void *context, void *arg);
-static int s5j_i2c1_interrupt(int irq, void *context, void *arg);
-static int s5j_i2c2_interrupt(int irq, void *context, void *arg);
-static int s5j_i2c3_interrupt(int irq, void *context, void *arg);
-static int s5j_i2c_initialize(struct s5j_i2c_priv_s *priv, unsigned int frequency);
-static int s5j_i2c_uninitialize(struct s5j_i2c_priv_s *priv);
 
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
+
 unsigned int s5j_i2c_setclock(struct i2c_dev_s *dev, unsigned int frequency);
-int s5j_i2c_setownaddress(FAR struct i2c_dev_s *dev, int addr, int nbits);
+int s5j_i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits);
 int s5j_i2c_transfer(struct i2c_dev_s *dev, struct i2c_msg_s *msgv, int msgc);
 int s5j_i2c_read(FAR struct i2c_dev_s *dev, FAR uint8_t *buffer, int buflen);
 int s5j_i2c_write(FAR struct i2c_dev_s *dev, FAR const uint8_t *buffer, int buflen);
@@ -280,4 +85,4 @@ struct i2c_dev_s *up_i2cinitialize(int port);
 int s5j_i2cbus_uninitialize(FAR struct i2c_dev_s *dev);
 void s5j_i2c_register(int bus);
 
-#endif /* __ARCH_ARM_SRC_S5J_I2C_H */
+#endif                                                 /* __ARCH_ARM_SRC_S5J_I2C_H */