Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=fa64efa1f2a0672767ad0753a6e4bfa4bcc77b87
Commit:     fa64efa1f2a0672767ad0753a6e4bfa4bcc77b87
Parent:     46f555f2731a14545a09ec06d27bd18e8e07069f
Author:     Pierre Ossman <[EMAIL PROTECTED]>
AuthorDate: Sun May 27 14:22:37 2007 +0200
Committer:  Pierre Ossman <[EMAIL PROTECTED]>
CommitDate: Sun Sep 23 20:10:56 2007 +0200

    mmc: enable/disable functions for SDIO
    
    Like many other buses, the devices (functions) on the SDIO bus
    must be enabled before they can be used. Add functions that allow
    drivers to do so.
    
    Signed-off-by: Pierre Ossman <[EMAIL PROTECTED]>
---
 drivers/mmc/core/sdio_io.c    |   93 +++++++++++++++++++++++++++++++++++++++++
 include/linux/mmc/sdio.h      |   92 ++++++++++++++++++++++++++++++++++++++++
 include/linux/mmc/sdio_func.h |    3 +
 3 files changed, 188 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index 4ad06e5..eb6c209 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -11,6 +11,7 @@
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
 
 #include "sdio_ops.h"
@@ -48,6 +49,98 @@ void sdio_release_host(struct sdio_func *func)
 EXPORT_SYMBOL_GPL(sdio_release_host);
 
 /**
+ *     sdio_enable_func - enables a SDIO function for usage
+ *     @func: SDIO function to enable
+ *
+ *     Powers up and activates a SDIO function so that register
+ *     access is possible.
+ */
+int sdio_enable_func(struct sdio_func *func)
+{
+       int ret;
+       unsigned char reg;
+       unsigned long timeout;
+
+       BUG_ON(!func);
+       BUG_ON(!func->card);
+
+       pr_debug("SDIO: Enabling device %s...\n", sdio_func_id(func));
+
+       ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, &reg);
+       if (ret)
+               goto err;
+
+       reg |= 1 << func->num;
+
+       ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
+       if (ret)
+               goto err;
+
+       /*
+        * FIXME: This should timeout based on information in the CIS,
+        * but we don't have card to parse that yet.
+        */
+       timeout = jiffies + HZ;
+
+       while (1) {
+               ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, 
&reg);
+               if (ret)
+                       goto err;
+               if (reg & (1 << func->num))
+                       break;
+               ret = -ETIME;
+               if (time_after(jiffies, timeout))
+                       goto err;
+       }
+
+       pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func));
+
+       return 0;
+
+err:
+       pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func));
+       return ret;
+}
+EXPORT_SYMBOL_GPL(sdio_enable_func);
+
+/**
+ *     sdio_disable_func - disable a SDIO function
+ *     @func: SDIO function to disable
+ *
+ *     Powers down and deactivates a SDIO function. Register access
+ *     to this function will fail until the function is reenabled.
+ */
+int sdio_disable_func(struct sdio_func *func)
+{
+       int ret;
+       unsigned char reg;
+
+       BUG_ON(!func);
+       BUG_ON(!func->card);
+
+       pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func));
+
+       ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, &reg);
+       if (ret)
+               goto err;
+
+       reg &= ~(1 << func->num);
+
+       ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
+       if (ret)
+               goto err;
+
+       pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func));
+
+       return 0;
+
+err:
+       pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func));
+       return -EIO;
+}
+EXPORT_SYMBOL_GPL(sdio_disable_func);
+
+/**
  *     sdio_readb - read a single byte from a SDIO function
  *     @func: SDIO function to access
  *     @addr: address to read
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index e5f06de..56239f4 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -49,5 +49,97 @@
 #define R5_STATUS(x)           (x & 0xCB00)
 #define R5_IO_CURRENT_STATE(x) ((x & 0x3000) >> 12) /* s, b */
 
+/*
+ * Card Common Control Registers (CCCR)
+ */
+
+#define SDIO_CCCR_CCCR         0x00
+
+#define  SDIO_CCCR_REV_1_00    0       /* CCCR/FBR Version 1.00 */
+#define  SDIO_CCCR_REV_1_10    1       /* CCCR/FBR Version 1.10 */
+#define  SDIO_CCCR_REV_1_20    2       /* CCCR/FBR Version 1.20 */
+
+#define  SDIO_SDIO_REV_1_00    0       /* SDIO Spec Version 1.00 */
+#define  SDIO_SDIO_REV_1_10    1       /* SDIO Spec Version 1.10 */
+#define  SDIO_SDIO_REV_1_20    2       /* SDIO Spec Version 1.20 */
+#define  SDIO_SDIO_REV_2_00    3       /* SDIO Spec Version 2.00 */
+
+#define SDIO_CCCR_SD           0x01
+
+#define  SDIO_SD_REV_1_01      0       /* SD Physical Spec Version 1.01 */
+#define  SDIO_SD_REV_1_10      1       /* SD Physical Spec Version 1.10 */
+#define  SDIO_SD_REV_2_00      2       /* SD Physical Spec Version 2.00 */
+
+#define SDIO_CCCR_IOEx         0x02
+#define SDIO_CCCR_IORx         0x03
+
+#define SDIO_CCCR_IENx         0x04    /* Function/Master Interrupt Enable */
+#define SDIO_CCCR_INTx         0x05    /* Function Interrupt Pending */
+
+#define SDIO_CCCR_ABORT                0x06    /* function abort/card reset */
+
+#define SDIO_CCCR_IF           0x07    /* bus interface controls */
+
+#define  SDIO_BUS_WIDTH_1BIT   0x00
+#define  SDIO_BUS_WIDTH_4BIT   0x02
+
+#define  SDIO_BUS_CD_DISABLE     0x80  /* disable pull-up on DAT3 (pin 1) */
+
+#define SDIO_CCCR_CAPS         0x08
+
+#define  SDIO_CCCR_CAP_SDC     0x01    /* can do CMD52 while data transfer */
+#define  SDIO_CCCR_CAP_SMB     0x02    /* can do multi-block xfers (CMD53) */
+#define  SDIO_CCCR_CAP_SRW     0x04    /* supports read-wait protocol */
+#define  SDIO_CCCR_CAP_SBS     0x08    /* supports suspend/resume */
+#define  SDIO_CCCR_CAP_S4MI    0x10    /* interrupt during 4-bit CMD53 */
+#define  SDIO_CCCR_CAP_E4MI    0x20    /* enable ints during 4-bit CMD53 */
+#define  SDIO_CCCR_CAP_LSC     0x40    /* low speed card */
+#define  SDIO_CCCR_CAP_4BLS    0x80    /* 4 bit low speed card */
+
+#define SDIO_CCCR_CIS          0x09    /* common CIS pointer (3 bytes) */
+
+/* Following 4 regs are valid only if SBS is set */
+#define SDIO_CCCR_SUSPEND      0x0c
+#define SDIO_CCCR_SELx         0x0d
+#define SDIO_CCCR_EXECx                0x0e
+#define SDIO_CCCR_READYx       0x0f
+
+#define SDIO_CCCR_BLKSIZE      0x10
+
+#define SDIO_CCCR_POWER                0x12
+
+#define  SDIO_POWER_SMPC       0x01    /* Supports Master Power Control */
+#define  SDIO_POWER_EMPC       0x02    /* Enable Master Power Control */
+
+#define SDIO_CCCR_SPEED                0x13
+
+#define  SDIO_SPEED_SHS                0x01    /* Supports High-Speed mode */
+#define  SDIO_SPEED_EHS                0x02    /* Enable High-Speed mode */
+
+/*
+ * Function Basic Registers (FBR)
+ */
+
+#define SDIO_FBR_STD_IF                0x00
+
+#define  SDIO_FBR_SUPPORTS_CSA 0x40    /* supports Code Storage Area */
+#define  SDIO_FBR_ENABLE_CSA   0x80    /* enable Code Storage Area */
+
+#define SDIO_FBR_STD_IF_EXT    0x01
+
+#define SDIO_FBR_POWER         0x02
+
+#define  SDIO_FBR_POWER_SPS    0x01    /* Supports Power Selection */
+#define  SDIO_FBR_POWER_EPS    0x02    /* Enable (low) Power Selection */
+
+#define SDIO_FBR_CIS           0x09    /* CIS pointer (3 bytes) */
+
+
+#define SDIO_FBR_CSA           0x0C    /* CSA pointer (3 bytes) */
+
+#define SDIO_FBR_CSA_DATA      0x0F
+
+#define SDIO_FBR_BLKSIZE       0x10    /* block size (2 bytes) */
+
 #endif
 
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index 5c56df1..3365fef 100644
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -55,6 +55,9 @@ extern void sdio_unregister_driver(struct sdio_driver *);
 extern void sdio_claim_host(struct sdio_func *func);
 extern void sdio_release_host(struct sdio_func *func);
 
+extern int sdio_enable_func(struct sdio_func *func);
+extern int sdio_disable_func(struct sdio_func *func);
+
 extern unsigned char sdio_readb(struct sdio_func *func,
        unsigned int addr, int *err_ret);
 
-
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