coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
spi_sdcard.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #include <stdint.h>
3 #include <string.h>
4 #include <spi-generic.h>
5 #include <spi_sdcard.h>
6 #include <crc_byte.h>
7 #include <commonlib/helpers.h>
8 #include <console/console.h>
9 
10 //#define SPI_SDCARD_DEBUG
11 
12 #ifdef SPI_SDCARD_DEBUG
13 #define dprintk(fmt, args...) \
14  printk(BIOS_DEBUG, fmt, ##args)
15 #else
16 #define dprintk(fmt, args...) \
17  do {} while (0)
18 #endif
19 
20 #define SDCARD_TYPE_SDSC 1
21 #define SDCARD_TYPE_SDHC 2
22 #define SDCARD_TYPE_SDXC 3
23 
24 /* CMD */
25 #define GO_IDLE_STATE 0
26 #define SEND_OP_COND 1
27 #define SWITCH_FUNC 6
28 #define SEND_IF_COND 8
29 #define SEND_CSD 9
30 #define SEND_CID 10
31 #define STOP_TRANSMISSION 12
32 #define SEND_STATUS 13
33 #define SET_BLOCKLEN 16
34 #define READ_SINGLE_BLOCK 17
35 #define READ_MULTIPLEBLOCK 18
36 #define WRITE_BLOCK 24
37 #define WRITE_MULTIPLEBLOCK 25
38 #define PROGRAM_CSD 27
39 #define SET_WRITE_PROT 28
40 #define CLR_WRITE_PROT 29
41 #define SEND_WRITE_PROT 30
42 #define ERASE_WR_BLK_START_ADDR 32
43 #define ERASE_WR_BLK_END_ADDR 33
44 #define ERASE 38
45 #define LOCK_UNLOCK 42
46 #define APP_CMD 55
47 #define GEN_CMD 56
48 #define READ_OCR 58
49 #define CRC_ON_OFF 59
50 
51 /* ACMD */
52 #define SD_STATUS 13
53 #define SEND_NUM_WR_BLOCKS 22
54 #define SET_WR_BLK_ERASE_COUNT 23
55 #define SD_SEND_OP_COND 41
56 #define SET_CLR_CARD_DETECT 42
57 #define SEND_SCR 51
58 
59 /* control tokens */
60 #define CT_BLOCK_START 0xfe
61 #define CT_MULTIPLE_BLOCK_START 0xfc
62 #define CT_MULTIPLE_BLOCK_STOP 0xfd
63 #define CT_RESPONSE_MASK 0x1f
64 #define CT_RESPONSE_ACCEPTED 0x05
65 #define CT_RESPONSE_REJECTED_CRC 0x0b
66 #define CT_RESPONSE_REJECTED_WRITE_ERR 0x0d
67 
68 /* response type */
69 #define RSP_R1 0
70 #define RSP_R1b 1
71 #define RSP_R2 2
72 #define RSP_R3 3
73 #define RSP_R4 4
74 #define RSP_R5 5
75 #define RSP_R7 7
76 
77 #define RSP_ERR_CARD_IS_LOCKED (1 << 0)
78 #define RSP_ERR_WP_ERASE_SKIP (1 << 1)
79 #define RSP_ERR_GENERAL (1 << 2)
80 #define RSP_ERR_CC (1 << 3)
81 #define RSP_ERR_ECC (1 << 4)
82 #define RSP_ERR_WP_VIOLATION (1 << 5)
83 #define RSP_ERR_ERASE_PARAM (1 << 6)
84 #define RSP_ERR_OUT_OF_RANGE (1 << 7)
85 #define RSP_ERR_IN_IDLE (1 << 8)
86 #define RSP_ERR_ERASE_RESET (1 << 9)
87 #define RSP_ERR_ILLEGAL_COMMAND (1 << 10)
88 #define RSP_ERR_COM_CRC (1 << 11)
89 #define RSP_ERR_ERASE_SEQUENCE (1 << 12)
90 #define RSP_ERR_ADDRESS (1 << 13)
91 #define RSP_ERR_PARAMETER (1 << 14)
92 
93 #define BLOCK_SIZE 512
94 
95 static unsigned long long extract_bits(uint8_t *buff,
96  int width, int start, int end)
97 {
98  unsigned long long r = 0;
99  for (int i = end; i >= start; i--) {
100  int bitpos = width - i - 1;
101  int b = bitpos / 8;
102  int shift = 7 - bitpos % 8;
103  r = (r << 1) | ((buff[b] >> shift) & 1);
104  }
105  return r;
106 }
107 
108 static void spi_sdcard_enable_cs(const struct spi_sdcard *card)
109 {
111 }
112 
113 static void spi_sdcard_disable_cs(const struct spi_sdcard *card)
114 {
116 }
117 
118 static void spi_sdcard_sendbyte(const struct spi_sdcard *card, uint8_t b)
119 {
120  dprintk("sdcard -> %#x\n", b);
121  spi_xfer(&card->slave, &b, 1, NULL, 0);
122 }
123 
125 {
126  uint8_t b, t = 0xff;
127  spi_xfer(&card->slave, &t, 1, &b, 1);
128  dprintk("sdcard <- %#x\n", b);
129  return b;
130 }
131 
133 {
134  uint8_t crc = 0;
135  crc = crc7_byte(crc, (cmd | 0x40) & 0x7f);
136  crc = crc7_byte(crc, (argument >> (3 * 8)) & 0xff);
137  crc = crc7_byte(crc, (argument >> (2 * 8)) & 0xff);
138  crc = crc7_byte(crc, (argument >> (1 * 8)) & 0xff);
139  crc = crc7_byte(crc, (argument >> (0 * 8)) & 0xff);
140  return crc | 1;
141 }
142 
144 {
145  switch (cmd) {
146  case GO_IDLE_STATE:
147  case SEND_OP_COND:
148  case SWITCH_FUNC:
149  case SEND_CSD:
150  case SEND_CID:
151  case SET_BLOCKLEN:
152  case READ_SINGLE_BLOCK:
153  case READ_MULTIPLEBLOCK:
154  case WRITE_BLOCK:
155  case WRITE_MULTIPLEBLOCK:
156  case PROGRAM_CSD:
157  case SEND_WRITE_PROT:
160  case LOCK_UNLOCK:
161  case APP_CMD:
162  case GEN_CMD:
163  case CRC_ON_OFF:
164  return RSP_R1;
165  case STOP_TRANSMISSION:
166  case SET_WRITE_PROT:
167  case CLR_WRITE_PROT:
168  case ERASE:
169  return RSP_R1b;
170  case SEND_STATUS:
171  return RSP_R2;
172  case READ_OCR:
173  return RSP_R3;
174  case SEND_IF_COND:
175  return RSP_R7;
176  }
177  return -1;
178 }
179 
181 {
182  switch (cmd) {
183  case SEND_NUM_WR_BLOCKS:
185  case SD_SEND_OP_COND:
186  case SET_CLR_CARD_DETECT:
187  case SEND_SCR:
188  return RSP_R1;
189  case SD_STATUS:
190  return RSP_R2;
191  }
192  return -1;
193 }
194 
195 static int lookup_response_length(int response_type)
196 {
197  switch (response_type) {
198  case RSP_R1:
199  case RSP_R1b:
200  return 1;
201  case RSP_R2:
202  return 2;
203  case RSP_R3:
204  case RSP_R7:
205  return 5;
206  }
207  return -1;
208 }
209 
210 static int response_resolve(int response_type, uint8_t *response,
211  uint32_t *out_register)
212 {
213  __unused static const char * const sd_err[] = {
214  "Card is locked",
215  "wp erase skip | lock/unlok cmd failed",
216  "error",
217  "CC error",
218  "card err failed",
219  "wp violation",
220  "erase param",
221  "out of range | csd overwrite",
222  "in idle state",
223  "erase reset",
224  "illegal command",
225  "com crc error",
226  "erase sequence error",
227  "address error",
228  "parameter error"
229  };
230  uint8_t r1 = 0, r2 = 0;
231 
232  if ((response_type == RSP_R1)
233  || (response_type == RSP_R1b)
234  || (response_type == RSP_R2)
235  || (response_type == RSP_R3)
236  || (response_type == RSP_R7))
237  r1 = response[0];
238 
239  if (response_type == RSP_R2)
240  r2 = response[1];
241 
242  if (((response_type == RSP_R3) || (response_type == RSP_R7))
243  && (out_register != NULL)) {
244  *out_register = 0;
245  *out_register = (*out_register << 8) | response[1];
246  *out_register = (*out_register << 8) | response[2];
247  *out_register = (*out_register << 8) | response[3];
248  *out_register = (*out_register << 8) | response[4];
249  }
250 
251  if (r1 != 0 || r2 != 0) {
252  int i = 0;
253  uint16_t r = (r1 << 8) | r2;
254  while (r) {
255  if (r & 1)
256  dprintk("SDCARD ERROR: %s\n", sd_err[i]);
257  r = r >> 1;
258  i++;
259  }
260  return (r1 << 8) | r2;
261  }
262 
263  return 0;
264 }
265 
266 static int spi_sdcard_do_command_help(const struct spi_sdcard *card,
267  int is_acmd,
268  uint8_t cmd,
269  uint32_t argument,
270  uint32_t *out_register)
271 {
272  int ret, type, length, wait;
273  uint8_t crc, c, response[5];
274 
275  /* calculate crc for command */
276  crc = spi_sdcard_calculate_command_crc(cmd, argument);
277 
278  if (is_acmd)
279  dprintk("\nsdcard execute acmd%d, argument = %#x, crc = %#x\n",
280  cmd, argument, crc);
281  else
282  dprintk("\nsdcard execute cmd%d, argument = %#x, crc = %#x\n",
283  cmd, argument, crc);
284 
285  /* lookup response type of command */
286  if (!is_acmd)
288  else
290 
291  /* lookup response length of command */
293 
294  /* enable cs */
296 
297  /* just delay 8 clocks */
299 
300  /* send command */
301  spi_sdcard_sendbyte(card, (cmd | 0x40) & 0x7f);
302  /* send argument */
303  spi_sdcard_sendbyte(card, (argument >> (8 * 3)) & 0xff);
304  spi_sdcard_sendbyte(card, (argument >> (8 * 2)) & 0xff);
305  spi_sdcard_sendbyte(card, (argument >> (8 * 1)) & 0xff);
306  spi_sdcard_sendbyte(card, (argument >> (8 * 0)) & 0xff);
307  /* send crc */
309 
310  /* waitting for response */
311  wait = 0xffff;
312  while (((c = spi_sdcard_recvbyte(card)) & 0x80) && --wait)
313  ;
314  if (!wait) {
316  return -1; /* timeout */
317  }
318 
319  /* obtain response */
320  for (int i = 0; i < length; i++) {
321  response[i] = c;
323  }
324 
325  if (type == RSP_R1b) {
326  /* waitting done */
327  wait = 0xffffff;
328  while (c == 0 && --wait)
330  if (!wait) {
332  return -1; /* timeout */
333  }
334  }
335 
337 
338  ret = response_resolve(type, response, out_register);
339 
340  return ret;
341 }
342 
343 static int spi_sdcard_do_command(const struct spi_sdcard *card,
344  uint8_t cmd,
345  uint32_t argument,
346  uint32_t *out_register)
347 {
348  return spi_sdcard_do_command_help(card, 0, cmd, argument, out_register);
349 }
350 
351 static int spi_sdcard_do_app_command(const struct spi_sdcard *card,
352  uint8_t cmd,
353  uint32_t argument,
354  uint32_t *out_register)
355 {
356  /* CMD55 */
358  return -1;
359 
360  return spi_sdcard_do_command_help(card, 1, cmd, argument, out_register);
361 }
362 
363 size_t spi_sdcard_size(const struct spi_sdcard *card)
364 {
365  int wait;
366  uint8_t csd[16];
367  uint16_t c = 0;
368 
369  /* CMD9, send csd (128bits register) */
371  return -1;
372 
373  /* enable CS */
375 
376  /* waitting start block token */
377  wait = 0xffff;
378  while ((spi_sdcard_recvbyte(card) != CT_BLOCK_START) && --wait)
379  ;
380  if (!wait) {
382  return -1;
383  }
384 
385  /* receive data */
386  for (int i = 0; i < 16; i++) {
387  csd[i] = spi_sdcard_recvbyte(card);
388  c = crc16_byte(c, csd[i]);
389  }
390 
391  /* receive crc and verify check sum */
392  if (((c >> 8) & 0xff) != spi_sdcard_recvbyte(card)) {
394  return -1;
395  }
396  if (((c >> 0) & 0xff) != spi_sdcard_recvbyte(card)) {
398  return -1;
399  }
400 
401  /* disable cs */
403 
404  if (extract_bits(csd, 128, 126, 127) == 0) {
405  /* csd version 1.0 */
406  size_t c_size = extract_bits(csd, 128, 62, 73);
407  size_t mult = extract_bits(csd, 128, 47, 49);
408  size_t read_bl_len = extract_bits(csd, 128, 80, 83);
409  return (c_size + 1) * mult * (1 << read_bl_len);
410  }
411 
412  if (extract_bits(csd, 128, 126, 127) == 1) {
413  /* csd version 2.0 */
414  size_t c_size = extract_bits(csd, 128, 48, 69);
415  return (c_size + 1) * 512 * 1024;
416  }
417 
418  return -1;
419 }
420 
422  const unsigned int bus, const unsigned int cs)
423 {
424  int resolve, wait;
425  uint32_t ocr;
426 
427  /* initialize spi controller */
428  spi_setup_slave(bus, cs, &card->slave);
429 
430  /* must wait at least 74 clock ticks after reset
431  * disable cs pin to enter spi mode */
433  for (int i = 0; i < 10; i++)
434  spi_sdcard_sendbyte(card, 0xff);
435 
436  /* CMD0, reset sdcard */
437  wait = 0xffff;
439  != RSP_ERR_IN_IDLE) && --wait)
440  ;
441  if (!wait)
442  return -1; /* timeout */
443 
444  /* CMD8 */
445  resolve = spi_sdcard_do_command(card, SEND_IF_COND, 0x1aa, NULL);
446  if (resolve & RSP_ERR_ILLEGAL_COMMAND) {
447  /* ACMD41, initialize card */
448  wait = 0xffff;
449  while ((resolve = spi_sdcard_do_app_command(card,
450  SD_SEND_OP_COND, 0, NULL)) && --wait)
451  ;
452  if ((resolve & RSP_ERR_ILLEGAL_COMMAND) || !wait) {
453  wait = 0xffff;
454  /* CMD1, initialize card for 2.1mm SD Memory Card */
456  0, NULL) && --wait)
457  ;
458  if (!wait)
459  return -1; /* unknown card */
460  }
461  } else {
462  /* ACMD41, initialize card */
463  wait = 0xffff;
465  0x40000000, NULL) && --wait)
466  ;
467  if (!wait)
468  return -1;
469  }
470 
471  /* CMD58, read ocr register */
472  if (spi_sdcard_do_command(card, READ_OCR, 0, &ocr))
473  return -1;
474 
475  /* CMD16, set block length to 512 bytes */
477  return -1;
478 
479  /* CCS is bit30 of ocr register
480  * CCS = 0 -> SDSC
481  * CCS = 1 -> SDHC/SDXC
482  * */
483  if ((ocr & 0x40000000) == 0)
485  else {
486  /* size > 32G -> SDXC */
487  if (spi_sdcard_size(card) > 32LL * 1024 * 1024 * 1024)
489  else
491  }
492 
493  return 0;
494 }
495 
497  size_t block_address,
498  void *buff)
499 {
500  int wait;
501  uint16_t c = 0;
502 
503  if (card->type == SDCARD_TYPE_SDSC)
504  block_address = block_address * 512;
505 
506  /* CMD17, start single block read */
507  if (spi_sdcard_do_command(card, READ_SINGLE_BLOCK, block_address, NULL))
508  return -1;
509 
510  /* enable cs */
512 
513  /* waitting start block token */
514  wait = 0xffff;
515  while ((spi_sdcard_recvbyte(card) != CT_BLOCK_START) && --wait)
516  ;
517  if (!wait) { /* timeout */
519  return -1;
520  }
521 
522  /* receive data */
523  for (int i = 0; i < 512; i++) {
524  ((uint8_t *)buff)[i] = spi_sdcard_recvbyte(card);
525  c = crc16_byte(c, ((uint8_t *)buff)[i]);
526  }
527 
528  /* receive crc and verify check sum */
529  if (((c >> 8) & 0xff) != spi_sdcard_recvbyte(card)) {
531  return -1;
532  }
533  if (((c >> 0) & 0xff) != spi_sdcard_recvbyte(card)) {
535  return -1;
536  }
537 
538  /* disable cs */
540 
541  return 0;
542 }
543 
545  size_t start_block_address,
546  size_t end_block_address,
547  void *buff)
548 {
549  int wait;
550  int block_num = end_block_address - start_block_address + 1;
551  if (card->type == SDCARD_TYPE_SDSC) {
552  start_block_address = start_block_address * 512;
553  end_block_address = end_block_address * 512;
554  }
555  /* CMD18, start multiple block read */
557  READ_MULTIPLEBLOCK, start_block_address, NULL))
558  return -1;
559 
560  /* enable cs */
562 
563  for (int i = 0; i < block_num; i++) {
564  uint16_t c = 0;
565 
566  /* waitting start block token */
567  wait = 0xffff;
568  while ((spi_sdcard_recvbyte(card) != CT_BLOCK_START) && --wait)
569  ;
570  if (!wait) { /* timeout */
572  return -1;
573  }
574 
575  /* receive data */
576  for (int k = 0; k < 512; k++) {
578  ((uint8_t *)buff)[512 * i + k] = tmp;
579  c = crc16_byte(c, tmp);
580  }
581 
582  /* receive crc and verify check sum */
583  if (((c >> 8) & 0xff) != spi_sdcard_recvbyte(card)) {
585  return -1;
586  }
587  if (((c >> 0) & 0xff) != spi_sdcard_recvbyte(card)) {
589  return -1;
590  }
591  }
592 
593  /* disable cs */
595 
598  return -1;
599 
600  return 0;
601 }
602 
603 int spi_sdcard_read(const struct spi_sdcard *card,
604  void *dest,
605  size_t offset,
606  size_t count)
607 {
608  size_t start_block_address = offset / BLOCK_SIZE;
609  size_t end_block_address = (offset + count - 1) / BLOCK_SIZE;
610  size_t has_begin = !!(offset % BLOCK_SIZE);
611  size_t has_end = !!((offset + count) % BLOCK_SIZE);
612 
613  if (start_block_address == end_block_address) {
614  uint8_t tmp[BLOCK_SIZE];
615  size_t o = offset % BLOCK_SIZE;
616  size_t l = count;
617  if (spi_sdcard_single_read(card, start_block_address, tmp))
618  return -1;
619  memcpy(dest, tmp + o, l);
620  return 0;
621  }
622 
623  if (has_begin) {
624  uint8_t tmp[BLOCK_SIZE];
625  size_t o = offset % BLOCK_SIZE;
626  size_t l = BLOCK_SIZE - o;
627  if (spi_sdcard_single_read(card, start_block_address, tmp))
628  return -1;
629  memcpy(dest, tmp + o, l);
630  }
631 
632  if (start_block_address + has_begin <= end_block_address - has_end) {
633  size_t start_lba = start_block_address + has_begin;
634  size_t end_lba = end_block_address - has_end;
635  size_t o = has_begin ? BLOCK_SIZE - offset % BLOCK_SIZE : 0;
636  if (start_lba < end_lba) {
637  if (spi_sdcard_multiple_read(card, start_lba, end_lba,
638  dest + o))
639  return -1;
640  } else {
641  if (spi_sdcard_single_read(card, start_lba, dest + o))
642  return -1;
643  }
644  }
645 
646  if (has_end) {
647  uint8_t tmp[BLOCK_SIZE];
648  size_t o = 0;
649  size_t l = (offset + count) % BLOCK_SIZE;
650  if (spi_sdcard_single_read(card, end_block_address, tmp))
651  return -1;
652  memcpy(dest + count - l, tmp + o, l);
653  }
654 
655  return 0;
656 }
657 
659  size_t block_address,
660  void *buff)
661 {
662  int wait;
663  uint16_t c = 0;
664  if (card->type == SDCARD_TYPE_SDSC)
665  block_address = block_address * 512;
666 
667  if (spi_sdcard_do_command(card, WRITE_BLOCK, block_address, NULL))
668  return -1;
669 
670  /* eanbele cs */
672 
673  /* send start block token */
675 
676  /* send data */
677  for (int i = 0; i < 512; i++) {
678  spi_sdcard_sendbyte(card, ((uint8_t *)buff)[i]);
679  c = crc16_byte(c, ((uint8_t *)buff)[i]);
680  }
681 
682  /* send crc check sum */
683  spi_sdcard_sendbyte(card, 0xff & (c >> 8));
684  spi_sdcard_sendbyte(card, 0xff & (c >> 0));
685 
686  /* receive and verify data response token */
690  return -1;
691  }
692 
693  wait = 0xffff;
694  while ((spi_sdcard_recvbyte(card) == 0) && --wait)
695  ;/* wait for complete */
696  if (!wait) {
698  return -1;
699  }
700 
701  /* disable cs */
703 
704  return 0;
705 }
706 
708  size_t start_block_address,
709  size_t end_block_address,
710  void *buff)
711 {
712  int wait, ret = 0;
713  int block_num = end_block_address - start_block_address + 1;
714  if (card->type == SDCARD_TYPE_SDSC) {
715  start_block_address = start_block_address * 512;
716  end_block_address = end_block_address * 512;
717  }
718 
720  start_block_address, NULL))
721  return -1;
722 
723  /* enable cs */
725 
726  for (int i = 0; i < block_num; i++) {
727  uint16_t c = 0;
728 
729  ret = -1;
730 
731  /* send start block token */
733 
734  /* send data */
735  for (int k = 0; k < 512; k++) {
736  uint8_t tmp = ((uint8_t *)buff)[512 * i + k];
738  c = crc16_byte(c, tmp);
739  }
740 
741  /* send crc check sum */
742  spi_sdcard_sendbyte(card, 0xff & (c >> 8));
743  spi_sdcard_sendbyte(card, 0xff & (c >> 0));
744 
745  /* receive and verify data response token */
748  break;
749 
750  wait = 0xffff;
751  while ((spi_sdcard_recvbyte(card) == 0) && --wait)
752  ;/* wait for complete */
753  if (!wait)
754  break;
755 
756  ret = 0;
757  }
758 
759  /* send stop transmission token */
761 
762  /* disable cs */
764 
767  return -1;
768 
769  return ret;
770 }
771 
772 int spi_sdcard_erase(const struct spi_sdcard *card,
773  size_t start_block_address,
774  size_t end_block_address)
775 {
776  if (card->type == SDCARD_TYPE_SDSC) {
777  start_block_address = start_block_address * 512;
778  end_block_address = end_block_address * 512;
779  }
780 
781  /* CMD32, set erase start address */
783  start_block_address, NULL))
784  return -1;
785 
786  /* CMD33, set erase end address */
788  end_block_address, NULL))
789  return -1;
790 
791  /* CMD38, erase */
793  return -1;
794 
795  return 0;
796 }
797 
799 {
801 }
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
static int width
Definition: bochs.c:42
uint16_t crc16_byte(uint16_t prev_crc, uint8_t data)
Definition: crc_byte.c:17
uint8_t crc7_byte(uint8_t prev_crc, uint8_t data)
Definition: crc_byte.c:5
static void wait(unsigned int bus)
Definition: software_i2c.c:55
static size_t offset
Definition: flashconsole.c:16
uint64_t length
Definition: fw_cfg_if.h:1
#define __unused
Definition: helpers.h:38
unsigned int type
Definition: edid.c:57
static struct spi_sdcard card
Definition: media.c:26
int spi_claim_bus(const struct spi_slave *slave)
Definition: spi-generic.c:9
int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin)
Definition: spi-generic.c:68
void spi_release_bus(const struct spi_slave *slave)
Definition: spi-generic.c:17
int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
Definition: spi-generic.c:122
#define SEND_IF_COND
Definition: spi_sdcard.c:28
#define CT_RESPONSE_ACCEPTED
Definition: spi_sdcard.c:64
#define READ_SINGLE_BLOCK
Definition: spi_sdcard.c:34
#define SD_STATUS
Definition: spi_sdcard.c:52
#define ERASE
Definition: spi_sdcard.c:44
#define STOP_TRANSMISSION
Definition: spi_sdcard.c:31
#define RSP_R1b
Definition: spi_sdcard.c:70
#define READ_MULTIPLEBLOCK
Definition: spi_sdcard.c:35
static void spi_sdcard_sendbyte(const struct spi_sdcard *card, uint8_t b)
Definition: spi_sdcard.c:118
#define SDCARD_TYPE_SDXC
Definition: spi_sdcard.c:22
#define ERASE_WR_BLK_END_ADDR
Definition: spi_sdcard.c:43
#define SEND_OP_COND
Definition: spi_sdcard.c:26
#define SEND_CID
Definition: spi_sdcard.c:30
static int lookup_acmd_response_type(uint8_t cmd)
Definition: spi_sdcard.c:180
#define dprintk(fmt, args...)
Definition: spi_sdcard.c:16
int spi_sdcard_multiple_write(const struct spi_sdcard *card, size_t start_block_address, size_t end_block_address, void *buff)
Definition: spi_sdcard.c:707
#define RSP_R1
Definition: spi_sdcard.c:69
static uint8_t spi_sdcard_recvbyte(const struct spi_sdcard *card)
Definition: spi_sdcard.c:124
#define SD_SEND_OP_COND
Definition: spi_sdcard.c:55
static void spi_sdcard_disable_cs(const struct spi_sdcard *card)
Definition: spi_sdcard.c:113
int spi_sdcard_read(const struct spi_sdcard *card, void *dest, size_t offset, size_t count)
Definition: spi_sdcard.c:603
#define CT_MULTIPLE_BLOCK_STOP
Definition: spi_sdcard.c:62
static int spi_sdcard_do_app_command(const struct spi_sdcard *card, uint8_t cmd, uint32_t argument, uint32_t *out_register)
Definition: spi_sdcard.c:351
static void spi_sdcard_enable_cs(const struct spi_sdcard *card)
Definition: spi_sdcard.c:108
#define ERASE_WR_BLK_START_ADDR
Definition: spi_sdcard.c:42
#define SET_WR_BLK_ERASE_COUNT
Definition: spi_sdcard.c:54
#define CRC_ON_OFF
Definition: spi_sdcard.c:49
#define RSP_R7
Definition: spi_sdcard.c:75
static int lookup_response_length(int response_type)
Definition: spi_sdcard.c:195
#define CT_RESPONSE_MASK
Definition: spi_sdcard.c:63
#define WRITE_MULTIPLEBLOCK
Definition: spi_sdcard.c:37
#define SEND_NUM_WR_BLOCKS
Definition: spi_sdcard.c:53
#define WRITE_BLOCK
Definition: spi_sdcard.c:36
#define SDCARD_TYPE_SDHC
Definition: spi_sdcard.c:21
#define SEND_STATUS
Definition: spi_sdcard.c:32
static int spi_sdcard_do_command_help(const struct spi_sdcard *card, int is_acmd, uint8_t cmd, uint32_t argument, uint32_t *out_register)
Definition: spi_sdcard.c:266
#define SEND_CSD
Definition: spi_sdcard.c:29
#define SWITCH_FUNC
Definition: spi_sdcard.c:27
static unsigned long long extract_bits(uint8_t *buff, int width, int start, int end)
Definition: spi_sdcard.c:95
#define GO_IDLE_STATE
Definition: spi_sdcard.c:25
int spi_sdcard_single_write(const struct spi_sdcard *card, size_t block_address, void *buff)
Definition: spi_sdcard.c:658
#define SEND_SCR
Definition: spi_sdcard.c:57
#define READ_OCR
Definition: spi_sdcard.c:48
#define LOCK_UNLOCK
Definition: spi_sdcard.c:45
static int spi_sdcard_do_command(const struct spi_sdcard *card, uint8_t cmd, uint32_t argument, uint32_t *out_register)
Definition: spi_sdcard.c:343
static int lookup_cmd_response_type(uint8_t cmd)
Definition: spi_sdcard.c:143
int spi_sdcard_erase(const struct spi_sdcard *card, size_t start_block_address, size_t end_block_address)
Definition: spi_sdcard.c:772
#define SDCARD_TYPE_SDSC
Definition: spi_sdcard.c:20
static uint8_t spi_sdcard_calculate_command_crc(uint8_t cmd, uint32_t argument)
Definition: spi_sdcard.c:132
static int response_resolve(int response_type, uint8_t *response, uint32_t *out_register)
Definition: spi_sdcard.c:210
#define SEND_WRITE_PROT
Definition: spi_sdcard.c:41
int spi_sdcard_erase_all(const struct spi_sdcard *card)
Definition: spi_sdcard.c:798
#define CLR_WRITE_PROT
Definition: spi_sdcard.c:40
int spi_sdcard_single_read(const struct spi_sdcard *card, size_t block_address, void *buff)
Definition: spi_sdcard.c:496
#define APP_CMD
Definition: spi_sdcard.c:46
#define SET_CLR_CARD_DETECT
Definition: spi_sdcard.c:56
#define PROGRAM_CSD
Definition: spi_sdcard.c:38
#define BLOCK_SIZE
Definition: spi_sdcard.c:93
#define SET_WRITE_PROT
Definition: spi_sdcard.c:39
#define RSP_ERR_IN_IDLE
Definition: spi_sdcard.c:85
#define RSP_R2
Definition: spi_sdcard.c:71
int spi_sdcard_init(struct spi_sdcard *card, const unsigned int bus, const unsigned int cs)
Definition: spi_sdcard.c:421
int spi_sdcard_multiple_read(const struct spi_sdcard *card, size_t start_block_address, size_t end_block_address, void *buff)
Definition: spi_sdcard.c:544
#define SET_BLOCKLEN
Definition: spi_sdcard.c:33
#define CT_BLOCK_START
Definition: spi_sdcard.c:60
#define GEN_CMD
Definition: spi_sdcard.c:47
#define CT_MULTIPLE_BLOCK_START
Definition: spi_sdcard.c:61
#define RSP_R3
Definition: spi_sdcard.c:72
size_t spi_sdcard_size(const struct spi_sdcard *card)
Definition: spi_sdcard.c:363
#define RSP_ERR_ILLEGAL_COMMAND
Definition: spi_sdcard.c:87
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
Definition: device.h:76
struct spi_slave slave
Definition: spi_sdcard.h:10
int type
Definition: spi_sdcard.h:9
#define c(value, pmcreg, dst_bits)
#define count