···25612561W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html25622562S: Maintained2563256325642564-MULTIMEDIA CARD (MMC) AND SECURE DIGITAL (SD) SUBSYSTEM25642564+MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM25652565P: Pierre Ossman25662566M: drzeus-mmc@drzeus.cx25672567L: linux-kernel@vger.kernel.org
···3434 return sprintf(buf, "MMC\n");3535 case MMC_TYPE_SD:3636 return sprintf(buf, "SD\n");3737+ case MMC_TYPE_SDIO:3838+ return sprintf(buf, "SDIO\n");3739 default:3840 return -EFAULT;3941 }···7775 break;7876 case MMC_TYPE_SD:7977 add_env("MMC_TYPE=%s", "SD");7878+ break;7979+ case MMC_TYPE_SDIO:8080+ add_env("MMC_TYPE=%s", "SDIO");8081 break;8182 }8283···225220 type = "SD";226221 if (mmc_card_blockaddr(card))227222 type = "SDHC";223223+ break;224224+ case MMC_TYPE_SDIO:225225+ type = "SDIO";228226 break;229227 default:230228 type = "?";
+29-13
drivers/mmc/core/core.c
···32323333#include "mmc_ops.h"3434#include "sd_ops.h"3535+#include "sdio_ops.h"35363637extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr);3738extern int mmc_attach_sd(struct mmc_host *host, u32 ocr);3939+extern int mmc_attach_sdio(struct mmc_host *host, u32 ocr);38403941static struct workqueue_struct *workqueue;4042···597595598596 mmc_send_if_cond(host, host->ocr_avail);599597598598+ /*599599+ * First we search for SDIO...600600+ */601601+ err = mmc_send_io_op_cond(host, 0, &ocr);602602+ if (!err) {603603+ if (mmc_attach_sdio(host, ocr))604604+ mmc_power_off(host);605605+ return;606606+ }607607+608608+ /*609609+ * ...then normal SD...610610+ */600611 err = mmc_send_app_op_cond(host, 0, &ocr);601612 if (!err) {602613 if (mmc_attach_sd(host, ocr))603614 mmc_power_off(host);604604- } else {605605- /*606606- * If we fail to detect any SD cards then try607607- * searching for MMC cards.608608- */609609- err = mmc_send_op_cond(host, 0, &ocr);610610- if (!err) {611611- if (mmc_attach_mmc(host, ocr))612612- mmc_power_off(host);613613- } else {614614- mmc_power_off(host);615615- mmc_release_host(host);616616- }615615+ return;617616 }617617+618618+ /*619619+ * ...and finally MMC.620620+ */621621+ err = mmc_send_op_cond(host, 0, &ocr);622622+ if (!err) {623623+ if (mmc_attach_mmc(host, ocr))624624+ mmc_power_off(host);625625+ return;626626+ }627627+628628+ mmc_release_host(host);629629+ mmc_power_off(host);618630 } else {619631 if (host->bus_ops->detect && !host->bus_dead)620632 host->bus_ops->detect(host);
+176
drivers/mmc/core/sdio.c
···11+/*22+ * linux/drivers/mmc/sdio.c33+ *44+ * Copyright 2006-2007 Pierre Ossman55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License as published by88+ * the Free Software Foundation; either version 2 of the License, or (at99+ * your option) any later version.1010+ */1111+1212+#include <linux/err.h>1313+1414+#include <linux/mmc/host.h>1515+#include <linux/mmc/card.h>1616+1717+#include "core.h"1818+#include "bus.h"1919+#include "mmc_ops.h"2020+#include "sd_ops.h"2121+#include "sdio_ops.h"2222+2323+/*2424+ * Host is being removed. Free up the current card.2525+ */2626+static void mmc_sdio_remove(struct mmc_host *host)2727+{2828+ BUG_ON(!host);2929+ BUG_ON(!host->card);3030+3131+ mmc_remove_card(host->card);3232+ host->card = NULL;3333+}3434+3535+/*3636+ * Card detection callback from host.3737+ */3838+static void mmc_sdio_detect(struct mmc_host *host)3939+{4040+ int err;4141+4242+ BUG_ON(!host);4343+ BUG_ON(!host->card);4444+4545+ mmc_claim_host(host);4646+4747+ /*4848+ * Just check if our card has been removed.4949+ */5050+ err = mmc_select_card(host->card);5151+5252+ mmc_release_host(host);5353+5454+ if (err) {5555+ mmc_sdio_remove(host);5656+5757+ mmc_claim_host(host);5858+ mmc_detach_bus(host);5959+ mmc_release_host(host);6060+ }6161+}6262+6363+6464+static const struct mmc_bus_ops mmc_sdio_ops = {6565+ .remove = mmc_sdio_remove,6666+ .detect = mmc_sdio_detect,6767+};6868+6969+7070+/*7171+ * Starting point for SDIO card init.7272+ */7373+int mmc_attach_sdio(struct mmc_host *host, u32 ocr)7474+{7575+ int err;7676+ int funcs;7777+ struct mmc_card *card;7878+7979+ BUG_ON(!host);8080+ BUG_ON(!host->claimed);8181+8282+ mmc_attach_bus(host, &mmc_sdio_ops);8383+8484+ /*8585+ * Sanity check the voltages that the card claims to8686+ * support.8787+ */8888+ if (ocr & 0x7F) {8989+ printk(KERN_WARNING "%s: card claims to support voltages "9090+ "below the defined range. These will be ignored.\n",9191+ mmc_hostname(host));9292+ ocr &= ~0x7F;9393+ }9494+9595+ if (ocr & MMC_VDD_165_195) {9696+ printk(KERN_WARNING "%s: SDIO card claims to support the "9797+ "incompletely defined 'low voltage range'. This "9898+ "will be ignored.\n", mmc_hostname(host));9999+ ocr &= ~MMC_VDD_165_195;100100+ }101101+102102+ host->ocr = mmc_select_voltage(host, ocr);103103+104104+ /*105105+ * Can we support the voltage(s) of the card(s)?106106+ */107107+ if (!host->ocr) {108108+ err = -EINVAL;109109+ goto err;110110+ }111111+112112+ /*113113+ * Inform the card of the voltage114114+ */115115+ err = mmc_send_io_op_cond(host, host->ocr, &ocr);116116+ if (err)117117+ goto err;118118+119119+ /*120120+ * The number of functions on the card is encoded inside121121+ * the ocr.122122+ */123123+ funcs = (ocr & 0x70000000) >> 28;124124+125125+ /*126126+ * Allocate card structure.127127+ */128128+ card = mmc_alloc_card(host);129129+ if (IS_ERR(card)) {130130+ err = PTR_ERR(card);131131+ goto err;132132+ }133133+134134+ card->type = MMC_TYPE_SDIO;135135+136136+ /*137137+ * Set card RCA.138138+ */139139+ err = mmc_send_relative_addr(host, &card->rca);140140+ if (err)141141+ goto free_card;142142+143143+ mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);144144+145145+ /*146146+ * Select card, as all following commands rely on that.147147+ */148148+ err = mmc_select_card(card);149149+ if (err)150150+ goto free_card;151151+152152+ host->card = card;153153+154154+ mmc_release_host(host);155155+156156+ err = mmc_add_card(host->card);157157+ if (err)158158+ goto reclaim_host;159159+160160+ return 0;161161+162162+reclaim_host:163163+ mmc_claim_host(host);164164+free_card:165165+ mmc_remove_card(card);166166+ host->card = NULL;167167+err:168168+ mmc_detach_bus(host);169169+ mmc_release_host(host);170170+171171+ printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n",172172+ mmc_hostname(host), err);173173+174174+ return err;175175+}176176+
+49
drivers/mmc/core/sdio_ops.c
···11+/*22+ * linux/drivers/mmc/sdio_ops.c33+ *44+ * Copyright 2006-2007 Pierre Ossman55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License as published by88+ * the Free Software Foundation; either version 2 of the License, or (at99+ * your option) any later version.1010+ */1111+1212+#include <linux/mmc/host.h>1313+#include <linux/mmc/mmc.h>1414+#include <linux/mmc/sdio.h>1515+1616+#include "core.h"1717+1818+int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)1919+{2020+ struct mmc_command cmd;2121+ int i, err = 0;2222+2323+ BUG_ON(!host);2424+2525+ memset(&cmd, 0, sizeof(struct mmc_command));2626+2727+ cmd.opcode = SD_IO_SEND_OP_COND;2828+ cmd.arg = ocr;2929+ cmd.flags = MMC_RSP_R4 | MMC_CMD_BCR;3030+3131+ for (i = 100; i; i--) {3232+ err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);3333+ if (err)3434+ break;3535+3636+ if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)3737+ break;3838+3939+ err = -ETIMEDOUT;4040+4141+ mmc_delay(10);4242+ }4343+4444+ if (rocr)4545+ *rocr = cmd.resp[0];4646+4747+ return err;4848+}4949+
+18
drivers/mmc/core/sdio_ops.h
···11+/*22+ * linux/drivers/mmc/sdio_ops.c33+ *44+ * Copyright 2006-2007 Pierre Ossman55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License as published by88+ * the Free Software Foundation; either version 2 of the License, or (at99+ * your option) any later version.1010+ */1111+1212+#ifndef _MMC_SDIO_OPS_H1313+#define _MMC_SDIO_OPS_H1414+1515+int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr);1616+1717+#endif1818+
···11+/*22+ * include/linux/mmc/sdio.h33+ *44+ * Copyright 2006-2007 Pierre Ossman55+ *66+ * This program is free software; you can redistribute it and/or modify77+ * it under the terms of the GNU General Public License as published by88+ * the Free Software Foundation; either version 2 of the License, or (at99+ * your option) any later version.1010+ */1111+1212+#ifndef MMC_SDIO_H1313+#define MMC_SDIO_H1414+1515+/* SDIO commands type argument response */1616+#define SD_IO_SEND_OP_COND 5 /* bcr [23:0] OCR R4 */1717+1818+#endif1919+