2 ** $Id: //Department/DaVinci/BRANCHES/MT662X_593X_WIFI_DRIVER_V2_3/os/linux/hif/ehpi/ehpi.c#1 $
6 \brief Brief description.
11 /******************************************************************************
12 * Copyright (c) 2007 MediaTek Inc.
14 * All rights reserved. Copying, compilation, modification, distribution
15 * or any other use whatsoever of this material is strictly prohibited
16 * except in accordance with a Software License Agreement with
18 *******************************************************************************
21 /******************************************************************************
24 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
25 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
26 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
27 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
28 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
29 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
30 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
31 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
32 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
33 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
34 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
35 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
36 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
38 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
39 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
40 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
41 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
42 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
44 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
45 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
46 * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
47 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
48 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
50 *******************************************************************************
57 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
58 * change eHPI-8/eHPI-16 selection to config.mk.
61 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
62 * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface
63 * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR
64 * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26
67 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
68 * add porting layer for eHPI.
71 /******************************************************************************
72 * C O M P I L E R F L A G S
73 *******************************************************************************
75 #if !defined(MCR_EHTCR)
76 #define MCR_EHTCR 0x0054
79 /*******************************************************************************
80 * E X T E R N A L R E F E R E N C E S
81 ********************************************************************************
87 /*******************************************************************************
89 ********************************************************************************
92 /*******************************************************************************
94 ********************************************************************************
97 /*******************************************************************************
98 * P R I V A T E D A T A
99 ********************************************************************************
102 /*******************************************************************************
104 ********************************************************************************
107 /*******************************************************************************
108 * F U N C T I O N D E C L A R A T I O N S
109 ********************************************************************************
113 IN P_GLUE_INFO_T prGlueInfo,
114 IN UINT_32 u4Register,
115 OUT PUINT_32 pu4Value
120 IN P_GLUE_INFO_T prGlueInfo,
121 IN UINT_32 u4Register,
126 /*******************************************************************************
128 ********************************************************************************
131 /*----------------------------------------------------------------------------*/
133 * \brief This routine is used to read a 32 bit register value from device.
135 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
136 * \param[in] u4Register The register offset.
137 * \param[out] pu4Value Pointer to the 32-bit value of the register been read.
142 /*----------------------------------------------------------------------------*/
145 IN P_GLUE_INFO_T prGlueInfo,
146 IN UINT_32 u4Register,
147 OUT PUINT_32 pu4Value
150 GLUE_SPIN_LOCK_DECLARATION();
155 /* 0. acquire spinlock */
156 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
159 kalDevRegRead_impl(prGlueInfo, u4Register, pu4Value);
161 /* 2. release spin lock */
162 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
168 /*----------------------------------------------------------------------------*/
170 * \brief This routine is used to write a 32 bit register value to device.
172 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
173 * \param[in] u4Register The register offset.
174 * \param[out] u4Value The 32-bit value of the register to be written.
179 /*----------------------------------------------------------------------------*/
182 P_GLUE_INFO_T prGlueInfo,
183 IN UINT_32 u4Register,
187 GLUE_SPIN_LOCK_DECLARATION();
191 /* 0. acquire spinlock */
192 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
195 kalDevRegWrite_impl(prGlueInfo, u4Register, u4Value);
197 /* 2. release spin lock */
198 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
204 /*----------------------------------------------------------------------------*/
206 * \brief This routine is used to read port data from device in unit of byte.
208 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
209 * \param[in] u2Port The register offset.
210 * \param[in] u2Len The number of byte to be read.
211 * \param[out] pucBuf Pointer to data buffer for read
212 * \param[in] u2ValidOutBufSize Length of the buffer valid to be accessed
217 /*----------------------------------------------------------------------------*/
220 IN P_GLUE_INFO_T prGlueInfo,
224 IN UINT_16 u2ValidOutBufSize
228 GLUE_SPIN_LOCK_DECLARATION();
232 /* 0. acquire spinlock */
233 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
235 /* 1. indicate correct length to HIFSYS if larger than 4-bytes */
237 kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, ALIGN_4(u2Len));
240 /* 2. address cycle */
242 writew(u2Port, prGlueInfo->rHifInfo.mcr_addr_base);
244 writew((u2Port & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base);
245 writew(((u2Port & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base);
249 for(i = 0 ; i < ALIGN_4(u2Len) ; i += 4) {
251 *((PUINT_16)&(pucBuf[i])) = (UINT_16) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFFFF);
252 *((PUINT_16)&(pucBuf[i+2])) = (UINT_16) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFFFF);
254 *((PUINT_8)&(pucBuf[i])) = (UINT_8) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF);
255 *((PUINT_8)&(pucBuf[i+1])) = (UINT_8) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF);
256 *((PUINT_8)&(pucBuf[i+2])) = (UINT_8) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF);
257 *((PUINT_8)&(pucBuf[i+3])) = (UINT_8) (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF);
261 /* 4. restore length to 4 if necessary */
263 kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, 4);
266 /* 5. release spin lock */
267 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
273 /*----------------------------------------------------------------------------*/
275 * \brief This routine is used to write port data to device in unit of byte.
277 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
278 * \param[in] u2Port The register offset.
279 * \param[in] u2Len The number of byte to be write.
280 * \param[out] pucBuf Pointer to data buffer for write
281 * \param[in] u2ValidOutBufSize Length of the buffer valid to be accessed
286 /*----------------------------------------------------------------------------*/
289 P_GLUE_INFO_T prGlueInfo,
293 IN UINT_16 u2ValidInBufSize
297 GLUE_SPIN_LOCK_DECLARATION();
301 /* 0. acquire spinlock */
302 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
304 /* 1. indicate correct length to HIFSYS if larger than 4-bytes */
306 kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, ALIGN_4(u2Len));
309 /* 2. address cycle */
311 writew(u2Port, prGlueInfo->rHifInfo.mcr_addr_base);
313 writew((u2Port & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base);
314 writew(((u2Port & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base);
318 for(i = 0 ; i < ALIGN_4(u2Len) ; i += 4) {
320 writew((UINT_32)(*((PUINT_16) &(pucBuf[i]))), prGlueInfo->rHifInfo.mcr_data_base);
321 writew((UINT_32)(*((PUINT_16) &(pucBuf[i+2]))), prGlueInfo->rHifInfo.mcr_data_base);
323 writew((UINT_32)(*((PUINT_8) &(pucBuf[i]))), prGlueInfo->rHifInfo.mcr_data_base);
324 writew((UINT_32)(*((PUINT_8) &(pucBuf[i+1]))), prGlueInfo->rHifInfo.mcr_data_base);
325 writew((UINT_32)(*((PUINT_8) &(pucBuf[i+2]))), prGlueInfo->rHifInfo.mcr_data_base);
326 writew((UINT_32)(*((PUINT_8) &(pucBuf[i+3]))), prGlueInfo->rHifInfo.mcr_data_base);
330 /* 4. restore length to 4 if necessary */
332 kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, 4);
335 /* 5. release spin lock */
336 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
342 /*----------------------------------------------------------------------------*/
344 * \brief Write device I/O port with single byte (for SDIO compatibility)
346 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
347 * \param[in] u4Addr I/O port offset
348 * \param[in] ucData single byte of data to be written
349 * \param[in] u4ValidInBufSize Length of the buffer valid to be accessed
351 * \retval TRUE operation success
352 * \retval FALSE operation fail
354 /*----------------------------------------------------------------------------*/
356 kalDevWriteWithSdioCmd52 (
357 IN P_GLUE_INFO_T prGlueInfo,
364 GLUE_SPIN_LOCK_DECLARATION();
368 /* 0. acquire spinlock */
369 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
371 /* 1. there is no single byte access support for eHPI, use 4-bytes write-after-read approach instead */
372 if(kalDevRegRead_impl(prGlueInfo, u4Addr, &u4RegValue) == TRUE) {
374 u4RegValue |= ucData;
376 bRet = kalDevRegWrite_impl(prGlueInfo, u4Addr, u4RegValue);
382 /* 2. release spin lock */
383 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
389 /*----------------------------------------------------------------------------*/
391 * \brief This routine is used to read a 32 bit register value from device
392 * without spin lock protection and dedicated for internal use
394 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
395 * \param[in] u4Register The register offset.
396 * \param[out] pu4Value Pointer to the 32-bit value of the register been read.
401 /*----------------------------------------------------------------------------*/
404 IN P_GLUE_INFO_T prGlueInfo,
405 IN UINT_32 u4Register,
406 OUT PUINT_32 pu4Value
411 /* 1. address cycle */
413 writew(u4Register, prGlueInfo->rHifInfo.mcr_addr_base);
415 writew((u4Register & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base);
416 writew(((u4Register & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base);
421 *pu4Value = (readw(prGlueInfo->rHifInfo.mcr_data_base)& 0xFFFF);
422 *pu4Value |= ((readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFFFF) << 16);
424 *pu4Value = (readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF);
425 *pu4Value |= ((readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF) << 8);
426 *pu4Value |= ((readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF) << 16);
427 *pu4Value |= ((readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFF) << 24);
434 /*----------------------------------------------------------------------------*/
436 * \brief This routine is used to write a 32 bit register value to device.
437 * without spin lock protection and dedicated for internal use
439 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
440 * \param[in] u4Register The register offset.
441 * \param[out] u4Value The 32-bit value of the register to be written.
446 /*----------------------------------------------------------------------------*/
449 IN P_GLUE_INFO_T prGlueInfo,
450 IN UINT_32 u4Register,
456 /* 1. address cycle */
458 writew(u4Register, prGlueInfo->rHifInfo.mcr_addr_base);
460 writew((u4Register & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base);
461 writew(((u4Register & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base);
466 writew(u4Value, prGlueInfo->rHifInfo.mcr_data_base);
467 writew((u4Value & 0xFFFF0000) >> 16, prGlueInfo->rHifInfo.mcr_data_base);
469 writew((u4Value & 0x000000FF), prGlueInfo->rHifInfo.mcr_data_base);
470 writew((u4Value & 0x0000FF00) >> 8, prGlueInfo->rHifInfo.mcr_data_base);
471 writew((u4Value & 0x00FF0000) >> 16, prGlueInfo->rHifInfo.mcr_data_base);
472 writew((u4Value & 0xFF000000) >> 24, prGlueInfo->rHifInfo.mcr_data_base);