Commit | Line | Data |
---|---|---|
c5c77ba1 JK |
1 | #include "wilc_wfi_netdevice.h" |
2 | ||
3 | #include <linux/mmc/sdio_func.h> | |
4 | #include <linux/mmc/card.h> | |
5 | #include <linux/mmc/sdio_ids.h> | |
6 | #include <linux/mmc/sdio.h> | |
7 | #include <linux/mmc/host.h> | |
8 | ||
9 | ||
10 | ||
11 | #if defined (NM73131_0_BOARD) | |
12 | #define SDIO_MODALIAS "wilc_sdio" | |
13 | #else | |
14 | #define SDIO_MODALIAS "wilc1000_sdio" | |
15 | #endif | |
16 | ||
17 | #if defined (NM73131_0_BOARD) | |
18 | #define MAX_SPEED 50000000 | |
19 | #elif defined(CUSTOMER_PLATFORM) | |
20 | /* TODO : User have to stable bus clock as user's environment. */ | |
21 | #ifdef MAX_BUS_SPEED | |
22 | #define MAX_SPEED MAX_BUS_SPEED | |
23 | #else | |
24 | #define MAX_SPEED 50000000 | |
25 | #endif | |
26 | #else | |
27 | #define MAX_SPEED (6 * 1000000) /* Max 50M */ | |
28 | #endif | |
29 | ||
30 | ||
31 | struct sdio_func *local_sdio_func; | |
32 | extern linux_wlan_t *g_linux_wlan; | |
33 | extern int wilc_netdev_init(void); | |
c5c77ba1 JK |
34 | extern void wilc_handle_isr(void); |
35 | ||
36 | static unsigned int sdio_default_speed; | |
37 | ||
38 | #define SDIO_VENDOR_ID_WILC 0x0296 | |
39 | #define SDIO_DEVICE_ID_WILC 0x5347 | |
40 | ||
41 | static const struct sdio_device_id wilc_sdio_ids[] = { | |
42 | { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) }, | |
43 | }; | |
44 | ||
45 | ||
46 | static void wilc_sdio_interrupt(struct sdio_func *func) | |
47 | { | |
48 | #ifndef WILC_SDIO_IRQ_GPIO | |
49 | sdio_release_host(func); | |
50 | wilc_handle_isr(); | |
51 | sdio_claim_host(func); | |
52 | #endif | |
53 | } | |
54 | ||
55 | ||
56 | int linux_sdio_cmd52(sdio_cmd52_t *cmd) | |
57 | { | |
58 | struct sdio_func *func = g_linux_wlan->wilc_sdio_func; | |
59 | int ret; | |
60 | u8 data; | |
61 | ||
62 | sdio_claim_host(func); | |
63 | ||
64 | func->num = cmd->function; | |
65 | if (cmd->read_write) { /* write */ | |
66 | if (cmd->raw) { | |
67 | sdio_writeb(func, cmd->data, cmd->address, &ret); | |
68 | data = sdio_readb(func, cmd->address, &ret); | |
69 | cmd->data = data; | |
70 | } else { | |
71 | sdio_writeb(func, cmd->data, cmd->address, &ret); | |
72 | } | |
73 | } else { /* read */ | |
74 | data = sdio_readb(func, cmd->address, &ret); | |
75 | cmd->data = data; | |
76 | } | |
77 | ||
78 | sdio_release_host(func); | |
79 | ||
80 | if (ret < 0) { | |
81 | PRINT_ER("wilc_sdio_cmd52..failed, err(%d)\n", ret); | |
82 | return 0; | |
83 | } | |
84 | return 1; | |
85 | } | |
86 | ||
87 | ||
88 | int linux_sdio_cmd53(sdio_cmd53_t *cmd) | |
89 | { | |
90 | struct sdio_func *func = g_linux_wlan->wilc_sdio_func; | |
91 | int size, ret; | |
92 | ||
93 | sdio_claim_host(func); | |
94 | ||
95 | func->num = cmd->function; | |
96 | func->cur_blksize = cmd->block_size; | |
97 | if (cmd->block_mode) | |
98 | size = cmd->count * cmd->block_size; | |
99 | else | |
100 | size = cmd->count; | |
101 | ||
102 | if (cmd->read_write) { /* write */ | |
103 | ret = sdio_memcpy_toio(func, cmd->address, (void *)cmd->buffer, size); | |
104 | } else { /* read */ | |
105 | ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, cmd->address, size); | |
106 | } | |
107 | ||
108 | sdio_release_host(func); | |
109 | ||
110 | ||
111 | if (ret < 0) { | |
112 | PRINT_ER("wilc_sdio_cmd53..failed, err(%d)\n", ret); | |
113 | return 0; | |
114 | } | |
115 | ||
116 | return 1; | |
117 | } | |
118 | ||
119 | volatile int probe; /* COMPLEMENT_BOOT */ | |
120 | static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) | |
121 | { | |
122 | PRINT_D(INIT_DBG, "probe function\n"); | |
123 | ||
124 | #ifdef COMPLEMENT_BOOT | |
125 | if (local_sdio_func != NULL) { | |
126 | local_sdio_func = func; | |
127 | probe = 1; | |
128 | PRINT_D(INIT_DBG, "local_sdio_func isn't NULL\n"); | |
129 | return 0; | |
130 | } | |
131 | #endif | |
132 | PRINT_D(INIT_DBG, "Initializing netdev\n"); | |
133 | local_sdio_func = func; | |
134 | if (wilc_netdev_init()) { | |
135 | PRINT_ER("Couldn't initialize netdev\n"); | |
136 | return -1; | |
137 | } | |
138 | ||
139 | printk("Driver Initializing success\n"); | |
140 | return 0; | |
141 | } | |
142 | ||
143 | static void linux_sdio_remove(struct sdio_func *func) | |
144 | { | |
145 | /** | |
146 | * TODO | |
147 | **/ | |
148 | ||
149 | } | |
150 | ||
151 | struct sdio_driver wilc_bus = { | |
152 | .name = SDIO_MODALIAS, | |
153 | .id_table = wilc_sdio_ids, | |
154 | .probe = linux_sdio_probe, | |
155 | .remove = linux_sdio_remove, | |
156 | }; | |
157 | ||
158 | int enable_sdio_interrupt(void) | |
159 | { | |
160 | int ret = 0; | |
161 | #ifndef WILC_SDIO_IRQ_GPIO | |
162 | ||
163 | sdio_claim_host(local_sdio_func); | |
164 | ret = sdio_claim_irq(local_sdio_func, wilc_sdio_interrupt); | |
165 | sdio_release_host(local_sdio_func); | |
166 | ||
167 | if (ret < 0) { | |
168 | PRINT_ER("can't claim sdio_irq, err(%d)\n", ret); | |
169 | ret = -EIO; | |
170 | } | |
171 | #endif | |
172 | return ret; | |
173 | } | |
174 | ||
175 | void disable_sdio_interrupt(void) | |
176 | { | |
177 | ||
178 | #ifndef WILC_SDIO_IRQ_GPIO | |
179 | int ret; | |
180 | ||
181 | PRINT_D(INIT_DBG, "disable_sdio_interrupt IN\n"); | |
182 | ||
183 | sdio_claim_host(local_sdio_func); | |
184 | ret = sdio_release_irq(local_sdio_func); | |
185 | if (ret < 0) { | |
186 | PRINT_ER("can't release sdio_irq, err(%d)\n", ret); | |
187 | } | |
188 | sdio_release_host(local_sdio_func); | |
189 | ||
190 | PRINT_D(INIT_DBG, "disable_sdio_interrupt OUT\n"); | |
191 | #endif | |
192 | } | |
193 | ||
194 | static int linux_sdio_set_speed(int speed) | |
195 | { | |
196 | struct mmc_ios ios; | |
197 | sdio_claim_host(local_sdio_func); | |
198 | ||
199 | memcpy((void *)&ios, (void *)&local_sdio_func->card->host->ios, sizeof(struct mmc_ios)); | |
200 | local_sdio_func->card->host->ios.clock = speed; | |
201 | ios.clock = speed; | |
202 | local_sdio_func->card->host->ops->set_ios(local_sdio_func->card->host, &ios); | |
203 | sdio_release_host(local_sdio_func); | |
204 | PRINT_INFO(INIT_DBG, "@@@@@@@@@@@@ change SDIO speed to %d @@@@@@@@@\n", speed); | |
205 | ||
206 | return 1; | |
207 | } | |
208 | ||
209 | static int linux_sdio_get_speed(void) | |
210 | { | |
211 | return local_sdio_func->card->host->ios.clock; | |
212 | } | |
213 | ||
214 | int linux_sdio_init(void *pv) | |
215 | { | |
216 | ||
217 | /** | |
218 | * TODO : | |
219 | **/ | |
220 | ||
221 | ||
222 | sdio_default_speed = linux_sdio_get_speed(); | |
223 | return 1; | |
224 | } | |
225 | ||
226 | void linux_sdio_deinit(void *pv) | |
227 | { | |
228 | ||
229 | /** | |
230 | * TODO : | |
231 | **/ | |
232 | ||
233 | ||
234 | sdio_unregister_driver(&wilc_bus); | |
235 | } | |
236 | ||
237 | int linux_sdio_set_max_speed(void) | |
238 | { | |
239 | return linux_sdio_set_speed(MAX_SPEED); | |
240 | } | |
241 | ||
242 | int linux_sdio_set_default_speed(void) | |
243 | { | |
244 | return linux_sdio_set_speed(sdio_default_speed); | |
245 | } | |
246 | ||
247 | ||
248 |