linux/drivers/mmc/core/sdio_io.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/mmc/core/sdio_io.c
   3 *
   4 *  Copyright 2007 Pierre Ossman
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or (at
   9 * your option) any later version.
  10 */
  11
  12#include <linux/mmc/host.h>
  13#include <linux/mmc/card.h>
  14#include <linux/mmc/sdio.h>
  15#include <linux/mmc/sdio_func.h>
  16
  17#include "sdio_ops.h"
  18
  19/**
  20 *      sdio_claim_host - exclusively claim a bus for a certain SDIO function
  21 *      @func: SDIO function that will be accessed
  22 *
  23 *      Claim a bus for a set of operations. The SDIO function given
  24 *      is used to figure out which bus is relevant.
  25 */
  26void sdio_claim_host(struct sdio_func *func)
  27{
  28        BUG_ON(!func);
  29        BUG_ON(!func->card);
  30
  31        mmc_claim_host(func->card->host);
  32}
  33EXPORT_SYMBOL_GPL(sdio_claim_host);
  34
  35/**
  36 *      sdio_release_host - release a bus for a certain SDIO function
  37 *      @func: SDIO function that was accessed
  38 *
  39 *      Release a bus, allowing others to claim the bus for their
  40 *      operations.
  41 */
  42void sdio_release_host(struct sdio_func *func)
  43{
  44        BUG_ON(!func);
  45        BUG_ON(!func->card);
  46
  47        mmc_release_host(func->card->host);
  48}
  49EXPORT_SYMBOL_GPL(sdio_release_host);
  50
  51/**
  52 *      sdio_enable_func - enables a SDIO function for usage
  53 *      @func: SDIO function to enable
  54 *
  55 *      Powers up and activates a SDIO function so that register
  56 *      access is possible.
  57 */
  58int sdio_enable_func(struct sdio_func *func)
  59{
  60        int ret;
  61        unsigned char reg;
  62        unsigned long timeout;
  63
  64        BUG_ON(!func);
  65        BUG_ON(!func->card);
  66
  67        pr_debug("SDIO: Enabling device %s...\n", sdio_func_id(func));
  68
  69        ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, &reg);
  70        if (ret)
  71                goto err;
  72
  73        reg |= 1 << func->num;
  74
  75        ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
  76        if (ret)
  77                goto err;
  78
  79        /*
  80         * FIXME: This should timeout based on information in the CIS,
  81         * but we don't have card to parse that yet.
  82         */
  83        timeout = jiffies + HZ;
  84
  85        while (1) {
  86                ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, &reg);
  87                if (ret)
  88                        goto err;
  89                if (reg & (1 << func->num))
  90                        break;
  91                ret = -ETIME;
  92                if (time_after(jiffies, timeout))
  93                        goto err;
  94        }
  95
  96        pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func));
  97
  98        return 0;
  99
 100err:
 101        pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func));
 102        return ret;
 103}
 104EXPORT_SYMBOL_GPL(sdio_enable_func);
 105
 106/**
 107 *      sdio_disable_func - disable a SDIO function
 108 *      @func: SDIO function to disable
 109 *
 110 *      Powers down and deactivates a SDIO function. Register access
 111 *      to this function will fail until the function is reenabled.
 112 */
 113int sdio_disable_func(struct sdio_func *func)
 114{
 115        int ret;
 116        unsigned char reg;
 117
 118        BUG_ON(!func);
 119        BUG_ON(!func->card);
 120
 121        pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func));
 122
 123        ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, &reg);
 124        if (ret)
 125                goto err;
 126
 127        reg &= ~(1 << func->num);
 128
 129        ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
 130        if (ret)
 131                goto err;
 132
 133        pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func));
 134
 135        return 0;
 136
 137err:
 138        pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func));
 139        return -EIO;
 140}
 141EXPORT_SYMBOL_GPL(sdio_disable_func);
 142
 143/**
 144 *      sdio_set_block_size - set the block size of an SDIO function
 145 *      @func: SDIO function to change
 146 *      @blksz: new block size or 0 to use the default.
 147 *
 148 *      The default block size is the largest supported by both the function
 149 *      and the host, with a maximum of 512 to ensure that arbitrarily sized
 150 *      data transfer use the optimal (least) number of commands.
 151 *
 152 *      A driver may call this to override the default block size set by the
 153 *      core. This can be used to set a block size greater than the maximum
 154 *      that reported by the card; it is the driver's responsibility to ensure
 155 *      it uses a value that the card supports.
 156 *
 157 *      Returns 0 on success, -EINVAL if the host does not support the
 158 *      requested block size, or -EIO (etc.) if one of the resultant FBR block
 159 *      size register writes failed.
 160 *
 161 */
 162int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
 163{
 164        int ret;
 165
 166        if (blksz > func->card->host->max_blk_size)
 167                return -EINVAL;
 168
 169        if (blksz == 0) {
 170                blksz = min(min(
 171                        func->max_blksize,
 172                        func->card->host->max_blk_size),
 173                        512u);
 174        }
 175
 176        ret = mmc_io_rw_direct(func->card, 1, 0,
 177                SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
 178                blksz & 0xff, NULL);
 179        if (ret)
 180                return ret;
 181        ret = mmc_io_rw_direct(func->card, 1, 0,
 182                SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
 183                (blksz >> 8) & 0xff, NULL);
 184        if (ret)
 185                return ret;
 186        func->cur_blksize = blksz;
 187        return 0;
 188}
 189
 190EXPORT_SYMBOL_GPL(sdio_set_block_size);
 191
 192/* Split an arbitrarily sized data transfer into several
 193 * IO_RW_EXTENDED commands. */
 194static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
 195        unsigned addr, int incr_addr, u8 *buf, unsigned size)
 196{
 197        unsigned remainder = size;
 198        unsigned max_blocks;
 199        int ret;
 200
 201        /* Do the bulk of the transfer using block mode (if supported). */
 202        if (func->card->cccr.multi_block) {
 203                /* Blocks per command is limited by host count, host transfer
 204                 * size (we only use a single sg entry) and the maximum for
 205                 * IO_RW_EXTENDED of 511 blocks. */
 206                max_blocks = min(min(
 207                        func->card->host->max_blk_count,
 208                        func->card->host->max_seg_size / func->cur_blksize),
 209                        511u);
 210
 211                while (remainder > func->cur_blksize) {
 212                        unsigned blocks;
 213
 214                        blocks = remainder / func->cur_blksize;
 215                        if (blocks > max_blocks)
 216                                blocks = max_blocks;
 217                        size = blocks * func->cur_blksize;
 218
 219                        ret = mmc_io_rw_extended(func->card, write,
 220                                func->num, addr, incr_addr, buf,
 221                                blocks, func->cur_blksize);
 222                        if (ret)
 223                                return ret;
 224
 225                        remainder -= size;
 226                        buf += size;
 227                        if (incr_addr)
 228                                addr += size;
 229                }
 230        }
 231
 232        /* Write the remainder using byte mode. */
 233        while (remainder > 0) {
 234                size = remainder;
 235                if (size > func->cur_blksize)
 236                        size = func->cur_blksize;
 237                if (size > 512)
 238                        size = 512; /* maximum size for byte mode */
 239
 240                ret = mmc_io_rw_extended(func->card, write, func->num, addr,
 241                         incr_addr, buf, 1, size);
 242                if (ret)
 243                        return ret;
 244
 245                remainder -= size;
 246                buf += size;
 247                if (incr_addr)
 248                        addr += size;
 249        }
 250        return 0;
 251}
 252
 253/**
 254 *      sdio_readb - read a single byte from a SDIO function
 255 *      @func: SDIO function to access
 256 *      @addr: address to read
 257 *      @err_ret: optional status value from transfer
 258 *
 259 *      Reads a single byte from the address space of a given SDIO
 260 *      function. If there is a problem reading the address, 0xff
 261 *      is returned and @err_ret will contain the error code.
 262 */
 263unsigned char sdio_readb(struct sdio_func *func, unsigned int addr,
 264        int *err_ret)
 265{
 266        int ret;
 267        unsigned char val;
 268
 269        BUG_ON(!func);
 270
 271        if (err_ret)
 272                *err_ret = 0;
 273
 274        ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val);
 275        if (ret) {
 276                if (err_ret)
 277                        *err_ret = ret;
 278                return 0xFF;
 279        }
 280
 281        return val;
 282}
 283EXPORT_SYMBOL_GPL(sdio_readb);
 284
 285/**
 286 *      sdio_writeb - write a single byte to a SDIO function
 287 *      @func: SDIO function to access
 288 *      @b: byte to write
 289 *      @addr: address to write to
 290 *      @err_ret: optional status value from transfer
 291 *
 292 *      Writes a single byte to the address space of a given SDIO
 293 *      function. @err_ret will contain the status of the actual
 294 *      transfer.
 295 */
 296void sdio_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
 297        int *err_ret)
 298{
 299        int ret;
 300
 301        BUG_ON(!func);
 302
 303        ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL);
 304        if (err_ret)
 305                *err_ret = ret;
 306}
 307EXPORT_SYMBOL_GPL(sdio_writeb);
 308
 309/**
 310 *      sdio_memcpy_fromio - read a chunk of memory from a SDIO function
 311 *      @func: SDIO function to access
 312 *      @dst: buffer to store the data
 313 *      @addr: address to begin reading from
 314 *      @count: number of bytes to read
 315 *
 316 *      Reads from the address space of a given SDIO function. Return
 317 *      value indicates if the transfer succeeded or not.
 318 */
 319int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
 320        unsigned int addr, int count)
 321{
 322        return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count);
 323}
 324EXPORT_SYMBOL_GPL(sdio_memcpy_fromio);
 325
 326/**
 327 *      sdio_memcpy_toio - write a chunk of memory to a SDIO function
 328 *      @func: SDIO function to access
 329 *      @addr: address to start writing to
 330 *      @src: buffer that contains the data to write
 331 *      @count: number of bytes to write
 332 *
 333 *      Writes to the address space of a given SDIO function. Return
 334 *      value indicates if the transfer succeeded or not.
 335 */
 336int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
 337        void *src, int count)
 338{
 339        return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count);
 340}
 341EXPORT_SYMBOL_GPL(sdio_memcpy_toio);
 342
 343/**
 344 *      sdio_readsb - read from a FIFO on a SDIO function
 345 *      @func: SDIO function to access
 346 *      @dst: buffer to store the data
 347 *      @addr: address of (single byte) FIFO
 348 *      @count: number of bytes to read
 349 *
 350 *      Reads from the specified FIFO of a given SDIO function. Return
 351 *      value indicates if the transfer succeeded or not.
 352 */
 353int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr,
 354        int count)
 355{
 356        return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count);
 357}
 358
 359EXPORT_SYMBOL_GPL(sdio_readsb);
 360
 361/**
 362 *      sdio_writesb - write to a FIFO of a SDIO function
 363 *      @func: SDIO function to access
 364 *      @addr: address of (single byte) FIFO
 365 *      @src: buffer that contains the data to write
 366 *      @count: number of bytes to write
 367 *
 368 *      Writes to the specified FIFO of a given SDIO function. Return
 369 *      value indicates if the transfer succeeded or not.
 370 */
 371int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src,
 372        int count)
 373{
 374        return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count);
 375}
 376EXPORT_SYMBOL_GPL(sdio_writesb);
 377
 378/**
 379 *      sdio_readw - read a 16 bit integer from a SDIO function
 380 *      @func: SDIO function to access
 381 *      @addr: address to read
 382 *      @err_ret: optional status value from transfer
 383 *
 384 *      Reads a 16 bit integer from the address space of a given SDIO
 385 *      function. If there is a problem reading the address, 0xffff
 386 *      is returned and @err_ret will contain the error code.
 387 */
 388unsigned short sdio_readw(struct sdio_func *func, unsigned int addr,
 389        int *err_ret)
 390{
 391        int ret;
 392
 393        if (err_ret)
 394                *err_ret = 0;
 395
 396        ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2);
 397        if (ret) {
 398                if (err_ret)
 399                        *err_ret = ret;
 400                return 0xFFFF;
 401        }
 402
 403        return le16_to_cpu(*(u16*)func->tmpbuf);
 404}
 405EXPORT_SYMBOL_GPL(sdio_readw);
 406
 407/**
 408 *      sdio_writew - write a 16 bit integer to a SDIO function
 409 *      @func: SDIO function to access
 410 *      @b: integer to write
 411 *      @addr: address to write to
 412 *      @err_ret: optional status value from transfer
 413 *
 414 *      Writes a 16 bit integer to the address space of a given SDIO
 415 *      function. @err_ret will contain the status of the actual
 416 *      transfer.
 417 */
 418void sdio_writew(struct sdio_func *func, unsigned short b, unsigned int addr,
 419        int *err_ret)
 420{
 421        int ret;
 422
 423        *(u16*)func->tmpbuf = cpu_to_le16(b);
 424
 425        ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
 426        if (err_ret)
 427                *err_ret = ret;
 428}
 429EXPORT_SYMBOL_GPL(sdio_writew);
 430
 431/**
 432 *      sdio_readl - read a 32 bit integer from a SDIO function
 433 *      @func: SDIO function to access
 434 *      @addr: address to read
 435 *      @err_ret: optional status value from transfer
 436 *
 437 *      Reads a 32 bit integer from the address space of a given SDIO
 438 *      function. If there is a problem reading the address,
 439 *      0xffffffff is returned and @err_ret will contain the error
 440 *      code.
 441 */
 442unsigned long sdio_readl(struct sdio_func *func, unsigned int addr,
 443        int *err_ret)
 444{
 445        int ret;
 446
 447        if (err_ret)
 448                *err_ret = 0;
 449
 450        ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4);
 451        if (ret) {
 452                if (err_ret)
 453                        *err_ret = ret;
 454                return 0xFFFFFFFF;
 455        }
 456
 457        return le32_to_cpu(*(u32*)func->tmpbuf);
 458}
 459EXPORT_SYMBOL_GPL(sdio_readl);
 460
 461/**
 462 *      sdio_writel - write a 32 bit integer to a SDIO function
 463 *      @func: SDIO function to access
 464 *      @b: integer to write
 465 *      @addr: address to write to
 466 *      @err_ret: optional status value from transfer
 467 *
 468 *      Writes a 32 bit integer to the address space of a given SDIO
 469 *      function. @err_ret will contain the status of the actual
 470 *      transfer.
 471 */
 472void sdio_writel(struct sdio_func *func, unsigned long b, unsigned int addr,
 473        int *err_ret)
 474{
 475        int ret;
 476
 477        *(u32*)func->tmpbuf = cpu_to_le32(b);
 478
 479        ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
 480        if (err_ret)
 481                *err_ret = ret;
 482}
 483EXPORT_SYMBOL_GPL(sdio_writel);
 484
 485/**
 486 *      sdio_f0_readb - read a single byte from SDIO function 0
 487 *      @func: an SDIO function of the card
 488 *      @addr: address to read
 489 *      @err_ret: optional status value from transfer
 490 *
 491 *      Reads a single byte from the address space of SDIO function 0.
 492 *      If there is a problem reading the address, 0xff is returned
 493 *      and @err_ret will contain the error code.
 494 */
 495unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr,
 496        int *err_ret)
 497{
 498        int ret;
 499        unsigned char val;
 500
 501        BUG_ON(!func);
 502
 503        if (err_ret)
 504                *err_ret = 0;
 505
 506        ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val);
 507        if (ret) {
 508                if (err_ret)
 509                        *err_ret = ret;
 510                return 0xFF;
 511        }
 512
 513        return val;
 514}
 515EXPORT_SYMBOL_GPL(sdio_f0_readb);
 516
 517/**
 518 *      sdio_f0_writeb - write a single byte to SDIO function 0
 519 *      @func: an SDIO function of the card
 520 *      @b: byte to write
 521 *      @addr: address to write to
 522 *      @err_ret: optional status value from transfer
 523 *
 524 *      Writes a single byte to the address space of SDIO function 0.
 525 *      @err_ret will contain the status of the actual transfer.
 526 *
 527 *      Only writes to the vendor specific CCCR registers (0xF0 -
 528 *      0xFF) are permiited; @err_ret will be set to -EINVAL for *
 529 *      writes outside this range.
 530 */
 531void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
 532        int *err_ret)
 533{
 534        int ret;
 535
 536        BUG_ON(!func);
 537
 538        if (addr < 0xF0 || addr > 0xFF) {
 539                if (err_ret)
 540                        *err_ret = -EINVAL;
 541                return;
 542        }
 543
 544        ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL);
 545        if (err_ret)
 546                *err_ret = ret;
 547}
 548EXPORT_SYMBOL_GPL(sdio_f0_writeb);
 549