diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2008-08-31 11:22:46 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2008-10-12 05:04:34 -0400 |
commit | d16f57700475f670ca2828c150a34fa7102a05fc (patch) | |
tree | 81d7e341fb4cdeb17b2ba2beddd5bc7b5d5dbd46 /drivers/mmc | |
parent | 08846698703dedae6c6915eb4b4d0a36188c5635 (diff) |
sdio: high-speed support
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/sdio.c | 52 |
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 | */ | ||
170 | static 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 | */ |
170 | static void mmc_sdio_remove(struct mmc_host *host) | 200 | static 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). |