1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 // ********************************************************
79 //
80 // $Workfile: PCMCIA.c $
81 //
82 // Author/Copyright Gero Kuehn / GkWare e.K.
83 // Humboldtstrasse 177
84 // 45149 Essen
85 // GERMANY
86 // Tel: +49 174 520 8026
87 // Email: support@gkware.com
88 // Web: http://www.gkware.com
89 //
90 // $Date: 2006-06-22 23:05:10 +0200 (Do, 22 Jun 2006) $
91 // $Revision: 21 $
92 //
93 // ********************************************************
94 //
95 // This file contains the portable PCMCIA CIS decoder
96 //
97
98 ///////////////////////////////////////////////////////////////////////////////
99 ///
100 /// file drvPCMCIA.c
101 /// @brief PCMCIA Driver Interface
102 /// @author MStar Semiconductor Inc.
103 ///////////////////////////////////////////////////////////////////////////////
104
105 /*****************************************************************************/
106 /* Header Files */
107 /*****************************************************************************/
108 // Common Definition
109
110 #include "MsCommon.h"
111 #include "MsVersion.h"
112 #include "drvPCMCIA.h"
113 #include "drvMMIO.h"
114 #include "halPCMCIA.h"
115 #include "utopia_dapi.h"
116 #include "utopia.h"
117 #include "pcmcia_private.h"
118 #include <string.h>
119
120 #if defined ( MSOS_TYPE_LINUX )
121 #include <sys/ioctl.h>
122 #include <unistd.h>
123 #include <fcntl.h> // O_RDWR
124 #include "mdrv_system_io.h"
125 #endif
126
127 #ifdef CONFIG_PCMCIA_MSPI
128 #include "drvMSPI.h"
129 #endif
130 /*****************************************************************************/
131 /* Define */
132 /*****************************************************************************/
133 #define PCMCIA_MAX_DETECT_COUNT 1UL
134 #define PCMCIA_MAX_POLLING_COUNT 20000UL
135 #define PCMCIA_DEFAULT_RESET_DURATION 20UL
136 #define PCMCIA_HW_MAX_RETRY_COUNT 100UL // PCMCIA hardware register maximum access times
137
138 #define PCMCIA_DEBUG_ENABLE FALSE
139 #define PCMCIA_DUMP_REG FALSE
140
141 #define PCMCIA_UTOPIA2 TRUE
142
143 //#define ECOS_OBERON
144 #ifdef ECOS_OBERON
145 #undef PCMCIA_IRQ_ENABLE
146 #define PCMCIA_IRQ_ENABLE 0UL
147 extern int diag_printf( const char *fmt, ... ); /* Formatted print */
148 #define printf diag_printf
149 #define REG(addr) (*(volatile MS_U32 *)(addr))
150 #endif
151
152 //#define AEON_CHAKRA
153 #ifdef AEON_CHAKRA
154 #undef PCMCIA_IRQ_ENABLE
155 #define PCMCIA_IRQ_ENABLE 0UL
156 extern void msAPI_Timer_Delayms(MS_U32 u32DelayTime);
157 extern MS_U32 msAPI_Timer_GetTime0(void);
158 #define MsOS_DelayTask msAPI_Timer_Delayms
159 #define MsOS_GetSystemTime msAPI_Timer_GetTime0
160 #endif
161
162 /*****************************************************************************/
163 /* Global Variables */
164 /*****************************************************************************/
165 extern PCMCIA_RESOURCE_PRIVATE* pPcmEnv;
166 #if PCMCIA_IRQ_ENABLE
167 static MS_BOOL _gbPCMCIA_Irq[E_PCMCIA_MODULE_MAX] = {DISABLE};
168 static MS_BOOL _gbPCMCIA_IrqStatus[E_PCMCIA_MODULE_MAX] = {FALSE};
169 #endif
170 static MS_U8 _gu8PCMCIA_Command[E_PCMCIA_MODULE_MAX] = {0};
171 static MS_U8 _gu8HW_ResetDuration = PCMCIA_DEFAULT_RESET_DURATION;
172
173 #if defined ( MSOS_TYPE_LINUX )
174 static MS_S32 SYS_fd = -1;
175
176 #if PCMCIA_UTOPIA2
177 extern void* pModulePcm;
178 extern void* psResource;
179 #else
180 static MS_S32 Pcmcia_Mutex= -1;
181 #endif
182 /* PCMCIA_MAP_IOC_INFO */
183 typedef struct
184 {
185 MS_U16 u16Addr;
186 MS_U8 u8Value;
187 MS_U8 u8Type; // 1: AttribMem, 2: IOMem
188 MS_U16 u16DataLen;
189 MS_U8 * u8pReadBuffer;
190 MS_U8 * u8pWriteBuffer;
191 } PCMCIA_Map_Info_t;
192 #endif
193
194 #ifdef CONFIG_PCMCIA_MSPI_BURST
195 static MS_U8 u8MspiBuf[256];
196 #endif
197 /*****************************************************************************/
198 /* Macro */
199 /*****************************************************************************/
200 #if PCMCIA_DEBUG_ENABLE
201 #define PCMCIA_DEBUG( x ) printf x
202 #else
203 #define PCMCIA_DEBUG( x )
204 #endif
205
206 #define pcmcia_min( x, y ) ( (MS_U8)x < (MS_U8)y ? (MS_U8)x : (MS_U8)y )
207
208 #if defined ( MSOS_TYPE_LINUX )
209 #if PCMCIA_UTOPIA2
210 #define PCM_ENTER() if(UTOPIA_STATUS_FAIL == UtopiaResourceObtain(pModulePcm, E_PCMCIA_RESOURCE, &psResource)) \
211 { \
212 ULOGE("PCMCIA", "[PCMCIA][%06d] Mutex taking timeout\n", __LINE__); \
213 }
214
215 #define PCM_EXIT() UtopiaResourceRelease(psResource)
216 #else
217 #define PCM_ENTER() if (!MsOS_ObtainMutex(Pcmcia_Mutex, MSOS_WAIT_FOREVER)) \
218 { \
219 ULOGE("PCMCIA", "[PCMCIA][%06d] Mutex taking timeout\n", __LINE__); \
220 }
221
222 #define PCM_EXIT() MsOS_ReleaseMutex(Pcmcia_Mutex)
223 #endif
224 #else
225 #define PCM_ENTER()
226 #define PCM_EXIT()
227 #endif
228
229 #define BIT0 0x0001UL
230 #define BIT1 0x0002UL
231 #define BIT2 0x0004UL
232 #define BIT3 0x0008UL
233 #define BIT4 0x0010UL
234 #define BIT5 0x0020UL
235 #define BIT6 0x0040UL
236 #define BIT7 0x0080UL
237 #define BIT8 0x0100UL
238 #define BIT9 0x0200UL
239 #define BIT10 0x0400UL
240 #define BIT11 0x0800UL
241 #define BIT12 0x1000UL
242 #define BIT13 0x2000UL
243 #define BIT14 0x4000UL
244 #define BIT15 0x8000UL
245
246 #define PCMCIA_FIRE_COMMAND BIT0
247 #define PCMCIA_CLEAN_STATE_RD_DONE BIT1
248 #define PCMCIA_STATE_RD_DONE BIT0
249 #define PCMCIA_STATE_BUS_IDLE BIT1
250 #define PCMCIA_DETECT_PIN_MODULEA BIT2
251 #define PCMCIA_DETECT_PIN_MODULEB BIT3
252
253 /* Table 2-6 Tuple Summary Tabl (Spec P.24)*/
254 /* Layer 1 Tuples */
255 #define CISTPL_NULL 0x00UL
256 #define CISTPL_DEVICE 0x01UL
257 #define CISTPL_LONGLINK_CB 0x02UL
258 #define CISTPL_INDIRECT 0x03UL
259 #define CISTPL_CONFIG_CB 0x04UL
260 #define CISTPL_CFTABLE_ENTRY_CB 0x05UL
261 #define CISTPL_LONGLINK_MFC 0x06UL
262 #define CISTPL_BAR 0x07UL
263 #define CISTPL_PWR_MGMNT 0x08UL
264 #define CISTPL_EXTDEVICE 0x09UL
265 #define CISTPL_CHECKSUM 0x10UL
266 #define CISTPL_LONGLINK_A 0x11UL
267 #define CISTPL_LONGLINK_C 0x12UL
268 #define CISTPL_LINKTARGET 0x13UL
269 #define CISTPL_NO_LINK 0x14UL
270 #define CISTPL_VERS_1 0x15UL
271 #define CISTPL_ALTSTR 0x16UL
272 #define CISTPL_DEVICE_A 0x17UL
273 #define CISTPL_JEDEC_C 0x18UL
274 #define CISTPL_JEDEC_A 0x19UL
275 #define CISTPL_CONFIG 0x1AUL
276 #define CISTPL_CFTABLE_ENTRY 0x1BUL
277 #define CISTPL_DEVICE_OC 0x1CUL
278 #define CISTPL_DEVICE_OA 0x1DUL
279 #define CISTPL_DEVICE_GEO 0x1EUL
280 #define CISTPL_DEVICE_GEO_A 0x1FUL
281 #define CISTPL_MANFID 0x20UL
282 #define CISTPL_FUNCID 0x21UL
283 #define CISTPL_FUNCE 0x22UL
284 #define CISTPL_END 0xFFUL
285 /* Layer 2 Tuples */
286 #define CISTPL_SWIL 0x23UL
287 #define CISTPL_VERS_2 0x40UL
288 #define CISTPL_FORMAT 0x41UL
289 #define CISTPL_GEOMETRY 0x42UL
290 #define CISTPL_BYTEORDER 0x43UL
291 #define CISTPL_DATE 0x44UL
292 #define CISTPL_BATTERY 0x45UL
293 #define CISTPL_FORMAT_A 0x47UL
294 /* Layer 3 Tuples */
295 #define CISTPL_ORG 0x46UL
296 /* Layer 4 Tuples */
297 #define CISTPL_SPCL 0x90UL
298
299 /*****************************************************************************/
300 /* Local Variables */
301 /*****************************************************************************/
302 /// Version string
303 static MSIF_Version _drv_pcmcia_version = {
304 .DDI = { PCMCIA_DRV_VERSION, },
305 };
306
307 static MS_BOOL _gbHighActive;
308 static MS_BOOL _gbCardInside[E_PCMCIA_MODULE_MAX];
309 static MS_BOOL _gbPCMCIA_Detect_Enable;
310 static MS_U32 _gu32PCMCIA_CD_To_HWRST_Timer[E_PCMCIA_MODULE_MAX];
311 //static MS_U8 _gu8PCMCIACurModule = PCMCIA_DEFAULT_MODULE;
312 #if PCMCIA_IRQ_ENABLE
313 static IsrCallback _fnIsrCallback[E_PCMCIA_MODULE_MAX] = {NULL};
314 static PCMCIA_ISR _gPCMCIA_ISR;
315 #endif
316
317 /*****************************************************************************/
318 /* Local Functions */
319 /*****************************************************************************/
320 static MS_BOOL _MDrv_PCMCIA_ReadReg( MS_U32 u32Addr, MS_U8 *pu8Value );
321 static MS_BOOL _MDrv_PCMCIA_WriteReg( MS_U32 u32Addr, MS_U8 u8Value );
322
323 #ifdef CONFIG_PCMCIA_MSPI_BURST
324 static MS_BOOL _MDrv_PCMCIA_WriteRegMask( MS_U32 u32Addr, MS_U8 u8Value , MS_U8 u8Mask);
325 static MS_BOOL _MSPI_RWLong(MS_U8 u8Cmd, MS_U16 u16Addr, MS_U8* u8data, MS_U16 u16Len);
326 static void _MSPI_BurstRst(void);
327 static MS_BOOL _MSPI_MIU_CheckDone(void);
328 #endif
329
_MDrv_PCMCIA_ReadReg(MS_U32 u32Addr,MS_U8 * pu8Value)330 static MS_BOOL _MDrv_PCMCIA_ReadReg( MS_U32 u32Addr, MS_U8 *pu8Value )
331 {
332 if ( NULL == pu8Value )
333 {
334 return FALSE;
335 }
336 *pu8Value = HAL_PCMCIA_Read_Byte( u32Addr );
337
338 #if PCMCIA_DUMP_REG
339 ULOGD("PCMCIA", "R: Addr %02X, Value %02X\n", u8Addr, *pu8Value );
340 #endif
341
342 return TRUE;
343 }
344
_MDrv_PCMCIA_WriteReg(MS_U32 u32Addr,MS_U8 u8Value)345 static MS_BOOL _MDrv_PCMCIA_WriteReg( MS_U32 u32Addr, MS_U8 u8Value )
346 {
347 HAL_PCMCIA_Write_Byte( u32Addr , u8Value );
348
349 #if PCMCIA_DUMP_REG
350 ULOGD("PCMCIA", "W: Addr %02X, Value %02X\n", u8Addr, u8Value );
351 #endif
352
353 return TRUE;
354 }
355 #ifdef CONFIG_PCMCIA_MSPI_BURST
_MDrv_PCMCIA_WriteRegMask(MS_U32 u32Addr,MS_U8 u8Value,MS_U8 u8Mask)356 static MS_BOOL _MDrv_PCMCIA_WriteRegMask( MS_U32 u32Addr, MS_U8 u8Value , MS_U8 u8Mask)
357 {
358 HAL_PCMCIA_Write_ByteMask( u32Addr , u8Value, u8Mask);
359 return TRUE;
360 }
361 #endif
362
_MDrv_PCMCIA_SwitchModule(PCMCIA_MODULE eModule)363 static void _MDrv_PCMCIA_SwitchModule(PCMCIA_MODULE eModule)
364 {
365 MS_U8 u8Reg = 0x0;
366
367 if(pPcmEnv->u8PCMCIACurModule == eModule)
368 return;
369
370 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_MODULE_VCC_OOB, (MS_U8 *)&u8Reg );
371 u8Reg &= ~(BIT0|BIT1);
372
373 // MODULE_SEL[1:0] 1:0 Module select.
374 // 00: No destination selected.
375 // 01: Select module A.
376 // 10: Select module B.
377 // 11: Reserved.
378
379 if(eModule == E_PCMCIA_MODULE_A)
380 {
381 u8Reg |= BIT0;
382 }
383 else
384 {
385 u8Reg |= BIT1;
386 }
387
388 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_MODULE_VCC_OOB, u8Reg );
389 pPcmEnv->u8PCMCIACurModule = eModule;
390 }
391
392 #ifdef CONFIG_PCMCIA_MSPI_BURST
_MSPI_RWLong(MS_U8 u8Cmd,MS_U16 u16Addr,MS_U8 * u8data,MS_U16 u16Len)393 static MS_BOOL _MSPI_RWLong(MS_U8 u8Cmd, MS_U16 u16Addr, MS_U8* u8data, MS_U16 u16Len)
394 {
395 MS_U16 i = 0;
396 MS_U16 Size = 0;
397 MS_U16 SizePcmBurst = 0;
398 MS_BOOL bRet = TRUE;
399 MS_U8 u8reg = 0;
400 if(u8Cmd == PCMCIA_ATTRIBMEMORY_WRITE || u8Cmd == PCMCIA_IO_WRITE)
401 {
402 while(u16Len)
403 {
404 SizePcmBurst = (u16Len > MAX_PCMCIA_BURST_WRITE_SIZE) ? MAX_PCMCIA_BURST_WRITE_SIZE : u16Len;
405 //printf("PCM Burst %d, left %d\n", (int)SizePcmBurst, (int)u16Len);
406
407 u16Len -= SizePcmBurst;
408 i=0;
409 u8MspiBuf[i++] = MSPI_CMD_MIU_W;
410 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_ADDR >> 0) & 0xFF;
411 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_ADDR >> 8) & 0xFF;
412 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_ADDR >> 16) & 0xFF;
413 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_ADDR >> 24) & 0xFF;
414 u8MspiBuf[i++] = 0x0; // reg_status_expect
415 u8MspiBuf[i++] = 0x0; // reg_status_mask
416 u8MspiBuf[i++] = 0x0; // reg_pcm_burst_addr_offset
417 u8MspiBuf[i++] = 0x0;
418 u8MspiBuf[i++] = u8Cmd; // reg_pcm_cmd
419 u8MspiBuf[i++] = 0x0;
420 u8MspiBuf[i++] = u16Addr & 0xFF; // reg_adr
421 u8MspiBuf[i++] = ( u16Addr >> 8 ) & 0xFF;
422 u8MspiBuf[i++] = SizePcmBurst; // reg_total_burst_num
423 u8MspiBuf[i++] = 0;
424 u8MspiBuf[i++] = PCMBURST_WRITE & 0xFF;
425 u8MspiBuf[i++] = (PCMBURST_WRITE >> 8 ) & 0xFF;
426
427 MDrv_MSPI_RWBytes(MSPI_READ_OPERATION, 0); // clean rbf_size
428 while(SizePcmBurst)
429 {
430 Size = (SizePcmBurst > MAX_MSPI_BURST_WRITE_SIZE - i) ?
431 (MAX_MSPI_BURST_WRITE_SIZE - i) : SizePcmBurst;
432
433
434 MDrv_MSPI_SlaveEnable(TRUE);
435 MDrv_MSPI_Write(u8MspiBuf, i);
436
437 //MsOS_DelayTask(100);
438 MDrv_MSPI_Write(u8data, Size);
439 MDrv_MSPI_SlaveEnable(FALSE);
440 SizePcmBurst -= Size;
441 u8data += Size;
442 //MsOS_DelayTask(100);
443 i=0;
444 u8MspiBuf[i++] = MSPI_CMD_MIU_W;
445 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_WFIFO >> 0) & 0xFF;
446 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_WFIFO >> 8) & 0xFF;
447 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_WFIFO >> 16) & 0xFF;
448 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_WFIFO >> 24) & 0xFF;
449 }
450
451 for(i=0;i<MAX_MSPI_STATUS_COUNT;i++)
452 {
453 _MDrv_PCMCIA_ReadReg(REG_PCM_BURST_STATUS_0, &u8reg);
454 if(u8reg & REG_PCM_BURST_WRITE_DONE)
455 {
456 _MDrv_PCMCIA_WriteRegMask(REG_PCM_BURST_STATUS_CLR,
457 REG_PCM_WRITE_FINISH_CLR, REG_PCM_WRITE_FINISH_CLR);
458 break;
459 }
460 }
461 if(i == MAX_MSPI_STATUS_COUNT)
462 printf("[PCM] warning, BURST Write not finish\n");
463
464 _MDrv_PCMCIA_ReadReg(REG_PCM_BURST_WFIFO_RMN, &u8reg);
465 if(u8reg != 0)
466 printf("[PCM] warning, WFIFO not empty %d\n", (int)u8reg);
467
468 }
469 }
470 else if(u8Cmd == PCMCIA_ATTRIBMEMORY_READ || u8Cmd == PCMCIA_IO_READ)
471 {
472 while(u16Len)
473 {
474 MS_U16 index = 0;
475 SizePcmBurst = (u16Len > MAX_PCMCIA_BURST_READ_SIZE) ? MAX_PCMCIA_BURST_READ_SIZE : u16Len;
476 //printf("PCM Burst %d, left %d\n", (int)SizePcmBurst, (int)u16Len);
477
478 u16Len -= SizePcmBurst;
479
480 i = 0;
481 u8MspiBuf[i++] = MSPI_CMD_MIU_W;
482 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_ADDR >> 0) & 0xFF;
483 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_ADDR >> 8) & 0xFF;
484 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_ADDR >> 16) & 0xFF;
485 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_ADDR >> 24) & 0xFF;
486 u8MspiBuf[i++] = 0x0; // reg_status_expect
487 u8MspiBuf[i++] = 0x0; // reg_status_mask
488 u8MspiBuf[i++] = 0x0; // reg_pcm_burst_addr_offset
489 u8MspiBuf[i++] = 0x0;
490 u8MspiBuf[i++] = u8Cmd; // reg_pcm_cmd
491 u8MspiBuf[i++] = 0x0;
492 u8MspiBuf[i++] = u16Addr & 0xFF; // reg_adr
493 u8MspiBuf[i++] = ( u16Addr >> 8 ) & 0xFF;
494 u8MspiBuf[i++] = SizePcmBurst; // reg_total_burst_num
495 u8MspiBuf[i++] = 0;
496 u8MspiBuf[i++] = PCMBURST_READ & 0xFF;
497 u8MspiBuf[i++] = (PCMBURST_READ >> 8 ) & 0xFF;
498
499 MDrv_MSPI_RWBytes(MSPI_READ_OPERATION, 0); // clean rbf_size
500 MDrv_MSPI_SlaveEnable(TRUE);
501 MDrv_MSPI_Write(u8MspiBuf, i);
502 MDrv_MSPI_SlaveEnable(FALSE);
503
504 for(i=0;i<MAX_MSPI_STATUS_COUNT;i++)
505 {
506 _MDrv_PCMCIA_ReadReg(REG_PCM_BURST_STATUS_0, &u8reg);
507 if(u8reg & REG_PCM_BURST_READ_DONE)
508 {
509 _MDrv_PCMCIA_WriteRegMask(REG_PCM_BURST_STATUS_CLR,
510 REG_PCM_READ_FINISH_CLR, REG_PCM_READ_FINISH_CLR);
511 break;
512
513 }
514 MsOS_DelayTask(1);
515 }
516 if(i == MAX_MSPI_STATUS_COUNT)
517 {
518 printf("[PCM] warning, BURST Write not finish\n");
519 }
520
521 while(SizePcmBurst)
522 {
523 MS_U8 u8TmpBuf[MAX_MSPI_BURST_READ_SIZE + 1];
524 Size = ( SizePcmBurst > MAX_MSPI_BURST_READ_SIZE ) ? MAX_MSPI_BURST_READ_SIZE : SizePcmBurst;
525 _MSPI_MIU_CheckDone();
526
527
528 i = 0;
529 u8MspiBuf[i++] = MSPI_CMD_MIU_R;
530 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_RFIFO >> 0) & 0xFF;
531 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_RFIFO >> 8) & 0xFF;
532 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_RFIFO >> 16) & 0xFF;
533 u8MspiBuf[i++] = (REG_COMPANION_PCMBURST_RFIFO >> 24) & 0xFF;
534 u8MspiBuf[i++] = Size + 1; // 1 for MSPI status
535 MDrv_MSPI_RWBytes(MSPI_READ_OPERATION, 0); // clean rbf_size
536 MDrv_MSPI_SlaveEnable(TRUE);
537 MDrv_MSPI_Write(u8MspiBuf, i);
538 MDrv_MSPI_SlaveEnable(FALSE);
539
540 _MSPI_MIU_CheckDone();
541 u8MspiBuf[0] = MSPI_CMD_MIU_ST;
542 MDrv_MSPI_SlaveEnable(TRUE);
543 MDrv_MSPI_Write(u8MspiBuf, 1);
544 MDrv_MSPI_RWBytes(MSPI_WRITE_OPERATION, 0); // clean rbf_size
545 MDrv_MSPI_Read(u8TmpBuf, Size + 1);
546 MDrv_MSPI_SlaveEnable(FALSE);
547 if(u8TmpBuf[0] != 0x0A)
548 {
549 printf("[PCM] warning, MIU_ST status 0x%x\n", (int)u8TmpBuf[0]);
550 }
551
552 memcpy(u8data, &u8TmpBuf[1], Size);
553 SizePcmBurst -= Size;
554 u8data += Size;
555 _MDrv_PCMCIA_ReadReg(REG_PCM_BURST_RFIFO_RMN, &u8reg);
556 if(u8reg != SizePcmBurst)
557 printf("[PCM] warning, RFIFO rmn %d, SizePcmBurst %d\n", (int)u8reg, (int)SizePcmBurst);
558
559 MsOS_DelayTask(10);
560 }
561
562 _MDrv_PCMCIA_ReadReg(REG_PCM_BURST_RFIFO_RMN, &u8reg);
563 if(u8reg != 0)
564 printf("[PCM] warning, RFIFO not empty, %d\n", (int)u8reg);
565 }
566 }
567 return bRet;
568 }
569
_MSPI_MIU_CheckDone(void)570 static MS_BOOL _MSPI_MIU_CheckDone(void)
571 {
572 MS_U8 u8tmp = 0;
573 int i = 0;
574 u8MspiBuf[0] = MSPI_CMD_MIU_ST;
575
576 for(;i<MAX_MSPI_STATUS_COUNT;i++)
577 {
578 MDrv_MSPI_SlaveEnable(TRUE);
579 MDrv_MSPI_RWBytes(MSPI_READ_OPERATION, 0); // clean rbf_size
580 MDrv_MSPI_Write(u8MspiBuf, 1);
581 MDrv_MSPI_RWBytes(MSPI_WRITE_OPERATION, 0); // clean rbf_size
582 MDrv_MSPI_Read(&u8tmp, 1);
583 MDrv_MSPI_SlaveEnable(FALSE);
584 if(u8tmp == MSPI_MIU_STATUS_DONE || u8tmp == MSPI_MIU_STATUS_NONE)
585 break;
586 }
587 MDrv_MSPI_RWBytes(MSPI_READ_OPERATION, 0); // clean rbf_size
588 MDrv_MSPI_RWBytes(MSPI_WRITE_OPERATION, 0); // clean rbf_size
589
590 if(i == MAX_MSPI_STATUS_COUNT)
591 {
592 printf("[PCM] MSPI MIU timeout, status 0x%x\n", (int)u8tmp);
593 return FALSE ;
594 }
595 return TRUE ;
596 }
597
_MSPI_BurstRst(void)598 static void _MSPI_BurstRst(void)
599 {
600 _MDrv_PCMCIA_WriteRegMask(REG_PCM_BURST_CTRL, REG_PCM_BURST_SW_RST_ON, REG_PCM_BURST_SW_RST_MASK);
601 _MDrv_PCMCIA_WriteRegMask(REG_PCM_BURST_CTRL, REG_PCM_BURST_SW_RST_OFF, REG_PCM_BURST_SW_RST_MASK);
602 }
603 #endif
604
605 #if PCMCIA_IRQ_ENABLE
_MDrv_PCMCIA_Isr(void)606 static void _MDrv_PCMCIA_Isr( void )
607 {
608 ISR_STS IsrSts;
609 PCMCIA_MODULE eModule = E_PCMCIA_MODULE_A;
610 memset(&_gPCMCIA_ISR, 0x00, sizeof(_gPCMCIA_ISR));
611 memset(&IsrSts, 0x00, sizeof(ISR_STS));
612
613 /* MASK PCMCIA IRQ */
614 HAL_PCMCIA_GetIntStatus(&IsrSts);
615 HAL_PCMCIA_MaskInt(0x0, TRUE);
616 HAL_PCMCIA_ClrInt(0x0);
617
618 if(IsrSts.bCardAInsert || IsrSts.bCardARemove || IsrSts.bCardAData)
619 {
620 if (_gbPCMCIA_Irq[E_PCMCIA_MODULE_A])
621 {
622 _gbPCMCIA_IrqStatus[E_PCMCIA_MODULE_A] = TRUE;
623 }
624 if(IsrSts.bCardAInsert)
625 {
626 _gPCMCIA_ISR.bISRCardInsert=TRUE;
627 }
628 if(IsrSts.bCardARemove)
629 {
630 _gPCMCIA_ISR.bISRCardRemove=TRUE;
631 }
632 if(IsrSts.bCardAData)
633 {
634 _gPCMCIA_ISR.bISRCardData=TRUE;
635 }
636 if (NULL != _fnIsrCallback[E_PCMCIA_MODULE_A])
637 {
638 eModule = E_PCMCIA_MODULE_A;
639 _fnIsrCallback[E_PCMCIA_MODULE_A]((void*)(&_gPCMCIA_ISR), (void*)&eModule);
640 }
641 }
642 else if(IsrSts.bCardBInsert || IsrSts.bCardBRemove || IsrSts.bCardBData)
643 {
644 if (_gbPCMCIA_Irq[E_PCMCIA_MODULE_B])
645 {
646 _gbPCMCIA_IrqStatus[E_PCMCIA_MODULE_B] = TRUE;
647 }
648 if(IsrSts.bCardBInsert)
649 {
650 _gPCMCIA_ISR.bISRCardInsert=TRUE;
651 }
652 if(IsrSts.bCardBRemove)
653 {
654 _gPCMCIA_ISR.bISRCardRemove=TRUE;
655 }
656 if(IsrSts.bCardBData)
657 {
658 _gPCMCIA_ISR.bISRCardData=TRUE;
659 }
660 if (NULL != _fnIsrCallback[E_PCMCIA_MODULE_B])
661 {
662 eModule = E_PCMCIA_MODULE_B;
663 _fnIsrCallback[E_PCMCIA_MODULE_B]((void*)(&_gPCMCIA_ISR), (void*)&eModule);
664 }
665 }
666 else
667 {
668 #ifndef CONFIG_PCMCIA_MSPI
669 ULOGE("PCMCIA", "[PCMCIA] IRQ but nothing happen\n");
670 //MS_ASSERT( 0 );
671 #endif
672 }
673
674
675
676 /* Enable HK PCMCIA IRQ */
677 MsOS_EnableInterrupt(E_INT_IRQ_PCM);
678 MsOS_CompleteInterrupt(E_INT_IRQ_PCM);
679
680 /* UNMASK PCMCIA IRQ */
681 HAL_PCMCIA_MaskInt(0x0, FALSE);
682
683 }
684 #endif
685
_MDrv_PCMCIA_Exit(MS_BOOL bSuspend)686 void _MDrv_PCMCIA_Exit( MS_BOOL bSuspend )
687 {
688 if(FALSE == bSuspend)
689 {
690 #if defined ( MSOS_TYPE_LINUX )
691
692 #if PCMCIA_UTOPIA2
693 #else
694 MsOS_DeleteMutex(Pcmcia_Mutex);
695 Pcmcia_Mutex = -1;
696
697 if(Pcmcia_Mutex == -1)
698 {
699 ULOGE("PCMCIA", "[%s] PCMCIA mutex not exist!\n", __FUNCTION__);
700 return;
701 }
702 MsOS_ObtainMutex(Pcmcia_Mutex, MSOS_WAIT_FOREVER);
703 #endif
704
705 //printf ("PCMCIA close /dev/system >> SYS_fd= %ld\n", SYS_fd);
706 if (close (SYS_fd) == -1)
707 {
708 MS_ASSERT(0);
709 perror ("close");
710 }
711 else
712 {
713 //printf ("<<< %s >>> LINE %d , _MDrv_PCMCIA_Exit\r\n", __FILE__, __LINE__);
714 }
715 SYS_fd = -1;
716
717 #if PCMCIA_IRQ_ENABLE
718 MsOS_DisableInterrupt( E_INT_IRQ_PCM ); // Disable PCMCIA interrupt
719 MsOS_DetachInterrupt( E_INT_IRQ_PCM ); // Detach PCMCIA interrupt
720 #endif
721 #endif // MSOS_TYPE_LINUX
722 }
723 else
724 {
725 // suspend
726 #if PCMCIA_IRQ_ENABLE
727 MsOS_DisableInterrupt( E_INT_IRQ_PCM ); // Disable PCMCIA interrupt
728 #endif
729 }
730 HAL_PCMCIA_ClkCtrl(FALSE);
731 }
732
733 /*****************************************************************************/
734 /* Global Functions */
735 /*****************************************************************************/
_MDrv_PCMCIA_InitSW(MS_BOOL bHighActiveTrigger)736 void _MDrv_PCMCIA_InitSW( MS_BOOL bHighActiveTrigger )
737 {
738 MS_VIRT u32PCMCIA_RiuBaseAddr = 0;
739 MS_PHY u32NonPMBankSize;
740 MS_U32 i = 0;
741
742 #if defined ( MSOS_TYPE_LINUX )
743 if(SYS_fd != -1)
744 return;
745
746 #define SYS_MODULE_KERNAL_NAME "/dev/system"
747
748 SYS_fd = open(SYS_MODULE_KERNAL_NAME, O_RDWR);
749 if (0 > SYS_fd) //First time open
750 {
751 MS_ASSERT(0);
752 ULOGE("PCMCIA", "[%s][%d] open fail /dev/system\n", __FUNCTION__, __LINE__);
753 }
754 else
755 {
756 printf ("PCMCIA open /dev/system success >> SYS_fd= %d\n", (int)SYS_fd);
757 }
758 #endif
759
760 // get MMIO base
761 if ( MDrv_MMIO_GetBASE( &u32PCMCIA_RiuBaseAddr, &u32NonPMBankSize, MS_MODULE_PCMCIA ) != TRUE )
762 {
763 #if ( defined ( MCU_AEON ) || defined ( MCU_MIPS ))
764 u32PCMCIA_RiuBaseAddr = PCMCIA_RIU_DEFAULT_BASE_ADDR;
765 #else
766 ULOGE("PCMCIA", "PCMCIA error RIU base address assigned \n");
767 #endif
768
769 ULOGE("PCMCIA", "MDrv_PCMCIA_Init GetBASE failure, use default base address: [ %td ]\n", (ptrdiff_t)u32PCMCIA_RiuBaseAddr );
770 }
771 else
772 {
773 PCMCIA_DEBUG( ( "PCMCIA Base Addr: [ %td ]\n", u32PCMCIA_RiuBaseAddr ) );
774 }
775
776 _gbHighActive = bHighActiveTrigger;
777
778 HAL_PCMCIA_Set_RIU_base( u32PCMCIA_RiuBaseAddr );
779
780 #if defined ( MSOS_TYPE_LINUX ) && !(PCMCIA_UTOPIA2)
781 if(-1 != Pcmcia_Mutex)
782 {
783 ULOGE("PCMCIA", "[%s] open PCMCIA mutex more than once\n", __FUNCTION__);
784 return;
785 }
786
787 Pcmcia_Mutex = MsOS_CreateMutex(E_MSOS_FIFO, "PCMCIA mutex", MSOS_PROCESS_SHARED);
788 if(-1 == Pcmcia_Mutex)
789 {
790 ULOGE("PCMCIA", "[%s] open PCMCIA mutex fail\n", __FUNCTION__);
791 return;
792 }
793 #endif
794
795 for(i = 0; i < E_PCMCIA_MODULE_MAX; i++)
796 {
797 _gbCardInside[i] = FALSE;
798 _gu32PCMCIA_CD_To_HWRST_Timer[i] = 0;
799 _gu8PCMCIA_Command[i] = 0;
800 _fnIsrCallback[i] = NULL;
801 _gbPCMCIA_Irq[i] = DISABLE;
802 _gbPCMCIA_IrqStatus[i] = FALSE;
803 }
804 pPcmEnv->u8PCMCIACurModule = PCMCIA_DEFAULT_MODULE;
805 _gbPCMCIA_Detect_Enable = TRUE;
806 }
807
_MDrv_PCMCIA_InitHW(MS_BOOL bResume)808 void _MDrv_PCMCIA_InitHW( MS_BOOL bResume )
809 {
810
811 MS_U8 u8Reg;
812
813 HAL_PCMCIA_ClkCtrl(TRUE);
814
815 #ifdef CONFIG_PCMCIA_MSPI_BURST
816 _MSPI_BurstRst();
817 #endif
818 /* Initailze PCMCIA Registers. */
819 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_MODULE_VCC_OOB, (MS_U8 *)&u8Reg );
820
821 u8Reg = ( BIT6 | BIT0 ); // reg_module_sel(BIT 1~0): module select
822 // 01: select module A
823 // reg_single_card(BIT4): Only support single card
824 // 1: support 1 card only
825 // reg_vcc_en(BIT5): 0: VCC Disable
826 // reg_oob_en(BIT6): 1: OOB enable
827
828 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_MODULE_VCC_OOB, u8Reg );
829
830
831 #if PCMCIA_IRQ_ENABLE
832
833 if(FALSE == bResume)
834 {
835 MsOS_DisableInterrupt( E_INT_IRQ_PCM ); // Disable PCMCIA interrupt
836 MsOS_DetachInterrupt( E_INT_IRQ_PCM ); // Detach PCMCIA interrupt
837
838 MsOS_AttachInterrupt( E_INT_IRQ_PCM, (InterruptCb)_MDrv_PCMCIA_Isr );// Attach PCMCIA interrupt
839 }
840
841 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_INT_MASK_CLEAR, 0x7C ); // unmask cardA insert/ remove
842 MsOS_EnableInterrupt( E_INT_IRQ_PCM ); // Enable PCMCIA interrupt
843 #endif
844
845 return;
846 }
847
_MDrv_PCMCIA_SetPowerState(EN_POWER_MODE u16PowerState)848 MS_U32 _MDrv_PCMCIA_SetPowerState(EN_POWER_MODE u16PowerState)
849 {
850 switch (u16PowerState)
851 {
852 case E_POWER_RESUME:
853 _MDrv_PCMCIA_InitHW(TRUE);
854 break;
855 case E_POWER_SUSPEND:
856 _MDrv_PCMCIA_Exit(TRUE);
857 break;
858 case E_POWER_MECHANICAL:
859 case E_POWER_SOFT_OFF:
860 default:
861 break;
862 }
863 return UTOPIA_STATUS_SUCCESS;
864 }
865
866 /*
867 void MDrv_PCMCIA_Exit( void )
868 {
869 _MDrv_PCMCIA_Exit();
870 }
871 */
_MDrv_PCMCIA_DetectV2(PCMCIA_MODULE eModule)872 MS_BOOL _MDrv_PCMCIA_DetectV2( PCMCIA_MODULE eModule )
873 {
874 MS_U8 u8value = 0;
875
876 MS_U8 u8DetectPin =
877 (eModule == E_PCMCIA_MODULE_A) ? PCMCIA_DETECT_PIN_MODULEA : PCMCIA_DETECT_PIN_MODULEB;
878
879 // if(eModule >= E_PCMCIA_MODULE_MAX)
880 // {
881 // ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
882 // return FALSE;
883 // }
884
885 if(!_gbPCMCIA_Detect_Enable)
886 return FALSE;
887
888 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA_DONE_BUS_IDLE, &u8value );
889 if((u8value & u8DetectPin) != 0)
890 return (TRUE == _gbHighActive);
891 else
892 return (FALSE == _gbHighActive);
893 }
894
_MDrv_PCMCIA_PollingV2(PCMCIA_MODULE eModule)895 MS_BOOL _MDrv_PCMCIA_PollingV2( PCMCIA_MODULE eModule )
896 {
897 MS_BOOL bCardDetect;
898 MS_BOOL bModuleStatusChange = FALSE;
899
900 if(eModule >= E_PCMCIA_MODULE_MAX)
901 {
902 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
903 return FALSE;
904 }
905
906 bCardDetect = MDrv_PCMCIA_DetectV2(eModule);
907
908 if(_gbCardInside[eModule] != bCardDetect)
909 bModuleStatusChange = TRUE;
910
911 _gbCardInside[eModule] = bCardDetect;
912
913 if(bModuleStatusChange)
914 {
915 if(_gbCardInside[eModule])
916 {
917 _gu32PCMCIA_CD_To_HWRST_Timer[eModule] = MsOS_GetSystemTime();
918 PCMCIA_DEBUG( ( "Card detected\n" ) );
919 }
920 else
921 {
922 PCMCIA_DEBUG( ( "Card removed\n" ) );
923 }
924 }
925
926 return bModuleStatusChange;
927 }
928
_MDrv_PCMCIA_Set_HW_ResetDuration(MS_U8 u8HW_ResetDuration)929 void _MDrv_PCMCIA_Set_HW_ResetDuration( MS_U8 u8HW_ResetDuration )
930 {
931 _gu8HW_ResetDuration = u8HW_ResetDuration;
932 }
933
_MDrv_PCMCIA_ResetHW_V2(PCMCIA_MODULE eModule)934 void _MDrv_PCMCIA_ResetHW_V2( PCMCIA_MODULE eModule)
935 {
936 MS_U8 u8Reg = 0;
937
938 MS_U8 bit = (eModule == E_PCMCIA_MODULE_A) ? BIT2 : BIT3;
939
940 if(eModule >= E_PCMCIA_MODULE_MAX)
941 {
942 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
943 return;
944 }
945
946 PCM_ENTER();
947
948 #if PCMCIA_IRQ_ENABLE
949 MDrv_PCMCIA_Enable_Interrupt( DISABLE );
950 #endif
951
952 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_MODULE_VCC_OOB, (MS_U8 *)&u8Reg );
953 u8Reg |= bit; // 1: RESET = HIGH
954
955
956 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_MODULE_VCC_OOB, u8Reg );
957 MsOS_DelayTask( _gu8HW_ResetDuration ); // MUST...for HW reset
958 u8Reg &= ~bit; // 0: RESET = LOW
959
960 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_MODULE_VCC_OOB, u8Reg );
961
962 /* Comment? */ // FIXME_Alec
963 _MDrv_PCMCIA_WriteReg( 0x18, 0xBD );
964 _MDrv_PCMCIA_WriteReg( 0x19, 0x00 );
965 _MDrv_PCMCIA_WriteReg( 0x1A, 0x31 );
966
967 /* Reset PCMCIA IRQ Mask. */
968 #if PCMCIA_IRQ_ENABLE
969 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_INT_MASK_CLEAR, 0x7C ); //unmask IRQ cardA insert/ remove
970 #else
971 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_INT_MASK_CLEAR, 0x7F );
972 #endif
973 PCM_EXIT();
974 }
975
976 #if defined ( MSOS_TYPE_LINUX ) && !defined (CONFIG_PCMCIA_MSPI)
_MDrv_PCMCIA_WriteAttribMemV2(PCMCIA_MODULE eModule,MS_U16 u16Addr,MS_U8 u8Value)977 void _MDrv_PCMCIA_WriteAttribMemV2( PCMCIA_MODULE eModule, MS_U16 u16Addr, MS_U8 u8Value)
978 {
979 PCMCIA_Map_Info_t stMapInfo;
980 MS_U32 u32Ret = UTOPIA_STATUS_FAIL;
981
982 if(eModule >= E_PCMCIA_MODULE_MAX)
983 {
984 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
985 return;
986 }
987
988 stMapInfo.u16Addr = u16Addr ;
989 stMapInfo.u8Value = u8Value ;
990 stMapInfo.u8Type = 1 ;
991
992 PCM_ENTER();
993 _MDrv_PCMCIA_SwitchModule(eModule);
994 u32Ret = ioctl(SYS_fd, IOCTL_SYS_PCMCIA_WRITE , &stMapInfo);
995 PCM_EXIT();
996
997 if(UTOPIA_STATUS_SUCCESS != u32Ret)
998 {
999 ULOGE("PCMCIA", "[%s][%d] write data fail\n", __FUNCTION__, __LINE__);
1000 }
1001 }
1002
_MDrv_PCMCIA_ReadAttribMemV2(PCMCIA_MODULE eModule,MS_U16 u16Addr,MS_U8 * pDest)1003 void _MDrv_PCMCIA_ReadAttribMemV2( PCMCIA_MODULE eModule, MS_U16 u16Addr, MS_U8 *pDest )
1004 {
1005 PCMCIA_Map_Info_t stMapInfo;
1006 MS_U32 u32Ret = UTOPIA_STATUS_FAIL;
1007
1008 if(eModule >= E_PCMCIA_MODULE_MAX)
1009 {
1010 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1011 return;
1012 }
1013
1014 stMapInfo.u16Addr = u16Addr ;
1015 stMapInfo.u8Type = 1 ;
1016
1017 PCM_ENTER();
1018 _MDrv_PCMCIA_SwitchModule(eModule);
1019
1020 u32Ret = ioctl(SYS_fd, IOCTL_SYS_PCMCIA_READ , &stMapInfo);
1021 if(UTOPIA_STATUS_SUCCESS != u32Ret)
1022 {
1023 *pDest = 0xFF;
1024 }
1025 else
1026 {
1027 *pDest = stMapInfo.u8Value;
1028 }
1029 PCM_EXIT();
1030 }
1031
_MDrv_PCMCIA_WriteIOMemV2(PCMCIA_MODULE eModule,MS_U16 u16Addr,MS_U8 u8Value)1032 void _MDrv_PCMCIA_WriteIOMemV2( PCMCIA_MODULE eModule, MS_U16 u16Addr, MS_U8 u8Value)
1033 {
1034 PCMCIA_Map_Info_t stMapInfo;
1035 MS_U32 u32Ret = UTOPIA_STATUS_FAIL;
1036 if(eModule >= E_PCMCIA_MODULE_MAX)
1037 {
1038 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1039 return;
1040 }
1041
1042 stMapInfo.u16Addr = u16Addr ;
1043 stMapInfo.u8Value = u8Value;
1044 stMapInfo.u8Type = 2;
1045
1046 PCM_ENTER();
1047 _MDrv_PCMCIA_SwitchModule(eModule);
1048 u32Ret = ioctl(SYS_fd, IOCTL_SYS_PCMCIA_WRITE , &stMapInfo);
1049 PCM_EXIT();
1050
1051 if(UTOPIA_STATUS_SUCCESS != u32Ret)
1052 {
1053 ULOGE("PCMCIA", "[%s][%d] write data fail\n", __FUNCTION__, __LINE__);
1054 }
1055 }
1056
_MDrv_PCMCIA_WriteIOMemLongV2(PCMCIA_MODULE eModule,MS_U16 u16Addr,MS_U8 u8Value,MS_U16 u16DataLen,MS_U8 * u8pWriteBuffer)1057 void _MDrv_PCMCIA_WriteIOMemLongV2( PCMCIA_MODULE eModule, MS_U16 u16Addr, MS_U8 u8Value, MS_U16 u16DataLen, MS_U8* u8pWriteBuffer)
1058 {
1059 PCMCIA_Map_Info_t stMapInfo;
1060 MS_U32 u32Ret = UTOPIA_STATUS_FAIL;
1061
1062 if(eModule >= E_PCMCIA_MODULE_MAX)
1063 {
1064 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1065 return;
1066 }
1067 stMapInfo.u16Addr = u16Addr ;
1068 stMapInfo.u8Value = u8Value;
1069 stMapInfo.u8Type = 3;
1070 stMapInfo.u16DataLen = u16DataLen;
1071 stMapInfo.u8pWriteBuffer = u8pWriteBuffer;
1072 PCM_ENTER();
1073 _MDrv_PCMCIA_SwitchModule(eModule);
1074 u32Ret = ioctl(SYS_fd, IOCTL_SYS_PCMCIA_WRITE , &stMapInfo);
1075 PCM_EXIT();
1076
1077 if(UTOPIA_STATUS_SUCCESS != u32Ret)
1078 {
1079 ULOGE("PCMCIA", "[%s][%d] write data fail\n", __FUNCTION__, __LINE__);
1080 }
1081 }
1082
1083 //! This function is read one byte of from the card IO memory at address wAddr.
_MDrv_PCMCIA_ReadIOMemV2(PCMCIA_MODULE eModule,MS_U16 u16Addr)1084 MS_U8 _MDrv_PCMCIA_ReadIOMemV2( PCMCIA_MODULE eModule, MS_U16 u16Addr )
1085 {
1086 PCMCIA_Map_Info_t stMapInfo;
1087 MS_U32 u32Ret = UTOPIA_STATUS_FAIL;
1088 if(eModule >= E_PCMCIA_MODULE_MAX)
1089 {
1090 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1091 return 0;
1092 }
1093 stMapInfo.u16Addr = u16Addr ;
1094 stMapInfo.u8Value = 0;
1095 stMapInfo.u8Type = 2 ;
1096 PCM_ENTER();
1097 _MDrv_PCMCIA_SwitchModule(eModule);
1098 u32Ret = ioctl(SYS_fd, IOCTL_SYS_PCMCIA_READ , &stMapInfo);
1099 PCM_EXIT();
1100
1101 if((u16Addr == PCMCIA_PHYS_REG_COMMANDSTATUS))
1102 {
1103 if(stMapInfo.u8Value & PCMCIA_STATUS_WRITEERROR)
1104 {
1105 printf("PCMCIA WRITE ERROR!!!\n");
1106 }
1107 else if(stMapInfo.u8Value & PCMCIA_STATUS_READERROR)
1108 {
1109 printf("PCMCIA READ ERROR!!!\n");
1110 }
1111 }
1112
1113 if(UTOPIA_STATUS_SUCCESS != u32Ret)
1114 {
1115 return 0xFF;
1116 }
1117 else
1118 {
1119 return stMapInfo.u8Value;
1120 }
1121 }
1122 #else
_MDrv_PCMCIA_WriteAttribMemV2(PCMCIA_MODULE eModule,MS_U16 u16Addr,MS_U8 u8Value)1123 void _MDrv_PCMCIA_WriteAttribMemV2( PCMCIA_MODULE eModule, MS_U16 u16Addr, MS_U8 u8Value )
1124 {
1125 MS_U8 u8Reg = 0;
1126 MS_U16 i;
1127
1128 if(eModule >= E_PCMCIA_MODULE_MAX)
1129 {
1130 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1131 return;
1132 }
1133
1134 _MDrv_PCMCIA_SwitchModule(eModule);
1135
1136 // select attribute memory write, low byte
1137 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_PCM_MEM_IO_CMD, PCMCIA_ATTRIBMEMORY_WRITE );
1138
1139 // write address
1140 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR1, ( u16Addr >> 8 ) );
1141 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR0, u16Addr );
1142
1143 // write data
1144 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_WRITE_DATA, u8Value );
1145
1146 // fire command
1147 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, PCMCIA_FIRE_COMMAND );
1148
1149
1150 //polling if fire is done
1151 for ( i = 0; i < PCMCIA_MAX_POLLING_COUNT; i++ )
1152 {
1153 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, (MS_U8 *)&u8Reg );
1154
1155 if ( !( u8Reg & PCMCIA_FIRE_COMMAND ) )
1156 {
1157 break;
1158 }
1159 }
1160
1161 // polling if bus is idle
1162 for ( i = 0; i < PCMCIA_MAX_POLLING_COUNT; i++ )
1163 {
1164 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA_DONE_BUS_IDLE, (MS_U8 *)&u8Reg );
1165
1166 if ( u8Reg & PCMCIA_STATE_BUS_IDLE )
1167 {
1168 break;
1169 }
1170 }
1171
1172 return;
1173 }
1174
_MDrv_PCMCIA_ReadAttribMemV2(PCMCIA_MODULE eModule,MS_U16 u16Addr,MS_U8 * pDest)1175 void _MDrv_PCMCIA_ReadAttribMemV2( PCMCIA_MODULE eModule, MS_U16 u16Addr, MS_U8 *pDest )
1176 {
1177 MS_U16 u16TryLoop = 0;
1178 MS_U8 u8Reg = 0;
1179
1180 if(eModule >= E_PCMCIA_MODULE_MAX)
1181 {
1182 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1183 return;
1184 }
1185 // CIS readout with 8Bit I/O accesses
1186 // requires that we read only every second
1187 // byte. (The result of reading the even addresses does not seem to work on most modules)
1188
1189 _MDrv_PCMCIA_SwitchModule(eModule);
1190
1191 // select attribute memory read, low byte
1192 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_PCM_MEM_IO_CMD, PCMCIA_ATTRIBMEMORY_READ );
1193
1194 // read address
1195 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR1, (MS_U8)( ( u16Addr * 2 ) >> 8 ) );
1196 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR0, (MS_U8)( u16Addr * 2 ) );
1197
1198 // fire command
1199 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, PCMCIA_FIRE_COMMAND );
1200
1201 //polling if fire is done
1202 while (1)
1203 {
1204 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, (MS_U8 *)&u8Reg );
1205
1206 if ( !( u8Reg & PCMCIA_FIRE_COMMAND ) )
1207 {
1208 break;
1209 }
1210 else
1211 {
1212 u16TryLoop++;
1213 if ( u16TryLoop > PCMCIA_HW_MAX_RETRY_COUNT )
1214 {
1215 u16TryLoop = 0;
1216 ULOGE("PCMCIA", "[%s:%d][Warning!][PCMCIA] Timeout!\n", __FILE__, __LINE__ );
1217
1218 return ;
1219 }
1220 }
1221 }
1222
1223 //polling if data ready
1224 while (1)
1225 {
1226 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA_DONE_BUS_IDLE, (MS_U8 *)&u8Reg );
1227
1228 if ( u8Reg & PCMCIA_STATE_RD_DONE )
1229 {
1230 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA, pDest );
1231 break;
1232 }
1233 else
1234 {
1235 u16TryLoop++;
1236 if ( u16TryLoop > PCMCIA_HW_MAX_RETRY_COUNT )
1237 {
1238 u16TryLoop = 0;
1239 ULOGE("PCMCIA", "[%s:%d][Warning!][PCMCIA] Timeout!\n", __FILE__, __LINE__ );
1240
1241 return ;
1242 }
1243 }
1244 }
1245
1246 // clean stat_rd done
1247 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, PCMCIA_CLEAN_STATE_RD_DONE );
1248
1249 // polling if bus is idle
1250 while (1)
1251 {
1252 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA_DONE_BUS_IDLE, (MS_U8 *)&u8Reg );
1253
1254 if ( PCMCIA_STATE_BUS_IDLE == ( u8Reg & ( PCMCIA_STATE_BUS_IDLE | PCMCIA_STATE_RD_DONE ) ) )
1255 {
1256 break;
1257 }
1258 else
1259 {
1260 u16TryLoop++;
1261 if ( u16TryLoop > PCMCIA_HW_MAX_RETRY_COUNT )
1262 {
1263 u16TryLoop = 0;
1264 ULOGE("PCMCIA", "[%s:%d][Warning!][PCMCIA] Timeout!\n", __FILE__, __LINE__ );
1265
1266 return ;
1267 }
1268 }
1269 }
1270
1271 //printk("Read Type %bx, Addr %x, value %bx\n", u8AccessType, Addr, u8mem);
1272 }
1273
_MDrv_PCMCIA_WriteIOMemV2(PCMCIA_MODULE eModule,MS_U16 u16Addr,MS_U8 u8Value)1274 void _MDrv_PCMCIA_WriteIOMemV2( PCMCIA_MODULE eModule, MS_U16 u16Addr, MS_U8 u8Value )
1275 {
1276 MS_U8 u8Reg = 0;
1277 MS_U16 i;
1278
1279 if(eModule >= E_PCMCIA_MODULE_MAX)
1280 {
1281 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1282 return;
1283 }
1284
1285 _MDrv_PCMCIA_SwitchModule(eModule);
1286
1287 // select attribute memory write, low byte
1288 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_PCM_MEM_IO_CMD, PCMCIA_IO_WRITE );
1289
1290 // write address
1291 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR1, ( u16Addr >> 8 ) );
1292 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR0, u16Addr );
1293 // write data
1294 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_WRITE_DATA, u8Value );
1295
1296 // fire command
1297 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, PCMCIA_FIRE_COMMAND );
1298
1299
1300 //polling if fire is done
1301 for ( i = 0; i < PCMCIA_MAX_POLLING_COUNT; i++ )
1302 {
1303 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, (MS_U8 *)&u8Reg );
1304
1305 if ( !( u8Reg & PCMCIA_FIRE_COMMAND ) )
1306 {
1307 break;
1308 }
1309 else
1310 {
1311 if ( !_MDrv_PCMCIA_IsModuleStillPluggedV2(eModule) )
1312 {
1313 return;
1314 }
1315 }
1316 }
1317
1318 // polling if bus is idle
1319 for ( i = 0; i < PCMCIA_MAX_POLLING_COUNT; i++ )
1320 {
1321 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA_DONE_BUS_IDLE, (MS_U8 *)&u8Reg );
1322
1323 if ( u8Reg & PCMCIA_STATE_BUS_IDLE )
1324 {
1325 break;
1326 }
1327 else
1328 {
1329 if ( !_MDrv_PCMCIA_IsModuleStillPluggedV2(eModule) )
1330 {
1331 return;
1332 }
1333 }
1334 }
1335 }
1336
_MDrv_PCMCIA_WriteIOMemLongV2(PCMCIA_MODULE eModule,MS_U16 u16Addr,MS_U8 u8Value,MS_U16 u16DataLen,MS_U8 * u8pWriteBuffer)1337 void _MDrv_PCMCIA_WriteIOMemLongV2( PCMCIA_MODULE eModule, MS_U16 u16Addr, MS_U8 u8Value, MS_U16 u16DataLen, MS_U8* u8pWriteBuffer)
1338 {
1339
1340 if(eModule >= E_PCMCIA_MODULE_MAX)
1341 {
1342 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1343 return;
1344 }
1345 _MDrv_PCMCIA_SwitchModule(eModule);
1346
1347 #ifdef CONFIG_PCMCIA_MSPI_BURST
1348 _MSPI_RWLong(PCMCIA_IO_WRITE, u16Addr, u8pWriteBuffer, u16DataLen);
1349 #else
1350 MS_U8 u8Reg = 0;
1351 MS_U16 i,j;
1352
1353 // select attribute memory write, low byte
1354 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_PCM_MEM_IO_CMD, PCMCIA_IO_WRITE );
1355
1356 // write address
1357 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR1, ( u16Addr >> 8 ) );
1358 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR0, u16Addr );
1359
1360 for ( i = 0; i < u16DataLen; i++ )
1361 {
1362 // write data
1363 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_WRITE_DATA, u8pWriteBuffer[i] );
1364
1365 // fire command
1366 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, PCMCIA_FIRE_COMMAND );
1367
1368 //polling if fire is done
1369 for ( j = 0; j < PCMCIA_MAX_POLLING_COUNT; ++j )
1370 {
1371 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, (MS_U8 *)&u8Reg );
1372
1373 if ( !( u8Reg & PCMCIA_FIRE_COMMAND ) )
1374 {
1375 break;
1376 }
1377 else
1378 {
1379 if ( !_MDrv_PCMCIA_IsModuleStillPluggedV2(eModule) )
1380 {
1381 return;
1382 }
1383 }
1384 }
1385
1386 // polling if bus is idle
1387 for ( j = 0; j < PCMCIA_MAX_POLLING_COUNT; ++j )
1388 {
1389 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA_DONE_BUS_IDLE, (MS_U8 *)&u8Reg );
1390
1391 if ( u8Reg & PCMCIA_STATE_BUS_IDLE )
1392 {
1393 break;
1394 }
1395 else
1396 {
1397 if ( !MDrv_PCMCIA_IsModuleStillPlugged() )
1398 {
1399 return;
1400 }
1401 }
1402 }
1403 }
1404 #endif
1405
1406 }
1407
1408 //! This function is read one byte of from the card IO memory at address wAddr.
_MDrv_PCMCIA_ReadIOMemV2(PCMCIA_MODULE eModule,MS_U16 u16Addr)1409 MS_U8 _MDrv_PCMCIA_ReadIOMemV2( PCMCIA_MODULE eModule, MS_U16 u16Addr )
1410 {
1411 MS_U8 u8Reg = 0;
1412 MS_U8 u8Value = 0;
1413 MS_U16 i;
1414
1415 if(eModule >= E_PCMCIA_MODULE_MAX)
1416 {
1417 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1418 return 0;
1419 }
1420 _MDrv_PCMCIA_SwitchModule(eModule);
1421
1422 // select attribute memory read, low byte
1423 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_PCM_MEM_IO_CMD, PCMCIA_IO_READ );
1424
1425 // read address
1426 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR1, ( u16Addr >> 8 ) );
1427 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_ADDR0, u16Addr);
1428
1429 // fire command
1430 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, PCMCIA_FIRE_COMMAND );
1431
1432 //polling if fire is done
1433 for ( i = 0; i < PCMCIA_MAX_POLLING_COUNT; i++ )
1434 {
1435 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, (MS_U8 *)&u8Reg );
1436
1437 if ( !( u8Reg & PCMCIA_FIRE_COMMAND ) )
1438 {
1439 break;
1440 }
1441 else
1442 {
1443 if ( !MDrv_PCMCIA_IsModuleStillPlugged() )
1444 {
1445 return 0x00;
1446 }
1447 }
1448 }
1449
1450 //polling if data ready
1451 for ( i = 0; i < PCMCIA_MAX_POLLING_COUNT; i++ )
1452 {
1453 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA_DONE_BUS_IDLE, (MS_U8 *)&u8Reg );
1454
1455 if ( u8Reg & PCMCIA_STATE_RD_DONE )
1456 {
1457 //_MDrv_PCMCIA_GetSemaphore();
1458 {
1459 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA, (MS_U8 *)&u8Value );
1460 }
1461 //_MDrv_PCMCIA_ReleaseSemaphore();
1462 break;
1463 }
1464 else
1465 {
1466 if ( !_MDrv_PCMCIA_IsModuleStillPluggedV2(eModule) )
1467 {
1468 return 0x00;
1469 }
1470 }
1471 }
1472
1473 // clean stat_rd done
1474 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_FIRE_READ_DATA_CLEAR, PCMCIA_CLEAN_STATE_RD_DONE );
1475
1476 // polling if bus is idle
1477 for ( i = 0; i < PCMCIA_MAX_POLLING_COUNT; i++ )
1478 {
1479 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_READ_DATA_DONE_BUS_IDLE, (MS_U8 *)&u8Reg );
1480
1481 if ( PCMCIA_STATE_BUS_IDLE == ( u8Reg & ( PCMCIA_STATE_BUS_IDLE | PCMCIA_STATE_RD_DONE ) ) )
1482 {
1483 break;
1484 }
1485 else
1486 {
1487 if ( !_MDrv_PCMCIA_IsModuleStillPluggedV2(eModule) )
1488 {
1489 return 0x00;
1490 }
1491 }
1492 }
1493
1494 //printk("Read Addr %x, value %bx\n", u16Addr, u8mem);
1495
1496 return u8Value;
1497 }
1498 #endif
1499
_MDrv_PCMCIA_IsModuleStillPluggedV2(PCMCIA_MODULE eModule)1500 MS_BOOL _MDrv_PCMCIA_IsModuleStillPluggedV2( PCMCIA_MODULE eModule )
1501 {
1502 if(eModule >= E_PCMCIA_MODULE_MAX)
1503 {
1504 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1505 return FALSE;
1506 }
1507
1508 return ( _gbCardInside[eModule] );
1509 }
1510
_MDrv_PCMCIA_Set_Detect_Trigger(MS_BOOL bHighActive)1511 void _MDrv_PCMCIA_Set_Detect_Trigger( MS_BOOL bHighActive )
1512 {
1513 _gbHighActive = bHighActive;
1514 return;
1515 }
1516
_MDrv_PCMCIA_Set_Detect_Enable(MS_BOOL bEnable)1517 void _MDrv_PCMCIA_Set_Detect_Enable( MS_BOOL bEnable )
1518 {
1519 _gbPCMCIA_Detect_Enable = bEnable;
1520 }
1521
_MDrv_PCMCIA_Get_CD_IntervalV2(PCMCIA_MODULE eModule)1522 MS_U32 _MDrv_PCMCIA_Get_CD_IntervalV2( PCMCIA_MODULE eModule )
1523 {
1524 if(eModule >= E_PCMCIA_MODULE_MAX)
1525 {
1526 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1527 return 0;
1528 }
1529
1530 return _gu32PCMCIA_CD_To_HWRST_Timer[eModule];
1531 }
1532
_MDrv_PCMCIA_ParseAttribMem(MS_U8 * pAttribMem,MS_U16 dwLen,PCMCIA_INFO * pInfo)1533 void _MDrv_PCMCIA_ParseAttribMem( MS_U8 *pAttribMem, MS_U16 dwLen, PCMCIA_INFO *pInfo )
1534 {
1535 MS_U8 bTag = 0;
1536 MS_U8 bTagLen = 0;
1537 MS_U16 i = 0;
1538 MS_U8 FieldSize = 0;
1539 //MS_U8 LastIndex = 0;
1540 //MS_U8 MaskByte = 0;
1541 //MS_U8 SubTagByte = 0;
1542 MS_U8 SubTagLen = 0;
1543 //MS_U16 STCI_IFN = 0;
1544 MS_U8 fInterface = 0;
1545 char CiDetStr[20];
1546
1547 if ( ( NULL == pAttribMem ) || ( NULL == pInfo ) )
1548 {
1549 return;
1550 }
1551
1552 memset( pInfo, 0x00, sizeof( PCMCIA_INFO ) );
1553 do
1554 {
1555 bTag = pAttribMem[0];
1556 bTagLen = pAttribMem[1];
1557 if ( (MS_U16)bTagLen + 2 > dwLen )
1558 {
1559 return ;
1560 }
1561
1562 dwLen -= ( bTagLen + 2 );
1563 PCMCIA_DEBUG( ( "Parse_PCMCIA_AttribMem:bTag[0x%02X] dwLen[%d bytes]\n", bTag, dwLen ) );
1564 switch ( bTag )
1565 {
1566 case CISTPL_NULL:
1567 PCMCIA_DEBUG( ( "Parse_PCMCIA_AttribMem case 0x00\n" ) );
1568 break;
1569
1570 case CISTPL_DEVICE:
1571 PCMCIA_DEBUG( ( "CISTPL_DEVICE\n" ) );
1572 // Memory type
1573 // Access speed
1574 // Memory Size
1575 break;
1576 case CISTPL_LINKTARGET:
1577 PCMCIA_DEBUG( ( "CISTPL_LINKTARGET\n" ) );
1578 // "CIS"
1579 break;
1580 case CISTPL_NO_LINK:
1581 //PCMCIA_DEBUG(("CISTPL_NOLINK\n"));
1582 break;
1583 case CISTPL_VERS_1:
1584 pInfo->wPCMCIAStdRev = (MS_U16)pAttribMem[2] << 8 | (MS_U16)pAttribMem[3];
1585 pInfo->dwValidFlags |= PCMCIAINFO_VERS1_VALID;
1586 i = 4;
1587 if ( bTagLen < 2 )
1588 {
1589 break;
1590 } // error
1591 memcpy( pInfo->pszManufacturerName, pAttribMem + i,
1592 pcmcia_min( bTagLen + 2 - i, MAX_PCMCIA_STRLEN - 1 ) );
1593 pInfo->pszManufacturerName[pcmcia_min( bTagLen + 2 - i, MAX_PCMCIA_STRLEN - 1 )] = '\0';
1594 i += strlen( ( char* )pAttribMem + i ) + 1;
1595 if ( i < bTagLen + 2 )
1596 {
1597 memcpy( pInfo->pszProductName, pAttribMem + i,
1598 pcmcia_min( bTagLen + 2 - i, MAX_PCMCIA_STRLEN - 1 ) );
1599 pInfo->pszProductName[pcmcia_min( bTagLen + 2 - i, MAX_PCMCIA_STRLEN - 1 )] = '\0';
1600 i += strlen( ( char* )pAttribMem + i ) + 1;
1601 }
1602
1603 if ( 0xFF != *( pAttribMem + i ) )
1604 {
1605 if ( i < bTagLen + 2 )
1606 {
1607 memcpy( pInfo->pszProductInfo1, pAttribMem + i,
1608 pcmcia_min( bTagLen + 2 - i, MAX_PCMCIA_STRLEN - 1 ) );
1609 pInfo->pszProductInfo1[pcmcia_min( bTagLen + 2 - i, MAX_PCMCIA_STRLEN - 1 )] = '\0';
1610 i += strlen( ( char* )pAttribMem + i ) + 1;
1611
1612 /* $compatible[ciplus=1]$ */
1613 {
1614 MS_U8 u8aCI_PLUS_STRING1[] = "$compatible[ciplus=";
1615 MS_U8 u8aCI_PLUS_STRING2[] = "$COMPATIBLE[CIPLUS=";
1616 if ( ( 0 == memcmp( pInfo->pszProductInfo1, u8aCI_PLUS_STRING1, sizeof( u8aCI_PLUS_STRING1 ) - 1 ) ) ||
1617 ( 0 == memcmp( pInfo->pszProductInfo1, u8aCI_PLUS_STRING2, sizeof( u8aCI_PLUS_STRING2 ) - 1 ) ) )
1618 {
1619 PCMCIA_DEBUG( ( "CI+ CAM\n" ) );
1620 pInfo->bCI_PLUS = 1;
1621 }
1622 }
1623 }
1624
1625 if ( i < bTagLen + 2 )
1626 {
1627 memcpy( pInfo->pszProductInfo2, pAttribMem + i,
1628 pcmcia_min( bTagLen + 2 - i, MAX_PCMCIA_STRLEN - 1 ) );
1629 pInfo->pszProductInfo2[pcmcia_min( bTagLen + 2 - i, MAX_PCMCIA_STRLEN - 1 )] = '\0';
1630 }
1631 }
1632 #if 0//PCMCIA_DEBUG_ENABLE
1633 ULOGD("PCMCIA", "ManufacturerName %s \n", pInfo->pszManufacturerName );
1634 ULOGD("PCMCIA", "ProductName %s \n", pInfo->pszProductName );
1635 ULOGD("PCMCIA", "ProductInfo1 %s \n", pInfo->pszProductInfo1 );
1636 ULOGD("PCMCIA", "ProductInfo2 %s \n", pInfo->pszProductInfo2 );
1637 #endif
1638 break;
1639 case CISTPL_DEVICE_A:
1640 //PCMCIA_DEBUG( ( "CISTPL_DEVICE_A\n" ) );
1641 // Like 0x01... for device(s) in attribute memory
1642 // Memory type
1643 // Access speed
1644 // Memory Size
1645 break;
1646 case CISTPL_CONFIG:
1647 PCMCIA_DEBUG( ( "CISTPL_CONFIG\n" ) );
1648 /*
1649 {
1650 MS_U8 bNumAddrBytes;
1651 MS_U8 bNumConfigRegs;
1652 MS_U8 bLastIndex;
1653 bNumAddrBytes = (pAttribMem[2]&0x03)+1;
1654 bNumConfigRegs = ((pAttribMem[2]>>2)&0x0F)+1;
1655 bLastIndex = pAttribMem[3]&0x3F;
1656 for ( i = 0; i < bNumAddrBytes; i++ )
1657 {
1658 pInfo->ConfigOffset = pInfo->ConfigOffset<<8;
1659 pInfo->ConfigOffset |= pAttribMem[4+i];
1660 PCMCIA_DEBUG( ( "ConfigOffset %08lX\n", pInfo->ConfigOffset ) );
1661 }
1662 i++;
1663 }
1664 */
1665 FieldSize = pAttribMem[2];
1666 //LastIndex = pAttribMem[3];
1667 if ( FieldSize == 0 )
1668 {
1669 pInfo->ConfigOffset = pAttribMem[4];
1670 }
1671 else if ( FieldSize == 1 )
1672 {
1673 pInfo->ConfigOffset = (MS_U32)pAttribMem[5] << 8 | (MS_U32)pAttribMem[4];
1674 }
1675 PCMCIA_DEBUG( ( "ConfigOffset 0x%lx\n", pInfo->ConfigOffset ) );
1676 //MaskByte = pAttribMem[5 + FieldSize];
1677 //SubTagByte = pAttribMem[6 + FieldSize];
1678 SubTagLen = pAttribMem[7 + FieldSize];
1679 //STCI_IFN = (MS_U16)pAttribMem[9 + FieldSize] << 8 | (MS_U16)pAttribMem[8 + FieldSize];
1680 memcpy( CiDetStr, pAttribMem + 10 + FieldSize, pcmcia_min( SubTagLen - 2, sizeof( CiDetStr ) - 1 ) );
1681 CiDetStr[pcmcia_min( SubTagLen - 2, sizeof( CiDetStr ) - 1 )] = 0;
1682 //PCMCIA_DEBUG( ( "FieldSize %d, LastIndex %d MaskByte %02X SubTag %02X ID %02X %s\n", FieldSize, LastIndex, MaskByte, SubTagByte, STCI_IFN, CiDetStr ) );
1683 break;
1684 case CISTPL_CFTABLE_ENTRY:
1685 PCMCIA_DEBUG( ( "CISTPL_CFTABLE_ENTRY\n" ) );
1686 {
1687 //MS_U8 bIF = 0;
1688 MS_U8 bFlags = 0;
1689 MS_U16 j = 0;
1690
1691 pInfo->bINT = FALSE; // It's MUST because there are multiple CISTPL_CFTABLE_ENTRYs.
1692
1693 pInfo->Config[pInfo->bNumConfigs].bConfigIndex = ( pAttribMem[2] & 0x3F );
1694 PCMCIA_DEBUG(("Config Entry value 0x02%X\n",pInfo->Config[pInfo->bNumConfigs].bConfigIndex));
1695 if ( pAttribMem[2] & 0x40 )
1696 {
1697 ;
1698 } // Default
1699 if ( pAttribMem[2] & 0x80 )
1700 {
1701 //bIF = pAttribMem[3];
1702 i = 4;
1703 }
1704 else
1705 {
1706 i = 3;
1707 }
1708 bFlags = pAttribMem[i]; // TPCE_FS: Feature Selection Byte
1709 i++;
1710
1711 if ( bFlags & (BIT0 | BIT1) ) // BIT0 | BIT1 = TPCE_FS: Power
1712 {/* TPCE_PD: Power Description Structure */
1713 MS_U8 bPowerBits = pAttribMem[i]; // Parameter Selection Byte
1714
1715 //PCMCIA_DEBUG( ( "PowerDesc %02X\n", bPowerBits ) );
1716 i++;
1717 for ( j = 0; j < 7; j++ )
1718 {
1719 if ( ( bPowerBits >> j ) & 0x01 )
1720 {
1721 i++;
1722 }
1723 while ( pAttribMem[i] & 0x80 )
1724 {
1725 i++;
1726 } // extension byte
1727 }
1728 }
1729
1730 if ( bFlags & BIT2 ) // BIT2 = Timing
1731 {/* TPCE_TD: Configuration Timing Information */
1732 //PCMCIA_DEBUG( ( "TimingDesc %02X\n", pAttribMem[i] ) );
1733 i++;
1734 }
1735
1736 if ( bFlags & BIT3 ) // BIT3 = IO Space
1737 {/* TPCE_IO: I/O Space Addresses Required For This Configuration */
1738 if ( pAttribMem[i] & 0x80 ) // BIT7 = Range
1739 {
1740 /* Range = 1: The I/O Space definition byte is followed by an I/O Range Descriptor byte, and
1741 one or more I/O Address Range Description fields.
1742 */
1743 MS_U8 bAddrBytes;
1744 MS_U8 bLenBytes;
1745 //MS_U8 bNumDesc;
1746 MS_U32 dwEALen = 0;
1747 MS_U32 dwEAAddr = 0;
1748 //bNumDesc = pAttribMem[i + 1] & 0x0F; // I/O Range Descriptor Byte: Number of I/O Address Ranges (Bit 0~3))
1749 bAddrBytes = ( pAttribMem[i + 1] >> 4 ) & 0x03; // I/O Range Descriptor Byte: Size of Address (Bit 4~5)
1750 bLenBytes = ( pAttribMem[i + 1] >> 6 ) & 0x03; // I/O Range Descriptor Byte: Size of Length (Bit 6~7)
1751 //PCMCIA_DEBUG( ( "EADesc %02X %d %d %d\n", pAttribMem[i + 1], bNumDesc, bAddrBytes, bLenBytes ) );
1752 i += 2;
1753 switch ( bAddrBytes )
1754 {
1755 case 1:
1756 dwEAAddr = pAttribMem[i];
1757 break;
1758 case 2:
1759 dwEAAddr = (MS_U32)pAttribMem[i] | (MS_U32)pAttribMem[i + 1] << 8;
1760 break;
1761 }
1762 pInfo->Config[pInfo->bNumConfigs].dwEAAddr = dwEAAddr;
1763 i += bLenBytes;
1764 switch ( bLenBytes )
1765 {
1766 case 1:
1767 dwEALen = pAttribMem[i];
1768 break;
1769 case 2:
1770 dwEALen = (MS_U32)pAttribMem[i] | (MS_U32)pAttribMem[i + 1] << 8;
1771 break;
1772 }
1773 pInfo->Config[pInfo->bNumConfigs].dwEALen = dwEALen;
1774 i += bAddrBytes;
1775 //PCMCIA_DEBUG( ( "Addr %04X Len %04X", dwEAAddr, dwEALen ) );
1776 }
1777 else
1778 {
1779 i++;
1780 }
1781 }
1782
1783 if ( bFlags & BIT4 ) // BIT4 = IRQ
1784 {/* TPCE_IR: Interrupt Request Description Structure */
1785 PCMCIA_DEBUG( ( "IrqDesc: 0x%02X\n", pAttribMem[i] ) );
1786 pInfo->Config[pInfo->bNumConfigs].bIRQDesc1 = pAttribMem[i];
1787 if ( ( pAttribMem[i] & BIT5) && ( !(pAttribMem[i] & (~BIT5) ) ) )
1788 {
1789 pInfo->bINT = ENABLE;
1790 }
1791 else if ( pAttribMem[i] & BIT4 )
1792 {
1793 pInfo->Config[pInfo->bNumConfigs].wIRQData = (MS_U16)pAttribMem[i + 1] << 8 |
1794 (MS_U16)pAttribMem[i + 2];
1795 i += 2;
1796 }
1797 i++;
1798 }
1799 if ( bFlags & 0x60 )
1800 {
1801 PCMCIA_DEBUG( ( "MemoryDesc\n" ) );
1802 i++;
1803 }
1804 if ( bFlags & 0x80 )
1805 {
1806 PCMCIA_DEBUG( ( "MixedDesc\n" ) );
1807 i++;
1808 }
1809
1810 while ( i < ( bTagLen + 2 ) )
1811 {
1812 PCMCIA_DEBUG( ( "SubTag 0x%02X %d %d\n", pAttribMem[i], i, bTagLen ) );
1813 if ( pAttribMem[i] == 0xc0 )
1814 {
1815 if ( strcmp( ( char* )pAttribMem + i + 2, "DVB_HOST" ) == 0 )
1816 {
1817 pInfo->Config[pInfo->bNumConfigs].fCITagsPresent |= 0x01;
1818 }
1819 PCMCIA_DEBUG( ( "%s\n", pAttribMem + i + 2 ) );
1820 }
1821 if ( pAttribMem[i] == 0xc1 )
1822 {
1823 if ( strcmp( ( char* )pAttribMem + i + 2, "DVB_CI_MODULE" ) == 0 )
1824 {
1825 pInfo->Config[pInfo->bNumConfigs].fCITagsPresent |= 0x02;
1826 }
1827 PCMCIA_DEBUG( ( "%s\n", pAttribMem + i + 2 ) );
1828 }
1829 i += pAttribMem[i + 1] + 2;
1830 }
1831
1832 pInfo->bNumConfigs++;
1833 }
1834 fInterface = ( pAttribMem[2] >> 6 ) & 0x01;
1835 if ( fInterface )
1836 {
1837 //PCMCIA_DEBUG( ( "IF %02X ", pAttribMem[3] ) );
1838 }
1839
1840 #if 0
1841 PCMCIA_DEBUG( ( "\n" ) );
1842
1843 for ( i = 0; i < bTagLen; i++ )
1844 {
1845 PCMCIA_DEBUG( ( "%02X ", pAttribMem[2 + i] ) );
1846 }
1847 PCMCIA_DEBUG( ( "\n" ) );
1848 for ( i = 0; i < bTagLen; i++ )
1849 {
1850 PCMCIA_DEBUG( ( "%c ", pAttribMem[2 + i] ) );
1851 }
1852 PCMCIA_DEBUG( ( "\n" ) );
1853 #endif
1854 break;
1855 case CISTPL_DEVICE_OC:
1856 PCMCIA_DEBUG( ( "CISTPL_DEVICE_OC\n" ) );
1857 break;
1858 case CISTPL_DEVICE_OA:
1859 PCMCIA_DEBUG( ( "CISTPL_DEVICE_OA\n" ) );
1860 break;
1861 case CISTPL_MANFID:
1862 PCMCIA_DEBUG( ( "CISTPL_MANFID\n" ) );
1863 pInfo->dwValidFlags |= PCMCIAINFO_MANID_VALID;
1864 pInfo->wManufacturerId = (MS_U16)pAttribMem[2] << 8 | (MS_U16)pAttribMem[3];
1865 pInfo->wCardID = (MS_U16)pAttribMem[4] << 8 | (MS_U16)pAttribMem[5];
1866 PCMCIA_DEBUG( ( "Manufacturer code %04X Product Code %04X\n",
1867 pInfo->wManufacturerId, pInfo->wCardID ) );
1868 #if 0//PCMCIA_DUMP_CISMANID
1869 ULOGD("PCMCIA", "wManufacturerId %x \n", pInfo->wManufacturerId );
1870 ULOGD("PCMCIA", "CardID %x \n", pInfo->wCardID );
1871 #endif
1872 break;
1873 case CISTPL_FUNCID:
1874 PCMCIA_DEBUG( ( "CISTPL_FUNCID\n" ) );
1875 pInfo->dwValidFlags |= PCMCIAINFO_FUNCID_VALID;
1876 pInfo->FuncType = ( PCMCIA_FUNCTYPE )pAttribMem[2];
1877 pInfo->bFuncIDSysInfo = pAttribMem[3];
1878 break;
1879 case CISTPL_VERS_2:
1880 // CISTPL_VERS2
1881 PCMCIA_DEBUG( ( "Parse_PCMCIA_AttribMem case 0x40\n" ) );
1882 break;
1883 default:
1884 #if 0
1885 PCMCIA_DEBUG( ( "Parse_PCMCIA_AttribMem case else\n" ) );
1886 PCMCIA_DEBUG( ( "Tag %02X, Len %d\n", bTag, bTagLen ) );
1887 for ( i = 0; i < bTagLen; i++ )
1888 {
1889 PCMCIA_DEBUG( ( "%02X ", pAttribMem[2 + i] ) );
1890 }
1891 PCMCIA_DEBUG( ( "\n" ) );
1892 for ( i = 0; i < bTagLen; i++ )
1893 {
1894 PCMCIA_DEBUG( ( "%c", pAttribMem[2 + i] ) );
1895 }
1896 PCMCIA_DEBUG( ( "\n" ) );
1897 #endif
1898 break;
1899 }
1900 pAttribMem += ( 2 + (MS_U16)bTagLen );
1901 }
1902 while ( ( bTag != 0x14 ) && ( bTag != 0xFF ) && ( dwLen ) );
1903
1904 return;
1905 }
1906
_MDrv_PCMCIA_SetCommandBitV2(PCMCIA_MODULE eModule,MS_U8 u8CommandBit,MS_BOOL bValue)1907 void _MDrv_PCMCIA_SetCommandBitV2( PCMCIA_MODULE eModule, MS_U8 u8CommandBit, MS_BOOL bValue )
1908 {
1909 if(eModule >= E_PCMCIA_MODULE_MAX)
1910 {
1911 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1912 return;
1913 }
1914
1915 if ( bValue )
1916 _gu8PCMCIA_Command[eModule] |= u8CommandBit;
1917 else
1918 _gu8PCMCIA_Command[eModule] &= ( ~u8CommandBit );
1919
1920 _MDrv_PCMCIA_WriteIOMemV2( eModule, PCMCIA_PHYS_REG_COMMANDSTATUS, _gu8PCMCIA_Command[eModule] );
1921 }
1922
_MDrv_PCMCIA_ResetInterfaceV2(PCMCIA_MODULE eModule)1923 MS_BOOL _MDrv_PCMCIA_ResetInterfaceV2( PCMCIA_MODULE eModule )
1924 {
1925 MS_BOOL bRet = TRUE;
1926
1927 if(eModule >= E_PCMCIA_MODULE_MAX)
1928 {
1929 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1930 return FALSE;
1931 }
1932
1933 _gu8PCMCIA_Command[eModule] = 0x00; // Reset CI Command
1934
1935 MsOS_DelayTask( 300 ); // The waiting time in for loop of _MDrv_PCMCIA_WaitForStatusBit() is the key factor.
1936
1937 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_RESET, TRUE ); // Up RS
1938
1939 bRet = _MDrv_PCMCIA_WaitForStatusBitV2( eModule, PCMCIA_STATUS_FREE );
1940
1941 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_RESET, FALSE ); // Down RS
1942
1943 // For some specific CAMs, it sets the Free bit after RS bit is clear.
1944 if(bRet == FALSE)
1945 {
1946 bRet = MDrv_PCMCIA_WaitForStatusBitV2( eModule, PCMCIA_STATUS_FREE );
1947 }
1948 return bRet;
1949 }
1950
_MDrv_PCMCIA_IsDataAvailableV2(PCMCIA_MODULE eModule)1951 MS_BOOL _MDrv_PCMCIA_IsDataAvailableV2( PCMCIA_MODULE eModule )
1952 {
1953 MS_U8 u8StatusBit = 0;
1954
1955 if(eModule >= E_PCMCIA_MODULE_MAX)
1956 {
1957 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1958 return FALSE;
1959 }
1960 u8StatusBit = _MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_COMMANDSTATUS );
1961
1962 return ( u8StatusBit & PCMCIA_STATUS_DATAAVAILABLE );
1963 }
1964
_MDrv_PCMCIA_ReadDataV2(PCMCIA_MODULE eModule,MS_U8 * u8pReadBuffer,MS_U16 u16ReadBufferSize)1965 MS_U16 _MDrv_PCMCIA_ReadDataV2( PCMCIA_MODULE eModule, MS_U8* u8pReadBuffer, MS_U16 u16ReadBufferSize )
1966 {
1967 if(eModule >= E_PCMCIA_MODULE_MAX)
1968 {
1969 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
1970 return FALSE;
1971 }
1972
1973 #if defined ( MSOS_TYPE_LINUX ) && !defined (CONFIG_PCMCIA_MSPI)
1974 PCMCIA_Map_Info_t stMapInfo;
1975 stMapInfo.u16DataLen = u16ReadBufferSize;
1976 stMapInfo.u8pReadBuffer = u8pReadBuffer;
1977 MS_U32 u32Ret = UTOPIA_STATUS_FAIL;
1978
1979 PCM_ENTER();
1980 _MDrv_PCMCIA_SwitchModule(eModule);
1981
1982 u32Ret = ioctl(SYS_fd, IOCTL_SYS_PCMCIA_READ_DATA , &stMapInfo);
1983
1984 PCM_EXIT();
1985
1986 if(UTOPIA_STATUS_SUCCESS != u32Ret)
1987 {
1988 return 0;
1989 }
1990 else
1991 {
1992 return stMapInfo.u16DataLen;
1993 }
1994 #else
1995 MS_U16 u16DataLen = 0;
1996
1997 u16DataLen = (MS_U16)_MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_SIZEHIGH ) << 8 |
1998 (MS_U16)_MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_SIZELOW );
1999
2000 if ( ( 0 != u16ReadBufferSize ) & ( u16DataLen > u16ReadBufferSize ) )
2001 u16DataLen = u16ReadBufferSize;
2002
2003 #ifdef CONFIG_PCMCIA_MSPI_BURST
2004 _MSPI_RWLong(PCMCIA_IO_READ, PCMCIA_PHYS_REG_DATA, u8pReadBuffer, u16DataLen);
2005 #else
2006 MS_U16 i = 0;
2007 for ( i = 0; i < u16DataLen; i++ )
2008 {
2009 u8pReadBuffer[i] = _MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_DATA );
2010 }
2011 #endif
2012
2013 return u16DataLen;
2014 #endif
2015 }
2016
_MDrv_PCMCIA_WriteDataV2(PCMCIA_MODULE eModule,MS_U8 * u8pWriteBuffer,MS_U16 u16DataLen)2017 MS_BOOL _MDrv_PCMCIA_WriteDataV2( PCMCIA_MODULE eModule, MS_U8* u8pWriteBuffer, MS_U16 u16DataLen )
2018 {
2019 MS_U16 u16TryLoop = 0;
2020 MS_U16 i = 0;
2021
2022 if(eModule >= E_PCMCIA_MODULE_MAX)
2023 {
2024 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
2025 return FALSE;
2026 }
2027
2028 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_HOSTCONTROL, TRUE ); // Up HC
2029 while ( ( !( _MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_COMMANDSTATUS ) & PCMCIA_STATUS_FREE ) ) &&
2030 ( u16TryLoop < PCMCIA_HW_MAX_RETRY_COUNT ) )
2031 {
2032 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_HOSTCONTROL, FALSE ); // Down HC
2033 MsOS_DelayTask( 1 );
2034 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_HOSTCONTROL, TRUE ); // Up HC
2035 u16TryLoop++;
2036 }
2037
2038 if ( PCMCIA_HW_MAX_RETRY_COUNT == u16TryLoop )
2039 {
2040 ULOGE("PCMCIA", "MDrv_PCMCIA_WriteData: not \"free\", retry %d times fail!\r\n", u16TryLoop);
2041 return FALSE;
2042 }
2043
2044 _MDrv_PCMCIA_WriteIOMemV2( eModule, PCMCIA_PHYS_REG_SIZELOW, (MS_U8)( u16DataLen & 0xFF ) );
2045 _MDrv_PCMCIA_WriteIOMemV2( eModule, PCMCIA_PHYS_REG_SIZEHIGH, (MS_U8)( u16DataLen >> 8 ) );
2046 _MDrv_PCMCIA_WriteIOMemLongV2( eModule, PCMCIA_PHYS_REG_DATA, u8pWriteBuffer[i], u16DataLen, u8pWriteBuffer );
2047
2048 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_HOSTCONTROL, FALSE ); // Down HC
2049 if(_MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_COMMANDSTATUS ) & PCMCIA_STATUS_WRITEERROR)
2050 {
2051 printf("%s WE = 1\n", __FUNCTION__);
2052 return FALSE;
2053 }
2054 else
2055 {
2056 return TRUE;
2057 }
2058 }
2059
_MDrv_PCMCIA_SwitchToIOmodeV2(PCMCIA_MODULE eModule,PCMCIA_INFO * pInfo)2060 MS_BOOL _MDrv_PCMCIA_SwitchToIOmodeV2( PCMCIA_MODULE eModule, PCMCIA_INFO *pInfo )
2061 {
2062 MS_U8 i = 0;
2063
2064 if(eModule >= E_PCMCIA_MODULE_MAX)
2065 {
2066 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
2067 return FALSE;
2068 }
2069
2070 MsOS_DelayTask( 1000 );
2071
2072 for ( i = 0; i < pInfo->bNumConfigs; i++ )
2073 {
2074 if ( pInfo->Config[i].fCITagsPresent == 0x03 )
2075 {
2076 _MDrv_PCMCIA_WriteAttribMemV2( eModule, (MS_U16)( pInfo->ConfigOffset ), pInfo->Config[i].bConfigIndex ); //switch to i/o mode
2077
2078 return TRUE;
2079 }
2080 }
2081
2082 return FALSE;
2083 }
2084
_MDrv_PCMCIA_NegotiateBufferSizeV2(PCMCIA_MODULE eModule,PCMCIA_INFO * pInfo)2085 MS_U16 _MDrv_PCMCIA_NegotiateBufferSizeV2( PCMCIA_MODULE eModule, PCMCIA_INFO *pInfo )
2086 {
2087 MS_U16 u16BufferSize;
2088
2089 if(eModule >= E_PCMCIA_MODULE_MAX)
2090 {
2091 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
2092 return 0;
2093 }
2094
2095 if ( NULL == pInfo )
2096 {
2097 PCMCIA_DEBUG( ( "ERROR: MDrv_PCMCIA_NegotiateBufferSize: NULL == pInfo!\n" ) );
2098 return 0;
2099 }
2100
2101 // write size read
2102 PCMCIA_DEBUG( ( "Write Size Read\n" ) );
2103 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_SIZEREAD, TRUE ); // Up SR
2104 if ( !_MDrv_PCMCIA_WaitForStatusBitV2( eModule, PCMCIA_STATUS_DATAAVAILABLE ) )
2105 {
2106 PCMCIA_DEBUG( ( "ERROR: MDrv_PCMCIA_NegotiateBufferSize NG!\n" ) );
2107 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_SIZEREAD, FALSE ); // Down SR
2108 return 0;
2109 }
2110
2111 // Dump Buffersize
2112 // read the size (this is always 0002, byteswapped)
2113 u16BufferSize = (MS_U16)_MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_SIZEHIGH ) << 8 |
2114 (MS_U16)_MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_SIZELOW );
2115 PCMCIA_DEBUG( ( "Datalen %04X\n", u16BufferSize ) );
2116 // if the module returned an invalid data size, initiate a reset
2117 if ( u16BufferSize != 0x0002 )
2118 {
2119 PCMCIA_DEBUG( ( "ERROR: MDrv_PCMCIA_NegotiateBufferSize: Invalid BufferSize!\n" ) );
2120 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_SIZEREAD, FALSE ); // Down SR
2121 return 0;
2122 }
2123 u16BufferSize = (MS_U16)_MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_DATA ) << 8;
2124 u16BufferSize |= (MS_U16)_MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_DATA );
2125 PCMCIA_DEBUG( ( "BufferSize %02X\n", u16BufferSize ) );
2126
2127 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_SIZEREAD, FALSE ); // Down SR
2128
2129 return u16BufferSize;
2130 }
2131
_MDrv_PCMCIA_WriteBufferSizeV2(PCMCIA_MODULE eModule,MS_U16 u16BufferSize)2132 void _MDrv_PCMCIA_WriteBufferSizeV2( PCMCIA_MODULE eModule, MS_U16 u16BufferSize )
2133 {
2134 MS_U16 u16TryLoop = 0;
2135
2136 if(eModule >= E_PCMCIA_MODULE_MAX)
2137 {
2138 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
2139 return;
2140 }
2141
2142 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_SIZEWRITE, TRUE ); // Up SW
2143 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_HOSTCONTROL, TRUE ); // Up HC
2144
2145 while ( ( !( _MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_COMMANDSTATUS ) & PCMCIA_STATUS_FREE ) ) &&
2146 ( u16TryLoop < PCMCIA_HW_MAX_RETRY_COUNT ) )
2147 {
2148 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_HOSTCONTROL, FALSE ); // Down HC
2149 MsOS_DelayTask( 1 );
2150 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_HOSTCONTROL, TRUE ); // Up HC
2151 u16TryLoop++;
2152 }
2153
2154 if ( PCMCIA_HW_MAX_RETRY_COUNT == u16TryLoop )
2155 {
2156 ULOGE("PCMCIA", "ERROR: MDrv_PCMCIA_WriteBufferSize NG!\n" );
2157 }
2158
2159 _MDrv_PCMCIA_WriteIOMemV2( eModule, PCMCIA_PHYS_REG_SIZELOW, 0x02 );
2160 _MDrv_PCMCIA_WriteIOMemV2( eModule, PCMCIA_PHYS_REG_SIZEHIGH, 0x00 );
2161 _MDrv_PCMCIA_WriteIOMemV2( eModule, PCMCIA_PHYS_REG_DATA, (MS_U8)( u16BufferSize >> 8 ) );
2162 _MDrv_PCMCIA_WriteIOMemV2( eModule, PCMCIA_PHYS_REG_DATA, (MS_U8)( u16BufferSize ) );
2163
2164 MsOS_DelayTask( 50 );
2165
2166 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_HOSTCONTROL, FALSE ); // Down HC
2167 _MDrv_PCMCIA_SetCommandBitV2( eModule, PCMCIA_COMMAND_SIZEWRITE, FALSE ); // Down SW
2168
2169 PCMCIA_DEBUG( ( "Write Buffersize: 0x%04X bytes\n", u16BufferSize ) );
2170 MsOS_DelayTask( 100 );//Black Viacess
2171 }
2172
MDrv_PCMCIA_ReadyStatus(void)2173 MS_U8 MDrv_PCMCIA_ReadyStatus( void )
2174 {
2175 MS_U8 u8Reg = 0, u8Reg2 = 0, temp = 0;
2176
2177 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_INT_MASK_CLEAR, (MS_U8 *) &temp );
2178 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_INT_MASK_CLEAR, 0x7B );
2179
2180 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_STAT_INT_RAW_INT, (MS_U8 *) &u8Reg );
2181 ULOGD("PCMCIA", "REG_PCMCIA_STAT_INT_RAW_INT %x\n",u8Reg );
2182
2183 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_STAT_INT_RAW_INT1, (MS_U8 *)&u8Reg2 );
2184 ULOGD("PCMCIA", "REG_PCMCIA_STAT_INT_RAW_INT1 %x\n",u8Reg2 );
2185
2186 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_INT_MASK_CLEAR, temp );
2187
2188 return ( u8Reg );
2189
2190 }
2191 //------------------------------------------------------------------------------
2192 /// Get PCMCIA driver version
2193 /// @return -the pointer to the driver version
2194 //------------------------------------------------------------------------------
_MDrv_PCMCIA_GetLibVer(const MSIF_Version ** ppVersion)2195 MS_BOOL _MDrv_PCMCIA_GetLibVer( const MSIF_Version **ppVersion )
2196 {
2197 if (!ppVersion)
2198 return FALSE;
2199
2200 *ppVersion = &_drv_pcmcia_version;
2201 return TRUE;
2202 }
2203
2204 #if PCMCIA_IRQ_ENABLE
_MDrv_PCMCIA_Enable_InterruptV2(PCMCIA_MODULE eModule,MS_BOOL bEnable)2205 void _MDrv_PCMCIA_Enable_InterruptV2( PCMCIA_MODULE eModule, MS_BOOL bEnable )
2206 {
2207 MS_U8 u8Reg;
2208
2209 if(eModule >= E_PCMCIA_MODULE_MAX)
2210 {
2211 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
2212 return;
2213 }
2214
2215 _MDrv_PCMCIA_Set_InterruptStatusV2( eModule, FALSE );
2216
2217 if ( ENABLE == bEnable )
2218 {
2219 _gbPCMCIA_Irq[eModule] = ENABLE;
2220
2221 /* Enable MPU PCMCIA IRQ. */
2222 MsOS_EnableInterrupt( E_INT_IRQ_PCM );
2223
2224 /* Enable IP PCMCIA IRQ. */
2225 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_INT_MASK_CLEAR, (MS_U8 *)&u8Reg );
2226 if(eModule == E_PCMCIA_MODULE_A)
2227 {
2228 u8Reg &= ( ~BIT2 );
2229 u8Reg &= ( ~BIT1 );
2230 u8Reg &= ( ~BIT0 );
2231 }
2232 else
2233 { // Module B
2234 u8Reg &= ( ~BIT5 );
2235 u8Reg &= ( ~BIT4 );
2236 u8Reg &= ( ~BIT3 );
2237 }
2238 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_INT_MASK_CLEAR, u8Reg );
2239 }
2240 else
2241 {
2242 _gbPCMCIA_Irq[eModule] = DISABLE;
2243
2244 /* Here DON"T Disable MPU PCMCIA IRQ. */
2245 /* Disable IP PCMCIA IRQ. */
2246 _MDrv_PCMCIA_ReadReg( REG_PCMCIA_INT_MASK_CLEAR, (MS_U8 *)&u8Reg );
2247 if(eModule == E_PCMCIA_MODULE_A)
2248 {
2249 u8Reg |= BIT2; //Don't mask cardA insert/remove
2250 }
2251 else
2252 { // Module B
2253 u8Reg |= BIT5;
2254 }
2255 _MDrv_PCMCIA_WriteReg( REG_PCMCIA_INT_MASK_CLEAR, u8Reg );
2256 }
2257 }
2258
_MDrv_PCMCIA_Set_InterruptStatusV2(PCMCIA_MODULE eModule,MS_BOOL Status)2259 void _MDrv_PCMCIA_Set_InterruptStatusV2( PCMCIA_MODULE eModule, MS_BOOL Status )
2260 {
2261 _gbPCMCIA_IrqStatus[eModule] = Status;
2262 }
2263
_MDrv_PCMCIA_Get_InterruptStatusV2(PCMCIA_MODULE eModule)2264 MS_BOOL _MDrv_PCMCIA_Get_InterruptStatusV2( PCMCIA_MODULE eModule )
2265 {
2266 return _gbPCMCIA_IrqStatus[eModule];
2267 }
2268
_MDrv_PCMCIA_InstarllIsrCallbackV2(PCMCIA_MODULE eModule,IsrCallback fnIsrCallback)2269 void _MDrv_PCMCIA_InstarllIsrCallbackV2( PCMCIA_MODULE eModule, IsrCallback fnIsrCallback )
2270 {
2271 _fnIsrCallback[eModule] = fnIsrCallback;
2272 }
2273 #endif
2274
_MDrv_PCMCIA_WaitForStatusBitV2(PCMCIA_MODULE eModule,MS_U8 u8StatusBit)2275 MS_BOOL _MDrv_PCMCIA_WaitForStatusBitV2( PCMCIA_MODULE eModule, MS_U8 u8StatusBit )
2276 {
2277 MS_U16 i = 0;
2278
2279 if(eModule >= E_PCMCIA_MODULE_MAX)
2280 {
2281 ULOGE("PCMCIA", "ERROR: Module 0x%x not support\n", (int)eModule);
2282 return FALSE;
2283 }
2284
2285 for ( i = 0; i < 500; i++ )
2286 {
2287 if ( MDrv_PCMCIA_ReadIOMemV2( eModule, PCMCIA_PHYS_REG_COMMANDSTATUS ) & u8StatusBit )
2288 {
2289 return TRUE;
2290 }
2291 MsOS_DelayTask( 15 );
2292 if(!MDrv_PCMCIA_DetectV2(eModule))
2293 {
2294 PCMCIA_DEBUG( ( "ERROR: Card Removed\n" ) );
2295 return FALSE;
2296 }
2297 }
2298
2299 PCMCIA_DEBUG( ( "ERROR: Waiting Timeout for PCMCIA Status Bit\n" ) );
2300
2301 return FALSE;
2302 }
2303
2304 // backward compatible
2305
2306 #if PCMCIA_IRQ_ENABLE
2307
MDrv_PCMCIA_Enable_Interrupt(MS_BOOL bEnable)2308 void MDrv_PCMCIA_Enable_Interrupt( MS_BOOL bEnable )
2309 {
2310 MDrv_PCMCIA_Enable_InterruptV2(PCMCIA_DEFAULT_MODULE, bEnable);
2311 }
2312
MDrv_PCMCIA_Set_InterruptStatus(MS_BOOL Status)2313 void MDrv_PCMCIA_Set_InterruptStatus( MS_BOOL Status )
2314 {
2315 MDrv_PCMCIA_Set_InterruptStatusV2(PCMCIA_DEFAULT_MODULE, Status);
2316 }
2317
MDrv_PCMCIA_Get_InterruptStatus(void)2318 MS_BOOL MDrv_PCMCIA_Get_InterruptStatus( void )
2319 {
2320 return MDrv_PCMCIA_Get_InterruptStatusV2(PCMCIA_DEFAULT_MODULE);
2321 }
2322
MDrv_PCMCIA_InstarllIsrCallback(IsrCallback fnIsrCallback)2323 void MDrv_PCMCIA_InstarllIsrCallback( IsrCallback fnIsrCallback )
2324 {
2325 MDrv_PCMCIA_InstarllIsrCallbackV2(PCMCIA_DEFAULT_MODULE, fnIsrCallback);
2326 }
2327
2328 #endif // PCMCIA_IRQ_ENABLE
2329
MDrv_PCMCIA_Polling(void)2330 MS_BOOL MDrv_PCMCIA_Polling( void )
2331 {
2332 return MDrv_PCMCIA_PollingV2(PCMCIA_DEFAULT_MODULE);
2333 }
2334
MDrv_PCMCIA_IsModuleStillPlugged(void)2335 MS_BOOL MDrv_PCMCIA_IsModuleStillPlugged( void )
2336 {
2337 return MDrv_PCMCIA_IsModuleStillPluggedV2(PCMCIA_DEFAULT_MODULE);
2338 }
2339
MDrv_PCMCIA_SetCommandBit(MS_U8 u8CommandBit,MS_BOOL bValue)2340 void MDrv_PCMCIA_SetCommandBit( MS_U8 u8CommandBit, MS_BOOL bValue )
2341 {
2342 MDrv_PCMCIA_SetCommandBitV2(PCMCIA_DEFAULT_MODULE, u8CommandBit, bValue);
2343 }
2344
MDrv_PCMCIA_ResetInterface(void)2345 MS_BOOL MDrv_PCMCIA_ResetInterface( void )
2346 {
2347 return MDrv_PCMCIA_ResetInterfaceV2(PCMCIA_DEFAULT_MODULE);
2348 }
2349
MDrv_PCMCIA_IsDataAvailable(void)2350 MS_BOOL MDrv_PCMCIA_IsDataAvailable( void )
2351 {
2352 return MDrv_PCMCIA_IsDataAvailableV2(PCMCIA_DEFAULT_MODULE);
2353 }
2354
MDrv_PCMCIA_ReadData(MS_U8 * u8pReadBuffer,MS_U16 u16ReadBufferSize)2355 MS_U16 MDrv_PCMCIA_ReadData( MS_U8* u8pReadBuffer, MS_U16 u16ReadBufferSize )
2356 {
2357 return MDrv_PCMCIA_ReadDataV2(PCMCIA_DEFAULT_MODULE, u8pReadBuffer, u16ReadBufferSize);
2358 }
2359
MDrv_PCMCIA_WriteData(MS_U8 * u8pWriteBuffer,MS_U16 u16DataLen)2360 MS_BOOL MDrv_PCMCIA_WriteData( MS_U8* u8pWriteBuffer, MS_U16 u16DataLen )
2361 {
2362 return MDrv_PCMCIA_WriteDataV2(PCMCIA_DEFAULT_MODULE, u8pWriteBuffer, u16DataLen);
2363 }
2364
MDrv_PCMCIA_SwitchToIOmode(PCMCIA_INFO * pInfo)2365 MS_BOOL MDrv_PCMCIA_SwitchToIOmode( PCMCIA_INFO *pInfo )
2366 {
2367 return MDrv_PCMCIA_SwitchToIOmodeV2(PCMCIA_DEFAULT_MODULE, pInfo);
2368 }
2369
MDrv_PCMCIA_NegotiateBufferSize(PCMCIA_INFO * pInfo)2370 MS_U16 MDrv_PCMCIA_NegotiateBufferSize( PCMCIA_INFO *pInfo )
2371 {
2372 return MDrv_PCMCIA_NegotiateBufferSizeV2(PCMCIA_DEFAULT_MODULE, pInfo);
2373 }
2374
MDrv_PCMCIA_WriteBufferSize(MS_U16 u16BufferSize)2375 void MDrv_PCMCIA_WriteBufferSize( MS_U16 u16BufferSize )
2376 {
2377 MDrv_PCMCIA_WriteBufferSizeV2(PCMCIA_DEFAULT_MODULE, u16BufferSize);
2378 }
2379
MDrv_PCMCIA_WaitForStatusBit(MS_U8 u8StatusBit)2380 MS_BOOL MDrv_PCMCIA_WaitForStatusBit( MS_U8 u8StatusBit )
2381 {
2382 return MDrv_PCMCIA_WaitForStatusBitV2(PCMCIA_DEFAULT_MODULE, u8StatusBit);
2383 }
2384
MDrv_PCMCIA_ResetHW(void)2385 void MDrv_PCMCIA_ResetHW( void )
2386 {
2387 MDrv_PCMCIA_ResetHW_V2(PCMCIA_DEFAULT_MODULE);
2388 }
2389
MDrv_PCMCIA_WriteAttribMem(MS_U16 wAddr,MS_U8 bData)2390 void MDrv_PCMCIA_WriteAttribMem( MS_U16 wAddr, MS_U8 bData )
2391 {
2392 MDrv_PCMCIA_WriteAttribMemV2(PCMCIA_DEFAULT_MODULE, wAddr, bData);
2393 }
2394
MDrv_PCMCIA_ReadAttribMem(MS_U16 u16Addr,MS_U8 * pDest)2395 void MDrv_PCMCIA_ReadAttribMem( MS_U16 u16Addr, MS_U8 *pDest )
2396 {
2397 MDrv_PCMCIA_ReadAttribMemV2(PCMCIA_DEFAULT_MODULE, u16Addr, pDest);
2398 }
2399
MDrv_PCMCIA_WriteIOMem(MS_U16 wAddr,MS_U8 bData)2400 void MDrv_PCMCIA_WriteIOMem( MS_U16 wAddr, MS_U8 bData )
2401 {
2402 MDrv_PCMCIA_WriteIOMemV2(PCMCIA_DEFAULT_MODULE, wAddr, bData);
2403 }
2404
MDrv_PCMCIA_WriteIOMemLong(MS_U16 u16Addr,MS_U8 u8Value,MS_U16 u16DataLen,MS_U8 * u8pWriteBuffer)2405 void MDrv_PCMCIA_WriteIOMemLong( MS_U16 u16Addr, MS_U8 u8Value, MS_U16 u16DataLen, MS_U8* u8pWriteBuffer)
2406 {
2407 MDrv_PCMCIA_WriteIOMemLongV2(PCMCIA_DEFAULT_MODULE, u16Addr, u8Value, u16DataLen, u8pWriteBuffer);
2408 }
2409
MDrv_PCMCIA_ReadIOMem(MS_U16 wAddr)2410 MS_U8 MDrv_PCMCIA_ReadIOMem( MS_U16 wAddr )
2411 {
2412 return MDrv_PCMCIA_ReadIOMemV2(PCMCIA_DEFAULT_MODULE, wAddr);
2413 }
2414
MDrv_PCMCIA_Get_CD_Interval(void)2415 MS_U32 MDrv_PCMCIA_Get_CD_Interval( void )
2416 {
2417 return MDrv_PCMCIA_Get_CD_IntervalV2(PCMCIA_DEFAULT_MODULE);
2418 }
2419