Commit | Line | Data |
---|---|---|
fa590c22 MC |
1 | /* Driver for Realtek PCI-Express card reader |
2 | * | |
3 | * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms of the GNU General Public License as published by the | |
7 | * Free Software Foundation; either version 2, or (at your option) any | |
8 | * later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; if not, see <http://www.gnu.org/licenses/>. | |
17 | * | |
18 | * Author: | |
19 | * Wei WANG (wei_wang@realsil.com.cn) | |
20 | * Micky Ching (micky_ching@realsil.com.cn) | |
21 | */ | |
22 | ||
23 | #include <linux/blkdev.h> | |
24 | #include <linux/kthread.h> | |
25 | #include <linux/sched.h> | |
26 | #include <linux/workqueue.h> | |
27 | #include <linux/kernel.h> | |
28 | ||
29 | #include "rtsx.h" | |
fa590c22 MC |
30 | #include "sd.h" |
31 | #include "xd.h" | |
32 | #include "ms.h" | |
33 | ||
34 | void do_remaining_work(struct rtsx_chip *chip) | |
35 | { | |
36 | struct sd_info *sd_card = &(chip->sd_card); | |
37 | #ifdef XD_DELAY_WRITE | |
38 | struct xd_info *xd_card = &(chip->xd_card); | |
39 | #endif | |
40 | struct ms_info *ms_card = &(chip->ms_card); | |
41 | ||
42 | if (chip->card_ready & SD_CARD) { | |
43 | if (sd_card->seq_mode) { | |
44 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
45 | sd_card->cleanup_counter++; | |
46 | } else { | |
47 | sd_card->cleanup_counter = 0; | |
48 | } | |
49 | } | |
50 | ||
51 | #ifdef XD_DELAY_WRITE | |
52 | if (chip->card_ready & XD_CARD) { | |
53 | if (xd_card->delay_write.delay_write_flag) { | |
54 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
55 | xd_card->cleanup_counter++; | |
56 | } else { | |
57 | xd_card->cleanup_counter = 0; | |
58 | } | |
59 | } | |
60 | #endif | |
61 | ||
62 | if (chip->card_ready & MS_CARD) { | |
63 | if (CHK_MSPRO(ms_card)) { | |
64 | if (ms_card->seq_mode) { | |
65 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
66 | ms_card->cleanup_counter++; | |
67 | } else { | |
68 | ms_card->cleanup_counter = 0; | |
69 | } | |
70 | } else { | |
71 | #ifdef MS_DELAY_WRITE | |
72 | if (ms_card->delay_write.delay_write_flag) { | |
73 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
74 | ms_card->cleanup_counter++; | |
75 | } else { | |
76 | ms_card->cleanup_counter = 0; | |
77 | } | |
78 | #endif | |
79 | } | |
80 | } | |
81 | ||
82 | if (sd_card->cleanup_counter > POLLING_WAIT_CNT) | |
83 | sd_cleanup_work(chip); | |
84 | ||
85 | if (xd_card->cleanup_counter > POLLING_WAIT_CNT) | |
86 | xd_cleanup_work(chip); | |
87 | ||
88 | if (ms_card->cleanup_counter > POLLING_WAIT_CNT) | |
89 | ms_cleanup_work(chip); | |
90 | } | |
91 | ||
92 | void try_to_switch_sdio_ctrl(struct rtsx_chip *chip) | |
93 | { | |
94 | u8 reg1 = 0, reg2 = 0; | |
95 | ||
96 | rtsx_read_register(chip, 0xFF34, ®1); | |
97 | rtsx_read_register(chip, 0xFF38, ®2); | |
bf6c0d11 FF |
98 | dev_dbg(rtsx_dev(chip), "reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", |
99 | reg1, reg2); | |
fa590c22 MC |
100 | if ((reg1 & 0xC0) && (reg2 & 0xC0)) { |
101 | chip->sd_int = 1; | |
8470e791 GK |
102 | rtsx_write_register(chip, SDIO_CTRL, 0xFF, |
103 | SDIO_BUS_CTRL | SDIO_CD_CTRL); | |
104 | rtsx_write_register(chip, PWR_GATE_CTRL, | |
105 | LDO3318_PWR_MASK, LDO_ON); | |
fa590c22 MC |
106 | } |
107 | } | |
108 | ||
109 | #ifdef SUPPORT_SDIO_ASPM | |
110 | void dynamic_configure_sdio_aspm(struct rtsx_chip *chip) | |
111 | { | |
112 | u8 buf[12], reg; | |
113 | int i; | |
114 | ||
115 | for (i = 0; i < 12; i++) | |
116 | rtsx_read_register(chip, 0xFF08 + i, &buf[i]); | |
117 | rtsx_read_register(chip, 0xFF25, ®); | |
118 | if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) { | |
119 | chip->sdio_counter = 0; | |
120 | chip->sdio_idle = 0; | |
121 | } else { | |
122 | if (!chip->sdio_idle) { | |
123 | chip->sdio_counter++; | |
124 | if (chip->sdio_counter >= SDIO_IDLE_COUNT) { | |
125 | chip->sdio_counter = 0; | |
126 | chip->sdio_idle = 1; | |
127 | } | |
128 | } | |
129 | } | |
130 | memcpy(chip->sdio_raw_data, buf, 12); | |
131 | ||
132 | if (chip->sdio_idle) { | |
133 | if (!chip->sdio_aspm) { | |
bf6c0d11 | 134 | dev_dbg(rtsx_dev(chip), "SDIO enter ASPM!\n"); |
fa590c22 MC |
135 | rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, |
136 | 0x30 | (chip->aspm_level[1] << 2)); | |
137 | chip->sdio_aspm = 1; | |
138 | } | |
139 | } else { | |
140 | if (chip->sdio_aspm) { | |
bf6c0d11 | 141 | dev_dbg(rtsx_dev(chip), "SDIO exit ASPM!\n"); |
fa590c22 MC |
142 | rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30); |
143 | chip->sdio_aspm = 0; | |
144 | } | |
145 | } | |
146 | } | |
147 | #endif | |
148 | ||
149 | void do_reset_sd_card(struct rtsx_chip *chip) | |
150 | { | |
151 | int retval; | |
152 | ||
bf6c0d11 FF |
153 | dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__, |
154 | chip->sd_reset_counter, chip->card2lun[SD_CARD]); | |
fa590c22 MC |
155 | |
156 | if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) { | |
157 | clear_bit(SD_NR, &(chip->need_reset)); | |
158 | chip->sd_reset_counter = 0; | |
159 | chip->sd_show_cnt = 0; | |
160 | return; | |
161 | } | |
162 | ||
163 | chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; | |
164 | ||
165 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
166 | rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); | |
167 | ||
168 | retval = reset_sd_card(chip); | |
169 | if (chip->need_release & SD_CARD) | |
170 | return; | |
171 | if (retval == STATUS_SUCCESS) { | |
172 | clear_bit(SD_NR, &(chip->need_reset)); | |
173 | chip->sd_reset_counter = 0; | |
174 | chip->sd_show_cnt = 0; | |
175 | chip->card_ready |= SD_CARD; | |
176 | chip->card_fail &= ~SD_CARD; | |
177 | chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw; | |
178 | } else { | |
179 | if (chip->sd_io || (chip->sd_reset_counter >= MAX_RESET_CNT)) { | |
180 | clear_bit(SD_NR, &(chip->need_reset)); | |
181 | chip->sd_reset_counter = 0; | |
182 | chip->sd_show_cnt = 0; | |
183 | } else { | |
184 | chip->sd_reset_counter++; | |
185 | } | |
186 | chip->card_ready &= ~SD_CARD; | |
187 | chip->card_fail |= SD_CARD; | |
188 | chip->capacity[chip->card2lun[SD_CARD]] = 0; | |
189 | chip->rw_card[chip->card2lun[SD_CARD]] = NULL; | |
190 | ||
191 | rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); | |
192 | if (!chip->ft2_fast_mode) | |
193 | card_power_off(chip, SD_CARD); | |
194 | if (chip->sd_io) { | |
195 | chip->sd_int = 0; | |
196 | try_to_switch_sdio_ctrl(chip); | |
197 | } else { | |
198 | disable_card_clock(chip, SD_CARD); | |
199 | } | |
200 | } | |
201 | } | |
202 | ||
203 | void do_reset_xd_card(struct rtsx_chip *chip) | |
204 | { | |
205 | int retval; | |
206 | ||
bf6c0d11 FF |
207 | dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__, |
208 | chip->xd_reset_counter, chip->card2lun[XD_CARD]); | |
fa590c22 MC |
209 | |
210 | if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) { | |
211 | clear_bit(XD_NR, &(chip->need_reset)); | |
212 | chip->xd_reset_counter = 0; | |
213 | chip->xd_show_cnt = 0; | |
214 | return; | |
215 | } | |
216 | ||
217 | chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; | |
218 | ||
219 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
220 | rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); | |
221 | ||
222 | retval = reset_xd_card(chip); | |
223 | if (chip->need_release & XD_CARD) | |
224 | return; | |
225 | if (retval == STATUS_SUCCESS) { | |
226 | clear_bit(XD_NR, &(chip->need_reset)); | |
227 | chip->xd_reset_counter = 0; | |
228 | chip->card_ready |= XD_CARD; | |
229 | chip->card_fail &= ~XD_CARD; | |
230 | chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw; | |
231 | } else { | |
232 | if (chip->xd_reset_counter >= MAX_RESET_CNT) { | |
233 | clear_bit(XD_NR, &(chip->need_reset)); | |
234 | chip->xd_reset_counter = 0; | |
235 | chip->xd_show_cnt = 0; | |
236 | } else { | |
237 | chip->xd_reset_counter++; | |
238 | } | |
239 | chip->card_ready &= ~XD_CARD; | |
240 | chip->card_fail |= XD_CARD; | |
241 | chip->capacity[chip->card2lun[XD_CARD]] = 0; | |
242 | chip->rw_card[chip->card2lun[XD_CARD]] = NULL; | |
243 | ||
244 | rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); | |
245 | if (!chip->ft2_fast_mode) | |
246 | card_power_off(chip, XD_CARD); | |
247 | disable_card_clock(chip, XD_CARD); | |
248 | } | |
249 | } | |
250 | ||
251 | void do_reset_ms_card(struct rtsx_chip *chip) | |
252 | { | |
253 | int retval; | |
254 | ||
bf6c0d11 FF |
255 | dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__, |
256 | chip->ms_reset_counter, chip->card2lun[MS_CARD]); | |
fa590c22 MC |
257 | |
258 | if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) { | |
259 | clear_bit(MS_NR, &(chip->need_reset)); | |
260 | chip->ms_reset_counter = 0; | |
261 | chip->ms_show_cnt = 0; | |
262 | return; | |
263 | } | |
264 | ||
265 | chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; | |
266 | ||
267 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
268 | rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); | |
269 | ||
270 | retval = reset_ms_card(chip); | |
271 | if (chip->need_release & MS_CARD) | |
272 | return; | |
273 | if (retval == STATUS_SUCCESS) { | |
274 | clear_bit(MS_NR, &(chip->need_reset)); | |
275 | chip->ms_reset_counter = 0; | |
276 | chip->card_ready |= MS_CARD; | |
277 | chip->card_fail &= ~MS_CARD; | |
278 | chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw; | |
279 | } else { | |
280 | if (chip->ms_reset_counter >= MAX_RESET_CNT) { | |
281 | clear_bit(MS_NR, &(chip->need_reset)); | |
282 | chip->ms_reset_counter = 0; | |
283 | chip->ms_show_cnt = 0; | |
284 | } else { | |
285 | chip->ms_reset_counter++; | |
286 | } | |
287 | chip->card_ready &= ~MS_CARD; | |
288 | chip->card_fail |= MS_CARD; | |
289 | chip->capacity[chip->card2lun[MS_CARD]] = 0; | |
290 | chip->rw_card[chip->card2lun[MS_CARD]] = NULL; | |
291 | ||
292 | rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); | |
293 | if (!chip->ft2_fast_mode) | |
294 | card_power_off(chip, MS_CARD); | |
295 | disable_card_clock(chip, MS_CARD); | |
296 | } | |
297 | } | |
298 | ||
299 | static void release_sdio(struct rtsx_chip *chip) | |
300 | { | |
301 | if (chip->sd_io) { | |
302 | rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, | |
303 | SD_STOP | SD_CLR_ERR); | |
304 | ||
305 | if (chip->chip_insert_with_sdio) { | |
306 | chip->chip_insert_with_sdio = 0; | |
307 | ||
308 | if (CHECK_PID(chip, 0x5288)) | |
309 | rtsx_write_register(chip, 0xFE5A, 0x08, 0x00); | |
310 | else | |
311 | rtsx_write_register(chip, 0xFE70, 0x80, 0x00); | |
312 | } | |
313 | ||
314 | rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0); | |
315 | chip->sd_io = 0; | |
316 | } | |
317 | } | |
318 | ||
319 | void rtsx_power_off_card(struct rtsx_chip *chip) | |
320 | { | |
321 | if ((chip->card_ready & SD_CARD) || chip->sd_io) { | |
322 | sd_cleanup_work(chip); | |
323 | sd_power_off_card3v3(chip); | |
324 | } | |
325 | ||
326 | if (chip->card_ready & XD_CARD) { | |
327 | xd_cleanup_work(chip); | |
328 | xd_power_off_card3v3(chip); | |
329 | } | |
330 | ||
331 | if (chip->card_ready & MS_CARD) { | |
332 | ms_cleanup_work(chip); | |
333 | ms_power_off_card3v3(chip); | |
334 | } | |
335 | } | |
336 | ||
337 | void rtsx_release_cards(struct rtsx_chip *chip) | |
338 | { | |
339 | chip->int_reg = rtsx_readl(chip, RTSX_BIPR); | |
340 | ||
341 | if ((chip->card_ready & SD_CARD) || chip->sd_io) { | |
342 | if (chip->int_reg & SD_EXIST) | |
343 | sd_cleanup_work(chip); | |
344 | release_sd_card(chip); | |
345 | } | |
346 | ||
347 | if (chip->card_ready & XD_CARD) { | |
348 | if (chip->int_reg & XD_EXIST) | |
349 | xd_cleanup_work(chip); | |
350 | release_xd_card(chip); | |
351 | } | |
352 | ||
353 | if (chip->card_ready & MS_CARD) { | |
354 | if (chip->int_reg & MS_EXIST) | |
355 | ms_cleanup_work(chip); | |
356 | release_ms_card(chip); | |
357 | } | |
358 | } | |
359 | ||
360 | void rtsx_reset_cards(struct rtsx_chip *chip) | |
361 | { | |
362 | if (!chip->need_reset) | |
363 | return; | |
364 | ||
365 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
366 | ||
367 | rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); | |
368 | ||
369 | rtsx_disable_aspm(chip); | |
370 | ||
371 | if ((chip->need_reset & SD_CARD) && chip->chip_insert_with_sdio) | |
372 | clear_bit(SD_NR, &(chip->need_reset)); | |
373 | ||
374 | if (chip->need_reset & XD_CARD) { | |
375 | chip->card_exist |= XD_CARD; | |
376 | ||
377 | if (chip->xd_show_cnt >= MAX_SHOW_CNT) | |
378 | do_reset_xd_card(chip); | |
379 | else | |
380 | chip->xd_show_cnt++; | |
381 | } | |
382 | if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { | |
383 | if (chip->card_exist & XD_CARD) { | |
384 | clear_bit(SD_NR, &(chip->need_reset)); | |
385 | clear_bit(MS_NR, &(chip->need_reset)); | |
386 | } | |
387 | } | |
388 | if (chip->need_reset & SD_CARD) { | |
389 | chip->card_exist |= SD_CARD; | |
390 | ||
391 | if (chip->sd_show_cnt >= MAX_SHOW_CNT) { | |
392 | rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); | |
393 | do_reset_sd_card(chip); | |
394 | } else { | |
395 | chip->sd_show_cnt++; | |
396 | } | |
397 | } | |
398 | if (chip->need_reset & MS_CARD) { | |
399 | chip->card_exist |= MS_CARD; | |
400 | ||
401 | if (chip->ms_show_cnt >= MAX_SHOW_CNT) | |
402 | do_reset_ms_card(chip); | |
403 | else | |
404 | chip->ms_show_cnt++; | |
405 | } | |
406 | } | |
407 | ||
408 | void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip) | |
409 | { | |
410 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
411 | ||
412 | rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); | |
413 | ||
414 | if (reset_chip) | |
415 | rtsx_reset_chip(chip); | |
416 | ||
417 | chip->int_reg = rtsx_readl(chip, RTSX_BIPR); | |
418 | ||
419 | if ((chip->int_reg & SD_EXIST) && (chip->need_reinit & SD_CARD)) { | |
420 | release_sdio(chip); | |
421 | release_sd_card(chip); | |
422 | ||
423 | wait_timeout(100); | |
424 | ||
425 | chip->card_exist |= SD_CARD; | |
426 | do_reset_sd_card(chip); | |
427 | } | |
428 | ||
429 | if ((chip->int_reg & XD_EXIST) && (chip->need_reinit & XD_CARD)) { | |
430 | release_xd_card(chip); | |
431 | ||
432 | wait_timeout(100); | |
433 | ||
434 | chip->card_exist |= XD_CARD; | |
435 | do_reset_xd_card(chip); | |
436 | } | |
437 | ||
438 | if ((chip->int_reg & MS_EXIST) && (chip->need_reinit & MS_CARD)) { | |
439 | release_ms_card(chip); | |
440 | ||
441 | wait_timeout(100); | |
442 | ||
443 | chip->card_exist |= MS_CARD; | |
444 | do_reset_ms_card(chip); | |
445 | } | |
446 | ||
447 | chip->need_reinit = 0; | |
448 | } | |
449 | ||
450 | #ifdef DISABLE_CARD_INT | |
8470e791 GK |
451 | void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, |
452 | unsigned long *need_release) | |
fa590c22 MC |
453 | { |
454 | u8 release_map = 0, reset_map = 0; | |
455 | ||
456 | chip->int_reg = rtsx_readl(chip, RTSX_BIPR); | |
457 | ||
458 | if (chip->card_exist) { | |
459 | if (chip->card_exist & XD_CARD) { | |
460 | if (!(chip->int_reg & XD_EXIST)) | |
461 | release_map |= XD_CARD; | |
462 | } else if (chip->card_exist & SD_CARD) { | |
463 | if (!(chip->int_reg & SD_EXIST)) | |
464 | release_map |= SD_CARD; | |
465 | } else if (chip->card_exist & MS_CARD) { | |
466 | if (!(chip->int_reg & MS_EXIST)) | |
467 | release_map |= MS_CARD; | |
468 | } | |
469 | } else { | |
470 | if (chip->int_reg & XD_EXIST) | |
471 | reset_map |= XD_CARD; | |
472 | else if (chip->int_reg & SD_EXIST) | |
473 | reset_map |= SD_CARD; | |
474 | else if (chip->int_reg & MS_EXIST) | |
475 | reset_map |= MS_CARD; | |
476 | } | |
477 | ||
478 | if (reset_map) { | |
479 | int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0; | |
480 | int i; | |
481 | ||
482 | for (i = 0; i < (DEBOUNCE_CNT); i++) { | |
483 | chip->int_reg = rtsx_readl(chip, RTSX_BIPR); | |
484 | ||
485 | if (chip->int_reg & XD_EXIST) | |
486 | xd_cnt++; | |
487 | else | |
488 | xd_cnt = 0; | |
489 | ||
490 | if (chip->int_reg & SD_EXIST) | |
491 | sd_cnt++; | |
492 | else | |
493 | sd_cnt = 0; | |
494 | ||
495 | if (chip->int_reg & MS_EXIST) | |
496 | ms_cnt++; | |
497 | else | |
498 | ms_cnt = 0; | |
499 | ||
500 | wait_timeout(30); | |
501 | } | |
502 | ||
503 | reset_map = 0; | |
8470e791 GK |
504 | if (!(chip->card_exist & XD_CARD) && |
505 | (xd_cnt > (DEBOUNCE_CNT-1))) | |
fa590c22 | 506 | reset_map |= XD_CARD; |
8470e791 GK |
507 | if (!(chip->card_exist & SD_CARD) && |
508 | (sd_cnt > (DEBOUNCE_CNT-1))) | |
fa590c22 | 509 | reset_map |= SD_CARD; |
8470e791 GK |
510 | if (!(chip->card_exist & MS_CARD) && |
511 | (ms_cnt > (DEBOUNCE_CNT-1))) | |
fa590c22 MC |
512 | reset_map |= MS_CARD; |
513 | } | |
514 | ||
515 | if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) | |
516 | rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0x00); | |
517 | ||
518 | if (need_reset) | |
519 | *need_reset = reset_map; | |
520 | if (need_release) | |
521 | *need_release = release_map; | |
522 | } | |
523 | #endif | |
524 | ||
525 | void rtsx_init_cards(struct rtsx_chip *chip) | |
526 | { | |
527 | if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) { | |
bf6c0d11 | 528 | dev_dbg(rtsx_dev(chip), "Reset chip in polling thread!\n"); |
fa590c22 MC |
529 | rtsx_reset_chip(chip); |
530 | RTSX_CLR_DELINK(chip); | |
531 | } | |
532 | ||
533 | #ifdef DISABLE_CARD_INT | |
534 | card_cd_debounce(chip, &(chip->need_reset), &(chip->need_release)); | |
535 | #endif | |
536 | ||
537 | if (chip->need_release) { | |
538 | if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { | |
539 | if (chip->int_reg & XD_EXIST) { | |
540 | clear_bit(SD_NR, &(chip->need_release)); | |
541 | clear_bit(MS_NR, &(chip->need_release)); | |
542 | } | |
543 | } | |
544 | ||
545 | if (!(chip->card_exist & SD_CARD) && !chip->sd_io) | |
546 | clear_bit(SD_NR, &(chip->need_release)); | |
547 | if (!(chip->card_exist & XD_CARD)) | |
548 | clear_bit(XD_NR, &(chip->need_release)); | |
549 | if (!(chip->card_exist & MS_CARD)) | |
550 | clear_bit(MS_NR, &(chip->need_release)); | |
551 | ||
bf6c0d11 FF |
552 | dev_dbg(rtsx_dev(chip), "chip->need_release = 0x%x\n", |
553 | (unsigned int)(chip->need_release)); | |
fa590c22 MC |
554 | |
555 | #ifdef SUPPORT_OCP | |
556 | if (chip->need_release) { | |
557 | if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER)) | |
558 | rtsx_write_register(chip, OCPCLR, | |
559 | CARD_OC_INT_CLR | CARD_OC_CLR, | |
560 | CARD_OC_INT_CLR | CARD_OC_CLR); | |
561 | chip->ocp_stat = 0; | |
562 | } | |
563 | #endif | |
564 | if (chip->need_release) { | |
565 | rtsx_set_stat(chip, RTSX_STAT_RUN); | |
566 | rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); | |
567 | } | |
568 | ||
569 | if (chip->need_release & SD_CARD) { | |
570 | clear_bit(SD_NR, &(chip->need_release)); | |
571 | chip->card_exist &= ~SD_CARD; | |
572 | chip->card_ejected &= ~SD_CARD; | |
573 | chip->card_fail &= ~SD_CARD; | |
574 | CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]); | |
575 | chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; | |
576 | rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); | |
577 | ||
578 | release_sdio(chip); | |
579 | release_sd_card(chip); | |
580 | } | |
581 | ||
582 | if (chip->need_release & XD_CARD) { | |
583 | clear_bit(XD_NR, &(chip->need_release)); | |
584 | chip->card_exist &= ~XD_CARD; | |
585 | chip->card_ejected &= ~XD_CARD; | |
586 | chip->card_fail &= ~XD_CARD; | |
587 | CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]); | |
588 | chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; | |
589 | ||
590 | release_xd_card(chip); | |
591 | ||
8470e791 GK |
592 | if (CHECK_PID(chip, 0x5288) && |
593 | CHECK_BARO_PKG(chip, QFN)) | |
594 | rtsx_write_register(chip, HOST_SLEEP_STATE, | |
595 | 0xC0, 0xC0); | |
fa590c22 MC |
596 | } |
597 | ||
598 | if (chip->need_release & MS_CARD) { | |
599 | clear_bit(MS_NR, &(chip->need_release)); | |
600 | chip->card_exist &= ~MS_CARD; | |
601 | chip->card_ejected &= ~MS_CARD; | |
602 | chip->card_fail &= ~MS_CARD; | |
603 | CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]); | |
604 | chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; | |
605 | ||
606 | release_ms_card(chip); | |
607 | } | |
608 | ||
bf6c0d11 FF |
609 | dev_dbg(rtsx_dev(chip), "chip->card_exist = 0x%x\n", |
610 | chip->card_exist); | |
fa590c22 MC |
611 | |
612 | if (!chip->card_exist) | |
613 | turn_off_led(chip, LED_GPIO); | |
614 | } | |
615 | ||
616 | if (chip->need_reset) { | |
bf6c0d11 FF |
617 | dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x\n", |
618 | (unsigned int)(chip->need_reset)); | |
fa590c22 MC |
619 | |
620 | rtsx_reset_cards(chip); | |
621 | } | |
622 | ||
623 | if (chip->need_reinit) { | |
bf6c0d11 FF |
624 | dev_dbg(rtsx_dev(chip), "chip->need_reinit = 0x%x\n", |
625 | (unsigned int)(chip->need_reinit)); | |
fa590c22 MC |
626 | |
627 | rtsx_reinit_cards(chip, 0); | |
628 | } | |
629 | } | |
630 | ||
fa590c22 MC |
631 | int switch_ssc_clock(struct rtsx_chip *chip, int clk) |
632 | { | |
633 | int retval; | |
634 | u8 N = (u8)(clk - 2), min_N, max_N; | |
635 | u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask; | |
636 | int sd_vpclk_phase_reset = 0; | |
637 | ||
638 | if (chip->cur_clk == clk) | |
639 | return STATUS_SUCCESS; | |
640 | ||
641 | min_N = 60; | |
642 | max_N = 120; | |
643 | max_div = CLK_DIV_4; | |
644 | ||
bf6c0d11 FF |
645 | dev_dbg(rtsx_dev(chip), "Switch SSC clock to %dMHz (cur_clk = %d)\n", |
646 | clk, chip->cur_clk); | |
fa590c22 | 647 | |
031366ea JP |
648 | if ((clk <= 2) || (N > max_N)) { |
649 | rtsx_trace(chip); | |
650 | return STATUS_FAIL; | |
651 | } | |
fa590c22 MC |
652 | |
653 | mcu_cnt = (u8)(125/clk + 3); | |
654 | if (mcu_cnt > 7) | |
655 | mcu_cnt = 7; | |
656 | ||
657 | div = CLK_DIV_1; | |
658 | while ((N < min_N) && (div < max_div)) { | |
659 | N = (N + 2) * 2 - 2; | |
660 | div++; | |
661 | } | |
bf6c0d11 | 662 | dev_dbg(rtsx_dev(chip), "N = %d, div = %d\n", N, div); |
fa590c22 MC |
663 | |
664 | if (chip->ssc_en) { | |
665 | ssc_depth = 0x01; | |
666 | N -= 2; | |
667 | } else { | |
668 | ssc_depth = 0; | |
669 | } | |
670 | ||
671 | ssc_depth_mask = 0x03; | |
672 | ||
bf6c0d11 | 673 | dev_dbg(rtsx_dev(chip), "ssc_depth = %d\n", ssc_depth); |
fa590c22 MC |
674 | |
675 | rtsx_init_cmd(chip); | |
676 | rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); | |
677 | rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); | |
678 | rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); | |
679 | rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth); | |
680 | rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); | |
681 | rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); | |
682 | if (sd_vpclk_phase_reset) { | |
8470e791 GK |
683 | rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, |
684 | PHASE_NOT_RESET, 0); | |
685 | rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, | |
686 | PHASE_NOT_RESET, PHASE_NOT_RESET); | |
fa590c22 MC |
687 | } |
688 | ||
689 | retval = rtsx_send_cmd(chip, 0, WAIT_TIME); | |
031366ea JP |
690 | if (retval < 0) { |
691 | rtsx_trace(chip); | |
692 | return STATUS_ERROR; | |
693 | } | |
fa590c22 MC |
694 | |
695 | udelay(10); | |
8ee775f9 JP |
696 | retval = rtsx_write_register(chip, CLK_CTL, CLK_LOW_FREQ, 0); |
697 | if (retval) { | |
698 | rtsx_trace(chip); | |
699 | return retval; | |
700 | } | |
fa590c22 MC |
701 | |
702 | chip->cur_clk = clk; | |
703 | ||
704 | return STATUS_SUCCESS; | |
705 | } | |
706 | ||
707 | int switch_normal_clock(struct rtsx_chip *chip, int clk) | |
708 | { | |
8ee775f9 | 709 | int retval; |
fa590c22 MC |
710 | u8 sel, div, mcu_cnt; |
711 | int sd_vpclk_phase_reset = 0; | |
712 | ||
713 | if (chip->cur_clk == clk) | |
714 | return STATUS_SUCCESS; | |
715 | ||
716 | switch (clk) { | |
717 | case CLK_20: | |
bf6c0d11 | 718 | dev_dbg(rtsx_dev(chip), "Switch clock to 20MHz\n"); |
fa590c22 MC |
719 | sel = SSC_80; |
720 | div = CLK_DIV_4; | |
721 | mcu_cnt = 7; | |
722 | break; | |
723 | ||
724 | case CLK_30: | |
bf6c0d11 | 725 | dev_dbg(rtsx_dev(chip), "Switch clock to 30MHz\n"); |
fa590c22 MC |
726 | sel = SSC_120; |
727 | div = CLK_DIV_4; | |
728 | mcu_cnt = 7; | |
729 | break; | |
730 | ||
731 | case CLK_40: | |
bf6c0d11 | 732 | dev_dbg(rtsx_dev(chip), "Switch clock to 40MHz\n"); |
fa590c22 MC |
733 | sel = SSC_80; |
734 | div = CLK_DIV_2; | |
735 | mcu_cnt = 7; | |
736 | break; | |
737 | ||
738 | case CLK_50: | |
bf6c0d11 | 739 | dev_dbg(rtsx_dev(chip), "Switch clock to 50MHz\n"); |
fa590c22 MC |
740 | sel = SSC_100; |
741 | div = CLK_DIV_2; | |
742 | mcu_cnt = 6; | |
743 | break; | |
744 | ||
745 | case CLK_60: | |
bf6c0d11 | 746 | dev_dbg(rtsx_dev(chip), "Switch clock to 60MHz\n"); |
fa590c22 MC |
747 | sel = SSC_120; |
748 | div = CLK_DIV_2; | |
749 | mcu_cnt = 6; | |
750 | break; | |
751 | ||
752 | case CLK_80: | |
bf6c0d11 | 753 | dev_dbg(rtsx_dev(chip), "Switch clock to 80MHz\n"); |
fa590c22 MC |
754 | sel = SSC_80; |
755 | div = CLK_DIV_1; | |
756 | mcu_cnt = 5; | |
757 | break; | |
758 | ||
759 | case CLK_100: | |
bf6c0d11 | 760 | dev_dbg(rtsx_dev(chip), "Switch clock to 100MHz\n"); |
fa590c22 MC |
761 | sel = SSC_100; |
762 | div = CLK_DIV_1; | |
763 | mcu_cnt = 5; | |
764 | break; | |
765 | ||
766 | case CLK_120: | |
bf6c0d11 | 767 | dev_dbg(rtsx_dev(chip), "Switch clock to 120MHz\n"); |
fa590c22 MC |
768 | sel = SSC_120; |
769 | div = CLK_DIV_1; | |
770 | mcu_cnt = 5; | |
771 | break; | |
772 | ||
773 | case CLK_150: | |
bf6c0d11 | 774 | dev_dbg(rtsx_dev(chip), "Switch clock to 150MHz\n"); |
fa590c22 MC |
775 | sel = SSC_150; |
776 | div = CLK_DIV_1; | |
777 | mcu_cnt = 4; | |
778 | break; | |
779 | ||
780 | case CLK_200: | |
bf6c0d11 | 781 | dev_dbg(rtsx_dev(chip), "Switch clock to 200MHz\n"); |
fa590c22 MC |
782 | sel = SSC_200; |
783 | div = CLK_DIV_1; | |
784 | mcu_cnt = 4; | |
785 | break; | |
786 | ||
787 | default: | |
bf6c0d11 FF |
788 | dev_dbg(rtsx_dev(chip), "Try to switch to an illegal clock (%d)\n", |
789 | clk); | |
031366ea JP |
790 | rtsx_trace(chip); |
791 | return STATUS_FAIL; | |
fa590c22 MC |
792 | } |
793 | ||
8ee775f9 JP |
794 | retval = rtsx_write_register(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ); |
795 | if (retval) { | |
796 | rtsx_trace(chip); | |
797 | return retval; | |
798 | } | |
fa590c22 | 799 | if (sd_vpclk_phase_reset) { |
8ee775f9 JP |
800 | retval = rtsx_write_register(chip, SD_VPCLK0_CTL, |
801 | PHASE_NOT_RESET, 0); | |
802 | if (retval) { | |
803 | rtsx_trace(chip); | |
804 | return retval; | |
805 | } | |
806 | retval = rtsx_write_register(chip, SD_VPCLK1_CTL, | |
807 | PHASE_NOT_RESET, 0); | |
808 | if (retval) { | |
809 | rtsx_trace(chip); | |
810 | return retval; | |
811 | } | |
812 | } | |
813 | retval = rtsx_write_register(chip, CLK_DIV, 0xFF, | |
814 | (div << 4) | mcu_cnt); | |
815 | if (retval) { | |
816 | rtsx_trace(chip); | |
817 | return retval; | |
818 | } | |
819 | retval = rtsx_write_register(chip, CLK_SEL, 0xFF, sel); | |
820 | if (retval) { | |
821 | rtsx_trace(chip); | |
822 | return retval; | |
fa590c22 | 823 | } |
fa590c22 MC |
824 | |
825 | if (sd_vpclk_phase_reset) { | |
826 | udelay(200); | |
8ee775f9 JP |
827 | retval = rtsx_write_register(chip, SD_VPCLK0_CTL, |
828 | PHASE_NOT_RESET, PHASE_NOT_RESET); | |
829 | if (retval) { | |
830 | rtsx_trace(chip); | |
831 | return retval; | |
832 | } | |
833 | retval = rtsx_write_register(chip, SD_VPCLK1_CTL, | |
834 | PHASE_NOT_RESET, PHASE_NOT_RESET); | |
835 | if (retval) { | |
836 | rtsx_trace(chip); | |
837 | return retval; | |
838 | } | |
fa590c22 MC |
839 | udelay(200); |
840 | } | |
8ee775f9 JP |
841 | retval = rtsx_write_register(chip, CLK_CTL, 0xFF, 0); |
842 | if (retval) { | |
843 | rtsx_trace(chip); | |
844 | return retval; | |
845 | } | |
fa590c22 MC |
846 | |
847 | chip->cur_clk = clk; | |
848 | ||
849 | return STATUS_SUCCESS; | |
850 | } | |
851 | ||
8470e791 GK |
852 | void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, |
853 | u32 byte_cnt, u8 pack_size) | |
fa590c22 MC |
854 | { |
855 | if (pack_size > DMA_1024) | |
856 | pack_size = DMA_512; | |
857 | ||
858 | rtsx_add_cmd(chip, WRITE_REG_CMD, IRQSTAT0, DMA_DONE_INT, DMA_DONE_INT); | |
859 | ||
860 | rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(byte_cnt >> 24)); | |
861 | rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(byte_cnt >> 16)); | |
862 | rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(byte_cnt >> 8)); | |
863 | rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC0, 0xFF, (u8)byte_cnt); | |
864 | ||
865 | if (dir == DMA_FROM_DEVICE) { | |
8470e791 GK |
866 | rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, |
867 | 0x03 | DMA_PACK_SIZE_MASK, | |
fa590c22 MC |
868 | DMA_DIR_FROM_CARD | DMA_EN | pack_size); |
869 | } else { | |
8470e791 GK |
870 | rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, |
871 | 0x03 | DMA_PACK_SIZE_MASK, | |
fa590c22 MC |
872 | DMA_DIR_TO_CARD | DMA_EN | pack_size); |
873 | } | |
874 | ||
875 | rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); | |
876 | } | |
877 | ||
878 | int enable_card_clock(struct rtsx_chip *chip, u8 card) | |
879 | { | |
8ee775f9 | 880 | int retval; |
fa590c22 MC |
881 | u8 clk_en = 0; |
882 | ||
883 | if (card & XD_CARD) | |
884 | clk_en |= XD_CLK_EN; | |
885 | if (card & SD_CARD) | |
886 | clk_en |= SD_CLK_EN; | |
887 | if (card & MS_CARD) | |
888 | clk_en |= MS_CLK_EN; | |
889 | ||
8ee775f9 JP |
890 | retval = rtsx_write_register(chip, CARD_CLK_EN, clk_en, clk_en); |
891 | if (retval) { | |
892 | rtsx_trace(chip); | |
893 | return retval; | |
894 | } | |
fa590c22 MC |
895 | |
896 | return STATUS_SUCCESS; | |
897 | } | |
898 | ||
899 | int disable_card_clock(struct rtsx_chip *chip, u8 card) | |
900 | { | |
8ee775f9 | 901 | int retval; |
fa590c22 MC |
902 | u8 clk_en = 0; |
903 | ||
904 | if (card & XD_CARD) | |
905 | clk_en |= XD_CLK_EN; | |
906 | if (card & SD_CARD) | |
907 | clk_en |= SD_CLK_EN; | |
908 | if (card & MS_CARD) | |
909 | clk_en |= MS_CLK_EN; | |
910 | ||
8ee775f9 JP |
911 | retval = rtsx_write_register(chip, CARD_CLK_EN, clk_en, 0); |
912 | if (retval) { | |
913 | rtsx_trace(chip); | |
914 | return retval; | |
915 | } | |
fa590c22 MC |
916 | |
917 | return STATUS_SUCCESS; | |
918 | } | |
919 | ||
920 | int card_power_on(struct rtsx_chip *chip, u8 card) | |
921 | { | |
922 | int retval; | |
923 | u8 mask, val1, val2; | |
924 | ||
925 | if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { | |
926 | mask = MS_POWER_MASK; | |
927 | val1 = MS_PARTIAL_POWER_ON; | |
928 | val2 = MS_POWER_ON; | |
929 | } else { | |
930 | mask = SD_POWER_MASK; | |
931 | val1 = SD_PARTIAL_POWER_ON; | |
932 | val2 = SD_POWER_ON; | |
933 | } | |
934 | ||
935 | rtsx_init_cmd(chip); | |
936 | rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1); | |
937 | ||
938 | retval = rtsx_send_cmd(chip, 0, 100); | |
031366ea JP |
939 | if (retval != STATUS_SUCCESS) { |
940 | rtsx_trace(chip); | |
941 | return STATUS_FAIL; | |
942 | } | |
fa590c22 MC |
943 | |
944 | udelay(chip->pmos_pwr_on_interval); | |
945 | ||
946 | rtsx_init_cmd(chip); | |
947 | rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2); | |
948 | ||
949 | retval = rtsx_send_cmd(chip, 0, 100); | |
031366ea JP |
950 | if (retval != STATUS_SUCCESS) { |
951 | rtsx_trace(chip); | |
952 | return STATUS_FAIL; | |
953 | } | |
fa590c22 MC |
954 | |
955 | return STATUS_SUCCESS; | |
956 | } | |
957 | ||
958 | int card_power_off(struct rtsx_chip *chip, u8 card) | |
959 | { | |
8ee775f9 | 960 | int retval; |
fa590c22 MC |
961 | u8 mask, val; |
962 | ||
963 | if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { | |
964 | mask = MS_POWER_MASK; | |
965 | val = MS_POWER_OFF; | |
966 | } else { | |
967 | mask = SD_POWER_MASK; | |
968 | val = SD_POWER_OFF; | |
969 | } | |
970 | ||
8ee775f9 JP |
971 | retval = rtsx_write_register(chip, CARD_PWR_CTL, mask, val); |
972 | if (retval) { | |
973 | rtsx_trace(chip); | |
974 | return retval; | |
975 | } | |
fa590c22 MC |
976 | |
977 | return STATUS_SUCCESS; | |
978 | } | |
979 | ||
8470e791 GK |
980 | int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, |
981 | u32 sec_addr, u16 sec_cnt) | |
fa590c22 MC |
982 | { |
983 | int retval; | |
984 | unsigned int lun = SCSI_LUN(srb); | |
985 | int i; | |
986 | ||
031366ea JP |
987 | if (chip->rw_card[lun] == NULL) { |
988 | rtsx_trace(chip); | |
989 | return STATUS_FAIL; | |
990 | } | |
fa590c22 MC |
991 | |
992 | for (i = 0; i < 3; i++) { | |
993 | chip->rw_need_retry = 0; | |
994 | ||
995 | retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt); | |
996 | if (retval != STATUS_SUCCESS) { | |
997 | if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) { | |
998 | rtsx_release_chip(chip); | |
031366ea JP |
999 | rtsx_trace(chip); |
1000 | return STATUS_FAIL; | |
fa590c22 | 1001 | } |
8470e791 | 1002 | if (detect_card_cd(chip, chip->cur_card) != |
031366ea JP |
1003 | STATUS_SUCCESS) { |
1004 | rtsx_trace(chip); | |
1005 | return STATUS_FAIL; | |
1006 | } | |
fa590c22 MC |
1007 | |
1008 | if (!chip->rw_need_retry) { | |
bf6c0d11 | 1009 | dev_dbg(rtsx_dev(chip), "RW fail, but no need to retry\n"); |
fa590c22 MC |
1010 | break; |
1011 | } | |
1012 | } else { | |
1013 | chip->rw_need_retry = 0; | |
1014 | break; | |
1015 | } | |
1016 | ||
bf6c0d11 | 1017 | dev_dbg(rtsx_dev(chip), "Retry RW, (i = %d)\n", i); |
fa590c22 MC |
1018 | } |
1019 | ||
1020 | return retval; | |
1021 | } | |
1022 | ||
1023 | int card_share_mode(struct rtsx_chip *chip, int card) | |
1024 | { | |
8ee775f9 | 1025 | int retval; |
fa590c22 MC |
1026 | u8 mask, value; |
1027 | ||
1028 | if (CHECK_PID(chip, 0x5208)) { | |
1029 | mask = CARD_SHARE_MASK; | |
1030 | if (card == SD_CARD) | |
1031 | value = CARD_SHARE_48_SD; | |
1032 | else if (card == MS_CARD) | |
1033 | value = CARD_SHARE_48_MS; | |
1034 | else if (card == XD_CARD) | |
1035 | value = CARD_SHARE_48_XD; | |
031366ea JP |
1036 | else { |
1037 | rtsx_trace(chip); | |
1038 | return STATUS_FAIL; | |
1039 | } | |
fa590c22 MC |
1040 | |
1041 | } else if (CHECK_PID(chip, 0x5288)) { | |
1042 | mask = 0x03; | |
1043 | if (card == SD_CARD) | |
1044 | value = CARD_SHARE_BAROSSA_SD; | |
1045 | else if (card == MS_CARD) | |
1046 | value = CARD_SHARE_BAROSSA_MS; | |
1047 | else if (card == XD_CARD) | |
1048 | value = CARD_SHARE_BAROSSA_XD; | |
031366ea JP |
1049 | else { |
1050 | rtsx_trace(chip); | |
1051 | return STATUS_FAIL; | |
1052 | } | |
fa590c22 MC |
1053 | |
1054 | } else { | |
031366ea JP |
1055 | rtsx_trace(chip); |
1056 | return STATUS_FAIL; | |
fa590c22 MC |
1057 | } |
1058 | ||
8ee775f9 JP |
1059 | retval = rtsx_write_register(chip, CARD_SHARE_MODE, mask, value); |
1060 | if (retval) { | |
1061 | rtsx_trace(chip); | |
1062 | return retval; | |
1063 | } | |
fa590c22 MC |
1064 | |
1065 | return STATUS_SUCCESS; | |
1066 | } | |
1067 | ||
fa590c22 MC |
1068 | int select_card(struct rtsx_chip *chip, int card) |
1069 | { | |
1070 | int retval; | |
1071 | ||
1072 | if (chip->cur_card != card) { | |
1073 | u8 mod; | |
1074 | ||
1075 | if (card == SD_CARD) | |
1076 | mod = SD_MOD_SEL; | |
1077 | else if (card == MS_CARD) | |
1078 | mod = MS_MOD_SEL; | |
1079 | else if (card == XD_CARD) | |
1080 | mod = XD_MOD_SEL; | |
1081 | else if (card == SPI_CARD) | |
1082 | mod = SPI_MOD_SEL; | |
031366ea JP |
1083 | else { |
1084 | rtsx_trace(chip); | |
1085 | return STATUS_FAIL; | |
1086 | } | |
fa590c22 | 1087 | |
8ee775f9 JP |
1088 | retval = rtsx_write_register(chip, CARD_SELECT, 0x07, mod); |
1089 | if (retval) { | |
1090 | rtsx_trace(chip); | |
1091 | return retval; | |
1092 | } | |
fa590c22 MC |
1093 | chip->cur_card = card; |
1094 | ||
1095 | retval = card_share_mode(chip, card); | |
031366ea JP |
1096 | if (retval != STATUS_SUCCESS) { |
1097 | rtsx_trace(chip); | |
1098 | return STATUS_FAIL; | |
1099 | } | |
fa590c22 MC |
1100 | } |
1101 | ||
1102 | return STATUS_SUCCESS; | |
1103 | } | |
1104 | ||
1105 | void toggle_gpio(struct rtsx_chip *chip, u8 gpio) | |
1106 | { | |
1107 | u8 temp_reg; | |
1108 | ||
1109 | rtsx_read_register(chip, CARD_GPIO, &temp_reg); | |
1110 | temp_reg ^= (0x01 << gpio); | |
1111 | rtsx_write_register(chip, CARD_GPIO, 0xFF, temp_reg); | |
1112 | } | |
1113 | ||
1114 | void turn_on_led(struct rtsx_chip *chip, u8 gpio) | |
1115 | { | |
1116 | if (CHECK_PID(chip, 0x5288)) | |
8470e791 GK |
1117 | rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), |
1118 | (u8)(1 << gpio)); | |
fa590c22 MC |
1119 | else |
1120 | rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); | |
1121 | } | |
1122 | ||
1123 | void turn_off_led(struct rtsx_chip *chip, u8 gpio) | |
1124 | { | |
1125 | if (CHECK_PID(chip, 0x5288)) | |
1126 | rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); | |
1127 | else | |
8470e791 GK |
1128 | rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), |
1129 | (u8)(1 << gpio)); | |
fa590c22 MC |
1130 | } |
1131 | ||
1132 | int detect_card_cd(struct rtsx_chip *chip, int card) | |
1133 | { | |
1134 | u32 card_cd, status; | |
1135 | ||
1136 | if (card == SD_CARD) { | |
1137 | card_cd = SD_EXIST; | |
1138 | } else if (card == MS_CARD) { | |
1139 | card_cd = MS_EXIST; | |
1140 | } else if (card == XD_CARD) { | |
1141 | card_cd = XD_EXIST; | |
1142 | } else { | |
bf6c0d11 | 1143 | dev_dbg(rtsx_dev(chip), "Wrong card type: 0x%x\n", card); |
031366ea JP |
1144 | rtsx_trace(chip); |
1145 | return STATUS_FAIL; | |
fa590c22 MC |
1146 | } |
1147 | ||
1148 | status = rtsx_readl(chip, RTSX_BIPR); | |
031366ea JP |
1149 | if (!(status & card_cd)) { |
1150 | rtsx_trace(chip); | |
1151 | return STATUS_FAIL; | |
1152 | } | |
fa590c22 MC |
1153 | |
1154 | return STATUS_SUCCESS; | |
1155 | } | |
1156 | ||
1157 | int check_card_exist(struct rtsx_chip *chip, unsigned int lun) | |
1158 | { | |
1159 | if (chip->card_exist & chip->lun2card[lun]) | |
1160 | return 1; | |
1161 | ||
1162 | return 0; | |
1163 | } | |
1164 | ||
1165 | int check_card_ready(struct rtsx_chip *chip, unsigned int lun) | |
1166 | { | |
1167 | if (chip->card_ready & chip->lun2card[lun]) | |
1168 | return 1; | |
1169 | ||
1170 | return 0; | |
1171 | } | |
1172 | ||
1173 | int check_card_wp(struct rtsx_chip *chip, unsigned int lun) | |
1174 | { | |
1175 | if (chip->card_wp & chip->lun2card[lun]) | |
1176 | return 1; | |
1177 | ||
1178 | return 0; | |
1179 | } | |
1180 | ||
fa590c22 MC |
1181 | u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun) |
1182 | { | |
1183 | if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) | |
1184 | return (u8)XD_CARD; | |
1185 | else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) | |
1186 | return (u8)SD_CARD; | |
1187 | else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) | |
1188 | return (u8)MS_CARD; | |
1189 | ||
1190 | return 0; | |
1191 | } | |
1192 | ||
1193 | void eject_card(struct rtsx_chip *chip, unsigned int lun) | |
1194 | { | |
1195 | do_remaining_work(chip); | |
1196 | ||
1197 | if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { | |
1198 | release_sd_card(chip); | |
1199 | chip->card_ejected |= SD_CARD; | |
1200 | chip->card_ready &= ~SD_CARD; | |
1201 | chip->capacity[lun] = 0; | |
1202 | } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { | |
1203 | release_xd_card(chip); | |
1204 | chip->card_ejected |= XD_CARD; | |
1205 | chip->card_ready &= ~XD_CARD; | |
1206 | chip->capacity[lun] = 0; | |
1207 | } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { | |
1208 | release_ms_card(chip); | |
1209 | chip->card_ejected |= MS_CARD; | |
1210 | chip->card_ready &= ~MS_CARD; | |
1211 | chip->capacity[lun] = 0; | |
1212 | } | |
1213 | } |