1
2
3
4
5
6
7
8
9
10
11
12#include <linux/export.h>
13#include <linux/mmc/host.h>
14#include <linux/mmc/card.h>
15#include <linux/mmc/sdio.h>
16#include <linux/mmc/sdio_func.h>
17
18#include "sdio_ops.h"
19
20
21
22
23
24
25
26
27void sdio_claim_host(struct sdio_func *func)
28{
29 BUG_ON(!func);
30 BUG_ON(!func->card);
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 BUG_ON(!func);
46 BUG_ON(!func->card);
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 BUG_ON(!func);
66 BUG_ON(!func->card);
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 BUG_ON(!func);
116 BUG_ON(!func->card);
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
209
210
211
212
213
214
215
216
217
218unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
219{
220 unsigned int orig_sz;
221 unsigned int blk_sz, byte_sz;
222 unsigned chunk_sz;
223
224 orig_sz = sz;
225
226
227
228
229
230
231 sz = mmc_align_data_size(func->card, sz);
232
233
234
235
236
237 if (sz <= sdio_max_byte_size(func))
238 return sz;
239
240 if (func->card->cccr.multi_block) {
241
242
243
244 if ((sz % func->cur_blksize) == 0)
245 return sz;
246
247
248
249
250
251 blk_sz = ((sz + func->cur_blksize - 1) /
252 func->cur_blksize) * func->cur_blksize;
253 blk_sz = mmc_align_data_size(func->card, blk_sz);
254
255
256
257
258
259 if ((blk_sz % func->cur_blksize) == 0)
260 return blk_sz;
261
262
263
264
265
266 byte_sz = mmc_align_data_size(func->card,
267 sz % func->cur_blksize);
268 if (byte_sz <= sdio_max_byte_size(func)) {
269 blk_sz = sz / func->cur_blksize;
270 return blk_sz * func->cur_blksize + byte_sz;
271 }
272 } else {
273
274
275
276
277 chunk_sz = mmc_align_data_size(func->card,
278 sdio_max_byte_size(func));
279 if (chunk_sz == sdio_max_byte_size(func)) {
280
281
282
283 byte_sz = orig_sz % chunk_sz;
284 if (byte_sz) {
285 byte_sz = mmc_align_data_size(func->card,
286 byte_sz);
287 }
288
289 return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
290 }
291 }
292
293
294
295
296
297 return orig_sz;
298}
299EXPORT_SYMBOL_GPL(sdio_align_size);
300
301
302
303static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
304 unsigned addr, int incr_addr, u8 *buf, unsigned size)
305{
306 unsigned remainder = size;
307 unsigned max_blocks;
308 int ret;
309
310
311 if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) {
312
313
314 max_blocks = min(func->card->host->max_blk_count, 511u);
315
316 while (remainder >= func->cur_blksize) {
317 unsigned blocks;
318
319 blocks = remainder / func->cur_blksize;
320 if (blocks > max_blocks)
321 blocks = max_blocks;
322 size = blocks * func->cur_blksize;
323
324 ret = mmc_io_rw_extended(func->card, write,
325 func->num, addr, incr_addr, buf,
326 blocks, func->cur_blksize);
327 if (ret)
328 return ret;
329
330 remainder -= size;
331 buf += size;
332 if (incr_addr)
333 addr += size;
334 }
335 }
336
337
338 while (remainder > 0) {
339 size = min(remainder, sdio_max_byte_size(func));
340
341
342 ret = mmc_io_rw_extended(func->card, write, func->num, addr,
343 incr_addr, buf, 0, size);
344 if (ret)
345 return ret;
346
347 remainder -= size;
348 buf += size;
349 if (incr_addr)
350 addr += size;
351 }
352 return 0;
353}
354
355
356
357
358
359
360
361
362
363
364
365u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret)
366{
367 int ret;
368 u8 val;
369
370 BUG_ON(!func);
371
372 if (err_ret)
373 *err_ret = 0;
374
375 ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val);
376 if (ret) {
377 if (err_ret)
378 *err_ret = ret;
379 return 0xFF;
380 }
381
382 return val;
383}
384EXPORT_SYMBOL_GPL(sdio_readb);
385
386
387
388
389
390
391
392
393
394
395
396
397void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret)
398{
399 int ret;
400
401 BUG_ON(!func);
402
403 ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL);
404 if (err_ret)
405 *err_ret = ret;
406}
407EXPORT_SYMBOL_GPL(sdio_writeb);
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422u8 sdio_writeb_readb(struct sdio_func *func, u8 write_byte,
423 unsigned int addr, int *err_ret)
424{
425 int ret;
426 u8 val;
427
428 ret = mmc_io_rw_direct(func->card, 1, func->num, addr,
429 write_byte, &val);
430 if (err_ret)
431 *err_ret = ret;
432 if (ret)
433 val = 0xff;
434
435 return val;
436}
437EXPORT_SYMBOL_GPL(sdio_writeb_readb);
438
439
440
441
442
443
444
445
446
447
448
449int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
450 unsigned int addr, int count)
451{
452 return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count);
453}
454EXPORT_SYMBOL_GPL(sdio_memcpy_fromio);
455
456
457
458
459
460
461
462
463
464
465
466int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
467 void *src, int count)
468{
469 return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count);
470}
471EXPORT_SYMBOL_GPL(sdio_memcpy_toio);
472
473
474
475
476
477
478
479
480
481
482
483int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr,
484 int count)
485{
486 return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count);
487}
488EXPORT_SYMBOL_GPL(sdio_readsb);
489
490
491
492
493
494
495
496
497
498
499
500int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src,
501 int count)
502{
503 return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count);
504}
505EXPORT_SYMBOL_GPL(sdio_writesb);
506
507
508
509
510
511
512
513
514
515
516
517u16 sdio_readw(struct sdio_func *func, unsigned int addr, int *err_ret)
518{
519 int ret;
520
521 if (err_ret)
522 *err_ret = 0;
523
524 ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2);
525 if (ret) {
526 if (err_ret)
527 *err_ret = ret;
528 return 0xFFFF;
529 }
530
531 return le16_to_cpup((__le16 *)func->tmpbuf);
532}
533EXPORT_SYMBOL_GPL(sdio_readw);
534
535
536
537
538
539
540
541
542
543
544
545
546void sdio_writew(struct sdio_func *func, u16 b, unsigned int addr, int *err_ret)
547{
548 int ret;
549
550 *(__le16 *)func->tmpbuf = cpu_to_le16(b);
551
552 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
553 if (err_ret)
554 *err_ret = ret;
555}
556EXPORT_SYMBOL_GPL(sdio_writew);
557
558
559
560
561
562
563
564
565
566
567
568
569u32 sdio_readl(struct sdio_func *func, unsigned int addr, int *err_ret)
570{
571 int ret;
572
573 if (err_ret)
574 *err_ret = 0;
575
576 ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4);
577 if (ret) {
578 if (err_ret)
579 *err_ret = ret;
580 return 0xFFFFFFFF;
581 }
582
583 return le32_to_cpup((__le32 *)func->tmpbuf);
584}
585EXPORT_SYMBOL_GPL(sdio_readl);
586
587
588
589
590
591
592
593
594
595
596
597
598void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret)
599{
600 int ret;
601
602 *(__le32 *)func->tmpbuf = cpu_to_le32(b);
603
604 ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
605 if (err_ret)
606 *err_ret = ret;
607}
608EXPORT_SYMBOL_GPL(sdio_writel);
609
610
611
612
613
614
615
616
617
618
619
620unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr,
621 int *err_ret)
622{
623 int ret;
624 unsigned char val;
625
626 BUG_ON(!func);
627
628 if (err_ret)
629 *err_ret = 0;
630
631 ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val);
632 if (ret) {
633 if (err_ret)
634 *err_ret = ret;
635 return 0xFF;
636 }
637
638 return val;
639}
640EXPORT_SYMBOL_GPL(sdio_f0_readb);
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
657 int *err_ret)
658{
659 int ret;
660
661 BUG_ON(!func);
662
663 if ((addr < 0xF0 || addr > 0xFF) && (!mmc_card_lenient_fn0(func->card))) {
664 if (err_ret)
665 *err_ret = -EINVAL;
666 return;
667 }
668
669 ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL);
670 if (err_ret)
671 *err_ret = ret;
672}
673EXPORT_SYMBOL_GPL(sdio_f0_writeb);
674
675
676
677
678
679
680
681
682
683
684
685mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func)
686{
687 BUG_ON(!func);
688 BUG_ON(!func->card);
689
690 return func->card->host->pm_caps;
691}
692EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps);
693
694
695
696
697
698
699
700
701
702
703
704
705
706int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
707{
708 struct mmc_host *host;
709
710 BUG_ON(!func);
711 BUG_ON(!func->card);
712
713 host = func->card->host;
714
715 if (flags & ~host->pm_caps)
716 return -EINVAL;
717
718
719 host->pm_flags |= flags;
720 return 0;
721}
722EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
723