From 3b9cbb37296004113f9228dd6dcb972850963efa Mon Sep 17 00:00:00 2001 From: Shivam Garg Date: Thu, 14 Sep 2017 17:02:20 +0900 Subject: [PATCH] Adding i2c and clock changes for audio framework --- os/arch/arm/src/s5j/Make.defs | 2 + os/arch/arm/src/s5j/chip/s5jt200_cmu.h | 455 +++++++++++++++++++ os/arch/arm/src/s5j/chip/s5jt200_i2c.h | 136 ++++++ os/arch/arm/src/s5j/s5j_clock.c | 340 ++++++++++++++ os/arch/arm/src/s5j/s5j_clock.h | 323 +++++++++++++ os/arch/arm/src/s5j/s5j_i2c.c | 801 ++++++++------------------------- os/arch/arm/src/s5j/s5j_i2c.h | 211 +-------- 7 files changed, 1455 insertions(+), 813 deletions(-) create mode 100644 os/arch/arm/src/s5j/chip/s5jt200_cmu.h create mode 100644 os/arch/arm/src/s5j/chip/s5jt200_i2c.h create mode 100644 os/arch/arm/src/s5j/s5j_clock.c create mode 100644 os/arch/arm/src/s5j/s5j_clock.h diff --git a/os/arch/arm/src/s5j/Make.defs b/os/arch/arm/src/s5j/Make.defs index 541635d..22360a5 100644 --- a/os/arch/arm/src/s5j/Make.defs +++ b/os/arch/arm/src/s5j/Make.defs @@ -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 index 0000000..92c21e6 --- /dev/null +++ b/os/arch/arm/src/s5j/chip/s5jt200_cmu.h @@ -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 + * + * 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 index 0000000..f42486c --- /dev/null +++ b/os/arch/arm/src/s5j/chip/s5jt200_i2c.h @@ -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 + * + * 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 index 0000000..90680a7 --- /dev/null +++ b/os/arch/arm/src/s5j/s5j_clock.c @@ -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 + * + * 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 + +#include +#include +#include +#include + +#include + +#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 index 0000000..d1d3d35 --- /dev/null +++ b/os/arch/arm/src/s5j/s5j_clock.h @@ -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 + * + * 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 + +#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 */ diff --git a/os/arch/arm/src/s5j/s5j_i2c.c b/os/arch/arm/src/s5j/s5j_i2c.c index 7b926fb..2221fe0 100644 --- a/os/arch/arm/src/s5j/s5j_i2c.c +++ b/os/arch/arm/src/s5j/s5j_i2c.c @@ -63,41 +63,99 @@ #include #include -#include -#include -#include #include #include #include #include - #include -#include #include -#include - -#include #include #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); } } diff --git a/os/arch/arm/src/s5j/s5j_i2c.h b/os/arch/arm/src/s5j/s5j_i2c.h index 30c6f93..f01a9be 100644 --- a/os/arch/arm/src/s5j/s5j_i2c.h +++ b/os/arch/arm/src/s5j/s5j_i2c.h @@ -63,216 +63,21 @@ * Included Files ****************************************************************************/ #include -#include - -#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 -/* 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 */ -- 2.7.4