1 #include <linux/kernel.h>
2 #include <linux/string.h>
3 #include <linux/slab.h>
4
5 #include <linux/uaccess.h>
6 #include <linux/compat.h>
7 #include "MsTypes.h"
8 #include "utopia.h"
9 #include "drvHWI2C.h"
10 #include "drvHWI2C_v2.h"
11 #include "HWI2C_adp.h"
12 #include "utopia_adp.h"
13 #include "drvHWI2C_private.h"
14
15 // no pointer member
16 //UADP_SPT_0NXT_DEF(MS_U8);
17 //UADP_SPT_0NXT_DEF(HWI2C_Status);
18 extern void* spt_MS_U8;
19
20 //#define CONFIG_COMPAT
21 #define MSOS_TYPE_LINUX_KERNEL
22 //------------------------------------------------------------------------------
23 // Global Variables
24 //------------------------------------------------------------------------------
25
26 #ifdef CONFIG_COMPAT
27 typedef struct DLL_PACKED
28 {
29 MS_U16 u16SlaveCfg;
30 MS_U32 uAddrCnt;
31 compat_uptr_t pRegAddr;
32 MS_U32 uSize;
33 compat_uptr_t pData;
34 MS_BOOL bReturn;
35 } _compat_stHWI2C_PRIVATE_PARAM_WriteBytes;
36
37 typedef struct DLL_PACKED
38 {
39 MS_U16 u16SlaveCfg;
40 MS_U32 uAddrCnt;
41 compat_uptr_t pRegAddr;
42 MS_U32 uSize;
43 compat_uptr_t pData;
44 MS_BOOL bReturn;
45 } _compat_stHWI2C_PRIVATE_PARAM_ReadBytes;
46 #endif
47
48
49 //------------------------------------------------------------------------------
50 // Local Defines
51 //------------------------------------------------------------------------------
52
53
54 //------------------------------------------------------------------------------
55 // Local Defines
56 //------------------------------------------------------------------------------
57
58 #ifdef MSOS_TYPE_LINUX_KERNEL
59 #define CPY_FROM_USER(a,b,c) if(copy_from_user(a,b,c) != 0) { break; }
60 #define CPY_to_USER(a,b,c) if(copy_to_user(a,b,c) != 0) { break; }
61 #else
62 #define CPY_FROM_USER memcpy
63 #define CPY_to_USER memcpy
64 #endif //MSOS_TYPE_LINUX_KERNEL
65
66 #if (defined(MSOS_TYPE_LINUX_KERNEL) && defined(CONFIG_COMPAT))
67 #define COMPAT_PTR(a) compat_ptr(a)
68 #define COMPAT_NEXT_PTR(a) (*((MS_U32*)compat_ptr((unsigned long)a)))
69 #define IS_CMP_TASK() is_compat_task()
70
71 #define CMP_CPY_FROM_USER(a,b,c) if(copy_from_user(a, compat_ptr((unsigned long)b), c) != 0) { break; }
72 #define CMP_CPY_TO_USER(a,b,c) if(copy_to_user(compat_ptr((unsigned long)a), b, c) != 0) { break; }
73
74 #else
75 #define COMPAT_PTR(a) (a)
76 #define COMPAT_NEXT_PTR(a) (*((MS_U32*)a))
77 #define IS_CMP_TASK() (FALSE)
78 #define CMP_CPY_FROM_USER CPY_FROM_USER
79 #define CMP_CPY_TO_USER CPY_to_USER
80 #endif //CONFIG_COMPAT
81
82
83 UADP_SPT_0NXT_DEF(HWI2C_UnitCfg);
84
85
86 UADP_SPT_0NXT_DEF(HWI2C_PRIVATE_PARAM_SelectPort);
87 UADP_SPT_0NXT_DEF(HWI2C_PRIVATE_PARAM_SetClk);
88 //UADP_SPT_0NXT_DEF(HWI2C_PRIVATE_PARAM_SetReadMode);
89 //UADP_SPT_0NXT_DEF(HWI2C_PRIVATE_PARAM_WriteByte);
90 //UADP_SPT_0NXT_DEF(HWI2C_PRIVATE_PARAM_SelectPort1);
91 //UADP_SPT_0NXT_DEF(HWI2C_PRIVATE_PARAM_SetClkP1);
92 //UADP_SPT_0NXT_DEF(HWI2C_PRIVATE_PARAM_SetReadModeP1);
93 //UADP_SPT_0NXT_DEF(HWI2C_PRIVATE_PARAM_WriteByteP1);
94 //UADP_SPT_0NXT_DEF(HWI2C_PRIVATE_PARAM_SetDbgLevel);
95 // one pointer member
96
97 //UADP_SPT_1NXT_DEF(HWI2C_PRIVATE_PARAM_Init);
98 //UADP_SPT_1NXT_DEF(HWI2C_PRIVATE_PARAM_GetPortIndex);
99 //UADP_SPT_1NXT_DEF(HWI2C_PRIVATE_PARAM_ReadByte);
100 //UADP_SPT_1NXT_DEF(HWI2C_PRIVATE_PARAM_ReadByteP1);
101 //UADP_SPT_1NXT_DEF(HWI2C_PRIVATE_PARAM_GetLibVer);
102 //UADP_SPT_1NXT_DEF(HWI2C_PRIVATE_PARAM_GetStatus);
103 // two pointer member
104 //UADP_SPT_2NXT_DEF(HWI2C_PRIVATE_PARAM_WriteBytes);
105 //UADP_SPT_2NXT_DEF(HWI2C_PRIVATE_PARAM_ReadBytes);
106 //UADP_SPT_2NXT_DEF(HWI2C_PRIVATE_PARAM_WriteBytesP1);
107 //UADP_SPT_2NXT_DEF(HWI2C_PRIVATE_PARAM_ReadBytesP1);
108
109 UADP_SDT_0_DEF(IIC_CFG_INIT);
110 UADP_SDT_1_DEF(HWIIC_PRIVATE_INIT);
111
112
HWI2C_adp_Init(FUtopiaIOctl * pIoctl)113 MS_U32 HWI2C_adp_Init(FUtopiaIOctl* pIoctl)
114 {
115 //member of struct
116 UADP_SPT_0NXT(HWI2C_UnitCfg);
117 //set table
118 UADP_SPT_0NXT(HWI2C_PRIVATE_PARAM_SelectPort);
119 UADP_SPT_0NXT(HWI2C_PRIVATE_PARAM_SetClk);
120 // UADP_SPT_0NXT(HWI2C_PRIVATE_PARAM_SetReadMode);
121 // UADP_SPT_0NXT(HWI2C_PRIVATE_PARAM_WriteByte);
122 // UADP_SPT_0NXT(HWI2C_PRIVATE_PARAM_SelectPort1);
123 // UADP_SPT_0NXT(HWI2C_PRIVATE_PARAM_SetClkP1);
124 // UADP_SPT_0NXT(HWI2C_PRIVATE_PARAM_SetReadModeP1);
125 // UADP_SPT_0NXT(HWI2C_PRIVATE_PARAM_WriteByteP1);
126 // UADP_SPT_0NXT(HWI2C_PRIVATE_PARAM_SetDbgLevel);
127
128 //UADP_SPT_1NXT(HWI2C_PRIVATE_PARAM_Init, psCfg, HWI2C_UnitCfg);
129 // UADP_SPT_1NXT(HWI2C_PRIVATE_PARAM_GetPortIndex, pu8Port, MS_U8);
130 // UADP_SPT_1NXT(HWI2C_PRIVATE_PARAM_ReadByte, pData, MS_U8);
131 // UADP_SPT_1NXT(HWI2C_PRIVATE_PARAM_ReadByteP1, pData, MS_U8);
132 //UADP_SPT_1NXT(HWI2C_PRIVATE_PARAM_GetLibVer, ppVersion, MSIF_Version);
133 // UADP_SPT_1NXT(HWI2C_PRIVATE_PARAM_GetStatus, pStatus, HWI2C_Status);
134
135 //UADP_SPT_2NXT(HWI2C_PRIVATE_PARAM_WriteBytes, pRegAddr, MS_U8, pData, MS_U8);
136 //UADP_SPT_2NXT(HWI2C_PRIVATE_PARAM_ReadBytes, pRegAddr, MS_U8, pData, MS_U8);
137 // UADP_SPT_2NXT(HWI2C_PRIVATE_PARAM_WriteBytesP1, pRegAddr, MS_U8, pData, MS_U8);
138 // UADP_SPT_2NXT(HWI2C_PRIVATE_PARAM_ReadBytesP1, pRegAddr, MS_U8, pData, MS_U8);
139 //set table
140
141 UADP_SDT_NAME0(IIC_CFG_INIT,HWI2C_UnitCfg);
142 UADP_SDT_NAME1(HWIIC_PRIVATE_INIT,HWI2C_PRIVATE_PARAM_Init,UADP_SDT_P2N,psCfg,IIC_CFG_INIT);
143
144 *pIoctl= (FUtopiaIOctl)HWI2C_adp_Ioctl;
145 return 0;
146 }
147
HWI2C_adp_Ioctl(void * pInstanceTmp,MS_U32 u32Cmd,void * const pArgs)148 MS_U32 HWI2C_adp_Ioctl(void* pInstanceTmp, MS_U32 u32Cmd, void* const pArgs)
149 {
150 MS_U32 u32Ret=0;
151 char buffer_arg[128];
152
153 switch(u32Cmd)
154 {
155 case MDrv_CMD_HWI2C_Init :
156 //u32Ret=UADPBypassIoctl(pInstanceTmp,u32Cmd,pArgs,spt_HWI2C_PRIVATE_PARAM_Init, NULL,buffer_arg,sizeof(buffer_arg));
157 u32Ret=UADPBypassIoctl(pInstanceTmp,u32Cmd,pArgs,spt_HWIIC_PRIVATE_INIT, spt_HWIIC_PRIVATE_INIT,buffer_arg,sizeof(buffer_arg));
158 break;
159 case MDrv_CMD_HWI2C_Start:
160 u32Ret=UtopiaIoctl(pInstanceTmp,u32Cmd,pArgs);
161 break;
162 case MDrv_CMD_HWI2C_Stop:
163 u32Ret=UtopiaIoctl(pInstanceTmp,u32Cmd,pArgs);
164 break;
165 case MDrv_CMD_HWI2C_SelectPort:
166 u32Ret=UADPBypassIoctl(pInstanceTmp,u32Cmd,pArgs,spt_HWI2C_PRIVATE_PARAM_SelectPort, NULL,buffer_arg,sizeof(buffer_arg));
167 break;
168 case MDrv_CMD_HWI2C_SetClk:
169 u32Ret=UADPBypassIoctl(pInstanceTmp,u32Cmd,pArgs,spt_HWI2C_PRIVATE_PARAM_SetClk, NULL,buffer_arg,sizeof(buffer_arg));
170 break;
171 case MDrv_CMD_HWI2C_WriteBytes:
172 {
173 #ifdef CONFIG_COMPAT
174 if(IS_CMP_TASK())
175 {
176 HWI2C_PRIVATE_PARAM_WriteBytes tmp;
177 _compat_stHWI2C_PRIVATE_PARAM_WriteBytes tmp_compat;
178 CMP_CPY_FROM_USER(&tmp_compat, pArgs, sizeof(_compat_stHWI2C_PRIVATE_PARAM_WriteBytes));
179 tmp.pRegAddr = kmalloc(sizeof(MS_U8)*tmp_compat.uAddrCnt,GFP_KERNEL);
180 tmp.pData = kmalloc(sizeof(MS_U8)*tmp_compat.uSize,GFP_KERNEL);
181 CMP_CPY_FROM_USER(tmp.pRegAddr, tmp_compat.pRegAddr, sizeof(MS_U8)*tmp_compat.uAddrCnt);
182 CMP_CPY_FROM_USER(tmp.pData, tmp_compat.pData, sizeof(MS_U8)*tmp_compat.uSize);
183 tmp.u16SlaveCfg=tmp_compat.u16SlaveCfg;
184 tmp.uAddrCnt=tmp_compat.uAddrCnt;
185 tmp.uSize=tmp_compat.uSize;
186 u32Ret = UtopiaIoctl(pInstanceTmp,u32Cmd,&tmp);
187 tmp_compat.bReturn = tmp.bReturn;
188 CMP_CPY_TO_USER(pArgs,&tmp_compat,sizeof(_compat_stHWI2C_PRIVATE_PARAM_WriteBytes));
189 kfree(tmp.pRegAddr);
190 kfree(tmp.pData);
191 }
192 else
193 #endif
194 {
195
196 HWI2C_PRIVATE_PARAM_WriteBytes paramW;
197 CPY_FROM_USER(¶mW,pArgs,sizeof(HWI2C_PRIVATE_PARAM_WriteBytes));
198 MS_U8 u8AddLen = (paramW.uAddrCnt>0?paramW.uAddrCnt:1);
199 MS_U8 u8DataLen = (paramW.uSize>0?paramW.uSize:1);
200 MS_U8 u8Addr[u8AddLen];
201 MS_U8 u8Data[u8DataLen];
202
203 if (paramW.uAddrCnt > 0)
204 CPY_FROM_USER(u8Addr, paramW.pRegAddr,paramW.uAddrCnt);
205 if (paramW.uSize > 0)
206 CPY_FROM_USER(u8Data, paramW.pData, paramW.uSize);
207 paramW.pData = u8Data;
208 paramW.pRegAddr = u8Addr;
209 u32Ret = UtopiaIoctl(pInstanceTmp,u32Cmd,¶mW);
210 CPY_to_USER(&((HWI2C_PRIVATE_PARAM_WriteBytes *)pArgs)->bReturn , ¶mW.bReturn, sizeof(MS_BOOL));
211 }
212 break;
213 }
214 case MDrv_CMD_HWI2C_ReadBytes:
215 {
216 #ifdef CONFIG_COMPAT
217 if(IS_CMP_TASK())
218 {
219 HWI2C_PRIVATE_PARAM_ReadBytes tmpr;
220 _compat_stHWI2C_PRIVATE_PARAM_ReadBytes tmpr_compat;
221 CMP_CPY_FROM_USER(&tmpr_compat, pArgs, sizeof(_compat_stHWI2C_PRIVATE_PARAM_ReadBytes));
222 tmpr.pRegAddr = kmalloc(sizeof(MS_U8)*tmpr_compat.uAddrCnt,GFP_KERNEL);
223 tmpr.pData = kmalloc(sizeof(MS_U8)*tmpr_compat.uSize,GFP_KERNEL);
224 CMP_CPY_FROM_USER(tmpr.pRegAddr, tmpr_compat.pRegAddr, sizeof(MS_U8)*tmpr_compat.uAddrCnt);
225 tmpr.u16SlaveCfg=tmpr_compat.u16SlaveCfg;
226 tmpr.uAddrCnt=tmpr_compat.uAddrCnt;
227 tmpr.uSize=tmpr_compat.uSize;
228 u32Ret = UtopiaIoctl(pInstanceTmp,u32Cmd,&tmpr);
229 tmpr_compat.bReturn = tmpr.bReturn;
230 CMP_CPY_TO_USER(tmpr_compat.pData,tmpr.pData,sizeof(MS_U8)*tmpr_compat.uSize);
231 CMP_CPY_TO_USER(pArgs,&tmpr_compat,sizeof(_compat_stHWI2C_PRIVATE_PARAM_ReadBytes));
232 kfree(tmpr.pRegAddr);
233 kfree(tmpr.pData);
234 }
235 else
236 #endif
237 {
238
239 HWI2C_PRIVATE_PARAM_ReadBytes paramR;
240 CPY_FROM_USER(¶mR,pArgs,sizeof(HWI2C_PRIVATE_PARAM_ReadBytes));
241 MS_U8 u8AddLen = (paramR.uAddrCnt>0?paramR.uAddrCnt:1);
242 MS_U8 u8DataLen = (paramR.uSize>0?paramR.uSize:1);
243 MS_U8 u8Addr[u8AddLen];
244 MS_U8 u8Data[u8DataLen];
245 if (paramR.uAddrCnt > 0)
246 CPY_FROM_USER(u8Addr, paramR.pRegAddr,paramR.uAddrCnt);
247 paramR.pRegAddr = u8Addr;
248 paramR.pData = u8Data;
249 u32Ret = UtopiaIoctl(pInstanceTmp,u32Cmd,¶mR);
250 if (paramR.uSize > 0)
251 CPY_to_USER(((HWI2C_PRIVATE_PARAM_WriteBytes *)pArgs)->pData, u8Data, paramR.uSize);
252 CPY_to_USER(&((HWI2C_PRIVATE_PARAM_WriteBytes *)pArgs)->bReturn , ¶mR.bReturn, sizeof(MS_BOOL));
253 }
254
255 break;
256 }
257 default:
258 break;
259 }
260 return u32Ret;
261 }
262
263
264
265
266