Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 65604
b: refs/heads/master
c: fa64efa
h: refs/heads/master
v: v3
  • Loading branch information
Pierre Ossman committed Sep 23, 2007
1 parent ef60339 commit fb10868
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 46f555f2731a14545a09ec06d27bd18e8e07069f
refs/heads/master: fa64efa1f2a0672767ad0753a6e4bfa4bcc77b87
93 changes: 93 additions & 0 deletions trunk/drivers/mmc/core/sdio_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -47,6 +48,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
Expand Down
92 changes: 92 additions & 0 deletions trunk/include/linux/mmc/sdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

3 changes: 3 additions & 0 deletions trunk/include/linux/mmc/sdio_func.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit fb10868

Please sign in to comment.