0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/export.h>
0009 #include <linux/kernel.h>
0010 #include <linux/mmc/host.h>
0011 #include <linux/mmc/card.h>
0012 #include <linux/mmc/sdio.h>
0013 #include <linux/mmc/sdio_func.h>
0014
0015 #include "sdio_ops.h"
0016 #include "core.h"
0017 #include "card.h"
0018 #include "host.h"
0019
0020
0021
0022
0023
0024
0025
0026
0027 void sdio_claim_host(struct sdio_func *func)
0028 {
0029 if (WARN_ON(!func))
0030 return;
0031
0032 mmc_claim_host(func->card->host);
0033 }
0034 EXPORT_SYMBOL_GPL(sdio_claim_host);
0035
0036
0037
0038
0039
0040
0041
0042
0043 void sdio_release_host(struct sdio_func *func)
0044 {
0045 if (WARN_ON(!func))
0046 return;
0047
0048 mmc_release_host(func->card->host);
0049 }
0050 EXPORT_SYMBOL_GPL(sdio_release_host);
0051
0052
0053
0054
0055
0056
0057
0058
0059 int sdio_enable_func(struct sdio_func *func)
0060 {
0061 int ret;
0062 unsigned char reg;
0063 unsigned long timeout;
0064
0065 if (!func)
0066 return -EINVAL;
0067
0068 pr_debug("SDIO: Enabling device %s...\n", sdio_func_id(func));
0069
0070 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®);
0071 if (ret)
0072 goto err;
0073
0074 reg |= 1 << func->num;
0075
0076 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
0077 if (ret)
0078 goto err;
0079
0080 timeout = jiffies + msecs_to_jiffies(func->enable_timeout);
0081
0082 while (1) {
0083 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, ®);
0084 if (ret)
0085 goto err;
0086 if (reg & (1 << func->num))
0087 break;
0088 ret = -ETIME;
0089 if (time_after(jiffies, timeout))
0090 goto err;
0091 }
0092
0093 pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func));
0094
0095 return 0;
0096
0097 err:
0098 pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func));
0099 return ret;
0100 }
0101 EXPORT_SYMBOL_GPL(sdio_enable_func);
0102
0103
0104
0105
0106
0107
0108
0109
0110 int sdio_disable_func(struct sdio_func *func)
0111 {
0112 int ret;
0113 unsigned char reg;
0114
0115 if (!func)
0116 return -EINVAL;
0117
0118 pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func));
0119
0120 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®);
0121 if (ret)
0122 goto err;
0123
0124 reg &= ~(1 << func->num);
0125
0126 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
0127 if (ret)
0128 goto err;
0129
0130 pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func));
0131
0132 return 0;
0133
0134 err:
0135 pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func));
0136 return ret;
0137 }
0138 EXPORT_SYMBOL_GPL(sdio_disable_func);
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159 int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
0160 {
0161 int ret;
0162
0163 if (blksz > func->card->host->max_blk_size)
0164 return -EINVAL;
0165
0166 if (blksz == 0) {
0167 blksz = min(func->max_blksize, func->card->host->max_blk_size);
0168 blksz = min(blksz, 512u);
0169 }
0170
0171 ret = mmc_io_rw_direct(func->card, 1, 0,
0172 SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
0173 blksz & 0xff, NULL);
0174 if (ret)
0175 return ret;
0176 ret = mmc_io_rw_direct(func->card, 1, 0,
0177 SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
0178 (blksz >> 8) & 0xff, NULL);
0179 if (ret)
0180 return ret;
0181 func->cur_blksize = blksz;
0182 return 0;
0183 }
0184 EXPORT_SYMBOL_GPL(sdio_set_block_size);
0185
0186
0187
0188
0189 static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
0190 {
0191 unsigned mval = func->card->host->max_blk_size;
0192
0193 if (mmc_blksz_for_byte_mode(func->card))
0194 mval = min(mval, func->cur_blksize);
0195 else
0196 mval = min(mval, func->max_blksize);
0197
0198 if (mmc_card_broken_byte_mode_512(func->card))
0199 return min(mval, 511u);
0200
0201 return min(mval, 512u);
0202 }
0203
0204
0205
0206
0207
0208
0209 static inline unsigned int _sdio_align_size(unsigned int sz)
0210 {
0211
0212
0213
0214
0215
0216 return ALIGN(sz, 4);
0217 }
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233 unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
0234 {
0235 unsigned int orig_sz;
0236 unsigned int blk_sz, byte_sz;
0237 unsigned chunk_sz;
0238
0239 orig_sz = sz;
0240
0241
0242
0243
0244
0245
0246 sz = _sdio_align_size(sz);
0247
0248
0249
0250
0251
0252 if (sz <= sdio_max_byte_size(func))
0253 return sz;
0254
0255 if (func->card->cccr.multi_block) {
0256
0257
0258
0259 if ((sz % func->cur_blksize) == 0)
0260 return sz;
0261
0262
0263
0264
0265
0266 blk_sz = ((sz + func->cur_blksize - 1) /
0267 func->cur_blksize) * func->cur_blksize;
0268 blk_sz = _sdio_align_size(blk_sz);
0269
0270
0271
0272
0273
0274 if ((blk_sz % func->cur_blksize) == 0)
0275 return blk_sz;
0276
0277
0278
0279
0280
0281 byte_sz = _sdio_align_size(sz % func->cur_blksize);
0282 if (byte_sz <= sdio_max_byte_size(func)) {
0283 blk_sz = sz / func->cur_blksize;
0284 return blk_sz * func->cur_blksize + byte_sz;
0285 }
0286 } else {
0287
0288
0289
0290
0291 chunk_sz = _sdio_align_size(sdio_max_byte_size(func));
0292 if (chunk_sz == sdio_max_byte_size(func)) {
0293
0294
0295
0296 byte_sz = orig_sz % chunk_sz;
0297 if (byte_sz) {
0298 byte_sz = _sdio_align_size(byte_sz);
0299 }
0300
0301 return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
0302 }
0303 }
0304
0305
0306
0307
0308
0309 return orig_sz;
0310 }
0311 EXPORT_SYMBOL_GPL(sdio_align_size);
0312
0313
0314
0315 static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
0316 unsigned addr, int incr_addr, u8 *buf, unsigned size)
0317 {
0318 unsigned remainder = size;
0319 unsigned max_blocks;
0320 int ret;
0321
0322 if (!func || (func->num > 7))
0323 return -EINVAL;
0324
0325
0326 if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
0327
0328
0329 max_blocks = min(func->card->host->max_blk_count, 511u);
0330
0331 while (remainder >= func->cur_blksize) {
0332 unsigned blocks;
0333
0334 blocks = remainder / func->cur_blksize;
0335 if (blocks > max_blocks)
0336 blocks = max_blocks;
0337 size = blocks * func->cur_blksize;
0338
0339 ret = mmc_io_rw_extended(func->card, write,
0340 func->num, addr, incr_addr, buf,
0341 blocks, func->cur_blksize);
0342 if (ret)
0343 return ret;
0344
0345 remainder -= size;
0346 buf += size;
0347 if (incr_addr)
0348 addr += size;
0349 }
0350 }
0351
0352
0353 while (remainder > 0) {
0354 size = min(remainder, sdio_max_byte_size(func));
0355
0356
0357 ret = mmc_io_rw_extended(func->card, write, func->num, addr,
0358 incr_addr, buf, 0, size);
0359 if (ret)
0360 return ret;
0361
0362 remainder -= size;
0363 buf += size;
0364 if (incr_addr)
0365 addr += size;
0366 }
0367 return 0;
0368 }
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret)
0381 {
0382 int ret;
0383 u8 val;
0384
0385 if (!func) {
0386 if (err_ret)
0387 *err_ret = -EINVAL;
0388 return 0xFF;
0389 }
0390
0391 ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val);
0392 if (err_ret)
0393 *err_ret = ret;
0394 if (ret)
0395 return 0xFF;
0396
0397 return val;
0398 }
0399 EXPORT_SYMBOL_GPL(sdio_readb);
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret)
0413 {
0414 int ret;
0415
0416 if (!func) {
0417 if (err_ret)
0418 *err_ret = -EINVAL;
0419 return;
0420 }
0421
0422 ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL);
0423 if (err_ret)
0424 *err_ret = ret;
0425 }
0426 EXPORT_SYMBOL_GPL(sdio_writeb);
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441 u8 sdio_writeb_readb(struct sdio_func *func, u8 write_byte,
0442 unsigned int addr, int *err_ret)
0443 {
0444 int ret;
0445 u8 val;
0446
0447 ret = mmc_io_rw_direct(func->card, 1, func->num, addr,
0448 write_byte, &val);
0449 if (err_ret)
0450 *err_ret = ret;
0451 if (ret)
0452 return 0xff;
0453
0454 return val;
0455 }
0456 EXPORT_SYMBOL_GPL(sdio_writeb_readb);
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468 int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
0469 unsigned int addr, int count)
0470 {
0471 return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count);
0472 }
0473 EXPORT_SYMBOL_GPL(sdio_memcpy_fromio);
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485 int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
0486 void *src, int count)
0487 {
0488 return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count);
0489 }
0490 EXPORT_SYMBOL_GPL(sdio_memcpy_toio);
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502 int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr,
0503 int count)
0504 {
0505 return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count);
0506 }
0507 EXPORT_SYMBOL_GPL(sdio_readsb);
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519 int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src,
0520 int count)
0521 {
0522 return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count);
0523 }
0524 EXPORT_SYMBOL_GPL(sdio_writesb);
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536 u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret)
0537 {
0538 int ret;
0539
0540 ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2);
0541 if (err_ret)
0542 *err_ret = ret;
0543 if (ret)
0544 return 0xFFFF;
0545
0546 return le16_to_cpup((__le16 *)func->tmpbuf);
0547 }
0548 EXPORT_SYMBOL_GPL(sdio_readw);
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561 void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret)
0562 {
0563 int ret;
0564
0565 *(__le16 *)func->tmpbuf = cpu_to_le16(b);
0566
0567 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
0568 if (err_ret)
0569 *err_ret = ret;
0570 }
0571 EXPORT_SYMBOL_GPL(sdio_writew);
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584 u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret)
0585 {
0586 int ret;
0587
0588 ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4);
0589 if (err_ret)
0590 *err_ret = ret;
0591 if (ret)
0592 return 0xFFFFFFFF;
0593
0594 return le32_to_cpup((__le32 *)func->tmpbuf);
0595 }
0596 EXPORT_SYMBOL_GPL(sdio_readl);
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609 void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret)
0610 {
0611 int ret;
0612
0613 *(__le32 *)func->tmpbuf = cpu_to_le32(b);
0614
0615 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
0616 if (err_ret)
0617 *err_ret = ret;
0618 }
0619 EXPORT_SYMBOL_GPL(sdio_writel);
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631 unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr,
0632 int *err_ret)
0633 {
0634 int ret;
0635 unsigned char val;
0636
0637 if (!func) {
0638 if (err_ret)
0639 *err_ret = -EINVAL;
0640 return 0xFF;
0641 }
0642
0643 ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val);
0644 if (err_ret)
0645 *err_ret = ret;
0646 if (ret)
0647 return 0xFF;
0648
0649 return val;
0650 }
0651 EXPORT_SYMBOL_GPL(sdio_f0_readb);
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667 void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
0668 int *err_ret)
0669 {
0670 int ret;
0671
0672 if (!func) {
0673 if (err_ret)
0674 *err_ret = -EINVAL;
0675 return;
0676 }
0677
0678 if ((addr < 0xF0 || addr > 0xFF) && (!mmc_card_lenient_fn0(func->card))) {
0679 if (err_ret)
0680 *err_ret = -EINVAL;
0681 return;
0682 }
0683
0684 ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL);
0685 if (err_ret)
0686 *err_ret = ret;
0687 }
0688 EXPORT_SYMBOL_GPL(sdio_f0_writeb);
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700 mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func)
0701 {
0702 if (!func)
0703 return 0;
0704
0705 return func->card->host->pm_caps;
0706 }
0707 EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps);
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722 int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
0723 {
0724 struct mmc_host *host;
0725
0726 if (!func)
0727 return -EINVAL;
0728
0729 host = func->card->host;
0730
0731 if (flags & ~host->pm_caps)
0732 return -EINVAL;
0733
0734
0735 host->pm_flags |= flags;
0736 return 0;
0737 }
0738 EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759 void sdio_retune_crc_disable(struct sdio_func *func)
0760 {
0761 func->card->host->retune_crc_disable = true;
0762 }
0763 EXPORT_SYMBOL_GPL(sdio_retune_crc_disable);
0764
0765
0766
0767
0768
0769
0770
0771 void sdio_retune_crc_enable(struct sdio_func *func)
0772 {
0773 func->card->host->retune_crc_disable = false;
0774 }
0775 EXPORT_SYMBOL_GPL(sdio_retune_crc_enable);
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794 void sdio_retune_hold_now(struct sdio_func *func)
0795 {
0796 mmc_retune_hold_now(func->card->host);
0797 }
0798 EXPORT_SYMBOL_GPL(sdio_retune_hold_now);
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810 void sdio_retune_release(struct sdio_func *func)
0811 {
0812 mmc_retune_release(func->card->host);
0813 }
0814 EXPORT_SYMBOL_GPL(sdio_retune_release);