blob: 5d50928b4a255a201bd24b05d2c84cd28585a023 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2005
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35
36/*****************************************************************************
37 *
38 * Filename:
39 * ---------
40 * dcl_i2c.c
41 *
42 * Project:
43 * --------
44 * MOLYA_Software
45 *
46 * Description:
47 * ------------
48 * This Module defines DCL (Driver Common Layer) of the I2C driver.
49 *
50 * Author:
51 * -------
52 * -------
53 *
54 *============================================================================
55 * HISTORY
56 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
57 *------------------------------------------------------------------------------
58 * removed!
59 * removed!
60 * removed!
61 *
62 * removed!
63 *------------------------------------------------------------------------------
64 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
65 *============================================================================
66 ****************************************************************************/
67
68#include "drv_features.h"
69#include "drv_comm.h"
70
71#include "dcl.h"
72
73#include "kal_general_types.h"
74#include "dcl_i2c_owner.h"
75#include "drv_i2c.h"
76#include "kal_public_api.h"
77
78#if !defined(DRV_I2C_OFF)
79
80// Global variable for DCL I2C API usage
81#define DCL_I2C_DEV_MAGIC_NUM (0x50000000)
82#define MAX_DCL_I2C_HANDLE DCL_I2C_NUM_OF_OWNER
83
84extern i2c_handle_struct i2c_handle[DCL_I2C_NUM_OF_OWNER];
85extern i2c_status_struct dcl_i2c_status;
86
87DCL_STATUS _ConvertDclReturnStatus(I2C_TRANSACTION_RESULT result)
88{
89 if (result == I2C_TRANSACTION_COMPLETE)
90 {
91 return STATUS_OK;
92 }
93 else
94 {
95 if (result == I2C_TRANSACTION_IS_BUSY)
96 return STATUS_DEVICE_IS_BUSY;
97 else if (result == I2C_TRANSACTION_ACKERR)
98 return STATUS_ACKERR;
99 else if (result == I2C_TRANSACTION_HS_NACKERR)
100 return STATUS_HS_NACKERR;
101 else
102 return STATUS_FAIL;
103 }
104
105 //return STATUS_OK;
106}
107
108
109/*************************************************************************
110* FUNCTION
111* DclSI2C_Initialize
112*
113* DESCRIPTION
114* This function is to initialize S/W I2C module
115*
116* PARAMETERS
117* None
118*
119* RETURNS
120* STATUS_OK
121*
122*************************************************************************/
123DCL_STATUS DclSI2C_Initialize(void)
124{
125 //*/ DclSI2C_Initialize() should be called only once, when system init /*//
126 dcl_i2c_init();
127
128 return STATUS_OK;
129}
130
131/*************************************************************************
132* FUNCTION
133* DclSI2C_Open
134*
135* DESCRIPTION
136* This function is to open the I2C module and return a handle
137*
138* PARAMETERS
139* dev: only valid for DCL_I2C
140* flags: no sepcial flags is needed. Please use FLAGS_NONE
141*
142* RETURNS
143* DCL_HANDLE_INVALID: Open failed
144* Other value: A valid handle
145*
146*************************************************************************/
147
148DCL_HANDLE DclSI2C_Open(DCL_DEV dev, DCL_FLAGS flags)
149{
150 kal_uint32 i2c_owner = flags & 0xFF; //*/ DCL_I2C_OWNER should be transfered through the low 8bit of flags /*//
151
152 if (i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed) //*/ when system init or called DclSI2C_Close(), config->Fast_Mode_Speed == 0 /*//
153 {
154 return DCL_HANDLE_OCCUPIED; //*/ This Handle has been opened /*//
155 }
156
157 //*/ Tricky! when != 0, indicate that the owner has owned a handle, to avoid one owner call DclSI2C_Open() more than once. /*//
158 i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed = 1;
159
160 return (DCL_I2C_DEV_MAGIC_NUM | i2c_owner);
161}
162
163/*************************************************************************
164* FUNCTION
165* DclSI2C_ReadData
166*
167* DESCRIPTION
168* This function is not supported for the I2C module now.
169*
170* PARAMETERS
171* N/A
172*
173* RETURNS
174* STATUS_UNSUPPORTED
175*
176*************************************************************************/
177DCL_STATUS DclSI2C_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options){
178 return STATUS_UNSUPPORTED;
179}
180
181/*************************************************************************
182* FUNCTION
183* DclSI2C_WriteData
184*
185* DESCRIPTION
186* This function is not supported for the I2C module now.
187*
188* PARAMETERS
189* N/A
190*
191* RETURNS
192* STATUS_UNSUPPORTED
193*
194*************************************************************************/
195DCL_STATUS DclSI2C_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options){
196 return STATUS_UNSUPPORTED;
197}
198
199/*************************************************************************
200* FUNCTION
201* DclSI2C_Configure
202*
203* DESCRIPTION
204* This function is to configure the I2C module.
205*
206* PARAMETERS
207* handle: the returned handle value of DclSI2C_Open
208* configure: a structure which include the I2C configuration.
209*
210* RETURNS
211* STATUS_OK: Successfully configure I2C module.
212* STATUS_INVALID_DCL_HANDLE: It's a invalid handle.
213* STATUS_NOT_OPENED: The module has not been opened.
214* STATUS_INVALID_CONFIGURATION: The configuration is invalid.
215*
216*************************************************************************/
217DCL_STATUS DclSI2C_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure){
218
219 // Check magic number
220 if ((handle & DCL_I2C_DEV_MAGIC_NUM) != DCL_I2C_DEV_MAGIC_NUM)
221 {
222 MD_TRC(I2C_INVALID_HANDLE_MSG,__FUNCTION__, handle);
223 return STATUS_INVALID_DCL_HANDLE;
224 }
225
226 {
227 I2C_CONFIG_T* prI2CConfig = (I2C_CONFIG_T*) configure;
228 DCL_I2C_OWNER i2c_owner = prI2CConfig->eOwner;
229
230 //*/ check if the handle is opened /*//
231 if (i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed == 0)
232 {
233 MD_TRC(I2C_NOT_OPENED_MSG,__FUNCTION__);
234 return STATUS_NOT_OPENED;
235 }
236 // Check owner
237 if (i2c_owner >= (kal_uint8)DCL_I2C_NUM_OF_OWNER )
238 {
239 MD_TRC(I2C_INVALID_OWNER_MSG,__FUNCTION__,i2c_owner);
240 return STATUS_INVALID_CONFIGURATION;
241 }
242
243 i2c_handle[i2c_owner].i2c_config.get_handle_wait = (kal_bool)prI2CConfig->fgGetHandleWait;
244
245 i2c_handle[i2c_owner].i2c_config.slave_address = prI2CConfig->u1SlaveAddress;
246 i2c_handle[i2c_owner].i2c_config.delay_len = prI2CConfig->u1DelayLen;
247
248 i2c_handle[i2c_owner].i2c_config.transaction_mode = (I2C_TRANSACTION_MODE)prI2CConfig->eTransactionMode;
249
250 i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed = prI2CConfig->u4FastModeSpeed;
251 i2c_handle[i2c_owner].i2c_config.HS_Mode_Speed = prI2CConfig->u4HSModeSpeed;
252
253 MD_TRC(I2C_CONFIG_MSG,__FUNCTION__,i2c_owner,i2c_handle[i2c_owner].i2c_config.slave_address,i2c_handle[i2c_owner].i2c_config.transaction_mode,i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed,i2c_handle[i2c_owner].i2c_config.HS_Mode_Speed);
254 dcl_i2c_set_transaction_speed(i2c_owner,i2c_handle[i2c_owner].i2c_config.transaction_mode,&(i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed),&(i2c_handle[i2c_owner].i2c_config.HS_Mode_Speed));
255
256 prI2CConfig->u4FastModeSpeed = i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed;
257 prI2CConfig->u4HSModeSpeed = i2c_handle[i2c_owner].i2c_config.HS_Mode_Speed;
258 }
259
260 return STATUS_OK;
261}
262
263/*************************************************************************
264* FUNCTION
265* DclSI2C_RegisterCallback
266*
267* DESCRIPTION
268* This function is to set callback function for the I2C module.
269*
270* PARAMETERS
271* handle: the returned handle value of DclSI2C_Open
272* event: Supported events:
273* callback: the callback function for registered events
274*
275* RETURNS
276* STATUS_UNSUPPORTED
277*
278*************************************************************************/
279DCL_STATUS DclSI2C_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback){
280 return STATUS_UNSUPPORTED;
281}
282
283/*************************************************************************
284* FUNCTION
285* DclSI2C_Control
286*
287* DESCRIPTION
288* This function is to send command to control the I2C module.
289*
290* PARAMETERS
291* handle: The handle value returned from DclSI2C_Open
292* cmd: A control command for I2C module
293* 1. I2C_CMD_GET_TRANSACTION_MODE: to get transaction mode
294* 2. I2C_CMD_SET_TRANSACTION_SPEED: to set transaction speed
295* 3. I2C_CMD_SINGLE_WRITE: to perform a single WRITE
296* 4. I2C_CMD_SINGLE_READ: to perform a single READ
297* 5. I2C_CMD_CONT_WRITE: to perform a continuous WRITE
298* 6. I2C_CMD_CONT_READ: to perform a continuous READ
299* 7. I2C_CMD_WRITE_AND_READ: to perform a specific sequence "WRITE then READ"
300* 8. I2C_CMD_ENABLE_DMA: to enable/disable DMA
301* data: The data of the control command
302* 1. I2C_CMD_GET_TRANSACTION_MODE: pointer to a I2C_CTRL_GET_TRANSACTION_MODE_T structure
303* 2. I2C_CMD_SET_TRANSACTION_SPEED: pointer to a I2C_CTRL_SET_TRANSACTION_SPEED_T structure
304* 3. I2C_CMD_SINGLE_WRITE: pointer to a I2C_CTRL_SINGLE_WRITE_T structure
305* 4. I2C_CMD_SINGLE_READ: pointer to a I2C_CTRL_SINGLE_READ_T structure
306* 5. I2C_CMD_CONT_WRITE: pointer to a I2C_CTRL_CONT_WRITE_T structure
307* 6. I2C_CMD_CONT_READ: pointer to a I2C_CTRL_CONT_READ_T structure
308* 7. I2C_CMD_WRITE_AND_READ: pointer to a I2C_CTRL_WRITE_AND_READE_T structure
309* 8. I2C_CMD_ENABLE_DMA: pointer to a I2C_CTRL_ENABLE_DMA_T structure
310*
311* RETURNS
312* STATUS_OK: command is executed successfully.
313* STATUS_FAIL: command is failed.
314* STATUS_INVALID_CMD: It's a invalid command.
315*
316*************************************************************************/
317DCL_STATUS DclSI2C_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
318{
319 DCL_I2C_OWNER i2c_owner;
320
321 // Check magic number
322 if ((handle & DCL_I2C_DEV_MAGIC_NUM) != DCL_I2C_DEV_MAGIC_NUM)
323 {
324 MD_TRC(I2C_INVALID_HANDLE_MSG,__FUNCTION__, handle);
325 return STATUS_INVALID_DCL_HANDLE;
326 }
327
328 //*/ check if the handle is opened /*//
329 if ((i2c_handle[(kal_uint8)(handle & 0xFF)].i2c_config.Fast_Mode_Speed) == 0)
330 {
331 MD_TRC(I2C_NOT_OPENED_MSG,__FUNCTION__);
332 return STATUS_NOT_OPENED;
333 }
334
335 i2c_owner = (DCL_I2C_OWNER)(handle & 0xFF);
336 MD_TRC(I2C_CMD_MSG,cmd);
337 switch (cmd)
338 {
339 case I2C_CMD_GET_TRANSACTION_MODE:
340 {
341 I2C_CTRL_GET_TRANSACTION_MODE_T *prGetTransactionMode;
342 prGetTransactionMode = &(data->rGetTransactionMode);
343
344 prGetTransactionMode->eTransactionMode = (DCL_I2C_TRANSACTION_MODE)i2c_handle[i2c_owner].i2c_config.transaction_mode;
345 return STATUS_OK;
346 }
347 //break;
348 case I2C_CMD_SET_TRANSACTION_SPEED:
349 {
350 I2C_CTRL_SET_TRANSACTION_SPEED_T *prSetTransactionSpeed;
351 prSetTransactionSpeed = &(data->rSetTransactionSpeed);
352
353 i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed = prSetTransactionSpeed->u4FastModeSpeed;
354 i2c_handle[i2c_owner].i2c_config.HS_Mode_Speed = prSetTransactionSpeed->u4HSModeSpeed;
355
356 dcl_i2c_set_transaction_speed(i2c_owner,i2c_handle[i2c_owner].i2c_config.transaction_mode,&(i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed),&(i2c_handle[i2c_owner].i2c_config.HS_Mode_Speed));
357
358 prSetTransactionSpeed->u4FastModeSpeed = i2c_handle[i2c_owner].i2c_config.Fast_Mode_Speed;
359 prSetTransactionSpeed->u4HSModeSpeed = i2c_handle[i2c_owner].i2c_config.HS_Mode_Speed;
360
361 return STATUS_OK;
362 }
363 //break;
364 case I2C_CMD_SINGLE_WRITE:
365 case I2C_CMD_SINGLE_READ:
366 case I2C_CMD_CONT_WRITE:
367 case I2C_CMD_CONT_READ:
368 case I2C_CMD_WRITE_AND_READ:
369 {
370 kal_uint32 savedMask;
371 I2C_CTRL_SINGLE_WRITE_T *prSingleWrite;
372 I2C_CTRL_SINGLE_READ_T *prSingleRead;
373 I2C_CTRL_CONT_WRITE_T *prContWrite;
374 I2C_CTRL_CONT_READ_T *prContRead;
375 I2C_CTRL_WRITE_AND_READE_T *prWriteAndRead;
376
377 savedMask=dcl_i2c_wait_transaction_complete_and_lock(i2c_owner);
378 if (dcl_i2c_status.owner!=i2c_owner)
379 {
380 return STATUS_DEVICE_IS_BUSY;
381 }
382 switch(cmd){
383 case I2C_CMD_SINGLE_WRITE:
384 prSingleWrite= &(data->rSingleWrite);
385 dcl_i2c_hw_cfg (i2c_owner, I2C_TRANSACTION_WRITE, prSingleWrite->pu1Data, prSingleWrite->u4DataLen, NULL, 0, 1);
386 break;
387 case I2C_CMD_SINGLE_READ:
388 prSingleRead= &(data->rSingleRead);
389 dcl_i2c_hw_cfg (i2c_owner, I2C_TRANSACTION_READ, NULL, 0, prSingleRead->pu1Data, prSingleRead->u4DataLen, 1);
390 break;
391 case I2C_CMD_CONT_WRITE:
392
393 prContWrite = &(data->rContWrite);
394 dcl_i2c_hw_cfg (i2c_owner, I2C_TRANSACTION_CONT_WRITE, prContWrite->pu1Data, prContWrite->u4DataLen, NULL, 0, prContWrite->u4TransferNum);
395 break;
396 case I2C_CMD_CONT_READ:
397
398 prContRead= &(data->rContRead);
399 dcl_i2c_hw_cfg (i2c_owner, I2C_TRANSACTION_CONT_READ, NULL, 0, prContRead->pu1Data, prContRead->u4DataLen, prContRead->u4TransferNum);
400 break;
401 case I2C_CMD_WRITE_AND_READ:
402
403 prWriteAndRead= &(data->rWriteAndRead);
404 dcl_i2c_hw_cfg (i2c_owner, I2C_TRANSACTION_WRITE_AND_READ, prWriteAndRead->pu1OutData, prWriteAndRead->u4OutDataLen, prWriteAndRead->pu1InData, prWriteAndRead->u4InDataLen, 2);
405 break;
406 default:
407 break;
408 }
409 dcl_i2c_wait_transaction_complete(savedMask);
410 return _ConvertDclReturnStatus(i2c_handle[i2c_owner].transaction_result);
411 }
412 //break;
413 case I2C_CMD_SET_SLAVE_ADDRESS:
414 {
415 I2C_CTRL_SET_SLAVE_ADDRESS_T *prSetSlaveAddress;
416 prSetSlaveAddress = &(data->rSetSlaveAddress);
417
418 i2c_handle[i2c_owner].i2c_config.slave_address=prSetSlaveAddress->u1SlaveAddress;
419 return STATUS_OK;
420 }
421 // break;
422 default:
423 return STATUS_INVALID_CMD;
424 // break;
425 }
426 return STATUS_FAIL;
427}
428
429/*************************************************************************
430* FUNCTION
431* DclSI2C_Close
432*
433* DESCRIPTION
434* This function is to close the I2C module.
435*
436* PARAMETERS
437* handle: the returned handle value of DclSI2C_Open
438*
439* RETURNS
440* STATUS_OK
441*
442*************************************************************************/
443DCL_STATUS DclSI2C_Close(DCL_HANDLE handle)
444{
445 i2c_config_struct* config = &i2c_handle[(kal_uint8)(handle & 0xFF)].i2c_config;
446
447 // Check magic number
448 if ((handle & DCL_I2C_DEV_MAGIC_NUM) != DCL_I2C_DEV_MAGIC_NUM)
449 {
450 return STATUS_INVALID_DCL_HANDLE;
451 }
452
453 MD_TRC(I2C_CLOSE_MSG,__FUNCTION__);
454 //*/ check if the handle is opened, if i2c handle is opened, the related Fast_Mode_Speed not equal to zero /*//
455 if (config->Fast_Mode_Speed == 0)
456 {
457 return STATUS_NOT_OPENED;
458 }
459 dcl_i2c_deinit();
460 config->Fast_Mode_Speed = 0;
461
462 return STATUS_OK;
463}
464
465#else //#if (!defined(DRV_I2C_OFF) && defined(DCL_I2C_INTERFACE))
466
467DCL_STATUS DclSI2C_Initialize(void)
468{
469 return STATUS_FAIL;
470}
471
472DCL_HANDLE DclSI2C_Open(DCL_DEV dev, DCL_FLAGS flags)
473{
474 return 0;
475}
476DCL_STATUS DclSI2C_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
477{
478 return STATUS_UNSUPPORTED;
479}
480
481DCL_STATUS DclSI2C_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
482{
483 return STATUS_UNSUPPORTED;
484}
485
486DCL_STATUS DclSI2C_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
487{
488 return STATUS_FAIL;
489}
490
491DCL_STATUS DclSI2C_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
492{
493 return STATUS_UNSUPPORTED;
494}
495
496DCL_STATUS DclSI2C_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
497{
498 return STATUS_FAIL;
499}
500DCL_STATUS DclSI2C_Close(DCL_HANDLE handle)
501{
502 return STATUS_FAIL;
503}
504#endif
505