• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 /* ****************************************************************************
20   1 Header File Including
21 **************************************************************************** */
22 #include "oal_sdio.h"
23 #include "oal_sdio_host_if.h"
24 #include "oal_mm.h"
25 
26 #include "plat_sdio.h"
27 #include "plat_pm.h"
28 #include "plat_firmware.h"
29 #include "oal_time.h"
30 #include "oam_ext_if.h"
31 
32 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
33 extern struct sdio_func *g_p_gst_sdio_func;
34 #endif
35 
36 /* ****************************************************************************
37   2 Global Variable Definition
38 **************************************************************************** */
39 /* ****************************************************************************
40   3 Function Definition
41 **************************************************************************** */
42 /*
43  * Description  : provide interface for pm driver
44  * Input        : hi_u8* buf, hi_u32 len
45  * Output       : None
46  * Return Value : hi_s32
47  *
48  */
sdio_patch_writesb(hi_u8 * buf,hi_u32 len)49 hi_s32 sdio_patch_writesb(hi_u8 *buf, hi_u32 len)
50 {
51     int ret;
52     struct BusDev *bus = oal_get_bus_default_handler();
53 
54     if (bus == NULL || bus->priData.data == NULL) {
55         return -FAILURE;
56     }
57 
58     if (buf == NULL || len == 0) {
59         return -FAILURE;
60     }
61 
62     len = HISDIO_ALIGN_4_OR_BLK(len);
63 
64     bus->ops.claimHost(bus);
65     ret = bus->ops.bulkWrite(bus, HISDIO_REG_FUNC1_FIFO, len, buf, 0);
66     bus->ops.releaseHost(bus);
67     return ret;
68 }
69 
70 /*
71  * Description  : provide interface for pm driver
72  * Input        : hi_u8* buf, hi_u32 len hi_u32 timeout (ms)
73  * Output       : None
74  * Return Value : hi_s32
75  */
sdio_patch_readsb(hi_u8 * buf,hi_u32 len,hi_u32 timeout)76 hi_s32 sdio_patch_readsb(hi_u8 *buf, hi_u32 len, hi_u32 timeout)
77 {
78     hi_u8   int_mask;
79     hi_u8  *ver_info = HI_NULL;
80     int     ret = 0;
81     unsigned long timeout_jiffies;
82     hi_u32  xfer_count;
83     hi_u32  i;
84     struct BusDev *bus = oal_get_bus_default_handler();
85     hi_u8  *bus_buf = NULL;
86 
87     if (bus == NULL || bus->priData.data == NULL) {
88         return -FAILURE;
89     }
90 
91     if (buf == NULL || len == 0) {
92         return -FAILURE;
93     }
94     bus->ops.claimHost(bus);
95     timeout_jiffies = OAL_TIME_JIFFY + OAL_MSECS_TO_JIFFIES(timeout);
96     for (;;) {
97         ret =  bus->ops.readData(bus, HISDIO_REG_FUNC1_INT_STATUS, ONE_BYTE, &int_mask);
98         if (ret) {
99             bus->ops.releaseHost(bus);
100             return -FAILURE;
101         }
102 
103         if (int_mask & HISDIO_FUNC1_INT_MASK) {
104             /* sdio int came */
105             break;
106         }
107 
108         if (oal_time_after(OAL_TIME_JIFFY, timeout_jiffies) > 0) {
109             bus->ops.releaseHost(bus);
110             return -FAILURE;
111         }
112 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
113         cpu_relax();
114 #endif
115     }
116 
117     bus_buf = &int_mask;
118     ret = bus->ops.writeData(bus, HISDIO_REG_FUNC1_INT_STATUS, ONE_BYTE, bus_buf);
119     if (ret < 0) {
120         bus->ops.releaseHost(bus);
121         return -FAILURE;
122     }
123 
124     timeout_jiffies = OAL_TIME_JIFFY + OAL_MSECS_TO_JIFFIES(timeout);
125     for (;;) {
126         ret = bus->ops.readData(bus, HISDIO_REG_FUNC1_INT_STATUS, ONE_BYTE, &int_mask);
127         if (ret) {
128             bus->ops.releaseHost(bus);
129             return -FAILURE;
130         }
131 
132         if ((int_mask & HISDIO_FUNC1_INT_MASK) == 0) {
133             /* sdio int came */
134             break;
135         }
136 
137         if (oal_time_after((hi_u32)OAL_TIME_JIFFY, timeout_jiffies) > 0) {
138             bus->ops.releaseHost(bus);
139             return -FAILURE;
140         }
141 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
142         cpu_relax();
143 #endif
144     }
145     bus_buf = (hi_u8 *)&xfer_count;
146     ret = bus->ops.readData(bus, HISDIO_REG_FUNC1_XFER_COUNT, FOUR_BYTE, bus_buf);
147     if (ret < 0) {
148         bus->ops.releaseHost(bus);
149         return -FAILURE;
150     }
151 
152     if (xfer_count < len) {
153         len = xfer_count;
154     }
155 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
156     ver_info = oal_kzalloc((xfer_count + 1), OAL_GFP_KERNEL);
157 #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
158     ver_info = (hi_u8 *)memalign(32, SKB_DATA_ALIGN(xfer_count + 1)); /* 32 */
159 #endif
160     if (ver_info == NULL) {
161         bus->ops.releaseHost(bus);
162         return -ENOMEM;
163     }
164 
165     /* 安全编程规则6.6例外(3) 从堆中分配内存后,赋予初值 */
166     memset_s(ver_info, xfer_count + 1, 0, xfer_count);
167     ret = bus->ops.bulkRead(bus, HISDIO_REG_FUNC1_FIFO, xfer_count, ver_info, 0);
168     if (ret >= 0) {
169         for (i = 0; i < len; i++) {
170             buf[i] = ver_info[i];
171         }
172     }
173     oal_free(ver_info);
174 
175     bus->ops.releaseHost(bus);
176 
177     return xfer_count;
178 }
179