1 /******************************************************************************
2 ** File Name: I2C_drv.c *
5 ** Copyright: 2010 Spreatrum, Incoporated. All Rights Reserved. *
6 ** Description: This file define the hal layer of I2C device. *
7 ******************************************************************************
9 ******************************************************************************
11 ** ------------------------------------------------------------------------- *
12 ** DATE NAME DESCRIPTION *
13 ** 06/28/2010 liuhao Create. *
14 ******************************************************************************/
16 /**---------------------------------------------------------------------------*
18 **---------------------------------------------------------------------------*/
19 #include "asm/arch/sci_types.h"
21 //#include "chip_plf_export.h"
22 #include "sp8830_i2c.h"
23 #include "sc8830_i2c_cfg.h"
25 /**---------------------------------------------------------------------------*
27 **---------------------------------------------------------------------------*/
29 /**---------------------------------------------------------------------------*
31 **---------------------------------------------------------------------------*/
37 /**---------------------------------------------------------------------------*
39 **---------------------------------------------------------------------------*/
42 //SCI_MUTEX_PTR mutex;
50 #define I2C_GetMutex(mutex) {\
51 uint32 ret = SCI_SUCCESS;\
54 return ERR_I2C_NO_MUTEX;\
56 if(SCI_InThreadContext())\
58 ret = SCI_GetMutex(mutex, SCI_INVALID_BLOCK_ID != SCI_IdentifyThread() ? SCI_WAIT_FOREVER : 0);\
60 SCI_ASSERT( ret == SCI_SUCCESS );//assert verified\
63 #define I2C_PutMutex(mutex) {\
64 uint32 ret = SCI_SUCCESS;\
67 return ERR_I2C_NO_MUTEX;\
69 if(SCI_InThreadContext())\
71 ret = SCI_PutMutex( mutex );\
73 SCI_ASSERT( ret == SCI_SUCCESS );//assert verified\
76 /**---------------------------------------------------------------------------*
78 **---------------------------------------------------------------------------*/
79 LOCAL I2C_DEV __i2c_dev[I2C_BUS_MAX *I2C_DEV_MAX];
81 /**---------------------------------------------------------------------------*
83 **---------------------------------------------------------------------------*/
84 I2C_BUS __i2c_bus[I2C_BUS_MAX];
85 extern const I2C_PHY_CFG __i2c_phy_cfg[I2C_ID_MAX];
87 /**---------------------------------------------------------------------------*
88 ** Function Definitions
89 **---------------------------------------------------------------------------*/
90 /*********************************************************************************************************
99 *********************************************************************************************************/
100 LOCAL uint32 I2C_Bus_CFG (uint32 logic_id)
102 uint32 bus_id = __i2c_phy_cfg[logic_id].phy_id;
103 /*config bus method*/
104 __i2c_bus[bus_id].phy_fun = __i2c_phy_cfg[logic_id].phy_fun;
107 /*********************************************************************************************************
114 ** output parameters:
116 *********************************************************************************************************/
117 LOCAL uint32 I2C_Bus_Init (uint32 logic_id, uint32 freq, uint32 port_id)
119 uint32 bus_id = __i2c_phy_cfg[logic_id].phy_id;
120 /*config bus property*/
121 __i2c_bus[bus_id].current_freq = freq;
122 __i2c_bus[bus_id].current_port = port_id;
123 //__i2c_bus[bus_id].mutex = SCI_CreateMutex ("I2C SYNC MUTEX", SCI_INHERIT);
124 //SCI_PASSERT ( (NULL!= __i2c_bus[bus_id].mutex), ("I2C Great MUTEX fail!"));/*assert verified*/
125 /*config bus method*/
126 I2C_Bus_CFG (logic_id);
130 /*********************************************************************************************************
137 ** output parameters:
139 *********************************************************************************************************/
140 LOCAL uint32 I2C_Bus_Exit (uint32 bus_id)
142 __i2c_bus[bus_id].reference = 0;
145 if (NULL != __i2c_bus[bus_id].mutex)
147 uint32 status_val = 0;
148 status_val = SCI_DeleteMutex (__i2c_bus[bus_id].mutex);
149 //SCI_PASSERT((0 != status_val),("I2C delete MUTEX fail!"));
150 __i2c_bus[bus_id].mutex = NULL;
153 /*release the bus method*/
154 __i2c_bus[bus_id].phy_fun = NULL;
158 /*********************************************************************************************************
159 ** Function name: I2C_HAL_Open
160 ** Descriptions: i2c bus open function
162 ** dev - pointer of i2c slave dev
165 ** output parameters: NONE
166 ** Returned value: handle
167 *********************************************************************************************************/
168 PUBLIC int32 I2C_HAL_Open (I2C_DEV *dev)
175 //SCI_ASSERT (NULL != dev);/*assert verified*/
176 /*check if use the wrong port number*/
177 //SCI_ASSERT ( ( (I2C_ID_MAX > dev->id) && (0 <= dev->id)));/*assert verified*/
178 /*now we should get the i2c bus id and the controller's port id*/
179 bus_id = __i2c_phy_cfg[dev->id].phy_id;
180 port_id = __i2c_phy_cfg[dev->id].port_id;
181 /*reference shouldn't larger than I2C_DEV_MAX*/
182 //SCI_ASSERT ( ( (I2C_DEV_MAX > __i2c_bus[bus_id].reference) && (0 <= __i2c_bus[bus_id].reference)));/*assert verified*/
184 /*look for the handle: return the 1st available array member*/
185 for (i=0; i< I2C_DEV_MAX; i++)
187 if (0 == __i2c_dev[idx + bus_id * I2C_DEV_MAX].freq)
194 if (I2C_DEV_MAX == idx)
201 handle = idx + bus_id * I2C_DEV_MAX;
202 /*set the parameters for i2c slave device*/
203 __i2c_dev[handle].id = dev->id;
204 __i2c_dev[handle].freq = dev->freq;
205 __i2c_dev[handle].bus = bus_id;
206 __i2c_dev[handle].slave_addr = dev->slave_addr;
207 __i2c_dev[handle].reg_addr_num = dev->reg_addr_num;
208 __i2c_dev[handle].check_ack = dev->check_ack;
209 __i2c_dev[handle].no_stop = dev->no_stop;
211 /*first open, than init i2c controller*/
212 if (0 == __i2c_bus[bus_id].reference)
214 I2C_Bus_Init (dev->id, dev->freq, port_id);
215 __i2c_bus[bus_id].phy_fun->init (bus_id, dev->freq, port_id);
218 __i2c_bus[bus_id].reference++;
223 /*********************************************************************************************************
230 ** output parameters:
232 *********************************************************************************************************/
233 PUBLIC int32 I2C_HAL_Close (uint32 handle)
236 /*handle shouldn't larger than I2C_BUS_MAX*I2C_DEV_MAX*/
237 //SCI_ASSERT ( ( (I2C_BUS_MAX * I2C_DEV_MAX > handle) && (0 <= handle)));/*assert verified*/
239 /*this handle is already closed*/
240 if (0 == __i2c_dev[handle].freq)
245 bus_id = __i2c_dev[handle].bus;
247 if (1 == __i2c_bus[bus_id].reference)
249 I2C_Bus_Exit (bus_id);
253 __i2c_bus[bus_id].reference--;
256 /*release the handle*/
257 __i2c_dev[handle].id = 0;
258 __i2c_dev[handle].freq = 0;
259 __i2c_dev[handle].slave_addr = 0;
260 __i2c_dev[handle].reg_addr_num = 0;
261 __i2c_dev[handle].check_ack = 0;
262 __i2c_dev[handle].no_stop = 0;
267 /*********************************************************************************************************
274 ** output parameters:
276 *********************************************************************************************************/
277 PUBLIC uint32 I2C_HAL_Read (uint32 handle, uint8 *reg_addr, uint8 *buffer, uint32 bytes)
283 /*handle shouldn't larger than I2C_BUS_MAX*I2C_DEV_MAX*/
284 //SCI_ASSERT ( ( (I2C_BUS_MAX * I2C_DEV_MAX > handle) && (0 <= handle)));/*assert verified*/
285 //SCI_ASSERT (NULL != buffer);/*assert verified*/
286 //SCI_ASSERT (0 < bytes);/*assert verified*/
287 /*the handle has destroied*/
288 //SCI_ASSERT (0 != __i2c_dev[handle].freq);/*assert verified*/
289 bus_id = __i2c_dev[handle].bus;
290 port_id = __i2c_phy_cfg[__i2c_dev[handle].id].port_id;
292 //I2C_GetMutex (__i2c_bus[bus_id].mutex);
294 /*set i2c controller*/
295 if ( (__i2c_bus[bus_id].current_freq != __i2c_dev[handle].freq) ||
296 (__i2c_bus[bus_id].current_port != port_id))
298 __i2c_bus[bus_id].phy_fun->init (bus_id, __i2c_dev[handle].freq, port_id);
299 __i2c_bus[bus_id].current_freq = __i2c_dev[handle].freq;
300 __i2c_bus[bus_id].current_port = port_id;
307 /*this is for combined format*/
308 if (0 < __i2c_dev[handle].reg_addr_num)
310 //SCI_ASSERT (NULL != reg_addr);/*assert verified*/
312 ret_val = __i2c_bus[bus_id].phy_fun->start (bus_id, __i2c_dev[handle].slave_addr, 0, __i2c_dev[handle].check_ack);
314 if (ERR_I2C_NONE != ret_val)
319 /*write i2c slave device's sub address*/
320 ret_val = __i2c_bus[bus_id].phy_fun->write (bus_id, reg_addr, __i2c_dev[handle].reg_addr_num, __i2c_dev[handle].check_ack, __i2c_dev[handle].no_stop);
322 if (ERR_I2C_NONE != ret_val)
329 ret_val = __i2c_bus[bus_id].phy_fun->start (bus_id, __i2c_dev[handle].slave_addr, 1, __i2c_dev[handle].check_ack);
331 if (ERR_I2C_NONE != ret_val)
336 /*read data and stop bus*/
337 ret_val = __i2c_bus[bus_id].phy_fun->read (bus_id, buffer, bytes, __i2c_dev[handle].check_ack);
339 if (ERR_I2C_NONE != ret_val)
349 //I2C_PutMutex (__i2c_bus[bus_id].mutex);
353 /*********************************************************************************************************
360 ** output parameters:
362 *********************************************************************************************************/
363 PUBLIC uint32 I2C_HAL_Write (uint32 handle, uint8 *reg_addr, uint8 *buffer, uint32 bytes)
369 /*handle shouldn't larger than I2C_BUS_MAX*I2C_DEV_MAX*/
370 //SCI_ASSERT ( ( (I2C_BUS_MAX * I2C_DEV_MAX > handle) && (0 <= handle)));/*assert verified*/
371 //SCI_ASSERT (NULL != buffer);/*assert verified*/
372 //SCI_ASSERT (0 < bytes);/*assert verified*/
373 /*the handle has destroied*/
374 //SCI_ASSERT (0 != __i2c_dev[handle].freq);/*assert verified*/
375 bus_id = __i2c_dev[handle].bus;
376 port_id = __i2c_phy_cfg[__i2c_dev[handle].id].port_id;
378 //I2C_GetMutex (__i2c_bus[bus_id].mutex);
380 /*set i2c controller*/
381 if ( (__i2c_bus[bus_id].current_freq != __i2c_dev[handle].freq) ||
382 (__i2c_bus[bus_id].current_port != port_id))
384 __i2c_bus[bus_id].phy_fun->init (bus_id, __i2c_dev[handle].freq, port_id);
385 __i2c_bus[bus_id].current_freq = __i2c_dev[handle].freq;
386 __i2c_bus[bus_id].current_port = port_id;
393 ret_val = __i2c_bus[bus_id].phy_fun->start (bus_id, __i2c_dev[handle].slave_addr, 0, __i2c_dev[handle].check_ack);
395 if (ERR_I2C_NONE != ret_val)
400 /*write i2c slave device's sub address*/
401 if (0 < __i2c_dev[handle].reg_addr_num)
403 //SCI_ASSERT (NULL != reg_addr);/*assert verified*/
404 ret_val = __i2c_bus[bus_id].phy_fun->write (bus_id, reg_addr, __i2c_dev[handle].reg_addr_num, __i2c_dev[handle].check_ack, 2);
406 if (ERR_I2C_NONE != ret_val)
412 /*write i2c slave device's data and stop bus*/
413 ret_val = __i2c_bus[bus_id].phy_fun->write (bus_id, buffer, bytes, __i2c_dev[handle].check_ack, 0);
415 if (ERR_I2C_NONE != ret_val)
425 //I2C_PutMutex (__i2c_bus[bus_id].mutex);
429 /*********************************************************************************************************
436 ** output parameters:
438 *********************************************************************************************************/
439 PUBLIC uint32 I2C_HAL_Ioctl (uint32 handle, uint32 cmd, uint32 *arg)
443 /*handle shouldn't larger than I2C_BUS_MAX*I2C_DEV_MAX*/
444 //SCI_ASSERT ( ( (I2C_BUS_MAX * I2C_DEV_MAX > handle) && (0 <= handle)));/*assert verified*/
445 //SCI_ASSERT (NULL != arg);/*assert verified*/
446 bus_id = __i2c_dev[handle].bus;
451 *arg = __i2c_dev[handle].freq;
454 __i2c_dev[handle].freq = *arg;
457 *arg = __i2c_dev[handle].id;
460 __i2c_dev[handle].id = *arg;
462 case I2C_CTL_STOP_BUS:
464 // I2C_GetMutex (__i2c_bus[bus_id].mutex);
465 ret_val = __i2c_bus[bus_id].phy_fun->stop (bus_id);
467 // I2C_PutMutex (__i2c_bus[bus_id].mutex);
476 /**---------------------------------------------------------------------------*
478 **---------------------------------------------------------------------------*/