@@ -160,9 +160,7 @@ static int sdio_enable_wide(struct mmc_card *card)
160
160
if (ret )
161
161
return ret ;
162
162
163
- mmc_set_bus_width (card -> host , MMC_BUS_WIDTH_4 );
164
-
165
- return 0 ;
163
+ return 1 ;
166
164
}
167
165
168
166
/*
@@ -222,10 +220,34 @@ static int sdio_disable_wide(struct mmc_card *card)
222
220
return 0 ;
223
221
}
224
222
223
+
224
+ static int sdio_enable_4bit_bus (struct mmc_card * card )
225
+ {
226
+ int err ;
227
+
228
+ if (card -> type == MMC_TYPE_SDIO )
229
+ return sdio_enable_wide (card );
230
+
231
+ if ((card -> host -> caps & MMC_CAP_4_BIT_DATA ) &&
232
+ (card -> scr .bus_widths & SD_SCR_BUS_WIDTH_4 )) {
233
+ err = mmc_app_set_bus_width (card , MMC_BUS_WIDTH_4 );
234
+ if (err )
235
+ return err ;
236
+ } else
237
+ return 0 ;
238
+
239
+ err = sdio_enable_wide (card );
240
+ if (err <= 0 )
241
+ mmc_app_set_bus_width (card , MMC_BUS_WIDTH_1 );
242
+
243
+ return err ;
244
+ }
245
+
246
+
225
247
/*
226
248
* Test if the card supports high-speed mode and, if so, switch to it.
227
249
*/
228
- static int sdio_enable_hs (struct mmc_card * card )
250
+ static int mmc_sdio_switch_hs (struct mmc_card * card , int enable )
229
251
{
230
252
int ret ;
231
253
u8 speed ;
@@ -240,7 +262,10 @@ static int sdio_enable_hs(struct mmc_card *card)
240
262
if (ret )
241
263
return ret ;
242
264
243
- speed |= SDIO_SPEED_EHS ;
265
+ if (enable )
266
+ speed |= SDIO_SPEED_EHS ;
267
+ else
268
+ speed &= ~SDIO_SPEED_EHS ;
244
269
245
270
ret = mmc_io_rw_direct (card , 1 , 0 , SDIO_CCCR_SPEED , speed , NULL );
246
271
if (ret )
@@ -249,6 +274,24 @@ static int sdio_enable_hs(struct mmc_card *card)
249
274
return 1 ;
250
275
}
251
276
277
+ /*
278
+ * Enable SDIO/combo card's high-speed mode. Return 0/1 if [not]supported.
279
+ */
280
+ static int sdio_enable_hs (struct mmc_card * card )
281
+ {
282
+ int ret ;
283
+
284
+ ret = mmc_sdio_switch_hs (card , true);
285
+ if (ret <= 0 || card -> type == MMC_TYPE_SDIO )
286
+ return ret ;
287
+
288
+ ret = mmc_sd_switch_hs (card );
289
+ if (ret <= 0 )
290
+ mmc_sdio_switch_hs (card , false);
291
+
292
+ return ret ;
293
+ }
294
+
252
295
static unsigned mmc_sdio_get_max_clock (struct mmc_card * card )
253
296
{
254
297
unsigned max_dtr ;
@@ -265,6 +308,9 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card)
265
308
max_dtr = card -> cis .max_dtr ;
266
309
}
267
310
311
+ if (card -> type == MMC_TYPE_SD_COMBO )
312
+ max_dtr = min (max_dtr , mmc_sd_get_max_clock (card ));
313
+
268
314
return max_dtr ;
269
315
}
270
316
@@ -310,7 +356,24 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
310
356
goto err ;
311
357
}
312
358
313
- card -> type = MMC_TYPE_SDIO ;
359
+ err = mmc_sd_get_cid (host , host -> ocr & ocr , card -> raw_cid );
360
+
361
+ if (!err ) {
362
+ card -> type = MMC_TYPE_SD_COMBO ;
363
+
364
+ if (oldcard && (oldcard -> type != MMC_TYPE_SD_COMBO ||
365
+ memcmp (card -> raw_cid , oldcard -> raw_cid , sizeof (card -> raw_cid )) != 0 )) {
366
+ mmc_remove_card (card );
367
+ return - ENOENT ;
368
+ }
369
+ } else {
370
+ card -> type = MMC_TYPE_SDIO ;
371
+
372
+ if (oldcard && oldcard -> type != MMC_TYPE_SDIO ) {
373
+ mmc_remove_card (card );
374
+ return - ENOENT ;
375
+ }
376
+ }
314
377
315
378
/*
316
379
* Call the optional HC's init_card function to handle quirks.
@@ -329,6 +392,17 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
329
392
mmc_set_bus_mode (host , MMC_BUSMODE_PUSHPULL );
330
393
}
331
394
395
+ /*
396
+ * Read CSD, before selecting the card
397
+ */
398
+ if (!oldcard && card -> type == MMC_TYPE_SD_COMBO ) {
399
+ err = mmc_sd_get_csd (host , card );
400
+ if (err )
401
+ return err ;
402
+
403
+ mmc_decode_cid (card );
404
+ }
405
+
332
406
/*
333
407
* Select card, as all following commands rely on that.
334
408
*/
@@ -356,14 +430,33 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
356
430
int same = (card -> cis .vendor == oldcard -> cis .vendor &&
357
431
card -> cis .device == oldcard -> cis .device );
358
432
mmc_remove_card (card );
359
- if (!same ) {
360
- err = - ENOENT ;
361
- goto err ;
362
- }
433
+ if (!same )
434
+ return - ENOENT ;
435
+
363
436
card = oldcard ;
364
437
return 0 ;
365
438
}
366
439
440
+ if (card -> type == MMC_TYPE_SD_COMBO ) {
441
+ err = mmc_sd_setup_card (host , card , oldcard != NULL );
442
+ /* handle as SDIO-only card if memory init failed */
443
+ if (err ) {
444
+ mmc_go_idle (host );
445
+ if (mmc_host_is_spi (host ))
446
+ /* should not fail, as it worked previously */
447
+ mmc_spi_set_crc (host , use_spi_crc );
448
+ card -> type = MMC_TYPE_SDIO ;
449
+ } else
450
+ card -> dev .type = & sd_type ;
451
+ }
452
+
453
+ /*
454
+ * If needed, disconnect card detection pull-up resistor.
455
+ */
456
+ err = sdio_disable_cd (card );
457
+ if (err )
458
+ goto remove ;
459
+
367
460
/*
368
461
* Switch to high-speed (if supported).
369
462
*/
@@ -381,8 +474,10 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
381
474
/*
382
475
* Switch to wider bus (if supported).
383
476
*/
384
- err = sdio_enable_wide (card );
385
- if (err )
477
+ err = sdio_enable_4bit_bus (card );
478
+ if (err > 0 )
479
+ mmc_set_bus_width (card -> host , MMC_BUS_WIDTH_4 );
480
+ else if (err )
386
481
goto remove ;
387
482
388
483
if (!oldcard )
@@ -496,9 +591,14 @@ static int mmc_sdio_resume(struct mmc_host *host)
496
591
mmc_claim_host (host );
497
592
err = mmc_sdio_init_card (host , host -> ocr , host -> card ,
498
593
(host -> pm_flags & MMC_PM_KEEP_POWER ));
499
- if (!err )
594
+ if (!err ) {
500
595
/* We may have switched to 1-bit mode during suspend. */
501
- err = sdio_enable_wide (host -> card );
596
+ err = sdio_enable_4bit_bus (host -> card );
597
+ if (err > 0 ) {
598
+ mmc_set_bus_width (host , MMC_BUS_WIDTH_4 );
599
+ err = 0 ;
600
+ }
601
+ }
502
602
if (!err && host -> sdio_irqs )
503
603
mmc_signal_sdio_irq (host );
504
604
mmc_release_host (host );
@@ -582,13 +682,6 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
582
682
funcs = (ocr & 0x70000000 ) >> 28 ;
583
683
card -> sdio_funcs = 0 ;
584
684
585
- /*
586
- * If needed, disconnect card detection pull-up resistor.
587
- */
588
- err = sdio_disable_cd (card );
589
- if (err )
590
- goto remove ;
591
-
592
685
/*
593
686
* Initialize (but don't add) all present functions.
594
687
*/
0 commit comments