1
2
3
4
5
6
7
8#include <linux/export.h>
9#include <linux/kernel.h>
10#include <linux/mmc/host.h>
11#include <linux/mmc/card.h>
12#include <linux/mmc/sdio.h>
13#include <linux/mmc/sdio_func.h>
14
15#include "sdio_ops.h"
16#include "core.h"
17#include "card.h"
18#include "host.h"
19
20
21
22
23
24
25
26
27void sdio_claim_host(struct sdio_func *func)
28{
29 if (WARN_ON(!func))
30 return;
31
32 mmc_claim_host(func->card->host);
33}
34EXPORT_SYMBOL_GPL(sdio_claim_host);
35
36
37
38
39
40
41
42
43void sdio_release_host(struct sdio_func *func)
44{
45 if (WARN_ON(!func))
46 return;
47
48 mmc_release_host(func->card->host);
49}
50EXPORT_SYMBOL_GPL(sdio_release_host);
51
52
53
54
55
56
57
58
59int sdio_enable_func(struct sdio_func *func)
60{
61 int ret;
62 unsigned char reg;
63 unsigned long timeout;
64
65 if (!func)
66 return -EINVAL;
67
68 pr_debug("SDIO: Enabling device %s...\n", sdio_func_id(func));
69
70 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®);
71 if (ret)
72 goto err;
73
74 reg |= 1 << func->num;
75
76 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
77 if (ret)
78 goto err;
79
80 timeout = jiffies + msecs_to_jiffies(func->enable_timeout);
81
82 while (1) {
83 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, ®);
84 if (ret)
85 goto err;
86 if (reg & (1 << func->num))
87 break;
88 ret = -ETIME;
89 if (time_after(jiffies, timeout))
90 goto err;
91 }
92
93 pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func));
94
95 return 0;
96
97err:
98 pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func));
99 return ret;
100}
101EXPORT_SYMBOL_GPL(sdio_enable_func);
102
103
104
105
106
107
108
109
110int sdio_disable_func(struct sdio_func *func)
111{
112 int ret;
113 unsigned char reg;
114
115 if (!func)
116 return -EINVAL;
117
118 pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func));
119
120 ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, ®);
121 if (ret)
122 goto err;
123
124 reg &= ~(1 << func->num);
125
126 ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
127 if (ret)
128 goto err;
129
130 pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func));
131
132 return 0;
133
134err:
135 pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func));
136 return -EIO;
137}
138EXPORT_SYMBOL_GPL(sdio_disable_func);
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
160{
161 int ret;
162
163 if (blksz > func->card->host->max_blk_size)
164 return -EINVAL;
165
166 if (blksz == 0) {
167 blksz = min(func->max_blksize, func->card->host->max_blk_size);
168 blksz = min(blksz, 512u);
169 }
170
171 ret = mmc_io_rw_direct(func->card, 1, 0,
172 SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
173 blksz & 0xff, NULL);
174 if (ret)
175 return ret;
176 ret = mmc_io_rw_direct(func->card, 1, 0,
177 SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
178 (blksz >> 8) & 0xff, NULL);
179 if (ret)
180 return ret;
181 func->cur_blksize = blksz;
182 return 0;
183}
184EXPORT_SYMBOL_GPL(sdio_set_block_size);
185
186
187
188
189static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
190{
191 unsigned mval = func->card->host->max_blk_size;
192
193 if (mmc_blksz_for_byte_mode(func->card))
194 mval = min(mval, func->cur_blksize);
195 else
196 mval = min(mval, func->max_blksize);
197
198 if (mmc_card_broken_byte_mode_512(func->card))
199 return min(mval, 511u);
200
201 return min(mval, 512u);
202}
203
204
205
206
207
208
209static inline unsigned int _sdio_align_size(unsigned int sz)
210{
211
212
213
214
215
216 return ALIGN(sz, 4);
217}
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
234{
235 unsigned int orig_sz;
236 unsigned int blk_sz, byte_sz;
237 unsigned chunk_sz;
238
239 orig_sz = sz;
240
241
242
243
244
245
246 sz = _sdio_align_size(sz);
247
248
249
250
251
252 if (sz <= sdio_max_byte_size(func))
253 return sz;
254
255 if (func->card->cccr.multi_block) {
256
257
258
259 if ((sz % func->cur_blksize) == 0)
260 return sz;
261
262
263
264
265
266 blk_sz = ((sz + func->cur_blksize - 1) /
267 func->cur_blksize) * func->cur_blksize;
268 blk_sz = _sdio_align_size(blk_sz);
269
270
271
272
273
274 if ((blk_sz % func->cur_blksize) == 0)
275 return blk_sz;
276
277
278
279
280
281 byte_sz = _sdio_align_size(sz % func->cur_blksize);
282 if (byte_sz <= sdio_max_byte_size(func)) {
283 blk_sz = sz / func->cur_blksize;
284 return blk_sz * func->cur_blksize + byte_sz;
285 }
286 } else {
287
288
289
290
291 chunk_sz = _sdio_align_size(sdio_max_byte_size(func));
292 if (chunk_sz == sdio_max_byte_size(func)) {
293
294
295
296 byte_sz = orig_sz % chunk_sz;
297 if (byte_sz) {
298 byte_sz = _sdio_align_size(byte_sz);
299 }
300
301 return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
302 }
303 }
304
305
306
307
308
309 return orig_sz;
310}
311EXPORT_SYMBOL_GPL(sdio_align_size);
312
313
314
315static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
316 unsigned addr, int incr_addr, u8 *buf, unsigned size)
317{
318 unsigned remainder = size;
319 unsigned max_blocks;
320 int ret;
321
322 if (!func || (func->num > 7))
323 return -EINVAL;
324
325
326 if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
327
328
329 max_blocks = min(func->card->host->max_blk_count, 511u);
330
331 while (remainder >= func->cur_blksize) {
332 unsigned blocks;
333
334 blocks = remainder / func->cur_blksize;
335 if (blocks > max_blocks)
336 blocks = max_blocks;
337 size = blocks * func->cur_blksize;
338
339 ret = mmc_io_rw_extended(func->card, write,
340 func->num, addr, incr_addr, buf,
341 blocks, func->cur_blksize);
342 if (ret)
343 return ret;
344
345 remainder -= size;
346 buf += size;
347 if (incr_addr)
348 addr += size;
349 }
350 }
351
352
353 while (remainder > 0) {
354 size = min(remainder, sdio_max_byte_size(func));
355
356
357 ret = mmc_io_rw_extended(func->card, write, func->num, addr,
358 incr_addr, buf, 0, size);
359 if (ret)
360 return ret;
361
362 remainder -= size;
363 buf += size;
364 if (incr_addr)
365 addr += size;
366 }
367 return 0;
368}
369
370
371
372
373
374
375
376
377
378
379
380u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret)
381{
382 int ret;
383 u8 val;
384
385 if (!func) {
386 if (err_ret)
387 *err_ret = -EINVAL;
388 return 0xFF;
389 }
390
391 ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val);
392 if (err_ret)
393 *err_ret = ret;
394 if (ret)
395 return 0xFF;
396
397 return val;
398}
399EXPORT_SYMBOL_GPL(sdio_readb);
400
401
402
403
404
405
406
407
408
409
410
411
412void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret)
413{
414 int ret;
415
416 if (!func) {
417 if (err_ret)
418 *err_ret = -EINVAL;
419 return;
420 }
421
422 ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL);
423 if (err_ret)
424 *err_ret = ret;
425}
426EXPORT_SYMBOL_GPL(sdio_writeb);
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441u8 sdio_writeb_readb(struct sdio_func *func, u8 write_byte,
442 unsigned int addr, int *err_ret)
443{
444 int ret;
445 u8 val;
446
447 ret = mmc_io_rw_direct(func->card, 1, func->num, addr,
448 write_byte, &val);
449 if (err_ret)
450 *err_ret = ret;
451 if (ret)
452 return 0xff;
453
454 return val;
455}
456EXPORT_SYMBOL_GPL(sdio_writeb_readb);
457
458
459
460
461
462
463
464
465
466
467
468int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
469 unsigned int addr, int count)
470{
471 return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count);
472}
473EXPORT_SYMBOL_GPL(sdio_memcpy_fromio);
474
475
476
477
478
479
480
481
482
483
484
485int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
486 void *src, int count)
487{
488 return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count);
489}
490EXPORT_SYMBOL_GPL(sdio_memcpy_toio);
491
492
493
494
495
496
497
498
499
500
501
502int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr,
503 int count)
504{
505 return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count);
506}
507EXPORT_SYMBOL_GPL(sdio_readsb);
508
509
510
511
512
513
514
515
516
517
518
519int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src,
520 int count)
521{
522 return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count);
523}
524EXPORT_SYMBOL_GPL(sdio_writesb);
525
526
527
528
529
530
531
532
533
534
535
536u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret)
537{
538 int ret;
539
540 ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2);
541 if (err_ret)
542 *err_ret = ret;
543 if (ret)
544 return 0xFFFF;
545
546 return le16_to_cpup((__le16 *)func->tmpbuf);
547}
548EXPORT_SYMBOL_GPL(sdio_readw);
549
550
551
552
553
554
555
556
557
558
559
560
561void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret)
562{
563 int ret;
564
565 *(__le16 *)func->tmpbuf = cpu_to_le16(b);
566
567 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
568 if (err_ret)
569 *err_ret = ret;
570}
571EXPORT_SYMBOL_GPL(sdio_writew);
572
573
574
575
576
577
578
579
580
581
582
583
584u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret)
585{
586 int ret;
587
588 ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4);
589 if (err_ret)
590 *err_ret = ret;
591 if (ret)
592 return 0xFFFFFFFF;
593
594 return le32_to_cpup((__le32 *)func->tmpbuf);
595}
596EXPORT_SYMBOL_GPL(sdio_readl);
597
598
599
600
601
602
603
604
605
606
607
608
609void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret)
610{
611 int ret;
612
613 *(__le32 *)func->tmpbuf = cpu_to_le32(b);
614
615 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
616 if (err_ret)
617 *err_ret = ret;
618}
619EXPORT_SYMBOL_GPL(sdio_writel);
620
621
622
623
624
625
626
627
628
629
630
631unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr,
632 int *err_ret)
633{
634 int ret;
635 unsigned char val;
636
637 if (!func) {
638 if (err_ret)
639 *err_ret = -EINVAL;
640 return 0xFF;
641 }
642
643 ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val);
644 if (err_ret)
645 *err_ret = ret;
646 if (ret)
647 return 0xFF;
648
649 return val;
650}
651EXPORT_SYMBOL_GPL(sdio_f0_readb);
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
668 int *err_ret)
669{
670 int ret;
671
672 if (!func) {
673 if (err_ret)
674 *err_ret = -EINVAL;
675 return;
676 }
677
678 if ((addr < 0xF0 || addr > 0xFF) && (!mmc_card_lenient_fn0(func->card))) {
679 if (err_ret)
680 *err_ret = -EINVAL;
681 return;
682 }
683
684 ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL);
685 if (err_ret)
686 *err_ret = ret;
687}
688EXPORT_SYMBOL_GPL(sdio_f0_writeb);
689
690
691
692
693
694
695
696
697
698
699
700mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func)
701{
702 if (!func)
703 return 0;
704
705 return func->card->host->pm_caps;
706}
707EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps);
708
709
710
711
712
713
714
715
716
717
718
719
720
721int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
722{
723 struct mmc_host *host;
724
725 if (!func)
726 return -EINVAL;
727
728 host = func->card->host;
729
730 if (flags & ~host->pm_caps)
731 return -EINVAL;
732
733
734 host->pm_flags |= flags;
735 return 0;
736}
737EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758void sdio_retune_crc_disable(struct sdio_func *func)
759{
760 func->card->host->retune_crc_disable = true;
761}
762EXPORT_SYMBOL_GPL(sdio_retune_crc_disable);
763
764
765
766
767
768
769
770void sdio_retune_crc_enable(struct sdio_func *func)
771{
772 func->card->host->retune_crc_disable = false;
773}
774EXPORT_SYMBOL_GPL(sdio_retune_crc_enable);
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793void sdio_retune_hold_now(struct sdio_func *func)
794{
795 mmc_retune_hold_now(func->card->host);
796}
797EXPORT_SYMBOL_GPL(sdio_retune_hold_now);
798
799
800
801
802
803
804
805
806
807
808
809void sdio_retune_release(struct sdio_func *func)
810{
811 mmc_retune_release(func->card->host);
812}
813EXPORT_SYMBOL_GPL(sdio_retune_release);
814