1 /*
2 * Copyright (c) 2017 Google LLC.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT zephyr_mmc_spi_slot
8
9 #include <logging/log.h>
10
11 LOG_MODULE_REGISTER(sdmmc_spi, CONFIG_SDMMC_LOG_LEVEL);
12
13 #include <drivers/disk.h>
14 #include <drivers/gpio.h>
15 #include <sys/byteorder.h>
16 #include <drivers/spi.h>
17 #include <sys/crc.h>
18 #include "sdmmc_sdhc.h"
19
20 /* Clock speed used during initialisation */
21 #define SDHC_SPI_INIT_SPEED KHZ(400)
22 /* Maximum clock speed used after initialisation (actual speed set in DTS).
23 * SD Specifications Part 1 Physical layer states 25MHz maximum.
24 */
25 #define SDHC_SPI_MAX_OPER_SPEED MHZ(25)
26
27 #define SPI_SDHC_NODE DT_DRV_INST(0)
28
29 #if !DT_NODE_HAS_STATUS(SPI_SDHC_NODE, okay)
30 #warning NO SDHC slot specified on board
31 #else
32 struct sdhc_spi_data {
33 const struct device *spi;
34 const struct spi_config *spi_cfg;
35 bool high_capacity;
36 uint32_t sector_count;
37 uint8_t status;
38 #if LOG_LEVEL >= LOG_LEVEL_DBG
39 int trace_dir;
40 #endif
41 };
42
43 struct sdhc_spi_config {
44 struct spi_config init_cfg;
45 struct spi_config oper_cfg;
46 #if DT_SPI_DEV_HAS_CS_GPIOS(SPI_SDHC_NODE)
47 struct spi_cs_control cs;
48 #endif
49 };
50
sdhc_spi_set_status(const struct device * dev,uint8_t status)51 static void sdhc_spi_set_status(const struct device *dev, uint8_t status)
52 {
53 struct sdhc_spi_data *data = dev->data;
54 const struct sdhc_spi_config *cfg = dev->config;
55
56 data->status = status;
57 if (status == DISK_STATUS_UNINIT) {
58 data->spi_cfg = &cfg->init_cfg;
59 } else if (status == DISK_STATUS_OK) {
60 data->spi_cfg = &cfg->oper_cfg;
61 }
62 }
63
64 /* Traces card traffic for LOG_LEVEL_DBG */
sdhc_spi_trace(struct sdhc_spi_data * data,int dir,int err,const uint8_t * buf,int len)65 static int sdhc_spi_trace(struct sdhc_spi_data *data, int dir, int err,
66 const uint8_t *buf, int len)
67 {
68 #if LOG_LEVEL >= LOG_LEVEL_DBG
69 if (err != 0) {
70 printk("(err=%d)", err);
71 data->trace_dir = 0;
72 }
73
74 if (dir != data->trace_dir) {
75 data->trace_dir = dir;
76
77 printk("\n");
78
79 if (dir == 1) {
80 printk(">>");
81 } else if (dir == -1) {
82 printk("<<");
83 }
84 }
85
86 for (; len != 0; len--) {
87 printk(" %x", *buf++);
88 }
89 #endif
90 return err;
91 }
92
93 /* Receives a fixed number of bytes */
sdhc_spi_rx_bytes(struct sdhc_spi_data * data,uint8_t * buf,int len)94 static int sdhc_spi_rx_bytes(struct sdhc_spi_data *data, uint8_t *buf, int len)
95 {
96 struct spi_buf tx_bufs[] = {
97 {
98 .buf = (uint8_t *)sdhc_ones,
99 .len = len
100 }
101 };
102
103 const struct spi_buf_set tx = {
104 .buffers = tx_bufs,
105 .count = 1,
106 };
107
108 struct spi_buf rx_bufs[] = {
109 {
110 .buf = buf,
111 .len = len
112 }
113 };
114
115 const struct spi_buf_set rx = {
116 .buffers = rx_bufs,
117 .count = 1,
118 };
119
120 return sdhc_spi_trace(data, -1,
121 spi_transceive(data->spi, data->spi_cfg, &tx, &rx),
122 buf, len);
123 }
124
125 /* Receives and returns a single byte */
sdhc_spi_rx_u8(struct sdhc_spi_data * data)126 static int sdhc_spi_rx_u8(struct sdhc_spi_data *data)
127 {
128 uint8_t buf[1];
129 int err = sdhc_spi_rx_bytes(data, buf, sizeof(buf));
130
131 if (err != 0) {
132 return err;
133 }
134
135 return buf[0];
136 }
137
138 /* Transmits a block of bytes */
sdhc_spi_tx(struct sdhc_spi_data * data,const uint8_t * buf,int len)139 static int sdhc_spi_tx(struct sdhc_spi_data *data, const uint8_t *buf, int len)
140 {
141 struct spi_buf spi_bufs[] = {
142 {
143 .buf = (uint8_t *)buf,
144 .len = len
145 }
146 };
147
148 const struct spi_buf_set tx = {
149 .buffers = spi_bufs,
150 .count = 1
151 };
152
153 return sdhc_spi_trace(data, 1,
154 spi_write(data->spi, data->spi_cfg, &tx), buf,
155 len);
156 }
157
158 /* Transmits the command and payload */
sdhc_spi_tx_cmd(struct sdhc_spi_data * data,uint8_t cmd,uint32_t payload)159 static int sdhc_spi_tx_cmd(struct sdhc_spi_data *data, uint8_t cmd, uint32_t payload)
160 {
161 uint8_t buf[SDHC_CMD_SIZE];
162
163 LOG_DBG("cmd%d payload=%u", cmd, payload);
164 sdhc_spi_trace(data, 0, 0, NULL, 0);
165
166 /* Encode the command */
167 buf[0] = SDHC_TX | (cmd & ~SDHC_START);
168 sys_put_be32(payload, &buf[1]);
169
170 /* Add CRC and set LSB as 'end bit' */
171 buf[SDHC_CMD_BODY_SIZE] = crc7_be(0, buf, SDHC_CMD_BODY_SIZE) | 0x01;
172
173 return sdhc_spi_tx(data, buf, sizeof(buf));
174 }
175
176 /* Reads until anything but `discard` is received */
sdhc_spi_skip(struct sdhc_spi_data * data,int discard)177 static int sdhc_spi_skip(struct sdhc_spi_data *data, int discard)
178 {
179 int err;
180 struct sdhc_retry retry;
181
182 sdhc_retry_init(&retry, SDHC_READY_TIMEOUT, 0);
183
184 do {
185 err = sdhc_spi_rx_u8(data);
186 if (err != discard) {
187 return err;
188 }
189 } while (sdhc_retry_ok(&retry));
190
191 LOG_WRN("Timeout while waiting for !%d", discard);
192 return -ETIMEDOUT;
193 }
194
195 /* Reads until the first byte in a response is received */
sdhc_spi_skip_until_start(struct sdhc_spi_data * data)196 static int sdhc_spi_skip_until_start(struct sdhc_spi_data *data)
197 {
198 struct sdhc_retry retry;
199 int status;
200
201 sdhc_retry_init(&retry, SDHC_READY_TIMEOUT, 0);
202
203 do {
204 status = sdhc_spi_rx_u8(data);
205 if (status < 0) {
206 return status;
207 }
208
209 if ((status & SDHC_START) == 0) {
210 return status;
211 }
212 } while (sdhc_retry_ok(&retry));
213
214 return -ETIMEDOUT;
215 }
216
217 /* Reads until the bus goes high */
sdhc_spi_skip_until_ready(struct sdhc_spi_data * data)218 static int sdhc_spi_skip_until_ready(struct sdhc_spi_data *data)
219 {
220 struct sdhc_retry retry;
221 int status;
222
223 sdhc_retry_init(&retry, SDHC_READY_TIMEOUT, 0);
224
225 do {
226 status = sdhc_spi_rx_u8(data);
227 if (status < 0) {
228 return status;
229 }
230
231 if (status == 0) {
232 /* Card is still busy */
233 continue;
234 }
235
236 if (status == 0xFF) {
237 return 0;
238 }
239
240 /* Got something else. Some cards release MISO part
241 * way through the transfer. Read another and see if
242 * MISO went high.
243 */
244 status = sdhc_spi_rx_u8(data);
245 if (status < 0) {
246 return status;
247 }
248
249 if (status == 0xFF) {
250 return 0;
251 }
252
253 return -EPROTO;
254 } while (sdhc_retry_ok(&retry));
255
256 return -ETIMEDOUT;
257 }
258
259 /* Sends a command and returns the received R1 status code */
sdhc_spi_cmd_r1_raw(struct sdhc_spi_data * data,uint8_t cmd,uint32_t payload)260 static int sdhc_spi_cmd_r1_raw(struct sdhc_spi_data *data,
261 uint8_t cmd, uint32_t payload)
262 {
263 int err;
264
265 err = sdhc_spi_tx_cmd(data, cmd, payload);
266 if (err != 0) {
267 return err;
268 }
269
270 err = sdhc_spi_skip_until_start(data);
271
272 /* Ensure there's a idle byte between commands */
273 if (cmd != SDHC_SEND_CSD && cmd != SDHC_SEND_CID &&
274 cmd != SDHC_READ_SINGLE_BLOCK && cmd != SDHC_READ_MULTIPLE_BLOCK &&
275 cmd != SDHC_WRITE_BLOCK && cmd != SDHC_WRITE_MULTIPLE_BLOCK) {
276 sdhc_spi_rx_u8(data);
277 }
278
279 return err;
280 }
281
282 /* Sends a command and returns the mapped error code */
sdhc_spi_cmd_r1(struct sdhc_spi_data * data,uint8_t cmd,uint32_t payload)283 static int sdhc_spi_cmd_r1(struct sdhc_spi_data *data,
284 uint8_t cmd, uint32_t payload)
285 {
286 return sdhc_map_r1_status(sdhc_spi_cmd_r1_raw(data, cmd, payload));
287 }
288
289 /* Sends a command in idle mode returns the mapped error code */
sdhc_spi_cmd_r1_idle(struct sdhc_spi_data * data,uint8_t cmd,uint32_t payload)290 static int sdhc_spi_cmd_r1_idle(struct sdhc_spi_data *data, uint8_t cmd,
291 uint32_t payload)
292 {
293 return sdhc_map_r1_idle_status(sdhc_spi_cmd_r1_raw(data, cmd, payload));
294 }
295
296 /* Sends a command and returns the received multi-byte R2 status code */
sdhc_spi_cmd_r2(struct sdhc_spi_data * data,uint8_t cmd,uint32_t payload)297 static int sdhc_spi_cmd_r2(struct sdhc_spi_data *data,
298 uint8_t cmd, uint32_t payload)
299 {
300 int err;
301 int r1;
302 int r2;
303
304 err = sdhc_spi_tx_cmd(data, cmd, payload);
305 if (err != 0) {
306 return err;
307 }
308
309 r1 = sdhc_map_r1_status(sdhc_spi_skip_until_start(data));
310 /* Always read the rest of the reply */
311 r2 = sdhc_spi_rx_u8(data);
312
313 /* Ensure there's a idle byte between commands */
314 sdhc_spi_rx_u8(data);
315
316 if (r1 < 0) {
317 return r1;
318 }
319
320 return r2;
321 }
322
323 /* Sends a command and returns the received multi-byte status code */
sdhc_spi_cmd_r37_raw(struct sdhc_spi_data * data,uint8_t cmd,uint32_t payload,uint32_t * reply)324 static int sdhc_spi_cmd_r37_raw(struct sdhc_spi_data *data,
325 uint8_t cmd, uint32_t payload, uint32_t *reply)
326 {
327 int err;
328 int status;
329 uint8_t buf[sizeof(*reply)];
330
331 err = sdhc_spi_tx_cmd(data, cmd, payload);
332 if (err != 0) {
333 return err;
334 }
335
336 status = sdhc_spi_skip_until_start(data);
337
338 /* Always read the rest of the reply */
339 err = sdhc_spi_rx_bytes(data, buf, sizeof(buf));
340 *reply = sys_get_be32(buf);
341
342 /* Ensure there's a idle byte between commands */
343 sdhc_spi_rx_u8(data);
344
345 if (err != 0) {
346 return err;
347 }
348
349 return status;
350 }
351
352 /* Sends a command in idle mode returns the mapped error code */
sdhc_spi_cmd_r7_idle(struct sdhc_spi_data * data,uint8_t cmd,uint32_t payload,uint32_t * reply)353 static int sdhc_spi_cmd_r7_idle(struct sdhc_spi_data *data,
354 uint8_t cmd, uint32_t payload, uint32_t *reply)
355 {
356 return sdhc_map_r1_idle_status(
357 sdhc_spi_cmd_r37_raw(data, cmd, payload, reply));
358 }
359
360 /* Sends a command and returns the received multi-byte R3 error code */
sdhc_spi_cmd_r3(struct sdhc_spi_data * data,uint8_t cmd,uint32_t payload,uint32_t * reply)361 static int sdhc_spi_cmd_r3(struct sdhc_spi_data *data,
362 uint8_t cmd, uint32_t payload, uint32_t *reply)
363 {
364 return sdhc_map_r1_status(
365 sdhc_spi_cmd_r37_raw(data, cmd, payload, reply));
366 }
367
368 /* Receives a SDHC data block */
sdhc_spi_rx_block(struct sdhc_spi_data * data,uint8_t * buf,int len)369 static int sdhc_spi_rx_block(struct sdhc_spi_data *data,
370 uint8_t *buf, int len)
371 {
372 int err;
373 int token;
374 int i;
375 /* Note the one extra byte to ensure there's an idle byte
376 * between commands.
377 */
378 uint8_t crc[SDHC_CRC16_SIZE + 1];
379
380 token = sdhc_spi_skip(data, 0xFF);
381 if (token < 0) {
382 return token;
383 }
384
385 if (token != SDHC_TOKEN_SINGLE) {
386 /* No start token */
387 return -EIO;
388 }
389
390 /* Read the data in batches */
391 for (i = 0; i < len; i += sizeof(sdhc_ones)) {
392 int remain = MIN(sizeof(sdhc_ones), len - i);
393
394 struct spi_buf tx_bufs[] = {
395 {
396 .buf = (uint8_t *)sdhc_ones,
397 .len = remain
398 }
399 };
400
401 const struct spi_buf_set tx = {
402 .buffers = tx_bufs,
403 .count = 1,
404 };
405
406 struct spi_buf rx_bufs[] = {
407 {
408 .buf = &buf[i],
409 .len = remain
410 }
411 };
412
413 const struct spi_buf_set rx = {
414 .buffers = rx_bufs,
415 .count = 1,
416 };
417
418 err = sdhc_spi_trace(data, -1,
419 spi_transceive(data->spi, data->spi_cfg,
420 &tx, &rx),
421 &buf[i], remain);
422 if (err != 0) {
423 return err;
424 }
425 }
426
427 err = sdhc_spi_rx_bytes(data, crc, sizeof(crc));
428 if (err != 0) {
429 return err;
430 }
431
432 if (sys_get_be16(crc) != crc16_itu_t(0, buf, len)) {
433 /* Bad CRC */
434 return -EILSEQ;
435 }
436
437 return 0;
438 }
439
440 /* Transmits a SDHC data block */
sdhc_spi_tx_block(struct sdhc_spi_data * data,uint8_t * send,int len)441 static int sdhc_spi_tx_block(struct sdhc_spi_data *data,
442 uint8_t *send, int len)
443 {
444 uint8_t buf[SDHC_CRC16_SIZE];
445 int err;
446
447 /* Start the block */
448 buf[0] = SDHC_TOKEN_SINGLE;
449 err = sdhc_spi_tx(data, buf, 1);
450 if (err != 0) {
451 return err;
452 }
453
454 /* Write the payload */
455 err = sdhc_spi_tx(data, send, len);
456 if (err != 0) {
457 return err;
458 }
459
460 /* Build and write the trailing CRC */
461 sys_put_be16(crc16_itu_t(0, send, len), buf);
462
463 err = sdhc_spi_tx(data, buf, sizeof(buf));
464 if (err != 0) {
465 return err;
466 }
467
468 return sdhc_map_data_status(sdhc_spi_rx_u8(data));
469 }
470
sdhc_spi_recover(struct sdhc_spi_data * data)471 static int sdhc_spi_recover(struct sdhc_spi_data *data)
472 {
473 /* TODO(nzmichaelh): implement */
474 return sdhc_spi_cmd_r1(data, SDHC_SEND_STATUS, 0);
475 }
476
477 /* Attempts to return the card to idle mode */
sdhc_spi_go_idle(struct sdhc_spi_data * data)478 static int sdhc_spi_go_idle(struct sdhc_spi_data *data)
479 {
480 /* Write the initial >= 74 clocks */
481 sdhc_spi_tx(data, sdhc_ones, 10);
482 spi_release(data->spi, data->spi_cfg);
483
484 return sdhc_spi_cmd_r1_idle(data, SDHC_GO_IDLE_STATE, 0);
485 }
486
487 /* Checks the supported host voltage and basic protocol of a SDHC card */
sdhc_spi_check_interface(struct sdhc_spi_data * data)488 static int sdhc_spi_check_interface(struct sdhc_spi_data *data)
489 {
490 uint32_t cond;
491 int err;
492
493 /* Check that the current voltage is supported */
494 err = sdhc_spi_cmd_r7_idle(data, SDHC_SEND_IF_COND,
495 SDHC_VHS_3V3 | SDHC_CHECK, &cond);
496 if (err != 0) {
497 return err;
498 }
499
500 if ((cond & 0xFF) != SDHC_CHECK) {
501 /* Card returned a different check pattern */
502 return -ENOENT;
503 }
504
505 if ((cond & SDHC_VHS_MASK) != SDHC_VHS_3V3) {
506 /* Card doesn't support this voltage */
507 return -ENOTSUP;
508 }
509
510 return 0;
511 }
512
513 /* Detect and initialise the card */
sdhc_spi_detect(const struct device * dev)514 static int sdhc_spi_detect(const struct device *dev)
515 {
516 struct sdhc_spi_data *data = dev->data;
517
518 int err;
519 uint32_t ocr;
520 struct sdhc_retry retry;
521 uint8_t structure;
522 uint8_t readbllen;
523 uint32_t csize;
524 uint8_t csizemult;
525 uint8_t buf[SDHC_CSD_SIZE];
526 bool is_v2;
527
528 sdhc_spi_set_status(dev, DISK_STATUS_UNINIT);
529
530 sdhc_retry_init(&retry, SDHC_INIT_TIMEOUT, SDHC_RETRY_DELAY);
531
532 /* Synchronise with the card by sending it to idle */
533 do {
534 err = sdhc_spi_go_idle(data);
535 if (err == 0) {
536 err = sdhc_spi_check_interface(data);
537 is_v2 = (err == 0) ? true : false;
538 break;
539 }
540
541 if (!sdhc_retry_ok(&retry)) {
542 return -ENOENT;
543 }
544 } while (true);
545
546 /* Enable CRC mode */
547 err = sdhc_spi_cmd_r1_idle(data, SDHC_CRC_ON_OFF, 1);
548 if (err != 0) {
549 return err;
550 }
551
552 /* Wait for the card to leave idle state */
553 do {
554 sdhc_spi_cmd_r1_raw(data, SDHC_APP_CMD, 0);
555
556 /* Set HCS only if card conforms to specification v2.00 (cf. 4.2.3) */
557 err = sdhc_spi_cmd_r1(data, SDHC_SEND_OP_COND, is_v2 ? SDHC_HCS : 0);
558 if (err == 0) {
559 break;
560 }
561 } while (sdhc_retry_ok(&retry));
562
563 if (err != 0) {
564 /* Card never exited idle */
565 return -ETIMEDOUT;
566 }
567
568 ocr = 0;
569 if (is_v2) {
570 do {
571 /* Read OCR to check if this is a SDSC or SDHC card.
572 * CCS bit is valid after BUSY bit is set.
573 */
574 err = sdhc_spi_cmd_r3(data, SDHC_READ_OCR, 0, &ocr);
575 if (err != 0) {
576 return err;
577 }
578 if ((ocr & SDHC_BUSY) != 0U) {
579 break;
580 }
581 } while (sdhc_retry_ok(&retry));
582 }
583
584 if ((ocr & SDHC_CCS) != 0U) {
585 data->high_capacity = true;
586 } else {
587 /* A 'SDSC' card: Set block length to 512 bytes. */
588 data->high_capacity = false;
589 err = sdhc_spi_cmd_r1(data, SDHC_SET_BLOCK_SIZE, SDMMC_DEFAULT_BLOCK_SIZE);
590 if (err != 0) {
591 return err;
592 }
593 }
594
595 /* Read the CSD */
596 err = sdhc_spi_cmd_r1(data, SDHC_SEND_CSD, 0);
597 if (err != 0) {
598 return err;
599 }
600
601 err = sdhc_spi_rx_block(data, buf, sizeof(buf));
602 if (err != 0) {
603 return err;
604 }
605
606 /* Bits 126..127 are the structure version */
607 structure = (buf[0] >> 6);
608 switch (structure) {
609 case SDHC_CSD_V1:
610 /* The maximum read data block length is given by bits 80..83 raised
611 * to the power of 2. Possible values are 9, 10 and 11 for 512, 1024
612 * and 2048 bytes, respectively. This driver does not make use of block
613 * lengths greater than 512 bytes, but forces 512 byte block transfers
614 * instead.
615 */
616 readbllen = buf[5] & ((1 << 4) - 1);
617 if ((readbllen < 9) || (readbllen > 11)) {
618 /* Invalid maximum read data block length (cf. section 5.3.2) */
619 return -ENOTSUP;
620 }
621 /* The capacity of the card is given by bits 62..73 plus 1 multiplied
622 * by bits 47..49 plus 2 raised to the power of 2 in maximum read data
623 * blocks.
624 */
625 csize = (sys_get_be32(&buf[6]) >> 14) & ((1 << 12) - 1);
626 csizemult = (uint8_t) ((sys_get_be16(&buf[9]) >> 7) & ((1 << 3) - 1));
627 data->sector_count = ((csize + 1) << (csizemult + 2 + readbllen - 9));
628 break;
629 case SDHC_CSD_V2:
630 /* Bits 48..69 are the capacity of the card in 512 KiB units, minus 1.
631 */
632 csize = sys_get_be32(&buf[6]) & ((1 << 22) - 1);
633 if (csize < 4112) {
634 /* Invalid capacity (cf. section 5.3.3) */
635 return -ENOTSUP;
636 }
637 data->sector_count = (csize + 1) *
638 (512 * 1024 / SDMMC_DEFAULT_BLOCK_SIZE);
639 break;
640 default:
641 /* Unsupported CSD format */
642 return -ENOTSUP;
643 }
644
645 LOG_INF("Found a ~%u MiB SDHC card.",
646 data->sector_count / (1024 * 1024 / SDMMC_DEFAULT_BLOCK_SIZE));
647
648 /* Read the CID */
649 err = sdhc_spi_cmd_r1(data, SDHC_SEND_CID, 0);
650 if (err != 0) {
651 return err;
652 }
653
654 err = sdhc_spi_rx_block(data, buf, sizeof(buf));
655 if (err != 0) {
656 return err;
657 }
658
659 LOG_INF("Manufacturer ID=%d OEM='%c%c' Name='%c%c%c%c%c' "
660 "Revision=0x%x Serial=0x%x",
661 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
662 buf[7], buf[8], sys_get_be32(&buf[9]));
663
664 /* Initilisation complete */
665 sdhc_spi_set_status(dev, DISK_STATUS_OK);
666
667 return 0;
668 }
669
sdhc_spi_read(struct sdhc_spi_data * data,uint8_t * buf,uint32_t sector,uint32_t count)670 static int sdhc_spi_read(struct sdhc_spi_data *data,
671 uint8_t *buf, uint32_t sector, uint32_t count)
672 {
673 int err;
674 uint32_t addr;
675
676 err = sdhc_map_disk_status(data->status);
677 if (err != 0) {
678 return err;
679 }
680
681 /* Translate sector number to data address.
682 * SDSC cards use byte addressing, SDHC cards use block addressing.
683 */
684 if (data->high_capacity) {
685 addr = sector;
686 } else {
687 addr = sector * SDMMC_DEFAULT_BLOCK_SIZE;
688 }
689
690 /* Send the start read command */
691 err = sdhc_spi_cmd_r1(data, SDHC_READ_MULTIPLE_BLOCK, addr);
692 if (err != 0) {
693 goto error;
694 }
695
696 /* Read the sectors */
697 for (; count != 0U; count--) {
698 err = sdhc_spi_rx_block(data, buf, SDMMC_DEFAULT_BLOCK_SIZE);
699 if (err != 0) {
700 goto error;
701 }
702
703 buf += SDMMC_DEFAULT_BLOCK_SIZE;
704 }
705
706 /* Ignore the error as STOP_TRANSMISSION always returns 0x7F */
707 sdhc_spi_cmd_r1(data, SDHC_STOP_TRANSMISSION, 0);
708
709 /* Wait until the card becomes ready */
710 err = sdhc_spi_skip_until_ready(data);
711
712 error:
713 spi_release(data->spi, data->spi_cfg);
714
715 return err;
716 }
717
sdhc_spi_write(struct sdhc_spi_data * data,const uint8_t * buf,uint32_t sector,uint32_t count)718 static int sdhc_spi_write(struct sdhc_spi_data *data,
719 const uint8_t *buf, uint32_t sector, uint32_t count)
720 {
721 int err;
722 uint32_t addr;
723
724 err = sdhc_map_disk_status(data->status);
725 if (err != 0) {
726 return err;
727 }
728
729 /* Write the blocks one-by-one */
730 for (; count != 0U; count--) {
731 /* Translate sector number to data address.
732 * SDSC cards use byte addressing, SDHC cards use block addressing.
733 */
734 if (data->high_capacity) {
735 addr = sector;
736 } else {
737 addr = sector * SDMMC_DEFAULT_BLOCK_SIZE;
738 }
739
740 err = sdhc_spi_cmd_r1(data, SDHC_WRITE_BLOCK, addr);
741 if (err < 0) {
742 goto error;
743 }
744
745 err = sdhc_spi_tx_block(data, (uint8_t *)buf,
746 SDMMC_DEFAULT_BLOCK_SIZE);
747 if (err != 0) {
748 goto error;
749 }
750
751 /* Wait for the card to finish programming */
752 err = sdhc_spi_skip_until_ready(data);
753 if (err != 0) {
754 goto error;
755 }
756
757 err = sdhc_spi_cmd_r2(data, SDHC_SEND_STATUS, 0);
758 if (err != 0) {
759 goto error;
760 }
761
762 buf += SDMMC_DEFAULT_BLOCK_SIZE;
763 sector++;
764 }
765
766 err = 0;
767 error:
768 spi_release(data->spi, data->spi_cfg);
769
770 return err;
771 }
772
773 /* this function is optimized to write multiple blocks */
sdhc_spi_write_multi(struct sdhc_spi_data * data,const uint8_t * buf,uint32_t sector,uint32_t count)774 static int sdhc_spi_write_multi(struct sdhc_spi_data *data,
775 const uint8_t *buf, uint32_t sector, uint32_t count)
776 {
777 int err;
778 uint32_t addr;
779 uint8_t block[SDHC_CRC16_SIZE];
780
781 err = sdhc_map_disk_status(data->status);
782 if (err != 0) {
783 return err;
784 }
785
786 if (data->high_capacity) {
787 addr = sector;
788 } else {
789 addr = sector * SDMMC_DEFAULT_BLOCK_SIZE;
790 }
791
792 err = sdhc_spi_cmd_r1(data, SDHC_WRITE_MULTIPLE_BLOCK, addr);
793 if (err < 0) {
794 goto exit;
795 }
796
797 /* Write the blocks */
798 for (; count != 0U; count--) {
799 /* Start the block */
800 block[0] = SDHC_TOKEN_MULTI_WRITE;
801 err = sdhc_spi_tx(data, block, 1);
802 if (err != 0) {
803 goto exit;
804 }
805
806 /* Write the payload */
807 err = sdhc_spi_tx(data, buf, SDMMC_DEFAULT_BLOCK_SIZE);
808 if (err != 0) {
809 goto exit;
810 }
811
812 /* Build and write the trailing CRC */
813 sys_put_be16(crc16_itu_t(0, buf, SDMMC_DEFAULT_BLOCK_SIZE),
814 block);
815
816 err = sdhc_spi_tx(data, block, sizeof(block));
817 if (err != 0) {
818 goto exit;
819 }
820
821 err = sdhc_map_data_status(sdhc_spi_rx_u8(data));
822 if (err != 0) {
823 goto exit;
824 }
825
826 /* Wait for the card to finish programming */
827 err = sdhc_spi_skip_until_ready(data);
828 if (err != 0) {
829 goto exit;
830 }
831
832 buf += SDMMC_DEFAULT_BLOCK_SIZE;
833 sector++;
834 }
835
836 /* Stop the transmission */
837 sdhc_spi_tx_cmd(data, SDHC_STOP_TRANSMISSION, 0);
838
839 /* Wait for the card to finish operation */
840 err = sdhc_spi_skip_until_ready(data);
841 if (err != 0) {
842 goto exit;
843 }
844
845 err = 0;
846 exit:
847 spi_release(data->spi, data->spi_cfg);
848
849 return err;
850 }
851
852 static int disk_spi_sdhc_init(const struct device *dev);
853
sdhc_spi_init(const struct device * dev)854 static int sdhc_spi_init(const struct device *dev)
855 {
856 struct sdhc_spi_data *data = dev->data;
857
858 data->spi = device_get_binding(DT_BUS_LABEL(SPI_SDHC_NODE));
859
860 disk_spi_sdhc_init(dev);
861
862 return 0;
863 }
864
disk_spi_sdhc_access_status(struct disk_info * disk)865 static int disk_spi_sdhc_access_status(struct disk_info *disk)
866 {
867 const struct device *dev = disk->dev;
868 struct sdhc_spi_data *data = dev->data;
869
870 return data->status;
871 }
872
disk_spi_sdhc_access_read(struct disk_info * disk,uint8_t * buf,uint32_t sector,uint32_t count)873 static int disk_spi_sdhc_access_read(struct disk_info *disk,
874 uint8_t *buf, uint32_t sector, uint32_t count)
875 {
876 const struct device *dev = disk->dev;
877 struct sdhc_spi_data *data = dev->data;
878 int err;
879
880 LOG_DBG("sector=%u count=%u", sector, count);
881
882 err = sdhc_spi_read(data, buf, sector, count);
883 if (err != 0 && sdhc_is_retryable(err)) {
884 sdhc_spi_recover(data);
885 err = sdhc_spi_read(data, buf, sector, count);
886 }
887
888 return err;
889 }
890
disk_spi_sdhc_access_write(struct disk_info * disk,const uint8_t * buf,uint32_t sector,uint32_t count)891 static int disk_spi_sdhc_access_write(struct disk_info *disk,
892 const uint8_t *buf, uint32_t sector, uint32_t count)
893 {
894 const struct device *dev = disk->dev;
895 struct sdhc_spi_data *data = dev->data;
896 int err;
897
898 /* for more than 2 blocks the multiple block is preferred */
899 if (count > 2) {
900 LOG_DBG("multi block sector=%u count=%u", sector, count);
901
902 err = sdhc_spi_write_multi(data, buf, sector, count);
903 if (err != 0 && sdhc_is_retryable(err)) {
904 sdhc_spi_recover(data);
905 err = sdhc_spi_write_multi(data, buf, sector, count);
906 }
907 } else {
908 LOG_DBG("sector=%u count=%u", sector, count);
909
910 err = sdhc_spi_write(data, buf, sector, count);
911 if (err != 0 && sdhc_is_retryable(err)) {
912 sdhc_spi_recover(data);
913 err = sdhc_spi_write(data, buf, sector, count);
914 }
915 }
916 return err;
917 }
918
disk_spi_sdhc_access_ioctl(struct disk_info * disk,uint8_t cmd,void * buf)919 static int disk_spi_sdhc_access_ioctl(struct disk_info *disk,
920 uint8_t cmd, void *buf)
921 {
922 const struct device *dev = disk->dev;
923 struct sdhc_spi_data *data = dev->data;
924 int err;
925
926 err = sdhc_map_disk_status(data->status);
927 if (err != 0) {
928 return err;
929 }
930
931 switch (cmd) {
932 case DISK_IOCTL_CTRL_SYNC:
933 break;
934 case DISK_IOCTL_GET_SECTOR_COUNT:
935 *(uint32_t *)buf = data->sector_count;
936 break;
937 case DISK_IOCTL_GET_SECTOR_SIZE:
938 *(uint32_t *)buf = SDMMC_DEFAULT_BLOCK_SIZE;
939 break;
940 case DISK_IOCTL_GET_ERASE_BLOCK_SZ:
941 *(uint32_t *)buf = SDMMC_DEFAULT_BLOCK_SIZE;
942 break;
943 default:
944 return -EINVAL;
945 }
946
947 return 0;
948 }
949
disk_spi_sdhc_access_init(struct disk_info * disk)950 static int disk_spi_sdhc_access_init(struct disk_info *disk)
951 {
952 const struct device *dev = disk->dev;
953 struct sdhc_spi_data *data = dev->data;
954 int err;
955
956 err = sdhc_spi_detect(dev);
957 spi_release(data->spi, data->spi_cfg);
958
959 return err;
960 }
961
962 static const struct disk_operations spi_sdhc_disk_ops = {
963 .init = disk_spi_sdhc_access_init,
964 .status = disk_spi_sdhc_access_status,
965 .read = disk_spi_sdhc_access_read,
966 .write = disk_spi_sdhc_access_write,
967 .ioctl = disk_spi_sdhc_access_ioctl,
968 };
969
970 static struct disk_info spi_sdhc_disk = {
971 .name = CONFIG_SDMMC_VOLUME_NAME,
972 .ops = &spi_sdhc_disk_ops,
973 };
974
disk_spi_sdhc_init(const struct device * dev)975 static int disk_spi_sdhc_init(const struct device *dev)
976 {
977 sdhc_spi_set_status(dev, DISK_STATUS_UNINIT);
978
979 spi_sdhc_disk.dev = dev;
980
981 return disk_access_register(&spi_sdhc_disk);
982 }
983
984 static struct sdhc_spi_data sdhc_spi_data_0;
985
986 static const struct sdhc_spi_config sdhc_spi_cfg_0 = {
987 .init_cfg = {
988 .frequency = SDHC_SPI_INIT_SPEED,
989 .operation = SPI_WORD_SET(8) | SPI_HOLD_ON_CS,
990 .slave = DT_REG_ADDR(SPI_SDHC_NODE),
991 #if DT_SPI_DEV_HAS_CS_GPIOS(SPI_SDHC_NODE)
992 .cs = &sdhc_spi_cfg_0.cs,
993 #endif
994 },
995 .oper_cfg = {
996 .frequency = MIN(SDHC_SPI_MAX_OPER_SPEED,
997 DT_INST_PROP(0, spi_max_frequency)),
998 .operation = SPI_WORD_SET(8) | SPI_HOLD_ON_CS,
999 .slave = DT_REG_ADDR(SPI_SDHC_NODE),
1000 #if DT_SPI_DEV_HAS_CS_GPIOS(SPI_SDHC_NODE)
1001 .cs = &sdhc_spi_cfg_0.cs,
1002 #endif
1003 },
1004 #if DT_SPI_DEV_HAS_CS_GPIOS(SPI_SDHC_NODE)
1005 .cs = {
1006 .gpio_dev = DEVICE_DT_GET(DT_SPI_DEV_CS_GPIOS_CTLR(SPI_SDHC_NODE)),
1007 .gpio_pin = DT_SPI_DEV_CS_GPIOS_PIN(SPI_SDHC_NODE),
1008 .gpio_dt_flags = DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_SDHC_NODE),
1009 },
1010 #endif
1011 };
1012
1013 DEVICE_DT_INST_DEFINE(0, sdhc_spi_init, NULL,
1014 &sdhc_spi_data_0, &sdhc_spi_cfg_0,
1015 POST_KERNEL, CONFIG_SDMMC_INIT_PRIORITY, NULL);
1016 #endif
1017