support different wifi bt chip auto compatible
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / mt5931_kk / drv_wlan / os / linux / hif / ehpi / ehpi.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT662X_593X_WIFI_DRIVER_V2_3/os/linux/hif/ehpi/ehpi.c#1 $
3 */
4
5 /*! \file   "ehpi.c"
6     \brief  Brief description.
7
8     Detail description.
9 */
10
11 /******************************************************************************
12 * Copyright (c) 2007 MediaTek Inc.
13 *
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
17 * MediaTek Inc.
18 *******************************************************************************
19 */
20
21 /******************************************************************************
22 * LEGAL DISCLAIMER
23 *
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.
37 *
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.
43 *
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
49 * (ICC).
50 *******************************************************************************
51 */
52
53 /*
54 ** $Log: ehpi.c $
55  *
56  * 04 25 2011 cp.wu
57  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
58  * change eHPI-8/eHPI-16 selection to config.mk.
59  *
60  * 04 01 2011 cp.wu
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
65  *
66  * 03 11 2011 cp.wu
67  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
68  * add porting layer for eHPI.
69 */
70
71 /******************************************************************************
72 *                         C O M P I L E R   F L A G S
73 *******************************************************************************
74 */
75 #if !defined(MCR_EHTCR)
76 #define MCR_EHTCR                           0x0054
77 #endif
78
79 /*******************************************************************************
80 *                E X T E R N A L   R E F E R E N C E S
81 ********************************************************************************
82 */
83 #include "gl_os.h"
84 #include "colibri.h"
85 #include "wlan_lib.h"
86
87 /*******************************************************************************
88 *                         D A T A   T Y P E S
89 ********************************************************************************
90 */
91
92 /*******************************************************************************
93 *                        P U B L I C   D A T A
94 ********************************************************************************
95 */
96
97 /*******************************************************************************
98 *                       P R I V A T E   D A T A
99 ********************************************************************************
100 */
101
102 /*******************************************************************************
103 *                             M A C R O S
104 ********************************************************************************
105 */
106
107 /*******************************************************************************
108 *              F U N C T I O N   D E C L A R A T I O N S
109 ********************************************************************************
110 */
111 static BOOL
112 kalDevRegRead_impl(
113     IN  P_GLUE_INFO_T  prGlueInfo,
114     IN  UINT_32        u4Register,
115     OUT PUINT_32       pu4Value
116     );
117
118 static BOOL
119 kalDevRegWrite_impl(
120     IN  P_GLUE_INFO_T  prGlueInfo,
121     IN  UINT_32        u4Register,
122     IN  UINT_32        u4Value
123     );
124
125
126 /*******************************************************************************
127 *                          F U N C T I O N S
128 ********************************************************************************
129 */
130
131 /*----------------------------------------------------------------------------*/
132 /*!
133 * \brief This routine is used to read a 32 bit register value from device.
134 *
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.
138 *
139 * \retval TRUE
140 * \retval FALSE
141 */
142 /*----------------------------------------------------------------------------*/
143 BOOL
144 kalDevRegRead(
145     IN  P_GLUE_INFO_T  prGlueInfo,
146     IN  UINT_32        u4Register,
147     OUT PUINT_32       pu4Value
148     )
149 {
150     GLUE_SPIN_LOCK_DECLARATION();
151
152     ASSERT(prGlueInfo);
153     ASSERT(pu4Value);
154
155     /* 0. acquire spinlock */
156     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
157
158     /* 1. I/O stuff */
159     kalDevRegRead_impl(prGlueInfo, u4Register, pu4Value);
160
161     /* 2. release spin lock */
162     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
163
164     return TRUE;
165 }
166
167
168 /*----------------------------------------------------------------------------*/
169 /*!
170 * \brief This routine is used to write a 32 bit register value to device.
171 *
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.
175 *
176 * \retval TRUE
177 * \retval FALSE
178 */
179 /*----------------------------------------------------------------------------*/
180 BOOL
181 kalDevRegWrite(
182     P_GLUE_INFO_T  prGlueInfo,
183     IN UINT_32     u4Register,
184     IN UINT_32     u4Value
185     )
186 {
187     GLUE_SPIN_LOCK_DECLARATION();
188
189     ASSERT(prGlueInfo);
190
191     /* 0. acquire spinlock */
192     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
193
194     /* 1. I/O stuff */
195     kalDevRegWrite_impl(prGlueInfo, u4Register, u4Value);
196
197     /* 2. release spin lock */
198     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
199
200     return TRUE;
201 }
202
203
204 /*----------------------------------------------------------------------------*/
205 /*!
206 * \brief This routine is used to read port data from device in unit of byte.
207 *
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
213 *
214 * \retval TRUE
215 * \retval FALSE
216 */
217 /*----------------------------------------------------------------------------*/
218 BOOL
219 kalDevPortRead(
220     IN  P_GLUE_INFO_T   prGlueInfo,
221     IN  UINT_16         u2Port,
222     IN  UINT_16         u2Len,
223     OUT PUINT_8         pucBuf,
224     IN  UINT_16         u2ValidOutBufSize
225     )
226 {
227     UINT_32 i;
228     GLUE_SPIN_LOCK_DECLARATION();
229
230     ASSERT(prGlueInfo);
231
232     /* 0. acquire spinlock */
233     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
234
235     /* 1. indicate correct length to HIFSYS if larger than 4-bytes */
236     if(u2Len > 4) {
237         kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, ALIGN_4(u2Len));
238     }
239
240     /* 2. address cycle */
241 #if EHPI16
242     writew(u2Port, prGlueInfo->rHifInfo.mcr_addr_base);
243 #elif EHPI8
244     writew((u2Port & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base);
245     writew(((u2Port & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base);
246 #endif
247
248     /* 3. data cycle */
249     for(i = 0 ; i < ALIGN_4(u2Len) ; i += 4) {
250 #if EHPI16
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);
253 #elif EHPI8
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);
258 #endif
259     }
260
261     /* 4. restore length to 4 if necessary */
262     if(u2Len > 4) {
263         kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, 4);
264     }
265
266     /* 5. release spin lock */
267     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
268
269     return TRUE;
270 }
271
272
273 /*----------------------------------------------------------------------------*/
274 /*!
275 * \brief This routine is used to write port data to device in unit of byte.
276 *
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
282 *
283 * \retval TRUE
284 * \retval FALSE
285 */
286 /*----------------------------------------------------------------------------*/
287 BOOL
288 kalDevPortWrite(
289     P_GLUE_INFO_T  prGlueInfo,
290     IN UINT_16     u2Port,
291     IN UINT_16     u2Len,
292     IN PUINT_8     pucBuf,
293     IN UINT_16     u2ValidInBufSize
294     )
295 {
296     UINT_32 i;
297     GLUE_SPIN_LOCK_DECLARATION();
298
299     ASSERT(prGlueInfo);
300
301     /* 0. acquire spinlock */
302     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
303
304     /* 1. indicate correct length to HIFSYS if larger than 4-bytes */
305     if(u2Len > 4) {
306         kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, ALIGN_4(u2Len));
307     }
308
309     /* 2. address cycle */
310 #if EHPI16
311     writew(u2Port, prGlueInfo->rHifInfo.mcr_addr_base);
312 #elif EHPI8
313     writew((u2Port & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base);
314     writew(((u2Port & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base);
315 #endif
316
317     /* 3. data cycle */
318     for(i = 0 ; i < ALIGN_4(u2Len) ; i += 4) {
319 #if EHPI16
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);
322 #elif EHPI8
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);
327 #endif
328     }
329  
330     /* 4. restore length to 4 if necessary */
331     if(u2Len > 4) {
332         kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, 4);
333     }
334
335     /* 5. release spin lock */
336     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
337
338     return TRUE;
339 }
340
341
342 /*----------------------------------------------------------------------------*/
343 /*!
344 * \brief Write device I/O port with single byte (for SDIO compatibility)
345 *
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
350 *
351 * \retval TRUE          operation success
352 * \retval FALSE         operation fail
353 */
354 /*----------------------------------------------------------------------------*/
355 BOOL
356 kalDevWriteWithSdioCmd52 (
357     IN P_GLUE_INFO_T    prGlueInfo,
358     IN UINT_32          u4Addr,
359     IN UINT_8           ucData
360     )
361 {
362     UINT_32 u4RegValue;
363     BOOLEAN bRet;
364     GLUE_SPIN_LOCK_DECLARATION();
365
366     ASSERT(prGlueInfo);
367
368     /* 0. acquire spinlock */
369     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
370
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) {
373         u4RegValue &= 0x00;
374         u4RegValue |= ucData;
375
376         bRet = kalDevRegWrite_impl(prGlueInfo, u4Addr, u4RegValue);
377     }
378     else {
379         bRet = FALSE;
380     }
381
382     /* 2. release spin lock */
383     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS);
384
385     return bRet;
386 }
387
388
389 /*----------------------------------------------------------------------------*/
390 /*!
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
393 *
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.
397 *
398 * \retval TRUE
399 * \retval FALSE
400 */
401 /*----------------------------------------------------------------------------*/
402 static BOOL
403 kalDevRegRead_impl(
404     IN  P_GLUE_INFO_T  prGlueInfo,
405     IN  UINT_32        u4Register,
406     OUT PUINT_32       pu4Value
407     )
408 {
409     ASSERT(prGlueInfo);
410
411     /* 1. address cycle */
412 #if EHPI16
413     writew(u4Register, prGlueInfo->rHifInfo.mcr_addr_base);
414 #elif EHPI8
415     writew((u4Register & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base);
416     writew(((u4Register & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base);
417 #endif
418
419     /* 2. data cycle */
420 #if EHPI16
421     *pu4Value   = (readw(prGlueInfo->rHifInfo.mcr_data_base)& 0xFFFF);
422     *pu4Value   |= ((readw(prGlueInfo->rHifInfo.mcr_data_base) & 0xFFFF) << 16);
423 #elif EHPI8
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);
428 #endif
429
430     return TRUE;
431 }
432
433
434 /*----------------------------------------------------------------------------*/
435 /*!
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
438 *
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.
442 *
443 * \retval TRUE
444 * \retval FALSE
445 */
446 /*----------------------------------------------------------------------------*/
447 static BOOL
448 kalDevRegWrite_impl(
449     IN  P_GLUE_INFO_T  prGlueInfo,
450     IN  UINT_32        u4Register,
451     IN  UINT_32        u4Value
452     )
453 {
454     ASSERT(prGlueInfo);
455
456     /* 1. address cycle */
457 #if EHPI16
458     writew(u4Register, prGlueInfo->rHifInfo.mcr_addr_base);
459 #elif EHPI8
460     writew((u4Register & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base);
461     writew(((u4Register & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base);
462 #endif
463
464     /* 2. data cycle */
465 #if EHPI16
466     writew(u4Value, prGlueInfo->rHifInfo.mcr_data_base);
467     writew((u4Value & 0xFFFF0000) >> 16, prGlueInfo->rHifInfo.mcr_data_base);
468 #elif EHPI8
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);
473 #endif
474
475     return TRUE;
476 }
477
478