aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2008-08-31 11:22:46 -0400
committerPierre Ossman <drzeus@drzeus.cx>2008-10-12 05:04:34 -0400
commitd16f57700475f670ca2828c150a34fa7102a05fc (patch)
tree81d7e341fb4cdeb17b2ba2beddd5bc7b5d5dbd46 /drivers/mmc/core
parent08846698703dedae6c6915eb4b4d0a36188c5635 (diff)
sdio: high-speed support
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/sdio.c52
1 files changed, 49 insertions, 3 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 4eab79e09ccc..fb99ccff9080 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -165,6 +165,36 @@ static int sdio_enable_wide(struct mmc_card *card)
165} 165}
166 166
167/* 167/*
168 * Test if the card supports high-speed mode and, if so, switch to it.
169 */
170static int sdio_enable_hs(struct mmc_card *card)
171{
172 int ret;
173 u8 speed;
174
175 if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
176 return 0;
177
178 if (!card->cccr.high_speed)
179 return 0;
180
181 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
182 if (ret)
183 return ret;
184
185 speed |= SDIO_SPEED_EHS;
186
187 ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
188 if (ret)
189 return ret;
190
191 mmc_card_set_highspeed(card);
192 mmc_set_timing(card->host, MMC_TIMING_SD_HS);
193
194 return 0;
195}
196
197/*
168 * Host is being removed. Free up the current card. 198 * Host is being removed. Free up the current card.
169 */ 199 */
170static void mmc_sdio_remove(struct mmc_host *host) 200static void mmc_sdio_remove(struct mmc_host *host)
@@ -333,10 +363,26 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
333 goto remove; 363 goto remove;
334 364
335 /* 365 /*
336 * No support for high-speed yet, so just set 366 * Switch to high-speed (if supported).
337 * the card's maximum speed.
338 */ 367 */
339 mmc_set_clock(host, card->cis.max_dtr); 368 err = sdio_enable_hs(card);
369 if (err)
370 goto remove;
371
372 /*
373 * Change to the card's maximum speed.
374 */
375 if (mmc_card_highspeed(card)) {
376 /*
377 * The SDIO specification doesn't mention how
378 * the CIS transfer speed register relates to
379 * high-speed, but it seems that 50 MHz is
380 * mandatory.
381 */
382 mmc_set_clock(host, 50000000);
383 } else {
384 mmc_set_clock(host, card->cis.max_dtr);
385 }
340 386
341 /* 387 /*
342 * Switch to wider bus (if supported). 388 * Switch to wider bus (if supported).