diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/sd.c | 6 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c | 523 |
2 files changed, 67 insertions, 462 deletions
diff --git a/firmware/drivers/sd.c b/firmware/drivers/sd.c index d566e614d2..4034b9453d 100644 --- a/firmware/drivers/sd.c +++ b/firmware/drivers/sd.c | |||
@@ -20,6 +20,7 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include "logf.h" | ||
23 | #include "hotswap.h" | 24 | #include "hotswap.h" |
24 | #include "storage.h" | 25 | #include "storage.h" |
25 | 26 | ||
@@ -42,14 +43,12 @@ void sd_parse_csd(tCardInfo *card) | |||
42 | max_read_bl_len = 1 << card_extract_bits(card->csd, 83, 4); | 43 | max_read_bl_len = 1 << card_extract_bits(card->csd, 83, 4); |
43 | card->numblocks = c_size * c_mult * (max_read_bl_len/512); | 44 | card->numblocks = c_size * c_mult * (max_read_bl_len/512); |
44 | } | 45 | } |
45 | #ifdef HAVE_MULTIVOLUME | ||
46 | else if(csd_version == 1) | 46 | else if(csd_version == 1) |
47 | { | 47 | { |
48 | /* CSD version 2.0 */ | 48 | /* CSD version 2.0 */ |
49 | c_size = card_extract_bits(card->csd, 69, 22) + 1; | 49 | c_size = card_extract_bits(card->csd, 69, 22) + 1; |
50 | card->numblocks = c_size << 10; | 50 | card->numblocks = c_size << 10; |
51 | } | 51 | } |
52 | #endif | ||
53 | 52 | ||
54 | card->blocksize = 512; /* Always use 512 byte blocks */ | 53 | card->blocksize = 512; /* Always use 512 byte blocks */ |
55 | 54 | ||
@@ -62,6 +61,9 @@ void sd_parse_csd(tCardInfo *card) | |||
62 | sd_exponent[card_extract_bits(card->csd, 114, 3)]; | 61 | sd_exponent[card_extract_bits(card->csd, 114, 3)]; |
63 | 62 | ||
64 | card->r2w_factor = card_extract_bits(card->csd, 28, 3); | 63 | card->r2w_factor = card_extract_bits(card->csd, 28, 3); |
64 | |||
65 | logf("CSD%d.0 numblocks:%d speed:%d", csd_version+1, card->numblocks, card->speed); | ||
66 | logf("nsac: %d taac: %d r2w: %d", card->nsac, card->taac, card->r2w_factor); | ||
65 | } | 67 | } |
66 | 68 | ||
67 | void sd_sleep(void) | 69 | void sd_sleep(void) |
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c index c48ee0be73..5de40c99dc 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | static struct wakeup sd_wakeup; | 36 | static struct wakeup sd_wakeup; |
37 | static long last_disk_activity = -1; | 37 | static long last_disk_activity = -1; |
38 | static tCardInfo card; | ||
38 | 39 | ||
39 | //#define SD_DMA_ENABLE | 40 | //#define SD_DMA_ENABLE |
40 | #define SD_DMA_INTERRUPT 0 | 41 | #define SD_DMA_INTERRUPT 0 |
@@ -44,7 +45,7 @@ static long last_disk_activity = -1; | |||
44 | #define SD_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN) | 45 | #define SD_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN) |
45 | #define SD_RESET() __msc_reset() | 46 | #define SD_RESET() __msc_reset() |
46 | 47 | ||
47 | #define SD_IRQ_MASK() \ | 48 | #define SD_IRQ_MASK() \ |
48 | do { \ | 49 | do { \ |
49 | REG_MSC_IMASK = 0xffff; \ | 50 | REG_MSC_IMASK = 0xffff; \ |
50 | REG_MSC_IREG = 0xffff; \ | 51 | REG_MSC_IREG = 0xffff; \ |
@@ -80,7 +81,6 @@ enum sd_result_t | |||
80 | 81 | ||
81 | /* Standard MMC/SD clock speeds */ | 82 | /* Standard MMC/SD clock speeds */ |
82 | #define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */ | 83 | #define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */ |
83 | #define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */ | ||
84 | #define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ | 84 | #define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */ |
85 | #define SD_CLOCK_HIGH 48000000 /* 48 MHz for SD Cards */ | 85 | #define SD_CLOCK_HIGH 48000000 /* 48 MHz for SD Cards */ |
86 | 86 | ||
@@ -164,115 +164,13 @@ struct sd_response_r1 | |||
164 | unsigned int status; | 164 | unsigned int status; |
165 | }; | 165 | }; |
166 | 166 | ||
167 | struct sd_cid | ||
168 | { | ||
169 | unsigned char mid; | ||
170 | unsigned short oid; | ||
171 | unsigned char pnm[7]; /* Product name (we null-terminate) */ | ||
172 | unsigned char prv; | ||
173 | unsigned int psn; | ||
174 | unsigned char mdt; | ||
175 | }; | ||
176 | |||
177 | struct sd_csd | ||
178 | { | ||
179 | unsigned char csd_structure; | ||
180 | unsigned char spec_vers; | ||
181 | unsigned char taac; | ||
182 | unsigned char nsac; | ||
183 | unsigned char tran_speed; | ||
184 | unsigned short ccc; | ||
185 | unsigned char read_bl_len; | ||
186 | unsigned char read_bl_partial; | ||
187 | unsigned char write_blk_misalign; | ||
188 | unsigned char read_blk_misalign; | ||
189 | unsigned char dsr_imp; | ||
190 | unsigned short c_size; | ||
191 | unsigned char vdd_r_curr_min; | ||
192 | unsigned char vdd_r_curr_max; | ||
193 | unsigned char vdd_w_curr_min; | ||
194 | unsigned char vdd_w_curr_max; | ||
195 | unsigned char c_size_mult; | ||
196 | union | ||
197 | { | ||
198 | struct /* MMC system specification version 3.1 */ | ||
199 | { | ||
200 | unsigned char erase_grp_size; | ||
201 | unsigned char erase_grp_mult; | ||
202 | } v31; | ||
203 | struct /* MMC system specification version 2.2 */ | ||
204 | { | ||
205 | unsigned char sector_size; | ||
206 | unsigned char erase_grp_size; | ||
207 | } v22; | ||
208 | } erase; | ||
209 | unsigned char wp_grp_size; | ||
210 | unsigned char wp_grp_enable; | ||
211 | unsigned char default_ecc; | ||
212 | unsigned char r2w_factor; | ||
213 | unsigned char write_bl_len; | ||
214 | unsigned char write_bl_partial; | ||
215 | unsigned char file_format_grp; | ||
216 | unsigned char copy; | ||
217 | unsigned char perm_write_protect; | ||
218 | unsigned char tmp_write_protect; | ||
219 | unsigned char file_format; | ||
220 | unsigned char ecc; | ||
221 | }; | ||
222 | |||
223 | struct sd_response_r3 | 167 | struct sd_response_r3 |
224 | { | 168 | { |
225 | unsigned int ocr; | 169 | unsigned int ocr; |
226 | }; | 170 | }; |
227 | 171 | ||
228 | #define SD_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */ | ||
229 | #define SD_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */ | ||
230 | #define SD_VDD_155_160 0x00000004 /* VDD voltage 1.55 - 1.60 */ | ||
231 | #define SD_VDD_160_165 0x00000008 /* VDD voltage 1.60 - 1.65 */ | ||
232 | #define SD_VDD_165_170 0x00000010 /* VDD voltage 1.65 - 1.70 */ | ||
233 | #define SD_VDD_17_18 0x00000020 /* VDD voltage 1.7 - 1.8 */ | ||
234 | #define SD_VDD_18_19 0x00000040 /* VDD voltage 1.8 - 1.9 */ | ||
235 | #define SD_VDD_19_20 0x00000080 /* VDD voltage 1.9 - 2.0 */ | ||
236 | #define SD_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ | ||
237 | #define SD_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ | ||
238 | #define SD_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ | ||
239 | #define SD_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ | ||
240 | #define SD_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ | ||
241 | #define SD_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ | ||
242 | #define SD_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ | ||
243 | #define SD_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ | ||
244 | #define SD_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ | ||
245 | #define SD_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ | ||
246 | #define SD_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ | ||
247 | #define SD_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ | ||
248 | #define SD_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ | ||
249 | #define SD_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ | ||
250 | #define SD_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ | ||
251 | #define SD_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ | ||
252 | #define SD_CARD_BUSY 0x80000000 /* Card Power up status bit */ | 172 | #define SD_CARD_BUSY 0x80000000 /* Card Power up status bit */ |
253 | 173 | ||
254 | |||
255 | /* CSD field definitions */ | ||
256 | #define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */ | ||
257 | #define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */ | ||
258 | #define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 */ | ||
259 | |||
260 | #define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */ | ||
261 | #define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */ | ||
262 | #define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ | ||
263 | #define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */ | ||
264 | |||
265 | /* the information structure of SD Card */ | ||
266 | typedef struct SD_INFO | ||
267 | { | ||
268 | int rca; /* RCA */ | ||
269 | struct sd_cid cid; | ||
270 | struct sd_csd csd; | ||
271 | unsigned int block_num; | ||
272 | unsigned int block_len; | ||
273 | unsigned int ocr; | ||
274 | } sd_info; | ||
275 | |||
276 | struct sd_request | 174 | struct sd_request |
277 | { | 175 | { |
278 | int index; /* Slot index - used for CS lines */ | 176 | int index; /* Slot index - used for CS lines */ |
@@ -304,7 +202,6 @@ struct sd_request | |||
304 | static int use_4bit = 1; /* Use 4-bit data bus */ | 202 | static int use_4bit = 1; /* Use 4-bit data bus */ |
305 | static int num_6 = 0; | 203 | static int num_6 = 0; |
306 | static int sd2_0 = 0; | 204 | static int sd2_0 = 0; |
307 | static sd_info sdinfo; | ||
308 | 205 | ||
309 | /************************************************************************** | 206 | /************************************************************************** |
310 | * Utility functions | 207 | * Utility functions |
@@ -317,197 +214,6 @@ static sd_info sdinfo; | |||
317 | #define PARSE_U16(_buf,_index) \ | 214 | #define PARSE_U16(_buf,_index) \ |
318 | (((unsigned short)_buf[_index]) << 8) | ((unsigned short)_buf[_index+1]); | 215 | (((unsigned short)_buf[_index]) << 8) | ((unsigned short)_buf[_index+1]); |
319 | 216 | ||
320 | int sd_unpack_csd(struct sd_request *request, struct sd_csd *csd) | ||
321 | { | ||
322 | unsigned char *buf = request->response; | ||
323 | int num = 0; | ||
324 | |||
325 | if (request->result) | ||
326 | return request->result; | ||
327 | |||
328 | csd->csd_structure = (buf[1] & 0xc0) >> 6; | ||
329 | if (csd->csd_structure) | ||
330 | sd2_0 = 1; | ||
331 | else | ||
332 | sd2_0 = 0; | ||
333 | |||
334 | switch (csd->csd_structure) { | ||
335 | case 0 : | ||
336 | csd->taac = buf[2]; | ||
337 | csd->nsac = buf[3]; | ||
338 | csd->tran_speed = buf[4]; | ||
339 | csd->ccc = (((unsigned short)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4); | ||
340 | csd->read_bl_len = buf[6] & 0x0f; | ||
341 | /* for support 2GB card*/ | ||
342 | if (csd->read_bl_len >= 10) | ||
343 | { | ||
344 | num = csd->read_bl_len - 9; | ||
345 | csd->read_bl_len = 9; | ||
346 | } | ||
347 | |||
348 | csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0; | ||
349 | csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0; | ||
350 | csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0; | ||
351 | csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0; | ||
352 | csd->c_size = ((((unsigned short)buf[7]) & 0x03) << 10) | (((unsigned short)buf[8]) << 2) | (((unsigned short)buf[9]) & 0xc0) >> 6; | ||
353 | |||
354 | if (num) | ||
355 | csd->c_size = csd->c_size << num; | ||
356 | |||
357 | |||
358 | csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3; | ||
359 | csd->vdd_r_curr_max = buf[9] & 0x07; | ||
360 | csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5; | ||
361 | csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2; | ||
362 | csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7); | ||
363 | switch (csd->csd_structure) { | ||
364 | case CSD_STRUCT_VER_1_0: | ||
365 | case CSD_STRUCT_VER_1_1: | ||
366 | csd->erase.v22.sector_size = (buf[11] & 0x7c) >> 2; | ||
367 | csd->erase.v22.erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5); | ||
368 | |||
369 | break; | ||
370 | case CSD_STRUCT_VER_1_2: | ||
371 | default: | ||
372 | csd->erase.v31.erase_grp_size = (buf[11] & 0x7c) >> 2; | ||
373 | csd->erase.v31.erase_grp_mult = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5); | ||
374 | break; | ||
375 | } | ||
376 | csd->wp_grp_size = buf[12] & 0x1f; | ||
377 | csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0; | ||
378 | csd->default_ecc = (buf[13] & 0x60) >> 5; | ||
379 | csd->r2w_factor = (buf[13] & 0x1c) >> 2; | ||
380 | csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6); | ||
381 | if (csd->write_bl_len >= 10) | ||
382 | csd->write_bl_len = 9; | ||
383 | |||
384 | csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0; | ||
385 | csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0; | ||
386 | csd->copy = (buf[15] & 0x40) ? 1 : 0; | ||
387 | csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0; | ||
388 | csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0; | ||
389 | csd->file_format = (buf[15] & 0x0c) >> 2; | ||
390 | csd->ecc = buf[15] & 0x03; | ||
391 | |||
392 | DEBUG("csd_structure=%d spec_vers=%d taac=%02x nsac=%02x tran_speed=%02x", | ||
393 | csd->csd_structure, csd->spec_vers, | ||
394 | csd->taac, csd->nsac, csd->tran_speed); | ||
395 | DEBUG("ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d", | ||
396 | csd->ccc, csd->read_bl_len, | ||
397 | csd->read_bl_partial, csd->write_blk_misalign); | ||
398 | DEBUG("read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d", | ||
399 | csd->read_blk_misalign, csd->dsr_imp, | ||
400 | csd->c_size, csd->vdd_r_curr_min); | ||
401 | DEBUG("vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d", | ||
402 | csd->vdd_r_curr_max, csd->vdd_w_curr_min, | ||
403 | csd->vdd_w_curr_max, csd->c_size_mult); | ||
404 | DEBUG("wp_grp_size=%d wp_grp_enable=%d default_ecc=%d r2w_factor=%d", | ||
405 | csd->wp_grp_size, csd->wp_grp_enable, | ||
406 | csd->default_ecc, csd->r2w_factor); | ||
407 | DEBUG("write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d", | ||
408 | csd->write_bl_len, csd->write_bl_partial, | ||
409 | csd->file_format_grp, csd->copy); | ||
410 | DEBUG("perm_write_protect=%d tmp_write_protect=%d file_format=%d ecc=%d", | ||
411 | csd->perm_write_protect, csd->tmp_write_protect, | ||
412 | csd->file_format, csd->ecc); | ||
413 | switch (csd->csd_structure) { | ||
414 | case CSD_STRUCT_VER_1_0: | ||
415 | case CSD_STRUCT_VER_1_1: | ||
416 | DEBUG("V22 sector_size=%d erase_grp_size=%d", | ||
417 | csd->erase.v22.sector_size, | ||
418 | csd->erase.v22.erase_grp_size); | ||
419 | break; | ||
420 | case CSD_STRUCT_VER_1_2: | ||
421 | default: | ||
422 | DEBUG("V31 erase_grp_size=%d erase_grp_mult=%d", | ||
423 | csd->erase.v31.erase_grp_size, | ||
424 | csd->erase.v31.erase_grp_mult); | ||
425 | break; | ||
426 | |||
427 | } | ||
428 | break; | ||
429 | |||
430 | case 1 : | ||
431 | csd->taac = 0; | ||
432 | csd->nsac = 0; | ||
433 | csd->tran_speed = buf[4]; | ||
434 | csd->ccc = (((unsigned short)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4); | ||
435 | |||
436 | csd->read_bl_len = 9; | ||
437 | csd->read_bl_partial = 0; | ||
438 | csd->write_blk_misalign = 0; | ||
439 | csd->read_blk_misalign = 0; | ||
440 | csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0; | ||
441 | csd->c_size = ((((unsigned short)buf[8]) & 0x3f) << 16) | (((unsigned short)buf[9]) << 8) | ((unsigned short)buf[10]) ; | ||
442 | switch (csd->csd_structure) { | ||
443 | case CSD_STRUCT_VER_1_0: | ||
444 | case CSD_STRUCT_VER_1_1: | ||
445 | csd->erase.v22.sector_size = 0x7f; | ||
446 | csd->erase.v22.erase_grp_size = 0; | ||
447 | break; | ||
448 | case CSD_STRUCT_VER_1_2: | ||
449 | default: | ||
450 | csd->erase.v31.erase_grp_size = 0x7f; | ||
451 | csd->erase.v31.erase_grp_mult = 0; | ||
452 | break; | ||
453 | } | ||
454 | csd->wp_grp_size = 0; | ||
455 | csd->wp_grp_enable = 0; | ||
456 | csd->default_ecc = (buf[13] & 0x60) >> 5; | ||
457 | csd->r2w_factor = 4;/* Unused */ | ||
458 | csd->write_bl_len = 9; | ||
459 | |||
460 | csd->write_bl_partial = 0; | ||
461 | csd->file_format_grp = 0; | ||
462 | csd->copy = (buf[15] & 0x40) ? 1 : 0; | ||
463 | csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0; | ||
464 | csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0; | ||
465 | csd->file_format = 0; | ||
466 | csd->ecc = buf[15] & 0x03; | ||
467 | |||
468 | DEBUG("csd_structure=%d spec_vers=%d taac=%02x nsac=%02x tran_speed=%02x", | ||
469 | csd->csd_structure, csd->spec_vers, | ||
470 | csd->taac, csd->nsac, csd->tran_speed); | ||
471 | DEBUG("ccc=%04x read_bl_len=%d read_bl_partial=%d write_blk_misalign=%d", | ||
472 | csd->ccc, csd->read_bl_len, | ||
473 | csd->read_bl_partial, csd->write_blk_misalign); | ||
474 | DEBUG("read_blk_misalign=%d dsr_imp=%d c_size=%d vdd_r_curr_min=%d", | ||
475 | csd->read_blk_misalign, csd->dsr_imp, | ||
476 | csd->c_size, csd->vdd_r_curr_min); | ||
477 | DEBUG("vdd_r_curr_max=%d vdd_w_curr_min=%d vdd_w_curr_max=%d c_size_mult=%d", | ||
478 | csd->vdd_r_curr_max, csd->vdd_w_curr_min, | ||
479 | csd->vdd_w_curr_max, csd->c_size_mult); | ||
480 | DEBUG("wp_grp_size=%d wp_grp_enable=%d default_ecc=%d r2w_factor=%d", | ||
481 | csd->wp_grp_size, csd->wp_grp_enable, | ||
482 | csd->default_ecc, csd->r2w_factor); | ||
483 | DEBUG("write_bl_len=%d write_bl_partial=%d file_format_grp=%d copy=%d", | ||
484 | csd->write_bl_len, csd->write_bl_partial, | ||
485 | csd->file_format_grp, csd->copy); | ||
486 | DEBUG("perm_write_protect=%d tmp_write_protect=%d file_format=%d ecc=%d", | ||
487 | csd->perm_write_protect, csd->tmp_write_protect, | ||
488 | csd->file_format, csd->ecc); | ||
489 | switch (csd->csd_structure) { | ||
490 | case CSD_STRUCT_VER_1_0: | ||
491 | case CSD_STRUCT_VER_1_1: | ||
492 | DEBUG("V22 sector_size=%d erase_grp_size=%d", | ||
493 | csd->erase.v22.sector_size, | ||
494 | csd->erase.v22.erase_grp_size); | ||
495 | break; | ||
496 | case CSD_STRUCT_VER_1_2: | ||
497 | default: | ||
498 | DEBUG("V31 erase_grp_size=%d erase_grp_mult=%d", | ||
499 | csd->erase.v31.erase_grp_size, | ||
500 | csd->erase.v31.erase_grp_mult); | ||
501 | break; | ||
502 | } | ||
503 | } | ||
504 | |||
505 | if (buf[0] != 0x3f) | ||
506 | return SD_ERROR_HEADER_MISMATCH; | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | int sd_unpack_r1(struct sd_request *request, struct sd_response_r1 *r1) | 217 | int sd_unpack_r1(struct sd_request *request, struct sd_response_r1 *r1) |
512 | { | 218 | { |
513 | unsigned char *buf = request->response; | 219 | unsigned char *buf = request->response; |
@@ -557,44 +263,20 @@ int sd_unpack_scr(struct sd_request *request, struct sd_response_r1 *r1, unsigne | |||
557 | return sd_unpack_r1(request, r1); | 263 | return sd_unpack_r1(request, r1); |
558 | } | 264 | } |
559 | 265 | ||
560 | int sd_unpack_r6(struct sd_request *request, struct sd_response_r1 *r1, int *rca) | 266 | static inline int sd_unpack_r6(struct sd_request *request, struct sd_response_r1 *r1, unsigned long *rca) |
561 | { | 267 | { |
562 | unsigned char *buf = request->response; | 268 | unsigned char *buf = request->response; |
563 | 269 | ||
564 | if (request->result) return request->result; | 270 | if (request->result) |
565 | 271 | return request->result; | |
566 | *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */ | ||
567 | |||
568 | *(buf+1) = 0; | ||
569 | *(buf+2) = 0; | ||
570 | 272 | ||
571 | return sd_unpack_r1(request, r1); | 273 | *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */ |
572 | } | ||
573 | |||
574 | int sd_unpack_cid(struct sd_request *request, struct sd_cid *cid) | ||
575 | { | ||
576 | unsigned char *buf = request->response; | ||
577 | int i; | ||
578 | |||
579 | if (request->result) return request->result; | ||
580 | |||
581 | cid->mid = buf[1]; | ||
582 | cid->oid = PARSE_U16(buf,2); | ||
583 | for (i = 0 ; i < 6 ; i++) | ||
584 | cid->pnm[i] = buf[4+i]; | ||
585 | cid->pnm[6] = 0; | ||
586 | cid->prv = buf[10]; | ||
587 | cid->psn = PARSE_U32(buf,11); | ||
588 | cid->mdt = buf[15]; | ||
589 | 274 | ||
590 | DEBUG("sd_unpack_cid: mid=%d oid=%d pnm=%s prv=%d.%d psn=%08x mdt=%d/%d", | 275 | *(buf+1) = 0; |
591 | cid->mid, cid->oid, cid->pnm, | 276 | *(buf+2) = 0; |
592 | (cid->prv>>4), (cid->prv&0xf), | 277 | |
593 | cid->psn, (cid->mdt>>4), (cid->mdt&0xf)+1997); | 278 | return sd_unpack_r1(request, r1); |
594 | 279 | } | |
595 | if (buf[0] != 0x3f) return SD_ERROR_HEADER_MISMATCH; | ||
596 | return 0; | ||
597 | } | ||
598 | 280 | ||
599 | int sd_unpack_r3(struct sd_request *request, struct sd_response_r3 *r3) | 281 | int sd_unpack_r3(struct sd_request *request, struct sd_response_r3 *r3) |
600 | { | 282 | { |
@@ -918,10 +600,10 @@ static int jz_sd_transmit_data(struct sd_request *req) | |||
918 | } | 600 | } |
919 | #endif | 601 | #endif |
920 | 602 | ||
921 | static inline unsigned int jz_sd_calc_clkrt(int is_sd, unsigned int rate) | 603 | static inline unsigned int jz_sd_calc_clkrt(unsigned int rate) |
922 | { | 604 | { |
923 | unsigned int clkrt; | 605 | unsigned int clkrt; |
924 | unsigned int clk_src = is_sd ? (sd2_0 ? 48000000 : 24000000) : 20000000; | 606 | unsigned int clk_src = sd2_0 ? SD_CLOCK_HIGH : SD_CLOCK_FAST; |
925 | 607 | ||
926 | clkrt = 0; | 608 | clkrt = 0; |
927 | while (rate < clk_src) | 609 | while (rate < clk_src) |
@@ -932,31 +614,28 @@ static inline unsigned int jz_sd_calc_clkrt(int is_sd, unsigned int rate) | |||
932 | return clkrt; | 614 | return clkrt; |
933 | } | 615 | } |
934 | 616 | ||
935 | /* Set the MMC clock frequency */ | 617 | static inline void cpm_select_msc_clk(unsigned int rate) |
936 | static void jz_sd_set_clock(int sd, unsigned int rate) | ||
937 | { | 618 | { |
938 | int clkrt = 0; | 619 | unsigned int div = __cpm_get_pllout2() / rate; |
620 | |||
621 | REG_CPM_MSCCDR = div - 1; | ||
622 | } | ||
939 | 623 | ||
940 | sd = sd ? 1 : 0; | 624 | /* Set the MMC clock frequency */ |
625 | static void jz_sd_set_clock(unsigned int rate) | ||
626 | { | ||
627 | int clkrt; | ||
941 | 628 | ||
942 | jz_sd_stop_clock(); | 629 | jz_sd_stop_clock(); |
943 | 630 | ||
944 | if (sd2_0) | 631 | /* select clock source from CPM */ |
945 | { | 632 | cpm_select_msc_clk(rate); |
946 | __cpm_select_msc_hs_clk(sd); /* select clock source from CPM */ | 633 | |
947 | REG_CPM_CPCCR |= CPM_CPCCR_CE; | 634 | REG_CPM_CPCCR |= CPM_CPCCR_CE; |
948 | clkrt = jz_sd_calc_clkrt(sd, rate); | 635 | clkrt = jz_sd_calc_clkrt(rate); |
949 | REG_MSC_CLKRT = clkrt; | 636 | REG_MSC_CLKRT = clkrt; |
950 | } | 637 | |
951 | else | 638 | DEBUG("set clock to %u Hz clkrt=%d", rate, clkrt); |
952 | { | ||
953 | __cpm_select_msc_clk(sd); /* select clock source from CPM */ | ||
954 | REG_CPM_CPCCR |= CPM_CPCCR_CE; | ||
955 | clkrt = jz_sd_calc_clkrt(sd, rate); | ||
956 | REG_MSC_CLKRT = clkrt; | ||
957 | } | ||
958 | |||
959 | DEBUG("set clock to %u Hz is_sd=%d clkrt=%d", rate, sd, clkrt); | ||
960 | } | 639 | } |
961 | 640 | ||
962 | /******************************************************************************************************************** | 641 | /******************************************************************************************************************** |
@@ -981,7 +660,7 @@ static int jz_sd_exec_cmd(struct sd_request *request) | |||
981 | __msc_reset(); | 660 | __msc_reset(); |
982 | 661 | ||
983 | /* On reset, drop SD clock down */ | 662 | /* On reset, drop SD clock down */ |
984 | jz_sd_set_clock(1, MMC_CLOCK_SLOW); | 663 | jz_sd_set_clock(MMC_CLOCK_SLOW); |
985 | 664 | ||
986 | /* On reset, stop SD clock */ | 665 | /* On reset, stop SD clock */ |
987 | jz_sd_stop_clock(); | 666 | jz_sd_stop_clock(); |
@@ -1318,49 +997,6 @@ static void sd_simple_cmd(struct sd_request *request, int cmd, unsigned int arg, | |||
1318 | sd_send_cmd(request, cmd, arg, 0, 0, rtype, NULL); | 997 | sd_send_cmd(request, cmd, arg, 0, 0, rtype, NULL); |
1319 | } | 998 | } |
1320 | 999 | ||
1321 | #define KBPS 1 | ||
1322 | #define MBPS 1000 | ||
1323 | static unsigned int ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 }; | ||
1324 | static unsigned int ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000, | ||
1325 | 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 }; | ||
1326 | |||
1327 | unsigned int sd_tran_speed(unsigned char ts) | ||
1328 | { | ||
1329 | unsigned int rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3]; | ||
1330 | |||
1331 | if (rate <= 0) | ||
1332 | { | ||
1333 | DEBUG("sd_tran_speed: error - unrecognized speed 0x%02x", ts); | ||
1334 | return 1; | ||
1335 | } | ||
1336 | |||
1337 | return rate; | ||
1338 | } | ||
1339 | |||
1340 | static void sd_configure_card(void) | ||
1341 | { | ||
1342 | unsigned int rate; | ||
1343 | |||
1344 | /* Get card info */ | ||
1345 | if (sd2_0) | ||
1346 | sdinfo.block_num = (sdinfo.csd.c_size + 1) << 10; | ||
1347 | else | ||
1348 | sdinfo.block_num = (sdinfo.csd.c_size + 1) * (1 << (sdinfo.csd.c_size_mult + 2)); | ||
1349 | |||
1350 | sdinfo.block_len = 1 << sdinfo.csd.read_bl_len; | ||
1351 | |||
1352 | /* Fix the clock rate */ | ||
1353 | rate = sd_tran_speed(sdinfo.csd.tran_speed); | ||
1354 | if (rate < MMC_CLOCK_SLOW) | ||
1355 | rate = MMC_CLOCK_SLOW; | ||
1356 | if (rate > SD_CLOCK_FAST) | ||
1357 | rate = SD_CLOCK_FAST; | ||
1358 | |||
1359 | DEBUG("sd_configure_card: block_len=%d block_num=%d rate=%d", sdinfo.block_len, sdinfo.block_num, rate); | ||
1360 | |||
1361 | jz_sd_set_clock(1, rate); | ||
1362 | } | ||
1363 | |||
1364 | #define SD_INIT_DOING 0 | 1000 | #define SD_INIT_DOING 0 |
1365 | #define SD_INIT_PASSED 1 | 1001 | #define SD_INIT_PASSED 1 |
1366 | #define SD_INIT_FAILED 2 | 1002 | #define SD_INIT_FAILED 2 |
@@ -1369,9 +1005,7 @@ static int sd_init_card_state(struct sd_request *request) | |||
1369 | { | 1005 | { |
1370 | struct sd_response_r1 r1; | 1006 | struct sd_response_r1 r1; |
1371 | struct sd_response_r3 r3; | 1007 | struct sd_response_r3 r3; |
1372 | int retval; | 1008 | int retval, i, ocr = 0x40300000, limit_41 = 0; |
1373 | int ocr = 0x40300000; | ||
1374 | int limit_41 = 0; | ||
1375 | 1009 | ||
1376 | switch (request->cmd) | 1010 | switch (request->cmd) |
1377 | { | 1011 | { |
@@ -1409,7 +1043,7 @@ static int sd_init_card_state(struct sd_request *request) | |||
1409 | } | 1043 | } |
1410 | 1044 | ||
1411 | DEBUG("sd_init_card_state: read ocr value = 0x%08x", r3.ocr); | 1045 | DEBUG("sd_init_card_state: read ocr value = 0x%08x", r3.ocr); |
1412 | sdinfo.ocr = r3.ocr; | 1046 | card.ocr = r3.ocr; |
1413 | 1047 | ||
1414 | if(!(r3.ocr & SD_CARD_BUSY || ocr == 0)){ | 1048 | if(!(r3.ocr & SD_CARD_BUSY || ocr == 0)){ |
1415 | udelay(10000); | 1049 | udelay(10000); |
@@ -1423,21 +1057,18 @@ static int sd_init_card_state(struct sd_request *request) | |||
1423 | } | 1057 | } |
1424 | break; | 1058 | break; |
1425 | 1059 | ||
1426 | case SD_ALL_SEND_CID: | 1060 | case SD_ALL_SEND_CID: |
1427 | retval = sd_unpack_cid( request, &sdinfo.cid ); | 1061 | for(i=0; i<4; i++) |
1428 | 1062 | card.cid[i] = ((request->response[1+i*4]<<24) | (request->response[2+i*4]<<16) | | |
1429 | if ( retval && (retval != SD_ERROR_CRC)) { | 1063 | (request->response[3+i*4]<< 8) | request->response[4+i*4]); |
1430 | DEBUG("sd_init_card_state: unable to ALL_SEND_CID error=%d", | 1064 | |
1431 | retval); | 1065 | logf("CID: %08lx%08lx%08lx%08lx", card.cid[0], card.cid[1], card.cid[2], card.cid[3]); |
1432 | return SD_INIT_FAILED; | ||
1433 | } | ||
1434 | sd_simple_cmd(request, SD_SEND_RELATIVE_ADDR, 0, RESPONSE_R6); | 1066 | sd_simple_cmd(request, SD_SEND_RELATIVE_ADDR, 0, RESPONSE_R6); |
1435 | break; | 1067 | break; |
1436 | |||
1437 | case SD_SEND_RELATIVE_ADDR: | 1068 | case SD_SEND_RELATIVE_ADDR: |
1438 | retval = sd_unpack_r6(request, &r1, &sdinfo.rca); | 1069 | retval = sd_unpack_r6(request, &r1, &card.rca); |
1439 | sdinfo.rca = sdinfo.rca << 16; | 1070 | card.rca = card.rca << 16; |
1440 | DEBUG("sd_init_card_state: Get RCA from SD: 0x%04x Status: %x", sdinfo.rca, r1.status); | 1071 | DEBUG("sd_init_card_state: Get RCA from SD: 0x%04x Status: %x", card.rca, r1.status); |
1441 | if (retval) | 1072 | if (retval) |
1442 | { | 1073 | { |
1443 | DEBUG("sd_init_card_state: unable to SET_RELATIVE_ADDR error=%d", | 1074 | DEBUG("sd_init_card_state: unable to SET_RELATIVE_ADDR error=%d", |
@@ -1445,24 +1076,21 @@ static int sd_init_card_state(struct sd_request *request) | |||
1445 | return SD_INIT_FAILED; | 1076 | return SD_INIT_FAILED; |
1446 | } | 1077 | } |
1447 | 1078 | ||
1448 | sd_simple_cmd(request, SD_SEND_CSD, sdinfo.rca, RESPONSE_R2_CSD); | 1079 | sd_simple_cmd(request, SD_SEND_CSD, card.rca, RESPONSE_R2_CSD); |
1449 | break; | 1080 | break; |
1450 | 1081 | ||
1451 | case SD_SEND_CSD: | 1082 | case SD_SEND_CSD: |
1452 | retval = sd_unpack_csd(request, &sdinfo.csd); | 1083 | for(i=0; i<4; i++) |
1084 | card.csd[i] = ((request->response[1+i*4]<<24) | (request->response[2+i*4]<<16) | | ||
1085 | (request->response[3+i*4]<< 8) | request->response[4+i*4]); | ||
1086 | |||
1087 | sd_parse_csd(&card); | ||
1088 | sd2_0 = (card_extract_bits(card.csd, 127, 2) == 1); | ||
1453 | 1089 | ||
1090 | logf("CSD: %08lx%08lx%08lx%08lx", card.csd[0], card.csd[1], card.csd[2], card.csd[3]); | ||
1454 | DEBUG("SD card is ready"); | 1091 | DEBUG("SD card is ready"); |
1455 | 1092 | jz_sd_set_clock(SD_CLOCK_FAST); | |
1456 | /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */ | ||
1457 | if (retval && (retval != SD_ERROR_CRC)) | ||
1458 | { | ||
1459 | DEBUG("sd_init_card_state: unable to SEND_CSD error=%d", | ||
1460 | retval); | ||
1461 | return SD_INIT_FAILED; | ||
1462 | } | ||
1463 | sd_configure_card(); | ||
1464 | return SD_INIT_PASSED; | 1093 | return SD_INIT_PASSED; |
1465 | |||
1466 | default: | 1094 | default: |
1467 | DEBUG("sd_init_card_state: error! Illegal last cmd %d", request->cmd); | 1095 | DEBUG("sd_init_card_state: error! Illegal last cmd %d", request->cmd); |
1468 | return SD_INIT_FAILED; | 1096 | return SD_INIT_FAILED; |
@@ -1471,7 +1099,7 @@ static int sd_init_card_state(struct sd_request *request) | |||
1471 | return SD_INIT_DOING; | 1099 | return SD_INIT_DOING; |
1472 | } | 1100 | } |
1473 | 1101 | ||
1474 | static int sd_sd_switch(struct sd_request *request, int mode, int group, | 1102 | static int sd_switch(struct sd_request *request, int mode, int group, |
1475 | unsigned char value, unsigned char * resp) | 1103 | unsigned char value, unsigned char * resp) |
1476 | { | 1104 | { |
1477 | unsigned int arg; | 1105 | unsigned int arg; |
@@ -1494,7 +1122,7 @@ static int sd_read_switch(struct sd_request *request) | |||
1494 | unsigned int status[64 / 4]; | 1122 | unsigned int status[64 / 4]; |
1495 | 1123 | ||
1496 | memset((unsigned char *)status, 0, 64); | 1124 | memset((unsigned char *)status, 0, 64); |
1497 | sd_sd_switch(request, 0, 0, 1, (unsigned char*) status); | 1125 | sd_switch(request, 0, 0, 1, (unsigned char*) status); |
1498 | 1126 | ||
1499 | if (((unsigned char *)status)[13] & 0x02) | 1127 | if (((unsigned char *)status)[13] & 0x02) |
1500 | return 0; | 1128 | return 0; |
@@ -1509,7 +1137,7 @@ static int sd_switch_hs(struct sd_request *request) | |||
1509 | { | 1137 | { |
1510 | unsigned int status[64 / 4]; | 1138 | unsigned int status[64 / 4]; |
1511 | 1139 | ||
1512 | sd_sd_switch(request, 1, 0, 1, (unsigned char*) status); | 1140 | sd_switch(request, 1, 0, 1, (unsigned char*) status); |
1513 | return 0; | 1141 | return 0; |
1514 | } | 1142 | } |
1515 | 1143 | ||
@@ -1519,7 +1147,7 @@ int sd_select_card(void) | |||
1519 | struct sd_response_r1 r1; | 1147 | struct sd_response_r1 r1; |
1520 | int retval; | 1148 | int retval; |
1521 | 1149 | ||
1522 | sd_simple_cmd(&request, SD_SELECT_CARD, sdinfo.rca, | 1150 | sd_simple_cmd(&request, SD_SELECT_CARD, card.rca, |
1523 | RESPONSE_R1B); | 1151 | RESPONSE_R1B); |
1524 | retval = sd_unpack_r1(&request, &r1); | 1152 | retval = sd_unpack_r1(&request, &r1); |
1525 | if (retval) | 1153 | if (retval) |
@@ -1531,11 +1159,11 @@ int sd_select_card(void) | |||
1531 | if (!retval) | 1159 | if (!retval) |
1532 | { | 1160 | { |
1533 | sd_switch_hs(&request); | 1161 | sd_switch_hs(&request); |
1534 | jz_sd_set_clock(1, SD_CLOCK_HIGH); | 1162 | jz_sd_set_clock(SD_CLOCK_HIGH); |
1535 | } | 1163 | } |
1536 | } | 1164 | } |
1537 | num_6 = 3; | 1165 | num_6 = 3; |
1538 | sd_simple_cmd(&request, SD_APP_CMD, sdinfo.rca, | 1166 | sd_simple_cmd(&request, SD_APP_CMD, card.rca, |
1539 | RESPONSE_R1); | 1167 | RESPONSE_R1); |
1540 | retval = sd_unpack_r1(&request, &r1); | 1168 | retval = sd_unpack_r1(&request, &r1); |
1541 | if (retval) | 1169 | if (retval) |
@@ -1591,34 +1219,9 @@ void card_enable_monitoring_target(bool on) | |||
1591 | } | 1219 | } |
1592 | #endif | 1220 | #endif |
1593 | 1221 | ||
1594 | /* TODO */ | ||
1595 | tCardInfo* card_get_info_target(int card_no) | 1222 | tCardInfo* card_get_info_target(int card_no) |
1596 | { | 1223 | { |
1597 | (void)card_no; | 1224 | (void)card_no; |
1598 | int i, temp; | ||
1599 | static tCardInfo card; | ||
1600 | |||
1601 | static const unsigned char sd_mantissa[] = { /* *10 */ | ||
1602 | 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; | ||
1603 | static const unsigned int sd_exponent[] = { /* use varies */ | ||
1604 | 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 }; | ||
1605 | |||
1606 | card.initialized = true; | ||
1607 | card.ocr = sdinfo.ocr; | ||
1608 | for(i=0; i<4; i++) | ||
1609 | card.csd[i] = ((unsigned long*)&sdinfo.csd)[i]; | ||
1610 | for(i=0; i<4; i++) | ||
1611 | card.cid[i] = ((unsigned long*)&sdinfo.cid)[i]; | ||
1612 | temp = card_extract_bits(card.csd, 98, 3); | ||
1613 | card.speed = sd_mantissa[card_extract_bits(card.csd, 102, 4)] | ||
1614 | * sd_exponent[temp > 2 ? 7 : temp + 4]; | ||
1615 | card.nsac = 100 * card_extract_bits(card.csd, 111, 8); | ||
1616 | temp = card_extract_bits(card.csd, 114, 3); | ||
1617 | card.taac = sd_mantissa[card_extract_bits(card.csd, 118, 4)] | ||
1618 | * sd_exponent[temp] / 10; | ||
1619 | card.numblocks = sdinfo.block_num; | ||
1620 | card.blocksize = sdinfo.block_len; | ||
1621 | |||
1622 | return &card; | 1225 | return &card; |
1623 | } | 1226 | } |
1624 | 1227 | ||
@@ -1633,10 +1236,10 @@ int sd_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf | |||
1633 | struct sd_response_r1 r1; | 1236 | struct sd_response_r1 r1; |
1634 | int retval; | 1237 | int retval; |
1635 | 1238 | ||
1636 | if (!card_detect_target() || count == 0 || start > sdinfo.block_num) | 1239 | if (!card_detect_target() || count == 0 || start > card.numblocks) |
1637 | return -1; | 1240 | return -1; |
1638 | 1241 | ||
1639 | sd_simple_cmd(&request, SD_SEND_STATUS, sdinfo.rca, RESPONSE_R1); | 1242 | sd_simple_cmd(&request, SD_SEND_STATUS, card.rca, RESPONSE_R1); |
1640 | retval = sd_unpack_r1(&request, &r1); | 1243 | retval = sd_unpack_r1(&request, &r1); |
1641 | if (retval && (retval != SD_ERROR_STATE_MISMATCH)) | 1244 | if (retval && (retval != SD_ERROR_STATE_MISMATCH)) |
1642 | return retval; | 1245 | return retval; |
@@ -1683,10 +1286,10 @@ int sd_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const vo | |||
1683 | struct sd_response_r1 r1; | 1286 | struct sd_response_r1 r1; |
1684 | int retval; | 1287 | int retval; |
1685 | 1288 | ||
1686 | if (!card_detect_target() || count == 0 || start > sdinfo.block_num) | 1289 | if (!card_detect_target() || count == 0 || start > card.numblocks) |
1687 | return -1; | 1290 | return -1; |
1688 | 1291 | ||
1689 | sd_simple_cmd(&request, SD_SEND_STATUS, sdinfo.rca, RESPONSE_R1); | 1292 | sd_simple_cmd(&request, SD_SEND_STATUS, card.rca, RESPONSE_R1); |
1690 | retval = sd_unpack_r1(&request, &r1); | 1293 | retval = sd_unpack_r1(&request, &r1); |
1691 | if (retval && (retval != SD_ERROR_STATE_MISMATCH)) | 1294 | if (retval && (retval != SD_ERROR_STATE_MISMATCH)) |
1692 | return retval; | 1295 | return retval; |
@@ -1741,5 +1344,5 @@ bool sd_present(IF_MV_NONVOID(int drive)) | |||
1741 | #ifdef HAVE_MULTIVOLUME | 1344 | #ifdef HAVE_MULTIVOLUME |
1742 | (void)drive; | 1345 | (void)drive; |
1743 | #endif | 1346 | #endif |
1744 | return (sdinfo.block_num > 0 && card_detect_target()); | 1347 | return (card.numblocks > 0 && card_detect_target()); |
1745 | } | 1348 | } |