linux/drivers/mmc/core/sdio_io.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/mmc/core/sdio_io.c
   3 *
   4 *  Copyright 2007-2008 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        timeout = jiffies + msecs_to_jiffies(func->enable_timeout);
  80
  81        while (1) {
  82                ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, &reg);
  83                if (ret)
  84                        goto err;
  85                if (reg & (1 << func->num))
  86                        break;
  87                ret = -ETIME;
  88                if (time_after(jiffies, timeout))
  89                        goto err;
  90        }
  91
  92        pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func));
  93
  94        return 0;
  95
  96err:
  97        pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func));
  98        return ret;
  99}
 100EXPORT_SYMBOL_GPL(sdio_enable_func);
 101
 102/**
 103 *      sdio_disable_func - disable a SDIO function
 104 *      @func: SDIO function to disable
 105 *
 106 *      Powers down and deactivates a SDIO function. Register access
 107 *      to this function will fail until the function is reenabled.
 108 */
 109int sdio_disable_func(struct sdio_func *func)
 110{
 111        int ret;
 112        unsigned char reg;
 113
 114        BUG_ON(!func);
 115        BUG_ON(!func->card);
 116
 117        pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func));
 118
 119        ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, &reg);
 120        if (ret)
 121                goto err;
 122
 123        reg &= ~(1 << func->num);
 124
 125        ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
 126        if (ret)
 127                goto err;
 128
 129        pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func));
 130
 131        return 0;
 132
 133err:
 134        pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func));
 135        return -EIO;
 136}
 137EXPORT_SYMBOL_GPL(sdio_disable_func);
 138
 139/**
 140 *      sdio_set_block_size - set the block size of an SDIO function
 141 *      @func: SDIO function to change
 142 *      @blksz: new block size or 0 to use the default.
 143 *
 144 *      The default block size is the largest supported by both the function
 145 *      and the host, with a maximum of 512 to ensure that arbitrarily sized
 146 *      data transfer use the optimal (least) number of commands.
 147 *
 148 *      A driver may call this to override the default block size set by the
 149 *      core. This can be used to set a block size greater than the maximum
 150 *      that reported by the card; it is the driver's responsibility to ensure
 151 *      it uses a value that the card supports.
 152 *
 153 *      Returns 0 on success, -EINVAL if the host does not support the
 154 *      requested block size, or -EIO (etc.) if one of the resultant FBR block
 155 *      size register writes failed.
 156 *
 157 */
 158int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
 159{
 160        int ret;
 161
 162        if (blksz > func->card->host->max_blk_size)
 163                return -EINVAL;
 164
 165        if (blksz == 0) {
 166                blksz = min(func->max_blksize, func->card->host->max_blk_size);
 167                blksz = min(blksz, 512u);
 168        }
 169
 170        ret = mmc_io_rw_direct(func->card, 1, 0,
 171                SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
 172                blksz & 0xff, NULL);
 173        if (ret)
 174                return ret;
 175        ret = mmc_io_rw_direct(func->card, 1, 0,
 176                SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
 177                (blksz >> 8) & 0xff, NULL);
 178        if (ret)
 179                return ret;
 180        func->cur_blksize = blksz;
 181        return 0;
 182}
 183EXPORT_SYMBOL_GPL(sdio_set_block_size);
 184
 185/*
 186 * Calculate the maximum byte mode transfer size
 187 */
 188static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
 189{
 190        unsigned mval = min(func->card->host->max_seg_size,
 191                            func->card->host->max_blk_size);
 192        mval = min(mval, func->max_blksize);
 193        return min(mval, 512u); /* maximum size for byte mode */
 194}
 195
 196/**
 197 *      sdio_align_size - pads a transfer size to a more optimal value
 198 *      @func: SDIO function
 199 *      @sz: original transfer size
 200 *
 201 *      Pads the original data size with a number of extra bytes in
 202 *      order to avoid controller bugs and/or performance hits
 203 *      (e.g. some controllers revert to PIO for certain sizes).
 204 *
 205 *      If possible, it will also adjust the size so that it can be
 206 *      handled in just a single request.
 207 *
 208 *      Returns the improved size, which might be unmodified.
 209 */
 210unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
 211{
 212        unsigned int orig_sz;
 213        unsigned int blk_sz, byte_sz;
 214        unsigned chunk_sz;
 215
 216        orig_sz = sz;
 217
 218        /*
 219         * Do a first check with the controller, in case it
 220         * wants to increase the size up to a point where it
 221         * might need more than one block.
 222         */
 223        sz = mmc_align_data_size(func->card, sz);
 224
 225        /*
 226         * If we can still do this with just a byte transfer, then
 227         * we're done.
 228         */
 229        if (sz <= sdio_max_byte_size(func))
 230                return sz;
 231
 232        if (func->card->cccr.multi_block) {
 233                /*
 234                 * Check if the transfer is already block aligned
 235                 */
 236                if ((sz % func->cur_blksize) == 0)
 237                        return sz;
 238
 239                /*
 240                 * Realign it so that it can be done with one request,
 241                 * and recheck if the controller still likes it.
 242                 */
 243                blk_sz = ((sz + func->cur_blksize - 1) /
 244                        func->cur_blksize) * func->cur_blksize;
 245                blk_sz = mmc_align_data_size(func->card, blk_sz);
 246
 247                /*
 248                 * This value is only good if it is still just
 249                 * one request.
 250                 */
 251                if ((blk_sz % func->cur_blksize) == 0)
 252                        return blk_sz;
 253
 254                /*
 255                 * We failed to do one request, but at least try to
 256                 * pad the remainder properly.
 257                 */
 258                byte_sz = mmc_align_data_size(func->card,
 259                                sz % func->cur_blksize);
 260                if (byte_sz <= sdio_max_byte_size(func)) {
 261                        blk_sz = sz / func->cur_blksize;
 262                        return blk_sz * func->cur_blksize + byte_sz;
 263                }
 264        } else {
 265                /*
 266                 * We need multiple requests, so first check that the
 267                 * controller can handle the chunk size;
 268                 */
 269                chunk_sz = mmc_align_data_size(func->card,
 270                                sdio_max_byte_size(func));
 271                if (chunk_sz == sdio_max_byte_size(func)) {
 272                        /*
 273                         * Fix up the size of the remainder (if any)
 274                         */
 275                        byte_sz = orig_sz % chunk_sz;
 276                        if (byte_sz) {
 277                                byte_sz = mmc_align_data_size(func->card,
 278                                                byte_sz);
 279                        }
 280
 281                        return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
 282                }
 283        }
 284
 285        /*
 286         * The controller is simply incapable of transferring the size
 287         * we want in decent manner, so just return the original size.
 288         */
 289        return orig_sz;
 290}
 291EXPORT_SYMBOL_GPL(sdio_align_size);
 292
 293/* Split an arbitrarily sized data transfer into several
 294 * IO_RW_EXTENDED commands. */
 295static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
 296        unsigned addr, int incr_addr, u8 *buf, unsigned size)
 297{
 298        unsigned remainder = size;
 299        unsigned max_blocks;
 300        int ret;
 301
 302        /* Do the bulk of the transfer using block mode (if supported). */
 303        if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
 304                /* Blocks per command is limited by host count, host transfer
 305                 * size (we only use a single sg entry) and the maximum for
 306                 * IO_RW_EXTENDED of 511 blocks. */
 307                max_blocks = min(func->card->host->max_blk_count,
 308                        func->card->host->max_seg_size / func->cur_blksize);
 309                max_blocks = min(max_blocks, 511u);
 310
 311                while (remainder > func->cur_blksize) {
 312                        unsigned blocks;
 313
 314                        blocks = remainder / func->cur_blksize;
 315                        if (blocks > max_blocks)
 316                                blocks = max_blocks;
 317                        size = blocks * func->cur_blksize;
 318
 319                        ret = mmc_io_rw_extended(func->card, write,
 320                                func->num, addr, incr_addr, buf,
 321                                blocks, func->cur_blksize);
 322                        if (ret)
 323                                return ret;
 324
 325                        remainder -= size;
 326                        buf += size;
 327                        if (incr_addr)
 328                                addr += size;
 329                }
 330        }
 331
 332        /* Write the remainder using byte mode. */
 333        while (remainder > 0) {
 334                size = min(remainder, sdio_max_byte_size(func));
 335
 336                ret = mmc_io_rw_extended(func->card, write, func->num, addr,
 337                         incr_addr, buf, 1, size);
 338                if (ret)
 339                        return ret;
 340
 341                remainder -= size;
 342                buf += size;
 343                if (incr_addr)
 344                        addr += size;
 345        }
 346        return 0;
 347}
 348
 349/**
 350 *      sdio_readb - read a single byte from a SDIO function
 351 *      @func: SDIO function to access
 352 *      @addr: address to read
 353 *      @err_ret: optional status value from transfer
 354 *
 355 *      Reads a single byte from the address space of a given SDIO
 356 *      function. If there is a problem reading the address, 0xff
 357 *      is returned and @err_ret will contain the error code.
 358 */
 359u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret)
 360{
 361        int ret;
 362        u8 val;
 363
 364        BUG_ON(!func);
 365
 366        if (err_ret)
 367                *err_ret = 0;
 368
 369        ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val);
 370        if (ret) {
 371                if (err_ret)
 372                        *err_ret = ret;
 373                return 0xFF;
 374        }
 375
 376        return val;
 377}
 378EXPORT_SYMBOL_GPL(sdio_readb);
 379
 380/**
 381 *      sdio_writeb - write a single byte to a SDIO function
 382 *      @func: SDIO function to access
 383 *      @b: byte to write
 384 *      @addr: address to write to
 385 *      @err_ret: optional status value from transfer
 386 *
 387 *      Writes a single byte to the address space of a given SDIO
 388 *      function. @err_ret will contain the status of the actual
 389 *      transfer.
 390 */
 391void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret)
 392{
 393        int ret;
 394
 395        BUG_ON(!func);
 396
 397        ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL);
 398        if (err_ret)
 399                *err_ret = ret;
 400}
 401EXPORT_SYMBOL_GPL(sdio_writeb);
 402
 403/**
 404 *      sdio_memcpy_fromio - read a chunk of memory from a SDIO function
 405 *      @func: SDIO function to access
 406 *      @dst: buffer to store the data
 407 *      @addr: address to begin reading from
 408 *      @count: number of bytes to read
 409 *
 410 *      Reads from the address space of a given SDIO function. Return
 411 *      value indicates if the transfer succeeded or not.
 412 */
 413int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
 414        unsigned int addr, int count)
 415{
 416        return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count);
 417}
 418EXPORT_SYMBOL_GPL(sdio_memcpy_fromio);
 419
 420/**
 421 *      sdio_memcpy_toio - write a chunk of memory to a SDIO function
 422 *      @func: SDIO function to access
 423 *      @addr: address to start writing to
 424 *      @src: buffer that contains the data to write
 425 *      @count: number of bytes to write
 426 *
 427 *      Writes to the address space of a given SDIO function. Return
 428 *      value indicates if the transfer succeeded or not.
 429 */
 430int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
 431        void *src, int count)
 432{
 433        return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count);
 434}
 435EXPORT_SYMBOL_GPL(sdio_memcpy_toio);
 436
 437/**
 438 *      sdio_readsb - read from a FIFO on a SDIO function
 439 *      @func: SDIO function to access
 440 *      @dst: buffer to store the data
 441 *      @addr: address of (single byte) FIFO
 442 *      @count: number of bytes to read
 443 *
 444 *      Reads from the specified FIFO of a given SDIO function. Return
 445 *      value indicates if the transfer succeeded or not.
 446 */
 447int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr,
 448        int count)
 449{
 450        return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count);
 451}
 452EXPORT_SYMBOL_GPL(sdio_readsb);
 453
 454/**
 455 *      sdio_writesb - write to a FIFO of a SDIO function
 456 *      @func: SDIO function to access
 457 *      @addr: address of (single byte) FIFO
 458 *      @src: buffer that contains the data to write
 459 *      @count: number of bytes to write
 460 *
 461 *      Writes to the specified FIFO of a given SDIO function. Return
 462 *      value indicates if the transfer succeeded or not.
 463 */
 464int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src,
 465        int count)
 466{
 467        return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count);
 468}
 469EXPORT_SYMBOL_GPL(sdio_writesb);
 470
 471/**
 472 *      sdio_readw - read a 16 bit integer from a SDIO function
 473 *      @func: SDIO function to access
 474 *      @addr: address to read
 475 *      @err_ret: optional status value from transfer
 476 *
 477 *      Reads a 16 bit integer from the address space of a given SDIO
 478 *      function. If there is a problem reading the address, 0xffff
 479 *      is returned and @err_ret will contain the error code.
 480 */
 481u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret)
 482{
 483        int ret;
 484
 485        if (err_ret)
 486                *err_ret = 0;
 487
 488        ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2);
 489        if (ret) {
 490                if (err_ret)
 491                        *err_ret = ret;
 492                return 0xFFFF;
 493        }
 494
 495        return le16_to_cpup((__le16 *)func->tmpbuf);
 496}
 497EXPORT_SYMBOL_GPL(sdio_readw);
 498
 499/**
 500 *      sdio_writew - write a 16 bit integer to a SDIO function
 501 *      @func: SDIO function to access
 502 *      @b: integer to write
 503 *      @addr: address to write to
 504 *      @err_ret: optional status value from transfer
 505 *
 506 *      Writes a 16 bit integer to the address space of a given SDIO
 507 *      function. @err_ret will contain the status of the actual
 508 *      transfer.
 509 */
 510void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret)
 511{
 512        int ret;
 513
 514        *(__le16 *)func->tmpbuf = cpu_to_le16(b);
 515
 516        ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
 517        if (err_ret)
 518                *err_ret = ret;
 519}
 520EXPORT_SYMBOL_GPL(sdio_writew);
 521
 522/**
 523 *      sdio_readl - read a 32 bit integer from a SDIO function
 524 *      @func: SDIO function to access
 525 *      @addr: address to read
 526 *      @err_ret: optional status value from transfer
 527 *
 528 *      Reads a 32 bit integer from the address space of a given SDIO
 529 *      function. If there is a problem reading the address,
 530 *      0xffffffff is returned and @err_ret will contain the error
 531 *      code.
 532 */
 533u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret)
 534{
 535        int ret;
 536
 537        if (err_ret)
 538                *err_ret = 0;
 539
 540        ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4);
 541        if (ret) {
 542                if (err_ret)
 543                        *err_ret = ret;
 544                return 0xFFFFFFFF;
 545        }
 546
 547        return le32_to_cpup((__le32 *)func->tmpbuf);
 548}
 549EXPORT_SYMBOL_GPL(sdio_readl);
 550
 551/**
 552 *      sdio_writel - write a 32 bit integer to a SDIO function
 553 *      @func: SDIO function to access
 554 *      @b: integer to write
 555 *      @addr: address to write to
 556 *      @err_ret: optional status value from transfer
 557 *
 558 *      Writes a 32 bit integer to the address space of a given SDIO
 559 *      function. @err_ret will contain the status of the actual
 560 *      transfer.
 561 */
 562void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret)
 563{
 564        int ret;
 565
 566        *(__le32 *)func->tmpbuf = cpu_to_le32(b);
 567
 568        ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
 569        if (err_ret)
 570                *err_ret = ret;
 571}
 572EXPORT_SYMBOL_GPL(sdio_writel);
 573
 574/**
 575 *      sdio_f0_readb - read a single byte from SDIO function 0
 576 *      @func: an SDIO function of the card
 577 *      @addr: address to read
 578 *      @err_ret: optional status value from transfer
 579 *
 580 *      Reads a single byte from the address space of SDIO function 0.
 581 *      If there is a problem reading the address, 0xff is returned
 582 *      and @err_ret will contain the error code.
 583 */
 584unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr,
 585        int *err_ret)
 586{
 587        int ret;
 588        unsigned char val;
 589
 590        BUG_ON(!func);
 591
 592        if (err_ret)
 593                *err_ret = 0;
 594
 595        ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val);
 596        if (ret) {
 597                if (err_ret)
 598                        *err_ret = ret;
 599                return 0xFF;
 600        }
 601
 602        return val;
 603}
 604EXPORT_SYMBOL_GPL(sdio_f0_readb);
 605
 606/**
 607 *      sdio_f0_writeb - write a single byte to SDIO function 0
 608 *      @func: an SDIO function of the card
 609 *      @b: byte to write
 610 *      @addr: address to write to
 611 *      @err_ret: optional status value from transfer
 612 *
 613 *      Writes a single byte to the address space of SDIO function 0.
 614 *      @err_ret will contain the status of the actual transfer.
 615 *
 616 *      Only writes to the vendor specific CCCR registers (0xF0 -
 617 *      0xFF) are permiited; @err_ret will be set to -EINVAL for *
 618 *      writes outside this range.
 619 */
 620void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
 621        int *err_ret)
 622{
 623        int ret;
 624
 625        BUG_ON(!func);
 626
 627        if (addr < 0xF0 || addr > 0xFF) {
 628                if (err_ret)
 629                        *err_ret = -EINVAL;
 630                return;
 631        }
 632
 633        ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL);
 634        if (err_ret)
 635                *err_ret = ret;
 636}
 637EXPORT_SYMBOL_GPL(sdio_f0_writeb);
 638
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.