Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=35c66c19088bddb11110c124bad8abd4441a8421
Commit:     35c66c19088bddb11110c124bad8abd4441a8421
Parent:     fa64efa1f2a0672767ad0753a6e4bfa4bcc77b87
Author:     Pierre Ossman <[EMAIL PROTECTED]>
AuthorDate: Mon Jun 11 20:25:43 2007 +0200
Committer:  Pierre Ossman <[EMAIL PROTECTED]>
CommitDate: Sun Sep 23 20:12:18 2007 +0200

    sdio: read and decode interesting parts of the CCCR
    
    Signed-off-by: Pierre Ossman <[EMAIL PROTECTED]>
---
 drivers/mmc/core/sdio.c  |   63 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mmc/card.h |   11 ++++++++
 2 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 4443285..7ce3e31 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -13,6 +13,7 @@
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
 
 #include "core.h"
@@ -39,6 +40,61 @@ static int sdio_init_func(struct mmc_card *card, unsigned 
int fn)
        return 0;
 }
 
+static int sdio_read_cccr(struct mmc_card *card)
+{
+       int ret;
+       int cccr_vsn;
+       unsigned char data;
+
+       memset(&card->cccr, 0, sizeof(struct sdio_cccr));
+
+       ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, 0, &data);
+       if (ret)
+               goto out;
+
+       cccr_vsn = data & 0x0f;
+
+       if (cccr_vsn > SDIO_CCCR_REV_1_20) {
+               printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n",
+                       mmc_hostname(card->host), cccr_vsn);
+               return -EINVAL;
+       }
+
+       card->cccr.sdio_vsn = (data & 0xf0) >> 4;
+
+       ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CAPS, 0, &data);
+       if (ret)
+               goto out;
+
+       if (data & SDIO_CCCR_CAP_SMB)
+               card->cccr.multi_block = 1;
+       if (data & SDIO_CCCR_CAP_LSC)
+               card->cccr.low_speed = 1;
+       if (data & SDIO_CCCR_CAP_4BLS)
+               card->cccr.wide_bus = 1;
+
+       if (cccr_vsn >= SDIO_CCCR_REV_1_10) {
+               ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_POWER, 0, &data);
+               if (ret)
+                       goto out;
+
+               if (data & SDIO_POWER_SMPC)
+                       card->cccr.high_power = 1;
+       }
+
+       if (cccr_vsn >= SDIO_CCCR_REV_1_20) {
+               ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data);
+               if (ret)
+                       goto out;
+
+               if (data & SDIO_SPEED_SHS)
+                       card->cccr.high_speed = 1;
+       }
+
+out:
+       return ret;
+}
+
 /*
  * Host is being removed. Free up the current card.
  */
@@ -181,6 +237,13 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
                goto remove;
 
        /*
+        * Read the common registers.
+        */
+       err = sdio_read_cccr(card);
+       if (err)
+               goto remove;
+
+       /*
         * Initialize (but don't add) all present functions.
         */
        for (i = 0;i < funcs;i++) {
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 9f5f744..520d9d2 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -55,6 +55,16 @@ struct sd_switch_caps {
        unsigned int            hs_max_dtr;
 };
 
+struct sdio_cccr {
+       unsigned int            sdio_vsn;
+       unsigned int            sd_vsn;
+       unsigned int            multi_block:1,
+                               low_speed:1,
+                               wide_bus:1,
+                               high_power:1,
+                               high_speed:1;
+};
+
 struct mmc_host;
 struct sdio_func;
 
@@ -87,6 +97,7 @@ struct mmc_card {
        struct sd_switch_caps   sw_caps;        /* switch (CMD6) caps */
 
        unsigned int            sdio_funcs;     /* number of SDIO functions */
+       struct sdio_cccr        cccr;           /* common card info */
        struct sdio_func        *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions 
(devices) */
 };
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to