1 /******************************************************************************
2 ** File Name: I2C_phy_v0.c *
5 ** Copyright: 2010 Spreatrum, Incoporated. All Rights Reserved. *
6 ** Description: This file define the physical layer of I2C device. *
7 ******************************************************************************
9 ******************************************************************************
11 ** ------------------------------------------------------------------------- *
12 ** DATE NAME DESCRIPTION *
13 ** 06/28/2010 liuhao Create. *
14 ******************************************************************************/
16 /**---------------------------------------------------------------------------*
18 **---------------------------------------------------------------------------*/
20 //#include "chip_plf_export.h"
21 //#include "timer_drvapi.h"
22 #include "i2c_reg_v0.h"
23 #include "asm/arch/sys_timer_reg_v0.h"
24 //#include "sci_types.h"
25 #include <asm/arch/chip_drv_common_io.h>
27 #include "../sc8830_i2c_cfg.h"
28 #include "../i2c_phy.h"
30 /**---------------------------------------------------------------------------*
32 **---------------------------------------------------------------------------*/
34 /**---------------------------------------------------------------------------*
36 **---------------------------------------------------------------------------*/
42 /**---------------------------------------------------------------------------*
44 **---------------------------------------------------------------------------*/
45 //extern uint32 TIMER_GetSystemCounterReg (void);
46 //extern void SyscntEnable (void);
48 #define I2C_TIMEOUT_FACTOR 500000 //the critical value is 10000
50 #define I2C_WAIT_INT \
52 timetick = SYSTEM_CURRENT_CLOCK; \
53 while(!(ptr->ctl & I2CCTL_INT)) \
55 uint32 wait_counter=0x00; \
56 for(wait_counter=0x00; wait_counter<0xff;wait_counter++) \
60 if((SYSTEM_CURRENT_CLOCK - timetick) >= g_i2c_timeout) \
62 if(ERR_I2C_NONE == ret_value) \
64 ret_value = ERR_I2C_INT_TIMEOUT; \
73 #define I2C_WAIT_BUSY \
75 timetick = SYSTEM_CURRENT_CLOCK; \
76 while(ptr->cmd & I2CCMD_BUS) \
78 if ((SYSTEM_CURRENT_CLOCK - timetick) >= g_i2c_timeout) \
80 if(ERR_I2C_NONE == ret_value) \
82 ret_value = ERR_I2C_BUSY_TIMEOUT; \
90 #define I2C_WAIT_ACK \
92 timetick = SYSTEM_CURRENT_CLOCK; \
93 while(ptr->cmd & I2CCMD_ACK) \
95 if ((SYSTEM_CURRENT_CLOCK - timetick) >= g_i2c_timeout) \
97 if(ERR_I2C_NONE == ret_value) \
99 ret_value = ERR_I2C_ACK_TIMEOUT; \
107 #define I2C_CLEAR_INT \
110 ptr->cmd |= I2CCMD_INT_ACK; \
113 /**---------------------------------------------------------------------------*
115 **---------------------------------------------------------------------------*/
117 /**---------------------------------------------------------------------------*
119 **---------------------------------------------------------------------------*/
120 LOCAL volatile uint32 g_i2c_timeout = 2; //unit is ms
121 extern const I2C_BASE_INFO __i2c_base_info[I2C_BUS_MAX];
123 /*********************************************************************************************************
130 ** output parameters:
132 *********************************************************************************************************/
133 LOCAL uint32 __I2C_PHY_GetBase (uint32 phy_id)
140 for (i = 0; i < I2C_BUS_MAX; i++)
142 if (phy_id == (uint32) __i2c_base_info[i].phy_id)
144 ret = (uint32) __i2c_base_info[i].base_addr;
149 CHIP_REG_OR (GR_GEN0, (GEN0_I2C0_EN));
152 CHIP_REG_OR (GR_GEN0, (GEN0_I2C1_EN));
155 CHIP_REG_OR (GR_GEN0, (GEN0_I2C2_EN));
158 CHIP_REG_OR (GR_GEN0, (GEN0_I2C3_EN));
161 CHIP_REG_OR (GR_GEN0, (GEN0_I2C4_EN));
164 CHIP_REG_OR (AON_APB_EB0, (AON_I2C_EN));
171 //SCI_PASSERT ( (0 != ret), ("get I2C controller base address fail!"));/*assert verified*/
174 /*********************************************************************************************************
181 ** output parameters:
183 *********************************************************************************************************/
184 LOCAL ERR_I2C_E __I2C_PHY_SetSCL (uint32 phy_id, uint32 freq)
186 uint32 APB_clk,i2c_dvd;
187 volatile I2C_CTL_REG_T *ptr = (volatile I2C_CTL_REG_T *) __I2C_PHY_GetBase (phy_id);
188 APB_clk= 26*1000*1000;//CHIP_GetAPBClk();
189 i2c_dvd=APB_clk/ (4*freq)-1;
190 ptr->div0= (uint16) (i2c_dvd & 0xffff);
191 ptr->div1= (uint16) (i2c_dvd>>16);
192 g_i2c_timeout = I2C_TIMEOUT_FACTOR / (freq);
194 if (g_i2c_timeout < 2)
202 /*********************************************************************************************************
209 ** output parameters:
211 *********************************************************************************************************/
212 LOCAL ERR_I2C_E __I2C_PHY_SetPort (uint32 port)
217 /*********************************************************************************************************
224 ** output parameters:
226 *********************************************************************************************************/
227 LOCAL ERR_I2C_E I2C_PHY_ControlInit_V0 (uint32 phy_id, uint32 freq, uint32 port)
229 volatile I2C_CTL_REG_T *ptr = (volatile I2C_CTL_REG_T *) __I2C_PHY_GetBase (phy_id);
231 ptr->rst = BIT_0;//why reset
232 ptr->ctl &= ~ (I2CCTL_EN); //you must first disable i2c module then change clock
233 ptr->ctl &= ~ (I2CCTL_IE);
234 //ptr->ctl &= ~ (I2CCTL_CMDBUF_EN);
235 __I2C_PHY_SetSCL (phy_id, freq);
237 if (I2C_PORT_NUM < port)
239 //SCI_ASSERT (0);/*assert to do*/
242 __I2C_PHY_SetPort (port);
244 //CHIP_REG_OR (I2C_CTL, (I2CCTL_IE | I2CCTL_EN));
245 ptr->ctl |= (I2CCTL_IE | I2CCTL_EN);
247 //CHIP_REG_OR (I2C_CMD, I2CCMD_INT_ACK);
248 ptr->cmd &= ~ (I2CCMD_INT_ACK);
250 IIC_PRINT ("[IIC DRV:]I2C_PHY_ControlInit_V0: freq=%d, port=%d", freq, port);
254 /*********************************************************************************************************
261 ** output parameters:
263 *********************************************************************************************************/
264 LOCAL ERR_I2C_E I2C_PHY_StartBus_V0 (uint32 phy_id, uint8 addr, BOOLEAN rw, BOOLEAN ack_en)
268 volatile I2C_CTL_REG_T *ptr = (volatile I2C_CTL_REG_T *) __I2C_PHY_GetBase (phy_id);
269 uint32 ret_value = ERR_I2C_NONE;
274 cmd = ( (uint32) (addr |0x1)) <<8;
279 cmd = ( (uint32) addr) <<8;
282 cmd = cmd | I2CCMD_START | I2CCMD_WRITE;
283 IIC_PRINT ("[IIC DRV:]I2C_PHY_StartBus_V0: cmd=%x", cmd);
297 /*********************************************************************************************************
304 ** output parameters:
306 *********************************************************************************************************/
307 LOCAL ERR_I2C_E I2C_PHY_WriteBytes_V0 (uint32 phy_id, uint8 *pCmd, uint32 len, BOOLEAN ack_en, BOOLEAN no_stop)
312 volatile I2C_CTL_REG_T *ptr = (volatile I2C_CTL_REG_T *) __I2C_PHY_GetBase (phy_id);
313 uint32 ret_value = ERR_I2C_NONE;
315 for (i=0; i<len; i++)
317 cmd = ( (uint32) pCmd[i]) <<8;
318 cmd = cmd | I2CCMD_WRITE ;
320 if ( (i== (len-1)) && (!no_stop))
322 cmd = cmd | I2CCMD_STOP;
326 IIC_PRINT ("[IIC DRV:]I2C_PHY_WriteBytes_V0: cmd=%x", cmd);
341 /*********************************************************************************************************
348 ** output parameters:
350 *********************************************************************************************************/
351 LOCAL ERR_I2C_E I2C_PHY_ReadBytes_V0 (uint32 phy_id, uint8 *pCmd, uint32 len, BOOLEAN ack_en)
356 volatile I2C_CTL_REG_T *ptr = (volatile I2C_CTL_REG_T *) __I2C_PHY_GetBase (phy_id);
357 uint32 ret_value = ERR_I2C_NONE;
359 for (i=0; i<len; i++)
361 cmd = I2CCMD_READ; /*FIXME |I2CCMD_TX_ACK;*/
365 cmd = cmd |I2CCMD_STOP |I2CCMD_TX_ACK;
369 IIC_PRINT ("[IIC DRV:]I2C_PHY_ReadBytes_V0: cmd=%x", cmd);
372 pCmd[i] = (uint8) ( (ptr->cmd) >>8);
378 /*********************************************************************************************************
385 ** output parameters:
387 *********************************************************************************************************/
388 LOCAL ERR_I2C_E I2C_PHY_StopBus_V0 (uint32 phy_id)
392 volatile I2C_CTL_REG_T *ptr = (volatile I2C_CTL_REG_T *) __I2C_PHY_GetBase (phy_id);
393 uint32 ret_value = ERR_I2C_NONE;
401 /*********************************************************************************************************
408 ** output parameters:
410 *********************************************************************************************************/
411 LOCAL ERR_I2C_E I2C_PHY_SendACK_V0 (uint32 phy_id)
416 /*********************************************************************************************************
423 ** output parameters:
425 *********************************************************************************************************/
426 LOCAL ERR_I2C_E I2C_PHY_GetACK_V0 (uint32 phy_id)
431 /*this version armcc can not support this method :(*/
433 PUBLIC I2C_PHY_FUN phy_fun_v0 = {
434 .init = I2C_PHY_ControlInit_V0,
435 .start = I2C_PHY_StartBus_V0,
436 .stop = I2C_PHY_StopBus_V0,
437 .read = I2C_PHY_ReadBytes_V0,
438 .write = I2C_PHY_WriteBytes_V0,
439 .sendack = I2C_PHY_SendACK_V0,
440 .getack = I2C_PHY_GetACK_V0,
445 PUBLIC I2C_PHY_FUN phy_fun_v0 =
447 I2C_PHY_ControlInit_V0,
449 I2C_PHY_WriteBytes_V0,
450 I2C_PHY_ReadBytes_V0,
456 /**---------------------------------------------------------------------------*
458 **---------------------------------------------------------------------------*/