tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / i2c / i2c_hal.c
1 /******************************************************************************
2  ** File Name:      I2C_drv.c                                                *
3  ** Author:         liuhao                                                   *
4  ** DATE:           06/28/2010                                                *
5  ** Copyright:      2010 Spreatrum, Incoporated. All Rights Reserved.         *
6  ** Description:    This file define the hal layer of I2C device.      *
7  ******************************************************************************
8
9  ******************************************************************************
10  **                        Edit History                                       *
11  ** ------------------------------------------------------------------------- *
12  ** DATE           NAME             DESCRIPTION                               *
13  ** 06/28/2010     liuhao     Create.                                   *
14  ******************************************************************************/
15
16 /**---------------------------------------------------------------------------*
17  **                         Dependencies                                      *
18  **---------------------------------------------------------------------------*/
19 #include "asm/arch/sci_types.h"
20 //#include "os_api.h"
21 //#include "chip_plf_export.h"
22 #include "sp8830_i2c.h"
23 #include "sc8830_i2c_cfg.h"
24
25 /**---------------------------------------------------------------------------*
26  **                         Debugging Flag                                    *
27  **---------------------------------------------------------------------------*/
28
29 /**---------------------------------------------------------------------------*
30  **                         Compiler Flag                                     *
31  **---------------------------------------------------------------------------*/
32 #ifdef   __cplusplus
33 extern   "C"
34 {
35 #endif
36
37 /**---------------------------------------------------------------------------*
38  **                            Macro Define
39  **---------------------------------------------------------------------------*/
40 typedef struct
41 {
42     //SCI_MUTEX_PTR mutex;
43     uint32 current_port;
44     uint32 current_freq;
45     uint32 reference;
46     I2C_PHY_FUN *phy_fun;
47 } I2C_BUS;
48
49 /*
50 #define I2C_GetMutex(mutex)  {\
51         uint32 ret = SCI_SUCCESS;\
52         if( NULL == mutex )\
53         {\
54             return ERR_I2C_NO_MUTEX;\
55         }\
56         if(SCI_InThreadContext())\
57         {\
58             ret = SCI_GetMutex(mutex, SCI_INVALID_BLOCK_ID != SCI_IdentifyThread() ? SCI_WAIT_FOREVER : 0);\
59         }\
60         SCI_ASSERT( ret == SCI_SUCCESS );//assert verified\
61     }
62
63 #define I2C_PutMutex(mutex)  {\
64         uint32 ret = SCI_SUCCESS;\
65         if( NULL == mutex )\
66         {\
67             return ERR_I2C_NO_MUTEX;\
68         }\
69         if(SCI_InThreadContext())\
70         {\
71             ret = SCI_PutMutex( mutex );\
72         }\
73         SCI_ASSERT( ret == SCI_SUCCESS );//assert verified\
74     }
75 */
76 /**---------------------------------------------------------------------------*
77  **                            Local Variables
78  **---------------------------------------------------------------------------*/
79 LOCAL I2C_DEV __i2c_dev[I2C_BUS_MAX *I2C_DEV_MAX];
80
81 /**---------------------------------------------------------------------------*
82  **                            Global Variables
83  **---------------------------------------------------------------------------*/
84 I2C_BUS __i2c_bus[I2C_BUS_MAX];
85 extern const I2C_PHY_CFG __i2c_phy_cfg[I2C_ID_MAX];
86
87 /**---------------------------------------------------------------------------*
88  **                      Function  Definitions
89  **---------------------------------------------------------------------------*/
90 /*********************************************************************************************************
91 ** Function name:
92 ** Descriptions:
93 ** input parameters:
94 **
95 **
96 **
97 ** output parameters:
98 ** Returned value:
99 *********************************************************************************************************/
100 LOCAL uint32 I2C_Bus_CFG (uint32 logic_id)
101 {
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;
105     return 0;
106 }
107 /*********************************************************************************************************
108 ** Function name:
109 ** Descriptions:
110 ** input parameters:
111 **
112 **
113 **
114 ** output parameters:
115 ** Returned value:
116 *********************************************************************************************************/
117 LOCAL uint32 I2C_Bus_Init (uint32 logic_id, uint32 freq, uint32 port_id)
118 {
119     uint32 bus_id = __i2c_phy_cfg[logic_id].phy_id;
120     IIC_PRINT ("[IIC DRV:]I2C_Bus_Init");
121     /*config bus property*/
122     __i2c_bus[bus_id].current_freq = freq;
123     __i2c_bus[bus_id].current_port = port_id;
124     //__i2c_bus[bus_id].mutex = SCI_CreateMutex ("I2C SYNC MUTEX", SCI_INHERIT);
125     //SCI_PASSERT ( (NULL!= __i2c_bus[bus_id].mutex), ("I2C Great MUTEX fail!"));/*assert verified*/
126     /*config bus method*/
127     I2C_Bus_CFG (logic_id);
128     return 0;
129 }
130
131 /*********************************************************************************************************
132 ** Function name:
133 ** Descriptions:
134 ** input parameters:
135 **
136 **
137 **
138 ** output parameters:
139 ** Returned value:
140 *********************************************************************************************************/
141 LOCAL uint32 I2C_Bus_Exit (uint32 bus_id)
142 {
143     uint32 status_val = 0;
144     __i2c_bus[bus_id].reference =  0;
145
146 /*
147     if (NULL != __i2c_bus[bus_id].mutex)
148     {
149         status_val = SCI_DeleteMutex (__i2c_bus[bus_id].mutex);
150         //SCI_PASSERT((0 != status_val),("I2C delete MUTEX fail!"));
151         __i2c_bus[bus_id].mutex = NULL;
152     }
153 */
154     IIC_PRINT ("[IIC DRV:]I2C_Bus_Exit: status=%d", status_val);
155     /*release the bus method*/
156     __i2c_bus[bus_id].phy_fun = NULL;
157     return 0;
158 }
159
160 /*********************************************************************************************************
161 ** Function name: I2C_HAL_Open
162 ** Descriptions: i2c bus open function
163 ** input parameters:
164 **      dev - pointer of i2c slave dev
165 **
166 **
167 ** output parameters: NONE
168 ** Returned value: handle
169 *********************************************************************************************************/
170 PUBLIC int32 I2C_HAL_Open (I2C_DEV *dev)
171 {
172     uint32 handle;
173     uint32 bus_id;
174     uint32 port_id;
175     uint32 idx = 0;
176     int32 i =0;
177     //SCI_ASSERT (NULL != dev);/*assert verified*/
178     /*check if use the wrong port number*/
179    //SCI_ASSERT ( ( (I2C_ID_MAX > dev->id) && (0 <= dev->id)));/*assert verified*/
180     /*now we should get the i2c bus id and the controller's port id*/
181     bus_id = __i2c_phy_cfg[dev->id].phy_id;
182     port_id = __i2c_phy_cfg[dev->id].port_id;
183     /*reference shouldn't larger than I2C_DEV_MAX*/
184     //SCI_ASSERT ( ( (I2C_DEV_MAX > __i2c_bus[bus_id].reference) && (0 <= __i2c_bus[bus_id].reference)));/*assert verified*/
185
186     /*look for the handle: return the 1st available array member*/
187     for (i=0; i< I2C_DEV_MAX; i++)
188     {
189         if (0 == __i2c_dev[idx + bus_id * I2C_DEV_MAX].freq)
190         {
191             break;
192         }
193
194         idx++;
195
196         if (I2C_DEV_MAX == idx)
197         {
198             return -1;
199         }
200     }
201
202     /*caculate handle*/
203     handle = idx + bus_id * I2C_DEV_MAX;
204     /*set the parameters for i2c slave device*/
205     __i2c_dev[handle].id = dev->id;
206     __i2c_dev[handle].freq = dev->freq;
207     __i2c_dev[handle].bus = bus_id;
208     __i2c_dev[handle].slave_addr = dev->slave_addr;
209     __i2c_dev[handle].reg_addr_num = dev->reg_addr_num;
210     __i2c_dev[handle].check_ack = dev->check_ack;
211     __i2c_dev[handle].no_stop = dev->no_stop;
212
213     /*first open, than init i2c controller*/
214     if (0 == __i2c_bus[bus_id].reference)
215     {
216         I2C_Bus_Init (dev->id, dev->freq, port_id);
217         __i2c_bus[bus_id].phy_fun->init (bus_id, dev->freq, port_id);
218     }
219
220     __i2c_bus[bus_id].reference++;
221
222     IIC_PRINT ("[IIC DRV:]I2C_HAL_Open: handle=%d, ref=%d", handle, __i2c_bus[bus_id].reference);
223
224     return  handle;
225 }
226
227 /*********************************************************************************************************
228 ** Function name:
229 ** Descriptions:
230 ** input parameters:
231 **
232 **
233 **
234 ** output parameters:
235 ** Returned value:
236 *********************************************************************************************************/
237 PUBLIC int32 I2C_HAL_Close (uint32 handle)
238 {
239     uint32 bus_id;
240     /*handle shouldn't larger than I2C_BUS_MAX*I2C_DEV_MAX*/
241     //SCI_ASSERT ( ( (I2C_BUS_MAX * I2C_DEV_MAX > handle) && (0 <= handle)));/*assert verified*/
242
243     /*this handle is already closed*/
244     if (0 == __i2c_dev[handle].freq)
245     {
246         return -1;
247     }
248
249     bus_id = __i2c_dev[handle].bus;
250
251     if (1 == __i2c_bus[bus_id].reference)
252     {
253         I2C_Bus_Exit (bus_id);
254     }
255     else
256     {
257         __i2c_bus[bus_id].reference--;
258     }
259
260     /*release the handle*/
261     __i2c_dev[handle].id = 0;
262     __i2c_dev[handle].freq = 0;
263     __i2c_dev[handle].slave_addr = 0;
264     __i2c_dev[handle].reg_addr_num = 0;
265     __i2c_dev[handle].check_ack = 0;
266     __i2c_dev[handle].no_stop = 0;
267
268     IIC_PRINT ("[IIC DRV:]I2C_HAL_Close: handle=%d, ref=%d", handle, __i2c_bus[bus_id].reference);
269
270     return  0;
271 }
272
273 /*********************************************************************************************************
274 ** Function name:
275 ** Descriptions:
276 ** input parameters:
277 **
278 **
279 **
280 ** output parameters:
281 ** Returned value:
282 *********************************************************************************************************/
283 PUBLIC uint32 I2C_HAL_Read (uint32 handle, uint8 *reg_addr, uint8 *buffer, uint32 bytes)
284 {
285     uint32 ret_val;
286     uint32 bus_id;
287     uint32 port_id;
288     uint32 err_code;
289     /*handle shouldn't larger than I2C_BUS_MAX*I2C_DEV_MAX*/
290     //SCI_ASSERT ( ( (I2C_BUS_MAX * I2C_DEV_MAX > handle) && (0 <= handle)));/*assert verified*/
291     //SCI_ASSERT (NULL != buffer);/*assert verified*/
292     //SCI_ASSERT (0 < bytes);/*assert verified*/
293     /*the handle has destroied*/
294     //SCI_ASSERT (0 != __i2c_dev[handle].freq);/*assert verified*/
295     bus_id = __i2c_dev[handle].bus;
296     port_id = __i2c_phy_cfg[__i2c_dev[handle].id].port_id;
297     /*get i2c bus*/
298     //I2C_GetMutex (__i2c_bus[bus_id].mutex);
299
300     /*set i2c controller*/
301     if ( (__i2c_bus[bus_id].current_freq != __i2c_dev[handle].freq) ||
302             (__i2c_bus[bus_id].current_port != port_id))
303     {
304         __i2c_bus[bus_id].phy_fun->init (bus_id,  __i2c_dev[handle].freq, port_id);
305         __i2c_bus[bus_id].current_freq = __i2c_dev[handle].freq;
306         __i2c_bus[bus_id].current_port = port_id;
307     }
308
309     do
310     {
311         err_code = 0;
312
313         /*this is for combined format*/
314         if (0 < __i2c_dev[handle].reg_addr_num)
315         {
316             //SCI_ASSERT (NULL != reg_addr);/*assert verified*/
317             /*start i2c bus*/
318             ret_val = __i2c_bus[bus_id].phy_fun->start (bus_id, __i2c_dev[handle].slave_addr, 0, __i2c_dev[handle].check_ack);
319
320             if (ERR_I2C_NONE != ret_val)
321             {
322                 break;
323             }
324
325             /*write i2c slave device's sub address*/
326             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);
327
328             if (ERR_I2C_NONE != ret_val)
329             {
330                 break;
331             }
332         }
333
334         /*restart i2c bus*/
335         ret_val = __i2c_bus[bus_id].phy_fun->start (bus_id, __i2c_dev[handle].slave_addr, 1, __i2c_dev[handle].check_ack);
336
337         if (ERR_I2C_NONE != ret_val)
338         {
339             break;
340         }
341
342         /*read data and stop bus*/
343         ret_val = __i2c_bus[bus_id].phy_fun->read (bus_id, buffer, bytes, __i2c_dev[handle].check_ack);
344
345         if (ERR_I2C_NONE != ret_val)
346         {
347             break;
348         }
349
350         err_code = bytes;
351     }
352     while (0);
353
354     /*release i2c bus*/
355     //I2C_PutMutex (__i2c_bus[bus_id].mutex);
356     return  err_code;
357 }
358
359 /*********************************************************************************************************
360 ** Function name:
361 ** Descriptions:
362 ** input parameters:
363 **
364 **
365 **
366 ** output parameters:
367 ** Returned value:
368 *********************************************************************************************************/
369 PUBLIC uint32 I2C_HAL_Write (uint32 handle, uint8 *reg_addr, uint8 *buffer, uint32 bytes)
370 {
371     uint32 ret_val;
372     uint32 bus_id;
373     uint32 port_id;
374     uint32 err_code;
375     /*handle shouldn't larger than I2C_BUS_MAX*I2C_DEV_MAX*/
376     //SCI_ASSERT ( ( (I2C_BUS_MAX * I2C_DEV_MAX > handle) && (0 <= handle)));/*assert verified*/
377     //SCI_ASSERT (NULL != buffer);/*assert verified*/
378     //SCI_ASSERT (0 < bytes);/*assert verified*/
379     /*the handle has destroied*/
380     //SCI_ASSERT (0 != __i2c_dev[handle].freq);/*assert verified*/
381     bus_id = __i2c_dev[handle].bus;
382     port_id = __i2c_phy_cfg[__i2c_dev[handle].id].port_id;
383     /*get i2c bus*/
384     //I2C_GetMutex (__i2c_bus[bus_id].mutex);
385
386     /*set i2c controller*/
387     if ( (__i2c_bus[bus_id].current_freq != __i2c_dev[handle].freq) ||
388             (__i2c_bus[bus_id].current_port != port_id))
389     {
390         __i2c_bus[bus_id].phy_fun->init (bus_id, __i2c_dev[handle].freq, port_id);
391         __i2c_bus[bus_id].current_freq = __i2c_dev[handle].freq;
392         __i2c_bus[bus_id].current_port = port_id;
393     }
394
395     do
396     {
397         err_code = 0;
398         /*start i2c bus*/
399         ret_val = __i2c_bus[bus_id].phy_fun->start (bus_id, __i2c_dev[handle].slave_addr, 0, __i2c_dev[handle].check_ack);
400
401         if (ERR_I2C_NONE != ret_val)
402         {
403             break;
404         }
405
406         /*write i2c slave device's sub address*/
407         if (0 < __i2c_dev[handle].reg_addr_num)
408         {
409             //SCI_ASSERT (NULL != reg_addr);/*assert verified*/
410             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);
411
412             if (ERR_I2C_NONE != ret_val)
413             {
414                 break;
415             }
416         }
417
418         /*write i2c slave device's data and stop bus*/
419         ret_val = __i2c_bus[bus_id].phy_fun->write (bus_id, buffer, bytes, __i2c_dev[handle].check_ack, 0);
420
421         if (ERR_I2C_NONE != ret_val)
422         {
423             break;
424         }
425
426         err_code = bytes;
427     }
428     while (0);
429
430     /*release i2c bus*/
431     //I2C_PutMutex (__i2c_bus[bus_id].mutex);
432     return  err_code;
433 }
434
435 /*********************************************************************************************************
436 ** Function name:
437 ** Descriptions:
438 ** input parameters:
439 **
440 **
441 **
442 ** output parameters:
443 ** Returned value:
444 *********************************************************************************************************/
445 PUBLIC uint32 I2C_HAL_Ioctl (uint32 handle, uint32 cmd, uint32 *arg)
446 {
447     uint32 ret_val = 0;
448     uint32 bus_id;
449     /*handle shouldn't larger than I2C_BUS_MAX*I2C_DEV_MAX*/
450     //SCI_ASSERT ( ( (I2C_BUS_MAX * I2C_DEV_MAX > handle) && (0 <= handle)));/*assert verified*/
451     //SCI_ASSERT (NULL != arg);/*assert verified*/
452     bus_id = __i2c_dev[handle].bus;
453
454     switch (cmd)
455     {
456         case I2C_CTL_G_FREQ:
457             *arg = __i2c_dev[handle].freq;
458             break;
459         case I2C_CTL_S_FREQ:
460             __i2c_dev[handle].freq = *arg;
461             break;
462         case I2C_CTL_G_PORT:
463             *arg = __i2c_dev[handle].id;
464             break;
465         case I2C_CTL_S_PORT:
466             __i2c_dev[handle].id = *arg;
467             break;
468         case I2C_CTL_STOP_BUS:
469             /*get i2c bus*/
470            // I2C_GetMutex (__i2c_bus[bus_id].mutex);
471             ret_val = __i2c_bus[bus_id].phy_fun->stop (bus_id);
472             /*release i2c bus*/
473            // I2C_PutMutex (__i2c_bus[bus_id].mutex);
474             break;
475         default:
476             break;
477     }
478
479     return  ret_val;
480 }
481
482 /**---------------------------------------------------------------------------*
483  **                         Compiler Flag                                     *
484  **---------------------------------------------------------------------------*/
485 #ifdef   __cplusplus
486 }
487 #endif
488 /*  End Of File */